diff options
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_lrw.c')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_lrw.c | 123 |
1 files changed, 20 insertions, 103 deletions
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 67efe3308980..5d9cfd91ad08 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_ag.h" | 25 | #include "xfs_ag.h" |
26 | #include "xfs_dir.h" | ||
27 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
28 | #include "xfs_alloc.h" | 27 | #include "xfs_alloc.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
@@ -32,7 +31,6 @@ | |||
32 | #include "xfs_bmap_btree.h" | 31 | #include "xfs_bmap_btree.h" |
33 | #include "xfs_alloc_btree.h" | 32 | #include "xfs_alloc_btree.h" |
34 | #include "xfs_ialloc_btree.h" | 33 | #include "xfs_ialloc_btree.h" |
35 | #include "xfs_dir_sf.h" | ||
36 | #include "xfs_dir2_sf.h" | 34 | #include "xfs_dir2_sf.h" |
37 | #include "xfs_attr_sf.h" | 35 | #include "xfs_attr_sf.h" |
38 | #include "xfs_dinode.h" | 36 | #include "xfs_dinode.h" |
@@ -206,7 +204,7 @@ xfs_read( | |||
206 | xfs_fsize_t n; | 204 | xfs_fsize_t n; |
207 | xfs_inode_t *ip; | 205 | xfs_inode_t *ip; |
208 | xfs_mount_t *mp; | 206 | xfs_mount_t *mp; |
209 | vnode_t *vp; | 207 | bhv_vnode_t *vp; |
210 | unsigned long seg; | 208 | unsigned long seg; |
211 | 209 | ||
212 | ip = XFS_BHVTOI(bdp); | 210 | ip = XFS_BHVTOI(bdp); |
@@ -258,7 +256,7 @@ xfs_read( | |||
258 | 256 | ||
259 | if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) && | 257 | if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) && |
260 | !(ioflags & IO_INVIS)) { | 258 | !(ioflags & IO_INVIS)) { |
261 | vrwlock_t locktype = VRWLOCK_READ; | 259 | bhv_vrwlock_t locktype = VRWLOCK_READ; |
262 | int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags); | 260 | int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags); |
263 | 261 | ||
264 | ret = -XFS_SEND_DATA(mp, DM_EVENT_READ, | 262 | ret = -XFS_SEND_DATA(mp, DM_EVENT_READ, |
@@ -271,7 +269,7 @@ xfs_read( | |||
271 | } | 269 | } |
272 | 270 | ||
273 | if (unlikely((ioflags & IO_ISDIRECT) && VN_CACHED(vp))) | 271 | if (unlikely((ioflags & IO_ISDIRECT) && VN_CACHED(vp))) |
274 | VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(*offset)), | 272 | bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)), |
275 | -1, FI_REMAPF_LOCKED); | 273 | -1, FI_REMAPF_LOCKED); |
276 | 274 | ||
277 | xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore, | 275 | xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore, |
@@ -313,7 +311,7 @@ xfs_sendfile( | |||
313 | 311 | ||
314 | if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) && | 312 | if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) && |
315 | (!(ioflags & IO_INVIS))) { | 313 | (!(ioflags & IO_INVIS))) { |
316 | vrwlock_t locktype = VRWLOCK_READ; | 314 | bhv_vrwlock_t locktype = VRWLOCK_READ; |
317 | int error; | 315 | int error; |
318 | 316 | ||
319 | error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), | 317 | error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), |
@@ -357,7 +355,7 @@ xfs_splice_read( | |||
357 | 355 | ||
358 | if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) && | 356 | if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) && |
359 | (!(ioflags & IO_INVIS))) { | 357 | (!(ioflags & IO_INVIS))) { |
360 | vrwlock_t locktype = VRWLOCK_READ; | 358 | bhv_vrwlock_t locktype = VRWLOCK_READ; |
361 | int error; | 359 | int error; |
362 | 360 | ||
363 | error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), | 361 | error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), |
@@ -401,7 +399,7 @@ xfs_splice_write( | |||
401 | 399 | ||
402 | if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_WRITE) && | 400 | if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_WRITE) && |
403 | (!(ioflags & IO_INVIS))) { | 401 | (!(ioflags & IO_INVIS))) { |
404 | vrwlock_t locktype = VRWLOCK_WRITE; | 402 | bhv_vrwlock_t locktype = VRWLOCK_WRITE; |
405 | int error; | 403 | int error; |
406 | 404 | ||
407 | error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, BHV_TO_VNODE(bdp), | 405 | error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, BHV_TO_VNODE(bdp), |
@@ -458,7 +456,7 @@ xfs_zero_last_block( | |||
458 | last_fsb = XFS_B_TO_FSBT(mp, isize); | 456 | last_fsb = XFS_B_TO_FSBT(mp, isize); |
459 | nimaps = 1; | 457 | nimaps = 1; |
460 | error = XFS_BMAPI(mp, NULL, io, last_fsb, 1, 0, NULL, 0, &imap, | 458 | error = XFS_BMAPI(mp, NULL, io, last_fsb, 1, 0, NULL, 0, &imap, |
461 | &nimaps, NULL); | 459 | &nimaps, NULL, NULL); |
462 | if (error) { | 460 | if (error) { |
463 | return error; | 461 | return error; |
464 | } | 462 | } |
@@ -499,7 +497,7 @@ xfs_zero_last_block( | |||
499 | 497 | ||
500 | int /* error (positive) */ | 498 | int /* error (positive) */ |
501 | xfs_zero_eof( | 499 | xfs_zero_eof( |
502 | vnode_t *vp, | 500 | bhv_vnode_t *vp, |
503 | xfs_iocore_t *io, | 501 | xfs_iocore_t *io, |
504 | xfs_off_t offset, /* starting I/O offset */ | 502 | xfs_off_t offset, /* starting I/O offset */ |
505 | xfs_fsize_t isize, /* current inode size */ | 503 | xfs_fsize_t isize, /* current inode size */ |
@@ -510,7 +508,6 @@ xfs_zero_eof( | |||
510 | xfs_fileoff_t end_zero_fsb; | 508 | xfs_fileoff_t end_zero_fsb; |
511 | xfs_fileoff_t zero_count_fsb; | 509 | xfs_fileoff_t zero_count_fsb; |
512 | xfs_fileoff_t last_fsb; | 510 | xfs_fileoff_t last_fsb; |
513 | xfs_extlen_t buf_len_fsb; | ||
514 | xfs_mount_t *mp = io->io_mount; | 511 | xfs_mount_t *mp = io->io_mount; |
515 | int nimaps; | 512 | int nimaps; |
516 | int error = 0; | 513 | int error = 0; |
@@ -556,7 +553,7 @@ xfs_zero_eof( | |||
556 | nimaps = 1; | 553 | nimaps = 1; |
557 | zero_count_fsb = end_zero_fsb - start_zero_fsb + 1; | 554 | zero_count_fsb = end_zero_fsb - start_zero_fsb + 1; |
558 | error = XFS_BMAPI(mp, NULL, io, start_zero_fsb, zero_count_fsb, | 555 | error = XFS_BMAPI(mp, NULL, io, start_zero_fsb, zero_count_fsb, |
559 | 0, NULL, 0, &imap, &nimaps, NULL); | 556 | 0, NULL, 0, &imap, &nimaps, NULL, NULL); |
560 | if (error) { | 557 | if (error) { |
561 | ASSERT(ismrlocked(io->io_lock, MR_UPDATE)); | 558 | ASSERT(ismrlocked(io->io_lock, MR_UPDATE)); |
562 | ASSERT(ismrlocked(io->io_iolock, MR_UPDATE)); | 559 | ASSERT(ismrlocked(io->io_iolock, MR_UPDATE)); |
@@ -579,16 +576,7 @@ xfs_zero_eof( | |||
579 | } | 576 | } |
580 | 577 | ||
581 | /* | 578 | /* |
582 | * There are blocks in the range requested. | 579 | * There are blocks we need to zero. |
583 | * Zero them a single write at a time. We actually | ||
584 | * don't zero the entire range returned if it is | ||
585 | * too big and simply loop around to get the rest. | ||
586 | * That is not the most efficient thing to do, but it | ||
587 | * is simple and this path should not be exercised often. | ||
588 | */ | ||
589 | buf_len_fsb = XFS_FILBLKS_MIN(imap.br_blockcount, | ||
590 | mp->m_writeio_blocks << 8); | ||
591 | /* | ||
592 | * Drop the inode lock while we're doing the I/O. | 580 | * Drop the inode lock while we're doing the I/O. |
593 | * We'll still have the iolock to protect us. | 581 | * We'll still have the iolock to protect us. |
594 | */ | 582 | */ |
@@ -596,14 +584,13 @@ xfs_zero_eof( | |||
596 | 584 | ||
597 | error = xfs_iozero(ip, | 585 | error = xfs_iozero(ip, |
598 | XFS_FSB_TO_B(mp, start_zero_fsb), | 586 | XFS_FSB_TO_B(mp, start_zero_fsb), |
599 | XFS_FSB_TO_B(mp, buf_len_fsb), | 587 | XFS_FSB_TO_B(mp, imap.br_blockcount), |
600 | end_size); | 588 | end_size); |
601 | |||
602 | if (error) { | 589 | if (error) { |
603 | goto out_lock; | 590 | goto out_lock; |
604 | } | 591 | } |
605 | 592 | ||
606 | start_zero_fsb = imap.br_startoff + buf_len_fsb; | 593 | start_zero_fsb = imap.br_startoff + imap.br_blockcount; |
607 | ASSERT(start_zero_fsb <= (end_zero_fsb + 1)); | 594 | ASSERT(start_zero_fsb <= (end_zero_fsb + 1)); |
608 | 595 | ||
609 | XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD); | 596 | XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD); |
@@ -637,11 +624,11 @@ xfs_write( | |||
637 | ssize_t ret = 0, error = 0; | 624 | ssize_t ret = 0, error = 0; |
638 | xfs_fsize_t isize, new_size; | 625 | xfs_fsize_t isize, new_size; |
639 | xfs_iocore_t *io; | 626 | xfs_iocore_t *io; |
640 | vnode_t *vp; | 627 | bhv_vnode_t *vp; |
641 | unsigned long seg; | 628 | unsigned long seg; |
642 | int iolock; | 629 | int iolock; |
643 | int eventsent = 0; | 630 | int eventsent = 0; |
644 | vrwlock_t locktype; | 631 | bhv_vrwlock_t locktype; |
645 | size_t ocount = 0, count; | 632 | size_t ocount = 0, count; |
646 | loff_t pos; | 633 | loff_t pos; |
647 | int need_i_mutex = 1, need_flush = 0; | 634 | int need_i_mutex = 1, need_flush = 0; |
@@ -679,11 +666,11 @@ xfs_write( | |||
679 | io = &xip->i_iocore; | 666 | io = &xip->i_iocore; |
680 | mp = io->io_mount; | 667 | mp = io->io_mount; |
681 | 668 | ||
669 | vfs_wait_for_freeze(vp->v_vfsp, SB_FREEZE_WRITE); | ||
670 | |||
682 | if (XFS_FORCED_SHUTDOWN(mp)) | 671 | if (XFS_FORCED_SHUTDOWN(mp)) |
683 | return -EIO; | 672 | return -EIO; |
684 | 673 | ||
685 | fs_check_frozen(vp->v_vfsp, SB_FREEZE_WRITE); | ||
686 | |||
687 | if (ioflags & IO_ISDIRECT) { | 674 | if (ioflags & IO_ISDIRECT) { |
688 | xfs_buftarg_t *target = | 675 | xfs_buftarg_t *target = |
689 | (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? | 676 | (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? |
@@ -814,7 +801,7 @@ retry: | |||
814 | if (need_flush) { | 801 | if (need_flush) { |
815 | xfs_inval_cached_trace(io, pos, -1, | 802 | xfs_inval_cached_trace(io, pos, -1, |
816 | ctooff(offtoct(pos)), -1); | 803 | ctooff(offtoct(pos)), -1); |
817 | VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(pos)), | 804 | bhv_vop_flushinval_pages(vp, ctooff(offtoct(pos)), |
818 | -1, FI_REMAPF_LOCKED); | 805 | -1, FI_REMAPF_LOCKED); |
819 | } | 806 | } |
820 | 807 | ||
@@ -903,79 +890,9 @@ retry: | |||
903 | 890 | ||
904 | /* Handle various SYNC-type writes */ | 891 | /* Handle various SYNC-type writes */ |
905 | if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) { | 892 | if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) { |
906 | /* | 893 | error = xfs_write_sync_logforce(mp, xip); |
907 | * If we're treating this as O_DSYNC and we have not updated the | 894 | if (error) |
908 | * size, force the log. | 895 | goto out_unlock_internal; |
909 | */ | ||
910 | if (!(mp->m_flags & XFS_MOUNT_OSYNCISOSYNC) && | ||
911 | !(xip->i_update_size)) { | ||
912 | xfs_inode_log_item_t *iip = xip->i_itemp; | ||
913 | |||
914 | /* | ||
915 | * If an allocation transaction occurred | ||
916 | * without extending the size, then we have to force | ||
917 | * the log up the proper point to ensure that the | ||
918 | * allocation is permanent. We can't count on | ||
919 | * the fact that buffered writes lock out direct I/O | ||
920 | * writes - the direct I/O write could have extended | ||
921 | * the size nontransactionally, then finished before | ||
922 | * we started. xfs_write_file will think that the file | ||
923 | * didn't grow but the update isn't safe unless the | ||
924 | * size change is logged. | ||
925 | * | ||
926 | * Force the log if we've committed a transaction | ||
927 | * against the inode or if someone else has and | ||
928 | * the commit record hasn't gone to disk (e.g. | ||
929 | * the inode is pinned). This guarantees that | ||
930 | * all changes affecting the inode are permanent | ||
931 | * when we return. | ||
932 | */ | ||
933 | if (iip && iip->ili_last_lsn) { | ||
934 | xfs_log_force(mp, iip->ili_last_lsn, | ||
935 | XFS_LOG_FORCE | XFS_LOG_SYNC); | ||
936 | } else if (xfs_ipincount(xip) > 0) { | ||
937 | xfs_log_force(mp, (xfs_lsn_t)0, | ||
938 | XFS_LOG_FORCE | XFS_LOG_SYNC); | ||
939 | } | ||
940 | |||
941 | } else { | ||
942 | xfs_trans_t *tp; | ||
943 | |||
944 | /* | ||
945 | * O_SYNC or O_DSYNC _with_ a size update are handled | ||
946 | * the same way. | ||
947 | * | ||
948 | * If the write was synchronous then we need to make | ||
949 | * sure that the inode modification time is permanent. | ||
950 | * We'll have updated the timestamp above, so here | ||
951 | * we use a synchronous transaction to log the inode. | ||
952 | * It's not fast, but it's necessary. | ||
953 | * | ||
954 | * If this a dsync write and the size got changed | ||
955 | * non-transactionally, then we need to ensure that | ||
956 | * the size change gets logged in a synchronous | ||
957 | * transaction. | ||
958 | */ | ||
959 | |||
960 | tp = xfs_trans_alloc(mp, XFS_TRANS_WRITE_SYNC); | ||
961 | if ((error = xfs_trans_reserve(tp, 0, | ||
962 | XFS_SWRITE_LOG_RES(mp), | ||
963 | 0, 0, 0))) { | ||
964 | /* Transaction reserve failed */ | ||
965 | xfs_trans_cancel(tp, 0); | ||
966 | } else { | ||
967 | /* Transaction reserve successful */ | ||
968 | xfs_ilock(xip, XFS_ILOCK_EXCL); | ||
969 | xfs_trans_ijoin(tp, xip, XFS_ILOCK_EXCL); | ||
970 | xfs_trans_ihold(tp, xip); | ||
971 | xfs_trans_log_inode(tp, xip, XFS_ILOG_CORE); | ||
972 | xfs_trans_set_sync(tp); | ||
973 | error = xfs_trans_commit(tp, 0, NULL); | ||
974 | xfs_iunlock(xip, XFS_ILOCK_EXCL); | ||
975 | } | ||
976 | if (error) | ||
977 | goto out_unlock_internal; | ||
978 | } | ||
979 | 896 | ||
980 | xfs_rwunlock(bdp, locktype); | 897 | xfs_rwunlock(bdp, locktype); |
981 | if (need_i_mutex) | 898 | if (need_i_mutex) |