diff options
Diffstat (limited to 'fs/overlayfs/super.c')
| -rw-r--r-- | fs/overlayfs/super.c | 61 | 
1 files changed, 49 insertions, 12 deletions
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 08b704cebfc4..f16d318b71f8 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -24,7 +24,7 @@ MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>");  MODULE_DESCRIPTION("Overlay filesystem");  MODULE_LICENSE("GPL"); -#define OVERLAYFS_SUPER_MAGIC 0x794c764f +#define OVERLAYFS_SUPER_MAGIC 0x794c7630  struct ovl_config {  	char *lowerdir; @@ -84,12 +84,7 @@ enum ovl_path_type ovl_path_type(struct dentry *dentry)  static struct dentry *ovl_upperdentry_dereference(struct ovl_entry *oe)  { -	struct dentry *upperdentry = ACCESS_ONCE(oe->__upperdentry); -	/* -	 * Make sure to order reads to upperdentry wrt ovl_dentry_update() -	 */ -	smp_read_barrier_depends(); -	return upperdentry; +	return lockless_dereference(oe->__upperdentry);  }  void ovl_path_upper(struct dentry *dentry, struct path *path) @@ -462,11 +457,34 @@ static const match_table_t ovl_tokens = {  	{OPT_ERR,			NULL}  }; +static char *ovl_next_opt(char **s) +{ +	char *sbegin = *s; +	char *p; + +	if (sbegin == NULL) +		return NULL; + +	for (p = sbegin; *p; p++) { +		if (*p == '\\') { +			p++; +			if (!*p) +				break; +		} else if (*p == ',') { +			*p = '\0'; +			*s = p + 1; +			return sbegin; +		} +	} +	*s = NULL; +	return sbegin; +} +  static int ovl_parse_opt(char *opt, struct ovl_config *config)  {  	char *p; -	while ((p = strsep(&opt, ",")) != NULL) { +	while ((p = ovl_next_opt(&opt)) != NULL) {  		int token;  		substring_t args[MAX_OPT_ARGS]; @@ -554,15 +572,34 @@ out_dput:  	goto out_unlock;  } +static void ovl_unescape(char *s) +{ +	char *d = s; + +	for (;; s++, d++) { +		if (*s == '\\') +			s++; +		*d = *s; +		if (!*s) +			break; +	} +} +  static int ovl_mount_dir(const char *name, struct path *path)  {  	int err; +	char *tmp = kstrdup(name, GFP_KERNEL); + +	if (!tmp) +		return -ENOMEM; -	err = kern_path(name, LOOKUP_FOLLOW, path); +	ovl_unescape(tmp); +	err = kern_path(tmp, LOOKUP_FOLLOW, path);  	if (err) { -		pr_err("overlayfs: failed to resolve '%s': %i\n", name, err); +		pr_err("overlayfs: failed to resolve '%s': %i\n", tmp, err);  		err = -EINVAL;  	} +	kfree(tmp);  	return err;  } @@ -776,11 +813,11 @@ static struct dentry *ovl_mount(struct file_system_type *fs_type, int flags,  static struct file_system_type ovl_fs_type = {  	.owner		= THIS_MODULE, -	.name		= "overlayfs", +	.name		= "overlay",  	.mount		= ovl_mount,  	.kill_sb	= kill_anon_super,  }; -MODULE_ALIAS_FS("overlayfs"); +MODULE_ALIAS_FS("overlay");  static int __init ovl_init(void)  {  | 
