Skip to content

Commit

Permalink
GFS2: Ensure that the inode goal block settings are updated
Browse files Browse the repository at this point in the history
GFS2 has a goal block associated with each inode indicating the
search start position for future block allocations (in fact there
are two, but thats for backward compatibility with GFS1 as they
are set to identical locations in GFS2).

In some circumstances, depending on the ordering of updates to
the inode it was possible for the goal block settings to not
be updated on disk. This patch ensures that the goal block will
always get updated, thus reducing the potential for searching
the same (already allocated) blocks again when looking for free
space during block allocation.

Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
  • Loading branch information
Steven Whitehouse committed Apr 23, 2009
1 parent d8bd504 commit d9ba761
Showing 1 changed file with 9 additions and 1 deletion.
10 changes: 9 additions & 1 deletion fs/gfs2/rgrp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1444,10 +1444,12 @@ static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, u64 bstart,
u64 gfs2_alloc_block(struct gfs2_inode *ip, unsigned int *n)
{
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct buffer_head *dibh;
struct gfs2_alloc *al = ip->i_alloc;
struct gfs2_rgrpd *rgd = al->al_rgd;
u32 goal, blk;
u64 block;
int error;

if (rgrp_contains_block(rgd, ip->i_goal))
goal = ip->i_goal - rgd->rd_data0;
Expand All @@ -1460,7 +1462,13 @@ u64 gfs2_alloc_block(struct gfs2_inode *ip, unsigned int *n)
rgd->rd_last_alloc = blk;
block = rgd->rd_data0 + blk;
ip->i_goal = block;

error = gfs2_meta_inode_buffer(ip, &dibh);
if (error == 0) {
struct gfs2_dinode *di = (struct gfs2_dinode *)dibh->b_data;
gfs2_trans_add_bh(ip->i_gl, dibh, 1);
di->di_goal_meta = di->di_goal_data = cpu_to_be64(ip->i_goal);
brelse(dibh);
}
gfs2_assert_withdraw(sdp, rgd->rd_free >= *n);
rgd->rd_free -= *n;

Expand Down

0 comments on commit d9ba761

Please sign in to comment.