aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/linux-2.6')
-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 = {