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.c1360
1 files changed, 629 insertions, 731 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 70625e577c70..d384e489705f 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -89,7 +89,7 @@ xfs_bmap_add_attrfork_local(
89 int *flags); /* inode logging flags */ 89 int *flags); /* inode logging flags */
90 90
91/* 91/*
92 * Called by xfs_bmapi to update extent list structure and the btree 92 * Called by xfs_bmapi to update file extent records and the btree
93 * after allocating space (or doing a delayed allocation). 93 * after allocating space (or doing a delayed allocation).
94 */ 94 */
95STATIC int /* error */ 95STATIC int /* error */
@@ -97,7 +97,7 @@ xfs_bmap_add_extent(
97 xfs_inode_t *ip, /* incore inode pointer */ 97 xfs_inode_t *ip, /* incore inode pointer */
98 xfs_extnum_t idx, /* extent number to update/insert */ 98 xfs_extnum_t idx, /* extent number to update/insert */
99 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 99 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
100 xfs_bmbt_irec_t *new, /* new data to put in extent list */ 100 xfs_bmbt_irec_t *new, /* new data to add to file extents */
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 */
@@ -113,7 +113,7 @@ xfs_bmap_add_extent_delay_real(
113 xfs_inode_t *ip, /* incore inode pointer */ 113 xfs_inode_t *ip, /* incore inode pointer */
114 xfs_extnum_t idx, /* extent number to update/insert */ 114 xfs_extnum_t idx, /* extent number to update/insert */
115 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 115 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
116 xfs_bmbt_irec_t *new, /* new data to put in extent list */ 116 xfs_bmbt_irec_t *new, /* new data to add to file extents */
117 xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */ 117 xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */
118 xfs_fsblock_t *first, /* pointer to firstblock variable */ 118 xfs_fsblock_t *first, /* pointer to firstblock variable */
119 xfs_bmap_free_t *flist, /* list of extents to be freed */ 119 xfs_bmap_free_t *flist, /* list of extents to be freed */
@@ -129,7 +129,7 @@ xfs_bmap_add_extent_hole_delay(
129 xfs_inode_t *ip, /* incore inode pointer */ 129 xfs_inode_t *ip, /* incore inode pointer */
130 xfs_extnum_t idx, /* extent number to update/insert */ 130 xfs_extnum_t idx, /* extent number to update/insert */
131 xfs_btree_cur_t *cur, /* if null, not a btree */ 131 xfs_btree_cur_t *cur, /* if null, not a btree */
132 xfs_bmbt_irec_t *new, /* new data to put in extent list */ 132 xfs_bmbt_irec_t *new, /* new data to add to file extents */
133 int *logflagsp,/* inode logging flags */ 133 int *logflagsp,/* inode logging flags */
134 int rsvd); /* OK to allocate reserved blocks */ 134 int rsvd); /* OK to allocate reserved blocks */
135 135
@@ -142,7 +142,7 @@ xfs_bmap_add_extent_hole_real(
142 xfs_inode_t *ip, /* incore inode pointer */ 142 xfs_inode_t *ip, /* incore inode pointer */
143 xfs_extnum_t idx, /* extent number to update/insert */ 143 xfs_extnum_t idx, /* extent number to update/insert */
144 xfs_btree_cur_t *cur, /* if null, not a btree */ 144 xfs_btree_cur_t *cur, /* if null, not a btree */
145 xfs_bmbt_irec_t *new, /* new data to put in extent list */ 145 xfs_bmbt_irec_t *new, /* new data to add to file extents */
146 int *logflagsp, /* inode logging flags */ 146 int *logflagsp, /* inode logging flags */
147 int whichfork); /* data or attr fork */ 147 int whichfork); /* data or attr fork */
148 148
@@ -155,7 +155,7 @@ xfs_bmap_add_extent_unwritten_real(
155 xfs_inode_t *ip, /* incore inode pointer */ 155 xfs_inode_t *ip, /* incore inode pointer */
156 xfs_extnum_t idx, /* extent number to update/insert */ 156 xfs_extnum_t idx, /* extent number to update/insert */
157 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 157 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
158 xfs_bmbt_irec_t *new, /* new data to put in extent list */ 158 xfs_bmbt_irec_t *new, /* new data to add to file extents */
159 int *logflagsp); /* inode logging flags */ 159 int *logflagsp); /* inode logging flags */
160 160
161/* 161/*
@@ -169,7 +169,7 @@ xfs_bmap_alloc(
169/* 169/*
170 * Transform a btree format file with only one leaf node, where the 170 * Transform a btree format file with only one leaf node, where the
171 * extents list will fit in the inode, into an extents format file. 171 * extents list will fit in the inode, into an extents format file.
172 * Since the extent list is already in-core, all we have to do is 172 * Since the file extents are already in-core, all we have to do is
173 * give up the space for the btree root and pitch the leaf block. 173 * give up the space for the btree root and pitch the leaf block.
174 */ 174 */
175STATIC int /* error */ 175STATIC int /* error */
@@ -191,7 +191,7 @@ xfs_bmap_check_extents(
191#endif 191#endif
192 192
193/* 193/*
194 * Called by xfs_bmapi to update extent list structure and the btree 194 * Called by xfs_bmapi to update file extent records and the btree
195 * after removing space (or undoing a delayed allocation). 195 * after removing space (or undoing a delayed allocation).
196 */ 196 */
197STATIC int /* error */ 197STATIC int /* error */
@@ -201,7 +201,7 @@ xfs_bmap_del_extent(
201 xfs_extnum_t idx, /* extent number to update/insert */ 201 xfs_extnum_t idx, /* extent number to update/insert */
202 xfs_bmap_free_t *flist, /* list of extents to be freed */ 202 xfs_bmap_free_t *flist, /* list of extents to be freed */
203 xfs_btree_cur_t *cur, /* if null, not a btree */ 203 xfs_btree_cur_t *cur, /* if null, not a btree */
204 xfs_bmbt_irec_t *new, /* new data to put in extent list */ 204 xfs_bmbt_irec_t *new, /* new data to add to file extents */
205 int *logflagsp,/* inode logging flags */ 205 int *logflagsp,/* inode logging flags */
206 int whichfork, /* data or attr fork */ 206 int whichfork, /* data or attr fork */
207 int rsvd); /* OK to allocate reserved blocks */ 207 int rsvd); /* OK to allocate reserved blocks */
@@ -217,18 +217,6 @@ xfs_bmap_del_free(
217 xfs_bmap_free_item_t *free); /* list item to be freed */ 217 xfs_bmap_free_item_t *free); /* list item to be freed */
218 218
219/* 219/*
220 * Remove count entries from the extents array for inode "ip", starting
221 * at index "idx". Copies the remaining items down over the deleted ones,
222 * and gives back the excess memory.
223 */
224STATIC void
225xfs_bmap_delete_exlist(
226 xfs_inode_t *ip, /* incode inode pointer */
227 xfs_extnum_t idx, /* starting delete index */
228 xfs_extnum_t count, /* count of items to delete */
229 int whichfork); /* data or attr fork */
230
231/*
232 * Convert an extents-format file into a btree-format file. 220 * Convert an extents-format file into a btree-format file.
233 * The new file will have a root block (in the inode) and a single child block. 221 * The new file will have a root block (in the inode) and a single child block.
234 */ 222 */
@@ -244,18 +232,6 @@ xfs_bmap_extents_to_btree(
244 int whichfork); /* data or attr fork */ 232 int whichfork); /* data or attr fork */
245 233
246/* 234/*
247 * Insert new item(s) in the extent list for inode "ip".
248 * Count new items are inserted at offset idx.
249 */
250STATIC void
251xfs_bmap_insert_exlist(
252 xfs_inode_t *ip, /* incore inode pointer */
253 xfs_extnum_t idx, /* starting index of new items */
254 xfs_extnum_t count, /* number of inserted items */
255 xfs_bmbt_irec_t *new, /* items to insert */
256 int whichfork); /* data or attr fork */
257
258/*
259 * Convert a local file to an extents file. 235 * Convert a local file to an extents file.
260 * This code is sort of bogus, since the file data needs to get 236 * This code is sort of bogus, since the file data needs to get
261 * logged so it won't be lost. The bmap-level manipulations are ok, though. 237 * logged so it won't be lost. The bmap-level manipulations are ok, though.
@@ -316,7 +292,7 @@ xfs_bmap_trace_addentry(
316 int whichfork); /* data or attr fork */ 292 int whichfork); /* data or attr fork */
317 293
318/* 294/*
319 * Add bmap trace entry prior to a call to xfs_bmap_delete_exlist. 295 * Add bmap trace entry prior to a call to xfs_iext_remove.
320 */ 296 */
321STATIC void 297STATIC void
322xfs_bmap_trace_delete( 298xfs_bmap_trace_delete(
@@ -328,7 +304,7 @@ xfs_bmap_trace_delete(
328 int whichfork); /* data or attr fork */ 304 int whichfork); /* data or attr fork */
329 305
330/* 306/*
331 * Add bmap trace entry prior to a call to xfs_bmap_insert_exlist, or 307 * Add bmap trace entry prior to a call to xfs_iext_insert, or
332 * reading in the extents list from the disk (in the btree). 308 * reading in the extents list from the disk (in the btree).
333 */ 309 */
334STATIC void 310STATIC void
@@ -343,7 +319,7 @@ xfs_bmap_trace_insert(
343 int whichfork); /* data or attr fork */ 319 int whichfork); /* data or attr fork */
344 320
345/* 321/*
346 * Add bmap trace entry after updating an extent list entry in place. 322 * Add bmap trace entry after updating an extent record in place.
347 */ 323 */
348STATIC void 324STATIC void
349xfs_bmap_trace_post_update( 325xfs_bmap_trace_post_update(
@@ -354,7 +330,7 @@ xfs_bmap_trace_post_update(
354 int whichfork); /* data or attr fork */ 330 int whichfork); /* data or attr fork */
355 331
356/* 332/*
357 * Add bmap trace entry prior to updating an extent list entry in place. 333 * Add bmap trace entry prior to updating an extent record in place.
358 */ 334 */
359STATIC void 335STATIC void
360xfs_bmap_trace_pre_update( 336xfs_bmap_trace_pre_update(
@@ -413,19 +389,24 @@ STATIC int
413xfs_bmap_count_tree( 389xfs_bmap_count_tree(
414 xfs_mount_t *mp, 390 xfs_mount_t *mp,
415 xfs_trans_t *tp, 391 xfs_trans_t *tp,
392 xfs_ifork_t *ifp,
416 xfs_fsblock_t blockno, 393 xfs_fsblock_t blockno,
417 int levelin, 394 int levelin,
418 int *count); 395 int *count);
419 396
420STATIC int 397STATIC int
421xfs_bmap_count_leaves( 398xfs_bmap_count_leaves(
422 xfs_bmbt_rec_t *frp, 399 xfs_ifork_t *ifp,
400 xfs_extnum_t idx,
423 int numrecs, 401 int numrecs,
424 int *count); 402 int *count);
425 403
426STATIC int 404STATIC int
427xfs_bmap_disk_count_leaves( 405xfs_bmap_disk_count_leaves(
428 xfs_bmbt_rec_t *frp, 406 xfs_ifork_t *ifp,
407 xfs_mount_t *mp,
408 xfs_extnum_t idx,
409 xfs_bmbt_block_t *block,
429 int numrecs, 410 int numrecs,
430 int *count); 411 int *count);
431 412
@@ -537,7 +518,7 @@ xfs_bmap_add_attrfork_local(
537} 518}
538 519
539/* 520/*
540 * Called by xfs_bmapi to update extent list structure and the btree 521 * Called by xfs_bmapi to update file extent records and the btree
541 * after allocating space (or doing a delayed allocation). 522 * after allocating space (or doing a delayed allocation).
542 */ 523 */
543STATIC int /* error */ 524STATIC int /* error */
@@ -545,7 +526,7 @@ xfs_bmap_add_extent(
545 xfs_inode_t *ip, /* incore inode pointer */ 526 xfs_inode_t *ip, /* incore inode pointer */
546 xfs_extnum_t idx, /* extent number to update/insert */ 527 xfs_extnum_t idx, /* extent number to update/insert */
547 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 528 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
548 xfs_bmbt_irec_t *new, /* new data to put in extent list */ 529 xfs_bmbt_irec_t *new, /* new data to add to file extents */
549 xfs_fsblock_t *first, /* pointer to firstblock variable */ 530 xfs_fsblock_t *first, /* pointer to firstblock variable */
550 xfs_bmap_free_t *flist, /* list of extents to be freed */ 531 xfs_bmap_free_t *flist, /* list of extents to be freed */
551 int *logflagsp, /* inode logging flags */ 532 int *logflagsp, /* inode logging flags */
@@ -578,7 +559,7 @@ xfs_bmap_add_extent(
578 if (nextents == 0) { 559 if (nextents == 0) {
579 xfs_bmap_trace_insert(fname, "insert empty", ip, 0, 1, new, 560 xfs_bmap_trace_insert(fname, "insert empty", ip, 0, 1, new,
580 NULL, whichfork); 561 NULL, whichfork);
581 xfs_bmap_insert_exlist(ip, 0, 1, new, whichfork); 562 xfs_iext_insert(ifp, 0, 1, new);
582 ASSERT(cur == NULL); 563 ASSERT(cur == NULL);
583 ifp->if_lastex = 0; 564 ifp->if_lastex = 0;
584 if (!ISNULLSTARTBLOCK(new->br_startblock)) { 565 if (!ISNULLSTARTBLOCK(new->br_startblock)) {
@@ -614,7 +595,7 @@ xfs_bmap_add_extent(
614 /* 595 /*
615 * Get the record referred to by idx. 596 * Get the record referred to by idx.
616 */ 597 */
617 xfs_bmbt_get_all(&ifp->if_u1.if_extents[idx], &prev); 598 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx), &prev);
618 /* 599 /*
619 * If it's a real allocation record, and the new allocation ends 600 * If it's a real allocation record, and the new allocation ends
620 * after the start of the referred to record, then we're filling 601 * after the start of the referred to record, then we're filling
@@ -714,14 +695,13 @@ xfs_bmap_add_extent_delay_real(
714 xfs_inode_t *ip, /* incore inode pointer */ 695 xfs_inode_t *ip, /* incore inode pointer */
715 xfs_extnum_t idx, /* extent number to update/insert */ 696 xfs_extnum_t idx, /* extent number to update/insert */
716 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 697 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
717 xfs_bmbt_irec_t *new, /* new data to put in extent list */ 698 xfs_bmbt_irec_t *new, /* new data to add to file extents */
718 xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */ 699 xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */
719 xfs_fsblock_t *first, /* pointer to firstblock variable */ 700 xfs_fsblock_t *first, /* pointer to firstblock variable */
720 xfs_bmap_free_t *flist, /* list of extents to be freed */ 701 xfs_bmap_free_t *flist, /* list of extents to be freed */
721 int *logflagsp, /* inode logging flags */ 702 int *logflagsp, /* inode logging flags */
722 int rsvd) /* OK to use reserved data block allocation */ 703 int rsvd) /* OK to use reserved data block allocation */
723{ 704{
724 xfs_bmbt_rec_t *base; /* base of extent entry list */
725 xfs_btree_cur_t *cur; /* btree cursor */ 705 xfs_btree_cur_t *cur; /* btree cursor */
726 int diff; /* temp value */ 706 int diff; /* temp value */
727 xfs_bmbt_rec_t *ep; /* extent entry for idx */ 707 xfs_bmbt_rec_t *ep; /* extent entry for idx */
@@ -730,6 +710,7 @@ xfs_bmap_add_extent_delay_real(
730 static char fname[] = "xfs_bmap_add_extent_delay_real"; 710 static char fname[] = "xfs_bmap_add_extent_delay_real";
731#endif 711#endif
732 int i; /* temp state */ 712 int i; /* temp state */
713 xfs_ifork_t *ifp; /* inode fork pointer */
733 xfs_fileoff_t new_endoff; /* end offset of new entry */ 714 xfs_fileoff_t new_endoff; /* end offset of new entry */
734 xfs_bmbt_irec_t r[3]; /* neighbor extent entries */ 715 xfs_bmbt_irec_t r[3]; /* neighbor extent entries */
735 /* left is 0, right is 1, prev is 2 */ 716 /* left is 0, right is 1, prev is 2 */
@@ -763,8 +744,8 @@ xfs_bmap_add_extent_delay_real(
763 * Set up a bunch of variables to make the tests simpler. 744 * Set up a bunch of variables to make the tests simpler.
764 */ 745 */
765 cur = *curp; 746 cur = *curp;
766 base = ip->i_df.if_u1.if_extents; 747 ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
767 ep = &base[idx]; 748 ep = xfs_iext_get_ext(ifp, idx);
768 xfs_bmbt_get_all(ep, &PREV); 749 xfs_bmbt_get_all(ep, &PREV);
769 new_endoff = new->br_startoff + new->br_blockcount; 750 new_endoff = new->br_startoff + new->br_blockcount;
770 ASSERT(PREV.br_startoff <= new->br_startoff); 751 ASSERT(PREV.br_startoff <= new->br_startoff);
@@ -781,7 +762,7 @@ xfs_bmap_add_extent_delay_real(
781 * Don't set contiguous if the combined extent would be too large. 762 * Don't set contiguous if the combined extent would be too large.
782 */ 763 */
783 if (STATE_SET_TEST(LEFT_VALID, idx > 0)) { 764 if (STATE_SET_TEST(LEFT_VALID, idx > 0)) {
784 xfs_bmbt_get_all(ep - 1, &LEFT); 765 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &LEFT);
785 STATE_SET(LEFT_DELAY, ISNULLSTARTBLOCK(LEFT.br_startblock)); 766 STATE_SET(LEFT_DELAY, ISNULLSTARTBLOCK(LEFT.br_startblock));
786 } 767 }
787 STATE_SET(LEFT_CONTIG, 768 STATE_SET(LEFT_CONTIG,
@@ -798,7 +779,7 @@ xfs_bmap_add_extent_delay_real(
798 if (STATE_SET_TEST(RIGHT_VALID, 779 if (STATE_SET_TEST(RIGHT_VALID,
799 idx < 780 idx <
800 ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1)) { 781 ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1)) {
801 xfs_bmbt_get_all(ep + 1, &RIGHT); 782 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx + 1), &RIGHT);
802 STATE_SET(RIGHT_DELAY, ISNULLSTARTBLOCK(RIGHT.br_startblock)); 783 STATE_SET(RIGHT_DELAY, ISNULLSTARTBLOCK(RIGHT.br_startblock));
803 } 784 }
804 STATE_SET(RIGHT_CONTIG, 785 STATE_SET(RIGHT_CONTIG,
@@ -825,14 +806,14 @@ xfs_bmap_add_extent_delay_real(
825 */ 806 */
826 xfs_bmap_trace_pre_update(fname, "LF|RF|LC|RC", ip, idx - 1, 807 xfs_bmap_trace_pre_update(fname, "LF|RF|LC|RC", ip, idx - 1,
827 XFS_DATA_FORK); 808 XFS_DATA_FORK);
828 xfs_bmbt_set_blockcount(ep - 1, 809 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
829 LEFT.br_blockcount + PREV.br_blockcount + 810 LEFT.br_blockcount + PREV.br_blockcount +
830 RIGHT.br_blockcount); 811 RIGHT.br_blockcount);
831 xfs_bmap_trace_post_update(fname, "LF|RF|LC|RC", ip, idx - 1, 812 xfs_bmap_trace_post_update(fname, "LF|RF|LC|RC", ip, idx - 1,
832 XFS_DATA_FORK); 813 XFS_DATA_FORK);
833 xfs_bmap_trace_delete(fname, "LF|RF|LC|RC", ip, idx, 2, 814 xfs_bmap_trace_delete(fname, "LF|RF|LC|RC", ip, idx, 2,
834 XFS_DATA_FORK); 815 XFS_DATA_FORK);
835 xfs_bmap_delete_exlist(ip, idx, 2, XFS_DATA_FORK); 816 xfs_iext_remove(ifp, idx, 2);
836 ip->i_df.if_lastex = idx - 1; 817 ip->i_df.if_lastex = idx - 1;
837 ip->i_d.di_nextents--; 818 ip->i_d.di_nextents--;
838 if (cur == NULL) 819 if (cur == NULL)
@@ -867,14 +848,14 @@ xfs_bmap_add_extent_delay_real(
867 */ 848 */
868 xfs_bmap_trace_pre_update(fname, "LF|RF|LC", ip, idx - 1, 849 xfs_bmap_trace_pre_update(fname, "LF|RF|LC", ip, idx - 1,
869 XFS_DATA_FORK); 850 XFS_DATA_FORK);
870 xfs_bmbt_set_blockcount(ep - 1, 851 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
871 LEFT.br_blockcount + PREV.br_blockcount); 852 LEFT.br_blockcount + PREV.br_blockcount);
872 xfs_bmap_trace_post_update(fname, "LF|RF|LC", ip, idx - 1, 853 xfs_bmap_trace_post_update(fname, "LF|RF|LC", ip, idx - 1,
873 XFS_DATA_FORK); 854 XFS_DATA_FORK);
874 ip->i_df.if_lastex = idx - 1; 855 ip->i_df.if_lastex = idx - 1;
875 xfs_bmap_trace_delete(fname, "LF|RF|LC", ip, idx, 1, 856 xfs_bmap_trace_delete(fname, "LF|RF|LC", ip, idx, 1,
876 XFS_DATA_FORK); 857 XFS_DATA_FORK);
877 xfs_bmap_delete_exlist(ip, idx, 1, XFS_DATA_FORK); 858 xfs_iext_remove(ifp, idx, 1);
878 if (cur == NULL) 859 if (cur == NULL)
879 rval = XFS_ILOG_DEXT; 860 rval = XFS_ILOG_DEXT;
880 else { 861 else {
@@ -908,7 +889,7 @@ xfs_bmap_add_extent_delay_real(
908 ip->i_df.if_lastex = idx; 889 ip->i_df.if_lastex = idx;
909 xfs_bmap_trace_delete(fname, "LF|RF|RC", ip, idx + 1, 1, 890 xfs_bmap_trace_delete(fname, "LF|RF|RC", ip, idx + 1, 1,
910 XFS_DATA_FORK); 891 XFS_DATA_FORK);
911 xfs_bmap_delete_exlist(ip, idx + 1, 1, XFS_DATA_FORK); 892 xfs_iext_remove(ifp, idx + 1, 1);
912 if (cur == NULL) 893 if (cur == NULL)
913 rval = XFS_ILOG_DEXT; 894 rval = XFS_ILOG_DEXT;
914 else { 895 else {
@@ -964,7 +945,7 @@ xfs_bmap_add_extent_delay_real(
964 */ 945 */
965 xfs_bmap_trace_pre_update(fname, "LF|LC", ip, idx - 1, 946 xfs_bmap_trace_pre_update(fname, "LF|LC", ip, idx - 1,
966 XFS_DATA_FORK); 947 XFS_DATA_FORK);
967 xfs_bmbt_set_blockcount(ep - 1, 948 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
968 LEFT.br_blockcount + new->br_blockcount); 949 LEFT.br_blockcount + new->br_blockcount);
969 xfs_bmbt_set_startoff(ep, 950 xfs_bmbt_set_startoff(ep,
970 PREV.br_startoff + new->br_blockcount); 951 PREV.br_startoff + new->br_blockcount);
@@ -1010,7 +991,7 @@ xfs_bmap_add_extent_delay_real(
1010 xfs_bmbt_set_blockcount(ep, temp); 991 xfs_bmbt_set_blockcount(ep, temp);
1011 xfs_bmap_trace_insert(fname, "LF", ip, idx, 1, new, NULL, 992 xfs_bmap_trace_insert(fname, "LF", ip, idx, 1, new, NULL,
1012 XFS_DATA_FORK); 993 XFS_DATA_FORK);
1013 xfs_bmap_insert_exlist(ip, idx, 1, new, XFS_DATA_FORK); 994 xfs_iext_insert(ifp, idx, 1, new);
1014 ip->i_df.if_lastex = idx; 995 ip->i_df.if_lastex = idx;
1015 ip->i_d.di_nextents++; 996 ip->i_d.di_nextents++;
1016 if (cur == NULL) 997 if (cur == NULL)
@@ -1039,8 +1020,7 @@ xfs_bmap_add_extent_delay_real(
1039 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), 1020 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
1040 STARTBLOCKVAL(PREV.br_startblock) - 1021 STARTBLOCKVAL(PREV.br_startblock) -
1041 (cur ? cur->bc_private.b.allocated : 0)); 1022 (cur ? cur->bc_private.b.allocated : 0));
1042 base = ip->i_df.if_u1.if_extents; 1023 ep = xfs_iext_get_ext(ifp, idx + 1);
1043 ep = &base[idx + 1];
1044 xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); 1024 xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp));
1045 xfs_bmap_trace_post_update(fname, "LF", ip, idx + 1, 1025 xfs_bmap_trace_post_update(fname, "LF", ip, idx + 1,
1046 XFS_DATA_FORK); 1026 XFS_DATA_FORK);
@@ -1058,7 +1038,8 @@ xfs_bmap_add_extent_delay_real(
1058 xfs_bmap_trace_pre_update(fname, "RF|RC", ip, idx + 1, 1038 xfs_bmap_trace_pre_update(fname, "RF|RC", ip, idx + 1,
1059 XFS_DATA_FORK); 1039 XFS_DATA_FORK);
1060 xfs_bmbt_set_blockcount(ep, temp); 1040 xfs_bmbt_set_blockcount(ep, temp);
1061 xfs_bmbt_set_allf(ep + 1, new->br_startoff, new->br_startblock, 1041 xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, idx + 1),
1042 new->br_startoff, new->br_startblock,
1062 new->br_blockcount + RIGHT.br_blockcount, 1043 new->br_blockcount + RIGHT.br_blockcount,
1063 RIGHT.br_state); 1044 RIGHT.br_state);
1064 xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx + 1, 1045 xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx + 1,
@@ -1098,7 +1079,7 @@ xfs_bmap_add_extent_delay_real(
1098 xfs_bmbt_set_blockcount(ep, temp); 1079 xfs_bmbt_set_blockcount(ep, temp);
1099 xfs_bmap_trace_insert(fname, "RF", ip, idx + 1, 1, 1080 xfs_bmap_trace_insert(fname, "RF", ip, idx + 1, 1,
1100 new, NULL, XFS_DATA_FORK); 1081 new, NULL, XFS_DATA_FORK);
1101 xfs_bmap_insert_exlist(ip, idx + 1, 1, new, XFS_DATA_FORK); 1082 xfs_iext_insert(ifp, idx + 1, 1, new);
1102 ip->i_df.if_lastex = idx + 1; 1083 ip->i_df.if_lastex = idx + 1;
1103 ip->i_d.di_nextents++; 1084 ip->i_d.di_nextents++;
1104 if (cur == NULL) 1085 if (cur == NULL)
@@ -1127,8 +1108,7 @@ xfs_bmap_add_extent_delay_real(
1127 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), 1108 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
1128 STARTBLOCKVAL(PREV.br_startblock) - 1109 STARTBLOCKVAL(PREV.br_startblock) -
1129 (cur ? cur->bc_private.b.allocated : 0)); 1110 (cur ? cur->bc_private.b.allocated : 0));
1130 base = ip->i_df.if_u1.if_extents; 1111 ep = xfs_iext_get_ext(ifp, idx);
1131 ep = &base[idx];
1132 xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); 1112 xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp));
1133 xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK); 1113 xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK);
1134 *dnew = temp; 1114 *dnew = temp;
@@ -1149,7 +1129,7 @@ xfs_bmap_add_extent_delay_real(
1149 r[1].br_blockcount = temp2; 1129 r[1].br_blockcount = temp2;
1150 xfs_bmap_trace_insert(fname, "0", ip, idx + 1, 2, &r[0], &r[1], 1130 xfs_bmap_trace_insert(fname, "0", ip, idx + 1, 2, &r[0], &r[1],
1151 XFS_DATA_FORK); 1131 XFS_DATA_FORK);
1152 xfs_bmap_insert_exlist(ip, idx + 1, 2, &r[0], XFS_DATA_FORK); 1132 xfs_iext_insert(ifp, idx + 1, 2, &r[0]);
1153 ip->i_df.if_lastex = idx + 1; 1133 ip->i_df.if_lastex = idx + 1;
1154 ip->i_d.di_nextents++; 1134 ip->i_d.di_nextents++;
1155 if (cur == NULL) 1135 if (cur == NULL)
@@ -1204,13 +1184,13 @@ xfs_bmap_add_extent_delay_real(
1204 } 1184 }
1205 } 1185 }
1206 } 1186 }
1207 base = ip->i_df.if_u1.if_extents; 1187 ep = xfs_iext_get_ext(ifp, idx);
1208 ep = &base[idx];
1209 xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); 1188 xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp));
1210 xfs_bmap_trace_post_update(fname, "0", ip, idx, XFS_DATA_FORK); 1189 xfs_bmap_trace_post_update(fname, "0", ip, idx, XFS_DATA_FORK);
1211 xfs_bmap_trace_pre_update(fname, "0", ip, idx + 2, 1190 xfs_bmap_trace_pre_update(fname, "0", ip, idx + 2,
1212 XFS_DATA_FORK); 1191 XFS_DATA_FORK);
1213 xfs_bmbt_set_startblock(ep + 2, NULLSTARTBLOCK((int)temp2)); 1192 xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx + 2),
1193 NULLSTARTBLOCK((int)temp2));
1214 xfs_bmap_trace_post_update(fname, "0", ip, idx + 2, 1194 xfs_bmap_trace_post_update(fname, "0", ip, idx + 2,
1215 XFS_DATA_FORK); 1195 XFS_DATA_FORK);
1216 *dnew = temp + temp2; 1196 *dnew = temp + temp2;
@@ -1254,10 +1234,9 @@ xfs_bmap_add_extent_unwritten_real(
1254 xfs_inode_t *ip, /* incore inode pointer */ 1234 xfs_inode_t *ip, /* incore inode pointer */
1255 xfs_extnum_t idx, /* extent number to update/insert */ 1235 xfs_extnum_t idx, /* extent number to update/insert */
1256 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 1236 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
1257 xfs_bmbt_irec_t *new, /* new data to put in extent list */ 1237 xfs_bmbt_irec_t *new, /* new data to add to file extents */
1258 int *logflagsp) /* inode logging flags */ 1238 int *logflagsp) /* inode logging flags */
1259{ 1239{
1260 xfs_bmbt_rec_t *base; /* base of extent entry list */
1261 xfs_btree_cur_t *cur; /* btree cursor */ 1240 xfs_btree_cur_t *cur; /* btree cursor */
1262 xfs_bmbt_rec_t *ep; /* extent entry for idx */ 1241 xfs_bmbt_rec_t *ep; /* extent entry for idx */
1263 int error; /* error return value */ 1242 int error; /* error return value */
@@ -1265,6 +1244,7 @@ xfs_bmap_add_extent_unwritten_real(
1265 static char fname[] = "xfs_bmap_add_extent_unwritten_real"; 1244 static char fname[] = "xfs_bmap_add_extent_unwritten_real";
1266#endif 1245#endif
1267 int i; /* temp state */ 1246 int i; /* temp state */
1247 xfs_ifork_t *ifp; /* inode fork pointer */
1268 xfs_fileoff_t new_endoff; /* end offset of new entry */ 1248 xfs_fileoff_t new_endoff; /* end offset of new entry */
1269 xfs_exntst_t newext; /* new extent state */ 1249 xfs_exntst_t newext; /* new extent state */
1270 xfs_exntst_t oldext; /* old extent state */ 1250 xfs_exntst_t oldext; /* old extent state */
@@ -1298,8 +1278,8 @@ xfs_bmap_add_extent_unwritten_real(
1298 */ 1278 */
1299 error = 0; 1279 error = 0;
1300 cur = *curp; 1280 cur = *curp;
1301 base = ip->i_df.if_u1.if_extents; 1281 ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
1302 ep = &base[idx]; 1282 ep = xfs_iext_get_ext(ifp, idx);
1303 xfs_bmbt_get_all(ep, &PREV); 1283 xfs_bmbt_get_all(ep, &PREV);
1304 newext = new->br_state; 1284 newext = new->br_state;
1305 oldext = (newext == XFS_EXT_UNWRITTEN) ? 1285 oldext = (newext == XFS_EXT_UNWRITTEN) ?
@@ -1320,7 +1300,7 @@ xfs_bmap_add_extent_unwritten_real(
1320 * Don't set contiguous if the combined extent would be too large. 1300 * Don't set contiguous if the combined extent would be too large.
1321 */ 1301 */
1322 if (STATE_SET_TEST(LEFT_VALID, idx > 0)) { 1302 if (STATE_SET_TEST(LEFT_VALID, idx > 0)) {
1323 xfs_bmbt_get_all(ep - 1, &LEFT); 1303 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &LEFT);
1324 STATE_SET(LEFT_DELAY, ISNULLSTARTBLOCK(LEFT.br_startblock)); 1304 STATE_SET(LEFT_DELAY, ISNULLSTARTBLOCK(LEFT.br_startblock));
1325 } 1305 }
1326 STATE_SET(LEFT_CONTIG, 1306 STATE_SET(LEFT_CONTIG,
@@ -1337,7 +1317,7 @@ xfs_bmap_add_extent_unwritten_real(
1337 if (STATE_SET_TEST(RIGHT_VALID, 1317 if (STATE_SET_TEST(RIGHT_VALID,
1338 idx < 1318 idx <
1339 ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1)) { 1319 ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1)) {
1340 xfs_bmbt_get_all(ep + 1, &RIGHT); 1320 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx + 1), &RIGHT);
1341 STATE_SET(RIGHT_DELAY, ISNULLSTARTBLOCK(RIGHT.br_startblock)); 1321 STATE_SET(RIGHT_DELAY, ISNULLSTARTBLOCK(RIGHT.br_startblock));
1342 } 1322 }
1343 STATE_SET(RIGHT_CONTIG, 1323 STATE_SET(RIGHT_CONTIG,
@@ -1363,14 +1343,14 @@ xfs_bmap_add_extent_unwritten_real(
1363 */ 1343 */
1364 xfs_bmap_trace_pre_update(fname, "LF|RF|LC|RC", ip, idx - 1, 1344 xfs_bmap_trace_pre_update(fname, "LF|RF|LC|RC", ip, idx - 1,
1365 XFS_DATA_FORK); 1345 XFS_DATA_FORK);
1366 xfs_bmbt_set_blockcount(ep - 1, 1346 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
1367 LEFT.br_blockcount + PREV.br_blockcount + 1347 LEFT.br_blockcount + PREV.br_blockcount +
1368 RIGHT.br_blockcount); 1348 RIGHT.br_blockcount);
1369 xfs_bmap_trace_post_update(fname, "LF|RF|LC|RC", ip, idx - 1, 1349 xfs_bmap_trace_post_update(fname, "LF|RF|LC|RC", ip, idx - 1,
1370 XFS_DATA_FORK); 1350 XFS_DATA_FORK);
1371 xfs_bmap_trace_delete(fname, "LF|RF|LC|RC", ip, idx, 2, 1351 xfs_bmap_trace_delete(fname, "LF|RF|LC|RC", ip, idx, 2,
1372 XFS_DATA_FORK); 1352 XFS_DATA_FORK);
1373 xfs_bmap_delete_exlist(ip, idx, 2, XFS_DATA_FORK); 1353 xfs_iext_remove(ifp, idx, 2);
1374 ip->i_df.if_lastex = idx - 1; 1354 ip->i_df.if_lastex = idx - 1;
1375 ip->i_d.di_nextents -= 2; 1355 ip->i_d.di_nextents -= 2;
1376 if (cur == NULL) 1356 if (cur == NULL)
@@ -1409,14 +1389,14 @@ xfs_bmap_add_extent_unwritten_real(
1409 */ 1389 */
1410 xfs_bmap_trace_pre_update(fname, "LF|RF|LC", ip, idx - 1, 1390 xfs_bmap_trace_pre_update(fname, "LF|RF|LC", ip, idx - 1,
1411 XFS_DATA_FORK); 1391 XFS_DATA_FORK);
1412 xfs_bmbt_set_blockcount(ep - 1, 1392 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
1413 LEFT.br_blockcount + PREV.br_blockcount); 1393 LEFT.br_blockcount + PREV.br_blockcount);
1414 xfs_bmap_trace_post_update(fname, "LF|RF|LC", ip, idx - 1, 1394 xfs_bmap_trace_post_update(fname, "LF|RF|LC", ip, idx - 1,
1415 XFS_DATA_FORK); 1395 XFS_DATA_FORK);
1416 ip->i_df.if_lastex = idx - 1; 1396 ip->i_df.if_lastex = idx - 1;
1417 xfs_bmap_trace_delete(fname, "LF|RF|LC", ip, idx, 1, 1397 xfs_bmap_trace_delete(fname, "LF|RF|LC", ip, idx, 1,
1418 XFS_DATA_FORK); 1398 XFS_DATA_FORK);
1419 xfs_bmap_delete_exlist(ip, idx, 1, XFS_DATA_FORK); 1399 xfs_iext_remove(ifp, idx, 1);
1420 ip->i_d.di_nextents--; 1400 ip->i_d.di_nextents--;
1421 if (cur == NULL) 1401 if (cur == NULL)
1422 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 1402 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
@@ -1456,7 +1436,7 @@ xfs_bmap_add_extent_unwritten_real(
1456 ip->i_df.if_lastex = idx; 1436 ip->i_df.if_lastex = idx;
1457 xfs_bmap_trace_delete(fname, "LF|RF|RC", ip, idx + 1, 1, 1437 xfs_bmap_trace_delete(fname, "LF|RF|RC", ip, idx + 1, 1,
1458 XFS_DATA_FORK); 1438 XFS_DATA_FORK);
1459 xfs_bmap_delete_exlist(ip, idx + 1, 1, XFS_DATA_FORK); 1439 xfs_iext_remove(ifp, idx + 1, 1);
1460 ip->i_d.di_nextents--; 1440 ip->i_d.di_nextents--;
1461 if (cur == NULL) 1441 if (cur == NULL)
1462 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 1442 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
@@ -1516,7 +1496,7 @@ xfs_bmap_add_extent_unwritten_real(
1516 */ 1496 */
1517 xfs_bmap_trace_pre_update(fname, "LF|LC", ip, idx - 1, 1497 xfs_bmap_trace_pre_update(fname, "LF|LC", ip, idx - 1,
1518 XFS_DATA_FORK); 1498 XFS_DATA_FORK);
1519 xfs_bmbt_set_blockcount(ep - 1, 1499 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
1520 LEFT.br_blockcount + new->br_blockcount); 1500 LEFT.br_blockcount + new->br_blockcount);
1521 xfs_bmbt_set_startoff(ep, 1501 xfs_bmbt_set_startoff(ep,
1522 PREV.br_startoff + new->br_blockcount); 1502 PREV.br_startoff + new->br_blockcount);
@@ -1571,7 +1551,7 @@ xfs_bmap_add_extent_unwritten_real(
1571 xfs_bmap_trace_post_update(fname, "LF", ip, idx, XFS_DATA_FORK); 1551 xfs_bmap_trace_post_update(fname, "LF", ip, idx, XFS_DATA_FORK);
1572 xfs_bmap_trace_insert(fname, "LF", ip, idx, 1, new, NULL, 1552 xfs_bmap_trace_insert(fname, "LF", ip, idx, 1, new, NULL,
1573 XFS_DATA_FORK); 1553 XFS_DATA_FORK);
1574 xfs_bmap_insert_exlist(ip, idx, 1, new, XFS_DATA_FORK); 1554 xfs_iext_insert(ifp, idx, 1, new);
1575 ip->i_df.if_lastex = idx; 1555 ip->i_df.if_lastex = idx;
1576 ip->i_d.di_nextents++; 1556 ip->i_d.di_nextents++;
1577 if (cur == NULL) 1557 if (cur == NULL)
@@ -1609,7 +1589,8 @@ xfs_bmap_add_extent_unwritten_real(
1609 PREV.br_blockcount - new->br_blockcount); 1589 PREV.br_blockcount - new->br_blockcount);
1610 xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx, 1590 xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx,
1611 XFS_DATA_FORK); 1591 XFS_DATA_FORK);
1612 xfs_bmbt_set_allf(ep + 1, new->br_startoff, new->br_startblock, 1592 xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, idx + 1),
1593 new->br_startoff, new->br_startblock,
1613 new->br_blockcount + RIGHT.br_blockcount, newext); 1594 new->br_blockcount + RIGHT.br_blockcount, newext);
1614 xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx + 1, 1595 xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx + 1,
1615 XFS_DATA_FORK); 1596 XFS_DATA_FORK);
@@ -1649,7 +1630,7 @@ xfs_bmap_add_extent_unwritten_real(
1649 xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK); 1630 xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK);
1650 xfs_bmap_trace_insert(fname, "RF", ip, idx + 1, 1, 1631 xfs_bmap_trace_insert(fname, "RF", ip, idx + 1, 1,
1651 new, NULL, XFS_DATA_FORK); 1632 new, NULL, XFS_DATA_FORK);
1652 xfs_bmap_insert_exlist(ip, idx + 1, 1, new, XFS_DATA_FORK); 1633 xfs_iext_insert(ifp, idx + 1, 1, new);
1653 ip->i_df.if_lastex = idx + 1; 1634 ip->i_df.if_lastex = idx + 1;
1654 ip->i_d.di_nextents++; 1635 ip->i_d.di_nextents++;
1655 if (cur == NULL) 1636 if (cur == NULL)
@@ -1696,7 +1677,7 @@ xfs_bmap_add_extent_unwritten_real(
1696 r[1].br_state = oldext; 1677 r[1].br_state = oldext;
1697 xfs_bmap_trace_insert(fname, "0", ip, idx + 1, 2, &r[0], &r[1], 1678 xfs_bmap_trace_insert(fname, "0", ip, idx + 1, 2, &r[0], &r[1],
1698 XFS_DATA_FORK); 1679 XFS_DATA_FORK);
1699 xfs_bmap_insert_exlist(ip, idx + 1, 2, &r[0], XFS_DATA_FORK); 1680 xfs_iext_insert(ifp, idx + 1, 2, &r[0]);
1700 ip->i_df.if_lastex = idx + 1; 1681 ip->i_df.if_lastex = idx + 1;
1701 ip->i_d.di_nextents += 2; 1682 ip->i_d.di_nextents += 2;
1702 if (cur == NULL) 1683 if (cur == NULL)
@@ -1770,15 +1751,15 @@ xfs_bmap_add_extent_hole_delay(
1770 xfs_inode_t *ip, /* incore inode pointer */ 1751 xfs_inode_t *ip, /* incore inode pointer */
1771 xfs_extnum_t idx, /* extent number to update/insert */ 1752 xfs_extnum_t idx, /* extent number to update/insert */
1772 xfs_btree_cur_t *cur, /* if null, not a btree */ 1753 xfs_btree_cur_t *cur, /* if null, not a btree */
1773 xfs_bmbt_irec_t *new, /* new data to put in extent list */ 1754 xfs_bmbt_irec_t *new, /* new data to add to file extents */
1774 int *logflagsp, /* inode logging flags */ 1755 int *logflagsp, /* inode logging flags */
1775 int rsvd) /* OK to allocate reserved blocks */ 1756 int rsvd) /* OK to allocate reserved blocks */
1776{ 1757{
1777 xfs_bmbt_rec_t *base; /* base of extent entry list */ 1758 xfs_bmbt_rec_t *ep; /* extent record for idx */
1778 xfs_bmbt_rec_t *ep; /* extent list entry for idx */
1779#ifdef XFS_BMAP_TRACE 1759#ifdef XFS_BMAP_TRACE
1780 static char fname[] = "xfs_bmap_add_extent_hole_delay"; 1760 static char fname[] = "xfs_bmap_add_extent_hole_delay";
1781#endif 1761#endif
1762 xfs_ifork_t *ifp; /* inode fork pointer */
1782 xfs_bmbt_irec_t left; /* left neighbor extent entry */ 1763 xfs_bmbt_irec_t left; /* left neighbor extent entry */
1783 xfs_filblks_t newlen=0; /* new indirect size */ 1764 xfs_filblks_t newlen=0; /* new indirect size */
1784 xfs_filblks_t oldlen=0; /* old indirect size */ 1765 xfs_filblks_t oldlen=0; /* old indirect size */
@@ -1799,15 +1780,15 @@ xfs_bmap_add_extent_hole_delay(
1799 ((state &= ~MASK(b)), 0)) 1780 ((state &= ~MASK(b)), 0))
1800#define SWITCH_STATE (state & MASK2(LEFT_CONTIG, RIGHT_CONTIG)) 1781#define SWITCH_STATE (state & MASK2(LEFT_CONTIG, RIGHT_CONTIG))
1801 1782
1802 base = ip->i_df.if_u1.if_extents; 1783 ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
1803 ep = &base[idx]; 1784 ep = xfs_iext_get_ext(ifp, idx);
1804 state = 0; 1785 state = 0;
1805 ASSERT(ISNULLSTARTBLOCK(new->br_startblock)); 1786 ASSERT(ISNULLSTARTBLOCK(new->br_startblock));
1806 /* 1787 /*
1807 * Check and set flags if this segment has a left neighbor 1788 * Check and set flags if this segment has a left neighbor
1808 */ 1789 */
1809 if (STATE_SET_TEST(LEFT_VALID, idx > 0)) { 1790 if (STATE_SET_TEST(LEFT_VALID, idx > 0)) {
1810 xfs_bmbt_get_all(ep - 1, &left); 1791 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &left);
1811 STATE_SET(LEFT_DELAY, ISNULLSTARTBLOCK(left.br_startblock)); 1792 STATE_SET(LEFT_DELAY, ISNULLSTARTBLOCK(left.br_startblock));
1812 } 1793 }
1813 /* 1794 /*
@@ -1844,23 +1825,24 @@ xfs_bmap_add_extent_hole_delay(
1844 /* 1825 /*
1845 * New allocation is contiguous with delayed allocations 1826 * New allocation is contiguous with delayed allocations
1846 * on the left and on the right. 1827 * on the left and on the right.
1847 * Merge all three into a single extent list entry. 1828 * Merge all three into a single extent record.
1848 */ 1829 */
1849 temp = left.br_blockcount + new->br_blockcount + 1830 temp = left.br_blockcount + new->br_blockcount +
1850 right.br_blockcount; 1831 right.br_blockcount;
1851 xfs_bmap_trace_pre_update(fname, "LC|RC", ip, idx - 1, 1832 xfs_bmap_trace_pre_update(fname, "LC|RC", ip, idx - 1,
1852 XFS_DATA_FORK); 1833 XFS_DATA_FORK);
1853 xfs_bmbt_set_blockcount(ep - 1, temp); 1834 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), temp);
1854 oldlen = STARTBLOCKVAL(left.br_startblock) + 1835 oldlen = STARTBLOCKVAL(left.br_startblock) +
1855 STARTBLOCKVAL(new->br_startblock) + 1836 STARTBLOCKVAL(new->br_startblock) +
1856 STARTBLOCKVAL(right.br_startblock); 1837 STARTBLOCKVAL(right.br_startblock);
1857 newlen = xfs_bmap_worst_indlen(ip, temp); 1838 newlen = xfs_bmap_worst_indlen(ip, temp);
1858 xfs_bmbt_set_startblock(ep - 1, NULLSTARTBLOCK((int)newlen)); 1839 xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx - 1),
1840 NULLSTARTBLOCK((int)newlen));
1859 xfs_bmap_trace_post_update(fname, "LC|RC", ip, idx - 1, 1841 xfs_bmap_trace_post_update(fname, "LC|RC", ip, idx - 1,
1860 XFS_DATA_FORK); 1842 XFS_DATA_FORK);
1861 xfs_bmap_trace_delete(fname, "LC|RC", ip, idx, 1, 1843 xfs_bmap_trace_delete(fname, "LC|RC", ip, idx, 1,
1862 XFS_DATA_FORK); 1844 XFS_DATA_FORK);
1863 xfs_bmap_delete_exlist(ip, idx, 1, XFS_DATA_FORK); 1845 xfs_iext_remove(ifp, idx, 1);
1864 ip->i_df.if_lastex = idx - 1; 1846 ip->i_df.if_lastex = idx - 1;
1865 break; 1847 break;
1866 1848
@@ -1873,11 +1855,12 @@ xfs_bmap_add_extent_hole_delay(
1873 temp = left.br_blockcount + new->br_blockcount; 1855 temp = left.br_blockcount + new->br_blockcount;
1874 xfs_bmap_trace_pre_update(fname, "LC", ip, idx - 1, 1856 xfs_bmap_trace_pre_update(fname, "LC", ip, idx - 1,
1875 XFS_DATA_FORK); 1857 XFS_DATA_FORK);
1876 xfs_bmbt_set_blockcount(ep - 1, temp); 1858 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), temp);
1877 oldlen = STARTBLOCKVAL(left.br_startblock) + 1859 oldlen = STARTBLOCKVAL(left.br_startblock) +
1878 STARTBLOCKVAL(new->br_startblock); 1860 STARTBLOCKVAL(new->br_startblock);
1879 newlen = xfs_bmap_worst_indlen(ip, temp); 1861 newlen = xfs_bmap_worst_indlen(ip, temp);
1880 xfs_bmbt_set_startblock(ep - 1, NULLSTARTBLOCK((int)newlen)); 1862 xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx - 1),
1863 NULLSTARTBLOCK((int)newlen));
1881 xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, 1864 xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1,
1882 XFS_DATA_FORK); 1865 XFS_DATA_FORK);
1883 ip->i_df.if_lastex = idx - 1; 1866 ip->i_df.if_lastex = idx - 1;
@@ -1909,7 +1892,7 @@ xfs_bmap_add_extent_hole_delay(
1909 oldlen = newlen = 0; 1892 oldlen = newlen = 0;
1910 xfs_bmap_trace_insert(fname, "0", ip, idx, 1, new, NULL, 1893 xfs_bmap_trace_insert(fname, "0", ip, idx, 1, new, NULL,
1911 XFS_DATA_FORK); 1894 XFS_DATA_FORK);
1912 xfs_bmap_insert_exlist(ip, idx, 1, new, XFS_DATA_FORK); 1895 xfs_iext_insert(ifp, idx, 1, new);
1913 ip->i_df.if_lastex = idx; 1896 ip->i_df.if_lastex = idx;
1914 break; 1897 break;
1915 } 1898 }
@@ -1940,7 +1923,7 @@ xfs_bmap_add_extent_hole_real(
1940 xfs_inode_t *ip, /* incore inode pointer */ 1923 xfs_inode_t *ip, /* incore inode pointer */
1941 xfs_extnum_t idx, /* extent number to update/insert */ 1924 xfs_extnum_t idx, /* extent number to update/insert */
1942 xfs_btree_cur_t *cur, /* if null, not a btree */ 1925 xfs_btree_cur_t *cur, /* if null, not a btree */
1943 xfs_bmbt_irec_t *new, /* new data to put in extent list */ 1926 xfs_bmbt_irec_t *new, /* new data to add to file extents */
1944 int *logflagsp, /* inode logging flags */ 1927 int *logflagsp, /* inode logging flags */
1945 int whichfork) /* data or attr fork */ 1928 int whichfork) /* data or attr fork */
1946{ 1929{
@@ -1970,13 +1953,13 @@ xfs_bmap_add_extent_hole_real(
1970 1953
1971 ifp = XFS_IFORK_PTR(ip, whichfork); 1954 ifp = XFS_IFORK_PTR(ip, whichfork);
1972 ASSERT(idx <= ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)); 1955 ASSERT(idx <= ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t));
1973 ep = &ifp->if_u1.if_extents[idx]; 1956 ep = xfs_iext_get_ext(ifp, idx);
1974 state = 0; 1957 state = 0;
1975 /* 1958 /*
1976 * Check and set flags if this segment has a left neighbor. 1959 * Check and set flags if this segment has a left neighbor.
1977 */ 1960 */
1978 if (STATE_SET_TEST(LEFT_VALID, idx > 0)) { 1961 if (STATE_SET_TEST(LEFT_VALID, idx > 0)) {
1979 xfs_bmbt_get_all(ep - 1, &left); 1962 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &left);
1980 STATE_SET(LEFT_DELAY, ISNULLSTARTBLOCK(left.br_startblock)); 1963 STATE_SET(LEFT_DELAY, ISNULLSTARTBLOCK(left.br_startblock));
1981 } 1964 }
1982 /* 1965 /*
@@ -2019,18 +2002,18 @@ xfs_bmap_add_extent_hole_real(
2019 /* 2002 /*
2020 * New allocation is contiguous with real allocations on the 2003 * New allocation is contiguous with real allocations on the
2021 * left and on the right. 2004 * left and on the right.
2022 * Merge all three into a single extent list entry. 2005 * Merge all three into a single extent record.
2023 */ 2006 */
2024 xfs_bmap_trace_pre_update(fname, "LC|RC", ip, idx - 1, 2007 xfs_bmap_trace_pre_update(fname, "LC|RC", ip, idx - 1,
2025 whichfork); 2008 whichfork);
2026 xfs_bmbt_set_blockcount(ep - 1, 2009 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
2027 left.br_blockcount + new->br_blockcount + 2010 left.br_blockcount + new->br_blockcount +
2028 right.br_blockcount); 2011 right.br_blockcount);
2029 xfs_bmap_trace_post_update(fname, "LC|RC", ip, idx - 1, 2012 xfs_bmap_trace_post_update(fname, "LC|RC", ip, idx - 1,
2030 whichfork); 2013 whichfork);
2031 xfs_bmap_trace_delete(fname, "LC|RC", ip, 2014 xfs_bmap_trace_delete(fname, "LC|RC", ip,
2032 idx, 1, whichfork); 2015 idx, 1, whichfork);
2033 xfs_bmap_delete_exlist(ip, idx, 1, whichfork); 2016 xfs_iext_remove(ifp, idx, 1);
2034 ifp->if_lastex = idx - 1; 2017 ifp->if_lastex = idx - 1;
2035 XFS_IFORK_NEXT_SET(ip, whichfork, 2018 XFS_IFORK_NEXT_SET(ip, whichfork,
2036 XFS_IFORK_NEXTENTS(ip, whichfork) - 1); 2019 XFS_IFORK_NEXTENTS(ip, whichfork) - 1);
@@ -2062,7 +2045,7 @@ xfs_bmap_add_extent_hole_real(
2062 * Merge the new allocation with the left neighbor. 2045 * Merge the new allocation with the left neighbor.
2063 */ 2046 */
2064 xfs_bmap_trace_pre_update(fname, "LC", ip, idx - 1, whichfork); 2047 xfs_bmap_trace_pre_update(fname, "LC", ip, idx - 1, whichfork);
2065 xfs_bmbt_set_blockcount(ep - 1, 2048 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1),
2066 left.br_blockcount + new->br_blockcount); 2049 left.br_blockcount + new->br_blockcount);
2067 xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, whichfork); 2050 xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, whichfork);
2068 ifp->if_lastex = idx - 1; 2051 ifp->if_lastex = idx - 1;
@@ -2116,7 +2099,7 @@ xfs_bmap_add_extent_hole_real(
2116 */ 2099 */
2117 xfs_bmap_trace_insert(fname, "0", ip, idx, 1, new, NULL, 2100 xfs_bmap_trace_insert(fname, "0", ip, idx, 1, new, NULL,
2118 whichfork); 2101 whichfork);
2119 xfs_bmap_insert_exlist(ip, idx, 1, new, whichfork); 2102 xfs_iext_insert(ifp, idx, 1, new);
2120 ifp->if_lastex = idx; 2103 ifp->if_lastex = idx;
2121 XFS_IFORK_NEXT_SET(ip, whichfork, 2104 XFS_IFORK_NEXT_SET(ip, whichfork,
2122 XFS_IFORK_NEXTENTS(ip, whichfork) + 1); 2105 XFS_IFORK_NEXTENTS(ip, whichfork) + 1);
@@ -2311,25 +2294,15 @@ xfs_bmap_extsize_align(
2311 2294
2312#define XFS_ALLOC_GAP_UNITS 4 2295#define XFS_ALLOC_GAP_UNITS 4
2313 2296
2314/*
2315 * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file.
2316 * It figures out where to ask the underlying allocator to put the new extent.
2317 */
2318STATIC int 2297STATIC int
2319xfs_bmap_alloc( 2298xfs_bmap_adjacent(
2320 xfs_bmalloca_t *ap) /* bmap alloc argument struct */ 2299 xfs_bmalloca_t *ap) /* bmap alloc argument struct */
2321{ 2300{
2322 xfs_fsblock_t adjust; /* adjustment to block numbers */ 2301 xfs_fsblock_t adjust; /* adjustment to block numbers */
2323 xfs_alloctype_t atype=0; /* type for allocation routines */
2324 int error; /* error return value */
2325 xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */ 2302 xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */
2326 xfs_mount_t *mp; /* mount point structure */ 2303 xfs_mount_t *mp; /* mount point structure */
2327 int nullfb; /* true if ap->firstblock isn't set */ 2304 int nullfb; /* true if ap->firstblock isn't set */
2328 int rt; /* true if inode is realtime */ 2305 int rt; /* true if inode is realtime */
2329 xfs_extlen_t prod = 0; /* product factor for allocators */
2330 xfs_extlen_t ralen = 0; /* realtime allocation length */
2331 xfs_extlen_t align; /* minimum allocation alignment */
2332 xfs_rtblock_t rtx;
2333 2306
2334#define ISVALID(x,y) \ 2307#define ISVALID(x,y) \
2335 (rt ? \ 2308 (rt ? \
@@ -2338,75 +2311,10 @@ xfs_bmap_alloc(
2338 XFS_FSB_TO_AGNO(mp, x) < mp->m_sb.sb_agcount && \ 2311 XFS_FSB_TO_AGNO(mp, x) < mp->m_sb.sb_agcount && \
2339 XFS_FSB_TO_AGBNO(mp, x) < mp->m_sb.sb_agblocks) 2312 XFS_FSB_TO_AGBNO(mp, x) < mp->m_sb.sb_agblocks)
2340 2313
2341 /*
2342 * Set up variables.
2343 */
2344 mp = ap->ip->i_mount; 2314 mp = ap->ip->i_mount;
2345 nullfb = ap->firstblock == NULLFSBLOCK; 2315 nullfb = ap->firstblock == NULLFSBLOCK;
2346 rt = XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata; 2316 rt = XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata;
2347 fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock); 2317 fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock);
2348 if (rt) {
2349 align = ap->ip->i_d.di_extsize ?
2350 ap->ip->i_d.di_extsize : mp->m_sb.sb_rextsize;
2351 /* Set prod to match the extent size */
2352 prod = align / mp->m_sb.sb_rextsize;
2353
2354 error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp,
2355 align, rt, ap->eof, 0,
2356 ap->conv, &ap->off, &ap->alen);
2357 if (error)
2358 return error;
2359 ASSERT(ap->alen);
2360 ASSERT(ap->alen % mp->m_sb.sb_rextsize == 0);
2361
2362 /*
2363 * If the offset & length are not perfectly aligned
2364 * then kill prod, it will just get us in trouble.
2365 */
2366 if (do_mod(ap->off, align) || ap->alen % align)
2367 prod = 1;
2368 /*
2369 * Set ralen to be the actual requested length in rtextents.
2370 */
2371 ralen = ap->alen / mp->m_sb.sb_rextsize;
2372 /*
2373 * If the old value was close enough to MAXEXTLEN that
2374 * we rounded up to it, cut it back so it's valid again.
2375 * Note that if it's a really large request (bigger than
2376 * MAXEXTLEN), we don't hear about that number, and can't
2377 * adjust the starting point to match it.
2378 */
2379 if (ralen * mp->m_sb.sb_rextsize >= MAXEXTLEN)
2380 ralen = MAXEXTLEN / mp->m_sb.sb_rextsize;
2381 /*
2382 * If it's an allocation to an empty file at offset 0,
2383 * pick an extent that will space things out in the rt area.
2384 */
2385 if (ap->eof && ap->off == 0) {
2386 error = xfs_rtpick_extent(mp, ap->tp, ralen, &rtx);
2387 if (error)
2388 return error;
2389 ap->rval = rtx * mp->m_sb.sb_rextsize;
2390 } else
2391 ap->rval = 0;
2392 } else {
2393 align = (ap->userdata && ap->ip->i_d.di_extsize &&
2394 (ap->ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE)) ?
2395 ap->ip->i_d.di_extsize : 0;
2396 if (unlikely(align)) {
2397 error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp,
2398 align, rt,
2399 ap->eof, 0, ap->conv,
2400 &ap->off, &ap->alen);
2401 ASSERT(!error);
2402 ASSERT(ap->alen);
2403 }
2404 if (nullfb)
2405 ap->rval = XFS_INO_TO_FSB(mp, ap->ip->i_ino);
2406 else
2407 ap->rval = ap->firstblock;
2408 }
2409
2410 /* 2318 /*
2411 * If allocating at eof, and there's a previous real block, 2319 * If allocating at eof, and there's a previous real block,
2412 * try to use it's last block as our starting point. 2320 * try to use it's last block as our starting point.
@@ -2531,287 +2439,384 @@ xfs_bmap_alloc(
2531 else if (gotbno != NULLFSBLOCK) 2439 else if (gotbno != NULLFSBLOCK)
2532 ap->rval = gotbno; 2440 ap->rval = gotbno;
2533 } 2441 }
2442#undef ISVALID
2443 return 0;
2444}
2445
2446STATIC int
2447xfs_bmap_rtalloc(
2448 xfs_bmalloca_t *ap) /* bmap alloc argument struct */
2449{
2450 xfs_alloctype_t atype = 0; /* type for allocation routines */
2451 int error; /* error return value */
2452 xfs_mount_t *mp; /* mount point structure */
2453 xfs_extlen_t prod = 0; /* product factor for allocators */
2454 xfs_extlen_t ralen = 0; /* realtime allocation length */
2455 xfs_extlen_t align; /* minimum allocation alignment */
2456 xfs_rtblock_t rtx; /* realtime extent number */
2457 xfs_rtblock_t rtb;
2458
2459 mp = ap->ip->i_mount;
2460 align = ap->ip->i_d.di_extsize ?
2461 ap->ip->i_d.di_extsize : mp->m_sb.sb_rextsize;
2462 prod = align / mp->m_sb.sb_rextsize;
2463 error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp,
2464 align, 1, ap->eof, 0,
2465 ap->conv, &ap->off, &ap->alen);
2466 if (error)
2467 return error;
2468 ASSERT(ap->alen);
2469 ASSERT(ap->alen % mp->m_sb.sb_rextsize == 0);
2470
2471 /*
2472 * If the offset & length are not perfectly aligned
2473 * then kill prod, it will just get us in trouble.
2474 */
2475 if (do_mod(ap->off, align) || ap->alen % align)
2476 prod = 1;
2477 /*
2478 * Set ralen to be the actual requested length in rtextents.
2479 */
2480 ralen = ap->alen / mp->m_sb.sb_rextsize;
2481 /*
2482 * If the old value was close enough to MAXEXTLEN that
2483 * we rounded up to it, cut it back so it's valid again.
2484 * Note that if it's a really large request (bigger than
2485 * MAXEXTLEN), we don't hear about that number, and can't
2486 * adjust the starting point to match it.
2487 */
2488 if (ralen * mp->m_sb.sb_rextsize >= MAXEXTLEN)
2489 ralen = MAXEXTLEN / mp->m_sb.sb_rextsize;
2490 /*
2491 * If it's an allocation to an empty file at offset 0,
2492 * pick an extent that will space things out in the rt area.
2493 */
2494 if (ap->eof && ap->off == 0) {
2495 error = xfs_rtpick_extent(mp, ap->tp, ralen, &rtx);
2496 if (error)
2497 return error;
2498 ap->rval = rtx * mp->m_sb.sb_rextsize;
2499 } else {
2500 ap->rval = 0;
2501 }
2502
2503 xfs_bmap_adjacent(ap);
2504
2505 /*
2506 * Realtime allocation, done through xfs_rtallocate_extent.
2507 */
2508 atype = ap->rval == 0 ? XFS_ALLOCTYPE_ANY_AG : XFS_ALLOCTYPE_NEAR_BNO;
2509 do_div(ap->rval, mp->m_sb.sb_rextsize);
2510 rtb = ap->rval;
2511 ap->alen = ralen;
2512 if ((error = xfs_rtallocate_extent(ap->tp, ap->rval, 1, ap->alen,
2513 &ralen, atype, ap->wasdel, prod, &rtb)))
2514 return error;
2515 if (rtb == NULLFSBLOCK && prod > 1 &&
2516 (error = xfs_rtallocate_extent(ap->tp, ap->rval, 1,
2517 ap->alen, &ralen, atype,
2518 ap->wasdel, 1, &rtb)))
2519 return error;
2520 ap->rval = rtb;
2521 if (ap->rval != NULLFSBLOCK) {
2522 ap->rval *= mp->m_sb.sb_rextsize;
2523 ralen *= mp->m_sb.sb_rextsize;
2524 ap->alen = ralen;
2525 ap->ip->i_d.di_nblocks += ralen;
2526 xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE);
2527 if (ap->wasdel)
2528 ap->ip->i_delayed_blks -= ralen;
2529 /*
2530 * Adjust the disk quota also. This was reserved
2531 * earlier.
2532 */
2533 XFS_TRANS_MOD_DQUOT_BYINO(mp, ap->tp, ap->ip,
2534 ap->wasdel ? XFS_TRANS_DQ_DELRTBCOUNT :
2535 XFS_TRANS_DQ_RTBCOUNT, (long) ralen);
2536 } else {
2537 ap->alen = 0;
2538 }
2539 return 0;
2540}
2541
2542STATIC int
2543xfs_bmap_btalloc(
2544 xfs_bmalloca_t *ap) /* bmap alloc argument struct */
2545{
2546 xfs_mount_t *mp; /* mount point structure */
2547 xfs_alloctype_t atype = 0; /* type for allocation routines */
2548 xfs_extlen_t align; /* minimum allocation alignment */
2549 xfs_agnumber_t ag;
2550 xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */
2551 xfs_agnumber_t startag;
2552 xfs_alloc_arg_t args;
2553 xfs_extlen_t blen;
2554 xfs_extlen_t delta;
2555 xfs_extlen_t longest;
2556 xfs_extlen_t need;
2557 xfs_extlen_t nextminlen = 0;
2558 xfs_perag_t *pag;
2559 int nullfb; /* true if ap->firstblock isn't set */
2560 int isaligned;
2561 int notinit;
2562 int tryagain;
2563 int error;
2564
2565 mp = ap->ip->i_mount;
2566 align = (ap->userdata && ap->ip->i_d.di_extsize &&
2567 (ap->ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE)) ?
2568 ap->ip->i_d.di_extsize : 0;
2569 if (unlikely(align)) {
2570 error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp,
2571 align, 0, ap->eof, 0, ap->conv,
2572 &ap->off, &ap->alen);
2573 ASSERT(!error);
2574 ASSERT(ap->alen);
2575 }
2576 nullfb = ap->firstblock == NULLFSBLOCK;
2577 fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock);
2578 if (nullfb)
2579 ap->rval = XFS_INO_TO_FSB(mp, ap->ip->i_ino);
2580 else
2581 ap->rval = ap->firstblock;
2582
2583 xfs_bmap_adjacent(ap);
2584
2534 /* 2585 /*
2535 * If allowed, use ap->rval; otherwise must use firstblock since 2586 * If allowed, use ap->rval; otherwise must use firstblock since
2536 * it's in the right allocation group. 2587 * it's in the right allocation group.
2537 */ 2588 */
2538 if (nullfb || rt || XFS_FSB_TO_AGNO(mp, ap->rval) == fb_agno) 2589 if (nullfb || XFS_FSB_TO_AGNO(mp, ap->rval) == fb_agno)
2539 ; 2590 ;
2540 else 2591 else
2541 ap->rval = ap->firstblock; 2592 ap->rval = ap->firstblock;
2542 /* 2593 /*
2543 * Realtime allocation, done through xfs_rtallocate_extent. 2594 * Normal allocation, done through xfs_alloc_vextent.
2544 */ 2595 */
2545 if (rt) { 2596 tryagain = isaligned = 0;
2546#ifndef __KERNEL__ 2597 args.tp = ap->tp;
2547 ASSERT(0); 2598 args.mp = mp;
2548#else 2599 args.fsbno = ap->rval;
2549 xfs_rtblock_t rtb; 2600 args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks);
2550 2601 blen = 0;
2551 atype = ap->rval == 0 ? 2602 if (nullfb) {
2552 XFS_ALLOCTYPE_ANY_AG : XFS_ALLOCTYPE_NEAR_BNO; 2603 args.type = XFS_ALLOCTYPE_START_BNO;
2553 do_div(ap->rval, mp->m_sb.sb_rextsize); 2604 args.total = ap->total;
2554 rtb = ap->rval; 2605 /*
2555 ap->alen = ralen; 2606 * Find the longest available space.
2556 if ((error = xfs_rtallocate_extent(ap->tp, ap->rval, 1, ap->alen, 2607 * We're going to try for the whole allocation at once.
2557 &ralen, atype, ap->wasdel, prod, &rtb))) 2608 */
2558 return error; 2609 startag = ag = XFS_FSB_TO_AGNO(mp, args.fsbno);
2559 if (rtb == NULLFSBLOCK && prod > 1 && 2610 notinit = 0;
2560 (error = xfs_rtallocate_extent(ap->tp, ap->rval, 1, 2611 down_read(&mp->m_peraglock);
2561 ap->alen, &ralen, atype, 2612 while (blen < ap->alen) {
2562 ap->wasdel, 1, &rtb))) 2613 pag = &mp->m_perag[ag];
2563 return error; 2614 if (!pag->pagf_init &&
2564 ap->rval = rtb; 2615 (error = xfs_alloc_pagf_init(mp, args.tp,
2565 if (ap->rval != NULLFSBLOCK) { 2616 ag, XFS_ALLOC_FLAG_TRYLOCK))) {
2566 ap->rval *= mp->m_sb.sb_rextsize; 2617 up_read(&mp->m_peraglock);
2567 ralen *= mp->m_sb.sb_rextsize; 2618 return error;
2568 ap->alen = ralen; 2619 }
2569 ap->ip->i_d.di_nblocks += ralen;
2570 xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE);
2571 if (ap->wasdel)
2572 ap->ip->i_delayed_blks -= ralen;
2573 /* 2620 /*
2574 * Adjust the disk quota also. This was reserved 2621 * See xfs_alloc_fix_freelist...
2575 * earlier.
2576 */ 2622 */
2577 XFS_TRANS_MOD_DQUOT_BYINO(mp, ap->tp, ap->ip, 2623 if (pag->pagf_init) {
2578 ap->wasdel ? XFS_TRANS_DQ_DELRTBCOUNT : 2624 need = XFS_MIN_FREELIST_PAG(pag, mp);
2579 XFS_TRANS_DQ_RTBCOUNT, 2625 delta = need > pag->pagf_flcount ?
2580 (long) ralen); 2626 need - pag->pagf_flcount : 0;
2581 } else 2627 longest = (pag->pagf_longest > delta) ?
2582 ap->alen = 0; 2628 (pag->pagf_longest - delta) :
2583#endif /* __KERNEL__ */ 2629 (pag->pagf_flcount > 0 ||
2630 pag->pagf_longest > 0);
2631 if (blen < longest)
2632 blen = longest;
2633 } else
2634 notinit = 1;
2635 if (++ag == mp->m_sb.sb_agcount)
2636 ag = 0;
2637 if (ag == startag)
2638 break;
2639 }
2640 up_read(&mp->m_peraglock);
2641 /*
2642 * Since the above loop did a BUF_TRYLOCK, it is
2643 * possible that there is space for this request.
2644 */
2645 if (notinit || blen < ap->minlen)
2646 args.minlen = ap->minlen;
2647 /*
2648 * If the best seen length is less than the request
2649 * length, use the best as the minimum.
2650 */
2651 else if (blen < ap->alen)
2652 args.minlen = blen;
2653 /*
2654 * Otherwise we've seen an extent as big as alen,
2655 * use that as the minimum.
2656 */
2657 else
2658 args.minlen = ap->alen;
2659 } else if (ap->low) {
2660 args.type = XFS_ALLOCTYPE_FIRST_AG;
2661 args.total = args.minlen = ap->minlen;
2662 } else {
2663 args.type = XFS_ALLOCTYPE_NEAR_BNO;
2664 args.total = ap->total;
2665 args.minlen = ap->minlen;
2666 }
2667 if (unlikely(ap->userdata && ap->ip->i_d.di_extsize &&
2668 (ap->ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE))) {
2669 args.prod = ap->ip->i_d.di_extsize;
2670 if ((args.mod = (xfs_extlen_t)do_mod(ap->off, args.prod)))
2671 args.mod = (xfs_extlen_t)(args.prod - args.mod);
2672 } else if (unlikely(mp->m_sb.sb_blocksize >= NBPP)) {
2673 args.prod = 1;
2674 args.mod = 0;
2675 } else {
2676 args.prod = NBPP >> mp->m_sb.sb_blocklog;
2677 if ((args.mod = (xfs_extlen_t)(do_mod(ap->off, args.prod))))
2678 args.mod = (xfs_extlen_t)(args.prod - args.mod);
2584 } 2679 }
2585 /* 2680 /*
2586 * Normal allocation, done through xfs_alloc_vextent. 2681 * If we are not low on available data blocks, and the
2682 * underlying logical volume manager is a stripe, and
2683 * the file offset is zero then try to allocate data
2684 * blocks on stripe unit boundary.
2685 * NOTE: ap->aeof is only set if the allocation length
2686 * is >= the stripe unit and the allocation offset is
2687 * at the end of file.
2587 */ 2688 */
2588 else { 2689 if (!ap->low && ap->aeof) {
2589 xfs_agnumber_t ag; 2690 if (!ap->off) {
2590 xfs_alloc_arg_t args; 2691 args.alignment = mp->m_dalign;
2591 xfs_extlen_t blen; 2692 atype = args.type;
2592 xfs_extlen_t delta; 2693 isaligned = 1;
2593 int isaligned;
2594 xfs_extlen_t longest;
2595 xfs_extlen_t need;
2596 xfs_extlen_t nextminlen=0;
2597 int notinit;
2598 xfs_perag_t *pag;
2599 xfs_agnumber_t startag;
2600 int tryagain;
2601
2602 tryagain = isaligned = 0;
2603 args.tp = ap->tp;
2604 args.mp = mp;
2605 args.fsbno = ap->rval;
2606 args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks);
2607 blen = 0;
2608 if (nullfb) {
2609 args.type = XFS_ALLOCTYPE_START_BNO;
2610 args.total = ap->total;
2611 /*
2612 * Find the longest available space.
2613 * We're going to try for the whole allocation at once.
2614 */
2615 startag = ag = XFS_FSB_TO_AGNO(mp, args.fsbno);
2616 notinit = 0;
2617 down_read(&mp->m_peraglock);
2618 while (blen < ap->alen) {
2619 pag = &mp->m_perag[ag];
2620 if (!pag->pagf_init &&
2621 (error = xfs_alloc_pagf_init(mp, args.tp,
2622 ag, XFS_ALLOC_FLAG_TRYLOCK))) {
2623 up_read(&mp->m_peraglock);
2624 return error;
2625 }
2626 /*
2627 * See xfs_alloc_fix_freelist...
2628 */
2629 if (pag->pagf_init) {
2630 need = XFS_MIN_FREELIST_PAG(pag, mp);
2631 delta = need > pag->pagf_flcount ?
2632 need - pag->pagf_flcount : 0;
2633 longest = (pag->pagf_longest > delta) ?
2634 (pag->pagf_longest - delta) :
2635 (pag->pagf_flcount > 0 ||
2636 pag->pagf_longest > 0);
2637 if (blen < longest)
2638 blen = longest;
2639 } else
2640 notinit = 1;
2641 if (++ag == mp->m_sb.sb_agcount)
2642 ag = 0;
2643 if (ag == startag)
2644 break;
2645 }
2646 up_read(&mp->m_peraglock);
2647 /* 2694 /*
2648 * Since the above loop did a BUF_TRYLOCK, it is 2695 * Adjust for alignment
2649 * possible that there is space for this request.
2650 */ 2696 */
2651 if (notinit || blen < ap->minlen) 2697 if (blen > args.alignment && blen <= ap->alen)
2652 args.minlen = ap->minlen; 2698 args.minlen = blen - args.alignment;
2699 args.minalignslop = 0;
2700 } else {
2653 /* 2701 /*
2654 * If the best seen length is less than the request 2702 * First try an exact bno allocation.
2655 * length, use the best as the minimum. 2703 * If it fails then do a near or start bno
2704 * allocation with alignment turned on.
2656 */ 2705 */
2657 else if (blen < ap->alen) 2706 atype = args.type;
2658 args.minlen = blen; 2707 tryagain = 1;
2708 args.type = XFS_ALLOCTYPE_THIS_BNO;
2709 args.alignment = 1;
2659 /* 2710 /*
2660 * Otherwise we've seen an extent as big as alen, 2711 * Compute the minlen+alignment for the
2661 * use that as the minimum. 2712 * next case. Set slop so that the value
2713 * of minlen+alignment+slop doesn't go up
2714 * between the calls.
2662 */ 2715 */
2716 if (blen > mp->m_dalign && blen <= ap->alen)
2717 nextminlen = blen - mp->m_dalign;
2663 else 2718 else
2664 args.minlen = ap->alen; 2719 nextminlen = args.minlen;
2665 } else if (ap->low) { 2720 if (nextminlen + mp->m_dalign > args.minlen + 1)
2666 args.type = XFS_ALLOCTYPE_FIRST_AG; 2721 args.minalignslop =
2667 args.total = args.minlen = ap->minlen; 2722 nextminlen + mp->m_dalign -
2668 } else { 2723 args.minlen - 1;
2669 args.type = XFS_ALLOCTYPE_NEAR_BNO; 2724 else
2670 args.total = ap->total; 2725 args.minalignslop = 0;
2671 args.minlen = ap->minlen;
2672 }
2673 if (unlikely(ap->userdata && ap->ip->i_d.di_extsize &&
2674 (ap->ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE))) {
2675 args.prod = ap->ip->i_d.di_extsize;
2676 if ((args.mod = (xfs_extlen_t)do_mod(ap->off, args.prod)))
2677 args.mod = (xfs_extlen_t)(args.prod - args.mod);
2678 } else if (unlikely(mp->m_sb.sb_blocksize >= NBPP)) {
2679 args.prod = 1;
2680 args.mod = 0;
2681 } else {
2682 args.prod = NBPP >> mp->m_sb.sb_blocklog;
2683 if ((args.mod = (xfs_extlen_t)(do_mod(ap->off, args.prod))))
2684 args.mod = (xfs_extlen_t)(args.prod - args.mod);
2685 } 2726 }
2727 } else {
2728 args.alignment = 1;
2729 args.minalignslop = 0;
2730 }
2731 args.minleft = ap->minleft;
2732 args.wasdel = ap->wasdel;
2733 args.isfl = 0;
2734 args.userdata = ap->userdata;
2735 if ((error = xfs_alloc_vextent(&args)))
2736 return error;
2737 if (tryagain && args.fsbno == NULLFSBLOCK) {
2686 /* 2738 /*
2687 * If we are not low on available data blocks, and the 2739 * Exact allocation failed. Now try with alignment
2688 * underlying logical volume manager is a stripe, and 2740 * turned on.
2689 * the file offset is zero then try to allocate data
2690 * blocks on stripe unit boundary.
2691 * NOTE: ap->aeof is only set if the allocation length
2692 * is >= the stripe unit and the allocation offset is
2693 * at the end of file.
2694 */ 2741 */
2695 if (!ap->low && ap->aeof) { 2742 args.type = atype;
2696 if (!ap->off) { 2743 args.fsbno = ap->rval;
2697 args.alignment = mp->m_dalign; 2744 args.alignment = mp->m_dalign;
2698 atype = args.type; 2745 args.minlen = nextminlen;
2699 isaligned = 1; 2746 args.minalignslop = 0;
2700 /* 2747 isaligned = 1;
2701 * Adjust for alignment
2702 */
2703 if (blen > args.alignment && blen <= ap->alen)
2704 args.minlen = blen - args.alignment;
2705 args.minalignslop = 0;
2706 } else {
2707 /*
2708 * First try an exact bno allocation.
2709 * If it fails then do a near or start bno
2710 * allocation with alignment turned on.
2711 */
2712 atype = args.type;
2713 tryagain = 1;
2714 args.type = XFS_ALLOCTYPE_THIS_BNO;
2715 args.alignment = 1;
2716 /*
2717 * Compute the minlen+alignment for the
2718 * next case. Set slop so that the value
2719 * of minlen+alignment+slop doesn't go up
2720 * between the calls.
2721 */
2722 if (blen > mp->m_dalign && blen <= ap->alen)
2723 nextminlen = blen - mp->m_dalign;
2724 else
2725 nextminlen = args.minlen;
2726 if (nextminlen + mp->m_dalign > args.minlen + 1)
2727 args.minalignslop =
2728 nextminlen + mp->m_dalign -
2729 args.minlen - 1;
2730 else
2731 args.minalignslop = 0;
2732 }
2733 } else {
2734 args.alignment = 1;
2735 args.minalignslop = 0;
2736 }
2737 args.minleft = ap->minleft;
2738 args.wasdel = ap->wasdel;
2739 args.isfl = 0;
2740 args.userdata = ap->userdata;
2741 if ((error = xfs_alloc_vextent(&args))) 2748 if ((error = xfs_alloc_vextent(&args)))
2742 return error; 2749 return error;
2743 if (tryagain && args.fsbno == NULLFSBLOCK) { 2750 }
2744 /* 2751 if (isaligned && args.fsbno == NULLFSBLOCK) {
2745 * Exact allocation failed. Now try with alignment 2752 /*
2746 * turned on. 2753 * allocation failed, so turn off alignment and
2747 */ 2754 * try again.
2748 args.type = atype; 2755 */
2749 args.fsbno = ap->rval; 2756 args.type = atype;
2750 args.alignment = mp->m_dalign; 2757 args.fsbno = ap->rval;
2751 args.minlen = nextminlen; 2758 args.alignment = 0;
2752 args.minalignslop = 0; 2759 if ((error = xfs_alloc_vextent(&args)))
2753 isaligned = 1; 2760 return error;
2754 if ((error = xfs_alloc_vextent(&args))) 2761 }
2755 return error; 2762 if (args.fsbno == NULLFSBLOCK && nullfb &&
2756 } 2763 args.minlen > ap->minlen) {
2757 if (isaligned && args.fsbno == NULLFSBLOCK) { 2764 args.minlen = ap->minlen;
2758 /* 2765 args.type = XFS_ALLOCTYPE_START_BNO;
2759 * allocation failed, so turn off alignment and 2766 args.fsbno = ap->rval;
2760 * try again. 2767 if ((error = xfs_alloc_vextent(&args)))
2761 */ 2768 return error;
2762 args.type = atype; 2769 }
2763 args.fsbno = ap->rval; 2770 if (args.fsbno == NULLFSBLOCK && nullfb) {
2764 args.alignment = 0; 2771 args.fsbno = 0;
2765 if ((error = xfs_alloc_vextent(&args))) 2772 args.type = XFS_ALLOCTYPE_FIRST_AG;
2766 return error; 2773 args.total = ap->minlen;
2767 } 2774 args.minleft = 0;
2768 if (args.fsbno == NULLFSBLOCK && nullfb && 2775 if ((error = xfs_alloc_vextent(&args)))
2769 args.minlen > ap->minlen) { 2776 return error;
2770 args.minlen = ap->minlen; 2777 ap->low = 1;
2771 args.type = XFS_ALLOCTYPE_START_BNO; 2778 }
2772 args.fsbno = ap->rval; 2779 if (args.fsbno != NULLFSBLOCK) {
2773 if ((error = xfs_alloc_vextent(&args))) 2780 ap->firstblock = ap->rval = args.fsbno;
2774 return error; 2781 ASSERT(nullfb || fb_agno == args.agno ||
2775 } 2782 (ap->low && fb_agno < args.agno));
2776 if (args.fsbno == NULLFSBLOCK && nullfb) { 2783 ap->alen = args.len;
2777 args.fsbno = 0; 2784 ap->ip->i_d.di_nblocks += args.len;
2778 args.type = XFS_ALLOCTYPE_FIRST_AG; 2785 xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE);
2779 args.total = ap->minlen; 2786 if (ap->wasdel)
2780 args.minleft = 0; 2787 ap->ip->i_delayed_blks -= args.len;
2781 if ((error = xfs_alloc_vextent(&args))) 2788 /*
2782 return error; 2789 * Adjust the disk quota also. This was reserved
2783 ap->low = 1; 2790 * earlier.
2784 } 2791 */
2785 if (args.fsbno != NULLFSBLOCK) { 2792 XFS_TRANS_MOD_DQUOT_BYINO(mp, ap->tp, ap->ip,
2786 ap->firstblock = ap->rval = args.fsbno; 2793 ap->wasdel ? XFS_TRANS_DQ_DELBCOUNT :
2787 ASSERT(nullfb || fb_agno == args.agno || 2794 XFS_TRANS_DQ_BCOUNT,
2788 (ap->low && fb_agno < args.agno)); 2795 (long) args.len);
2789 ap->alen = args.len; 2796 } else {
2790 ap->ip->i_d.di_nblocks += args.len; 2797 ap->rval = NULLFSBLOCK;
2791 xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE); 2798 ap->alen = 0;
2792 if (ap->wasdel)
2793 ap->ip->i_delayed_blks -= args.len;
2794 /*
2795 * Adjust the disk quota also. This was reserved
2796 * earlier.
2797 */
2798 XFS_TRANS_MOD_DQUOT_BYINO(mp, ap->tp, ap->ip,
2799 ap->wasdel ? XFS_TRANS_DQ_DELBCOUNT :
2800 XFS_TRANS_DQ_BCOUNT,
2801 (long) args.len);
2802 } else {
2803 ap->rval = NULLFSBLOCK;
2804 ap->alen = 0;
2805 }
2806 } 2799 }
2807 return 0; 2800 return 0;
2808#undef ISVALID 2801}
2802
2803/*
2804 * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file.
2805 * It figures out where to ask the underlying allocator to put the new extent.
2806 */
2807STATIC int
2808xfs_bmap_alloc(
2809 xfs_bmalloca_t *ap) /* bmap alloc argument struct */
2810{
2811 if ((ap->ip->i_d.di_flags & XFS_DIFLAG_REALTIME) && ap->userdata)
2812 return xfs_bmap_rtalloc(ap);
2813 return xfs_bmap_btalloc(ap);
2809} 2814}
2810 2815
2811/* 2816/*
2812 * Transform a btree format file with only one leaf node, where the 2817 * Transform a btree format file with only one leaf node, where the
2813 * extents list will fit in the inode, into an extents format file. 2818 * extents list will fit in the inode, into an extents format file.
2814 * Since the extent list is already in-core, all we have to do is 2819 * Since the file extents are already in-core, all we have to do is
2815 * give up the space for the btree root and pitch the leaf block. 2820 * give up the space for the btree root and pitch the leaf block.
2816 */ 2821 */
2817STATIC int /* error */ 2822STATIC int /* error */
@@ -2868,7 +2873,7 @@ xfs_bmap_btree_to_extents(
2868} 2873}
2869 2874
2870/* 2875/*
2871 * Called by xfs_bmapi to update extent list structure and the btree 2876 * Called by xfs_bmapi to update file extent records and the btree
2872 * after removing space (or undoing a delayed allocation). 2877 * after removing space (or undoing a delayed allocation).
2873 */ 2878 */
2874STATIC int /* error */ 2879STATIC int /* error */
@@ -2878,7 +2883,7 @@ xfs_bmap_del_extent(
2878 xfs_extnum_t idx, /* extent number to update/delete */ 2883 xfs_extnum_t idx, /* extent number to update/delete */
2879 xfs_bmap_free_t *flist, /* list of extents to be freed */ 2884 xfs_bmap_free_t *flist, /* list of extents to be freed */
2880 xfs_btree_cur_t *cur, /* if null, not a btree */ 2885 xfs_btree_cur_t *cur, /* if null, not a btree */
2881 xfs_bmbt_irec_t *del, /* data to remove from extent list */ 2886 xfs_bmbt_irec_t *del, /* data to remove from extents */
2882 int *logflagsp, /* inode logging flags */ 2887 int *logflagsp, /* inode logging flags */
2883 int whichfork, /* data or attr fork */ 2888 int whichfork, /* data or attr fork */
2884 int rsvd) /* OK to allocate reserved blocks */ 2889 int rsvd) /* OK to allocate reserved blocks */
@@ -2903,7 +2908,6 @@ xfs_bmap_del_extent(
2903 xfs_filblks_t nblks; /* quota/sb block count */ 2908 xfs_filblks_t nblks; /* quota/sb block count */
2904 xfs_bmbt_irec_t new; /* new record to be inserted */ 2909 xfs_bmbt_irec_t new; /* new record to be inserted */
2905 /* REFERENCED */ 2910 /* REFERENCED */
2906 xfs_extnum_t nextents; /* number of extents in list */
2907 uint qfield; /* quota field to update */ 2911 uint qfield; /* quota field to update */
2908 xfs_filblks_t temp; /* for indirect length calculations */ 2912 xfs_filblks_t temp; /* for indirect length calculations */
2909 xfs_filblks_t temp2; /* for indirect length calculations */ 2913 xfs_filblks_t temp2; /* for indirect length calculations */
@@ -2911,10 +2915,10 @@ xfs_bmap_del_extent(
2911 XFS_STATS_INC(xs_del_exlist); 2915 XFS_STATS_INC(xs_del_exlist);
2912 mp = ip->i_mount; 2916 mp = ip->i_mount;
2913 ifp = XFS_IFORK_PTR(ip, whichfork); 2917 ifp = XFS_IFORK_PTR(ip, whichfork);
2914 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 2918 ASSERT((idx >= 0) && (idx < ifp->if_bytes /
2915 ASSERT(idx >= 0 && idx < nextents); 2919 (uint)sizeof(xfs_bmbt_rec_t)));
2916 ASSERT(del->br_blockcount > 0); 2920 ASSERT(del->br_blockcount > 0);
2917 ep = &ifp->if_u1.if_extents[idx]; 2921 ep = xfs_iext_get_ext(ifp, idx);
2918 xfs_bmbt_get_all(ep, &got); 2922 xfs_bmbt_get_all(ep, &got);
2919 ASSERT(got.br_startoff <= del->br_startoff); 2923 ASSERT(got.br_startoff <= del->br_startoff);
2920 del_endoff = del->br_startoff + del->br_blockcount; 2924 del_endoff = del->br_startoff + del->br_blockcount;
@@ -2990,7 +2994,7 @@ xfs_bmap_del_extent(
2990 * Matches the whole extent. Delete the entry. 2994 * Matches the whole extent. Delete the entry.
2991 */ 2995 */
2992 xfs_bmap_trace_delete(fname, "3", ip, idx, 1, whichfork); 2996 xfs_bmap_trace_delete(fname, "3", ip, idx, 1, whichfork);
2993 xfs_bmap_delete_exlist(ip, idx, 1, whichfork); 2997 xfs_iext_remove(ifp, idx, 1);
2994 ifp->if_lastex = idx; 2998 ifp->if_lastex = idx;
2995 if (delay) 2999 if (delay)
2996 break; 3000 break;
@@ -3160,7 +3164,7 @@ xfs_bmap_del_extent(
3160 xfs_bmap_trace_post_update(fname, "0", ip, idx, whichfork); 3164 xfs_bmap_trace_post_update(fname, "0", ip, idx, whichfork);
3161 xfs_bmap_trace_insert(fname, "0", ip, idx + 1, 1, &new, NULL, 3165 xfs_bmap_trace_insert(fname, "0", ip, idx + 1, 1, &new, NULL,
3162 whichfork); 3166 whichfork);
3163 xfs_bmap_insert_exlist(ip, idx + 1, 1, &new, whichfork); 3167 xfs_iext_insert(ifp, idx + 1, 1, &new);
3164 ifp->if_lastex = idx + 1; 3168 ifp->if_lastex = idx + 1;
3165 break; 3169 break;
3166 } 3170 }
@@ -3213,31 +3217,6 @@ xfs_bmap_del_free(
3213} 3217}
3214 3218
3215/* 3219/*
3216 * Remove count entries from the extents array for inode "ip", starting
3217 * at index "idx". Copies the remaining items down over the deleted ones,
3218 * and gives back the excess memory.
3219 */
3220STATIC void
3221xfs_bmap_delete_exlist(
3222 xfs_inode_t *ip, /* incore inode pointer */
3223 xfs_extnum_t idx, /* starting delete index */
3224 xfs_extnum_t count, /* count of items to delete */
3225 int whichfork) /* data or attr fork */
3226{
3227 xfs_bmbt_rec_t *base; /* base of extent list */
3228 xfs_ifork_t *ifp; /* inode fork pointer */
3229 xfs_extnum_t nextents; /* number of extents in list after */
3230
3231 ifp = XFS_IFORK_PTR(ip, whichfork);
3232 ASSERT(ifp->if_flags & XFS_IFEXTENTS);
3233 base = ifp->if_u1.if_extents;
3234 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - count;
3235 memmove(&base[idx], &base[idx + count],
3236 (nextents - idx) * sizeof(*base));
3237 xfs_iext_realloc(ip, -count, whichfork);
3238}
3239
3240/*
3241 * Convert an extents-format file into a btree-format file. 3220 * Convert an extents-format file into a btree-format file.
3242 * The new file will have a root block (in the inode) and a single child block. 3221 * The new file will have a root block (in the inode) and a single child block.
3243 */ 3222 */
@@ -3258,13 +3237,13 @@ xfs_bmap_extents_to_btree(
3258 xfs_bmbt_rec_t *arp; /* child record pointer */ 3237 xfs_bmbt_rec_t *arp; /* child record pointer */
3259 xfs_bmbt_block_t *block; /* btree root block */ 3238 xfs_bmbt_block_t *block; /* btree root block */
3260 xfs_btree_cur_t *cur; /* bmap btree cursor */ 3239 xfs_btree_cur_t *cur; /* bmap btree cursor */
3261 xfs_bmbt_rec_t *ep; /* extent list pointer */ 3240 xfs_bmbt_rec_t *ep; /* extent record pointer */
3262 int error; /* error return value */ 3241 int error; /* error return value */
3263 xfs_extnum_t i, cnt; /* extent list index */ 3242 xfs_extnum_t i, cnt; /* extent record index */
3264 xfs_ifork_t *ifp; /* inode fork pointer */ 3243 xfs_ifork_t *ifp; /* inode fork pointer */
3265 xfs_bmbt_key_t *kp; /* root block key pointer */ 3244 xfs_bmbt_key_t *kp; /* root block key pointer */
3266 xfs_mount_t *mp; /* mount structure */ 3245 xfs_mount_t *mp; /* mount structure */
3267 xfs_extnum_t nextents; /* extent list size */ 3246 xfs_extnum_t nextents; /* number of file extents */
3268 xfs_bmbt_ptr_t *pp; /* root block address pointer */ 3247 xfs_bmbt_ptr_t *pp; /* root block address pointer */
3269 3248
3270 ifp = XFS_IFORK_PTR(ip, whichfork); 3249 ifp = XFS_IFORK_PTR(ip, whichfork);
@@ -3343,7 +3322,8 @@ xfs_bmap_extents_to_btree(
3343 ablock->bb_rightsib = cpu_to_be64(NULLDFSBNO); 3322 ablock->bb_rightsib = cpu_to_be64(NULLDFSBNO);
3344 arp = XFS_BMAP_REC_IADDR(ablock, 1, cur); 3323 arp = XFS_BMAP_REC_IADDR(ablock, 1, cur);
3345 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 3324 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
3346 for (ep = ifp->if_u1.if_extents, cnt = i = 0; i < nextents; i++, ep++) { 3325 for (cnt = i = 0; i < nextents; i++) {
3326 ep = xfs_iext_get_ext(ifp, i);
3347 if (!ISNULLSTARTBLOCK(xfs_bmbt_get_startblock(ep))) { 3327 if (!ISNULLSTARTBLOCK(xfs_bmbt_get_startblock(ep))) {
3348 arp->l0 = INT_GET(ep->l0, ARCH_CONVERT); 3328 arp->l0 = INT_GET(ep->l0, ARCH_CONVERT);
3349 arp->l1 = INT_GET(ep->l1, ARCH_CONVERT); 3329 arp->l1 = INT_GET(ep->l1, ARCH_CONVERT);
@@ -3373,34 +3353,6 @@ xfs_bmap_extents_to_btree(
3373} 3353}
3374 3354
3375/* 3355/*
3376 * Insert new item(s) in the extent list for inode "ip".
3377 * Count new items are inserted at offset idx.
3378 */
3379STATIC void
3380xfs_bmap_insert_exlist(
3381 xfs_inode_t *ip, /* incore inode pointer */
3382 xfs_extnum_t idx, /* starting index of new items */
3383 xfs_extnum_t count, /* number of inserted items */
3384 xfs_bmbt_irec_t *new, /* items to insert */
3385 int whichfork) /* data or attr fork */
3386{
3387 xfs_bmbt_rec_t *base; /* extent list base */
3388 xfs_ifork_t *ifp; /* inode fork pointer */
3389 xfs_extnum_t nextents; /* extent list size */
3390 xfs_extnum_t to; /* extent list index */
3391
3392 ifp = XFS_IFORK_PTR(ip, whichfork);
3393 ASSERT(ifp->if_flags & XFS_IFEXTENTS);
3394 xfs_iext_realloc(ip, count, whichfork);
3395 base = ifp->if_u1.if_extents;
3396 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
3397 memmove(&base[idx + count], &base[idx],
3398 (nextents - (idx + count)) * sizeof(*base));
3399 for (to = idx; to < idx + count; to++, new++)
3400 xfs_bmbt_set_all(&base[to], new);
3401}
3402
3403/*
3404 * Helper routine to reset inode di_forkoff field when switching 3356 * Helper routine to reset inode di_forkoff field when switching
3405 * attribute fork from local to extent format - we reset it where 3357 * attribute fork from local to extent format - we reset it where
3406 * possible to make space available for inline data fork extents. 3358 * possible to make space available for inline data fork extents.
@@ -3457,12 +3409,13 @@ xfs_bmap_local_to_extents(
3457 error = 0; 3409 error = 0;
3458 if (ifp->if_bytes) { 3410 if (ifp->if_bytes) {
3459 xfs_alloc_arg_t args; /* allocation arguments */ 3411 xfs_alloc_arg_t args; /* allocation arguments */
3460 xfs_buf_t *bp; /* buffer for extent list block */ 3412 xfs_buf_t *bp; /* buffer for extent block */
3461 xfs_bmbt_rec_t *ep; /* extent list pointer */ 3413 xfs_bmbt_rec_t *ep; /* extent record pointer */
3462 3414
3463 args.tp = tp; 3415 args.tp = tp;
3464 args.mp = ip->i_mount; 3416 args.mp = ip->i_mount;
3465 ASSERT(ifp->if_flags & XFS_IFINLINE); 3417 ASSERT((ifp->if_flags &
3418 (XFS_IFINLINE|XFS_IFEXTENTS|XFS_IFEXTIREC)) == XFS_IFINLINE);
3466 /* 3419 /*
3467 * Allocate a block. We know we need only one, since the 3420 * Allocate a block. We know we need only one, since the
3468 * file currently fits in an inode. 3421 * file currently fits in an inode.
@@ -3492,8 +3445,8 @@ xfs_bmap_local_to_extents(
3492 xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1); 3445 xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1);
3493 xfs_bmap_forkoff_reset(args.mp, ip, whichfork); 3446 xfs_bmap_forkoff_reset(args.mp, ip, whichfork);
3494 xfs_idata_realloc(ip, -ifp->if_bytes, whichfork); 3447 xfs_idata_realloc(ip, -ifp->if_bytes, whichfork);
3495 xfs_iext_realloc(ip, 1, whichfork); 3448 xfs_iext_add(ifp, 0, 1);
3496 ep = ifp->if_u1.if_extents; 3449 ep = xfs_iext_get_ext(ifp, 0);
3497 xfs_bmbt_set_allf(ep, 0, args.fsbno, 1, XFS_EXT_NORM); 3450 xfs_bmbt_set_allf(ep, 0, args.fsbno, 1, XFS_EXT_NORM);
3498 xfs_bmap_trace_post_update(fname, "new", ip, 0, whichfork); 3451 xfs_bmap_trace_post_update(fname, "new", ip, 0, whichfork);
3499 XFS_IFORK_NEXT_SET(ip, whichfork, 1); 3452 XFS_IFORK_NEXT_SET(ip, whichfork, 1);
@@ -3514,110 +3467,54 @@ done:
3514 return error; 3467 return error;
3515} 3468}
3516 3469
3470/*
3471 * Search the extent records for the entry containing block bno.
3472 * If bno lies in a hole, point to the next entry. If bno lies
3473 * past eof, *eofp will be set, and *prevp will contain the last
3474 * entry (null if none). Else, *lastxp will be set to the index
3475 * of the found entry; *gotp will contain the entry.
3476 */
3517xfs_bmbt_rec_t * /* pointer to found extent entry */ 3477xfs_bmbt_rec_t * /* pointer to found extent entry */
3518xfs_bmap_do_search_extents( 3478xfs_bmap_search_multi_extents(
3519 xfs_bmbt_rec_t *base, /* base of extent list */ 3479 xfs_ifork_t *ifp, /* inode fork pointer */
3520 xfs_extnum_t lastx, /* last extent index used */
3521 xfs_extnum_t nextents, /* extent list size */
3522 xfs_fileoff_t bno, /* block number searched for */ 3480 xfs_fileoff_t bno, /* block number searched for */
3523 int *eofp, /* out: end of file found */ 3481 int *eofp, /* out: end of file found */
3524 xfs_extnum_t *lastxp, /* out: last extent index */ 3482 xfs_extnum_t *lastxp, /* out: last extent index */
3525 xfs_bmbt_irec_t *gotp, /* out: extent entry found */ 3483 xfs_bmbt_irec_t *gotp, /* out: extent entry found */
3526 xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ 3484 xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */
3527{ 3485{
3528 xfs_bmbt_rec_t *ep; /* extent list entry pointer */ 3486 xfs_bmbt_rec_t *ep; /* extent record pointer */
3529 xfs_bmbt_irec_t got; /* extent list entry, decoded */ 3487 xfs_extnum_t lastx; /* last extent index */
3530 int high; /* high index of binary search */
3531 int low; /* low index of binary search */
3532 3488
3533 /* 3489 /*
3534 * Initialize the extent entry structure to catch access to 3490 * Initialize the extent entry structure to catch access to
3535 * uninitialized br_startblock field. 3491 * uninitialized br_startblock field.
3536 */ 3492 */
3537 got.br_startoff = 0xffa5a5a5a5a5a5a5LL; 3493 gotp->br_startoff = 0xffa5a5a5a5a5a5a5LL;
3538 got.br_blockcount = 0xa55a5a5a5a5a5a5aLL; 3494 gotp->br_blockcount = 0xa55a5a5a5a5a5a5aLL;
3539 got.br_state = XFS_EXT_INVALID; 3495 gotp->br_state = XFS_EXT_INVALID;
3540
3541#if XFS_BIG_BLKNOS 3496#if XFS_BIG_BLKNOS
3542 got.br_startblock = 0xffffa5a5a5a5a5a5LL; 3497 gotp->br_startblock = 0xffffa5a5a5a5a5a5LL;
3543#else 3498#else
3544 got.br_startblock = 0xffffa5a5; 3499 gotp->br_startblock = 0xffffa5a5;
3545#endif 3500#endif
3546
3547 if (lastx != NULLEXTNUM && lastx < nextents)
3548 ep = base + lastx;
3549 else
3550 ep = NULL;
3551 prevp->br_startoff = NULLFILEOFF; 3501 prevp->br_startoff = NULLFILEOFF;
3552 if (ep && bno >= (got.br_startoff = xfs_bmbt_get_startoff(ep)) && 3502
3553 bno < got.br_startoff + 3503 ep = xfs_iext_bno_to_ext(ifp, bno, &lastx);
3554 (got.br_blockcount = xfs_bmbt_get_blockcount(ep))) 3504 if (lastx > 0) {
3555 *eofp = 0; 3505 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx - 1), prevp);
3556 else if (ep && lastx < nextents - 1 && 3506 }
3557 bno >= (got.br_startoff = xfs_bmbt_get_startoff(ep + 1)) && 3507 if (lastx < (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))) {
3558 bno < got.br_startoff + 3508 xfs_bmbt_get_all(ep, gotp);
3559 (got.br_blockcount = xfs_bmbt_get_blockcount(ep + 1))) {
3560 lastx++;
3561 ep++;
3562 *eofp = 0;
3563 } else if (nextents == 0)
3564 *eofp = 1;
3565 else if (bno == 0 &&
3566 (got.br_startoff = xfs_bmbt_get_startoff(base)) == 0) {
3567 ep = base;
3568 lastx = 0;
3569 got.br_blockcount = xfs_bmbt_get_blockcount(ep);
3570 *eofp = 0; 3509 *eofp = 0;
3571 } else { 3510 } else {
3572 /* binary search the extents array */ 3511 if (lastx > 0) {
3573 low = 0; 3512 *gotp = *prevp;
3574 high = nextents - 1;
3575 while (low <= high) {
3576 XFS_STATS_INC(xs_cmp_exlist);
3577 lastx = (low + high) >> 1;
3578 ep = base + lastx;
3579 got.br_startoff = xfs_bmbt_get_startoff(ep);
3580 got.br_blockcount = xfs_bmbt_get_blockcount(ep);
3581 if (bno < got.br_startoff)
3582 high = lastx - 1;
3583 else if (bno >= got.br_startoff + got.br_blockcount)
3584 low = lastx + 1;
3585 else {
3586 got.br_startblock = xfs_bmbt_get_startblock(ep);
3587 got.br_state = xfs_bmbt_get_state(ep);
3588 *eofp = 0;
3589 *lastxp = lastx;
3590 *gotp = got;
3591 return ep;
3592 }
3593 }
3594 if (bno >= got.br_startoff + got.br_blockcount) {
3595 lastx++;
3596 if (lastx == nextents) {
3597 *eofp = 1;
3598 got.br_startblock = xfs_bmbt_get_startblock(ep);
3599 got.br_state = xfs_bmbt_get_state(ep);
3600 *prevp = got;
3601 ep = NULL;
3602 } else {
3603 *eofp = 0;
3604 xfs_bmbt_get_all(ep, prevp);
3605 ep++;
3606 got.br_startoff = xfs_bmbt_get_startoff(ep);
3607 got.br_blockcount = xfs_bmbt_get_blockcount(ep);
3608 }
3609 } else {
3610 *eofp = 0;
3611 if (ep > base)
3612 xfs_bmbt_get_all(ep - 1, prevp);
3613 } 3513 }
3614 } 3514 *eofp = 1;
3615 if (ep) { 3515 ep = NULL;
3616 got.br_startblock = xfs_bmbt_get_startblock(ep);
3617 got.br_state = xfs_bmbt_get_state(ep);
3618 } 3516 }
3619 *lastxp = lastx; 3517 *lastxp = lastx;
3620 *gotp = got;
3621 return ep; 3518 return ep;
3622} 3519}
3623 3520
@@ -3639,20 +3536,14 @@ xfs_bmap_search_extents(
3639 xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ 3536 xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */
3640{ 3537{
3641 xfs_ifork_t *ifp; /* inode fork pointer */ 3538 xfs_ifork_t *ifp; /* inode fork pointer */
3642 xfs_bmbt_rec_t *base; /* base of extent list */ 3539 xfs_bmbt_rec_t *ep; /* extent record pointer */
3643 xfs_extnum_t lastx; /* last extent index used */
3644 xfs_extnum_t nextents; /* extent list size */
3645 xfs_bmbt_rec_t *ep; /* extent list entry pointer */
3646 int rt; /* realtime flag */ 3540 int rt; /* realtime flag */
3647 3541
3648 XFS_STATS_INC(xs_look_exlist); 3542 XFS_STATS_INC(xs_look_exlist);
3649 ifp = XFS_IFORK_PTR(ip, whichfork); 3543 ifp = XFS_IFORK_PTR(ip, whichfork);
3650 lastx = ifp->if_lastex;
3651 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
3652 base = &ifp->if_u1.if_extents[0];
3653 3544
3654 ep = xfs_bmap_do_search_extents(base, lastx, nextents, bno, eofp, 3545 ep = xfs_bmap_search_multi_extents(ifp, bno, eofp, lastxp, gotp, prevp);
3655 lastxp, gotp, prevp); 3546
3656 rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip); 3547 rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip);
3657 if (unlikely(!rt && !gotp->br_startblock && (*lastxp != NULLEXTNUM))) { 3548 if (unlikely(!rt && !gotp->br_startblock && (*lastxp != NULLEXTNUM))) {
3658 cmn_err(CE_PANIC,"Access to block zero: fs: <%s> inode: %lld " 3549 cmn_err(CE_PANIC,"Access to block zero: fs: <%s> inode: %lld "
@@ -3732,7 +3623,7 @@ xfs_bmap_trace_addentry(
3732} 3623}
3733 3624
3734/* 3625/*
3735 * Add bmap trace entry prior to a call to xfs_bmap_delete_exlist. 3626 * Add bmap trace entry prior to a call to xfs_iext_remove.
3736 */ 3627 */
3737STATIC void 3628STATIC void
3738xfs_bmap_trace_delete( 3629xfs_bmap_trace_delete(
@@ -3747,13 +3638,13 @@ xfs_bmap_trace_delete(
3747 3638
3748 ifp = XFS_IFORK_PTR(ip, whichfork); 3639 ifp = XFS_IFORK_PTR(ip, whichfork);
3749 xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_DELETE, fname, desc, ip, idx, 3640 xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_DELETE, fname, desc, ip, idx,
3750 cnt, &ifp->if_u1.if_extents[idx], 3641 cnt, xfs_iext_get_ext(ifp, idx),
3751 cnt == 2 ? &ifp->if_u1.if_extents[idx + 1] : NULL, 3642 cnt == 2 ? xfs_iext_get_ext(ifp, idx + 1) : NULL,
3752 whichfork); 3643 whichfork);
3753} 3644}
3754 3645
3755/* 3646/*
3756 * Add bmap trace entry prior to a call to xfs_bmap_insert_exlist, or 3647 * Add bmap trace entry prior to a call to xfs_iext_insert, or
3757 * reading in the extents list from the disk (in the btree). 3648 * reading in the extents list from the disk (in the btree).
3758 */ 3649 */
3759STATIC void 3650STATIC void
@@ -3783,7 +3674,7 @@ xfs_bmap_trace_insert(
3783} 3674}
3784 3675
3785/* 3676/*
3786 * Add bmap trace entry after updating an extent list entry in place. 3677 * Add bmap trace entry after updating an extent record in place.
3787 */ 3678 */
3788STATIC void 3679STATIC void
3789xfs_bmap_trace_post_update( 3680xfs_bmap_trace_post_update(
@@ -3797,11 +3688,11 @@ xfs_bmap_trace_post_update(
3797 3688
3798 ifp = XFS_IFORK_PTR(ip, whichfork); 3689 ifp = XFS_IFORK_PTR(ip, whichfork);
3799 xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_POST_UP, fname, desc, ip, idx, 3690 xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_POST_UP, fname, desc, ip, idx,
3800 1, &ifp->if_u1.if_extents[idx], NULL, whichfork); 3691 1, xfs_iext_get_ext(ifp, idx), NULL, whichfork);
3801} 3692}
3802 3693
3803/* 3694/*
3804 * Add bmap trace entry prior to updating an extent list entry in place. 3695 * Add bmap trace entry prior to updating an extent record in place.
3805 */ 3696 */
3806STATIC void 3697STATIC void
3807xfs_bmap_trace_pre_update( 3698xfs_bmap_trace_pre_update(
@@ -3815,7 +3706,7 @@ xfs_bmap_trace_pre_update(
3815 3706
3816 ifp = XFS_IFORK_PTR(ip, whichfork); 3707 ifp = XFS_IFORK_PTR(ip, whichfork);
3817 xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_PRE_UP, fname, desc, ip, idx, 1, 3708 xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_PRE_UP, fname, desc, ip, idx, 1,
3818 &ifp->if_u1.if_extents[idx], NULL, whichfork); 3709 xfs_iext_get_ext(ifp, idx), NULL, whichfork);
3819} 3710}
3820#endif /* XFS_BMAP_TRACE */ 3711#endif /* XFS_BMAP_TRACE */
3821 3712
@@ -3892,7 +3783,7 @@ xfs_bmap_add_attrfork(
3892 int rsvd) /* xact may use reserved blks */ 3783 int rsvd) /* xact may use reserved blks */
3893{ 3784{
3894 xfs_fsblock_t firstblock; /* 1st block/ag allocated */ 3785 xfs_fsblock_t firstblock; /* 1st block/ag allocated */
3895 xfs_bmap_free_t flist; /* freed extent list */ 3786 xfs_bmap_free_t flist; /* freed extent records */
3896 xfs_mount_t *mp; /* mount structure */ 3787 xfs_mount_t *mp; /* mount structure */
3897 xfs_trans_t *tp; /* transaction pointer */ 3788 xfs_trans_t *tp; /* transaction pointer */
3898 unsigned long s; /* spinlock spl value */ 3789 unsigned long s; /* spinlock spl value */
@@ -4146,7 +4037,7 @@ xfs_bmap_finish(
4146 xfs_efd_log_item_t *efd; /* extent free data */ 4037 xfs_efd_log_item_t *efd; /* extent free data */
4147 xfs_efi_log_item_t *efi; /* extent free intention */ 4038 xfs_efi_log_item_t *efi; /* extent free intention */
4148 int error; /* error return value */ 4039 int error; /* error return value */
4149 xfs_bmap_free_item_t *free; /* free extent list item */ 4040 xfs_bmap_free_item_t *free; /* free extent item */
4150 unsigned int logres; /* new log reservation */ 4041 unsigned int logres; /* new log reservation */
4151 unsigned int logcount; /* new log count */ 4042 unsigned int logcount; /* new log count */
4152 xfs_mount_t *mp; /* filesystem mount structure */ 4043 xfs_mount_t *mp; /* filesystem mount structure */
@@ -4242,9 +4133,9 @@ xfs_bmap_first_unused(
4242 xfs_fileoff_t *first_unused, /* unused block */ 4133 xfs_fileoff_t *first_unused, /* unused block */
4243 int whichfork) /* data or attr fork */ 4134 int whichfork) /* data or attr fork */
4244{ 4135{
4245 xfs_bmbt_rec_t *base; /* base of extent array */
4246 xfs_bmbt_rec_t *ep; /* pointer to an extent entry */ 4136 xfs_bmbt_rec_t *ep; /* pointer to an extent entry */
4247 int error; /* error return value */ 4137 int error; /* error return value */
4138 int idx; /* extent record index */
4248 xfs_ifork_t *ifp; /* inode fork pointer */ 4139 xfs_ifork_t *ifp; /* inode fork pointer */
4249 xfs_fileoff_t lastaddr; /* last block number seen */ 4140 xfs_fileoff_t lastaddr; /* last block number seen */
4250 xfs_fileoff_t lowest; /* lowest useful block */ 4141 xfs_fileoff_t lowest; /* lowest useful block */
@@ -4265,10 +4156,8 @@ xfs_bmap_first_unused(
4265 return error; 4156 return error;
4266 lowest = *first_unused; 4157 lowest = *first_unused;
4267 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 4158 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
4268 base = &ifp->if_u1.if_extents[0]; 4159 for (idx = 0, lastaddr = 0, max = lowest; idx < nextents; idx++) {
4269 for (lastaddr = 0, max = lowest, ep = base; 4160 ep = xfs_iext_get_ext(ifp, idx);
4270 ep < &base[nextents];
4271 ep++) {
4272 off = xfs_bmbt_get_startoff(ep); 4161 off = xfs_bmbt_get_startoff(ep);
4273 /* 4162 /*
4274 * See if the hole before this extent will work. 4163 * See if the hole before this extent will work.
@@ -4287,8 +4176,8 @@ xfs_bmap_first_unused(
4287/* 4176/*
4288 * Returns the file-relative block number of the last block + 1 before 4177 * Returns the file-relative block number of the last block + 1 before
4289 * last_block (input value) in the file. 4178 * last_block (input value) in the file.
4290 * This is not based on i_size, it is based on the extent list. 4179 * This is not based on i_size, it is based on the extent records.
4291 * Returns 0 for local files, as they do not have an extent list. 4180 * Returns 0 for local files, as they do not have extent records.
4292 */ 4181 */
4293int /* error */ 4182int /* error */
4294xfs_bmap_last_before( 4183xfs_bmap_last_before(
@@ -4335,8 +4224,8 @@ xfs_bmap_last_before(
4335 4224
4336/* 4225/*
4337 * Returns the file-relative block number of the first block past eof in 4226 * Returns the file-relative block number of the first block past eof in
4338 * the file. This is not based on i_size, it is based on the extent list. 4227 * the file. This is not based on i_size, it is based on the extent records.
4339 * Returns 0 for local files, as they do not have an extent list. 4228 * Returns 0 for local files, as they do not have extent records.
4340 */ 4229 */
4341int /* error */ 4230int /* error */
4342xfs_bmap_last_offset( 4231xfs_bmap_last_offset(
@@ -4345,7 +4234,6 @@ xfs_bmap_last_offset(
4345 xfs_fileoff_t *last_block, /* last block */ 4234 xfs_fileoff_t *last_block, /* last block */
4346 int whichfork) /* data or attr fork */ 4235 int whichfork) /* data or attr fork */
4347{ 4236{
4348 xfs_bmbt_rec_t *base; /* base of extent array */
4349 xfs_bmbt_rec_t *ep; /* pointer to last extent */ 4237 xfs_bmbt_rec_t *ep; /* pointer to last extent */
4350 int error; /* error return value */ 4238 int error; /* error return value */
4351 xfs_ifork_t *ifp; /* inode fork pointer */ 4239 xfs_ifork_t *ifp; /* inode fork pointer */
@@ -4368,9 +4256,7 @@ xfs_bmap_last_offset(
4368 *last_block = 0; 4256 *last_block = 0;
4369 return 0; 4257 return 0;
4370 } 4258 }
4371 base = &ifp->if_u1.if_extents[0]; 4259 ep = xfs_iext_get_ext(ifp, nextents - 1);
4372 ASSERT(base != NULL);
4373 ep = &base[nextents - 1];
4374 *last_block = xfs_bmbt_get_startoff(ep) + xfs_bmbt_get_blockcount(ep); 4260 *last_block = xfs_bmbt_get_startoff(ep) + xfs_bmbt_get_blockcount(ep);
4375 return 0; 4261 return 0;
4376} 4262}
@@ -4400,7 +4286,7 @@ xfs_bmap_one_block(
4400 return 0; 4286 return 0;
4401 ifp = XFS_IFORK_PTR(ip, whichfork); 4287 ifp = XFS_IFORK_PTR(ip, whichfork);
4402 ASSERT(ifp->if_flags & XFS_IFEXTENTS); 4288 ASSERT(ifp->if_flags & XFS_IFEXTENTS);
4403 ep = ifp->if_u1.if_extents; 4289 ep = xfs_iext_get_ext(ifp, 0);
4404 xfs_bmbt_get_all(ep, &s); 4290 xfs_bmbt_get_all(ep, &s);
4405 rval = s.br_startoff == 0 && s.br_blockcount == 1; 4291 rval = s.br_startoff == 0 && s.br_blockcount == 1;
4406 if (rval && whichfork == XFS_DATA_FORK) 4292 if (rval && whichfork == XFS_DATA_FORK)
@@ -4435,7 +4321,6 @@ xfs_bmap_read_extents(
4435 xfs_bmbt_ptr_t *pp; /* pointer to block address */ 4321 xfs_bmbt_ptr_t *pp; /* pointer to block address */
4436 /* REFERENCED */ 4322 /* REFERENCED */
4437 xfs_extnum_t room; /* number of entries there's room for */ 4323 xfs_extnum_t room; /* number of entries there's room for */
4438 xfs_bmbt_rec_t *trp; /* target record pointer */
4439 4324
4440 bno = NULLFSBLOCK; 4325 bno = NULLFSBLOCK;
4441 mp = ip->i_mount; 4326 mp = ip->i_mount;
@@ -4478,16 +4363,16 @@ xfs_bmap_read_extents(
4478 /* 4363 /*
4479 * Here with bp and block set to the leftmost leaf node in the tree. 4364 * Here with bp and block set to the leftmost leaf node in the tree.
4480 */ 4365 */
4481 room = ifp->if_bytes / (uint)sizeof(*trp); 4366 room = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
4482 trp = ifp->if_u1.if_extents;
4483 i = 0; 4367 i = 0;
4484 /* 4368 /*
4485 * Loop over all leaf nodes. Copy information to the extent list. 4369 * Loop over all leaf nodes. Copy information to the extent records.
4486 */ 4370 */
4487 for (;;) { 4371 for (;;) {
4488 xfs_bmbt_rec_t *frp, *temp; 4372 xfs_bmbt_rec_t *frp, *trp;
4489 xfs_fsblock_t nextbno; 4373 xfs_fsblock_t nextbno;
4490 xfs_extnum_t num_recs; 4374 xfs_extnum_t num_recs;
4375 xfs_extnum_t start;
4491 4376
4492 4377
4493 num_recs = be16_to_cpu(block->bb_numrecs); 4378 num_recs = be16_to_cpu(block->bb_numrecs);
@@ -4511,12 +4396,13 @@ xfs_bmap_read_extents(
4511 if (nextbno != NULLFSBLOCK) 4396 if (nextbno != NULLFSBLOCK)
4512 xfs_btree_reada_bufl(mp, nextbno, 1); 4397 xfs_btree_reada_bufl(mp, nextbno, 1);
4513 /* 4398 /*
4514 * Copy records into the extent list. 4399 * Copy records into the extent records.
4515 */ 4400 */
4516 frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, 4401 frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt,
4517 block, 1, mp->m_bmap_dmxr[0]); 4402 block, 1, mp->m_bmap_dmxr[0]);
4518 temp = trp; 4403 start = i;
4519 for (j = 0; j < num_recs; j++, frp++, trp++) { 4404 for (j = 0; j < num_recs; j++, i++, frp++) {
4405 trp = xfs_iext_get_ext(ifp, i);
4520 trp->l0 = INT_GET(frp->l0, ARCH_CONVERT); 4406 trp->l0 = INT_GET(frp->l0, ARCH_CONVERT);
4521 trp->l1 = INT_GET(frp->l1, ARCH_CONVERT); 4407 trp->l1 = INT_GET(frp->l1, ARCH_CONVERT);
4522 } 4408 }
@@ -4526,14 +4412,14 @@ xfs_bmap_read_extents(
4526 * any "older" data bmap btree records for a 4412 * any "older" data bmap btree records for a
4527 * set bit in the "extent flag" position. 4413 * set bit in the "extent flag" position.
4528 */ 4414 */
4529 if (unlikely(xfs_check_nostate_extents(temp, num_recs))) { 4415 if (unlikely(xfs_check_nostate_extents(ifp,
4416 start, num_recs))) {
4530 XFS_ERROR_REPORT("xfs_bmap_read_extents(2)", 4417 XFS_ERROR_REPORT("xfs_bmap_read_extents(2)",
4531 XFS_ERRLEVEL_LOW, 4418 XFS_ERRLEVEL_LOW,
4532 ip->i_mount); 4419 ip->i_mount);
4533 goto error0; 4420 goto error0;
4534 } 4421 }
4535 } 4422 }
4536 i += num_recs;
4537 xfs_trans_brelse(tp, bp); 4423 xfs_trans_brelse(tp, bp);
4538 bno = nextbno; 4424 bno = nextbno;
4539 /* 4425 /*
@@ -4546,7 +4432,7 @@ xfs_bmap_read_extents(
4546 return error; 4432 return error;
4547 block = XFS_BUF_TO_BMBT_BLOCK(bp); 4433 block = XFS_BUF_TO_BMBT_BLOCK(bp);
4548 } 4434 }
4549 ASSERT(i == ifp->if_bytes / (uint)sizeof(*trp)); 4435 ASSERT(i == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)));
4550 ASSERT(i == XFS_IFORK_NEXTENTS(ip, whichfork)); 4436 ASSERT(i == XFS_IFORK_NEXTENTS(ip, whichfork));
4551 xfs_bmap_trace_exlist(fname, ip, i, whichfork); 4437 xfs_bmap_trace_exlist(fname, ip, i, whichfork);
4552 return 0; 4438 return 0;
@@ -4557,7 +4443,7 @@ error0:
4557 4443
4558#ifdef XFS_BMAP_TRACE 4444#ifdef XFS_BMAP_TRACE
4559/* 4445/*
4560 * Add bmap trace insert entries for all the contents of the extent list. 4446 * Add bmap trace insert entries for all the contents of the extent records.
4561 */ 4447 */
4562void 4448void
4563xfs_bmap_trace_exlist( 4449xfs_bmap_trace_exlist(
@@ -4566,16 +4452,15 @@ xfs_bmap_trace_exlist(
4566 xfs_extnum_t cnt, /* count of entries in the list */ 4452 xfs_extnum_t cnt, /* count of entries in the list */
4567 int whichfork) /* data or attr fork */ 4453 int whichfork) /* data or attr fork */
4568{ 4454{
4569 xfs_bmbt_rec_t *base; /* base of extent list */ 4455 xfs_bmbt_rec_t *ep; /* current extent record */
4570 xfs_bmbt_rec_t *ep; /* current entry in extent list */ 4456 xfs_extnum_t idx; /* extent record index */
4571 xfs_extnum_t idx; /* extent list entry number */
4572 xfs_ifork_t *ifp; /* inode fork pointer */ 4457 xfs_ifork_t *ifp; /* inode fork pointer */
4573 xfs_bmbt_irec_t s; /* extent list record */ 4458 xfs_bmbt_irec_t s; /* file extent record */
4574 4459
4575 ifp = XFS_IFORK_PTR(ip, whichfork); 4460 ifp = XFS_IFORK_PTR(ip, whichfork);
4576 ASSERT(cnt == ifp->if_bytes / (uint)sizeof(*base)); 4461 ASSERT(cnt == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)));
4577 base = ifp->if_u1.if_extents; 4462 for (idx = 0; idx < cnt; idx++) {
4578 for (idx = 0, ep = base; idx < cnt; idx++, ep++) { 4463 ep = xfs_iext_get_ext(ifp, idx);
4579 xfs_bmbt_get_all(ep, &s); 4464 xfs_bmbt_get_all(ep, &s);
4580 xfs_bmap_trace_insert(fname, "exlist", ip, idx, 1, &s, NULL, 4465 xfs_bmap_trace_insert(fname, "exlist", ip, idx, 1, &s, NULL,
4581 whichfork); 4466 whichfork);
@@ -4661,14 +4546,10 @@ xfs_bmapi(
4661 xfs_bmalloca_t bma; /* args for xfs_bmap_alloc */ 4546 xfs_bmalloca_t bma; /* args for xfs_bmap_alloc */
4662 xfs_btree_cur_t *cur; /* bmap btree cursor */ 4547 xfs_btree_cur_t *cur; /* bmap btree cursor */
4663 xfs_fileoff_t end; /* end of mapped file region */ 4548 xfs_fileoff_t end; /* end of mapped file region */
4664 int eof; /* we've hit the end of extent list */ 4549 int eof; /* we've hit the end of extents */
4665 char contig; /* allocation must be one extent */ 4550 xfs_bmbt_rec_t *ep; /* extent record pointer */
4666 char delay; /* this request is for delayed alloc */
4667 char exact; /* don't do all of wasdelayed extent */
4668 char convert; /* unwritten extent I/O completion */
4669 xfs_bmbt_rec_t *ep; /* extent list entry pointer */
4670 int error; /* error return */ 4551 int error; /* error return */
4671 xfs_bmbt_irec_t got; /* current extent list record */ 4552 xfs_bmbt_irec_t got; /* current file extent record */
4672 xfs_ifork_t *ifp; /* inode fork pointer */ 4553 xfs_ifork_t *ifp; /* inode fork pointer */
4673 xfs_extlen_t indlen; /* indirect blocks length */ 4554 xfs_extlen_t indlen; /* indirect blocks length */
4674 xfs_extnum_t lastx; /* last useful extent number */ 4555 xfs_extnum_t lastx; /* last useful extent number */
@@ -4680,17 +4561,13 @@ xfs_bmapi(
4680 int nallocs; /* number of extents alloc\'d */ 4561 int nallocs; /* number of extents alloc\'d */
4681 xfs_extnum_t nextents; /* number of extents in file */ 4562 xfs_extnum_t nextents; /* number of extents in file */
4682 xfs_fileoff_t obno; /* old block number (offset) */ 4563 xfs_fileoff_t obno; /* old block number (offset) */
4683 xfs_bmbt_irec_t prev; /* previous extent list record */ 4564 xfs_bmbt_irec_t prev; /* previous file extent record */
4684 int tmp_logflags; /* temp flags holder */ 4565 int tmp_logflags; /* temp flags holder */
4685 int whichfork; /* data or attr fork */ 4566 int whichfork; /* data or attr fork */
4686 char inhole; /* current location is hole in file */ 4567 char inhole; /* current location is hole in file */
4687 char stateless; /* ignore state flag set */
4688 char trim; /* output trimmed to match range */
4689 char userdata; /* allocating non-metadata */
4690 char wasdelay; /* old extent was delayed */ 4568 char wasdelay; /* old extent was delayed */
4691 char wr; /* this is a write request */ 4569 char wr; /* this is a write request */
4692 char rt; /* this is a realtime file */ 4570 char rt; /* this is a realtime file */
4693 char rsvd; /* OK to allocate reserved blocks */
4694#ifdef DEBUG 4571#ifdef DEBUG
4695 xfs_fileoff_t orig_bno; /* original block number value */ 4572 xfs_fileoff_t orig_bno; /* original block number value */
4696 int orig_flags; /* original flags arg value */ 4573 int orig_flags; /* original flags arg value */
@@ -4727,15 +4604,8 @@ xfs_bmapi(
4727 XFS_STATS_INC(xs_blk_mapw); 4604 XFS_STATS_INC(xs_blk_mapw);
4728 else 4605 else
4729 XFS_STATS_INC(xs_blk_mapr); 4606 XFS_STATS_INC(xs_blk_mapr);
4730 delay = (flags & XFS_BMAPI_DELAY) != 0;
4731 trim = (flags & XFS_BMAPI_ENTIRE) == 0;
4732 userdata = (flags & XFS_BMAPI_METADATA) == 0;
4733 convert = (flags & XFS_BMAPI_CONVERT) != 0;
4734 exact = (flags & XFS_BMAPI_EXACT) != 0;
4735 rsvd = (flags & XFS_BMAPI_RSVBLOCKS) != 0;
4736 contig = (flags & XFS_BMAPI_CONTIG) != 0;
4737 /* 4607 /*
4738 * stateless is used to combine extents which 4608 * IGSTATE flag is used to combine extents which
4739 * differ only due to the state of the extents. 4609 * differ only due to the state of the extents.
4740 * This technique is used from xfs_getbmap() 4610 * This technique is used from xfs_getbmap()
4741 * when the caller does not wish to see the 4611 * when the caller does not wish to see the
@@ -4751,10 +4621,9 @@ xfs_bmapi(
4751 * xfs_strat_comp(), where the xfs_bmapi() call 4621 * xfs_strat_comp(), where the xfs_bmapi() call
4752 * is transactioned, and the extents combined. 4622 * is transactioned, and the extents combined.
4753 */ 4623 */
4754 stateless = (flags & XFS_BMAPI_IGSTATE) != 0; 4624 if ((flags & XFS_BMAPI_IGSTATE) && wr) /* if writing unwritten space */
4755 if (stateless && wr) /* if writing unwritten space, no */ 4625 wr = 0; /* no allocations are allowed */
4756 wr = 0; /* allocations are allowed */ 4626 ASSERT(wr || !(flags & XFS_BMAPI_DELAY));
4757 ASSERT(wr || !delay);
4758 logflags = 0; 4627 logflags = 0;
4759 nallocs = 0; 4628 nallocs = 0;
4760 cur = NULL; 4629 cur = NULL;
@@ -4789,7 +4658,7 @@ xfs_bmapi(
4789 if (eof && !wr) 4658 if (eof && !wr)
4790 got.br_startoff = end; 4659 got.br_startoff = end;
4791 inhole = eof || got.br_startoff > bno; 4660 inhole = eof || got.br_startoff > bno;
4792 wasdelay = wr && !inhole && !delay && 4661 wasdelay = wr && !inhole && !(flags & XFS_BMAPI_DELAY) &&
4793 ISNULLSTARTBLOCK(got.br_startblock); 4662 ISNULLSTARTBLOCK(got.br_startblock);
4794 /* 4663 /*
4795 * First, deal with the hole before the allocated space 4664 * First, deal with the hole before the allocated space
@@ -4801,11 +4670,11 @@ xfs_bmapi(
4801 * allocate the stuff asked for in this bmap call 4670 * allocate the stuff asked for in this bmap call
4802 * but that wouldn't be as good. 4671 * but that wouldn't be as good.
4803 */ 4672 */
4804 if (wasdelay && !exact) { 4673 if (wasdelay && !(flags & XFS_BMAPI_EXACT)) {
4805 alen = (xfs_extlen_t)got.br_blockcount; 4674 alen = (xfs_extlen_t)got.br_blockcount;
4806 aoff = got.br_startoff; 4675 aoff = got.br_startoff;
4807 if (lastx != NULLEXTNUM && lastx) { 4676 if (lastx != NULLEXTNUM && lastx) {
4808 ep = &ifp->if_u1.if_extents[lastx - 1]; 4677 ep = xfs_iext_get_ext(ifp, lastx - 1);
4809 xfs_bmbt_get_all(ep, &prev); 4678 xfs_bmbt_get_all(ep, &prev);
4810 } 4679 }
4811 } else if (wasdelay) { 4680 } else if (wasdelay) {
@@ -4823,8 +4692,8 @@ xfs_bmapi(
4823 got.br_startoff - bno); 4692 got.br_startoff - bno);
4824 aoff = bno; 4693 aoff = bno;
4825 } 4694 }
4826 minlen = contig ? alen : 1; 4695 minlen = (flags & XFS_BMAPI_CONTIG) ? alen : 1;
4827 if (delay) { 4696 if (flags & XFS_BMAPI_DELAY) {
4828 xfs_extlen_t extsz; 4697 xfs_extlen_t extsz;
4829 4698
4830 /* Figure out the extent size, adjust alen */ 4699 /* Figure out the extent size, adjust alen */
@@ -4837,7 +4706,9 @@ xfs_bmapi(
4837 if (extsz) { 4706 if (extsz) {
4838 error = xfs_bmap_extsize_align(mp, 4707 error = xfs_bmap_extsize_align(mp,
4839 &got, &prev, extsz, 4708 &got, &prev, extsz,
4840 rt, eof, delay, convert, 4709 rt, eof,
4710 flags&XFS_BMAPI_DELAY,
4711 flags&XFS_BMAPI_CONVERT,
4841 &aoff, &alen); 4712 &aoff, &alen);
4842 ASSERT(!error); 4713 ASSERT(!error);
4843 } 4714 }
@@ -4875,24 +4746,29 @@ xfs_bmapi(
4875 if (rt) { 4746 if (rt) {
4876 error = xfs_mod_incore_sb(mp, 4747 error = xfs_mod_incore_sb(mp,
4877 XFS_SBS_FREXTENTS, 4748 XFS_SBS_FREXTENTS,
4878 -(extsz), rsvd); 4749 -(extsz), (flags &
4750 XFS_BMAPI_RSVBLOCKS));
4879 } else { 4751 } else {
4880 error = xfs_mod_incore_sb(mp, 4752 error = xfs_mod_incore_sb(mp,
4881 XFS_SBS_FDBLOCKS, 4753 XFS_SBS_FDBLOCKS,
4882 -(alen), rsvd); 4754 -(alen), (flags &
4755 XFS_BMAPI_RSVBLOCKS));
4883 } 4756 }
4884 if (!error) { 4757 if (!error) {
4885 error = xfs_mod_incore_sb(mp, 4758 error = xfs_mod_incore_sb(mp,
4886 XFS_SBS_FDBLOCKS, 4759 XFS_SBS_FDBLOCKS,
4887 -(indlen), rsvd); 4760 -(indlen), (flags &
4761 XFS_BMAPI_RSVBLOCKS));
4888 if (error && rt) 4762 if (error && rt)
4889 xfs_mod_incore_sb(mp, 4763 xfs_mod_incore_sb(mp,
4890 XFS_SBS_FREXTENTS, 4764 XFS_SBS_FREXTENTS,
4891 extsz, rsvd); 4765 extsz, (flags &
4766 XFS_BMAPI_RSVBLOCKS));
4892 else if (error) 4767 else if (error)
4893 xfs_mod_incore_sb(mp, 4768 xfs_mod_incore_sb(mp,
4894 XFS_SBS_FDBLOCKS, 4769 XFS_SBS_FDBLOCKS,
4895 alen, rsvd); 4770 alen, (flags &
4771 XFS_BMAPI_RSVBLOCKS));
4896 } 4772 }
4897 4773
4898 if (error) { 4774 if (error) {
@@ -4925,7 +4801,7 @@ xfs_bmapi(
4925 /* Indicate if this is the first user data 4801 /* Indicate if this is the first user data
4926 * in the file, or just any user data. 4802 * in the file, or just any user data.
4927 */ 4803 */
4928 if (userdata) { 4804 if (!(flags & XFS_BMAPI_METADATA)) {
4929 bma.userdata = (aoff == 0) ? 4805 bma.userdata = (aoff == 0) ?
4930 XFS_ALLOC_INITIAL_USER_DATA : 4806 XFS_ALLOC_INITIAL_USER_DATA :
4931 XFS_ALLOC_USERDATA; 4807 XFS_ALLOC_USERDATA;
@@ -4937,7 +4813,7 @@ xfs_bmapi(
4937 bma.firstblock = *firstblock; 4813 bma.firstblock = *firstblock;
4938 bma.alen = alen; 4814 bma.alen = alen;
4939 bma.off = aoff; 4815 bma.off = aoff;
4940 bma.conv = convert; 4816 bma.conv = (flags & XFS_BMAPI_CONVERT);
4941 bma.wasdel = wasdelay; 4817 bma.wasdel = wasdelay;
4942 bma.minlen = minlen; 4818 bma.minlen = minlen;
4943 bma.low = flist->xbf_low; 4819 bma.low = flist->xbf_low;
@@ -4948,7 +4824,8 @@ xfs_bmapi(
4948 * is larger than a stripe unit. 4824 * is larger than a stripe unit.
4949 */ 4825 */
4950 if (mp->m_dalign && alen >= mp->m_dalign && 4826 if (mp->m_dalign && alen >= mp->m_dalign &&
4951 userdata && whichfork == XFS_DATA_FORK) { 4827 (!(flags & XFS_BMAPI_METADATA)) &&
4828 (whichfork == XFS_DATA_FORK)) {
4952 if ((error = xfs_bmap_isaeof(ip, aoff, 4829 if ((error = xfs_bmap_isaeof(ip, aoff,
4953 whichfork, &bma.aeof))) 4830 whichfork, &bma.aeof)))
4954 goto error0; 4831 goto error0;
@@ -5011,19 +4888,19 @@ xfs_bmapi(
5011 } 4888 }
5012 error = xfs_bmap_add_extent(ip, lastx, &cur, &got, 4889 error = xfs_bmap_add_extent(ip, lastx, &cur, &got,
5013 firstblock, flist, &tmp_logflags, whichfork, 4890 firstblock, flist, &tmp_logflags, whichfork,
5014 rsvd); 4891 (flags & XFS_BMAPI_RSVBLOCKS));
5015 logflags |= tmp_logflags; 4892 logflags |= tmp_logflags;
5016 if (error) 4893 if (error)
5017 goto error0; 4894 goto error0;
5018 lastx = ifp->if_lastex; 4895 lastx = ifp->if_lastex;
5019 ep = &ifp->if_u1.if_extents[lastx]; 4896 ep = xfs_iext_get_ext(ifp, lastx);
5020 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 4897 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
5021 xfs_bmbt_get_all(ep, &got); 4898 xfs_bmbt_get_all(ep, &got);
5022 ASSERT(got.br_startoff <= aoff); 4899 ASSERT(got.br_startoff <= aoff);
5023 ASSERT(got.br_startoff + got.br_blockcount >= 4900 ASSERT(got.br_startoff + got.br_blockcount >=
5024 aoff + alen); 4901 aoff + alen);
5025#ifdef DEBUG 4902#ifdef DEBUG
5026 if (delay) { 4903 if (flags & XFS_BMAPI_DELAY) {
5027 ASSERT(ISNULLSTARTBLOCK(got.br_startblock)); 4904 ASSERT(ISNULLSTARTBLOCK(got.br_startblock));
5028 ASSERT(STARTBLOCKVAL(got.br_startblock) > 0); 4905 ASSERT(STARTBLOCKVAL(got.br_startblock) > 0);
5029 } 4906 }
@@ -5052,14 +4929,15 @@ xfs_bmapi(
5052 * Then deal with the allocated space we found. 4929 * Then deal with the allocated space we found.
5053 */ 4930 */
5054 ASSERT(ep != NULL); 4931 ASSERT(ep != NULL);
5055 if (trim && (got.br_startoff + got.br_blockcount > obno)) { 4932 if (!(flags & XFS_BMAPI_ENTIRE) &&
4933 (got.br_startoff + got.br_blockcount > obno)) {
5056 if (obno > bno) 4934 if (obno > bno)
5057 bno = obno; 4935 bno = obno;
5058 ASSERT((bno >= obno) || (n == 0)); 4936 ASSERT((bno >= obno) || (n == 0));
5059 ASSERT(bno < end); 4937 ASSERT(bno < end);
5060 mval->br_startoff = bno; 4938 mval->br_startoff = bno;
5061 if (ISNULLSTARTBLOCK(got.br_startblock)) { 4939 if (ISNULLSTARTBLOCK(got.br_startblock)) {
5062 ASSERT(!wr || delay); 4940 ASSERT(!wr || (flags & XFS_BMAPI_DELAY));
5063 mval->br_startblock = DELAYSTARTBLOCK; 4941 mval->br_startblock = DELAYSTARTBLOCK;
5064 } else 4942 } else
5065 mval->br_startblock = 4943 mval->br_startblock =
@@ -5081,7 +4959,7 @@ xfs_bmapi(
5081 } else { 4959 } else {
5082 *mval = got; 4960 *mval = got;
5083 if (ISNULLSTARTBLOCK(mval->br_startblock)) { 4961 if (ISNULLSTARTBLOCK(mval->br_startblock)) {
5084 ASSERT(!wr || delay); 4962 ASSERT(!wr || (flags & XFS_BMAPI_DELAY));
5085 mval->br_startblock = DELAYSTARTBLOCK; 4963 mval->br_startblock = DELAYSTARTBLOCK;
5086 } 4964 }
5087 } 4965 }
@@ -5107,12 +4985,12 @@ xfs_bmapi(
5107 mval->br_state = XFS_EXT_NORM; 4985 mval->br_state = XFS_EXT_NORM;
5108 error = xfs_bmap_add_extent(ip, lastx, &cur, mval, 4986 error = xfs_bmap_add_extent(ip, lastx, &cur, mval,
5109 firstblock, flist, &tmp_logflags, whichfork, 4987 firstblock, flist, &tmp_logflags, whichfork,
5110 rsvd); 4988 (flags & XFS_BMAPI_RSVBLOCKS));
5111 logflags |= tmp_logflags; 4989 logflags |= tmp_logflags;
5112 if (error) 4990 if (error)
5113 goto error0; 4991 goto error0;
5114 lastx = ifp->if_lastex; 4992 lastx = ifp->if_lastex;
5115 ep = &ifp->if_u1.if_extents[lastx]; 4993 ep = xfs_iext_get_ext(ifp, lastx);
5116 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 4994 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
5117 xfs_bmbt_get_all(ep, &got); 4995 xfs_bmbt_get_all(ep, &got);
5118 /* 4996 /*
@@ -5124,9 +5002,10 @@ xfs_bmapi(
5124 continue; 5002 continue;
5125 } 5003 }
5126 5004
5127 ASSERT(!trim || 5005 ASSERT((flags & XFS_BMAPI_ENTIRE) ||
5128 ((mval->br_startoff + mval->br_blockcount) <= end)); 5006 ((mval->br_startoff + mval->br_blockcount) <= end));
5129 ASSERT(!trim || (mval->br_blockcount <= len) || 5007 ASSERT((flags & XFS_BMAPI_ENTIRE) ||
5008 (mval->br_blockcount <= len) ||
5130 (mval->br_startoff < obno)); 5009 (mval->br_startoff < obno));
5131 bno = mval->br_startoff + mval->br_blockcount; 5010 bno = mval->br_startoff + mval->br_blockcount;
5132 len = end - bno; 5011 len = end - bno;
@@ -5141,7 +5020,8 @@ xfs_bmapi(
5141 mval[-1].br_startblock != HOLESTARTBLOCK && 5020 mval[-1].br_startblock != HOLESTARTBLOCK &&
5142 mval->br_startblock == 5021 mval->br_startblock ==
5143 mval[-1].br_startblock + mval[-1].br_blockcount && 5022 mval[-1].br_startblock + mval[-1].br_blockcount &&
5144 (stateless || mval[-1].br_state == mval->br_state)) { 5023 ((flags & XFS_BMAPI_IGSTATE) ||
5024 mval[-1].br_state == mval->br_state)) {
5145 ASSERT(mval->br_startoff == 5025 ASSERT(mval->br_startoff ==
5146 mval[-1].br_startoff + mval[-1].br_blockcount); 5026 mval[-1].br_startoff + mval[-1].br_blockcount);
5147 mval[-1].br_blockcount += mval->br_blockcount; 5027 mval[-1].br_blockcount += mval->br_blockcount;
@@ -5168,8 +5048,7 @@ xfs_bmapi(
5168 /* 5048 /*
5169 * Else go on to the next record. 5049 * Else go on to the next record.
5170 */ 5050 */
5171 ep++; 5051 ep = xfs_iext_get_ext(ifp, ++lastx);
5172 lastx++;
5173 if (lastx >= nextents) { 5052 if (lastx >= nextents) {
5174 eof = 1; 5053 eof = 1;
5175 prev = got; 5054 prev = got;
@@ -5199,7 +5078,7 @@ xfs_bmapi(
5199error0: 5078error0:
5200 /* 5079 /*
5201 * Log everything. Do this after conversion, there's no point in 5080 * Log everything. Do this after conversion, there's no point in
5202 * logging the extent list if we've converted to btree format. 5081 * logging the extent records if we've converted to btree format.
5203 */ 5082 */
5204 if ((logflags & XFS_ILOG_FEXT(whichfork)) && 5083 if ((logflags & XFS_ILOG_FEXT(whichfork)) &&
5205 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) 5084 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)
@@ -5252,12 +5131,12 @@ xfs_bmapi_single(
5252 xfs_fsblock_t *fsb, /* output: mapped block */ 5131 xfs_fsblock_t *fsb, /* output: mapped block */
5253 xfs_fileoff_t bno) /* starting file offs. mapped */ 5132 xfs_fileoff_t bno) /* starting file offs. mapped */
5254{ 5133{
5255 int eof; /* we've hit the end of extent list */ 5134 int eof; /* we've hit the end of extents */
5256 int error; /* error return */ 5135 int error; /* error return */
5257 xfs_bmbt_irec_t got; /* current extent list record */ 5136 xfs_bmbt_irec_t got; /* current file extent record */
5258 xfs_ifork_t *ifp; /* inode fork pointer */ 5137 xfs_ifork_t *ifp; /* inode fork pointer */
5259 xfs_extnum_t lastx; /* last useful extent number */ 5138 xfs_extnum_t lastx; /* last useful extent number */
5260 xfs_bmbt_irec_t prev; /* previous extent list record */ 5139 xfs_bmbt_irec_t prev; /* previous file extent record */
5261 5140
5262 ifp = XFS_IFORK_PTR(ip, whichfork); 5141 ifp = XFS_IFORK_PTR(ip, whichfork);
5263 if (unlikely( 5142 if (unlikely(
@@ -5312,18 +5191,18 @@ xfs_bunmapi(
5312 xfs_btree_cur_t *cur; /* bmap btree cursor */ 5191 xfs_btree_cur_t *cur; /* bmap btree cursor */
5313 xfs_bmbt_irec_t del; /* extent being deleted */ 5192 xfs_bmbt_irec_t del; /* extent being deleted */
5314 int eof; /* is deleting at eof */ 5193 int eof; /* is deleting at eof */
5315 xfs_bmbt_rec_t *ep; /* extent list entry pointer */ 5194 xfs_bmbt_rec_t *ep; /* extent record pointer */
5316 int error; /* error return value */ 5195 int error; /* error return value */
5317 xfs_extnum_t extno; /* extent number in list */ 5196 xfs_extnum_t extno; /* extent number in list */
5318 xfs_bmbt_irec_t got; /* current extent list entry */ 5197 xfs_bmbt_irec_t got; /* current extent record */
5319 xfs_ifork_t *ifp; /* inode fork pointer */ 5198 xfs_ifork_t *ifp; /* inode fork pointer */
5320 int isrt; /* freeing in rt area */ 5199 int isrt; /* freeing in rt area */
5321 xfs_extnum_t lastx; /* last extent index used */ 5200 xfs_extnum_t lastx; /* last extent index used */
5322 int logflags; /* transaction logging flags */ 5201 int logflags; /* transaction logging flags */
5323 xfs_extlen_t mod; /* rt extent offset */ 5202 xfs_extlen_t mod; /* rt extent offset */
5324 xfs_mount_t *mp; /* mount structure */ 5203 xfs_mount_t *mp; /* mount structure */
5325 xfs_extnum_t nextents; /* size of extent list */ 5204 xfs_extnum_t nextents; /* number of file extents */
5326 xfs_bmbt_irec_t prev; /* previous extent list entry */ 5205 xfs_bmbt_irec_t prev; /* previous extent record */
5327 xfs_fileoff_t start; /* first file offset deleted */ 5206 xfs_fileoff_t start; /* first file offset deleted */
5328 int tmp_logflags; /* partial logging flags */ 5207 int tmp_logflags; /* partial logging flags */
5329 int wasdel; /* was a delayed alloc extent */ 5208 int wasdel; /* was a delayed alloc extent */
@@ -5369,7 +5248,7 @@ xfs_bunmapi(
5369 * file, back up to the last block if so... 5248 * file, back up to the last block if so...
5370 */ 5249 */
5371 if (eof) { 5250 if (eof) {
5372 ep = &ifp->if_u1.if_extents[--lastx]; 5251 ep = xfs_iext_get_ext(ifp, --lastx);
5373 xfs_bmbt_get_all(ep, &got); 5252 xfs_bmbt_get_all(ep, &got);
5374 bno = got.br_startoff + got.br_blockcount - 1; 5253 bno = got.br_startoff + got.br_blockcount - 1;
5375 } 5254 }
@@ -5393,7 +5272,7 @@ xfs_bunmapi(
5393 if (got.br_startoff > bno) { 5272 if (got.br_startoff > bno) {
5394 if (--lastx < 0) 5273 if (--lastx < 0)
5395 break; 5274 break;
5396 ep--; 5275 ep = xfs_iext_get_ext(ifp, lastx);
5397 xfs_bmbt_get_all(ep, &got); 5276 xfs_bmbt_get_all(ep, &got);
5398 } 5277 }
5399 /* 5278 /*
@@ -5440,7 +5319,8 @@ xfs_bunmapi(
5440 del.br_blockcount : mod; 5319 del.br_blockcount : mod;
5441 if (bno < got.br_startoff) { 5320 if (bno < got.br_startoff) {
5442 if (--lastx >= 0) 5321 if (--lastx >= 0)
5443 xfs_bmbt_get_all(--ep, &got); 5322 xfs_bmbt_get_all(xfs_iext_get_ext(
5323 ifp, lastx), &got);
5444 } 5324 }
5445 continue; 5325 continue;
5446 } 5326 }
@@ -5500,7 +5380,8 @@ xfs_bunmapi(
5500 * try again. 5380 * try again.
5501 */ 5381 */
5502 ASSERT(lastx > 0); 5382 ASSERT(lastx > 0);
5503 xfs_bmbt_get_all(ep - 1, &prev); 5383 xfs_bmbt_get_all(xfs_iext_get_ext(ifp,
5384 lastx - 1), &prev);
5504 ASSERT(prev.br_state == XFS_EXT_NORM); 5385 ASSERT(prev.br_state == XFS_EXT_NORM);
5505 ASSERT(!ISNULLSTARTBLOCK(prev.br_startblock)); 5386 ASSERT(!ISNULLSTARTBLOCK(prev.br_startblock));
5506 ASSERT(del.br_startblock == 5387 ASSERT(del.br_startblock ==
@@ -5587,12 +5468,12 @@ nodelete:
5587 * If not done go on to the next (previous) record. 5468 * If not done go on to the next (previous) record.
5588 * Reset ep in case the extents array was re-alloced. 5469 * Reset ep in case the extents array was re-alloced.
5589 */ 5470 */
5590 ep = &ifp->if_u1.if_extents[lastx]; 5471 ep = xfs_iext_get_ext(ifp, lastx);
5591 if (bno != (xfs_fileoff_t)-1 && bno >= start) { 5472 if (bno != (xfs_fileoff_t)-1 && bno >= start) {
5592 if (lastx >= XFS_IFORK_NEXTENTS(ip, whichfork) || 5473 if (lastx >= XFS_IFORK_NEXTENTS(ip, whichfork) ||
5593 xfs_bmbt_get_startoff(ep) > bno) { 5474 xfs_bmbt_get_startoff(ep) > bno) {
5594 lastx--; 5475 if (--lastx >= 0)
5595 ep--; 5476 ep = xfs_iext_get_ext(ifp, lastx);
5596 } 5477 }
5597 if (lastx >= 0) 5478 if (lastx >= 0)
5598 xfs_bmbt_get_all(ep, &got); 5479 xfs_bmbt_get_all(ep, &got);
@@ -5636,7 +5517,7 @@ nodelete:
5636error0: 5517error0:
5637 /* 5518 /*
5638 * Log everything. Do this after conversion, there's no point in 5519 * Log everything. Do this after conversion, there's no point in
5639 * logging the extent list if we've converted to btree format. 5520 * logging the extent records if we've converted to btree format.
5640 */ 5521 */
5641 if ((logflags & XFS_ILOG_FEXT(whichfork)) && 5522 if ((logflags & XFS_ILOG_FEXT(whichfork)) &&
5642 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) 5523 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)
@@ -5892,9 +5773,9 @@ xfs_bmap_isaeof(
5892{ 5773{
5893 int error; /* error return value */ 5774 int error; /* error return value */
5894 xfs_ifork_t *ifp; /* inode fork pointer */ 5775 xfs_ifork_t *ifp; /* inode fork pointer */
5895 xfs_bmbt_rec_t *lastrec; /* extent list entry pointer */ 5776 xfs_bmbt_rec_t *lastrec; /* extent record pointer */
5896 xfs_extnum_t nextents; /* size of extent list */ 5777 xfs_extnum_t nextents; /* number of file extents */
5897 xfs_bmbt_irec_t s; /* expanded extent list entry */ 5778 xfs_bmbt_irec_t s; /* expanded extent record */
5898 5779
5899 ASSERT(whichfork == XFS_DATA_FORK); 5780 ASSERT(whichfork == XFS_DATA_FORK);
5900 ifp = XFS_IFORK_PTR(ip, whichfork); 5781 ifp = XFS_IFORK_PTR(ip, whichfork);
@@ -5909,7 +5790,7 @@ xfs_bmap_isaeof(
5909 /* 5790 /*
5910 * Go to the last extent 5791 * Go to the last extent
5911 */ 5792 */
5912 lastrec = &ifp->if_u1.if_extents[nextents - 1]; 5793 lastrec = xfs_iext_get_ext(ifp, nextents - 1);
5913 xfs_bmbt_get_all(lastrec, &s); 5794 xfs_bmbt_get_all(lastrec, &s);
5914 /* 5795 /*
5915 * Check we are allocating in the last extent (for delayed allocations) 5796 * Check we are allocating in the last extent (for delayed allocations)
@@ -5936,8 +5817,8 @@ xfs_bmap_eof(
5936 xfs_fsblock_t blockcount; /* extent block count */ 5817 xfs_fsblock_t blockcount; /* extent block count */
5937 int error; /* error return value */ 5818 int error; /* error return value */
5938 xfs_ifork_t *ifp; /* inode fork pointer */ 5819 xfs_ifork_t *ifp; /* inode fork pointer */
5939 xfs_bmbt_rec_t *lastrec; /* extent list entry pointer */ 5820 xfs_bmbt_rec_t *lastrec; /* extent record pointer */
5940 xfs_extnum_t nextents; /* size of extent list */ 5821 xfs_extnum_t nextents; /* number of file extents */
5941 xfs_fileoff_t startoff; /* extent starting file offset */ 5822 xfs_fileoff_t startoff; /* extent starting file offset */
5942 5823
5943 ASSERT(whichfork == XFS_DATA_FORK); 5824 ASSERT(whichfork == XFS_DATA_FORK);
@@ -5953,7 +5834,7 @@ xfs_bmap_eof(
5953 /* 5834 /*
5954 * Go to the last extent 5835 * Go to the last extent
5955 */ 5836 */
5956 lastrec = &ifp->if_u1.if_extents[nextents - 1]; 5837 lastrec = xfs_iext_get_ext(ifp, nextents - 1);
5957 startoff = xfs_bmbt_get_startoff(lastrec); 5838 startoff = xfs_bmbt_get_startoff(lastrec);
5958 blockcount = xfs_bmbt_get_blockcount(lastrec); 5839 blockcount = xfs_bmbt_get_blockcount(lastrec);
5959 *eof = endoff >= startoff + blockcount; 5840 *eof = endoff >= startoff + blockcount;
@@ -5969,18 +5850,21 @@ xfs_bmap_check_extents(
5969 xfs_inode_t *ip, /* incore inode pointer */ 5850 xfs_inode_t *ip, /* incore inode pointer */
5970 int whichfork) /* data or attr fork */ 5851 int whichfork) /* data or attr fork */
5971{ 5852{
5972 xfs_bmbt_rec_t *base; /* base of extents list */
5973 xfs_bmbt_rec_t *ep; /* current extent entry */ 5853 xfs_bmbt_rec_t *ep; /* current extent entry */
5854 xfs_extnum_t idx; /* extent record index */
5974 xfs_ifork_t *ifp; /* inode fork pointer */ 5855 xfs_ifork_t *ifp; /* inode fork pointer */
5975 xfs_extnum_t nextents; /* number of extents in list */ 5856 xfs_extnum_t nextents; /* number of extents in list */
5857 xfs_bmbt_rec_t *nextp; /* next extent entry */
5976 5858
5977 ifp = XFS_IFORK_PTR(ip, whichfork); 5859 ifp = XFS_IFORK_PTR(ip, whichfork);
5978 ASSERT(ifp->if_flags & XFS_IFEXTENTS); 5860 ASSERT(ifp->if_flags & XFS_IFEXTENTS);
5979 base = ifp->if_u1.if_extents;
5980 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 5861 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
5981 for (ep = base; ep < &base[nextents - 1]; ep++) { 5862 ep = xfs_iext_get_ext(ifp, 0);
5863 for (idx = 0; idx < nextents - 1; idx++) {
5864 nextp = xfs_iext_get_ext(ifp, idx + 1);
5982 xfs_btree_check_rec(XFS_BTNUM_BMAP, (void *)ep, 5865 xfs_btree_check_rec(XFS_BTNUM_BMAP, (void *)ep,
5983 (void *)(ep + 1)); 5866 (void *)(nextp));
5867 ep = nextp;
5984 } 5868 }
5985} 5869}
5986 5870
@@ -6119,12 +6003,14 @@ xfs_bmap_check_leaf_extents(
6119 xfs_fsblock_t bno; /* block # of "block" */ 6003 xfs_fsblock_t bno; /* block # of "block" */
6120 xfs_buf_t *bp; /* buffer for "block" */ 6004 xfs_buf_t *bp; /* buffer for "block" */
6121 int error; /* error return value */ 6005 int error; /* error return value */
6122 xfs_extnum_t i=0; /* index into the extents list */ 6006 xfs_extnum_t i=0, j; /* index into the extents list */
6123 xfs_ifork_t *ifp; /* fork structure */ 6007 xfs_ifork_t *ifp; /* fork structure */
6124 int level; /* btree level, for checking */ 6008 int level; /* btree level, for checking */
6125 xfs_mount_t *mp; /* file system mount structure */ 6009 xfs_mount_t *mp; /* file system mount structure */
6126 xfs_bmbt_ptr_t *pp; /* pointer to block address */ 6010 xfs_bmbt_ptr_t *pp; /* pointer to block address */
6127 xfs_bmbt_rec_t *ep, *lastp; /* extent pointers in block entry */ 6011 xfs_bmbt_rec_t *ep; /* pointer to current extent */
6012 xfs_bmbt_rec_t *lastp; /* pointer to previous extent */
6013 xfs_bmbt_rec_t *nextp; /* pointer to next extent */
6128 int bp_release = 0; 6014 int bp_release = 0;
6129 6015
6130 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) { 6016 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) {
@@ -6194,7 +6080,6 @@ xfs_bmap_check_leaf_extents(
6194 */ 6080 */
6195 lastp = NULL; 6081 lastp = NULL;
6196 for (;;) { 6082 for (;;) {
6197 xfs_bmbt_rec_t *frp;
6198 xfs_fsblock_t nextbno; 6083 xfs_fsblock_t nextbno;
6199 xfs_extnum_t num_recs; 6084 xfs_extnum_t num_recs;
6200 6085
@@ -6213,18 +6098,20 @@ xfs_bmap_check_leaf_extents(
6213 * conform with the first entry in this one. 6098 * conform with the first entry in this one.
6214 */ 6099 */
6215 6100
6216 frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, 6101 ep = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt,
6217 block, 1, mp->m_bmap_dmxr[0]); 6102 block, 1, mp->m_bmap_dmxr[0]);
6218 6103 for (j = 1; j < num_recs; j++) {
6219 for (ep = frp;ep < frp + (num_recs - 1); ep++) { 6104 nextp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt,
6105 block, j + 1, mp->m_bmap_dmxr[0]);
6220 if (lastp) { 6106 if (lastp) {
6221 xfs_btree_check_rec(XFS_BTNUM_BMAP, 6107 xfs_btree_check_rec(XFS_BTNUM_BMAP,
6222 (void *)lastp, (void *)ep); 6108 (void *)lastp, (void *)ep);
6223 } 6109 }
6224 xfs_btree_check_rec(XFS_BTNUM_BMAP, (void *)ep, 6110 xfs_btree_check_rec(XFS_BTNUM_BMAP, (void *)ep,
6225 (void *)(ep + 1)); 6111 (void *)(nextp));
6112 lastp = ep;
6113 ep = nextp;
6226 } 6114 }
6227 lastp = frp + num_recs - 1; /* For the next iteration */
6228 6115
6229 i += num_recs; 6116 i += num_recs;
6230 if (bp_release) { 6117 if (bp_release) {
@@ -6288,7 +6175,7 @@ xfs_bmap_count_blocks(
6288 mp = ip->i_mount; 6175 mp = ip->i_mount;
6289 ifp = XFS_IFORK_PTR(ip, whichfork); 6176 ifp = XFS_IFORK_PTR(ip, whichfork);
6290 if ( XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS ) { 6177 if ( XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS ) {
6291 if (unlikely(xfs_bmap_count_leaves(ifp->if_u1.if_extents, 6178 if (unlikely(xfs_bmap_count_leaves(ifp, 0,
6292 ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t), 6179 ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t),
6293 count) < 0)) { 6180 count) < 0)) {
6294 XFS_ERROR_REPORT("xfs_bmap_count_blocks(1)", 6181 XFS_ERROR_REPORT("xfs_bmap_count_blocks(1)",
@@ -6310,7 +6197,7 @@ xfs_bmap_count_blocks(
6310 ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks); 6197 ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks);
6311 bno = INT_GET(*pp, ARCH_CONVERT); 6198 bno = INT_GET(*pp, ARCH_CONVERT);
6312 6199
6313 if (unlikely(xfs_bmap_count_tree(mp, tp, bno, level, count) < 0)) { 6200 if (unlikely(xfs_bmap_count_tree(mp, tp, ifp, bno, level, count) < 0)) {
6314 XFS_ERROR_REPORT("xfs_bmap_count_blocks(2)", XFS_ERRLEVEL_LOW, 6201 XFS_ERROR_REPORT("xfs_bmap_count_blocks(2)", XFS_ERRLEVEL_LOW,
6315 mp); 6202 mp);
6316 return XFS_ERROR(EFSCORRUPTED); 6203 return XFS_ERROR(EFSCORRUPTED);
@@ -6327,6 +6214,7 @@ int /* error */
6327xfs_bmap_count_tree( 6214xfs_bmap_count_tree(
6328 xfs_mount_t *mp, /* file system mount point */ 6215 xfs_mount_t *mp, /* file system mount point */
6329 xfs_trans_t *tp, /* transaction pointer */ 6216 xfs_trans_t *tp, /* transaction pointer */
6217 xfs_ifork_t *ifp, /* inode fork pointer */
6330 xfs_fsblock_t blockno, /* file system block number */ 6218 xfs_fsblock_t blockno, /* file system block number */
6331 int levelin, /* level in btree */ 6219 int levelin, /* level in btree */
6332 int *count) /* Count of blocks */ 6220 int *count) /* Count of blocks */
@@ -6339,7 +6227,6 @@ xfs_bmap_count_tree(
6339 xfs_fsblock_t nextbno; 6227 xfs_fsblock_t nextbno;
6340 xfs_bmbt_block_t *block, *nextblock; 6228 xfs_bmbt_block_t *block, *nextblock;
6341 int numrecs; 6229 int numrecs;
6342 xfs_bmbt_rec_t *frp;
6343 6230
6344 if ((error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, XFS_BMAP_BTREE_REF))) 6231 if ((error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, XFS_BMAP_BTREE_REF)))
6345 return error; 6232 return error;
@@ -6364,7 +6251,7 @@ xfs_bmap_count_tree(
6364 xfs_bmbt, block, 1, mp->m_bmap_dmxr[1]); 6251 xfs_bmbt, block, 1, mp->m_bmap_dmxr[1]);
6365 bno = INT_GET(*pp, ARCH_CONVERT); 6252 bno = INT_GET(*pp, ARCH_CONVERT);
6366 if (unlikely((error = 6253 if (unlikely((error =
6367 xfs_bmap_count_tree(mp, tp, bno, level, count)) < 0)) { 6254 xfs_bmap_count_tree(mp, tp, ifp, bno, level, count)) < 0)) {
6368 xfs_trans_brelse(tp, bp); 6255 xfs_trans_brelse(tp, bp);
6369 XFS_ERROR_REPORT("xfs_bmap_count_tree(1)", 6256 XFS_ERROR_REPORT("xfs_bmap_count_tree(1)",
6370 XFS_ERRLEVEL_LOW, mp); 6257 XFS_ERRLEVEL_LOW, mp);
@@ -6376,9 +6263,8 @@ xfs_bmap_count_tree(
6376 for (;;) { 6263 for (;;) {
6377 nextbno = be64_to_cpu(block->bb_rightsib); 6264 nextbno = be64_to_cpu(block->bb_rightsib);
6378 numrecs = be16_to_cpu(block->bb_numrecs); 6265 numrecs = be16_to_cpu(block->bb_numrecs);
6379 frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, 6266 if (unlikely(xfs_bmap_disk_count_leaves(ifp, mp,
6380 xfs_bmbt, block, 1, mp->m_bmap_dmxr[0]); 6267 0, block, numrecs, count) < 0)) {
6381 if (unlikely(xfs_bmap_disk_count_leaves(frp, numrecs, count) < 0)) {
6382 xfs_trans_brelse(tp, bp); 6268 xfs_trans_brelse(tp, bp);
6383 XFS_ERROR_REPORT("xfs_bmap_count_tree(2)", 6269 XFS_ERROR_REPORT("xfs_bmap_count_tree(2)",
6384 XFS_ERRLEVEL_LOW, mp); 6270 XFS_ERRLEVEL_LOW, mp);
@@ -6399,33 +6285,45 @@ xfs_bmap_count_tree(
6399} 6285}
6400 6286
6401/* 6287/*
6402 * Count leaf blocks given a pointer to an extent list. 6288 * Count leaf blocks given a range of extent records.
6403 */ 6289 */
6404int 6290int
6405xfs_bmap_count_leaves( 6291xfs_bmap_count_leaves(
6406 xfs_bmbt_rec_t *frp, 6292 xfs_ifork_t *ifp,
6293 xfs_extnum_t idx,
6407 int numrecs, 6294 int numrecs,
6408 int *count) 6295 int *count)
6409{ 6296{
6410 int b; 6297 int b;
6298 xfs_bmbt_rec_t *frp;
6411 6299
6412 for ( b = 1; b <= numrecs; b++, frp++) 6300 for (b = 0; b < numrecs; b++) {
6301 frp = xfs_iext_get_ext(ifp, idx + b);
6413 *count += xfs_bmbt_get_blockcount(frp); 6302 *count += xfs_bmbt_get_blockcount(frp);
6303 }
6414 return 0; 6304 return 0;
6415} 6305}
6416 6306
6417/* 6307/*
6418 * Count leaf blocks given a pointer to an extent list originally in btree format. 6308 * Count leaf blocks given a range of extent records originally
6309 * in btree format.
6419 */ 6310 */
6420int 6311int
6421xfs_bmap_disk_count_leaves( 6312xfs_bmap_disk_count_leaves(
6422 xfs_bmbt_rec_t *frp, 6313 xfs_ifork_t *ifp,
6314 xfs_mount_t *mp,
6315 xfs_extnum_t idx,
6316 xfs_bmbt_block_t *block,
6423 int numrecs, 6317 int numrecs,
6424 int *count) 6318 int *count)
6425{ 6319{
6426 int b; 6320 int b;
6321 xfs_bmbt_rec_t *frp;
6427 6322
6428 for ( b = 1; b <= numrecs; b++, frp++) 6323 for (b = 1; b <= numrecs; b++) {
6324 frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize,
6325 xfs_bmbt, block, idx + b, mp->m_bmap_dmxr[0]);
6429 *count += xfs_bmbt_disk_get_blockcount(frp); 6326 *count += xfs_bmbt_disk_get_blockcount(frp);
6327 }
6430 return 0; 6328 return 0;
6431} 6329}