Yehuda Sadeh Weinraub
2008-Dec-19 21:14 UTC
[PATCH 1/1] ioctl to fetch csums of file extents
This adds a new ioctl that requests for the csums of file''s extent. The csums of contiguous extents can also be requested. The call will not return anything for extents that don''t have csum information for their data, or that the csum list is not available. Presumably, the user calls fiemap first in order to get the list of extents. The max number of requested csum items is specified in the request and is updated according to the actual number of returned items. Signed-off-by: Yehuda Sadeh <yehuda@hq.newdream.net> --- fs/btrfs/ioctl.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/btrfs/ioctl.h | 9 +++++ 2 files changed, 110 insertions(+), 0 deletions(-) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index ab429fe..18a57c1 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -990,6 +990,105 @@ out_drop_write: return ret; } +static long btrfs_ioctl_getcsum(struct file *file, + void __user *arg) +{ + struct inode *inode = fdentry(file)->d_inode; + struct btrfs_root *root = BTRFS_I(inode)->root; + struct btrfs_ioctl_get_csum_args *req; + struct btrfs_ioctl_get_csum_args __user *ureq = arg; + int ret; + u64 off, max; + struct extent_map *em = NULL; + u32 count = 0; + size_t end; + unsigned long flags; + + req = kmalloc(sizeof(*req), GFP_NOFS); + if (!req) + return -ENOMEM; + if (copy_from_user(req, arg, sizeof(*req))) { + kfree(req); + return -EFAULT; + } + + off = req->off; + max = off + req->len; + end = (off + req->len + root->sectorsize - 1) & ~(root->sectorsize - 1); + + ret = 0; + lock_extent(&BTRFS_I(inode)->io_tree, req->off, max, + GFP_NOFS); + while (off < max) { + struct list_head list; + size_t len = 0; + size_t offset; + struct btrfs_ordered_sum *sums; + struct btrfs_sector_sum *sector_sum; + + em = btrfs_get_extent(inode, NULL, 0, off, max - off, 0); + + if (!em) + goto out; + if (IS_ERR(em)) { + ret = PTR_ERR(em); + goto out; + } + + if (em->block_start > EXTENT_MAP_LAST_BYTE) + goto out_free; + + INIT_LIST_HEAD(&list); + len = 0; + + offset = (off - em->start) & ~(root->sectorsize - 1); + + ret = btrfs_lookup_csums_range(root, em->block_start + offset, + em->block_start + em->block_len - 1, &list); + if (ret < 0) + goto out_free; + + len = 0; + while (!list_empty(&list)) { + sums = list_entry(list.next, + struct btrfs_ordered_sum, list); + list_del_init(&sums->list); + + sector_sum = sums->sums; + + while ((len < sums->len) && + (offset + len < end) && + (count < req->size)) { + put_user((u32)sector_sum->sum, + &ureq->csum[count++]); + sector_sum++; + len += root->sectorsize; + } + kfree(sums); + } + + flags = em->flags; + off = em->start + em->len; + + free_extent_map(em); + + if (test_bit(EXTENT_FLAG_VACANCY, &flags)) + break; + + if (count == req->size) + break; + } +out: + unlock_extent(&BTRFS_I(inode)->io_tree, req->off, max, + GFP_NOFS); + + put_user((u32)count, &ureq->size); + return ret; +out_free: + free_extent_map(em); + goto out; +} + static long btrfs_ioctl_clone_range(struct file *file, void __user *argp) { struct btrfs_ioctl_clone_range_args args; @@ -1102,6 +1201,8 @@ long btrfs_ioctl(struct file *file, unsigned int case BTRFS_IOC_SYNC: btrfs_sync_fs(file->f_dentry->d_sb, 1); return 0; + case BTRFS_IOC_GETCSUM: + return btrfs_ioctl_getcsum(file, argp); } return -ENOTTY; diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h index 78049ea..9962579 100644 --- a/fs/btrfs/ioctl.h +++ b/fs/btrfs/ioctl.h @@ -64,4 +64,13 @@ struct btrfs_ioctl_clone_range_args { #define BTRFS_IOC_SUBVOL_CREATE _IOW(BTRFS_IOCTL_MAGIC, 14, \ struct btrfs_ioctl_vol_args) +struct btrfs_ioctl_get_csum_args { + __u64 off; + __u64 len; + __u32 size; /* in/out */ + __u32 csum[0]; +}; + +#define BTRFS_IOC_GETCSUM _IO(BTRFS_IOCTL_MAGIC, 15) + #endif -- 1.5.6.5 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Fri, 2008-12-19 at 13:14 -0800, Yehuda Sadeh Weinraub wrote:> This adds a new ioctl that requests for the csums of file''s extent. > The csums of contiguous extents can also be requested. The call will > not return anything for extents that don''t have csum information for > their data, or that the csum list is not available. > Presumably, the user calls fiemap first in order to get the list of > extents. The max number of requested csum items is specified in the > request and is updated according to the actual number of returned > items. >Sorry, I''m holding off on this and the fiemap patch until after the merge with mainline. I''m a little swamped verifying things, but both patches look good to me. Thanks for sending them. -chris -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Fri, 2008-12-19 at 13:14 -0800, Yehuda Sadeh Weinraub wrote:> This adds a new ioctl that requests for the csums of file''s extent. > The csums of contiguous extents can also be requested. The call will > not return anything for extents that don''t have csum information for > their data, or that the csum list is not available. > Presumably, the user calls fiemap first in order to get the list of > extents. The max number of requested csum items is specified in the > request and is updated according to the actual number of returned > items. >The swapfile discussions convinced me we''re better off taking fiemap support now and disabling bmap entirely, at least until we can fix the swapfile code to work properly with btrfs. So, I''d like to take this patch, but there is line wrapping and other whitespace problems. Could you please send it with a mail client that doesn''t mangle? ;) (Attaching it is fine too, at least on this list) Thanks! -chris -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Yehuda Sadeh Weinraub
2009-Jan-21 18:23 UTC
Re: [PATCH 1/1] ioctl to fetch csums of file extents
> > So, I''d like to take this patch, but there is line wrapping and other > whitespace problems. Could you please send it with a mail client that > doesn''t mangle? ;) > > (Attaching it is fine too, at least on this list)Attached both patches. Thanks, Yehuda