diff options
author | Olaf Weber <olaf@sgi.com> | 2006-06-09 00:48:12 -0400 |
---|---|---|
committer | Nathan Scott <nathans@sgi.com> | 2006-06-09 00:48:12 -0400 |
commit | 3e57ecf640428c01ba1ed8c8fc538447ada1715b (patch) | |
tree | bcc92b0017b5ec8e106649cd53beffdd6addde07 /fs/xfs/xfs_bmap.c | |
parent | 128e6ced247cda88f96fa9f2e4ba8b2c4a681560 (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/xfs_bmap.c')
-rw-r--r-- | fs/xfs/xfs_bmap.c | 363 |
1 files changed, 282 insertions, 81 deletions
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 | } | ||
1212 | done: | 1269 | done: |
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 | } | ||
1728 | done: | 1828 | done: |
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 | } | ||
2285 | done: | ||
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 | } | ||
3196 | done: | 3369 | done: |
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 | } | ||
5077 | error0: | 5262 | error0: |
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 | } | ||
5516 | error0: | 5716 | error0: |
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); |