aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_file.c')
-rw-r--r--fs/xfs/xfs_file.c67
1 files changed, 43 insertions, 24 deletions
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 13e974e6a889..1cdba95c78cb 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -127,6 +127,42 @@ xfs_iozero(
127 return (-status); 127 return (-status);
128} 128}
129 129
130int
131xfs_update_prealloc_flags(
132 struct xfs_inode *ip,
133 enum xfs_prealloc_flags flags)
134{
135 struct xfs_trans *tp;
136 int error;
137
138 tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_WRITEID);
139 error = xfs_trans_reserve(tp, &M_RES(ip->i_mount)->tr_writeid, 0, 0);
140 if (error) {
141 xfs_trans_cancel(tp, 0);
142 return error;
143 }
144
145 xfs_ilock(ip, XFS_ILOCK_EXCL);
146 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
147
148 if (!(flags & XFS_PREALLOC_INVISIBLE)) {
149 ip->i_d.di_mode &= ~S_ISUID;
150 if (ip->i_d.di_mode & S_IXGRP)
151 ip->i_d.di_mode &= ~S_ISGID;
152 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
153 }
154
155 if (flags & XFS_PREALLOC_SET)
156 ip->i_d.di_flags |= XFS_DIFLAG_PREALLOC;
157 if (flags & XFS_PREALLOC_CLEAR)
158 ip->i_d.di_flags &= ~XFS_DIFLAG_PREALLOC;
159
160 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
161 if (flags & XFS_PREALLOC_SYNC)
162 xfs_trans_set_sync(tp);
163 return xfs_trans_commit(tp, 0);
164}
165
130/* 166/*
131 * Fsync operations on directories are much simpler than on regular files, 167 * Fsync operations on directories are much simpler than on regular files,
132 * as there is no file data to flush, and thus also no need for explicit 168 * as there is no file data to flush, and thus also no need for explicit
@@ -699,7 +735,7 @@ xfs_file_buffered_aio_write(
699 735
700 iov_iter_truncate(from, count); 736 iov_iter_truncate(from, count);
701 /* We can write back this queue in page reclaim */ 737 /* We can write back this queue in page reclaim */
702 current->backing_dev_info = mapping->backing_dev_info; 738 current->backing_dev_info = inode_to_bdi(inode);
703 739
704write_retry: 740write_retry:
705 trace_xfs_file_buffered_write(ip, count, iocb->ki_pos, 0); 741 trace_xfs_file_buffered_write(ip, count, iocb->ki_pos, 0);
@@ -784,8 +820,8 @@ xfs_file_fallocate(
784{ 820{
785 struct inode *inode = file_inode(file); 821 struct inode *inode = file_inode(file);
786 struct xfs_inode *ip = XFS_I(inode); 822 struct xfs_inode *ip = XFS_I(inode);
787 struct xfs_trans *tp;
788 long error; 823 long error;
824 enum xfs_prealloc_flags flags = 0;
789 loff_t new_size = 0; 825 loff_t new_size = 0;
790 826
791 if (!S_ISREG(inode->i_mode)) 827 if (!S_ISREG(inode->i_mode))
@@ -822,6 +858,8 @@ xfs_file_fallocate(
822 if (error) 858 if (error)
823 goto out_unlock; 859 goto out_unlock;
824 } else { 860 } else {
861 flags |= XFS_PREALLOC_SET;
862
825 if (!(mode & FALLOC_FL_KEEP_SIZE) && 863 if (!(mode & FALLOC_FL_KEEP_SIZE) &&
826 offset + len > i_size_read(inode)) { 864 offset + len > i_size_read(inode)) {
827 new_size = offset + len; 865 new_size = offset + len;
@@ -839,28 +877,10 @@ xfs_file_fallocate(
839 goto out_unlock; 877 goto out_unlock;
840 } 878 }
841 879
842 tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_WRITEID);
843 error = xfs_trans_reserve(tp, &M_RES(ip->i_mount)->tr_writeid, 0, 0);
844 if (error) {
845 xfs_trans_cancel(tp, 0);
846 goto out_unlock;
847 }
848
849 xfs_ilock(ip, XFS_ILOCK_EXCL);
850 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
851 ip->i_d.di_mode &= ~S_ISUID;
852 if (ip->i_d.di_mode & S_IXGRP)
853 ip->i_d.di_mode &= ~S_ISGID;
854
855 if (!(mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_COLLAPSE_RANGE)))
856 ip->i_d.di_flags |= XFS_DIFLAG_PREALLOC;
857
858 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
859 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
860
861 if (file->f_flags & O_DSYNC) 880 if (file->f_flags & O_DSYNC)
862 xfs_trans_set_sync(tp); 881 flags |= XFS_PREALLOC_SYNC;
863 error = xfs_trans_commit(tp, 0); 882
883 error = xfs_update_prealloc_flags(ip, flags);
864 if (error) 884 if (error)
865 goto out_unlock; 885 goto out_unlock;
866 886
@@ -1384,5 +1404,4 @@ static const struct vm_operations_struct xfs_file_vm_ops = {
1384 .fault = filemap_fault, 1404 .fault = filemap_fault,
1385 .map_pages = filemap_map_pages, 1405 .map_pages = filemap_map_pages,
1386 .page_mkwrite = xfs_vm_page_mkwrite, 1406 .page_mkwrite = xfs_vm_page_mkwrite,
1387 .remap_pages = generic_file_remap_pages,
1388}; 1407};