aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorhujianyang <hujianyang@huawei.com>2015-01-15 00:20:57 -0500
committerMiklos Szeredi <mszeredi@suse.cz>2015-03-18 05:29:48 -0400
commit71cbad7e694ee81233b3be3a38b81c3d5872cc6f (patch)
treefc347950aaca4246d692295ec925b7ec81e72168 /fs
parent6be4506e34cf6075a1307b646e0a6c46c1c9010d (diff)
ovl: upper fs should not be R/O
After importing multi-lower layer support, users could mount a r/o partition as the left most lowerdir instead of using it as upperdir. And a r/o upperdir may cause an error like overlayfs: failed to create directory ./workdir/work during mount. This patch check the *s_flags* of upper fs and return an error if it is a r/o partition. The checking of *upper_mnt->mnt_sb->s_flags* can be removed now. This patch also remove /* FIXME: workdir is not needed for a R/O mount */ from ovl_fill_super() because: 1) for upper fs r/o case Setting a r/o partition as upper is prevented, no need to care about workdir in this case. 2) for "mount overlay -o ro" with a r/w upper fs case Users could remount overlayfs to r/w in this case, so workdir should not be omitted. Signed-off-by: hujianyang <hujianyang@huawei.com> Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Diffstat (limited to 'fs')
-rw-r--r--fs/overlayfs/super.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index edbb3ebcdaad..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;
@@ -619,6 +618,15 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
619 return -EINVAL; 618 return -EINVAL;
620 } 619 }
621 } 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
622 return 0; 630 return 0;
623} 631}
624 632
@@ -838,7 +846,6 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
838 846
839 sb->s_stack_depth = 0; 847 sb->s_stack_depth = 0;
840 if (ufs->config.upperdir) { 848 if (ufs->config.upperdir) {
841 /* FIXME: workdir is not needed for a R/O mount */
842 if (!ufs->config.workdir) { 849 if (!ufs->config.workdir) {
843 pr_err("overlayfs: missing 'workdir'\n"); 850 pr_err("overlayfs: missing 'workdir'\n");
844 goto out_free_config; 851 goto out_free_config;
@@ -848,6 +855,13 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
848 if (err) 855 if (err)
849 goto out_free_config; 856 goto out_free_config;
850 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
851 err = ovl_mount_dir(ufs->config.workdir, &workpath); 865 err = ovl_mount_dir(ufs->config.workdir, &workpath);
852 if (err) 866 if (err)
853 goto out_put_upperpath; 867 goto out_put_upperpath;
@@ -939,8 +953,8 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
939 ufs->numlower++; 953 ufs->numlower++;
940 } 954 }
941 955
942 /* 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 */
943 if (!ufs->upper_mnt || (ufs->upper_mnt->mnt_sb->s_flags & MS_RDONLY)) 957 if (!ufs->upper_mnt)
944 sb->s_flags |= MS_RDONLY; 958 sb->s_flags |= MS_RDONLY;
945 959
946 sb->s_d_op = &ovl_dentry_operations; 960 sb->s_d_op = &ovl_dentry_operations;