summary refs log tree commit diff
path: root/fs/notify
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2014-11-16 10:50:25 +0100
committerIngo Molnar <mingo@kernel.org>2014-11-16 10:50:25 +0100
commite9ac5f0fa8549dffe2a15870217a9c2e7cd557ec (patch)
tree863e0e108f7b7ba2dffc7575bbdfc2d454fc2017 /fs/notify
parent44dba3d5d6a10685fb15bd1954e62016334825e0 (diff)
parent6e998916dfe327e785e7c2447959b2c1a3ea4930 (diff)
downloadlinux-e9ac5f0fa8549dffe2a15870217a9c2e7cd557ec.tar.gz
Merge branch 'sched/urgent' into sched/core, to pick up fixes before applying more changes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'fs/notify')
-rw-r--r--fs/notify/inode_mark.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c
index 9ce062218de9..e8497144b323 100644
--- a/fs/notify/inode_mark.c
+++ b/fs/notify/inode_mark.c
@@ -288,20 +288,25 @@ void fsnotify_unmount_inodes(struct list_head *list)
 		spin_unlock(&inode->i_lock);
 
 		/* In case the dropping of a reference would nuke next_i. */
-		if ((&next_i->i_sb_list != list) &&
-		    atomic_read(&next_i->i_count)) {
+		while (&next_i->i_sb_list != list) {
 			spin_lock(&next_i->i_lock);
-			if (!(next_i->i_state & (I_FREEING | I_WILL_FREE))) {
+			if (!(next_i->i_state & (I_FREEING | I_WILL_FREE)) &&
+						atomic_read(&next_i->i_count)) {
 				__iget(next_i);
 				need_iput = next_i;
+				spin_unlock(&next_i->i_lock);
+				break;
 			}
 			spin_unlock(&next_i->i_lock);
+			next_i = list_entry(next_i->i_sb_list.next,
+						struct inode, i_sb_list);
 		}
 
 		/*
-		 * We can safely drop inode_sb_list_lock here because we hold
-		 * references on both inode and next_i.  Also no new inodes
-		 * will be added since the umount has begun.
+		 * We can safely drop inode_sb_list_lock here because either
+		 * we actually hold references on both inode and next_i or
+		 * end of list.  Also no new inodes will be added since the
+		 * umount has begun.
 		 */
 		spin_unlock(&inode_sb_list_lock);