[GFS2] fix GFP_KERNEL misuses
Josef Bacik [Wed, 9 Apr 2008 13:33:41 +0000 (09:33 -0400)]
There are several places where GFP_KERNEL allocations happen under a glock,
which will result in hangs if we're under memory pressure and go to re-enter the
fs in order to flush stuff out.  This patch changes the culprits to GFS_NOFS to
keep this problem from happening.  Thank you,

Signed-off-by: Josef Bacik <jbacik@redhat.com>
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>

fs/gfs2/acl.c
fs/gfs2/dir.c
fs/gfs2/eattr.c
fs/gfs2/inode.c
fs/gfs2/locking/dlm/lock.c
fs/gfs2/locking/nolock/main.c
fs/gfs2/quota.c
fs/gfs2/recovery.c
fs/gfs2/super.c

index 1047a8c..3e9bd46 100644 (file)
@@ -116,7 +116,7 @@ static int acl_get(struct gfs2_inode *ip, int access, struct posix_acl **acl,
                goto out;
 
        er.er_data_len = GFS2_EA_DATA_LEN(el->el_ea);
-       er.er_data = kmalloc(er.er_data_len, GFP_KERNEL);
+       er.er_data = kmalloc(er.er_data_len, GFP_NOFS);
        error = -ENOMEM;
        if (!er.er_data)
                goto out;
@@ -222,7 +222,7 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip)
                return error;
        }
 
-       clone = posix_acl_clone(acl, GFP_KERNEL);
+       clone = posix_acl_clone(acl, GFP_NOFS);
        error = -ENOMEM;
        if (!clone)
                goto out;
@@ -272,7 +272,7 @@ int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr)
        if (!acl)
                return gfs2_setattr_simple(ip, attr);
 
-       clone = posix_acl_clone(acl, GFP_KERNEL);
+       clone = posix_acl_clone(acl, GFP_NOFS);
        error = -ENOMEM;
        if (!clone)
                goto out;
index 94070ad..eed040d 100644 (file)
@@ -1089,7 +1089,7 @@ static int dir_double_exhash(struct gfs2_inode *dip)
 
        /*  Allocate both the "from" and "to" buffers in one big chunk  */
 
