diff options
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_lrw.c')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_lrw.c | 79 |
1 files changed, 36 insertions, 43 deletions
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 166353388490..1ebd8004469c 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include "xfs_vnodeops.h" | 51 | #include "xfs_vnodeops.h" |
52 | 52 | ||
53 | #include <linux/capability.h> | 53 | #include <linux/capability.h> |
54 | #include <linux/mount.h> | ||
54 | #include <linux/writeback.h> | 55 | #include <linux/writeback.h> |
55 | 56 | ||
56 | 57 | ||
@@ -176,7 +177,6 @@ xfs_read( | |||
176 | { | 177 | { |
177 | struct file *file = iocb->ki_filp; | 178 | struct file *file = iocb->ki_filp; |
178 | struct inode *inode = file->f_mapping->host; | 179 | struct inode *inode = file->f_mapping->host; |
179 | bhv_vnode_t *vp = XFS_ITOV(ip); | ||
180 | xfs_mount_t *mp = ip->i_mount; | 180 | xfs_mount_t *mp = ip->i_mount; |
181 | size_t size = 0; | 181 | size_t size = 0; |
182 | ssize_t ret = 0; | 182 | ssize_t ret = 0; |
@@ -228,11 +228,11 @@ xfs_read( | |||
228 | xfs_ilock(ip, XFS_IOLOCK_SHARED); | 228 | xfs_ilock(ip, XFS_IOLOCK_SHARED); |
229 | 229 | ||
230 | if (DM_EVENT_ENABLED(ip, DM_EVENT_READ) && !(ioflags & IO_INVIS)) { | 230 | if (DM_EVENT_ENABLED(ip, DM_EVENT_READ) && !(ioflags & IO_INVIS)) { |
231 | bhv_vrwlock_t locktype = VRWLOCK_READ; | ||
232 | int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags); | 231 | int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags); |
232 | int iolock = XFS_IOLOCK_SHARED; | ||
233 | 233 | ||
234 | ret = -XFS_SEND_DATA(mp, DM_EVENT_READ, vp, *offset, size, | 234 | ret = -XFS_SEND_DATA(mp, DM_EVENT_READ, ip, *offset, size, |
235 | dmflags, &locktype); | 235 | dmflags, &iolock); |
236 | if (ret) { | 236 | if (ret) { |
237 | xfs_iunlock(ip, XFS_IOLOCK_SHARED); | 237 | xfs_iunlock(ip, XFS_IOLOCK_SHARED); |
238 | if (unlikely(ioflags & IO_ISDIRECT)) | 238 | if (unlikely(ioflags & IO_ISDIRECT)) |
@@ -242,7 +242,7 @@ xfs_read( | |||
242 | } | 242 | } |
243 | 243 | ||
244 | if (unlikely(ioflags & IO_ISDIRECT)) { | 244 | if (unlikely(ioflags & IO_ISDIRECT)) { |
245 | if (VN_CACHED(vp)) | 245 | if (inode->i_mapping->nrpages) |
246 | ret = xfs_flushinval_pages(ip, (*offset & PAGE_CACHE_MASK), | 246 | ret = xfs_flushinval_pages(ip, (*offset & PAGE_CACHE_MASK), |
247 | -1, FI_REMAPF_LOCKED); | 247 | -1, FI_REMAPF_LOCKED); |
248 | mutex_unlock(&inode->i_mutex); | 248 | mutex_unlock(&inode->i_mutex); |
@@ -276,7 +276,6 @@ xfs_splice_read( | |||
276 | int flags, | 276 | int flags, |
277 | int ioflags) | 277 | int ioflags) |
278 | { | 278 | { |
279 | bhv_vnode_t *vp = XFS_ITOV(ip); | ||
280 | xfs_mount_t *mp = ip->i_mount; | 279 | xfs_mount_t *mp = ip->i_mount; |
281 | ssize_t ret; | 280 | ssize_t ret; |
282 | 281 | ||
@@ -287,11 +286,11 @@ xfs_splice_read( | |||
287 | xfs_ilock(ip, XFS_IOLOCK_SHARED); | 286 | xfs_ilock(ip, XFS_IOLOCK_SHARED); |
288 | 287 | ||
289 | if (DM_EVENT_ENABLED(ip, DM_EVENT_READ) && !(ioflags & IO_INVIS)) { | 288 | if (DM_EVENT_ENABLED(ip, DM_EVENT_READ) && !(ioflags & IO_INVIS)) { |
290 | bhv_vrwlock_t locktype = VRWLOCK_READ; | 289 | int iolock = XFS_IOLOCK_SHARED; |
291 | int error; | 290 | int error; |
292 | 291 | ||
293 | error = XFS_SEND_DATA(mp, DM_EVENT_READ, vp, *ppos, count, | 292 | error = XFS_SEND_DATA(mp, DM_EVENT_READ, ip, *ppos, count, |
294 | FILP_DELAY_FLAG(infilp), &locktype); | 293 | FILP_DELAY_FLAG(infilp), &iolock); |
295 | if (error) { | 294 | if (error) { |
296 | xfs_iunlock(ip, XFS_IOLOCK_SHARED); | 295 | xfs_iunlock(ip, XFS_IOLOCK_SHARED); |
297 | return -error; | 296 | return -error; |
@@ -317,7 +316,6 @@ xfs_splice_write( | |||
317 | int flags, | 316 | int flags, |
318 | int ioflags) | 317 | int ioflags) |
319 | { | 318 | { |
320 | bhv_vnode_t *vp = XFS_ITOV(ip); | ||
321 | xfs_mount_t *mp = ip->i_mount; | 319 | xfs_mount_t *mp = ip->i_mount; |
322 | ssize_t ret; | 320 | ssize_t ret; |
323 | struct inode *inode = outfilp->f_mapping->host; | 321 | struct inode *inode = outfilp->f_mapping->host; |
@@ -330,11 +328,11 @@ xfs_splice_write( | |||
330 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | 328 | xfs_ilock(ip, XFS_IOLOCK_EXCL); |
331 | 329 | ||
332 | if (DM_EVENT_ENABLED(ip, DM_EVENT_WRITE) && !(ioflags & IO_INVIS)) { | 330 | if (DM_EVENT_ENABLED(ip, DM_EVENT_WRITE) && !(ioflags & IO_INVIS)) { |
333 | bhv_vrwlock_t locktype = VRWLOCK_WRITE; | 331 | int iolock = XFS_IOLOCK_EXCL; |
334 | int error; | 332 | int error; |
335 | 333 | ||
336 | error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, vp, *ppos, count, | 334 | error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, ip, *ppos, count, |
337 | FILP_DELAY_FLAG(outfilp), &locktype); | 335 | FILP_DELAY_FLAG(outfilp), &iolock); |
338 | if (error) { | 336 | if (error) { |
339 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | 337 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); |
340 | return -error; | 338 | return -error; |
@@ -573,14 +571,12 @@ xfs_write( | |||
573 | struct file *file = iocb->ki_filp; | 571 | struct file *file = iocb->ki_filp; |
574 | struct address_space *mapping = file->f_mapping; | 572 | struct address_space *mapping = file->f_mapping; |
575 | struct inode *inode = mapping->host; | 573 | struct inode *inode = mapping->host; |
576 | bhv_vnode_t *vp = XFS_ITOV(xip); | ||
577 | unsigned long segs = nsegs; | 574 | unsigned long segs = nsegs; |
578 | xfs_mount_t *mp; | 575 | xfs_mount_t *mp; |
579 | ssize_t ret = 0, error = 0; | 576 | ssize_t ret = 0, error = 0; |
580 | xfs_fsize_t isize, new_size; | 577 | xfs_fsize_t isize, new_size; |
581 | int iolock; | 578 | int iolock; |
582 | int eventsent = 0; | 579 | int eventsent = 0; |
583 | bhv_vrwlock_t locktype; | ||
584 | size_t ocount = 0, count; | 580 | size_t ocount = 0, count; |
585 | loff_t pos; | 581 | loff_t pos; |
586 | int need_i_mutex; | 582 | int need_i_mutex; |
@@ -607,11 +603,9 @@ xfs_write( | |||
607 | relock: | 603 | relock: |
608 | if (ioflags & IO_ISDIRECT) { | 604 | if (ioflags & IO_ISDIRECT) { |
609 | iolock = XFS_IOLOCK_SHARED; | 605 | iolock = XFS_IOLOCK_SHARED; |
610 | locktype = VRWLOCK_WRITE_DIRECT; | ||
611 | need_i_mutex = 0; | 606 | need_i_mutex = 0; |
612 | } else { | 607 | } else { |
613 | iolock = XFS_IOLOCK_EXCL; | 608 | iolock = XFS_IOLOCK_EXCL; |
614 | locktype = VRWLOCK_WRITE; | ||
615 | need_i_mutex = 1; | 609 | need_i_mutex = 1; |
616 | mutex_lock(&inode->i_mutex); | 610 | mutex_lock(&inode->i_mutex); |
617 | } | 611 | } |
@@ -634,9 +628,8 @@ start: | |||
634 | dmflags |= DM_FLAGS_IMUX; | 628 | dmflags |= DM_FLAGS_IMUX; |
635 | 629 | ||
636 | xfs_iunlock(xip, XFS_ILOCK_EXCL); | 630 | xfs_iunlock(xip, XFS_ILOCK_EXCL); |
637 | error = XFS_SEND_DATA(xip->i_mount, DM_EVENT_WRITE, vp, | 631 | error = XFS_SEND_DATA(xip->i_mount, DM_EVENT_WRITE, xip, |
638 | pos, count, | 632 | pos, count, dmflags, &iolock); |
639 | dmflags, &locktype); | ||
640 | if (error) { | 633 | if (error) { |
641 | goto out_unlock_internal; | 634 | goto out_unlock_internal; |
642 | } | 635 | } |
@@ -664,10 +657,9 @@ start: | |||
664 | return XFS_ERROR(-EINVAL); | 657 | return XFS_ERROR(-EINVAL); |
665 | } | 658 | } |
666 | 659 | ||
667 | if (!need_i_mutex && (VN_CACHED(vp) || pos > xip->i_size)) { | 660 | if (!need_i_mutex && (mapping->nrpages || pos > xip->i_size)) { |
668 | xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock); | 661 | xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock); |
669 | iolock = XFS_IOLOCK_EXCL; | 662 | iolock = XFS_IOLOCK_EXCL; |
670 | locktype = VRWLOCK_WRITE; | ||
671 | need_i_mutex = 1; | 663 | need_i_mutex = 1; |
672 | mutex_lock(&inode->i_mutex); | 664 | mutex_lock(&inode->i_mutex); |
673 | xfs_ilock(xip, XFS_ILOCK_EXCL|iolock); | 665 | xfs_ilock(xip, XFS_ILOCK_EXCL|iolock); |
@@ -679,10 +671,16 @@ start: | |||
679 | if (new_size > xip->i_size) | 671 | if (new_size > xip->i_size) |
680 | xip->i_new_size = new_size; | 672 | xip->i_new_size = new_size; |
681 | 673 | ||
682 | if (likely(!(ioflags & IO_INVIS))) { | 674 | /* |
675 | * We're not supposed to change timestamps in readonly-mounted | ||
676 | * filesystems. Throw it away if anyone asks us. | ||
677 | */ | ||
678 | if (likely(!(ioflags & IO_INVIS) && | ||
679 | !mnt_want_write(file->f_path.mnt))) { | ||
683 | file_update_time(file); | 680 | file_update_time(file); |
684 | xfs_ichgtime_fast(xip, inode, | 681 | xfs_ichgtime_fast(xip, inode, |
685 | XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | 682 | XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); |
683 | mnt_drop_write(file->f_path.mnt); | ||
686 | } | 684 | } |
687 | 685 | ||
688 | /* | 686 | /* |
@@ -727,7 +725,7 @@ retry: | |||
727 | current->backing_dev_info = mapping->backing_dev_info; | 725 | current->backing_dev_info = mapping->backing_dev_info; |
728 | 726 | ||
729 | if ((ioflags & IO_ISDIRECT)) { | 727 | if ((ioflags & IO_ISDIRECT)) { |
730 | if (VN_CACHED(vp)) { | 728 | if (mapping->nrpages) { |
731 | WARN_ON(need_i_mutex == 0); | 729 | WARN_ON(need_i_mutex == 0); |
732 | xfs_inval_cached_trace(xip, pos, -1, | 730 | xfs_inval_cached_trace(xip, pos, -1, |
733 | (pos & PAGE_CACHE_MASK), -1); | 731 | (pos & PAGE_CACHE_MASK), -1); |
@@ -744,7 +742,6 @@ retry: | |||
744 | mutex_unlock(&inode->i_mutex); | 742 | mutex_unlock(&inode->i_mutex); |
745 | 743 | ||
746 | iolock = XFS_IOLOCK_SHARED; | 744 | iolock = XFS_IOLOCK_SHARED; |
747 | locktype = VRWLOCK_WRITE_DIRECT; | ||
748 | need_i_mutex = 0; | 745 | need_i_mutex = 0; |
749 | } | 746 | } |
750 | 747 | ||
@@ -781,15 +778,15 @@ retry: | |||
781 | 778 | ||
782 | if (ret == -ENOSPC && | 779 | if (ret == -ENOSPC && |
783 | DM_EVENT_ENABLED(xip, DM_EVENT_NOSPACE) && !(ioflags & IO_INVIS)) { | 780 | DM_EVENT_ENABLED(xip, DM_EVENT_NOSPACE) && !(ioflags & IO_INVIS)) { |
784 | xfs_rwunlock(xip, locktype); | 781 | xfs_iunlock(xip, iolock); |
785 | if (need_i_mutex) | 782 | if (need_i_mutex) |
786 | mutex_unlock(&inode->i_mutex); | 783 | mutex_unlock(&inode->i_mutex); |
787 | error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp, | 784 | error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, xip, |
788 | DM_RIGHT_NULL, vp, DM_RIGHT_NULL, NULL, NULL, | 785 | DM_RIGHT_NULL, xip, DM_RIGHT_NULL, NULL, NULL, |
789 | 0, 0, 0); /* Delay flag intentionally unused */ | 786 | 0, 0, 0); /* Delay flag intentionally unused */ |
790 | if (need_i_mutex) | 787 | if (need_i_mutex) |
791 | mutex_lock(&inode->i_mutex); | 788 | mutex_lock(&inode->i_mutex); |
792 | xfs_rwlock(xip, locktype); | 789 | xfs_ilock(xip, iolock); |
793 | if (error) | 790 | if (error) |
794 | goto out_unlock_internal; | 791 | goto out_unlock_internal; |
795 | pos = xip->i_size; | 792 | pos = xip->i_size; |
@@ -817,7 +814,8 @@ retry: | |||
817 | /* Handle various SYNC-type writes */ | 814 | /* Handle various SYNC-type writes */ |
818 | if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) { | 815 | if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) { |
819 | int error2; | 816 | int error2; |
820 | xfs_rwunlock(xip, locktype); | 817 | |
818 | xfs_iunlock(xip, iolock); | ||
821 | if (need_i_mutex) | 819 | if (need_i_mutex) |
822 | mutex_unlock(&inode->i_mutex); | 820 | mutex_unlock(&inode->i_mutex); |
823 | error2 = sync_page_range(inode, mapping, pos, ret); | 821 | error2 = sync_page_range(inode, mapping, pos, ret); |
@@ -825,7 +823,7 @@ retry: | |||
825 | error = error2; | 823 | error = error2; |
826 | if (need_i_mutex) | 824 | if (need_i_mutex) |
827 | mutex_lock(&inode->i_mutex); | 825 | mutex_lock(&inode->i_mutex); |
828 | xfs_rwlock(xip, locktype); | 826 | xfs_ilock(xip, iolock); |
829 | error2 = xfs_write_sync_logforce(mp, xip); | 827 | error2 = xfs_write_sync_logforce(mp, xip); |
830 | if (!error) | 828 | if (!error) |
831 | error = error2; | 829 | error = error2; |
@@ -846,7 +844,7 @@ retry: | |||
846 | xip->i_d.di_size = xip->i_size; | 844 | xip->i_d.di_size = xip->i_size; |
847 | xfs_iunlock(xip, XFS_ILOCK_EXCL); | 845 | xfs_iunlock(xip, XFS_ILOCK_EXCL); |
848 | } | 846 | } |
849 | xfs_rwunlock(xip, locktype); | 847 | xfs_iunlock(xip, iolock); |
850 | out_unlock_mutex: | 848 | out_unlock_mutex: |
851 | if (need_i_mutex) | 849 | if (need_i_mutex) |
852 | mutex_unlock(&inode->i_mutex); | 850 | mutex_unlock(&inode->i_mutex); |
@@ -884,28 +882,23 @@ xfs_bdstrat_cb(struct xfs_buf *bp) | |||
884 | } | 882 | } |
885 | 883 | ||
886 | /* | 884 | /* |
887 | * Wrapper around bdstrat so that we can stop data | 885 | * Wrapper around bdstrat so that we can stop data from going to disk in case |
888 | * from going to disk in case we are shutting down the filesystem. | 886 | * we are shutting down the filesystem. Typically user data goes thru this |
889 | * Typically user data goes thru this path; one of the exceptions | 887 | * path; one of the exceptions is the superblock. |
890 | * is the superblock. | ||
891 | */ | 888 | */ |
892 | int | 889 | void |
893 | xfsbdstrat( | 890 | xfsbdstrat( |
894 | struct xfs_mount *mp, | 891 | struct xfs_mount *mp, |
895 | struct xfs_buf *bp) | 892 | struct xfs_buf *bp) |
896 | { | 893 | { |
897 | ASSERT(mp); | 894 | ASSERT(mp); |
898 | if (!XFS_FORCED_SHUTDOWN(mp)) { | 895 | if (!XFS_FORCED_SHUTDOWN(mp)) { |
899 | /* Grio redirection would go here | ||
900 | * if (XFS_BUF_IS_GRIO(bp)) { | ||
901 | */ | ||
902 | |||
903 | xfs_buf_iorequest(bp); | 896 | xfs_buf_iorequest(bp); |
904 | return 0; | 897 | return; |
905 | } | 898 | } |
906 | 899 | ||
907 | xfs_buftrace("XFSBDSTRAT IOERROR", bp); | 900 | xfs_buftrace("XFSBDSTRAT IOERROR", bp); |
908 | return (xfs_bioerror_relse(bp)); | 901 | xfs_bioerror_relse(bp); |
909 | } | 902 | } |
910 | 903 | ||
911 | /* | 904 | /* |