mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 16:54:21 +00:00 
			
		
		
		
	[GFS2] fix GFP_KERNEL misuses
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>
This commit is contained in:
		
							parent
							
								
									773adff8e9
								
							
						
					
					
						commit
						16c5f06f15
					
				
					 9 changed files with 21 additions and 21 deletions
				
			
		|  | @ -116,7 +116,7 @@ static int acl_get(struct gfs2_inode *ip, int access, struct posix_acl **acl, | ||||||
| 		goto out; | 		goto out; | ||||||
| 
 | 
 | ||||||
| 	er.er_data_len = GFS2_EA_DATA_LEN(el->el_ea); | 	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; | 	error = -ENOMEM; | ||||||
| 	if (!er.er_data) | 	if (!er.er_data) | ||||||
| 		goto out; | 		goto out; | ||||||
|  | @ -222,7 +222,7 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip) | ||||||
| 		return error; | 		return error; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	clone = posix_acl_clone(acl, GFP_KERNEL); | 	clone = posix_acl_clone(acl, GFP_NOFS); | ||||||
| 	error = -ENOMEM; | 	error = -ENOMEM; | ||||||
| 	if (!clone) | 	if (!clone) | ||||||
| 		goto out; | 		goto out; | ||||||
|  | @ -272,7 +272,7 @@ int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr) | ||||||
| 	if (!acl) | 	if (!acl) | ||||||
| 		return gfs2_setattr_simple(ip, attr); | 		return gfs2_setattr_simple(ip, attr); | ||||||
| 
 | 
 | ||||||
| 	clone = posix_acl_clone(acl, GFP_KERNEL); | 	clone = posix_acl_clone(acl, GFP_NOFS); | ||||||
| 	error = -ENOMEM; | 	error = -ENOMEM; | ||||||
| 	if (!clone) | 	if (!clone) | ||||||
| 		goto out; | 		goto out; | ||||||
|  |  | ||||||
|  | @ -1089,7 +1089,7 @@ static int dir_double_exhash(struct gfs2_inode *dip) | ||||||
| 
 | 
 | ||||||
