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

Reply via email to