Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 38857
b: refs/heads/master
c: 7a6bbac
h: refs/heads/master
i:
  38855: 1633ede
v: v3
  • Loading branch information
Steven Whitehouse committed Sep 18, 2006
1 parent 7ac7a87 commit 81674fd
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 142 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: 65952fb4e91c159d253bd28ceaf028a86dbb0b02
refs/heads/master: 7a6bbacbb8dec6fbd1242c959250388f907d429e
131 changes: 64 additions & 67 deletions trunk/fs/gfs2/bmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -423,8 +423,7 @@ static int lookup_block(struct gfs2_inode *ip, struct buffer_head *bh,
* gfs2_block_pointers - Map a block from an inode to a disk block
* @inode: The inode
* @lblock: The logical block number
* @new: Value/Result argument (1 = may create/did create new blocks)
* @boundary: gets set if we've hit a block boundary
* @map_bh: The bh to be mapped
* @mp: metapath to use
*
* Find the block number on the current device which corresponds to an
Expand All @@ -433,70 +432,90 @@ static int lookup_block(struct gfs2_inode *ip, struct buffer_head *bh,
* Returns: errno
*/

static struct buffer_head *gfs2_block_pointers(struct inode *inode, u64 lblock,
int *new, u64 *dblock,
int *boundary,
struct metapath *mp)
static int gfs2_block_pointers(struct inode *inode, u64 lblock, int create,
struct buffer_head *bh_map, struct metapath *mp,
unsigned int maxlen)
{
struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_sbd *sdp = GFS2_SB(inode);
struct buffer_head *bh;
int create = *new;
unsigned int bsize;
unsigned int height;
unsigned int end_of_metadata;
unsigned int x;
int error = 0;

*new = 0;
*dblock = 0;
int new = 0;
u64 dblock = 0;
int boundary;

if (gfs2_assert_warn(sdp, !gfs2_is_stuffed(ip)))
goto out;
return 0;

bsize = gfs2_is_dir(ip) ? sdp->sd_jbsize : sdp->sd_sb.sb_bsize;

height = calc_tree_height(ip, (lblock + 1) * bsize);
if (ip->i_di.di_height < height) {
if (!create)
goto out;
return 0;

error = build_height(inode, height);
if (error)
goto out;
return error;
}

find_metapath(ip, lblock, mp);
end_of_metadata = ip->i_di.di_height - 1;

error = gfs2_meta_inode_buffer(ip, &bh);
if (error)
goto out;
return error;

for (x = 0; x < end_of_metadata; x++) {
lookup_block(ip, bh, x, mp, create, new, dblock);
lookup_block(ip, bh, x, mp, create, &new, &dblock);
brelse(bh);
if (!*dblock)
goto out;
if (!dblock)
return 0;

error = gfs2_meta_indirect_buffer(ip, x+1, *dblock, *new, &bh);
error = gfs2_meta_indirect_buffer(ip, x+1, dblock, new, &bh);
if (error)
goto out;
return error;
}

*boundary = lookup_block(ip, bh, end_of_metadata, mp, create, new, dblock);
if (*new) {
struct buffer_head *dibh;
error = gfs2_meta_inode_buffer(ip, &dibh);
if (!error) {
gfs2_trans_add_bh(ip->i_gl, dibh, 1);
gfs2_dinode_out(&ip->i_di, dibh->b_data);
brelse(dibh);
boundary = lookup_block(ip, bh, end_of_metadata, mp, create, &new, &dblock);
clear_buffer_mapped(bh_map);
clear_buffer_new(bh_map);
clear_buffer_boundary(bh_map);

if (dblock) {
map_bh(bh_map, inode->i_sb, dblock);
if (boundary)
set_buffer_boundary(bh);
if (new) {
struct buffer_head *dibh;
error = gfs2_meta_inode_buffer(ip, &dibh);
if (!error) {
gfs2_trans_add_bh(ip->i_gl, dibh, 1);
gfs2_dinode_out(&ip->i_di, dibh->b_data);
brelse(dibh);
}
set_buffer_new(bh_map);
goto out_brelse;
}
while(--maxlen && !buffer_boundary(bh_map)) {
u64 eblock;

mp->mp_list[end_of_metadata]++;
boundary = lookup_block(ip, bh, end_of_metadata, mp, 0, &new, &eblock);
if (eblock != ++dblock)
break;
bh_map->b_size += inode->i_blksize;
if (boundary)
set_buffer_boundary(bh_map);
}
}
return bh;
out:
return ERR_PTR(error);
out_brelse:
brelse(bh);
return 0;
}


Expand All @@ -518,61 +537,39 @@ static inline void bmap_unlock(struct inode *inode, int create)
up_read(&ip->i_rw_mutex);
}

int gfs2_block_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, int *boundary)
int gfs2_block_map(struct inode *inode, u64 lblock, int create,
struct buffer_head *bh, unsigned int maxlen)
{
struct metapath mp;
struct buffer_head *bh;
int create = *new;
int ret;

bmap_lock(inode, create);
bh = gfs2_block_pointers(inode, lblock, new, dblock, boundary, &mp);
ret = gfs2_block_pointers(inode, lblock, create, bh, &mp, maxlen);
bmap_unlock(inode, create);
if (!bh)
return 0;
if (IS_ERR(bh))
return PTR_ERR(bh);
brelse(bh);
return 0;
return ret;
}

int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen)
{
struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_sbd *sdp = GFS2_SB(inode);
struct metapath mp;
struct buffer_head *bh;
int boundary;
struct buffer_head bh = { .b_state = 0, .b_blocknr = 0, .b_size = 0 };
int ret;
int create = *new;

BUG_ON(!extlen);
BUG_ON(!dblock);
BUG_ON(!new);

bmap_lock(inode, create);
bh = gfs2_block_pointers(inode, lblock, new, dblock, &boundary, &mp);
*extlen = 1;

if (bh != NULL && !IS_ERR(bh) && *dblock != 0 && *new == 0) {
u64 tmp_dblock;
int tmp_new;
unsigned int nptrs;
unsigned end_of_metadata = ip->i_di.di_height - 1;

nptrs = (end_of_metadata) ? sdp->sd_inptrs : sdp->sd_diptrs;
while (++mp.mp_list[end_of_metadata] < nptrs) {
lookup_block(ip, bh, end_of_metadata, &mp, 0, &tmp_new, &tmp_dblock);
if (*dblock + *extlen != tmp_dblock)
break;
++*extlen;
}
}
ret = gfs2_block_pointers(inode, lblock, create, &bh, &mp, *extlen);
bmap_unlock(inode, create);
if (!bh)
return 0;
if (IS_ERR(bh))
return PTR_ERR(bh);
brelse(bh);
return 0;
*extlen = bh.b_size >> inode->i_blkbits;
*dblock = bh.b_blocknr;
if (buffer_new(&bh))
*new = 1;
else
*new = 0;
return ret;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion trunk/fs/gfs2/bmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ struct gfs2_inode;
struct page;

int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page);
int gfs2_block_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, int *boundary);
int gfs2_block_map(struct inode *inode, u64 lblock, int create, struct buffer_head *bh, unsigned int maxlen);
int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen);

