Commit 5da5bb15 authored by Andreas Gruenbacher's avatar Andreas Gruenbacher Committed by Khalid Elmously

gfs2: Fix fallocate chunk size

BugLink: https://bugs.launchpad.net/bugs/1775771

[ Upstream commit 174d1232 ]

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>
Signed-off-by: default avatarSasha Levin <alexander.levin@microsoft.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarJuerg Haefliger <juergh@canonical.com>
Signed-off-by: default avatarKhalid Elmously <khalid.elmously@canonical.com>
parent 15e53126
...@@ -806,7 +806,7 @@ static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t ...@@ -806,7 +806,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;
...@@ -858,7 +858,8 @@ static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t ...@@ -858,7 +858,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);
......
...@@ -43,6 +43,8 @@ static inline int gfs2_quota_lock_check(struct gfs2_inode *ip, ...@@ -43,6 +43,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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment