aboutsummaryrefslogtreecommitdiffstats
path: root/fs/overlayfs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/overlayfs/super.c')
-rw-r--r--fs/overlayfs/super.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index fd5ea4facc62..092d150643c1 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -211,9 +211,10 @@ static void ovl_put_super(struct super_block *sb)
211 211
212 dput(ufs->indexdir); 212 dput(ufs->indexdir);
213 dput(ufs->workdir); 213 dput(ufs->workdir);
214 ovl_inuse_unlock(ufs->workbasedir); 214 if (ufs->workdir_locked)
215 ovl_inuse_unlock(ufs->workbasedir);
215 dput(ufs->workbasedir); 216 dput(ufs->workbasedir);
216 if (ufs->upper_mnt) 217 if (ufs->upper_mnt && ufs->upperdir_locked)
217 ovl_inuse_unlock(ufs->upper_mnt->mnt_root); 218 ovl_inuse_unlock(ufs->upper_mnt->mnt_root);
218 mntput(ufs->upper_mnt); 219 mntput(ufs->upper_mnt);
219 for (i = 0; i < ufs->numlower; i++) 220 for (i = 0; i < ufs->numlower; i++)
@@ -881,9 +882,13 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
881 goto out_put_upperpath; 882 goto out_put_upperpath;
882 883
883 err = -EBUSY; 884 err = -EBUSY;
884 if (!ovl_inuse_trylock(upperpath.dentry)) { 885 if (ovl_inuse_trylock(upperpath.dentry)) {
885 pr_err("overlayfs: upperdir is in-use by another mount\n"); 886 ufs->upperdir_locked = true;
887 } else if (ufs->config.index) {
888 pr_err("overlayfs: upperdir is in-use by another mount, mount with '-o index=off' to override exclusive upperdir protection.\n");
886 goto out_put_upperpath; 889 goto out_put_upperpath;
890 } else {
891 pr_warn("overlayfs: upperdir is in-use by another mount, accessing files from both mounts will result in undefined behavior.\n");
887 } 892 }
888 893
889 err = ovl_mount_dir(ufs->config.workdir, &workpath); 894 err = ovl_mount_dir(ufs->config.workdir, &workpath);
@@ -901,9 +906,13 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
901 } 906 }
902 907
903 err = -EBUSY; 908 err = -EBUSY;
904 if (!ovl_inuse_trylock(workpath.dentry)) { 909 if (ovl_inuse_trylock(workpath.dentry)) {
905 pr_err("overlayfs: workdir is in-use by another mount\n"); 910 ufs->workdir_locked = true;
911 } else if (ufs->config.index) {
912 pr_err("overlayfs: workdir is in-use by another mount, mount with '-o index=off' to override exclusive workdir protection.\n");
906 goto out_put_workpath; 913 goto out_put_workpath;
914 } else {
915 pr_warn("overlayfs: workdir is in-use by another mount, accessing files from both mounts will result in undefined behavior.\n");
907 } 916 }
908 917
909 ufs->workbasedir = workpath.dentry; 918 ufs->workbasedir = workpath.dentry;
@@ -1156,11 +1165,13 @@ out_put_lowerpath:
1156out_free_lowertmp: 1165out_free_lowertmp:
1157 kfree(lowertmp); 1166 kfree(lowertmp);
1158out_unlock_workdentry: 1167out_unlock_workdentry:
1159 ovl_inuse_unlock(workpath.dentry); 1168 if (ufs->workdir_locked)
1169 ovl_inuse_unlock(workpath.dentry);
1160out_put_workpath: 1170out_put_workpath:
1161 path_put(&workpath); 1171 path_put(&workpath);
1162out_unlock_upperdentry: 1172out_unlock_upperdentry:
1163 ovl_inuse_unlock(upperpath.dentry); 1173 if (ufs->upperdir_locked)
1174 ovl_inuse_unlock(upperpath.dentry);
1164out_put_upperpath: 1175out_put_upperpath:
1165 path_put(&upperpath); 1176 path_put(&upperpath);
1166out_free_config: 1177out_free_config: