From mboxrd@z Thu Jan 1 00:00:00 1970 From: Bob Peterson Date: Fri, 3 Jan 2020 09:31:21 -0600 Subject: [Cluster-devel] [GFS2 PATCH 4/6] gfs2: revoke cleanup: gfs2_iomap_begin_write In-Reply-To: <20200103153123.402971-1-rpeterso@redhat.com> References: <20200103153123.402971-1-rpeterso@redhat.com> Message-ID: <20200103153123.402971-5-rpeterso@redhat.com> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Several gfs2 functions failed to reserve enough revoke entries for their transactions in the journal. Function gfs2_trans_remove_revoke unconditionally decrements tr->tr_num_revoke, and if not enough revokes are reserved, the value goes from 0 to 4294967295 (-1, but it's an unsigned int). This is later re-added to the system-wide revoke numbers, thereby decrementing the value (sd_log_commited_revoke) "properly," but by accident. This worked properly most of the time because one transaction would reserve space for revokes, then it would be merged with the system transaction (sdp->sd_log_tr) and it usually did not run out, because you can hold a lot of revoke entries per log descriptor block. Some of the code, such as gfs2_write_revokes, would work around this and somehow got it right most of the time. However, some jdata tests with xfstests generic/269 encountered problems when it actually ran out. This patch is part of a series that tries to do proper accounting of revokes. This patch adds the needed revoke entries to function gfs2_iomap_begin_write. Signed-off-by: Bob Peterson --- fs/gfs2/bmap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 08f6fbb3655e..403d5ada2f52 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -1074,7 +1074,7 @@ static int gfs2_iomap_begin_write(struct inode *inode, loff_t pos, if (unstuff || iomap->type == IOMAP_HOLE) { unsigned int data_blocks, ind_blocks; struct gfs2_alloc_parms ap = {}; - unsigned int rblocks; + unsigned int rblocks, new_blocks = 0; struct gfs2_trans *tr; gfs2_write_calc_reserv(ip, iomap->length, &data_blocks, @@ -1095,10 +1095,10 @@ static int gfs2_iomap_begin_write(struct inode *inode, loff_t pos, rblocks += RES_STATFS + RES_QUOTA; if (inode == sdp->sd_rindex) rblocks += 2 * RES_STATFS; - rblocks += gfs2_rg_blocks(ip, data_blocks + ind_blocks); + new_blocks += gfs2_rg_blocks(ip, data_blocks + ind_blocks); + rblocks += new_blocks; - ret = gfs2_trans_begin(sdp, rblocks, - iomap->length >> inode->i_blkbits); + ret = gfs2_trans_begin(sdp, rblocks, new_blocks); if (ret) goto out_trans_fail; -- 2.24.1