ext4: avoid deadlocks in the writeback path by using sb_getblk_gfp
authorNikolay Borisov <kernel@kyup.com>
Thu, 2 Jul 2015 05:34:07 +0000 (01:34 -0400)
committerBen Hutchings <ben@decadent.org.uk>
Wed, 12 Aug 2015 14:33:19 +0000 (16:33 +0200)
commit c45653c341f5c8a0ce19c8f0ad4678640849cb86 upstream.

Switch ext4 to using sb_getblk_gfp with GFP_NOFS added to fix possible
deadlocks in the page writeback path.

Signed-off-by: Nikolay Borisov <kernel@kyup.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
fs/ext4/extents.c

index 2da63ab..e3d65ab 100644 (file)
@@ -700,7 +700,8 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block,
                path[ppos].p_depth = i;
                path[ppos].p_ext = NULL;
 
-               bh = sb_getblk(inode->i_sb, path[ppos].p_block);
+               bh = sb_getblk_gfp(inode->i_sb, path[ppos].p_block,
+                                  __GFP_MOVABLE | GFP_NOFS);
                if (unlikely(!bh)) {
                        ret = -ENOMEM;
                        goto err;
@@ -905,7 +906,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
                err = -EIO;
                goto cleanup;
        }
-       bh = sb_getblk(inode->i_sb, newblock);
+       bh = sb_getblk_gfp(inode->i_sb, newblock, __GFP_MOVABLE | GFP_NOFS);
        if (!bh) {
                err = -ENOMEM;
                goto cleanup;
@@ -1089,7 +1090,7 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
        if (newblock == 0)
                return err;
 
-       bh = sb_getblk(inode->i_sb, newblock);
+       bh = sb_getblk_gfp(inode->i_sb, newblock, __GFP_MOVABLE | GFP_NOFS);
        if (!bh)
                return -ENOMEM;
        lock_buffer(bh);