aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorOlaf Weber <olaf@sgi.com>2006-06-09 00:48:12 -0400
committerNathan Scott <nathans@sgi.com>2006-06-09 00:48:12 -0400
commit3e57ecf640428c01ba1ed8c8fc538447ada1715b (patch)
treebcc92b0017b5ec8e106649cd53beffdd6addde07 /fs/xfs
parent128e6ced247cda88f96fa9f2e4ba8b2c4a681560 (diff)
[XFS] Add parameters to xfs_bmapi() and xfs_bunmapi() to have them report
the range spanned by modifications to the in-core extent map. Add XFS_BUNMAPI() and XFS_SWAP_EXTENTS() macros that call xfs_bunmapi() and xfs_swap_extents() via the ioops vector. Change all calls that may modify the in-core extent map for the data fork to go through the ioops vector. This allows a cache of extent map data to be kept in sync. SGI-PV: 947615 SGI-Modid: xfs-linux-melb:xfs-kern:209226a Signed-off-by: Olaf Weber <olaf@sgi.com> Signed-off-by: Nathan Scott <nathans@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c4
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.h2
-rw-r--r--fs/xfs/quota/xfs_dquot.c4
-rw-r--r--fs/xfs/quota/xfs_qm.c2
-rw-r--r--fs/xfs/xfs_attr.c12
-rw-r--r--fs/xfs/xfs_attr_leaf.c2
-rw-r--r--fs/xfs/xfs_bmap.c363
-rw-r--r--fs/xfs/xfs_bmap.h22
-rw-r--r--fs/xfs/xfs_da_btree.c9
-rw-r--r--fs/xfs/xfs_dfrag.c74
-rw-r--r--fs/xfs/xfs_dfrag.h3
-rw-r--r--fs/xfs/xfs_dir2.c7
-rw-r--r--fs/xfs/xfs_dir2_leaf.c2
-rw-r--r--fs/xfs/xfs_inode.c11
-rw-r--r--fs/xfs/xfs_iocore.c3
-rw-r--r--fs/xfs/xfs_iomap.c24
-rw-r--r--fs/xfs/xfs_mount.h23
-rw-r--r--fs/xfs/xfs_rtalloc.c2
-rw-r--r--fs/xfs/xfs_vnodeops.c34
19 files changed, 437 insertions, 166 deletions
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 67efe3308980..67b5e1c20deb 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -458,7 +458,7 @@ xfs_zero_last_block(
458 last_fsb = XFS_B_TO_FSBT(mp, isize); 458 last_fsb = XFS_B_TO_FSBT(mp, isize);
459 nimaps = 1; 459 nimaps = 1;
460 error = XFS_BMAPI(mp, NULL, io, last_fsb, 1, 0, NULL, 0, &imap, 460 error = XFS_BMAPI(mp, NULL, io, last_fsb, 1, 0, NULL, 0, &imap,
461 &nimaps, NULL); 461 &nimaps, NULL, NULL);
462 if (error) { 462 if (error) {
463 return error; 463 return error;
464 } 464 }
@@ -556,7 +556,7 @@ xfs_zero_eof(
556 nimaps = 1; 556 nimaps = 1;
557 zero_count_fsb = end_zero_fsb - start_zero_fsb + 1; 557 zero_count_fsb = end_zero_fsb - start_zero_fsb + 1;
558 error = XFS_BMAPI(mp, NULL, io, start_zero_fsb, zero_count_fsb, 558 error = XFS_BMAPI(mp, NULL, io, start_zero_fsb, zero_count_fsb,
559 0, NULL, 0, &imap, &nimaps, NULL); 559 0, NULL, 0, &imap, &nimaps, NULL, NULL);
560 if (error) { 560 if (error) {
561 ASSERT(ismrlocked(io->io_lock, MR_UPDATE)); 561 ASSERT(ismrlocked(io->io_lock, MR_UPDATE));
562 ASSERT(ismrlocked(io->io_iolock, MR_UPDATE)); 562 ASSERT(ismrlocked(io->io_iolock, MR_UPDATE));
diff --git a/fs/xfs/linux-2.6/xfs_lrw.h b/fs/xfs/linux-2.6/xfs_lrw.h
index 8f4539952350..dc49050688ca 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.h
+++ b/fs/xfs/linux-2.6/xfs_lrw.h
@@ -49,7 +49,7 @@ struct xfs_iomap;
49#define XFS_CTRUNC4 14 49#define XFS_CTRUNC4 14
50#define XFS_CTRUNC5 15 50#define XFS_CTRUNC5 15
51#define XFS_CTRUNC6 16 51#define XFS_CTRUNC6 16
52#define XFS_BUNMAPI 17 52#define XFS_BUNMAP 17
53#define XFS_INVAL_CACHED 18 53#define XFS_INVAL_CACHED 18
54#define XFS_DIORD_ENTER 19 54#define XFS_DIORD_ENTER 19
55#define XFS_DIOWR_ENTER 20 55#define XFS_DIOWR_ENTER 20
diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c
index 772ac48329ea..26ee5df4f83d 100644
--- a/fs/xfs/quota/xfs_dquot.c
+++ b/fs/xfs/quota/xfs_dquot.c
@@ -444,7 +444,7 @@ xfs_qm_dqalloc(
444 XFS_BMAPI_METADATA | XFS_BMAPI_WRITE, 444 XFS_BMAPI_METADATA | XFS_BMAPI_WRITE,
445 &firstblock, 445 &firstblock,
446 XFS_QM_DQALLOC_SPACE_RES(mp), 446 XFS_QM_DQALLOC_SPACE_RES(mp),
447 &map, &nmaps, &flist))) { 447 &map, &nmaps, &flist, NULL))) {
448 goto error0; 448 goto error0;
449 } 449 }
450 ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB); 450 ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB);
@@ -559,7 +559,7 @@ xfs_qm_dqtobp(
559 error = xfs_bmapi(NULL, quotip, dqp->q_fileoffset, 559 error = xfs_bmapi(NULL, quotip, dqp->q_fileoffset,
560 XFS_DQUOT_CLUSTER_SIZE_FSB, 560 XFS_DQUOT_CLUSTER_SIZE_FSB,
561 XFS_BMAPI_METADATA, 561 XFS_BMAPI_METADATA,
562 NULL, 0, &map, &nmaps, NULL); 562 NULL, 0, &map, &nmaps, NULL, NULL);
563 563
564 xfs_iunlock(quotip, XFS_ILOCK_SHARED); 564 xfs_iunlock(quotip, XFS_ILOCK_SHARED);
565 if (error) 565 if (error)
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index 7fb5eca9bd50..492840b2a354 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -1603,7 +1603,7 @@ xfs_qm_dqiterate(
1603 maxlblkcnt - lblkno, 1603 maxlblkcnt - lblkno,
1604 XFS_BMAPI_METADATA, 1604 XFS_BMAPI_METADATA,
1605 NULL, 1605 NULL,
1606 0, map, &nmaps, NULL); 1606 0, map, &nmaps, NULL, NULL);
1607 xfs_iunlock(qip, XFS_ILOCK_SHARED); 1607 xfs_iunlock(qip, XFS_ILOCK_SHARED);
1608 if (error) 1608 if (error)
1609 break; 1609 break;
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
index b6e1e02bbb28..3ef41e75d08a 100644
--- a/fs/xfs/xfs_attr.c
+++ b/fs/xfs/xfs_attr.c
@@ -1910,7 +1910,7 @@ xfs_attr_rmtval_get(xfs_da_args_t *args)
1910 error = xfs_bmapi(args->trans, args->dp, (xfs_fileoff_t)lblkno, 1910 error = xfs_bmapi(args->trans, args->dp, (xfs_fileoff_t)lblkno,
1911 args->rmtblkcnt, 1911 args->rmtblkcnt,
1912 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, 1912 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
1913 NULL, 0, map, &nmap, NULL); 1913 NULL, 0, map, &nmap, NULL, NULL);
1914 if (error) 1914 if (error)
1915 return(error); 1915 return(error);
1916 ASSERT(nmap >= 1); 1916 ASSERT(nmap >= 1);
@@ -1988,7 +1988,7 @@ xfs_attr_rmtval_set(xfs_da_args_t *args)
1988 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA | 1988 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA |
1989 XFS_BMAPI_WRITE, 1989 XFS_BMAPI_WRITE,
1990 args->firstblock, args->total, &map, &nmap, 1990 args->firstblock, args->total, &map, &nmap,
1991 args->flist); 1991 args->flist, NULL);
1992 if (!error) { 1992 if (!error) {
1993 error = xfs_bmap_finish(&args->trans, args->flist, 1993 error = xfs_bmap_finish(&args->trans, args->flist,
1994 *args->firstblock, &committed); 1994 *args->firstblock, &committed);
@@ -2039,7 +2039,8 @@ xfs_attr_rmtval_set(xfs_da_args_t *args)
2039 error = xfs_bmapi(NULL, dp, (xfs_fileoff_t)lblkno, 2039 error = xfs_bmapi(NULL, dp, (xfs_fileoff_t)lblkno,
2040 args->rmtblkcnt, 2040 args->rmtblkcnt,
2041 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, 2041 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
2042 args->firstblock, 0, &map, &nmap, NULL); 2042 args->firstblock, 0, &map, &nmap,
2043 NULL, NULL);
2043 if (error) { 2044 if (error) {
2044 return(error); 2045 return(error);
2045 } 2046 }
@@ -2104,7 +2105,7 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args)
2104 args->rmtblkcnt, 2105 args->rmtblkcnt,
2105 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, 2106 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
2106 args->firstblock, 0, &map, &nmap, 2107 args->firstblock, 0, &map, &nmap,
2107 args->flist); 2108 args->flist, NULL);
2108 if (error) { 2109 if (error) {
2109 return(error); 2110 return(error);
2110 } 2111 }
@@ -2142,7 +2143,8 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args)
2142 XFS_BMAP_INIT(args->flist, args->firstblock); 2143 XFS_BMAP_INIT(args->flist, args->firstblock);
2143 error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt, 2144 error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt,
2144 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, 2145 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
2145 1, args->firstblock, args->flist, &done); 2146 1, args->firstblock, args->flist,
2147 NULL, &done);
2146 if (!error) { 2148 if (!error) {
2147 error = xfs_bmap_finish(&args->trans, args->flist, 2149 error = xfs_bmap_finish(&args->trans, args->flist,
2148 *args->firstblock, &committed); 2150 *args->firstblock, &committed);
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index 9462be86aa14..5c44343d4a36 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -2990,7 +2990,7 @@ xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp,
2990 nmap = 1; 2990 nmap = 1;
2991 error = xfs_bmapi(*trans, dp, (xfs_fileoff_t)tblkno, tblkcnt, 2991 error = xfs_bmapi(*trans, dp, (xfs_fileoff_t)tblkno, tblkcnt,
2992 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, 2992 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
2993 NULL, 0, &map, &nmap, NULL); 2993 NULL, 0, &map, &nmap, NULL, NULL);
2994 if (error) { 2994 if (error) {
2995 return(error); 2995 return(error);
2996 } 2996 }
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 26939d364bc4..890ad3528174 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -101,6 +101,7 @@ xfs_bmap_add_extent(
101 xfs_fsblock_t *first, /* pointer to firstblock variable */ 101 xfs_fsblock_t *first, /* pointer to firstblock variable */
102 xfs_bmap_free_t *flist, /* list of extents to be freed */ 102 xfs_bmap_free_t *flist, /* list of extents to be freed */
103 int *logflagsp, /* inode logging flags */ 103 int *logflagsp, /* inode logging flags */
104 xfs_extdelta_t *delta, /* Change made to incore extents */
104 int whichfork, /* data or attr fork */ 105 int whichfork, /* data or attr fork */
105 int rsvd); /* OK to allocate reserved blocks */ 106 int rsvd); /* OK to allocate reserved blocks */
106 107
@@ -118,6 +119,7 @@ xfs_bmap_add_extent_delay_real(
118 xfs_fsblock_t *first, /* pointer to firstblock variable */ 119 xfs_fsblock_t *first, /* pointer to firstblock variable */
119 xfs_bmap_free_t *flist, /* list of extents to be freed */ 120 xfs_bmap_free_t *flist, /* list of extents to be freed */
120 int *logflagsp, /* inode logging flags */ 121 int *logflagsp, /* inode logging flags */
122 xfs_extdelta_t *delta, /* Change made to incore extents */
121 int rsvd); /* OK to allocate reserved blocks */ 123 int rsvd); /* OK to allocate reserved blocks */
122 124
123/* 125/*
@@ -131,6 +133,7 @@ xfs_bmap_add_extent_hole_delay(
131 xfs_btree_cur_t *cur, /* if null, not a btree */ 133 xfs_btree_cur_t *cur, /* if null, not a btree */
132 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 134 xfs_bmbt_irec_t *new, /* new data to add to file extents */
133 int *logflagsp,/* inode logging flags */ 135 int *logflagsp,/* inode logging flags */
136 xfs_extdelta_t *delta, /* Change made to incore extents */
134 int rsvd); /* OK to allocate reserved blocks */ 137 int rsvd); /* OK to allocate reserved blocks */
135 138
136/* 139/*
@@ -144,6 +147,7 @@ xfs_bmap_add_extent_hole_real(
144 xfs_btree_cur_t *cur, /* if null, not a btree */ 147 xfs_btree_cur_t *cur, /* if null, not a btree */
145 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 148 xfs_bmbt_irec_t *new, /* new data to add to file extents */
146 int *logflagsp, /* inode logging flags */ 149 int *logflagsp, /* inode logging flags */
150 xfs_extdelta_t *delta, /* Change made to incore extents */
147 int whichfork); /* data or attr fork */ 151 int whichfork); /* data or attr fork */
148 152
149/* 153/*
@@ -156,7 +160,8 @@ xfs_bmap_add_extent_unwritten_real(
156 xfs_extnum_t idx, /* extent number to update/insert */ 160 xfs_extnum_t idx, /* extent number to update/insert */
157 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 161 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
158 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 162 xfs_bmbt_irec_t *new, /* new data to add to file extents */
159 int *logflagsp); /* inode logging flags */ 163 int *logflagsp, /* inode logging flags */
164 xfs_extdelta_t *delta); /* Change made to incore extents */
160 165
161/* 166/*
162 * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file. 167 * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file.
@@ -203,6 +208,7 @@ xfs_bmap_del_extent(
203 xfs_btree_cur_t *cur, /* if null, not a btree */ 208 xfs_btree_cur_t *cur, /* if null, not a btree */
204 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 209 xfs_bmbt_irec_t *new, /* new data to add to file extents */
205 int *logflagsp,/* inode logging flags */ 210 int *logflagsp,/* inode logging flags */
211 xfs_extdelta_t *delta, /* Change made to incore extents */
206 int whichfork, /* data or attr fork */ 212 int whichfork, /* data or attr fork */
207 int rsvd); /* OK to allocate reserved blocks */ 213 int rsvd); /* OK to allocate reserved blocks */
208 214
@@ -530,6 +536,7 @@ xfs_bmap_add_extent(
530 xfs_fsblock_t *first, /* pointer to firstblock variable */ 536 xfs_fsblock_t *first, /* pointer to firstblock variable */
531 xfs_bmap_free_t *flist, /* list of extents to be freed */ 537 xfs_bmap_free_t *flist, /* list of extents to be freed */
532 int *logflagsp, /* inode logging flags */ 538 int *logflagsp, /* inode logging flags */
539 xfs_extdelta_t *delta, /* Change made to incore extents */
533 int whichfork, /* data or attr fork */ 540 int whichfork, /* data or attr fork */
534 int rsvd) /* OK to use reserved data blocks */ 541 int rsvd) /* OK to use reserved data blocks */
535{ 542{
@@ -567,6 +574,15 @@ xfs_bmap_add_extent(
567 logflags = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); 574 logflags = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
568 } else 575 } else
569 logflags = 0; 576 logflags = 0;
577 /* DELTA: single new extent */
578 if (delta) {
579 if (delta->xed_startoff > new->br_startoff)
580 delta->xed_startoff = new->br_startoff;
581 if (delta->xed_blockcount <
582 new->br_startoff + new->br_blockcount)
583 delta->xed_blockcount = new->br_startoff +
584 new->br_blockcount;
585 }
570 } 586 }
571 /* 587 /*
572 * Any kind of new delayed allocation goes here. 588 * Any kind of new delayed allocation goes here.
@@ -576,7 +592,7 @@ xfs_bmap_add_extent(
576 ASSERT((cur->bc_private.b.flags & 592 ASSERT((cur->bc_private.b.flags &
577 XFS_BTCUR_BPRV_WASDEL) == 0); 593 XFS_BTCUR_BPRV_WASDEL) == 0);
578 if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, cur, new, 594 if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, cur, new,
579 &logflags, rsvd))) 595 &logflags, delta, rsvd)))
580 goto done; 596 goto done;
581 } 597 }
582 /* 598 /*
@@ -587,7 +603,7 @@ xfs_bmap_add_extent(
587 ASSERT((cur->bc_private.b.flags & 603 ASSERT((cur->bc_private.b.flags &
588 XFS_BTCUR_BPRV_WASDEL) == 0); 604 XFS_BTCUR_BPRV_WASDEL) == 0);
589 if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new, 605 if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new,
590 &logflags, whichfork))) 606 &logflags, delta, whichfork)))
591 goto done; 607 goto done;
592 } else { 608 } else {
593 xfs_bmbt_irec_t prev; /* old extent at offset idx */ 609 xfs_bmbt_irec_t prev; /* old extent at offset idx */
@@ -612,17 +628,17 @@ xfs_bmap_add_extent(
612 XFS_BTCUR_BPRV_WASDEL); 628 XFS_BTCUR_BPRV_WASDEL);
613 if ((error = xfs_bmap_add_extent_delay_real(ip, 629 if ((error = xfs_bmap_add_extent_delay_real(ip,
614 idx, &cur, new, &da_new, first, flist, 630 idx, &cur, new, &da_new, first, flist,
615 &logflags, rsvd))) 631 &logflags, delta, rsvd)))
616 goto done; 632 goto done;
617 } else if (new->br_state == XFS_EXT_NORM) { 633 } else if (new->br_state == XFS_EXT_NORM) {
618 ASSERT(new->br_state == XFS_EXT_NORM); 634 ASSERT(new->br_state == XFS_EXT_NORM);
619 if ((error = xfs_bmap_add_extent_unwritten_real( 635 if ((error = xfs_bmap_add_extent_unwritten_real(
620 ip, idx, &cur, new, &logflags))) 636 ip, idx, &cur, new, &logflags, delta)))
621 goto done; 637 goto done;
622 } else { 638 } else {
623 ASSERT(new->br_state == XFS_EXT_UNWRITTEN); 639 ASSERT(new->br_state == XFS_EXT_UNWRITTEN);
624 if ((error = xfs_bmap_add_extent_unwritten_real( 640 if ((error = xfs_bmap_add_extent_unwritten_real(
625 ip, idx, &cur, new, &logflags))) 641 ip, idx, &cur, new, &logflags, delta)))
626 goto done; 642 goto done;
627 } 643 }
628 ASSERT(*curp == cur || *curp == NULL); 644 ASSERT(*curp == cur || *curp == NULL);
@@ -635,7 +651,7 @@ xfs_bmap_add_extent(
635 ASSERT((cur->bc_private.b.flags & 651 ASSERT((cur->bc_private.b.flags &
636 XFS_BTCUR_BPRV_WASDEL) == 0); 652 XFS_BTCUR_BPRV_WASDEL) == 0);
637 if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, 653 if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur,
638 new, &logflags, whichfork))) 654 new, &logflags, delta, whichfork)))
639 goto done; 655 goto done;
640 } 656 }
641 } 657 }
@@ -700,6 +716,7 @@ xfs_bmap_add_extent_delay_real(
700 xfs_fsblock_t *first, /* pointer to firstblock variable */ 716 xfs_fsblock_t *first, /* pointer to firstblock variable */
701 xfs_bmap_free_t *flist, /* list of extents to be freed */ 717 xfs_bmap_free_t *flist, /* list of extents to be freed */
702 int *logflagsp, /* inode logging flags */ 718 int *logflagsp, /* inode logging flags */
719 xfs_extdelta_t *delta, /* Change made to incore extents */
703 int rsvd) /* OK to use reserved data block allocation */ 720 int rsvd) /* OK to use reserved data block allocation */
704{ 721{
705 xfs_btree_cur_t *cur; /* btree cursor */ 722 xfs_btree_cur_t *cur; /* btree cursor */
@@ -716,8 +733,8 @@ xfs_bmap_add_extent_delay_real(
716 /* left is 0, right is 1, prev is 2 */ 733 /* left is 0, right is 1, prev is 2 */
717 int rval=0; /* return value (logging flags) */ 734 int rval=0; /* return value (logging flags) */
718 int state = 0;/* state bits, accessed thru macros */ 735 int state = 0;/* state bits, accessed thru macros */
719 xfs_filblks_t temp; /* value for dnew calculations */ 736 xfs_filblks_t temp=0; /* value for dnew calculations */
720 xfs_filblks_t temp2; /* value for dnew calculations */ 737 xfs_filblks_t temp2=0;/* value for dnew calculations */
721 int tmp_rval; /* partial logging flags */ 738 int tmp_rval; /* partial logging flags */
722 enum { /* bit number definitions for state */ 739 enum { /* bit number definitions for state */
723 LEFT_CONTIG, RIGHT_CONTIG, 740 LEFT_CONTIG, RIGHT_CONTIG,
@@ -839,6 +856,11 @@ xfs_bmap_add_extent_delay_real(
839 goto done; 856 goto done;
840 } 857 }
841 *dnew = 0; 858 *dnew = 0;
859 /* DELTA: Three in-core extents are replaced by one. */
860 temp = LEFT.br_startoff;
861 temp2 = LEFT.br_blockcount +
862 PREV.br_blockcount +
863 RIGHT.br_blockcount;
842 break; 864 break;
843 865
844 case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG): 866 case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG):
@@ -872,6 +894,10 @@ xfs_bmap_add_extent_delay_real(
872 goto done; 894 goto done;
873 } 895 }
874 *dnew = 0; 896 *dnew = 0;
897 /* DELTA: Two in-core extents are replaced by one. */
898 temp = LEFT.br_startoff;
899 temp2 = LEFT.br_blockcount +
900 PREV.br_blockcount;
875 break; 901 break;
876 902
877 case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG): 903 case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG):
@@ -906,6 +932,10 @@ xfs_bmap_add_extent_delay_real(
906 goto done; 932 goto done;
907 } 933 }
908 *dnew = 0; 934 *dnew = 0;
935 /* DELTA: Two in-core extents are replaced by one. */
936 temp = PREV.br_startoff;
937 temp2 = PREV.br_blockcount +
938 RIGHT.br_blockcount;
909 break; 939 break;
910 940
911 case MASK2(LEFT_FILLING, RIGHT_FILLING): 941 case MASK2(LEFT_FILLING, RIGHT_FILLING):
@@ -936,6 +966,9 @@ xfs_bmap_add_extent_delay_real(
936 ASSERT(i == 1); 966 ASSERT(i == 1);
937 } 967 }
938 *dnew = 0; 968 *dnew = 0;
969 /* DELTA: The in-core extent described by new changed type. */
970 temp = new->br_startoff;
971 temp2 = new->br_blockcount;
939 break; 972 break;
940 973
941 case MASK2(LEFT_FILLING, LEFT_CONTIG): 974 case MASK2(LEFT_FILLING, LEFT_CONTIG):
@@ -978,6 +1011,10 @@ xfs_bmap_add_extent_delay_real(
978 xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx, 1011 xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx,
979 XFS_DATA_FORK); 1012 XFS_DATA_FORK);
980 *dnew = temp; 1013 *dnew = temp;
1014 /* DELTA: The boundary between two in-core extents moved. */
1015 temp = LEFT.br_startoff;
1016 temp2 = LEFT.br_blockcount +
1017 PREV.br_blockcount;
981 break; 1018 break;
982 1019
983 case MASK(LEFT_FILLING): 1020 case MASK(LEFT_FILLING):
@@ -1025,6 +1062,9 @@ xfs_bmap_add_extent_delay_real(
1025 xfs_bmap_trace_post_update(fname, "LF", ip, idx + 1, 1062 xfs_bmap_trace_post_update(fname, "LF", ip, idx + 1,
1026 XFS_DATA_FORK); 1063 XFS_DATA_FORK);
1027 *dnew = temp; 1064 *dnew = temp;
1065 /* DELTA: One in-core extent is split in two. */
1066 temp = PREV.br_startoff;
1067 temp2 = PREV.br_blockcount;
1028 break; 1068 break;
1029 1069
1030 case MASK2(RIGHT_FILLING, RIGHT_CONTIG): 1070 case MASK2(RIGHT_FILLING, RIGHT_CONTIG):
@@ -1067,6 +1107,10 @@ xfs_bmap_add_extent_delay_real(
1067 xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx, 1107 xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx,
1068 XFS_DATA_FORK); 1108 XFS_DATA_FORK);
1069 *dnew = temp; 1109 *dnew = temp;
1110 /* DELTA: The boundary between two in-core extents moved. */
1111 temp = PREV.br_startoff;
1112 temp2 = PREV.br_blockcount +
1113 RIGHT.br_blockcount;
1070 break; 1114 break;
1071 1115
1072 case MASK(RIGHT_FILLING): 1116 case MASK(RIGHT_FILLING):
@@ -1112,6 +1156,9 @@ xfs_bmap_add_extent_delay_real(
1112 xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); 1156 xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp));
1113 xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK); 1157 xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK);
1114 *dnew = temp; 1158 *dnew = temp;
1159 /* DELTA: One in-core extent is split in two. */
1160 temp = PREV.br_startoff;
1161 temp2 = PREV.br_blockcount;
1115 break; 1162 break;
1116 1163
1117 case 0: 1164 case 0:
@@ -1194,6 +1241,9 @@ xfs_bmap_add_extent_delay_real(
1194 xfs_bmap_trace_post_update(fname, "0", ip, idx + 2, 1241 xfs_bmap_trace_post_update(fname, "0", ip, idx + 2,
1195 XFS_DATA_FORK); 1242 XFS_DATA_FORK);
1196 *dnew = temp + temp2; 1243 *dnew = temp + temp2;
1244 /* DELTA: One in-core extent is split in three. */
1245 temp = PREV.br_startoff;
1246 temp2 = PREV.br_blockcount;
1197 break; 1247 break;
1198 1248
1199 case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG): 1249 case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
@@ -1209,6 +1259,13 @@ xfs_bmap_add_extent_delay_real(
1209 ASSERT(0); 1259 ASSERT(0);
1210 } 1260 }
1211 *curp = cur; 1261 *curp = cur;
1262 if (delta) {
1263 temp2 += temp;
1264 if (delta->xed_startoff > temp)
1265 delta->xed_startoff = temp;
1266 if (delta->xed_blockcount < temp2)
1267 delta->xed_blockcount = temp2;
1268 }
1212done: 1269done:
1213 *logflagsp = rval; 1270 *logflagsp = rval;
1214 return error; 1271 return error;
@@ -1235,7 +1292,8 @@ xfs_bmap_add_extent_unwritten_real(
1235 xfs_extnum_t idx, /* extent number to update/insert */ 1292 xfs_extnum_t idx, /* extent number to update/insert */
1236 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 1293 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
1237 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 1294 xfs_bmbt_irec_t *new, /* new data to add to file extents */
1238 int *logflagsp) /* inode logging flags */ 1295 int *logflagsp, /* inode logging flags */
1296 xfs_extdelta_t *delta) /* Change made to incore extents */
1239{ 1297{
1240 xfs_btree_cur_t *cur; /* btree cursor */ 1298 xfs_btree_cur_t *cur; /* btree cursor */
1241 xfs_bmbt_rec_t *ep; /* extent entry for idx */ 1299 xfs_bmbt_rec_t *ep; /* extent entry for idx */
@@ -1252,6 +1310,8 @@ xfs_bmap_add_extent_unwritten_real(
1252 /* left is 0, right is 1, prev is 2 */ 1310 /* left is 0, right is 1, prev is 2 */
1253 int rval=0; /* return value (logging flags) */ 1311 int rval=0; /* return value (logging flags) */
1254 int state = 0;/* state bits, accessed thru macros */ 1312 int state = 0;/* state bits, accessed thru macros */
1313 xfs_filblks_t temp=0;
1314 xfs_filblks_t temp2=0;
1255 enum { /* bit number definitions for state */ 1315 enum { /* bit number definitions for state */
1256 LEFT_CONTIG, RIGHT_CONTIG, 1316 LEFT_CONTIG, RIGHT_CONTIG,
1257 LEFT_FILLING, RIGHT_FILLING, 1317 LEFT_FILLING, RIGHT_FILLING,
@@ -1380,6 +1440,11 @@ xfs_bmap_add_extent_unwritten_real(
1380 RIGHT.br_blockcount, LEFT.br_state))) 1440 RIGHT.br_blockcount, LEFT.br_state)))
1381 goto done; 1441 goto done;
1382 } 1442 }
1443 /* DELTA: Three in-core extents are replaced by one. */
1444 temp = LEFT.br_startoff;
1445 temp2 = LEFT.br_blockcount +
1446 PREV.br_blockcount +
1447 RIGHT.br_blockcount;
1383 break; 1448 break;
1384 1449
1385 case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG): 1450 case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG):
@@ -1419,6 +1484,10 @@ xfs_bmap_add_extent_unwritten_real(
1419 LEFT.br_state))) 1484 LEFT.br_state)))
1420 goto done; 1485 goto done;
1421 } 1486 }
1487 /* DELTA: Two in-core extents are replaced by one. */
1488 temp = LEFT.br_startoff;
1489 temp2 = LEFT.br_blockcount +
1490 PREV.br_blockcount;
1422 break; 1491 break;
1423 1492
1424 case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG): 1493 case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG):
@@ -1459,6 +1528,10 @@ xfs_bmap_add_extent_unwritten_real(
1459 newext))) 1528 newext)))
1460 goto done; 1529 goto done;
1461 } 1530 }
1531 /* DELTA: Two in-core extents are replaced by one. */
1532 temp = PREV.br_startoff;
1533 temp2 = PREV.br_blockcount +
1534 RIGHT.br_blockcount;
1462 break; 1535 break;
1463 1536
1464 case MASK2(LEFT_FILLING, RIGHT_FILLING): 1537 case MASK2(LEFT_FILLING, RIGHT_FILLING):
@@ -1487,6 +1560,9 @@ xfs_bmap_add_extent_unwritten_real(
1487 newext))) 1560 newext)))
1488 goto done; 1561 goto done;
1489 } 1562 }
1563 /* DELTA: The in-core extent described by new changed type. */
1564 temp = new->br_startoff;
1565 temp2 = new->br_blockcount;
1490 break; 1566 break;
1491 1567
1492 case MASK2(LEFT_FILLING, LEFT_CONTIG): 1568 case MASK2(LEFT_FILLING, LEFT_CONTIG):
@@ -1534,6 +1610,10 @@ xfs_bmap_add_extent_unwritten_real(
1534 LEFT.br_state)) 1610 LEFT.br_state))
1535 goto done; 1611 goto done;
1536 } 1612 }
1613 /* DELTA: The boundary between two in-core extents moved. */
1614 temp = LEFT.br_startoff;
1615 temp2 = LEFT.br_blockcount +
1616 PREV.br_blockcount;
1537 break; 1617 break;
1538 1618
1539 case MASK(LEFT_FILLING): 1619 case MASK(LEFT_FILLING):
@@ -1574,6 +1654,9 @@ xfs_bmap_add_extent_unwritten_real(
1574 goto done; 1654 goto done;
1575 ASSERT(i == 1); 1655 ASSERT(i == 1);
1576 } 1656 }
1657 /* DELTA: One in-core extent is split in two. */
1658 temp = PREV.br_startoff;
1659 temp2 = PREV.br_blockcount;
1577 break; 1660 break;
1578 1661
1579 case MASK2(RIGHT_FILLING, RIGHT_CONTIG): 1662 case MASK2(RIGHT_FILLING, RIGHT_CONTIG):
@@ -1617,6 +1700,10 @@ xfs_bmap_add_extent_unwritten_real(
1617 newext))) 1700 newext)))
1618 goto done; 1701 goto done;
1619 } 1702 }
1703 /* DELTA: The boundary between two in-core extents moved. */
1704 temp = PREV.br_startoff;
1705 temp2 = PREV.br_blockcount +
1706 RIGHT.br_blockcount;
1620 break; 1707 break;
1621 1708
1622 case MASK(RIGHT_FILLING): 1709 case MASK(RIGHT_FILLING):
@@ -1657,6 +1744,9 @@ xfs_bmap_add_extent_unwritten_real(
1657 goto done; 1744 goto done;
1658 ASSERT(i == 1); 1745 ASSERT(i == 1);
1659 } 1746 }
1747 /* DELTA: One in-core extent is split in two. */
1748 temp = PREV.br_startoff;
1749 temp2 = PREV.br_blockcount;
1660 break; 1750 break;
1661 1751
1662 case 0: 1752 case 0:
@@ -1710,6 +1800,9 @@ xfs_bmap_add_extent_unwritten_real(
1710 goto done; 1800 goto done;
1711 ASSERT(i == 1); 1801 ASSERT(i == 1);
1712 } 1802 }
1803 /* DELTA: One in-core extent is split in three. */
1804 temp = PREV.br_startoff;
1805 temp2 = PREV.br_blockcount;
1713 break; 1806 break;
1714 1807
1715 case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG): 1808 case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
@@ -1725,6 +1818,13 @@ xfs_bmap_add_extent_unwritten_real(
1725 ASSERT(0); 1818 ASSERT(0);
1726 } 1819 }
1727 *curp = cur; 1820 *curp = cur;
1821 if (delta) {
1822 temp2 += temp;
1823 if (delta->xed_startoff > temp)
1824 delta->xed_startoff = temp;
1825 if (delta->xed_blockcount < temp2)
1826 delta->xed_blockcount = temp2;
1827 }
1728done: 1828done:
1729 *logflagsp = rval; 1829 *logflagsp = rval;
1730 return error; 1830 return error;
@@ -1753,6 +1853,7 @@ xfs_bmap_add_extent_hole_delay(
1753 xfs_btree_cur_t *cur, /* if null, not a btree */ 1853 xfs_btree_cur_t *cur, /* if null, not a btree */
1754 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 1854 xfs_bmbt_irec_t *new, /* new data to add to file extents */
1755 int *logflagsp, /* inode logging flags */ 1855 int *logflagsp, /* inode logging flags */
1856 xfs_extdelta_t *delta, /* Change made to incore extents */
1756 int rsvd) /* OK to allocate reserved blocks */ 1857 int rsvd) /* OK to allocate reserved blocks */
1757{ 1858{
1758 xfs_bmbt_rec_t *ep; /* extent record for idx */ 1859 xfs_bmbt_rec_t *ep; /* extent record for idx */
@@ -1765,7 +1866,8 @@ xfs_bmap_add_extent_hole_delay(
1765 xfs_filblks_t oldlen=0; /* old indirect size */ 1866 xfs_filblks_t oldlen=0; /* old indirect size */
1766 xfs_bmbt_irec_t right; /* right neighbor extent entry */ 1867 xfs_bmbt_irec_t right; /* right neighbor extent entry */
1767 int state; /* state bits, accessed thru macros */ 1868 int state; /* state bits, accessed thru macros */
1768 xfs_filblks_t temp; /* temp for indirect calculations */ 1869 xfs_filblks_t temp=0; /* temp for indirect calculations */
1870 xfs_filblks_t temp2=0;
1769 enum { /* bit number definitions for state */ 1871 enum { /* bit number definitions for state */
1770 LEFT_CONTIG, RIGHT_CONTIG, 1872 LEFT_CONTIG, RIGHT_CONTIG,
1771 LEFT_DELAY, RIGHT_DELAY, 1873 LEFT_DELAY, RIGHT_DELAY,
@@ -1844,6 +1946,9 @@ xfs_bmap_add_extent_hole_delay(
1844 XFS_DATA_FORK); 1946 XFS_DATA_FORK);
1845 xfs_iext_remove(ifp, idx, 1); 1947 xfs_iext_remove(ifp, idx, 1);
1846 ip->i_df.if_lastex = idx - 1; 1948 ip->i_df.if_lastex = idx - 1;
1949 /* DELTA: Two in-core extents were replaced by one. */
1950 temp2 = temp;
1951 temp = left.br_startoff;
1847 break; 1952 break;
1848 1953
1849 case MASK(LEFT_CONTIG): 1954 case MASK(LEFT_CONTIG):
@@ -1864,6 +1969,9 @@ xfs_bmap_add_extent_hole_delay(
1864 xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, 1969 xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1,
1865 XFS_DATA_FORK); 1970 XFS_DATA_FORK);
1866 ip->i_df.if_lastex = idx - 1; 1971 ip->i_df.if_lastex = idx - 1;
1972 /* DELTA: One in-core extent grew into a hole. */
1973 temp2 = temp;
1974 temp = left.br_startoff;
1867 break; 1975 break;
1868 1976
1869 case MASK(RIGHT_CONTIG): 1977 case MASK(RIGHT_CONTIG):
@@ -1881,6 +1989,9 @@ xfs_bmap_add_extent_hole_delay(
1881 NULLSTARTBLOCK((int)newlen), temp, right.br_state); 1989 NULLSTARTBLOCK((int)newlen), temp, right.br_state);
1882 xfs_bmap_trace_post_update(fname, "RC", ip, idx, XFS_DATA_FORK); 1990 xfs_bmap_trace_post_update(fname, "RC", ip, idx, XFS_DATA_FORK);
1883 ip->i_df.if_lastex = idx; 1991 ip->i_df.if_lastex = idx;
1992 /* DELTA: One in-core extent grew into a hole. */
1993 temp2 = temp;
1994 temp = new->br_startoff;
1884 break; 1995 break;
1885 1996
1886 case 0: 1997 case 0:
@@ -1894,6 +2005,9 @@ xfs_bmap_add_extent_hole_delay(
1894 XFS_DATA_FORK); 2005 XFS_DATA_FORK);
1895 xfs_iext_insert(ifp, idx, 1, new); 2006 xfs_iext_insert(ifp, idx, 1, new);
1896 ip->i_df.if_lastex = idx; 2007 ip->i_df.if_lastex = idx;
2008 /* DELTA: A new in-core extent was added in a hole. */
2009 temp2 = new->br_blockcount;
2010 temp = new->br_startoff;
1897 break; 2011 break;
1898 } 2012 }
1899 if (oldlen != newlen) { 2013 if (oldlen != newlen) {
@@ -1904,6 +2018,13 @@ xfs_bmap_add_extent_hole_delay(
1904 * Nothing to do for disk quota accounting here. 2018 * Nothing to do for disk quota accounting here.
1905 */ 2019 */
1906 } 2020 }
2021 if (delta) {
2022 temp2 += temp;
2023 if (delta->xed_startoff > temp)
2024 delta->xed_startoff = temp;
2025 if (delta->xed_blockcount < temp2)
2026 delta->xed_blockcount = temp2;
2027 }
1907 *logflagsp = 0; 2028 *logflagsp = 0;
1908 return 0; 2029 return 0;
1909#undef MASK 2030#undef MASK
@@ -1925,6 +2046,7 @@ xfs_bmap_add_extent_hole_real(
1925 xfs_btree_cur_t *cur, /* if null, not a btree */ 2046 xfs_btree_cur_t *cur, /* if null, not a btree */
1926 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 2047 xfs_bmbt_irec_t *new, /* new data to add to file extents */
1927 int *logflagsp, /* inode logging flags */ 2048 int *logflagsp, /* inode logging flags */
2049 xfs_extdelta_t *delta, /* Change made to incore extents */
1928 int whichfork) /* data or attr fork */ 2050 int whichfork) /* data or attr fork */
1929{ 2051{
1930 xfs_bmbt_rec_t *ep; /* pointer to extent entry ins. point */ 2052 xfs_bmbt_rec_t *ep; /* pointer to extent entry ins. point */
@@ -1936,7 +2058,10 @@ xfs_bmap_add_extent_hole_real(
1936 xfs_ifork_t *ifp; /* inode fork pointer */ 2058 xfs_ifork_t *ifp; /* inode fork pointer */
1937 xfs_bmbt_irec_t left; /* left neighbor extent entry */ 2059 xfs_bmbt_irec_t left; /* left neighbor extent entry */
1938 xfs_bmbt_irec_t right; /* right neighbor extent entry */ 2060 xfs_bmbt_irec_t right; /* right neighbor extent entry */
2061 int rval=0; /* return value (logging flags) */
1939 int state; /* state bits, accessed thru macros */ 2062 int state; /* state bits, accessed thru macros */
2063 xfs_filblks_t temp=0;
2064 xfs_filblks_t temp2=0;
1940 enum { /* bit number definitions for state */ 2065 enum { /* bit number definitions for state */
1941 LEFT_CONTIG, RIGHT_CONTIG, 2066 LEFT_CONTIG, RIGHT_CONTIG,
1942 LEFT_DELAY, RIGHT_DELAY, 2067 LEFT_DELAY, RIGHT_DELAY,
@@ -1993,6 +2118,7 @@ xfs_bmap_add_extent_hole_real(
1993 left.br_blockcount + new->br_blockcount + 2118 left.br_blockcount + new->br_blockcount +
1994 right.br_blockcount <= MAXEXTLEN)); 2119 right.br_blockcount <= MAXEXTLEN));
1995 2120
2121 error = 0;
1996 /* 2122 /*
1997 * Select which case we're in here, and implement it. 2123 * Select which case we're in here, and implement it.
1998 */ 2124 */
@@ -2018,25 +2144,35 @@ xfs_bmap_add_extent_hole_real(
2018 XFS_IFORK_NEXT_SET(ip, whichfork, 2144 XFS_IFORK_NEXT_SET(ip, whichfork,
2019 XFS_IFORK_NEXTENTS(ip, whichfork) - 1); 2145 XFS_IFORK_NEXTENTS(ip, whichfork) - 1);
2020 if (cur == NULL) { 2146 if (cur == NULL) {
2021 *logflagsp = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); 2147 rval = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
2022 return 0; 2148 } else {
2149 rval = XFS_ILOG_CORE;
2150 if ((error = xfs_bmbt_lookup_eq(cur,
2151 right.br_startoff,
2152 right.br_startblock,
2153 right.br_blockcount, &i)))
2154 goto done;
2155 ASSERT(i == 1);
2156 if ((error = xfs_bmbt_delete(cur, &i)))
2157 goto done;
2158 ASSERT(i == 1);
2159 if ((error = xfs_bmbt_decrement(cur, 0, &i)))
2160 goto done;
2161 ASSERT(i == 1);
2162 if ((error = xfs_bmbt_update(cur, left.br_startoff,
2163 left.br_startblock,
2164 left.br_blockcount +
2165 new->br_blockcount +
2166 right.br_blockcount,
2167 left.br_state)))
2168 goto done;
2023 } 2169 }
2024 *logflagsp = XFS_ILOG_CORE; 2170 /* DELTA: Two in-core extents were replaced by one. */
2025 if ((error = xfs_bmbt_lookup_eq(cur, right.br_startoff, 2171 temp = left.br_startoff;
2026 right.br_startblock, right.br_blockcount, &i))) 2172 temp2 = left.br_blockcount +
2027 return error; 2173 new->br_blockcount +
2028 ASSERT(i == 1); 2174 right.br_blockcount;
2029 if ((error = xfs_bmbt_delete(cur, &i))) 2175 break;
2030 return error;
2031 ASSERT(i == 1);
2032 if ((error = xfs_bmbt_decrement(cur, 0, &i)))
2033 return error;
2034 ASSERT(i == 1);
2035 error = xfs_bmbt_update(cur, left.br_startoff,
2036 left.br_startblock,
2037 left.br_blockcount + new->br_blockcount +
2038 right.br_blockcount, left.br_state);
2039 return error;
2040 2176
2041 case MASK(LEFT_CONTIG): 2177 case MASK(LEFT_CONTIG):
2042 /* 2178 /*
@@ -2050,19 +2186,27 @@ xfs_bmap_add_extent_hole_real(
2050 xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, whichfork); 2186 xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, whichfork);
2051 ifp->if_lastex = idx - 1; 2187 ifp->if_lastex = idx - 1;
2052 if (cur == NULL) { 2188 if (cur == NULL) {
2053 *logflagsp = XFS_ILOG_FEXT(whichfork); 2189 rval = XFS_ILOG_FEXT(whichfork);
2054 return 0; 2190 } else {
2191 rval = 0;
2192 if ((error = xfs_bmbt_lookup_eq(cur,
2193 left.br_startoff,
2194 left.br_startblock,
2195 left.br_blockcount, &i)))
2196 goto done;
2197 ASSERT(i == 1);
2198 if ((error = xfs_bmbt_update(cur, left.br_startoff,
2199 left.br_startblock,
2200 left.br_blockcount +
2201 new->br_blockcount,
2202 left.br_state)))
2203 goto done;
2055 } 2204 }
2056 *logflagsp = 0; 2205 /* DELTA: One in-core extent grew. */
2057 if ((error = xfs_bmbt_lookup_eq(cur, left.br_startoff, 2206 temp = left.br_startoff;
2058 left.br_startblock, left.br_blockcount, &i))) 2207 temp2 = left.br_blockcount +
2059 return error; 2208 new->br_blockcount;
2060 ASSERT(i == 1); 2209 break;
2061 error = xfs_bmbt_update(cur, left.br_startoff,
2062 left.br_startblock,
2063 left.br_blockcount + new->br_blockcount,
2064 left.br_state);
2065 return error;
2066 2210
2067 case MASK(RIGHT_CONTIG): 2211 case MASK(RIGHT_CONTIG):
2068 /* 2212 /*
@@ -2077,19 +2221,27 @@ xfs_bmap_add_extent_hole_real(
2077 xfs_bmap_trace_post_update(fname, "RC", ip, idx, whichfork); 2221 xfs_bmap_trace_post_update(fname, "RC", ip, idx, whichfork);
2078 ifp->if_lastex = idx; 2222 ifp->if_lastex = idx;
2079 if (cur == NULL) { 2223 if (cur == NULL) {
2080 *logflagsp = XFS_ILOG_FEXT(whichfork); 2224 rval = XFS_ILOG_FEXT(whichfork);
2081 return 0; 2225 } else {
2226 rval = 0;
2227 if ((error = xfs_bmbt_lookup_eq(cur,
2228 right.br_startoff,
2229 right.br_startblock,
2230 right.br_blockcount, &i)))
2231 goto done;
2232 ASSERT(i == 1);
2233 if ((error = xfs_bmbt_update(cur, new->br_startoff,
2234 new->br_startblock,
2235 new->br_blockcount +
2236 right.br_blockcount,
2237 right.br_state)))
2238 goto done;
2082 } 2239 }
2083 *logflagsp = 0; 2240 /* DELTA: One in-core extent grew. */
2084 if ((error = xfs_bmbt_lookup_eq(cur, right.br_startoff, 2241 temp = new->br_startoff;
2085 right.br_startblock, right.br_blockcount, &i))) 2242 temp2 = new->br_blockcount +
2086 return error; 2243 right.br_blockcount;
2087 ASSERT(i == 1); 2244 break;
2088 error = xfs_bmbt_update(cur, new->br_startoff,
2089 new->br_startblock,
2090 new->br_blockcount + right.br_blockcount,
2091 right.br_state);
2092 return error;
2093 2245
2094 case 0: 2246 case 0:
2095 /* 2247 /*
@@ -2104,29 +2256,41 @@ xfs_bmap_add_extent_hole_real(
2104 XFS_IFORK_NEXT_SET(ip, whichfork, 2256 XFS_IFORK_NEXT_SET(ip, whichfork,
2105 XFS_IFORK_NEXTENTS(ip, whichfork) + 1); 2257 XFS_IFORK_NEXTENTS(ip, whichfork) + 1);
2106 if (cur == NULL) { 2258 if (cur == NULL) {
2107 *logflagsp = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); 2259 rval = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
2108 return 0; 2260 } else {
2261 rval = XFS_ILOG_CORE;
2262 if ((error = xfs_bmbt_lookup_eq(cur,
2263 new->br_startoff,
2264 new->br_startblock,
2265 new->br_blockcount, &i)))
2266 goto done;
2267 ASSERT(i == 0);
2268 cur->bc_rec.b.br_state = new->br_state;
2269 if ((error = xfs_bmbt_insert(cur, &i)))
2270 goto done;
2271 ASSERT(i == 1);
2109 } 2272 }
2110 *logflagsp = XFS_ILOG_CORE; 2273 /* DELTA: A new extent was added in a hole. */
2111 if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, 2274 temp = new->br_startoff;
2112 new->br_startblock, new->br_blockcount, &i))) 2275 temp2 = new->br_blockcount;
2113 return error; 2276 break;
2114 ASSERT(i == 0);
2115 cur->bc_rec.b.br_state = new->br_state;
2116 if ((error = xfs_bmbt_insert(cur, &i)))
2117 return error;
2118 ASSERT(i == 1);
2119 return 0;
2120 } 2277 }
2278 if (delta) {
2279 temp2 += temp;
2280 if (delta->xed_startoff > temp)
2281 delta->xed_startoff = temp;
2282 if (delta->xed_blockcount < temp2)
2283 delta->xed_blockcount = temp2;
2284 }
2285done:
2286 *logflagsp = rval;
2287 return error;
2121#undef MASK 2288#undef MASK
2122#undef MASK2 2289#undef MASK2
2123#undef STATE_SET 2290#undef STATE_SET
2124#undef STATE_TEST 2291#undef STATE_TEST
2125#undef STATE_SET_TEST 2292#undef STATE_SET_TEST
2126#undef SWITCH_STATE 2293#undef SWITCH_STATE
2127 /* NOTREACHED */
2128 ASSERT(0);
2129 return 0; /* keep gcc quite */
2130} 2294}
2131 2295
2132/* 2296/*
@@ -2885,6 +3049,7 @@ xfs_bmap_del_extent(
2885 xfs_btree_cur_t *cur, /* if null, not a btree */ 3049 xfs_btree_cur_t *cur, /* if null, not a btree */
2886 xfs_bmbt_irec_t *del, /* data to remove from extents */ 3050 xfs_bmbt_irec_t *del, /* data to remove from extents */
2887 int *logflagsp, /* inode logging flags */ 3051 int *logflagsp, /* inode logging flags */
3052 xfs_extdelta_t *delta, /* Change made to incore extents */
2888 int whichfork, /* data or attr fork */ 3053 int whichfork, /* data or attr fork */
2889 int rsvd) /* OK to allocate reserved blocks */ 3054 int rsvd) /* OK to allocate reserved blocks */
2890{ 3055{
@@ -3193,6 +3358,14 @@ xfs_bmap_del_extent(
3193 if (da_old > da_new) 3358 if (da_old > da_new)
3194 xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, (int)(da_old - da_new), 3359 xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, (int)(da_old - da_new),
3195 rsvd); 3360 rsvd);
3361 if (delta) {
3362 /* DELTA: report the original extent. */
3363 if (delta->xed_startoff > got.br_startoff)
3364 delta->xed_startoff = got.br_startoff;
3365 if (delta->xed_blockcount < got.br_startoff+got.br_blockcount)
3366 delta->xed_blockcount = got.br_startoff +
3367 got.br_blockcount;
3368 }
3196done: 3369done:
3197 *logflagsp = flags; 3370 *logflagsp = flags;
3198 return error; 3371 return error;
@@ -3753,7 +3926,7 @@ xfs_bunmap_trace(
3753 if (ip->i_rwtrace == NULL) 3926 if (ip->i_rwtrace == NULL)
3754 return; 3927 return;
3755 ktrace_enter(ip->i_rwtrace, 3928 ktrace_enter(ip->i_rwtrace,
3756 (void *)(__psint_t)XFS_BUNMAPI, 3929 (void *)(__psint_t)XFS_BUNMAP,
3757 (void *)ip, 3930 (void *)ip,
3758 (void *)(__psint_t)((ip->i_d.di_size >> 32) & 0xffffffff), 3931 (void *)(__psint_t)((ip->i_d.di_size >> 32) & 0xffffffff),
3759 (void *)(__psint_t)(ip->i_d.di_size & 0xffffffff), 3932 (void *)(__psint_t)(ip->i_d.di_size & 0xffffffff),
@@ -4538,7 +4711,8 @@ xfs_bmapi(
4538 xfs_extlen_t total, /* total blocks needed */ 4711 xfs_extlen_t total, /* total blocks needed */
4539 xfs_bmbt_irec_t *mval, /* output: map values */ 4712 xfs_bmbt_irec_t *mval, /* output: map values */
4540 int *nmap, /* i/o: mval size/count */ 4713 int *nmap, /* i/o: mval size/count */
4541 xfs_bmap_free_t *flist) /* i/o: list extents to free */ 4714 xfs_bmap_free_t *flist, /* i/o: list extents to free */
4715 xfs_extdelta_t *delta) /* o: change made to incore extents */
4542{ 4716{
4543 xfs_fsblock_t abno; /* allocated block number */ 4717 xfs_fsblock_t abno; /* allocated block number */
4544 xfs_extlen_t alen; /* allocated extent length */ 4718 xfs_extlen_t alen; /* allocated extent length */
@@ -4650,6 +4824,10 @@ xfs_bmapi(
4650 end = bno + len; 4824 end = bno + len;
4651 obno = bno; 4825 obno = bno;
4652 bma.ip = NULL; 4826 bma.ip = NULL;
4827 if (delta) {
4828 delta->xed_startoff = NULLFILEOFF;
4829 delta->xed_blockcount = 0;
4830 }
4653 while (bno < end && n < *nmap) { 4831 while (bno < end && n < *nmap) {
4654 /* 4832 /*
4655 * Reading past eof, act as though there's a hole 4833 * Reading past eof, act as though there's a hole
@@ -4886,8 +5064,8 @@ xfs_bmapi(
4886 got.br_state = XFS_EXT_UNWRITTEN; 5064 got.br_state = XFS_EXT_UNWRITTEN;
4887 } 5065 }
4888 error = xfs_bmap_add_extent(ip, lastx, &cur, &got, 5066 error = xfs_bmap_add_extent(ip, lastx, &cur, &got,
4889 firstblock, flist, &tmp_logflags, whichfork, 5067 firstblock, flist, &tmp_logflags, delta,
4890 (flags & XFS_BMAPI_RSVBLOCKS)); 5068 whichfork, (flags & XFS_BMAPI_RSVBLOCKS));
4891 logflags |= tmp_logflags; 5069 logflags |= tmp_logflags;
4892 if (error) 5070 if (error)
4893 goto error0; 5071 goto error0;
@@ -4983,8 +5161,8 @@ xfs_bmapi(
4983 } 5161 }
4984 mval->br_state = XFS_EXT_NORM; 5162 mval->br_state = XFS_EXT_NORM;
4985 error = xfs_bmap_add_extent(ip, lastx, &cur, mval, 5163 error = xfs_bmap_add_extent(ip, lastx, &cur, mval,
4986 firstblock, flist, &tmp_logflags, whichfork, 5164 firstblock, flist, &tmp_logflags, delta,
4987 (flags & XFS_BMAPI_RSVBLOCKS)); 5165 whichfork, (flags & XFS_BMAPI_RSVBLOCKS));
4988 logflags |= tmp_logflags; 5166 logflags |= tmp_logflags;
4989 if (error) 5167 if (error)
4990 goto error0; 5168 goto error0;
@@ -5073,7 +5251,14 @@ xfs_bmapi(
5073 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE || 5251 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE ||
5074 XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max); 5252 XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max);
5075 error = 0; 5253 error = 0;
5076 5254 if (delta && delta->xed_startoff != NULLFILEOFF) {
5255 /* A change was actually made.
5256 * Note that delta->xed_blockount is an offset at this
5257 * point and needs to be converted to a block count.
5258 */
5259 ASSERT(delta->xed_blockcount > delta->xed_startoff);
5260 delta->xed_blockcount -= delta->xed_startoff;
5261 }
5077error0: 5262error0:
5078 /* 5263 /*
5079 * Log everything. Do this after conversion, there's no point in 5264 * Log everything. Do this after conversion, there's no point in
@@ -5185,6 +5370,8 @@ xfs_bunmapi(
5185 xfs_fsblock_t *firstblock, /* first allocated block 5370 xfs_fsblock_t *firstblock, /* first allocated block
5186 controls a.g. for allocs */ 5371 controls a.g. for allocs */
5187 xfs_bmap_free_t *flist, /* i/o: list extents to free */ 5372 xfs_bmap_free_t *flist, /* i/o: list extents to free */
5373 xfs_extdelta_t *delta, /* o: change made to incore
5374 extents */
5188 int *done) /* set if not done yet */ 5375 int *done) /* set if not done yet */
5189{ 5376{
5190 xfs_btree_cur_t *cur; /* bmap btree cursor */ 5377 xfs_btree_cur_t *cur; /* bmap btree cursor */
@@ -5242,6 +5429,10 @@ xfs_bunmapi(
5242 bno = start + len - 1; 5429 bno = start + len - 1;
5243 ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, 5430 ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got,
5244 &prev); 5431 &prev);
5432 if (delta) {
5433 delta->xed_startoff = NULLFILEOFF;
5434 delta->xed_blockcount = 0;
5435 }
5245 /* 5436 /*
5246 * Check to see if the given block number is past the end of the 5437 * Check to see if the given block number is past the end of the
5247 * file, back up to the last block if so... 5438 * file, back up to the last block if so...
@@ -5340,7 +5531,8 @@ xfs_bunmapi(
5340 } 5531 }
5341 del.br_state = XFS_EXT_UNWRITTEN; 5532 del.br_state = XFS_EXT_UNWRITTEN;
5342 error = xfs_bmap_add_extent(ip, lastx, &cur, &del, 5533 error = xfs_bmap_add_extent(ip, lastx, &cur, &del,
5343 firstblock, flist, &logflags, XFS_DATA_FORK, 0); 5534 firstblock, flist, &logflags, delta,
5535 XFS_DATA_FORK, 0);
5344 if (error) 5536 if (error)
5345 goto error0; 5537 goto error0;
5346 goto nodelete; 5538 goto nodelete;
@@ -5394,7 +5586,7 @@ xfs_bunmapi(
5394 prev.br_state = XFS_EXT_UNWRITTEN; 5586 prev.br_state = XFS_EXT_UNWRITTEN;
5395 error = xfs_bmap_add_extent(ip, lastx - 1, &cur, 5587 error = xfs_bmap_add_extent(ip, lastx - 1, &cur,
5396 &prev, firstblock, flist, &logflags, 5588 &prev, firstblock, flist, &logflags,
5397 XFS_DATA_FORK, 0); 5589 delta, XFS_DATA_FORK, 0);
5398 if (error) 5590 if (error)
5399 goto error0; 5591 goto error0;
5400 goto nodelete; 5592 goto nodelete;
@@ -5403,7 +5595,7 @@ xfs_bunmapi(
5403 del.br_state = XFS_EXT_UNWRITTEN; 5595 del.br_state = XFS_EXT_UNWRITTEN;
5404 error = xfs_bmap_add_extent(ip, lastx, &cur, 5596 error = xfs_bmap_add_extent(ip, lastx, &cur,
5405 &del, firstblock, flist, &logflags, 5597 &del, firstblock, flist, &logflags,
5406 XFS_DATA_FORK, 0); 5598 delta, XFS_DATA_FORK, 0);
5407 if (error) 5599 if (error)
5408 goto error0; 5600 goto error0;
5409 goto nodelete; 5601 goto nodelete;
@@ -5456,7 +5648,7 @@ xfs_bunmapi(
5456 goto error0; 5648 goto error0;
5457 } 5649 }
5458 error = xfs_bmap_del_extent(ip, tp, lastx, flist, cur, &del, 5650 error = xfs_bmap_del_extent(ip, tp, lastx, flist, cur, &del,
5459 &tmp_logflags, whichfork, rsvd); 5651 &tmp_logflags, delta, whichfork, rsvd);
5460 logflags |= tmp_logflags; 5652 logflags |= tmp_logflags;
5461 if (error) 5653 if (error)
5462 goto error0; 5654 goto error0;
@@ -5513,6 +5705,14 @@ nodelete:
5513 ASSERT(ifp->if_ext_max == 5705 ASSERT(ifp->if_ext_max ==
5514 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); 5706 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
5515 error = 0; 5707 error = 0;
5708 if (delta && delta->xed_startoff != NULLFILEOFF) {
5709 /* A change was actually made.
5710 * Note that delta->xed_blockount is an offset at this
5711 * point and needs to be converted to a block count.
5712 */
5713 ASSERT(delta->xed_blockcount > delta->xed_startoff);
5714 delta->xed_blockcount -= delta->xed_startoff;
5715 }
5516error0: 5716error0:
5517 /* 5717 /*
5518 * Log everything. Do this after conversion, there's no point in 5718 * Log everything. Do this after conversion, there's no point in
@@ -5689,7 +5889,8 @@ xfs_getbmap(
5689 nmap = (nexleft > subnex) ? subnex : nexleft; 5889 nmap = (nexleft > subnex) ? subnex : nexleft;
5690 error = xfs_bmapi(NULL, ip, XFS_BB_TO_FSBT(mp, bmv->bmv_offset), 5890 error = xfs_bmapi(NULL, ip, XFS_BB_TO_FSBT(mp, bmv->bmv_offset),
5691 XFS_BB_TO_FSB(mp, bmv->bmv_length), 5891 XFS_BB_TO_FSB(mp, bmv->bmv_length),
5692 bmapi_flags, NULL, 0, map, &nmap, NULL); 5892 bmapi_flags, NULL, 0, map, &nmap,
5893 NULL, NULL);
5693 if (error) 5894 if (error)
5694 goto unlock_and_return; 5895 goto unlock_and_return;
5695 ASSERT(nmap <= subnex); 5896 ASSERT(nmap <= subnex);
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h
index 8e0d73d9ccc4..80e93409b78d 100644
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -26,6 +26,20 @@ struct xfs_mount;
26struct xfs_trans; 26struct xfs_trans;
27 27
28/* 28/*
29 * DELTA: describe a change to the in-core extent list.
30 *
31 * Internally the use of xed_blockount is somewhat funky.
32 * xed_blockcount contains an offset much of the time because this
33 * makes merging changes easier. (xfs_fileoff_t and xfs_filblks_t are
34 * the same underlying type).
35 */
36typedef struct xfs_extdelta
37{
38 xfs_fileoff_t xed_startoff; /* offset of range */
39 xfs_filblks_t xed_blockcount; /* blocks in range */
40} xfs_extdelta_t;
41
42/*
29 * List of extents to be free "later". 43 * List of extents to be free "later".
30 * The list is kept sorted on xbf_startblock. 44 * The list is kept sorted on xbf_startblock.
31 */ 45 */
@@ -275,7 +289,9 @@ xfs_bmapi(
275 xfs_extlen_t total, /* total blocks needed */ 289 xfs_extlen_t total, /* total blocks needed */
276 struct xfs_bmbt_irec *mval, /* output: map values */ 290 struct xfs_bmbt_irec *mval, /* output: map values */
277 int *nmap, /* i/o: mval size/count */ 291 int *nmap, /* i/o: mval size/count */
278 xfs_bmap_free_t *flist); /* i/o: list extents to free */ 292 xfs_bmap_free_t *flist, /* i/o: list extents to free */
293 xfs_extdelta_t *delta); /* o: change made to incore
294 extents */
279 295
280/* 296/*
281 * Map file blocks to filesystem blocks, simple version. 297 * Map file blocks to filesystem blocks, simple version.
@@ -309,6 +325,8 @@ xfs_bunmapi(
309 xfs_fsblock_t *firstblock, /* first allocated block 325 xfs_fsblock_t *firstblock, /* first allocated block
310 controls a.g. for allocs */ 326 controls a.g. for allocs */
311 xfs_bmap_free_t *flist, /* i/o: list extents to free */ 327 xfs_bmap_free_t *flist, /* i/o: list extents to free */
328 xfs_extdelta_t *delta, /* o: change made to incore
329 extents */
312 int *done); /* set if not done yet */ 330 int *done); /* set if not done yet */
313 331
314/* 332/*
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c
index 8988b9051175..47b86f9f69f9 100644
--- a/fs/xfs/xfs_da_btree.c
+++ b/fs/xfs/xfs_da_btree.c
@@ -1655,7 +1655,7 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
1655 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE|XFS_BMAPI_METADATA| 1655 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|
1656 XFS_BMAPI_CONTIG, 1656 XFS_BMAPI_CONTIG,
1657 args->firstblock, args->total, &map, &nmap, 1657 args->firstblock, args->total, &map, &nmap,
1658 args->flist))) { 1658 args->flist, NULL))) {
1659 return error; 1659 return error;
1660 } 1660 }
1661 ASSERT(nmap <= 1); 1661 ASSERT(nmap <= 1);
@@ -1676,7 +1676,8 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
1676 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE| 1676 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE|
1677 XFS_BMAPI_METADATA, 1677 XFS_BMAPI_METADATA,
1678 args->firstblock, args->total, 1678 args->firstblock, args->total,
1679 &mapp[mapi], &nmap, args->flist))) { 1679 &mapp[mapi], &nmap, args->flist,
1680 NULL))) {
1680 kmem_free(mapp, sizeof(*mapp) * count); 1681 kmem_free(mapp, sizeof(*mapp) * count);
1681 return error; 1682 return error;
1682 } 1683 }
@@ -1961,7 +1962,7 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,
1961 */ 1962 */
1962 if ((error = xfs_bunmapi(tp, dp, dead_blkno, count, 1963 if ((error = xfs_bunmapi(tp, dp, dead_blkno, count,
1963 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_METADATA, 1964 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_METADATA,
1964 0, args->firstblock, args->flist, 1965 0, args->firstblock, args->flist, NULL,
1965 &done)) == ENOSPC) { 1966 &done)) == ENOSPC) {
1966 if (w != XFS_DATA_FORK) 1967 if (w != XFS_DATA_FORK)
1967 goto done; 1968 goto done;
@@ -2086,7 +2087,7 @@ xfs_da_do_buf(
2086 nfsb, 2087 nfsb,
2087 XFS_BMAPI_METADATA | 2088 XFS_BMAPI_METADATA |
2088 XFS_BMAPI_AFLAG(whichfork), 2089 XFS_BMAPI_AFLAG(whichfork),
2089 NULL, 0, mapp, &nmap, NULL))) 2090 NULL, 0, mapp, &nmap, NULL, NULL)))
2090 goto exit0; 2091 goto exit0;
2091 } 2092 }
2092 } else { 2093 } else {
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
index 4968a6358e61..99daf8c0f900 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -54,24 +54,14 @@ xfs_swapext(
54 xfs_swapext_t __user *sxu) 54 xfs_swapext_t __user *sxu)
55{ 55{
56 xfs_swapext_t *sxp; 56 xfs_swapext_t *sxp;
57 xfs_inode_t *ip=NULL, *tip=NULL, *ips[2]; 57 xfs_inode_t *ip=NULL, *tip=NULL;
58 xfs_trans_t *tp;
59 xfs_mount_t *mp; 58 xfs_mount_t *mp;
60 xfs_bstat_t *sbp;
61 struct file *fp = NULL, *tfp = NULL; 59 struct file *fp = NULL, *tfp = NULL;
62 vnode_t *vp, *tvp; 60 vnode_t *vp, *tvp;
63 static uint lock_flags = XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL;
64 int ilf_fields, tilf_fields;
65 int error = 0; 61 int error = 0;
66 xfs_ifork_t *tempifp, *ifp, *tifp;
67 __uint64_t tmp;
68 int aforkblks = 0;
69 int taforkblks = 0;
70 char locked = 0;
71 62
72 sxp = kmem_alloc(sizeof(xfs_swapext_t), KM_MAYFAIL); 63 sxp = kmem_alloc(sizeof(xfs_swapext_t), KM_MAYFAIL);
73 tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL); 64 if (!sxp) {
74 if (!sxp || !tempifp) {
75 error = XFS_ERROR(ENOMEM); 65 error = XFS_ERROR(ENOMEM);
76 goto error0; 66 goto error0;
77 } 67 }
@@ -118,14 +108,56 @@ xfs_swapext(
118 108
119 mp = ip->i_mount; 109 mp = ip->i_mount;
120 110
121 sbp = &sxp->sx_stat;
122
123 if (XFS_FORCED_SHUTDOWN(mp)) { 111 if (XFS_FORCED_SHUTDOWN(mp)) {
124 error = XFS_ERROR(EIO); 112 error = XFS_ERROR(EIO);
125 goto error0; 113 goto error0;
126 } 114 }
127 115
128 locked = 1; 116 error = XFS_SWAP_EXTENTS(mp, &ip->i_iocore, &tip->i_iocore, sxp);
117
118 error0:
119 if (fp != NULL)
120 fput(fp);
121 if (tfp != NULL)
122 fput(tfp);
123
124 if (sxp != NULL)
125 kmem_free(sxp, sizeof(xfs_swapext_t));
126
127 return error;
128}
129
130int
131xfs_swap_extents(
132 xfs_inode_t *ip,
133 xfs_inode_t *tip,
134 xfs_swapext_t *sxp)
135{
136 xfs_mount_t *mp;
137 xfs_inode_t *ips[2];
138 xfs_trans_t *tp;
139 xfs_bstat_t *sbp = &sxp->sx_stat;
140 vnode_t *vp, *tvp;
141 xfs_ifork_t *tempifp, *ifp, *tifp;
142 int ilf_fields, tilf_fields;
143 static uint lock_flags = XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL;
144 int error = 0;
145 int aforkblks = 0;
146 int taforkblks = 0;
147 __uint64_t tmp;
148 char locked = 0;
149
150 mp = ip->i_mount;
151
152 tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL);
153 if (!tempifp) {
154 error = XFS_ERROR(ENOMEM);
155 goto error0;
156 }
157
158 sbp = &sxp->sx_stat;
159 vp = XFS_ITOV(ip);
160 tvp = XFS_ITOV(tip);
129 161
130 /* Lock in i_ino order */ 162 /* Lock in i_ino order */
131 if (ip->i_ino < tip->i_ino) { 163 if (ip->i_ino < tip->i_ino) {
@@ -137,6 +169,7 @@ xfs_swapext(
137 } 169 }
138 170
139 xfs_lock_inodes(ips, 2, 0, lock_flags); 171 xfs_lock_inodes(ips, 2, 0, lock_flags);
172 locked = 1;
140 173
141 /* Check permissions */ 174 /* Check permissions */
142 error = xfs_iaccess(ip, S_IWUSR, NULL); 175 error = xfs_iaccess(ip, S_IWUSR, NULL);
@@ -360,16 +393,7 @@ xfs_swapext(
360 xfs_iunlock(ip, lock_flags); 393 xfs_iunlock(ip, lock_flags);
361 xfs_iunlock(tip, lock_flags); 394 xfs_iunlock(tip, lock_flags);
362 } 395 }
363
364 if (fp != NULL)
365 fput(fp);
366 if (tfp != NULL)
367 fput(tfp);
368
369 if (sxp != NULL)
370 kmem_free(sxp, sizeof(xfs_swapext_t));
371 if (tempifp != NULL) 396 if (tempifp != NULL)
372 kmem_free(tempifp, sizeof(xfs_ifork_t)); 397 kmem_free(tempifp, sizeof(xfs_ifork_t));
373
374 return error; 398 return error;
375} 399}
diff --git a/fs/xfs/xfs_dfrag.h b/fs/xfs/xfs_dfrag.h
index f678559abc45..da178205be68 100644
--- a/fs/xfs/xfs_dfrag.h
+++ b/fs/xfs/xfs_dfrag.h
@@ -48,6 +48,9 @@ typedef struct xfs_swapext
48 */ 48 */
49int xfs_swapext(struct xfs_swapext __user *sx); 49int xfs_swapext(struct xfs_swapext __user *sx);
50 50
51int xfs_swap_extents(struct xfs_inode *ip, struct xfs_inode *tip,
52 struct xfs_swapext *sxp);
53
51#endif /* __KERNEL__ */ 54#endif /* __KERNEL__ */
52 55
53#endif /* __XFS_DFRAG_H__ */ 56#endif /* __XFS_DFRAG_H__ */
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c
index 022c8398ab62..80238a2263fa 100644
--- a/fs/xfs/xfs_dir2.c
+++ b/fs/xfs/xfs_dir2.c
@@ -549,7 +549,7 @@ xfs_dir2_grow_inode(
549 if ((error = xfs_bmapi(tp, dp, bno, count, 549 if ((error = xfs_bmapi(tp, dp, bno, count,
550 XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG, 550 XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG,
551 args->firstblock, args->total, &map, &nmap, 551 args->firstblock, args->total, &map, &nmap,
552 args->flist))) { 552 args->flist, NULL))) {
553 return error; 553 return error;
554 } 554 }
555 ASSERT(nmap <= 1); 555 ASSERT(nmap <= 1);
@@ -585,7 +585,8 @@ xfs_dir2_grow_inode(
585 if ((error = xfs_bmapi(tp, dp, b, c, 585 if ((error = xfs_bmapi(tp, dp, b, c,
586 XFS_BMAPI_WRITE|XFS_BMAPI_METADATA, 586 XFS_BMAPI_WRITE|XFS_BMAPI_METADATA,
587 args->firstblock, args->total, 587 args->firstblock, args->total,
588 &mapp[mapi], &nmap, args->flist))) { 588 &mapp[mapi], &nmap, args->flist,
589 NULL))) {
589 kmem_free(mapp, sizeof(*mapp) * count); 590 kmem_free(mapp, sizeof(*mapp) * count);
590 return error; 591 return error;
591 } 592 }
@@ -786,7 +787,7 @@ xfs_dir2_shrink_inode(
786 */ 787 */
787 if ((error = xfs_bunmapi(tp, dp, da, mp->m_dirblkfsbs, 788 if ((error = xfs_bunmapi(tp, dp, da, mp->m_dirblkfsbs,
788 XFS_BMAPI_METADATA, 0, args->firstblock, args->flist, 789 XFS_BMAPI_METADATA, 0, args->firstblock, args->flist,
789 &done))) { 790 NULL, &done))) {
790 /* 791 /*
791 * ENOSPC actually can happen if we're in a removename with 792 * ENOSPC actually can happen if we're in a removename with
792 * no space reservation, and the resulting block removal 793 * no space reservation, and the resulting block removal
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index 0f5e2f2ce6ec..5fe88d546c75 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -884,7 +884,7 @@ xfs_dir2_leaf_getdents(
884 XFS_DIR2_BYTE_TO_DA(mp, 884 XFS_DIR2_BYTE_TO_DA(mp,
885 XFS_DIR2_LEAF_OFFSET) - map_off, 885 XFS_DIR2_LEAF_OFFSET) - map_off,
886 XFS_BMAPI_METADATA, NULL, 0, 886 XFS_BMAPI_METADATA, NULL, 0,
887 &map[map_valid], &nmap, NULL); 887 &map[map_valid], &nmap, NULL, NULL);
888 /* 888 /*
889 * Don't know if we should ignore this or 889 * Don't know if we should ignore this or
890 * try to return an error. 890 * try to return an error.
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 94b60dd03801..020de5637e06 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -1285,7 +1285,7 @@ xfs_isize_check(
1285 (xfs_ufsize_t)XFS_MAXIOFFSET(mp)) - 1285 (xfs_ufsize_t)XFS_MAXIOFFSET(mp)) -
1286 map_first), 1286 map_first),
1287 XFS_BMAPI_ENTIRE, NULL, 0, imaps, &nimaps, 1287 XFS_BMAPI_ENTIRE, NULL, 0, imaps, &nimaps,
1288 NULL)) 1288 NULL, NULL))
1289 return; 1289 return;
1290 ASSERT(nimaps == 1); 1290 ASSERT(nimaps == 1);
1291 ASSERT(imaps[0].br_startblock == HOLESTARTBLOCK); 1291 ASSERT(imaps[0].br_startblock == HOLESTARTBLOCK);
@@ -1666,12 +1666,13 @@ xfs_itruncate_finish(
1666 * runs. 1666 * runs.
1667 */ 1667 */
1668 XFS_BMAP_INIT(&free_list, &first_block); 1668 XFS_BMAP_INIT(&free_list, &first_block);
1669 error = xfs_bunmapi(ntp, ip, first_unmap_block, 1669 error = XFS_BUNMAPI(mp, ntp, &ip->i_iocore,
1670 unmap_len, 1670 first_unmap_block, unmap_len,
1671 XFS_BMAPI_AFLAG(fork) | 1671 XFS_BMAPI_AFLAG(fork) |
1672 (sync ? 0 : XFS_BMAPI_ASYNC), 1672 (sync ? 0 : XFS_BMAPI_ASYNC),
1673 XFS_ITRUNC_MAX_EXTENTS, 1673 XFS_ITRUNC_MAX_EXTENTS,
1674 &first_block, &free_list, &done); 1674 &first_block, &free_list,
1675 NULL, &done);
1675 if (error) { 1676 if (error) {
1676 /* 1677 /*
1677 * If the bunmapi call encounters an error, 1678 * If the bunmapi call encounters an error,
diff --git a/fs/xfs/xfs_iocore.c b/fs/xfs/xfs_iocore.c
index a07815661a8c..d3da194f8b7d 100644
--- a/fs/xfs/xfs_iocore.c
+++ b/fs/xfs/xfs_iocore.c
@@ -26,6 +26,7 @@
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h" 27#include "xfs_dir.h"
28#include "xfs_dir2.h" 28#include "xfs_dir2.h"
29#include "xfs_dfrag.h"
29#include "xfs_dmapi.h" 30#include "xfs_dmapi.h"
30#include "xfs_mount.h" 31#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 32#include "xfs_bmap_btree.h"
@@ -68,6 +69,7 @@ xfs_ioinit(
68xfs_ioops_t xfs_iocore_xfs = { 69xfs_ioops_t xfs_iocore_xfs = {
69 .xfs_ioinit = (xfs_ioinit_t) xfs_ioinit, 70 .xfs_ioinit = (xfs_ioinit_t) xfs_ioinit,
70 .xfs_bmapi_func = (xfs_bmapi_t) xfs_bmapi, 71 .xfs_bmapi_func = (xfs_bmapi_t) xfs_bmapi,
72 .xfs_bunmapi_func = (xfs_bunmapi_t) xfs_bunmapi,
71 .xfs_bmap_eof_func = (xfs_bmap_eof_t) xfs_bmap_eof, 73 .xfs_bmap_eof_func = (xfs_bmap_eof_t) xfs_bmap_eof,
72 .xfs_iomap_write_direct = 74 .xfs_iomap_write_direct =
73 (xfs_iomap_write_direct_t) xfs_iomap_write_direct, 75 (xfs_iomap_write_direct_t) xfs_iomap_write_direct,
@@ -84,6 +86,7 @@ xfs_ioops_t xfs_iocore_xfs = {
84 .xfs_unlock = (xfs_unlk_t) xfs_iunlock, 86 .xfs_unlock = (xfs_unlk_t) xfs_iunlock,
85 .xfs_size_func = (xfs_size_t) xfs_size_fn, 87 .xfs_size_func = (xfs_size_t) xfs_size_fn,
86 .xfs_iodone = (xfs_iodone_t) fs_noerr, 88 .xfs_iodone = (xfs_iodone_t) fs_noerr,
89 .xfs_swap_extents_func = (xfs_swap_extents_t) xfs_swap_extents,
87}; 90};
88 91
89void 92void
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index d5dfedcb8922..d79055207fbf 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -252,7 +252,7 @@ xfs_iomap(
252 error = XFS_BMAPI(mp, NULL, io, offset_fsb, 252 error = XFS_BMAPI(mp, NULL, io, offset_fsb,
253 (xfs_filblks_t)(end_fsb - offset_fsb), 253 (xfs_filblks_t)(end_fsb - offset_fsb),
254 bmapi_flags, NULL, 0, &imap, 254 bmapi_flags, NULL, 0, &imap,
255 &nimaps, NULL); 255 &nimaps, NULL, NULL);
256 256
257 if (error) 257 if (error)
258 goto out; 258 goto out;
@@ -519,8 +519,8 @@ xfs_iomap_write_direct(
519 */ 519 */
520 XFS_BMAP_INIT(&free_list, &firstfsb); 520 XFS_BMAP_INIT(&free_list, &firstfsb);
521 nimaps = 1; 521 nimaps = 1;
522 error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, 522 error = XFS_BMAPI(mp, tp, io, offset_fsb, count_fsb, bmapi_flag,
523 bmapi_flag, &firstfsb, 0, &imap, &nimaps, &free_list); 523 &firstfsb, 0, &imap, &nimaps, &free_list, NULL);
524 if (error) 524 if (error)
525 goto error0; 525 goto error0;
526 526
@@ -610,8 +610,8 @@ xfs_iomap_eof_want_preallocate(
610 while (count_fsb > 0) { 610 while (count_fsb > 0) {
611 imaps = nimaps; 611 imaps = nimaps;
612 firstblock = NULLFSBLOCK; 612 firstblock = NULLFSBLOCK;
613 error = XFS_BMAPI(mp, NULL, io, start_fsb, count_fsb, 613 error = XFS_BMAPI(mp, NULL, io, start_fsb, count_fsb, 0,
614 0, &firstblock, 0, imap, &imaps, NULL); 614 &firstblock, 0, imap, &imaps, NULL, NULL);
615 if (error) 615 if (error)
616 return error; 616 return error;
617 for (n = 0; n < imaps; n++) { 617 for (n = 0; n < imaps; n++) {
@@ -695,11 +695,11 @@ retry:
695 695
696 nimaps = XFS_WRITE_IMAPS; 696 nimaps = XFS_WRITE_IMAPS;
697 firstblock = NULLFSBLOCK; 697 firstblock = NULLFSBLOCK;
698 error = xfs_bmapi(NULL, ip, offset_fsb, 698 error = XFS_BMAPI(mp, NULL, io, offset_fsb,
699 (xfs_filblks_t)(last_fsb - offset_fsb), 699 (xfs_filblks_t)(last_fsb - offset_fsb),
700 XFS_BMAPI_DELAY | XFS_BMAPI_WRITE | 700 XFS_BMAPI_DELAY | XFS_BMAPI_WRITE |
701 XFS_BMAPI_ENTIRE, &firstblock, 1, imap, 701 XFS_BMAPI_ENTIRE, &firstblock, 1, imap,
702 &nimaps, NULL); 702 &nimaps, NULL, NULL);
703 if (error && (error != ENOSPC)) 703 if (error && (error != ENOSPC))
704 return XFS_ERROR(error); 704 return XFS_ERROR(error);
705 705
@@ -832,9 +832,9 @@ xfs_iomap_write_allocate(
832 } 832 }
833 833
834 /* Go get the actual blocks */ 834 /* Go get the actual blocks */
835 error = xfs_bmapi(tp, ip, map_start_fsb, count_fsb, 835 error = XFS_BMAPI(mp, tp, io, map_start_fsb, count_fsb,
836 XFS_BMAPI_WRITE, &first_block, 1, 836 XFS_BMAPI_WRITE, &first_block, 1,
837 imap, &nimaps, &free_list); 837 imap, &nimaps, &free_list, NULL);
838 if (error) 838 if (error)
839 goto trans_cancel; 839 goto trans_cancel;
840 840
@@ -955,9 +955,9 @@ xfs_iomap_write_unwritten(
955 */ 955 */
956 XFS_BMAP_INIT(&free_list, &firstfsb); 956 XFS_BMAP_INIT(&free_list, &firstfsb);
957 nimaps = 1; 957 nimaps = 1;
958 error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, 958 error = XFS_BMAPI(mp, tp, io, offset_fsb, count_fsb,
959 XFS_BMAPI_WRITE|XFS_BMAPI_CONVERT, &firstfsb, 959 XFS_BMAPI_WRITE|XFS_BMAPI_CONVERT, &firstfsb,
960 1, &imap, &nimaps, &free_list); 960 1, &imap, &nimaps, &free_list, NULL);
961 if (error) 961 if (error)
962 goto error_on_bmapi_transaction; 962 goto error_on_bmapi_transaction;
963 963
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 668ad23fd37c..a682eb558102 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -63,6 +63,8 @@ struct xfs_perag;
63struct xfs_iocore; 63struct xfs_iocore;
64struct xfs_bmbt_irec; 64struct xfs_bmbt_irec;
65struct xfs_bmap_free; 65struct xfs_bmap_free;
66struct xfs_extdelta;
67struct xfs_swapext;
66 68
67extern struct vfsops xfs_vfsops; 69extern struct vfsops xfs_vfsops;
68extern struct vnodeops xfs_vnodeops; 70extern struct vnodeops xfs_vnodeops;
@@ -194,7 +196,12 @@ typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *,
194 xfs_fileoff_t, xfs_filblks_t, int, 196 xfs_fileoff_t, xfs_filblks_t, int,
195 xfs_fsblock_t *, xfs_extlen_t, 197 xfs_fsblock_t *, xfs_extlen_t,
196 struct xfs_bmbt_irec *, int *, 198 struct xfs_bmbt_irec *, int *,
197 struct xfs_bmap_free *); 199 struct xfs_bmap_free *, struct xfs_extdelta *);
200typedef int (*xfs_bunmapi_t)(struct xfs_trans *,
201 void *, xfs_fileoff_t,
202 xfs_filblks_t, int, xfs_extnum_t,
203 xfs_fsblock_t *, struct xfs_bmap_free *,
204 struct xfs_extdelta *, int *);
198typedef int (*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *); 205typedef int (*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *);
199typedef int (*xfs_iomap_write_direct_t)( 206typedef int (*xfs_iomap_write_direct_t)(
200 void *, xfs_off_t, size_t, int, 207 void *, xfs_off_t, size_t, int,
@@ -214,10 +221,13 @@ typedef int (*xfs_lock_nowait_t)(void *, uint);
214typedef void (*xfs_unlk_t)(void *, unsigned int); 221typedef void (*xfs_unlk_t)(void *, unsigned int);
215typedef xfs_fsize_t (*xfs_size_t)(void *); 222typedef xfs_fsize_t (*xfs_size_t)(void *);
216typedef xfs_fsize_t (*xfs_iodone_t)(struct vfs *); 223typedef xfs_fsize_t (*xfs_iodone_t)(struct vfs *);
224typedef int (*xfs_swap_extents_t)(void *, void *,
225 struct xfs_swapext*);
217 226
218typedef struct xfs_ioops { 227typedef struct xfs_ioops {
219 xfs_ioinit_t xfs_ioinit; 228 xfs_ioinit_t xfs_ioinit;
220 xfs_bmapi_t xfs_bmapi_func; 229 xfs_bmapi_t xfs_bmapi_func;
230 xfs_bunmapi_t xfs_bunmapi_func;
221 xfs_bmap_eof_t xfs_bmap_eof_func; 231 xfs_bmap_eof_t xfs_bmap_eof_func;
222 xfs_iomap_write_direct_t xfs_iomap_write_direct; 232 xfs_iomap_write_direct_t xfs_iomap_write_direct;
223 xfs_iomap_write_delay_t xfs_iomap_write_delay; 233 xfs_iomap_write_delay_t xfs_iomap_write_delay;
@@ -230,13 +240,17 @@ typedef struct xfs_ioops {
230 xfs_unlk_t xfs_unlock; 240 xfs_unlk_t xfs_unlock;
231 xfs_size_t xfs_size_func; 241 xfs_size_t xfs_size_func;
232 xfs_iodone_t xfs_iodone; 242 xfs_iodone_t xfs_iodone;
243 xfs_swap_extents_t xfs_swap_extents_func;
233} xfs_ioops_t; 244} xfs_ioops_t;
234 245
235#define XFS_IOINIT(vfsp, args, flags) \ 246#define XFS_IOINIT(vfsp, args, flags) \
236 (*(mp)->m_io_ops.xfs_ioinit)(vfsp, args, flags) 247 (*(mp)->m_io_ops.xfs_ioinit)(vfsp, args, flags)
237#define XFS_BMAPI(mp, trans,io,bno,len,f,first,tot,mval,nmap,flist) \ 248#define XFS_BMAPI(mp, trans,io,bno,len,f,first,tot,mval,nmap,flist,delta) \
238 (*(mp)->m_io_ops.xfs_bmapi_func) \ 249 (*(mp)->m_io_ops.xfs_bmapi_func) \
239 (trans,(io)->io_obj,bno,len,f,first,tot,mval,nmap,flist) 250 (trans,(io)->io_obj,bno,len,f,first,tot,mval,nmap,flist,delta)
251#define XFS_BUNMAPI(mp, trans,io,bno,len,f,nexts,first,flist,delta,done) \
252 (*(mp)->m_io_ops.xfs_bunmapi_func) \
253 (trans,(io)->io_obj,bno,len,f,nexts,first,flist,delta,done)
240#define XFS_BMAP_EOF(mp, io, endoff, whichfork, eof) \ 254#define XFS_BMAP_EOF(mp, io, endoff, whichfork, eof) \
241 (*(mp)->m_io_ops.xfs_bmap_eof_func) \ 255 (*(mp)->m_io_ops.xfs_bmap_eof_func) \
242 ((io)->io_obj, endoff, whichfork, eof) 256 ((io)->io_obj, endoff, whichfork, eof)
@@ -266,6 +280,9 @@ typedef struct xfs_ioops {
266 (*(mp)->m_io_ops.xfs_size_func)((io)->io_obj) 280 (*(mp)->m_io_ops.xfs_size_func)((io)->io_obj)
267#define XFS_IODONE(vfsp) \ 281#define XFS_IODONE(vfsp) \
268 (*(mp)->m_io_ops.xfs_iodone)(vfsp) 282 (*(mp)->m_io_ops.xfs_iodone)(vfsp)
283#define XFS_SWAP_EXTENTS(mp, io, tio, sxp) \
284 (*(mp)->m_io_ops.xfs_swap_extents_func) \
285 ((io)->io_obj, (tio)->io_obj, sxp)
269 286
270#ifdef HAVE_PERCPU_SB 287#ifdef HAVE_PERCPU_SB
271 288
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 5b413946b1c5..f5944c8b3788 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -141,7 +141,7 @@ xfs_growfs_rt_alloc(
141 cancelflags |= XFS_TRANS_ABORT; 141 cancelflags |= XFS_TRANS_ABORT;
142 error = xfs_bmapi(tp, ip, oblocks, nblocks - oblocks, 142 error = xfs_bmapi(tp, ip, oblocks, nblocks - oblocks,
143 XFS_BMAPI_WRITE | XFS_BMAPI_METADATA, &firstblock, 143 XFS_BMAPI_WRITE | XFS_BMAPI_METADATA, &firstblock,
144 resblks, &map, &nmap, &flist); 144 resblks, &map, &nmap, &flist, NULL);
145 if (!error && nmap < 1) 145 if (!error && nmap < 1)
146 error = XFS_ERROR(ENOSPC); 146 error = XFS_ERROR(ENOSPC);
147 if (error) 147 if (error)
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 7027ae68ee38..567d14d06d95 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -1000,7 +1000,7 @@ xfs_readlink(
1000 nmaps = SYMLINK_MAPS; 1000 nmaps = SYMLINK_MAPS;
1001 1001
1002 error = xfs_bmapi(NULL, ip, 0, XFS_B_TO_FSB(mp, pathlen), 1002 error = xfs_bmapi(NULL, ip, 0, XFS_B_TO_FSB(mp, pathlen),
1003 0, NULL, 0, mval, &nmaps, NULL); 1003 0, NULL, 0, mval, &nmaps, NULL, NULL);
1004 1004
1005 if (error) { 1005 if (error) {
1006 goto error_return; 1006 goto error_return;
@@ -1208,8 +1208,8 @@ xfs_inactive_free_eofblocks(
1208 1208
1209 nimaps = 1; 1209 nimaps = 1;
1210 xfs_ilock(ip, XFS_ILOCK_SHARED); 1210 xfs_ilock(ip, XFS_ILOCK_SHARED);
1211 error = xfs_bmapi(NULL, ip, end_fsb, map_len, 0, 1211 error = XFS_BMAPI(mp, NULL, &ip->i_iocore, end_fsb, map_len, 0,
1212 NULL, 0, &imap, &nimaps, NULL); 1212 NULL, 0, &imap, &nimaps, NULL, NULL);
1213 xfs_iunlock(ip, XFS_ILOCK_SHARED); 1213 xfs_iunlock(ip, XFS_ILOCK_SHARED);
1214 1214
1215 if (!error && (nimaps != 0) && 1215 if (!error && (nimaps != 0) &&
@@ -1338,7 +1338,7 @@ xfs_inactive_symlink_rmt(
1338 nmaps = ARRAY_SIZE(mval); 1338 nmaps = ARRAY_SIZE(mval);
1339 if ((error = xfs_bmapi(tp, ip, 0, XFS_B_TO_FSB(mp, size), 1339 if ((error = xfs_bmapi(tp, ip, 0, XFS_B_TO_FSB(mp, size),
1340 XFS_BMAPI_METADATA, &first_block, 0, mval, &nmaps, 1340 XFS_BMAPI_METADATA, &first_block, 0, mval, &nmaps,
1341 &free_list))) 1341 &free_list, NULL)))
1342 goto error0; 1342 goto error0;
1343 /* 1343 /*
1344 * Invalidate the block(s). 1344 * Invalidate the block(s).
@@ -1353,7 +1353,7 @@ xfs_inactive_symlink_rmt(
1353 * Unmap the dead block(s) to the free_list. 1353 * Unmap the dead block(s) to the free_list.
1354 */ 1354 */
1355 if ((error = xfs_bunmapi(tp, ip, 0, size, XFS_BMAPI_METADATA, nmaps, 1355 if ((error = xfs_bunmapi(tp, ip, 0, size, XFS_BMAPI_METADATA, nmaps,
1356 &first_block, &free_list, &done))) 1356 &first_block, &free_list, NULL, &done)))
1357 goto error1; 1357 goto error1;
1358 ASSERT(done); 1358 ASSERT(done);
1359 /* 1359 /*
@@ -3457,7 +3457,7 @@ xfs_symlink(
3457 error = xfs_bmapi(tp, ip, first_fsb, fs_blocks, 3457 error = xfs_bmapi(tp, ip, first_fsb, fs_blocks,
3458 XFS_BMAPI_WRITE | XFS_BMAPI_METADATA, 3458 XFS_BMAPI_WRITE | XFS_BMAPI_METADATA,
3459 &first_block, resblks, mval, &nmaps, 3459 &first_block, resblks, mval, &nmaps,
3460 &free_list); 3460 &free_list, NULL);
3461 if (error) { 3461 if (error) {
3462 goto error1; 3462 goto error1;
3463 } 3463 }
@@ -4116,10 +4116,10 @@ retry:
4116 * Issue the xfs_bmapi() call to allocate the blocks 4116 * Issue the xfs_bmapi() call to allocate the blocks
4117 */ 4117 */
4118 XFS_BMAP_INIT(&free_list, &firstfsb); 4118 XFS_BMAP_INIT(&free_list, &firstfsb);
4119 error = xfs_bmapi(tp, ip, startoffset_fsb, 4119 error = XFS_BMAPI(mp, tp, &ip->i_iocore, startoffset_fsb,
4120 allocatesize_fsb, bmapi_flag, 4120 allocatesize_fsb, bmapi_flag,
4121 &firstfsb, 0, imapp, &nimaps, 4121 &firstfsb, 0, imapp, &nimaps,
4122 &free_list); 4122 &free_list, NULL);
4123 if (error) { 4123 if (error) {
4124 goto error0; 4124 goto error0;
4125 } 4125 }
@@ -4199,8 +4199,8 @@ xfs_zero_remaining_bytes(
4199 for (offset = startoff; offset <= endoff; offset = lastoffset + 1) { 4199 for (offset = startoff; offset <= endoff; offset = lastoffset + 1) {
4200 offset_fsb = XFS_B_TO_FSBT(mp, offset); 4200 offset_fsb = XFS_B_TO_FSBT(mp, offset);
4201 nimap = 1; 4201 nimap = 1;
4202 error = xfs_bmapi(NULL, ip, offset_fsb, 1, 0, NULL, 0, &imap, 4202 error = XFS_BMAPI(mp, NULL, &ip->i_iocore, offset_fsb, 1, 0,
4203 &nimap, NULL); 4203 NULL, 0, &imap, &nimap, NULL, NULL);
4204 if (error || nimap < 1) 4204 if (error || nimap < 1)
4205 break; 4205 break;
4206 ASSERT(imap.br_blockcount >= 1); 4206 ASSERT(imap.br_blockcount >= 1);
@@ -4338,8 +4338,8 @@ xfs_free_file_space(
4338 */ 4338 */
4339 if (rt && !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) { 4339 if (rt && !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) {
4340 nimap = 1; 4340 nimap = 1;
4341 error = xfs_bmapi(NULL, ip, startoffset_fsb, 1, 0, NULL, 0, 4341 error = XFS_BMAPI(mp, NULL, &ip->i_iocore, startoffset_fsb,
4342 &imap, &nimap, NULL); 4342 1, 0, NULL, 0, &imap, &nimap, NULL, NULL);
4343 if (error) 4343 if (error)
4344 goto out_unlock_iolock; 4344 goto out_unlock_iolock;
4345 ASSERT(nimap == 0 || nimap == 1); 4345 ASSERT(nimap == 0 || nimap == 1);
@@ -4353,8 +4353,8 @@ xfs_free_file_space(
4353 startoffset_fsb += mp->m_sb.sb_rextsize - mod; 4353 startoffset_fsb += mp->m_sb.sb_rextsize - mod;
4354 } 4354 }
4355 nimap = 1; 4355 nimap = 1;
4356 error = xfs_bmapi(NULL, ip, endoffset_fsb - 1, 1, 0, NULL, 0, 4356 error = XFS_BMAPI(mp, NULL, &ip->i_iocore, endoffset_fsb - 1,
4357 &imap, &nimap, NULL); 4357 1, 0, NULL, 0, &imap, &nimap, NULL, NULL);
4358 if (error) 4358 if (error)
4359 goto out_unlock_iolock; 4359 goto out_unlock_iolock;
4360 ASSERT(nimap == 0 || nimap == 1); 4360 ASSERT(nimap == 0 || nimap == 1);
@@ -4426,9 +4426,9 @@ xfs_free_file_space(
4426 * issue the bunmapi() call to free the blocks 4426 * issue the bunmapi() call to free the blocks
4427 */ 4427 */
4428 XFS_BMAP_INIT(&free_list, &firstfsb); 4428 XFS_BMAP_INIT(&free_list, &firstfsb);
4429 error = xfs_bunmapi(tp, ip, startoffset_fsb, 4429 error = XFS_BUNMAPI(mp, tp, &ip->i_iocore, startoffset_fsb,
4430 endoffset_fsb - startoffset_fsb, 4430 endoffset_fsb - startoffset_fsb,
4431 0, 2, &firstfsb, &free_list, &done); 4431 0, 2, &firstfsb, &free_list, NULL, &done);
4432 if (error) { 4432 if (error) {
4433 goto error0; 4433 goto error0;
4434 } 4434 }