Btrfs: fix balancing oops when invalidate_inode_pages2 returns EBUSY
authorYan Zheng <zheng.yan@oracle.com>
Fri, 7 Aug 2009 17:51:33 +0000 (13:51 -0400)
committerChris Mason <chris.mason@oracle.com>
Fri, 7 Aug 2009 17:51:33 +0000 (13:51 -0400)
invalidate_inode_pages2_range may return -EBUSY occasionally
which results Oops. This patch fixes the issue by moving
invalidate_inode_pages2_range into a loop and keeping calling
it until the return value is not -EBUSY.

The EBUSY return is temporary, and can happen when the btrfs release page
function is unable to release a page because the EXTENT_LOCK
bit is set.

Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>
fs/btrfs/relocation.c

index e71264d1c2c93acc3e1f418b6362c231dd61ad5f..c04f7f212602c4bcb71e58db938fcd0d8a9128ad 100644 (file)
@@ -2553,8 +2553,13 @@ int relocate_inode_pages(struct inode *inode, u64 start, u64 len)
        last_index = (start + len - 1) >> PAGE_CACHE_SHIFT;
 
        /* make sure the dirty trick played by the caller work */
-       ret = invalidate_inode_pages2_range(inode->i_mapping,
-                                           first_index, last_index);
+       while (1) {
+               ret = invalidate_inode_pages2_range(inode->i_mapping,
+                                                   first_index, last_index);
+               if (ret != -EBUSY)
+                       break;
+               schedule_timeout(HZ/10);
+       }
        if (ret)
                goto out_unlock;