aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDavid Chinner <dgc@sgi.com>2007-11-23 00:29:25 -0500
committerLachlan McIlroy <lachlan@redback.melbourne.sgi.com>2008-02-07 02:16:17 -0500
commit3ed6526441053d79b85d206b14d75125e6f51cc2 (patch)
tree338c4d47130cd5c2e35852309da273edf9d21146 /fs
parent5d51eff4538bdfeb9b7a2ec030ee3b0980b067d2 (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')
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c43
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
798STATIC long
799xfs_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);
836out_error:
837 return error;
838}
797 839
798const struct inode_operations xfs_inode_operations = { 840const 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
809const struct inode_operations xfs_dir_inode_operations = { 852const struct inode_operations xfs_dir_inode_operations = {