]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
ovl: fix missing unlock_rename() in ovl_do_copy_up()
authorAmir Goldstein <amir73il@gmail.com>
Mon, 25 Sep 2017 13:39:55 +0000 (16:39 +0300)
committerSeth Forshee <seth.forshee@canonical.com>
Thu, 19 Oct 2017 14:49:06 +0000 (09:49 -0500)
BugLink: http://bugs.launchpad.net/bugs/1723145
commit 5820dc0888d302ac05f8b91ffdf7e4e53b4fbf53 upstream.

Use the ovl_lock_rename_workdir() helper which requires
unlock_rename() only on lock success.

Fixes: ("fd210b7d67ee ovl: move copy up lock out")
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
fs/overlayfs/copy_up.c
fs/overlayfs/dir.c
fs/overlayfs/overlayfs.h
fs/overlayfs/util.c

index 55e3bd9b2df6b91d7c12a19ce8c9649cddab71e3..1d9f862e6bddce05e6bd778d7914b76420c52cf4 100644 (file)
@@ -578,10 +578,8 @@ static int ovl_do_copy_up(struct ovl_copy_up_ctx *c)
                c->tmpfile = true;
                err = ovl_copy_up_locked(c);
        } else {
-               err = -EIO;
-               if (lock_rename(c->workdir, c->destdir) != NULL) {
-                       pr_err("overlayfs: failed to lock workdir+upperdir\n");
-               } else {
+               err = ovl_lock_rename_workdir(c->workdir, c->destdir);
+               if (!err) {
                        err = ovl_copy_up_locked(c);
                        unlock_rename(c->workdir, c->destdir);
                }
index 48b70e6490f32e9c7f9c34f8dcb20735279b3946..9b97b35b39c89de3393768c7359a15d82f28f73b 100644 (file)
@@ -216,26 +216,6 @@ out_unlock:
        return err;
 }
 
-static int ovl_lock_rename_workdir(struct dentry *workdir,
-                                  struct dentry *upperdir)
-{
-       /* Workdir should not be the same as upperdir */
-       if (workdir == upperdir)
-               goto err;
-
-       /* Workdir should not be subdir of upperdir and vice versa */
-       if (lock_rename(workdir, upperdir) != NULL)
-               goto err_unlock;
-
-       return 0;
-
-err_unlock:
-       unlock_rename(workdir, upperdir);
-err:
-       pr_err("overlayfs: failed to lock workdir+upperdir\n");
-       return -EIO;
-}
-
 static struct dentry *ovl_clear_empty(struct dentry *dentry,
                                      struct list_head *list)
 {
index 425fdcf84064cf59c52eb3298559875de300286b..aea164678c00621bdda870b01a7b7b967c2be5a7 100644 (file)
@@ -246,6 +246,7 @@ bool ovl_inuse_trylock(struct dentry *dentry);
 void ovl_inuse_unlock(struct dentry *dentry);
 int ovl_nlink_start(struct dentry *dentry, bool *locked);
 void ovl_nlink_end(struct dentry *dentry, bool locked);
+int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *upperdir);
 
 static inline bool ovl_is_impuredir(struct dentry *dentry)
 {
index 91f54ed25bd2d54b622453ccd1e2843692219fe2..8bff64f14190bc474476f556598ff315493f765f 100644 (file)
@@ -548,3 +548,22 @@ void ovl_nlink_end(struct dentry *dentry, bool locked)
                mutex_unlock(&OVL_I(d_inode(dentry))->lock);
        }
 }
+
+int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *upperdir)
+{
+       /* Workdir should not be the same as upperdir */
+       if (workdir == upperdir)
+               goto err;
+
+       /* Workdir should not be subdir of upperdir and vice versa */
+       if (lock_rename(workdir, upperdir) != NULL)
+               goto err_unlock;
+
+       return 0;
+
+err_unlock:
+       unlock_rename(workdir, upperdir);
+err:
+       pr_err("overlayfs: failed to lock workdir+upperdir\n");
+       return -EIO;
+}