Btrfs: [PATCH] extent_map: provide generic bmap
authorChristoph Hellwig <hch@lst.de>
Tue, 11 Sep 2007 00:02:30 +0000 (20:02 -0400)
committerDavid Woodhouse <dwmw2@hera.kernel.org>
Tue, 11 Sep 2007 00:02:30 +0000 (20:02 -0400)
generic_bmap is completely trivial, while the extent to bh mapping in
btrfs is rather complex.  So provide a extent_bmap instead that takes
a get_extent callback and can be used by filesystem using the extent_map
code.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Chris Mason <chris.mason@oracle.com>
fs/btrfs/extent_map.c
fs/btrfs/extent_map.h
fs/btrfs/inode.c

index 3021564ac62c41a9a6f7d1a07eecd641993fe657..ff2b1dd25bf92ff0398bbdb810217de45d42867a 100644 (file)
@@ -1816,3 +1816,22 @@ int try_release_extent_mapping(struct extent_map_tree *tree, struct page *page)
 }
 EXPORT_SYMBOL(try_release_extent_mapping);
 
+sector_t extent_bmap(struct address_space *mapping, sector_t iblock,
+               get_extent_t *get_extent)
+{
+       struct inode *inode = mapping->host;
+       u64 start = iblock << inode->i_blkbits;
+       u64 end = start + (1 << inode->i_blkbits) - 1;
+       struct extent_map *em;
+
+       em = get_extent(inode, NULL, 0, start, end, 0);
+       if (!em || IS_ERR(em))
+               return 0;
+
+       // XXX(hch): block 0 is valid in some cases, e.g. XFS RT device
+       if (em->block_start == EXTENT_MAP_INLINE ||
+           em->block_start == 0)
+               return 0;
+
+       return (em->block_start + start - em->start) >> inode->i_blkbits;
+}
index 0eae6c420acbaa6fbcb982a2b718b5bd1d4f047b..da41aca74e0bb644cfe008e928731c48c6285964 100644 (file)
@@ -99,6 +99,8 @@ int extent_prepare_write(struct extent_map_tree *tree,
 int extent_commit_write(struct extent_map_tree *tree,
                        struct inode *inode, struct page *page,
                        unsigned from, unsigned to);
+sector_t extent_bmap(struct address_space *mapping, sector_t iblock,
+               get_extent_t *get_extent);
 int set_range_dirty(struct extent_map_tree *tree, u64 start, u64 end);
 int set_state_private(struct extent_map_tree *tree, u64 start, u64 private);
 int get_state_private(struct extent_map_tree *tree, u64 start, u64 *private);
index 1ace6d11e09766a9294f8a3210f18ba0d49cab10..39c1fe178f477169b064fa71537ece6e68944458 100644 (file)
@@ -1567,28 +1567,9 @@ out:
        return em;
 }
 
-static int btrfs_get_block_bmap(struct inode *inode, sector_t iblock,
-                          struct buffer_head *result, int create)
+static sector_t btrfs_bmap(struct address_space *mapping, sector_t iblock)
 {
-       struct btrfs_root *root = BTRFS_I(inode)->root;
-       u64 start = iblock << inode->i_blkbits;
-       u64 end = start + root->blocksize -1;
-       struct extent_map *em;
-
-       em = btrfs_get_extent(inode, NULL, 0, start, end, 0);
-       if (em && !IS_ERR(em) && em->block_start != EXTENT_MAP_INLINE &&
-           em->block_start != 0) {
-               u64 offset;
-               offset = start - em->start;
-               start = (em->block_start + offset) >> inode->i_blkbits;
-               btrfs_map_bh_to_logical(root, result, start);
-       }
-       return 0;
-}
-
-static sector_t btrfs_bmap(struct address_space *as, sector_t block)
-{
-       return generic_block_bmap(as, block, btrfs_get_block_bmap);
+       return extent_bmap(mapping, iblock, btrfs_get_extent);
 }
 
 static int btrfs_prepare_write(struct file *file, struct page *page,