Commit 9b8c81d1 authored by Steven Whitehouse's avatar Steven Whitehouse

[GFS2] Allow bmap to allocate extents

We've supported mapping of extents when no block allocation is required
for some time. This patch extends that to mapping of extents when an
allocation has been requested. In that case we try to allocate as many
blocks as are requested, but we might return fewer in case there is
something preventing us from returning the complete amount (e.g. an
already allocated block is in the way).

Currently the only code path which can actually request multiple data
blocks in a single bmap call is the page_mkwrite path and even then it
only happens if there are multiple blocks per page. What this patch does
do however, is merge the allocation requests for metadata (growing the
metadata tree in either height or depth) with the allocation of the data
blocks in the case that both are needed. This results in lower overheads
even in the single block allocation case.

The one thing which we can't handle here at the moment is unstuffing. I
would like to be able to do that, but the problem which arises is that
in order to unstuff one has to get a locked page from the page cache
which results in locking problems in the (usual) case that the caller is
holding the page lock on the page it wishes to map. So that case will
have to be addressed in future patches.
Signed-off-by: default avatarSteven Whitehouse <swhiteho@redhat.com>
parent 7afd88d9
This diff is collapsed.
......@@ -159,6 +159,7 @@ static int gfs2_dir_write_data(struct gfs2_inode *ip, const char *buf,
unsigned int o;
int copied = 0;
int error = 0;
int new = 0;
if (!size)
return 0;
......@@ -183,7 +184,6 @@ static int gfs2_dir_write_data(struct gfs2_inode *ip, const char *buf,
while (copied < size) {
unsigned int amount;
struct buffer_head *bh;
int new = 0;
amount = size - copied;
if (amount > sdp->sd_sb.sb_bsize - o)
......
......@@ -1357,16 +1357,18 @@ static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal,
gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1);
gfs2_setbit(rgd, bi->bi_bh->b_data, bi->bi_clone, bi->bi_offset,
bi->bi_len, blk, new_state);
while(*n < elen) {
goal = blk;
while (*n < elen) {
goal++;
if (goal >= (bi->bi_len / GFS2_NBBY))
if (goal >= (bi->bi_len * GFS2_NBBY))
break;
if (gfs2_testbit(rgd, buffer, bi->bi_len, goal) !=
GFS2_BLKST_FREE)
break;
(*n)++;
gfs2_setbit(rgd, bi->bi_bh->b_data, bi->bi_clone,
bi->bi_offset, bi->bi_len, blk, new_state);
bi->bi_offset, bi->bi_len, goal,
new_state);
(*n)++;
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment