Commit 2ba9d57e authored by Amir Goldstein's avatar Amir Goldstein Committed by Miklos Szeredi

ovl: take mnt_want_write() for work/index dir setup

There are several write operations on upper fs not covered by
mnt_want_write():

- test set/remove OPAQUE xattr
- test create O_TMPFILE
- set ORIGIN xattr in ovl_verify_origin()
- cleanup of index entries in ovl_indexdir_cleanup()

Some of these go way back, but this patch only applies over the
v4.14 re-factoring of ovl_fill_super().

Cc: <stable@vger.kernel.org> #v4.14
Signed-off-by: default avatarAmir Goldstein <amir73il@gmail.com>
Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
parent f8167817
...@@ -521,10 +521,6 @@ static struct dentry *ovl_workdir_create(struct ovl_fs *ofs, ...@@ -521,10 +521,6 @@ static struct dentry *ovl_workdir_create(struct ovl_fs *ofs,
bool retried = false; bool retried = false;
bool locked = false; bool locked = false;
err = mnt_want_write(mnt);
if (err)
goto out_err;
inode_lock_nested(dir, I_MUTEX_PARENT); inode_lock_nested(dir, I_MUTEX_PARENT);
locked = true; locked = true;
...@@ -589,7 +585,6 @@ static struct dentry *ovl_workdir_create(struct ovl_fs *ofs, ...@@ -589,7 +585,6 @@ static struct dentry *ovl_workdir_create(struct ovl_fs *ofs,
goto out_err; goto out_err;
} }
out_unlock: out_unlock:
mnt_drop_write(mnt);
if (locked) if (locked)
inode_unlock(dir); inode_unlock(dir);
...@@ -930,12 +925,17 @@ static int ovl_get_upper(struct ovl_fs *ofs, struct path *upperpath) ...@@ -930,12 +925,17 @@ static int ovl_get_upper(struct ovl_fs *ofs, struct path *upperpath)
static int ovl_make_workdir(struct ovl_fs *ofs, struct path *workpath) static int ovl_make_workdir(struct ovl_fs *ofs, struct path *workpath)
{ {
struct vfsmount *mnt = ofs->upper_mnt;
struct dentry *temp; struct dentry *temp;
int err; int err;
err = mnt_want_write(mnt);
if (err)
return err;
ofs->workdir = ovl_workdir_create(ofs, OVL_WORKDIR_NAME, false); ofs->workdir = ovl_workdir_create(ofs, OVL_WORKDIR_NAME, false);
if (!ofs->workdir) if (!ofs->workdir)
return 0; goto out;
/* /*
* Upper should support d_type, else whiteouts are visible. Given * Upper should support d_type, else whiteouts are visible. Given
...@@ -945,7 +945,7 @@ static int ovl_make_workdir(struct ovl_fs *ofs, struct path *workpath) ...@@ -945,7 +945,7 @@ static int ovl_make_workdir(struct ovl_fs *ofs, struct path *workpath)
*/ */
err = ovl_check_d_type_supported(workpath); err = ovl_check_d_type_supported(workpath);
if (err < 0) if (err < 0)
return err; goto out;
/* /*
* We allowed this configuration and don't want to break users over * We allowed this configuration and don't want to break users over
...@@ -969,6 +969,7 @@ static int ovl_make_workdir(struct ovl_fs *ofs, struct path *workpath) ...@@ -969,6 +969,7 @@ static int ovl_make_workdir(struct ovl_fs *ofs, struct path *workpath)
if (err) { if (err) {
ofs->noxattr = true; ofs->noxattr = true;
pr_warn("overlayfs: upper fs does not support xattr.\n"); pr_warn("overlayfs: upper fs does not support xattr.\n");
err = 0;
} else { } else {
vfs_removexattr(ofs->workdir, OVL_XATTR_OPAQUE); vfs_removexattr(ofs->workdir, OVL_XATTR_OPAQUE);
} }
...@@ -980,7 +981,9 @@ static int ovl_make_workdir(struct ovl_fs *ofs, struct path *workpath) ...@@ -980,7 +981,9 @@ static int ovl_make_workdir(struct ovl_fs *ofs, struct path *workpath)
pr_warn("overlayfs: upper fs does not support file handles, falling back to index=off.\n"); pr_warn("overlayfs: upper fs does not support file handles, falling back to index=off.\n");
} }
return 0; out:
mnt_drop_write(mnt);
return err;
} }
static int ovl_get_workdir(struct ovl_fs *ofs, struct path *upperpath) static int ovl_get_workdir(struct ovl_fs *ofs, struct path *upperpath)
...@@ -1027,8 +1030,13 @@ static int ovl_get_workdir(struct ovl_fs *ofs, struct path *upperpath) ...@@ -1027,8 +1030,13 @@ static int ovl_get_workdir(struct ovl_fs *ofs, struct path *upperpath)
static int ovl_get_indexdir(struct ovl_fs *ofs, struct ovl_entry *oe, static int ovl_get_indexdir(struct ovl_fs *ofs, struct ovl_entry *oe,
struct path *upperpath) struct path *upperpath)
{ {
struct vfsmount *mnt = ofs->upper_mnt;
int err; int err;
err = mnt_want_write(mnt);
if (err)
return err;
/* Verify lower root is upper root origin */ /* Verify lower root is upper root origin */
err = ovl_verify_origin(upperpath->dentry, oe->lowerstack[0].dentry, err = ovl_verify_origin(upperpath->dentry, oe->lowerstack[0].dentry,
false, true); false, true);
...@@ -1056,6 +1064,7 @@ static int ovl_get_indexdir(struct ovl_fs *ofs, struct ovl_entry *oe, ...@@ -1056,6 +1064,7 @@ static int ovl_get_indexdir(struct ovl_fs *ofs, struct ovl_entry *oe,
pr_warn("overlayfs: try deleting index dir or mounting with '-o index=off' to disable inodes index.\n"); pr_warn("overlayfs: try deleting index dir or mounting with '-o index=off' to disable inodes index.\n");
out: out:
mnt_drop_write(mnt);
return err; return err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment