From mboxrd@z Thu Jan 1 00:00:00 1970 From: Bob Peterson Date: Fri, 3 Jan 2020 09:31:22 -0600 Subject: [Cluster-devel] [GFS2 PATCH 5/6] gfs2: revoke cleanup: truncate functions In-Reply-To: <20200103153123.402971-1-rpeterso@redhat.com> References: <20200103153123.402971-1-rpeterso@redhat.com> Message-ID: <20200103153123.402971-6-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 truncate functions. Signed-off-by: Bob Peterson --- fs/gfs2/bmap.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 403d5ada2f52..9a4c9c8611f7 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -1355,8 +1355,6 @@ static int gfs2_block_zero_range(struct inode *inode, loff_t from, return iomap_zero_range(inode, from, length, NULL, &gfs2_iomap_ops); } -#define GFS2_JTRUNC_REVOKES 8192 - /** * gfs2_journaled_truncate - Wrapper for truncate_pagecache for jdata files * @inode: The inode being truncated @@ -1371,7 +1369,7 @@ static int gfs2_block_zero_range(struct inode *inode, loff_t from, static int gfs2_journaled_truncate(struct inode *inode, u64 oldsize, u64 newsize) { struct gfs2_sbd *sdp = GFS2_SB(inode); - u64 max_chunk = GFS2_JTRUNC_REVOKES * sdp->sd_vfs->s_blocksize; + u64 max_chunk = sdp->sd_ldptrs * sdp->sd_vfs->s_blocksize; u64 chunk; int error; @@ -1395,7 +1393,8 @@ static int gfs2_journaled_truncate(struct inode *inode, u64 oldsize, u64 newsize continue; gfs2_trans_end(sdp); - error = gfs2_trans_begin(sdp, RES_DINODE, GFS2_JTRUNC_REVOKES); + error = gfs2_trans_begin(sdp, RES_DINODE, + RES_DINODE + sdp->sd_ldptrs); if (error) return error; } @@ -1413,7 +1412,8 @@ static int trunc_start(struct inode *inode, u64 newsize) int error; if (journaled) - error = gfs2_trans_begin(sdp, RES_DINODE + RES_JDATA, GFS2_JTRUNC_REVOKES); + error = gfs2_trans_begin(sdp, RES_DINODE + RES_JDATA, + RES_DINODE + sdp->sd_ldptrs); else error = gfs2_trans_begin(sdp, RES_DINODE, 0); if (error) @@ -2404,7 +2404,7 @@ static int gfs2_journaled_truncate_range(struct inode *inode, loff_t offset, loff_t length) { struct gfs2_sbd *sdp = GFS2_SB(inode); - loff_t max_chunk = GFS2_JTRUNC_REVOKES * sdp->sd_vfs->s_blocksize; + loff_t max_chunk = sdp->sd_ldptrs * sdp->sd_vfs->s_blocksize; int error; while (length) { @@ -2429,7 +2429,8 @@ static int gfs2_journaled_truncate_range(struct inode *inode, loff_t offset, continue; gfs2_trans_end(sdp); - error = gfs2_trans_begin(sdp, RES_DINODE, GFS2_JTRUNC_REVOKES); + error = gfs2_trans_begin(sdp, RES_DINODE, + RES_DINODE + sdp->sd_ldptrs); if (error) return error; } @@ -2453,7 +2454,7 @@ int __gfs2_punch_hole(struct file *file, loff_t offset, loff_t length) if (gfs2_is_jdata(ip)) error = gfs2_trans_begin(sdp, RES_DINODE + 2 * RES_JDATA, - GFS2_JTRUNC_REVOKES); + RES_DINODE + sdp->sd_ldptrs); else error = gfs2_trans_begin(sdp, RES_DINODE, 0); if (error) -- 2.24.1