diff options
author | Christoph Hellwig <hch@lst.de> | 2007-09-10 20:02:30 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-09-10 20:02:30 -0400 |
commit | d396c6f554d182b7bce4e2bb2acb47f80430c05f (patch) | |
tree | 2bc7b567310474ed4562d4e1246efd69a868f8cd | |
parent | 90f1c19a9fd2a943adc69d2b9b8c83bcc4bba6f9 (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>
-rw-r--r-- | fs/btrfs/extent_map.c | 19 | ||||
-rw-r--r-- | fs/btrfs/extent_map.h | 2 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 23 |
3 files changed, 23 insertions, 21 deletions
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index 3021564ac62c..ff2b1dd25bf9 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) | |||
1816 | } | 1816 | } |
1817 | EXPORT_SYMBOL(try_release_extent_mapping); | 1817 | EXPORT_SYMBOL(try_release_extent_mapping); |
1818 | 1818 | ||
1819 | sector_t extent_bmap(struct address_space *mapping, sector_t iblock, | ||
1820 | get_extent_t *get_extent) | ||
1821 | { | ||
1822 | struct inode *inode = mapping->host; | ||
1823 | u64 start = iblock << inode->i_blkbits; | ||
1824 | u64 end = start + (1 << inode->i_blkbits) - 1; | ||
1825 | struct extent_map *em; | ||
1826 | |||
1827 | em = get_extent(inode, NULL, 0, start, end, 0); | ||
1828 | if (!em || IS_ERR(em)) | ||
1829 | return 0; | ||
1830 | |||
1831 | // XXX(hch): block 0 is valid in some cases, e.g. XFS RT device | ||
1832 | if (em->block_start == EXTENT_MAP_INLINE || | ||
1833 | em->block_start == 0) | ||
1834 | return 0; | ||
1835 | |||
1836 | return (em->block_start + start - em->start) >> inode->i_blkbits; | ||
1837 | } | ||
diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h index 0eae6c420acb..da41aca74e0b 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, | |||
99 | int extent_commit_write(struct extent_map_tree *tree, | 99 | int extent_commit_write(struct extent_map_tree *tree, |
100 | struct inode *inode, struct page *page, | 100 | struct inode *inode, struct page *page, |
101 | unsigned from, unsigned to); | 101 | unsigned from, unsigned to); |
102 | sector_t extent_bmap(struct address_space *mapping, sector_t iblock, | ||
103 | get_extent_t *get_extent); | ||
102 | int set_range_dirty(struct extent_map_tree *tree, u64 start, u64 end); | 104 | int set_range_dirty(struct extent_map_tree *tree, u64 start, u64 end); |
103 | int set_state_private(struct extent_map_tree *tree, u64 start, u64 private); | 105 | int set_state_private(struct extent_map_tree *tree, u64 start, u64 private); |
104 | int get_state_private(struct extent_map_tree *tree, u64 start, u64 *private); | 106 | 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 1ace6d11e097..39c1fe178f47 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -1567,28 +1567,9 @@ out: | |||
1567 | return em; | 1567 | return em; |
1568 | } | 1568 | } |
1569 | 1569 | ||
1570 | static int btrfs_get_block_bmap(struct inode *inode, sector_t iblock, | 1570 | static sector_t btrfs_bmap(struct address_space *mapping, sector_t iblock) |
1571 | struct buffer_head *result, int create) | ||
1572 | { | 1571 | { |
1573 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1572 | return extent_bmap(mapping, iblock, btrfs_get_extent); |
1574 | u64 start = iblock << inode->i_blkbits; | ||
1575 | u64 end = start + root->blocksize -1; | ||
1576 | struct extent_map *em; | ||
1577 | |||
1578 | em = btrfs_get_extent(inode, NULL, 0, start, end, 0); | ||
1579 | if (em && !IS_ERR(em) && em->block_start != EXTENT_MAP_INLINE && | ||
1580 | em->block_start != 0) { | ||
1581 | u64 offset; | ||
1582 | offset = start - em->start; | ||
1583 | start = (em->block_start + offset) >> inode->i_blkbits; | ||
1584 | btrfs_map_bh_to_logical(root, result, start); | ||
1585 | } | ||
1586 | return 0; | ||
1587 | } | ||
1588 | |||
1589 | static sector_t btrfs_bmap(struct address_space *as, sector_t block) | ||
1590 | { | ||
1591 | return generic_block_bmap(as, block, btrfs_get_block_bmap); | ||
1592 | } | 1573 | } |
1593 | 1574 | ||
1594 | static int btrfs_prepare_write(struct file *file, struct page *page, | 1575 | static int btrfs_prepare_write(struct file *file, struct page *page, |