int gfs2_truncatei(struct gfs2_inode *ip, u64 size);
Expand Down
14 changes: 6 additions & 8 deletions trunk/fs/gfs2/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,17 +204,15 @@ void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks)

static u64 log_bmap(struct gfs2_sbd *sdp, unsigned int lbn)
{
int new = 0;
u64 dbn;
int error;
int bdy;
struct buffer_head bh_map;

error = gfs2_block_map(sdp->sd_jdesc->jd_inode, lbn, &new, &dbn, &bdy);
if (error || !dbn)
printk(KERN_INFO "error=%d, dbn=%llu lbn=%u", error, (unsigned long long)dbn, lbn);
gfs2_assert_withdraw(sdp, !error && dbn);
error = gfs2_block_map(sdp->sd_jdesc->jd_inode, lbn, 0, &bh_map, 1);
if (error || !bh_map.b_blocknr)
printk(KERN_INFO "error=%d, dbn=%llu lbn=%u", error, bh_map.b_blocknr, lbn);
gfs2_assert_withdraw(sdp, !error && bh_map.b_blocknr);

return dbn;
return bh_map.b_blocknr;
}

/**
Expand Down
68 changes: 14 additions & 54 deletions trunk/fs/gfs2/ops_address.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,29 +65,11 @@ static void gfs2_page_add_databufs(struct gfs2_inode *ip, struct page *page,
int gfs2_get_block(struct inode *inode, sector_t lblock,
struct buffer_head *bh_result, int create)
{
int new = create;
u64 dblock;
int error;
int boundary;

error = gfs2_block_map(inode, lblock, &new, &dblock, &boundary);
if (error)
return error;

if (!dblock)
return 0;

map_bh(bh_result, inode->i_sb, dblock);
if (new)
set_buffer_new(bh_result);
if (boundary)
set_buffer_boundary(bh_result);

return 0;
return gfs2_block_map(inode, lblock, create, bh_result, 32);
}

/**
* get_block_noalloc - Fills in a buffer head with details about a block
* gfs2_get_block_noalloc - Fills in a buffer head with details about a block
* @inode: The inode
* @lblock: The block number to look up
* @bh_result: The buffer head to return the result in
Expand All @@ -96,47 +78,25 @@ int gfs2_get_block(struct inode *inode, sector_t lblock,
* Returns: errno
*/

