Christoph Hellwig
2007-Sep-02 08:00 UTC
[Btrfs-devel] [PATCH] extent_map: provide generic bmap address_space operation
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> Index: btrfs-9cb5f0f5c713/extent_map.c ==================================================================--- btrfs-9cb5f0f5c713.orig/extent_map.c 2007-09-01 23:08:17.000000000 +0200 +++ btrfs-9cb5f0f5c713/extent_map.c 2007-09-01 23:13:07.000000000 +0200 @@ -1812,3 +1812,22 @@ int try_release_extent_mapping(struct ex } 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: btrfs-9cb5f0f5c713/extent_map.h ==================================================================--- btrfs-9cb5f0f5c713.orig/extent_map.h 2007-09-01 23:09:10.000000000 +0200 +++ btrfs-9cb5f0f5c713/extent_map.h 2007-09-01 23:09:21.000000000 +0200 @@ -99,6 +99,8 @@ int extent_prepare_write(struct extent_m 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: btrfs-9cb5f0f5c713/inode.c ==================================================================--- btrfs-9cb5f0f5c713.orig/inode.c 2007-09-01 23:09:25.000000000 +0200 +++ btrfs-9cb5f0f5c713/inode.c 2007-09-02 00:27:10.000000000 +0200 @@ -1565,28 +1565,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,