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 <[email protected]>
---
 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

Reply via email to