From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1423372AbeE1LNC (ORCPT ); Mon, 28 May 2018 07:13:02 -0400 Received: from mail.kernel.org ([198.145.29.99]:60604 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1423949AbeE1LMz (ORCPT ); Mon, 28 May 2018 07:12:55 -0400 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Andreas Gruenbacher , Bob Peterson , Sasha Levin Subject: [PATCH 4.16 196/272] gfs2: Fix fallocate chunk size Date: Mon, 28 May 2018 12:03:49 +0200 Message-Id: <20180528100257.076003397@linuxfoundation.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180528100240.256525891@linuxfoundation.org> References: <20180528100240.256525891@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.16-stable review patch. If anyone has any objections, please let me know. ------------------ From: Andreas Gruenbacher [ Upstream commit 174d1232ebc84fcde8f5889d1171c9c7e74a10a7 ] 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 Signed-off-by: Bob Peterson Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- fs/gfs2/file.c | 5 +++-- fs/gfs2/quota.h | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -809,7 +809,7 @@ static long __gfs2_fallocate(struct file struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_alloc_parms ap = { .aflags = 0, }; 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; const loff_t pos = offset; const loff_t count = len; @@ -861,7 +861,8 @@ static long __gfs2_fallocate(struct file return error; /* ap.allowed tells us how many blocks quota will allow * 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; error = gfs2_inplace_reserve(ip, &ap); --- a/fs/gfs2/quota.h +++ b/fs/gfs2/quota.h @@ -45,6 +45,8 @@ static inline int gfs2_quota_lock_check( { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); int ret; + + ap->allowed = UINT_MAX; /* Assume we are permitted a whole lot */ if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) return 0; ret = gfs2_quota_lock(ip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE);