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

Commit 174d1232 authored by Andreas Gruenbacher's avatar Andreas Gruenbacher Committed by Bob Peterson
Browse files

gfs2: Fix fallocate chunk size



The chunk size of allocations in __gfs2_fallocate is calculated
incorrectly.  The size can collapse, causing __gfs2_fallocate to
allocate one block at a time, which is very inefficient.  This needs
fixing in two places:

In gfs2_quota_lock_check, always set ap->allowed to UINT_MAX to indicate
that there is no quota limit.  This fixes callers that rely on
ap->allowed to be set even when quotas are off.

In __gfs2_fallocate, reset max_blks to UINT_MAX in each iteration of the
loop to make sure that allocation limits from one resource group won't
spill over into another resource group.

Signed-off-by: default avatarAndreas Gruenbacher <agruenba@redhat.com>
Signed-off-by: default avatarBob Peterson <rpeterso@redhat.com>
parent 1b88accf
Loading
Loading
Loading
Loading
+3 −2
Original line number Original line Diff line number Diff line
@@ -809,7 +809,7 @@ static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t
	struct gfs2_inode *ip = GFS2_I(inode);
	struct gfs2_inode *ip = GFS2_I(inode);
	struct gfs2_alloc_parms ap = { .aflags = 0, };
	struct gfs2_alloc_parms ap = { .aflags = 0, };
	unsigned int data_blocks = 0, ind_blocks = 0, rblocks;
	unsigned int data_blocks = 0, ind_blocks = 0, rblocks;
	loff_t bytes, max_bytes, max_blks = UINT_MAX;
	loff_t bytes, max_bytes, max_blks;
	int error;
	int error;
	const loff_t pos = offset;
	const loff_t pos = offset;
	const loff_t count = len;
	const loff_t count = len;
@@ -861,7 +861,8 @@ static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t
			return error;
			return error;
		/* ap.allowed tells us how many blocks quota will allow
		/* ap.allowed tells us how many blocks quota will allow
		 * us to write. Check if this reduces max_blks */
		 * us to write. Check if this reduces max_blks */
		if (ap.allowed && ap.allowed < max_blks)
		max_blks = UINT_MAX;
		if (ap.allowed)
			max_blks = ap.allowed;
			max_blks = ap.allowed;


		error = gfs2_inplace_reserve(ip, &ap);
		error = gfs2_inplace_reserve(ip, &ap);
+2 −0
Original line number Original line Diff line number Diff line
@@ -45,6 +45,8 @@ static inline int gfs2_quota_lock_check(struct gfs2_inode *ip,
{
{
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
	int ret;
	int ret;

	ap->allowed = UINT_MAX; /* Assume we are permitted a whole lot */
	if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF)
	if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF)
		return 0;
		return 0;
	ret = gfs2_quota_lock(ip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE);
	ret = gfs2_quota_lock(ip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE);