diff options
| author | Christoph Hellwig <hch@infradead.org> | 2013-10-12 03:55:07 -0400 |
|---|---|---|
| committer | Ben Myers <bpm@sgi.com> | 2013-10-21 17:56:21 -0400 |
| commit | 83aee9e4c2976143f35b3a42ad1faadf58c53ae7 (patch) | |
| tree | 568ca76e660645e9762f14c1972514b7f59f247c /fs | |
| parent | 5f8aca8b43f41c4b2d4dc5389124a40cab92b644 (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')
| -rw-r--r-- | fs/xfs/xfs_bmap_util.c | 39 | ||||
| -rw-r--r-- | fs/xfs/xfs_bmap_util.h | 4 | ||||
| -rw-r--r-- | fs/xfs/xfs_file.c | 76 |
3 files changed, 56 insertions, 63 deletions
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index bdd552d83107..7e1c2ae81c35 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c | |||
| @@ -965,28 +965,9 @@ xfs_free_eofblocks( | |||
| 965 | return error; | 965 | return error; |
| 966 | } | 966 | } |
| 967 | 967 | ||
| 968 | /* | 968 | int |
| 969 | * xfs_alloc_file_space() | ||
| 970 | * This routine allocates disk space for the given file. | ||
| 971 | * | ||
| 972 | * If alloc_type == 0, this request is for an ALLOCSP type | ||
| 973 | * request which will change the file size. In this case, no | ||
| 974 | * DMAPI event will be generated by the call. A TRUNCATE event | ||
| 975 | * will be generated later by xfs_setattr. | ||
| 976 | * | ||
| 977 | * If alloc_type != 0, this request is for a RESVSP type | ||
| 978 | * request, and a DMAPI DM_EVENT_WRITE will be generated if the | ||
| 979 | * lower block boundary byte address is less than the file's | ||
| 980 | * length. | ||
| 981 | * | ||
| 982 | * RETURNS: | ||
| 983 | * 0 on success | ||
| 984 | * errno on error | ||
| 985 | * | ||
| 986 | */ | ||
| 987 | STATIC int | ||
| 988 | xfs_alloc_file_space( | 969 | xfs_alloc_file_space( |
| 989 | xfs_inode_t *ip, | 970 | struct xfs_inode *ip, |
| 990 | xfs_off_t offset, | 971 | xfs_off_t offset, |
| 991 | xfs_off_t len, | 972 | xfs_off_t len, |
| 992 | int alloc_type) | 973 | int alloc_type) |
| @@ -1231,21 +1212,9 @@ xfs_zero_remaining_bytes( | |||
| 1231 | return error; | 1212 | return error; |
| 1232 | } | 1213 | } |
| 1233 | 1214 | ||
| 1234 | /* | 1215 | int |
| 1235 | * xfs_free_file_space() | ||
| 1236 | * This routine frees disk space for the given file. | ||
| 1237 | * | ||
| 1238 | * This routine is only called by xfs_change_file_space | ||
| 1239 | * for an UNRESVSP type call. | ||
| 1240 | * | ||
| 1241 | * RETURNS: | ||
| 1242 | * 0 on success | ||
| 1243 | * errno on error | ||
| 1244 | * | ||
| 1245 | */ | ||
| 1246 | STATIC int | ||
| 1247 | xfs_free_file_space( | 1216 | xfs_free_file_space( |
| 1248 | xfs_inode_t *ip, | 1217 | struct xfs_inode *ip, |
| 1249 | xfs_off_t offset, | 1218 | xfs_off_t offset, |
| 1250 | xfs_off_t len) | 1219 | xfs_off_t len) |
| 1251 | { | 1220 | { |
diff --git a/fs/xfs/xfs_bmap_util.h b/fs/xfs/xfs_bmap_util.h index 061260946f7a..77cf5001719b 100644 --- a/fs/xfs/xfs_bmap_util.h +++ b/fs/xfs/xfs_bmap_util.h | |||
| @@ -96,6 +96,10 @@ int xfs_bmap_last_extent(struct xfs_trans *tp, struct xfs_inode *ip, | |||
| 96 | int xfs_change_file_space(struct xfs_inode *ip, int cmd, | 96 | int xfs_change_file_space(struct xfs_inode *ip, int cmd, |
| 97 | xfs_flock64_t *bf, xfs_off_t offset, | 97 | xfs_flock64_t *bf, xfs_off_t offset, |
| 98 | int attr_flags); | 98 | int attr_flags); |
| 99 | int xfs_alloc_file_space(struct xfs_inode *ip, xfs_off_t offset, | ||
| 100 | xfs_off_t len, int alloc_type); | ||
| 101 | int xfs_free_file_space(struct xfs_inode *ip, xfs_off_t offset, | ||
| 102 | xfs_off_t len); | ||
| 99 | 103 | ||
| 100 | /* EOF block manipulation functions */ | 104 | /* EOF block manipulation functions */ |
| 101 | bool xfs_can_free_eofblocks(struct xfs_inode *ip, bool force); | 105 | bool xfs_can_free_eofblocks(struct xfs_inode *ip, bool force); |
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 | ||
| 806 | STATIC long | 806 | STATIC long |
| 807 | xfs_file_fallocate( | 807 | xfs_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 | ||
| 858 | out_unlock: | 878 | out_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 | ||
