Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 564e12b1 authored by Bob Peterson's avatar Bob Peterson Committed by Steven Whitehouse
Browse files

GFS2: decouple quota allocations from block allocations



This patch separates the code pertaining to allocations into two
parts: quota-related information and block reservations.
This patch also moves all the block reservation structure allocations to
function gfs2_inplace_reserve to simplify the code, and moves
the frees to function gfs2_inplace_release.

Signed-off-by: default avatarBob Peterson <rpeterso@redhat.com>
Signed-off-by: default avatarSteven Whitehouse <swhiteho@redhat.com>
parent b3e47ca0
Loading
Loading
Loading
Loading
+9 −9
Original line number Diff line number Diff line
@@ -615,7 +615,7 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping,
	unsigned int data_blocks = 0, ind_blocks = 0, rblocks;
	int alloc_required;
	int error = 0;
	struct gfs2_alloc *al = NULL;
	struct gfs2_qadata *qa = NULL;
	pgoff_t index = pos >> PAGE_CACHE_SHIFT;
	unsigned from = pos & (PAGE_CACHE_SIZE - 1);
	struct page *page;
@@ -639,8 +639,8 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping,
		gfs2_write_calc_reserv(ip, len, &data_blocks, &ind_blocks);

	if (alloc_required) {
		al = gfs2_alloc_get(ip);
		if (!al) {
		qa = gfs2_qadata_get(ip);
		if (!qa) {
			error = -ENOMEM;
			goto out_unlock;
		}
@@ -649,8 +649,7 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping,
		if (error)
			goto out_alloc_put;

		al->al_requested = data_blocks + ind_blocks;
		error = gfs2_inplace_reserve(ip);
		error = gfs2_inplace_reserve(ip, data_blocks + ind_blocks);
		if (error)
			goto out_qunlock;
	}
@@ -711,7 +710,7 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping,
out_qunlock:
		gfs2_quota_unlock(ip);
out_alloc_put:
		gfs2_alloc_put(ip);
		gfs2_qadata_put(ip);
	}
