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>
This commit is contained in:
parent
90f1c19a9f
commit
d396c6f554
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue