]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
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)
committerZefan Li <lizefan@huawei.com>
Mon, 21 Mar 2016 01:17:40 +0000 (09:17 +0800)
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>
[lizf: Backported to 3.4: adjust context]
Signed-off-by: Zefan Li <lizefan@huawei.com>
fs/ext4/extents.c

index bbe09a975003afac114d5d3552e8343b90a5f3d2..e05cb4c91a9bd0bf72e31bf12be17c985d49ca6b 100644 (file)
@@ -699,7 +699,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;
@@ -904,7 +905,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;
@@ -1088,7 +1089,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);