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>"); | |||
24 | MODULE_DESCRIPTION("Overlay filesystem"); | 24 | MODULE_DESCRIPTION("Overlay filesystem"); |
25 | MODULE_LICENSE("GPL"); | 25 | MODULE_LICENSE("GPL"); |
26 | 26 | ||
27 | #define OVERLAYFS_SUPER_MAGIC 0x794c764f | 27 | #define OVERLAYFS_SUPER_MAGIC 0x794c7630 |
28 | 28 | ||
29 | struct ovl_config { | 29 | struct ovl_config { |
30 | char *lowerdir; | 30 | char *lowerdir; |
@@ -84,12 +84,7 @@ enum ovl_path_type ovl_path_type(struct dentry *dentry) | |||
84 | 84 | ||
85 | static struct dentry *ovl_upperdentry_dereference(struct ovl_entry *oe) | 85 | static struct dentry *ovl_upperdentry_dereference(struct ovl_entry *oe) |
86 | { | 86 | { |
87 | struct dentry *upperdentry = ACCESS_ONCE(oe->__upperdentry); | 87 | return lockless_dereference(oe->__upperdentry); |
88 | /* | ||
89 | * Make sure to order reads to upperdentry wrt ovl_dentry_update() | ||
90 | */ | ||
91 | smp_read_barrier_depends(); | ||
92 | return upperdentry; | ||
93 | } | 88 | } |
94 | 89 | ||
95 | void ovl_path_upper(struct dentry *dentry, struct path *path) | 90 | void ovl_path_upper(struct dentry *dentry, struct path *path) |
@@ -462,11 +457,34 @@ static const match_table_t ovl_tokens = { | |||
462 | {OPT_ERR, NULL} | 457 | {OPT_ERR, NULL} |
463 | }; | 458 | }; |
464 | 459 | ||
460 | static char *ovl_next_opt(char **s) | ||
461 | { | ||
462 | char *sbegin = *s; | ||
463 | char *p; | ||
464 | |||
465 | if (sbegin == NULL) | ||
466 | return NULL; | ||
467 | |||
468 | for (p = sbegin; *p; p++) { | ||
469 | if (*p == '\\') { | ||
470 | p++; | ||
471 | if (!*p) | ||
472 | break; | ||
473 | } else if (*p == ',') { | ||
474 | *p = '\0'; | ||
475 | *s = p + 1; | ||
476 | return sbegin; | ||
477 | } | ||
478 | } | ||
479 | *s = NULL; | ||
480 | return sbegin; | ||
481 | } | ||
482 | |||
465 | static int ovl_parse_opt(char *opt, struct ovl_config *config) | 483 | static int ovl_parse_opt(char *opt, struct ovl_config *config) |
466 | { | 484 | { |
467 | char *p; | 485 | char *p; |
468 | 486 | ||
469 | while ((p = strsep(&opt, ",")) != NULL) { | 487 | while ((p = ovl_next_opt(&opt)) != NULL) { |
470 | int token; | 488 | int token; |
471 | substring_t args[MAX_OPT_ARGS]; | 489 | substring_t args[MAX_OPT_ARGS]; |
472 | 490 | ||
@@ -554,15 +572,34 @@ out_dput: | |||
554 | goto out_unlock; | 572 | goto out_unlock; |
555 | } | 573 | } |
556 | 574 | ||
575 | static void ovl_unescape(char *s) | ||
576 | { | ||
577 | char *d = s; | ||
578 | |||
579 | for (;; s++, d++) { | ||
580 | if (*s == '\\') | ||
581 | s++; | ||
582 | *d = *s; | ||
583 | if (!*s) | ||
584 | break; | ||
585 | } | ||
586 | } | ||
587 | |||
557 | static int ovl_mount_dir(const char *name, struct path *path) | 588 | static int ovl_mount_dir(const char *name, struct path *path) |
558 | { | 589 | { |
559 | int err; | 590 | int err; |
591 | char *tmp = kstrdup(name, GFP_KERNEL); | ||
592 | |||
593 | if (!tmp) | ||
594 | return -ENOMEM; | ||
560 | 595 | ||
561 | err = kern_path(name, LOOKUP_FOLLOW, path); | 596 | ovl_unescape(tmp); |
597 | err = kern_path(tmp, LOOKUP_FOLLOW, path); | ||
562 | if (err) { | 598 | if (err) { |
563 | pr_err("overlayfs: failed to resolve '%s': %i\n", name, err); | 599 | pr_err("overlayfs: failed to resolve '%s': %i\n", tmp, err); |
564 | err = -EINVAL; | 600 | err = -EINVAL; |
565 | } | 601 | } |
602 | kfree(tmp); | ||
566 | return err; | 603 | return err; |
567 | } | 604 | } |
568 | 605 | ||
@@ -776,11 +813,11 @@ static struct dentry *ovl_mount(struct file_system_type *fs_type, int flags, | |||
776 | 813 | ||
777 | static struct file_system_type ovl_fs_type = { | 814 | static struct file_system_type ovl_fs_type = { |
778 | .owner = THIS_MODULE, | 815 | .owner = THIS_MODULE, |
779 | .name = "overlayfs", | 816 | .name = "overlay", |
780 | .mount = ovl_mount, | 817 | .mount = ovl_mount, |
781 | .kill_sb = kill_anon_super, | 818 | .kill_sb = kill_anon_super, |
782 | }; | 819 | }; |
783 | MODULE_ALIAS_FS("overlayfs"); | 820 | MODULE_ALIAS_FS("overlay"); |
784 | 821 | ||
785 | static int __init ovl_init(void) | 822 | static int __init ovl_init(void) |
786 | { | 823 | { |