aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2013-02-24 20:31:26 -0500
committerBen Myers <bpm@sgi.com>2013-03-07 13:35:22 -0500
commit9e5987a7792194ec338f53643237150c0db5f5e0 (patch)
tree3545c8d07dca8e3bd158aaa689c70e98425a83ad /fs/xfs
parentecb3403de1efb56f78d9093376aec0a8af76b316 (diff)
xfs: rearrange some code in xfs_bmap for better locality
xfs_bmap.c is a big file, and some of the related code is spread all throughout the file requiring function prototypes for static function and jumping all through the file to follow a single call path. Rearrange the code so that: a) related functionality is grouped together; and b) functions are grouped in call dependency order While the diffstat is large, there are no code changes in the patch; it is just moving the functionality around and removing the function prototypes at the top of the file. The resulting layout of the code is as follows (top of file to bottom): - miscellaneous helper functions - extent tree block counting routines - debug/sanity checking code - bmap free list manipulation functions - inode fork format manipulation functions - internal/external extent tree seach functions - extent tree manipulation functions used during allocation - functions used during extent read/allocate/removal operations (i.e. xfs_bmapi_write, xfs_bmapi_read, xfs_bunmapi and xfs_getbmap) This means that following logic paths through the bmapi code is much simpler - most of the code relevant to a specific operation is now clustered together rather than spread all over the file.... Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Mark Tinguely <tinguely@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_bmap.c4275
1 files changed, 2069 insertions, 2206 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index b44af9211bd9..d490fe8fd19f 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -52,175 +52,72 @@
52kmem_zone_t *xfs_bmap_free_item_zone; 52kmem_zone_t *xfs_bmap_free_item_zone;
53 53
54/* 54/*
55 * Prototypes for internal bmap routines. 55 * Miscellaneous helper functions
56 */ 56 */
57 57
58#ifdef DEBUG
59STATIC void
60xfs_bmap_check_leaf_extents(
61 struct xfs_btree_cur *cur,
62 struct xfs_inode *ip,
63 int whichfork);
64#else
65#define xfs_bmap_check_leaf_extents(cur, ip, whichfork) do { } while (0)
66#endif
67
68
69/*
70 * Called from xfs_bmap_add_attrfork to handle extents format files.
71 */
72STATIC int /* error */
73xfs_bmap_add_attrfork_extents(
74 xfs_trans_t *tp, /* transaction pointer */
75 xfs_inode_t *ip, /* incore inode pointer */
76 xfs_fsblock_t *firstblock, /* first block allocated */
77 xfs_bmap_free_t *flist, /* blocks to free at commit */
78 int *flags); /* inode logging flags */
79
80/* 58/*
81 * Called from xfs_bmap_add_attrfork to handle local format files. 59 * Compute and fill in the value of the maximum depth of a bmap btree
82 */ 60 * in this filesystem. Done once, during mount.
83STATIC int /* error */
84xfs_bmap_add_attrfork_local(
85 xfs_trans_t *tp, /* transaction pointer */
86 xfs_inode_t *ip, /* incore inode pointer */
87 xfs_fsblock_t *firstblock, /* first block allocated */
88 xfs_bmap_free_t *flist, /* blocks to free at commit */
89 int *flags); /* inode logging flags */
90
91/*
92 * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file.
93 * It figures out where to ask the underlying allocator to put the new extent.
94 */
95STATIC int /* error */
96xfs_bmap_alloc(
97 xfs_bmalloca_t *ap); /* bmap alloc argument struct */
98
99/*
100 * Transform a btree format file with only one leaf node, where the
101 * extents list will fit in the inode, into an extents format file.
102 * Since the file extents are already in-core, all we have to do is
103 * give up the space for the btree root and pitch the leaf block.
104 */
105STATIC int /* error */
106xfs_bmap_btree_to_extents(
107 xfs_trans_t *tp, /* transaction pointer */
108 xfs_inode_t *ip, /* incore inode pointer */
109 xfs_btree_cur_t *cur, /* btree cursor */
110 int *logflagsp, /* inode logging flags */
111 int whichfork); /* data or attr fork */
112
113/*
114 * Remove the entry "free" from the free item list. Prev points to the
115 * previous entry, unless "free" is the head of the list.
116 */
117STATIC void
118xfs_bmap_del_free(
119 xfs_bmap_free_t *flist, /* free item list header */
120 xfs_bmap_free_item_t *prev, /* previous item on list, if any */
121 xfs_bmap_free_item_t *free); /* list item to be freed */
122
123/*
124 * Convert an extents-format file into a btree-format file.
125 * The new file will have a root block (in the inode) and a single child block.
126 */
127STATIC int /* error */
128xfs_bmap_extents_to_btree(
129 xfs_trans_t *tp, /* transaction pointer */
130 xfs_inode_t *ip, /* incore inode pointer */
131 xfs_fsblock_t *firstblock, /* first-block-allocated */
132 xfs_bmap_free_t *flist, /* blocks freed in xaction */
133 xfs_btree_cur_t **curp, /* cursor returned to caller */
134 int wasdel, /* converting a delayed alloc */
135 int *logflagsp, /* inode logging flags */
136 int whichfork); /* data or attr fork */
137
138/*
139 * Convert a local file to an extents file.
140 * This code is sort of bogus, since the file data needs to get
141 * logged so it won't be lost. The bmap-level manipulations are ok, though.
142 */
143STATIC int /* error */
144xfs_bmap_local_to_extents(
145 xfs_trans_t *tp, /* transaction pointer */
146 xfs_inode_t *ip, /* incore inode pointer */
147 xfs_fsblock_t *firstblock, /* first block allocated in xaction */
148 xfs_extlen_t total, /* total blocks needed by transaction */
149 int *logflagsp, /* inode logging flags */
150 int whichfork, /* data or attr fork */
151 void (*init_fn)(struct xfs_buf *bp,
152 struct xfs_inode *ip,
153 struct xfs_ifork *ifp));
154
155/*
156 * Search the extents list for the inode, for the extent containing bno.
157 * If bno lies in a hole, point to the next entry. If bno lies past eof,
158 * *eofp will be set, and *prevp will contain the last entry (null if none).
159 * Else, *lastxp will be set to the index of the found
160 * entry; *gotp will contain the entry.
161 */
162STATIC xfs_bmbt_rec_host_t * /* pointer to found extent entry */
163xfs_bmap_search_extents(
164 xfs_inode_t *ip, /* incore inode pointer */
165 xfs_fileoff_t bno, /* block number searched for */
166 int whichfork, /* data or attr fork */
167 int *eofp, /* out: end of file found */
168 xfs_extnum_t *lastxp, /* out: last extent index */
169 xfs_bmbt_irec_t *gotp, /* out: extent entry found */
170 xfs_bmbt_irec_t *prevp); /* out: previous extent entry found */
171
172/*
173 * Compute the worst-case number of indirect blocks that will be used
174 * for ip's delayed extent of length "len".
175 */
176STATIC xfs_filblks_t
177xfs_bmap_worst_indlen(
178 xfs_inode_t *ip, /* incore inode pointer */
179 xfs_filblks_t len); /* delayed extent length */
180
181#ifdef DEBUG
182/*
183 * Perform various validation checks on the values being returned
184 * from xfs_bmapi().
185 */ 61 */
186STATIC void 62void
187xfs_bmap_validate_ret( 63xfs_bmap_compute_maxlevels(
188 xfs_fileoff_t bno, 64 xfs_mount_t *mp, /* file system mount structure */
189 xfs_filblks_t len, 65 int whichfork) /* data or attr fork */
190 int flags, 66{
191 xfs_bmbt_irec_t *mval, 67 int level; /* btree level */
192 int nmap, 68 uint maxblocks; /* max blocks at this level */
193 int ret_nmap); 69 uint maxleafents; /* max leaf entries possible */
194#else 70 int maxrootrecs; /* max records in root block */
195#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) 71 int minleafrecs; /* min records in leaf block */
196#endif /* DEBUG */ 72 int minnoderecs; /* min records in node block */
197 73 int sz; /* root block size */
198STATIC int
199xfs_bmap_count_tree(
200 xfs_mount_t *mp,
201 xfs_trans_t *tp,
202 xfs_ifork_t *ifp,
203 xfs_fsblock_t blockno,
204 int levelin,
205 int *count);
206
207STATIC void
208xfs_bmap_count_leaves(
209 xfs_ifork_t *ifp,
210 xfs_extnum_t idx,
211 int numrecs,
212 int *count);
213 74
214STATIC void 75 /*
215xfs_bmap_disk_count_leaves( 76 * The maximum number of extents in a file, hence the maximum
216 struct xfs_mount *mp, 77 * number of leaf entries, is controlled by the type of di_nextents
217 struct xfs_btree_block *block, 78 * (a signed 32-bit number, xfs_extnum_t), or by di_anextents
218 int numrecs, 79 * (a signed 16-bit number, xfs_aextnum_t).
219 int *count); 80 *
81 * Note that we can no longer assume that if we are in ATTR1 that
82 * the fork offset of all the inodes will be
83 * (xfs_default_attroffset(ip) >> 3) because we could have mounted
84 * with ATTR2 and then mounted back with ATTR1, keeping the
85 * di_forkoff's fixed but probably at various positions. Therefore,
86 * for both ATTR1 and ATTR2 we have to assume the worst case scenario
87 * of a minimum size available.
88 */
89 if (whichfork == XFS_DATA_FORK) {
90 maxleafents = MAXEXTNUM;
91 sz = XFS_BMDR_SPACE_CALC(MINDBTPTRS);
92 } else {
93 maxleafents = MAXAEXTNUM;
94 sz = XFS_BMDR_SPACE_CALC(MINABTPTRS);
95 }
96 maxrootrecs = xfs_bmdr_maxrecs(mp, sz, 0);
97 minleafrecs = mp->m_bmap_dmnr[0];
98 minnoderecs = mp->m_bmap_dmnr[1];
99 maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs;
100 for (level = 1; maxblocks > 1; level++) {
101 if (maxblocks <= maxrootrecs)
102 maxblocks = 1;
103 else
104 maxblocks = (maxblocks + minnoderecs - 1) / minnoderecs;
105 }
106 mp->m_bm_maxlevels[whichfork] = level;
107}
220 108
221/* 109/*
222 * Bmap internal routines. 110 * Convert the given file system block to a disk block. We have to treat it
111 * differently based on whether the file is a real time file or not, because the
112 * bmap code does.
223 */ 113 */
114xfs_daddr_t
115xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb)
116{
117 return (XFS_IS_REALTIME_INODE(ip) ? \
118 (xfs_daddr_t)XFS_FSB_TO_BB((ip)->i_mount, (fsb)) : \
119 XFS_FSB_TO_DADDR((ip)->i_mount, (fsb)));
120}
224 121
225STATIC int /* error */ 122STATIC int /* error */
226xfs_bmbt_lookup_eq( 123xfs_bmbt_lookup_eq(
@@ -290,6 +187,1057 @@ xfs_bmbt_update(
290} 187}
291 188
292/* 189/*
190 * Compute the worst-case number of indirect blocks that will be used
191 * for ip's delayed extent of length "len".
192 */
193STATIC xfs_filblks_t
194xfs_bmap_worst_indlen(
195 xfs_inode_t *ip, /* incore inode pointer */
196 xfs_filblks_t len) /* delayed extent length */
197{
198 int level; /* btree level number */
199 int maxrecs; /* maximum record count at this level */
200 xfs_mount_t *mp; /* mount structure */
201 xfs_filblks_t rval; /* return value */
202
203 mp = ip->i_mount;
204 maxrecs = mp->m_bmap_dmxr[0];
205 for (level = 0, rval = 0;
206 level < XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK);
207 level++) {
208 len += maxrecs - 1;
209 do_div(len, maxrecs);
210 rval += len;
211 if (len == 1)
212 return rval + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) -
213 level - 1;
214 if (level == 0)
215 maxrecs = mp->m_bmap_dmxr[1];
216 }
217 return rval;
218}
219
220/*
221 * Calculate the default attribute fork offset for newly created inodes.
222 */
223uint
224xfs_default_attroffset(
225 struct xfs_inode *ip)
226{
227 struct xfs_mount *mp = ip->i_mount;
228 uint offset;
229
230 if (mp->m_sb.sb_inodesize == 256) {
231 offset = XFS_LITINO(mp) -
232 XFS_BMDR_SPACE_CALC(MINABTPTRS);
233 } else {
234 offset = XFS_BMDR_SPACE_CALC(6 * MINABTPTRS);
235 }
236
237 ASSERT(offset < XFS_LITINO(mp));
238 return offset;
239}
240
241/*
242 * Helper routine to reset inode di_forkoff field when switching
243 * attribute fork from local to extent format - we reset it where
244 * possible to make space available for inline data fork extents.
245 */
246STATIC void
247xfs_bmap_forkoff_reset(
248 xfs_mount_t *mp,
249 xfs_inode_t *ip,
250 int whichfork)
251{
252 if (whichfork == XFS_ATTR_FORK &&
253 ip->i_d.di_format != XFS_DINODE_FMT_DEV &&
254 ip->i_d.di_format != XFS_DINODE_FMT_UUID &&
255 ip->i_d.di_format != XFS_DINODE_FMT_BTREE) {
256 uint dfl_forkoff = xfs_default_attroffset(ip) >> 3;
257
258 if (dfl_forkoff > ip->i_d.di_forkoff)
259 ip->i_d.di_forkoff = dfl_forkoff;
260 }
261}
262
263/*
264 * Extent tree block counting routines.
265 */
266
267/*
268 * Count leaf blocks given a range of extent records.
269 */
270STATIC void
271xfs_bmap_count_leaves(
272 xfs_ifork_t *ifp,
273 xfs_extnum_t idx,
274 int numrecs,
275 int *count)
276{
277 int b;
278
279 for (b = 0; b < numrecs; b++) {
280 xfs_bmbt_rec_host_t *frp = xfs_iext_get_ext(ifp, idx + b);
281 *count += xfs_bmbt_get_blockcount(frp);
282 }
283}
284
285/*
286 * Count leaf blocks given a range of extent records originally
287 * in btree format.
288 */
289STATIC void
290xfs_bmap_disk_count_leaves(
291 struct xfs_mount *mp,
292 struct xfs_btree_block *block,
293 int numrecs,
294 int *count)
295{
296 int b;
297 xfs_bmbt_rec_t *frp;
298
299 for (b = 1; b <= numrecs; b++) {
300 frp = XFS_BMBT_REC_ADDR(mp, block, b);
301 *count += xfs_bmbt_disk_get_blockcount(frp);
302 }
303}
304
305/*
306 * Recursively walks each level of a btree
307 * to count total fsblocks is use.
308 */
309STATIC int /* error */
310xfs_bmap_count_tree(
311 xfs_mount_t *mp, /* file system mount point */
312 xfs_trans_t *tp, /* transaction pointer */
313 xfs_ifork_t *ifp, /* inode fork pointer */
314 xfs_fsblock_t blockno, /* file system block number */
315 int levelin, /* level in btree */
316 int *count) /* Count of blocks */
317{
318 int error;
319 xfs_buf_t *bp, *nbp;
320 int level = levelin;
321 __be64 *pp;
322 xfs_fsblock_t bno = blockno;
323 xfs_fsblock_t nextbno;
324 struct xfs_btree_block *block, *nextblock;
325 int numrecs;
326
327 error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, XFS_BMAP_BTREE_REF,
328 &xfs_bmbt_buf_ops);
329 if (error)
330 return error;
331 *count += 1;
332 block = XFS_BUF_TO_BLOCK(bp);
333
334 if (--level) {
335 /* Not at node above leaves, count this level of nodes */
336 nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib);
337 while (nextbno != NULLFSBLOCK) {
338 error = xfs_btree_read_bufl(mp, tp, nextbno, 0, &nbp,
339 XFS_BMAP_BTREE_REF,
340 &xfs_bmbt_buf_ops);
341 if (error)
342 return error;
343 *count += 1;
344 nextblock = XFS_BUF_TO_BLOCK(nbp);
345 nextbno = be64_to_cpu(nextblock->bb_u.l.bb_rightsib);
346 xfs_trans_brelse(tp, nbp);
347 }
348
349 /* Dive to the next level */
350 pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]);
351 bno = be64_to_cpu(*pp);
352 if (unlikely((error =
353 xfs_bmap_count_tree(mp, tp, ifp, bno, level, count)) < 0)) {
354 xfs_trans_brelse(tp, bp);
355 XFS_ERROR_REPORT("xfs_bmap_count_tree(1)",
356 XFS_ERRLEVEL_LOW, mp);
357 return XFS_ERROR(EFSCORRUPTED);
358 }
359 xfs_trans_brelse(tp, bp);
360 } else {
361 /* count all level 1 nodes and their leaves */
362 for (;;) {
363 nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib);
364 numrecs = be16_to_cpu(block->bb_numrecs);
365 xfs_bmap_disk_count_leaves(mp, block, numrecs, count);
366 xfs_trans_brelse(tp, bp);
367 if (nextbno == NULLFSBLOCK)
368 break;
369 bno = nextbno;
370 error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp,
371 XFS_BMAP_BTREE_REF,
372 &xfs_bmbt_buf_ops);
373 if (error)
374 return error;
375 *count += 1;
376 block = XFS_BUF_TO_BLOCK(bp);
377 }
378 }
379 return 0;
380}
381
382/*
383 * Count fsblocks of the given fork.
384 */
385int /* error */
386xfs_bmap_count_blocks(
387 xfs_trans_t *tp, /* transaction pointer */
388 xfs_inode_t *ip, /* incore inode */
389 int whichfork, /* data or attr fork */
390 int *count) /* out: count of blocks */
391{
392 struct xfs_btree_block *block; /* current btree block */
393 xfs_fsblock_t bno; /* block # of "block" */
394 xfs_ifork_t *ifp; /* fork structure */
395 int level; /* btree level, for checking */
396 xfs_mount_t *mp; /* file system mount structure */
397 __be64 *pp; /* pointer to block address */
398
399 bno = NULLFSBLOCK;
400 mp = ip->i_mount;
401 ifp = XFS_IFORK_PTR(ip, whichfork);
402 if ( XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS ) {
403 xfs_bmap_count_leaves(ifp, 0,
404 ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t),
405 count);
406 return 0;
407 }
408
409 /*
410 * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
411 */
412 block = ifp->if_broot;
413 level = be16_to_cpu(block->bb_level);
414 ASSERT(level > 0);
415 pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes);
416 bno = be64_to_cpu(*pp);
417 ASSERT(bno != NULLDFSBNO);
418 ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount);
419 ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks);
420
421 if (unlikely(xfs_bmap_count_tree(mp, tp, ifp, bno, level, count) < 0)) {
422 XFS_ERROR_REPORT("xfs_bmap_count_blocks(2)", XFS_ERRLEVEL_LOW,
423 mp);
424 return XFS_ERROR(EFSCORRUPTED);
425 }
426
427 return 0;
428}
429
430/*
431 * Debug/sanity checking code
432 */
433
434STATIC int
435xfs_bmap_sanity_check(
436 struct xfs_mount *mp,
437 struct xfs_buf *bp,
438 int level)
439{
440 struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
441
442 if (block->bb_magic != cpu_to_be32(XFS_BMAP_MAGIC) ||
443 be16_to_cpu(block->bb_level) != level ||
444 be16_to_cpu(block->bb_numrecs) == 0 ||
445 be16_to_cpu(block->bb_numrecs) > mp->m_bmap_dmxr[level != 0])
446 return 0;
447 return 1;
448}
449
450#ifdef DEBUG
451STATIC struct xfs_buf *
452xfs_bmap_get_bp(
453 struct xfs_btree_cur *cur,
454 xfs_fsblock_t bno)
455{
456 struct xfs_log_item_desc *lidp;
457 int i;
458
459 if (!cur)
460 return NULL;
461
462 for (i = 0; i < XFS_BTREE_MAXLEVELS; i++) {
463 if (!cur->bc_bufs[i])
464 break;
465 if (XFS_BUF_ADDR(cur->bc_bufs[i]) == bno)
466 return cur->bc_bufs[i];
467 }
468
469 /* Chase down all the log items to see if the bp is there */
470 list_for_each_entry(lidp, &cur->bc_tp->t_items, lid_trans) {
471 struct xfs_buf_log_item *bip;
472 bip = (struct xfs_buf_log_item *)lidp->lid_item;
473 if (bip->bli_item.li_type == XFS_LI_BUF &&
474 XFS_BUF_ADDR(bip->bli_buf) == bno)
475 return bip->bli_buf;
476 }
477
478 return NULL;
479}
480
481STATIC void
482xfs_check_block(
483 struct xfs_btree_block *block,
484 xfs_mount_t *mp,
485 int root,
486 short sz)
487{
488 int i, j, dmxr;
489 __be64 *pp, *thispa; /* pointer to block address */
490 xfs_bmbt_key_t *prevp, *keyp;
491
492 ASSERT(be16_to_cpu(block->bb_level) > 0);
493
494 prevp = NULL;
495 for( i = 1; i <= xfs_btree_get_numrecs(block); i++) {
496 dmxr = mp->m_bmap_dmxr[0];
497 keyp = XFS_BMBT_KEY_ADDR(mp, block, i);
498
499 if (prevp) {
500 ASSERT(be64_to_cpu(prevp->br_startoff) <
501 be64_to_cpu(keyp->br_startoff));
502 }
503 prevp = keyp;
504
505 /*
506 * Compare the block numbers to see if there are dups.
507 */
508 if (root)
509 pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, i, sz);
510 else
511 pp = XFS_BMBT_PTR_ADDR(mp, block, i, dmxr);
512
513 for (j = i+1; j <= be16_to_cpu(block->bb_numrecs); j++) {
514 if (root)
515 thispa = XFS_BMAP_BROOT_PTR_ADDR(mp, block, j, sz);
516 else
517 thispa = XFS_BMBT_PTR_ADDR(mp, block, j, dmxr);
518 if (*thispa == *pp) {
519 xfs_warn(mp, "%s: thispa(%d) == pp(%d) %Ld",
520 __func__, j, i,
521 (unsigned long long)be64_to_cpu(*thispa));
522 panic("%s: ptrs are equal in node\n",
523 __func__);
524 }
525 }
526 }
527}
528
529/*
530 * Check that the extents for the inode ip are in the right order in all
531 * btree leaves.
532 */
533
534STATIC void
535xfs_bmap_check_leaf_extents(
536 xfs_btree_cur_t *cur, /* btree cursor or null */
537 xfs_inode_t *ip, /* incore inode pointer */
538 int whichfork) /* data or attr fork */
539{
540 struct xfs_btree_block *block; /* current btree block */
541 xfs_fsblock_t bno; /* block # of "block" */
542 xfs_buf_t *bp; /* buffer for "block" */
543 int error; /* error return value */
544 xfs_extnum_t i=0, j; /* index into the extents list */
545 xfs_ifork_t *ifp; /* fork structure */
546 int level; /* btree level, for checking */
547 xfs_mount_t *mp; /* file system mount structure */
548 __be64 *pp; /* pointer to block address */
549 xfs_bmbt_rec_t *ep; /* pointer to current extent */
550 xfs_bmbt_rec_t last = {0, 0}; /* last extent in prev block */
551 xfs_bmbt_rec_t *nextp; /* pointer to next extent */
552 int bp_release = 0;
553
554 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) {
555 return;
556 }
557
558 bno = NULLFSBLOCK;
559 mp = ip->i_mount;
560 ifp = XFS_IFORK_PTR(ip, whichfork);
561 block = ifp->if_broot;
562 /*
563 * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
564 */
565 level = be16_to_cpu(block->bb_level);
566 ASSERT(level > 0);
567 xfs_check_block(block, mp, 1, ifp->if_broot_bytes);
568 pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes);
569 bno = be64_to_cpu(*pp);
570
571 ASSERT(bno != NULLDFSBNO);
572 ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount);
573 ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks);
574
575 /*
576 * Go down the tree until leaf level is reached, following the first
577 * pointer (leftmost) at each level.
578 */
579 while (level-- > 0) {
580 /* See if buf is in cur first */
581 bp_release = 0;
582 bp = xfs_bmap_get_bp(cur, XFS_FSB_TO_DADDR(mp, bno));
583 if (!bp) {
584 bp_release = 1;
585 error = xfs_btree_read_bufl(mp, NULL, bno, 0, &bp,
586 XFS_BMAP_BTREE_REF,
587 &xfs_bmbt_buf_ops);
588 if (error)
589 goto error_norelse;
590 }
591 block = XFS_BUF_TO_BLOCK(bp);
592 XFS_WANT_CORRUPTED_GOTO(
593 xfs_bmap_sanity_check(mp, bp, level),
594 error0);
595 if (level == 0)
596 break;
597
598 /*
599 * Check this block for basic sanity (increasing keys and
600 * no duplicate blocks).
601 */
602
603 xfs_check_block(block, mp, 0, 0);
604 pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]);
605 bno = be64_to_cpu(*pp);
606 XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, bno), error0);
607 if (bp_release) {
608 bp_release = 0;
609 xfs_trans_brelse(NULL, bp);
610 }
611 }
612
613 /*
614 * Here with bp and block set to the leftmost leaf node in the tree.
615 */
616 i = 0;
617
618 /*
619 * Loop over all leaf nodes checking that all extents are in the right order.
620 */
621 for (;;) {
622 xfs_fsblock_t nextbno;
623 xfs_extnum_t num_recs;
624
625
626 num_recs = xfs_btree_get_numrecs(block);
627
628 /*
629 * Read-ahead the next leaf block, if any.
630 */
631
632 nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib);
633
634 /*
635 * Check all the extents to make sure they are OK.
636 * If we had a previous block, the last entry should
637 * conform with the first entry in this one.
638 */
639
640 ep = XFS_BMBT_REC_ADDR(mp, block, 1);
641 if (i) {
642 ASSERT(xfs_bmbt_disk_get_startoff(&last) +
643 xfs_bmbt_disk_get_blockcount(&last) <=
644 xfs_bmbt_disk_get_startoff(ep));
645 }
646 for (j = 1; j < num_recs; j++) {
647 nextp = XFS_BMBT_REC_ADDR(mp, block, j + 1);
648 ASSERT(xfs_bmbt_disk_get_startoff(ep) +
649 xfs_bmbt_disk_get_blockcount(ep) <=
650 xfs_bmbt_disk_get_startoff(nextp));
651 ep = nextp;
652 }
653
654 last = *ep;
655 i += num_recs;
656 if (bp_release) {
657 bp_release = 0;
658 xfs_trans_brelse(NULL, bp);
659 }
660 bno = nextbno;
661 /*
662 * If we've reached the end, stop.
663 */
664 if (bno == NULLFSBLOCK)
665 break;
666
667 bp_release = 0;
668 bp = xfs_bmap_get_bp(cur, XFS_FSB_TO_DADDR(mp, bno));
669 if (!bp) {
670 bp_release = 1;
671 error = xfs_btree_read_bufl(mp, NULL, bno, 0, &bp,
672 XFS_BMAP_BTREE_REF,
673 &xfs_bmbt_buf_ops);
674 if (error)
675 goto error_norelse;
676 }
677 block = XFS_BUF_TO_BLOCK(bp);
678 }
679 if (bp_release) {
680 bp_release = 0;
681 xfs_trans_brelse(NULL, bp);
682 }
683 return;
684
685error0:
686 xfs_warn(mp, "%s: at error0", __func__);
687 if (bp_release)
688 xfs_trans_brelse(NULL, bp);
689error_norelse:
690 xfs_warn(mp, "%s: BAD after btree leaves for %d extents",
691 __func__, i);
692 panic("%s: CORRUPTED BTREE OR SOMETHING", __func__);
693 return;
694}
695
696/*
697 * Add bmap trace insert entries for all the contents of the extent records.
698 */
699void
700xfs_bmap_trace_exlist(
701 xfs_inode_t *ip, /* incore inode pointer */
702 xfs_extnum_t cnt, /* count of entries in the list */
703 int whichfork, /* data or attr fork */
704 unsigned long caller_ip)
705{
706 xfs_extnum_t idx; /* extent record index */
707 xfs_ifork_t *ifp; /* inode fork pointer */
708 int state = 0;
709
710 if (whichfork == XFS_ATTR_FORK)
711 state |= BMAP_ATTRFORK;
712
713 ifp = XFS_IFORK_PTR(ip, whichfork);
714 ASSERT(cnt == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)));
715 for (idx = 0; idx < cnt; idx++)
716 trace_xfs_extlist(ip, idx, whichfork, caller_ip);
717}
718
719/*
720 * Validate that the bmbt_irecs being returned from bmapi are valid
721 * given the callers original parameters. Specifically check the
722 * ranges of the returned irecs to ensure that they only extent beyond
723 * the given parameters if the XFS_BMAPI_ENTIRE flag was set.
724 */
725STATIC void
726xfs_bmap_validate_ret(
727 xfs_fileoff_t bno,
728 xfs_filblks_t len,
729 int flags,
730 xfs_bmbt_irec_t *mval,
731 int nmap,
732 int ret_nmap)
733{
734 int i; /* index to map values */
735
736 ASSERT(ret_nmap <= nmap);
737
738 for (i = 0; i < ret_nmap; i++) {
739 ASSERT(mval[i].br_blockcount > 0);
740 if (!(flags & XFS_BMAPI_ENTIRE)) {
741 ASSERT(mval[i].br_startoff >= bno);
742 ASSERT(mval[i].br_blockcount <= len);
743 ASSERT(mval[i].br_startoff + mval[i].br_blockcount <=
744 bno + len);
745 } else {
746 ASSERT(mval[i].br_startoff < bno + len);
747 ASSERT(mval[i].br_startoff + mval[i].br_blockcount >
748 bno);
749 }
750 ASSERT(i == 0 ||
751 mval[i - 1].br_startoff + mval[i - 1].br_blockcount ==
752 mval[i].br_startoff);
753 ASSERT(mval[i].br_startblock != DELAYSTARTBLOCK &&
754 mval[i].br_startblock != HOLESTARTBLOCK);
755 ASSERT(mval[i].br_state == XFS_EXT_NORM ||
756 mval[i].br_state == XFS_EXT_UNWRITTEN);
757 }
758}
759
760#else
761#define xfs_bmap_check_leaf_extents(cur, ip, whichfork) do { } while (0)
762#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
763#endif /* DEBUG */
764
765/*
766 * bmap free list manipulation functions
767 */
768
769/*
770 * Add the extent to the list of extents to be free at transaction end.
771 * The list is maintained sorted (by block number).
772 */
773void
774xfs_bmap_add_free(
775 xfs_fsblock_t bno, /* fs block number of extent */
776 xfs_filblks_t len, /* length of extent */
777 xfs_bmap_free_t *flist, /* list of extents */
778 xfs_mount_t *mp) /* mount point structure */
779{
780 xfs_bmap_free_item_t *cur; /* current (next) element */
781 xfs_bmap_free_item_t *new; /* new element */
782 xfs_bmap_free_item_t *prev; /* previous element */
783#ifdef DEBUG
784 xfs_agnumber_t agno;
785 xfs_agblock_t agbno;
786
787 ASSERT(bno != NULLFSBLOCK);
788 ASSERT(len > 0);
789 ASSERT(len <= MAXEXTLEN);
790 ASSERT(!isnullstartblock(bno));
791 agno = XFS_FSB_TO_AGNO(mp, bno);
792 agbno = XFS_FSB_TO_AGBNO(mp, bno);
793 ASSERT(agno < mp->m_sb.sb_agcount);
794 ASSERT(agbno < mp->m_sb.sb_agblocks);
795 ASSERT(len < mp->m_sb.sb_agblocks);
796 ASSERT(agbno + len <= mp->m_sb.sb_agblocks);
797#endif
798 ASSERT(xfs_bmap_free_item_zone != NULL);
799 new = kmem_zone_alloc(xfs_bmap_free_item_zone, KM_SLEEP);
800 new->xbfi_startblock = bno;
801 new->xbfi_blockcount = (xfs_extlen_t)len;
802 for (prev = NULL, cur = flist->xbf_first;
803 cur != NULL;
804 prev = cur, cur = cur->xbfi_next) {
805 if (cur->xbfi_startblock >= bno)
806 break;
807 }
808 if (prev)
809 prev->xbfi_next = new;
810 else
811 flist->xbf_first = new;
812 new->xbfi_next = cur;
813 flist->xbf_count++;
814}
815
816/*
817 * Remove the entry "free" from the free item list. Prev points to the
818 * previous entry, unless "free" is the head of the list.
819 */
820STATIC void
821xfs_bmap_del_free(
822 xfs_bmap_free_t *flist, /* free item list header */
823 xfs_bmap_free_item_t *prev, /* previous item on list, if any */
824 xfs_bmap_free_item_t *free) /* list item to be freed */
825{
826 if (prev)
827 prev->xbfi_next = free->xbfi_next;
828 else
829 flist->xbf_first = free->xbfi_next;
830 flist->xbf_count--;
831 kmem_zone_free(xfs_bmap_free_item_zone, free);
832}
833
834
835/*
836 * Routine to be called at transaction's end by xfs_bmapi, xfs_bunmapi
837 * caller. Frees all the extents that need freeing, which must be done
838 * last due to locking considerations. We never free any extents in
839 * the first transaction.
840 *
841 * Return 1 if the given transaction was committed and a new one
842 * started, and 0 otherwise in the committed parameter.
843 */
844int /* error */
845xfs_bmap_finish(
846 xfs_trans_t **tp, /* transaction pointer addr */
847 xfs_bmap_free_t *flist, /* i/o: list extents to free */
848 int *committed) /* xact committed or not */
849{
850 xfs_efd_log_item_t *efd; /* extent free data */
851 xfs_efi_log_item_t *efi; /* extent free intention */
852 int error; /* error return value */
853 xfs_bmap_free_item_t *free; /* free extent item */
854 unsigned int logres; /* new log reservation */
855 unsigned int logcount; /* new log count */
856 xfs_mount_t *mp; /* filesystem mount structure */
857 xfs_bmap_free_item_t *next; /* next item on free list */
858 xfs_trans_t *ntp; /* new transaction pointer */
859
860 ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES);
861 if (flist->xbf_count == 0) {
862 *committed = 0;
863 return 0;
864 }
865 ntp = *tp;
866 efi = xfs_trans_get_efi(ntp, flist->xbf_count);
867 for (free = flist->xbf_first; free; free = free->xbfi_next)
868 xfs_trans_log_efi_extent(ntp, efi, free->xbfi_startblock,
869 free->xbfi_blockcount);
870 logres = ntp->t_log_res;
871 logcount = ntp->t_log_count;
872 ntp = xfs_trans_dup(*tp);
873 error = xfs_trans_commit(*tp, 0);
874 *tp = ntp;
875 *committed = 1;
876 /*
877 * We have a new transaction, so we should return committed=1,
878 * even though we're returning an error.
879 */
880 if (error)
881 return error;
882
883 /*
884 * transaction commit worked ok so we can drop the extra ticket
885 * reference that we gained in xfs_trans_dup()
886 */
887 xfs_log_ticket_put(ntp->t_ticket);
888
889 if ((error = xfs_trans_reserve(ntp, 0, logres, 0, XFS_TRANS_PERM_LOG_RES,
890 logcount)))
891 return error;
892 efd = xfs_trans_get_efd(ntp, efi, flist->xbf_count);
893 for (free = flist->xbf_first; free != NULL; free = next) {
894 next = free->xbfi_next;
895 if ((error = xfs_free_extent(ntp, free->xbfi_startblock,
896 free->xbfi_blockcount))) {
897 /*
898 * The bmap free list will be cleaned up at a
899 * higher level. The EFI will be canceled when
900 * this transaction is aborted.
901 * Need to force shutdown here to make sure it
902 * happens, since this transaction may not be
903 * dirty yet.
904 */
905 mp = ntp->t_mountp;
906 if (!XFS_FORCED_SHUTDOWN(mp))
907 xfs_force_shutdown(mp,
908 (error == EFSCORRUPTED) ?
909 SHUTDOWN_CORRUPT_INCORE :
910 SHUTDOWN_META_IO_ERROR);
911 return error;
912 }
913 xfs_trans_log_efd_extent(ntp, efd, free->xbfi_startblock,
914 free->xbfi_blockcount);
915 xfs_bmap_del_free(flist, NULL, free);
916 }
917 return 0;
918}
919
920/*
921 * Free up any items left in the list.
922 */
923void
924xfs_bmap_cancel(
925 xfs_bmap_free_t *flist) /* list of bmap_free_items */
926{
927 xfs_bmap_free_item_t *free; /* free list item */
928 xfs_bmap_free_item_t *next;
929
930 if (flist->xbf_count == 0)
931 return;
932 ASSERT(flist->xbf_first != NULL);
933 for (free = flist->xbf_first; free; free = next) {
934 next = free->xbfi_next;
935 xfs_bmap_del_free(flist, NULL, free);
936 }
937 ASSERT(flist->xbf_count == 0);
938}
939
940/*
941 * Inode fork format manipulation functions
942 */
943
944/*
945 * Transform a btree format file with only one leaf node, where the
946 * extents list will fit in the inode, into an extents format file.
947 * Since the file extents are already in-core, all we have to do is
948 * give up the space for the btree root and pitch the leaf block.
949 */
950STATIC int /* error */
951xfs_bmap_btree_to_extents(
952 xfs_trans_t *tp, /* transaction pointer */
953 xfs_inode_t *ip, /* incore inode pointer */
954 xfs_btree_cur_t *cur, /* btree cursor */
955 int *logflagsp, /* inode logging flags */
956 int whichfork) /* data or attr fork */
957{
958 /* REFERENCED */
959 struct xfs_btree_block *cblock;/* child btree block */
960 xfs_fsblock_t cbno; /* child block number */
961 xfs_buf_t *cbp; /* child block's buffer */
962 int error; /* error return value */
963 xfs_ifork_t *ifp; /* inode fork data */
964 xfs_mount_t *mp; /* mount point structure */
965 __be64 *pp; /* ptr to block address */
966 struct xfs_btree_block *rblock;/* root btree block */
967
968 mp = ip->i_mount;
969 ifp = XFS_IFORK_PTR(ip, whichfork);
970 ASSERT(ifp->if_flags & XFS_IFEXTENTS);
971 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE);
972 rblock = ifp->if_broot;
973 ASSERT(be16_to_cpu(rblock->bb_level) == 1);
974 ASSERT(be16_to_cpu(rblock->bb_numrecs) == 1);
975 ASSERT(xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0) == 1);
976 pp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, ifp->if_broot_bytes);
977 cbno = be64_to_cpu(*pp);
978 *logflagsp = 0;
979#ifdef DEBUG
980 if ((error = xfs_btree_check_lptr(cur, cbno, 1)))
981 return error;
982#endif
983 error = xfs_btree_read_bufl(mp, tp, cbno, 0, &cbp, XFS_BMAP_BTREE_REF,
984 &xfs_bmbt_buf_ops);
985 if (error)
986 return error;
987 cblock = XFS_BUF_TO_BLOCK(cbp);
988 if ((error = xfs_btree_check_block(cur, cblock, 0, cbp)))
989 return error;
990 xfs_bmap_add_free(cbno, 1, cur->bc_private.b.flist, mp);
991 ip->i_d.di_nblocks--;
992 xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L);
993 xfs_trans_binval(tp, cbp);
994 if (cur->bc_bufs[0] == cbp)
995 cur->bc_bufs[0] = NULL;
996 xfs_iroot_realloc(ip, -1, whichfork);
997 ASSERT(ifp->if_broot == NULL);
998 ASSERT((ifp->if_flags & XFS_IFBROOT) == 0);
999 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS);
1000 *logflagsp = XFS_ILOG_CORE | xfs_ilog_fext(whichfork);
1001 return 0;
1002}
1003
1004/*
1005 * Convert an extents-format file into a btree-format file.
1006 * The new file will have a root block (in the inode) and a single child block.
1007 */
1008STATIC int /* error */
1009xfs_bmap_extents_to_btree(
1010 xfs_trans_t *tp, /* transaction pointer */
1011 xfs_inode_t *ip, /* incore inode pointer */
1012 xfs_fsblock_t *firstblock, /* first-block-allocated */
1013 xfs_bmap_free_t *flist, /* blocks freed in xaction */
1014 xfs_btree_cur_t **curp, /* cursor returned to caller */
1015 int wasdel, /* converting a delayed alloc */
1016 int *logflagsp, /* inode logging flags */
1017 int whichfork) /* data or attr fork */
1018{
1019 struct xfs_btree_block *ablock; /* allocated (child) bt block */
1020 xfs_buf_t *abp; /* buffer for ablock */
1021 xfs_alloc_arg_t args; /* allocation arguments */
1022 xfs_bmbt_rec_t *arp; /* child record pointer */
1023 struct xfs_btree_block *block; /* btree root block */
1024 xfs_btree_cur_t *cur; /* bmap btree cursor */
1025 xfs_bmbt_rec_host_t *ep; /* extent record pointer */
1026 int error; /* error return value */
1027 xfs_extnum_t i, cnt; /* extent record index */
1028 xfs_ifork_t *ifp; /* inode fork pointer */
1029 xfs_bmbt_key_t *kp; /* root block key pointer */
1030 xfs_mount_t *mp; /* mount structure */
1031 xfs_extnum_t nextents; /* number of file extents */
1032 xfs_bmbt_ptr_t *pp; /* root block address pointer */
1033
1034 ifp = XFS_IFORK_PTR(ip, whichfork);
1035 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS);
1036
1037 /*
1038 * Make space in the inode incore.
1039 */
1040 xfs_iroot_realloc(ip, 1, whichfork);
1041 ifp->if_flags |= XFS_IFBROOT;
1042
1043 /*
1044 * Fill in the root.
1045 */
1046 block = ifp->if_broot;
1047 block->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC);
1048 block->bb_level = cpu_to_be16(1);
1049 block->bb_numrecs = cpu_to_be16(1);
1050 block->bb_u.l.bb_leftsib = cpu_to_be64(NULLDFSBNO);
1051 block->bb_u.l.bb_rightsib = cpu_to_be64(NULLDFSBNO);
1052
1053 /*
1054 * Need a cursor. Can't allocate until bb_level is filled in.
1055 */
1056 mp = ip->i_mount;
1057 cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
1058 cur->bc_private.b.firstblock = *firstblock;
1059 cur->bc_private.b.flist = flist;
1060 cur->bc_private.b.flags = wasdel ? XFS_BTCUR_BPRV_WASDEL : 0;
1061 /*
1062 * Convert to a btree with two levels, one record in root.
1063 */
1064 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE);
1065 memset(&args, 0, sizeof(args));
1066 args.tp = tp;
1067 args.mp = mp;
1068 args.firstblock = *firstblock;
1069 if (*firstblock == NULLFSBLOCK) {
1070 args.type = XFS_ALLOCTYPE_START_BNO;
1071 args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino);
1072 } else if (flist->xbf_low) {
1073 args.type = XFS_ALLOCTYPE_START_BNO;
1074 args.fsbno = *firstblock;
1075 } else {
1076 args.type = XFS_ALLOCTYPE_NEAR_BNO;
1077 args.fsbno = *firstblock;
1078 }
1079 args.minlen = args.maxlen = args.prod = 1;
1080 args.wasdel = wasdel;
1081 *logflagsp = 0;
1082 if ((error = xfs_alloc_vextent(&args))) {
1083 xfs_iroot_realloc(ip, -1, whichfork);
1084 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
1085 return error;
1086 }
1087 /*
1088 * Allocation can't fail, the space was reserved.
1089 */
1090 ASSERT(args.fsbno != NULLFSBLOCK);
1091 ASSERT(*firstblock == NULLFSBLOCK ||
1092 args.agno == XFS_FSB_TO_AGNO(mp, *firstblock) ||
1093 (flist->xbf_low &&
1094 args.agno > XFS_FSB_TO_AGNO(mp, *firstblock)));
1095 *firstblock = cur->bc_private.b.firstblock = args.fsbno;
1096 cur->bc_private.b.allocated++;
1097 ip->i_d.di_nblocks++;
1098 xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L);
1099 abp = xfs_btree_get_bufl(mp, tp, args.fsbno, 0);
1100 /*
1101 * Fill in the child block.
1102 */
1103 abp->b_ops = &xfs_bmbt_buf_ops;
1104 ablock = XFS_BUF_TO_BLOCK(abp);
1105 ablock->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC);
1106 ablock->bb_level = 0;
1107 ablock->bb_u.l.bb_leftsib = cpu_to_be64(NULLDFSBNO);
1108 ablock->bb_u.l.bb_rightsib = cpu_to_be64(NULLDFSBNO);
1109 arp = XFS_BMBT_REC_ADDR(mp, ablock, 1);
1110 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
1111 for (cnt = i = 0; i < nextents; i++) {
1112 ep = xfs_iext_get_ext(ifp, i);
1113 if (!isnullstartblock(xfs_bmbt_get_startblock(ep))) {
1114 arp->l0 = cpu_to_be64(ep->l0);
1115 arp->l1 = cpu_to_be64(ep->l1);
1116 arp++; cnt++;
1117 }
1118 }
1119 ASSERT(cnt == XFS_IFORK_NEXTENTS(ip, whichfork));
1120 xfs_btree_set_numrecs(ablock, cnt);
1121
1122 /*
1123 * Fill in the root key and pointer.
1124 */
1125 kp = XFS_BMBT_KEY_ADDR(mp, block, 1);
1126 arp = XFS_BMBT_REC_ADDR(mp, ablock, 1);
1127 kp->br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(arp));
1128 pp = XFS_BMBT_PTR_ADDR(mp, block, 1, xfs_bmbt_get_maxrecs(cur,
1129 be16_to_cpu(block->bb_level)));
1130 *pp = cpu_to_be64(args.fsbno);
1131
1132 /*
1133 * Do all this logging at the end so that
1134 * the root is at the right level.
1135 */
1136 xfs_btree_log_block(cur, abp, XFS_BB_ALL_BITS);
1137 xfs_btree_log_recs(cur, abp, 1, be16_to_cpu(ablock->bb_numrecs));
1138 ASSERT(*curp == NULL);
1139 *curp = cur;
1140 *logflagsp = XFS_ILOG_CORE | xfs_ilog_fbroot(whichfork);
1141 return 0;
1142}
1143
1144/*
1145 * Convert a local file to an extents file.
1146 * This code is out of bounds for data forks of regular files,
1147 * since the file data needs to get logged so things will stay consistent.
1148 * (The bmap-level manipulations are ok, though).
1149 */
1150STATIC int /* error */
1151xfs_bmap_local_to_extents(
1152 xfs_trans_t *tp, /* transaction pointer */
1153 xfs_inode_t *ip, /* incore inode pointer */
1154 xfs_fsblock_t *firstblock, /* first block allocated in xaction */
1155 xfs_extlen_t total, /* total blocks needed by transaction */
1156 int *logflagsp, /* inode logging flags */
1157 int whichfork,
1158 void (*init_fn)(struct xfs_buf *bp,
1159 struct xfs_inode *ip,
1160 struct xfs_ifork *ifp))
1161{
1162 int error; /* error return value */
1163 int flags; /* logging flags returned */
1164 xfs_ifork_t *ifp; /* inode fork pointer */
1165
1166 /*
1167 * We don't want to deal with the case of keeping inode data inline yet.
1168 * So sending the data fork of a regular inode is invalid.
1169 */
1170 ASSERT(!(S_ISREG(ip->i_d.di_mode) && whichfork == XFS_DATA_FORK));
1171 ifp = XFS_IFORK_PTR(ip, whichfork);
1172 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL);
1173 flags = 0;
1174 error = 0;
1175 if (ifp->if_bytes) {
1176 xfs_alloc_arg_t args; /* allocation arguments */
1177 xfs_buf_t *bp; /* buffer for extent block */
1178 xfs_bmbt_rec_host_t *ep;/* extent record pointer */
1179
1180 ASSERT((ifp->if_flags &
1181 (XFS_IFINLINE|XFS_IFEXTENTS|XFS_IFEXTIREC)) == XFS_IFINLINE);
1182 memset(&args, 0, sizeof(args));
1183 args.tp = tp;
1184 args.mp = ip->i_mount;
1185 args.firstblock = *firstblock;
1186 /*
1187 * Allocate a block. We know we need only one, since the
1188 * file currently fits in an inode.
1189 */
1190 if (*firstblock == NULLFSBLOCK) {
1191 args.fsbno = XFS_INO_TO_FSB(args.mp, ip->i_ino);
1192 args.type = XFS_ALLOCTYPE_START_BNO;
1193 } else {
1194 args.fsbno = *firstblock;
1195 args.type = XFS_ALLOCTYPE_NEAR_BNO;
1196 }
1197 args.total = total;
1198 args.minlen = args.maxlen = args.prod = 1;
1199 error = xfs_alloc_vextent(&args);
1200 if (error)
1201 goto done;
1202
1203 /* Can't fail, the space was reserved. */
1204 ASSERT(args.fsbno != NULLFSBLOCK);
1205 ASSERT(args.len == 1);
1206 *firstblock = args.fsbno;
1207 bp = xfs_btree_get_bufl(args.mp, tp, args.fsbno, 0);
1208
1209 /* initialise the block and copy the data */
1210 init_fn(bp, ip, ifp);
1211
1212 /* account for the change in fork size and log everything */
1213 xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1);
1214 xfs_bmap_forkoff_reset(args.mp, ip, whichfork);
1215 xfs_idata_realloc(ip, -ifp->if_bytes, whichfork);
1216 xfs_iext_add(ifp, 0, 1);
1217 ep = xfs_iext_get_ext(ifp, 0);
1218 xfs_bmbt_set_allf(ep, 0, args.fsbno, 1, XFS_EXT_NORM);
1219 trace_xfs_bmap_post_update(ip, 0,
1220 whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0,
1221 _THIS_IP_);
1222 XFS_IFORK_NEXT_SET(ip, whichfork, 1);
1223 ip->i_d.di_nblocks = 1;
1224 xfs_trans_mod_dquot_byino(tp, ip,
1225 XFS_TRANS_DQ_BCOUNT, 1L);
1226 flags |= xfs_ilog_fext(whichfork);
1227 } else {
1228 ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) == 0);
1229 xfs_bmap_forkoff_reset(ip->i_mount, ip, whichfork);
1230 }
1231 ifp->if_flags &= ~XFS_IFINLINE;
1232 ifp->if_flags |= XFS_IFEXTENTS;
1233 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS);
1234 flags |= XFS_ILOG_CORE;
1235done:
1236 *logflagsp = flags;
1237 return error;
1238}
1239
1240/*
293 * Called from xfs_bmap_add_attrfork to handle btree format files. 1241 * Called from xfs_bmap_add_attrfork to handle btree format files.
294 */ 1242 */
295STATIC int /* error */ 1243STATIC int /* error */
@@ -432,6 +1380,640 @@ xfs_bmap_add_attrfork_local(
432} 1380}
433 1381
434/* 1382/*
1383 * Convert inode from non-attributed to attributed.
1384 * Must not be in a transaction, ip must not be locked.
1385 */
1386int /* error code */
1387xfs_bmap_add_attrfork(
1388 xfs_inode_t *ip, /* incore inode pointer */
1389 int size, /* space new attribute needs */
1390 int rsvd) /* xact may use reserved blks */
1391{
1392 xfs_fsblock_t firstblock; /* 1st block/ag allocated */
1393 xfs_bmap_free_t flist; /* freed extent records */
1394 xfs_mount_t *mp; /* mount structure */
1395 xfs_trans_t *tp; /* transaction pointer */
1396 int blks; /* space reservation */
1397 int version = 1; /* superblock attr version */
1398 int committed; /* xaction was committed */
1399 int logflags; /* logging flags */
1400 int error; /* error return value */
1401
1402 ASSERT(XFS_IFORK_Q(ip) == 0);
1403
1404 mp = ip->i_mount;
1405 ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
1406 tp = xfs_trans_alloc(mp, XFS_TRANS_ADDAFORK);
1407 blks = XFS_ADDAFORK_SPACE_RES(mp);
1408 if (rsvd)
1409 tp->t_flags |= XFS_TRANS_RESERVE;
1410 if ((error = xfs_trans_reserve(tp, blks, XFS_ADDAFORK_LOG_RES(mp), 0,
1411 XFS_TRANS_PERM_LOG_RES, XFS_ADDAFORK_LOG_COUNT)))
1412 goto error0;
1413 xfs_ilock(ip, XFS_ILOCK_EXCL);
1414 error = xfs_trans_reserve_quota_nblks(tp, ip, blks, 0, rsvd ?
1415 XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES :
1416 XFS_QMOPT_RES_REGBLKS);
1417 if (error) {
1418 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1419 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES);
1420 return error;
1421 }
1422 if (XFS_IFORK_Q(ip))
1423 goto error1;
1424 if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS) {
1425 /*
1426 * For inodes coming from pre-6.2 filesystems.
1427 */
1428 ASSERT(ip->i_d.di_aformat == 0);
1429 ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
1430 }
1431 ASSERT(ip->i_d.di_anextents == 0);
1432
1433 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
1434 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1435
1436 switch (ip->i_d.di_format) {
1437 case XFS_DINODE_FMT_DEV:
1438 ip->i_d.di_forkoff = roundup(sizeof(xfs_dev_t), 8) >> 3;
1439 break;
1440 case XFS_DINODE_FMT_UUID:
1441 ip->i_d.di_forkoff = roundup(sizeof(uuid_t), 8) >> 3;
1442 break;
1443 case XFS_DINODE_FMT_LOCAL:
1444 case XFS_DINODE_FMT_EXTENTS:
1445 case XFS_DINODE_FMT_BTREE:
1446 ip->i_d.di_forkoff = xfs_attr_shortform_bytesfit(ip, size);
1447 if (!ip->i_d.di_forkoff)
1448 ip->i_d.di_forkoff = xfs_default_attroffset(ip) >> 3;
1449 else if (mp->m_flags & XFS_MOUNT_ATTR2)
1450 version = 2;
1451 break;
1452 default:
1453 ASSERT(0);
1454 error = XFS_ERROR(EINVAL);
1455 goto error1;
1456 }
1457
1458 ASSERT(ip->i_afp == NULL);
1459 ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP);
1460 ip->i_afp->if_flags = XFS_IFEXTENTS;
1461 logflags = 0;
1462 xfs_bmap_init(&flist, &firstblock);
1463 switch (ip->i_d.di_format) {
1464 case XFS_DINODE_FMT_LOCAL:
1465 error = xfs_bmap_add_attrfork_local(tp, ip, &firstblock, &flist,
1466 &logflags);
1467 break;
1468 case XFS_DINODE_FMT_EXTENTS:
1469 error = xfs_bmap_add_attrfork_extents(tp, ip, &firstblock,
1470 &flist, &logflags);
1471 break;
1472 case XFS_DINODE_FMT_BTREE:
1473 error = xfs_bmap_add_attrfork_btree(tp, ip, &firstblock, &flist,
1474 &logflags);
1475 break;
1476 default:
1477 error = 0;
1478 break;
1479 }
1480 if (logflags)
1481 xfs_trans_log_inode(tp, ip, logflags);
1482 if (error)
1483 goto error2;
1484 if (!xfs_sb_version_hasattr(&mp->m_sb) ||
1485 (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2)) {
1486 __int64_t sbfields = 0;
1487
1488 spin_lock(&mp->m_sb_lock);
1489 if (!xfs_sb_version_hasattr(&mp->m_sb)) {
1490 xfs_sb_version_addattr(&mp->m_sb);
1491 sbfields |= XFS_SB_VERSIONNUM;
1492 }
1493 if (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2) {
1494 xfs_sb_version_addattr2(&mp->m_sb);
1495 sbfields |= (XFS_SB_VERSIONNUM | XFS_SB_FEATURES2);
1496 }
1497 if (sbfields) {
1498 spin_unlock(&mp->m_sb_lock);
1499 xfs_mod_sb(tp, sbfields);
1500 } else
1501 spin_unlock(&mp->m_sb_lock);
1502 }
1503
1504 error = xfs_bmap_finish(&tp, &flist, &committed);
1505 if (error)
1506 goto error2;
1507 return xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
1508error2:
1509 xfs_bmap_cancel(&flist);
1510error1:
1511 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1512error0:
1513 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
1514 return error;
1515}
1516
1517/*
1518 * Internal and external extent tree search functions.
1519 */
1520
1521/*
1522 * Read in the extents to if_extents.
1523 * All inode fields are set up by caller, we just traverse the btree
1524 * and copy the records in. If the file system cannot contain unwritten
1525 * extents, the records are checked for no "state" flags.
1526 */
1527int /* error */
1528xfs_bmap_read_extents(
1529 xfs_trans_t *tp, /* transaction pointer */
1530 xfs_inode_t *ip, /* incore inode */
1531 int whichfork) /* data or attr fork */
1532{
1533 struct xfs_btree_block *block; /* current btree block */
1534 xfs_fsblock_t bno; /* block # of "block" */
1535 xfs_buf_t *bp; /* buffer for "block" */
1536 int error; /* error return value */
1537 xfs_exntfmt_t exntf; /* XFS_EXTFMT_NOSTATE, if checking */
1538 xfs_extnum_t i, j; /* index into the extents list */
1539 xfs_ifork_t *ifp; /* fork structure */
1540 int level; /* btree level, for checking */
1541 xfs_mount_t *mp; /* file system mount structure */
1542 __be64 *pp; /* pointer to block address */
1543 /* REFERENCED */
1544 xfs_extnum_t room; /* number of entries there's room for */
1545
1546 bno = NULLFSBLOCK;
1547 mp = ip->i_mount;
1548 ifp = XFS_IFORK_PTR(ip, whichfork);
1549 exntf = (whichfork != XFS_DATA_FORK) ? XFS_EXTFMT_NOSTATE :
1550 XFS_EXTFMT_INODE(ip);
1551 block = ifp->if_broot;
1552 /*
1553 * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
1554 */
1555 level = be16_to_cpu(block->bb_level);
1556 ASSERT(level > 0);
1557 pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes);
1558 bno = be64_to_cpu(*pp);
1559 ASSERT(bno != NULLDFSBNO);
1560 ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount);
1561 ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks);
1562 /*
1563 * Go down the tree until leaf level is reached, following the first
1564 * pointer (leftmost) at each level.
1565 */
1566 while (level-- > 0) {
1567 error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp,
1568 XFS_BMAP_BTREE_REF, &xfs_bmbt_buf_ops);
1569 if (error)
1570 return error;
1571 block = XFS_BUF_TO_BLOCK(bp);
1572 XFS_WANT_CORRUPTED_GOTO(
1573 xfs_bmap_sanity_check(mp, bp, level),
1574 error0);
1575 if (level == 0)
1576 break;
1577 pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]);
1578 bno = be64_to_cpu(*pp);
1579 XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, bno), error0);
1580 xfs_trans_brelse(tp, bp);
1581 }
1582 /*
1583 * Here with bp and block set to the leftmost leaf node in the tree.
1584 */
1585 room = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
1586 i = 0;
1587 /*
1588 * Loop over all leaf nodes. Copy information to the extent records.
1589 */
1590 for (;;) {
1591 xfs_bmbt_rec_t *frp;
1592 xfs_fsblock_t nextbno;
1593 xfs_extnum_t num_recs;
1594 xfs_extnum_t start;
1595
1596 num_recs = xfs_btree_get_numrecs(block);
1597 if (unlikely(i + num_recs > room)) {
1598 ASSERT(i + num_recs <= room);
1599 xfs_warn(ip->i_mount,
1600 "corrupt dinode %Lu, (btree extents).",
1601 (unsigned long long) ip->i_ino);
1602 XFS_CORRUPTION_ERROR("xfs_bmap_read_extents(1)",
1603 XFS_ERRLEVEL_LOW, ip->i_mount, block);
1604 goto error0;
1605 }
1606 XFS_WANT_CORRUPTED_GOTO(
1607 xfs_bmap_sanity_check(mp, bp, 0),
1608 error0);
1609 /*
1610 * Read-ahead the next leaf block, if any.
1611 */
1612 nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib);
1613 if (nextbno != NULLFSBLOCK)
1614 xfs_btree_reada_bufl(mp, nextbno, 1,
1615 &xfs_bmbt_buf_ops);
1616 /*
1617 * Copy records into the extent records.
1618 */
1619 frp = XFS_BMBT_REC_ADDR(mp, block, 1);
1620 start = i;
1621 for (j = 0; j < num_recs; j++, i++, frp++) {
1622 xfs_bmbt_rec_host_t *trp = xfs_iext_get_ext(ifp, i);
1623 trp->l0 = be64_to_cpu(frp->l0);
1624 trp->l1 = be64_to_cpu(frp->l1);
1625 }
1626 if (exntf == XFS_EXTFMT_NOSTATE) {
1627 /*
1628 * Check all attribute bmap btree records and
1629 * any "older" data bmap btree records for a
1630 * set bit in the "extent flag" position.
1631 */
1632 if (unlikely(xfs_check_nostate_extents(ifp,
1633 start, num_recs))) {
1634 XFS_ERROR_REPORT("xfs_bmap_read_extents(2)",
1635 XFS_ERRLEVEL_LOW,
1636 ip->i_mount);
1637 goto error0;
1638 }
1639 }
1640 xfs_trans_brelse(tp, bp);
1641 bno = nextbno;
1642 /*
1643 * If we've reached the end, stop.
1644 */
1645 if (bno == NULLFSBLOCK)
1646 break;
1647 error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp,
1648 XFS_BMAP_BTREE_REF, &xfs_bmbt_buf_ops);
1649 if (error)
1650 return error;
1651 block = XFS_BUF_TO_BLOCK(bp);
1652 }
1653 ASSERT(i == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)));
1654 ASSERT(i == XFS_IFORK_NEXTENTS(ip, whichfork));
1655 XFS_BMAP_TRACE_EXLIST(ip, i, whichfork);
1656 return 0;
1657error0:
1658 xfs_trans_brelse(tp, bp);
1659 return XFS_ERROR(EFSCORRUPTED);
1660}
1661
1662
1663/*
1664 * Search the extent records for the entry containing block bno.
1665 * If bno lies in a hole, point to the next entry. If bno lies
1666 * past eof, *eofp will be set, and *prevp will contain the last
1667 * entry (null if none). Else, *lastxp will be set to the index
1668 * of the found entry; *gotp will contain the entry.
1669 */
1670STATIC xfs_bmbt_rec_host_t * /* pointer to found extent entry */
1671xfs_bmap_search_multi_extents(
1672 xfs_ifork_t *ifp, /* inode fork pointer */
1673 xfs_fileoff_t bno, /* block number searched for */
1674 int *eofp, /* out: end of file found */
1675 xfs_extnum_t *lastxp, /* out: last extent index */
1676 xfs_bmbt_irec_t *gotp, /* out: extent entry found */
1677 xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */
1678{
1679 xfs_bmbt_rec_host_t *ep; /* extent record pointer */
1680 xfs_extnum_t lastx; /* last extent index */
1681
1682 /*
1683 * Initialize the extent entry structure to catch access to
1684 * uninitialized br_startblock field.
1685 */
1686 gotp->br_startoff = 0xffa5a5a5a5a5a5a5LL;
1687 gotp->br_blockcount = 0xa55a5a5a5a5a5a5aLL;
1688 gotp->br_state = XFS_EXT_INVALID;
1689#if XFS_BIG_BLKNOS
1690 gotp->br_startblock = 0xffffa5a5a5a5a5a5LL;
1691#else
1692 gotp->br_startblock = 0xffffa5a5;
1693#endif
1694 prevp->br_startoff = NULLFILEOFF;
1695
1696 ep = xfs_iext_bno_to_ext(ifp, bno, &lastx);
1697 if (lastx > 0) {
1698 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx - 1), prevp);
1699 }
1700 if (lastx < (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))) {
1701 xfs_bmbt_get_all(ep, gotp);
1702 *eofp = 0;
1703 } else {
1704 if (lastx > 0) {
1705 *gotp = *prevp;
1706 }
1707 *eofp = 1;
1708 ep = NULL;
1709 }
1710 *lastxp = lastx;
1711 return ep;
1712}
1713
1714/*
1715 * Search the extents list for the inode, for the extent containing bno.
1716 * If bno lies in a hole, point to the next entry. If bno lies past eof,
1717 * *eofp will be set, and *prevp will contain the last entry (null if none).
1718 * Else, *lastxp will be set to the index of the found
1719 * entry; *gotp will contain the entry.
1720 */
1721STATIC xfs_bmbt_rec_host_t * /* pointer to found extent entry */
1722xfs_bmap_search_extents(
1723 xfs_inode_t *ip, /* incore inode pointer */
1724 xfs_fileoff_t bno, /* block number searched for */
1725 int fork, /* data or attr fork */
1726 int *eofp, /* out: end of file found */
1727 xfs_extnum_t *lastxp, /* out: last extent index */
1728 xfs_bmbt_irec_t *gotp, /* out: extent entry found */
1729 xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */
1730{
1731 xfs_ifork_t *ifp; /* inode fork pointer */
1732 xfs_bmbt_rec_host_t *ep; /* extent record pointer */
1733
1734 XFS_STATS_INC(xs_look_exlist);
1735 ifp = XFS_IFORK_PTR(ip, fork);
1736
1737 ep = xfs_bmap_search_multi_extents(ifp, bno, eofp, lastxp, gotp, prevp);
1738
1739 if (unlikely(!(gotp->br_startblock) && (*lastxp != NULLEXTNUM) &&
1740 !(XFS_IS_REALTIME_INODE(ip) && fork == XFS_DATA_FORK))) {
1741 xfs_alert_tag(ip->i_mount, XFS_PTAG_FSBLOCK_ZERO,
1742 "Access to block zero in inode %llu "
1743 "start_block: %llx start_off: %llx "
1744 "blkcnt: %llx extent-state: %x lastx: %x\n",
1745 (unsigned long long)ip->i_ino,
1746 (unsigned long long)gotp->br_startblock,
1747 (unsigned long long)gotp->br_startoff,
1748 (unsigned long long)gotp->br_blockcount,
1749 gotp->br_state, *lastxp);
1750 *lastxp = NULLEXTNUM;
1751 *eofp = 1;
1752 return NULL;
1753 }
1754 return ep;
1755}
1756
1757/*
1758 * Returns the file-relative block number of the first unused block(s)
1759 * in the file with at least "len" logically contiguous blocks free.
1760 * This is the lowest-address hole if the file has holes, else the first block
1761 * past the end of file.
1762 * Return 0 if the file is currently local (in-inode).
1763 */
1764int /* error */
1765xfs_bmap_first_unused(
1766 xfs_trans_t *tp, /* transaction pointer */
1767 xfs_inode_t *ip, /* incore inode */
1768 xfs_extlen_t len, /* size of hole to find */
1769 xfs_fileoff_t *first_unused, /* unused block */
1770 int whichfork) /* data or attr fork */
1771{
1772 int error; /* error return value */
1773 int idx; /* extent record index */
1774 xfs_ifork_t *ifp; /* inode fork pointer */
1775 xfs_fileoff_t lastaddr; /* last block number seen */
1776 xfs_fileoff_t lowest; /* lowest useful block */
1777 xfs_fileoff_t max; /* starting useful block */
1778 xfs_fileoff_t off; /* offset for this block */
1779 xfs_extnum_t nextents; /* number of extent entries */
1780
1781 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE ||
1782 XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS ||
1783 XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL);
1784 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) {
1785 *first_unused = 0;
1786 return 0;
1787 }
1788 ifp = XFS_IFORK_PTR(ip, whichfork);
1789 if (!(ifp->if_flags & XFS_IFEXTENTS) &&
1790 (error = xfs_iread_extents(tp, ip, whichfork)))
1791 return error;
1792 lowest = *first_unused;
1793 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
1794 for (idx = 0, lastaddr = 0, max = lowest; idx < nextents; idx++) {
1795 xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, idx);
1796 off = xfs_bmbt_get_startoff(ep);
1797 /*
1798 * See if the hole before this extent will work.
1799 */
1800 if (off >= lowest + len && off - max >= len) {
1801 *first_unused = max;
1802 return 0;
1803 }
1804 lastaddr = off + xfs_bmbt_get_blockcount(ep);
1805 max = XFS_FILEOFF_MAX(lastaddr, lowest);
1806 }
1807 *first_unused = max;
1808 return 0;
1809}
1810
1811/*
1812 * Returns the file-relative block number of the last block + 1 before
1813 * last_block (input value) in the file.
1814 * This is not based on i_size, it is based on the extent records.
1815 * Returns 0 for local files, as they do not have extent records.
1816 */
1817int /* error */
1818xfs_bmap_last_before(
1819 xfs_trans_t *tp, /* transaction pointer */
1820 xfs_inode_t *ip, /* incore inode */
1821 xfs_fileoff_t *last_block, /* last block */
1822 int whichfork) /* data or attr fork */
1823{
1824 xfs_fileoff_t bno; /* input file offset */
1825 int eof; /* hit end of file */
1826 xfs_bmbt_rec_host_t *ep; /* pointer to last extent */
1827 int error; /* error return value */
1828 xfs_bmbt_irec_t got; /* current extent value */
1829 xfs_ifork_t *ifp; /* inode fork pointer */
1830 xfs_extnum_t lastx; /* last extent used */
1831 xfs_bmbt_irec_t prev; /* previous extent value */
1832
1833 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
1834 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
1835 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL)
1836 return XFS_ERROR(EIO);
1837 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) {
1838 *last_block = 0;
1839 return 0;
1840 }
1841 ifp = XFS_IFORK_PTR(ip, whichfork);
1842 if (!(ifp->if_flags & XFS_IFEXTENTS) &&
1843 (error = xfs_iread_extents(tp, ip, whichfork)))
1844 return error;
1845 bno = *last_block - 1;
1846 ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got,
1847 &prev);
1848 if (eof || xfs_bmbt_get_startoff(ep) > bno) {
1849 if (prev.br_startoff == NULLFILEOFF)
1850 *last_block = 0;
1851 else
1852 *last_block = prev.br_startoff + prev.br_blockcount;
1853 }
1854 /*
1855 * Otherwise *last_block is already the right answer.
1856 */
1857 return 0;
1858}
1859
1860STATIC int
1861xfs_bmap_last_extent(
1862 struct xfs_trans *tp,
1863 struct xfs_inode *ip,
1864 int whichfork,
1865 struct xfs_bmbt_irec *rec,
1866 int *is_empty)
1867{
1868 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
1869 int error;
1870 int nextents;
1871
1872 if (!(ifp->if_flags & XFS_IFEXTENTS)) {
1873 error = xfs_iread_extents(tp, ip, whichfork);
1874 if (error)
1875 return error;
1876 }
1877
1878 nextents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t);
1879 if (nextents == 0) {
1880 *is_empty = 1;
1881 return 0;
1882 }
1883
1884 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, nextents - 1), rec);
1885 *is_empty = 0;
1886 return 0;
1887}
1888
1889/*
1890 * Check the last inode extent to determine whether this allocation will result
1891 * in blocks being allocated at the end of the file. When we allocate new data
1892 * blocks at the end of the file which do not start at the previous data block,
1893 * we will try to align the new blocks at stripe unit boundaries.
1894 *
1895 * Returns 0 in bma->aeof if the file (fork) is empty as any new write will be
1896 * at, or past the EOF.
1897 */
1898STATIC int
1899xfs_bmap_isaeof(
1900 struct xfs_bmalloca *bma,
1901 int whichfork)
1902{
1903 struct xfs_bmbt_irec rec;
1904 int is_empty;
1905 int error;
1906
1907 bma->aeof = 0;
1908 error = xfs_bmap_last_extent(NULL, bma->ip, whichfork, &rec,
1909 &is_empty);
1910 if (error || is_empty)
1911 return error;
1912
1913 /*
1914 * Check if we are allocation or past the last extent, or at least into
1915 * the last delayed allocated extent.
1916 */
1917 bma->aeof = bma->offset >= rec.br_startoff + rec.br_blockcount ||
1918 (bma->offset >= rec.br_startoff &&
1919 isnullstartblock(rec.br_startblock));
1920 return 0;
1921}
1922
1923/*
1924 * Check if the endoff is outside the last extent. If so the caller will grow
1925 * the allocation to a stripe unit boundary. All offsets are considered outside
1926 * the end of file for an empty fork, so 1 is returned in *eof in that case.
1927 */
1928int
1929xfs_bmap_eof(
1930 struct xfs_inode *ip,
1931 xfs_fileoff_t endoff,
1932 int whichfork,
1933 int *eof)
1934{
1935 struct xfs_bmbt_irec rec;
1936 int error;
1937
1938 error = xfs_bmap_last_extent(NULL, ip, whichfork, &rec, eof);
1939 if (error || *eof)
1940 return error;
1941
1942 *eof = endoff >= rec.br_startoff + rec.br_blockcount;
1943 return 0;
1944}
1945
1946/*
1947 * Returns the file-relative block number of the first block past eof in
1948 * the file. This is not based on i_size, it is based on the extent records.
1949 * Returns 0 for local files, as they do not have extent records.
1950 */
1951int
1952xfs_bmap_last_offset(
1953 struct xfs_trans *tp,
1954 struct xfs_inode *ip,
1955 xfs_fileoff_t *last_block,
1956 int whichfork)
1957{
1958 struct xfs_bmbt_irec rec;
1959 int is_empty;
1960 int error;
1961
1962 *last_block = 0;
1963
1964 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL)
1965 return 0;
1966
1967 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
1968 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)
1969 return XFS_ERROR(EIO);
1970
1971 error = xfs_bmap_last_extent(NULL, ip, whichfork, &rec, &is_empty);
1972 if (error || is_empty)
1973 return error;
1974
1975 *last_block = rec.br_startoff + rec.br_blockcount;
1976 return 0;
1977}
1978
1979/*
1980 * Returns whether the selected fork of the inode has exactly one
1981 * block or not. For the data fork we check this matches di_size,
1982 * implying the file's range is 0..bsize-1.
1983 */
1984int /* 1=>1 block, 0=>otherwise */
1985xfs_bmap_one_block(
1986 xfs_inode_t *ip, /* incore inode */
1987 int whichfork) /* data or attr fork */
1988{
1989 xfs_bmbt_rec_host_t *ep; /* ptr to fork's extent */
1990 xfs_ifork_t *ifp; /* inode fork pointer */
1991 int rval; /* return value */
1992 xfs_bmbt_irec_t s; /* internal version of extent */
1993
1994#ifndef DEBUG
1995 if (whichfork == XFS_DATA_FORK)
1996 return XFS_ISIZE(ip) == ip->i_mount->m_sb.sb_blocksize;
1997#endif /* !DEBUG */
1998 if (XFS_IFORK_NEXTENTS(ip, whichfork) != 1)
1999 return 0;
2000 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)
2001 return 0;
2002 ifp = XFS_IFORK_PTR(ip, whichfork);
2003 ASSERT(ifp->if_flags & XFS_IFEXTENTS);
2004 ep = xfs_iext_get_ext(ifp, 0);
2005 xfs_bmbt_get_all(ep, &s);
2006 rval = s.br_startoff == 0 && s.br_blockcount == 1;
2007 if (rval && whichfork == XFS_DATA_FORK)
2008 ASSERT(XFS_ISIZE(ip) == ip->i_mount->m_sb.sb_blocksize);
2009 return rval;
2010}
2011
2012/*
2013 * Extent tree manipulation functions used during allocation.
2014 */
2015
2016/*
435 * Convert a delayed allocation to a real allocation. 2017 * Convert a delayed allocation to a real allocation.
436 */ 2018 */
437STATIC int /* error */ 2019STATIC int /* error */
@@ -1894,6 +3476,10 @@ done:
1894} 3476}
1895 3477
1896/* 3478/*
3479 * Functions used in the extent read, allocate and remove paths
3480 */
3481
3482/*
1897 * Adjust the size of the new extent based on di_extsize and rt extsize. 3483 * Adjust the size of the new extent based on di_extsize and rt extsize.
1898 */ 3484 */
1899STATIC int 3485STATIC int
@@ -2666,1628 +4252,6 @@ xfs_bmap_alloc(
2666} 4252}
2667 4253
2668/* 4254/*
2669 * Transform a btree format file with only one leaf node, where the
2670 * extents list will fit in the inode, into an extents format file.
2671 * Since the file extents are already in-core, all we have to do is
2672 * give up the space for the btree root and pitch the leaf block.
2673 */
2674STATIC int /* error */
2675xfs_bmap_btree_to_extents(
2676 xfs_trans_t *tp, /* transaction pointer */
2677 xfs_inode_t *ip, /* incore inode pointer */
2678 xfs_btree_cur_t *cur, /* btree cursor */
2679 int *logflagsp, /* inode logging flags */
2680 int whichfork) /* data or attr fork */
2681{
2682 /* REFERENCED */
2683 struct xfs_btree_block *cblock;/* child btree block */
2684 xfs_fsblock_t cbno; /* child block number */
2685 xfs_buf_t *cbp; /* child block's buffer */
2686 int error; /* error return value */
2687 xfs_ifork_t *ifp; /* inode fork data */
2688 xfs_mount_t *mp; /* mount point structure */
2689 __be64 *pp; /* ptr to block address */
2690 struct xfs_btree_block *rblock;/* root btree block */
2691
2692 mp = ip->i_mount;
2693 ifp = XFS_IFORK_PTR(ip, whichfork);
2694 ASSERT(ifp->if_flags & XFS_IFEXTENTS);
2695 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE);
2696 rblock = ifp->if_broot;
2697 ASSERT(be16_to_cpu(rblock->bb_level) == 1);
2698 ASSERT(be16_to_cpu(rblock->bb_numrecs) == 1);
2699 ASSERT(xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0) == 1);
2700 pp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, ifp->if_broot_bytes);
2701 cbno = be64_to_cpu(*pp);
2702 *logflagsp = 0;
2703#ifdef DEBUG
2704 if ((error = xfs_btree_check_lptr(cur, cbno, 1)))
2705 return error;
2706#endif
2707 error = xfs_btree_read_bufl(mp, tp, cbno, 0, &cbp, XFS_BMAP_BTREE_REF,
2708 &xfs_bmbt_buf_ops);
2709 if (error)
2710 return error;
2711 cblock = XFS_BUF_TO_BLOCK(cbp);
2712 if ((error = xfs_btree_check_block(cur, cblock, 0, cbp)))
2713 return error;
2714 xfs_bmap_add_free(cbno, 1, cur->bc_private.b.flist, mp);
2715 ip->i_d.di_nblocks--;
2716 xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L);
2717 xfs_trans_binval(tp, cbp);
2718 if (cur->bc_bufs[0] == cbp)
2719 cur->bc_bufs[0] = NULL;
2720 xfs_iroot_realloc(ip, -1, whichfork);
2721 ASSERT(ifp->if_broot == NULL);
2722 ASSERT((ifp->if_flags & XFS_IFBROOT) == 0);
2723 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS);
2724 *logflagsp = XFS_ILOG_CORE | xfs_ilog_fext(whichfork);
2725 return 0;
2726}
2727
2728/*
2729 * Called by xfs_bmapi to update file extent records and the btree
2730 * after removing space (or undoing a delayed allocation).
2731 */
2732STATIC int /* error */
2733xfs_bmap_del_extent(
2734 xfs_inode_t *ip, /* incore inode pointer */
2735 xfs_trans_t *tp, /* current transaction pointer */
2736 xfs_extnum_t *idx, /* extent number to update/delete */
2737 xfs_bmap_free_t *flist, /* list of extents to be freed */
2738 xfs_btree_cur_t *cur, /* if null, not a btree */
2739 xfs_bmbt_irec_t *del, /* data to remove from extents */
2740 int *logflagsp, /* inode logging flags */
2741 int whichfork) /* data or attr fork */
2742{
2743 xfs_filblks_t da_new; /* new delay-alloc indirect blocks */
2744 xfs_filblks_t da_old; /* old delay-alloc indirect blocks */
2745 xfs_fsblock_t del_endblock=0; /* first block past del */
2746 xfs_fileoff_t del_endoff; /* first offset past del */
2747 int delay; /* current block is delayed allocated */
2748 int do_fx; /* free extent at end of routine */
2749 xfs_bmbt_rec_host_t *ep; /* current extent entry pointer */
2750 int error; /* error return value */
2751 int flags; /* inode logging flags */
2752 xfs_bmbt_irec_t got; /* current extent entry */
2753 xfs_fileoff_t got_endoff; /* first offset past got */
2754 int i; /* temp state */
2755 xfs_ifork_t *ifp; /* inode fork pointer */
2756 xfs_mount_t *mp; /* mount structure */
2757 xfs_filblks_t nblks; /* quota/sb block count */
2758 xfs_bmbt_irec_t new; /* new record to be inserted */
2759 /* REFERENCED */
2760 uint qfield; /* quota field to update */
2761 xfs_filblks_t temp; /* for indirect length calculations */
2762 xfs_filblks_t temp2; /* for indirect length calculations */
2763 int state = 0;
2764
2765 XFS_STATS_INC(xs_del_exlist);
2766
2767 if (whichfork == XFS_ATTR_FORK)
2768 state |= BMAP_ATTRFORK;
2769
2770 mp = ip->i_mount;
2771 ifp = XFS_IFORK_PTR(ip, whichfork);
2772 ASSERT((*idx >= 0) && (*idx < ifp->if_bytes /
2773 (uint)sizeof(xfs_bmbt_rec_t)));
2774 ASSERT(del->br_blockcount > 0);
2775 ep = xfs_iext_get_ext(ifp, *idx);
2776 xfs_bmbt_get_all(ep, &got);
2777 ASSERT(got.br_startoff <= del->br_startoff);
2778 del_endoff = del->br_startoff + del->br_blockcount;
2779 got_endoff = got.br_startoff + got.br_blockcount;
2780 ASSERT(got_endoff >= del_endoff);
2781 delay = isnullstartblock(got.br_startblock);
2782 ASSERT(isnullstartblock(del->br_startblock) == delay);
2783 flags = 0;
2784 qfield = 0;
2785 error = 0;
2786 /*
2787 * If deleting a real allocation, must free up the disk space.
2788 */
2789 if (!delay) {
2790 flags = XFS_ILOG_CORE;
2791 /*
2792 * Realtime allocation. Free it and record di_nblocks update.
2793 */
2794 if (whichfork == XFS_DATA_FORK && XFS_IS_REALTIME_INODE(ip)) {
2795 xfs_fsblock_t bno;
2796 xfs_filblks_t len;
2797
2798 ASSERT(do_mod(del->br_blockcount,
2799 mp->m_sb.sb_rextsize) == 0);
2800 ASSERT(do_mod(del->br_startblock,
2801 mp->m_sb.sb_rextsize) == 0);
2802 bno = del->br_startblock;
2803 len = del->br_blockcount;
2804 do_div(bno, mp->m_sb.sb_rextsize);
2805 do_div(len, mp->m_sb.sb_rextsize);
2806 error = xfs_rtfree_extent(tp, bno, (xfs_extlen_t)len);
2807 if (error)
2808 goto done;
2809 do_fx = 0;
2810 nblks = len * mp->m_sb.sb_rextsize;
2811 qfield = XFS_TRANS_DQ_RTBCOUNT;
2812 }
2813 /*
2814 * Ordinary allocation.
2815 */
2816 else {
2817 do_fx = 1;
2818 nblks = del->br_blockcount;
2819 qfield = XFS_TRANS_DQ_BCOUNT;
2820 }
2821 /*
2822 * Set up del_endblock and cur for later.
2823 */
2824 del_endblock = del->br_startblock + del->br_blockcount;
2825 if (cur) {
2826 if ((error = xfs_bmbt_lookup_eq(cur, got.br_startoff,
2827 got.br_startblock, got.br_blockcount,
2828 &i)))
2829 goto done;
2830 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
2831 }
2832 da_old = da_new = 0;
2833 } else {
2834 da_old = startblockval(got.br_startblock);
2835 da_new = 0;
2836 nblks = 0;
2837 do_fx = 0;
2838 }
2839 /*
2840 * Set flag value to use in switch statement.
2841 * Left-contig is 2, right-contig is 1.
2842 */
2843 switch (((got.br_startoff == del->br_startoff) << 1) |
2844 (got_endoff == del_endoff)) {
2845 case 3:
2846 /*
2847 * Matches the whole extent. Delete the entry.
2848 */
2849 xfs_iext_remove(ip, *idx, 1,
2850 whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0);
2851 --*idx;
2852 if (delay)
2853 break;
2854
2855 XFS_IFORK_NEXT_SET(ip, whichfork,
2856 XFS_IFORK_NEXTENTS(ip, whichfork) - 1);
2857 flags |= XFS_ILOG_CORE;
2858 if (!cur) {
2859 flags |= xfs_ilog_fext(whichfork);
2860 break;
2861 }
2862 if ((error = xfs_btree_delete(cur, &i)))
2863 goto done;
2864 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
2865 break;
2866
2867 case 2:
2868 /*
2869 * Deleting the first part of the extent.
2870 */
2871 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
2872 xfs_bmbt_set_startoff(ep, del_endoff);
2873 temp = got.br_blockcount - del->br_blockcount;
2874 xfs_bmbt_set_blockcount(ep, temp);
2875 if (delay) {
2876 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
2877 da_old);
2878 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
2879 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
2880 da_new = temp;
2881 break;
2882 }
2883 xfs_bmbt_set_startblock(ep, del_endblock);
2884 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
2885 if (!cur) {
2886 flags |= xfs_ilog_fext(whichfork);
2887 break;
2888 }
2889 if ((error = xfs_bmbt_update(cur, del_endoff, del_endblock,
2890 got.br_blockcount - del->br_blockcount,
2891 got.br_state)))
2892 goto done;
2893 break;
2894
2895 case 1:
2896 /*
2897 * Deleting the last part of the extent.
2898 */
2899 temp = got.br_blockcount - del->br_blockcount;
2900 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
2901 xfs_bmbt_set_blockcount(ep, temp);
2902 if (delay) {
2903 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
2904 da_old);
2905 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
2906 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
2907 da_new = temp;
2908 break;
2909 }
2910 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
2911 if (!cur) {
2912 flags |= xfs_ilog_fext(whichfork);
2913 break;
2914 }
2915 if ((error = xfs_bmbt_update(cur, got.br_startoff,
2916 got.br_startblock,
2917 got.br_blockcount - del->br_blockcount,
2918 got.br_state)))
2919 goto done;
2920 break;
2921
2922 case 0:
2923 /*
2924 * Deleting the middle of the extent.
2925 */
2926 temp = del->br_startoff - got.br_startoff;
2927 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
2928 xfs_bmbt_set_blockcount(ep, temp);
2929 new.br_startoff = del_endoff;
2930 temp2 = got_endoff - del_endoff;
2931 new.br_blockcount = temp2;
2932 new.br_state = got.br_state;
2933 if (!delay) {
2934 new.br_startblock = del_endblock;
2935 flags |= XFS_ILOG_CORE;
2936 if (cur) {
2937 if ((error = xfs_bmbt_update(cur,
2938 got.br_startoff,
2939 got.br_startblock, temp,
2940 got.br_state)))
2941 goto done;
2942 if ((error = xfs_btree_increment(cur, 0, &i)))
2943 goto done;
2944 cur->bc_rec.b = new;
2945 error = xfs_btree_insert(cur, &i);
2946 if (error && error != ENOSPC)
2947 goto done;
2948 /*
2949 * If get no-space back from btree insert,
2950 * it tried a split, and we have a zero
2951 * block reservation.
2952 * Fix up our state and return the error.
2953 */
2954 if (error == ENOSPC) {
2955 /*
2956 * Reset the cursor, don't trust
2957 * it after any insert operation.
2958 */
2959 if ((error = xfs_bmbt_lookup_eq(cur,
2960 got.br_startoff,
2961 got.br_startblock,
2962 temp, &i)))
2963 goto done;
2964 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
2965 /*
2966 * Update the btree record back
2967 * to the original value.
2968 */
2969 if ((error = xfs_bmbt_update(cur,
2970 got.br_startoff,
2971 got.br_startblock,
2972 got.br_blockcount,
2973 got.br_state)))
2974 goto done;
2975 /*
2976 * Reset the extent record back
2977 * to the original value.
2978 */
2979 xfs_bmbt_set_blockcount(ep,
2980 got.br_blockcount);
2981 flags = 0;
2982 error = XFS_ERROR(ENOSPC);
2983 goto done;
2984 }
2985 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
2986 } else
2987 flags |= xfs_ilog_fext(whichfork);
2988 XFS_IFORK_NEXT_SET(ip, whichfork,
2989 XFS_IFORK_NEXTENTS(ip, whichfork) + 1);
2990 } else {
2991 ASSERT(whichfork == XFS_DATA_FORK);
2992 temp = xfs_bmap_worst_indlen(ip, temp);
2993 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
2994 temp2 = xfs_bmap_worst_indlen(ip, temp2);
2995 new.br_startblock = nullstartblock((int)temp2);
2996 da_new = temp + temp2;
2997 while (da_new > da_old) {
2998 if (temp) {
2999 temp--;
3000 da_new--;
3001 xfs_bmbt_set_startblock(ep,
3002 nullstartblock((int)temp));
3003 }
3004 if (da_new == da_old)
3005 break;
3006 if (temp2) {
3007 temp2--;
3008 da_new--;
3009 new.br_startblock =
3010 nullstartblock((int)temp2);
3011 }
3012 }
3013 }
3014 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
3015 xfs_iext_insert(ip, *idx + 1, 1, &new, state);
3016 ++*idx;
3017 break;
3018 }
3019 /*
3020 * If we need to, add to list of extents to delete.
3021 */
3022 if (do_fx)
3023 xfs_bmap_add_free(del->br_startblock, del->br_blockcount, flist,
3024 mp);
3025 /*
3026 * Adjust inode # blocks in the file.
3027 */
3028 if (nblks)
3029 ip->i_d.di_nblocks -= nblks;
3030 /*
3031 * Adjust quota data.
3032 */
3033 if (qfield)
3034 xfs_trans_mod_dquot_byino(tp, ip, qfield, (long)-nblks);
3035
3036 /*
3037 * Account for change in delayed indirect blocks.
3038 * Nothing to do for disk quota accounting here.
3039 */
3040 ASSERT(da_old >= da_new);
3041 if (da_old > da_new) {
3042 xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS,
3043 (int64_t)(da_old - da_new), 0);
3044 }
3045done:
3046 *logflagsp = flags;
3047 return error;
3048}
3049
3050/*
3051 * Remove the entry "free" from the free item list. Prev points to the
3052 * previous entry, unless "free" is the head of the list.
3053 */
3054STATIC void
3055xfs_bmap_del_free(
3056 xfs_bmap_free_t *flist, /* free item list header */
3057 xfs_bmap_free_item_t *prev, /* previous item on list, if any */
3058 xfs_bmap_free_item_t *free) /* list item to be freed */
3059{
3060 if (prev)
3061 prev->xbfi_next = free->xbfi_next;
3062 else
3063 flist->xbf_first = free->xbfi_next;
3064 flist->xbf_count--;
3065 kmem_zone_free(xfs_bmap_free_item_zone, free);
3066}
3067
3068/*
3069 * Convert an extents-format file into a btree-format file.
3070 * The new file will have a root block (in the inode) and a single child block.
3071 */
3072STATIC int /* error */
3073xfs_bmap_extents_to_btree(
3074 xfs_trans_t *tp, /* transaction pointer */
3075 xfs_inode_t *ip, /* incore inode pointer */
3076 xfs_fsblock_t *firstblock, /* first-block-allocated */
3077 xfs_bmap_free_t *flist, /* blocks freed in xaction */
3078 xfs_btree_cur_t **curp, /* cursor returned to caller */
3079 int wasdel, /* converting a delayed alloc */
3080 int *logflagsp, /* inode logging flags */
3081 int whichfork) /* data or attr fork */
3082{
3083 struct xfs_btree_block *ablock; /* allocated (child) bt block */
3084 xfs_buf_t *abp; /* buffer for ablock */
3085 xfs_alloc_arg_t args; /* allocation arguments */
3086 xfs_bmbt_rec_t *arp; /* child record pointer */
3087 struct xfs_btree_block *block; /* btree root block */
3088 xfs_btree_cur_t *cur; /* bmap btree cursor */
3089 xfs_bmbt_rec_host_t *ep; /* extent record pointer */
3090 int error; /* error return value */
3091 xfs_extnum_t i, cnt; /* extent record index */
3092 xfs_ifork_t *ifp; /* inode fork pointer */
3093 xfs_bmbt_key_t *kp; /* root block key pointer */
3094 xfs_mount_t *mp; /* mount structure */
3095 xfs_extnum_t nextents; /* number of file extents */
3096 xfs_bmbt_ptr_t *pp; /* root block address pointer */
3097
3098 ifp = XFS_IFORK_PTR(ip, whichfork);
3099 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS);
3100
3101 /*
3102 * Make space in the inode incore.
3103 */
3104 xfs_iroot_realloc(ip, 1, whichfork);
3105 ifp->if_flags |= XFS_IFBROOT;
3106
3107 /*
3108 * Fill in the root.
3109 */
3110 block = ifp->if_broot;
3111 block->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC);
3112 block->bb_level = cpu_to_be16(1);
3113 block->bb_numrecs = cpu_to_be16(1);
3114 block->bb_u.l.bb_leftsib = cpu_to_be64(NULLDFSBNO);
3115 block->bb_u.l.bb_rightsib = cpu_to_be64(NULLDFSBNO);
3116
3117 /*
3118 * Need a cursor. Can't allocate until bb_level is filled in.
3119 */
3120 mp = ip->i_mount;
3121 cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
3122 cur->bc_private.b.firstblock = *firstblock;
3123 cur->bc_private.b.flist = flist;
3124 cur->bc_private.b.flags = wasdel ? XFS_BTCUR_BPRV_WASDEL : 0;
3125 /*
3126 * Convert to a btree with two levels, one record in root.
3127 */
3128 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE);
3129 memset(&args, 0, sizeof(args));
3130 args.tp = tp;
3131 args.mp = mp;
3132 args.firstblock = *firstblock;
3133 if (*firstblock == NULLFSBLOCK) {
3134 args.type = XFS_ALLOCTYPE_START_BNO;
3135 args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino);
3136 } else if (flist->xbf_low) {
3137 args.type = XFS_ALLOCTYPE_START_BNO;
3138 args.fsbno = *firstblock;
3139 } else {
3140 args.type = XFS_ALLOCTYPE_NEAR_BNO;
3141 args.fsbno = *firstblock;
3142 }
3143 args.minlen = args.maxlen = args.prod = 1;
3144 args.wasdel = wasdel;
3145 *logflagsp = 0;
3146 if ((error = xfs_alloc_vextent(&args))) {
3147 xfs_iroot_realloc(ip, -1, whichfork);
3148 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
3149 return error;
3150 }
3151 /*
3152 * Allocation can't fail, the space was reserved.
3153 */
3154 ASSERT(args.fsbno != NULLFSBLOCK);
3155 ASSERT(*firstblock == NULLFSBLOCK ||
3156 args.agno == XFS_FSB_TO_AGNO(mp, *firstblock) ||
3157 (flist->xbf_low &&
3158 args.agno > XFS_FSB_TO_AGNO(mp, *firstblock)));
3159 *firstblock = cur->bc_private.b.firstblock = args.fsbno;
3160 cur->bc_private.b.allocated++;
3161 ip->i_d.di_nblocks++;
3162 xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L);
3163 abp = xfs_btree_get_bufl(mp, tp, args.fsbno, 0);
3164 /*
3165 * Fill in the child block.
3166 */
3167 abp->b_ops = &xfs_bmbt_buf_ops;
3168 ablock = XFS_BUF_TO_BLOCK(abp);
3169 ablock->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC);
3170 ablock->bb_level = 0;
3171 ablock->bb_u.l.bb_leftsib = cpu_to_be64(NULLDFSBNO);
3172 ablock->bb_u.l.bb_rightsib = cpu_to_be64(NULLDFSBNO);
3173 arp = XFS_BMBT_REC_ADDR(mp, ablock, 1);
3174 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
3175 for (cnt = i = 0; i < nextents; i++) {
3176 ep = xfs_iext_get_ext(ifp, i);
3177 if (!isnullstartblock(xfs_bmbt_get_startblock(ep))) {
3178 arp->l0 = cpu_to_be64(ep->l0);
3179 arp->l1 = cpu_to_be64(ep->l1);
3180 arp++; cnt++;
3181 }
3182 }
3183 ASSERT(cnt == XFS_IFORK_NEXTENTS(ip, whichfork));
3184 xfs_btree_set_numrecs(ablock, cnt);
3185
3186 /*
3187 * Fill in the root key and pointer.
3188 */
3189 kp = XFS_BMBT_KEY_ADDR(mp, block, 1);
3190 arp = XFS_BMBT_REC_ADDR(mp, ablock, 1);
3191 kp->br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(arp));
3192 pp = XFS_BMBT_PTR_ADDR(mp, block, 1, xfs_bmbt_get_maxrecs(cur,
3193 be16_to_cpu(block->bb_level)));
3194 *pp = cpu_to_be64(args.fsbno);
3195
3196 /*
3197 * Do all this logging at the end so that
3198 * the root is at the right level.
3199 */
3200 xfs_btree_log_block(cur, abp, XFS_BB_ALL_BITS);
3201 xfs_btree_log_recs(cur, abp, 1, be16_to_cpu(ablock->bb_numrecs));
3202 ASSERT(*curp == NULL);
3203 *curp = cur;
3204 *logflagsp = XFS_ILOG_CORE | xfs_ilog_fbroot(whichfork);
3205 return 0;
3206}
3207
3208/*
3209 * Calculate the default attribute fork offset for newly created inodes.
3210 */
3211uint
3212xfs_default_attroffset(
3213 struct xfs_inode *ip)
3214{
3215 struct xfs_mount *mp = ip->i_mount;
3216 uint offset;
3217
3218 if (mp->m_sb.sb_inodesize == 256) {
3219 offset = XFS_LITINO(mp) -
3220 XFS_BMDR_SPACE_CALC(MINABTPTRS);
3221 } else {
3222 offset = XFS_BMDR_SPACE_CALC(6 * MINABTPTRS);
3223 }
3224
3225 ASSERT(offset < XFS_LITINO(mp));
3226 return offset;
3227}
3228
3229/*
3230 * Helper routine to reset inode di_forkoff field when switching
3231 * attribute fork from local to extent format - we reset it where
3232 * possible to make space available for inline data fork extents.
3233 */
3234STATIC void
3235xfs_bmap_forkoff_reset(
3236 xfs_mount_t *mp,
3237 xfs_inode_t *ip,
3238 int whichfork)
3239{
3240 if (whichfork == XFS_ATTR_FORK &&
3241 ip->i_d.di_format != XFS_DINODE_FMT_DEV &&
3242 ip->i_d.di_format != XFS_DINODE_FMT_UUID &&
3243 ip->i_d.di_format != XFS_DINODE_FMT_BTREE) {
3244 uint dfl_forkoff = xfs_default_attroffset(ip) >> 3;
3245
3246 if (dfl_forkoff > ip->i_d.di_forkoff)
3247 ip->i_d.di_forkoff = dfl_forkoff;
3248 }
3249}
3250
3251/*
3252 * Convert a local file to an extents file.
3253 * This code is out of bounds for data forks of regular files,
3254 * since the file data needs to get logged so things will stay consistent.
3255 * (The bmap-level manipulations are ok, though).
3256 */
3257STATIC int /* error */
3258xfs_bmap_local_to_extents(
3259 xfs_trans_t *tp, /* transaction pointer */
3260 xfs_inode_t *ip, /* incore inode pointer */
3261 xfs_fsblock_t *firstblock, /* first block allocated in xaction */
3262 xfs_extlen_t total, /* total blocks needed by transaction */
3263 int *logflagsp, /* inode logging flags */
3264 int whichfork,
3265 void (*init_fn)(struct xfs_buf *bp,
3266 struct xfs_inode *ip,
3267 struct xfs_ifork *ifp))
3268{
3269 int error; /* error return value */
3270 int flags; /* logging flags returned */
3271 xfs_ifork_t *ifp; /* inode fork pointer */
3272
3273 /*
3274 * We don't want to deal with the case of keeping inode data inline yet.
3275 * So sending the data fork of a regular inode is invalid.
3276 */
3277 ASSERT(!(S_ISREG(ip->i_d.di_mode) && whichfork == XFS_DATA_FORK));
3278 ifp = XFS_IFORK_PTR(ip, whichfork);
3279 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL);
3280 flags = 0;
3281 error = 0;
3282 if (ifp->if_bytes) {
3283 xfs_alloc_arg_t args; /* allocation arguments */
3284 xfs_buf_t *bp; /* buffer for extent block */
3285 xfs_bmbt_rec_host_t *ep;/* extent record pointer */
3286
3287 ASSERT((ifp->if_flags &
3288 (XFS_IFINLINE|XFS_IFEXTENTS|XFS_IFEXTIREC)) == XFS_IFINLINE);
3289 memset(&args, 0, sizeof(args));
3290 args.tp = tp;
3291 args.mp = ip->i_mount;
3292 args.firstblock = *firstblock;
3293 /*
3294 * Allocate a block. We know we need only one, since the
3295 * file currently fits in an inode.
3296 */
3297 if (*firstblock == NULLFSBLOCK) {
3298 args.fsbno = XFS_INO_TO_FSB(args.mp, ip->i_ino);
3299 args.type = XFS_ALLOCTYPE_START_BNO;
3300 } else {
3301 args.fsbno = *firstblock;
3302 args.type = XFS_ALLOCTYPE_NEAR_BNO;
3303 }
3304 args.total = total;
3305 args.minlen = args.maxlen = args.prod = 1;
3306 error = xfs_alloc_vextent(&args);
3307 if (error)
3308 goto done;
3309
3310 /* Can't fail, the space was reserved. */
3311 ASSERT(args.fsbno != NULLFSBLOCK);
3312 ASSERT(args.len == 1);
3313 *firstblock = args.fsbno;
3314 bp = xfs_btree_get_bufl(args.mp, tp, args.fsbno, 0);
3315
3316 /* initialise the block and copy the data */
3317 init_fn(bp, ip, ifp);
3318
3319 /* account for the change in fork size and log everything */
3320 xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1);
3321 xfs_bmap_forkoff_reset(args.mp, ip, whichfork);
3322 xfs_idata_realloc(ip, -ifp->if_bytes, whichfork);
3323 xfs_iext_add(ifp, 0, 1);
3324 ep = xfs_iext_get_ext(ifp, 0);
3325 xfs_bmbt_set_allf(ep, 0, args.fsbno, 1, XFS_EXT_NORM);
3326 trace_xfs_bmap_post_update(ip, 0,
3327 whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0,
3328 _THIS_IP_);
3329 XFS_IFORK_NEXT_SET(ip, whichfork, 1);
3330 ip->i_d.di_nblocks = 1;
3331 xfs_trans_mod_dquot_byino(tp, ip,
3332 XFS_TRANS_DQ_BCOUNT, 1L);
3333 flags |= xfs_ilog_fext(whichfork);
3334 } else {
3335 ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) == 0);
3336 xfs_bmap_forkoff_reset(ip->i_mount, ip, whichfork);
3337 }
3338 ifp->if_flags &= ~XFS_IFINLINE;
3339 ifp->if_flags |= XFS_IFEXTENTS;
3340 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS);
3341 flags |= XFS_ILOG_CORE;
3342done:
3343 *logflagsp = flags;
3344 return error;
3345}
3346
3347/*
3348 * Search the extent records for the entry containing block bno.
3349 * If bno lies in a hole, point to the next entry. If bno lies
3350 * past eof, *eofp will be set, and *prevp will contain the last
3351 * entry (null if none). Else, *lastxp will be set to the index
3352 * of the found entry; *gotp will contain the entry.
3353 */
3354STATIC xfs_bmbt_rec_host_t * /* pointer to found extent entry */
3355xfs_bmap_search_multi_extents(
3356 xfs_ifork_t *ifp, /* inode fork pointer */
3357 xfs_fileoff_t bno, /* block number searched for */
3358 int *eofp, /* out: end of file found */
3359 xfs_extnum_t *lastxp, /* out: last extent index */
3360 xfs_bmbt_irec_t *gotp, /* out: extent entry found */
3361 xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */
3362{
3363 xfs_bmbt_rec_host_t *ep; /* extent record pointer */
3364 xfs_extnum_t lastx; /* last extent index */
3365
3366 /*
3367 * Initialize the extent entry structure to catch access to
3368 * uninitialized br_startblock field.
3369 */
3370 gotp->br_startoff = 0xffa5a5a5a5a5a5a5LL;
3371 gotp->br_blockcount = 0xa55a5a5a5a5a5a5aLL;
3372 gotp->br_state = XFS_EXT_INVALID;
3373#if XFS_BIG_BLKNOS
3374 gotp->br_startblock = 0xffffa5a5a5a5a5a5LL;
3375#else
3376 gotp->br_startblock = 0xffffa5a5;
3377#endif
3378 prevp->br_startoff = NULLFILEOFF;
3379
3380 ep = xfs_iext_bno_to_ext(ifp, bno, &lastx);
3381 if (lastx > 0) {
3382 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx - 1), prevp);
3383 }
3384 if (lastx < (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))) {
3385 xfs_bmbt_get_all(ep, gotp);
3386 *eofp = 0;
3387 } else {
3388 if (lastx > 0) {
3389 *gotp = *prevp;
3390 }
3391 *eofp = 1;
3392 ep = NULL;
3393 }
3394 *lastxp = lastx;
3395 return ep;
3396}
3397
3398/*
3399 * Search the extents list for the inode, for the extent containing bno.
3400 * If bno lies in a hole, point to the next entry. If bno lies past eof,
3401 * *eofp will be set, and *prevp will contain the last entry (null if none).
3402 * Else, *lastxp will be set to the index of the found
3403 * entry; *gotp will contain the entry.
3404 */
3405STATIC xfs_bmbt_rec_host_t * /* pointer to found extent entry */
3406xfs_bmap_search_extents(
3407 xfs_inode_t *ip, /* incore inode pointer */
3408 xfs_fileoff_t bno, /* block number searched for */
3409 int fork, /* data or attr fork */
3410 int *eofp, /* out: end of file found */
3411 xfs_extnum_t *lastxp, /* out: last extent index */
3412 xfs_bmbt_irec_t *gotp, /* out: extent entry found */
3413 xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */
3414{
3415 xfs_ifork_t *ifp; /* inode fork pointer */
3416 xfs_bmbt_rec_host_t *ep; /* extent record pointer */
3417
3418 XFS_STATS_INC(xs_look_exlist);
3419 ifp = XFS_IFORK_PTR(ip, fork);
3420
3421 ep = xfs_bmap_search_multi_extents(ifp, bno, eofp, lastxp, gotp, prevp);
3422
3423 if (unlikely(!(gotp->br_startblock) && (*lastxp != NULLEXTNUM) &&
3424 !(XFS_IS_REALTIME_INODE(ip) && fork == XFS_DATA_FORK))) {
3425 xfs_alert_tag(ip->i_mount, XFS_PTAG_FSBLOCK_ZERO,
3426 "Access to block zero in inode %llu "
3427 "start_block: %llx start_off: %llx "
3428 "blkcnt: %llx extent-state: %x lastx: %x\n",
3429 (unsigned long long)ip->i_ino,
3430 (unsigned long long)gotp->br_startblock,
3431 (unsigned long long)gotp->br_startoff,
3432 (unsigned long long)gotp->br_blockcount,
3433 gotp->br_state, *lastxp);
3434 *lastxp = NULLEXTNUM;
3435 *eofp = 1;
3436 return NULL;
3437 }
3438 return ep;
3439}
3440
3441/*
3442 * Compute the worst-case number of indirect blocks that will be used
3443 * for ip's delayed extent of length "len".
3444 */
3445STATIC xfs_filblks_t
3446xfs_bmap_worst_indlen(
3447 xfs_inode_t *ip, /* incore inode pointer */
3448 xfs_filblks_t len) /* delayed extent length */
3449{
3450 int level; /* btree level number */
3451 int maxrecs; /* maximum record count at this level */
3452 xfs_mount_t *mp; /* mount structure */
3453 xfs_filblks_t rval; /* return value */
3454
3455 mp = ip->i_mount;
3456 maxrecs = mp->m_bmap_dmxr[0];
3457 for (level = 0, rval = 0;
3458 level < XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK);
3459 level++) {
3460 len += maxrecs - 1;
3461 do_div(len, maxrecs);
3462 rval += len;
3463 if (len == 1)
3464 return rval + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) -
3465 level - 1;
3466 if (level == 0)
3467 maxrecs = mp->m_bmap_dmxr[1];
3468 }
3469 return rval;
3470}
3471
3472/*
3473 * Convert inode from non-attributed to attributed.
3474 * Must not be in a transaction, ip must not be locked.
3475 */
3476int /* error code */
3477xfs_bmap_add_attrfork(
3478 xfs_inode_t *ip, /* incore inode pointer */
3479 int size, /* space new attribute needs */
3480 int rsvd) /* xact may use reserved blks */
3481{
3482 xfs_fsblock_t firstblock; /* 1st block/ag allocated */
3483 xfs_bmap_free_t flist; /* freed extent records */
3484 xfs_mount_t *mp; /* mount structure */
3485 xfs_trans_t *tp; /* transaction pointer */
3486 int blks; /* space reservation */
3487 int version = 1; /* superblock attr version */
3488 int committed; /* xaction was committed */
3489 int logflags; /* logging flags */
3490 int error; /* error return value */
3491
3492 ASSERT(XFS_IFORK_Q(ip) == 0);
3493
3494 mp = ip->i_mount;
3495 ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
3496 tp = xfs_trans_alloc(mp, XFS_TRANS_ADDAFORK);
3497 blks = XFS_ADDAFORK_SPACE_RES(mp);
3498 if (rsvd)
3499 tp->t_flags |= XFS_TRANS_RESERVE;
3500 if ((error = xfs_trans_reserve(tp, blks, XFS_ADDAFORK_LOG_RES(mp), 0,
3501 XFS_TRANS_PERM_LOG_RES, XFS_ADDAFORK_LOG_COUNT)))
3502 goto error0;
3503 xfs_ilock(ip, XFS_ILOCK_EXCL);
3504 error = xfs_trans_reserve_quota_nblks(tp, ip, blks, 0, rsvd ?
3505 XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES :
3506 XFS_QMOPT_RES_REGBLKS);
3507 if (error) {
3508 xfs_iunlock(ip, XFS_ILOCK_EXCL);
3509 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES);
3510 return error;
3511 }
3512 if (XFS_IFORK_Q(ip))
3513 goto error1;
3514 if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS) {
3515 /*
3516 * For inodes coming from pre-6.2 filesystems.
3517 */
3518 ASSERT(ip->i_d.di_aformat == 0);
3519 ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
3520 }
3521 ASSERT(ip->i_d.di_anextents == 0);
3522
3523 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
3524 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
3525
3526 switch (ip->i_d.di_format) {
3527 case XFS_DINODE_FMT_DEV:
3528 ip->i_d.di_forkoff = roundup(sizeof(xfs_dev_t), 8) >> 3;
3529 break;
3530 case XFS_DINODE_FMT_UUID:
3531 ip->i_d.di_forkoff = roundup(sizeof(uuid_t), 8) >> 3;
3532 break;
3533 case XFS_DINODE_FMT_LOCAL:
3534 case XFS_DINODE_FMT_EXTENTS:
3535 case XFS_DINODE_FMT_BTREE:
3536 ip->i_d.di_forkoff = xfs_attr_shortform_bytesfit(ip, size);
3537 if (!ip->i_d.di_forkoff)
3538 ip->i_d.di_forkoff = xfs_default_attroffset(ip) >> 3;
3539 else if (mp->m_flags & XFS_MOUNT_ATTR2)
3540 version = 2;
3541 break;
3542 default:
3543 ASSERT(0);
3544 error = XFS_ERROR(EINVAL);
3545 goto error1;
3546 }
3547
3548 ASSERT(ip->i_afp == NULL);
3549 ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP);
3550 ip->i_afp->if_flags = XFS_IFEXTENTS;
3551 logflags = 0;
3552 xfs_bmap_init(&flist, &firstblock);
3553 switch (ip->i_d.di_format) {
3554 case XFS_DINODE_FMT_LOCAL:
3555 error = xfs_bmap_add_attrfork_local(tp, ip, &firstblock, &flist,
3556 &logflags);
3557 break;
3558 case XFS_DINODE_FMT_EXTENTS:
3559 error = xfs_bmap_add_attrfork_extents(tp, ip, &firstblock,
3560 &flist, &logflags);
3561 break;
3562 case XFS_DINODE_FMT_BTREE:
3563 error = xfs_bmap_add_attrfork_btree(tp, ip, &firstblock, &flist,
3564 &logflags);
3565 break;
3566 default:
3567 error = 0;
3568 break;
3569 }
3570 if (logflags)
3571 xfs_trans_log_inode(tp, ip, logflags);
3572 if (error)
3573 goto error2;
3574 if (!xfs_sb_version_hasattr(&mp->m_sb) ||
3575 (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2)) {
3576 __int64_t sbfields = 0;
3577
3578 spin_lock(&mp->m_sb_lock);
3579 if (!xfs_sb_version_hasattr(&mp->m_sb)) {
3580 xfs_sb_version_addattr(&mp->m_sb);
3581 sbfields |= XFS_SB_VERSIONNUM;
3582 }
3583 if (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2) {
3584 xfs_sb_version_addattr2(&mp->m_sb);
3585 sbfields |= (XFS_SB_VERSIONNUM | XFS_SB_FEATURES2);
3586 }
3587 if (sbfields) {
3588 spin_unlock(&mp->m_sb_lock);
3589 xfs_mod_sb(tp, sbfields);
3590 } else
3591 spin_unlock(&mp->m_sb_lock);
3592 }
3593
3594 error = xfs_bmap_finish(&tp, &flist, &committed);
3595 if (error)
3596 goto error2;
3597 return xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
3598error2:
3599 xfs_bmap_cancel(&flist);
3600error1:
3601 xfs_iunlock(ip, XFS_ILOCK_EXCL);
3602error0:
3603 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
3604 return error;
3605}
3606
3607/*
3608 * Add the extent to the list of extents to be free at transaction end.
3609 * The list is maintained sorted (by block number).
3610 */
3611/* ARGSUSED */
3612void
3613xfs_bmap_add_free(
3614 xfs_fsblock_t bno, /* fs block number of extent */
3615 xfs_filblks_t len, /* length of extent */
3616 xfs_bmap_free_t *flist, /* list of extents */
3617 xfs_mount_t *mp) /* mount point structure */
3618{
3619 xfs_bmap_free_item_t *cur; /* current (next) element */
3620 xfs_bmap_free_item_t *new; /* new element */
3621 xfs_bmap_free_item_t *prev; /* previous element */
3622#ifdef DEBUG
3623 xfs_agnumber_t agno;
3624 xfs_agblock_t agbno;
3625
3626 ASSERT(bno != NULLFSBLOCK);
3627 ASSERT(len > 0);
3628 ASSERT(len <= MAXEXTLEN);
3629 ASSERT(!isnullstartblock(bno));
3630 agno = XFS_FSB_TO_AGNO(mp, bno);
3631 agbno = XFS_FSB_TO_AGBNO(mp, bno);
3632 ASSERT(agno < mp->m_sb.sb_agcount);
3633 ASSERT(agbno < mp->m_sb.sb_agblocks);
3634 ASSERT(len < mp->m_sb.sb_agblocks);
3635 ASSERT(agbno + len <= mp->m_sb.sb_agblocks);
3636#endif
3637 ASSERT(xfs_bmap_free_item_zone != NULL);
3638 new = kmem_zone_alloc(xfs_bmap_free_item_zone, KM_SLEEP);
3639 new->xbfi_startblock = bno;
3640 new->xbfi_blockcount = (xfs_extlen_t)len;
3641 for (prev = NULL, cur = flist->xbf_first;
3642 cur != NULL;
3643 prev = cur, cur = cur->xbfi_next) {
3644 if (cur->xbfi_startblock >= bno)
3645 break;
3646 }
3647 if (prev)
3648 prev->xbfi_next = new;
3649 else
3650 flist->xbf_first = new;
3651 new->xbfi_next = cur;
3652 flist->xbf_count++;
3653}
3654
3655/*
3656 * Compute and fill in the value of the maximum depth of a bmap btree
3657 * in this filesystem. Done once, during mount.
3658 */
3659void
3660xfs_bmap_compute_maxlevels(
3661 xfs_mount_t *mp, /* file system mount structure */
3662 int whichfork) /* data or attr fork */
3663{
3664 int level; /* btree level */
3665 uint maxblocks; /* max blocks at this level */
3666 uint maxleafents; /* max leaf entries possible */
3667 int maxrootrecs; /* max records in root block */
3668 int minleafrecs; /* min records in leaf block */
3669 int minnoderecs; /* min records in node block */
3670 int sz; /* root block size */
3671
3672 /*
3673 * The maximum number of extents in a file, hence the maximum
3674 * number of leaf entries, is controlled by the type of di_nextents
3675 * (a signed 32-bit number, xfs_extnum_t), or by di_anextents
3676 * (a signed 16-bit number, xfs_aextnum_t).
3677 *
3678 * Note that we can no longer assume that if we are in ATTR1 that
3679 * the fork offset of all the inodes will be
3680 * (xfs_default_attroffset(ip) >> 3) because we could have mounted
3681 * with ATTR2 and then mounted back with ATTR1, keeping the
3682 * di_forkoff's fixed but probably at various positions. Therefore,
3683 * for both ATTR1 and ATTR2 we have to assume the worst case scenario
3684 * of a minimum size available.
3685 */
3686 if (whichfork == XFS_DATA_FORK) {
3687 maxleafents = MAXEXTNUM;
3688 sz = XFS_BMDR_SPACE_CALC(MINDBTPTRS);
3689 } else {
3690 maxleafents = MAXAEXTNUM;
3691 sz = XFS_BMDR_SPACE_CALC(MINABTPTRS);
3692 }
3693 maxrootrecs = xfs_bmdr_maxrecs(mp, sz, 0);
3694 minleafrecs = mp->m_bmap_dmnr[0];
3695 minnoderecs = mp->m_bmap_dmnr[1];
3696 maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs;
3697 for (level = 1; maxblocks > 1; level++) {
3698 if (maxblocks <= maxrootrecs)
3699 maxblocks = 1;
3700 else
3701 maxblocks = (maxblocks + minnoderecs - 1) / minnoderecs;
3702 }
3703 mp->m_bm_maxlevels[whichfork] = level;
3704}
3705
3706/*
3707 * Routine to be called at transaction's end by xfs_bmapi, xfs_bunmapi
3708 * caller. Frees all the extents that need freeing, which must be done
3709 * last due to locking considerations. We never free any extents in
3710 * the first transaction.
3711 *
3712 * Return 1 if the given transaction was committed and a new one
3713 * started, and 0 otherwise in the committed parameter.
3714 */
3715int /* error */
3716xfs_bmap_finish(
3717 xfs_trans_t **tp, /* transaction pointer addr */
3718 xfs_bmap_free_t *flist, /* i/o: list extents to free */
3719 int *committed) /* xact committed or not */
3720{
3721 xfs_efd_log_item_t *efd; /* extent free data */
3722 xfs_efi_log_item_t *efi; /* extent free intention */
3723 int error; /* error return value */
3724 xfs_bmap_free_item_t *free; /* free extent item */
3725 unsigned int logres; /* new log reservation */
3726 unsigned int logcount; /* new log count */
3727 xfs_mount_t *mp; /* filesystem mount structure */
3728 xfs_bmap_free_item_t *next; /* next item on free list */
3729 xfs_trans_t *ntp; /* new transaction pointer */
3730
3731 ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES);
3732 if (flist->xbf_count == 0) {
3733 *committed = 0;
3734 return 0;
3735 }
3736 ntp = *tp;
3737 efi = xfs_trans_get_efi(ntp, flist->xbf_count);
3738 for (free = flist->xbf_first; free; free = free->xbfi_next)
3739 xfs_trans_log_efi_extent(ntp, efi, free->xbfi_startblock,
3740 free->xbfi_blockcount);
3741 logres = ntp->t_log_res;
3742 logcount = ntp->t_log_count;
3743 ntp = xfs_trans_dup(*tp);
3744 error = xfs_trans_commit(*tp, 0);
3745 *tp = ntp;
3746 *committed = 1;
3747 /*
3748 * We have a new transaction, so we should return committed=1,
3749 * even though we're returning an error.
3750 */
3751 if (error)
3752 return error;
3753
3754 /*
3755 * transaction commit worked ok so we can drop the extra ticket
3756 * reference that we gained in xfs_trans_dup()
3757 */
3758 xfs_log_ticket_put(ntp->t_ticket);
3759
3760 if ((error = xfs_trans_reserve(ntp, 0, logres, 0, XFS_TRANS_PERM_LOG_RES,
3761 logcount)))
3762 return error;
3763 efd = xfs_trans_get_efd(ntp, efi, flist->xbf_count);
3764 for (free = flist->xbf_first; free != NULL; free = next) {
3765 next = free->xbfi_next;
3766 if ((error = xfs_free_extent(ntp, free->xbfi_startblock,
3767 free->xbfi_blockcount))) {
3768 /*
3769 * The bmap free list will be cleaned up at a
3770 * higher level. The EFI will be canceled when
3771 * this transaction is aborted.
3772 * Need to force shutdown here to make sure it
3773 * happens, since this transaction may not be
3774 * dirty yet.
3775 */
3776 mp = ntp->t_mountp;
3777 if (!XFS_FORCED_SHUTDOWN(mp))
3778 xfs_force_shutdown(mp,
3779 (error == EFSCORRUPTED) ?
3780 SHUTDOWN_CORRUPT_INCORE :
3781 SHUTDOWN_META_IO_ERROR);
3782 return error;
3783 }
3784 xfs_trans_log_efd_extent(ntp, efd, free->xbfi_startblock,
3785 free->xbfi_blockcount);
3786 xfs_bmap_del_free(flist, NULL, free);
3787 }
3788 return 0;
3789}
3790
3791/*
3792 * Free up any items left in the list.
3793 */
3794void
3795xfs_bmap_cancel(
3796 xfs_bmap_free_t *flist) /* list of bmap_free_items */
3797{
3798 xfs_bmap_free_item_t *free; /* free list item */
3799 xfs_bmap_free_item_t *next;
3800
3801 if (flist->xbf_count == 0)
3802 return;
3803 ASSERT(flist->xbf_first != NULL);
3804 for (free = flist->xbf_first; free; free = next) {
3805 next = free->xbfi_next;
3806 xfs_bmap_del_free(flist, NULL, free);
3807 }
3808 ASSERT(flist->xbf_count == 0);
3809}
3810
3811/*
3812 * Returns the file-relative block number of the first unused block(s)
3813 * in the file with at least "len" logically contiguous blocks free.
3814 * This is the lowest-address hole if the file has holes, else the first block
3815 * past the end of file.
3816 * Return 0 if the file is currently local (in-inode).
3817 */
3818int /* error */
3819xfs_bmap_first_unused(
3820 xfs_trans_t *tp, /* transaction pointer */
3821 xfs_inode_t *ip, /* incore inode */
3822 xfs_extlen_t len, /* size of hole to find */
3823 xfs_fileoff_t *first_unused, /* unused block */
3824 int whichfork) /* data or attr fork */
3825{
3826 int error; /* error return value */
3827 int idx; /* extent record index */
3828 xfs_ifork_t *ifp; /* inode fork pointer */
3829 xfs_fileoff_t lastaddr; /* last block number seen */
3830 xfs_fileoff_t lowest; /* lowest useful block */
3831 xfs_fileoff_t max; /* starting useful block */
3832 xfs_fileoff_t off; /* offset for this block */
3833 xfs_extnum_t nextents; /* number of extent entries */
3834
3835 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE ||
3836 XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS ||
3837 XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL);
3838 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) {
3839 *first_unused = 0;
3840 return 0;
3841 }
3842 ifp = XFS_IFORK_PTR(ip, whichfork);
3843 if (!(ifp->if_flags & XFS_IFEXTENTS) &&
3844 (error = xfs_iread_extents(tp, ip, whichfork)))
3845 return error;
3846 lowest = *first_unused;
3847 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
3848 for (idx = 0, lastaddr = 0, max = lowest; idx < nextents; idx++) {
3849 xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, idx);
3850 off = xfs_bmbt_get_startoff(ep);
3851 /*
3852 * See if the hole before this extent will work.
3853 */
3854 if (off >= lowest + len && off - max >= len) {
3855 *first_unused = max;
3856 return 0;
3857 }
3858 lastaddr = off + xfs_bmbt_get_blockcount(ep);
3859 max = XFS_FILEOFF_MAX(lastaddr, lowest);
3860 }
3861 *first_unused = max;
3862 return 0;
3863}
3864
3865/*
3866 * Returns the file-relative block number of the last block + 1 before
3867 * last_block (input value) in the file.
3868 * This is not based on i_size, it is based on the extent records.
3869 * Returns 0 for local files, as they do not have extent records.
3870 */
3871int /* error */
3872xfs_bmap_last_before(
3873 xfs_trans_t *tp, /* transaction pointer */
3874 xfs_inode_t *ip, /* incore inode */
3875 xfs_fileoff_t *last_block, /* last block */
3876 int whichfork) /* data or attr fork */
3877{
3878 xfs_fileoff_t bno; /* input file offset */
3879 int eof; /* hit end of file */
3880 xfs_bmbt_rec_host_t *ep; /* pointer to last extent */
3881 int error; /* error return value */
3882 xfs_bmbt_irec_t got; /* current extent value */
3883 xfs_ifork_t *ifp; /* inode fork pointer */
3884 xfs_extnum_t lastx; /* last extent used */
3885 xfs_bmbt_irec_t prev; /* previous extent value */
3886
3887 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
3888 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
3889 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL)
3890 return XFS_ERROR(EIO);
3891 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) {
3892 *last_block = 0;
3893 return 0;
3894 }
3895 ifp = XFS_IFORK_PTR(ip, whichfork);
3896 if (!(ifp->if_flags & XFS_IFEXTENTS) &&
3897 (error = xfs_iread_extents(tp, ip, whichfork)))
3898 return error;
3899 bno = *last_block - 1;
3900 ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got,
3901 &prev);
3902 if (eof || xfs_bmbt_get_startoff(ep) > bno) {
3903 if (prev.br_startoff == NULLFILEOFF)
3904 *last_block = 0;
3905 else
3906 *last_block = prev.br_startoff + prev.br_blockcount;
3907 }
3908 /*
3909 * Otherwise *last_block is already the right answer.
3910 */
3911 return 0;
3912}
3913
3914STATIC int
3915xfs_bmap_last_extent(
3916 struct xfs_trans *tp,
3917 struct xfs_inode *ip,
3918 int whichfork,
3919 struct xfs_bmbt_irec *rec,
3920 int *is_empty)
3921{
3922 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
3923 int error;
3924 int nextents;
3925
3926 if (!(ifp->if_flags & XFS_IFEXTENTS)) {
3927 error = xfs_iread_extents(tp, ip, whichfork);
3928 if (error)
3929 return error;
3930 }
3931
3932 nextents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t);
3933 if (nextents == 0) {
3934 *is_empty = 1;
3935 return 0;
3936 }
3937
3938 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, nextents - 1), rec);
3939 *is_empty = 0;
3940 return 0;
3941}
3942
3943/*
3944 * Check the last inode extent to determine whether this allocation will result
3945 * in blocks being allocated at the end of the file. When we allocate new data
3946 * blocks at the end of the file which do not start at the previous data block,
3947 * we will try to align the new blocks at stripe unit boundaries.
3948 *
3949 * Returns 0 in bma->aeof if the file (fork) is empty as any new write will be
3950 * at, or past the EOF.
3951 */
3952STATIC int
3953xfs_bmap_isaeof(
3954 struct xfs_bmalloca *bma,
3955 int whichfork)
3956{
3957 struct xfs_bmbt_irec rec;
3958 int is_empty;
3959 int error;
3960
3961 bma->aeof = 0;
3962 error = xfs_bmap_last_extent(NULL, bma->ip, whichfork, &rec,
3963 &is_empty);
3964 if (error || is_empty)
3965 return error;
3966
3967 /*
3968 * Check if we are allocation or past the last extent, or at least into
3969 * the last delayed allocated extent.
3970 */
3971 bma->aeof = bma->offset >= rec.br_startoff + rec.br_blockcount ||
3972 (bma->offset >= rec.br_startoff &&
3973 isnullstartblock(rec.br_startblock));
3974 return 0;
3975}
3976
3977/*
3978 * Check if the endoff is outside the last extent. If so the caller will grow
3979 * the allocation to a stripe unit boundary. All offsets are considered outside
3980 * the end of file for an empty fork, so 1 is returned in *eof in that case.
3981 */
3982int
3983xfs_bmap_eof(
3984 struct xfs_inode *ip,
3985 xfs_fileoff_t endoff,
3986 int whichfork,
3987 int *eof)
3988{
3989 struct xfs_bmbt_irec rec;
3990 int error;
3991
3992 error = xfs_bmap_last_extent(NULL, ip, whichfork, &rec, eof);
3993 if (error || *eof)
3994 return error;
3995
3996 *eof = endoff >= rec.br_startoff + rec.br_blockcount;
3997 return 0;
3998}
3999
4000/*
4001 * Returns the file-relative block number of the first block past eof in
4002 * the file. This is not based on i_size, it is based on the extent records.
4003 * Returns 0 for local files, as they do not have extent records.
4004 */
4005int
4006xfs_bmap_last_offset(
4007 struct xfs_trans *tp,
4008 struct xfs_inode *ip,
4009 xfs_fileoff_t *last_block,
4010 int whichfork)
4011{
4012 struct xfs_bmbt_irec rec;
4013 int is_empty;
4014 int error;
4015
4016 *last_block = 0;
4017
4018 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL)
4019 return 0;
4020
4021 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
4022 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)
4023 return XFS_ERROR(EIO);
4024
4025 error = xfs_bmap_last_extent(NULL, ip, whichfork, &rec, &is_empty);
4026 if (error || is_empty)
4027 return error;
4028
4029 *last_block = rec.br_startoff + rec.br_blockcount;
4030 return 0;
4031}
4032
4033/*
4034 * Returns whether the selected fork of the inode has exactly one
4035 * block or not. For the data fork we check this matches di_size,
4036 * implying the file's range is 0..bsize-1.
4037 */
4038int /* 1=>1 block, 0=>otherwise */
4039xfs_bmap_one_block(
4040 xfs_inode_t *ip, /* incore inode */
4041 int whichfork) /* data or attr fork */
4042{
4043 xfs_bmbt_rec_host_t *ep; /* ptr to fork's extent */
4044 xfs_ifork_t *ifp; /* inode fork pointer */
4045 int rval; /* return value */
4046 xfs_bmbt_irec_t s; /* internal version of extent */
4047
4048#ifndef DEBUG
4049 if (whichfork == XFS_DATA_FORK)
4050 return XFS_ISIZE(ip) == ip->i_mount->m_sb.sb_blocksize;
4051#endif /* !DEBUG */
4052 if (XFS_IFORK_NEXTENTS(ip, whichfork) != 1)
4053 return 0;
4054 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)
4055 return 0;
4056 ifp = XFS_IFORK_PTR(ip, whichfork);
4057 ASSERT(ifp->if_flags & XFS_IFEXTENTS);
4058 ep = xfs_iext_get_ext(ifp, 0);
4059 xfs_bmbt_get_all(ep, &s);
4060 rval = s.br_startoff == 0 && s.br_blockcount == 1;
4061 if (rval && whichfork == XFS_DATA_FORK)
4062 ASSERT(XFS_ISIZE(ip) == ip->i_mount->m_sb.sb_blocksize);
4063 return rval;
4064}
4065
4066STATIC int
4067xfs_bmap_sanity_check(
4068 struct xfs_mount *mp,
4069 struct xfs_buf *bp,
4070 int level)
4071{
4072 struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
4073
4074 if (block->bb_magic != cpu_to_be32(XFS_BMAP_MAGIC) ||
4075 be16_to_cpu(block->bb_level) != level ||
4076 be16_to_cpu(block->bb_numrecs) == 0 ||
4077 be16_to_cpu(block->bb_numrecs) > mp->m_bmap_dmxr[level != 0])
4078 return 0;
4079 return 1;
4080}
4081
4082/*
4083 * Read in the extents to if_extents.
4084 * All inode fields are set up by caller, we just traverse the btree
4085 * and copy the records in. If the file system cannot contain unwritten
4086 * extents, the records are checked for no "state" flags.
4087 */
4088int /* error */
4089xfs_bmap_read_extents(
4090 xfs_trans_t *tp, /* transaction pointer */
4091 xfs_inode_t *ip, /* incore inode */
4092 int whichfork) /* data or attr fork */
4093{
4094 struct xfs_btree_block *block; /* current btree block */
4095 xfs_fsblock_t bno; /* block # of "block" */
4096 xfs_buf_t *bp; /* buffer for "block" */
4097 int error; /* error return value */
4098 xfs_exntfmt_t exntf; /* XFS_EXTFMT_NOSTATE, if checking */
4099 xfs_extnum_t i, j; /* index into the extents list */
4100 xfs_ifork_t *ifp; /* fork structure */
4101 int level; /* btree level, for checking */
4102 xfs_mount_t *mp; /* file system mount structure */
4103 __be64 *pp; /* pointer to block address */
4104 /* REFERENCED */
4105 xfs_extnum_t room; /* number of entries there's room for */
4106
4107 bno = NULLFSBLOCK;
4108 mp = ip->i_mount;
4109 ifp = XFS_IFORK_PTR(ip, whichfork);
4110 exntf = (whichfork != XFS_DATA_FORK) ? XFS_EXTFMT_NOSTATE :
4111 XFS_EXTFMT_INODE(ip);
4112 block = ifp->if_broot;
4113 /*
4114 * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
4115 */
4116 level = be16_to_cpu(block->bb_level);
4117 ASSERT(level > 0);
4118 pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes);
4119 bno = be64_to_cpu(*pp);
4120 ASSERT(bno != NULLDFSBNO);
4121 ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount);
4122 ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks);
4123 /*
4124 * Go down the tree until leaf level is reached, following the first
4125 * pointer (leftmost) at each level.
4126 */
4127 while (level-- > 0) {
4128 error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp,
4129 XFS_BMAP_BTREE_REF, &xfs_bmbt_buf_ops);
4130 if (error)
4131 return error;
4132 block = XFS_BUF_TO_BLOCK(bp);
4133 XFS_WANT_CORRUPTED_GOTO(
4134 xfs_bmap_sanity_check(mp, bp, level),
4135 error0);
4136 if (level == 0)
4137 break;
4138 pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]);
4139 bno = be64_to_cpu(*pp);
4140 XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, bno), error0);
4141 xfs_trans_brelse(tp, bp);
4142 }
4143 /*
4144 * Here with bp and block set to the leftmost leaf node in the tree.
4145 */
4146 room = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
4147 i = 0;
4148 /*
4149 * Loop over all leaf nodes. Copy information to the extent records.
4150 */
4151 for (;;) {
4152 xfs_bmbt_rec_t *frp;
4153 xfs_fsblock_t nextbno;
4154 xfs_extnum_t num_recs;
4155 xfs_extnum_t start;
4156
4157 num_recs = xfs_btree_get_numrecs(block);
4158 if (unlikely(i + num_recs > room)) {
4159 ASSERT(i + num_recs <= room);
4160 xfs_warn(ip->i_mount,
4161 "corrupt dinode %Lu, (btree extents).",
4162 (unsigned long long) ip->i_ino);
4163 XFS_CORRUPTION_ERROR("xfs_bmap_read_extents(1)",
4164 XFS_ERRLEVEL_LOW, ip->i_mount, block);
4165 goto error0;
4166 }
4167 XFS_WANT_CORRUPTED_GOTO(
4168 xfs_bmap_sanity_check(mp, bp, 0),
4169 error0);
4170 /*
4171 * Read-ahead the next leaf block, if any.
4172 */
4173 nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib);
4174 if (nextbno != NULLFSBLOCK)
4175 xfs_btree_reada_bufl(mp, nextbno, 1,
4176 &xfs_bmbt_buf_ops);
4177 /*
4178 * Copy records into the extent records.
4179 */
4180 frp = XFS_BMBT_REC_ADDR(mp, block, 1);
4181 start = i;
4182 for (j = 0; j < num_recs; j++, i++, frp++) {
4183 xfs_bmbt_rec_host_t *trp = xfs_iext_get_ext(ifp, i);
4184 trp->l0 = be64_to_cpu(frp->l0);
4185 trp->l1 = be64_to_cpu(frp->l1);
4186 }
4187 if (exntf == XFS_EXTFMT_NOSTATE) {
4188 /*
4189 * Check all attribute bmap btree records and
4190 * any "older" data bmap btree records for a
4191 * set bit in the "extent flag" position.
4192 */
4193 if (unlikely(xfs_check_nostate_extents(ifp,
4194 start, num_recs))) {
4195 XFS_ERROR_REPORT("xfs_bmap_read_extents(2)",
4196 XFS_ERRLEVEL_LOW,
4197 ip->i_mount);
4198 goto error0;
4199 }
4200 }
4201 xfs_trans_brelse(tp, bp);
4202 bno = nextbno;
4203 /*
4204 * If we've reached the end, stop.
4205 */
4206 if (bno == NULLFSBLOCK)
4207 break;
4208 error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp,
4209 XFS_BMAP_BTREE_REF, &xfs_bmbt_buf_ops);
4210 if (error)
4211 return error;
4212 block = XFS_BUF_TO_BLOCK(bp);
4213 }
4214 ASSERT(i == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)));
4215 ASSERT(i == XFS_IFORK_NEXTENTS(ip, whichfork));
4216 XFS_BMAP_TRACE_EXLIST(ip, i, whichfork);
4217 return 0;
4218error0:
4219 xfs_trans_brelse(tp, bp);
4220 return XFS_ERROR(EFSCORRUPTED);
4221}
4222
4223#ifdef DEBUG
4224/*
4225 * Add bmap trace insert entries for all the contents of the extent records.
4226 */
4227void
4228xfs_bmap_trace_exlist(
4229 xfs_inode_t *ip, /* incore inode pointer */
4230 xfs_extnum_t cnt, /* count of entries in the list */
4231 int whichfork, /* data or attr fork */
4232 unsigned long caller_ip)
4233{
4234 xfs_extnum_t idx; /* extent record index */
4235 xfs_ifork_t *ifp; /* inode fork pointer */
4236 int state = 0;
4237
4238 if (whichfork == XFS_ATTR_FORK)
4239 state |= BMAP_ATTRFORK;
4240
4241 ifp = XFS_IFORK_PTR(ip, whichfork);
4242 ASSERT(cnt == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)));
4243 for (idx = 0; idx < cnt; idx++)
4244 trace_xfs_extlist(ip, idx, whichfork, caller_ip);
4245}
4246
4247/*
4248 * Validate that the bmbt_irecs being returned from bmapi are valid
4249 * given the callers original parameters. Specifically check the
4250 * ranges of the returned irecs to ensure that they only extent beyond
4251 * the given parameters if the XFS_BMAPI_ENTIRE flag was set.
4252 */
4253STATIC void
4254xfs_bmap_validate_ret(
4255 xfs_fileoff_t bno,
4256 xfs_filblks_t len,
4257 int flags,
4258 xfs_bmbt_irec_t *mval,
4259 int nmap,
4260 int ret_nmap)
4261{
4262 int i; /* index to map values */
4263
4264 ASSERT(ret_nmap <= nmap);
4265
4266 for (i = 0; i < ret_nmap; i++) {
4267 ASSERT(mval[i].br_blockcount > 0);
4268 if (!(flags & XFS_BMAPI_ENTIRE)) {
4269 ASSERT(mval[i].br_startoff >= bno);
4270 ASSERT(mval[i].br_blockcount <= len);
4271 ASSERT(mval[i].br_startoff + mval[i].br_blockcount <=
4272 bno + len);
4273 } else {
4274 ASSERT(mval[i].br_startoff < bno + len);
4275 ASSERT(mval[i].br_startoff + mval[i].br_blockcount >
4276 bno);
4277 }
4278 ASSERT(i == 0 ||
4279 mval[i - 1].br_startoff + mval[i - 1].br_blockcount ==
4280 mval[i].br_startoff);
4281 ASSERT(mval[i].br_startblock != DELAYSTARTBLOCK &&
4282 mval[i].br_startblock != HOLESTARTBLOCK);
4283 ASSERT(mval[i].br_state == XFS_EXT_NORM ||
4284 mval[i].br_state == XFS_EXT_UNWRITTEN);
4285 }
4286}
4287#endif /* DEBUG */
4288
4289
4290/*
4291 * Trim the returned map to the required bounds 4255 * Trim the returned map to the required bounds
4292 */ 4256 */
4293STATIC void 4257STATIC void
@@ -5151,6 +5115,328 @@ error0:
5151} 5115}
5152 5116
5153/* 5117/*
5118 * Called by xfs_bmapi to update file extent records and the btree
5119 * after removing space (or undoing a delayed allocation).
5120 */
5121STATIC int /* error */
5122xfs_bmap_del_extent(
5123 xfs_inode_t *ip, /* incore inode pointer */
5124 xfs_trans_t *tp, /* current transaction pointer */
5125 xfs_extnum_t *idx, /* extent number to update/delete */
5126 xfs_bmap_free_t *flist, /* list of extents to be freed */
5127 xfs_btree_cur_t *cur, /* if null, not a btree */
5128 xfs_bmbt_irec_t *del, /* data to remove from extents */
5129 int *logflagsp, /* inode logging flags */
5130 int whichfork) /* data or attr fork */
5131{
5132 xfs_filblks_t da_new; /* new delay-alloc indirect blocks */
5133 xfs_filblks_t da_old; /* old delay-alloc indirect blocks */
5134 xfs_fsblock_t del_endblock=0; /* first block past del */
5135 xfs_fileoff_t del_endoff; /* first offset past del */
5136 int delay; /* current block is delayed allocated */
5137 int do_fx; /* free extent at end of routine */
5138 xfs_bmbt_rec_host_t *ep; /* current extent entry pointer */
5139 int error; /* error return value */
5140 int flags; /* inode logging flags */
5141 xfs_bmbt_irec_t got; /* current extent entry */
5142 xfs_fileoff_t got_endoff; /* first offset past got */
5143 int i; /* temp state */
5144 xfs_ifork_t *ifp; /* inode fork pointer */
5145 xfs_mount_t *mp; /* mount structure */
5146 xfs_filblks_t nblks; /* quota/sb block count */
5147 xfs_bmbt_irec_t new; /* new record to be inserted */
5148 /* REFERENCED */
5149 uint qfield; /* quota field to update */
5150 xfs_filblks_t temp; /* for indirect length calculations */
5151 xfs_filblks_t temp2; /* for indirect length calculations */
5152 int state = 0;
5153
5154 XFS_STATS_INC(xs_del_exlist);
5155
5156 if (whichfork == XFS_ATTR_FORK)
5157 state |= BMAP_ATTRFORK;
5158
5159 mp = ip->i_mount;
5160 ifp = XFS_IFORK_PTR(ip, whichfork);
5161 ASSERT((*idx >= 0) && (*idx < ifp->if_bytes /
5162 (uint)sizeof(xfs_bmbt_rec_t)));
5163 ASSERT(del->br_blockcount > 0);
5164 ep = xfs_iext_get_ext(ifp, *idx);
5165 xfs_bmbt_get_all(ep, &got);
5166 ASSERT(got.br_startoff <= del->br_startoff);
5167 del_endoff = del->br_startoff + del->br_blockcount;
5168 got_endoff = got.br_startoff + got.br_blockcount;
5169 ASSERT(got_endoff >= del_endoff);
5170 delay = isnullstartblock(got.br_startblock);
5171 ASSERT(isnullstartblock(del->br_startblock) == delay);
5172 flags = 0;
5173 qfield = 0;
5174 error = 0;
5175 /*
5176 * If deleting a real allocation, must free up the disk space.
5177 */
5178 if (!delay) {
5179 flags = XFS_ILOG_CORE;
5180 /*
5181 * Realtime allocation. Free it and record di_nblocks update.
5182 */
5183 if (whichfork == XFS_DATA_FORK && XFS_IS_REALTIME_INODE(ip)) {
5184 xfs_fsblock_t bno;
5185 xfs_filblks_t len;
5186
5187 ASSERT(do_mod(del->br_blockcount,
5188 mp->m_sb.sb_rextsize) == 0);
5189 ASSERT(do_mod(del->br_startblock,
5190 mp->m_sb.sb_rextsize) == 0);
5191 bno = del->br_startblock;
5192 len = del->br_blockcount;
5193 do_div(bno, mp->m_sb.sb_rextsize);
5194 do_div(len, mp->m_sb.sb_rextsize);
5195 error = xfs_rtfree_extent(tp, bno, (xfs_extlen_t)len);
5196 if (error)
5197 goto done;
5198 do_fx = 0;
5199 nblks = len * mp->m_sb.sb_rextsize;
5200 qfield = XFS_TRANS_DQ_RTBCOUNT;
5201 }
5202 /*
5203 * Ordinary allocation.
5204 */
5205 else {
5206 do_fx = 1;
5207 nblks = del->br_blockcount;
5208 qfield = XFS_TRANS_DQ_BCOUNT;
5209 }
5210 /*
5211 * Set up del_endblock and cur for later.
5212 */
5213 del_endblock = del->br_startblock + del->br_blockcount;
5214 if (cur) {
5215 if ((error = xfs_bmbt_lookup_eq(cur, got.br_startoff,
5216 got.br_startblock, got.br_blockcount,
5217 &i)))
5218 goto done;
5219 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
5220 }
5221 da_old = da_new = 0;
5222 } else {
5223 da_old = startblockval(got.br_startblock);
5224 da_new = 0;
5225 nblks = 0;
5226 do_fx = 0;
5227 }
5228 /*
5229 * Set flag value to use in switch statement.
5230 * Left-contig is 2, right-contig is 1.
5231 */
5232 switch (((got.br_startoff == del->br_startoff) << 1) |
5233 (got_endoff == del_endoff)) {
5234 case 3:
5235 /*
5236 * Matches the whole extent. Delete the entry.
5237 */
5238 xfs_iext_remove(ip, *idx, 1,
5239 whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0);
5240 --*idx;
5241 if (delay)
5242 break;
5243
5244 XFS_IFORK_NEXT_SET(ip, whichfork,
5245 XFS_IFORK_NEXTENTS(ip, whichfork) - 1);
5246 flags |= XFS_ILOG_CORE;
5247 if (!cur) {
5248 flags |= xfs_ilog_fext(whichfork);
5249 break;
5250 }
5251 if ((error = xfs_btree_delete(cur, &i)))
5252 goto done;
5253 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
5254 break;
5255
5256 case 2:
5257 /*
5258 * Deleting the first part of the extent.
5259 */
5260 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
5261 xfs_bmbt_set_startoff(ep, del_endoff);
5262 temp = got.br_blockcount - del->br_blockcount;
5263 xfs_bmbt_set_blockcount(ep, temp);
5264 if (delay) {
5265 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
5266 da_old);
5267 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
5268 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
5269 da_new = temp;
5270 break;
5271 }
5272 xfs_bmbt_set_startblock(ep, del_endblock);
5273 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
5274 if (!cur) {
5275 flags |= xfs_ilog_fext(whichfork);
5276 break;
5277 }
5278 if ((error = xfs_bmbt_update(cur, del_endoff, del_endblock,
5279 got.br_blockcount - del->br_blockcount,
5280 got.br_state)))
5281 goto done;
5282 break;
5283
5284 case 1:
5285 /*
5286 * Deleting the last part of the extent.
5287 */
5288 temp = got.br_blockcount - del->br_blockcount;
5289 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
5290 xfs_bmbt_set_blockcount(ep, temp);
5291 if (delay) {
5292 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
5293 da_old);
5294 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
5295 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
5296 da_new = temp;
5297 break;
5298 }
5299 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
5300 if (!cur) {
5301 flags |= xfs_ilog_fext(whichfork);
5302 break;
5303 }
5304 if ((error = xfs_bmbt_update(cur, got.br_startoff,
5305 got.br_startblock,
5306 got.br_blockcount - del->br_blockcount,
5307 got.br_state)))
5308 goto done;
5309 break;
5310
5311 case 0:
5312 /*
5313 * Deleting the middle of the extent.
5314 */
5315 temp = del->br_startoff - got.br_startoff;
5316 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
5317 xfs_bmbt_set_blockcount(ep, temp);
5318 new.br_startoff = del_endoff;
5319 temp2 = got_endoff - del_endoff;
5320 new.br_blockcount = temp2;
5321 new.br_state = got.br_state;
5322 if (!delay) {
5323 new.br_startblock = del_endblock;
5324 flags |= XFS_ILOG_CORE;
5325 if (cur) {
5326 if ((error = xfs_bmbt_update(cur,
5327 got.br_startoff,
5328 got.br_startblock, temp,
5329 got.br_state)))
5330 goto done;
5331 if ((error = xfs_btree_increment(cur, 0, &i)))
5332 goto done;
5333 cur->bc_rec.b = new;
5334 error = xfs_btree_insert(cur, &i);
5335 if (error && error != ENOSPC)
5336 goto done;
5337 /*
5338 * If get no-space back from btree insert,
5339 * it tried a split, and we have a zero
5340 * block reservation.
5341 * Fix up our state and return the error.
5342 */
5343 if (error == ENOSPC) {
5344 /*
5345 * Reset the cursor, don't trust
5346 * it after any insert operation.
5347 */
5348 if ((error = xfs_bmbt_lookup_eq(cur,
5349 got.br_startoff,
5350 got.br_startblock,
5351 temp, &i)))
5352 goto done;
5353 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
5354 /*
5355 * Update the btree record back
5356 * to the original value.
5357 */
5358 if ((error = xfs_bmbt_update(cur,
5359 got.br_startoff,
5360 got.br_startblock,
5361 got.br_blockcount,
5362 got.br_state)))
5363 goto done;
5364 /*
5365 * Reset the extent record back
5366 * to the original value.
5367 */
5368 xfs_bmbt_set_blockcount(ep,
5369 got.br_blockcount);
5370 flags = 0;
5371 error = XFS_ERROR(ENOSPC);
5372 goto done;
5373 }
5374 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
5375 } else
5376 flags |= xfs_ilog_fext(whichfork);
5377 XFS_IFORK_NEXT_SET(ip, whichfork,
5378 XFS_IFORK_NEXTENTS(ip, whichfork) + 1);
5379 } else {
5380 ASSERT(whichfork == XFS_DATA_FORK);
5381 temp = xfs_bmap_worst_indlen(ip, temp);
5382 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
5383 temp2 = xfs_bmap_worst_indlen(ip, temp2);
5384 new.br_startblock = nullstartblock((int)temp2);
5385 da_new = temp + temp2;
5386 while (da_new > da_old) {
5387 if (temp) {
5388 temp--;
5389 da_new--;
5390 xfs_bmbt_set_startblock(ep,
5391 nullstartblock((int)temp));
5392 }
5393 if (da_new == da_old)
5394 break;
5395 if (temp2) {
5396 temp2--;
5397 da_new--;
5398 new.br_startblock =
5399 nullstartblock((int)temp2);
5400 }
5401 }
5402 }
5403 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
5404 xfs_iext_insert(ip, *idx + 1, 1, &new, state);
5405 ++*idx;
5406 break;
5407 }
5408 /*
5409 * If we need to, add to list of extents to delete.
5410 */
5411 if (do_fx)
5412 xfs_bmap_add_free(del->br_startblock, del->br_blockcount, flist,
5413 mp);
5414 /*
5415 * Adjust inode # blocks in the file.
5416 */
5417 if (nblks)
5418 ip->i_d.di_nblocks -= nblks;
5419 /*
5420 * Adjust quota data.
5421 */
5422 if (qfield)
5423 xfs_trans_mod_dquot_byino(tp, ip, qfield, (long)-nblks);
5424
5425 /*
5426 * Account for change in delayed indirect blocks.
5427 * Nothing to do for disk quota accounting here.
5428 */
5429 ASSERT(da_old >= da_new);
5430 if (da_old > da_new) {
5431 xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS,
5432 (int64_t)(da_old - da_new), 0);
5433 }
5434done:
5435 *logflagsp = flags;
5436 return error;
5437}
5438
5439/*
5154 * Unmap (remove) blocks from a file. 5440 * Unmap (remove) blocks from a file.
5155 * If nexts is nonzero then the number of extents to remove is limited to 5441 * If nexts is nonzero then the number of extents to remove is limited to
5156 * that value. If not all extents in the block range can be removed then 5442 * that value. If not all extents in the block range can be removed then
@@ -5811,416 +6097,6 @@ xfs_getbmap(
5811 return error; 6097 return error;
5812} 6098}
5813 6099
5814#ifdef DEBUG
5815STATIC struct xfs_buf *
5816xfs_bmap_get_bp(
5817 struct xfs_btree_cur *cur,
5818 xfs_fsblock_t bno)
5819{
5820 struct xfs_log_item_desc *lidp;
5821 int i;
5822
5823 if (!cur)
5824 return NULL;
5825
5826 for (i = 0; i < XFS_BTREE_MAXLEVELS; i++) {
5827 if (!cur->bc_bufs[i])
5828 break;
5829 if (XFS_BUF_ADDR(cur->bc_bufs[i]) == bno)
5830 return cur->bc_bufs[i];
5831 }
5832
5833 /* Chase down all the log items to see if the bp is there */
5834 list_for_each_entry(lidp, &cur->bc_tp->t_items, lid_trans) {
5835 struct xfs_buf_log_item *bip;
5836 bip = (struct xfs_buf_log_item *)lidp->lid_item;
5837 if (bip->bli_item.li_type == XFS_LI_BUF &&
5838 XFS_BUF_ADDR(bip->bli_buf) == bno)
5839 return bip->bli_buf;
5840 }
5841
5842 return NULL;
5843}
5844
5845STATIC void
5846xfs_check_block(
5847 struct xfs_btree_block *block,
5848 xfs_mount_t *mp,
5849 int root,
5850 short sz)
5851{
5852 int i, j, dmxr;
5853 __be64 *pp, *thispa; /* pointer to block address */
5854 xfs_bmbt_key_t *prevp, *keyp;
5855
5856 ASSERT(be16_to_cpu(block->bb_level) > 0);
5857
5858 prevp = NULL;
5859 for( i = 1; i <= xfs_btree_get_numrecs(block); i++) {
5860 dmxr = mp->m_bmap_dmxr[0];
5861 keyp = XFS_BMBT_KEY_ADDR(mp, block, i);
5862
5863 if (prevp) {
5864 ASSERT(be64_to_cpu(prevp->br_startoff) <
5865 be64_to_cpu(keyp->br_startoff));
5866 }
5867 prevp = keyp;
5868
5869 /*
5870 * Compare the block numbers to see if there are dups.
5871 */
5872 if (root)
5873 pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, i, sz);
5874 else
5875 pp = XFS_BMBT_PTR_ADDR(mp, block, i, dmxr);
5876
5877 for (j = i+1; j <= be16_to_cpu(block->bb_numrecs); j++) {
5878 if (root)
5879 thispa = XFS_BMAP_BROOT_PTR_ADDR(mp, block, j, sz);
5880 else
5881 thispa = XFS_BMBT_PTR_ADDR(mp, block, j, dmxr);
5882 if (*thispa == *pp) {
5883 xfs_warn(mp, "%s: thispa(%d) == pp(%d) %Ld",
5884 __func__, j, i,
5885 (unsigned long long)be64_to_cpu(*thispa));
5886 panic("%s: ptrs are equal in node\n",
5887 __func__);
5888 }
5889 }
5890 }
5891}
5892
5893/*
5894 * Check that the extents for the inode ip are in the right order in all
5895 * btree leaves.
5896 */
5897
5898STATIC void
5899xfs_bmap_check_leaf_extents(
5900 xfs_btree_cur_t *cur, /* btree cursor or null */
5901 xfs_inode_t *ip, /* incore inode pointer */
5902 int whichfork) /* data or attr fork */
5903{
5904 struct xfs_btree_block *block; /* current btree block */
5905 xfs_fsblock_t bno; /* block # of "block" */
5906 xfs_buf_t *bp; /* buffer for "block" */
5907 int error; /* error return value */
5908 xfs_extnum_t i=0, j; /* index into the extents list */
5909 xfs_ifork_t *ifp; /* fork structure */
5910 int level; /* btree level, for checking */
5911 xfs_mount_t *mp; /* file system mount structure */
5912 __be64 *pp; /* pointer to block address */
5913 xfs_bmbt_rec_t *ep; /* pointer to current extent */
5914 xfs_bmbt_rec_t last = {0, 0}; /* last extent in prev block */
5915 xfs_bmbt_rec_t *nextp; /* pointer to next extent */
5916 int bp_release = 0;
5917
5918 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) {
5919 return;
5920 }
5921
5922 bno = NULLFSBLOCK;
5923 mp = ip->i_mount;
5924 ifp = XFS_IFORK_PTR(ip, whichfork);
5925 block = ifp->if_broot;
5926 /*
5927 * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
5928 */
5929 level = be16_to_cpu(block->bb_level);
5930 ASSERT(level > 0);
5931 xfs_check_block(block, mp, 1, ifp->if_broot_bytes);
5932 pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes);
5933 bno = be64_to_cpu(*pp);
5934
5935 ASSERT(bno != NULLDFSBNO);
5936 ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount);
5937 ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks);
5938
5939 /*
5940 * Go down the tree until leaf level is reached, following the first
5941 * pointer (leftmost) at each level.
5942 */
5943 while (level-- > 0) {
5944 /* See if buf is in cur first */
5945 bp_release = 0;
5946 bp = xfs_bmap_get_bp(cur, XFS_FSB_TO_DADDR(mp, bno));
5947 if (!bp) {
5948 bp_release = 1;
5949 error = xfs_btree_read_bufl(mp, NULL, bno, 0, &bp,
5950 XFS_BMAP_BTREE_REF,
5951 &xfs_bmbt_buf_ops);
5952 if (error)
5953 goto error_norelse;
5954 }
5955 block = XFS_BUF_TO_BLOCK(bp);
5956 XFS_WANT_CORRUPTED_GOTO(
5957 xfs_bmap_sanity_check(mp, bp, level),
5958 error0);
5959 if (level == 0)
5960 break;
5961
5962 /*
5963 * Check this block for basic sanity (increasing keys and
5964 * no duplicate blocks).
5965 */
5966
5967 xfs_check_block(block, mp, 0, 0);
5968 pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]);
5969 bno = be64_to_cpu(*pp);
5970 XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, bno), error0);
5971 if (bp_release) {
5972 bp_release = 0;
5973 xfs_trans_brelse(NULL, bp);
5974 }
5975 }
5976
5977 /*
5978 * Here with bp and block set to the leftmost leaf node in the tree.
5979 */
5980 i = 0;
5981
5982 /*
5983 * Loop over all leaf nodes checking that all extents are in the right order.
5984 */
5985 for (;;) {
5986 xfs_fsblock_t nextbno;
5987 xfs_extnum_t num_recs;
5988
5989
5990 num_recs = xfs_btree_get_numrecs(block);
5991
5992 /*
5993 * Read-ahead the next leaf block, if any.
5994 */
5995
5996 nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib);
5997
5998 /*
5999 * Check all the extents to make sure they are OK.
6000 * If we had a previous block, the last entry should
6001 * conform with the first entry in this one.
6002 */
6003
6004 ep = XFS_BMBT_REC_ADDR(mp, block, 1);
6005 if (i) {
6006 ASSERT(xfs_bmbt_disk_get_startoff(&last) +
6007 xfs_bmbt_disk_get_blockcount(&last) <=
6008 xfs_bmbt_disk_get_startoff(ep));
6009 }
6010 for (j = 1; j < num_recs; j++) {
6011 nextp = XFS_BMBT_REC_ADDR(mp, block, j + 1);
6012 ASSERT(xfs_bmbt_disk_get_startoff(ep) +
6013 xfs_bmbt_disk_get_blockcount(ep) <=
6014 xfs_bmbt_disk_get_startoff(nextp));
6015 ep = nextp;
6016 }
6017
6018 last = *ep;
6019 i += num_recs;
6020 if (bp_release) {
6021 bp_release = 0;
6022 xfs_trans_brelse(NULL, bp);
6023 }
6024 bno = nextbno;
6025 /*
6026 * If we've reached the end, stop.
6027 */
6028 if (bno == NULLFSBLOCK)
6029 break;
6030
6031 bp_release = 0;
6032 bp = xfs_bmap_get_bp(cur, XFS_FSB_TO_DADDR(mp, bno));
6033 if (!bp) {
6034 bp_release = 1;
6035 error = xfs_btree_read_bufl(mp, NULL, bno, 0, &bp,
6036 XFS_BMAP_BTREE_REF,
6037 &xfs_bmbt_buf_ops);
6038 if (error)
6039 goto error_norelse;
6040 }
6041 block = XFS_BUF_TO_BLOCK(bp);
6042 }
6043 if (bp_release) {
6044 bp_release = 0;
6045 xfs_trans_brelse(NULL, bp);
6046 }
6047 return;
6048
6049error0:
6050 xfs_warn(mp, "%s: at error0", __func__);
6051 if (bp_release)
6052 xfs_trans_brelse(NULL, bp);
6053error_norelse:
6054 xfs_warn(mp, "%s: BAD after btree leaves for %d extents",
6055 __func__, i);
6056 panic("%s: CORRUPTED BTREE OR SOMETHING", __func__);
6057 return;
6058}
6059#endif
6060
6061/*
6062 * Count fsblocks of the given fork.
6063 */
6064int /* error */
6065xfs_bmap_count_blocks(
6066 xfs_trans_t *tp, /* transaction pointer */
6067 xfs_inode_t *ip, /* incore inode */
6068 int whichfork, /* data or attr fork */
6069 int *count) /* out: count of blocks */
6070{
6071 struct xfs_btree_block *block; /* current btree block */
6072 xfs_fsblock_t bno; /* block # of "block" */
6073 xfs_ifork_t *ifp; /* fork structure */
6074 int level; /* btree level, for checking */
6075 xfs_mount_t *mp; /* file system mount structure */
6076 __be64 *pp; /* pointer to block address */
6077
6078 bno = NULLFSBLOCK;
6079 mp = ip->i_mount;
6080 ifp = XFS_IFORK_PTR(ip, whichfork);
6081 if ( XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS ) {
6082 xfs_bmap_count_leaves(ifp, 0,
6083 ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t),
6084 count);
6085 return 0;
6086 }
6087
6088 /*
6089 * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
6090 */
6091 block = ifp->if_broot;
6092 level = be16_to_cpu(block->bb_level);
6093 ASSERT(level > 0);
6094 pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes);
6095 bno = be64_to_cpu(*pp);
6096 ASSERT(bno != NULLDFSBNO);
6097 ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount);
6098 ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks);
6099
6100 if (unlikely(xfs_bmap_count_tree(mp, tp, ifp, bno, level, count) < 0)) {
6101 XFS_ERROR_REPORT("xfs_bmap_count_blocks(2)", XFS_ERRLEVEL_LOW,
6102 mp);
6103 return XFS_ERROR(EFSCORRUPTED);
6104 }
6105
6106 return 0;
6107}
6108
6109/*
6110 * Recursively walks each level of a btree
6111 * to count total fsblocks is use.
6112 */
6113STATIC int /* error */
6114xfs_bmap_count_tree(
6115 xfs_mount_t *mp, /* file system mount point */
6116 xfs_trans_t *tp, /* transaction pointer */
6117 xfs_ifork_t *ifp, /* inode fork pointer */
6118 xfs_fsblock_t blockno, /* file system block number */
6119 int levelin, /* level in btree */
6120 int *count) /* Count of blocks */
6121{
6122 int error;
6123 xfs_buf_t *bp, *nbp;
6124 int level = levelin;
6125 __be64 *pp;
6126 xfs_fsblock_t bno = blockno;
6127 xfs_fsblock_t nextbno;
6128 struct xfs_btree_block *block, *nextblock;
6129 int numrecs;
6130
6131 error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, XFS_BMAP_BTREE_REF,
6132 &xfs_bmbt_buf_ops);
6133 if (error)
6134 return error;
6135 *count += 1;
6136 block = XFS_BUF_TO_BLOCK(bp);
6137
6138 if (--level) {
6139 /* Not at node above leaves, count this level of nodes */
6140 nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib);
6141 while (nextbno != NULLFSBLOCK) {
6142 error = xfs_btree_read_bufl(mp, tp, nextbno, 0, &nbp,
6143 XFS_BMAP_BTREE_REF,
6144 &xfs_bmbt_buf_ops);
6145 if (error)
6146 return error;
6147 *count += 1;
6148 nextblock = XFS_BUF_TO_BLOCK(nbp);
6149 nextbno = be64_to_cpu(nextblock->bb_u.l.bb_rightsib);
6150 xfs_trans_brelse(tp, nbp);
6151 }
6152
6153 /* Dive to the next level */
6154 pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]);
6155 bno = be64_to_cpu(*pp);
6156 if (unlikely((error =
6157 xfs_bmap_count_tree(mp, tp, ifp, bno, level, count)) < 0)) {
6158 xfs_trans_brelse(tp, bp);
6159 XFS_ERROR_REPORT("xfs_bmap_count_tree(1)",
6160 XFS_ERRLEVEL_LOW, mp);
6161 return XFS_ERROR(EFSCORRUPTED);
6162 }
6163 xfs_trans_brelse(tp, bp);
6164 } else {
6165 /* count all level 1 nodes and their leaves */
6166 for (;;) {
6167 nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib);
6168 numrecs = be16_to_cpu(block->bb_numrecs);
6169 xfs_bmap_disk_count_leaves(mp, block, numrecs, count);
6170 xfs_trans_brelse(tp, bp);
6171 if (nextbno == NULLFSBLOCK)
6172 break;
6173 bno = nextbno;
6174 error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp,
6175 XFS_BMAP_BTREE_REF,
6176 &xfs_bmbt_buf_ops);
6177 if (error)
6178 return error;
6179 *count += 1;
6180 block = XFS_BUF_TO_BLOCK(bp);
6181 }
6182 }
6183 return 0;
6184}
6185
6186/*
6187 * Count leaf blocks given a range of extent records.
6188 */
6189STATIC void
6190xfs_bmap_count_leaves(
6191 xfs_ifork_t *ifp,
6192 xfs_extnum_t idx,
6193 int numrecs,
6194 int *count)
6195{
6196 int b;
6197
6198 for (b = 0; b < numrecs; b++) {
6199 xfs_bmbt_rec_host_t *frp = xfs_iext_get_ext(ifp, idx + b);
6200 *count += xfs_bmbt_get_blockcount(frp);
6201 }
6202}
6203
6204/*
6205 * Count leaf blocks given a range of extent records originally
6206 * in btree format.
6207 */
6208STATIC void
6209xfs_bmap_disk_count_leaves(
6210 struct xfs_mount *mp,
6211 struct xfs_btree_block *block,
6212 int numrecs,
6213 int *count)
6214{
6215 int b;
6216 xfs_bmbt_rec_t *frp;
6217
6218 for (b = 1; b <= numrecs; b++) {
6219 frp = XFS_BMBT_REC_ADDR(mp, block, b);
6220 *count += xfs_bmbt_disk_get_blockcount(frp);
6221 }
6222}
6223
6224/* 6100/*
6225 * dead simple method of punching delalyed allocation blocks from a range in 6101 * dead simple method of punching delalyed allocation blocks from a range in
6226 * the inode. Walks a block at a time so will be slow, but is only executed in 6102 * the inode. Walks a block at a time so will be slow, but is only executed in
@@ -6295,16 +6171,3 @@ next_block:
6295 6171
6296 return error; 6172 return error;
6297} 6173}
6298
6299/*
6300 * Convert the given file system block to a disk block. We have to treat it
6301 * differently based on whether the file is a real time file or not, because the
6302 * bmap code does.
6303 */
6304xfs_daddr_t
6305xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb)
6306{
6307 return (XFS_IS_REALTIME_INODE(ip) ? \
6308 (xfs_daddr_t)XFS_FSB_TO_BB((ip)->i_mount, (fsb)) : \
6309 XFS_FSB_TO_DADDR((ip)->i_mount, (fsb)));
6310}