aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6/xfs_iops.c
diff options
context:
space:
mode:
authorEric Sandeen <sandeen@sandeen.net>2008-11-27 22:23:35 -0500
committerNiv Sardi <xaiki@sgi.com>2008-11-30 19:29:42 -0500
commitf35642e2f89f2b0379e929bd9027342365abc839 (patch)
tree1a00bb1501497bb25d597b113fabfaa7a631e406 /fs/xfs/linux-2.6/xfs_iops.c
parent5af317c942aebc928ab244eb69581bd8e5333215 (diff)
[XFS] Hook up the fiemap ioctl.
This adds the fiemap inode_operation, which for us converts the fiemap values & flags into a getbmapx structure which can be sent to xfs_getbmap. The formatter then copies the bmv array back into the user's fiemap buffer via the fiemap helpers. If we wanted to be more clever, we could also return mapping data for in-inode attributes, but I'm not terribly motivated to do that just yet. Signed-off-by: Eric Sandeen <sandeen@sandeen.net> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Niv Sardi <xaiki@sgi.com>
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_iops.c')
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index 69c98cf32336..2903faf6a26a 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -53,6 +53,7 @@
53#include <linux/namei.h> 53#include <linux/namei.h>
54#include <linux/security.h> 54#include <linux/security.h>
55#include <linux/falloc.h> 55#include <linux/falloc.h>
56#include <linux/fiemap.h>
56 57
57/* 58/*
58 * Bring the atime in the XFS inode uptodate. 59 * Bring the atime in the XFS inode uptodate.
@@ -661,6 +662,88 @@ out_error:
661 return error; 662 return error;
662} 663}
663 664
665#define XFS_FIEMAP_FLAGS (FIEMAP_FLAG_SYNC|FIEMAP_FLAG_XATTR)
666
667/*
668 * Call fiemap helper to fill in user data.
669 * Returns positive errors to xfs_getbmap.
670 */
671STATIC int
672xfs_fiemap_format(
673 void **arg,
674 struct getbmapx *bmv,
675 int *full)
676{
677 int error;
678 struct fiemap_extent_info *fieinfo = *arg;
679 u32 fiemap_flags = 0;
680 u64 logical, physical, length;
681
682 /* Do nothing for a hole */
683 if (bmv->bmv_block == -1LL)
684 return 0;
685
686 logical = BBTOB(bmv->bmv_offset);
687 physical = BBTOB(bmv->bmv_block);
688 length = BBTOB(bmv->bmv_length);
689
690 if (bmv->bmv_oflags & BMV_OF_PREALLOC)
691 fiemap_flags |= FIEMAP_EXTENT_UNWRITTEN;
692 else if (bmv->bmv_oflags & BMV_OF_DELALLOC) {
693 fiemap_flags |= FIEMAP_EXTENT_DELALLOC;
694 physical = 0; /* no block yet */
695 }
696 if (bmv->bmv_oflags & BMV_OF_LAST)
697 fiemap_flags |= FIEMAP_EXTENT_LAST;
698
699 error = fiemap_fill_next_extent(fieinfo, logical, physical,
700 length, fiemap_flags);
701 if (error > 0) {
702 error = 0;
703 *full = 1; /* user array now full */
704 }
705
706 return -error;
707}
708
709STATIC int
710xfs_vn_fiemap(
711 struct inode *inode,
712 struct fiemap_extent_info *fieinfo,
713 u64 start,
714 u64 length)
715{
716 xfs_inode_t *ip = XFS_I(inode);
717 struct getbmapx bm;
718 int error;
719
720 error = fiemap_check_flags(fieinfo, XFS_FIEMAP_FLAGS);
721 if (error)
722 return error;
723
724 /* Set up bmap header for xfs internal routine */
725 bm.bmv_offset = BTOBB(start);
726 /* Special case for whole file */
727 if (length == FIEMAP_MAX_OFFSET)
728 bm.bmv_length = -1LL;
729 else
730 bm.bmv_length = BTOBB(length);
731
732 /* our formatter will tell xfs_getbmap when to stop. */
733 bm.bmv_count = MAXEXTNUM;
734 bm.bmv_iflags = BMV_IF_PREALLOC;
735 if (fieinfo->fi_flags & FIEMAP_FLAG_XATTR)
736 bm.bmv_iflags |= BMV_IF_ATTRFORK;
737 if (!(fieinfo->fi_flags & FIEMAP_FLAG_SYNC))
738 bm.bmv_iflags |= BMV_IF_DELALLOC;
739
740 error = xfs_getbmap(ip, &bm, xfs_fiemap_format, fieinfo);
741 if (error)
742 return -error;
743
744 return 0;
745}
746
664static const struct inode_operations xfs_inode_operations = { 747static const struct inode_operations xfs_inode_operations = {
665 .permission = xfs_vn_permission, 748 .permission = xfs_vn_permission,
666 .truncate = xfs_vn_truncate, 749 .truncate = xfs_vn_truncate,
@@ -671,6 +754,7 @@ static const struct inode_operations xfs_inode_operations = {
671 .removexattr = generic_removexattr, 754 .removexattr = generic_removexattr,
672 .listxattr = xfs_vn_listxattr, 755 .listxattr = xfs_vn_listxattr,
673 .fallocate = xfs_vn_fallocate, 756 .fallocate = xfs_vn_fallocate,
757 .fiemap = xfs_vn_fiemap,
674}; 758};
675 759
676static const struct inode_operations xfs_dir_inode_operations = { 760static const struct inode_operations xfs_dir_inode_operations = {