Whamcloud - gitweb
ext2fs: add new APIs needed for fast commits
[tools/e2fsprogs.git] / lib / ext2fs / extent.c
index ac3dbfe..bde6b0f 100644 (file)
@@ -1785,6 +1785,70 @@ out:
        return errcode;
 }
 
+errcode_t ext2fs_decode_extent(struct ext2fs_extent *to, void *addr, int len)
+{
+       struct ext3_extent *from = (struct ext3_extent *)addr;
+
+       if (len != sizeof(struct ext3_extent))
+               return EXT2_ET_INVALID_ARGUMENT;
+
+       to->e_pblk = ext2fs_le32_to_cpu(from->ee_start) +
+               ((__u64) ext2fs_le16_to_cpu(from->ee_start_hi)
+                       << 32);
+       to->e_lblk = ext2fs_le32_to_cpu(from->ee_block);
+       to->e_len = ext2fs_le16_to_cpu(from->ee_len);
+       to->e_flags |= EXT2_EXTENT_FLAGS_LEAF;
+       if (to->e_len > EXT_INIT_MAX_LEN) {
+               to->e_len -= EXT_INIT_MAX_LEN;
+               to->e_flags |= EXT2_EXTENT_FLAGS_UNINIT;
+       }
+
+       return 0;
+}
+
+errcode_t ext2fs_count_blocks(ext2_filsys fs, ext2_ino_t ino,
+                             struct ext2_inode *inode, blk64_t *ret_count)
+{
+       ext2_extent_handle_t    handle;
+       struct ext2fs_extent    extent;
+       errcode_t               errcode;
+       int                     i;
+       blk64_t                 blkcount = 0;
+       blk64_t                 *intermediate_nodes;
+
+       errcode = ext2fs_extent_open2(fs, ino, inode, &handle);
+       if (errcode)
+               goto out;
+
+       errcode = ext2fs_extent_get(handle, EXT2_EXTENT_ROOT, &extent);
+       if (errcode)
+               goto out;
+
+       ext2fs_get_array(handle->max_depth, sizeof(blk64_t),
+                               &intermediate_nodes);
+       blkcount = handle->level;
+       while (!errcode) {
+               if (extent.e_flags & EXT2_EXTENT_FLAGS_LEAF) {
+                       blkcount += extent.e_len;
+                       for (i = 0; i < handle->level; i++) {
+                               if (intermediate_nodes[i] !=
+                                       handle->path[i].end_blk) {
+                                       blkcount++;
+                                       intermediate_nodes[i] =
+                                               handle->path[i].end_blk;
+                               }
+                       }
+               }
+               errcode = ext2fs_extent_get(handle, EXT2_EXTENT_NEXT, &extent);
+       }
+       ext2fs_free_mem(&intermediate_nodes);
+out:
+       *ret_count = blkcount;
+       ext2fs_extent_free(handle);
+
+       return 0;
+}
+
 #ifdef DEBUG
 /*
  * Override debugfs's prompt