commit 5037ac8cde5b5f961a2212d698522953104b854b
Author: Erez Zadok <[EMAIL PROTECTED](none)>
Date: Tue May 22 23:50:44 2007 -0400
bug fix: prevent self deadlock with remount code in pivot_root scenarios
Signed-off-by: Erez Zadok <[EMAIL PROTECTED]>
diff --git a/fs/unionfs/inode.c b/fs/unionfs/inode.c
index 4f4650e..b279cc0 100644
--- a/fs/unionfs/inode.c
+++ b/fs/unionfs/inode.c
@@ -688,7 +688,23 @@ static int unionfs_permission(struct inode *inode, int
mask,
const int is_file = !S_ISDIR(inode->i_mode);
const int write_mask = (mask & MAY_WRITE) && !(mask & MAY_READ);
- unionfs_read_lock(inode->i_sb);
+ /*
+ * If the same process which is pivot_root'ed on a unionfs, tries to
+ * insert a new branch, then the caller (remount code) already has
+ * the write lock on this rwsem. It then calls here to check the
+ * permission of a new branch to add. It could get into a self
+ * deadlock with this attempt to get the read lock (which is crucial
+ * for dynamic branch-management) unless no one else is waiting on
+ * this lock. Essentially this test tries to figure out if the same
+ * process which also holds a write lock on the rwsem, also tries to
+ * grab a read lock, and then skip trying to grab this "harmless"
+ * read lock; otherwise we DO want to grab the read lock, and block
+ * as needed (dynamic branch management). (BTW, if there's a better
+ * way to find out who is the lock owner compared to "current", that
+ * should be used instead.)
+ */
+ if (!list_empty(&UNIONFS_SB(inode->i_sb)->rwsem.wait_list))
+ unionfs_read_lock(inode->i_sb);
bstart = ibstart(inode);
bend = ibend(inode);
@@ -742,7 +758,8 @@ static int unionfs_permission(struct inode *inode, int mask,
}
out:
- unionfs_read_unlock(inode->i_sb);
+ if (!list_empty(&UNIONFS_SB(inode->i_sb)->rwsem.wait_list))
+ unionfs_read_unlock(inode->i_sb);
unionfs_check_inode(inode);
return err;
}
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs