fix GFP_KERNEL misuses
PATCH 1/1 fix GFP_KERNEL misuses
Hello,
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 <[email protected]>
fs/gfs2/acl.c +3 -3
@@ -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;
fs/gfs2/dir.c +5 -5
@@ -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_di.di_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 ;
@@ -1790,7 +1790,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 ;
@@ -1865,7 +1865,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 ;
fs/gfs2/eattr.c +2 -2
@@ -449,7 +449,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 ;
@@ -1210,7 +1210,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 ;
fs/gfs2/inode.c +1 -1
@@ -1152,7 +1152,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;
fs/gfs2/locking/dlm/lock.c +2 -2
@@ -164,7 +164,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 ;
@@ -382,7 +382,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 ;
fs/gfs2/locking/nolock/main.c +1 -1
@@ -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 ;
fs/gfs2/quota.c +4 -4
@@ -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 ;
@@ -685,7 +685,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 ;
@@ -1116,12 +1116,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; }
fs/gfs2/recovery.c +1 -1
@@ -69,7 +69,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 ;
fs/gfs2/super.c +2 -2
@@ -219,7 +219,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 ;
@@ -227,7 +227,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 ;