aboutsummaryrefslogtreecommitdiff
path: root/fs/btrfs/extent_map.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2007-09-10 20:02:30 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-09-10 20:02:30 -0400
commitd396c6f554d182b7bce4e2bb2acb47f80430c05f (patch)
tree2bc7b567310474ed4562d4e1246efd69a868f8cd /fs/btrfs/extent_map.c
parent90f1c19a9fd2a943adc69d2b9b8c83bcc4bba6f9 (diff)
Btrfs: [PATCH] extent_map: provide generic bmap
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>
Diffstat (limited to 'fs/btrfs/extent_map.c')
-rw-r--r--fs/btrfs/extent_map.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
index 3021564ac62..ff2b1dd25bf 100644
--- a/fs/btrfs/extent_map.c
+++ b/fs/btrfs/extent_map.c
@@ -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;
+}