out_unlock:
	if (&ip->i_inode == sdp->sd_rindex) {
@@ -848,7 +847,7 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping,
	struct gfs2_sbd *sdp = GFS2_SB(inode);
	struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
	struct buffer_head *dibh;
	struct gfs2_alloc *al = ip->i_alloc;
	struct gfs2_qadata *qa = ip->i_qadata;
	unsigned int from = pos & (PAGE_CACHE_SIZE - 1);
	unsigned int to = from + len;
	int ret;
@@ -880,10 +879,11 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping,
	brelse(dibh);
failed:
	gfs2_trans_end(sdp);
	if (al) {
	if (ip->i_res)
		gfs2_inplace_release(ip);
	if (qa) {
		gfs2_quota_unlock(ip);
		gfs2_alloc_put(ip);
		gfs2_qadata_put(ip);
	}
	if (inode == sdp->sd_rindex) {
		gfs2_glock_dq(&m_ip->i_gh);
+9 −10
Original line number Diff line number Diff line
@@ -1041,7 +1041,7 @@ static int trunc_dealloc(struct gfs2_inode *ip, u64 size)
		lblock = (size - 1) >> sdp->sd_sb.sb_bsize_shift;

	find_metapath(sdp, lblock, &mp, ip->i_height);
	if (!gfs2_alloc_get(ip))
	if (!gfs2_qadata_get(ip))
		return -ENOMEM;

	error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
@@ -1061,7 +1061,7 @@ static int trunc_dealloc(struct gfs2_inode *ip, u64 size)
	gfs2_quota_unhold(ip);

out:
	gfs2_alloc_put(ip);
	gfs2_qadata_put(ip);
	return error;
}

@@ -1163,21 +1163,20 @@ static int do_grow(struct inode *inode, u64 size)
	struct gfs2_inode *ip = GFS2_I(inode);
	struct gfs2_sbd *sdp = GFS2_SB(inode);
	struct buffer_head *dibh;
	struct gfs2_alloc *al = NULL;
	struct gfs2_qadata *qa = NULL;
	int error;

	if (gfs2_is_stuffed(ip) &&
	    (size > (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)))) {
		al = gfs2_alloc_get(ip);
		if (al == NULL)
		qa = gfs2_qadata_get(ip);
		if (qa == NULL)
			return -ENOMEM;

		error = gfs2_quota_lock_check(ip);
		if (error)
			goto do_grow_alloc_put;

		al->al_requested = 1;
		error = gfs2_inplace_reserve(ip);
		error = gfs2_inplace_reserve(ip, 1);
		if (error)
			goto do_grow_qunlock;
	}
@@ -1186,7 +1185,7 @@ static int do_grow(struct inode *inode, u64 size)
	if (error)
		goto do_grow_release;

	if (al) {
	if (qa) {
		error = gfs2_unstuff_dinode(ip, NULL);
		if (error)
			goto do_end_trans;
@@ -1205,12 +1204,12 @@ static int do_grow(struct inode *inode, u64 size)
do_end_trans:
	gfs2_trans_end(sdp);
do_grow_release:
	if (al) {
	if (qa) {
		gfs2_inplace_release(ip);
do_grow_qunlock:
		gfs2_quota_unlock(ip);
do_grow_alloc_put:
		gfs2_alloc_put(ip);
		gfs2_qadata_put(ip);
	}
	return error;
}
+2 −2
Original line number Diff line number Diff line
@@ -1850,7 +1850,7 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len,
	if (!ht)
		return -ENOMEM;

	if (!gfs2_alloc_get(dip)) {
	if (!gfs2_qadata_get(dip)) {
		error = -ENOMEM;
		goto out;
	}
@@ -1939,7 +1939,7 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len,
	gfs2_rlist_free(&rlist);
	gfs2_quota_unhold(dip);
out_put:
	gfs2_alloc_put(dip);
	gfs2_qadata_put(dip);
out:
	kfree(ht);
	return error;
+11 −14
Original line number Diff line number Diff line
@@ -365,7 +365,7 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
	u64 pos = page->index << PAGE_CACHE_SHIFT;
	unsigned int data_blocks, ind_blocks, rblocks;
	struct gfs2_holder gh;
	struct gfs2_alloc *al;
	struct gfs2_qadata *qa;
	loff_t size;
	int ret;

@@ -393,16 +393,15 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
	}

	ret = -ENOMEM;
	al = gfs2_alloc_get(ip);
	if (al == NULL)
	qa = gfs2_qadata_get(ip);
	if (qa == NULL)
		goto out_unlock;

	ret = gfs2_quota_lock_check(ip);
	if (ret)
		goto out_alloc_put;
	gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks);
	al->al_requested = data_blocks + ind_blocks;
	ret = gfs2_inplace_reserve(ip);
	ret = gfs2_inplace_reserve(ip, data_blocks + ind_blocks);
	if (ret)
		goto out_quota_unlock;

@@ -448,7 +447,7 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
out_quota_unlock:
	gfs2_quota_unlock(ip);
out_alloc_put:
	gfs2_alloc_put(ip);
	gfs2_qadata_put(ip);
out_unlock:
	gfs2_glock_dq(&gh);
out:
@@ -750,7 +749,7 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
	struct gfs2_inode *ip = GFS2_I(inode);
	unsigned int data_blocks = 0, ind_blocks = 0, rblocks;
	loff_t bytes, max_bytes;
	struct gfs2_alloc *al;
	struct gfs2_qadata *qa;
	int error;
	const loff_t pos = offset;
	const loff_t count = len;
@@ -784,8 +783,8 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
	while (len > 0) {
		if (len < bytes)
			bytes = len;
		al = gfs2_alloc_get(ip);
		if (!al) {
		qa = gfs2_qadata_get(ip);
		if (!qa) {
			error = -ENOMEM;
			goto out_unlock;
		}
@@ -797,8 +796,7 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
retry:
		gfs2_write_calc_reserv(ip, bytes, &data_blocks, &ind_blocks);

		al->al_requested = data_blocks + ind_blocks;
		error = gfs2_inplace_reserve(ip);
		error = gfs2_inplace_reserve(ip, data_blocks + ind_blocks);
		if (error) {
			if (error == -ENOSPC && bytes > sdp->sd_sb.sb_bsize) {
				bytes >>= 1;
@@ -812,7 +810,6 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
		max_bytes = bytes;
		calc_max_reserv(ip, (len > max_chunk_size)? max_chunk_size: len,
				&max_bytes, &data_blocks, &ind_blocks);
		al->al_requested = data_blocks + ind_blocks;

		rblocks = RES_DINODE + ind_blocks + RES_STATFS + RES_QUOTA +
			  RES_RG_HDR + gfs2_rg_blocks(ip);
@@ -834,7 +831,7 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
		offset += max_bytes;
		gfs2_inplace_release(ip);
		gfs2_quota_unlock(ip);
		gfs2_alloc_put(ip);
		gfs2_qadata_put(ip);
	}

	if (error == 0)
@@ -846,7 +843,7 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
out_qunlock:
	gfs2_quota_unlock(ip);
out_alloc_put:
	gfs2_alloc_put(ip);
	gfs2_qadata_put(ip);
out_unlock:
	gfs2_glock_dq(&ip->i_gh);
out_uninit:
+10 −9
Original line number Diff line number Diff line
@@ -244,16 +244,16 @@ struct gfs2_glock {

#define GFS2_MIN_LVB_SIZE 32	/* Min size of LVB that gfs2 supports */

struct gfs2_alloc {
struct gfs2_qadata { /* quota allocation data */
	/* Quota stuff */
	struct gfs2_quota_data *al_qd[2*MAXQUOTAS];
	struct gfs2_holder al_qd_ghs[2*MAXQUOTAS];
	unsigned int al_qd_num;

	u32 al_requested; /* Filled in by caller of gfs2_inplace_reserve() */
	struct gfs2_quota_data *qa_qd[2*MAXQUOTAS];
	struct gfs2_holder qa_qd_ghs[2*MAXQUOTAS];
	unsigned int qa_qd_num;
};

	/* Filled in by gfs2_inplace_reserve() */
	struct gfs2_holder al_rgd_gh;
struct gfs2_blkreserv {
	u32 rs_requested; /* Filled in by caller of gfs2_inplace_reserve() */
	struct gfs2_holder rs_rgd_gh; /* Filled in by gfs2_inplace_reserve() */
};

enum {
@@ -274,7 +274,8 @@ struct gfs2_inode {
	struct gfs2_glock *i_gl; /* Move into i_gh? */
	struct gfs2_holder i_iopen_gh;
	struct gfs2_holder i_gh; /* for prepare/commit_write only */
	struct gfs2_alloc *i_alloc;
	struct gfs2_qadata *i_qadata; /* quota allocation data */
	struct gfs2_blkreserv *i_res; /* resource group block reservation */
	struct gfs2_rgrpd *i_rgd;
	u64 i_goal;	/* goal block for allocations */
	struct rw_semaphore i_rw_mutex;
Loading