aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_bmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_bmap.c')
-rw-r--r--fs/xfs/xfs_bmap.c386
1 files changed, 295 insertions, 91 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 26939d364bc4..3a6137539064 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
@@ -24,13 +24,11 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_da_btree.h" 28#include "xfs_da_btree.h"
30#include "xfs_bmap_btree.h" 29#include "xfs_bmap_btree.h"
31#include "xfs_alloc_btree.h" 30#include "xfs_alloc_btree.h"
32#include "xfs_ialloc_btree.h" 31#include "xfs_ialloc_btree.h"
33#include "xfs_dir_sf.h"
34#include "xfs_dir2_sf.h" 32#include "xfs_dir2_sf.h"
35#include "xfs_attr_sf.h" 33#include "xfs_attr_sf.h"
36#include "xfs_dinode.h" 34#include "xfs_dinode.h"
@@ -40,13 +38,15 @@
40#include "xfs_mount.h" 38#include "xfs_mount.h"
41#include "xfs_ialloc.h" 39#include "xfs_ialloc.h"
42#include "xfs_itable.h" 40#include "xfs_itable.h"
41#include "xfs_dir2_data.h"
42#include "xfs_dir2_leaf.h"
43#include "xfs_dir2_block.h"
43#include "xfs_inode_item.h" 44#include "xfs_inode_item.h"
44#include "xfs_extfree_item.h" 45#include "xfs_extfree_item.h"
45#include "xfs_alloc.h" 46#include "xfs_alloc.h"
46#include "xfs_bmap.h" 47#include "xfs_bmap.h"
47#include "xfs_rtalloc.h" 48#include "xfs_rtalloc.h"
48#include "xfs_error.h" 49#include "xfs_error.h"
49#include "xfs_dir_leaf.h"
50#include "xfs_attr_leaf.h" 50#include "xfs_attr_leaf.h"
51#include "xfs_rw.h" 51#include "xfs_rw.h"
52#include "xfs_quota.h" 52#include "xfs_quota.h"
@@ -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
@@ -510,7 +516,7 @@ xfs_bmap_add_attrfork_local(
510 dargs.total = mp->m_dirblkfsbs; 516 dargs.total = mp->m_dirblkfsbs;
511 dargs.whichfork = XFS_DATA_FORK; 517 dargs.whichfork = XFS_DATA_FORK;
512 dargs.trans = tp; 518 dargs.trans = tp;
513 error = XFS_DIR_SHORTFORM_TO_SINGLE(mp, &dargs); 519 error = xfs_dir2_sf_to_block(&dargs);
514 } else 520 } else
515 error = xfs_bmap_local_to_extents(tp, ip, firstblock, 1, flags, 521 error = xfs_bmap_local_to_extents(tp, ip, firstblock, 1, flags,
516 XFS_DATA_FORK); 522 XFS_DATA_FORK);
@@ -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); 2277 }
2115 cur->bc_rec.b.br_state = new->br_state; 2278 if (delta) {
2116 if ((error = xfs_bmbt_insert(cur, &i))) 2279 temp2 += temp;
2117 return error; 2280 if (delta->xed_startoff > temp)
2118 ASSERT(i == 1); 2281 delta->xed_startoff = temp;
2119 return 0; 2282 if (delta->xed_blockcount < temp2)
2283 delta->xed_blockcount = temp2;
2120 } 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/*
@@ -2598,6 +2762,7 @@ xfs_bmap_btalloc(
2598 args.mp = mp; 2762 args.mp = mp;
2599 args.fsbno = ap->rval; 2763 args.fsbno = ap->rval;
2600 args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks); 2764 args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks);
2765 args.firstblock = ap->firstblock;
2601 blen = 0; 2766 blen = 0;
2602 if (nullfb) { 2767 if (nullfb) {
2603 args.type = XFS_ALLOCTYPE_START_BNO; 2768 args.type = XFS_ALLOCTYPE_START_BNO;
@@ -2657,7 +2822,7 @@ xfs_bmap_btalloc(
2657 else 2822 else
2658 args.minlen = ap->alen; 2823 args.minlen = ap->alen;
2659 } else if (ap->low) { 2824 } else if (ap->low) {
2660 args.type = XFS_ALLOCTYPE_FIRST_AG; 2825 args.type = XFS_ALLOCTYPE_START_BNO;
2661 args.total = args.minlen = ap->minlen; 2826 args.total = args.minlen = ap->minlen;
2662 } else { 2827 } else {
2663 args.type = XFS_ALLOCTYPE_NEAR_BNO; 2828 args.type = XFS_ALLOCTYPE_NEAR_BNO;
@@ -2669,7 +2834,7 @@ xfs_bmap_btalloc(
2669 args.prod = ap->ip->i_d.di_extsize; 2834 args.prod = ap->ip->i_d.di_extsize;
2670 if ((args.mod = (xfs_extlen_t)do_mod(ap->off, args.prod))) 2835 if ((args.mod = (xfs_extlen_t)do_mod(ap->off, args.prod)))
2671 args.mod = (xfs_extlen_t)(args.prod - args.mod); 2836 args.mod = (xfs_extlen_t)(args.prod - args.mod);
2672 } else if (unlikely(mp->m_sb.sb_blocksize >= NBPP)) { 2837 } else if (mp->m_sb.sb_blocksize >= NBPP) {
2673 args.prod = 1; 2838 args.prod = 1;
2674 args.mod = 0; 2839 args.mod = 0;
2675 } else { 2840 } else {
@@ -2885,6 +3050,7 @@ xfs_bmap_del_extent(
2885 xfs_btree_cur_t *cur, /* if null, not a btree */ 3050 xfs_btree_cur_t *cur, /* if null, not a btree */
2886 xfs_bmbt_irec_t *del, /* data to remove from extents */ 3051 xfs_bmbt_irec_t *del, /* data to remove from extents */
2887 int *logflagsp, /* inode logging flags */ 3052 int *logflagsp, /* inode logging flags */
3053 xfs_extdelta_t *delta, /* Change made to incore extents */
2888 int whichfork, /* data or attr fork */ 3054 int whichfork, /* data or attr fork */
2889 int rsvd) /* OK to allocate reserved blocks */ 3055 int rsvd) /* OK to allocate reserved blocks */
2890{ 3056{
@@ -3193,6 +3359,14 @@ xfs_bmap_del_extent(
3193 if (da_old > da_new) 3359 if (da_old > da_new)
3194 xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, (int)(da_old - da_new), 3360 xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, (int)(da_old - da_new),
3195 rsvd); 3361 rsvd);
3362 if (delta) {
3363 /* DELTA: report the original extent. */
3364 if (delta->xed_startoff > got.br_startoff)
3365 delta->xed_startoff = got.br_startoff;
3366 if (delta->xed_blockcount < got.br_startoff+got.br_blockcount)
3367 delta->xed_blockcount = got.br_startoff +
3368 got.br_blockcount;
3369 }
3196done: 3370done:
3197 *logflagsp = flags; 3371 *logflagsp = flags;
3198 return error; 3372 return error;
@@ -3279,6 +3453,7 @@ xfs_bmap_extents_to_btree(
3279 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE); 3453 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE);
3280 args.tp = tp; 3454 args.tp = tp;
3281 args.mp = mp; 3455 args.mp = mp;
3456 args.firstblock = *firstblock;
3282 if (*firstblock == NULLFSBLOCK) { 3457 if (*firstblock == NULLFSBLOCK) {
3283 args.type = XFS_ALLOCTYPE_START_BNO; 3458 args.type = XFS_ALLOCTYPE_START_BNO;
3284 args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino); 3459 args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino);
@@ -3414,6 +3589,7 @@ xfs_bmap_local_to_extents(
3414 3589
3415 args.tp = tp; 3590 args.tp = tp;
3416 args.mp = ip->i_mount; 3591 args.mp = ip->i_mount;
3592 args.firstblock = *firstblock;
3417 ASSERT((ifp->if_flags & 3593 ASSERT((ifp->if_flags &
3418 (XFS_IFINLINE|XFS_IFEXTENTS|XFS_IFEXTIREC)) == XFS_IFINLINE); 3594 (XFS_IFINLINE|XFS_IFEXTENTS|XFS_IFEXTIREC)) == XFS_IFINLINE);
3419 /* 3595 /*
@@ -3753,7 +3929,7 @@ xfs_bunmap_trace(
3753 if (ip->i_rwtrace == NULL) 3929 if (ip->i_rwtrace == NULL)
3754 return; 3930 return;
3755 ktrace_enter(ip->i_rwtrace, 3931 ktrace_enter(ip->i_rwtrace,
3756 (void *)(__psint_t)XFS_BUNMAPI, 3932 (void *)(__psint_t)XFS_BUNMAP,
3757 (void *)ip, 3933 (void *)ip,
3758 (void *)(__psint_t)((ip->i_d.di_size >> 32) & 0xffffffff), 3934 (void *)(__psint_t)((ip->i_d.di_size >> 32) & 0xffffffff),
3759 (void *)(__psint_t)(ip->i_d.di_size & 0xffffffff), 3935 (void *)(__psint_t)(ip->i_d.di_size & 0xffffffff),
@@ -4087,8 +4263,8 @@ xfs_bmap_finish(
4087 if (!XFS_FORCED_SHUTDOWN(mp)) 4263 if (!XFS_FORCED_SHUTDOWN(mp))
4088 xfs_force_shutdown(mp, 4264 xfs_force_shutdown(mp,
4089 (error == EFSCORRUPTED) ? 4265 (error == EFSCORRUPTED) ?
4090 XFS_CORRUPT_INCORE : 4266 SHUTDOWN_CORRUPT_INCORE :
4091 XFS_METADATA_IO_ERROR); 4267 SHUTDOWN_META_IO_ERROR);
4092 return error; 4268 return error;
4093 } 4269 }
4094 xfs_trans_log_efd_extent(ntp, efd, free->xbfi_startblock, 4270 xfs_trans_log_efd_extent(ntp, efd, free->xbfi_startblock,
@@ -4538,7 +4714,8 @@ xfs_bmapi(
4538 xfs_extlen_t total, /* total blocks needed */ 4714 xfs_extlen_t total, /* total blocks needed */
4539 xfs_bmbt_irec_t *mval, /* output: map values */ 4715 xfs_bmbt_irec_t *mval, /* output: map values */
4540 int *nmap, /* i/o: mval size/count */ 4716 int *nmap, /* i/o: mval size/count */
4541 xfs_bmap_free_t *flist) /* i/o: list extents to free */ 4717 xfs_bmap_free_t *flist, /* i/o: list extents to free */
4718 xfs_extdelta_t *delta) /* o: change made to incore extents */
4542{ 4719{
4543 xfs_fsblock_t abno; /* allocated block number */ 4720 xfs_fsblock_t abno; /* allocated block number */
4544 xfs_extlen_t alen; /* allocated extent length */ 4721 xfs_extlen_t alen; /* allocated extent length */
@@ -4650,6 +4827,10 @@ xfs_bmapi(
4650 end = bno + len; 4827 end = bno + len;
4651 obno = bno; 4828 obno = bno;
4652 bma.ip = NULL; 4829 bma.ip = NULL;
4830 if (delta) {
4831 delta->xed_startoff = NULLFILEOFF;
4832 delta->xed_blockcount = 0;
4833 }
4653 while (bno < end && n < *nmap) { 4834 while (bno < end && n < *nmap) {
4654 /* 4835 /*
4655 * Reading past eof, act as though there's a hole 4836 * Reading past eof, act as though there's a hole
@@ -4886,8 +5067,8 @@ xfs_bmapi(
4886 got.br_state = XFS_EXT_UNWRITTEN; 5067 got.br_state = XFS_EXT_UNWRITTEN;
4887 } 5068 }
4888 error = xfs_bmap_add_extent(ip, lastx, &cur, &got, 5069 error = xfs_bmap_add_extent(ip, lastx, &cur, &got,
4889 firstblock, flist, &tmp_logflags, whichfork, 5070 firstblock, flist, &tmp_logflags, delta,
4890 (flags & XFS_BMAPI_RSVBLOCKS)); 5071 whichfork, (flags & XFS_BMAPI_RSVBLOCKS));
4891 logflags |= tmp_logflags; 5072 logflags |= tmp_logflags;
4892 if (error) 5073 if (error)
4893 goto error0; 5074 goto error0;
@@ -4983,8 +5164,8 @@ xfs_bmapi(
4983 } 5164 }
4984 mval->br_state = XFS_EXT_NORM; 5165 mval->br_state = XFS_EXT_NORM;
4985 error = xfs_bmap_add_extent(ip, lastx, &cur, mval, 5166 error = xfs_bmap_add_extent(ip, lastx, &cur, mval,
4986 firstblock, flist, &tmp_logflags, whichfork, 5167 firstblock, flist, &tmp_logflags, delta,
4987 (flags & XFS_BMAPI_RSVBLOCKS)); 5168 whichfork, (flags & XFS_BMAPI_RSVBLOCKS));
4988 logflags |= tmp_logflags; 5169 logflags |= tmp_logflags;
4989 if (error) 5170 if (error)
4990 goto error0; 5171 goto error0;
@@ -5073,7 +5254,14 @@ xfs_bmapi(
5073 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE || 5254 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE ||
5074 XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max); 5255 XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max);
5075 error = 0; 5256 error = 0;
5076 5257 if (delta && delta->xed_startoff != NULLFILEOFF) {
5258 /* A change was actually made.
5259 * Note that delta->xed_blockount is an offset at this
5260 * point and needs to be converted to a block count.
5261 */
5262 ASSERT(delta->xed_blockcount > delta->xed_startoff);
5263 delta->xed_blockcount -= delta->xed_startoff;
5264 }
5077error0: 5265error0:
5078 /* 5266 /*
5079 * Log everything. Do this after conversion, there's no point in 5267 * Log everything. Do this after conversion, there's no point in
@@ -5185,6 +5373,8 @@ xfs_bunmapi(
5185 xfs_fsblock_t *firstblock, /* first allocated block 5373 xfs_fsblock_t *firstblock, /* first allocated block
5186 controls a.g. for allocs */ 5374 controls a.g. for allocs */
5187 xfs_bmap_free_t *flist, /* i/o: list extents to free */ 5375 xfs_bmap_free_t *flist, /* i/o: list extents to free */
5376 xfs_extdelta_t *delta, /* o: change made to incore
5377 extents */
5188 int *done) /* set if not done yet */ 5378 int *done) /* set if not done yet */
5189{ 5379{
5190 xfs_btree_cur_t *cur; /* bmap btree cursor */ 5380 xfs_btree_cur_t *cur; /* bmap btree cursor */
@@ -5242,6 +5432,10 @@ xfs_bunmapi(
5242 bno = start + len - 1; 5432 bno = start + len - 1;
5243 ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, 5433 ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got,
5244 &prev); 5434 &prev);
5435 if (delta) {
5436 delta->xed_startoff = NULLFILEOFF;
5437 delta->xed_blockcount = 0;
5438 }
5245 /* 5439 /*
5246 * Check to see if the given block number is past the end of the 5440 * Check to see if the given block number is past the end of the
5247 * file, back up to the last block if so... 5441 * file, back up to the last block if so...
@@ -5340,7 +5534,8 @@ xfs_bunmapi(
5340 } 5534 }
5341 del.br_state = XFS_EXT_UNWRITTEN; 5535 del.br_state = XFS_EXT_UNWRITTEN;
5342 error = xfs_bmap_add_extent(ip, lastx, &cur, &del, 5536 error = xfs_bmap_add_extent(ip, lastx, &cur, &del,
5343 firstblock, flist, &logflags, XFS_DATA_FORK, 0); 5537 firstblock, flist, &logflags, delta,
5538 XFS_DATA_FORK, 0);
5344 if (error) 5539 if (error)
5345 goto error0; 5540 goto error0;
5346 goto nodelete; 5541 goto nodelete;
@@ -5394,7 +5589,7 @@ xfs_bunmapi(
5394 prev.br_state = XFS_EXT_UNWRITTEN; 5589 prev.br_state = XFS_EXT_UNWRITTEN;
5395 error = xfs_bmap_add_extent(ip, lastx - 1, &cur, 5590 error = xfs_bmap_add_extent(ip, lastx - 1, &cur,
5396 &prev, firstblock, flist, &logflags, 5591 &prev, firstblock, flist, &logflags,
5397 XFS_DATA_FORK, 0); 5592 delta, XFS_DATA_FORK, 0);
5398 if (error) 5593 if (error)
5399 goto error0; 5594 goto error0;
5400 goto nodelete; 5595 goto nodelete;
@@ -5403,7 +5598,7 @@ xfs_bunmapi(
5403 del.br_state = XFS_EXT_UNWRITTEN; 5598 del.br_state = XFS_EXT_UNWRITTEN;
5404 error = xfs_bmap_add_extent(ip, lastx, &cur, 5599 error = xfs_bmap_add_extent(ip, lastx, &cur,
5405 &del, firstblock, flist, &logflags, 5600 &del, firstblock, flist, &logflags,
5406 XFS_DATA_FORK, 0); 5601 delta, XFS_DATA_FORK, 0);
5407 if (error) 5602 if (error)
5408 goto error0; 5603 goto error0;
5409 goto nodelete; 5604 goto nodelete;
@@ -5456,7 +5651,7 @@ xfs_bunmapi(
5456 goto error0; 5651 goto error0;
5457 } 5652 }
5458 error = xfs_bmap_del_extent(ip, tp, lastx, flist, cur, &del, 5653 error = xfs_bmap_del_extent(ip, tp, lastx, flist, cur, &del,
5459 &tmp_logflags, whichfork, rsvd); 5654 &tmp_logflags, delta, whichfork, rsvd);
5460 logflags |= tmp_logflags; 5655 logflags |= tmp_logflags;
5461 if (error) 5656 if (error)
5462 goto error0; 5657 goto error0;
@@ -5513,6 +5708,14 @@ nodelete:
5513 ASSERT(ifp->if_ext_max == 5708 ASSERT(ifp->if_ext_max ==
5514 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); 5709 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
5515 error = 0; 5710 error = 0;
5711 if (delta && delta->xed_startoff != NULLFILEOFF) {
5712 /* A change was actually made.
5713 * Note that delta->xed_blockount is an offset at this
5714 * point and needs to be converted to a block count.
5715 */
5716 ASSERT(delta->xed_blockcount > delta->xed_startoff);
5717 delta->xed_blockcount -= delta->xed_startoff;
5718 }
5516error0: 5719error0:
5517 /* 5720 /*
5518 * Log everything. Do this after conversion, there's no point in 5721 * Log everything. Do this after conversion, there's no point in
@@ -5556,7 +5759,7 @@ xfs_getbmap(
5556 __int64_t fixlen; /* length for -1 case */ 5759 __int64_t fixlen; /* length for -1 case */
5557 int i; /* extent number */ 5760 int i; /* extent number */
5558 xfs_inode_t *ip; /* xfs incore inode pointer */ 5761 xfs_inode_t *ip; /* xfs incore inode pointer */
5559 vnode_t *vp; /* corresponding vnode */ 5762 bhv_vnode_t *vp; /* corresponding vnode */
5560 int lock; /* lock state */ 5763 int lock; /* lock state */
5561 xfs_bmbt_irec_t *map; /* buffer for user's data */ 5764 xfs_bmbt_irec_t *map; /* buffer for user's data */
5562 xfs_mount_t *mp; /* file system mount point */ 5765 xfs_mount_t *mp; /* file system mount point */
@@ -5653,7 +5856,7 @@ xfs_getbmap(
5653 5856
5654 if (whichfork == XFS_DATA_FORK && ip->i_delayed_blks) { 5857 if (whichfork == XFS_DATA_FORK && ip->i_delayed_blks) {
5655 /* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */ 5858 /* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */
5656 VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, 0, FI_REMAPF, error); 5859 error = bhv_vop_flush_pages(vp, (xfs_off_t)0, -1, 0, FI_REMAPF);
5657 } 5860 }
5658 5861
5659 ASSERT(whichfork == XFS_ATTR_FORK || ip->i_delayed_blks == 0); 5862 ASSERT(whichfork == XFS_ATTR_FORK || ip->i_delayed_blks == 0);
@@ -5689,7 +5892,8 @@ xfs_getbmap(
5689 nmap = (nexleft > subnex) ? subnex : nexleft; 5892 nmap = (nexleft > subnex) ? subnex : nexleft;
5690 error = xfs_bmapi(NULL, ip, XFS_BB_TO_FSBT(mp, bmv->bmv_offset), 5893 error = xfs_bmapi(NULL, ip, XFS_BB_TO_FSBT(mp, bmv->bmv_offset),
5691 XFS_BB_TO_FSB(mp, bmv->bmv_length), 5894 XFS_BB_TO_FSB(mp, bmv->bmv_length),
5692 bmapi_flags, NULL, 0, map, &nmap, NULL); 5895 bmapi_flags, NULL, 0, map, &nmap,
5896 NULL, NULL);
5693 if (error) 5897 if (error)
5694 goto unlock_and_return; 5898 goto unlock_and_return;
5695 ASSERT(nmap <= subnex); 5899 ASSERT(nmap <= subnex);