aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6/xfs_lrw.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_lrw.c')
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c123
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
500int /* error (positive) */ 498int /* error (positive) */
501xfs_zero_eof( 499xfs_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)