diff options
Diffstat (limited to 'fs/tracefs/inode.c')
| -rw-r--r-- | fs/tracefs/inode.c | 31 | 
1 files changed, 23 insertions, 8 deletions
diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c index 81d26abf486f..da85b3979195 100644 --- a/fs/tracefs/inode.c +++ b/fs/tracefs/inode.c @@ -141,6 +141,8 @@ struct tracefs_mount_opts {  	kuid_t uid;  	kgid_t gid;  	umode_t mode; +	/* Opt_* bitfield. */ +	unsigned int opts;  };  enum { @@ -241,6 +243,7 @@ static int tracefs_parse_options(char *data, struct tracefs_mount_opts *opts)  	kgid_t gid;  	char *p; +	opts->opts = 0;  	opts->mode = TRACEFS_DEFAULT_MODE;  	while ((p = strsep(&data, ",")) != NULL) { @@ -275,24 +278,36 @@ static int tracefs_parse_options(char *data, struct tracefs_mount_opts *opts)  		 * but traditionally tracefs has ignored all mount options  		 */  		} + +		opts->opts |= BIT(token);  	}  	return 0;  } -static int tracefs_apply_options(struct super_block *sb) +static int tracefs_apply_options(struct super_block *sb, bool remount)  {  	struct tracefs_fs_info *fsi = sb->s_fs_info;  	struct inode *inode = d_inode(sb->s_root);  	struct tracefs_mount_opts *opts = &fsi->mount_opts; -	inode->i_mode &= ~S_IALLUGO; -	inode->i_mode |= opts->mode; +	/* +	 * On remount, only reset mode/uid/gid if they were provided as mount +	 * options. +	 */ + +	if (!remount || opts->opts & BIT(Opt_mode)) { +		inode->i_mode &= ~S_IALLUGO; +		inode->i_mode |= opts->mode; +	} -	inode->i_uid = opts->uid; +	if (!remount || opts->opts & BIT(Opt_uid)) +		inode->i_uid = opts->uid; -	/* Set all the group ids to the mount option */ -	set_gid(sb->s_root, opts->gid); +	if (!remount || opts->opts & BIT(Opt_gid)) { +		/* Set all the group ids to the mount option */ +		set_gid(sb->s_root, opts->gid); +	}  	return 0;  } @@ -307,7 +322,7 @@ static int tracefs_remount(struct super_block *sb, int *flags, char *data)  	if (err)  		goto fail; -	tracefs_apply_options(sb); +	tracefs_apply_options(sb, true);  fail:  	return err; @@ -359,7 +374,7 @@ static int trace_fill_super(struct super_block *sb, void *data, int silent)  	sb->s_op = &tracefs_super_operations; -	tracefs_apply_options(sb); +	tracefs_apply_options(sb, false);  	return 0;  |