Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f3a09c92 authored by Al Viro's avatar Al Viro
Browse files

introduce fs_context methods



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent e1a91586
Loading
Loading
Loading
Loading
+22 −6
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ static struct fs_context *alloc_fs_context(struct file_system_type *fs_type,
				      unsigned int sb_flags_mask,
				      enum fs_context_purpose purpose)
{
	int (*init_fs_context)(struct fs_context *);
	struct fs_context *fc;
	int ret = -ENOMEM;

@@ -81,7 +82,12 @@ static struct fs_context *alloc_fs_context(struct file_system_type *fs_type,
		break;
	}

	ret = legacy_init_fs_context(fc);
	/* TODO: Make all filesystems support this unconditionally */
	init_fs_context = fc->fs_type->init_fs_context;
	if (!init_fs_context)
		init_fs_context = legacy_init_fs_context;

	ret = init_fs_context(fc);
	if (ret < 0)
		goto err_fc;
	fc->need_free = true;
@@ -141,8 +147,8 @@ void put_fs_context(struct fs_context *fc)
		deactivate_super(sb);
	}

	if (fc->need_free)
		legacy_fs_context_free(fc);
	if (fc->need_free && fc->ops && fc->ops->free)
		fc->ops->free(fc);

	security_free_mnt_opts(&fc->security);
	put_net(fc->net_ns);
@@ -180,7 +186,7 @@ static int legacy_parse_monolithic(struct fs_context *fc, void *data)
/*
 * Get a mountable root with the legacy mount command.
 */
int legacy_get_tree(struct fs_context *fc)
static int legacy_get_tree(struct fs_context *fc)
{
	struct legacy_fs_context *ctx = fc->fs_private;
	struct super_block *sb;
@@ -201,7 +207,7 @@ int legacy_get_tree(struct fs_context *fc)
/*
 * Handle remount.
 */
int legacy_reconfigure(struct fs_context *fc)
static int legacy_reconfigure(struct fs_context *fc)
{
	struct legacy_fs_context *ctx = fc->fs_private;
	struct super_block *sb = fc->root->d_sb;
@@ -213,6 +219,13 @@ int legacy_reconfigure(struct fs_context *fc)
				    ctx ? ctx->legacy_data : NULL);
}

const struct fs_context_operations legacy_fs_context_ops = {
	.free			= legacy_fs_context_free,
	.parse_monolithic	= legacy_parse_monolithic,
	.get_tree		= legacy_get_tree,
	.reconfigure		= legacy_reconfigure,
};

/*
 * Initialise a legacy context for a filesystem that doesn't support
 * fs_context.
@@ -222,10 +235,13 @@ static int legacy_init_fs_context(struct fs_context *fc)
	fc->fs_private = kzalloc(sizeof(struct legacy_fs_context), GFP_KERNEL);
	if (!fc->fs_private)
		return -ENOMEM;
	fc->ops = &legacy_fs_context_ops;
	return 0;
}

int parse_monolithic_mount_data(struct fs_context *fc, void *data)
{
	return legacy_parse_monolithic(fc, data);
	int (*monolithic_mount_data)(struct fs_context *, void *);
	monolithic_mount_data = fc->ops->parse_monolithic;
	return monolithic_mount_data(fc, data);
}
+0 −2
Original line number Diff line number Diff line
@@ -55,8 +55,6 @@ extern void __init chrdev_init(void);
/*
 * fs_context.c
 */
extern int legacy_get_tree(struct fs_context *fc);
extern int legacy_reconfigure(struct fs_context *fc);
extern int parse_monolithic_mount_data(struct fs_context *, void *);
extern void fc_drop_locked(struct fs_context *);

+28 −8
Original line number Diff line number Diff line
@@ -894,7 +894,8 @@ int reconfigure_super(struct fs_context *fc)
		}
	}

	retval = legacy_reconfigure(fc);
	if (fc->ops->reconfigure) {
		retval = fc->ops->reconfigure(fc);
		if (retval) {
			if (!force)
				goto cancel_readonly;
@@ -902,6 +903,7 @@ int reconfigure_super(struct fs_context *fc)
			WARN(1, "forced remount of a %s fs returned %i\n",
			     sb->s_type->name, retval);
		}
	}

	WRITE_ONCE(sb->s_flags, ((sb->s_flags & ~fc->sb_flags_mask) |
				 (fc->sb_flags & fc->sb_flags_mask)));
@@ -1294,10 +1296,28 @@ int vfs_get_tree(struct fs_context *fc)
	struct super_block *sb;
	int error;

	error = legacy_get_tree(fc);
	if (fc->fs_type->fs_flags & FS_REQUIRES_DEV && !fc->source)
		return -ENOENT;

	if (fc->root)
		return -EBUSY;

	/* Get the mountable root in fc->root, with a ref on the root and a ref
	 * on the superblock.
	 */
	error = fc->ops->get_tree(fc);
	if (error < 0)
		return error;

	if (!fc->root) {
		pr_err("Filesystem %s get_tree() didn't set fc->root\n",
		       fc->fs_type->name);
		/* We don't know what the locking state of the superblock is -
		 * if there is a superblock.
		 */
		BUG();
	}

	sb = fc->root->d_sb;
	WARN_ON(!sb->s_bdi);

+2 −0
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ struct workqueue_struct;
struct iov_iter;
struct fscrypt_info;
struct fscrypt_operations;
struct fs_context;

extern void __init inode_init(void);
extern void __init inode_init_early(void);
@@ -2173,6 +2174,7 @@ struct file_system_type {
#define FS_HAS_SUBTYPE		4
#define FS_USERNS_MOUNT		8	/* Can be mounted by userns root */
#define FS_RENAME_DOES_D_MOVE	32768	/* FS will handle d_move() during rename() internally. */
	int (*init_fs_context)(struct fs_context *);
	struct dentry *(*mount) (struct file_system_type *, int,
		       const char *, void *);
	void (*kill_sb) (struct super_block *);
+13 −0
Original line number Diff line number Diff line
@@ -20,8 +20,13 @@ struct cred;
struct dentry;
struct file_operations;
struct file_system_type;
struct mnt_namespace;
struct net;
struct pid_namespace;
struct super_block;
struct user_namespace;
struct vfsmount;
struct path;

enum fs_context_purpose {
	FS_CONTEXT_FOR_MOUNT,		/* New superblock for explicit mount */
@@ -39,6 +44,7 @@ enum fs_context_purpose {
 * See Documentation/filesystems/mounting.txt
 */
struct fs_context {
	const struct fs_context_operations *ops;
	struct file_system_type	*fs_type;
	void			*fs_private;	/* The filesystem's context */
	struct dentry		*root;		/* The root and superblock */
@@ -54,6 +60,13 @@ struct fs_context {
	bool			need_free:1;	/* Need to call ops->free() */
};

struct fs_context_operations {
	void (*free)(struct fs_context *fc);
	int (*parse_monolithic)(struct fs_context *fc, void *data);
	int (*get_tree)(struct fs_context *fc);
	int (*reconfigure)(struct fs_context *fc);
};

/*
 * fs_context manipulation functions.
 */