summaryrefslogtreecommitdiffstats
path: root/fs/gfs2/bmap.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2008-02-06 10:11:15 +0000
committerSteven Whitehouse <swhiteho@redhat.com>2008-03-31 10:40:47 +0100
commitb45e41d7d56dfef1ae9e02e6c59990066ba82e5c (patch)
treec139447fa57beb3886def4e17449cc34bf40cf3c /fs/gfs2/bmap.c
parent1639431a3f57b43da1e15e9268a1d691ac01ba26 (diff)
[GFS2] Add extent allocation to block allocator
Rather than having to allocate a single block at a time, this patch allows the block allocator to allocate an extent. Since there is no difference (so far as the block allocator is concerned) between data blocks and indirect blocks, it is posible to allocate a single extent and for the caller to unrevoke just the blocks required for indirect blocks. Currently the only bit of GFS2 to make use of this feature is the build height function. The intention is that gfs2_block_map will be changed to make use of this feature in future patches. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/bmap.c')
-rw-r--r--fs/gfs2/bmap.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index e3a75a27cee..1fda731c074 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -136,8 +136,9 @@ int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page)
/* Get a free block, fill it with the stuffed data,
and write it out to disk */
+ unsigned int n = 1;
+ block = gfs2_alloc_block(ip, &n);
if (isdir) {
- block = gfs2_alloc_block(ip);
gfs2_trans_add_unrevoke(GFS2_SB(&ip->i_inode), block, 1);
error = gfs2_dir_get_new_buffer(ip, block, &bh);
if (error)
@@ -146,8 +147,6 @@ int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page)
dibh, sizeof(struct gfs2_dinode));
brelse(bh);
} else {
- block = gfs2_alloc_block(ip);
-
error = gfs2_unstuffer_page(ip, dibh, block, page);
if (error)
goto out_brelse;
@@ -195,7 +194,7 @@ static int build_height(struct inode *inode, struct metapath *mp, unsigned heigh
int error;
__be64 *bp;
u64 bn;
- unsigned n;
+ unsigned n, i = 0;
if (height <= ip->i_height)
return 0;
@@ -204,12 +203,16 @@ static int build_height(struct inode *inode, struct metapath *mp, unsigned heigh
if (error)
return error;
- for(n = 0; n < new_height; n++) {
- bn = gfs2_alloc_block(ip);
- gfs2_trans_add_unrevoke(GFS2_SB(inode), bn, 1);
- mp->mp_bh[n] = gfs2_meta_new(ip->i_gl, bn);
- gfs2_trans_add_bh(ip->i_gl, mp->mp_bh[n], 1);
- }
+ do {
+ n = new_height - i;
+ bn = gfs2_alloc_block(ip, &n);
+ gfs2_trans_add_unrevoke(GFS2_SB(inode), bn, n);
+ do {
+ mp->mp_bh[i] = gfs2_meta_new(ip->i_gl, bn++);
+ gfs2_trans_add_bh(ip->i_gl, mp->mp_bh[i], 1);
+ i++;
+ } while(i < n);
+ } while(i < new_height);
n = 0;
bn = mp->mp_bh[0]->b_blocknr;
@@ -358,6 +361,7 @@ static int lookup_block(struct gfs2_inode *ip, unsigned int height,
{
int boundary;
__be64 *ptr = metapointer(&boundary, height, mp);
+ unsigned int n = 1;
if (*ptr) {
*block = be64_to_cpu(*ptr);
@@ -369,7 +373,7 @@ static int lookup_block(struct gfs2_inode *ip, unsigned int height,
if (!create)
return 0;
- *block = gfs2_alloc_block(ip);
+ *block = gfs2_alloc_block(ip, &n);
if (height != ip->i_height - 1 || gfs2_is_dir(ip))
gfs2_trans_add_unrevoke(GFS2_SB(&ip->i_inode), *block, 1);