Skip to content

Commit

Permalink
overlayfs: fix lockdep misannotation
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
szmi authored and Al Viro committed Oct 28, 2014
1 parent c209653 commit d1b72cc
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 5 deletions.
2 changes: 1 addition & 1 deletion fs/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion fs/overlayfs/readdir.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
9 changes: 6 additions & 3 deletions include/linux/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -639,19 +639,22 @@ 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
{
I_MUTEX_NORMAL,
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*);
Expand Down

0 comments on commit d1b72cc

Please sign in to comment.