static int get_block_noalloc(struct inode *inode, sector_t lblock,
struct buffer_head *bh_result, int create)
static int gfs2_get_block_noalloc(struct inode *inode, sector_t lblock,
struct buffer_head *bh_result, int create)
{
int new = 0;
u64 dblock;
int error;
int boundary;

error = gfs2_block_map(inode, lblock, &new, &dblock, &boundary);
error = gfs2_block_map(inode, lblock, 0, bh_result, 1);
if (error)
return error;

if (dblock)
map_bh(bh_result, inode->i_sb, dblock);
else if (gfs2_assert_withdraw(GFS2_SB(inode), !create))
error = -EIO;
if (boundary)
set_buffer_boundary(bh_result);

return error;
if (bh_result->b_blocknr == 0)
return -EIO;
return 0;
}

static int get_block_direct(struct inode *inode, sector_t lblock,
struct buffer_head *bh_result, int create)
static int gfs2_get_block_direct(struct inode *inode, sector_t lblock,
struct buffer_head *bh_result, int create)
{
int new = 0;
u64 dblock;
int error, boundary;

error = gfs2_block_map(inode, lblock, &new, &dblock, &boundary);
if (error)
return error;

if (dblock) {
map_bh(bh_result, inode->i_sb, dblock);
if (boundary)
set_buffer_boundary(bh_result);
}

return 0;
return gfs2_block_map(inode, lblock, 0, bh_result, 512);
}

/**
* gfs2_writepage - Write complete page
* @page: Page to write
Expand Down Expand Up @@ -184,7 +144,7 @@ static int gfs2_writepage(struct page *page, struct writeback_control *wbc)
gfs2_page_add_databufs(ip, page, 0, sdp->sd_vfs->s_blocksize-1);
done_trans = 1;
}
error = block_write_full_page(page, get_block_noalloc, wbc);
error = block_write_full_page(page, gfs2_get_block_noalloc, wbc);
if (done_trans)
gfs2_trans_end(sdp);
gfs2_meta_cache_flush(ip);
Expand Down Expand Up @@ -680,7 +640,7 @@ static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb,
rv = blockdev_direct_IO_own_locking(rw, iocb, inode,
inode->i_sb->s_bdev,
iov, offset, nr_segs,
get_block_direct, NULL);
gfs2_get_block_direct, NULL);
out:
gfs2_glock_dq_m(1, &gh);
gfs2_holder_uninit(&gh);
Expand Down
8 changes: 3 additions & 5 deletions trunk/fs/gfs2/quota.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,11 +248,9 @@ static int bh_get(struct gfs2_quota_data *qd)
struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd;
struct gfs2_inode *ip = GFS2_I(sdp->sd_qc_inode);
unsigned int block, offset;
u64 dblock;
int new = 0;
struct buffer_head *bh;
int error;
int boundary;
struct buffer_head bh_map;

mutex_lock(&sdp->sd_quota_mutex);

Expand All @@ -264,10 +262,10 @@ static int bh_get(struct gfs2_quota_data *qd)
block = qd->qd_slot / sdp->sd_qc_per_block;
offset = qd->qd_slot % sdp->sd_qc_per_block;;

error = gfs2_block_map(&ip->i_inode, block, &new, &dblock, &boundary);
error = gfs2_block_map(&ip->i_inode, block, 0, &bh_map, 1);
if (error)
goto fail;
error = gfs2_meta_read(ip->i_gl, dblock, DIO_START | DIO_WAIT, &bh);
error = gfs2_meta_read(ip->i_gl, bh_map.b_blocknr, DIO_START | DIO_WAIT, &bh);
if (error)
goto fail;
error = -EIO;
Expand Down
Loading

0 comments on commit 81674fd

Please sign in to comment.