aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2011-01-10 18:17:30 -0500
committerDave Chinner <david@fromorbit.com>2011-01-10 18:17:30 -0500
commit637bbc75d9fda57c7bc77ce5ee37e29a77a0520d (patch)
tree285e82a7afdf7b5e1468f17288e122f7ec269ac7 /fs/xfs/linux-2.6
parentf0d26e860b6c496464c5c8165d7df08dabde01fa (diff)
xfs: split buffered IO write path from xfs_file_aio_write
Complete the split of the different write IO paths by splitting the buffered IO write path out of xfs_file_aio_write(). This makes the different mechanisms of the write patchs easier to follow. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Alex Elder <aelder@sgi.com> Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/xfs/linux-2.6')
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c146
1 files changed, 69 insertions, 77 deletions
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 00661fd21fc0..e2bcf51d292e 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -739,58 +739,31 @@ xfs_file_dio_aio_write(
739} 739}
740 740
741STATIC ssize_t 741STATIC ssize_t
742xfs_file_aio_write( 742xfs_file_buffered_aio_write(
743 struct kiocb *iocb, 743 struct kiocb *iocb,
744 const struct iovec *iovp, 744 const struct iovec *iovp,
745 unsigned long nr_segs, 745 unsigned long nr_segs,
746 loff_t pos) 746 loff_t pos,
747 size_t ocount,
748 int *iolock)
747{ 749{
748 struct file *file = iocb->ki_filp; 750 struct file *file = iocb->ki_filp;
749 struct address_space *mapping = file->f_mapping; 751 struct address_space *mapping = file->f_mapping;
750 struct inode *inode = mapping->host; 752 struct inode *inode = mapping->host;
751 struct xfs_inode *ip = XFS_I(inode); 753 struct xfs_inode *ip = XFS_I(inode);
752 struct xfs_mount *mp = ip->i_mount; 754 ssize_t ret;
753 ssize_t ret = 0; 755 int enospc = 0;
754 int ioflags = 0;
755 xfs_fsize_t new_size; 756 xfs_fsize_t new_size;
756 int iolock; 757 size_t count = ocount;
757 size_t ocount = 0, count;
758
759 XFS_STATS_INC(xs_write_calls);
760
761 BUG_ON(iocb->ki_pos != pos);
762
763 if (unlikely(file->f_flags & O_DIRECT))
764 ioflags |= IO_ISDIRECT;
765 if (file->f_mode & FMODE_NOCMTIME)
766 ioflags |= IO_INVIS;
767
768 ret = generic_segment_checks(iovp, &nr_segs, &ocount, VERIFY_READ);
769 if (ret)
770 return ret;
771
772 count = ocount;
773 if (count == 0)
774 return 0;
775
776 xfs_wait_for_freeze(mp, SB_FREEZE_WRITE);
777
778 if (XFS_FORCED_SHUTDOWN(mp))
779 return -EIO;
780 758
781relock: 759 *iolock = XFS_IOLOCK_EXCL;
782 if (ioflags & IO_ISDIRECT) { 760 xfs_rw_ilock(ip, XFS_ILOCK_EXCL | *iolock);
783 ret = xfs_file_dio_aio_write(iocb, iovp, nr_segs, pos,
784 ocount, &iolock);
785 goto done_io;
786 }
787 iolock = XFS_IOLOCK_EXCL;
788 761
789 xfs_rw_ilock(ip, XFS_ILOCK_EXCL|iolock);
790 ret = generic_write_checks(file, &pos, &count, 762 ret = generic_write_checks(file, &pos, &count,
791 S_ISBLK(inode->i_mode)); 763 S_ISBLK(inode->i_mode));
792 if (ret) { 764 if (ret) {
793 xfs_rw_iunlock(ip, XFS_ILOCK_EXCL|iolock); 765 xfs_rw_iunlock(ip, XFS_ILOCK_EXCL | *iolock);
766 *iolock = 0;
794 return ret; 767 return ret;
795 } 768 }
796 769
@@ -798,67 +771,86 @@ relock:
798 if (new_size > ip->i_size) 771 if (new_size > ip->i_size)
799 ip->i_new_size = new_size; 772 ip->i_new_size = new_size;
800 773
801 if (likely(!(ioflags & IO_INVIS))) 774 if (likely(!(file->f_mode & FMODE_NOCMTIME)))
802 file_update_time(file); 775 file_update_time(file);
803 776
804 /*
805 * If the offset is beyond the size of the file, we have a couple
806 * of things to do. First, if there is already space allocated
807 * we need to either create holes or zero the disk or ...
808 *
809 * If there is a page where the previous size lands, we need
810 * to zero it out up to the new size.
811 */
812
813 if (pos > ip->i_size) { 777 if (pos > ip->i_size) {
814 ret = -xfs_zero_eof(ip, pos, ip->i_size); 778 ret = -xfs_zero_eof(ip, pos, ip->i_size);
815 if (ret) { 779 if (ret) {
816 xfs_rw_iunlock(ip, XFS_ILOCK_EXCL); 780 xfs_rw_iunlock(ip, XFS_ILOCK_EXCL);
817 goto out_unlock_internal; 781 return ret;
818 } 782 }
819 } 783 }
820 xfs_rw_iunlock(ip, XFS_ILOCK_EXCL); 784 xfs_rw_iunlock(ip, XFS_ILOCK_EXCL);
821 785
822 /*
823 * If we're writing the file then make sure to clear the
824 * setuid and setgid bits if the process is not being run
825 * by root. This keeps people from modifying setuid and
826 * setgid binaries.
827 */
828 ret = file_remove_suid(file); 786 ret = file_remove_suid(file);
829 if (unlikely(ret)) 787 if (unlikely(ret))
830 goto out_unlock_internal; 788 return ret;
831 789
832 /* We can write back this queue in page reclaim */ 790 /* We can write back this queue in page reclaim */
833 current->backing_dev_info = mapping->backing_dev_info; 791 current->backing_dev_info = mapping->backing_dev_info;
834 792
835 if (!(ioflags & IO_ISDIRECT)) {
836 int enospc = 0;
837
838write_retry: 793write_retry:
839 trace_xfs_file_buffered_write(ip, count, iocb->ki_pos, ioflags); 794 trace_xfs_file_buffered_write(ip, count, iocb->ki_pos, 0);
840 ret = generic_file_buffered_write(iocb, iovp, nr_segs, 795 ret = generic_file_buffered_write(iocb, iovp, nr_segs,
841 pos, &iocb->ki_pos, count, ret); 796 pos, &iocb->ki_pos, count, ret);
842 /* 797 /*
843 * if we just got an ENOSPC, flush the inode now we 798 * if we just got an ENOSPC, flush the inode now we aren't holding any
844 * aren't holding any page locks and retry *once* 799 * page locks and retry *once*
845 */ 800 */
846 if (ret == -ENOSPC && !enospc) { 801 if (ret == -ENOSPC && !enospc) {
847 ret = xfs_flush_pages(ip, 0, -1, 0, FI_NONE); 802 ret = -xfs_flush_pages(ip, 0, -1, 0, FI_NONE);
848 if (ret) 803 if (ret)
849 goto out_unlock_internal; 804 return ret;
850 enospc = 1; 805 enospc = 1;
851 goto write_retry; 806 goto write_retry;
852 }
853 } 807 }
854
855 current->backing_dev_info = NULL; 808 current->backing_dev_info = NULL;
809 return ret;
810}
811
812STATIC ssize_t
813xfs_file_aio_write(
814 struct kiocb *iocb,
815 const struct iovec *iovp,
816 unsigned long nr_segs,
817 loff_t pos)
818{
819 struct file *file = iocb->ki_filp;
820 struct address_space *mapping = file->f_mapping;
821 struct inode *inode = mapping->host;
822 struct xfs_inode *ip = XFS_I(inode);
823 ssize_t ret;
824 int iolock;
825 size_t ocount = 0;
826
827 XFS_STATS_INC(xs_write_calls);
828
829 BUG_ON(iocb->ki_pos != pos);
830
831 ret = generic_segment_checks(iovp, &nr_segs, &ocount, VERIFY_READ);
832 if (ret)
833 return ret;
834
835 if (ocount == 0)
836 return 0;
837
838 xfs_wait_for_freeze(ip->i_mount, SB_FREEZE_WRITE);
839
840 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
841 return -EIO;
842
843 if (unlikely(file->f_flags & O_DIRECT))
844 ret = xfs_file_dio_aio_write(iocb, iovp, nr_segs, pos,
845 ocount, &iolock);
846 else
847 ret = xfs_file_buffered_aio_write(iocb, iovp, nr_segs, pos,
848 ocount, &iolock);
856 849
857done_io:
858 xfs_aio_write_isize_update(inode, &iocb->ki_pos, ret); 850 xfs_aio_write_isize_update(inode, &iocb->ki_pos, ret);
859 851
860 if (ret <= 0) 852 if (ret <= 0)
861 goto out_unlock_internal; 853 goto out_unlock;
862 854
863 /* Handle various SYNC-type writes */ 855 /* Handle various SYNC-type writes */
864 if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) { 856 if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) {
@@ -877,7 +869,7 @@ done_io:
877 ret = error2; 869 ret = error2;
878 } 870 }
879 871
880 out_unlock_internal: 872out_unlock:
881 xfs_aio_write_newsize_update(ip); 873 xfs_aio_write_newsize_update(ip);
882 xfs_rw_iunlock(ip, iolock); 874 xfs_rw_iunlock(ip, iolock);
883 return ret; 875 return ret;