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.c1305
1 files changed, 655 insertions, 650 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 70625e577c70..2d702e4a74a3 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 2748 if ((error = xfs_alloc_vextent(&args)))
2702 */ 2749 return error;
2703 if (blen > args.alignment && blen <= ap->alen) 2750 }
2704 args.minlen = blen - args.alignment; 2751 if (isaligned && args.fsbno == NULLFSBLOCK) {
2705 args.minalignslop = 0; 2752 /*
2706 } else { 2753 * allocation failed, so turn off alignment and
2707 /* 2754 * try again.
2708 * First try an exact bno allocation. 2755 */
2709 * If it fails then do a near or start bno 2756 args.type = atype;
2710 * allocation with alignment turned on. 2757 args.fsbno = ap->rval;
2711 */ 2758 args.alignment = 0;
2712 atype = args.type; 2759 if ((error = xfs_alloc_vextent(&args)))
2713 tryagain = 1; 2760 return error;
2714 args.type = XFS_ALLOCTYPE_THIS_BNO; 2761 }
2715 args.alignment = 1; 2762 if (args.fsbno == NULLFSBLOCK && nullfb &&
2716 /* 2763 args.minlen > ap->minlen) {
2717 * Compute the minlen+alignment for the 2764 args.minlen = ap->minlen;
2718 * next case. Set slop so that the value 2765 args.type = XFS_ALLOCTYPE_START_BNO;
2719 * of minlen+alignment+slop doesn't go up 2766 args.fsbno = ap->rval;
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))) 2767 if ((error = xfs_alloc_vextent(&args)))
2742 return error; 2768 return error;
2743 if (tryagain && args.fsbno == NULLFSBLOCK) { 2769 }
2744 /* 2770 if (args.fsbno == NULLFSBLOCK && nullfb) {
2745 * Exact allocation failed. Now try with alignment 2771 args.fsbno = 0;
2746 * turned on. 2772 args.type = XFS_ALLOCTYPE_FIRST_AG;
2747 */ 2773 args.total = ap->minlen;
2748 args.type = atype; 2774 args.minleft = 0;
2749 args.fsbno = ap->rval; 2775 if ((error = xfs_alloc_vextent(&args)))
2750 args.alignment = mp->m_dalign; 2776 return error;
2751 args.minlen = nextminlen; 2777 ap->low = 1;
2752 args.minalignslop = 0; 2778 }
2753 isaligned = 1; 2779 if (args.fsbno != NULLFSBLOCK) {
2754 if ((error = xfs_alloc_vextent(&args))) 2780 ap->firstblock = ap->rval = args.fsbno;
2755 return error; 2781 ASSERT(nullfb || fb_agno == args.agno ||
2756 } 2782 (ap->low && fb_agno < args.agno));
2757 if (isaligned && args.fsbno == NULLFSBLOCK) { 2783 ap->alen = args.len;
2758 /* 2784 ap->ip->i_d.di_nblocks += args.len;
2759 * allocation failed, so turn off alignment and 2785 xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE);
2760 * try again. 2786 if (ap->wasdel)
2761 */ 2787 ap->ip->i_delayed_blks -= args.len;
2762 args.type = atype; 2788 /*
2763 args.fsbno = ap->rval; 2789 * Adjust the disk quota also. This was reserved
2764 args.alignment = 0; 2790 * earlier.
2765 if ((error = xfs_alloc_vextent(&args))) 2791 */
2766 return error; 2792 XFS_TRANS_MOD_DQUOT_BYINO(mp, ap->tp, ap->ip,
2767 } 2793 ap->wasdel ? XFS_TRANS_DQ_DELBCOUNT :
2768 if (args.fsbno == NULLFSBLOCK && nullfb && 2794 XFS_TRANS_DQ_BCOUNT,
2769 args.minlen > ap->minlen) { 2795 (long) args.len);
2770 args.minlen = ap->minlen; 2796 } else {
2771 args.type = XFS_ALLOCTYPE_START_BNO; 2797 ap->rval = NULLFSBLOCK;
2772 args.fsbno = ap->rval; 2798 ap->alen = 0;
2773 if ((error = xfs_alloc_vextent(&args)))
2774 return error;
2775 }
2776 if (args.fsbno == NULLFSBLOCK && nullfb) {
2777 args.fsbno = 0;
2778 args.type = XFS_ALLOCTYPE_FIRST_AG;
2779 args.total = ap->minlen;
2780 args.minleft = 0;
2781 if ((error = xfs_alloc_vextent(&args)))
2782 return error;
2783 ap->low = 1;
2784 }
2785 if (args.fsbno != NULLFSBLOCK) {
2786 ap->firstblock = ap->rval = args.fsbno;
2787 ASSERT(nullfb || fb_agno == args.agno ||
2788 (ap->low && fb_agno < args.agno));
2789 ap->alen = args.len;
2790 ap->ip->i_d.di_nblocks += args.len;
2791 xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE);
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);
@@ -3518,7 +3471,7 @@ xfs_bmbt_rec_t * /* pointer to found extent entry */
3518xfs_bmap_do_search_extents( 3471xfs_bmap_do_search_extents(
3519 xfs_bmbt_rec_t *base, /* base of extent list */ 3472 xfs_bmbt_rec_t *base, /* base of extent list */
3520 xfs_extnum_t lastx, /* last extent index used */ 3473 xfs_extnum_t lastx, /* last extent index used */
3521 xfs_extnum_t nextents, /* extent list size */ 3474 xfs_extnum_t nextents, /* number of file extents */
3522 xfs_fileoff_t bno, /* block number searched for */ 3475 xfs_fileoff_t bno, /* block number searched for */
3523 int *eofp, /* out: end of file found */ 3476 int *eofp, /* out: end of file found */
3524 xfs_extnum_t *lastxp, /* out: last extent index */ 3477 xfs_extnum_t *lastxp, /* out: last extent index */
@@ -3569,9 +3522,9 @@ xfs_bmap_do_search_extents(
3569 got.br_blockcount = xfs_bmbt_get_blockcount(ep); 3522 got.br_blockcount = xfs_bmbt_get_blockcount(ep);
3570 *eofp = 0; 3523 *eofp = 0;
3571 } else { 3524 } else {
3572 /* binary search the extents array */
3573 low = 0; 3525 low = 0;
3574 high = nextents - 1; 3526 high = nextents - 1;
3527 /* binary search the extents array */
3575 while (low <= high) { 3528 while (low <= high) {
3576 XFS_STATS_INC(xs_cmp_exlist); 3529 XFS_STATS_INC(xs_cmp_exlist);
3577 lastx = (low + high) >> 1; 3530 lastx = (low + high) >> 1;
@@ -3622,6 +3575,57 @@ xfs_bmap_do_search_extents(
3622} 3575}
3623 3576
3624/* 3577/*
3578 * Search the extent records for the entry containing block bno.
3579 * If bno lies in a hole, point to the next entry. If bno lies
3580 * past eof, *eofp will be set, and *prevp will contain the last
3581 * entry (null if none). Else, *lastxp will be set to the index
3582 * of the found entry; *gotp will contain the entry.
3583 */
3584xfs_bmbt_rec_t * /* pointer to found extent entry */
3585xfs_bmap_search_multi_extents(
3586 xfs_ifork_t *ifp, /* inode fork pointer */
3587 xfs_fileoff_t bno, /* block number searched for */
3588 int *eofp, /* out: end of file found */
3589 xfs_extnum_t *lastxp, /* out: last extent index */
3590 xfs_bmbt_irec_t *gotp, /* out: extent entry found */
3591 xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */
3592{
3593 xfs_bmbt_rec_t *ep; /* extent record pointer */
3594 xfs_extnum_t lastx; /* last extent index */
3595
3596 /*
3597 * Initialize the extent entry structure to catch access to
3598 * uninitialized br_startblock field.
3599 */
3600 gotp->br_startoff = 0xffa5a5a5a5a5a5a5LL;
3601 gotp->br_blockcount = 0xa55a5a5a5a5a5a5aLL;
3602 gotp->br_state = XFS_EXT_INVALID;
3603#if XFS_BIG_BLKNOS
3604 gotp->br_startblock = 0xffffa5a5a5a5a5a5LL;
3605#else
3606 gotp->br_startblock = 0xffffa5a5;
3607#endif
3608 prevp->br_startoff = NULLFILEOFF;
3609
3610 ep = xfs_iext_bno_to_ext(ifp, bno, &lastx);
3611 if (lastx > 0) {
3612 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx - 1), prevp);
3613 }
3614 if (lastx < (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))) {
3615 xfs_bmbt_get_all(ep, gotp);
3616 *eofp = 0;
3617 } else {
3618 if (lastx > 0) {
3619 *gotp = *prevp;
3620 }
3621 *eofp = 1;
3622 ep = NULL;
3623 }
3624 *lastxp = lastx;
3625 return ep;
3626}
3627
3628/*
3625 * Search the extents list for the inode, for the extent containing bno. 3629 * Search the extents list for the inode, for the extent containing bno.
3626 * If bno lies in a hole, point to the next entry. If bno lies past eof, 3630 * If bno lies in a hole, point to the next entry. If bno lies past eof,
3627 * *eofp will be set, and *prevp will contain the last entry (null if none). 3631 * *eofp will be set, and *prevp will contain the last entry (null if none).
@@ -3639,20 +3643,14 @@ xfs_bmap_search_extents(
3639 xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ 3643 xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */
3640{ 3644{
3641 xfs_ifork_t *ifp; /* inode fork pointer */ 3645 xfs_ifork_t *ifp; /* inode fork pointer */
3642 xfs_bmbt_rec_t *base; /* base of extent list */ 3646 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 */ 3647 int rt; /* realtime flag */
3647 3648
3648 XFS_STATS_INC(xs_look_exlist); 3649 XFS_STATS_INC(xs_look_exlist);
3649 ifp = XFS_IFORK_PTR(ip, whichfork); 3650 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 3651
3654 ep = xfs_bmap_do_search_extents(base, lastx, nextents, bno, eofp, 3652 ep = xfs_bmap_search_multi_extents(ifp, bno, eofp, lastxp, gotp, prevp);
3655 lastxp, gotp, prevp); 3653
3656 rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip); 3654 rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip);
3657 if (unlikely(!rt && !gotp->br_startblock && (*lastxp != NULLEXTNUM))) { 3655 if (unlikely(!rt && !gotp->br_startblock && (*lastxp != NULLEXTNUM))) {
3658 cmn_err(CE_PANIC,"Access to block zero: fs: <%s> inode: %lld " 3656 cmn_err(CE_PANIC,"Access to block zero: fs: <%s> inode: %lld "
@@ -3732,7 +3730,7 @@ xfs_bmap_trace_addentry(
3732} 3730}
3733 3731
3734/* 3732/*
3735 * Add bmap trace entry prior to a call to xfs_bmap_delete_exlist. 3733 * Add bmap trace entry prior to a call to xfs_iext_remove.
3736 */ 3734 */
3737STATIC void 3735STATIC void
3738xfs_bmap_trace_delete( 3736xfs_bmap_trace_delete(
@@ -3747,13 +3745,13 @@ xfs_bmap_trace_delete(
3747 3745
3748 ifp = XFS_IFORK_PTR(ip, whichfork); 3746 ifp = XFS_IFORK_PTR(ip, whichfork);
3749 xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_DELETE, fname, desc, ip, idx, 3747 xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_DELETE, fname, desc, ip, idx,
3750 cnt, &ifp->if_u1.if_extents[idx], 3748 cnt, xfs_iext_get_ext(ifp, idx),
3751 cnt == 2 ? &ifp->if_u1.if_extents[idx + 1] : NULL, 3749 cnt == 2 ? xfs_iext_get_ext(ifp, idx + 1) : NULL,
3752 whichfork); 3750 whichfork);
3753} 3751}
3754 3752
3755/* 3753/*
3756 * Add bmap trace entry prior to a call to xfs_bmap_insert_exlist, or 3754 * 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). 3755 * reading in the extents list from the disk (in the btree).
3758 */ 3756 */
3759STATIC void 3757STATIC void
@@ -3783,7 +3781,7 @@ xfs_bmap_trace_insert(
3783} 3781}
3784 3782
3785/* 3783/*
3786 * Add bmap trace entry after updating an extent list entry in place. 3784 * Add bmap trace entry after updating an extent record in place.
3787 */ 3785 */
3788STATIC void 3786STATIC void
3789xfs_bmap_trace_post_update( 3787xfs_bmap_trace_post_update(
@@ -3797,11 +3795,11 @@ xfs_bmap_trace_post_update(
3797 3795
3798 ifp = XFS_IFORK_PTR(ip, whichfork); 3796 ifp = XFS_IFORK_PTR(ip, whichfork);
3799 xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_POST_UP, fname, desc, ip, idx, 3797 xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_POST_UP, fname, desc, ip, idx,
3800 1, &ifp->if_u1.if_extents[idx], NULL, whichfork); 3798 1, xfs_iext_get_ext(ifp, idx), NULL, whichfork);
3801} 3799}
3802 3800
3803/* 3801/*
3804 * Add bmap trace entry prior to updating an extent list entry in place. 3802 * Add bmap trace entry prior to updating an extent record in place.
3805 */ 3803 */
3806STATIC void 3804STATIC void
3807xfs_bmap_trace_pre_update( 3805xfs_bmap_trace_pre_update(
@@ -3815,7 +3813,7 @@ xfs_bmap_trace_pre_update(
3815 3813
3816 ifp = XFS_IFORK_PTR(ip, whichfork); 3814 ifp = XFS_IFORK_PTR(ip, whichfork);
3817 xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_PRE_UP, fname, desc, ip, idx, 1, 3815 xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_PRE_UP, fname, desc, ip, idx, 1,
3818 &ifp->if_u1.if_extents[idx], NULL, whichfork); 3816 xfs_iext_get_ext(ifp, idx), NULL, whichfork);
3819} 3817}
3820#endif /* XFS_BMAP_TRACE */ 3818#endif /* XFS_BMAP_TRACE */
3821 3819
@@ -3892,7 +3890,7 @@ xfs_bmap_add_attrfork(
3892 int rsvd) /* xact may use reserved blks */ 3890 int rsvd) /* xact may use reserved blks */
3893{ 3891{
3894 xfs_fsblock_t firstblock; /* 1st block/ag allocated */ 3892 xfs_fsblock_t firstblock; /* 1st block/ag allocated */
3895 xfs_bmap_free_t flist; /* freed extent list */ 3893 xfs_bmap_free_t flist; /* freed extent records */
3896 xfs_mount_t *mp; /* mount structure */ 3894 xfs_mount_t *mp; /* mount structure */
3897 xfs_trans_t *tp; /* transaction pointer */ 3895 xfs_trans_t *tp; /* transaction pointer */
3898 unsigned long s; /* spinlock spl value */ 3896 unsigned long s; /* spinlock spl value */
@@ -4146,7 +4144,7 @@ xfs_bmap_finish(
4146 xfs_efd_log_item_t *efd; /* extent free data */ 4144 xfs_efd_log_item_t *efd; /* extent free data */
4147 xfs_efi_log_item_t *efi; /* extent free intention */ 4145 xfs_efi_log_item_t *efi; /* extent free intention */
4148 int error; /* error return value */ 4146 int error; /* error return value */
4149 xfs_bmap_free_item_t *free; /* free extent list item */ 4147 xfs_bmap_free_item_t *free; /* free extent item */
4150 unsigned int logres; /* new log reservation */ 4148 unsigned int logres; /* new log reservation */
4151 unsigned int logcount; /* new log count */ 4149 unsigned int logcount; /* new log count */
4152 xfs_mount_t *mp; /* filesystem mount structure */ 4150 xfs_mount_t *mp; /* filesystem mount structure */
@@ -4242,9 +4240,9 @@ xfs_bmap_first_unused(
4242 xfs_fileoff_t *first_unused, /* unused block */ 4240 xfs_fileoff_t *first_unused, /* unused block */
4243 int whichfork) /* data or attr fork */ 4241 int whichfork) /* data or attr fork */
4244{ 4242{
4245 xfs_bmbt_rec_t *base; /* base of extent array */
4246 xfs_bmbt_rec_t *ep; /* pointer to an extent entry */ 4243 xfs_bmbt_rec_t *ep; /* pointer to an extent entry */
4247 int error; /* error return value */ 4244 int error; /* error return value */
4245 int idx; /* extent record index */
4248 xfs_ifork_t *ifp; /* inode fork pointer */ 4246 xfs_ifork_t *ifp; /* inode fork pointer */
4249 xfs_fileoff_t lastaddr; /* last block number seen */ 4247 xfs_fileoff_t lastaddr; /* last block number seen */
4250 xfs_fileoff_t lowest; /* lowest useful block */ 4248 xfs_fileoff_t lowest; /* lowest useful block */
@@ -4265,10 +4263,8 @@ xfs_bmap_first_unused(
4265 return error; 4263 return error;
4266 lowest = *first_unused; 4264 lowest = *first_unused;
4267 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 4265 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
4268 base = &ifp->if_u1.if_extents[0]; 4266 for (idx = 0, lastaddr = 0, max = lowest; idx < nextents; idx++) {
4269 for (lastaddr = 0, max = lowest, ep = base; 4267 ep = xfs_iext_get_ext(ifp, idx);
4270 ep < &base[nextents];
4271 ep++) {
4272 off = xfs_bmbt_get_startoff(ep); 4268 off = xfs_bmbt_get_startoff(ep);
4273 /* 4269 /*
4274 * See if the hole before this extent will work. 4270 * See if the hole before this extent will work.
@@ -4287,8 +4283,8 @@ xfs_bmap_first_unused(
4287/* 4283/*
4288 * Returns the file-relative block number of the last block + 1 before 4284 * Returns the file-relative block number of the last block + 1 before
4289 * last_block (input value) in the file. 4285 * last_block (input value) in the file.
4290 * This is not based on i_size, it is based on the extent list. 4286 * 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. 4287 * Returns 0 for local files, as they do not have extent records.
4292 */ 4288 */
4293int /* error */ 4289int /* error */
4294xfs_bmap_last_before( 4290xfs_bmap_last_before(
@@ -4335,8 +4331,8 @@ xfs_bmap_last_before(
4335 4331
4336/* 4332/*
4337 * Returns the file-relative block number of the first block past eof in 4333 * 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. 4334 * 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. 4335 * Returns 0 for local files, as they do not have extent records.
4340 */ 4336 */
4341int /* error */ 4337int /* error */
4342xfs_bmap_last_offset( 4338xfs_bmap_last_offset(
@@ -4345,7 +4341,6 @@ xfs_bmap_last_offset(
4345 xfs_fileoff_t *last_block, /* last block */ 4341 xfs_fileoff_t *last_block, /* last block */
4346 int whichfork) /* data or attr fork */ 4342 int whichfork) /* data or attr fork */
4347{ 4343{
4348 xfs_bmbt_rec_t *base; /* base of extent array */
4349 xfs_bmbt_rec_t *ep; /* pointer to last extent */ 4344 xfs_bmbt_rec_t *ep; /* pointer to last extent */
4350 int error; /* error return value */ 4345 int error; /* error return value */
4351 xfs_ifork_t *ifp; /* inode fork pointer */ 4346 xfs_ifork_t *ifp; /* inode fork pointer */
@@ -4368,9 +4363,7 @@ xfs_bmap_last_offset(
4368 *last_block = 0; 4363 *last_block = 0;
4369 return 0; 4364 return 0;
4370 } 4365 }
4371 base = &ifp->if_u1.if_extents[0]; 4366 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); 4367 *last_block = xfs_bmbt_get_startoff(ep) + xfs_bmbt_get_blockcount(ep);
4375 return 0; 4368 return 0;
4376} 4369}
@@ -4400,7 +4393,7 @@ xfs_bmap_one_block(
4400 return 0; 4393 return 0;
4401 ifp = XFS_IFORK_PTR(ip, whichfork); 4394 ifp = XFS_IFORK_PTR(ip, whichfork);
4402 ASSERT(ifp->if_flags & XFS_IFEXTENTS); 4395 ASSERT(ifp->if_flags & XFS_IFEXTENTS);
4403 ep = ifp->if_u1.if_extents; 4396 ep = xfs_iext_get_ext(ifp, 0);
4404 xfs_bmbt_get_all(ep, &s); 4397 xfs_bmbt_get_all(ep, &s);
4405 rval = s.br_startoff == 0 && s.br_blockcount == 1; 4398 rval = s.br_startoff == 0 && s.br_blockcount == 1;
4406 if (rval && whichfork == XFS_DATA_FORK) 4399 if (rval && whichfork == XFS_DATA_FORK)
@@ -4435,7 +4428,6 @@ xfs_bmap_read_extents(
4435 xfs_bmbt_ptr_t *pp; /* pointer to block address */ 4428 xfs_bmbt_ptr_t *pp; /* pointer to block address */
4436 /* REFERENCED */ 4429 /* REFERENCED */
4437 xfs_extnum_t room; /* number of entries there's room for */ 4430 xfs_extnum_t room; /* number of entries there's room for */
4438 xfs_bmbt_rec_t *trp; /* target record pointer */
4439 4431
4440 bno = NULLFSBLOCK; 4432 bno = NULLFSBLOCK;
4441 mp = ip->i_mount; 4433 mp = ip->i_mount;
@@ -4478,16 +4470,16 @@ xfs_bmap_read_extents(
4478 /* 4470 /*
4479 * Here with bp and block set to the leftmost leaf node in the tree. 4471 * Here with bp and block set to the leftmost leaf node in the tree.
4480 */ 4472 */
4481 room = ifp->if_bytes / (uint)sizeof(*trp); 4473 room = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
4482 trp = ifp->if_u1.if_extents;
4483 i = 0; 4474 i = 0;
4484 /* 4475 /*
4485 * Loop over all leaf nodes. Copy information to the extent list. 4476 * Loop over all leaf nodes. Copy information to the extent records.
4486 */ 4477 */
4487 for (;;) { 4478 for (;;) {
4488 xfs_bmbt_rec_t *frp, *temp; 4479 xfs_bmbt_rec_t *frp, *trp;
4489 xfs_fsblock_t nextbno; 4480 xfs_fsblock_t nextbno;
4490 xfs_extnum_t num_recs; 4481 xfs_extnum_t num_recs;
4482 xfs_extnum_t start;
4491 4483
4492 4484
4493 num_recs = be16_to_cpu(block->bb_numrecs); 4485 num_recs = be16_to_cpu(block->bb_numrecs);
@@ -4511,12 +4503,13 @@ xfs_bmap_read_extents(
4511 if (nextbno != NULLFSBLOCK) 4503 if (nextbno != NULLFSBLOCK)
4512 xfs_btree_reada_bufl(mp, nextbno, 1); 4504 xfs_btree_reada_bufl(mp, nextbno, 1);
4513 /* 4505 /*
4514 * Copy records into the extent list. 4506 * Copy records into the extent records.
4515 */ 4507 */
4516 frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, 4508 frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt,
4517 block, 1, mp->m_bmap_dmxr[0]); 4509 block, 1, mp->m_bmap_dmxr[0]);
4518 temp = trp; 4510 start = i;
4519 for (j = 0; j < num_recs; j++, frp++, trp++) { 4511 for (j = 0; j < num_recs; j++, i++, frp++) {
4512 trp = xfs_iext_get_ext(ifp, i);
4520 trp->l0 = INT_GET(frp->l0, ARCH_CONVERT); 4513 trp->l0 = INT_GET(frp->l0, ARCH_CONVERT);
4521 trp->l1 = INT_GET(frp->l1, ARCH_CONVERT); 4514 trp->l1 = INT_GET(frp->l1, ARCH_CONVERT);
4522 } 4515 }
@@ -4526,14 +4519,14 @@ xfs_bmap_read_extents(
4526 * any "older" data bmap btree records for a 4519 * any "older" data bmap btree records for a
4527 * set bit in the "extent flag" position. 4520 * set bit in the "extent flag" position.
4528 */ 4521 */
4529 if (unlikely(xfs_check_nostate_extents(temp, num_recs))) { 4522 if (unlikely(xfs_check_nostate_extents(ifp,
4523 start, num_recs))) {
4530 XFS_ERROR_REPORT("xfs_bmap_read_extents(2)", 4524 XFS_ERROR_REPORT("xfs_bmap_read_extents(2)",
4531 XFS_ERRLEVEL_LOW, 4525 XFS_ERRLEVEL_LOW,
4532 ip->i_mount); 4526 ip->i_mount);
4533 goto error0; 4527 goto error0;
4534 } 4528 }
4535 } 4529 }
4536 i += num_recs;
4537 xfs_trans_brelse(tp, bp); 4530 xfs_trans_brelse(tp, bp);
4538 bno = nextbno; 4531 bno = nextbno;
4539 /* 4532 /*
@@ -4546,7 +4539,7 @@ xfs_bmap_read_extents(
4546 return error; 4539 return error;
4547 block = XFS_BUF_TO_BMBT_BLOCK(bp); 4540 block = XFS_BUF_TO_BMBT_BLOCK(bp);
4548 } 4541 }
4549 ASSERT(i == ifp->if_bytes / (uint)sizeof(*trp)); 4542 ASSERT(i == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)));
4550 ASSERT(i == XFS_IFORK_NEXTENTS(ip, whichfork)); 4543 ASSERT(i == XFS_IFORK_NEXTENTS(ip, whichfork));
4551 xfs_bmap_trace_exlist(fname, ip, i, whichfork); 4544 xfs_bmap_trace_exlist(fname, ip, i, whichfork);
4552 return 0; 4545 return 0;
@@ -4557,7 +4550,7 @@ error0:
4557 4550
4558#ifdef XFS_BMAP_TRACE 4551#ifdef XFS_BMAP_TRACE
4559/* 4552/*
4560 * Add bmap trace insert entries for all the contents of the extent list. 4553 * Add bmap trace insert entries for all the contents of the extent records.
4561 */ 4554 */
4562void 4555void
4563xfs_bmap_trace_exlist( 4556xfs_bmap_trace_exlist(
@@ -4566,16 +4559,15 @@ xfs_bmap_trace_exlist(
4566 xfs_extnum_t cnt, /* count of entries in the list */ 4559 xfs_extnum_t cnt, /* count of entries in the list */
4567 int whichfork) /* data or attr fork */ 4560 int whichfork) /* data or attr fork */
4568{ 4561{
4569 xfs_bmbt_rec_t *base; /* base of extent list */ 4562 xfs_bmbt_rec_t *ep; /* current extent record */
4570 xfs_bmbt_rec_t *ep; /* current entry in extent list */ 4563 xfs_extnum_t idx; /* extent record index */
4571 xfs_extnum_t idx; /* extent list entry number */
4572 xfs_ifork_t *ifp; /* inode fork pointer */ 4564 xfs_ifork_t *ifp; /* inode fork pointer */
4573 xfs_bmbt_irec_t s; /* extent list record */ 4565 xfs_bmbt_irec_t s; /* file extent record */
4574 4566
4575 ifp = XFS_IFORK_PTR(ip, whichfork); 4567 ifp = XFS_IFORK_PTR(ip, whichfork);
4576 ASSERT(cnt == ifp->if_bytes / (uint)sizeof(*base)); 4568 ASSERT(cnt == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)));
4577 base = ifp->if_u1.if_extents; 4569 for (idx = 0; idx < cnt; idx++) {
4578 for (idx = 0, ep = base; idx < cnt; idx++, ep++) { 4570 ep = xfs_iext_get_ext(ifp, idx);
4579 xfs_bmbt_get_all(ep, &s); 4571 xfs_bmbt_get_all(ep, &s);
4580 xfs_bmap_trace_insert(fname, "exlist", ip, idx, 1, &s, NULL, 4572 xfs_bmap_trace_insert(fname, "exlist", ip, idx, 1, &s, NULL,
4581 whichfork); 4573 whichfork);
@@ -4661,14 +4653,10 @@ xfs_bmapi(
4661 xfs_bmalloca_t bma; /* args for xfs_bmap_alloc */ 4653 xfs_bmalloca_t bma; /* args for xfs_bmap_alloc */
4662 xfs_btree_cur_t *cur; /* bmap btree cursor */ 4654 xfs_btree_cur_t *cur; /* bmap btree cursor */
4663 xfs_fileoff_t end; /* end of mapped file region */ 4655 xfs_fileoff_t end; /* end of mapped file region */
4664 int eof; /* we've hit the end of extent list */ 4656 int eof; /* we've hit the end of extents */
4665 char contig; /* allocation must be one extent */ 4657 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 */ 4658 int error; /* error return */
4671 xfs_bmbt_irec_t got; /* current extent list record */ 4659 xfs_bmbt_irec_t got; /* current file extent record */
4672 xfs_ifork_t *ifp; /* inode fork pointer */ 4660 xfs_ifork_t *ifp; /* inode fork pointer */
4673 xfs_extlen_t indlen; /* indirect blocks length */ 4661 xfs_extlen_t indlen; /* indirect blocks length */
4674 xfs_extnum_t lastx; /* last useful extent number */ 4662 xfs_extnum_t lastx; /* last useful extent number */
@@ -4680,17 +4668,13 @@ xfs_bmapi(
4680 int nallocs; /* number of extents alloc\'d */ 4668 int nallocs; /* number of extents alloc\'d */
4681 xfs_extnum_t nextents; /* number of extents in file */ 4669 xfs_extnum_t nextents; /* number of extents in file */
4682 xfs_fileoff_t obno; /* old block number (offset) */ 4670 xfs_fileoff_t obno; /* old block number (offset) */
4683 xfs_bmbt_irec_t prev; /* previous extent list record */ 4671 xfs_bmbt_irec_t prev; /* previous file extent record */
4684 int tmp_logflags; /* temp flags holder */ 4672 int tmp_logflags; /* temp flags holder */
4685 int whichfork; /* data or attr fork */ 4673 int whichfork; /* data or attr fork */
4686 char inhole; /* current location is hole in file */ 4674 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 */ 4675 char wasdelay; /* old extent was delayed */
4691 char wr; /* this is a write request */ 4676 char wr; /* this is a write request */
4692 char rt; /* this is a realtime file */ 4677 char rt; /* this is a realtime file */
4693 char rsvd; /* OK to allocate reserved blocks */
4694#ifdef DEBUG 4678#ifdef DEBUG
4695 xfs_fileoff_t orig_bno; /* original block number value */ 4679 xfs_fileoff_t orig_bno; /* original block number value */
4696 int orig_flags; /* original flags arg value */ 4680 int orig_flags; /* original flags arg value */
@@ -4727,15 +4711,8 @@ xfs_bmapi(
4727 XFS_STATS_INC(xs_blk_mapw); 4711 XFS_STATS_INC(xs_blk_mapw);
4728 else 4712 else
4729 XFS_STATS_INC(xs_blk_mapr); 4713 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 /* 4714 /*
4738 * stateless is used to combine extents which 4715 * IGSTATE flag is used to combine extents which
4739 * differ only due to the state of the extents. 4716 * differ only due to the state of the extents.
4740 * This technique is used from xfs_getbmap() 4717 * This technique is used from xfs_getbmap()
4741 * when the caller does not wish to see the 4718 * when the caller does not wish to see the
@@ -4751,10 +4728,9 @@ xfs_bmapi(
4751 * xfs_strat_comp(), where the xfs_bmapi() call 4728 * xfs_strat_comp(), where the xfs_bmapi() call
4752 * is transactioned, and the extents combined. 4729 * is transactioned, and the extents combined.
4753 */ 4730 */
4754 stateless = (flags & XFS_BMAPI_IGSTATE) != 0; 4731 if ((flags & XFS_BMAPI_IGSTATE) && wr) /* if writing unwritten space */
4755 if (stateless && wr) /* if writing unwritten space, no */ 4732 wr = 0; /* no allocations are allowed */
4756 wr = 0; /* allocations are allowed */ 4733 ASSERT(wr || !(flags & XFS_BMAPI_DELAY));
4757 ASSERT(wr || !delay);
4758 logflags = 0; 4734 logflags = 0;
4759 nallocs = 0; 4735 nallocs = 0;
4760 cur = NULL; 4736 cur = NULL;
@@ -4789,7 +4765,7 @@ xfs_bmapi(
4789 if (eof && !wr) 4765 if (eof && !wr)
4790 got.br_startoff = end; 4766 got.br_startoff = end;
4791 inhole = eof || got.br_startoff > bno; 4767 inhole = eof || got.br_startoff > bno;
4792 wasdelay = wr && !inhole && !delay && 4768 wasdelay = wr && !inhole && !(flags & XFS_BMAPI_DELAY) &&
4793 ISNULLSTARTBLOCK(got.br_startblock); 4769 ISNULLSTARTBLOCK(got.br_startblock);
4794 /* 4770 /*
4795 * First, deal with the hole before the allocated space 4771 * First, deal with the hole before the allocated space
@@ -4801,11 +4777,11 @@ xfs_bmapi(
4801 * allocate the stuff asked for in this bmap call 4777 * allocate the stuff asked for in this bmap call
4802 * but that wouldn't be as good. 4778 * but that wouldn't be as good.
4803 */ 4779 */
4804 if (wasdelay && !exact) { 4780 if (wasdelay && !(flags & XFS_BMAPI_EXACT)) {
4805 alen = (xfs_extlen_t)got.br_blockcount; 4781 alen = (xfs_extlen_t)got.br_blockcount;
4806 aoff = got.br_startoff; 4782 aoff = got.br_startoff;
4807 if (lastx != NULLEXTNUM && lastx) { 4783 if (lastx != NULLEXTNUM && lastx) {
4808 ep = &ifp->if_u1.if_extents[lastx - 1]; 4784 ep = xfs_iext_get_ext(ifp, lastx - 1);
4809 xfs_bmbt_get_all(ep, &prev); 4785 xfs_bmbt_get_all(ep, &prev);
4810 } 4786 }
4811 } else if (wasdelay) { 4787 } else if (wasdelay) {
@@ -4823,8 +4799,8 @@ xfs_bmapi(
4823 got.br_startoff - bno); 4799 got.br_startoff - bno);
4824 aoff = bno; 4800 aoff = bno;
4825 } 4801 }
4826 minlen = contig ? alen : 1; 4802 minlen = (flags & XFS_BMAPI_CONTIG) ? alen : 1;
4827 if (delay) { 4803 if (flags & XFS_BMAPI_DELAY) {
4828 xfs_extlen_t extsz; 4804 xfs_extlen_t extsz;
4829 4805
4830 /* Figure out the extent size, adjust alen */ 4806 /* Figure out the extent size, adjust alen */
@@ -4837,7 +4813,9 @@ xfs_bmapi(
4837 if (extsz) { 4813 if (extsz) {
4838 error = xfs_bmap_extsize_align(mp, 4814 error = xfs_bmap_extsize_align(mp,
4839 &got, &prev, extsz, 4815 &got, &prev, extsz,
4840 rt, eof, delay, convert, 4816 rt, eof,
4817 flags&XFS_BMAPI_DELAY,
4818 flags&XFS_BMAPI_CONVERT,
4841 &aoff, &alen); 4819 &aoff, &alen);
4842 ASSERT(!error); 4820 ASSERT(!error);
4843 } 4821 }
@@ -4875,24 +4853,29 @@ xfs_bmapi(
4875 if (rt) { 4853 if (rt) {
4876 error = xfs_mod_incore_sb(mp, 4854 error = xfs_mod_incore_sb(mp,
4877 XFS_SBS_FREXTENTS, 4855 XFS_SBS_FREXTENTS,
4878 -(extsz), rsvd); 4856 -(extsz), (flags &
4857 XFS_BMAPI_RSVBLOCKS));
4879 } else { 4858 } else {
4880 error = xfs_mod_incore_sb(mp, 4859 error = xfs_mod_incore_sb(mp,
4881 XFS_SBS_FDBLOCKS, 4860 XFS_SBS_FDBLOCKS,
4882 -(alen), rsvd); 4861 -(alen), (flags &
4862 XFS_BMAPI_RSVBLOCKS));
4883 } 4863 }
4884 if (!error) { 4864 if (!error) {
4885 error = xfs_mod_incore_sb(mp, 4865 error = xfs_mod_incore_sb(mp,
4886 XFS_SBS_FDBLOCKS, 4866 XFS_SBS_FDBLOCKS,
4887 -(indlen), rsvd); 4867 -(indlen), (flags &
4868 XFS_BMAPI_RSVBLOCKS));
4888 if (error && rt) 4869 if (error && rt)
4889 xfs_mod_incore_sb(mp, 4870 xfs_mod_incore_sb(mp,
4890 XFS_SBS_FREXTENTS, 4871 XFS_SBS_FREXTENTS,
4891 extsz, rsvd); 4872 extsz, (flags &
4873 XFS_BMAPI_RSVBLOCKS));
4892 else if (error) 4874 else if (error)
4893 xfs_mod_incore_sb(mp, 4875 xfs_mod_incore_sb(mp,
4894 XFS_SBS_FDBLOCKS, 4876 XFS_SBS_FDBLOCKS,
4895 alen, rsvd); 4877 alen, (flags &
4878 XFS_BMAPI_RSVBLOCKS));
4896 } 4879 }
4897 4880
4898 if (error) { 4881 if (error) {
@@ -4925,7 +4908,7 @@ xfs_bmapi(
4925 /* Indicate if this is the first user data 4908 /* Indicate if this is the first user data
4926 * in the file, or just any user data. 4909 * in the file, or just any user data.
4927 */ 4910 */
4928 if (userdata) { 4911 if (!(flags & XFS_BMAPI_METADATA)) {
4929 bma.userdata = (aoff == 0) ? 4912 bma.userdata = (aoff == 0) ?
4930 XFS_ALLOC_INITIAL_USER_DATA : 4913 XFS_ALLOC_INITIAL_USER_DATA :
4931 XFS_ALLOC_USERDATA; 4914 XFS_ALLOC_USERDATA;
@@ -4937,7 +4920,7 @@ xfs_bmapi(
4937 bma.firstblock = *firstblock; 4920 bma.firstblock = *firstblock;
4938 bma.alen = alen; 4921 bma.alen = alen;
4939 bma.off = aoff; 4922 bma.off = aoff;
4940 bma.conv = convert; 4923 bma.conv = (flags & XFS_BMAPI_CONVERT);
4941 bma.wasdel = wasdelay; 4924 bma.wasdel = wasdelay;
4942 bma.minlen = minlen; 4925 bma.minlen = minlen;
4943 bma.low = flist->xbf_low; 4926 bma.low = flist->xbf_low;
@@ -4948,7 +4931,8 @@ xfs_bmapi(
4948 * is larger than a stripe unit. 4931 * is larger than a stripe unit.
4949 */ 4932 */
4950 if (mp->m_dalign && alen >= mp->m_dalign && 4933 if (mp->m_dalign && alen >= mp->m_dalign &&
4951 userdata && whichfork == XFS_DATA_FORK) { 4934 (!(flags & XFS_BMAPI_METADATA)) &&
4935 (whichfork == XFS_DATA_FORK)) {
4952 if ((error = xfs_bmap_isaeof(ip, aoff, 4936 if ((error = xfs_bmap_isaeof(ip, aoff,
4953 whichfork, &bma.aeof))) 4937 whichfork, &bma.aeof)))
4954 goto error0; 4938 goto error0;
@@ -5011,19 +4995,19 @@ xfs_bmapi(
5011 } 4995 }
5012 error = xfs_bmap_add_extent(ip, lastx, &cur, &got, 4996 error = xfs_bmap_add_extent(ip, lastx, &cur, &got,
5013 firstblock, flist, &tmp_logflags, whichfork, 4997 firstblock, flist, &tmp_logflags, whichfork,
5014 rsvd); 4998 (flags & XFS_BMAPI_RSVBLOCKS));
5015 logflags |= tmp_logflags; 4999 logflags |= tmp_logflags;
5016 if (error) 5000 if (error)
5017 goto error0; 5001 goto error0;
5018 lastx = ifp->if_lastex; 5002 lastx = ifp->if_lastex;
5019 ep = &ifp->if_u1.if_extents[lastx]; 5003 ep = xfs_iext_get_ext(ifp, lastx);
5020 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 5004 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
5021 xfs_bmbt_get_all(ep, &got); 5005 xfs_bmbt_get_all(ep, &got);
5022 ASSERT(got.br_startoff <= aoff); 5006 ASSERT(got.br_startoff <= aoff);
5023 ASSERT(got.br_startoff + got.br_blockcount >= 5007 ASSERT(got.br_startoff + got.br_blockcount >=
5024 aoff + alen); 5008 aoff + alen);
5025#ifdef DEBUG 5009#ifdef DEBUG
5026 if (delay) { 5010 if (flags & XFS_BMAPI_DELAY) {
5027 ASSERT(ISNULLSTARTBLOCK(got.br_startblock)); 5011 ASSERT(ISNULLSTARTBLOCK(got.br_startblock));
5028 ASSERT(STARTBLOCKVAL(got.br_startblock) > 0); 5012 ASSERT(STARTBLOCKVAL(got.br_startblock) > 0);
5029 } 5013 }
@@ -5052,14 +5036,15 @@ xfs_bmapi(
5052 * Then deal with the allocated space we found. 5036 * Then deal with the allocated space we found.
5053 */ 5037 */
5054 ASSERT(ep != NULL); 5038 ASSERT(ep != NULL);
5055 if (trim && (got.br_startoff + got.br_blockcount > obno)) { 5039 if (!(flags & XFS_BMAPI_ENTIRE) &&
5040 (got.br_startoff + got.br_blockcount > obno)) {
5056 if (obno > bno) 5041 if (obno > bno)
5057 bno = obno; 5042 bno = obno;
5058 ASSERT((bno >= obno) || (n == 0)); 5043 ASSERT((bno >= obno) || (n == 0));
5059 ASSERT(bno < end); 5044 ASSERT(bno < end);
5060 mval->br_startoff = bno; 5045 mval->br_startoff = bno;
5061 if (ISNULLSTARTBLOCK(got.br_startblock)) { 5046 if (ISNULLSTARTBLOCK(got.br_startblock)) {
5062 ASSERT(!wr || delay); 5047 ASSERT(!wr || (flags & XFS_BMAPI_DELAY));
5063 mval->br_startblock = DELAYSTARTBLOCK; 5048 mval->br_startblock = DELAYSTARTBLOCK;
5064 } else 5049 } else
5065 mval->br_startblock = 5050 mval->br_startblock =
@@ -5081,7 +5066,7 @@ xfs_bmapi(
5081 } else { 5066 } else {
5082 *mval = got; 5067 *mval = got;
5083 if (ISNULLSTARTBLOCK(mval->br_startblock)) { 5068 if (ISNULLSTARTBLOCK(mval->br_startblock)) {
5084 ASSERT(!wr || delay); 5069 ASSERT(!wr || (flags & XFS_BMAPI_DELAY));
5085 mval->br_startblock = DELAYSTARTBLOCK; 5070 mval->br_startblock = DELAYSTARTBLOCK;
5086 } 5071 }
5087 } 5072 }
@@ -5107,12 +5092,12 @@ xfs_bmapi(
5107 mval->br_state = XFS_EXT_NORM; 5092 mval->br_state = XFS_EXT_NORM;
5108 error = xfs_bmap_add_extent(ip, lastx, &cur, mval, 5093 error = xfs_bmap_add_extent(ip, lastx, &cur, mval,
5109 firstblock, flist, &tmp_logflags, whichfork, 5094 firstblock, flist, &tmp_logflags, whichfork,
5110 rsvd); 5095 (flags & XFS_BMAPI_RSVBLOCKS));
5111 logflags |= tmp_logflags; 5096 logflags |= tmp_logflags;
5112 if (error) 5097 if (error)
5113 goto error0; 5098 goto error0;
5114 lastx = ifp->if_lastex; 5099 lastx = ifp->if_lastex;
5115 ep = &ifp->if_u1.if_extents[lastx]; 5100 ep = xfs_iext_get_ext(ifp, lastx);
5116 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 5101 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
5117 xfs_bmbt_get_all(ep, &got); 5102 xfs_bmbt_get_all(ep, &got);
5118 /* 5103 /*
@@ -5124,9 +5109,10 @@ xfs_bmapi(
5124 continue; 5109 continue;
5125 } 5110 }
5126 5111
5127 ASSERT(!trim || 5112 ASSERT((flags & XFS_BMAPI_ENTIRE) ||
5128 ((mval->br_startoff + mval->br_blockcount) <= end)); 5113 ((mval->br_startoff + mval->br_blockcount) <= end));
5129 ASSERT(!trim || (mval->br_blockcount <= len) || 5114 ASSERT((flags & XFS_BMAPI_ENTIRE) ||
5115 (mval->br_blockcount <= len) ||
5130 (mval->br_startoff < obno)); 5116 (mval->br_startoff < obno));
5131 bno = mval->br_startoff + mval->br_blockcount; 5117 bno = mval->br_startoff + mval->br_blockcount;
5132 len = end - bno; 5118 len = end - bno;
@@ -5141,7 +5127,8 @@ xfs_bmapi(
5141 mval[-1].br_startblock != HOLESTARTBLOCK && 5127 mval[-1].br_startblock != HOLESTARTBLOCK &&
5142 mval->br_startblock == 5128 mval->br_startblock ==
5143 mval[-1].br_startblock + mval[-1].br_blockcount && 5129 mval[-1].br_startblock + mval[-1].br_blockcount &&
5144 (stateless || mval[-1].br_state == mval->br_state)) { 5130 ((flags & XFS_BMAPI_IGSTATE) ||
5131 mval[-1].br_state == mval->br_state)) {
5145 ASSERT(mval->br_startoff == 5132 ASSERT(mval->br_startoff ==
5146 mval[-1].br_startoff + mval[-1].br_blockcount); 5133 mval[-1].br_startoff + mval[-1].br_blockcount);
5147 mval[-1].br_blockcount += mval->br_blockcount; 5134 mval[-1].br_blockcount += mval->br_blockcount;
@@ -5168,8 +5155,7 @@ xfs_bmapi(
5168 /* 5155 /*
5169 * Else go on to the next record. 5156 * Else go on to the next record.
5170 */ 5157 */
5171 ep++; 5158 ep = xfs_iext_get_ext(ifp, ++lastx);
5172 lastx++;
5173 if (lastx >= nextents) { 5159 if (lastx >= nextents) {
5174 eof = 1; 5160 eof = 1;
5175 prev = got; 5161 prev = got;
@@ -5199,7 +5185,7 @@ xfs_bmapi(
5199error0: 5185error0:
5200 /* 5186 /*
5201 * Log everything. Do this after conversion, there's no point in 5187 * Log everything. Do this after conversion, there's no point in
5202 * logging the extent list if we've converted to btree format. 5188 * logging the extent records if we've converted to btree format.
5203 */ 5189 */
5204 if ((logflags & XFS_ILOG_FEXT(whichfork)) && 5190 if ((logflags & XFS_ILOG_FEXT(whichfork)) &&
5205 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) 5191 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)
@@ -5252,12 +5238,12 @@ xfs_bmapi_single(
5252 xfs_fsblock_t *fsb, /* output: mapped block */ 5238 xfs_fsblock_t *fsb, /* output: mapped block */
5253 xfs_fileoff_t bno) /* starting file offs. mapped */ 5239 xfs_fileoff_t bno) /* starting file offs. mapped */
5254{ 5240{
5255 int eof; /* we've hit the end of extent list */ 5241 int eof; /* we've hit the end of extents */
5256 int error; /* error return */ 5242 int error; /* error return */
5257 xfs_bmbt_irec_t got; /* current extent list record */ 5243 xfs_bmbt_irec_t got; /* current file extent record */
5258 xfs_ifork_t *ifp; /* inode fork pointer */ 5244 xfs_ifork_t *ifp; /* inode fork pointer */
5259 xfs_extnum_t lastx; /* last useful extent number */ 5245 xfs_extnum_t lastx; /* last useful extent number */
5260 xfs_bmbt_irec_t prev; /* previous extent list record */ 5246 xfs_bmbt_irec_t prev; /* previous file extent record */
5261 5247
5262 ifp = XFS_IFORK_PTR(ip, whichfork); 5248 ifp = XFS_IFORK_PTR(ip, whichfork);
5263 if (unlikely( 5249 if (unlikely(
@@ -5312,18 +5298,18 @@ xfs_bunmapi(
5312 xfs_btree_cur_t *cur; /* bmap btree cursor */ 5298 xfs_btree_cur_t *cur; /* bmap btree cursor */
5313 xfs_bmbt_irec_t del; /* extent being deleted */ 5299 xfs_bmbt_irec_t del; /* extent being deleted */
5314 int eof; /* is deleting at eof */ 5300 int eof; /* is deleting at eof */
5315 xfs_bmbt_rec_t *ep; /* extent list entry pointer */ 5301 xfs_bmbt_rec_t *ep; /* extent record pointer */
5316 int error; /* error return value */ 5302 int error; /* error return value */
5317 xfs_extnum_t extno; /* extent number in list */ 5303 xfs_extnum_t extno; /* extent number in list */
5318 xfs_bmbt_irec_t got; /* current extent list entry */ 5304 xfs_bmbt_irec_t got; /* current extent record */
5319 xfs_ifork_t *ifp; /* inode fork pointer */ 5305 xfs_ifork_t *ifp; /* inode fork pointer */
5320 int isrt; /* freeing in rt area */ 5306 int isrt; /* freeing in rt area */
5321 xfs_extnum_t lastx; /* last extent index used */ 5307 xfs_extnum_t lastx; /* last extent index used */
5322 int logflags; /* transaction logging flags */ 5308 int logflags; /* transaction logging flags */
5323 xfs_extlen_t mod; /* rt extent offset */ 5309 xfs_extlen_t mod; /* rt extent offset */
5324 xfs_mount_t *mp; /* mount structure */ 5310 xfs_mount_t *mp; /* mount structure */
5325 xfs_extnum_t nextents; /* size of extent list */ 5311 xfs_extnum_t nextents; /* number of file extents */
5326 xfs_bmbt_irec_t prev; /* previous extent list entry */ 5312 xfs_bmbt_irec_t prev; /* previous extent record */
5327 xfs_fileoff_t start; /* first file offset deleted */ 5313 xfs_fileoff_t start; /* first file offset deleted */
5328 int tmp_logflags; /* partial logging flags */ 5314 int tmp_logflags; /* partial logging flags */
5329 int wasdel; /* was a delayed alloc extent */ 5315 int wasdel; /* was a delayed alloc extent */
@@ -5369,7 +5355,7 @@ xfs_bunmapi(
5369 * file, back up to the last block if so... 5355 * file, back up to the last block if so...
5370 */ 5356 */
5371 if (eof) { 5357 if (eof) {
5372 ep = &ifp->if_u1.if_extents[--lastx]; 5358 ep = xfs_iext_get_ext(ifp, --lastx);
5373 xfs_bmbt_get_all(ep, &got); 5359 xfs_bmbt_get_all(ep, &got);
5374 bno = got.br_startoff + got.br_blockcount - 1; 5360 bno = got.br_startoff + got.br_blockcount - 1;
5375 } 5361 }
@@ -5393,7 +5379,7 @@ xfs_bunmapi(
5393 if (got.br_startoff > bno) { 5379 if (got.br_startoff > bno) {
5394 if (--lastx < 0) 5380 if (--lastx < 0)
5395 break; 5381 break;
5396 ep--; 5382 ep = xfs_iext_get_ext(ifp, lastx);
5397 xfs_bmbt_get_all(ep, &got); 5383 xfs_bmbt_get_all(ep, &got);
5398 } 5384 }
5399 /* 5385 /*
@@ -5440,7 +5426,8 @@ xfs_bunmapi(
5440 del.br_blockcount : mod; 5426 del.br_blockcount : mod;
5441 if (bno < got.br_startoff) { 5427 if (bno < got.br_startoff) {
5442 if (--lastx >= 0) 5428 if (--lastx >= 0)
5443 xfs_bmbt_get_all(--ep, &got); 5429 xfs_bmbt_get_all(xfs_iext_get_ext(
5430 ifp, lastx), &got);
5444 } 5431 }
5445 continue; 5432 continue;
5446 } 5433 }
@@ -5500,7 +5487,8 @@ xfs_bunmapi(
5500 * try again. 5487 * try again.
5501 */ 5488 */
5502 ASSERT(lastx > 0); 5489 ASSERT(lastx > 0);
5503 xfs_bmbt_get_all(ep - 1, &prev); 5490 xfs_bmbt_get_all(xfs_iext_get_ext(ifp,
5491 lastx - 1), &prev);
5504 ASSERT(prev.br_state == XFS_EXT_NORM); 5492 ASSERT(prev.br_state == XFS_EXT_NORM);
5505 ASSERT(!ISNULLSTARTBLOCK(prev.br_startblock)); 5493 ASSERT(!ISNULLSTARTBLOCK(prev.br_startblock));
5506 ASSERT(del.br_startblock == 5494 ASSERT(del.br_startblock ==
@@ -5587,12 +5575,12 @@ nodelete:
5587 * If not done go on to the next (previous) record. 5575 * If not done go on to the next (previous) record.
5588 * Reset ep in case the extents array was re-alloced. 5576 * Reset ep in case the extents array was re-alloced.
5589 */ 5577 */
5590 ep = &ifp->if_u1.if_extents[lastx]; 5578 ep = xfs_iext_get_ext(ifp, lastx);
5591 if (bno != (xfs_fileoff_t)-1 && bno >= start) { 5579 if (bno != (xfs_fileoff_t)-1 && bno >= start) {
5592 if (lastx >= XFS_IFORK_NEXTENTS(ip, whichfork) || 5580 if (lastx >= XFS_IFORK_NEXTENTS(ip, whichfork) ||
5593 xfs_bmbt_get_startoff(ep) > bno) { 5581 xfs_bmbt_get_startoff(ep) > bno) {
5594 lastx--; 5582 if (--lastx >= 0)
5595 ep--; 5583 ep = xfs_iext_get_ext(ifp, lastx);
5596 } 5584 }
5597 if (lastx >= 0) 5585 if (lastx >= 0)
5598 xfs_bmbt_get_all(ep, &got); 5586 xfs_bmbt_get_all(ep, &got);
@@ -5636,7 +5624,7 @@ nodelete:
5636error0: 5624error0:
5637 /* 5625 /*
5638 * Log everything. Do this after conversion, there's no point in 5626 * Log everything. Do this after conversion, there's no point in
5639 * logging the extent list if we've converted to btree format. 5627 * logging the extent records if we've converted to btree format.
5640 */ 5628 */
5641 if ((logflags & XFS_ILOG_FEXT(whichfork)) && 5629 if ((logflags & XFS_ILOG_FEXT(whichfork)) &&
5642 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) 5630 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)
@@ -5892,9 +5880,9 @@ xfs_bmap_isaeof(
5892{ 5880{
5893 int error; /* error return value */ 5881 int error; /* error return value */
5894 xfs_ifork_t *ifp; /* inode fork pointer */ 5882 xfs_ifork_t *ifp; /* inode fork pointer */
5895 xfs_bmbt_rec_t *lastrec; /* extent list entry pointer */ 5883 xfs_bmbt_rec_t *lastrec; /* extent record pointer */
5896 xfs_extnum_t nextents; /* size of extent list */ 5884 xfs_extnum_t nextents; /* number of file extents */
5897 xfs_bmbt_irec_t s; /* expanded extent list entry */ 5885 xfs_bmbt_irec_t s; /* expanded extent record */
5898 5886
5899 ASSERT(whichfork == XFS_DATA_FORK); 5887 ASSERT(whichfork == XFS_DATA_FORK);
5900 ifp = XFS_IFORK_PTR(ip, whichfork); 5888 ifp = XFS_IFORK_PTR(ip, whichfork);
@@ -5909,7 +5897,7 @@ xfs_bmap_isaeof(
5909 /* 5897 /*
5910 * Go to the last extent 5898 * Go to the last extent
5911 */ 5899 */
5912 lastrec = &ifp->if_u1.if_extents[nextents - 1]; 5900 lastrec = xfs_iext_get_ext(ifp, nextents - 1);
5913 xfs_bmbt_get_all(lastrec, &s); 5901 xfs_bmbt_get_all(lastrec, &s);
5914 /* 5902 /*
5915 * Check we are allocating in the last extent (for delayed allocations) 5903 * Check we are allocating in the last extent (for delayed allocations)
@@ -5936,8 +5924,8 @@ xfs_bmap_eof(
5936 xfs_fsblock_t blockcount; /* extent block count */ 5924 xfs_fsblock_t blockcount; /* extent block count */
5937 int error; /* error return value */ 5925 int error; /* error return value */
5938 xfs_ifork_t *ifp; /* inode fork pointer */ 5926 xfs_ifork_t *ifp; /* inode fork pointer */
5939 xfs_bmbt_rec_t *lastrec; /* extent list entry pointer */ 5927 xfs_bmbt_rec_t *lastrec; /* extent record pointer */
5940 xfs_extnum_t nextents; /* size of extent list */ 5928 xfs_extnum_t nextents; /* number of file extents */
5941 xfs_fileoff_t startoff; /* extent starting file offset */ 5929 xfs_fileoff_t startoff; /* extent starting file offset */
5942 5930
5943 ASSERT(whichfork == XFS_DATA_FORK); 5931 ASSERT(whichfork == XFS_DATA_FORK);
@@ -5953,7 +5941,7 @@ xfs_bmap_eof(
5953 /* 5941 /*
5954 * Go to the last extent 5942 * Go to the last extent
5955 */ 5943 */
5956 lastrec = &ifp->if_u1.if_extents[nextents - 1]; 5944 lastrec = xfs_iext_get_ext(ifp, nextents - 1);
5957 startoff = xfs_bmbt_get_startoff(lastrec); 5945 startoff = xfs_bmbt_get_startoff(lastrec);
5958 blockcount = xfs_bmbt_get_blockcount(lastrec); 5946 blockcount = xfs_bmbt_get_blockcount(lastrec);
5959 *eof = endoff >= startoff + blockcount; 5947 *eof = endoff >= startoff + blockcount;
@@ -5969,18 +5957,21 @@ xfs_bmap_check_extents(
5969 xfs_inode_t *ip, /* incore inode pointer */ 5957 xfs_inode_t *ip, /* incore inode pointer */
5970 int whichfork) /* data or attr fork */ 5958 int whichfork) /* data or attr fork */
5971{ 5959{
5972 xfs_bmbt_rec_t *base; /* base of extents list */
5973 xfs_bmbt_rec_t *ep; /* current extent entry */ 5960 xfs_bmbt_rec_t *ep; /* current extent entry */
5961 xfs_extnum_t idx; /* extent record index */
5974 xfs_ifork_t *ifp; /* inode fork pointer */ 5962 xfs_ifork_t *ifp; /* inode fork pointer */
5975 xfs_extnum_t nextents; /* number of extents in list */ 5963 xfs_extnum_t nextents; /* number of extents in list */
5964 xfs_bmbt_rec_t *nextp; /* next extent entry */
5976 5965
5977 ifp = XFS_IFORK_PTR(ip, whichfork); 5966 ifp = XFS_IFORK_PTR(ip, whichfork);
5978 ASSERT(ifp->if_flags & XFS_IFEXTENTS); 5967 ASSERT(ifp->if_flags & XFS_IFEXTENTS);
5979 base = ifp->if_u1.if_extents;
5980 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 5968 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
5981 for (ep = base; ep < &base[nextents - 1]; ep++) { 5969 ep = xfs_iext_get_ext(ifp, 0);
5970 for (idx = 0; idx < nextents - 1; idx++) {
5971 nextp = xfs_iext_get_ext(ifp, idx + 1);
5982 xfs_btree_check_rec(XFS_BTNUM_BMAP, (void *)ep, 5972 xfs_btree_check_rec(XFS_BTNUM_BMAP, (void *)ep,
5983 (void *)(ep + 1)); 5973 (void *)(nextp));
5974 ep = nextp;
5984 } 5975 }
5985} 5976}
5986 5977
@@ -6119,12 +6110,14 @@ xfs_bmap_check_leaf_extents(
6119 xfs_fsblock_t bno; /* block # of "block" */ 6110 xfs_fsblock_t bno; /* block # of "block" */
6120 xfs_buf_t *bp; /* buffer for "block" */ 6111 xfs_buf_t *bp; /* buffer for "block" */
6121 int error; /* error return value */ 6112 int error; /* error return value */
6122 xfs_extnum_t i=0; /* index into the extents list */ 6113 xfs_extnum_t i=0, j; /* index into the extents list */
6123 xfs_ifork_t *ifp; /* fork structure */ 6114 xfs_ifork_t *ifp; /* fork structure */
6124 int level; /* btree level, for checking */ 6115 int level; /* btree level, for checking */
6125 xfs_mount_t *mp; /* file system mount structure */ 6116 xfs_mount_t *mp; /* file system mount structure */
6126 xfs_bmbt_ptr_t *pp; /* pointer to block address */ 6117 xfs_bmbt_ptr_t *pp; /* pointer to block address */
6127 xfs_bmbt_rec_t *ep, *lastp; /* extent pointers in block entry */ 6118 xfs_bmbt_rec_t *ep; /* pointer to current extent */
6119 xfs_bmbt_rec_t *lastp; /* pointer to previous extent */
6120 xfs_bmbt_rec_t *nextp; /* pointer to next extent */
6128 int bp_release = 0; 6121 int bp_release = 0;
6129 6122
6130 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) { 6123 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) {
@@ -6194,7 +6187,6 @@ xfs_bmap_check_leaf_extents(
6194 */ 6187 */
6195 lastp = NULL; 6188 lastp = NULL;
6196 for (;;) { 6189 for (;;) {
6197 xfs_bmbt_rec_t *frp;
6198 xfs_fsblock_t nextbno; 6190 xfs_fsblock_t nextbno;
6199 xfs_extnum_t num_recs; 6191 xfs_extnum_t num_recs;
6200 6192
@@ -6213,18 +6205,20 @@ xfs_bmap_check_leaf_extents(
6213 * conform with the first entry in this one. 6205 * conform with the first entry in this one.
6214 */ 6206 */
6215 6207
6216 frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, 6208 ep = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt,
6217 block, 1, mp->m_bmap_dmxr[0]); 6209 block, 1, mp->m_bmap_dmxr[0]);
6218 6210 for (j = 1; j < num_recs; j++) {
6219 for (ep = frp;ep < frp + (num_recs - 1); ep++) { 6211 nextp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt,
6212 block, j + 1, mp->m_bmap_dmxr[0]);
6220 if (lastp) { 6213 if (lastp) {
6221 xfs_btree_check_rec(XFS_BTNUM_BMAP, 6214 xfs_btree_check_rec(XFS_BTNUM_BMAP,
6222 (void *)lastp, (void *)ep); 6215 (void *)lastp, (void *)ep);
6223 } 6216 }
6224 xfs_btree_check_rec(XFS_BTNUM_BMAP, (void *)ep, 6217 xfs_btree_check_rec(XFS_BTNUM_BMAP, (void *)ep,
6225 (void *)(ep + 1)); 6218 (void *)(nextp));
6219 lastp = ep;
6220 ep = nextp;
6226 } 6221 }
6227 lastp = frp + num_recs - 1; /* For the next iteration */
6228 6222
6229 i += num_recs; 6223 i += num_recs;
6230 if (bp_release) { 6224 if (bp_release) {
@@ -6288,7 +6282,7 @@ xfs_bmap_count_blocks(
6288 mp = ip->i_mount; 6282 mp = ip->i_mount;
6289 ifp = XFS_IFORK_PTR(ip, whichfork); 6283 ifp = XFS_IFORK_PTR(ip, whichfork);
6290 if ( XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS ) { 6284 if ( XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS ) {
6291 if (unlikely(xfs_bmap_count_leaves(ifp->if_u1.if_extents, 6285 if (unlikely(xfs_bmap_count_leaves(ifp, 0,
6292 ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t), 6286 ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t),
6293 count) < 0)) { 6287 count) < 0)) {
6294 XFS_ERROR_REPORT("xfs_bmap_count_blocks(1)", 6288 XFS_ERROR_REPORT("xfs_bmap_count_blocks(1)",
@@ -6310,7 +6304,7 @@ xfs_bmap_count_blocks(
6310 ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks); 6304 ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks);
6311 bno = INT_GET(*pp, ARCH_CONVERT); 6305 bno = INT_GET(*pp, ARCH_CONVERT);
6312 6306
6313 if (unlikely(xfs_bmap_count_tree(mp, tp, bno, level, count) < 0)) { 6307 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, 6308 XFS_ERROR_REPORT("xfs_bmap_count_blocks(2)", XFS_ERRLEVEL_LOW,
6315 mp); 6309 mp);
6316 return XFS_ERROR(EFSCORRUPTED); 6310 return XFS_ERROR(EFSCORRUPTED);
@@ -6327,6 +6321,7 @@ int /* error */
6327xfs_bmap_count_tree( 6321xfs_bmap_count_tree(
6328 xfs_mount_t *mp, /* file system mount point */ 6322 xfs_mount_t *mp, /* file system mount point */
6329 xfs_trans_t *tp, /* transaction pointer */ 6323 xfs_trans_t *tp, /* transaction pointer */
6324 xfs_ifork_t *ifp, /* inode fork pointer */
6330 xfs_fsblock_t blockno, /* file system block number */ 6325 xfs_fsblock_t blockno, /* file system block number */
6331 int levelin, /* level in btree */ 6326 int levelin, /* level in btree */
6332 int *count) /* Count of blocks */ 6327 int *count) /* Count of blocks */
@@ -6339,7 +6334,6 @@ xfs_bmap_count_tree(
6339 xfs_fsblock_t nextbno; 6334 xfs_fsblock_t nextbno;
6340 xfs_bmbt_block_t *block, *nextblock; 6335 xfs_bmbt_block_t *block, *nextblock;
6341 int numrecs; 6336 int numrecs;
6342 xfs_bmbt_rec_t *frp;
6343 6337
6344 if ((error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, XFS_BMAP_BTREE_REF))) 6338 if ((error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, XFS_BMAP_BTREE_REF)))
6345 return error; 6339 return error;
@@ -6364,7 +6358,7 @@ xfs_bmap_count_tree(
6364 xfs_bmbt, block, 1, mp->m_bmap_dmxr[1]); 6358 xfs_bmbt, block, 1, mp->m_bmap_dmxr[1]);
6365 bno = INT_GET(*pp, ARCH_CONVERT); 6359 bno = INT_GET(*pp, ARCH_CONVERT);
6366 if (unlikely((error = 6360 if (unlikely((error =
6367 xfs_bmap_count_tree(mp, tp, bno, level, count)) < 0)) { 6361 xfs_bmap_count_tree(mp, tp, ifp, bno, level, count)) < 0)) {
6368 xfs_trans_brelse(tp, bp); 6362 xfs_trans_brelse(tp, bp);
6369 XFS_ERROR_REPORT("xfs_bmap_count_tree(1)", 6363 XFS_ERROR_REPORT("xfs_bmap_count_tree(1)",
6370 XFS_ERRLEVEL_LOW, mp); 6364 XFS_ERRLEVEL_LOW, mp);
@@ -6376,9 +6370,8 @@ xfs_bmap_count_tree(
6376 for (;;) { 6370 for (;;) {
6377 nextbno = be64_to_cpu(block->bb_rightsib); 6371 nextbno = be64_to_cpu(block->bb_rightsib);
6378 numrecs = be16_to_cpu(block->bb_numrecs); 6372 numrecs = be16_to_cpu(block->bb_numrecs);
6379 frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, 6373 if (unlikely(xfs_bmap_disk_count_leaves(ifp, mp,
6380 xfs_bmbt, block, 1, mp->m_bmap_dmxr[0]); 6374 0, block, numrecs, count) < 0)) {
6381 if (unlikely(xfs_bmap_disk_count_leaves(frp, numrecs, count) < 0)) {
6382 xfs_trans_brelse(tp, bp); 6375 xfs_trans_brelse(tp, bp);
6383 XFS_ERROR_REPORT("xfs_bmap_count_tree(2)", 6376 XFS_ERROR_REPORT("xfs_bmap_count_tree(2)",
6384 XFS_ERRLEVEL_LOW, mp); 6377 XFS_ERRLEVEL_LOW, mp);
@@ -6399,33 +6392,45 @@ xfs_bmap_count_tree(
6399} 6392}
6400 6393
6401/* 6394/*
6402 * Count leaf blocks given a pointer to an extent list. 6395 * Count leaf blocks given a range of extent records.
6403 */ 6396 */
6404int 6397int
6405xfs_bmap_count_leaves( 6398xfs_bmap_count_leaves(
6406 xfs_bmbt_rec_t *frp, 6399 xfs_ifork_t *ifp,
6400 xfs_extnum_t idx,
6407 int numrecs, 6401 int numrecs,
6408 int *count) 6402 int *count)
6409{ 6403{
6410 int b; 6404 int b;
6405 xfs_bmbt_rec_t *frp;
6411 6406
6412 for ( b = 1; b <= numrecs; b++, frp++) 6407 for (b = 0; b < numrecs; b++) {
6408 frp = xfs_iext_get_ext(ifp, idx + b);
6413 *count += xfs_bmbt_get_blockcount(frp); 6409 *count += xfs_bmbt_get_blockcount(frp);
6410 }
6414 return 0; 6411 return 0;
6415} 6412}
6416 6413
6417/* 6414/*
6418 * Count leaf blocks given a pointer to an extent list originally in btree format. 6415 * Count leaf blocks given a range of extent records originally
6416 * in btree format.
6419 */ 6417 */
6420int 6418int
6421xfs_bmap_disk_count_leaves( 6419xfs_bmap_disk_count_leaves(
6422 xfs_bmbt_rec_t *frp, 6420 xfs_ifork_t *ifp,
6421 xfs_mount_t *mp,
6422 xfs_extnum_t idx,
6423 xfs_bmbt_block_t *block,
6423 int numrecs, 6424 int numrecs,
6424 int *count) 6425 int *count)
6425{ 6426{
6426 int b; 6427 int b;
6428 xfs_bmbt_rec_t *frp;
6427 6429
6428 for ( b = 1; b <= numrecs; b++, frp++) 6430 for (b = 1; b <= numrecs; b++) {
6431 frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize,
6432 xfs_bmbt, block, idx + b, mp->m_bmap_dmxr[0]);
6429 *count += xfs_bmbt_disk_get_blockcount(frp); 6433 *count += xfs_bmbt_disk_get_blockcount(frp);
6434 }
6430 return 0; 6435 return 0;
6431} 6436}