Function gfs2_bmap_alloc is used to allocate data blocks during a block_map operation. Before this patch, a buffer_head pointer was passed in. This patch removes that from the function, replacing it with other variables. This is a step toward allowing the iomap interface to operate properly in gfs2.
Signed-off-by: Bob Peterson <[email protected]> --- fs/gfs2/bmap.c | 56 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index fc5da4c..f50933a 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -426,11 +426,13 @@ enum alloc_state { * gfs2_bmap_alloc - Build a metadata tree of the requested height * @inode: The GFS2 inode * @lblock: The logical starting block of the extent - * @bh_map: This is used to return the mapping details + * @zero_new: True if newly allocated blocks should be zeroed * @mp: The metapath * @sheight: The starting height (i.e. whats already mapped) * @height: The height to build to * @maxlen: The max number of data blocks to alloc + * @dblock: Pointer to the physical block allocated + * @dblks: Pointer to an int number of data blocks in the span * * In this routine we may have to alloc: * i) Indirect blocks to grow the metadata tree height @@ -447,18 +449,18 @@ enum alloc_state { */ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock, - struct buffer_head *bh_map, struct metapath *mp, + bool zero_new, struct metapath *mp, const unsigned int sheight, const unsigned int height, - const size_t maxlen) + const size_t maxlen, sector_t *dblock, + unsigned int *dblks) { struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_sbd *sdp = GFS2_SB(inode); struct super_block *sb = sdp->sd_vfs; struct buffer_head *dibh = mp->mp_bh[0]; - u64 bn, dblock = 0; + u64 bn; unsigned n, i, blks, alloced = 0, iblks = 0, branch_start = 0; - unsigned dblks = 0; unsigned ptrs_per_blk; const unsigned end_of_metadata = height - 1; int ret; @@ -469,6 +471,8 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock, BUG_ON(sheight < 1); BUG_ON(dibh == NULL); + *dblock = 0; + *dblks = 0; gfs2_trans_add_meta(ip->i_gl, dibh); @@ -477,15 +481,15 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock, /* Bottom indirect block exists, find unalloced extent size */ ptr = metapointer(end_of_metadata, mp); bh = mp->mp_bh[end_of_metadata]; - dblks = gfs2_extent_length(bh->b_data, bh->b_size, ptr, maxlen, - &eob); - BUG_ON(dblks < 1); + *dblks = gfs2_extent_length(bh->b_data, bh->b_size, ptr, + maxlen, &eob); + BUG_ON(*dblks < 1); state = ALLOC_DATA; } else { /* Need to allocate indirect blocks */ ptrs_per_blk = height > 1 ? sdp->sd_inptrs : sdp->sd_diptrs; - dblks = min(maxlen, (size_t)(ptrs_per_blk - - mp->mp_list[end_of_metadata])); + *dblks = min(maxlen, (size_t)(ptrs_per_blk - + mp->mp_list[end_of_metadata])); if (height == ip->i_height) { /* Writing into existing tree, extend tree down */ iblks = height - sheight; @@ -501,7 +505,7 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock, /* start of the second part of the function (state machine) */ - blks = dblks + iblks; + blks = *dblks + iblks; i = sheight; do { int error; @@ -557,33 +561,30 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock, break; /* Tree complete, adding data blocks */ case ALLOC_DATA: - BUG_ON(n > dblks); + BUG_ON(n > *dblks); BUG_ON(mp->mp_bh[end_of_metadata] == NULL); gfs2_trans_add_meta(ip->i_gl, mp->mp_bh[end_of_metadata]); - dblks = n; + *dblks = n; ptr = metapointer(end_of_metadata, mp); - dblock = bn; + *dblock = bn; while (n-- > 0) *ptr++ = cpu_to_be64(bn++); - if (buffer_zeronew(bh_map)) { - ret = sb_issue_zeroout(sb, dblock, dblks, + if (zero_new) { + ret = sb_issue_zeroout(sb, *dblock, *dblks, GFP_NOFS); if (ret) { fs_err(sdp, "Failed to zero data buffers\n"); - clear_buffer_zeronew(bh_map); + zero_new = false; } } break; } - } while ((state != ALLOC_DATA) || !dblock); + } while ((state != ALLOC_DATA) || !(*dblock)); ip->i_height = height; gfs2_add_inode_blocks(&ip->i_inode, alloced); gfs2_dinode_out(ip, mp->mp_bh[0]->b_data); - map_bh(bh_map, inode->i_sb, dblock); - bh_map->b_size = dblks << inode->i_blkbits; - set_buffer_new(bh_map); return 0; } @@ -617,6 +618,9 @@ int gfs2_block_map(struct inode *inode, sector_t lblock, unsigned int len; struct buffer_head *bh; u8 height; + bool zero_new = false; + sector_t dblock; + unsigned int dblks = 0; BUG_ON(maxlen == 0); @@ -673,7 +677,15 @@ int gfs2_block_map(struct inode *inode, sector_t lblock, } /* At this point ret is the tree depth of already allocated blocks */ - ret = gfs2_bmap_alloc(inode, lblock, bh_map, &mp, ret, height, maxlen); + if (buffer_zeronew(bh_map)) + zero_new = true; + ret = gfs2_bmap_alloc(inode, lblock, zero_new, &mp, ret, height, + maxlen, &dblock, &dblks); + if (ret == 0) { + map_bh(bh_map, inode->i_sb, dblock); + bh_map->b_size = dblks << inode->i_blkbits; + set_buffer_new(bh_map); + } goto out; } -- 2.7.4
