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.c54
1 files changed, 41 insertions, 13 deletions
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 64b48eade91d..830c1c937b88 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -155,7 +155,7 @@ xfs_dir_fsync(
155 155
156 if (!lsn) 156 if (!lsn)
157 return 0; 157 return 0;
158 return _xfs_log_force_lsn(mp, lsn, XFS_LOG_SYNC, NULL); 158 return -_xfs_log_force_lsn(mp, lsn, XFS_LOG_SYNC, NULL);
159} 159}
160 160
161STATIC int 161STATIC int
@@ -295,7 +295,7 @@ xfs_file_aio_read(
295 xfs_rw_ilock(ip, XFS_IOLOCK_EXCL); 295 xfs_rw_ilock(ip, XFS_IOLOCK_EXCL);
296 296
297 if (inode->i_mapping->nrpages) { 297 if (inode->i_mapping->nrpages) {
298 ret = -filemap_write_and_wait_range( 298 ret = filemap_write_and_wait_range(
299 VFS_I(ip)->i_mapping, 299 VFS_I(ip)->i_mapping,
300 pos, -1); 300 pos, -1);
301 if (ret) { 301 if (ret) {
@@ -679,7 +679,7 @@ xfs_file_dio_aio_write(
679 goto out; 679 goto out;
680 680
681 if (mapping->nrpages) { 681 if (mapping->nrpages) {
682 ret = -filemap_write_and_wait_range(VFS_I(ip)->i_mapping, 682 ret = filemap_write_and_wait_range(VFS_I(ip)->i_mapping,
683 pos, -1); 683 pos, -1);
684 if (ret) 684 if (ret)
685 goto out; 685 goto out;
@@ -699,7 +699,7 @@ xfs_file_dio_aio_write(
699 699
700 trace_xfs_file_direct_write(ip, count, iocb->ki_pos, 0); 700 trace_xfs_file_direct_write(ip, count, iocb->ki_pos, 0);
701 ret = generic_file_direct_write(iocb, iovp, 701 ret = generic_file_direct_write(iocb, iovp,
702 &nr_segs, pos, &iocb->ki_pos, count, ocount); 702 &nr_segs, pos, count, ocount);
703 703
704out: 704out:
705 xfs_rw_iunlock(ip, iolock); 705 xfs_rw_iunlock(ip, iolock);
@@ -715,7 +715,7 @@ xfs_file_buffered_aio_write(
715 const struct iovec *iovp, 715 const struct iovec *iovp,
716 unsigned long nr_segs, 716 unsigned long nr_segs,
717 loff_t pos, 717 loff_t pos,
718 size_t ocount) 718 size_t count)
719{ 719{
720 struct file *file = iocb->ki_filp; 720 struct file *file = iocb->ki_filp;
721 struct address_space *mapping = file->f_mapping; 721 struct address_space *mapping = file->f_mapping;
@@ -724,7 +724,7 @@ xfs_file_buffered_aio_write(
724 ssize_t ret; 724 ssize_t ret;
725 int enospc = 0; 725 int enospc = 0;
726 int iolock = XFS_IOLOCK_EXCL; 726 int iolock = XFS_IOLOCK_EXCL;
727 size_t count = ocount; 727 struct iov_iter from;
728 728
729 xfs_rw_ilock(ip, iolock); 729 xfs_rw_ilock(ip, iolock);
730 730
@@ -732,14 +732,15 @@ xfs_file_buffered_aio_write(
732 if (ret) 732 if (ret)
733 goto out; 733 goto out;
734 734
735 iov_iter_init(&from, iovp, nr_segs, count, 0);
735 /* We can write back this queue in page reclaim */ 736 /* We can write back this queue in page reclaim */
736 current->backing_dev_info = mapping->backing_dev_info; 737 current->backing_dev_info = mapping->backing_dev_info;
737 738
738write_retry: 739write_retry:
739 trace_xfs_file_buffered_write(ip, count, iocb->ki_pos, 0); 740 trace_xfs_file_buffered_write(ip, count, iocb->ki_pos, 0);
740 ret = generic_file_buffered_write(iocb, iovp, nr_segs, 741 ret = generic_perform_write(file, &from, pos);
741 pos, &iocb->ki_pos, count, 0); 742 if (likely(ret >= 0))
742 743 iocb->ki_pos = pos + ret;
743 /* 744 /*
744 * If we just got an ENOSPC, try to write back all dirty inodes to 745 * If we just got an ENOSPC, try to write back all dirty inodes to
745 * convert delalloc space to free up some of the excess reserved 746 * convert delalloc space to free up some of the excess reserved
@@ -823,7 +824,8 @@ xfs_file_fallocate(
823 824
824 if (!S_ISREG(inode->i_mode)) 825 if (!S_ISREG(inode->i_mode))
825 return -EINVAL; 826 return -EINVAL;
826 if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) 827 if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE |
828 FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_ZERO_RANGE))
827 return -EOPNOTSUPP; 829 return -EOPNOTSUPP;
828 830
829 xfs_ilock(ip, XFS_IOLOCK_EXCL); 831 xfs_ilock(ip, XFS_IOLOCK_EXCL);
@@ -831,6 +833,28 @@ xfs_file_fallocate(
831 error = xfs_free_file_space(ip, offset, len); 833 error = xfs_free_file_space(ip, offset, len);
832 if (error) 834 if (error)
833 goto out_unlock; 835 goto out_unlock;
836 } else if (mode & FALLOC_FL_COLLAPSE_RANGE) {
837 unsigned blksize_mask = (1 << inode->i_blkbits) - 1;
838
839 if (offset & blksize_mask || len & blksize_mask) {
840 error = EINVAL;
841 goto out_unlock;
842 }
843
844 /*
845 * There is no need to overlap collapse range with EOF,
846 * in which case it is effectively a truncate operation
847 */
848 if (offset + len >= i_size_read(inode)) {
849 error = EINVAL;
850 goto out_unlock;
851 }
852
853 new_size = i_size_read(inode) - len;
854
855 error = xfs_collapse_file_space(ip, offset, len);
856 if (error)
857 goto out_unlock;
834 } else { 858 } else {
835 if (!(mode & FALLOC_FL_KEEP_SIZE) && 859 if (!(mode & FALLOC_FL_KEEP_SIZE) &&
836 offset + len > i_size_read(inode)) { 860 offset + len > i_size_read(inode)) {
@@ -840,8 +864,11 @@ xfs_file_fallocate(
840 goto out_unlock; 864 goto out_unlock;
841 } 865 }
842 866
843 error = xfs_alloc_file_space(ip, offset, len, 867 if (mode & FALLOC_FL_ZERO_RANGE)
844 XFS_BMAPI_PREALLOC); 868 error = xfs_zero_file_space(ip, offset, len);
869 else
870 error = xfs_alloc_file_space(ip, offset, len,
871 XFS_BMAPI_PREALLOC);
845 if (error) 872 if (error)
846 goto out_unlock; 873 goto out_unlock;
847 } 874 }
@@ -859,7 +886,7 @@ xfs_file_fallocate(
859 if (ip->i_d.di_mode & S_IXGRP) 886 if (ip->i_d.di_mode & S_IXGRP)
860 ip->i_d.di_mode &= ~S_ISGID; 887 ip->i_d.di_mode &= ~S_ISGID;
861 888
862 if (!(mode & FALLOC_FL_PUNCH_HOLE)) 889 if (!(mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_COLLAPSE_RANGE)))
863 ip->i_d.di_flags |= XFS_DIFLAG_PREALLOC; 890 ip->i_d.di_flags |= XFS_DIFLAG_PREALLOC;
864 891
865 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 892 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
@@ -1465,6 +1492,7 @@ const struct file_operations xfs_dir_file_operations = {
1465 1492
1466static const struct vm_operations_struct xfs_file_vm_ops = { 1493static const struct vm_operations_struct xfs_file_vm_ops = {
1467 .fault = filemap_fault, 1494 .fault = filemap_fault,
1495 .map_pages = filemap_map_pages,
1468 .page_mkwrite = xfs_vm_page_mkwrite, 1496 .page_mkwrite = xfs_vm_page_mkwrite,
1469 .remap_pages = generic_file_remap_pages, 1497 .remap_pages = generic_file_remap_pages,
1470}; 1498};