[PATCH v2] writeback: Fix inode->i_io_list not be protected by inode->i_lock error

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Commit b35250c0816c ("writeback: Protect inode->i_io_list with
inode->i_lock") made inode->i_io_list not only protected by
wb->list_lock but also inode->i_lock, but
inode_io_list_move_locked() was missed. Add lock there and also
update comment describing things protected by inode->i_lock.

Fixes: b35250c0816c ("writeback: Protect inode->i_io_list with inode->i_lock")
Reviewed-by: Jan Kara <jack@xxxxxxx>
Signed-off-by: Jchao Sun <sunjunchao2870@xxxxxxxxx>
---
 fs/fs-writeback.c | 11 +++++------
 fs/inode.c        |  2 +-
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 591fe9cf1659..30f9698e7c2c 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -120,6 +120,7 @@ static bool inode_io_list_move_locked(struct inode *inode,
 				      struct list_head *head)
 {
 	assert_spin_locked(&wb->list_lock);
+	assert_spin_locked(&inode->i_lock);
 
 	list_move(&inode->i_io_list, head);
 
@@ -293,8 +294,8 @@ static void inode_cgwb_move_to_attached(struct inode *inode,
  * @inode: inode of interest with i_lock held
  *
  * Returns @inode's wb with its list_lock held.  @inode->i_lock must be
- * held on entry and is released on return.  The returned wb is guaranteed
- * to stay @inode's associated wb until its list_lock is released.
+ * held on entry.  The returned wb is guaranteed to stay @inode's associated
+ * wb until its list_lock is released.
  */
 static struct bdi_writeback *
 locked_inode_to_wb_and_lock_list(struct inode *inode)
@@ -317,6 +318,7 @@ locked_inode_to_wb_and_lock_list(struct inode *inode)
 		/* i_wb may have changed inbetween, can't use inode_to_wb() */
 		if (likely(wb == inode->i_wb)) {
 			wb_put(wb);	/* @inode already has ref */
+			spin_lock(&inode->i_lock);
 			return wb;
 		}
 
@@ -1141,7 +1143,6 @@ locked_inode_to_wb_and_lock_list(struct inode *inode)
 {
 	struct bdi_writeback *wb = inode_to_wb(inode);
 
-	spin_unlock(&inode->i_lock);
 	spin_lock(&wb->list_lock);
 	return wb;
 }
@@ -1152,6 +1153,7 @@ static struct bdi_writeback *inode_to_wb_and_lock_list(struct inode *inode)
 	struct bdi_writeback *wb = inode_to_wb(inode);
 
 	spin_lock(&wb->list_lock);
+	spin_lock(&inode->i_lock);
 	return wb;
 }
 
@@ -1233,7 +1235,6 @@ void inode_io_list_del(struct inode *inode)
 	struct bdi_writeback *wb;
 
 	wb = inode_to_wb_and_lock_list(inode);
-	spin_lock(&inode->i_lock);
 
 	inode->i_state &= ~I_SYNC_QUEUED;
 	list_del_init(&inode->i_io_list);
@@ -1704,7 +1705,6 @@ static int writeback_single_inode(struct inode *inode,
 	wbc_detach_inode(wbc);
 
 	wb = inode_to_wb_and_lock_list(inode);
-	spin_lock(&inode->i_lock);
 	/*
 	 * If the inode is now fully clean, then it can be safely removed from
 	 * its writeback list (if any).  Otherwise the flusher threads are
@@ -1875,7 +1875,6 @@ static long writeback_sb_inodes(struct super_block *sb,
 		 * have been switched to another wb in the meantime.
 		 */
 		tmp_wb = inode_to_wb_and_lock_list(inode);
-		spin_lock(&inode->i_lock);
 		if (!(inode->i_state & I_DIRTY_ALL))
 			wrote++;
 		requeue_inode(inode, tmp_wb, &wbc);
diff --git a/fs/inode.c b/fs/inode.c
index 9d9b422504d1..bd4da9c5207e 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -27,7 +27,7 @@
  * Inode locking rules:
  *
  * inode->i_lock protects:
- *   inode->i_state, inode->i_hash, __iget()
+ *   inode->i_state, inode->i_hash, __iget(), inode->i_io_list
  * Inode LRU list locks protect:
  *   inode->i_sb->s_inode_lru, inode->i_lru
  * inode->i_sb->s_inode_list_lock protects:
-- 

Sry for my insufficient tests and any inconvenience in lauguage, because
my mother tongue is not english. It's my first commit to linux kernel
community, some strage for me...

Thanks a lot for your review and suggestion.
2.17.1




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux