diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-03-19 19:27:36 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-03-19 19:27:36 -0400 |
| commit | e409ac35507fb6aa434c0508c6d75ad7f4755d68 (patch) | |
| tree | e9f5235923b248cb96554bc75d3b8fb6e853ce98 | |
| parent | 32dafb94a619ef7e62a23e3e3646d0ba0107de32 (diff) | |
| parent | 71cbad7e694ee81233b3be3a38b81c3d5872cc6f (diff) | |
Merge branch 'overlayfs-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs
Pull overlayfs fixes from Miklos Szeredi:
"This fixes minor issues with the multi-layer update in v4.0"
* 'overlayfs-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs:
ovl: upper fs should not be R/O
ovl: check lowerdir amount for non-upper mount
ovl: print error message for invalid mount options
| -rw-r--r-- | fs/overlayfs/super.c | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index b90952f528b1..5f0d1993e6e3 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c | |||
| @@ -529,8 +529,7 @@ static int ovl_remount(struct super_block *sb, int *flags, char *data) | |||
| 529 | { | 529 | { |
| 530 | struct ovl_fs *ufs = sb->s_fs_info; | 530 | struct ovl_fs *ufs = sb->s_fs_info; |
| 531 | 531 | ||
| 532 | if (!(*flags & MS_RDONLY) && | 532 | if (!(*flags & MS_RDONLY) && !ufs->upper_mnt) |
| 533 | (!ufs->upper_mnt || (ufs->upper_mnt->mnt_sb->s_flags & MS_RDONLY))) | ||
| 534 | return -EROFS; | 533 | return -EROFS; |
| 535 | 534 | ||
| 536 | return 0; | 535 | return 0; |
| @@ -615,9 +614,19 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config) | |||
| 615 | break; | 614 | break; |
| 616 | 615 | ||
| 617 | default: | 616 | default: |
| 617 | pr_err("overlayfs: unrecognized mount option \"%s\" or missing value\n", p); | ||
| 618 | return -EINVAL; | 618 | return -EINVAL; |
| 619 | } | 619 | } |
| 620 | } | 620 | } |
| 621 | |||
| 622 | /* Workdir is useless in non-upper mount */ | ||
| 623 | if (!config->upperdir && config->workdir) { | ||
| 624 | pr_info("overlayfs: option \"workdir=%s\" is useless in a non-upper mount, ignore\n", | ||
| 625 | config->workdir); | ||
| 626 | kfree(config->workdir); | ||
| 627 | config->workdir = NULL; | ||
| 628 | } | ||
| 629 | |||
| 621 | return 0; | 630 | return 0; |
| 622 | } | 631 | } |
| 623 | 632 | ||
| @@ -837,7 +846,6 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) | |||
| 837 | 846 | ||
| 838 | sb->s_stack_depth = 0; | 847 | sb->s_stack_depth = 0; |
| 839 | if (ufs->config.upperdir) { | 848 | if (ufs->config.upperdir) { |
| 840 | /* FIXME: workdir is not needed for a R/O mount */ | ||
| 841 | if (!ufs->config.workdir) { | 849 | if (!ufs->config.workdir) { |
| 842 | pr_err("overlayfs: missing 'workdir'\n"); | 850 | pr_err("overlayfs: missing 'workdir'\n"); |
| 843 | goto out_free_config; | 851 | goto out_free_config; |
| @@ -847,6 +855,13 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) | |||
| 847 | if (err) | 855 | if (err) |
| 848 | goto out_free_config; | 856 | goto out_free_config; |
| 849 | 857 | ||
| 858 | /* Upper fs should not be r/o */ | ||
| 859 | if (upperpath.mnt->mnt_sb->s_flags & MS_RDONLY) { | ||
| 860 | pr_err("overlayfs: upper fs is r/o, try multi-lower layers mount\n"); | ||
| 861 | err = -EINVAL; | ||
| 862 | goto out_put_upperpath; | ||
| 863 | } | ||
| 864 | |||
| 850 | err = ovl_mount_dir(ufs->config.workdir, &workpath); | 865 | err = ovl_mount_dir(ufs->config.workdir, &workpath); |
| 851 | if (err) | 866 | if (err) |
| 852 | goto out_put_upperpath; | 867 | goto out_put_upperpath; |
| @@ -869,8 +884,14 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) | |||
| 869 | 884 | ||
| 870 | err = -EINVAL; | 885 | err = -EINVAL; |
| 871 | stacklen = ovl_split_lowerdirs(lowertmp); | 886 | stacklen = ovl_split_lowerdirs(lowertmp); |
| 872 | if (stacklen > OVL_MAX_STACK) | 887 | if (stacklen > OVL_MAX_STACK) { |
| 888 | pr_err("overlayfs: too many lower directries, limit is %d\n", | ||
| 889 | OVL_MAX_STACK); | ||
| 873 | goto out_free_lowertmp; | 890 | goto out_free_lowertmp; |
| 891 | } else if (!ufs->config.upperdir && stacklen == 1) { | ||
| 892 | pr_err("overlayfs: at least 2 lowerdir are needed while upperdir nonexistent\n"); | ||
| 893 | goto out_free_lowertmp; | ||
| 894 | } | ||
| 874 | 895 | ||
| 875 | stack = kcalloc(stacklen, sizeof(struct path), GFP_KERNEL); | 896 | stack = kcalloc(stacklen, sizeof(struct path), GFP_KERNEL); |
| 876 | if (!stack) | 897 | if (!stack) |
| @@ -932,8 +953,8 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) | |||
| 932 | ufs->numlower++; | 953 | ufs->numlower++; |
| 933 | } | 954 | } |
| 934 | 955 | ||
| 935 | /* If the upper fs is r/o or nonexistent, we mark overlayfs r/o too */ | 956 | /* If the upper fs is nonexistent, we mark overlayfs r/o too */ |
| 936 | if (!ufs->upper_mnt || (ufs->upper_mnt->mnt_sb->s_flags & MS_RDONLY)) | 957 | if (!ufs->upper_mnt) |
| 937 | sb->s_flags |= MS_RDONLY; | 958 | sb->s_flags |= MS_RDONLY; |
| 938 | 959 | ||
| 939 | sb->s_d_op = &ovl_dentry_operations; | 960 | sb->s_d_op = &ovl_dentry_operations; |
