aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_file.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2013-10-12 03:55:07 -0400
committerBen Myers <bpm@sgi.com>2013-10-21 17:56:21 -0400
commit83aee9e4c2976143f35b3a42ad1faadf58c53ae7 (patch)
tree568ca76e660645e9762f14c1972514b7f59f247c /fs/xfs/xfs_file.c
parent5f8aca8b43f41c4b2d4dc5389124a40cab92b644 (diff)
xfs: simplify the fallocate path
Call xfs_alloc_file_space or xfs_free_file_space directly from xfs_file_fallocate instead of going through xfs_change_file_space. This simplified the code by removing the unessecary marshalling of the arguments into an xfs_flock64_t structure and allows removing checks that are already done in the VFS code. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_file.c')
-rw-r--r--fs/xfs/xfs_file.c76
1 files changed, 48 insertions, 28 deletions
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 116300f3b1d4..c8a75a75e25a 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -805,44 +805,64 @@ out:
805 805
806STATIC long 806STATIC long
807xfs_file_fallocate( 807xfs_file_fallocate(
808 struct file *file, 808 struct file *file,
809 int mode, 809 int mode,
810 loff_t offset, 810 loff_t offset,
811 loff_t len) 811 loff_t len)
812{ 812{
813 struct inode *inode = file_inode(file); 813 struct inode *inode = file_inode(file);
814 long error; 814 struct xfs_inode *ip = XFS_I(inode);
815 loff_t new_size = 0; 815 struct xfs_trans *tp;
816 xfs_flock64_t bf; 816 long error;
817 xfs_inode_t *ip = XFS_I(inode); 817 loff_t new_size = 0;
818 int cmd = XFS_IOC_RESVSP;
819 int attr_flags = 0;
820 818
819 if (!S_ISREG(inode->i_mode))
820 return -EINVAL;
821 if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) 821 if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
822 return -EOPNOTSUPP; 822 return -EOPNOTSUPP;
823 823
824 bf.l_whence = 0;
825 bf.l_start = offset;
826 bf.l_len = len;
827
828 xfs_ilock(ip, XFS_IOLOCK_EXCL); 824 xfs_ilock(ip, XFS_IOLOCK_EXCL);
825 if (mode & FALLOC_FL_PUNCH_HOLE) {
826 error = xfs_free_file_space(ip, offset, len);
827 if (error)
828 goto out_unlock;
829 } else {
830 if (!(mode & FALLOC_FL_KEEP_SIZE) &&
831 offset + len > i_size_read(inode)) {
832 new_size = offset + len;
833 error = -inode_newsize_ok(inode, new_size);
834 if (error)
835 goto out_unlock;
836 }
829 837
830 if (mode & FALLOC_FL_PUNCH_HOLE) 838 error = xfs_alloc_file_space(ip, offset, len,
831 cmd = XFS_IOC_UNRESVSP; 839 XFS_BMAPI_PREALLOC);
832
833 /* check the new inode size is valid before allocating */
834 if (!(mode & FALLOC_FL_KEEP_SIZE) &&
835 offset + len > i_size_read(inode)) {
836 new_size = offset + len;
837 error = inode_newsize_ok(inode, new_size);
838 if (error) 840 if (error)
839 goto out_unlock; 841 goto out_unlock;
840 } 842 }
841 843
842 if (file->f_flags & O_DSYNC) 844 tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_WRITEID);
843 attr_flags |= XFS_ATTR_SYNC; 845 error = xfs_trans_reserve(tp, &M_RES(ip->i_mount)->tr_writeid, 0, 0);
846 if (error) {
847 xfs_trans_cancel(tp, 0);
848 goto out_unlock;
849 }
850
851 xfs_ilock(ip, XFS_ILOCK_EXCL);
852 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
853 ip->i_d.di_mode &= ~S_ISUID;
854 if (ip->i_d.di_mode & S_IXGRP)
855 ip->i_d.di_mode &= ~S_ISGID;
856
857 if (!(mode & FALLOC_FL_PUNCH_HOLE))
858 ip->i_d.di_flags |= XFS_DIFLAG_PREALLOC;
859
860 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
861 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
844 862
845 error = -xfs_change_file_space(ip, cmd, &bf, 0, attr_flags); 863 if (file->f_flags & O_DSYNC)
864 xfs_trans_set_sync(tp);
865 error = xfs_trans_commit(tp, 0);
846 if (error) 866 if (error)
847 goto out_unlock; 867 goto out_unlock;
848 868
@@ -852,12 +872,12 @@ xfs_file_fallocate(
852 872
853 iattr.ia_valid = ATTR_SIZE; 873 iattr.ia_valid = ATTR_SIZE;
854 iattr.ia_size = new_size; 874 iattr.ia_size = new_size;
855 error = -xfs_setattr_size(ip, &iattr); 875 error = xfs_setattr_size(ip, &iattr);
856 } 876 }
857 877
858out_unlock: 878out_unlock:
859 xfs_iunlock(ip, XFS_IOLOCK_EXCL); 879 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
860 return error; 880 return -error;
861} 881}
862 882
863 883