diff options
Diffstat (limited to 'fs/xfs/linux-2.6')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_iops.c | 84 |
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 | */ | ||
671 | STATIC int | ||
672 | xfs_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 | |||
709 | STATIC int | ||
710 | xfs_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 | |||
664 | static const struct inode_operations xfs_inode_operations = { | 747 | static 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 | ||
676 | static const struct inode_operations xfs_dir_inode_operations = { | 760 | static const struct inode_operations xfs_dir_inode_operations = { |