Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 344352
b: refs/heads/master
c: fa731fc
h: refs/heads/master
v: v3
  • Loading branch information
Steven Whitehouse committed Nov 13, 2012
1 parent 097916f commit e3dbf99
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9dbe9610b9df4efe0946299804ed46bb8f91dec2
refs/heads/master: fa731fc4e045a801814547188a63c2cd49a4cfe6
52 changes: 49 additions & 3 deletions trunk/fs/gfs2/bmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -991,6 +991,41 @@ static int gfs2_block_truncate_page(struct address_space *mapping, loff_t from)
return err;
}

/**
* gfs2_journaled_truncate - Wrapper for truncate_pagecache for jdata files
* @inode: The inode being truncated
* @oldsize: The original (larger) size
* @newsize: The new smaller size
*
* With jdata files, we have to journal a revoke for each block which is
* truncated. As a result, we need to split this into separate transactions
* if the number of pages being truncated gets too large.
*/

#define GFS2_JTRUNC_REVOKES 8192

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 chunk;
int error;

while (oldsize != newsize) {
chunk = oldsize - newsize;
if (chunk > max_chunk)
chunk = max_chunk;
truncate_pagecache(inode, oldsize, oldsize - chunk);
oldsize -= chunk;
gfs2_trans_end(sdp);
error = gfs2_trans_begin(sdp, RES_DINODE, GFS2_JTRUNC_REVOKES);
if (error)
return error;
}

return 0;
}

static int trunc_start(struct inode *inode, u64 oldsize, u64 newsize)
{
struct gfs2_inode *ip = GFS2_I(inode);
Expand All @@ -1000,8 +1035,10 @@ static int trunc_start(struct inode *inode, u64 oldsize, u64 newsize)
int journaled = gfs2_is_jdata(ip);
int error;

error = gfs2_trans_begin(sdp,
RES_DINODE + (journaled ? RES_JDATA : 0), 0);
if (journaled)
error = gfs2_trans_begin(sdp, RES_DINODE + RES_JDATA, GFS2_JTRUNC_REVOKES);
else
error = gfs2_trans_begin(sdp, RES_DINODE, 0);
if (error)
return error;

Expand All @@ -1026,7 +1063,16 @@ static int trunc_start(struct inode *inode, u64 oldsize, u64 newsize)
ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
gfs2_dinode_out(ip, dibh->b_data);

truncate_pagecache(inode, oldsize, newsize);
if (journaled)
error = gfs2_journaled_truncate(inode, oldsize, newsize);
else
truncate_pagecache(inode, oldsize, newsize);

if (error) {
brelse(dibh);
return error;
}

out_brelse:
brelse(dibh);
out:
Expand Down

0 comments on commit e3dbf99

Please sign in to comment.