]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
overlayfs: fix lockdep misannotation
authorMiklos Szeredi <miklos@szeredi.hu>
Mon, 27 Oct 2014 14:42:01 +0000 (15:42 +0100)
committerAl Viro <viro@zeniv.linux.org.uk>
Tue, 28 Oct 2014 22:32:47 +0000 (18:32 -0400)
In an overlay directory that shadows an empty lower directory, say
/mnt/a/empty102, do:

  touch /mnt/a/empty102/x
  unlink /mnt/a/empty102/x
  rmdir /mnt/a/empty102

It's actually harmless, but needs another level of nesting between
I_MUTEX_CHILD and I_MUTEX_NORMAL.

Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Tested-by: David Howells <dhowells@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/namei.c
fs/overlayfs/readdir.c
include/linux/fs.h

index 42df664e95e54a2148093c14fe1f1ce43b909f33..922f27068c4c4c015ceac5b6594914ca6e4a319f 100644 (file)
@@ -2497,7 +2497,7 @@ struct dentry *lock_rename(struct dentry *p1, struct dentry *p2)
        }
 
        mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_PARENT);
-       mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_CHILD);
+       mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_PARENT2);
        return NULL;
 }
 EXPORT_SYMBOL(lock_rename);
index 3fbf0d306e1207b35df9da16e2389bc24130e783..401f0840f5cc63d0d2b839a878889d85290503f3 100644 (file)
@@ -571,7 +571,7 @@ void ovl_cleanup_whiteouts(struct dentry *upper, struct list_head *list)
 {
        struct ovl_cache_entry *p;
 
-       mutex_lock_nested(&upper->d_inode->i_mutex, I_MUTEX_PARENT);
+       mutex_lock_nested(&upper->d_inode->i_mutex, I_MUTEX_CHILD);
        list_for_each_entry(p, list, l_node) {
                struct dentry *dentry;
 
index 4e41a4a331bbf96c4b59c05cd9a0c522efec92ca..01036262095fbbb0b0f6eb80cd3566123e04a50f 100644 (file)
@@ -639,11 +639,13 @@ static inline int inode_unhashed(struct inode *inode)
  * 2: child/target
  * 3: xattr
  * 4: second non-directory
- * The last is for certain operations (such as rename) which lock two
+ * 5: second parent (when locking independent directories in rename)
+ *
+ * I_MUTEX_NONDIR2 is for certain operations (such as rename) which lock two
  * non-directories at once.
  *
  * The locking order between these classes is
- * parent -> child -> normal -> xattr -> second non-directory
+ * parent[2] -> child -> grandchild -> normal -> xattr -> second non-directory
  */
 enum inode_i_mutex_lock_class
 {
@@ -651,7 +653,8 @@ enum inode_i_mutex_lock_class
        I_MUTEX_PARENT,
        I_MUTEX_CHILD,
        I_MUTEX_XATTR,
-       I_MUTEX_NONDIR2
+       I_MUTEX_NONDIR2,
+       I_MUTEX_PARENT2,
 };
 
 void lock_two_nondirectories(struct inode *, struct inode*);