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: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: Bob Peterson <rpeterso@redhat.com>
This commit is contained in:
parent
1b88accf6a
commit
174d1232eb
2 changed files with 5 additions and 2 deletions
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue