diff options
author | Josef Bacik <jbacik@redhat.com> | 2008-10-03 17:32:43 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2008-10-03 17:32:43 -0400 |
commit | 68c9d702bb72f367f3b148963ec6cf5e07ff7f65 (patch) | |
tree | 16fc61a1bd973c14a7858ab1fbcb306d3ae75184 /fs/ext2 | |
parent | 00dc417fa3e763345b34ccb6034d72de76eea0a1 (diff) | |
download | op-kernel-dev-68c9d702bb72f367f3b148963ec6cf5e07ff7f65.zip op-kernel-dev-68c9d702bb72f367f3b148963ec6cf5e07ff7f65.tar.gz |
generic block based fiemap implementation
Any block based fs (this patch includes ext3) just has to declare its own
fiemap() function and then call this generic function with its own
get_block_t. This works well for block based filesystems that will map
multiple contiguous blocks at one time, but will work for filesystems that
only map one block at a time, you will just end up with an "extent" for each
block. One gotcha is this will not play nicely where there is hole+data
after the EOF. This function will assume its hit the end of the data as soon
as it hits a hole after the EOF, so if there is any data past that it will
not pick that up. AFAIK no block based fs does this anyway, but its in the
comments of the function anyway just in case.
Signed-off-by: Josef Bacik <jbacik@redhat.com>
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Cc: linux-fsdevel@vger.kernel.org
Diffstat (limited to 'fs/ext2')
-rw-r--r-- | fs/ext2/ext2.h | 2 | ||||
-rw-r--r-- | fs/ext2/file.c | 1 | ||||
-rw-r--r-- | fs/ext2/inode.c | 8 |
3 files changed, 11 insertions, 0 deletions
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h index 47d88da..bae998c 100644 --- a/fs/ext2/ext2.h +++ b/fs/ext2/ext2.h @@ -133,6 +133,8 @@ extern void ext2_truncate (struct inode *); extern int ext2_setattr (struct dentry *, struct iattr *); extern void ext2_set_inode_flags(struct inode *inode); extern void ext2_get_inode_flags(struct ext2_inode_info *); +extern int ext2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, + u64 start, u64 len); int __ext2_write_begin(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata); diff --git a/fs/ext2/file.c b/fs/ext2/file.c index 5f2fa9c..45ed071 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -86,4 +86,5 @@ const struct inode_operations ext2_file_inode_operations = { #endif .setattr = ext2_setattr, .permission = ext2_permission, + .fiemap = ext2_fiemap, }; diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 991d6df..7658b33 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -31,6 +31,7 @@ #include <linux/writeback.h> #include <linux/buffer_head.h> #include <linux/mpage.h> +#include <linux/fiemap.h> #include "ext2.h" #include "acl.h" #include "xip.h" @@ -704,6 +705,13 @@ int ext2_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_ } +int ext2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, + u64 start, u64 len) +{ + return generic_block_fiemap(inode, fieinfo, start, len, + ext2_get_block); +} + static int ext2_writepage(struct page *page, struct writeback_control *wbc) { return block_write_full_page(page, ext2_get_block, wbc); |