-       buf = kcalloc(3, sdp->sd_hash_bsize, GFP_KERNEL | __GFP_NOFAIL);
+       buf = kcalloc(3, sdp->sd_hash_bsize, GFP_NOFS | __GFP_NOFAIL);
 
        for (block = dip->i_di.di_size >> sdp->sd_hash_bsize_shift; block--;) {
                error = gfs2_dir_read_data(dip, (char *)buf,
@@ -1378,7 +1378,7 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque,
        hash = gfs2_dir_offset2hash(*offset);
        index = hash >> (32 - dip->i_depth);
 
-       lp = kmalloc(sdp->sd_hash_bsize, GFP_KERNEL);
+       lp = kmalloc(sdp->sd_hash_bsize, GFP_NOFS);
        if (!lp)
                return -ENOMEM;
 
@@ -1443,7 +1443,7 @@ int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque,
 
        error = -ENOMEM;
        /* 96 is max number of dirents which can be stuffed into an inode */
-       darr = kmalloc(96 * sizeof(struct gfs2_dirent *), GFP_KERNEL);
+       darr = kmalloc(96 * sizeof(struct gfs2_dirent *), GFP_NOFS);
        if (darr) {
                g.pdent = darr;
                g.offset = 0;
@@ -1789,7 +1789,7 @@ static int foreach_leaf(struct gfs2_inode *dip, leaf_call_t lc, void *data)
                return -EIO;
        }
 
-       lp = kmalloc(sdp->sd_hash_bsize, GFP_KERNEL);
+       lp = kmalloc(sdp->sd_hash_bsize, GFP_NOFS);
        if (!lp)
                return -ENOMEM;
 
@@ -1864,7 +1864,7 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len,
 
        memset(&rlist, 0, sizeof(struct gfs2_rgrp_list));
 
-       ht = kzalloc(size, GFP_KERNEL);
+       ht = kzalloc(size, GFP_NOFS);
        if (!ht)
                return -ENOMEM;
 
index 8175592..e3f76f4 100644 (file)
@@ -448,7 +448,7 @@ static int ea_get_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
        unsigned int x;
        int error = 0;
 
-       bh = kcalloc(nptrs, sizeof(struct buffer_head *), GFP_KERNEL);
+       bh = kcalloc(nptrs, sizeof(struct buffer_head *), GFP_NOFS);
        if (!bh)
                return -ENOMEM;
 
@@ -1206,7 +1206,7 @@ static int ea_acl_chmod_unstuffed(struct gfs2_inode *ip,
        unsigned int x;
        int error;
 
-       bh = kcalloc(nptrs, sizeof(struct buffer_head *), GFP_KERNEL);
+       bh = kcalloc(nptrs, sizeof(struct buffer_head *), GFP_NOFS);
        if (!bh)
                return -ENOMEM;
 
index dcae2aa..3a9ef52 100644 (file)
@@ -1231,7 +1231,7 @@ int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len)
 
        x = ip->i_di.di_size + 1;
        if (x > *len) {
-               *buf = kmalloc(x, GFP_KERNEL);
+               *buf = kmalloc(x, GFP_NOFS);
                if (!*buf) {
                        error = -ENOMEM;
                        goto out_brelse;
index 53a6ab3..cf7ea8a 100644 (file)
@@ -165,7 +165,7 @@ static int gdlm_create_lp(struct gdlm_ls *ls, struct lm_lockname *name,
 {
        struct gdlm_lock *lp;
 
-       lp = kzalloc(sizeof(struct gdlm_lock), GFP_KERNEL);
+       lp = kzalloc(sizeof(struct gdlm_lock), GFP_NOFS);
        if (!lp)
                return -ENOMEM;
 
@@ -383,7 +383,7 @@ static int gdlm_add_lvb(struct gdlm_lock *lp)
 {
        char *lvb;
 
-       lvb = kzalloc(GDLM_LVB_SIZE, GFP_KERNEL);
+       lvb = kzalloc(GDLM_LVB_SIZE, GFP_NOFS);
        if (!lvb)
                return -ENOMEM;
 
index d3b8ce6..284a5ec 100644 (file)
@@ -140,7 +140,7 @@ static int nolock_hold_lvb(void *lock, char **lvbp)
        struct nolock_lockspace *nl = lock;
        int error = 0;
 
-       *lvbp = kzalloc(nl->nl_lvb_size, GFP_KERNEL);
+       *lvbp = kzalloc(nl->nl_lvb_size, GFP_NOFS);
        if (!*lvbp)
                error = -ENOMEM;
 
index c71f781..56aaf91 100644 (file)
@@ -94,7 +94,7 @@ static int qd_alloc(struct gfs2_sbd *sdp, int user, u32 id,
        struct gfs2_quota_data *qd;
        int error;
 
-       qd = kzalloc(sizeof(struct gfs2_quota_data), GFP_KERNEL);
+       qd = kzalloc(sizeof(struct gfs2_quota_data), GFP_NOFS);
        if (!qd)
                return -ENOMEM;
 
@@ -690,7 +690,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
        gfs2_write_calc_reserv(ip, sizeof(struct gfs2_quota),
                              &data_blocks, &ind_blocks);
 
-       ghs = kcalloc(num_qd, sizeof(struct gfs2_holder), GFP_KERNEL);
+       ghs = kcalloc(num_qd, sizeof(struct gfs2_holder), GFP_NOFS);
        if (!ghs)
                return -ENOMEM;
 
@@ -1118,12 +1118,12 @@ int gfs2_quota_init(struct gfs2_sbd *sdp)
        error = -ENOMEM;
 
        sdp->sd_quota_bitmap = kcalloc(sdp->sd_quota_chunks,
-                                      sizeof(unsigned char *), GFP_KERNEL);
+                                      sizeof(unsigned char *), GFP_NOFS);
        if (!sdp->sd_quota_bitmap)
                return error;
 
        for (x = 0; x < sdp->sd_quota_chunks; x++) {
-               sdp->sd_quota_bitmap[x] = kzalloc(PAGE_SIZE, GFP_KERNEL);
+               sdp->sd_quota_bitmap[x] = kzalloc(PAGE_SIZE, GFP_NOFS);
                if (!sdp->sd_quota_bitmap[x])
                        goto fail;
        }
index 06dcdc0..2888e4b 100644 (file)
@@ -68,7 +68,7 @@ int gfs2_revoke_add(struct gfs2_sbd *sdp, u64 blkno, unsigned int where)
                return 0;
        }
 
-       rr = kmalloc(sizeof(struct gfs2_revoke_replay), GFP_KERNEL);
+       rr = kmalloc(sizeof(struct gfs2_revoke_replay), GFP_NOFS);
        if (!rr)
                return -ENOMEM;
 
index 88497b0..7aeacbc 100644 (file)
@@ -210,7 +210,7 @@ int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector)
        struct page *page;
        struct bio *bio;
 
-       page = alloc_page(GFP_KERNEL);
+       page = alloc_page(GFP_NOFS);
        if (unlikely(!page))
                return -ENOBUFS;
 
@@ -218,7 +218,7 @@ int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector)
        ClearPageDirty(page);
        lock_page(page);
 
-       bio = bio_alloc(GFP_KERNEL, 1);
+       bio = bio_alloc(GFP_NOFS, 1);
        if (unlikely(!bio)) {
                __free_page(page);
                return -ENOBUFS;