convert do_remount_sb() to fs_context
Replace do_remount_sb() with a function, reconfigure_super(), that's fs_context aware. The fs_context is expected to be parameterised already and have ->root pointing to the superblock to be reconfigured. A legacy wrapper is provided that is intended to be called from the fs_context ops when those appear, but for now is called directly from reconfigure_super(). This wrapper invokes the ->remount_fs() superblock op for the moment. It is intended that the remount_fs() op will be phased out. The fs_context->purpose is set to FS_CONTEXT_FOR_RECONFIGURE to indicate that the context is being used for reconfiguration. do_umount_root() is provided to consolidate remount-to-R/O for umount and emergency remount by creating a context and invoking reconfiguration. do_remount(), do_umount() and do_emergency_remount_callback() are switched to use the new process. [AV -- fold UMOUNT and EMERGENCY_REMOUNT in; fixes the umount / bug, gets rid of pointless complexity] [AV -- set ->net_ns in all cases; nfs remount will need that] [AV -- shift security_sb_remount() call into reconfigure_super(); the callers that didn't do security_sb_remount() have NULL fc->security anyway, so it's a no-op for them] Signed-off-by: David Howells <dhowells@redhat.com> Co-developed-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
@@ -69,6 +69,13 @@ static struct fs_context *alloc_fs_context(struct file_system_type *fs_type,
|
||||
case FS_CONTEXT_FOR_MOUNT:
|
||||
fc->user_ns = get_user_ns(fc->cred->user_ns);
|
||||
break;
|
||||
case FS_CONTEXT_FOR_RECONFIGURE:
|
||||
/* We don't pin any namespaces as the superblock's
|
||||
* subscriptions cannot be changed at this point.
|
||||
*/
|
||||
atomic_inc(&reference->d_sb->s_active);
|
||||
fc->root = dget(reference);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = legacy_init_fs_context(fc);
|
||||
@@ -90,6 +97,15 @@ struct fs_context *fs_context_for_mount(struct file_system_type *fs_type,
|
||||
}
|
||||
EXPORT_SYMBOL(fs_context_for_mount);
|
||||
|
||||
struct fs_context *fs_context_for_reconfigure(struct dentry *dentry,
|
||||
unsigned int sb_flags,
|
||||
unsigned int sb_flags_mask)
|
||||
{
|
||||
return alloc_fs_context(dentry->d_sb->s_type, dentry, sb_flags,
|
||||
sb_flags_mask, FS_CONTEXT_FOR_RECONFIGURE);
|
||||
}
|
||||
EXPORT_SYMBOL(fs_context_for_reconfigure);
|
||||
|
||||
void fc_drop_locked(struct fs_context *fc)
|
||||
{
|
||||
struct super_block *sb = fc->root->d_sb;
|
||||
@@ -99,6 +115,7 @@ void fc_drop_locked(struct fs_context *fc)
|
||||
}
|
||||
|
||||
static void legacy_fs_context_free(struct fs_context *fc);
|
||||
|
||||
/**
|
||||
* put_fs_context - Dispose of a superblock configuration context.
|
||||
* @fc: The context to dispose of.
|
||||
@@ -118,8 +135,7 @@ void put_fs_context(struct fs_context *fc)
|
||||
legacy_fs_context_free(fc);
|
||||
|
||||
security_free_mnt_opts(&fc->security);
|
||||
if (fc->net_ns)
|
||||
put_net(fc->net_ns);
|
||||
put_net(fc->net_ns);
|
||||
put_user_ns(fc->user_ns);
|
||||
put_cred(fc->cred);
|
||||
kfree(fc->subtype);
|
||||
@@ -172,6 +188,21 @@ int legacy_get_tree(struct fs_context *fc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle remount.
|
||||
*/
|
||||
int legacy_reconfigure(struct fs_context *fc)
|
||||
{
|
||||
struct legacy_fs_context *ctx = fc->fs_private;
|
||||
struct super_block *sb = fc->root->d_sb;
|
||||
|
||||
if (!sb->s_op->remount_fs)
|
||||
return 0;
|
||||
|
||||
return sb->s_op->remount_fs(sb, &fc->sb_flags,
|
||||
ctx ? ctx->legacy_data : NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialise a legacy context for a filesystem that doesn't support
|
||||
* fs_context.
|
||||
|
Reference in New Issue
Block a user