]> Pileus Git - ~andy/linux/commitdiff
ext4: refactor code to read the extent tree block
authorTheodore Ts'o <tytso@mit.edu>
Sat, 17 Aug 2013 01:20:41 +0000 (21:20 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Sat, 17 Aug 2013 01:20:41 +0000 (21:20 -0400)
Refactor out the code needed to read the extent tree block into a
single read_extent_tree_block() function.  In addition to simplifying
the code, it also makes sure that we call the ext4_ext_load_extent
tracepoint whenever we need to read an extent tree block from disk.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Reviewed-by: Zheng Liu <wenqing.lz@taobao.com>
fs/ext4/extents.c

index 72ba4705d4fa40e12edd1097f0815381688df7e6..a40be59ddce6e637d3f384b333814fb8b97a6942 100644 (file)
@@ -464,25 +464,39 @@ int ext4_ext_check_inode(struct inode *inode)
        return ext4_ext_check(inode, ext_inode_hdr(inode), ext_depth(inode));
 }
 
-static int __ext4_ext_check_block(const char *function, unsigned int line,
-                                 struct inode *inode,
-                                 struct ext4_extent_header *eh,
-                                 int depth,
-                                 struct buffer_head *bh)
+static struct buffer_head *
+__read_extent_tree_block(const char *function, unsigned int line,
+                        struct inode *inode, ext4_fsblk_t pblk, int depth)
 {
-       int ret;
+       struct buffer_head              *bh;
+       int                             err;
 
+       bh = sb_getblk(inode->i_sb, pblk);
+       if (unlikely(!bh))
+               return ERR_PTR(-ENOMEM);
+
+       if (!bh_uptodate_or_lock(bh)) {
+               trace_ext4_ext_load_extent(inode, pblk, _RET_IP_);
+               err = bh_submit_read(bh);
+               if (err < 0)
+                       goto errout;
+       }
        if (buffer_verified(bh))
-               return 0;
-       ret = ext4_ext_check(inode, eh, depth);
-       if (ret)
-               return ret;
+               return bh;
+       err = __ext4_ext_check(function, line, inode,
+                              ext_block_hdr(bh), depth);
+       if (err)
+               goto errout;
        set_buffer_verified(bh);
-       return ret;
+       return bh;
+errout:
+       put_bh(bh);
+       return ERR_PTR(err);
+
 }
 
-#define ext4_ext_check_block(inode, eh, depth, bh)     \
-       __ext4_ext_check_block(__func__, __LINE__, inode, eh, depth, bh)
+#define read_extent_tree_block(inode, pblk, depth)             \
+       __read_extent_tree_block(__func__, __LINE__, (inode), (pblk), (depth))
 
 #ifdef EXT_DEBUG
 static void ext4_ext_show_path(struct inode *inode, struct ext4_ext_path *path)
@@ -748,20 +762,12 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block,
                path[ppos].p_depth = i;
                path[ppos].p_ext = NULL;
 
-               bh = sb_getblk(inode->i_sb, path[ppos].p_block);
-               if (unlikely(!bh)) {
-                       ret = -ENOMEM;
+               bh = read_extent_tree_block(inode, path[ppos].p_block, --i);
+               if (IS_ERR(bh)) {
+                       ret = PTR_ERR(bh);
                        goto err;
                }
-               if (!bh_uptodate_or_lock(bh)) {
-                       trace_ext4_ext_load_extent(inode, block,
-                                               path[ppos].p_block);
-                       ret = bh_submit_read(bh);
-                       if (ret < 0) {
-                               put_bh(bh);
-                               goto err;
-                       }
-               }
+
                eh = ext_block_hdr(bh);
                ppos++;
                if (unlikely(ppos > depth)) {
@@ -773,11 +779,6 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block,
                }
                path[ppos].p_bh = bh;
                path[ppos].p_hdr = eh;
-               i--;
-
-               ret = ext4_ext_check_block(inode, eh, i, bh);
-               if (ret < 0)
-                       goto err;
        }
 
        path[ppos].p_depth = i;
@@ -1412,29 +1413,21 @@ got_index:
        ix++;
        block = ext4_idx_pblock(ix);
        while (++depth < path->p_depth) {
-               bh = sb_bread(inode->i_sb, block);
-               if (bh == NULL)
-                       return -EIO;
-               eh = ext_block_hdr(bh);
                /* subtract from p_depth to get proper eh_depth */
-               if (ext4_ext_check_block(inode, eh,
-                                        path->p_depth - depth, bh)) {
-                       put_bh(bh);
-                       return -EIO;
-               }
+               bh = read_extent_tree_block(inode, block,
+                                           path->p_depth - depth);
+               if (IS_ERR(bh))
+                       return PTR_ERR(bh);
+               eh = ext_block_hdr(bh);
                ix = EXT_FIRST_INDEX(eh);
                block = ext4_idx_pblock(ix);
                put_bh(bh);
        }
 
-       bh = sb_bread(inode->i_sb, block);
-       if (bh == NULL)
-               return -EIO;
+       bh = read_extent_tree_block(inode, block, path->p_depth - depth);
+       if (IS_ERR(bh))
+               return PTR_ERR(bh);
        eh = ext_block_hdr(bh);
-       if (ext4_ext_check_block(inode, eh, path->p_depth - depth, bh)) {
-               put_bh(bh);
-               return -EIO;
-       }
        ex = EXT_FIRST_EXTENT(eh);
 found_extent:
        *logical = le32_to_cpu(ex->ee_block);
@@ -2829,10 +2822,11 @@ again:
                        ext_debug("move to level %d (block %llu)\n",
                                  i + 1, ext4_idx_pblock(path[i].p_idx));
                        memset(path + i + 1, 0, sizeof(*path));
-                       bh = sb_bread(sb, ext4_idx_pblock(path[i].p_idx));
-                       if (!bh) {
+                       bh = read_extent_tree_block(inode,
+                               ext4_idx_pblock(path[i].p_idx), depth - i - 1);
+                       if (IS_ERR(bh)) {
                                /* should we reset i_size? */
-                               err = -EIO;
+                               err = PTR_ERR(bh);
                                break;
                        }
                        /* Yield here to deal with large extent trees.
@@ -2842,11 +2836,6 @@ again:
                                err = -EIO;
                                break;
                        }
-                       if (ext4_ext_check_block(inode, ext_block_hdr(bh),
-                                                       depth - i - 1, bh)) {
-                               err = -EIO;
-                               break;
-                       }
                        path[i + 1].p_bh = bh;
 
                        /* save actual number of indexes since this