summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/extent_map.c19
-rw-r--r--fs/btrfs/extent_map.h2
-rw-r--r--fs/btrfs/inode.c23
3 files changed, 23 insertions, 21 deletions
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
index 3021564..ff2b1dd 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;
+}
diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h
index 0eae6c4..da41aca 100644
--- a/fs/btrfs/extent_map.h
+++ b/fs/btrfs/extent_map.h
@@ -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);
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 1ace6d1..39c1fe1 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -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,
OpenPOWER on IntegriCloud