| 	/*  Allocate both the "from" and "to" buffers in one big chunk  */ | 	/*  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--;) { | 	for (block = dip->i_di.di_size >> sdp->sd_hash_bsize_shift; block--;) { | ||||||
| 		error = gfs2_dir_read_data(dip, (char *)buf, | 		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); | 	hash = gfs2_dir_offset2hash(*offset); | ||||||
| 	index = hash >> (32 - dip->i_depth); | 	index = hash >> (32 - dip->i_depth); | ||||||
| 
 | 
 | ||||||
| 	lp = kmalloc(sdp->sd_hash_bsize, GFP_KERNEL); | 	lp = kmalloc(sdp->sd_hash_bsize, GFP_NOFS); | ||||||
| 	if (!lp) | 	if (!lp) | ||||||
| 		return -ENOMEM; | 		return -ENOMEM; | ||||||
| 
 | 
 | ||||||
|  | @ -1443,7 +1443,7 @@ int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque, | ||||||
| 
 | 
 | ||||||
| 	error = -ENOMEM; | 	error = -ENOMEM; | ||||||
| 	/* 96 is max number of dirents which can be stuffed into an inode */ | 	/* 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) { | 	if (darr) { | ||||||
| 		g.pdent = darr; | 		g.pdent = darr; | ||||||
| 		g.offset = 0; | 		g.offset = 0; | ||||||
|  | @ -1789,7 +1789,7 @@ static int foreach_leaf(struct gfs2_inode *dip, leaf_call_t lc, void *data) | ||||||
| 		return -EIO; | 		return -EIO; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	lp = kmalloc(sdp->sd_hash_bsize, GFP_KERNEL); | 	lp = kmalloc(sdp->sd_hash_bsize, GFP_NOFS); | ||||||
| 	if (!lp) | 	if (!lp) | ||||||
| 		return -ENOMEM; | 		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)); | 	memset(&rlist, 0, sizeof(struct gfs2_rgrp_list)); | ||||||
| 
 | 
 | ||||||
| 	ht = kzalloc(size, GFP_KERNEL); | 	ht = kzalloc(size, GFP_NOFS); | ||||||
| 	if (!ht) | 	if (!ht) | ||||||
| 		return -ENOMEM; | 		return -ENOMEM; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -448,7 +448,7 @@ static int ea_get_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea, | ||||||
| 	unsigned int x; | 	unsigned int x; | ||||||
| 	int error = 0; | 	int error = 0; | ||||||
| 
 | 
 | ||||||
| 	bh = kcalloc(nptrs, sizeof(struct buffer_head *), GFP_KERNEL); | 	bh = kcalloc(nptrs, sizeof(struct buffer_head *), GFP_NOFS); | ||||||
| 	if (!bh) | 	if (!bh) | ||||||
| 		return -ENOMEM; | 		return -ENOMEM; | ||||||
| 
 | 
 | ||||||
|  | @ -1206,7 +1206,7 @@ static int ea_acl_chmod_unstuffed(struct gfs2_inode *ip, | ||||||
| 	unsigned int x; | 	unsigned int x; | ||||||
| 	int error; | 	int error; | ||||||
| 
 | 
 | ||||||
| 	bh = kcalloc(nptrs, sizeof(struct buffer_head *), GFP_KERNEL); | 	bh = kcalloc(nptrs, sizeof(struct buffer_head *), GFP_NOFS); | ||||||
| 	if (!bh) | 	if (!bh) | ||||||
| 		return -ENOMEM; | 		return -ENOMEM; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1231,7 +1231,7 @@ int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len) | ||||||
| 
 | 
 | ||||||
| 	x = ip->i_di.di_size + 1; | 	x = ip->i_di.di_size + 1; | ||||||
| 	if (x > *len) { | 	if (x > *len) { | ||||||
| 		*buf = kmalloc(x, GFP_KERNEL); | 		*buf = kmalloc(x, GFP_NOFS); | ||||||
| 		if (!*buf) { | 		if (!*buf) { | ||||||
| 			error = -ENOMEM; | 			error = -ENOMEM; | ||||||
| 			goto out_brelse; | 			goto out_brelse; | ||||||
|  |  | ||||||
|  | @ -165,7 +165,7 @@ static int gdlm_create_lp(struct gdlm_ls *ls, struct lm_lockname *name, | ||||||
| { | { | ||||||
| 	struct gdlm_lock *lp; | 	struct gdlm_lock *lp; | ||||||
| 
 | 
 | ||||||
| 	lp = kzalloc(sizeof(struct gdlm_lock), GFP_KERNEL); | 	lp = kzalloc(sizeof(struct gdlm_lock), GFP_NOFS); | ||||||
| 	if (!lp) | 	if (!lp) | ||||||
| 		return -ENOMEM; | 		return -ENOMEM; | ||||||
| 
 | 
 | ||||||
|  | @ -383,7 +383,7 @@ static int gdlm_add_lvb(struct gdlm_lock *lp) | ||||||
| { | { | ||||||
| 	char *lvb; | 	char *lvb; | ||||||
| 
 | 
 | ||||||
| 	lvb = kzalloc(GDLM_LVB_SIZE, GFP_KERNEL); | 	lvb = kzalloc(GDLM_LVB_SIZE, GFP_NOFS); | ||||||
| 	if (!lvb) | 	if (!lvb) | ||||||
| 		return -ENOMEM; | 		return -ENOMEM; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -140,7 +140,7 @@ static int nolock_hold_lvb(void *lock, char **lvbp) | ||||||
| 	struct nolock_lockspace *nl = lock; | 	struct nolock_lockspace *nl = lock; | ||||||
| 	int error = 0; | 	int error = 0; | ||||||
| 
 | 
 | ||||||
| 	*lvbp = kzalloc(nl->nl_lvb_size, GFP_KERNEL); | 	*lvbp = kzalloc(nl->nl_lvb_size, GFP_NOFS); | ||||||
| 	if (!*lvbp) | 	if (!*lvbp) | ||||||
| 		error = -ENOMEM; | 		error = -ENOMEM; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -94,7 +94,7 @@ static int qd_alloc(struct gfs2_sbd *sdp, int user, u32 id, | ||||||
| 	struct gfs2_quota_data *qd; | 	struct gfs2_quota_data *qd; | ||||||
| 	int error; | 	int error; | ||||||
| 
 | 
 | ||||||
| 	qd = kzalloc(sizeof(struct gfs2_quota_data), GFP_KERNEL); | 	qd = kzalloc(sizeof(struct gfs2_quota_data), GFP_NOFS); | ||||||
| 	if (!qd) | 	if (!qd) | ||||||
| 		return -ENOMEM; | 		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), | 	gfs2_write_calc_reserv(ip, sizeof(struct gfs2_quota), | ||||||
| 			      &data_blocks, &ind_blocks); | 			      &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) | 	if (!ghs) | ||||||
| 		return -ENOMEM; | 		return -ENOMEM; | ||||||
| 
 | 
 | ||||||
|  | @ -1118,12 +1118,12 @@ int gfs2_quota_init(struct gfs2_sbd *sdp) | ||||||
| 	error = -ENOMEM; | 	error = -ENOMEM; | ||||||
| 
 | 
 | ||||||
| 	sdp->sd_quota_bitmap = kcalloc(sdp->sd_quota_chunks, | 	sdp->sd_quota_bitmap = kcalloc(sdp->sd_quota_chunks, | ||||||
| 				       sizeof(unsigned char *), GFP_KERNEL); | 				       sizeof(unsigned char *), GFP_NOFS); | ||||||
| 	if (!sdp->sd_quota_bitmap) | 	if (!sdp->sd_quota_bitmap) | ||||||
| 		return error; | 		return error; | ||||||
| 
 | 
 | ||||||
| 	for (x = 0; x < sdp->sd_quota_chunks; x++) { | 	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]) | 		if (!sdp->sd_quota_bitmap[x]) | ||||||
| 			goto fail; | 			goto fail; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -68,7 +68,7 @@ int gfs2_revoke_add(struct gfs2_sbd *sdp, u64 blkno, unsigned int where) | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	rr = kmalloc(sizeof(struct gfs2_revoke_replay), GFP_KERNEL); | 	rr = kmalloc(sizeof(struct gfs2_revoke_replay), GFP_NOFS); | ||||||
| 	if (!rr) | 	if (!rr) | ||||||
| 		return -ENOMEM; | 		return -ENOMEM; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -210,7 +210,7 @@ int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector) | ||||||
| 	struct page *page; | 	struct page *page; | ||||||
| 	struct bio *bio; | 	struct bio *bio; | ||||||
| 
 | 
 | ||||||
| 	page = alloc_page(GFP_KERNEL); | 	page = alloc_page(GFP_NOFS); | ||||||
| 	if (unlikely(!page)) | 	if (unlikely(!page)) | ||||||
| 		return -ENOBUFS; | 		return -ENOBUFS; | ||||||
| 
 | 
 | ||||||
|  | @ -218,7 +218,7 @@ int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector) | ||||||
| 	ClearPageDirty(page); | 	ClearPageDirty(page); | ||||||
| 	lock_page(page); | 	lock_page(page); | ||||||
| 
 | 
 | ||||||
| 	bio = bio_alloc(GFP_KERNEL, 1); | 	bio = bio_alloc(GFP_NOFS, 1); | ||||||
| 	if (unlikely(!bio)) { | 	if (unlikely(!bio)) { | ||||||
| 		__free_page(page); | 		__free_page(page); | ||||||
| 		return -ENOBUFS; | 		return -ENOBUFS; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Josef Bacik
						Josef Bacik