diff options
author | David Chinner <dgc@sgi.com> | 2007-11-23 00:29:25 -0500 |
---|---|---|
committer | Lachlan McIlroy <lachlan@redback.melbourne.sgi.com> | 2008-02-07 02:16:17 -0500 |
commit | 3ed6526441053d79b85d206b14d75125e6f51cc2 (patch) | |
tree | 338c4d47130cd5c2e35852309da273edf9d21146 /fs/xfs/linux-2.6/xfs_iops.c | |
parent | 5d51eff4538bdfeb9b7a2ec030ee3b0980b067d2 (diff) |
[XFS] Implement fallocate.
Implement the new generic callout for file preallocation. Atomically
change the file size if requested.
SGI-PV: 972756
SGI-Modid: xfs-linux-melb:xfs-kern:30009a
Signed-off-by: David Chinner <dgc@sgi.com>
Signed-off-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_iops.c')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_iops.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 264b1e7dacf7..9ddef91a436d 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <linux/xattr.h> | 52 | #include <linux/xattr.h> |
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 | 56 | ||
56 | /* | 57 | /* |
57 | * Bring the atime in the XFS inode uptodate. | 58 | * Bring the atime in the XFS inode uptodate. |
@@ -794,6 +795,47 @@ xfs_vn_removexattr( | |||
794 | return namesp->attr_remove(vp, attr, xflags); | 795 | return namesp->attr_remove(vp, attr, xflags); |
795 | } | 796 | } |
796 | 797 | ||
798 | STATIC long | ||
799 | xfs_vn_fallocate( | ||
800 | struct inode *inode, | ||
801 | int mode, | ||
802 | loff_t offset, | ||
803 | loff_t len) | ||
804 | { | ||
805 | long error; | ||
806 | loff_t new_size = 0; | ||
807 | xfs_flock64_t bf; | ||
808 | xfs_inode_t *ip = XFS_I(inode); | ||
809 | |||
810 | /* preallocation on directories not yet supported */ | ||
811 | error = -ENODEV; | ||
812 | if (S_ISDIR(inode->i_mode)) | ||
813 | goto out_error; | ||
814 | |||
815 | bf.l_whence = 0; | ||
816 | bf.l_start = offset; | ||
817 | bf.l_len = len; | ||
818 | |||
819 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | ||
820 | error = xfs_change_file_space(ip, XFS_IOC_RESVSP, &bf, | ||
821 | 0, NULL, ATTR_NOLOCK); | ||
822 | if (!error && !(mode & FALLOC_FL_KEEP_SIZE) && | ||
823 | offset + len > i_size_read(inode)) | ||
824 | new_size = offset + len; | ||
825 | |||
826 | /* Change file size if needed */ | ||
827 | if (new_size) { | ||
828 | bhv_vattr_t va; | ||
829 | |||
830 | va.va_mask = XFS_AT_SIZE; | ||
831 | va.va_size = new_size; | ||
832 | error = xfs_setattr(ip, &va, ATTR_NOLOCK, NULL); | ||
833 | } | ||
834 | |||
835 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
836 | out_error: | ||
837 | return error; | ||
838 | } | ||
797 | 839 | ||
798 | const struct inode_operations xfs_inode_operations = { | 840 | const struct inode_operations xfs_inode_operations = { |
799 | .permission = xfs_vn_permission, | 841 | .permission = xfs_vn_permission, |
@@ -804,6 +846,7 @@ const struct inode_operations xfs_inode_operations = { | |||
804 | .getxattr = xfs_vn_getxattr, | 846 | .getxattr = xfs_vn_getxattr, |
805 | .listxattr = xfs_vn_listxattr, | 847 | .listxattr = xfs_vn_listxattr, |
806 | .removexattr = xfs_vn_removexattr, | 848 | .removexattr = xfs_vn_removexattr, |
849 | .fallocate = xfs_vn_fallocate, | ||
807 | }; | 850 | }; |
808 | 851 | ||
809 | const struct inode_operations xfs_dir_inode_operations = { | 852 | const struct inode_operations xfs_dir_inode_operations = { |