aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMandy Kirkconnell <alkirkco@sgi.com>2006-03-13 21:29:52 -0500
committerNathan Scott <nathans@sgi.com>2006-03-13 21:29:52 -0500
commit4eea22f01bb4fdba1aab4430c33adbe88d9d4985 (patch)
tree90e2088cd821e1013088682843e11d600f8c711a
parent9f989c9455aac417c34af9c505e6b169055251da (diff)
[XFS] 929045 567344 This mod re-organizes some of the in-core file extent
code to prepare for an upcoming mod which will introduce multi-level in-core extent allocations. Although the in-core extent management is using a new code path in this mod, the functionality remains the same. Major changes include: - Introduce 10 new subroutines which re-orgainze the existing code but do NOT change functionality: xfs_iext_get_ext() xfs_iext_insert() xfs_iext_add() xfs_iext_remove() xfs_iext_remove_inline() xfs_iext_remove_direct() xfs_iext_realloc_direct() xfs_iext_direct_to_inline() xfs_iext_inline_to_direct() xfs_iext_destroy() - Remove 2 subroutines (functionality moved to new subroutines above): xfs_iext_realloc() -replaced by xfs_iext_add() and xfs_iext_remove() xfs_bmap_insert_exlist() - replaced by xfs_iext_insert() xfs_bmap_delete_exlist() - replaced by xfs_iext_remove() - Replace all hard-coded (indexed) extent assignments with a call to xfs_iext_get_ext() - Replace all extent record pointer arithmetic (ep++, ep--, base + lastx,..) with calls to xfs_iext_get_ext() - Update comments to remove the idea of a single "extent list" and introduce "extent record" terminology instead SGI-PV: 928864 SGI-Modid: xfs-linux-melb:xfs-kern:207390a Signed-off-by: Mandy Kirkconnell <alkirkco@sgi.com> Signed-off-by: Nathan Scott <nathans@sgi.com>
-rw-r--r--fs/xfs/quota/xfs_qm.c9
-rw-r--r--fs/xfs/xfs_bmap.c496
-rw-r--r--fs/xfs/xfs_bmap.h4
-rw-r--r--fs/xfs/xfs_bmap_btree.c10
-rw-r--r--fs/xfs/xfs_inode.c470
-rw-r--r--fs/xfs/xfs_inode.h18
6 files changed, 597 insertions, 410 deletions
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index fd4abb8a32c5..1fb757ef3f41 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -1704,9 +1704,9 @@ xfs_qm_get_rtblks(
1704 xfs_qcnt_t *O_rtblks) 1704 xfs_qcnt_t *O_rtblks)
1705{ 1705{
1706 xfs_filblks_t rtblks; /* total rt blks */ 1706 xfs_filblks_t rtblks; /* total rt blks */
1707 xfs_extnum_t idx; /* extent record index */
1707 xfs_ifork_t *ifp; /* inode fork pointer */ 1708 xfs_ifork_t *ifp; /* inode fork pointer */
1708 xfs_extnum_t nextents; /* number of extent entries */ 1709 xfs_extnum_t nextents; /* number of extent entries */
1709 xfs_bmbt_rec_t *base; /* base of extent array */
1710 xfs_bmbt_rec_t *ep; /* pointer to an extent entry */ 1710 xfs_bmbt_rec_t *ep; /* pointer to an extent entry */
1711 int error; 1711 int error;
1712 1712
@@ -1717,10 +1717,11 @@ xfs_qm_get_rtblks(
1717 return error; 1717 return error;
1718 } 1718 }
1719 rtblks = 0; 1719 rtblks = 0;
1720 nextents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); 1720 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
1721 base = &ifp->if_u1.if_extents[0]; 1721 for (idx = 0; idx < nextents; idx++) {
1722 for (ep = base; ep < &base[nextents]; ep++) 1722 ep = xfs_iext_get_ext(ifp, idx);
1723 rtblks += xfs_bmbt_get_blockcount(ep); 1723 rtblks += xfs_bmbt_get_blockcount(ep);
1724 }
1724 *O_rtblks = (xfs_qcnt_t)rtblks; 1725 *O_rtblks = (xfs_qcnt_t)rtblks;
1725 return 0; 1726 return 0;
1726} 1727}
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 70625e577c70..53c47a181f87 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);
@@ -2811,7 +2794,7 @@ xfs_bmap_alloc(
2811/* 2794/*
2812 * Transform a btree format file with only one leaf node, where the 2795 * 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. 2796 * 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 2797 * 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. 2798 * give up the space for the btree root and pitch the leaf block.
2816 */ 2799 */
2817STATIC int /* error */ 2800STATIC int /* error */
@@ -2868,7 +2851,7 @@ xfs_bmap_btree_to_extents(
2868} 2851}
2869 2852
2870/* 2853/*
2871 * Called by xfs_bmapi to update extent list structure and the btree 2854 * Called by xfs_bmapi to update file extent records and the btree
2872 * after removing space (or undoing a delayed allocation). 2855 * after removing space (or undoing a delayed allocation).
2873 */ 2856 */
2874STATIC int /* error */ 2857STATIC int /* error */
@@ -2878,7 +2861,7 @@ xfs_bmap_del_extent(
2878 xfs_extnum_t idx, /* extent number to update/delete */ 2861 xfs_extnum_t idx, /* extent number to update/delete */
2879 xfs_bmap_free_t *flist, /* list of extents to be freed */ 2862 xfs_bmap_free_t *flist, /* list of extents to be freed */
2880 xfs_btree_cur_t *cur, /* if null, not a btree */ 2863 xfs_btree_cur_t *cur, /* if null, not a btree */
2881 xfs_bmbt_irec_t *del, /* data to remove from extent list */ 2864 xfs_bmbt_irec_t *del, /* data to remove from extents */
2882 int *logflagsp, /* inode logging flags */ 2865 int *logflagsp, /* inode logging flags */
2883 int whichfork, /* data or attr fork */ 2866 int whichfork, /* data or attr fork */
2884 int rsvd) /* OK to allocate reserved blocks */ 2867 int rsvd) /* OK to allocate reserved blocks */
@@ -2903,7 +2886,6 @@ xfs_bmap_del_extent(
2903 xfs_filblks_t nblks; /* quota/sb block count */ 2886 xfs_filblks_t nblks; /* quota/sb block count */
2904 xfs_bmbt_irec_t new; /* new record to be inserted */ 2887 xfs_bmbt_irec_t new; /* new record to be inserted */
2905 /* REFERENCED */ 2888 /* REFERENCED */
2906 xfs_extnum_t nextents; /* number of extents in list */
2907 uint qfield; /* quota field to update */ 2889 uint qfield; /* quota field to update */
2908 xfs_filblks_t temp; /* for indirect length calculations */ 2890 xfs_filblks_t temp; /* for indirect length calculations */
2909 xfs_filblks_t temp2; /* for indirect length calculations */ 2891 xfs_filblks_t temp2; /* for indirect length calculations */
@@ -2911,10 +2893,10 @@ xfs_bmap_del_extent(
2911 XFS_STATS_INC(xs_del_exlist); 2893 XFS_STATS_INC(xs_del_exlist);
2912 mp = ip->i_mount; 2894 mp = ip->i_mount;
2913 ifp = XFS_IFORK_PTR(ip, whichfork); 2895 ifp = XFS_IFORK_PTR(ip, whichfork);
2914 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 2896 ASSERT((idx >= 0) && (idx < ifp->if_bytes /
2915 ASSERT(idx >= 0 && idx < nextents); 2897 (uint)sizeof(xfs_bmbt_rec_t)));
2916 ASSERT(del->br_blockcount > 0); 2898 ASSERT(del->br_blockcount > 0);
2917 ep = &ifp->if_u1.if_extents[idx]; 2899 ep = xfs_iext_get_ext(ifp, idx);
2918 xfs_bmbt_get_all(ep, &got); 2900 xfs_bmbt_get_all(ep, &got);
2919 ASSERT(got.br_startoff <= del->br_startoff); 2901 ASSERT(got.br_startoff <= del->br_startoff);
2920 del_endoff = del->br_startoff + del->br_blockcount; 2902 del_endoff = del->br_startoff + del->br_blockcount;
@@ -2990,7 +2972,7 @@ xfs_bmap_del_extent(
2990 * Matches the whole extent. Delete the entry. 2972 * Matches the whole extent. Delete the entry.
2991 */ 2973 */
2992 xfs_bmap_trace_delete(fname, "3", ip, idx, 1, whichfork); 2974 xfs_bmap_trace_delete(fname, "3", ip, idx, 1, whichfork);
2993 xfs_bmap_delete_exlist(ip, idx, 1, whichfork); 2975 xfs_iext_remove(ifp, idx, 1);
2994 ifp->if_lastex = idx; 2976 ifp->if_lastex = idx;
2995 if (delay) 2977 if (delay)
2996 break; 2978 break;
@@ -3160,7 +3142,7 @@ xfs_bmap_del_extent(
3160 xfs_bmap_trace_post_update(fname, "0", ip, idx, whichfork); 3142 xfs_bmap_trace_post_update(fname, "0", ip, idx, whichfork);
3161 xfs_bmap_trace_insert(fname, "0", ip, idx + 1, 1, &new, NULL, 3143 xfs_bmap_trace_insert(fname, "0", ip, idx + 1, 1, &new, NULL,
3162 whichfork); 3144 whichfork);
3163 xfs_bmap_insert_exlist(ip, idx + 1, 1, &new, whichfork); 3145 xfs_iext_insert(ifp, idx + 1, 1, &new);
3164 ifp->if_lastex = idx + 1; 3146 ifp->if_lastex = idx + 1;
3165 break; 3147 break;
3166 } 3148 }
@@ -3213,31 +3195,6 @@ xfs_bmap_del_free(
3213} 3195}
3214 3196
3215/* 3197/*
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. 3198 * 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. 3199 * The new file will have a root block (in the inode) and a single child block.
3243 */ 3200 */
@@ -3258,13 +3215,13 @@ xfs_bmap_extents_to_btree(
3258 xfs_bmbt_rec_t *arp; /* child record pointer */ 3215 xfs_bmbt_rec_t *arp; /* child record pointer */
3259 xfs_bmbt_block_t *block; /* btree root block */ 3216 xfs_bmbt_block_t *block; /* btree root block */
3260 xfs_btree_cur_t *cur; /* bmap btree cursor */ 3217 xfs_btree_cur_t *cur; /* bmap btree cursor */
3261 xfs_bmbt_rec_t *ep; /* extent list pointer */ 3218 xfs_bmbt_rec_t *ep; /* extent record pointer */
3262 int error; /* error return value */ 3219 int error; /* error return value */
3263 xfs_extnum_t i, cnt; /* extent list index */ 3220 xfs_extnum_t i, cnt; /* extent record index */
3264 xfs_ifork_t *ifp; /* inode fork pointer */ 3221 xfs_ifork_t *ifp; /* inode fork pointer */
3265 xfs_bmbt_key_t *kp; /* root block key pointer */ 3222 xfs_bmbt_key_t *kp; /* root block key pointer */
3266 xfs_mount_t *mp; /* mount structure */ 3223 xfs_mount_t *mp; /* mount structure */
3267 xfs_extnum_t nextents; /* extent list size */ 3224 xfs_extnum_t nextents; /* number of file extents */
3268 xfs_bmbt_ptr_t *pp; /* root block address pointer */ 3225 xfs_bmbt_ptr_t *pp; /* root block address pointer */
3269 3226
3270 ifp = XFS_IFORK_PTR(ip, whichfork); 3227 ifp = XFS_IFORK_PTR(ip, whichfork);
@@ -3343,7 +3300,8 @@ xfs_bmap_extents_to_btree(
3343 ablock->bb_rightsib = cpu_to_be64(NULLDFSBNO); 3300 ablock->bb_rightsib = cpu_to_be64(NULLDFSBNO);
3344 arp = XFS_BMAP_REC_IADDR(ablock, 1, cur); 3301 arp = XFS_BMAP_REC_IADDR(ablock, 1, cur);
3345 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 3302 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++) { 3303 for (cnt = i = 0; i < nextents; i++) {
3304 ep = xfs_iext_get_ext(ifp, i);
3347 if (!ISNULLSTARTBLOCK(xfs_bmbt_get_startblock(ep))) { 3305 if (!ISNULLSTARTBLOCK(xfs_bmbt_get_startblock(ep))) {
3348 arp->l0 = INT_GET(ep->l0, ARCH_CONVERT); 3306 arp->l0 = INT_GET(ep->l0, ARCH_CONVERT);
3349 arp->l1 = INT_GET(ep->l1, ARCH_CONVERT); 3307 arp->l1 = INT_GET(ep->l1, ARCH_CONVERT);
@@ -3373,34 +3331,6 @@ xfs_bmap_extents_to_btree(
3373} 3331}
3374 3332
3375/* 3333/*
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 3334 * Helper routine to reset inode di_forkoff field when switching
3405 * attribute fork from local to extent format - we reset it where 3335 * attribute fork from local to extent format - we reset it where
3406 * possible to make space available for inline data fork extents. 3336 * possible to make space available for inline data fork extents.
@@ -3457,8 +3387,8 @@ xfs_bmap_local_to_extents(
3457 error = 0; 3387 error = 0;
3458 if (ifp->if_bytes) { 3388 if (ifp->if_bytes) {
3459 xfs_alloc_arg_t args; /* allocation arguments */ 3389 xfs_alloc_arg_t args; /* allocation arguments */
3460 xfs_buf_t *bp; /* buffer for extent list block */ 3390 xfs_buf_t *bp; /* buffer for extent block */
3461 xfs_bmbt_rec_t *ep; /* extent list pointer */ 3391 xfs_bmbt_rec_t *ep; /* extent record pointer */
3462 3392
3463 args.tp = tp; 3393 args.tp = tp;
3464 args.mp = ip->i_mount; 3394 args.mp = ip->i_mount;
@@ -3492,8 +3422,8 @@ xfs_bmap_local_to_extents(
3492 xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1); 3422 xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1);
3493 xfs_bmap_forkoff_reset(args.mp, ip, whichfork); 3423 xfs_bmap_forkoff_reset(args.mp, ip, whichfork);
3494 xfs_idata_realloc(ip, -ifp->if_bytes, whichfork); 3424 xfs_idata_realloc(ip, -ifp->if_bytes, whichfork);
3495 xfs_iext_realloc(ip, 1, whichfork); 3425 xfs_iext_add(ifp, 0, 1);
3496 ep = ifp->if_u1.if_extents; 3426 ep = xfs_iext_get_ext(ifp, 0);
3497 xfs_bmbt_set_allf(ep, 0, args.fsbno, 1, XFS_EXT_NORM); 3427 xfs_bmbt_set_allf(ep, 0, args.fsbno, 1, XFS_EXT_NORM);
3498 xfs_bmap_trace_post_update(fname, "new", ip, 0, whichfork); 3428 xfs_bmap_trace_post_update(fname, "new", ip, 0, whichfork);
3499 XFS_IFORK_NEXT_SET(ip, whichfork, 1); 3429 XFS_IFORK_NEXT_SET(ip, whichfork, 1);
@@ -3518,7 +3448,7 @@ xfs_bmbt_rec_t * /* pointer to found extent entry */
3518xfs_bmap_do_search_extents( 3448xfs_bmap_do_search_extents(
3519 xfs_bmbt_rec_t *base, /* base of extent list */ 3449 xfs_bmbt_rec_t *base, /* base of extent list */
3520 xfs_extnum_t lastx, /* last extent index used */ 3450 xfs_extnum_t lastx, /* last extent index used */
3521 xfs_extnum_t nextents, /* extent list size */ 3451 xfs_extnum_t nextents, /* number of file extents */
3522 xfs_fileoff_t bno, /* block number searched for */ 3452 xfs_fileoff_t bno, /* block number searched for */
3523 int *eofp, /* out: end of file found */ 3453 int *eofp, /* out: end of file found */
3524 xfs_extnum_t *lastxp, /* out: last extent index */ 3454 xfs_extnum_t *lastxp, /* out: last extent index */
@@ -3569,9 +3499,9 @@ xfs_bmap_do_search_extents(
3569 got.br_blockcount = xfs_bmbt_get_blockcount(ep); 3499 got.br_blockcount = xfs_bmbt_get_blockcount(ep);
3570 *eofp = 0; 3500 *eofp = 0;
3571 } else { 3501 } else {
3572 /* binary search the extents array */
3573 low = 0; 3502 low = 0;
3574 high = nextents - 1; 3503 high = nextents - 1;
3504 /* binary search the extents array */
3575 while (low <= high) { 3505 while (low <= high) {
3576 XFS_STATS_INC(xs_cmp_exlist); 3506 XFS_STATS_INC(xs_cmp_exlist);
3577 lastx = (low + high) >> 1; 3507 lastx = (low + high) >> 1;
@@ -3641,8 +3571,8 @@ xfs_bmap_search_extents(
3641 xfs_ifork_t *ifp; /* inode fork pointer */ 3571 xfs_ifork_t *ifp; /* inode fork pointer */
3642 xfs_bmbt_rec_t *base; /* base of extent list */ 3572 xfs_bmbt_rec_t *base; /* base of extent list */
3643 xfs_extnum_t lastx; /* last extent index used */ 3573 xfs_extnum_t lastx; /* last extent index used */
3644 xfs_extnum_t nextents; /* extent list size */ 3574 xfs_extnum_t nextents; /* number of file extents */
3645 xfs_bmbt_rec_t *ep; /* extent list entry pointer */ 3575 xfs_bmbt_rec_t *ep; /* extent record pointer */
3646 int rt; /* realtime flag */ 3576 int rt; /* realtime flag */
3647 3577
3648 XFS_STATS_INC(xs_look_exlist); 3578 XFS_STATS_INC(xs_look_exlist);
@@ -3732,7 +3662,7 @@ xfs_bmap_trace_addentry(
3732} 3662}
3733 3663
3734/* 3664/*
3735 * Add bmap trace entry prior to a call to xfs_bmap_delete_exlist. 3665 * Add bmap trace entry prior to a call to xfs_iext_remove.
3736 */ 3666 */
3737STATIC void 3667STATIC void
3738xfs_bmap_trace_delete( 3668xfs_bmap_trace_delete(
@@ -3747,13 +3677,13 @@ xfs_bmap_trace_delete(
3747 3677
3748 ifp = XFS_IFORK_PTR(ip, whichfork); 3678 ifp = XFS_IFORK_PTR(ip, whichfork);
3749 xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_DELETE, fname, desc, ip, idx, 3679 xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_DELETE, fname, desc, ip, idx,
3750 cnt, &ifp->if_u1.if_extents[idx], 3680 cnt, xfs_iext_get_ext(ifp, idx),
3751 cnt == 2 ? &ifp->if_u1.if_extents[idx + 1] : NULL, 3681 cnt == 2 ? xfs_iext_get_ext(ifp, idx + 1) : NULL,
3752 whichfork); 3682 whichfork);
3753} 3683}
3754 3684
3755/* 3685/*
3756 * Add bmap trace entry prior to a call to xfs_bmap_insert_exlist, or 3686 * 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). 3687 * reading in the extents list from the disk (in the btree).
3758 */ 3688 */
3759STATIC void 3689STATIC void
@@ -3783,7 +3713,7 @@ xfs_bmap_trace_insert(
3783} 3713}
3784 3714
3785/* 3715/*
3786 * Add bmap trace entry after updating an extent list entry in place. 3716 * Add bmap trace entry after updating an extent record in place.
3787 */ 3717 */
3788STATIC void 3718STATIC void
3789xfs_bmap_trace_post_update( 3719xfs_bmap_trace_post_update(
@@ -3797,11 +3727,11 @@ xfs_bmap_trace_post_update(
3797 3727
3798 ifp = XFS_IFORK_PTR(ip, whichfork); 3728 ifp = XFS_IFORK_PTR(ip, whichfork);
3799 xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_POST_UP, fname, desc, ip, idx, 3729 xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_POST_UP, fname, desc, ip, idx,
3800 1, &ifp->if_u1.if_extents[idx], NULL, whichfork); 3730 1, xfs_iext_get_ext(ifp, idx), NULL, whichfork);
3801} 3731}
3802 3732
3803/* 3733/*
3804 * Add bmap trace entry prior to updating an extent list entry in place. 3734 * Add bmap trace entry prior to updating an extent record in place.
3805 */ 3735 */
3806STATIC void 3736STATIC void
3807xfs_bmap_trace_pre_update( 3737xfs_bmap_trace_pre_update(
@@ -3815,7 +3745,7 @@ xfs_bmap_trace_pre_update(
3815 3745
3816 ifp = XFS_IFORK_PTR(ip, whichfork); 3746 ifp = XFS_IFORK_PTR(ip, whichfork);
3817 xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_PRE_UP, fname, desc, ip, idx, 1, 3747 xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_PRE_UP, fname, desc, ip, idx, 1,
3818 &ifp->if_u1.if_extents[idx], NULL, whichfork); 3748 xfs_iext_get_ext(ifp, idx), NULL, whichfork);
3819} 3749}
3820#endif /* XFS_BMAP_TRACE */ 3750#endif /* XFS_BMAP_TRACE */
3821 3751
@@ -3892,7 +3822,7 @@ xfs_bmap_add_attrfork(
3892 int rsvd) /* xact may use reserved blks */ 3822 int rsvd) /* xact may use reserved blks */
3893{ 3823{
3894 xfs_fsblock_t firstblock; /* 1st block/ag allocated */ 3824 xfs_fsblock_t firstblock; /* 1st block/ag allocated */
3895 xfs_bmap_free_t flist; /* freed extent list */ 3825 xfs_bmap_free_t flist; /* freed extent records */
3896 xfs_mount_t *mp; /* mount structure */ 3826 xfs_mount_t *mp; /* mount structure */
3897 xfs_trans_t *tp; /* transaction pointer */ 3827 xfs_trans_t *tp; /* transaction pointer */
3898 unsigned long s; /* spinlock spl value */ 3828 unsigned long s; /* spinlock spl value */
@@ -4146,7 +4076,7 @@ xfs_bmap_finish(
4146 xfs_efd_log_item_t *efd; /* extent free data */ 4076 xfs_efd_log_item_t *efd; /* extent free data */
4147 xfs_efi_log_item_t *efi; /* extent free intention */ 4077 xfs_efi_log_item_t *efi; /* extent free intention */
4148 int error; /* error return value */ 4078 int error; /* error return value */
4149 xfs_bmap_free_item_t *free; /* free extent list item */ 4079 xfs_bmap_free_item_t *free; /* free extent item */
4150 unsigned int logres; /* new log reservation */ 4080 unsigned int logres; /* new log reservation */
4151 unsigned int logcount; /* new log count */ 4081 unsigned int logcount; /* new log count */
4152 xfs_mount_t *mp; /* filesystem mount structure */ 4082 xfs_mount_t *mp; /* filesystem mount structure */
@@ -4242,9 +4172,9 @@ xfs_bmap_first_unused(
4242 xfs_fileoff_t *first_unused, /* unused block */ 4172 xfs_fileoff_t *first_unused, /* unused block */
4243 int whichfork) /* data or attr fork */ 4173 int whichfork) /* data or attr fork */
4244{ 4174{
4245 xfs_bmbt_rec_t *base; /* base of extent array */
4246 xfs_bmbt_rec_t *ep; /* pointer to an extent entry */ 4175 xfs_bmbt_rec_t *ep; /* pointer to an extent entry */
4247 int error; /* error return value */ 4176 int error; /* error return value */
4177 int idx; /* extent record index */
4248 xfs_ifork_t *ifp; /* inode fork pointer */ 4178 xfs_ifork_t *ifp; /* inode fork pointer */
4249 xfs_fileoff_t lastaddr; /* last block number seen */ 4179 xfs_fileoff_t lastaddr; /* last block number seen */
4250 xfs_fileoff_t lowest; /* lowest useful block */ 4180 xfs_fileoff_t lowest; /* lowest useful block */
@@ -4265,10 +4195,8 @@ xfs_bmap_first_unused(
4265 return error; 4195 return error;
4266 lowest = *first_unused; 4196 lowest = *first_unused;
4267 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 4197 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
4268 base = &ifp->if_u1.if_extents[0]; 4198 for (idx = 0, lastaddr = 0, max = lowest; idx < nextents; idx++) {
4269 for (lastaddr = 0, max = lowest, ep = base; 4199 ep = xfs_iext_get_ext(ifp, idx);
4270 ep < &base[nextents];
4271 ep++) {
4272 off = xfs_bmbt_get_startoff(ep); 4200 off = xfs_bmbt_get_startoff(ep);
4273 /* 4201 /*
4274 * See if the hole before this extent will work. 4202 * See if the hole before this extent will work.
@@ -4287,8 +4215,8 @@ xfs_bmap_first_unused(
4287/* 4215/*
4288 * Returns the file-relative block number of the last block + 1 before 4216 * Returns the file-relative block number of the last block + 1 before
4289 * last_block (input value) in the file. 4217 * last_block (input value) in the file.
4290 * This is not based on i_size, it is based on the extent list. 4218 * 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. 4219 * Returns 0 for local files, as they do not have extent records.
4292 */ 4220 */
4293int /* error */ 4221int /* error */
4294xfs_bmap_last_before( 4222xfs_bmap_last_before(
@@ -4335,8 +4263,8 @@ xfs_bmap_last_before(
4335 4263
4336/* 4264/*
4337 * Returns the file-relative block number of the first block past eof in 4265 * 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. 4266 * 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. 4267 * Returns 0 for local files, as they do not have extent records.
4340 */ 4268 */
4341int /* error */ 4269int /* error */
4342xfs_bmap_last_offset( 4270xfs_bmap_last_offset(
@@ -4345,7 +4273,6 @@ xfs_bmap_last_offset(
4345 xfs_fileoff_t *last_block, /* last block */ 4273 xfs_fileoff_t *last_block, /* last block */
4346 int whichfork) /* data or attr fork */ 4274 int whichfork) /* data or attr fork */
4347{ 4275{
4348 xfs_bmbt_rec_t *base; /* base of extent array */
4349 xfs_bmbt_rec_t *ep; /* pointer to last extent */ 4276 xfs_bmbt_rec_t *ep; /* pointer to last extent */
4350 int error; /* error return value */ 4277 int error; /* error return value */
4351 xfs_ifork_t *ifp; /* inode fork pointer */ 4278 xfs_ifork_t *ifp; /* inode fork pointer */
@@ -4368,9 +4295,7 @@ xfs_bmap_last_offset(
4368 *last_block = 0; 4295 *last_block = 0;
4369 return 0; 4296 return 0;
4370 } 4297 }
4371 base = &ifp->if_u1.if_extents[0]; 4298 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); 4299 *last_block = xfs_bmbt_get_startoff(ep) + xfs_bmbt_get_blockcount(ep);
4375 return 0; 4300 return 0;
4376} 4301}
@@ -4400,7 +4325,7 @@ xfs_bmap_one_block(
4400 return 0; 4325 return 0;
4401 ifp = XFS_IFORK_PTR(ip, whichfork); 4326 ifp = XFS_IFORK_PTR(ip, whichfork);
4402 ASSERT(ifp->if_flags & XFS_IFEXTENTS); 4327 ASSERT(ifp->if_flags & XFS_IFEXTENTS);
4403 ep = ifp->if_u1.if_extents; 4328 ep = xfs_iext_get_ext(ifp, 0);
4404 xfs_bmbt_get_all(ep, &s); 4329 xfs_bmbt_get_all(ep, &s);
4405 rval = s.br_startoff == 0 && s.br_blockcount == 1; 4330 rval = s.br_startoff == 0 && s.br_blockcount == 1;
4406 if (rval && whichfork == XFS_DATA_FORK) 4331 if (rval && whichfork == XFS_DATA_FORK)
@@ -4435,7 +4360,6 @@ xfs_bmap_read_extents(
4435 xfs_bmbt_ptr_t *pp; /* pointer to block address */ 4360 xfs_bmbt_ptr_t *pp; /* pointer to block address */
4436 /* REFERENCED */ 4361 /* REFERENCED */
4437 xfs_extnum_t room; /* number of entries there's room for */ 4362 xfs_extnum_t room; /* number of entries there's room for */
4438 xfs_bmbt_rec_t *trp; /* target record pointer */
4439 4363
4440 bno = NULLFSBLOCK; 4364 bno = NULLFSBLOCK;
4441 mp = ip->i_mount; 4365 mp = ip->i_mount;
@@ -4478,16 +4402,16 @@ xfs_bmap_read_extents(
4478 /* 4402 /*
4479 * Here with bp and block set to the leftmost leaf node in the tree. 4403 * Here with bp and block set to the leftmost leaf node in the tree.
4480 */ 4404 */
4481 room = ifp->if_bytes / (uint)sizeof(*trp); 4405 room = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
4482 trp = ifp->if_u1.if_extents;
4483 i = 0; 4406 i = 0;
4484 /* 4407 /*
4485 * Loop over all leaf nodes. Copy information to the extent list. 4408 * Loop over all leaf nodes. Copy information to the extent records.
4486 */ 4409 */
4487 for (;;) { 4410 for (;;) {
4488 xfs_bmbt_rec_t *frp, *temp; 4411 xfs_bmbt_rec_t *frp, *trp;
4489 xfs_fsblock_t nextbno; 4412 xfs_fsblock_t nextbno;
4490 xfs_extnum_t num_recs; 4413 xfs_extnum_t num_recs;
4414 xfs_extnum_t start;
4491 4415
4492 4416
4493 num_recs = be16_to_cpu(block->bb_numrecs); 4417 num_recs = be16_to_cpu(block->bb_numrecs);
@@ -4511,12 +4435,13 @@ xfs_bmap_read_extents(
4511 if (nextbno != NULLFSBLOCK) 4435 if (nextbno != NULLFSBLOCK)
4512 xfs_btree_reada_bufl(mp, nextbno, 1); 4436 xfs_btree_reada_bufl(mp, nextbno, 1);
4513 /* 4437 /*
4514 * Copy records into the extent list. 4438 * Copy records into the extent records.
4515 */ 4439 */
4516 frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, 4440 frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt,
4517 block, 1, mp->m_bmap_dmxr[0]); 4441 block, 1, mp->m_bmap_dmxr[0]);
4518 temp = trp; 4442 start = i;
4519 for (j = 0; j < num_recs; j++, frp++, trp++) { 4443 for (j = 0; j < num_recs; j++, i++, frp++) {
4444 trp = xfs_iext_get_ext(ifp, i);
4520 trp->l0 = INT_GET(frp->l0, ARCH_CONVERT); 4445 trp->l0 = INT_GET(frp->l0, ARCH_CONVERT);
4521 trp->l1 = INT_GET(frp->l1, ARCH_CONVERT); 4446 trp->l1 = INT_GET(frp->l1, ARCH_CONVERT);
4522 } 4447 }
@@ -4526,14 +4451,14 @@ xfs_bmap_read_extents(
4526 * any "older" data bmap btree records for a 4451 * any "older" data bmap btree records for a
4527 * set bit in the "extent flag" position. 4452 * set bit in the "extent flag" position.
4528 */ 4453 */
4529 if (unlikely(xfs_check_nostate_extents(temp, num_recs))) { 4454 if (unlikely(xfs_check_nostate_extents(ifp,
4455 start, num_recs))) {
4530 XFS_ERROR_REPORT("xfs_bmap_read_extents(2)", 4456 XFS_ERROR_REPORT("xfs_bmap_read_extents(2)",
4531 XFS_ERRLEVEL_LOW, 4457 XFS_ERRLEVEL_LOW,
4532 ip->i_mount); 4458 ip->i_mount);
4533 goto error0; 4459 goto error0;
4534 } 4460 }
4535 } 4461 }
4536 i += num_recs;
4537 xfs_trans_brelse(tp, bp); 4462 xfs_trans_brelse(tp, bp);
4538 bno = nextbno; 4463 bno = nextbno;
4539 /* 4464 /*
@@ -4546,7 +4471,7 @@ xfs_bmap_read_extents(
4546 return error; 4471 return error;
4547 block = XFS_BUF_TO_BMBT_BLOCK(bp); 4472 block = XFS_BUF_TO_BMBT_BLOCK(bp);
4548 } 4473 }
4549 ASSERT(i == ifp->if_bytes / (uint)sizeof(*trp)); 4474 ASSERT(i == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)));
4550 ASSERT(i == XFS_IFORK_NEXTENTS(ip, whichfork)); 4475 ASSERT(i == XFS_IFORK_NEXTENTS(ip, whichfork));
4551 xfs_bmap_trace_exlist(fname, ip, i, whichfork); 4476 xfs_bmap_trace_exlist(fname, ip, i, whichfork);
4552 return 0; 4477 return 0;
@@ -4557,7 +4482,7 @@ error0:
4557 4482
4558#ifdef XFS_BMAP_TRACE 4483#ifdef XFS_BMAP_TRACE
4559/* 4484/*
4560 * Add bmap trace insert entries for all the contents of the extent list. 4485 * Add bmap trace insert entries for all the contents of the extent records.
4561 */ 4486 */
4562void 4487void
4563xfs_bmap_trace_exlist( 4488xfs_bmap_trace_exlist(
@@ -4566,16 +4491,15 @@ xfs_bmap_trace_exlist(
4566 xfs_extnum_t cnt, /* count of entries in the list */ 4491 xfs_extnum_t cnt, /* count of entries in the list */
4567 int whichfork) /* data or attr fork */ 4492 int whichfork) /* data or attr fork */
4568{ 4493{
4569 xfs_bmbt_rec_t *base; /* base of extent list */ 4494 xfs_bmbt_rec_t *ep; /* current extent record */
4570 xfs_bmbt_rec_t *ep; /* current entry in extent list */ 4495 xfs_extnum_t idx; /* extent record index */
4571 xfs_extnum_t idx; /* extent list entry number */
4572 xfs_ifork_t *ifp; /* inode fork pointer */ 4496 xfs_ifork_t *ifp; /* inode fork pointer */
4573 xfs_bmbt_irec_t s; /* extent list record */ 4497 xfs_bmbt_irec_t s; /* file extent record */
4574 4498
4575 ifp = XFS_IFORK_PTR(ip, whichfork); 4499 ifp = XFS_IFORK_PTR(ip, whichfork);
4576 ASSERT(cnt == ifp->if_bytes / (uint)sizeof(*base)); 4500 ASSERT(cnt == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)));
4577 base = ifp->if_u1.if_extents; 4501 for (idx = 0; idx < cnt; idx++) {
4578 for (idx = 0, ep = base; idx < cnt; idx++, ep++) { 4502 ep = xfs_iext_get_ext(ifp, idx);
4579 xfs_bmbt_get_all(ep, &s); 4503 xfs_bmbt_get_all(ep, &s);
4580 xfs_bmap_trace_insert(fname, "exlist", ip, idx, 1, &s, NULL, 4504 xfs_bmap_trace_insert(fname, "exlist", ip, idx, 1, &s, NULL,
4581 whichfork); 4505 whichfork);
@@ -4661,14 +4585,14 @@ xfs_bmapi(
4661 xfs_bmalloca_t bma; /* args for xfs_bmap_alloc */ 4585 xfs_bmalloca_t bma; /* args for xfs_bmap_alloc */
4662 xfs_btree_cur_t *cur; /* bmap btree cursor */ 4586 xfs_btree_cur_t *cur; /* bmap btree cursor */
4663 xfs_fileoff_t end; /* end of mapped file region */ 4587 xfs_fileoff_t end; /* end of mapped file region */
4664 int eof; /* we've hit the end of extent list */ 4588 int eof; /* we've hit the end of extents */
4665 char contig; /* allocation must be one extent */ 4589 char contig; /* allocation must be one extent */
4666 char delay; /* this request is for delayed alloc */ 4590 char delay; /* this request is for delayed alloc */
4667 char exact; /* don't do all of wasdelayed extent */ 4591 char exact; /* don't do all of wasdelayed extent */
4668 char convert; /* unwritten extent I/O completion */ 4592 char convert; /* unwritten extent I/O completion */
4669 xfs_bmbt_rec_t *ep; /* extent list entry pointer */ 4593 xfs_bmbt_rec_t *ep; /* extent record pointer */
4670 int error; /* error return */ 4594 int error; /* error return */
4671 xfs_bmbt_irec_t got; /* current extent list record */ 4595 xfs_bmbt_irec_t got; /* current file extent record */
4672 xfs_ifork_t *ifp; /* inode fork pointer */ 4596 xfs_ifork_t *ifp; /* inode fork pointer */
4673 xfs_extlen_t indlen; /* indirect blocks length */ 4597 xfs_extlen_t indlen; /* indirect blocks length */
4674 xfs_extnum_t lastx; /* last useful extent number */ 4598 xfs_extnum_t lastx; /* last useful extent number */
@@ -4680,7 +4604,7 @@ xfs_bmapi(
4680 int nallocs; /* number of extents alloc\'d */ 4604 int nallocs; /* number of extents alloc\'d */
4681 xfs_extnum_t nextents; /* number of extents in file */ 4605 xfs_extnum_t nextents; /* number of extents in file */
4682 xfs_fileoff_t obno; /* old block number (offset) */ 4606 xfs_fileoff_t obno; /* old block number (offset) */
4683 xfs_bmbt_irec_t prev; /* previous extent list record */ 4607 xfs_bmbt_irec_t prev; /* previous file extent record */
4684 int tmp_logflags; /* temp flags holder */ 4608 int tmp_logflags; /* temp flags holder */
4685 int whichfork; /* data or attr fork */ 4609 int whichfork; /* data or attr fork */
4686 char inhole; /* current location is hole in file */ 4610 char inhole; /* current location is hole in file */
@@ -4805,7 +4729,7 @@ xfs_bmapi(
4805 alen = (xfs_extlen_t)got.br_blockcount; 4729 alen = (xfs_extlen_t)got.br_blockcount;
4806 aoff = got.br_startoff; 4730 aoff = got.br_startoff;
4807 if (lastx != NULLEXTNUM && lastx) { 4731 if (lastx != NULLEXTNUM && lastx) {
4808 ep = &ifp->if_u1.if_extents[lastx - 1]; 4732 ep = xfs_iext_get_ext(ifp, lastx - 1);
4809 xfs_bmbt_get_all(ep, &prev); 4733 xfs_bmbt_get_all(ep, &prev);
4810 } 4734 }
4811 } else if (wasdelay) { 4735 } else if (wasdelay) {
@@ -5016,7 +4940,7 @@ xfs_bmapi(
5016 if (error) 4940 if (error)
5017 goto error0; 4941 goto error0;
5018 lastx = ifp->if_lastex; 4942 lastx = ifp->if_lastex;
5019 ep = &ifp->if_u1.if_extents[lastx]; 4943 ep = xfs_iext_get_ext(ifp, lastx);
5020 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 4944 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
5021 xfs_bmbt_get_all(ep, &got); 4945 xfs_bmbt_get_all(ep, &got);
5022 ASSERT(got.br_startoff <= aoff); 4946 ASSERT(got.br_startoff <= aoff);
@@ -5112,7 +5036,7 @@ xfs_bmapi(
5112 if (error) 5036 if (error)
5113 goto error0; 5037 goto error0;
5114 lastx = ifp->if_lastex; 5038 lastx = ifp->if_lastex;
5115 ep = &ifp->if_u1.if_extents[lastx]; 5039 ep = xfs_iext_get_ext(ifp, lastx);
5116 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 5040 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
5117 xfs_bmbt_get_all(ep, &got); 5041 xfs_bmbt_get_all(ep, &got);
5118 /* 5042 /*
@@ -5168,8 +5092,7 @@ xfs_bmapi(
5168 /* 5092 /*
5169 * Else go on to the next record. 5093 * Else go on to the next record.
5170 */ 5094 */
5171 ep++; 5095 ep = xfs_iext_get_ext(ifp, ++lastx);
5172 lastx++;
5173 if (lastx >= nextents) { 5096 if (lastx >= nextents) {
5174 eof = 1; 5097 eof = 1;
5175 prev = got; 5098 prev = got;
@@ -5199,7 +5122,7 @@ xfs_bmapi(
5199error0: 5122error0:
5200 /* 5123 /*
5201 * Log everything. Do this after conversion, there's no point in 5124 * Log everything. Do this after conversion, there's no point in
5202 * logging the extent list if we've converted to btree format. 5125 * logging the extent records if we've converted to btree format.
5203 */ 5126 */
5204 if ((logflags & XFS_ILOG_FEXT(whichfork)) && 5127 if ((logflags & XFS_ILOG_FEXT(whichfork)) &&
5205 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) 5128 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)
@@ -5252,12 +5175,12 @@ xfs_bmapi_single(
5252 xfs_fsblock_t *fsb, /* output: mapped block */ 5175 xfs_fsblock_t *fsb, /* output: mapped block */
5253 xfs_fileoff_t bno) /* starting file offs. mapped */ 5176 xfs_fileoff_t bno) /* starting file offs. mapped */
5254{ 5177{
5255 int eof; /* we've hit the end of extent list */ 5178 int eof; /* we've hit the end of extents */
5256 int error; /* error return */ 5179 int error; /* error return */
5257 xfs_bmbt_irec_t got; /* current extent list record */ 5180 xfs_bmbt_irec_t got; /* current file extent record */
5258 xfs_ifork_t *ifp; /* inode fork pointer */ 5181 xfs_ifork_t *ifp; /* inode fork pointer */
5259 xfs_extnum_t lastx; /* last useful extent number */ 5182 xfs_extnum_t lastx; /* last useful extent number */
5260 xfs_bmbt_irec_t prev; /* previous extent list record */ 5183 xfs_bmbt_irec_t prev; /* previous file extent record */
5261 5184
5262 ifp = XFS_IFORK_PTR(ip, whichfork); 5185 ifp = XFS_IFORK_PTR(ip, whichfork);
5263 if (unlikely( 5186 if (unlikely(
@@ -5312,18 +5235,18 @@ xfs_bunmapi(
5312 xfs_btree_cur_t *cur; /* bmap btree cursor */ 5235 xfs_btree_cur_t *cur; /* bmap btree cursor */
5313 xfs_bmbt_irec_t del; /* extent being deleted */ 5236 xfs_bmbt_irec_t del; /* extent being deleted */
5314 int eof; /* is deleting at eof */ 5237 int eof; /* is deleting at eof */
5315 xfs_bmbt_rec_t *ep; /* extent list entry pointer */ 5238 xfs_bmbt_rec_t *ep; /* extent record pointer */
5316 int error; /* error return value */ 5239 int error; /* error return value */
5317 xfs_extnum_t extno; /* extent number in list */ 5240 xfs_extnum_t extno; /* extent number in list */
5318 xfs_bmbt_irec_t got; /* current extent list entry */ 5241 xfs_bmbt_irec_t got; /* current extent record */
5319 xfs_ifork_t *ifp; /* inode fork pointer */ 5242 xfs_ifork_t *ifp; /* inode fork pointer */
5320 int isrt; /* freeing in rt area */ 5243 int isrt; /* freeing in rt area */
5321 xfs_extnum_t lastx; /* last extent index used */ 5244 xfs_extnum_t lastx; /* last extent index used */
5322 int logflags; /* transaction logging flags */ 5245 int logflags; /* transaction logging flags */
5323 xfs_extlen_t mod; /* rt extent offset */ 5246 xfs_extlen_t mod; /* rt extent offset */
5324 xfs_mount_t *mp; /* mount structure */ 5247 xfs_mount_t *mp; /* mount structure */
5325 xfs_extnum_t nextents; /* size of extent list */ 5248 xfs_extnum_t nextents; /* number of file extents */
5326 xfs_bmbt_irec_t prev; /* previous extent list entry */ 5249 xfs_bmbt_irec_t prev; /* previous extent record */
5327 xfs_fileoff_t start; /* first file offset deleted */ 5250 xfs_fileoff_t start; /* first file offset deleted */
5328 int tmp_logflags; /* partial logging flags */ 5251 int tmp_logflags; /* partial logging flags */
5329 int wasdel; /* was a delayed alloc extent */ 5252 int wasdel; /* was a delayed alloc extent */
@@ -5369,7 +5292,7 @@ xfs_bunmapi(
5369 * file, back up to the last block if so... 5292 * file, back up to the last block if so...
5370 */ 5293 */
5371 if (eof) { 5294 if (eof) {
5372 ep = &ifp->if_u1.if_extents[--lastx]; 5295 ep = xfs_iext_get_ext(ifp, --lastx);
5373 xfs_bmbt_get_all(ep, &got); 5296 xfs_bmbt_get_all(ep, &got);
5374 bno = got.br_startoff + got.br_blockcount - 1; 5297 bno = got.br_startoff + got.br_blockcount - 1;
5375 } 5298 }
@@ -5393,7 +5316,7 @@ xfs_bunmapi(
5393 if (got.br_startoff > bno) { 5316 if (got.br_startoff > bno) {
5394 if (--lastx < 0) 5317 if (--lastx < 0)
5395 break; 5318 break;
5396 ep--; 5319 ep = xfs_iext_get_ext(ifp, lastx);
5397 xfs_bmbt_get_all(ep, &got); 5320 xfs_bmbt_get_all(ep, &got);
5398 } 5321 }
5399 /* 5322 /*
@@ -5440,7 +5363,8 @@ xfs_bunmapi(
5440 del.br_blockcount : mod; 5363 del.br_blockcount : mod;
5441 if (bno < got.br_startoff) { 5364 if (bno < got.br_startoff) {
5442 if (--lastx >= 0) 5365 if (--lastx >= 0)
5443 xfs_bmbt_get_all(--ep, &got); 5366 xfs_bmbt_get_all(xfs_iext_get_ext(
5367 ifp, lastx), &got);
5444 } 5368 }
5445 continue; 5369 continue;
5446 } 5370 }
@@ -5500,7 +5424,8 @@ xfs_bunmapi(
5500 * try again. 5424 * try again.
5501 */ 5425 */
5502 ASSERT(lastx > 0); 5426 ASSERT(lastx > 0);
5503 xfs_bmbt_get_all(ep - 1, &prev); 5427 xfs_bmbt_get_all(xfs_iext_get_ext(ifp,
5428 lastx - 1), &prev);
5504 ASSERT(prev.br_state == XFS_EXT_NORM); 5429 ASSERT(prev.br_state == XFS_EXT_NORM);
5505 ASSERT(!ISNULLSTARTBLOCK(prev.br_startblock)); 5430 ASSERT(!ISNULLSTARTBLOCK(prev.br_startblock));
5506 ASSERT(del.br_startblock == 5431 ASSERT(del.br_startblock ==
@@ -5587,12 +5512,12 @@ nodelete:
5587 * If not done go on to the next (previous) record. 5512 * If not done go on to the next (previous) record.
5588 * Reset ep in case the extents array was re-alloced. 5513 * Reset ep in case the extents array was re-alloced.
5589 */ 5514 */
5590 ep = &ifp->if_u1.if_extents[lastx]; 5515 ep = xfs_iext_get_ext(ifp, lastx);
5591 if (bno != (xfs_fileoff_t)-1 && bno >= start) { 5516 if (bno != (xfs_fileoff_t)-1 && bno >= start) {
5592 if (lastx >= XFS_IFORK_NEXTENTS(ip, whichfork) || 5517 if (lastx >= XFS_IFORK_NEXTENTS(ip, whichfork) ||
5593 xfs_bmbt_get_startoff(ep) > bno) { 5518 xfs_bmbt_get_startoff(ep) > bno) {
5594 lastx--; 5519 if (--lastx >= 0)
5595 ep--; 5520 ep = xfs_iext_get_ext(ifp, lastx);
5596 } 5521 }
5597 if (lastx >= 0) 5522 if (lastx >= 0)
5598 xfs_bmbt_get_all(ep, &got); 5523 xfs_bmbt_get_all(ep, &got);
@@ -5636,7 +5561,7 @@ nodelete:
5636error0: 5561error0:
5637 /* 5562 /*
5638 * Log everything. Do this after conversion, there's no point in 5563 * Log everything. Do this after conversion, there's no point in
5639 * logging the extent list if we've converted to btree format. 5564 * logging the extent records if we've converted to btree format.
5640 */ 5565 */
5641 if ((logflags & XFS_ILOG_FEXT(whichfork)) && 5566 if ((logflags & XFS_ILOG_FEXT(whichfork)) &&
5642 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) 5567 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)
@@ -5892,9 +5817,9 @@ xfs_bmap_isaeof(
5892{ 5817{
5893 int error; /* error return value */ 5818 int error; /* error return value */
5894 xfs_ifork_t *ifp; /* inode fork pointer */ 5819 xfs_ifork_t *ifp; /* inode fork pointer */
5895 xfs_bmbt_rec_t *lastrec; /* extent list entry pointer */ 5820 xfs_bmbt_rec_t *lastrec; /* extent record pointer */
5896 xfs_extnum_t nextents; /* size of extent list */ 5821 xfs_extnum_t nextents; /* number of file extents */
5897 xfs_bmbt_irec_t s; /* expanded extent list entry */ 5822 xfs_bmbt_irec_t s; /* expanded extent record */
5898 5823
5899 ASSERT(whichfork == XFS_DATA_FORK); 5824 ASSERT(whichfork == XFS_DATA_FORK);
5900 ifp = XFS_IFORK_PTR(ip, whichfork); 5825 ifp = XFS_IFORK_PTR(ip, whichfork);
@@ -5909,7 +5834,7 @@ xfs_bmap_isaeof(
5909 /* 5834 /*
5910 * Go to the last extent 5835 * Go to the last extent
5911 */ 5836 */
5912 lastrec = &ifp->if_u1.if_extents[nextents - 1]; 5837 lastrec = xfs_iext_get_ext(ifp, nextents - 1);
5913 xfs_bmbt_get_all(lastrec, &s); 5838 xfs_bmbt_get_all(lastrec, &s);
5914 /* 5839 /*
5915 * Check we are allocating in the last extent (for delayed allocations) 5840 * Check we are allocating in the last extent (for delayed allocations)
@@ -5936,8 +5861,8 @@ xfs_bmap_eof(
5936 xfs_fsblock_t blockcount; /* extent block count */ 5861 xfs_fsblock_t blockcount; /* extent block count */
5937 int error; /* error return value */ 5862 int error; /* error return value */
5938 xfs_ifork_t *ifp; /* inode fork pointer */ 5863 xfs_ifork_t *ifp; /* inode fork pointer */
5939 xfs_bmbt_rec_t *lastrec; /* extent list entry pointer */ 5864 xfs_bmbt_rec_t *lastrec; /* extent record pointer */
5940 xfs_extnum_t nextents; /* size of extent list */ 5865 xfs_extnum_t nextents; /* number of file extents */
5941 xfs_fileoff_t startoff; /* extent starting file offset */ 5866 xfs_fileoff_t startoff; /* extent starting file offset */
5942 5867
5943 ASSERT(whichfork == XFS_DATA_FORK); 5868 ASSERT(whichfork == XFS_DATA_FORK);
@@ -5953,7 +5878,7 @@ xfs_bmap_eof(
5953 /* 5878 /*
5954 * Go to the last extent 5879 * Go to the last extent
5955 */ 5880 */
5956 lastrec = &ifp->if_u1.if_extents[nextents - 1]; 5881 lastrec = xfs_iext_get_ext(ifp, nextents - 1);
5957 startoff = xfs_bmbt_get_startoff(lastrec); 5882 startoff = xfs_bmbt_get_startoff(lastrec);
5958 blockcount = xfs_bmbt_get_blockcount(lastrec); 5883 blockcount = xfs_bmbt_get_blockcount(lastrec);
5959 *eof = endoff >= startoff + blockcount; 5884 *eof = endoff >= startoff + blockcount;
@@ -5969,18 +5894,21 @@ xfs_bmap_check_extents(
5969 xfs_inode_t *ip, /* incore inode pointer */ 5894 xfs_inode_t *ip, /* incore inode pointer */
5970 int whichfork) /* data or attr fork */ 5895 int whichfork) /* data or attr fork */
5971{ 5896{
5972 xfs_bmbt_rec_t *base; /* base of extents list */
5973 xfs_bmbt_rec_t *ep; /* current extent entry */ 5897 xfs_bmbt_rec_t *ep; /* current extent entry */
5898 xfs_extnum_t idx; /* extent record index */
5974 xfs_ifork_t *ifp; /* inode fork pointer */ 5899 xfs_ifork_t *ifp; /* inode fork pointer */
5975 xfs_extnum_t nextents; /* number of extents in list */ 5900 xfs_extnum_t nextents; /* number of extents in list */
5901 xfs_bmbt_rec_t *nextp; /* next extent entry */
5976 5902
5977 ifp = XFS_IFORK_PTR(ip, whichfork); 5903 ifp = XFS_IFORK_PTR(ip, whichfork);
5978 ASSERT(ifp->if_flags & XFS_IFEXTENTS); 5904 ASSERT(ifp->if_flags & XFS_IFEXTENTS);
5979 base = ifp->if_u1.if_extents;
5980 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 5905 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
5981 for (ep = base; ep < &base[nextents - 1]; ep++) { 5906 ep = xfs_iext_get_ext(ifp, 0);
5907 for (idx = 0; idx < nextents - 1; idx++) {
5908 nextp = xfs_iext_get_ext(ifp, idx + 1);
5982 xfs_btree_check_rec(XFS_BTNUM_BMAP, (void *)ep, 5909 xfs_btree_check_rec(XFS_BTNUM_BMAP, (void *)ep,
5983 (void *)(ep + 1)); 5910 (void *)(nextp));
5911 ep = nextp;
5984 } 5912 }
5985} 5913}
5986 5914
@@ -6119,12 +6047,14 @@ xfs_bmap_check_leaf_extents(
6119 xfs_fsblock_t bno; /* block # of "block" */ 6047 xfs_fsblock_t bno; /* block # of "block" */
6120 xfs_buf_t *bp; /* buffer for "block" */ 6048 xfs_buf_t *bp; /* buffer for "block" */
6121 int error; /* error return value */ 6049 int error; /* error return value */
6122 xfs_extnum_t i=0; /* index into the extents list */ 6050 xfs_extnum_t i=0, j; /* index into the extents list */
6123 xfs_ifork_t *ifp; /* fork structure */ 6051 xfs_ifork_t *ifp; /* fork structure */
6124 int level; /* btree level, for checking */ 6052 int level; /* btree level, for checking */
6125 xfs_mount_t *mp; /* file system mount structure */ 6053 xfs_mount_t *mp; /* file system mount structure */
6126 xfs_bmbt_ptr_t *pp; /* pointer to block address */ 6054 xfs_bmbt_ptr_t *pp; /* pointer to block address */
6127 xfs_bmbt_rec_t *ep, *lastp; /* extent pointers in block entry */ 6055 xfs_bmbt_rec_t *ep; /* pointer to current extent */
6056 xfs_bmbt_rec_t *lastp; /* pointer to previous extent */
6057 xfs_bmbt_rec_t *nextp; /* pointer to next extent */
6128 int bp_release = 0; 6058 int bp_release = 0;
6129 6059
6130 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) { 6060 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) {
@@ -6194,7 +6124,6 @@ xfs_bmap_check_leaf_extents(
6194 */ 6124 */
6195 lastp = NULL; 6125 lastp = NULL;
6196 for (;;) { 6126 for (;;) {
6197 xfs_bmbt_rec_t *frp;
6198 xfs_fsblock_t nextbno; 6127 xfs_fsblock_t nextbno;
6199 xfs_extnum_t num_recs; 6128 xfs_extnum_t num_recs;
6200 6129
@@ -6213,18 +6142,20 @@ xfs_bmap_check_leaf_extents(
6213 * conform with the first entry in this one. 6142 * conform with the first entry in this one.
6214 */ 6143 */
6215 6144
6216 frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, 6145 ep = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt,
6217 block, 1, mp->m_bmap_dmxr[0]); 6146 block, 1, mp->m_bmap_dmxr[0]);
6218 6147 for (j = 1; j < num_recs; j++) {
6219 for (ep = frp;ep < frp + (num_recs - 1); ep++) { 6148 nextp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt,
6149 block, j + 1, mp->m_bmap_dmxr[0]);
6220 if (lastp) { 6150 if (lastp) {
6221 xfs_btree_check_rec(XFS_BTNUM_BMAP, 6151 xfs_btree_check_rec(XFS_BTNUM_BMAP,
6222 (void *)lastp, (void *)ep); 6152 (void *)lastp, (void *)ep);
6223 } 6153 }
6224 xfs_btree_check_rec(XFS_BTNUM_BMAP, (void *)ep, 6154 xfs_btree_check_rec(XFS_BTNUM_BMAP, (void *)ep,
6225 (void *)(ep + 1)); 6155 (void *)(nextp));
6156 lastp = ep;
6157 ep = nextp;
6226 } 6158 }
6227 lastp = frp + num_recs - 1; /* For the next iteration */
6228 6159
6229 i += num_recs; 6160 i += num_recs;
6230 if (bp_release) { 6161 if (bp_release) {
@@ -6288,7 +6219,7 @@ xfs_bmap_count_blocks(
6288 mp = ip->i_mount; 6219 mp = ip->i_mount;
6289 ifp = XFS_IFORK_PTR(ip, whichfork); 6220 ifp = XFS_IFORK_PTR(ip, whichfork);
6290 if ( XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS ) { 6221 if ( XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS ) {
6291 if (unlikely(xfs_bmap_count_leaves(ifp->if_u1.if_extents, 6222 if (unlikely(xfs_bmap_count_leaves(ifp, 0,
6292 ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t), 6223 ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t),
6293 count) < 0)) { 6224 count) < 0)) {
6294 XFS_ERROR_REPORT("xfs_bmap_count_blocks(1)", 6225 XFS_ERROR_REPORT("xfs_bmap_count_blocks(1)",
@@ -6310,7 +6241,7 @@ xfs_bmap_count_blocks(
6310 ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks); 6241 ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks);
6311 bno = INT_GET(*pp, ARCH_CONVERT); 6242 bno = INT_GET(*pp, ARCH_CONVERT);
6312 6243
6313 if (unlikely(xfs_bmap_count_tree(mp, tp, bno, level, count) < 0)) { 6244 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, 6245 XFS_ERROR_REPORT("xfs_bmap_count_blocks(2)", XFS_ERRLEVEL_LOW,
6315 mp); 6246 mp);
6316 return XFS_ERROR(EFSCORRUPTED); 6247 return XFS_ERROR(EFSCORRUPTED);
@@ -6327,6 +6258,7 @@ int /* error */
6327xfs_bmap_count_tree( 6258xfs_bmap_count_tree(
6328 xfs_mount_t *mp, /* file system mount point */ 6259 xfs_mount_t *mp, /* file system mount point */
6329 xfs_trans_t *tp, /* transaction pointer */ 6260 xfs_trans_t *tp, /* transaction pointer */
6261 xfs_ifork_t *ifp, /* inode fork pointer */
6330 xfs_fsblock_t blockno, /* file system block number */ 6262 xfs_fsblock_t blockno, /* file system block number */
6331 int levelin, /* level in btree */ 6263 int levelin, /* level in btree */
6332 int *count) /* Count of blocks */ 6264 int *count) /* Count of blocks */
@@ -6339,7 +6271,6 @@ xfs_bmap_count_tree(
6339 xfs_fsblock_t nextbno; 6271 xfs_fsblock_t nextbno;
6340 xfs_bmbt_block_t *block, *nextblock; 6272 xfs_bmbt_block_t *block, *nextblock;
6341 int numrecs; 6273 int numrecs;
6342 xfs_bmbt_rec_t *frp;
6343 6274
6344 if ((error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, XFS_BMAP_BTREE_REF))) 6275 if ((error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, XFS_BMAP_BTREE_REF)))
6345 return error; 6276 return error;
@@ -6364,7 +6295,7 @@ xfs_bmap_count_tree(
6364 xfs_bmbt, block, 1, mp->m_bmap_dmxr[1]); 6295 xfs_bmbt, block, 1, mp->m_bmap_dmxr[1]);
6365 bno = INT_GET(*pp, ARCH_CONVERT); 6296 bno = INT_GET(*pp, ARCH_CONVERT);
6366 if (unlikely((error = 6297 if (unlikely((error =
6367 xfs_bmap_count_tree(mp, tp, bno, level, count)) < 0)) { 6298 xfs_bmap_count_tree(mp, tp, ifp, bno, level, count)) < 0)) {
6368 xfs_trans_brelse(tp, bp); 6299 xfs_trans_brelse(tp, bp);
6369 XFS_ERROR_REPORT("xfs_bmap_count_tree(1)", 6300 XFS_ERROR_REPORT("xfs_bmap_count_tree(1)",
6370 XFS_ERRLEVEL_LOW, mp); 6301 XFS_ERRLEVEL_LOW, mp);
@@ -6376,9 +6307,8 @@ xfs_bmap_count_tree(
6376 for (;;) { 6307 for (;;) {
6377 nextbno = be64_to_cpu(block->bb_rightsib); 6308 nextbno = be64_to_cpu(block->bb_rightsib);
6378 numrecs = be16_to_cpu(block->bb_numrecs); 6309 numrecs = be16_to_cpu(block->bb_numrecs);
6379 frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, 6310 if (unlikely(xfs_bmap_disk_count_leaves(ifp, mp,
6380 xfs_bmbt, block, 1, mp->m_bmap_dmxr[0]); 6311 0, block, numrecs, count) < 0)) {
6381 if (unlikely(xfs_bmap_disk_count_leaves(frp, numrecs, count) < 0)) {
6382 xfs_trans_brelse(tp, bp); 6312 xfs_trans_brelse(tp, bp);
6383 XFS_ERROR_REPORT("xfs_bmap_count_tree(2)", 6313 XFS_ERROR_REPORT("xfs_bmap_count_tree(2)",
6384 XFS_ERRLEVEL_LOW, mp); 6314 XFS_ERRLEVEL_LOW, mp);
@@ -6399,33 +6329,45 @@ xfs_bmap_count_tree(
6399} 6329}
6400 6330
6401/* 6331/*
6402 * Count leaf blocks given a pointer to an extent list. 6332 * Count leaf blocks given a range of extent records.
6403 */ 6333 */
6404int 6334int
6405xfs_bmap_count_leaves( 6335xfs_bmap_count_leaves(
6406 xfs_bmbt_rec_t *frp, 6336 xfs_ifork_t *ifp,
6337 xfs_extnum_t idx,
6407 int numrecs, 6338 int numrecs,
6408 int *count) 6339 int *count)
6409{ 6340{
6410 int b; 6341 int b;
6342 xfs_bmbt_rec_t *frp;
6411 6343
6412 for ( b = 1; b <= numrecs; b++, frp++) 6344 for (b = 0; b < numrecs; b++) {
6345 frp = xfs_iext_get_ext(ifp, idx + b);
6413 *count += xfs_bmbt_get_blockcount(frp); 6346 *count += xfs_bmbt_get_blockcount(frp);
6347 }
6414 return 0; 6348 return 0;
6415} 6349}
6416 6350
6417/* 6351/*
6418 * Count leaf blocks given a pointer to an extent list originally in btree format. 6352 * Count leaf blocks given a range of extent records originally
6353 * in btree format.
6419 */ 6354 */
6420int 6355int
6421xfs_bmap_disk_count_leaves( 6356xfs_bmap_disk_count_leaves(
6422 xfs_bmbt_rec_t *frp, 6357 xfs_ifork_t *ifp,
6358 xfs_mount_t *mp,
6359 xfs_extnum_t idx,
6360 xfs_bmbt_block_t *block,
6423 int numrecs, 6361 int numrecs,
6424 int *count) 6362 int *count)
6425{ 6363{
6426 int b; 6364 int b;
6365 xfs_bmbt_rec_t *frp;
6427 6366
6428 for ( b = 1; b <= numrecs; b++, frp++) 6367 for (b = 1; b <= numrecs; b++) {
6368 frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize,
6369 xfs_bmbt, block, idx + b, mp->m_bmap_dmxr[0]);
6429 *count += xfs_bmbt_disk_get_blockcount(frp); 6370 *count += xfs_bmbt_disk_get_blockcount(frp);
6371 }
6430 return 0; 6372 return 0;
6431} 6373}
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h
index 12cc63dfc2c4..4c05f95452c2 100644
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -20,6 +20,7 @@
20 20
21struct getbmap; 21struct getbmap;
22struct xfs_bmbt_irec; 22struct xfs_bmbt_irec;
23struct xfs_ifork;
23struct xfs_inode; 24struct xfs_inode;
24struct xfs_mount; 25struct xfs_mount;
25struct xfs_trans; 26struct xfs_trans;
@@ -347,7 +348,8 @@ xfs_bmap_count_blocks(
347 */ 348 */
348int 349int
349xfs_check_nostate_extents( 350xfs_check_nostate_extents(
350 xfs_bmbt_rec_t *ep, 351 struct xfs_ifork *ifp,
352 xfs_extnum_t idx,
351 xfs_extnum_t num); 353 xfs_extnum_t num);
352 354
353#endif /* __KERNEL__ */ 355#endif /* __KERNEL__ */
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c
index 3f1383d160e8..bea44709afbe 100644
--- a/fs/xfs/xfs_bmap_btree.c
+++ b/fs/xfs/xfs_bmap_btree.c
@@ -2754,7 +2754,7 @@ xfs_bmbt_update(
2754} 2754}
2755 2755
2756/* 2756/*
2757 * Check an extent list, which has just been read, for 2757 * Check extent records, which have just been read, for
2758 * any bit in the extent flag field. ASSERT on debug 2758 * any bit in the extent flag field. ASSERT on debug
2759 * kernels, as this condition should not occur. 2759 * kernels, as this condition should not occur.
2760 * Return an error condition (1) if any flags found, 2760 * Return an error condition (1) if any flags found,
@@ -2763,10 +2763,14 @@ xfs_bmbt_update(
2763 2763
2764int 2764int
2765xfs_check_nostate_extents( 2765xfs_check_nostate_extents(
2766 xfs_bmbt_rec_t *ep, 2766 xfs_ifork_t *ifp,
2767 xfs_extnum_t idx,
2767 xfs_extnum_t num) 2768 xfs_extnum_t num)
2768{ 2769{
2769 for (; num > 0; num--, ep++) { 2770 xfs_bmbt_rec_t *ep;
2771
2772 for (; num > 0; num--, idx++) {
2773 ep = xfs_iext_get_ext(ifp, idx);
2770 if ((ep->l0 >> 2774 if ((ep->l0 >>
2771 (64 - BMBT_EXNTFLAG_BITLEN)) != 0) { 2775 (64 - BMBT_EXNTFLAG_BITLEN)) != 0) {
2772 ASSERT(0); 2776 ASSERT(0);
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 1d7f5a7e063e..6459395a0e40 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -76,16 +76,18 @@ STATIC int xfs_iformat_btree(xfs_inode_t *, xfs_dinode_t *, int);
76 */ 76 */
77STATIC void 77STATIC void
78xfs_validate_extents( 78xfs_validate_extents(
79 xfs_bmbt_rec_t *ep, 79 xfs_ifork_t *ifp,
80 int nrecs, 80 int nrecs,
81 int disk, 81 int disk,
82 xfs_exntfmt_t fmt) 82 xfs_exntfmt_t fmt)
83{ 83{
84 xfs_bmbt_rec_t *ep;
84 xfs_bmbt_irec_t irec; 85 xfs_bmbt_irec_t irec;
85 xfs_bmbt_rec_t rec; 86 xfs_bmbt_rec_t rec;
86 int i; 87 int i;
87 88
88 for (i = 0; i < nrecs; i++) { 89 for (i = 0; i < nrecs; i++) {
90 ep = xfs_iext_get_ext(ifp, i);
89 rec.l0 = get_unaligned((__uint64_t*)&ep->l0); 91 rec.l0 = get_unaligned((__uint64_t*)&ep->l0);
90 rec.l1 = get_unaligned((__uint64_t*)&ep->l1); 92 rec.l1 = get_unaligned((__uint64_t*)&ep->l1);
91 if (disk) 93 if (disk)
@@ -94,11 +96,10 @@ xfs_validate_extents(
94 xfs_bmbt_get_all(&rec, &irec); 96 xfs_bmbt_get_all(&rec, &irec);
95 if (fmt == XFS_EXTFMT_NOSTATE) 97 if (fmt == XFS_EXTFMT_NOSTATE)
96 ASSERT(irec.br_state == XFS_EXT_NORM); 98 ASSERT(irec.br_state == XFS_EXT_NORM);
97 ep++;
98 } 99 }
99} 100}
100#else /* DEBUG */ 101#else /* DEBUG */
101#define xfs_validate_extents(ep, nrecs, disk, fmt) 102#define xfs_validate_extents(ifp, nrecs, disk, fmt)
102#endif /* DEBUG */ 103#endif /* DEBUG */
103 104
104/* 105/*
@@ -597,7 +598,6 @@ xfs_iformat_extents(
597 xfs_bmbt_rec_t *ep, *dp; 598 xfs_bmbt_rec_t *ep, *dp;
598 xfs_ifork_t *ifp; 599 xfs_ifork_t *ifp;
599 int nex; 600 int nex;
600 int real_size;
601 int size; 601 int size;
602 int i; 602 int i;
603 603
@@ -619,23 +619,20 @@ xfs_iformat_extents(
619 return XFS_ERROR(EFSCORRUPTED); 619 return XFS_ERROR(EFSCORRUPTED);
620 } 620 }
621 621
622 real_size = 0; 622 ifp->if_real_bytes = 0;
623 if (nex == 0) 623 if (nex == 0)
624 ifp->if_u1.if_extents = NULL; 624 ifp->if_u1.if_extents = NULL;
625 else if (nex <= XFS_INLINE_EXTS) 625 else if (nex <= XFS_INLINE_EXTS)
626 ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; 626 ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext;
627 else { 627 else
628 ifp->if_u1.if_extents = kmem_alloc(size, KM_SLEEP); 628 xfs_iext_add(ifp, 0, nex);
629 ASSERT(ifp->if_u1.if_extents != NULL); 629
630 real_size = size;
631 }
632 ifp->if_bytes = size; 630 ifp->if_bytes = size;
633 ifp->if_real_bytes = real_size;
634 if (size) { 631 if (size) {
635 dp = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork); 632 dp = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork);
636 xfs_validate_extents(dp, nex, 1, XFS_EXTFMT_INODE(ip)); 633 xfs_validate_extents(ifp, nex, 1, XFS_EXTFMT_INODE(ip));
637 ep = ifp->if_u1.if_extents; 634 for (i = 0; i < nex; i++, dp++) {
638 for (i = 0; i < nex; i++, ep++, dp++) { 635 ep = xfs_iext_get_ext(ifp, i);
639 ep->l0 = INT_GET(get_unaligned((__uint64_t*)&dp->l0), 636 ep->l0 = INT_GET(get_unaligned((__uint64_t*)&dp->l0),
640 ARCH_CONVERT); 637 ARCH_CONVERT);
641 ep->l1 = INT_GET(get_unaligned((__uint64_t*)&dp->l1), 638 ep->l1 = INT_GET(get_unaligned((__uint64_t*)&dp->l1),
@@ -646,7 +643,7 @@ xfs_iformat_extents(
646 if (whichfork != XFS_DATA_FORK || 643 if (whichfork != XFS_DATA_FORK ||
647 XFS_EXTFMT_INODE(ip) == XFS_EXTFMT_NOSTATE) 644 XFS_EXTFMT_INODE(ip) == XFS_EXTFMT_NOSTATE)
648 if (unlikely(xfs_check_nostate_extents( 645 if (unlikely(xfs_check_nostate_extents(
649 ifp->if_u1.if_extents, nex))) { 646 ifp, 0, nex))) {
650 XFS_ERROR_REPORT("xfs_iformat_extents(2)", 647 XFS_ERROR_REPORT("xfs_iformat_extents(2)",
651 XFS_ERRLEVEL_LOW, 648 XFS_ERRLEVEL_LOW,
652 ip->i_mount); 649 ip->i_mount);
@@ -1015,6 +1012,7 @@ xfs_iread_extents(
1015{ 1012{
1016 int error; 1013 int error;
1017 xfs_ifork_t *ifp; 1014 xfs_ifork_t *ifp;
1015 xfs_extnum_t nextents;
1018 size_t size; 1016 size_t size;
1019 1017
1020 if (unlikely(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) { 1018 if (unlikely(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) {
@@ -1022,26 +1020,24 @@ xfs_iread_extents(
1022 ip->i_mount); 1020 ip->i_mount);
1023 return XFS_ERROR(EFSCORRUPTED); 1021 return XFS_ERROR(EFSCORRUPTED);
1024 } 1022 }
1025 size = XFS_IFORK_NEXTENTS(ip, whichfork) * (uint)sizeof(xfs_bmbt_rec_t); 1023 nextents = XFS_IFORK_NEXTENTS(ip, whichfork);
1024 size = nextents * sizeof(xfs_bmbt_rec_t);
1026 ifp = XFS_IFORK_PTR(ip, whichfork); 1025 ifp = XFS_IFORK_PTR(ip, whichfork);
1026
1027 /* 1027 /*
1028 * We know that the size is valid (it's checked in iformat_btree) 1028 * We know that the size is valid (it's checked in iformat_btree)
1029 */ 1029 */
1030 ifp->if_u1.if_extents = kmem_alloc(size, KM_SLEEP);
1031 ASSERT(ifp->if_u1.if_extents != NULL);
1032 ifp->if_lastex = NULLEXTNUM; 1030 ifp->if_lastex = NULLEXTNUM;
1033 ifp->if_bytes = ifp->if_real_bytes = (int)size; 1031 ifp->if_bytes = ifp->if_real_bytes = 0;
1034 ifp->if_flags |= XFS_IFEXTENTS; 1032 ifp->if_flags |= XFS_IFEXTENTS;
1033 xfs_iext_add(ifp, 0, nextents);
1035 error = xfs_bmap_read_extents(tp, ip, whichfork); 1034 error = xfs_bmap_read_extents(tp, ip, whichfork);
1036 if (error) { 1035 if (error) {
1037 kmem_free(ifp->if_u1.if_extents, size); 1036 xfs_iext_destroy(ifp);
1038 ifp->if_u1.if_extents = NULL;
1039 ifp->if_bytes = ifp->if_real_bytes = 0;
1040 ifp->if_flags &= ~XFS_IFEXTENTS; 1037 ifp->if_flags &= ~XFS_IFEXTENTS;
1041 return error; 1038 return error;
1042 } 1039 }
1043 xfs_validate_extents((xfs_bmbt_rec_t *)ifp->if_u1.if_extents, 1040 xfs_validate_extents(ifp, nextents, 0, XFS_EXTFMT_INODE(ip));
1044 XFS_IFORK_NEXTENTS(ip, whichfork), 0, XFS_EXTFMT_INODE(ip));
1045 return 0; 1041 return 0;
1046} 1042}
1047 1043
@@ -2476,92 +2472,6 @@ xfs_iroot_realloc(
2476 2472
2477 2473
2478/* 2474/*
2479 * This is called when the amount of space needed for if_extents
2480 * is increased or decreased. The change in size is indicated by
2481 * the number of extents that need to be added or deleted in the
2482 * ext_diff parameter.
2483 *
2484 * If the amount of space needed has decreased below the size of the
2485 * inline buffer, then switch to using the inline buffer. Otherwise,
2486 * use kmem_realloc() or kmem_alloc() to adjust the size of the buffer
2487 * to what is needed.
2488 *
2489 * ip -- the inode whose if_extents area is changing
2490 * ext_diff -- the change in the number of extents, positive or negative,
2491 * requested for the if_extents array.
2492 */
2493void
2494xfs_iext_realloc(
2495 xfs_inode_t *ip,
2496 int ext_diff,
2497 int whichfork)
2498{
2499 int byte_diff;
2500 xfs_ifork_t *ifp;
2501 int new_size;
2502 uint rnew_size;
2503
2504 if (ext_diff == 0) {
2505 return;
2506 }
2507
2508 ifp = XFS_IFORK_PTR(ip, whichfork);
2509 byte_diff = ext_diff * (uint)sizeof(xfs_bmbt_rec_t);
2510 new_size = (int)ifp->if_bytes + byte_diff;
2511 ASSERT(new_size >= 0);
2512
2513 if (new_size == 0) {
2514 if (ifp->if_u1.if_extents != ifp->if_u2.if_inline_ext) {
2515 ASSERT(ifp->if_real_bytes != 0);
2516 kmem_free(ifp->if_u1.if_extents, ifp->if_real_bytes);
2517 }
2518 ifp->if_u1.if_extents = NULL;
2519 rnew_size = 0;
2520 } else if (new_size <= sizeof(ifp->if_u2.if_inline_ext)) {
2521 /*
2522 * If the valid extents can fit in if_inline_ext,
2523 * copy them from the malloc'd vector and free it.
2524 */
2525 if (ifp->if_u1.if_extents != ifp->if_u2.if_inline_ext) {
2526 /*
2527 * For now, empty files are format EXTENTS,
2528 * so the if_extents pointer is null.
2529 */
2530 if (ifp->if_u1.if_extents) {
2531 memcpy(ifp->if_u2.if_inline_ext,
2532 ifp->if_u1.if_extents, new_size);
2533 kmem_free(ifp->if_u1.if_extents,
2534 ifp->if_real_bytes);
2535 }
2536 ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext;
2537 }
2538 rnew_size = 0;
2539 } else {
2540 rnew_size = new_size;
2541 if ((rnew_size & (rnew_size - 1)) != 0)
2542 rnew_size = xfs_iroundup(rnew_size);
2543 /*
2544 * Stuck with malloc/realloc.
2545 */
2546 if (ifp->if_u1.if_extents == ifp->if_u2.if_inline_ext) {
2547 ifp->if_u1.if_extents = (xfs_bmbt_rec_t *)
2548 kmem_alloc(rnew_size, KM_SLEEP);
2549 memcpy(ifp->if_u1.if_extents, ifp->if_u2.if_inline_ext,
2550 sizeof(ifp->if_u2.if_inline_ext));
2551 } else if (rnew_size != ifp->if_real_bytes) {
2552 ifp->if_u1.if_extents = (xfs_bmbt_rec_t *)
2553 kmem_realloc(ifp->if_u1.if_extents,
2554 rnew_size,
2555 ifp->if_real_bytes,
2556 KM_NOFS);
2557 }
2558 }
2559 ifp->if_real_bytes = rnew_size;
2560 ifp->if_bytes = new_size;
2561}
2562
2563
2564/*
2565 * This is called when the amount of space needed for if_data 2475 * This is called when the amount of space needed for if_data
2566 * is increased or decreased. The change in size is indicated by 2476 * is increased or decreased. The change in size is indicated by
2567 * the number of bytes that need to be added or deleted in the 2477 * the number of bytes that need to be added or deleted in the
@@ -2723,9 +2633,7 @@ xfs_idestroy_fork(
2723 (ifp->if_u1.if_extents != NULL) && 2633 (ifp->if_u1.if_extents != NULL) &&
2724 (ifp->if_u1.if_extents != ifp->if_u2.if_inline_ext)) { 2634 (ifp->if_u1.if_extents != ifp->if_u2.if_inline_ext)) {
2725 ASSERT(ifp->if_real_bytes != 0); 2635 ASSERT(ifp->if_real_bytes != 0);
2726 kmem_free(ifp->if_u1.if_extents, ifp->if_real_bytes); 2636 xfs_iext_destroy(ifp);
2727 ifp->if_u1.if_extents = NULL;
2728 ifp->if_real_bytes = 0;
2729 } 2637 }
2730 ASSERT(ifp->if_u1.if_extents == NULL || 2638 ASSERT(ifp->if_u1.if_extents == NULL ||
2731 ifp->if_u1.if_extents == ifp->if_u2.if_inline_ext); 2639 ifp->if_u1.if_extents == ifp->if_u2.if_inline_ext);
@@ -2902,16 +2810,15 @@ xfs_iextents_copy(
2902 * the delayed ones. There must be at least one 2810 * the delayed ones. There must be at least one
2903 * non-delayed extent. 2811 * non-delayed extent.
2904 */ 2812 */
2905 ep = ifp->if_u1.if_extents;
2906 dest_ep = buffer; 2813 dest_ep = buffer;
2907 copied = 0; 2814 copied = 0;
2908 for (i = 0; i < nrecs; i++) { 2815 for (i = 0; i < nrecs; i++) {
2816 ep = xfs_iext_get_ext(ifp, i);
2909 start_block = xfs_bmbt_get_startblock(ep); 2817 start_block = xfs_bmbt_get_startblock(ep);
2910 if (ISNULLSTARTBLOCK(start_block)) { 2818 if (ISNULLSTARTBLOCK(start_block)) {
2911 /* 2819 /*
2912 * It's a delayed allocation extent, so skip it. 2820 * It's a delayed allocation extent, so skip it.
2913 */ 2821 */
2914 ep++;
2915 continue; 2822 continue;
2916 } 2823 }
2917 2824
@@ -2921,11 +2828,10 @@ xfs_iextents_copy(
2921 put_unaligned(INT_GET(ep->l1, ARCH_CONVERT), 2828 put_unaligned(INT_GET(ep->l1, ARCH_CONVERT),
2922 (__uint64_t*)&dest_ep->l1); 2829 (__uint64_t*)&dest_ep->l1);
2923 dest_ep++; 2830 dest_ep++;
2924 ep++;
2925 copied++; 2831 copied++;
2926 } 2832 }
2927 ASSERT(copied != 0); 2833 ASSERT(copied != 0);
2928 xfs_validate_extents(buffer, copied, 1, XFS_EXTFMT_INODE(ip)); 2834 xfs_validate_extents(ifp, copied, 1, XFS_EXTFMT_INODE(ip));
2929 2835
2930 return (copied * (uint)sizeof(xfs_bmbt_rec_t)); 2836 return (copied * (uint)sizeof(xfs_bmbt_rec_t));
2931} 2837}
@@ -2995,8 +2901,10 @@ xfs_iflush_fork(
2995 case XFS_DINODE_FMT_EXTENTS: 2901 case XFS_DINODE_FMT_EXTENTS:
2996 ASSERT((ifp->if_flags & XFS_IFEXTENTS) || 2902 ASSERT((ifp->if_flags & XFS_IFEXTENTS) ||
2997 !(iip->ili_format.ilf_fields & extflag[whichfork])); 2903 !(iip->ili_format.ilf_fields & extflag[whichfork]));
2998 ASSERT((ifp->if_u1.if_extents != NULL) || (ifp->if_bytes == 0)); 2904 ASSERT((xfs_iext_get_ext(ifp, 0) != NULL) ||
2999 ASSERT((ifp->if_u1.if_extents == NULL) || (ifp->if_bytes > 0)); 2905 (ifp->if_bytes == 0));
2906 ASSERT((xfs_iext_get_ext(ifp, 0) == NULL) ||
2907 (ifp->if_bytes > 0));
3000 if ((iip->ili_format.ilf_fields & extflag[whichfork]) && 2908 if ((iip->ili_format.ilf_fields & extflag[whichfork]) &&
3001 (ifp->if_bytes > 0)) { 2909 (ifp->if_bytes > 0)) {
3002 ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) > 0); 2910 ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) > 0);
@@ -3704,3 +3612,327 @@ xfs_ilock_trace(xfs_inode_t *ip, int lock, unsigned int lockflags, inst_t *ra)
3704 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); 3612 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
3705} 3613}
3706#endif 3614#endif
3615
3616/*
3617 * Return a pointer to the extent record at file index idx.
3618 */
3619xfs_bmbt_rec_t *
3620xfs_iext_get_ext(
3621 xfs_ifork_t *ifp, /* inode fork pointer */
3622 xfs_extnum_t idx) /* index of target extent */
3623{
3624 ASSERT(idx >= 0);
3625 if (ifp->if_bytes) {
3626 return &ifp->if_u1.if_extents[idx];
3627 } else {
3628 return NULL;
3629 }
3630}
3631
3632/*
3633 * Insert new item(s) into the extent records for incore inode
3634 * fork 'ifp'. 'count' new items are inserted at index 'idx'.
3635 */
3636void
3637xfs_iext_insert(
3638 xfs_ifork_t *ifp, /* inode fork pointer */
3639 xfs_extnum_t idx, /* starting index of new items */
3640 xfs_extnum_t count, /* number of inserted items */
3641 xfs_bmbt_irec_t *new) /* items to insert */
3642{
3643 xfs_bmbt_rec_t *ep; /* extent record pointer */
3644 xfs_extnum_t i; /* extent record index */
3645
3646 ASSERT(ifp->if_flags & XFS_IFEXTENTS);
3647 xfs_iext_add(ifp, idx, count);
3648 for (i = idx; i < idx + count; i++, new++) {
3649 ep = xfs_iext_get_ext(ifp, i);
3650 xfs_bmbt_set_all(ep, new);
3651 }
3652}
3653
3654/*
3655 * This is called when the amount of space required for incore file
3656 * extents needs to be increased. The ext_diff parameter stores the
3657 * number of new extents being added and the idx parameter contains
3658 * the extent index where the new extents will be added. If the new
3659 * extents are being appended, then we just need to (re)allocate and
3660 * initialize the space. Otherwise, if the new extents are being
3661 * inserted into the middle of the existing entries, a bit more work
3662 * is required to make room for the new extents to be inserted. The
3663 * caller is responsible for filling in the new extent entries upon
3664 * return.
3665 */
3666void
3667xfs_iext_add(
3668 xfs_ifork_t *ifp, /* inode fork pointer */
3669 xfs_extnum_t idx, /* index to begin adding exts */
3670 int ext_diff) /* nubmer of extents to add */
3671{
3672 int byte_diff; /* new bytes being added */
3673 int new_size; /* size of extents after adding */
3674 xfs_extnum_t nextents; /* number of extents in file */
3675
3676 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
3677 ASSERT((idx >= 0) && (idx <= nextents));
3678 byte_diff = ext_diff * sizeof(xfs_bmbt_rec_t);
3679 new_size = ifp->if_bytes + byte_diff;
3680 /*
3681 * If the new number of extents (nextents + ext_diff)
3682 * fits inside the inode, then continue to use the inline
3683 * extent buffer.
3684 */
3685 if (nextents + ext_diff <= XFS_INLINE_EXTS) {
3686 if (idx < nextents) {
3687 memmove(&ifp->if_u2.if_inline_ext[idx + ext_diff],
3688 &ifp->if_u2.if_inline_ext[idx],
3689 (nextents - idx) * sizeof(xfs_bmbt_rec_t));
3690 memset(&ifp->if_u2.if_inline_ext[idx], 0, byte_diff);
3691 }
3692 ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext;
3693 ifp->if_real_bytes = 0;
3694 }
3695 /*
3696 * Otherwise use a linear (direct) extent list.
3697 * If the extents are currently inside the inode,
3698 * xfs_iext_realloc_direct will switch us from
3699 * inline to direct extent allocation mode.
3700 */
3701 else {
3702 xfs_iext_realloc_direct(ifp, new_size);
3703 if (idx < nextents) {
3704 memmove(&ifp->if_u1.if_extents[idx + ext_diff],
3705 &ifp->if_u1.if_extents[idx],
3706 (nextents - idx) * sizeof(xfs_bmbt_rec_t));
3707 memset(&ifp->if_u1.if_extents[idx], 0, byte_diff);
3708 }
3709 }
3710 ifp->if_bytes = new_size;
3711}
3712
3713/*
3714 * This is called when the amount of space required for incore file
3715 * extents needs to be decreased. The ext_diff parameter stores the
3716 * number of extents to be removed and the idx parameter contains
3717 * the extent index where the extents will be removed from.
3718 */
3719void
3720xfs_iext_remove(
3721 xfs_ifork_t *ifp, /* inode fork pointer */
3722 xfs_extnum_t idx, /* index to begin removing exts */
3723 int ext_diff) /* number of extents to remove */
3724{
3725 xfs_extnum_t nextents; /* number of extents in file */
3726 int new_size; /* size of extents after removal */
3727
3728 ASSERT(ext_diff > 0);
3729 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
3730 new_size = (nextents - ext_diff) * sizeof(xfs_bmbt_rec_t);
3731
3732 if (new_size == 0) {
3733 xfs_iext_destroy(ifp);
3734 } else if (ifp->if_real_bytes) {
3735 xfs_iext_remove_direct(ifp, idx, ext_diff);
3736 } else {
3737 xfs_iext_remove_inline(ifp, idx, ext_diff);
3738 }
3739 ifp->if_bytes = new_size;
3740}
3741
3742/*
3743 * This removes ext_diff extents from the inline buffer, beginning
3744 * at extent index idx.
3745 */
3746void
3747xfs_iext_remove_inline(
3748 xfs_ifork_t *ifp, /* inode fork pointer */
3749 xfs_extnum_t idx, /* index to begin removing exts */
3750 int ext_diff) /* number of extents to remove */
3751{
3752 int nextents; /* number of extents in file */
3753
3754 ASSERT(idx < XFS_INLINE_EXTS);
3755 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
3756 ASSERT(((nextents - ext_diff) > 0) &&
3757 (nextents - ext_diff) < XFS_INLINE_EXTS);
3758
3759 if (idx + ext_diff < nextents) {
3760 memmove(&ifp->if_u2.if_inline_ext[idx],
3761 &ifp->if_u2.if_inline_ext[idx + ext_diff],
3762 (nextents - (idx + ext_diff)) *
3763 sizeof(xfs_bmbt_rec_t));
3764 memset(&ifp->if_u2.if_inline_ext[nextents - ext_diff],
3765 0, ext_diff * sizeof(xfs_bmbt_rec_t));
3766 } else {
3767 memset(&ifp->if_u2.if_inline_ext[idx], 0,
3768 ext_diff * sizeof(xfs_bmbt_rec_t));
3769 }
3770}
3771
3772/*
3773 * This removes ext_diff extents from a linear (direct) extent list,
3774 * beginning at extent index idx. If the extents are being removed
3775 * from the end of the list (ie. truncate) then we just need to re-
3776 * allocate the list to remove the extra space. Otherwise, if the
3777 * extents are being removed from the middle of the existing extent
3778 * entries, then we first need to move the extent records beginning
3779 * at idx + ext_diff up in the list to overwrite the records being
3780 * removed, then remove the extra space via kmem_realloc.
3781 */
3782void
3783xfs_iext_remove_direct(
3784 xfs_ifork_t *ifp, /* inode fork pointer */
3785 xfs_extnum_t idx, /* index to begin removing exts */
3786 int ext_diff) /* number of extents to remove */
3787{
3788 xfs_extnum_t nextents; /* number of extents in file */
3789 int new_size; /* size of extents after removal */
3790
3791 new_size = ifp->if_bytes -
3792 (ext_diff * sizeof(xfs_bmbt_rec_t));
3793 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
3794
3795 if (new_size == 0) {
3796 xfs_iext_destroy(ifp);
3797 return;
3798 }
3799 /* Move extents up in the list (if needed) */
3800 if (idx + ext_diff < nextents) {
3801 memmove(&ifp->if_u1.if_extents[idx],
3802 &ifp->if_u1.if_extents[idx + ext_diff],
3803 (nextents - (idx + ext_diff)) *
3804 sizeof(xfs_bmbt_rec_t));
3805 }
3806 memset(&ifp->if_u1.if_extents[nextents - ext_diff],
3807 0, ext_diff * sizeof(xfs_bmbt_rec_t));
3808 /*
3809 * Reallocate the direct extent list. If the extents
3810 * will fit inside the inode then xfs_iext_realloc_direct
3811 * will switch from direct to inline extent allocation
3812 * mode for us.
3813 */
3814 xfs_iext_realloc_direct(ifp, new_size);
3815 ifp->if_bytes = new_size;
3816}
3817
3818/*
3819 * Create, destroy, or resize a linear (direct) block of extents.
3820 */
3821void
3822xfs_iext_realloc_direct(
3823 xfs_ifork_t *ifp, /* inode fork pointer */
3824 int new_size) /* new size of extents */
3825{
3826 int rnew_size; /* real new size of extents */
3827
3828 rnew_size = new_size;
3829
3830 /* Free extent records */
3831 if (new_size == 0) {
3832 xfs_iext_destroy(ifp);
3833 }
3834 /* Resize direct extent list and zero any new bytes */
3835 else if (ifp->if_real_bytes) {
3836 /* Check if extents will fit inside the inode */
3837 if (new_size <= XFS_INLINE_EXTS * sizeof(xfs_bmbt_rec_t)) {
3838 xfs_iext_direct_to_inline(ifp, new_size /
3839 (uint)sizeof(xfs_bmbt_rec_t));
3840 ifp->if_bytes = new_size;
3841 return;
3842 }
3843 if ((new_size & (new_size - 1)) != 0) {
3844 rnew_size = xfs_iroundup(new_size);
3845 }
3846 if (rnew_size != ifp->if_real_bytes) {
3847 ifp->if_u1.if_extents = (xfs_bmbt_rec_t *)
3848 kmem_realloc(ifp->if_u1.if_extents,
3849 rnew_size,
3850 ifp->if_real_bytes,
3851 KM_SLEEP);
3852 }
3853 if (rnew_size > ifp->if_real_bytes) {
3854 memset(&ifp->if_u1.if_extents[ifp->if_bytes /
3855 (uint)sizeof(xfs_bmbt_rec_t)], 0,
3856 rnew_size - ifp->if_real_bytes);
3857 }
3858 }
3859 /*
3860 * Switch from the inline extent buffer to a direct
3861 * extent list. Be sure to include the inline extent
3862 * bytes in new_size.
3863 */
3864 else {
3865 new_size += ifp->if_bytes;
3866 if ((new_size & (new_size - 1)) != 0) {
3867 rnew_size = xfs_iroundup(new_size);
3868 }
3869 xfs_iext_inline_to_direct(ifp, rnew_size);
3870 }
3871 ifp->if_real_bytes = rnew_size;
3872 ifp->if_bytes = new_size;
3873}
3874
3875/*
3876 * Switch from linear (direct) extent records to inline buffer.
3877 */
3878void
3879xfs_iext_direct_to_inline(
3880 xfs_ifork_t *ifp, /* inode fork pointer */
3881 xfs_extnum_t nextents) /* number of extents in file */
3882{
3883 ASSERT(ifp->if_flags & XFS_IFEXTENTS);
3884 ASSERT(nextents <= XFS_INLINE_EXTS);
3885 /*
3886 * The inline buffer was zeroed when we switched
3887 * from inline to direct extent allocation mode,
3888 * so we don't need to clear it here.
3889 */
3890 memcpy(ifp->if_u2.if_inline_ext, ifp->if_u1.if_extents,
3891 nextents * sizeof(xfs_bmbt_rec_t));
3892 kmem_free(ifp->if_u1.if_extents, KM_SLEEP);
3893 ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext;
3894 ifp->if_real_bytes = 0;
3895}
3896
3897/*
3898 * Switch from inline buffer to linear (direct) extent records.
3899 * new_size should already be rounded up to the next power of 2
3900 * by the caller (when appropriate), so use new_size as it is.
3901 * However, since new_size may be rounded up, we can't update
3902 * if_bytes here. It is the caller's responsibility to update
3903 * if_bytes upon return.
3904 */
3905void
3906xfs_iext_inline_to_direct(
3907 xfs_ifork_t *ifp, /* inode fork pointer */
3908 int new_size) /* number of extents in file */
3909{
3910 ifp->if_u1.if_extents = (xfs_bmbt_rec_t *)
3911 kmem_alloc(new_size, KM_SLEEP);
3912 memset(ifp->if_u1.if_extents, 0, new_size);
3913 if (ifp->if_bytes) {
3914 memcpy(ifp->if_u1.if_extents, ifp->if_u2.if_inline_ext,
3915 ifp->if_bytes);
3916 memset(ifp->if_u2.if_inline_ext, 0, XFS_INLINE_EXTS *
3917 sizeof(xfs_bmbt_rec_t));
3918 }
3919 ifp->if_real_bytes = new_size;
3920}
3921
3922/*
3923 * Free incore file extents.
3924 */
3925void
3926xfs_iext_destroy(
3927 xfs_ifork_t *ifp) /* inode fork pointer */
3928{
3929 if (ifp->if_real_bytes) {
3930 kmem_free(ifp->if_u1.if_extents, ifp->if_real_bytes);
3931 } else if (ifp->if_bytes) {
3932 memset(ifp->if_u2.if_inline_ext, 0, XFS_INLINE_EXTS *
3933 sizeof(xfs_bmbt_rec_t));
3934 }
3935 ifp->if_u1.if_extents = NULL;
3936 ifp->if_real_bytes = 0;
3937 ifp->if_bytes = 0;
3938}
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 1cfbcf18ce86..740b73fabd2f 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -70,12 +70,6 @@ typedef struct xfs_ifork {
70 */ 70 */
71#define XFS_IMAP_LOOKUP 0x1 71#define XFS_IMAP_LOOKUP 0x1
72 72
73/*
74 * Maximum number of extent pointers in if_u1.if_extents.
75 */
76#define XFS_MAX_INCORE_EXTENTS 32768
77
78
79#ifdef __KERNEL__ 73#ifdef __KERNEL__
80struct bhv_desc; 74struct bhv_desc;
81struct cred; 75struct cred;
@@ -440,6 +434,18 @@ xfs_inode_t *xfs_vtoi(struct vnode *vp);
440 434
441void xfs_synchronize_atime(xfs_inode_t *); 435void xfs_synchronize_atime(xfs_inode_t *);
442 436
437xfs_bmbt_rec_t *xfs_iext_get_ext(xfs_ifork_t *, xfs_extnum_t);
438void xfs_iext_insert(xfs_ifork_t *, xfs_extnum_t, xfs_extnum_t,
439 xfs_bmbt_irec_t *);
440void xfs_iext_add(xfs_ifork_t *, xfs_extnum_t, int);
441void xfs_iext_remove(xfs_ifork_t *, xfs_extnum_t, int);
442void xfs_iext_remove_inline(xfs_ifork_t *, xfs_extnum_t, int);
443void xfs_iext_remove_direct(xfs_ifork_t *, xfs_extnum_t, int);
444void xfs_iext_realloc_direct(xfs_ifork_t *, int);
445void xfs_iext_direct_to_inline(xfs_ifork_t *, xfs_extnum_t);
446void xfs_iext_inline_to_direct(xfs_ifork_t *, int);
447void xfs_iext_destroy(xfs_ifork_t *);
448
443#define xfs_ipincount(ip) ((unsigned int) atomic_read(&ip->i_pincount)) 449#define xfs_ipincount(ip) ((unsigned int) atomic_read(&ip->i_pincount))
444 450
445#ifdef DEBUG 451#ifdef DEBUG