]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - libxfs/xfs_bmap.c
xfs: separate freelist fixing into a separate helper
[thirdparty/xfsprogs-dev.git] / libxfs / xfs_bmap.c
CommitLineData
2bd0ea18 1/*
5e656dbb 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
da23017d 3 * All Rights Reserved.
5000d01d 4 *
da23017d
NS
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
2bd0ea18 7 * published by the Free Software Foundation.
5000d01d 8 *
da23017d
NS
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
5000d01d 13 *
da23017d
NS
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2bd0ea18 17 */
9c799827 18#include "libxfs_priv.h"
b626fb59
DC
19#include "xfs_fs.h"
20#include "xfs_shared.h"
21#include "xfs_format.h"
22#include "xfs_log_format.h"
23#include "xfs_trans_resv.h"
24#include "xfs_bit.h"
25#include "xfs_sb.h"
26#include "xfs_mount.h"
27#include "xfs_da_format.h"
28#include "xfs_da_btree.h"
29#include "xfs_dir2.h"
30#include "xfs_inode.h"
31#include "xfs_btree.h"
32#include "xfs_trans.h"
33#include "xfs_alloc.h"
34#include "xfs_bmap.h"
35#include "xfs_bmap_btree.h"
36#include "xfs_trans_space.h"
37#include "xfs_trace.h"
38#include "xfs_attr_leaf.h"
39#include "xfs_quota_defs.h"
40
2bd0ea18 41
5e656dbb
BN
42kmem_zone_t *xfs_bmap_free_item_zone;
43
44/*
49f693fa 45 * Miscellaneous helper functions
5e656dbb 46 */
5e656dbb 47
5e656dbb 48/*
49f693fa
DC
49 * Compute and fill in the value of the maximum depth of a bmap btree
50 * in this filesystem. Done once, during mount.
5e656dbb 51 */
49f693fa
DC
52void
53xfs_bmap_compute_maxlevels(
54 xfs_mount_t *mp, /* file system mount structure */
55 int whichfork) /* data or attr fork */
56{
57 int level; /* btree level */
58 uint maxblocks; /* max blocks at this level */
59 uint maxleafents; /* max leaf entries possible */
60 int maxrootrecs; /* max records in root block */
61 int minleafrecs; /* min records in leaf block */
62 int minnoderecs; /* min records in node block */
63 int sz; /* root block size */
5e656dbb 64
49f693fa
DC
65 /*
66 * The maximum number of extents in a file, hence the maximum
67 * number of leaf entries, is controlled by the type of di_nextents
68 * (a signed 32-bit number, xfs_extnum_t), or by di_anextents
69 * (a signed 16-bit number, xfs_aextnum_t).
70 *
71 * Note that we can no longer assume that if we are in ATTR1 that
72 * the fork offset of all the inodes will be
73 * (xfs_default_attroffset(ip) >> 3) because we could have mounted
74 * with ATTR2 and then mounted back with ATTR1, keeping the
75 * di_forkoff's fixed but probably at various positions. Therefore,
76 * for both ATTR1 and ATTR2 we have to assume the worst case scenario
77 * of a minimum size available.
78 */
79 if (whichfork == XFS_DATA_FORK) {
80 maxleafents = MAXEXTNUM;
81 sz = XFS_BMDR_SPACE_CALC(MINDBTPTRS);
82 } else {
83 maxleafents = MAXAEXTNUM;
84 sz = XFS_BMDR_SPACE_CALC(MINABTPTRS);
85 }
ff105f75 86 maxrootrecs = xfs_bmdr_maxrecs(sz, 0);
49f693fa
DC
87 minleafrecs = mp->m_bmap_dmnr[0];
88 minnoderecs = mp->m_bmap_dmnr[1];
89 maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs;
90 for (level = 1; maxblocks > 1; level++) {
91 if (maxblocks <= maxrootrecs)
92 maxblocks = 1;
93 else
94 maxblocks = (maxblocks + minnoderecs - 1) / minnoderecs;
95 }
96 mp->m_bm_maxlevels[whichfork] = level;
97}
5e656dbb 98
b194c7d8
BN
99STATIC int /* error */
100xfs_bmbt_lookup_eq(
101 struct xfs_btree_cur *cur,
102 xfs_fileoff_t off,
103 xfs_fsblock_t bno,
104 xfs_filblks_t len,
105 int *stat) /* success/failure */
106{
107 cur->bc_rec.b.br_startoff = off;
108 cur->bc_rec.b.br_startblock = bno;
109 cur->bc_rec.b.br_blockcount = len;
110 return xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat);
111}
112
113STATIC int /* error */
114xfs_bmbt_lookup_ge(
115 struct xfs_btree_cur *cur,
116 xfs_fileoff_t off,
117 xfs_fsblock_t bno,
118 xfs_filblks_t len,
119 int *stat) /* success/failure */
120{
121 cur->bc_rec.b.br_startoff = off;
122 cur->bc_rec.b.br_startblock = bno;
123 cur->bc_rec.b.br_blockcount = len;
124 return xfs_btree_lookup(cur, XFS_LOOKUP_GE, stat);
125}
126
127/*
a2ceac1f
DC
128 * Check if the inode needs to be converted to btree format.
129 */
130static inline bool xfs_bmap_needs_btree(struct xfs_inode *ip, int whichfork)
131{
132 return XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS &&
133 XFS_IFORK_NEXTENTS(ip, whichfork) >
134 XFS_IFORK_MAXEXT(ip, whichfork);
135}
136
137/*
138 * Check if the inode should be converted to extent format.
139 */
140static inline bool xfs_bmap_wants_extents(struct xfs_inode *ip, int whichfork)
141{
142 return XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE &&
143 XFS_IFORK_NEXTENTS(ip, whichfork) <=
144 XFS_IFORK_MAXEXT(ip, whichfork);
145}
146
147/*
148 * Update the record referred to by cur to the value given
b194c7d8
BN
149 * by [off, bno, len, state].
150 * This either works (return 0) or gets an EFSCORRUPTED error.
151 */
152STATIC int
153xfs_bmbt_update(
154 struct xfs_btree_cur *cur,
155 xfs_fileoff_t off,
156 xfs_fsblock_t bno,
157 xfs_filblks_t len,
158 xfs_exntst_t state)
159{
160 union xfs_btree_rec rec;
161
162 xfs_bmbt_disk_set_allf(&rec.bmbt, off, bno, len, state);
163 return xfs_btree_update(cur, &rec);
164}
165
5e656dbb 166/*
49f693fa
DC
167 * Compute the worst-case number of indirect blocks that will be used
168 * for ip's delayed extent of length "len".
5e656dbb 169 */
49f693fa
DC
170STATIC xfs_filblks_t
171xfs_bmap_worst_indlen(
172 xfs_inode_t *ip, /* incore inode pointer */
173 xfs_filblks_t len) /* delayed extent length */
57c9fccb 174{
49f693fa
DC
175 int level; /* btree level number */
176 int maxrecs; /* maximum record count at this level */
177 xfs_mount_t *mp; /* mount structure */
178 xfs_filblks_t rval; /* return value */
57c9fccb
NS
179
180 mp = ip->i_mount;
49f693fa
DC
181 maxrecs = mp->m_bmap_dmxr[0];
182 for (level = 0, rval = 0;
183 level < XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK);
184 level++) {
185 len += maxrecs - 1;
186 do_div(len, maxrecs);
187 rval += len;
188 if (len == 1)
189 return rval + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) -
190 level - 1;
191 if (level == 0)
192 maxrecs = mp->m_bmap_dmxr[1];
57c9fccb 193 }
49f693fa 194 return rval;
57c9fccb
NS
195}
196
197/*
49f693fa 198 * Calculate the default attribute fork offset for newly created inodes.
57c9fccb 199 */
49f693fa
DC
200uint
201xfs_default_attroffset(
202 struct xfs_inode *ip)
57c9fccb 203{
49f693fa
DC
204 struct xfs_mount *mp = ip->i_mount;
205 uint offset;
57c9fccb 206
49f693fa
DC
207 if (mp->m_sb.sb_inodesize == 256) {
208 offset = XFS_LITINO(mp, ip->i_d.di_version) -
209 XFS_BMDR_SPACE_CALC(MINABTPTRS);
210 } else {
211 offset = XFS_BMDR_SPACE_CALC(6 * MINABTPTRS);
57c9fccb 212 }
49f693fa
DC
213
214 ASSERT(offset < XFS_LITINO(mp, ip->i_d.di_version));
215 return offset;
57c9fccb
NS
216}
217
218/*
49f693fa
DC
219 * Helper routine to reset inode di_forkoff field when switching
220 * attribute fork from local to extent format - we reset it where
221 * possible to make space available for inline data fork extents.
57c9fccb 222 */
49f693fa
DC
223STATIC void
224xfs_bmap_forkoff_reset(
49f693fa
DC
225 xfs_inode_t *ip,
226 int whichfork)
57c9fccb 227{
49f693fa
DC
228 if (whichfork == XFS_ATTR_FORK &&
229 ip->i_d.di_format != XFS_DINODE_FMT_DEV &&
230 ip->i_d.di_format != XFS_DINODE_FMT_UUID &&
231 ip->i_d.di_format != XFS_DINODE_FMT_BTREE) {
232 uint dfl_forkoff = xfs_default_attroffset(ip) >> 3;
57c9fccb 233
49f693fa
DC
234 if (dfl_forkoff > ip->i_d.di_forkoff)
235 ip->i_d.di_forkoff = dfl_forkoff;
236 }
57c9fccb
NS
237}
238
49f693fa
DC
239#ifdef DEBUG
240STATIC struct xfs_buf *
241xfs_bmap_get_bp(
242 struct xfs_btree_cur *cur,
243 xfs_fsblock_t bno)
244{
245 struct xfs_log_item_desc *lidp;
246 int i;
56b2de80 247
49f693fa
DC
248 if (!cur)
249 return NULL;
2bd0ea18 250
49f693fa
DC
251 for (i = 0; i < XFS_BTREE_MAXLEVELS; i++) {
252 if (!cur->bc_bufs[i])
253 break;
254 if (XFS_BUF_ADDR(cur->bc_bufs[i]) == bno)
255 return cur->bc_bufs[i];
256 }
56b2de80 257
49f693fa
DC
258 /* Chase down all the log items to see if the bp is there */
259 list_for_each_entry(lidp, &cur->bc_tp->t_items, lid_trans) {
260 struct xfs_buf_log_item *bip;
261 bip = (struct xfs_buf_log_item *)lidp->lid_item;
262 if (bip->bli_item.li_type == XFS_LI_BUF &&
263 XFS_BUF_ADDR(bip->bli_buf) == bno)
264 return bip->bli_buf;
265 }
2bd0ea18 266
49f693fa
DC
267 return NULL;
268}
56b2de80 269
49f693fa
DC
270STATIC void
271xfs_check_block(
272 struct xfs_btree_block *block,
273 xfs_mount_t *mp,
274 int root,
275 short sz)
276{
277 int i, j, dmxr;
278 __be64 *pp, *thispa; /* pointer to block address */
279 xfs_bmbt_key_t *prevp, *keyp;
2bd0ea18 280
49f693fa 281 ASSERT(be16_to_cpu(block->bb_level) > 0);
56b2de80 282
49f693fa
DC
283 prevp = NULL;
284 for( i = 1; i <= xfs_btree_get_numrecs(block); i++) {
285 dmxr = mp->m_bmap_dmxr[0];
286 keyp = XFS_BMBT_KEY_ADDR(mp, block, i);
a2ceac1f 287
49f693fa
DC
288 if (prevp) {
289 ASSERT(be64_to_cpu(prevp->br_startoff) <
290 be64_to_cpu(keyp->br_startoff));
291 }
292 prevp = keyp;
2bd0ea18 293
2bd0ea18 294 /*
49f693fa 295 * Compare the block numbers to see if there are dups.
2bd0ea18 296 */
49f693fa
DC
297 if (root)
298 pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, i, sz);
299 else
300 pp = XFS_BMBT_PTR_ADDR(mp, block, i, dmxr);
301
302 for (j = i+1; j <= be16_to_cpu(block->bb_numrecs); j++) {
303 if (root)
304 thispa = XFS_BMAP_BROOT_PTR_ADDR(mp, block, j, sz);
305 else
306 thispa = XFS_BMBT_PTR_ADDR(mp, block, j, dmxr);
307 if (*thispa == *pp) {
308 xfs_warn(mp, "%s: thispa(%d) == pp(%d) %Ld",
309 __func__, j, i,
310 (unsigned long long)be64_to_cpu(*thispa));
311 panic("%s: ptrs are equal in node\n",
312 __func__);
313 }
2bd0ea18 314 }
49f693fa
DC
315 }
316}
a2ceac1f 317
49f693fa
DC
318/*
319 * Check that the extents for the inode ip are in the right order in all
f07ae2a6
DC
320 * btree leaves. THis becomes prohibitively expensive for large extent count
321 * files, so don't bother with inodes that have more than 10,000 extents in
322 * them. The btree record ordering checks will still be done, so for such large
323 * bmapbt constructs that is going to catch most corruptions.
49f693fa 324 */
49f693fa
DC
325STATIC void
326xfs_bmap_check_leaf_extents(
327 xfs_btree_cur_t *cur, /* btree cursor or null */
328 xfs_inode_t *ip, /* incore inode pointer */
329 int whichfork) /* data or attr fork */
330{
331 struct xfs_btree_block *block; /* current btree block */
332 xfs_fsblock_t bno; /* block # of "block" */
333 xfs_buf_t *bp; /* buffer for "block" */
334 int error; /* error return value */
335 xfs_extnum_t i=0, j; /* index into the extents list */
336 xfs_ifork_t *ifp; /* fork structure */
337 int level; /* btree level, for checking */
338 xfs_mount_t *mp; /* file system mount structure */
339 __be64 *pp; /* pointer to block address */
340 xfs_bmbt_rec_t *ep; /* pointer to current extent */
341 xfs_bmbt_rec_t last = {0, 0}; /* last extent in prev block */
342 xfs_bmbt_rec_t *nextp; /* pointer to next extent */
343 int bp_release = 0;
344
345 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) {
346 return;
347 }
348
f07ae2a6
DC
349 /* skip large extent count inodes */
350 if (ip->i_d.di_nextents > 10000)
351 return;
352
49f693fa
DC
353 bno = NULLFSBLOCK;
354 mp = ip->i_mount;
355 ifp = XFS_IFORK_PTR(ip, whichfork);
356 block = ifp->if_broot;
357 /*
358 * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
359 */
360 level = be16_to_cpu(block->bb_level);
361 ASSERT(level > 0);
362 xfs_check_block(block, mp, 1, ifp->if_broot_bytes);
363 pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes);
364 bno = be64_to_cpu(*pp);
365
5a35bf2c 366 ASSERT(bno != NULLFSBLOCK);
49f693fa
DC
367 ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount);
368 ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks);
369
370 /*
371 * Go down the tree until leaf level is reached, following the first
372 * pointer (leftmost) at each level.
373 */
374 while (level-- > 0) {
375 /* See if buf is in cur first */
376 bp_release = 0;
377 bp = xfs_bmap_get_bp(cur, XFS_FSB_TO_DADDR(mp, bno));
378 if (!bp) {
379 bp_release = 1;
380 error = xfs_btree_read_bufl(mp, NULL, bno, 0, &bp,
381 XFS_BMAP_BTREE_REF,
382 &xfs_bmbt_buf_ops);
2bd0ea18 383 if (error)
49f693fa 384 goto error_norelse;
2bd0ea18 385 }
49f693fa 386 block = XFS_BUF_TO_BLOCK(bp);
49f693fa
DC
387 if (level == 0)
388 break;
2bd0ea18 389
2bd0ea18 390 /*
49f693fa
DC
391 * Check this block for basic sanity (increasing keys and
392 * no duplicate blocks).
2bd0ea18 393 */
49f693fa
DC
394
395 xfs_check_block(block, mp, 0, 0);
396 pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]);
397 bno = be64_to_cpu(*pp);
19ebedcf
DC
398 XFS_WANT_CORRUPTED_GOTO(mp,
399 XFS_FSB_SANITY_CHECK(mp, bno), error0);
49f693fa
DC
400 if (bp_release) {
401 bp_release = 0;
402 xfs_trans_brelse(NULL, bp);
2bd0ea18 403 }
49f693fa 404 }
a2ceac1f 405
49f693fa
DC
406 /*
407 * Here with bp and block set to the leftmost leaf node in the tree.
408 */
409 i = 0;
a2ceac1f 410
49f693fa
DC
411 /*
412 * Loop over all leaf nodes checking that all extents are in the right order.
413 */
414 for (;;) {
415 xfs_fsblock_t nextbno;
416 xfs_extnum_t num_recs;
417
418
419 num_recs = xfs_btree_get_numrecs(block);
2bd0ea18 420
2bd0ea18 421 /*
49f693fa 422 * Read-ahead the next leaf block, if any.
2bd0ea18 423 */
a2ceac1f 424
49f693fa 425 nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib);
a2ceac1f 426
49f693fa
DC
427 /*
428 * Check all the extents to make sure they are OK.
429 * If we had a previous block, the last entry should
430 * conform with the first entry in this one.
431 */
2bd0ea18 432
49f693fa
DC
433 ep = XFS_BMBT_REC_ADDR(mp, block, 1);
434 if (i) {
435 ASSERT(xfs_bmbt_disk_get_startoff(&last) +
436 xfs_bmbt_disk_get_blockcount(&last) <=
437 xfs_bmbt_disk_get_startoff(ep));
438 }
439 for (j = 1; j < num_recs; j++) {
440 nextp = XFS_BMBT_REC_ADDR(mp, block, j + 1);
441 ASSERT(xfs_bmbt_disk_get_startoff(ep) +
442 xfs_bmbt_disk_get_blockcount(ep) <=
443 xfs_bmbt_disk_get_startoff(nextp));
444 ep = nextp;
445 }
446
447 last = *ep;
448 i += num_recs;
449 if (bp_release) {
450 bp_release = 0;
451 xfs_trans_brelse(NULL, bp);
452 }
453 bno = nextbno;
2bd0ea18 454 /*
49f693fa 455 * If we've reached the end, stop.
2bd0ea18 456 */
49f693fa
DC
457 if (bno == NULLFSBLOCK)
458 break;
a2ceac1f 459
49f693fa
DC
460 bp_release = 0;
461 bp = xfs_bmap_get_bp(cur, XFS_FSB_TO_DADDR(mp, bno));
462 if (!bp) {
463 bp_release = 1;
464 error = xfs_btree_read_bufl(mp, NULL, bno, 0, &bp,
465 XFS_BMAP_BTREE_REF,
466 &xfs_bmbt_buf_ops);
a2ceac1f 467 if (error)
49f693fa 468 goto error_norelse;
2bd0ea18 469 }
49f693fa 470 block = XFS_BUF_TO_BLOCK(bp);
a2ceac1f 471 }
4d4a192c 472
49f693fa 473 return;
a2ceac1f 474
49f693fa
DC
475error0:
476 xfs_warn(mp, "%s: at error0", __func__);
477 if (bp_release)
478 xfs_trans_brelse(NULL, bp);
479error_norelse:
480 xfs_warn(mp, "%s: BAD after btree leaves for %d extents",
481 __func__, i);
482 panic("%s: CORRUPTED BTREE OR SOMETHING", __func__);
483 return;
2bd0ea18
NS
484}
485
486/*
49f693fa 487 * Add bmap trace insert entries for all the contents of the extent records.
2bd0ea18 488 */
49f693fa
DC
489void
490xfs_bmap_trace_exlist(
491 xfs_inode_t *ip, /* incore inode pointer */
492 xfs_extnum_t cnt, /* count of entries in the list */
493 int whichfork, /* data or attr fork */
494 unsigned long caller_ip)
2bd0ea18 495{
49f693fa
DC
496 xfs_extnum_t idx; /* extent record index */
497 xfs_ifork_t *ifp; /* inode fork pointer */
498 int state = 0;
a2ceac1f 499
49f693fa
DC
500 if (whichfork == XFS_ATTR_FORK)
501 state |= BMAP_ATTRFORK;
a2ceac1f 502
49f693fa
DC
503 ifp = XFS_IFORK_PTR(ip, whichfork);
504 ASSERT(cnt == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)));
505 for (idx = 0; idx < cnt; idx++)
506 trace_xfs_extlist(ip, idx, whichfork, caller_ip);
507}
a2ceac1f 508
49f693fa
DC
509/*
510 * Validate that the bmbt_irecs being returned from bmapi are valid
e6d77a21
DC
511 * given the caller's original parameters. Specifically check the
512 * ranges of the returned irecs to ensure that they only extend beyond
49f693fa
DC
513 * the given parameters if the XFS_BMAPI_ENTIRE flag was set.
514 */
515STATIC void
516xfs_bmap_validate_ret(
517 xfs_fileoff_t bno,
518 xfs_filblks_t len,
519 int flags,
520 xfs_bmbt_irec_t *mval,
521 int nmap,
522 int ret_nmap)
523{
524 int i; /* index to map values */
a2ceac1f 525
49f693fa 526 ASSERT(ret_nmap <= nmap);
a2ceac1f 527
49f693fa
DC
528 for (i = 0; i < ret_nmap; i++) {
529 ASSERT(mval[i].br_blockcount > 0);
530 if (!(flags & XFS_BMAPI_ENTIRE)) {
531 ASSERT(mval[i].br_startoff >= bno);
532 ASSERT(mval[i].br_blockcount <= len);
533 ASSERT(mval[i].br_startoff + mval[i].br_blockcount <=
534 bno + len);
535 } else {
536 ASSERT(mval[i].br_startoff < bno + len);
537 ASSERT(mval[i].br_startoff + mval[i].br_blockcount >
538 bno);
539 }
540 ASSERT(i == 0 ||
541 mval[i - 1].br_startoff + mval[i - 1].br_blockcount ==
542 mval[i].br_startoff);
543 ASSERT(mval[i].br_startblock != DELAYSTARTBLOCK &&
544 mval[i].br_startblock != HOLESTARTBLOCK);
545 ASSERT(mval[i].br_state == XFS_EXT_NORM ||
546 mval[i].br_state == XFS_EXT_UNWRITTEN);
547 }
548}
56b2de80 549
49f693fa
DC
550#else
551#define xfs_bmap_check_leaf_extents(cur, ip, whichfork) do { } while (0)
552#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
553#endif /* DEBUG */
56b2de80 554
49f693fa
DC
555/*
556 * bmap free list manipulation functions
557 */
56b2de80 558
49f693fa
DC
559/*
560 * Add the extent to the list of extents to be free at transaction end.
561 * The list is maintained sorted (by block number).
562 */
563void
564xfs_bmap_add_free(
af2e7c6e
DW
565 struct xfs_mount *mp, /* mount point structure */
566 struct xfs_bmap_free *flist, /* list of extents */
49f693fa 567 xfs_fsblock_t bno, /* fs block number of extent */
af2e7c6e 568 xfs_filblks_t len) /* length of extent */
49f693fa
DC
569{
570 xfs_bmap_free_item_t *cur; /* current (next) element */
571 xfs_bmap_free_item_t *new; /* new element */
572 xfs_bmap_free_item_t *prev; /* previous element */
573#ifdef DEBUG
574 xfs_agnumber_t agno;
575 xfs_agblock_t agbno;
56b2de80 576
49f693fa
DC
577 ASSERT(bno != NULLFSBLOCK);
578 ASSERT(len > 0);
579 ASSERT(len <= MAXEXTLEN);
580 ASSERT(!isnullstartblock(bno));
581 agno = XFS_FSB_TO_AGNO(mp, bno);
582 agbno = XFS_FSB_TO_AGBNO(mp, bno);
583 ASSERT(agno < mp->m_sb.sb_agcount);
584 ASSERT(agbno < mp->m_sb.sb_agblocks);
585 ASSERT(len < mp->m_sb.sb_agblocks);
586 ASSERT(agbno + len <= mp->m_sb.sb_agblocks);
587#endif
588 ASSERT(xfs_bmap_free_item_zone != NULL);
589 new = kmem_zone_alloc(xfs_bmap_free_item_zone, KM_SLEEP);
590 new->xbfi_startblock = bno;
591 new->xbfi_blockcount = (xfs_extlen_t)len;
592 for (prev = NULL, cur = flist->xbf_first;
593 cur != NULL;
594 prev = cur, cur = cur->xbfi_next) {
595 if (cur->xbfi_startblock >= bno)
596 break;
2bd0ea18 597 }
49f693fa
DC
598 if (prev)
599 prev->xbfi_next = new;
600 else
601 flist->xbf_first = new;
602 new->xbfi_next = cur;
603 flist->xbf_count++;
604}
56b2de80 605
49f693fa
DC
606/*
607 * Remove the entry "free" from the free item list. Prev points to the
608 * previous entry, unless "free" is the head of the list.
609 */
610void
611xfs_bmap_del_free(
612 xfs_bmap_free_t *flist, /* free item list header */
613 xfs_bmap_free_item_t *prev, /* previous item on list, if any */
614 xfs_bmap_free_item_t *free) /* list item to be freed */
615{
616 if (prev)
617 prev->xbfi_next = free->xbfi_next;
618 else
619 flist->xbf_first = free->xbfi_next;
620 flist->xbf_count--;
621 kmem_zone_free(xfs_bmap_free_item_zone, free);
622}
56b2de80 623
49f693fa
DC
624/*
625 * Free up any items left in the list.
626 */
627void
628xfs_bmap_cancel(
629 xfs_bmap_free_t *flist) /* list of bmap_free_items */
630{
631 xfs_bmap_free_item_t *free; /* free list item */
632 xfs_bmap_free_item_t *next;
56b2de80 633
49f693fa
DC
634 if (flist->xbf_count == 0)
635 return;
636 ASSERT(flist->xbf_first != NULL);
637 for (free = flist->xbf_first; free; free = next) {
638 next = free->xbfi_next;
639 xfs_bmap_del_free(flist, NULL, free);
640 }
641 ASSERT(flist->xbf_count == 0);
642}
2bd0ea18 643
49f693fa
DC
644/*
645 * Inode fork format manipulation functions
646 */
a2ceac1f 647
49f693fa
DC
648/*
649 * Transform a btree format file with only one leaf node, where the
650 * extents list will fit in the inode, into an extents format file.
651 * Since the file extents are already in-core, all we have to do is
652 * give up the space for the btree root and pitch the leaf block.
653 */
654STATIC int /* error */
655xfs_bmap_btree_to_extents(
656 xfs_trans_t *tp, /* transaction pointer */
657 xfs_inode_t *ip, /* incore inode pointer */
658 xfs_btree_cur_t *cur, /* btree cursor */
659 int *logflagsp, /* inode logging flags */
660 int whichfork) /* data or attr fork */
661{
662 /* REFERENCED */
663 struct xfs_btree_block *cblock;/* child btree block */
664 xfs_fsblock_t cbno; /* child block number */
665 xfs_buf_t *cbp; /* child block's buffer */
666 int error; /* error return value */
667 xfs_ifork_t *ifp; /* inode fork data */
668 xfs_mount_t *mp; /* mount point structure */
669 __be64 *pp; /* ptr to block address */
670 struct xfs_btree_block *rblock;/* root btree block */
56b2de80 671
49f693fa
DC
672 mp = ip->i_mount;
673 ifp = XFS_IFORK_PTR(ip, whichfork);
674 ASSERT(ifp->if_flags & XFS_IFEXTENTS);
675 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE);
676 rblock = ifp->if_broot;
677 ASSERT(be16_to_cpu(rblock->bb_level) == 1);
678 ASSERT(be16_to_cpu(rblock->bb_numrecs) == 1);
679 ASSERT(xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0) == 1);
680 pp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, ifp->if_broot_bytes);
681 cbno = be64_to_cpu(*pp);
682 *logflagsp = 0;
683#ifdef DEBUG
684 if ((error = xfs_btree_check_lptr(cur, cbno, 1)))
685 return error;
686#endif
687 error = xfs_btree_read_bufl(mp, tp, cbno, 0, &cbp, XFS_BMAP_BTREE_REF,
688 &xfs_bmbt_buf_ops);
689 if (error)
690 return error;
691 cblock = XFS_BUF_TO_BLOCK(cbp);
692 if ((error = xfs_btree_check_block(cur, cblock, 0, cbp)))
693 return error;
af2e7c6e 694 xfs_bmap_add_free(mp, cur->bc_private.b.flist, cbno, 1);
49f693fa
DC
695 ip->i_d.di_nblocks--;
696 xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L);
697 xfs_trans_binval(tp, cbp);
698 if (cur->bc_bufs[0] == cbp)
699 cur->bc_bufs[0] = NULL;
700 xfs_iroot_realloc(ip, -1, whichfork);
701 ASSERT(ifp->if_broot == NULL);
702 ASSERT((ifp->if_flags & XFS_IFBROOT) == 0);
703 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS);
704 *logflagsp = XFS_ILOG_CORE | xfs_ilog_fext(whichfork);
705 return 0;
706}
2bd0ea18
NS
707
708/*
49f693fa
DC
709 * Convert an extents-format file into a btree-format file.
710 * The new file will have a root block (in the inode) and a single child block.
2bd0ea18 711 */
49f693fa
DC
712STATIC int /* error */
713xfs_bmap_extents_to_btree(
714 xfs_trans_t *tp, /* transaction pointer */
715 xfs_inode_t *ip, /* incore inode pointer */
716 xfs_fsblock_t *firstblock, /* first-block-allocated */
717 xfs_bmap_free_t *flist, /* blocks freed in xaction */
718 xfs_btree_cur_t **curp, /* cursor returned to caller */
719 int wasdel, /* converting a delayed alloc */
720 int *logflagsp, /* inode logging flags */
721 int whichfork) /* data or attr fork */
2bd0ea18 722{
49f693fa
DC
723 struct xfs_btree_block *ablock; /* allocated (child) bt block */
724 xfs_buf_t *abp; /* buffer for ablock */
725 xfs_alloc_arg_t args; /* allocation arguments */
726 xfs_bmbt_rec_t *arp; /* child record pointer */
727 struct xfs_btree_block *block; /* btree root block */
728 xfs_btree_cur_t *cur; /* bmap btree cursor */
729 xfs_bmbt_rec_host_t *ep; /* extent record pointer */
730 int error; /* error return value */
731 xfs_extnum_t i, cnt; /* extent record index */
732 xfs_ifork_t *ifp; /* inode fork pointer */
733 xfs_bmbt_key_t *kp; /* root block key pointer */
734 xfs_mount_t *mp; /* mount structure */
735 xfs_extnum_t nextents; /* number of file extents */
736 xfs_bmbt_ptr_t *pp; /* root block address pointer */
2bd0ea18 737
5dfa5cd2 738 mp = ip->i_mount;
49f693fa
DC
739 ifp = XFS_IFORK_PTR(ip, whichfork);
740 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS);
56b2de80 741
2bd0ea18 742 /*
49f693fa 743 * Make space in the inode incore.
2bd0ea18 744 */
49f693fa
DC
745 xfs_iroot_realloc(ip, 1, whichfork);
746 ifp->if_flags |= XFS_IFBROOT;
56b2de80 747
2bd0ea18 748 /*
49f693fa 749 * Fill in the root.
2bd0ea18 750 */
49f693fa 751 block = ifp->if_broot;
5dfa5cd2
DC
752 if (xfs_sb_version_hascrc(&mp->m_sb))
753 xfs_btree_init_block_int(mp, block, XFS_BUF_DADDR_NULL,
754 XFS_BMAP_CRC_MAGIC, 1, 1, ip->i_ino,
755 XFS_BTREE_LONG_PTRS | XFS_BTREE_CRC_BLOCKS);
756 else
757 xfs_btree_init_block_int(mp, block, XFS_BUF_DADDR_NULL,
758 XFS_BMAP_MAGIC, 1, 1, ip->i_ino,
759 XFS_BTREE_LONG_PTRS);
56b2de80 760
49f693fa
DC
761 /*
762 * Need a cursor. Can't allocate until bb_level is filled in.
763 */
49f693fa
DC
764 cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
765 cur->bc_private.b.firstblock = *firstblock;
766 cur->bc_private.b.flist = flist;
767 cur->bc_private.b.flags = wasdel ? XFS_BTCUR_BPRV_WASDEL : 0;
768 /*
769 * Convert to a btree with two levels, one record in root.
770 */
771 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE);
772 memset(&args, 0, sizeof(args));
773 args.tp = tp;
774 args.mp = mp;
775 args.firstblock = *firstblock;
776 if (*firstblock == NULLFSBLOCK) {
777 args.type = XFS_ALLOCTYPE_START_BNO;
778 args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino);
779 } else if (flist->xbf_low) {
780 args.type = XFS_ALLOCTYPE_START_BNO;
781 args.fsbno = *firstblock;
782 } else {
783 args.type = XFS_ALLOCTYPE_NEAR_BNO;
784 args.fsbno = *firstblock;
785 }
786 args.minlen = args.maxlen = args.prod = 1;
787 args.wasdel = wasdel;
788 *logflagsp = 0;
789 if ((error = xfs_alloc_vextent(&args))) {
790 xfs_iroot_realloc(ip, -1, whichfork);
791 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
792 return error;
2bd0ea18
NS
793 }
794 /*
49f693fa 795 * Allocation can't fail, the space was reserved.
2bd0ea18 796 */
49f693fa
DC
797 ASSERT(args.fsbno != NULLFSBLOCK);
798 ASSERT(*firstblock == NULLFSBLOCK ||
799 args.agno == XFS_FSB_TO_AGNO(mp, *firstblock) ||
800 (flist->xbf_low &&
801 args.agno > XFS_FSB_TO_AGNO(mp, *firstblock)));
802 *firstblock = cur->bc_private.b.firstblock = args.fsbno;
803 cur->bc_private.b.allocated++;
804 ip->i_d.di_nblocks++;
805 xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L);
806 abp = xfs_btree_get_bufl(mp, tp, args.fsbno, 0);
2bd0ea18 807 /*
49f693fa 808 * Fill in the child block.
2bd0ea18 809 */
49f693fa
DC
810 abp->b_ops = &xfs_bmbt_buf_ops;
811 ablock = XFS_BUF_TO_BLOCK(abp);
5dfa5cd2
DC
812 if (xfs_sb_version_hascrc(&mp->m_sb))
813 xfs_btree_init_block_int(mp, ablock, abp->b_bn,
814 XFS_BMAP_CRC_MAGIC, 0, 0, ip->i_ino,
815 XFS_BTREE_LONG_PTRS | XFS_BTREE_CRC_BLOCKS);
816 else
817 xfs_btree_init_block_int(mp, ablock, abp->b_bn,
818 XFS_BMAP_MAGIC, 0, 0, ip->i_ino,
819 XFS_BTREE_LONG_PTRS);
820
49f693fa
DC
821 arp = XFS_BMBT_REC_ADDR(mp, ablock, 1);
822 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
823 for (cnt = i = 0; i < nextents; i++) {
824 ep = xfs_iext_get_ext(ifp, i);
825 if (!isnullstartblock(xfs_bmbt_get_startblock(ep))) {
826 arp->l0 = cpu_to_be64(ep->l0);
827 arp->l1 = cpu_to_be64(ep->l1);
828 arp++; cnt++;
829 }
830 }
831 ASSERT(cnt == XFS_IFORK_NEXTENTS(ip, whichfork));
832 xfs_btree_set_numrecs(ablock, cnt);
56b2de80 833
49f693fa
DC
834 /*
835 * Fill in the root key and pointer.
836 */
837 kp = XFS_BMBT_KEY_ADDR(mp, block, 1);
838 arp = XFS_BMBT_REC_ADDR(mp, ablock, 1);
839 kp->br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(arp));
840 pp = XFS_BMBT_PTR_ADDR(mp, block, 1, xfs_bmbt_get_maxrecs(cur,
841 be16_to_cpu(block->bb_level)));
842 *pp = cpu_to_be64(args.fsbno);
2bd0ea18 843
49f693fa
DC
844 /*
845 * Do all this logging at the end so that
846 * the root is at the right level.
847 */
5dfa5cd2 848 xfs_btree_log_block(cur, abp, XFS_BB_ALL_BITS);
613e6057 849 xfs_btree_log_recs(cur, abp, 1, be16_to_cpu(ablock->bb_numrecs));
49f693fa
DC
850 ASSERT(*curp == NULL);
851 *curp = cur;
852 *logflagsp = XFS_ILOG_CORE | xfs_ilog_fbroot(whichfork);
853 return 0;
854}
a2ceac1f 855
49f693fa
DC
856/*
857 * Convert a local file to an extents file.
858 * This code is out of bounds for data forks of regular files,
859 * since the file data needs to get logged so things will stay consistent.
860 * (The bmap-level manipulations are ok, though).
861 */
3f17ed4b
DC
862void
863xfs_bmap_local_to_extents_empty(
864 struct xfs_inode *ip,
865 int whichfork)
866{
867 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
868
869 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL);
870 ASSERT(ifp->if_bytes == 0);
871 ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) == 0);
872
ff105f75 873 xfs_bmap_forkoff_reset(ip, whichfork);
3f17ed4b
DC
874 ifp->if_flags &= ~XFS_IFINLINE;
875 ifp->if_flags |= XFS_IFEXTENTS;
876 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS);
877}
878
879
49f693fa
DC
880STATIC int /* error */
881xfs_bmap_local_to_extents(
882 xfs_trans_t *tp, /* transaction pointer */
883 xfs_inode_t *ip, /* incore inode pointer */
884 xfs_fsblock_t *firstblock, /* first block allocated in xaction */
885 xfs_extlen_t total, /* total blocks needed by transaction */
886 int *logflagsp, /* inode logging flags */
887 int whichfork,
5dfa5cd2
DC
888 void (*init_fn)(struct xfs_trans *tp,
889 struct xfs_buf *bp,
49f693fa
DC
890 struct xfs_inode *ip,
891 struct xfs_ifork *ifp))
892{
3f17ed4b 893 int error = 0;
49f693fa
DC
894 int flags; /* logging flags returned */
895 xfs_ifork_t *ifp; /* inode fork pointer */
3f17ed4b
DC
896 xfs_alloc_arg_t args; /* allocation arguments */
897 xfs_buf_t *bp; /* buffer for extent block */
898 xfs_bmbt_rec_host_t *ep; /* extent record pointer */
2bd0ea18 899
49f693fa
DC
900 /*
901 * We don't want to deal with the case of keeping inode data inline yet.
902 * So sending the data fork of a regular inode is invalid.
903 */
e37bf53c 904 ASSERT(!(S_ISREG(VFS_I(ip)->i_mode) && whichfork == XFS_DATA_FORK));
49f693fa
DC
905 ifp = XFS_IFORK_PTR(ip, whichfork);
906 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL);
3f17ed4b
DC
907
908 if (!ifp->if_bytes) {
909 xfs_bmap_local_to_extents_empty(ip, whichfork);
910 flags = XFS_ILOG_CORE;
911 goto done;
912 }
913
49f693fa
DC
914 flags = 0;
915 error = 0;
3f17ed4b
DC
916 ASSERT((ifp->if_flags & (XFS_IFINLINE|XFS_IFEXTENTS|XFS_IFEXTIREC)) ==
917 XFS_IFINLINE);
918 memset(&args, 0, sizeof(args));
919 args.tp = tp;
920 args.mp = ip->i_mount;
921 args.firstblock = *firstblock;
922 /*
923 * Allocate a block. We know we need only one, since the
924 * file currently fits in an inode.
925 */
926 if (*firstblock == NULLFSBLOCK) {
927 args.fsbno = XFS_INO_TO_FSB(args.mp, ip->i_ino);
928 args.type = XFS_ALLOCTYPE_START_BNO;
49f693fa 929 } else {
3f17ed4b
DC
930 args.fsbno = *firstblock;
931 args.type = XFS_ALLOCTYPE_NEAR_BNO;
2bd0ea18 932 }
3f17ed4b
DC
933 args.total = total;
934 args.minlen = args.maxlen = args.prod = 1;
935 error = xfs_alloc_vextent(&args);
936 if (error)
937 goto done;
938
939 /* Can't fail, the space was reserved. */
940 ASSERT(args.fsbno != NULLFSBLOCK);
941 ASSERT(args.len == 1);
942 *firstblock = args.fsbno;
943 bp = xfs_btree_get_bufl(args.mp, tp, args.fsbno, 0);
944
19ebedcf 945 /*
f44fbde0 946 * Initialize the block, copy the data and log the remote buffer.
19ebedcf 947 *
f44fbde0
BF
948 * The callout is responsible for logging because the remote format
949 * might differ from the local format and thus we don't know how much to
950 * log here. Note that init_fn must also set the buffer log item type
951 * correctly.
19ebedcf 952 */
3f17ed4b
DC
953 init_fn(tp, bp, ip, ifp);
954
f44fbde0 955 /* account for the change in fork size */
3f17ed4b
DC
956 xfs_idata_realloc(ip, -ifp->if_bytes, whichfork);
957 xfs_bmap_local_to_extents_empty(ip, whichfork);
49f693fa 958 flags |= XFS_ILOG_CORE;
3f17ed4b
DC
959
960 xfs_iext_add(ifp, 0, 1);
961 ep = xfs_iext_get_ext(ifp, 0);
962 xfs_bmbt_set_allf(ep, 0, args.fsbno, 1, XFS_EXT_NORM);
963 trace_xfs_bmap_post_update(ip, 0,
964 whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0,
965 _THIS_IP_);
966 XFS_IFORK_NEXT_SET(ip, whichfork, 1);
967 ip->i_d.di_nblocks = 1;
968 xfs_trans_mod_dquot_byino(tp, ip,
969 XFS_TRANS_DQ_BCOUNT, 1L);
970 flags |= xfs_ilog_fext(whichfork);
971
49f693fa
DC
972done:
973 *logflagsp = flags;
974 return error;
2bd0ea18
NS
975}
976
977/*
49f693fa 978 * Called from xfs_bmap_add_attrfork to handle btree format files.
2bd0ea18 979 */
49f693fa
DC
980STATIC int /* error */
981xfs_bmap_add_attrfork_btree(
982 xfs_trans_t *tp, /* transaction pointer */
983 xfs_inode_t *ip, /* incore inode pointer */
984 xfs_fsblock_t *firstblock, /* first block allocated */
985 xfs_bmap_free_t *flist, /* blocks to free at commit */
986 int *flags) /* inode logging flags */
2bd0ea18 987{
49f693fa
DC
988 xfs_btree_cur_t *cur; /* btree cursor */
989 int error; /* error return value */
990 xfs_mount_t *mp; /* file system mount struct */
991 int stat; /* newroot status */
56b2de80 992
49f693fa
DC
993 mp = ip->i_mount;
994 if (ip->i_df.if_broot_bytes <= XFS_IFORK_DSIZE(ip))
995 *flags |= XFS_ILOG_DBROOT;
996 else {
997 cur = xfs_bmbt_init_cursor(mp, tp, ip, XFS_DATA_FORK);
998 cur->bc_private.b.flist = flist;
999 cur->bc_private.b.firstblock = *firstblock;
1000 if ((error = xfs_bmbt_lookup_ge(cur, 0, 0, 0, &stat)))
1001 goto error0;
1002 /* must be at least one entry */
19ebedcf 1003 XFS_WANT_CORRUPTED_GOTO(mp, stat == 1, error0);
49f693fa
DC
1004 if ((error = xfs_btree_new_iroot(cur, flags, &stat)))
1005 goto error0;
1006 if (stat == 0) {
1007 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
12b53197 1008 return -ENOSPC;
49f693fa
DC
1009 }
1010 *firstblock = cur->bc_private.b.firstblock;
1011 cur->bc_private.b.allocated = 0;
1012 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
2bd0ea18 1013 }
49f693fa
DC
1014 return 0;
1015error0:
1016 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
1017 return error;
1018}
56b2de80 1019
49f693fa
DC
1020/*
1021 * Called from xfs_bmap_add_attrfork to handle extents format files.
1022 */
1023STATIC int /* error */
1024xfs_bmap_add_attrfork_extents(
1025 xfs_trans_t *tp, /* transaction pointer */
1026 xfs_inode_t *ip, /* incore inode pointer */
1027 xfs_fsblock_t *firstblock, /* first block allocated */
1028 xfs_bmap_free_t *flist, /* blocks to free at commit */
1029 int *flags) /* inode logging flags */
1030{
1031 xfs_btree_cur_t *cur; /* bmap btree cursor */
1032 int error; /* error return value */
1033
1034 if (ip->i_d.di_nextents * sizeof(xfs_bmbt_rec_t) <= XFS_IFORK_DSIZE(ip))
1035 return 0;
1036 cur = NULL;
1037 error = xfs_bmap_extents_to_btree(tp, ip, firstblock, flist, &cur, 0,
1038 flags, XFS_DATA_FORK);
1039 if (cur) {
1040 cur->bc_private.b.allocated = 0;
1041 xfs_btree_del_cursor(cur,
1042 error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR);
2bd0ea18 1043 }
49f693fa
DC
1044 return error;
1045}
56b2de80 1046
49f693fa
DC
1047/*
1048 * Called from xfs_bmap_add_attrfork to handle local format files. Each
1049 * different data fork content type needs a different callout to do the
1050 * conversion. Some are basic and only require special block initialisation
1051 * callouts for the data formating, others (directories) are so specialised they
1052 * handle everything themselves.
1053 *
1054 * XXX (dgc): investigate whether directory conversion can use the generic
1055 * formatting callout. It should be possible - it's just a very complex
5dfa5cd2 1056 * formatter.
49f693fa
DC
1057 */
1058STATIC int /* error */
1059xfs_bmap_add_attrfork_local(
1060 xfs_trans_t *tp, /* transaction pointer */
1061 xfs_inode_t *ip, /* incore inode pointer */
1062 xfs_fsblock_t *firstblock, /* first block allocated */
1063 xfs_bmap_free_t *flist, /* blocks to free at commit */
1064 int *flags) /* inode logging flags */
1065{
1066 xfs_da_args_t dargs; /* args for dir/attr code */
56b2de80 1067
49f693fa
DC
1068 if (ip->i_df.if_bytes <= XFS_IFORK_DSIZE(ip))
1069 return 0;
a2ceac1f 1070
e37bf53c 1071 if (S_ISDIR(VFS_I(ip)->i_mode)) {
49f693fa 1072 memset(&dargs, 0, sizeof(dargs));
ff105f75 1073 dargs.geo = ip->i_mount->m_dir_geo;
49f693fa
DC
1074 dargs.dp = ip;
1075 dargs.firstblock = firstblock;
1076 dargs.flist = flist;
ff105f75 1077 dargs.total = dargs.geo->fsbcount;
49f693fa
DC
1078 dargs.whichfork = XFS_DATA_FORK;
1079 dargs.trans = tp;
1080 return xfs_dir2_sf_to_block(&dargs);
1081 }
2bd0ea18 1082
e37bf53c 1083 if (S_ISLNK(VFS_I(ip)->i_mode))
49f693fa
DC
1084 return xfs_bmap_local_to_extents(tp, ip, firstblock, 1,
1085 flags, XFS_DATA_FORK,
1086 xfs_symlink_local_to_remote);
56b2de80 1087
3f17ed4b
DC
1088 /* should only be called for types that support local format data */
1089 ASSERT(0);
12b53197 1090 return -EFSCORRUPTED;
49f693fa 1091}
2bd0ea18 1092
49f693fa
DC
1093/*
1094 * Convert inode from non-attributed to attributed.
1095 * Must not be in a transaction, ip must not be locked.
1096 */
1097int /* error code */
1098xfs_bmap_add_attrfork(
1099 xfs_inode_t *ip, /* incore inode pointer */
1100 int size, /* space new attribute needs */
1101 int rsvd) /* xact may use reserved blks */
1102{
1103 xfs_fsblock_t firstblock; /* 1st block/ag allocated */
1104 xfs_bmap_free_t flist; /* freed extent records */
1105 xfs_mount_t *mp; /* mount structure */
1106 xfs_trans_t *tp; /* transaction pointer */
1107 int blks; /* space reservation */
1108 int version = 1; /* superblock attr version */
49f693fa
DC
1109 int logflags; /* logging flags */
1110 int error; /* error return value */
56b2de80 1111
49f693fa 1112 ASSERT(XFS_IFORK_Q(ip) == 0);
2bd0ea18 1113
49f693fa
DC
1114 mp = ip->i_mount;
1115 ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
9074815c 1116
49f693fa 1117 blks = XFS_ADDAFORK_SPACE_RES(mp);
9074815c
CH
1118
1119 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_addafork, blks, 0,
1120 rsvd ? XFS_TRANS_RESERVE : 0, &tp);
1121 if (error)
ff105f75 1122 return error;
9074815c 1123
49f693fa
DC
1124 xfs_ilock(ip, XFS_ILOCK_EXCL);
1125 error = xfs_trans_reserve_quota_nblks(tp, ip, blks, 0, rsvd ?
1126 XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES :
1127 XFS_QMOPT_RES_REGBLKS);
ff105f75
DC
1128 if (error)
1129 goto trans_cancel;
49f693fa 1130 if (XFS_IFORK_Q(ip))
ff105f75 1131 goto trans_cancel;
49f693fa 1132 if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS) {
2bd0ea18 1133 /*
49f693fa 1134 * For inodes coming from pre-6.2 filesystems.
2bd0ea18 1135 */
49f693fa
DC
1136 ASSERT(ip->i_d.di_aformat == 0);
1137 ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
5e656dbb 1138 }
49f693fa 1139 ASSERT(ip->i_d.di_anextents == 0);
a2ceac1f 1140
ff105f75 1141 xfs_trans_ijoin(tp, ip, 0);
49f693fa 1142 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
a2ceac1f 1143
49f693fa
DC
1144 switch (ip->i_d.di_format) {
1145 case XFS_DINODE_FMT_DEV:
1146 ip->i_d.di_forkoff = roundup(sizeof(xfs_dev_t), 8) >> 3;
1147 break;
1148 case XFS_DINODE_FMT_UUID:
1149 ip->i_d.di_forkoff = roundup(sizeof(uuid_t), 8) >> 3;
1150 break;
1151 case XFS_DINODE_FMT_LOCAL:
1152 case XFS_DINODE_FMT_EXTENTS:
1153 case XFS_DINODE_FMT_BTREE:
1154 ip->i_d.di_forkoff = xfs_attr_shortform_bytesfit(ip, size);
1155 if (!ip->i_d.di_forkoff)
1156 ip->i_d.di_forkoff = xfs_default_attroffset(ip) >> 3;
1157 else if (mp->m_flags & XFS_MOUNT_ATTR2)
1158 version = 2;
1159 break;
1160 default:
1161 ASSERT(0);
12b53197 1162 error = -EINVAL;
ff105f75 1163 goto trans_cancel;
a2ceac1f
DC
1164 }
1165
49f693fa
DC
1166 ASSERT(ip->i_afp == NULL);
1167 ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP);
1168 ip->i_afp->if_flags = XFS_IFEXTENTS;
1169 logflags = 0;
1170 xfs_bmap_init(&flist, &firstblock);
1171 switch (ip->i_d.di_format) {
1172 case XFS_DINODE_FMT_LOCAL:
1173 error = xfs_bmap_add_attrfork_local(tp, ip, &firstblock, &flist,
1174 &logflags);
1175 break;
1176 case XFS_DINODE_FMT_EXTENTS:
1177 error = xfs_bmap_add_attrfork_extents(tp, ip, &firstblock,
1178 &flist, &logflags);
1179 break;
1180 case XFS_DINODE_FMT_BTREE:
1181 error = xfs_bmap_add_attrfork_btree(tp, ip, &firstblock, &flist,
1182 &logflags);
1183 break;
1184 default:
1185 error = 0;
1186 break;
1187 }
1188 if (logflags)
1189 xfs_trans_log_inode(tp, ip, logflags);
1190 if (error)
ff105f75 1191 goto bmap_cancel;
49f693fa
DC
1192 if (!xfs_sb_version_hasattr(&mp->m_sb) ||
1193 (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2)) {
19ebedcf 1194 bool log_sb = false;
a2ceac1f 1195
49f693fa
DC
1196 spin_lock(&mp->m_sb_lock);
1197 if (!xfs_sb_version_hasattr(&mp->m_sb)) {
1198 xfs_sb_version_addattr(&mp->m_sb);
19ebedcf 1199 log_sb = true;
49f693fa
DC
1200 }
1201 if (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2) {
1202 xfs_sb_version_addattr2(&mp->m_sb);
19ebedcf 1203 log_sb = true;
49f693fa 1204 }
19ebedcf
DC
1205 spin_unlock(&mp->m_sb_lock);
1206 if (log_sb)
1207 xfs_log_sb(tp);
49f693fa
DC
1208 }
1209
0b66d459 1210 error = xfs_bmap_finish(&tp, &flist, NULL);
49f693fa 1211 if (error)
ff105f75 1212 goto bmap_cancel;
de5a3f46 1213 error = xfs_trans_commit(tp);
ff105f75
DC
1214 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1215 return error;
1216
1217bmap_cancel:
49f693fa 1218 xfs_bmap_cancel(&flist);
ff105f75 1219trans_cancel:
3d7434fe 1220 xfs_trans_cancel(tp);
49f693fa 1221 xfs_iunlock(ip, XFS_ILOCK_EXCL);
5e656dbb 1222 return error;
2bd0ea18
NS
1223}
1224
399ab595 1225/*
49f693fa
DC
1226 * Internal and external extent tree search functions.
1227 */
399ab595 1228
49f693fa
DC
1229/*
1230 * Read in the extents to if_extents.
1231 * All inode fields are set up by caller, we just traverse the btree
1232 * and copy the records in. If the file system cannot contain unwritten
1233 * extents, the records are checked for no "state" flags.
1234 */
1235int /* error */
1236xfs_bmap_read_extents(
1237 xfs_trans_t *tp, /* transaction pointer */
1238 xfs_inode_t *ip, /* incore inode */
1239 int whichfork) /* data or attr fork */
1240{
1241 struct xfs_btree_block *block; /* current btree block */
1242 xfs_fsblock_t bno; /* block # of "block" */
1243 xfs_buf_t *bp; /* buffer for "block" */
1244 int error; /* error return value */
1245 xfs_exntfmt_t exntf; /* XFS_EXTFMT_NOSTATE, if checking */
1246 xfs_extnum_t i, j; /* index into the extents list */
1247 xfs_ifork_t *ifp; /* fork structure */
1248 int level; /* btree level, for checking */
1249 xfs_mount_t *mp; /* file system mount structure */
1250 __be64 *pp; /* pointer to block address */
1251 /* REFERENCED */
1252 xfs_extnum_t room; /* number of entries there's room for */
399ab595 1253
49f693fa
DC
1254 bno = NULLFSBLOCK;
1255 mp = ip->i_mount;
1256 ifp = XFS_IFORK_PTR(ip, whichfork);
1257 exntf = (whichfork != XFS_DATA_FORK) ? XFS_EXTFMT_NOSTATE :
1258 XFS_EXTFMT_INODE(ip);
1259 block = ifp->if_broot;
399ab595 1260 /*
49f693fa 1261 * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
399ab595 1262 */
49f693fa
DC
1263 level = be16_to_cpu(block->bb_level);
1264 ASSERT(level > 0);
1265 pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes);
1266 bno = be64_to_cpu(*pp);
5a35bf2c 1267 ASSERT(bno != NULLFSBLOCK);
49f693fa
DC
1268 ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount);
1269 ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks);
399ab595 1270 /*
49f693fa
DC
1271 * Go down the tree until leaf level is reached, following the first
1272 * pointer (leftmost) at each level.
399ab595 1273 */
49f693fa
DC
1274 while (level-- > 0) {
1275 error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp,
1276 XFS_BMAP_BTREE_REF, &xfs_bmbt_buf_ops);
1277 if (error)
1278 return error;
1279 block = XFS_BUF_TO_BLOCK(bp);
49f693fa
DC
1280 if (level == 0)
1281 break;
1282 pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]);
1283 bno = be64_to_cpu(*pp);
19ebedcf
DC
1284 XFS_WANT_CORRUPTED_GOTO(mp,
1285 XFS_FSB_SANITY_CHECK(mp, bno), error0);
49f693fa 1286 xfs_trans_brelse(tp, bp);
399ab595
NS
1287 }
1288 /*
49f693fa 1289 * Here with bp and block set to the leftmost leaf node in the tree.
399ab595 1290 */
49f693fa
DC
1291 room = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
1292 i = 0;
399ab595 1293 /*
49f693fa 1294 * Loop over all leaf nodes. Copy information to the extent records.
399ab595 1295 */
49f693fa
DC
1296 for (;;) {
1297 xfs_bmbt_rec_t *frp;
1298 xfs_fsblock_t nextbno;
1299 xfs_extnum_t num_recs;
1300 xfs_extnum_t start;
399ab595 1301
49f693fa
DC
1302 num_recs = xfs_btree_get_numrecs(block);
1303 if (unlikely(i + num_recs > room)) {
1304 ASSERT(i + num_recs <= room);
1305 xfs_warn(ip->i_mount,
1306 "corrupt dinode %Lu, (btree extents).",
1307 (unsigned long long) ip->i_ino);
1308 XFS_CORRUPTION_ERROR("xfs_bmap_read_extents(1)",
1309 XFS_ERRLEVEL_LOW, ip->i_mount, block);
1310 goto error0;
399ab595
NS
1311 }
1312 /*
49f693fa 1313 * Read-ahead the next leaf block, if any.
399ab595 1314 */
49f693fa
DC
1315 nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib);
1316 if (nextbno != NULLFSBLOCK)
1317 xfs_btree_reada_bufl(mp, nextbno, 1,
1318 &xfs_bmbt_buf_ops);
399ab595 1319 /*
49f693fa 1320 * Copy records into the extent records.
399ab595 1321 */
49f693fa
DC
1322 frp = XFS_BMBT_REC_ADDR(mp, block, 1);
1323 start = i;
1324 for (j = 0; j < num_recs; j++, i++, frp++) {
1325 xfs_bmbt_rec_host_t *trp = xfs_iext_get_ext(ifp, i);
1326 trp->l0 = be64_to_cpu(frp->l0);
1327 trp->l1 = be64_to_cpu(frp->l1);
1328 }
1329 if (exntf == XFS_EXTFMT_NOSTATE) {
1330 /*
1331 * Check all attribute bmap btree records and
1332 * any "older" data bmap btree records for a
1333 * set bit in the "extent flag" position.
1334 */
1335 if (unlikely(xfs_check_nostate_extents(ifp,
1336 start, num_recs))) {
1337 XFS_ERROR_REPORT("xfs_bmap_read_extents(2)",
1338 XFS_ERRLEVEL_LOW,
1339 ip->i_mount);
1340 goto error0;
1341 }
399ab595 1342 }
49f693fa
DC
1343 xfs_trans_brelse(tp, bp);
1344 bno = nextbno;
399ab595 1345 /*
49f693fa 1346 * If we've reached the end, stop.
399ab595 1347 */
49f693fa
DC
1348 if (bno == NULLFSBLOCK)
1349 break;
1350 error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp,
1351 XFS_BMAP_BTREE_REF, &xfs_bmbt_buf_ops);
1352 if (error)
1353 return error;
1354 block = XFS_BUF_TO_BLOCK(bp);
399ab595 1355 }
49f693fa
DC
1356 ASSERT(i == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)));
1357 ASSERT(i == XFS_IFORK_NEXTENTS(ip, whichfork));
1358 XFS_BMAP_TRACE_EXLIST(ip, i, whichfork);
1359 return 0;
1360error0:
1361 xfs_trans_brelse(tp, bp);
12b53197 1362 return -EFSCORRUPTED;
49f693fa 1363}
399ab595 1364
49f693fa
DC
1365
1366/*
1367 * Search the extent records for the entry containing block bno.
1368 * If bno lies in a hole, point to the next entry. If bno lies
1369 * past eof, *eofp will be set, and *prevp will contain the last
1370 * entry (null if none). Else, *lastxp will be set to the index
1371 * of the found entry; *gotp will contain the entry.
1372 */
1373STATIC xfs_bmbt_rec_host_t * /* pointer to found extent entry */
1374xfs_bmap_search_multi_extents(
1375 xfs_ifork_t *ifp, /* inode fork pointer */
1376 xfs_fileoff_t bno, /* block number searched for */
1377 int *eofp, /* out: end of file found */
1378 xfs_extnum_t *lastxp, /* out: last extent index */
1379 xfs_bmbt_irec_t *gotp, /* out: extent entry found */
1380 xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */
1381{
1382 xfs_bmbt_rec_host_t *ep; /* extent record pointer */
1383 xfs_extnum_t lastx; /* last extent index */
1384
1385 /*
1386 * Initialize the extent entry structure to catch access to
1387 * uninitialized br_startblock field.
1388 */
1389 gotp->br_startoff = 0xffa5a5a5a5a5a5a5LL;
1390 gotp->br_blockcount = 0xa55a5a5a5a5a5a5aLL;
1391 gotp->br_state = XFS_EXT_INVALID;
49f693fa 1392 gotp->br_startblock = 0xffffa5a5a5a5a5a5LL;
49f693fa 1393 prevp->br_startoff = NULLFILEOFF;
399ab595 1394
49f693fa
DC
1395 ep = xfs_iext_bno_to_ext(ifp, bno, &lastx);
1396 if (lastx > 0) {
1397 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx - 1), prevp);
1398 }
1399 if (lastx < (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))) {
1400 xfs_bmbt_get_all(ep, gotp);
1401 *eofp = 0;
1402 } else {
1403 if (lastx > 0) {
1404 *gotp = *prevp;
1405 }
1406 *eofp = 1;
1407 ep = NULL;
1408 }
1409 *lastxp = lastx;
1410 return ep;
399ab595
NS
1411}
1412
49f693fa
DC
1413/*
1414 * Search the extents list for the inode, for the extent containing bno.
1415 * If bno lies in a hole, point to the next entry. If bno lies past eof,
1416 * *eofp will be set, and *prevp will contain the last entry (null if none).
1417 * Else, *lastxp will be set to the index of the found
1418 * entry; *gotp will contain the entry.
1419 */
1420xfs_bmbt_rec_host_t * /* pointer to found extent entry */
1421xfs_bmap_search_extents(
1422 xfs_inode_t *ip, /* incore inode pointer */
1423 xfs_fileoff_t bno, /* block number searched for */
1424 int fork, /* data or attr fork */
1425 int *eofp, /* out: end of file found */
1426 xfs_extnum_t *lastxp, /* out: last extent index */
1427 xfs_bmbt_irec_t *gotp, /* out: extent entry found */
1428 xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */
2bd0ea18 1429{
49f693fa
DC
1430 xfs_ifork_t *ifp; /* inode fork pointer */
1431 xfs_bmbt_rec_host_t *ep; /* extent record pointer */
399ab595 1432
79896434 1433 XFS_STATS_INC(ip->i_mount, xs_look_exlist);
49f693fa 1434 ifp = XFS_IFORK_PTR(ip, fork);
399ab595 1435
49f693fa
DC
1436 ep = xfs_bmap_search_multi_extents(ifp, bno, eofp, lastxp, gotp, prevp);
1437
1438 if (unlikely(!(gotp->br_startblock) && (*lastxp != NULLEXTNUM) &&
1439 !(XFS_IS_REALTIME_INODE(ip) && fork == XFS_DATA_FORK))) {
1440 xfs_alert_tag(ip->i_mount, XFS_PTAG_FSBLOCK_ZERO,
1441 "Access to block zero in inode %llu "
1442 "start_block: %llx start_off: %llx "
12864fd9 1443 "blkcnt: %llx extent-state: %x lastx: %x",
49f693fa
DC
1444 (unsigned long long)ip->i_ino,
1445 (unsigned long long)gotp->br_startblock,
1446 (unsigned long long)gotp->br_startoff,
1447 (unsigned long long)gotp->br_blockcount,
1448 gotp->br_state, *lastxp);
1449 *lastxp = NULLEXTNUM;
1450 *eofp = 1;
1451 return NULL;
2bd0ea18 1452 }
49f693fa
DC
1453 return ep;
1454}
2bd0ea18 1455
49f693fa
DC
1456/*
1457 * Returns the file-relative block number of the first unused block(s)
1458 * in the file with at least "len" logically contiguous blocks free.
1459 * This is the lowest-address hole if the file has holes, else the first block
1460 * past the end of file.
1461 * Return 0 if the file is currently local (in-inode).
1462 */
1463int /* error */
1464xfs_bmap_first_unused(
1465 xfs_trans_t *tp, /* transaction pointer */
1466 xfs_inode_t *ip, /* incore inode */
1467 xfs_extlen_t len, /* size of hole to find */
1468 xfs_fileoff_t *first_unused, /* unused block */
1469 int whichfork) /* data or attr fork */
1470{
1471 int error; /* error return value */
1472 int idx; /* extent record index */
1473 xfs_ifork_t *ifp; /* inode fork pointer */
1474 xfs_fileoff_t lastaddr; /* last block number seen */
1475 xfs_fileoff_t lowest; /* lowest useful block */
1476 xfs_fileoff_t max; /* starting useful block */
1477 xfs_fileoff_t off; /* offset for this block */
1478 xfs_extnum_t nextents; /* number of extent entries */
1479
1480 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE ||
1481 XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS ||
1482 XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL);
1483 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) {
1484 *first_unused = 0;
1485 return 0;
1486 }
1487 ifp = XFS_IFORK_PTR(ip, whichfork);
1488 if (!(ifp->if_flags & XFS_IFEXTENTS) &&
1489 (error = xfs_iread_extents(tp, ip, whichfork)))
1490 return error;
1491 lowest = *first_unused;
1492 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
1493 for (idx = 0, lastaddr = 0, max = lowest; idx < nextents; idx++) {
1494 xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, idx);
1495 off = xfs_bmbt_get_startoff(ep);
2bd0ea18 1496 /*
49f693fa 1497 * See if the hole before this extent will work.
2bd0ea18 1498 */
49f693fa
DC
1499 if (off >= lowest + len && off - max >= len) {
1500 *first_unused = max;
1501 return 0;
2bd0ea18 1502 }
49f693fa
DC
1503 lastaddr = off + xfs_bmbt_get_blockcount(ep);
1504 max = XFS_FILEOFF_MAX(lastaddr, lowest);
1505 }
1506 *first_unused = max;
1507 return 0;
1508}
1509
1510/*
e6d77a21 1511 * Returns the file-relative block number of the last block - 1 before
49f693fa
DC
1512 * last_block (input value) in the file.
1513 * This is not based on i_size, it is based on the extent records.
1514 * Returns 0 for local files, as they do not have extent records.
1515 */
1516int /* error */
1517xfs_bmap_last_before(
1518 xfs_trans_t *tp, /* transaction pointer */
1519 xfs_inode_t *ip, /* incore inode */
1520 xfs_fileoff_t *last_block, /* last block */
1521 int whichfork) /* data or attr fork */
1522{
1523 xfs_fileoff_t bno; /* input file offset */
1524 int eof; /* hit end of file */
1525 xfs_bmbt_rec_host_t *ep; /* pointer to last extent */
1526 int error; /* error return value */
1527 xfs_bmbt_irec_t got; /* current extent value */
1528 xfs_ifork_t *ifp; /* inode fork pointer */
1529 xfs_extnum_t lastx; /* last extent used */
1530 xfs_bmbt_irec_t prev; /* previous extent value */
1531
1532 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
1533 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
1534 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL)
12b53197 1535 return -EIO;
49f693fa
DC
1536 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) {
1537 *last_block = 0;
1538 return 0;
1539 }
1540 ifp = XFS_IFORK_PTR(ip, whichfork);
1541 if (!(ifp->if_flags & XFS_IFEXTENTS) &&
1542 (error = xfs_iread_extents(tp, ip, whichfork)))
1543 return error;
1544 bno = *last_block - 1;
1545 ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got,
1546 &prev);
1547 if (eof || xfs_bmbt_get_startoff(ep) > bno) {
1548 if (prev.br_startoff == NULLFILEOFF)
1549 *last_block = 0;
2bd0ea18 1550 else
49f693fa 1551 *last_block = prev.br_startoff + prev.br_blockcount;
2bd0ea18 1552 }
49f693fa
DC
1553 /*
1554 * Otherwise *last_block is already the right answer.
1555 */
1556 return 0;
5e656dbb
BN
1557}
1558
613e6057 1559int
49f693fa
DC
1560xfs_bmap_last_extent(
1561 struct xfs_trans *tp,
1562 struct xfs_inode *ip,
1563 int whichfork,
1564 struct xfs_bmbt_irec *rec,
1565 int *is_empty)
56b2de80 1566{
49f693fa 1567 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
56b2de80 1568 int error;
49f693fa 1569 int nextents;
56b2de80 1570
49f693fa
DC
1571 if (!(ifp->if_flags & XFS_IFEXTENTS)) {
1572 error = xfs_iread_extents(tp, ip, whichfork);
1573 if (error)
1574 return error;
1575 }
1576
1577 nextents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t);
1578 if (nextents == 0) {
1579 *is_empty = 1;
1580 return 0;
1581 }
1582
1583 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, nextents - 1), rec);
1584 *is_empty = 0;
1585 return 0;
1586}
1587
1588/*
1589 * Check the last inode extent to determine whether this allocation will result
1590 * in blocks being allocated at the end of the file. When we allocate new data
1591 * blocks at the end of the file which do not start at the previous data block,
1592 * we will try to align the new blocks at stripe unit boundaries.
1593 *
ff105f75 1594 * Returns 1 in bma->aeof if the file (fork) is empty as any new write will be
49f693fa
DC
1595 * at, or past the EOF.
1596 */
1597STATIC int
1598xfs_bmap_isaeof(
1599 struct xfs_bmalloca *bma,
1600 int whichfork)
1601{
1602 struct xfs_bmbt_irec rec;
1603 int is_empty;
1604 int error;
1605
1606 bma->aeof = 0;
1607 error = xfs_bmap_last_extent(NULL, bma->ip, whichfork, &rec,
1608 &is_empty);
ff105f75 1609 if (error)
49f693fa 1610 return error;
56b2de80 1611
ff105f75
DC
1612 if (is_empty) {
1613 bma->aeof = 1;
1614 return 0;
1615 }
1616
56b2de80 1617 /*
49f693fa
DC
1618 * Check if we are allocation or past the last extent, or at least into
1619 * the last delayed allocated extent.
56b2de80 1620 */
49f693fa
DC
1621 bma->aeof = bma->offset >= rec.br_startoff + rec.br_blockcount ||
1622 (bma->offset >= rec.br_startoff &&
1623 isnullstartblock(rec.br_startblock));
1624 return 0;
1625}
56b2de80 1626
49f693fa
DC
1627/*
1628 * Returns the file-relative block number of the first block past eof in
1629 * the file. This is not based on i_size, it is based on the extent records.
1630 * Returns 0 for local files, as they do not have extent records.
1631 */
1632int
1633xfs_bmap_last_offset(
49f693fa
DC
1634 struct xfs_inode *ip,
1635 xfs_fileoff_t *last_block,
1636 int whichfork)
1637{
1638 struct xfs_bmbt_irec rec;
1639 int is_empty;
1640 int error;
1641
1642 *last_block = 0;
1643
1644 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL)
1645 return 0;
1646
1647 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
1648 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)
12b53197 1649 return -EIO;
49f693fa
DC
1650
1651 error = xfs_bmap_last_extent(NULL, ip, whichfork, &rec, &is_empty);
1652 if (error || is_empty)
1653 return error;
1654
1655 *last_block = rec.br_startoff + rec.br_blockcount;
1656 return 0;
1657}
1658
1659/*
1660 * Returns whether the selected fork of the inode has exactly one
1661 * block or not. For the data fork we check this matches di_size,
1662 * implying the file's range is 0..bsize-1.
1663 */
1664int /* 1=>1 block, 0=>otherwise */
1665xfs_bmap_one_block(
1666 xfs_inode_t *ip, /* incore inode */
1667 int whichfork) /* data or attr fork */
1668{
1669 xfs_bmbt_rec_host_t *ep; /* ptr to fork's extent */
1670 xfs_ifork_t *ifp; /* inode fork pointer */
1671 int rval; /* return value */
1672 xfs_bmbt_irec_t s; /* internal version of extent */
1673
1674#ifndef DEBUG
1675 if (whichfork == XFS_DATA_FORK)
1676 return XFS_ISIZE(ip) == ip->i_mount->m_sb.sb_blocksize;
1677#endif /* !DEBUG */
1678 if (XFS_IFORK_NEXTENTS(ip, whichfork) != 1)
1679 return 0;
1680 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)
1681 return 0;
1682 ifp = XFS_IFORK_PTR(ip, whichfork);
1683 ASSERT(ifp->if_flags & XFS_IFEXTENTS);
1684 ep = xfs_iext_get_ext(ifp, 0);
1685 xfs_bmbt_get_all(ep, &s);
1686 rval = s.br_startoff == 0 && s.br_blockcount == 1;
1687 if (rval && whichfork == XFS_DATA_FORK)
1688 ASSERT(XFS_ISIZE(ip) == ip->i_mount->m_sb.sb_blocksize);
1689 return rval;
1690}
1691
1692/*
1693 * Extent tree manipulation functions used during allocation.
1694 */
1695
1696/*
1697 * Convert a delayed allocation to a real allocation.
1698 */
1699STATIC int /* error */
1700xfs_bmap_add_extent_delay_real(
1701 struct xfs_bmalloca *bma)
1702{
1703 struct xfs_bmbt_irec *new = &bma->got;
1704 int diff; /* temp value */
1705 xfs_bmbt_rec_host_t *ep; /* extent entry for idx */
1706 int error; /* error return value */
1707 int i; /* temp state */
1708 xfs_ifork_t *ifp; /* inode fork pointer */
1709 xfs_fileoff_t new_endoff; /* end offset of new entry */
1710 xfs_bmbt_irec_t r[3]; /* neighbor extent entries */
1711 /* left is 0, right is 1, prev is 2 */
1712 int rval=0; /* return value (logging flags) */
1713 int state = 0;/* state bits, accessed thru macros */
1714 xfs_filblks_t da_new; /* new count del alloc blocks used */
1715 xfs_filblks_t da_old; /* old count del alloc blocks used */
1716 xfs_filblks_t temp=0; /* value for da_new calculations */
1717 xfs_filblks_t temp2=0;/* value for da_new calculations */
1718 int tmp_rval; /* partial logging flags */
19ebedcf 1719 struct xfs_mount *mp;
36e8786d 1720 int whichfork = XFS_DATA_FORK;
49f693fa 1721
65ca3804 1722 mp = bma->ip->i_mount;
36e8786d 1723 ifp = XFS_IFORK_PTR(bma->ip, whichfork);
56b2de80 1724
49f693fa
DC
1725 ASSERT(bma->idx >= 0);
1726 ASSERT(bma->idx <= ifp->if_bytes / sizeof(struct xfs_bmbt_rec));
1727 ASSERT(!isnullstartblock(new->br_startblock));
1728 ASSERT(!bma->cur ||
1729 (bma->cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL));
56b2de80 1730
79896434 1731 XFS_STATS_INC(mp, xs_add_exlist);
49f693fa
DC
1732
1733#define LEFT r[0]
1734#define RIGHT r[1]
1735#define PREV r[2]
56b2de80
DC
1736
1737 /*
49f693fa 1738 * Set up a bunch of variables to make the tests simpler.
56b2de80 1739 */
49f693fa
DC
1740 ep = xfs_iext_get_ext(ifp, bma->idx);
1741 xfs_bmbt_get_all(ep, &PREV);
1742 new_endoff = new->br_startoff + new->br_blockcount;
1743 ASSERT(PREV.br_startoff <= new->br_startoff);
1744 ASSERT(PREV.br_startoff + PREV.br_blockcount >= new_endoff);
1745
1746 da_old = startblockval(PREV.br_startblock);
1747 da_new = 0;
1748
56b2de80 1749 /*
49f693fa
DC
1750 * Set flags determining what part of the previous delayed allocation
1751 * extent is being replaced by a real allocation.
56b2de80 1752 */
49f693fa
DC
1753 if (PREV.br_startoff == new->br_startoff)
1754 state |= BMAP_LEFT_FILLING;
1755 if (PREV.br_startoff + PREV.br_blockcount == new_endoff)
1756 state |= BMAP_RIGHT_FILLING;
1757
56b2de80 1758 /*
49f693fa
DC
1759 * Check and set flags if this segment has a left neighbor.
1760 * Don't set contiguous if the combined extent would be too large.
56b2de80 1761 */
49f693fa
DC
1762 if (bma->idx > 0) {
1763 state |= BMAP_LEFT_VALID;
1764 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx - 1), &LEFT);
1765
1766 if (isnullstartblock(LEFT.br_startblock))
1767 state |= BMAP_LEFT_DELAY;
1768 }
1769
1770 if ((state & BMAP_LEFT_VALID) && !(state & BMAP_LEFT_DELAY) &&
1771 LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff &&
1772 LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock &&
1773 LEFT.br_state == new->br_state &&
1774 LEFT.br_blockcount + new->br_blockcount <= MAXEXTLEN)
1775 state |= BMAP_LEFT_CONTIG;
56b2de80
DC
1776
1777 /*
49f693fa
DC
1778 * Check and set flags if this segment has a right neighbor.
1779 * Don't set contiguous if the combined extent would be too large.
1780 * Also check for all-three-contiguous being too large.
56b2de80 1781 */
36e8786d 1782 if (bma->idx < ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) {
49f693fa
DC
1783 state |= BMAP_RIGHT_VALID;
1784 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx + 1), &RIGHT);
56b2de80 1785
49f693fa
DC
1786 if (isnullstartblock(RIGHT.br_startblock))
1787 state |= BMAP_RIGHT_DELAY;
1788 }
56b2de80 1789
49f693fa
DC
1790 if ((state & BMAP_RIGHT_VALID) && !(state & BMAP_RIGHT_DELAY) &&
1791 new_endoff == RIGHT.br_startoff &&
1792 new->br_startblock + new->br_blockcount == RIGHT.br_startblock &&
1793 new->br_state == RIGHT.br_state &&
1794 new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN &&
1795 ((state & (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING |
1796 BMAP_RIGHT_FILLING)) !=
1797 (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING |
1798 BMAP_RIGHT_FILLING) ||
1799 LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount
1800 <= MAXEXTLEN))
1801 state |= BMAP_RIGHT_CONTIG;
5e656dbb 1802
49f693fa
DC
1803 error = 0;
1804 /*
1805 * Switch out based on the FILLING and CONTIG state bits.
1806 */
1807 switch (state & (BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG |
1808 BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG)) {
1809 case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG |
1810 BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG:
1811 /*
1812 * Filling in all of a previously delayed allocation extent.
1813 * The left and right neighbors are both contiguous with new.
1814 */
1815 bma->idx--;
1816 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
1817 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, bma->idx),
1818 LEFT.br_blockcount + PREV.br_blockcount +
1819 RIGHT.br_blockcount);
1820 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
a2ceac1f 1821
49f693fa
DC
1822 xfs_iext_remove(bma->ip, bma->idx + 1, 2, state);
1823 bma->ip->i_d.di_nextents--;
1824 if (bma->cur == NULL)
1825 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
1826 else {
1827 rval = XFS_ILOG_CORE;
1828 error = xfs_bmbt_lookup_eq(bma->cur, RIGHT.br_startoff,
1829 RIGHT.br_startblock,
1830 RIGHT.br_blockcount, &i);
1831 if (error)
1832 goto done;
19ebedcf 1833 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
1834 error = xfs_btree_delete(bma->cur, &i);
1835 if (error)
1836 goto done;
19ebedcf 1837 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
1838 error = xfs_btree_decrement(bma->cur, 0, &i);
1839 if (error)
1840 goto done;
19ebedcf 1841 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
1842 error = xfs_bmbt_update(bma->cur, LEFT.br_startoff,
1843 LEFT.br_startblock,
1844 LEFT.br_blockcount +
1845 PREV.br_blockcount +
1846 RIGHT.br_blockcount, LEFT.br_state);
1847 if (error)
1848 goto done;
5e656dbb 1849 }
49f693fa
DC
1850 break;
1851
1852 case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG:
1853 /*
1854 * Filling in all of a previously delayed allocation extent.
1855 * The left neighbor is contiguous, the right is not.
1856 */
1857 bma->idx--;
1858
1859 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
1860 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, bma->idx),
1861 LEFT.br_blockcount + PREV.br_blockcount);
1862 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
1863
1864 xfs_iext_remove(bma->ip, bma->idx + 1, 1, state);
1865 if (bma->cur == NULL)
1866 rval = XFS_ILOG_DEXT;
1867 else {
1868 rval = 0;
1869 error = xfs_bmbt_lookup_eq(bma->cur, LEFT.br_startoff,
1870 LEFT.br_startblock, LEFT.br_blockcount,
1871 &i);
1872 if (error)
1873 goto done;
19ebedcf 1874 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
1875 error = xfs_bmbt_update(bma->cur, LEFT.br_startoff,
1876 LEFT.br_startblock,
1877 LEFT.br_blockcount +
1878 PREV.br_blockcount, LEFT.br_state);
1879 if (error)
1880 goto done;
1881 }
1882 break;
1883
1884 case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG:
1885 /*
1886 * Filling in all of a previously delayed allocation extent.
1887 * The right neighbor is contiguous, the left is not.
1888 */
1889 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
1890 xfs_bmbt_set_startblock(ep, new->br_startblock);
1891 xfs_bmbt_set_blockcount(ep,
1892 PREV.br_blockcount + RIGHT.br_blockcount);
1893 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
1894
1895 xfs_iext_remove(bma->ip, bma->idx + 1, 1, state);
1896 if (bma->cur == NULL)
1897 rval = XFS_ILOG_DEXT;
1898 else {
1899 rval = 0;
1900 error = xfs_bmbt_lookup_eq(bma->cur, RIGHT.br_startoff,
1901 RIGHT.br_startblock,
1902 RIGHT.br_blockcount, &i);
1903 if (error)
1904 goto done;
19ebedcf 1905 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
1906 error = xfs_bmbt_update(bma->cur, PREV.br_startoff,
1907 new->br_startblock,
1908 PREV.br_blockcount +
1909 RIGHT.br_blockcount, PREV.br_state);
1910 if (error)
1911 goto done;
1912 }
1913 break;
1914
1915 case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING:
1916 /*
1917 * Filling in all of a previously delayed allocation extent.
1918 * Neither the left nor right neighbors are contiguous with
1919 * the new one.
1920 */
1921 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
1922 xfs_bmbt_set_startblock(ep, new->br_startblock);
1923 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
5e656dbb 1924
49f693fa
DC
1925 bma->ip->i_d.di_nextents++;
1926 if (bma->cur == NULL)
1927 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
1928 else {
1929 rval = XFS_ILOG_CORE;
1930 error = xfs_bmbt_lookup_eq(bma->cur, new->br_startoff,
1931 new->br_startblock, new->br_blockcount,
1932 &i);
1933 if (error)
1934 goto done;
19ebedcf 1935 XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done);
49f693fa
DC
1936 bma->cur->bc_rec.b.br_state = XFS_EXT_NORM;
1937 error = xfs_btree_insert(bma->cur, &i);
1938 if (error)
1939 goto done;
19ebedcf 1940 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
1941 }
1942 break;
5e656dbb 1943
49f693fa
DC
1944 case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG:
1945 /*
1946 * Filling in the first part of a previous delayed allocation.
1947 * The left neighbor is contiguous.
1948 */
1949 trace_xfs_bmap_pre_update(bma->ip, bma->idx - 1, state, _THIS_IP_);
1950 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, bma->idx - 1),
1951 LEFT.br_blockcount + new->br_blockcount);
1952 xfs_bmbt_set_startoff(ep,
1953 PREV.br_startoff + new->br_blockcount);
1954 trace_xfs_bmap_post_update(bma->ip, bma->idx - 1, state, _THIS_IP_);
a2ceac1f 1955
49f693fa
DC
1956 temp = PREV.br_blockcount - new->br_blockcount;
1957 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
1958 xfs_bmbt_set_blockcount(ep, temp);
1959 if (bma->cur == NULL)
1960 rval = XFS_ILOG_DEXT;
1961 else {
1962 rval = 0;
1963 error = xfs_bmbt_lookup_eq(bma->cur, LEFT.br_startoff,
1964 LEFT.br_startblock, LEFT.br_blockcount,
1965 &i);
1966 if (error)
1967 goto done;
19ebedcf 1968 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
1969 error = xfs_bmbt_update(bma->cur, LEFT.br_startoff,
1970 LEFT.br_startblock,
1971 LEFT.br_blockcount +
1972 new->br_blockcount,
1973 LEFT.br_state);
1974 if (error)
1975 goto done;
2bd0ea18 1976 }
49f693fa
DC
1977 da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp),
1978 startblockval(PREV.br_startblock));
1979 xfs_bmbt_set_startblock(ep, nullstartblock(da_new));
1980 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
1981
1982 bma->idx--;
1983 break;
1984
1985 case BMAP_LEFT_FILLING:
2bd0ea18 1986 /*
49f693fa
DC
1987 * Filling in the first part of a previous delayed allocation.
1988 * The left neighbor is not contiguous.
5000d01d 1989 */
49f693fa
DC
1990 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
1991 xfs_bmbt_set_startoff(ep, new_endoff);
1992 temp = PREV.br_blockcount - new->br_blockcount;
1993 xfs_bmbt_set_blockcount(ep, temp);
1994 xfs_iext_insert(bma->ip, bma->idx, 1, new, state);
1995 bma->ip->i_d.di_nextents++;
1996 if (bma->cur == NULL)
1997 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
1998 else {
1999 rval = XFS_ILOG_CORE;
2000 error = xfs_bmbt_lookup_eq(bma->cur, new->br_startoff,
2001 new->br_startblock, new->br_blockcount,
2002 &i);
2003 if (error)
2004 goto done;
19ebedcf 2005 XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done);
49f693fa
DC
2006 bma->cur->bc_rec.b.br_state = XFS_EXT_NORM;
2007 error = xfs_btree_insert(bma->cur, &i);
2008 if (error)
2009 goto done;
19ebedcf 2010 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
2011 }
2012
36e8786d 2013 if (xfs_bmap_needs_btree(bma->ip, whichfork)) {
49f693fa
DC
2014 error = xfs_bmap_extents_to_btree(bma->tp, bma->ip,
2015 bma->firstblock, bma->flist,
36e8786d 2016 &bma->cur, 1, &tmp_rval, whichfork);
49f693fa
DC
2017 rval |= tmp_rval;
2018 if (error)
2019 goto done;
2020 }
2021 da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp),
2022 startblockval(PREV.br_startblock) -
2023 (bma->cur ? bma->cur->bc_private.b.allocated : 0));
2024 ep = xfs_iext_get_ext(ifp, bma->idx + 1);
2025 xfs_bmbt_set_startblock(ep, nullstartblock(da_new));
2026 trace_xfs_bmap_post_update(bma->ip, bma->idx + 1, state, _THIS_IP_);
2027 break;
2028
2029 case BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG:
5e656dbb 2030 /*
49f693fa
DC
2031 * Filling in the last part of a previous delayed allocation.
2032 * The right neighbor is contiguous with the new allocation.
5e656dbb 2033 */
49f693fa
DC
2034 temp = PREV.br_blockcount - new->br_blockcount;
2035 trace_xfs_bmap_pre_update(bma->ip, bma->idx + 1, state, _THIS_IP_);
2036 xfs_bmbt_set_blockcount(ep, temp);
2037 xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, bma->idx + 1),
2038 new->br_startoff, new->br_startblock,
2039 new->br_blockcount + RIGHT.br_blockcount,
2040 RIGHT.br_state);
2041 trace_xfs_bmap_post_update(bma->ip, bma->idx + 1, state, _THIS_IP_);
2042 if (bma->cur == NULL)
2043 rval = XFS_ILOG_DEXT;
2044 else {
2045 rval = 0;
2046 error = xfs_bmbt_lookup_eq(bma->cur, RIGHT.br_startoff,
2047 RIGHT.br_startblock,
2048 RIGHT.br_blockcount, &i);
2049 if (error)
2050 goto done;
19ebedcf 2051 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
2052 error = xfs_bmbt_update(bma->cur, new->br_startoff,
2053 new->br_startblock,
2054 new->br_blockcount +
2055 RIGHT.br_blockcount,
2056 RIGHT.br_state);
2057 if (error)
2058 goto done;
2059 }
2060
2061 da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp),
2062 startblockval(PREV.br_startblock));
2063 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
2064 xfs_bmbt_set_startblock(ep, nullstartblock(da_new));
2065 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
2066
2067 bma->idx++;
2068 break;
2069
2070 case BMAP_RIGHT_FILLING:
a2ceac1f 2071 /*
49f693fa
DC
2072 * Filling in the last part of a previous delayed allocation.
2073 * The right neighbor is not contiguous.
a2ceac1f 2074 */
49f693fa
DC
2075 temp = PREV.br_blockcount - new->br_blockcount;
2076 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
2077 xfs_bmbt_set_blockcount(ep, temp);
2078 xfs_iext_insert(bma->ip, bma->idx + 1, 1, new, state);
2079 bma->ip->i_d.di_nextents++;
2080 if (bma->cur == NULL)
2081 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
2082 else {
2083 rval = XFS_ILOG_CORE;
2084 error = xfs_bmbt_lookup_eq(bma->cur, new->br_startoff,
2085 new->br_startblock, new->br_blockcount,
2086 &i);
2087 if (error)
2088 goto done;
19ebedcf 2089 XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done);
49f693fa
DC
2090 bma->cur->bc_rec.b.br_state = XFS_EXT_NORM;
2091 error = xfs_btree_insert(bma->cur, &i);
2092 if (error)
2093 goto done;
19ebedcf 2094 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa 2095 }
a2ceac1f 2096
36e8786d 2097 if (xfs_bmap_needs_btree(bma->ip, whichfork)) {
49f693fa
DC
2098 error = xfs_bmap_extents_to_btree(bma->tp, bma->ip,
2099 bma->firstblock, bma->flist, &bma->cur, 1,
36e8786d 2100 &tmp_rval, whichfork);
49f693fa
DC
2101 rval |= tmp_rval;
2102 if (error)
2103 goto done;
2104 }
2105 da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp),
2106 startblockval(PREV.br_startblock) -
2107 (bma->cur ? bma->cur->bc_private.b.allocated : 0));
2108 ep = xfs_iext_get_ext(ifp, bma->idx);
2109 xfs_bmbt_set_startblock(ep, nullstartblock(da_new));
2110 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
2111
2112 bma->idx++;
2113 break;
2114
2115 case 0:
5e656dbb 2116 /*
49f693fa
DC
2117 * Filling in the middle part of a previous delayed allocation.
2118 * Contiguity is impossible here.
2119 * This case is avoided almost all the time.
2120 *
2121 * We start with a delayed allocation:
2122 *
2123 * +ddddddddddddddddddddddddddddddddddddddddddddddddddddddd+
2124 * PREV @ idx
2125 *
2126 * and we are allocating:
2127 * +rrrrrrrrrrrrrrrrr+
2128 * new
2129 *
2130 * and we set it up for insertion as:
2131 * +ddddddddddddddddddd+rrrrrrrrrrrrrrrrr+ddddddddddddddddd+
2132 * new
2133 * PREV @ idx LEFT RIGHT
2134 * inserted at idx + 1
5e656dbb 2135 */
49f693fa
DC
2136 temp = new->br_startoff - PREV.br_startoff;
2137 temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff;
2138 trace_xfs_bmap_pre_update(bma->ip, bma->idx, 0, _THIS_IP_);
2139 xfs_bmbt_set_blockcount(ep, temp); /* truncate PREV */
2140 LEFT = *new;
2141 RIGHT.br_state = PREV.br_state;
2142 RIGHT.br_startblock = nullstartblock(
2143 (int)xfs_bmap_worst_indlen(bma->ip, temp2));
2144 RIGHT.br_startoff = new_endoff;
2145 RIGHT.br_blockcount = temp2;
2146 /* insert LEFT (r[0]) and RIGHT (r[1]) at the same time */
2147 xfs_iext_insert(bma->ip, bma->idx + 1, 2, &LEFT, state);
2148 bma->ip->i_d.di_nextents++;
2149 if (bma->cur == NULL)
2150 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
2151 else {
2152 rval = XFS_ILOG_CORE;
2153 error = xfs_bmbt_lookup_eq(bma->cur, new->br_startoff,
2154 new->br_startblock, new->br_blockcount,
2155 &i);
2156 if (error)
2157 goto done;
19ebedcf 2158 XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done);
49f693fa
DC
2159 bma->cur->bc_rec.b.br_state = XFS_EXT_NORM;
2160 error = xfs_btree_insert(bma->cur, &i);
2161 if (error)
2162 goto done;
19ebedcf 2163 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa 2164 }
5e656dbb 2165
36e8786d 2166 if (xfs_bmap_needs_btree(bma->ip, whichfork)) {
49f693fa
DC
2167 error = xfs_bmap_extents_to_btree(bma->tp, bma->ip,
2168 bma->firstblock, bma->flist, &bma->cur,
36e8786d 2169 1, &tmp_rval, whichfork);
49f693fa
DC
2170 rval |= tmp_rval;
2171 if (error)
2172 goto done;
2173 }
2174 temp = xfs_bmap_worst_indlen(bma->ip, temp);
2175 temp2 = xfs_bmap_worst_indlen(bma->ip, temp2);
2176 diff = (int)(temp + temp2 - startblockval(PREV.br_startblock) -
2177 (bma->cur ? bma->cur->bc_private.b.allocated : 0));
2178 if (diff > 0) {
19ebedcf
DC
2179 error = xfs_mod_fdblocks(bma->ip->i_mount,
2180 -((int64_t)diff), false);
49f693fa
DC
2181 ASSERT(!error);
2182 if (error)
2183 goto done;
2184 }
2bd0ea18 2185
49f693fa
DC
2186 ep = xfs_iext_get_ext(ifp, bma->idx);
2187 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
2188 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
2189 trace_xfs_bmap_pre_update(bma->ip, bma->idx + 2, state, _THIS_IP_);
2190 xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, bma->idx + 2),
2191 nullstartblock((int)temp2));
2192 trace_xfs_bmap_post_update(bma->ip, bma->idx + 2, state, _THIS_IP_);
2bd0ea18 2193
49f693fa
DC
2194 bma->idx++;
2195 da_new = temp + temp2;
2196 break;
2197
2198 case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG:
2199 case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG:
2200 case BMAP_LEFT_FILLING | BMAP_RIGHT_CONTIG:
2201 case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG:
2202 case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG:
2203 case BMAP_LEFT_CONTIG:
2204 case BMAP_RIGHT_CONTIG:
2205 /*
2206 * These cases are all impossible.
2207 */
2208 ASSERT(0);
2209 }
2210
2211 /* convert to a btree if necessary */
36e8786d 2212 if (xfs_bmap_needs_btree(bma->ip, whichfork)) {
49f693fa
DC
2213 int tmp_logflags; /* partial log flag return val */
2214
2215 ASSERT(bma->cur == NULL);
2216 error = xfs_bmap_extents_to_btree(bma->tp, bma->ip,
2217 bma->firstblock, bma->flist, &bma->cur,
36e8786d 2218 da_old > 0, &tmp_logflags, whichfork);
49f693fa
DC
2219 bma->logflags |= tmp_logflags;
2220 if (error)
2221 goto done;
2222 }
2223
2224 /* adjust for changes in reserved delayed indirect blocks */
2225 if (da_old || da_new) {
2226 temp = da_new;
2227 if (bma->cur)
2228 temp += bma->cur->bc_private.b.allocated;
2229 ASSERT(temp <= da_old);
2230 if (temp < da_old)
19ebedcf
DC
2231 xfs_mod_fdblocks(bma->ip->i_mount,
2232 (int64_t)(da_old - temp), false);
49f693fa
DC
2233 }
2234
2235 /* clear out the allocated field, done with it now in any case. */
2236 if (bma->cur)
2237 bma->cur->bc_private.b.allocated = 0;
2238
36e8786d 2239 xfs_bmap_check_leaf_extents(bma->cur, bma->ip, whichfork);
49f693fa
DC
2240done:
2241 bma->logflags |= rval;
2242 return error;
2243#undef LEFT
2244#undef RIGHT
2245#undef PREV
2bd0ea18
NS
2246}
2247
2248/*
49f693fa 2249 * Convert an unwritten allocation to a real allocation or vice versa.
2bd0ea18
NS
2250 */
2251STATIC int /* error */
49f693fa
DC
2252xfs_bmap_add_extent_unwritten_real(
2253 struct xfs_trans *tp,
2bd0ea18 2254 xfs_inode_t *ip, /* incore inode pointer */
49f693fa
DC
2255 xfs_extnum_t *idx, /* extent number to update/insert */
2256 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
2257 xfs_bmbt_irec_t *new, /* new data to add to file extents */
2258 xfs_fsblock_t *first, /* pointer to firstblock variable */
dfc130f3 2259 xfs_bmap_free_t *flist, /* list of extents to be freed */
49f693fa 2260 int *logflagsp) /* inode logging flags */
2bd0ea18 2261{
49f693fa
DC
2262 xfs_btree_cur_t *cur; /* btree cursor */
2263 xfs_bmbt_rec_host_t *ep; /* extent entry for idx */
2bd0ea18 2264 int error; /* error return value */
2bd0ea18
NS
2265 int i; /* temp state */
2266 xfs_ifork_t *ifp; /* inode fork pointer */
49f693fa
DC
2267 xfs_fileoff_t new_endoff; /* end offset of new entry */
2268 xfs_exntst_t newext; /* new extent state */
2269 xfs_exntst_t oldext; /* old extent state */
2270 xfs_bmbt_irec_t r[3]; /* neighbor extent entries */
2271 /* left is 0, right is 1, prev is 2 */
2272 int rval=0; /* return value (logging flags) */
2273 int state = 0;/* state bits, accessed thru macros */
19ebedcf 2274 struct xfs_mount *mp = tp->t_mountp;
5000d01d 2275
49f693fa 2276 *logflagsp = 0;
56b2de80 2277
49f693fa
DC
2278 cur = *curp;
2279 ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
56b2de80 2280
49f693fa
DC
2281 ASSERT(*idx >= 0);
2282 ASSERT(*idx <= ifp->if_bytes / sizeof(struct xfs_bmbt_rec));
2283 ASSERT(!isnullstartblock(new->br_startblock));
2284
79896434 2285 XFS_STATS_INC(mp, xs_add_exlist);
49f693fa
DC
2286
2287#define LEFT r[0]
2288#define RIGHT r[1]
2289#define PREV r[2]
2290
2291 /*
2292 * Set up a bunch of variables to make the tests simpler.
2293 */
2bd0ea18 2294 error = 0;
49f693fa
DC
2295 ep = xfs_iext_get_ext(ifp, *idx);
2296 xfs_bmbt_get_all(ep, &PREV);
2297 newext = new->br_state;
2298 oldext = (newext == XFS_EXT_UNWRITTEN) ?
2299 XFS_EXT_NORM : XFS_EXT_UNWRITTEN;
2300 ASSERT(PREV.br_state == oldext);
2301 new_endoff = new->br_startoff + new->br_blockcount;
2302 ASSERT(PREV.br_startoff <= new->br_startoff);
2303 ASSERT(PREV.br_startoff + PREV.br_blockcount >= new_endoff);
2304
2bd0ea18 2305 /*
49f693fa
DC
2306 * Set flags determining what part of the previous oldext allocation
2307 * extent is being replaced by a newext allocation.
2bd0ea18 2308 */
49f693fa
DC
2309 if (PREV.br_startoff == new->br_startoff)
2310 state |= BMAP_LEFT_FILLING;
2311 if (PREV.br_startoff + PREV.br_blockcount == new_endoff)
2312 state |= BMAP_RIGHT_FILLING;
2bd0ea18 2313
49f693fa
DC
2314 /*
2315 * Check and set flags if this segment has a left neighbor.
2316 * Don't set contiguous if the combined extent would be too large.
2317 */
2318 if (*idx > 0) {
2319 state |= BMAP_LEFT_VALID;
2320 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx - 1), &LEFT);
2321
2322 if (isnullstartblock(LEFT.br_startblock))
2323 state |= BMAP_LEFT_DELAY;
2bd0ea18 2324 }
49f693fa
DC
2325
2326 if ((state & BMAP_LEFT_VALID) && !(state & BMAP_LEFT_DELAY) &&
2327 LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff &&
2328 LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock &&
2329 LEFT.br_state == newext &&
2330 LEFT.br_blockcount + new->br_blockcount <= MAXEXTLEN)
2331 state |= BMAP_LEFT_CONTIG;
2332
2bd0ea18 2333 /*
49f693fa
DC
2334 * Check and set flags if this segment has a right neighbor.
2335 * Don't set contiguous if the combined extent would be too large.
2336 * Also check for all-three-contiguous being too large.
2bd0ea18 2337 */
49f693fa
DC
2338 if (*idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) {
2339 state |= BMAP_RIGHT_VALID;
2340 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx + 1), &RIGHT);
2341 if (isnullstartblock(RIGHT.br_startblock))
2342 state |= BMAP_RIGHT_DELAY;
2343 }
a2ceac1f 2344
49f693fa
DC
2345 if ((state & BMAP_RIGHT_VALID) && !(state & BMAP_RIGHT_DELAY) &&
2346 new_endoff == RIGHT.br_startoff &&
2347 new->br_startblock + new->br_blockcount == RIGHT.br_startblock &&
2348 newext == RIGHT.br_state &&
2349 new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN &&
2350 ((state & (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING |
2351 BMAP_RIGHT_FILLING)) !=
2352 (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING |
2353 BMAP_RIGHT_FILLING) ||
2354 LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount
2355 <= MAXEXTLEN))
2356 state |= BMAP_RIGHT_CONTIG;
2bd0ea18 2357
49f693fa
DC
2358 /*
2359 * Switch out based on the FILLING and CONTIG state bits.
2360 */
2361 switch (state & (BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG |
2362 BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG)) {
2363 case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG |
2364 BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG:
2bd0ea18 2365 /*
49f693fa
DC
2366 * Setting all of a previous oldext extent to newext.
2367 * The left and right neighbors are both contiguous with new.
2bd0ea18 2368 */
49f693fa
DC
2369 --*idx;
2370
a2ceac1f 2371 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
49f693fa
DC
2372 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx),
2373 LEFT.br_blockcount + PREV.br_blockcount +
2374 RIGHT.br_blockcount);
a2ceac1f 2375 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
49f693fa
DC
2376
2377 xfs_iext_remove(ip, *idx + 1, 2, state);
2378 ip->i_d.di_nextents -= 2;
2379 if (cur == NULL)
2380 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
2381 else {
2382 rval = XFS_ILOG_CORE;
2383 if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff,
2384 RIGHT.br_startblock,
2385 RIGHT.br_blockcount, &i)))
2386 goto done;
19ebedcf 2387 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
2388 if ((error = xfs_btree_delete(cur, &i)))
2389 goto done;
19ebedcf 2390 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
2391 if ((error = xfs_btree_decrement(cur, 0, &i)))
2392 goto done;
19ebedcf 2393 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
2394 if ((error = xfs_btree_delete(cur, &i)))
2395 goto done;
19ebedcf 2396 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
2397 if ((error = xfs_btree_decrement(cur, 0, &i)))
2398 goto done;
19ebedcf 2399 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
2400 if ((error = xfs_bmbt_update(cur, LEFT.br_startoff,
2401 LEFT.br_startblock,
2402 LEFT.br_blockcount + PREV.br_blockcount +
2403 RIGHT.br_blockcount, LEFT.br_state)))
2404 goto done;
2bd0ea18 2405 }
2bd0ea18
NS
2406 break;
2407
49f693fa 2408 case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG:
2bd0ea18 2409 /*
49f693fa
DC
2410 * Setting all of a previous oldext extent to newext.
2411 * The left neighbor is contiguous, the right is not.
2bd0ea18 2412 */
49f693fa
DC
2413 --*idx;
2414
a2ceac1f 2415 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
49f693fa
DC
2416 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx),
2417 LEFT.br_blockcount + PREV.br_blockcount);
a2ceac1f 2418 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
49f693fa
DC
2419
2420 xfs_iext_remove(ip, *idx + 1, 1, state);
2421 ip->i_d.di_nextents--;
2422 if (cur == NULL)
2423 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
2424 else {
2425 rval = XFS_ILOG_CORE;
2426 if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff,
2427 PREV.br_startblock, PREV.br_blockcount,
2428 &i)))
2429 goto done;
19ebedcf 2430 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
2431 if ((error = xfs_btree_delete(cur, &i)))
2432 goto done;
19ebedcf 2433 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
2434 if ((error = xfs_btree_decrement(cur, 0, &i)))
2435 goto done;
19ebedcf 2436 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
2437 if ((error = xfs_bmbt_update(cur, LEFT.br_startoff,
2438 LEFT.br_startblock,
2439 LEFT.br_blockcount + PREV.br_blockcount,
2440 LEFT.br_state)))
2441 goto done;
2bd0ea18 2442 }
2bd0ea18 2443 break;
5000d01d 2444
49f693fa 2445 case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG:
2bd0ea18 2446 /*
49f693fa
DC
2447 * Setting all of a previous oldext extent to newext.
2448 * The right neighbor is contiguous, the left is not.
2bd0ea18 2449 */
a2ceac1f 2450 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
49f693fa
DC
2451 xfs_bmbt_set_blockcount(ep,
2452 PREV.br_blockcount + RIGHT.br_blockcount);
2453 xfs_bmbt_set_state(ep, newext);
a2ceac1f 2454 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
49f693fa
DC
2455 xfs_iext_remove(ip, *idx + 1, 1, state);
2456 ip->i_d.di_nextents--;
2457 if (cur == NULL)
2458 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
2459 else {
2460 rval = XFS_ILOG_CORE;
2461 if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff,
2462 RIGHT.br_startblock,
2463 RIGHT.br_blockcount, &i)))
2464 goto done;
19ebedcf 2465 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
2466 if ((error = xfs_btree_delete(cur, &i)))
2467 goto done;
19ebedcf 2468 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
2469 if ((error = xfs_btree_decrement(cur, 0, &i)))
2470 goto done;
19ebedcf 2471 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
2472 if ((error = xfs_bmbt_update(cur, new->br_startoff,
2473 new->br_startblock,
2474 new->br_blockcount + RIGHT.br_blockcount,
2475 newext)))
2476 goto done;
2477 }
2478 break;
2bd0ea18 2479
49f693fa
DC
2480 case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING:
2481 /*
2482 * Setting all of a previous oldext extent to newext.
2483 * Neither the left nor right neighbors are contiguous with
2484 * the new one.
2485 */
2486 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
2487 xfs_bmbt_set_state(ep, newext);
2488 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
2bd0ea18 2489
49f693fa
DC
2490 if (cur == NULL)
2491 rval = XFS_ILOG_DEXT;
2492 else {
2493 rval = 0;
2494 if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff,
2495 new->br_startblock, new->br_blockcount,
2496 &i)))
2497 goto done;
19ebedcf 2498 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
2499 if ((error = xfs_bmbt_update(cur, new->br_startoff,
2500 new->br_startblock, new->br_blockcount,
2501 newext)))
2502 goto done;
2503 }
2504 break;
2bd0ea18 2505
49f693fa
DC
2506 case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG:
2507 /*
2508 * Setting the first part of a previous oldext extent to newext.
2509 * The left neighbor is contiguous.
2510 */
2511 trace_xfs_bmap_pre_update(ip, *idx - 1, state, _THIS_IP_);
2512 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx - 1),
2513 LEFT.br_blockcount + new->br_blockcount);
2514 xfs_bmbt_set_startoff(ep,
2515 PREV.br_startoff + new->br_blockcount);
2516 trace_xfs_bmap_post_update(ip, *idx - 1, state, _THIS_IP_);
a2ceac1f 2517
49f693fa
DC
2518 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
2519 xfs_bmbt_set_startblock(ep,
2520 new->br_startblock + new->br_blockcount);
2521 xfs_bmbt_set_blockcount(ep,
2522 PREV.br_blockcount - new->br_blockcount);
2523 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
b3563c19 2524
49f693fa 2525 --*idx;
b3563c19 2526
49f693fa
DC
2527 if (cur == NULL)
2528 rval = XFS_ILOG_DEXT;
2529 else {
2530 rval = 0;
2531 if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff,
2532 PREV.br_startblock, PREV.br_blockcount,
2533 &i)))
2534 goto done;
19ebedcf 2535 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
2536 if ((error = xfs_bmbt_update(cur,
2537 PREV.br_startoff + new->br_blockcount,
2538 PREV.br_startblock + new->br_blockcount,
2539 PREV.br_blockcount - new->br_blockcount,
2540 oldext)))
2541 goto done;
2542 if ((error = xfs_btree_decrement(cur, 0, &i)))
2543 goto done;
2544 error = xfs_bmbt_update(cur, LEFT.br_startoff,
2545 LEFT.br_startblock,
2546 LEFT.br_blockcount + new->br_blockcount,
2547 LEFT.br_state);
2548 if (error)
2549 goto done;
2bd0ea18 2550 }
49f693fa 2551 break;
b3563c19 2552
49f693fa
DC
2553 case BMAP_LEFT_FILLING:
2554 /*
2555 * Setting the first part of a previous oldext extent to newext.
2556 * The left neighbor is not contiguous.
2557 */
2558 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
2559 ASSERT(ep && xfs_bmbt_get_state(ep) == oldext);
2560 xfs_bmbt_set_startoff(ep, new_endoff);
2561 xfs_bmbt_set_blockcount(ep,
2562 PREV.br_blockcount - new->br_blockcount);
2563 xfs_bmbt_set_startblock(ep,
2564 new->br_startblock + new->br_blockcount);
2565 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
2bd0ea18 2566
49f693fa
DC
2567 xfs_iext_insert(ip, *idx, 1, new, state);
2568 ip->i_d.di_nextents++;
2569 if (cur == NULL)
2570 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
2571 else {
2572 rval = XFS_ILOG_CORE;
2573 if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff,
2574 PREV.br_startblock, PREV.br_blockcount,
2575 &i)))
2576 goto done;
19ebedcf 2577 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
2578 if ((error = xfs_bmbt_update(cur,
2579 PREV.br_startoff + new->br_blockcount,
2580 PREV.br_startblock + new->br_blockcount,
2581 PREV.br_blockcount - new->br_blockcount,
2582 oldext)))
2583 goto done;
2584 cur->bc_rec.b = *new;
2585 if ((error = xfs_btree_insert(cur, &i)))
2586 goto done;
19ebedcf 2587 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
2588 }
2589 break;
56b2de80 2590
49f693fa
DC
2591 case BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG:
2592 /*
2593 * Setting the last part of a previous oldext extent to newext.
2594 * The right neighbor is contiguous with the new allocation.
2595 */
2596 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
2597 xfs_bmbt_set_blockcount(ep,
2598 PREV.br_blockcount - new->br_blockcount);
2599 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
56b2de80 2600
49f693fa 2601 ++*idx;
56b2de80 2602
49f693fa
DC
2603 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
2604 xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, *idx),
2605 new->br_startoff, new->br_startblock,
2606 new->br_blockcount + RIGHT.br_blockcount, newext);
2607 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
56b2de80 2608
49f693fa
DC
2609 if (cur == NULL)
2610 rval = XFS_ILOG_DEXT;
2611 else {
2612 rval = 0;
2613 if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff,
2614 PREV.br_startblock,
2615 PREV.br_blockcount, &i)))
2616 goto done;
19ebedcf 2617 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
2618 if ((error = xfs_bmbt_update(cur, PREV.br_startoff,
2619 PREV.br_startblock,
2620 PREV.br_blockcount - new->br_blockcount,
2621 oldext)))
2622 goto done;
2623 if ((error = xfs_btree_increment(cur, 0, &i)))
2624 goto done;
2625 if ((error = xfs_bmbt_update(cur, new->br_startoff,
2626 new->br_startblock,
2627 new->br_blockcount + RIGHT.br_blockcount,
2628 newext)))
2629 goto done;
2630 }
2631 break;
ca86e759 2632
49f693fa
DC
2633 case BMAP_RIGHT_FILLING:
2634 /*
2635 * Setting the last part of a previous oldext extent to newext.
2636 * The right neighbor is not contiguous.
2637 */
2638 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
2639 xfs_bmbt_set_blockcount(ep,
2640 PREV.br_blockcount - new->br_blockcount);
2641 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
2bd0ea18 2642
49f693fa
DC
2643 ++*idx;
2644 xfs_iext_insert(ip, *idx, 1, new, state);
2bd0ea18 2645
49f693fa
DC
2646 ip->i_d.di_nextents++;
2647 if (cur == NULL)
2648 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
2649 else {
2650 rval = XFS_ILOG_CORE;
2651 if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff,
2652 PREV.br_startblock, PREV.br_blockcount,
2653 &i)))
2654 goto done;
19ebedcf 2655 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
2656 if ((error = xfs_bmbt_update(cur, PREV.br_startoff,
2657 PREV.br_startblock,
2658 PREV.br_blockcount - new->br_blockcount,
2659 oldext)))
2660 goto done;
2661 if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff,
2662 new->br_startblock, new->br_blockcount,
2663 &i)))
2664 goto done;
19ebedcf 2665 XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done);
49f693fa
DC
2666 cur->bc_rec.b.br_state = XFS_EXT_NORM;
2667 if ((error = xfs_btree_insert(cur, &i)))
2668 goto done;
19ebedcf 2669 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
2670 }
2671 break;
2672
2673 case 0:
2bd0ea18 2674 /*
49f693fa
DC
2675 * Setting the middle part of a previous oldext extent to
2676 * newext. Contiguity is impossible here.
2677 * One extent becomes three extents.
2bd0ea18 2678 */
49f693fa
DC
2679 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
2680 xfs_bmbt_set_blockcount(ep,
2681 new->br_startoff - PREV.br_startoff);
2682 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
2683
2684 r[0] = *new;
2685 r[1].br_startoff = new_endoff;
2686 r[1].br_blockcount =
2687 PREV.br_startoff + PREV.br_blockcount - new_endoff;
2688 r[1].br_startblock = new->br_startblock + new->br_blockcount;
2689 r[1].br_state = oldext;
2690
2691 ++*idx;
2692 xfs_iext_insert(ip, *idx, 2, &r[0], state);
2693
2694 ip->i_d.di_nextents += 2;
2695 if (cur == NULL)
2696 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
2697 else {
2698 rval = XFS_ILOG_CORE;
2699 if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff,
2700 PREV.br_startblock, PREV.br_blockcount,
2701 &i)))
2702 goto done;
19ebedcf 2703 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
2704 /* new right extent - oldext */
2705 if ((error = xfs_bmbt_update(cur, r[1].br_startoff,
2706 r[1].br_startblock, r[1].br_blockcount,
2707 r[1].br_state)))
2708 goto done;
2709 /* new left extent - oldext */
2710 cur->bc_rec.b = PREV;
2711 cur->bc_rec.b.br_blockcount =
2712 new->br_startoff - PREV.br_startoff;
2713 if ((error = xfs_btree_insert(cur, &i)))
2714 goto done;
19ebedcf 2715 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
2716 /*
2717 * Reset the cursor to the position of the new extent
2718 * we are about to insert as we can't trust it after
2719 * the previous insert.
2720 */
2721 if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff,
2722 new->br_startblock, new->br_blockcount,
2723 &i)))
2724 goto done;
19ebedcf 2725 XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done);
49f693fa
DC
2726 /* new middle extent - newext */
2727 cur->bc_rec.b.br_state = new->br_state;
2728 if ((error = xfs_btree_insert(cur, &i)))
2729 goto done;
19ebedcf 2730 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2bd0ea18 2731 }
49f693fa
DC
2732 break;
2733
2734 case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG:
2735 case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG:
2736 case BMAP_LEFT_FILLING | BMAP_RIGHT_CONTIG:
2737 case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG:
2738 case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG:
2739 case BMAP_LEFT_CONTIG:
2740 case BMAP_RIGHT_CONTIG:
5000d01d 2741 /*
49f693fa 2742 * These cases are all impossible.
2bd0ea18 2743 */
49f693fa
DC
2744 ASSERT(0);
2745 }
2746
2747 /* convert to a btree if necessary */
2748 if (xfs_bmap_needs_btree(ip, XFS_DATA_FORK)) {
2749 int tmp_logflags; /* partial log flag return val */
2750
2751 ASSERT(cur == NULL);
2752 error = xfs_bmap_extents_to_btree(tp, ip, first, flist, &cur,
2753 0, &tmp_logflags, XFS_DATA_FORK);
2754 *logflagsp |= tmp_logflags;
2755 if (error)
2756 goto done;
ca86e759 2757 }
49f693fa
DC
2758
2759 /* clear out the allocated field, done with it now in any case. */
2760 if (cur) {
2761 cur->bc_private.b.allocated = 0;
2762 *curp = cur;
2763 }
2764
2765 xfs_bmap_check_leaf_extents(*curp, ip, XFS_DATA_FORK);
2bd0ea18 2766done:
49f693fa 2767 *logflagsp |= rval;
2bd0ea18 2768 return error;
49f693fa
DC
2769#undef LEFT
2770#undef RIGHT
2771#undef PREV
2bd0ea18
NS
2772}
2773
5e656dbb 2774/*
49f693fa 2775 * Convert a hole to a delayed allocation.
5e656dbb 2776 */
49f693fa
DC
2777STATIC void
2778xfs_bmap_add_extent_hole_delay(
2779 xfs_inode_t *ip, /* incore inode pointer */
2780 xfs_extnum_t *idx, /* extent number to update/insert */
2781 xfs_bmbt_irec_t *new) /* new data to add to file extents */
2bd0ea18 2782{
49f693fa
DC
2783 xfs_ifork_t *ifp; /* inode fork pointer */
2784 xfs_bmbt_irec_t left; /* left neighbor extent entry */
2785 xfs_filblks_t newlen=0; /* new indirect size */
2786 xfs_filblks_t oldlen=0; /* old indirect size */
2787 xfs_bmbt_irec_t right; /* right neighbor extent entry */
2788 int state; /* state bits, accessed thru macros */
2789 xfs_filblks_t temp=0; /* temp for indirect calculations */
2790
2791 ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
2792 state = 0;
2793 ASSERT(isnullstartblock(new->br_startblock));
2bd0ea18 2794
062998e3 2795 /*
49f693fa 2796 * Check and set flags if this segment has a left neighbor
062998e3 2797 */
49f693fa
DC
2798 if (*idx > 0) {
2799 state |= BMAP_LEFT_VALID;
2800 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx - 1), &left);
5e656dbb 2801
49f693fa
DC
2802 if (isnullstartblock(left.br_startblock))
2803 state |= BMAP_LEFT_DELAY;
5e656dbb 2804 }
49f693fa
DC
2805
2806 /*
2807 * Check and set flags if the current (right) segment exists.
2808 * If it doesn't exist, we're converting the hole at end-of-file.
2809 */
2810 if (*idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) {
2811 state |= BMAP_RIGHT_VALID;
2812 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx), &right);
2813
2814 if (isnullstartblock(right.br_startblock))
2815 state |= BMAP_RIGHT_DELAY;
2816 }
2817
2818 /*
2819 * Set contiguity flags on the left and right neighbors.
2820 * Don't let extents get too large, even if the pieces are contiguous.
2821 */
2822 if ((state & BMAP_LEFT_VALID) && (state & BMAP_LEFT_DELAY) &&
2823 left.br_startoff + left.br_blockcount == new->br_startoff &&
2824 left.br_blockcount + new->br_blockcount <= MAXEXTLEN)
2825 state |= BMAP_LEFT_CONTIG;
2826
2827 if ((state & BMAP_RIGHT_VALID) && (state & BMAP_RIGHT_DELAY) &&
2828 new->br_startoff + new->br_blockcount == right.br_startoff &&
2829 new->br_blockcount + right.br_blockcount <= MAXEXTLEN &&
2830 (!(state & BMAP_LEFT_CONTIG) ||
2831 (left.br_blockcount + new->br_blockcount +
2832 right.br_blockcount <= MAXEXTLEN)))
2833 state |= BMAP_RIGHT_CONTIG;
2834
2835 /*
2836 * Switch out based on the contiguity flags.
2837 */
2838 switch (state & (BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG)) {
2839 case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG:
2840 /*
2841 * New allocation is contiguous with delayed allocations
2842 * on the left and on the right.
2843 * Merge all three into a single extent record.
2844 */
2845 --*idx;
2846 temp = left.br_blockcount + new->br_blockcount +
2847 right.br_blockcount;
2848
2849 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
2850 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), temp);
2851 oldlen = startblockval(left.br_startblock) +
2852 startblockval(new->br_startblock) +
2853 startblockval(right.br_startblock);
2854 newlen = xfs_bmap_worst_indlen(ip, temp);
2855 xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, *idx),
2856 nullstartblock((int)newlen));
2857 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
2858
2859 xfs_iext_remove(ip, *idx + 1, 1, state);
2860 break;
2861
2862 case BMAP_LEFT_CONTIG:
2863 /*
2864 * New allocation is contiguous with a delayed allocation
2865 * on the left.
2866 * Merge the new allocation with the left neighbor.
2867 */
2868 --*idx;
2869 temp = left.br_blockcount + new->br_blockcount;
2870
2871 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
2872 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, *idx), temp);
2873 oldlen = startblockval(left.br_startblock) +
2874 startblockval(new->br_startblock);
2875 newlen = xfs_bmap_worst_indlen(ip, temp);
2876 xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, *idx),
2877 nullstartblock((int)newlen));
2878 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
2879 break;
2880
2881 case BMAP_RIGHT_CONTIG:
2882 /*
2883 * New allocation is contiguous with a delayed allocation
2884 * on the right.
2885 * Merge the new allocation with the right neighbor.
2886 */
2887 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
2888 temp = new->br_blockcount + right.br_blockcount;
2889 oldlen = startblockval(new->br_startblock) +
2890 startblockval(right.br_startblock);
2891 newlen = xfs_bmap_worst_indlen(ip, temp);
2892 xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, *idx),
2893 new->br_startoff,
2894 nullstartblock((int)newlen), temp, right.br_state);
2895 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
2896 break;
2897
2898 case 0:
2899 /*
2900 * New allocation is not contiguous with another
2901 * delayed allocation.
2902 * Insert a new entry.
2903 */
2904 oldlen = newlen = 0;
2905 xfs_iext_insert(ip, *idx, 1, new, state);
2906 break;
2907 }
2908 if (oldlen != newlen) {
2909 ASSERT(oldlen > newlen);
19ebedcf
DC
2910 xfs_mod_fdblocks(ip->i_mount, (int64_t)(oldlen - newlen),
2911 false);
49f693fa
DC
2912 /*
2913 * Nothing to do for disk quota accounting here.
2914 */
2bd0ea18 2915 }
2bd0ea18
NS
2916}
2917
2918/*
49f693fa 2919 * Convert a hole to a real allocation.
2bd0ea18 2920 */
49f693fa
DC
2921STATIC int /* error */
2922xfs_bmap_add_extent_hole_real(
2923 struct xfs_bmalloca *bma,
2924 int whichfork)
5000d01d 2925{
49f693fa
DC
2926 struct xfs_bmbt_irec *new = &bma->got;
2927 int error; /* error return value */
2928 int i; /* temp state */
2929 xfs_ifork_t *ifp; /* inode fork pointer */
2930 xfs_bmbt_irec_t left; /* left neighbor extent entry */
2931 xfs_bmbt_irec_t right; /* right neighbor extent entry */
2932 int rval=0; /* return value (logging flags) */
2933 int state; /* state bits, accessed thru macros */
19ebedcf 2934 struct xfs_mount *mp;
2bd0ea18 2935
65ca3804 2936 mp = bma->ip->i_mount;
49f693fa 2937 ifp = XFS_IFORK_PTR(bma->ip, whichfork);
2bd0ea18 2938
49f693fa
DC
2939 ASSERT(bma->idx >= 0);
2940 ASSERT(bma->idx <= ifp->if_bytes / sizeof(struct xfs_bmbt_rec));
2941 ASSERT(!isnullstartblock(new->br_startblock));
2942 ASSERT(!bma->cur ||
2943 !(bma->cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL));
5e656dbb 2944
79896434 2945 XFS_STATS_INC(mp, xs_add_exlist);
49f693fa
DC
2946
2947 state = 0;
2948 if (whichfork == XFS_ATTR_FORK)
2949 state |= BMAP_ATTRFORK;
2950
2951 /*
2952 * Check and set flags if this segment has a left neighbor.
2953 */
2954 if (bma->idx > 0) {
2955 state |= BMAP_LEFT_VALID;
2956 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx - 1), &left);
2957 if (isnullstartblock(left.br_startblock))
2958 state |= BMAP_LEFT_DELAY;
5e656dbb 2959 }
2bd0ea18 2960
49f693fa
DC
2961 /*
2962 * Check and set flags if this segment has a current value.
2963 * Not true if we're inserting into the "hole" at eof.
2964 */
2965 if (bma->idx < ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) {
2966 state |= BMAP_RIGHT_VALID;
2967 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx), &right);
2968 if (isnullstartblock(right.br_startblock))
2969 state |= BMAP_RIGHT_DELAY;
2bd0ea18 2970 }
2bd0ea18 2971
49f693fa
DC
2972 /*
2973 * We're inserting a real allocation between "left" and "right".
2974 * Set the contiguity flags. Don't let extents get too large.
2975 */
2976 if ((state & BMAP_LEFT_VALID) && !(state & BMAP_LEFT_DELAY) &&
2977 left.br_startoff + left.br_blockcount == new->br_startoff &&
2978 left.br_startblock + left.br_blockcount == new->br_startblock &&
2979 left.br_state == new->br_state &&
2980 left.br_blockcount + new->br_blockcount <= MAXEXTLEN)
2981 state |= BMAP_LEFT_CONTIG;
57c9fccb 2982
49f693fa
DC
2983 if ((state & BMAP_RIGHT_VALID) && !(state & BMAP_RIGHT_DELAY) &&
2984 new->br_startoff + new->br_blockcount == right.br_startoff &&
2985 new->br_startblock + new->br_blockcount == right.br_startblock &&
2986 new->br_state == right.br_state &&
2987 new->br_blockcount + right.br_blockcount <= MAXEXTLEN &&
2988 (!(state & BMAP_LEFT_CONTIG) ||
2989 left.br_blockcount + new->br_blockcount +
2990 right.br_blockcount <= MAXEXTLEN))
2991 state |= BMAP_RIGHT_CONTIG;
ca86e759 2992
49f693fa
DC
2993 error = 0;
2994 /*
2995 * Select which case we're in here, and implement it.
2996 */
2997 switch (state & (BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG)) {
2998 case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG:
57c9fccb 2999 /*
49f693fa
DC
3000 * New allocation is contiguous with real allocations on the
3001 * left and on the right.
3002 * Merge all three into a single extent record.
57c9fccb 3003 */
49f693fa
DC
3004 --bma->idx;
3005 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
3006 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, bma->idx),
3007 left.br_blockcount + new->br_blockcount +
3008 right.br_blockcount);
3009 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
56b2de80 3010
49f693fa 3011 xfs_iext_remove(bma->ip, bma->idx + 1, 1, state);
56b2de80 3012
49f693fa
DC
3013 XFS_IFORK_NEXT_SET(bma->ip, whichfork,
3014 XFS_IFORK_NEXTENTS(bma->ip, whichfork) - 1);
3015 if (bma->cur == NULL) {
3016 rval = XFS_ILOG_CORE | xfs_ilog_fext(whichfork);
3017 } else {
3018 rval = XFS_ILOG_CORE;
3019 error = xfs_bmbt_lookup_eq(bma->cur, right.br_startoff,
3020 right.br_startblock, right.br_blockcount,
3021 &i);
3022 if (error)
3023 goto done;
19ebedcf 3024 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
3025 error = xfs_btree_delete(bma->cur, &i);
3026 if (error)
3027 goto done;
19ebedcf 3028 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
3029 error = xfs_btree_decrement(bma->cur, 0, &i);
3030 if (error)
3031 goto done;
19ebedcf 3032 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
3033 error = xfs_bmbt_update(bma->cur, left.br_startoff,
3034 left.br_startblock,
3035 left.br_blockcount +
3036 new->br_blockcount +
3037 right.br_blockcount,
3038 left.br_state);
3039 if (error)
3040 goto done;
3041 }
57c9fccb 3042 break;
49f693fa
DC
3043
3044 case BMAP_LEFT_CONTIG:
3045 /*
3046 * New allocation is contiguous with a real allocation
3047 * on the left.
3048 * Merge the new allocation with the left neighbor.
3049 */
3050 --bma->idx;
3051 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
3052 xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, bma->idx),
3053 left.br_blockcount + new->br_blockcount);
3054 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
3055
3056 if (bma->cur == NULL) {
3057 rval = xfs_ilog_fext(whichfork);
3058 } else {
3059 rval = 0;
3060 error = xfs_bmbt_lookup_eq(bma->cur, left.br_startoff,
3061 left.br_startblock, left.br_blockcount,
3062 &i);
3063 if (error)
3064 goto done;
19ebedcf 3065 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
3066 error = xfs_bmbt_update(bma->cur, left.br_startoff,
3067 left.br_startblock,
3068 left.br_blockcount +
3069 new->br_blockcount,
3070 left.br_state);
3071 if (error)
3072 goto done;
3073 }
57c9fccb 3074 break;
49f693fa
DC
3075
3076 case BMAP_RIGHT_CONTIG:
3077 /*
3078 * New allocation is contiguous with a real allocation
3079 * on the right.
3080 * Merge the new allocation with the right neighbor.
3081 */
3082 trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
3083 xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, bma->idx),
3084 new->br_startoff, new->br_startblock,
3085 new->br_blockcount + right.br_blockcount,
3086 right.br_state);
3087 trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
3088
3089 if (bma->cur == NULL) {
3090 rval = xfs_ilog_fext(whichfork);
3091 } else {
3092 rval = 0;
3093 error = xfs_bmbt_lookup_eq(bma->cur,
3094 right.br_startoff,
3095 right.br_startblock,
3096 right.br_blockcount, &i);
3097 if (error)
3098 goto done;
19ebedcf 3099 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
3100 error = xfs_bmbt_update(bma->cur, new->br_startoff,
3101 new->br_startblock,
3102 new->br_blockcount +
3103 right.br_blockcount,
3104 right.br_state);
3105 if (error)
3106 goto done;
3107 }
3108 break;
3109
3110 case 0:
3111 /*
3112 * New allocation is not contiguous with another
3113 * real allocation.
3114 * Insert a new entry.
3115 */
3116 xfs_iext_insert(bma->ip, bma->idx, 1, new, state);
3117 XFS_IFORK_NEXT_SET(bma->ip, whichfork,
3118 XFS_IFORK_NEXTENTS(bma->ip, whichfork) + 1);
3119 if (bma->cur == NULL) {
3120 rval = XFS_ILOG_CORE | xfs_ilog_fext(whichfork);
3121 } else {
3122 rval = XFS_ILOG_CORE;
3123 error = xfs_bmbt_lookup_eq(bma->cur,
3124 new->br_startoff,
3125 new->br_startblock,
3126 new->br_blockcount, &i);
3127 if (error)
3128 goto done;
19ebedcf 3129 XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done);
49f693fa
DC
3130 bma->cur->bc_rec.b.br_state = new->br_state;
3131 error = xfs_btree_insert(bma->cur, &i);
3132 if (error)
3133 goto done;
19ebedcf 3134 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa 3135 }
57c9fccb 3136 break;
57c9fccb 3137 }
a2ceac1f 3138
49f693fa
DC
3139 /* convert to a btree if necessary */
3140 if (xfs_bmap_needs_btree(bma->ip, whichfork)) {
3141 int tmp_logflags; /* partial log flag return val */
3f853c7a 3142
49f693fa
DC
3143 ASSERT(bma->cur == NULL);
3144 error = xfs_bmap_extents_to_btree(bma->tp, bma->ip,
3145 bma->firstblock, bma->flist, &bma->cur,
3146 0, &tmp_logflags, whichfork);
3147 bma->logflags |= tmp_logflags;
3148 if (error)
3149 goto done;
57c9fccb 3150 }
a2ceac1f 3151
49f693fa
DC
3152 /* clear out the allocated field, done with it now in any case. */
3153 if (bma->cur)
3154 bma->cur->bc_private.b.allocated = 0;
3155
3156 xfs_bmap_check_leaf_extents(bma->cur, bma->ip, whichfork);
3157done:
3158 bma->logflags |= rval;
57c9fccb
NS
3159 return error;
3160}
3161
2bd0ea18 3162/*
49f693fa 3163 * Functions used in the extent read, allocate and remove paths
2bd0ea18 3164 */
2bd0ea18 3165
5000d01d 3166/*
49f693fa 3167 * Adjust the size of the new extent based on di_extsize and rt extsize.
2bd0ea18 3168 */
613e6057 3169int
49f693fa
DC
3170xfs_bmap_extsize_align(
3171 xfs_mount_t *mp,
3172 xfs_bmbt_irec_t *gotp, /* next extent pointer */
3173 xfs_bmbt_irec_t *prevp, /* previous extent pointer */
3174 xfs_extlen_t extsz, /* align to this extent size */
3175 int rt, /* is this a realtime inode? */
3176 int eof, /* is extent at end-of-file? */
3177 int delay, /* creating delalloc extent? */
3178 int convert, /* overwriting unwritten extent? */
3179 xfs_fileoff_t *offp, /* in/out: aligned offset */
3180 xfs_extlen_t *lenp) /* in/out: aligned length */
2bd0ea18 3181{
49f693fa
DC
3182 xfs_fileoff_t orig_off; /* original offset */
3183 xfs_extlen_t orig_alen; /* original length */
3184 xfs_fileoff_t orig_end; /* original off+len */
3185 xfs_fileoff_t nexto; /* next file offset */
3186 xfs_fileoff_t prevo; /* previous file offset */
3187 xfs_fileoff_t align_off; /* temp for offset */
3188 xfs_extlen_t align_alen; /* temp for length */
3189 xfs_extlen_t temp; /* temp for calculations */
3190
3191 if (convert)
3192 return 0;
3193
3194 orig_off = align_off = *offp;
3195 orig_alen = align_alen = *lenp;
3196 orig_end = orig_off + orig_alen;
2bd0ea18
NS
3197
3198 /*
49f693fa
DC
3199 * If this request overlaps an existing extent, then don't
3200 * attempt to perform any additional alignment.
2bd0ea18 3201 */
49f693fa
DC
3202 if (!delay && !eof &&
3203 (orig_off >= gotp->br_startoff) &&
3204 (orig_end <= gotp->br_startoff + gotp->br_blockcount)) {
3205 return 0;
2bd0ea18 3206 }
57c9fccb 3207
49f693fa
DC
3208 /*
3209 * If the file offset is unaligned vs. the extent size
3210 * we need to align it. This will be possible unless
3211 * the file was previously written with a kernel that didn't
3212 * perform this alignment, or if a truncate shot us in the
3213 * foot.
3214 */
3215 temp = do_mod(orig_off, extsz);
3216 if (temp) {
3217 align_alen += temp;
3218 align_off -= temp;
3219 }
7cc23f0c
DC
3220
3221 /* Same adjustment for the end of the requested area. */
3222 temp = (align_alen % extsz);
3223 if (temp)
3224 align_alen += extsz - temp;
3225
49f693fa 3226 /*
7cc23f0c
DC
3227 * For large extent hint sizes, the aligned extent might be larger than
3228 * MAXEXTLEN. In that case, reduce the size by an extsz so that it pulls
3229 * the length back under MAXEXTLEN. The outer allocation loops handle
3230 * short allocation just fine, so it is safe to do this. We only want to
3231 * do it when we are forced to, though, because it means more allocation
3232 * operations are required.
49f693fa 3233 */
7cc23f0c
DC
3234 while (align_alen > MAXEXTLEN)
3235 align_alen -= extsz;
3236 ASSERT(align_alen <= MAXEXTLEN);
3237
49f693fa
DC
3238 /*
3239 * If the previous block overlaps with this proposed allocation
3240 * then move the start forward without adjusting the length.
3241 */
3242 if (prevp->br_startoff != NULLFILEOFF) {
3243 if (prevp->br_startblock == HOLESTARTBLOCK)
3244 prevo = prevp->br_startoff;
3245 else
3246 prevo = prevp->br_startoff + prevp->br_blockcount;
3247 } else
3248 prevo = 0;
3249 if (align_off != orig_off && align_off < prevo)
3250 align_off = prevo;
3251 /*
3252 * If the next block overlaps with this proposed allocation
3253 * then move the start back without adjusting the length,
3254 * but not before offset 0.
3255 * This may of course make the start overlap previous block,
3256 * and if we hit the offset 0 limit then the next block
3257 * can still overlap too.
3258 */
3259 if (!eof && gotp->br_startoff != NULLFILEOFF) {
3260 if ((delay && gotp->br_startblock == HOLESTARTBLOCK) ||
3261 (!delay && gotp->br_startblock == DELAYSTARTBLOCK))
3262 nexto = gotp->br_startoff + gotp->br_blockcount;
3263 else
3264 nexto = gotp->br_startoff;
3265 } else
3266 nexto = NULLFILEOFF;
3267 if (!eof &&
3268 align_off + align_alen != orig_end &&
3269 align_off + align_alen > nexto)
3270 align_off = nexto > align_alen ? nexto - align_alen : 0;
3271 /*
3272 * If we're now overlapping the next or previous extent that
3273 * means we can't fit an extsz piece in this hole. Just move
3274 * the start forward to the first valid spot and set
3275 * the length so we hit the end.
3276 */
3277 if (align_off != orig_off && align_off < prevo)
3278 align_off = prevo;
3279 if (align_off + align_alen != orig_end &&
3280 align_off + align_alen > nexto &&
3281 nexto != NULLFILEOFF) {
3282 ASSERT(nexto > prevo);
3283 align_alen = nexto - align_off;
57c9fccb 3284 }
2bd0ea18 3285
49f693fa
DC
3286 /*
3287 * If realtime, and the result isn't a multiple of the realtime
3288 * extent size we need to remove blocks until it is.
3289 */
3290 if (rt && (temp = (align_alen % mp->m_sb.sb_rextsize))) {
2bd0ea18 3291 /*
49f693fa
DC
3292 * We're not covering the original request, or
3293 * we won't be able to once we fix the length.
2bd0ea18 3294 */
49f693fa
DC
3295 if (orig_off < align_off ||
3296 orig_end > align_off + align_alen ||
3297 align_alen - temp < orig_alen)
12b53197 3298 return -EINVAL;
49f693fa
DC
3299 /*
3300 * Try to fix it by moving the start up.
3301 */
3302 if (align_off + temp <= orig_off) {
3303 align_alen -= temp;
3304 align_off += temp;
2bd0ea18 3305 }
49f693fa
DC
3306 /*
3307 * Try to fix it by moving the end in.
3308 */
3309 else if (align_off + align_alen - temp >= orig_end)
3310 align_alen -= temp;
3311 /*
3312 * Set the start to the minimum then trim the length.
3313 */
3314 else {
3315 align_alen -= orig_off - align_off;
3316 align_off = orig_off;
3317 align_alen -= align_alen % mp->m_sb.sb_rextsize;
3318 }
3319 /*
3320 * Result doesn't cover the request, fail it.
3321 */
3322 if (orig_off < align_off || orig_end > align_off + align_alen)
12b53197 3323 return -EINVAL;
49f693fa
DC
3324 } else {
3325 ASSERT(orig_off >= align_off);
7cc23f0c
DC
3326 /* see MAXEXTLEN handling above */
3327 ASSERT(orig_end <= align_off + align_alen ||
3328 align_alen + extsz > MAXEXTLEN);
2bd0ea18 3329 }
49f693fa
DC
3330
3331#ifdef DEBUG
3332 if (!eof && gotp->br_startoff != NULLFILEOFF)
3333 ASSERT(align_off + align_alen <= gotp->br_startoff);
3334 if (prevp->br_startoff != NULLFILEOFF)
3335 ASSERT(align_off >= prevp->br_startoff + prevp->br_blockcount);
3336#endif
3337
3338 *lenp = align_alen;
3339 *offp = align_off;
2bd0ea18
NS
3340 return 0;
3341}
3342
49f693fa
DC
3343#define XFS_ALLOC_GAP_UNITS 4
3344
613e6057 3345void
49f693fa 3346xfs_bmap_adjacent(
613e6057 3347 struct xfs_bmalloca *ap) /* bmap alloc argument struct */
2bd0ea18 3348{
49f693fa
DC
3349 xfs_fsblock_t adjust; /* adjustment to block numbers */
3350 xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */
3351 xfs_mount_t *mp; /* mount point structure */
3352 int nullfb; /* true if ap->firstblock isn't set */
3353 int rt; /* true if inode is realtime */
2bd0ea18 3354
49f693fa
DC
3355#define ISVALID(x,y) \
3356 (rt ? \
3357 (x) < mp->m_sb.sb_rblocks : \
3358 XFS_FSB_TO_AGNO(mp, x) == XFS_FSB_TO_AGNO(mp, y) && \
3359 XFS_FSB_TO_AGNO(mp, x) < mp->m_sb.sb_agcount && \
3360 XFS_FSB_TO_AGBNO(mp, x) < mp->m_sb.sb_agblocks)
3361
3362 mp = ap->ip->i_mount;
3363 nullfb = *ap->firstblock == NULLFSBLOCK;
3364 rt = XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata;
3365 fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, *ap->firstblock);
3366 /*
3367 * If allocating at eof, and there's a previous real block,
3368 * try to use its last block as our starting point.
3369 */
3370 if (ap->eof && ap->prev.br_startoff != NULLFILEOFF &&
3371 !isnullstartblock(ap->prev.br_startblock) &&
3372 ISVALID(ap->prev.br_startblock + ap->prev.br_blockcount,
3373 ap->prev.br_startblock)) {
3374 ap->blkno = ap->prev.br_startblock + ap->prev.br_blockcount;
3375 /*
3376 * Adjust for the gap between prevp and us.
3377 */
3378 adjust = ap->offset -
3379 (ap->prev.br_startoff + ap->prev.br_blockcount);
3380 if (adjust &&
3381 ISVALID(ap->blkno + adjust, ap->prev.br_startblock))
3382 ap->blkno += adjust;
2bd0ea18 3383 }
49f693fa
DC
3384 /*
3385 * If not at eof, then compare the two neighbor blocks.
3386 * Figure out whether either one gives us a good starting point,
3387 * and pick the better one.
3388 */
3389 else if (!ap->eof) {
3390 xfs_fsblock_t gotbno; /* right side block number */
3391 xfs_fsblock_t gotdiff=0; /* right side difference */
3392 xfs_fsblock_t prevbno; /* left side block number */
3393 xfs_fsblock_t prevdiff=0; /* left side difference */
3394
3395 /*
3396 * If there's a previous (left) block, select a requested
3397 * start block based on it.
3398 */
3399 if (ap->prev.br_startoff != NULLFILEOFF &&
3400 !isnullstartblock(ap->prev.br_startblock) &&
3401 (prevbno = ap->prev.br_startblock +
3402 ap->prev.br_blockcount) &&
3403 ISVALID(prevbno, ap->prev.br_startblock)) {
3404 /*
3405 * Calculate gap to end of previous block.
3406 */
3407 adjust = prevdiff = ap->offset -
3408 (ap->prev.br_startoff +
3409 ap->prev.br_blockcount);
3410 /*
3411 * Figure the startblock based on the previous block's
3412 * end and the gap size.
3413 * Heuristic!
3414 * If the gap is large relative to the piece we're
3415 * allocating, or using it gives us an invalid block
3416 * number, then just use the end of the previous block.
3417 */
3418 if (prevdiff <= XFS_ALLOC_GAP_UNITS * ap->length &&
3419 ISVALID(prevbno + prevdiff,
3420 ap->prev.br_startblock))
3421 prevbno += adjust;
3422 else
3423 prevdiff += adjust;
3424 /*
3425 * If the firstblock forbids it, can't use it,
3426 * must use default.
3427 */
3428 if (!rt && !nullfb &&
3429 XFS_FSB_TO_AGNO(mp, prevbno) != fb_agno)
3430 prevbno = NULLFSBLOCK;
3431 }
3432 /*
3433 * No previous block or can't follow it, just default.
3434 */
3435 else
3436 prevbno = NULLFSBLOCK;
3437 /*
3438 * If there's a following (right) block, select a requested
3439 * start block based on it.
3440 */
3441 if (!isnullstartblock(ap->got.br_startblock)) {
3442 /*
3443 * Calculate gap to start of next block.
3444 */
3445 adjust = gotdiff = ap->got.br_startoff - ap->offset;
3446 /*
3447 * Figure the startblock based on the next block's
3448 * start and the gap size.
3449 */
3450 gotbno = ap->got.br_startblock;
3451 /*
3452 * Heuristic!
3453 * If the gap is large relative to the piece we're
3454 * allocating, or using it gives us an invalid block
3455 * number, then just use the start of the next block
3456 * offset by our length.
3457 */
3458 if (gotdiff <= XFS_ALLOC_GAP_UNITS * ap->length &&
3459 ISVALID(gotbno - gotdiff, gotbno))
3460 gotbno -= adjust;
3461 else if (ISVALID(gotbno - ap->length, gotbno)) {
3462 gotbno -= ap->length;
3463 gotdiff += adjust - ap->length;
3464 } else
3465 gotdiff += adjust;
3466 /*
3467 * If the firstblock forbids it, can't use it,
3468 * must use default.
3469 */
3470 if (!rt && !nullfb &&
3471 XFS_FSB_TO_AGNO(mp, gotbno) != fb_agno)
3472 gotbno = NULLFSBLOCK;
3473 }
3474 /*
3475 * No next block, just default.
3476 */
2bd0ea18 3477 else
49f693fa
DC
3478 gotbno = NULLFSBLOCK;
3479 /*
3480 * If both valid, pick the better one, else the only good
3481 * one, else ap->blkno is already set (to 0 or the inode block).
3482 */
3483 if (prevbno != NULLFSBLOCK && gotbno != NULLFSBLOCK)
3484 ap->blkno = prevdiff <= gotdiff ? prevbno : gotbno;
3485 else if (prevbno != NULLFSBLOCK)
3486 ap->blkno = prevbno;
3487 else if (gotbno != NULLFSBLOCK)
3488 ap->blkno = gotbno;
a2ceac1f 3489 }
49f693fa 3490#undef ISVALID
a2ceac1f
DC
3491}
3492
ff105f75
DC
3493static int
3494xfs_bmap_longest_free_extent(
3495 struct xfs_trans *tp,
3496 xfs_agnumber_t ag,
3497 xfs_extlen_t *blen,
3498 int *notinit)
3499{
3500 struct xfs_mount *mp = tp->t_mountp;
3501 struct xfs_perag *pag;
3502 xfs_extlen_t longest;
3503 int error = 0;
3504
3505 pag = xfs_perag_get(mp, ag);
3506 if (!pag->pagf_init) {
3507 error = xfs_alloc_pagf_init(mp, tp, ag, XFS_ALLOC_FLAG_TRYLOCK);
3508 if (error)
3509 goto out;
3510
3511 if (!pag->pagf_init) {
3512 *notinit = 1;
3513 goto out;
3514 }
3515 }
3516
72bda06d 3517 longest = xfs_alloc_longest_free_extent(mp, pag,
de046644 3518 xfs_alloc_min_freelist(mp, pag));
ff105f75
DC
3519 if (*blen < longest)
3520 *blen = longest;
3521
3522out:
3523 xfs_perag_put(pag);
3524 return error;
3525}
3526
3527static void
3528xfs_bmap_select_minlen(
3529 struct xfs_bmalloca *ap,
3530 struct xfs_alloc_arg *args,
3531 xfs_extlen_t *blen,
3532 int notinit)
3533{
3534 if (notinit || *blen < ap->minlen) {
3535 /*
3536 * Since we did a BUF_TRYLOCK above, it is possible that
3537 * there is space for this request.
3538 */
3539 args->minlen = ap->minlen;
3540 } else if (*blen < args->maxlen) {
3541 /*
3542 * If the best seen length is less than the request length,
3543 * use the best as the minimum.
3544 */
3545 args->minlen = *blen;
3546 } else {
3547 /*
3548 * Otherwise we've seen an extent as big as maxlen, use that
3549 * as the minimum.
3550 */
3551 args->minlen = args->maxlen;
3552 }
3553}
3554
a2ceac1f 3555STATIC int
49f693fa
DC
3556xfs_bmap_btalloc_nullfb(
3557 struct xfs_bmalloca *ap,
3558 struct xfs_alloc_arg *args,
3559 xfs_extlen_t *blen)
a2ceac1f 3560{
49f693fa 3561 struct xfs_mount *mp = ap->ip->i_mount;
49f693fa
DC
3562 xfs_agnumber_t ag, startag;
3563 int notinit = 0;
a2ceac1f
DC
3564 int error;
3565
ff105f75 3566 args->type = XFS_ALLOCTYPE_START_BNO;
49f693fa 3567 args->total = ap->total;
a2ceac1f 3568
49f693fa
DC
3569 startag = ag = XFS_FSB_TO_AGNO(mp, args->fsbno);
3570 if (startag == NULLAGNUMBER)
3571 startag = ag = 0;
a2ceac1f 3572
49f693fa 3573 while (*blen < args->maxlen) {
ff105f75
DC
3574 error = xfs_bmap_longest_free_extent(args->tp, ag, blen,
3575 &notinit);
3576 if (error)
3577 return error;
a2ceac1f 3578
49f693fa
DC
3579 if (++ag == mp->m_sb.sb_agcount)
3580 ag = 0;
3581 if (ag == startag)
3582 break;
49f693fa 3583 }
2bd0ea18 3584
ff105f75
DC
3585 xfs_bmap_select_minlen(ap, args, blen, notinit);
3586 return 0;
3587}
3588
3589STATIC int
3590xfs_bmap_btalloc_filestreams(
3591 struct xfs_bmalloca *ap,
3592 struct xfs_alloc_arg *args,
3593 xfs_extlen_t *blen)
3594{
3595 struct xfs_mount *mp = ap->ip->i_mount;
3596 xfs_agnumber_t ag;
3597 int notinit = 0;
3598 int error;
3599
3600 args->type = XFS_ALLOCTYPE_NEAR_BNO;
3601 args->total = ap->total;
3602
3603 ag = XFS_FSB_TO_AGNO(mp, args->fsbno);
3604 if (ag == NULLAGNUMBER)
3605 ag = 0;
3606
3607 error = xfs_bmap_longest_free_extent(args->tp, ag, blen, &notinit);
3608 if (error)
3609 return error;
3610
3611 if (*blen < args->maxlen) {
3612 error = xfs_filestream_new_ag(ap, &ag);
3613 if (error)
3614 return error;
3615
3616 error = xfs_bmap_longest_free_extent(args->tp, ag, blen,
3617 &notinit);
3618 if (error)
3619 return error;
3620
3621 }
3622
3623 xfs_bmap_select_minlen(ap, args, blen, notinit);
2bd0ea18 3624
49f693fa 3625 /*
ff105f75
DC
3626 * Set the failure fallback case to look in the selected AG as stream
3627 * may have moved.
49f693fa 3628 */
ff105f75 3629 ap->blkno = args->fsbno = XFS_AGB_TO_FSB(mp, ag, 0);
49f693fa 3630 return 0;
2bd0ea18
NS
3631}
3632
b3563c19 3633STATIC int
49f693fa 3634xfs_bmap_btalloc(
613e6057 3635 struct xfs_bmalloca *ap) /* bmap alloc argument struct */
b3563c19 3636{
49f693fa
DC
3637 xfs_mount_t *mp; /* mount point structure */
3638 xfs_alloctype_t atype = 0; /* type for allocation routines */
3639 xfs_extlen_t align; /* minimum allocation alignment */
3640 xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */
3641 xfs_agnumber_t ag;
3642 xfs_alloc_arg_t args;
3643 xfs_extlen_t blen;
3644 xfs_extlen_t nextminlen = 0;
3645 int nullfb; /* true if ap->firstblock isn't set */
3646 int isaligned;
3647 int tryagain;
3648 int error;
ff105f75 3649 int stripe_align;
b3563c19 3650
49f693fa 3651 ASSERT(ap->length);
b3563c19 3652
49f693fa 3653 mp = ap->ip->i_mount;
ff105f75
DC
3654
3655 /* stripe alignment for allocation is determined by mount parameters */
3656 stripe_align = 0;
3657 if (mp->m_swidth && (mp->m_flags & XFS_MOUNT_SWALLOC))
3658 stripe_align = mp->m_swidth;
3659 else if (mp->m_dalign)
3660 stripe_align = mp->m_dalign;
3661
49f693fa
DC
3662 align = ap->userdata ? xfs_get_extsz_hint(ap->ip) : 0;
3663 if (unlikely(align)) {
3664 error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev,
3665 align, 0, ap->eof, 0, ap->conv,
3666 &ap->offset, &ap->length);
3667 ASSERT(!error);
3668 ASSERT(ap->length);
3669 }
ff105f75
DC
3670
3671
49f693fa
DC
3672 nullfb = *ap->firstblock == NULLFSBLOCK;
3673 fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, *ap->firstblock);
3674 if (nullfb) {
3675 if (ap->userdata && xfs_inode_is_filestream(ap->ip)) {
3676 ag = xfs_filestream_lookup_ag(ap->ip);
3677 ag = (ag != NULLAGNUMBER) ? ag : 0;
3678 ap->blkno = XFS_AGB_TO_FSB(mp, ag, 0);
3679 } else {
3680 ap->blkno = XFS_INO_TO_FSB(mp, ap->ip->i_ino);
3681 }
3682 } else
3683 ap->blkno = *ap->firstblock;
3684
3685 xfs_bmap_adjacent(ap);
2bd0ea18 3686
2bd0ea18 3687 /*
49f693fa
DC
3688 * If allowed, use ap->blkno; otherwise must use firstblock since
3689 * it's in the right allocation group.
2bd0ea18 3690 */
49f693fa
DC
3691 if (nullfb || XFS_FSB_TO_AGNO(mp, ap->blkno) == fb_agno)
3692 ;
3693 else
3694 ap->blkno = *ap->firstblock;
2bd0ea18 3695 /*
49f693fa 3696 * Normal allocation, done through xfs_alloc_vextent.
2bd0ea18 3697 */
49f693fa
DC
3698 tryagain = isaligned = 0;
3699 memset(&args, 0, sizeof(args));
3700 args.tp = ap->tp;
3701 args.mp = mp;
3702 args.fsbno = ap->blkno;
3703
3704 /* Trim the allocation back to the maximum an AG can fit. */
3705 args.maxlen = MIN(ap->length, XFS_ALLOC_AG_MAX_USABLE(mp));
3706 args.firstblock = *ap->firstblock;
3707 blen = 0;
3708 if (nullfb) {
ff105f75
DC
3709 /*
3710 * Search for an allocation group with a single extent large
3711 * enough for the request. If one isn't found, then adjust
3712 * the minimum allocation size to the largest space found.
3713 */
3714 if (ap->userdata && xfs_inode_is_filestream(ap->ip))
3715 error = xfs_bmap_btalloc_filestreams(ap, &args, &blen);
3716 else
3717 error = xfs_bmap_btalloc_nullfb(ap, &args, &blen);
a2ceac1f 3718 if (error)
2bd0ea18 3719 return error;
49f693fa
DC
3720 } else if (ap->flist->xbf_low) {
3721 if (xfs_inode_is_filestream(ap->ip))
3722 args.type = XFS_ALLOCTYPE_FIRST_AG;
3723 else
3724 args.type = XFS_ALLOCTYPE_START_BNO;
3725 args.total = args.minlen = ap->minlen;
3726 } else {
3727 args.type = XFS_ALLOCTYPE_NEAR_BNO;
3728 args.total = ap->total;
3729 args.minlen = ap->minlen;
3730 }
3731 /* apply extent size hints if obtained earlier */
3732 if (unlikely(align)) {
3733 args.prod = align;
3734 if ((args.mod = (xfs_extlen_t)do_mod(ap->offset, args.prod)))
3735 args.mod = (xfs_extlen_t)(args.prod - args.mod);
b2327e1a 3736 } else if (mp->m_sb.sb_blocksize >= PAGE_SIZE) {
49f693fa
DC
3737 args.prod = 1;
3738 args.mod = 0;
3739 } else {
b2327e1a 3740 args.prod = PAGE_SIZE >> mp->m_sb.sb_blocklog;
49f693fa
DC
3741 if ((args.mod = (xfs_extlen_t)(do_mod(ap->offset, args.prod))))
3742 args.mod = (xfs_extlen_t)(args.prod - args.mod);
2bd0ea18
NS
3743 }
3744 /*
49f693fa
DC
3745 * If we are not low on available data blocks, and the
3746 * underlying logical volume manager is a stripe, and
3747 * the file offset is zero then try to allocate data
3748 * blocks on stripe unit boundary.
3749 * NOTE: ap->aeof is only set if the allocation length
3750 * is >= the stripe unit and the allocation offset is
3751 * at the end of file.
2bd0ea18 3752 */
49f693fa
DC
3753 if (!ap->flist->xbf_low && ap->aeof) {
3754 if (!ap->offset) {
ff105f75 3755 args.alignment = stripe_align;
49f693fa
DC
3756 atype = args.type;
3757 isaligned = 1;
3758 /*
3759 * Adjust for alignment
3760 */
3761 if (blen > args.alignment && blen <= args.maxlen)
3762 args.minlen = blen - args.alignment;
3763 args.minalignslop = 0;
3764 } else {
3765 /*
3766 * First try an exact bno allocation.
3767 * If it fails then do a near or start bno
3768 * allocation with alignment turned on.
3769 */
3770 atype = args.type;
3771 tryagain = 1;
3772 args.type = XFS_ALLOCTYPE_THIS_BNO;
3773 args.alignment = 1;
3774 /*
3775 * Compute the minlen+alignment for the
3776 * next case. Set slop so that the value
3777 * of minlen+alignment+slop doesn't go up
3778 * between the calls.
3779 */
ff105f75
DC
3780 if (blen > stripe_align && blen <= args.maxlen)
3781 nextminlen = blen - stripe_align;
49f693fa
DC
3782 else
3783 nextminlen = args.minlen;
ff105f75 3784 if (nextminlen + stripe_align > args.minlen + 1)
49f693fa 3785 args.minalignslop =
ff105f75 3786 nextminlen + stripe_align -
49f693fa
DC
3787 args.minlen - 1;
3788 else
3789 args.minalignslop = 0;
2bd0ea18 3790 }
49f693fa
DC
3791 } else {
3792 args.alignment = 1;
3793 args.minalignslop = 0;
3794 }
3795 args.minleft = ap->minleft;
3796 args.wasdel = ap->wasdel;
3797 args.isfl = 0;
3798 args.userdata = ap->userdata;
9542ae13
DC
3799 if (ap->userdata & XFS_ALLOC_USERDATA_ZERO)
3800 args.ip = ap->ip;
3801
3802 error = xfs_alloc_vextent(&args);
3803 if (error)
49f693fa 3804 return error;
9542ae13 3805
49f693fa
DC
3806 if (tryagain && args.fsbno == NULLFSBLOCK) {
3807 /*
3808 * Exact allocation failed. Now try with alignment
3809 * turned on.
3810 */
3811 args.type = atype;
3812 args.fsbno = ap->blkno;
ff105f75 3813 args.alignment = stripe_align;
49f693fa
DC
3814 args.minlen = nextminlen;
3815 args.minalignslop = 0;
3816 isaligned = 1;
3817 if ((error = xfs_alloc_vextent(&args)))
3818 return error;
3819 }
3820 if (isaligned && args.fsbno == NULLFSBLOCK) {
2bd0ea18 3821 /*
49f693fa
DC
3822 * allocation failed, so turn off alignment and
3823 * try again.
2bd0ea18 3824 */
49f693fa
DC
3825 args.type = atype;
3826 args.fsbno = ap->blkno;
3827 args.alignment = 0;
3828 if ((error = xfs_alloc_vextent(&args)))
3829 return error;
3830 }
3831 if (args.fsbno == NULLFSBLOCK && nullfb &&
3832 args.minlen > ap->minlen) {
3833 args.minlen = ap->minlen;
3834 args.type = XFS_ALLOCTYPE_START_BNO;
3835 args.fsbno = ap->blkno;
3836 if ((error = xfs_alloc_vextent(&args)))
3837 return error;
3838 }
3839 if (args.fsbno == NULLFSBLOCK && nullfb) {
3840 args.fsbno = 0;
3841 args.type = XFS_ALLOCTYPE_FIRST_AG;
3842 args.total = ap->minlen;
3843 args.minleft = 0;
3844 if ((error = xfs_alloc_vextent(&args)))
3845 return error;
3846 ap->flist->xbf_low = 1;
3847 }
3848 if (args.fsbno != NULLFSBLOCK) {
2bd0ea18 3849 /*
49f693fa
DC
3850 * check the allocation happened at the same or higher AG than
3851 * the first block that was allocated.
2bd0ea18 3852 */
49f693fa
DC
3853 ASSERT(*ap->firstblock == NULLFSBLOCK ||
3854 XFS_FSB_TO_AGNO(mp, *ap->firstblock) ==
3855 XFS_FSB_TO_AGNO(mp, args.fsbno) ||
3856 (ap->flist->xbf_low &&
3857 XFS_FSB_TO_AGNO(mp, *ap->firstblock) <
3858 XFS_FSB_TO_AGNO(mp, args.fsbno)));
3859
3860 ap->blkno = args.fsbno;
3861 if (*ap->firstblock == NULLFSBLOCK)
3862 *ap->firstblock = args.fsbno;
3863 ASSERT(nullfb || fb_agno == args.agno ||
3864 (ap->flist->xbf_low && fb_agno < args.agno));
3865 ap->length = args.len;
3866 ap->ip->i_d.di_nblocks += args.len;
3867 xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE);
3868 if (ap->wasdel)
3869 ap->ip->i_delayed_blks -= args.len;
2bd0ea18 3870 /*
49f693fa
DC
3871 * Adjust the disk quota also. This was reserved
3872 * earlier.
2bd0ea18 3873 */
49f693fa
DC
3874 xfs_trans_mod_dquot_byino(ap->tp, ap->ip,
3875 ap->wasdel ? XFS_TRANS_DQ_DELBCOUNT :
3876 XFS_TRANS_DQ_BCOUNT,
3877 (long) args.len);
3878 } else {
3879 ap->blkno = NULLFSBLOCK;
3880 ap->length = 0;
2bd0ea18 3881 }
2bd0ea18 3882 return 0;
56b2de80
DC
3883}
3884
3885/*
49f693fa
DC
3886 * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file.
3887 * It figures out where to ask the underlying allocator to put the new extent.
56b2de80 3888 */
49f693fa
DC
3889STATIC int
3890xfs_bmap_alloc(
613e6057 3891 struct xfs_bmalloca *ap) /* bmap alloc argument struct */
56b2de80 3892{
49f693fa
DC
3893 if (XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata)
3894 return xfs_bmap_rtalloc(ap);
3895 return xfs_bmap_btalloc(ap);
56b2de80 3896}
56b2de80 3897
2bd0ea18 3898/*
a2ceac1f 3899 * Trim the returned map to the required bounds
2bd0ea18 3900 */
a2ceac1f
DC
3901STATIC void
3902xfs_bmapi_trim_map(
3903 struct xfs_bmbt_irec *mval,
3904 struct xfs_bmbt_irec *got,
3905 xfs_fileoff_t *bno,
3906 xfs_filblks_t len,
3907 xfs_fileoff_t obno,
3908 xfs_fileoff_t end,
3909 int n,
3910 int flags)
2bd0ea18 3911{
a2ceac1f
DC
3912 if ((flags & XFS_BMAPI_ENTIRE) ||
3913 got->br_startoff + got->br_blockcount <= obno) {
3914 *mval = *got;
3915 if (isnullstartblock(got->br_startblock))
3916 mval->br_startblock = DELAYSTARTBLOCK;
3917 return;
63be04eb 3918 }
a2ceac1f
DC
3919
3920 if (obno > *bno)
3921 *bno = obno;
3922 ASSERT((*bno >= obno) || (n == 0));
3923 ASSERT(*bno < end);
3924 mval->br_startoff = *bno;
3925 if (isnullstartblock(got->br_startblock))
3926 mval->br_startblock = DELAYSTARTBLOCK;
2bd0ea18 3927 else
a2ceac1f
DC
3928 mval->br_startblock = got->br_startblock +
3929 (*bno - got->br_startoff);
2bd0ea18 3930 /*
a2ceac1f
DC
3931 * Return the minimum of what we got and what we asked for for
3932 * the length. We can use the len variable here because it is
3933 * modified below and we could have been there before coming
3934 * here if the first part of the allocation didn't overlap what
3935 * was asked for.
2bd0ea18 3936 */
a2ceac1f
DC
3937 mval->br_blockcount = XFS_FILBLKS_MIN(end - *bno,
3938 got->br_blockcount - (*bno - got->br_startoff));
3939 mval->br_state = got->br_state;
3940 ASSERT(mval->br_blockcount <= len);
3941 return;
3942}
56b2de80 3943
a2ceac1f
DC
3944/*
3945 * Update and validate the extent map to return
3946 */
3947STATIC void
3948xfs_bmapi_update_map(
3949 struct xfs_bmbt_irec **map,
3950 xfs_fileoff_t *bno,
3951 xfs_filblks_t *len,
3952 xfs_fileoff_t obno,
3953 xfs_fileoff_t end,
3954 int *n,
3955 int flags)
3956{
3957 xfs_bmbt_irec_t *mval = *map;
3958
3959 ASSERT((flags & XFS_BMAPI_ENTIRE) ||
3960 ((mval->br_startoff + mval->br_blockcount) <= end));
3961 ASSERT((flags & XFS_BMAPI_ENTIRE) || (mval->br_blockcount <= *len) ||
3962 (mval->br_startoff < obno));
3963
3964 *bno = mval->br_startoff + mval->br_blockcount;
3965 *len = end - *bno;
3966 if (*n > 0 && mval->br_startoff == mval[-1].br_startoff) {
3967 /* update previous map with new information */
3968 ASSERT(mval->br_startblock == mval[-1].br_startblock);
3969 ASSERT(mval->br_blockcount > mval[-1].br_blockcount);
3970 ASSERT(mval->br_state == mval[-1].br_state);
3971 mval[-1].br_blockcount = mval->br_blockcount;
3972 mval[-1].br_state = mval->br_state;
3973 } else if (*n > 0 && mval->br_startblock != DELAYSTARTBLOCK &&
3974 mval[-1].br_startblock != DELAYSTARTBLOCK &&
3975 mval[-1].br_startblock != HOLESTARTBLOCK &&
3976 mval->br_startblock == mval[-1].br_startblock +
3977 mval[-1].br_blockcount &&
3978 ((flags & XFS_BMAPI_IGSTATE) ||
3979 mval[-1].br_state == mval->br_state)) {
3980 ASSERT(mval->br_startoff ==
3981 mval[-1].br_startoff + mval[-1].br_blockcount);
3982 mval[-1].br_blockcount += mval->br_blockcount;
3983 } else if (*n > 0 &&
3984 mval->br_startblock == DELAYSTARTBLOCK &&
3985 mval[-1].br_startblock == DELAYSTARTBLOCK &&
3986 mval->br_startoff ==
3987 mval[-1].br_startoff + mval[-1].br_blockcount) {
3988 mval[-1].br_blockcount += mval->br_blockcount;
3989 mval[-1].br_state = mval->br_state;
3990 } else if (!((*n == 0) &&
3991 ((mval->br_startoff + mval->br_blockcount) <=
3992 obno))) {
3993 mval++;
3994 (*n)++;
3995 }
3996 *map = mval;
3997}
399ab595 3998
a2ceac1f
DC
3999/*
4000 * Map file blocks to filesystem blocks without allocation.
4001 */
4002int
4003xfs_bmapi_read(
4004 struct xfs_inode *ip,
4005 xfs_fileoff_t bno,
4006 xfs_filblks_t len,
4007 struct xfs_bmbt_irec *mval,
4008 int *nmap,
4009 int flags)
4010{
4011 struct xfs_mount *mp = ip->i_mount;
4012 struct xfs_ifork *ifp;
4013 struct xfs_bmbt_irec got;
4014 struct xfs_bmbt_irec prev;
4015 xfs_fileoff_t obno;
4016 xfs_fileoff_t end;
4017 xfs_extnum_t lastx;
4018 int error;
4019 int eof;
4020 int n = 0;
4021 int whichfork = (flags & XFS_BMAPI_ATTRFORK) ?
4022 XFS_ATTR_FORK : XFS_DATA_FORK;
399ab595 4023
a2ceac1f
DC
4024 ASSERT(*nmap >= 1);
4025 ASSERT(!(flags & ~(XFS_BMAPI_ATTRFORK|XFS_BMAPI_ENTIRE|
4026 XFS_BMAPI_IGSTATE)));
ff105f75 4027 ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED|XFS_ILOCK_EXCL));
062998e3 4028
a2ceac1f
DC
4029 if (unlikely(XFS_TEST_ERROR(
4030 (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
4031 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE),
4032 mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) {
4033 XFS_ERROR_REPORT("xfs_bmapi_read", XFS_ERRLEVEL_LOW, mp);
12b53197 4034 return -EFSCORRUPTED;
a2ceac1f 4035 }
062998e3 4036
a2ceac1f 4037 if (XFS_FORCED_SHUTDOWN(mp))
12b53197 4038 return -EIO;
399ab595 4039
79896434 4040 XFS_STATS_INC(mp, xs_blk_mapr);
a2ceac1f
DC
4041
4042 ifp = XFS_IFORK_PTR(ip, whichfork);
4043
4044 if (!(ifp->if_flags & XFS_IFEXTENTS)) {
4045 error = xfs_iread_extents(NULL, ip, whichfork);
4046 if (error)
4047 return error;
4048 }
4049
4050 xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, &prev);
4051 end = bno + len;
4052 obno = bno;
4053
4054 while (bno < end && n < *nmap) {
4055 /* Reading past eof, act as though there's a hole up to end. */
4056 if (eof)
4057 got.br_startoff = end;
4058 if (got.br_startoff > bno) {
4059 /* Reading in a hole. */
2bd0ea18
NS
4060 mval->br_startoff = bno;
4061 mval->br_startblock = HOLESTARTBLOCK;
4062 mval->br_blockcount =
4063 XFS_FILBLKS_MIN(len, got.br_startoff - bno);
4064 mval->br_state = XFS_EXT_NORM;
4065 bno += mval->br_blockcount;
4066 len -= mval->br_blockcount;
4067 mval++;
4068 n++;
4069 continue;
4070 }
a2ceac1f
DC
4071
4072 /* set up the extent map to return. */
4073 xfs_bmapi_trim_map(mval, &got, &bno, len, obno, end, n, flags);
4074 xfs_bmapi_update_map(&mval, &bno, &len, obno, end, &n, flags);
4075
4076 /* If we're done, stop now. */
4077 if (bno >= end || n >= *nmap)
4078 break;
4079
4080 /* Else go on to the next record. */
4081 if (++lastx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t))
4082 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx), &got);
4083 else
4084 eof = 1;
4085 }
4086 *nmap = n;
4087 return 0;
4088}
4089
4090STATIC int
4091xfs_bmapi_reserve_delalloc(
4092 struct xfs_inode *ip,
4093 xfs_fileoff_t aoff,
4094 xfs_filblks_t len,
4095 struct xfs_bmbt_irec *got,
4096 struct xfs_bmbt_irec *prev,
4097 xfs_extnum_t *lastx,
4098 int eof)
4099{
4100 struct xfs_mount *mp = ip->i_mount;
4101 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
4102 xfs_extlen_t alen;
4103 xfs_extlen_t indlen;
4104 char rt = XFS_IS_REALTIME_INODE(ip);
4105 xfs_extlen_t extsz;
4106 int error;
4107
4108 alen = XFS_FILBLKS_MIN(len, MAXEXTLEN);
4109 if (!eof)
4110 alen = XFS_FILBLKS_MIN(alen, got->br_startoff - aoff);
4111
4112 /* Figure out the extent size, adjust alen */
4113 extsz = xfs_get_extsz_hint(ip);
4114 if (extsz) {
a2ceac1f
DC
4115 error = xfs_bmap_extsize_align(mp, got, prev, extsz, rt, eof,
4116 1, 0, &aoff, &alen);
4117 ASSERT(!error);
4118 }
4119
4120 if (rt)
4121 extsz = alen / mp->m_sb.sb_rextsize;
4122
4123 /*
4124 * Make a transaction-less quota reservation for delayed allocation
4125 * blocks. This number gets adjusted later. We return if we haven't
4126 * allocated blocks already inside this loop.
4127 */
4128 error = xfs_trans_reserve_quota_nblks(NULL, ip, (long)alen, 0,
4129 rt ? XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS);
4130 if (error)
4131 return error;
4132
4133 /*
4134 * Split changing sb for alen and indlen since they could be coming
4135 * from different places.
4136 */
4137 indlen = (xfs_extlen_t)xfs_bmap_worst_indlen(ip, alen);
4138 ASSERT(indlen > 0);
4139
4140 if (rt) {
19ebedcf 4141 error = xfs_mod_frextents(mp, -((int64_t)extsz));
a2ceac1f 4142 } else {
19ebedcf 4143 error = xfs_mod_fdblocks(mp, -((int64_t)alen), false);
a2ceac1f
DC
4144 }
4145
4146 if (error)
4147 goto out_unreserve_quota;
4148
19ebedcf 4149 error = xfs_mod_fdblocks(mp, -((int64_t)indlen), false);
a2ceac1f
DC
4150 if (error)
4151 goto out_unreserve_blocks;
4152
4153
4154 ip->i_delayed_blks += alen;
4155
4156 got->br_startoff = aoff;
4157 got->br_startblock = nullstartblock(indlen);
4158 got->br_blockcount = alen;
4159 got->br_state = XFS_EXT_NORM;
4160 xfs_bmap_add_extent_hole_delay(ip, lastx, got);
4161
4162 /*
4163 * Update our extent pointer, given that xfs_bmap_add_extent_hole_delay
4164 * might have merged it into one of the neighbouring ones.
4165 */
4166 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *lastx), got);
4167
4168 ASSERT(got->br_startoff <= aoff);
4169 ASSERT(got->br_startoff + got->br_blockcount >= aoff + alen);
4170 ASSERT(isnullstartblock(got->br_startblock));
4171 ASSERT(got->br_state == XFS_EXT_NORM);
4172 return 0;
4173
4174out_unreserve_blocks:
4175 if (rt)
19ebedcf 4176 xfs_mod_frextents(mp, extsz);
a2ceac1f 4177 else
19ebedcf 4178 xfs_mod_fdblocks(mp, alen, false);
a2ceac1f
DC
4179out_unreserve_quota:
4180 if (XFS_IS_QUOTA_ON(mp))
4181 xfs_trans_unreserve_quota_nblks(NULL, ip, (long)alen, 0, rt ?
4182 XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS);
4183 return error;
4184}
4185
4186/*
4187 * Map file blocks to filesystem blocks, adding delayed allocations as needed.
4188 */
4189int
4190xfs_bmapi_delay(
4191 struct xfs_inode *ip, /* incore inode */
4192 xfs_fileoff_t bno, /* starting file offs. mapped */
4193 xfs_filblks_t len, /* length to map in file */
4194 struct xfs_bmbt_irec *mval, /* output: map values */
4195 int *nmap, /* i/o: mval size/count */
4196 int flags) /* XFS_BMAPI_... */
4197{
4198 struct xfs_mount *mp = ip->i_mount;
4199 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
4200 struct xfs_bmbt_irec got; /* current file extent record */
4201 struct xfs_bmbt_irec prev; /* previous file extent record */
4202 xfs_fileoff_t obno; /* old block number (offset) */
4203 xfs_fileoff_t end; /* end of mapped file region */
4204 xfs_extnum_t lastx; /* last useful extent number */
4205 int eof; /* we've hit the end of extents */
4206 int n = 0; /* current extent index */
4207 int error = 0;
4208
4209 ASSERT(*nmap >= 1);
4210 ASSERT(*nmap <= XFS_BMAP_MAX_NMAP);
4211 ASSERT(!(flags & ~XFS_BMAPI_ENTIRE));
ff105f75 4212 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
a2ceac1f
DC
4213
4214 if (unlikely(XFS_TEST_ERROR(
4215 (XFS_IFORK_FORMAT(ip, XFS_DATA_FORK) != XFS_DINODE_FMT_EXTENTS &&
4216 XFS_IFORK_FORMAT(ip, XFS_DATA_FORK) != XFS_DINODE_FMT_BTREE),
4217 mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) {
4218 XFS_ERROR_REPORT("xfs_bmapi_delay", XFS_ERRLEVEL_LOW, mp);
12b53197 4219 return -EFSCORRUPTED;
a2ceac1f
DC
4220 }
4221
4222 if (XFS_FORCED_SHUTDOWN(mp))
12b53197 4223 return -EIO;
a2ceac1f 4224
79896434 4225 XFS_STATS_INC(mp, xs_blk_mapw);
a2ceac1f
DC
4226
4227 if (!(ifp->if_flags & XFS_IFEXTENTS)) {
4228 error = xfs_iread_extents(NULL, ip, XFS_DATA_FORK);
4229 if (error)
4230 return error;
4231 }
4232
4233 xfs_bmap_search_extents(ip, bno, XFS_DATA_FORK, &eof, &lastx, &got, &prev);
4234 end = bno + len;
4235 obno = bno;
4236
4237 while (bno < end && n < *nmap) {
4238 if (eof || got.br_startoff > bno) {
4239 error = xfs_bmapi_reserve_delalloc(ip, bno, len, &got,
4240 &prev, &lastx, eof);
4241 if (error) {
4242 if (n == 0) {
4243 *nmap = 0;
4244 return error;
4245 }
4246 break;
2bd0ea18
NS
4247 }
4248 }
4249
a2ceac1f
DC
4250 /* set up the extent map to return. */
4251 xfs_bmapi_trim_map(mval, &got, &bno, len, obno, end, n, flags);
4252 xfs_bmapi_update_map(&mval, &bno, &len, obno, end, &n, flags);
4253
4254 /* If we're done, stop now. */
4255 if (bno >= end || n >= *nmap)
4256 break;
4257
4258 /* Else go on to the next record. */
4259 prev = got;
4260 if (++lastx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t))
4261 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx), &got);
4262 else
4263 eof = 1;
4264 }
4265
4266 *nmap = n;
4267 return 0;
4268}
4269
4270
ff105f75
DC
4271static int
4272xfs_bmapi_allocate(
a2ceac1f
DC
4273 struct xfs_bmalloca *bma)
4274{
4275 struct xfs_mount *mp = bma->ip->i_mount;
4276 int whichfork = (bma->flags & XFS_BMAPI_ATTRFORK) ?
4277 XFS_ATTR_FORK : XFS_DATA_FORK;
4278 struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork);
4279 int tmp_logflags = 0;
4280 int error;
4281
4282 ASSERT(bma->length > 0);
4283
4284 /*
4285 * For the wasdelay case, we could also just allocate the stuff asked
4286 * for in this bmap call but that wouldn't be as good.
4287 */
4288 if (bma->wasdel) {
4289 bma->length = (xfs_extlen_t)bma->got.br_blockcount;
4290 bma->offset = bma->got.br_startoff;
4291 if (bma->idx != NULLEXTNUM && bma->idx) {
4292 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx - 1),
4293 &bma->prev);
4294 }
4295 } else {
4296 bma->length = XFS_FILBLKS_MIN(bma->length, MAXEXTLEN);
4297 if (!bma->eof)
4298 bma->length = XFS_FILBLKS_MIN(bma->length,
4299 bma->got.br_startoff - bma->offset);
4300 }
4301
4302 /*
4303 * Indicate if this is the first user data in the file, or just any
9542ae13
DC
4304 * user data. And if it is userdata, indicate whether it needs to
4305 * be initialised to zero during allocation.
a2ceac1f
DC
4306 */
4307 if (!(bma->flags & XFS_BMAPI_METADATA)) {
4308 bma->userdata = (bma->offset == 0) ?
4309 XFS_ALLOC_INITIAL_USER_DATA : XFS_ALLOC_USERDATA;
9542ae13
DC
4310 if (bma->flags & XFS_BMAPI_ZERO)
4311 bma->userdata |= XFS_ALLOC_USERDATA_ZERO;
a2ceac1f
DC
4312 }
4313
4314 bma->minlen = (bma->flags & XFS_BMAPI_CONTIG) ? bma->length : 1;
4315
4316 /*
4317 * Only want to do the alignment at the eof if it is userdata and
4318 * allocation length is larger than a stripe unit.
4319 */
4320 if (mp->m_dalign && bma->length >= mp->m_dalign &&
4321 !(bma->flags & XFS_BMAPI_METADATA) && whichfork == XFS_DATA_FORK) {
4322 error = xfs_bmap_isaeof(bma, whichfork);
4323 if (error)
4324 return error;
4325 }
4326
a2ceac1f
DC
4327 error = xfs_bmap_alloc(bma);
4328 if (error)
4329 return error;
4330
4331 if (bma->flist->xbf_low)
4332 bma->minleft = 0;
4333 if (bma->cur)
4334 bma->cur->bc_private.b.firstblock = *bma->firstblock;
4335 if (bma->blkno == NULLFSBLOCK)
4336 return 0;
4337 if ((ifp->if_flags & XFS_IFBROOT) && !bma->cur) {
4338 bma->cur = xfs_bmbt_init_cursor(mp, bma->tp, bma->ip, whichfork);
4339 bma->cur->bc_private.b.firstblock = *bma->firstblock;
4340 bma->cur->bc_private.b.flist = bma->flist;
4341 }
4342 /*
4343 * Bump the number of extents we've allocated
4344 * in this call.
4345 */
4346 bma->nallocs++;
4347
4348 if (bma->cur)
4349 bma->cur->bc_private.b.flags =
4350 bma->wasdel ? XFS_BTCUR_BPRV_WASDEL : 0;
4351
4352 bma->got.br_startoff = bma->offset;
4353 bma->got.br_startblock = bma->blkno;
4354 bma->got.br_blockcount = bma->length;
4355 bma->got.br_state = XFS_EXT_NORM;
4356
4357 /*
4358 * A wasdelay extent has been initialized, so shouldn't be flagged
4359 * as unwritten.
4360 */
4361 if (!bma->wasdel && (bma->flags & XFS_BMAPI_PREALLOC) &&
4362 xfs_sb_version_hasextflgbit(&mp->m_sb))
4363 bma->got.br_state = XFS_EXT_UNWRITTEN;
4364
4365 if (bma->wasdel)
4366 error = xfs_bmap_add_extent_delay_real(bma);
4367 else
4368 error = xfs_bmap_add_extent_hole_real(bma, whichfork);
4369
4370 bma->logflags |= tmp_logflags;
4371 if (error)
4372 return error;
4373
4374 /*
4375 * Update our extent pointer, given that xfs_bmap_add_extent_delay_real
4376 * or xfs_bmap_add_extent_hole_real might have merged it into one of
4377 * the neighbouring ones.
4378 */
4379 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx), &bma->got);
4380
4381 ASSERT(bma->got.br_startoff <= bma->offset);
4382 ASSERT(bma->got.br_startoff + bma->got.br_blockcount >=
4383 bma->offset + bma->length);
4384 ASSERT(bma->got.br_state == XFS_EXT_NORM ||
4385 bma->got.br_state == XFS_EXT_UNWRITTEN);
4386 return 0;
4387}
4388
a2ceac1f
DC
4389STATIC int
4390xfs_bmapi_convert_unwritten(
4391 struct xfs_bmalloca *bma,
4392 struct xfs_bmbt_irec *mval,
4393 xfs_filblks_t len,
4394 int flags)
4395{
4396 int whichfork = (flags & XFS_BMAPI_ATTRFORK) ?
4397 XFS_ATTR_FORK : XFS_DATA_FORK;
4398 struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork);
4399 int tmp_logflags = 0;
4400 int error;
4401
4402 /* check if we need to do unwritten->real conversion */
4403 if (mval->br_state == XFS_EXT_UNWRITTEN &&
4404 (flags & XFS_BMAPI_PREALLOC))
4405 return 0;
4406
4407 /* check if we need to do real->unwritten conversion */
4408 if (mval->br_state == XFS_EXT_NORM &&
4409 (flags & (XFS_BMAPI_PREALLOC | XFS_BMAPI_CONVERT)) !=
4410 (XFS_BMAPI_PREALLOC | XFS_BMAPI_CONVERT))
4411 return 0;
4412
4413 /*
4414 * Modify (by adding) the state flag, if writing.
4415 */
4416 ASSERT(mval->br_blockcount <= len);
4417 if ((ifp->if_flags & XFS_IFBROOT) && !bma->cur) {
4418 bma->cur = xfs_bmbt_init_cursor(bma->ip->i_mount, bma->tp,
4419 bma->ip, whichfork);
4420 bma->cur->bc_private.b.firstblock = *bma->firstblock;
4421 bma->cur->bc_private.b.flist = bma->flist;
4422 }
4423 mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN)
4424 ? XFS_EXT_NORM : XFS_EXT_UNWRITTEN;
4425
9542ae13
DC
4426 /*
4427 * Before insertion into the bmbt, zero the range being converted
4428 * if required.
4429 */
4430 if (flags & XFS_BMAPI_ZERO) {
4431 error = xfs_zero_extent(bma->ip, mval->br_startblock,
4432 mval->br_blockcount);
4433 if (error)
4434 return error;
4435 }
4436
a2ceac1f
DC
4437 error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, &bma->idx,
4438 &bma->cur, mval, bma->firstblock, bma->flist,
4439 &tmp_logflags);
23fc058d
BF
4440 /*
4441 * Log the inode core unconditionally in the unwritten extent conversion
4442 * path because the conversion might not have done so (e.g., if the
4443 * extent count hasn't changed). We need to make sure the inode is dirty
4444 * in the transaction for the sake of fsync(), even if nothing has
4445 * changed, because fsync() will not force the log for this transaction
4446 * unless it sees the inode pinned.
4447 */
4448 bma->logflags |= tmp_logflags | XFS_ILOG_CORE;
a2ceac1f
DC
4449 if (error)
4450 return error;
4451
4452 /*
4453 * Update our extent pointer, given that
4454 * xfs_bmap_add_extent_unwritten_real might have merged it into one
4455 * of the neighbouring ones.
4456 */
4457 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx), &bma->got);
4458
4459 /*
4460 * We may have combined previously unwritten space with written space,
4461 * so generate another request.
4462 */
4463 if (mval->br_blockcount < len)
12b53197 4464 return -EAGAIN;
a2ceac1f
DC
4465 return 0;
4466}
4467
4468/*
4469 * Map file blocks to filesystem blocks, and allocate blocks or convert the
4470 * extent state if necessary. Details behaviour is controlled by the flags
4471 * parameter. Only allocates blocks from a single allocation group, to avoid
4472 * locking problems.
4473 *
4474 * The returned value in "firstblock" from the first call in a transaction
4475 * must be remembered and presented to subsequent calls in "firstblock".
4476 * An upper bound for the number of blocks to be allocated is supplied to
4477 * the first call in "total"; if no allocation group has that many free
4478 * blocks then the call will fail (return NULLFSBLOCK in "firstblock").
4479 */
4480int
4481xfs_bmapi_write(
4482 struct xfs_trans *tp, /* transaction pointer */
4483 struct xfs_inode *ip, /* incore inode */
4484 xfs_fileoff_t bno, /* starting file offs. mapped */
4485 xfs_filblks_t len, /* length to map in file */
4486 int flags, /* XFS_BMAPI_... */
4487 xfs_fsblock_t *firstblock, /* first allocated block
4488 controls a.g. for allocs */
4489 xfs_extlen_t total, /* total blocks needed */
4490 struct xfs_bmbt_irec *mval, /* output: map values */
4491 int *nmap, /* i/o: mval size/count */
4492 struct xfs_bmap_free *flist) /* i/o: list extents to free */
4493{
4494 struct xfs_mount *mp = ip->i_mount;
4495 struct xfs_ifork *ifp;
389b3b07 4496 struct xfs_bmalloca bma = { NULL }; /* args for xfs_bmap_alloc */
a2ceac1f
DC
4497 xfs_fileoff_t end; /* end of mapped file region */
4498 int eof; /* after the end of extents */
4499 int error; /* error return */
4500 int n; /* current extent index */
4501 xfs_fileoff_t obno; /* old block number (offset) */
4502 int whichfork; /* data or attr fork */
4503 char inhole; /* current location is hole in file */
4504 char wasdelay; /* old extent was delayed */
4505
4506#ifdef DEBUG
4507 xfs_fileoff_t orig_bno; /* original block number value */
4508 int orig_flags; /* original flags arg value */
4509 xfs_filblks_t orig_len; /* original value of len arg */
4510 struct xfs_bmbt_irec *orig_mval; /* original value of mval */
4511 int orig_nmap; /* original value of *nmap */
4512
4513 orig_bno = bno;
4514 orig_len = len;
4515 orig_flags = flags;
4516 orig_mval = mval;
4517 orig_nmap = *nmap;
4518#endif
3f17ed4b
DC
4519 whichfork = (flags & XFS_BMAPI_ATTRFORK) ?
4520 XFS_ATTR_FORK : XFS_DATA_FORK;
a2ceac1f
DC
4521
4522 ASSERT(*nmap >= 1);
4523 ASSERT(*nmap <= XFS_BMAP_MAX_NMAP);
4524 ASSERT(!(flags & XFS_BMAPI_IGSTATE));
4525 ASSERT(tp != NULL);
4526 ASSERT(len > 0);
3f17ed4b 4527 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL);
ff105f75 4528 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
a2ceac1f 4529
9542ae13
DC
4530 /* zeroing is for currently only for data extents, not metadata */
4531 ASSERT((flags & (XFS_BMAPI_METADATA | XFS_BMAPI_ZERO)) !=
4532 (XFS_BMAPI_METADATA | XFS_BMAPI_ZERO));
4533 /*
4534 * we can allocate unwritten extents or pre-zero allocated blocks,
4535 * but it makes no sense to do both at once. This would result in
4536 * zeroing the unwritten extent twice, but it still being an
4537 * unwritten extent....
4538 */
4539 ASSERT((flags & (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO)) !=
4540 (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO));
4541
a2ceac1f
DC
4542 if (unlikely(XFS_TEST_ERROR(
4543 (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
3f17ed4b 4544 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE),
a2ceac1f
DC
4545 mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) {
4546 XFS_ERROR_REPORT("xfs_bmapi_write", XFS_ERRLEVEL_LOW, mp);
12b53197 4547 return -EFSCORRUPTED;
a2ceac1f
DC
4548 }
4549
4550 if (XFS_FORCED_SHUTDOWN(mp))
12b53197 4551 return -EIO;
a2ceac1f
DC
4552
4553 ifp = XFS_IFORK_PTR(ip, whichfork);
4554
79896434 4555 XFS_STATS_INC(mp, xs_blk_mapw);
a2ceac1f 4556
a2ceac1f
DC
4557 if (*firstblock == NULLFSBLOCK) {
4558 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE)
4559 bma.minleft = be16_to_cpu(ifp->if_broot->bb_level) + 1;
4560 else
4561 bma.minleft = 1;
4562 } else {
4563 bma.minleft = 0;
4564 }
4565
4566 if (!(ifp->if_flags & XFS_IFEXTENTS)) {
4567 error = xfs_iread_extents(tp, ip, whichfork);
4568 if (error)
4569 goto error0;
4570 }
4571
4572 xfs_bmap_search_extents(ip, bno, whichfork, &eof, &bma.idx, &bma.got,
4573 &bma.prev);
4574 n = 0;
4575 end = bno + len;
4576 obno = bno;
4577
4578 bma.tp = tp;
4579 bma.ip = ip;
4580 bma.total = total;
4581 bma.userdata = 0;
4582 bma.flist = flist;
4583 bma.firstblock = firstblock;
4584
4585 while (bno < end && n < *nmap) {
4586 inhole = eof || bma.got.br_startoff > bno;
4587 wasdelay = !inhole && isnullstartblock(bma.got.br_startblock);
4588
2bd0ea18 4589 /*
a2ceac1f
DC
4590 * First, deal with the hole before the allocated space
4591 * that we found, if any.
2bd0ea18 4592 */
a2ceac1f
DC
4593 if (inhole || wasdelay) {
4594 bma.eof = eof;
4595 bma.conv = !!(flags & XFS_BMAPI_CONVERT);
4596 bma.wasdel = wasdelay;
4597 bma.offset = bno;
4598 bma.flags = flags;
4599
2bd0ea18 4600 /*
a2ceac1f
DC
4601 * There's a 32/64 bit type mismatch between the
4602 * allocation length request (which can be 64 bits in
4603 * length) and the bma length request, which is
4604 * xfs_extlen_t and therefore 32 bits. Hence we have to
4605 * check for 32-bit overflows and handle them here.
2bd0ea18 4606 */
a2ceac1f
DC
4607 if (len > (xfs_filblks_t)MAXEXTLEN)
4608 bma.length = MAXEXTLEN;
4609 else
4610 bma.length = len;
4611
4612 ASSERT(len > 0);
4613 ASSERT(bma.length > 0);
4614 error = xfs_bmapi_allocate(&bma);
2bd0ea18
NS
4615 if (error)
4616 goto error0;
a2ceac1f
DC
4617 if (bma.blkno == NULLFSBLOCK)
4618 break;
2bd0ea18
NS
4619 }
4620
a2ceac1f
DC
4621 /* Deal with the allocated space we found. */
4622 xfs_bmapi_trim_map(mval, &bma.got, &bno, len, obno,
4623 end, n, flags);
4624
4625 /* Execute unwritten extent conversion if necessary */
4626 error = xfs_bmapi_convert_unwritten(&bma, mval, len, flags);
12b53197 4627 if (error == -EAGAIN)
a2ceac1f
DC
4628 continue;
4629 if (error)
4630 goto error0;
4631
4632 /* update the extent map to return */
4633 xfs_bmapi_update_map(&mval, &bno, &len, obno, end, &n, flags);
4634
2bd0ea18
NS
4635 /*
4636 * If we're done, stop now. Stop when we've allocated
4637 * XFS_BMAP_MAX_NMAP extents no matter what. Otherwise
4638 * the transaction may get too big.
4639 */
a2ceac1f 4640 if (bno >= end || n >= *nmap || bma.nallocs >= *nmap)
2bd0ea18 4641 break;
a2ceac1f
DC
4642
4643 /* Else go on to the next record. */
4644 bma.prev = bma.got;
4645 if (++bma.idx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t)) {
4646 xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma.idx),
4647 &bma.got);
4648 } else
2bd0ea18 4649 eof = 1;
2bd0ea18 4650 }
2bd0ea18 4651 *nmap = n;
a2ceac1f 4652
2bd0ea18
NS
4653 /*
4654 * Transform from btree to extents, give it cur.
4655 */
a2ceac1f
DC
4656 if (xfs_bmap_wants_extents(ip, whichfork)) {
4657 int tmp_logflags = 0;
4658
4659 ASSERT(bma.cur);
4660 error = xfs_bmap_btree_to_extents(tp, ip, bma.cur,
4ca431fc 4661 &tmp_logflags, whichfork);
a2ceac1f 4662 bma.logflags |= tmp_logflags;
2bd0ea18
NS
4663 if (error)
4664 goto error0;
4665 }
a2ceac1f 4666
2bd0ea18 4667 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE ||
a2ceac1f
DC
4668 XFS_IFORK_NEXTENTS(ip, whichfork) >
4669 XFS_IFORK_MAXEXT(ip, whichfork));
2bd0ea18 4670 error = 0;
2bd0ea18
NS
4671error0:
4672 /*
4673 * Log everything. Do this after conversion, there's no point in
5e656dbb 4674 * logging the extent records if we've converted to btree format.
2bd0ea18 4675 */
a2ceac1f 4676 if ((bma.logflags & xfs_ilog_fext(whichfork)) &&
2bd0ea18 4677 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)
a2ceac1f
DC
4678 bma.logflags &= ~xfs_ilog_fext(whichfork);
4679 else if ((bma.logflags & xfs_ilog_fbroot(whichfork)) &&
2bd0ea18 4680 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)
a2ceac1f 4681 bma.logflags &= ~xfs_ilog_fbroot(whichfork);
2bd0ea18
NS
4682 /*
4683 * Log whatever the flags say, even if error. Otherwise we might miss
4684 * detecting a case where the data is changed, there's an error,
4685 * and it's not logged so we don't shutdown when we should.
4686 */
a2ceac1f
DC
4687 if (bma.logflags)
4688 xfs_trans_log_inode(tp, ip, bma.logflags);
4689
4690 if (bma.cur) {
2bd0ea18
NS
4691 if (!error) {
4692 ASSERT(*firstblock == NULLFSBLOCK ||
eae766ca
NS
4693 XFS_FSB_TO_AGNO(mp, *firstblock) ==
4694 XFS_FSB_TO_AGNO(mp,
a2ceac1f 4695 bma.cur->bc_private.b.firstblock) ||
2bd0ea18 4696 (flist->xbf_low &&
eae766ca
NS
4697 XFS_FSB_TO_AGNO(mp, *firstblock) <
4698 XFS_FSB_TO_AGNO(mp,
a2ceac1f
DC
4699 bma.cur->bc_private.b.firstblock)));
4700 *firstblock = bma.cur->bc_private.b.firstblock;
2bd0ea18 4701 }
a2ceac1f 4702 xfs_btree_del_cursor(bma.cur,
2bd0ea18
NS
4703 error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR);
4704 }
4705 if (!error)
4706 xfs_bmap_validate_ret(orig_bno, orig_len, orig_flags, orig_mval,
4707 orig_nmap, *nmap);
4708 return error;
4709}
4710
01d1b786
BF
4711/*
4712 * When a delalloc extent is split (e.g., due to a hole punch), the original
4713 * indlen reservation must be shared across the two new extents that are left
4714 * behind.
4715 *
4716 * Given the original reservation and the worst case indlen for the two new
4717 * extents (as calculated by xfs_bmap_worst_indlen()), split the original
731ccdf9
BF
4718 * reservation fairly across the two new extents. If necessary, steal available
4719 * blocks from a deleted extent to make up a reservation deficiency (e.g., if
4720 * ores == 1). The number of stolen blocks is returned. The availability and
4721 * subsequent accounting of stolen blocks is the responsibility of the caller.
01d1b786 4722 */
731ccdf9 4723static xfs_filblks_t
01d1b786
BF
4724xfs_bmap_split_indlen(
4725 xfs_filblks_t ores, /* original res. */
4726 xfs_filblks_t *indlen1, /* ext1 worst indlen */
731ccdf9
BF
4727 xfs_filblks_t *indlen2, /* ext2 worst indlen */
4728 xfs_filblks_t avail) /* stealable blocks */
01d1b786
BF
4729{
4730 xfs_filblks_t len1 = *indlen1;
4731 xfs_filblks_t len2 = *indlen2;
4732 xfs_filblks_t nres = len1 + len2; /* new total res. */
731ccdf9
BF
4733 xfs_filblks_t stolen = 0;
4734
4735 /*
4736 * Steal as many blocks as we can to try and satisfy the worst case
4737 * indlen for both new extents.
4738 */
4739 while (nres > ores && avail) {
4740 nres--;
4741 avail--;
4742 stolen++;
4743 }
01d1b786
BF
4744
4745 /*
731ccdf9
BF
4746 * The only blocks available are those reserved for the original
4747 * extent and what we can steal from the extent being removed.
4748 * If this still isn't enough to satisfy the combined
4749 * requirements for the two new extents, skim blocks off of each
4750 * of the new reservations until they match what is available.
01d1b786
BF
4751 */
4752 while (nres > ores) {
4753 if (len1) {
4754 len1--;
4755 nres--;
4756 }
4757 if (nres == ores)
4758 break;
4759 if (len2) {
4760 len2--;
4761 nres--;
4762 }
4763 }
4764
4765 *indlen1 = len1;
4766 *indlen2 = len2;
731ccdf9
BF
4767
4768 return stolen;
01d1b786
BF
4769}
4770
2bd0ea18 4771/*
49f693fa
DC
4772 * Called by xfs_bmapi to update file extent records and the btree
4773 * after removing space (or undoing a delayed allocation).
2bd0ea18 4774 */
49f693fa
DC
4775STATIC int /* error */
4776xfs_bmap_del_extent(
4777 xfs_inode_t *ip, /* incore inode pointer */
4778 xfs_trans_t *tp, /* current transaction pointer */
4779 xfs_extnum_t *idx, /* extent number to update/delete */
4780 xfs_bmap_free_t *flist, /* list of extents to be freed */
4781 xfs_btree_cur_t *cur, /* if null, not a btree */
4782 xfs_bmbt_irec_t *del, /* data to remove from extents */
4783 int *logflagsp, /* inode logging flags */
4784 int whichfork) /* data or attr fork */
2bd0ea18 4785{
49f693fa
DC
4786 xfs_filblks_t da_new; /* new delay-alloc indirect blocks */
4787 xfs_filblks_t da_old; /* old delay-alloc indirect blocks */
4788 xfs_fsblock_t del_endblock=0; /* first block past del */
4789 xfs_fileoff_t del_endoff; /* first offset past del */
4790 int delay; /* current block is delayed allocated */
4791 int do_fx; /* free extent at end of routine */
4792 xfs_bmbt_rec_host_t *ep; /* current extent entry pointer */
4793 int error; /* error return value */
4794 int flags; /* inode logging flags */
4795 xfs_bmbt_irec_t got; /* current extent entry */
4796 xfs_fileoff_t got_endoff; /* first offset past got */
4797 int i; /* temp state */
4798 xfs_ifork_t *ifp; /* inode fork pointer */
4799 xfs_mount_t *mp; /* mount structure */
4800 xfs_filblks_t nblks; /* quota/sb block count */
4801 xfs_bmbt_irec_t new; /* new record to be inserted */
4802 /* REFERENCED */
4803 uint qfield; /* quota field to update */
4804 xfs_filblks_t temp; /* for indirect length calculations */
4805 xfs_filblks_t temp2; /* for indirect length calculations */
4806 int state = 0;
a2ceac1f 4807
79896434
BD
4808 mp = ip->i_mount;
4809 XFS_STATS_INC(mp, xs_del_exlist);
a2ceac1f 4810
49f693fa
DC
4811 if (whichfork == XFS_ATTR_FORK)
4812 state |= BMAP_ATTRFORK;
56b2de80 4813
49f693fa
DC
4814 ifp = XFS_IFORK_PTR(ip, whichfork);
4815 ASSERT((*idx >= 0) && (*idx < ifp->if_bytes /
4816 (uint)sizeof(xfs_bmbt_rec_t)));
4817 ASSERT(del->br_blockcount > 0);
4818 ep = xfs_iext_get_ext(ifp, *idx);
4819 xfs_bmbt_get_all(ep, &got);
4820 ASSERT(got.br_startoff <= del->br_startoff);
4821 del_endoff = del->br_startoff + del->br_blockcount;
4822 got_endoff = got.br_startoff + got.br_blockcount;
4823 ASSERT(got_endoff >= del_endoff);
4824 delay = isnullstartblock(got.br_startblock);
4825 ASSERT(isnullstartblock(del->br_startblock) == delay);
4826 flags = 0;
4827 qfield = 0;
4828 error = 0;
2bd0ea18 4829 /*
49f693fa 4830 * If deleting a real allocation, must free up the disk space.
2bd0ea18 4831 */
49f693fa
DC
4832 if (!delay) {
4833 flags = XFS_ILOG_CORE;
a2ceac1f 4834 /*
49f693fa 4835 * Realtime allocation. Free it and record di_nblocks update.
a2ceac1f 4836 */
49f693fa
DC
4837 if (whichfork == XFS_DATA_FORK && XFS_IS_REALTIME_INODE(ip)) {
4838 xfs_fsblock_t bno;
4839 xfs_filblks_t len;
a2ceac1f 4840
49f693fa
DC
4841 ASSERT(do_mod(del->br_blockcount,
4842 mp->m_sb.sb_rextsize) == 0);
4843 ASSERT(do_mod(del->br_startblock,
4844 mp->m_sb.sb_rextsize) == 0);
4845 bno = del->br_startblock;
4846 len = del->br_blockcount;
4847 do_div(bno, mp->m_sb.sb_rextsize);
4848 do_div(len, mp->m_sb.sb_rextsize);
4849 error = xfs_rtfree_extent(tp, bno, (xfs_extlen_t)len);
4850 if (error)
4851 goto done;
4852 do_fx = 0;
4853 nblks = len * mp->m_sb.sb_rextsize;
4854 qfield = XFS_TRANS_DQ_RTBCOUNT;
2bd0ea18
NS
4855 }
4856 /*
49f693fa 4857 * Ordinary allocation.
2bd0ea18 4858 */
49f693fa
DC
4859 else {
4860 do_fx = 1;
4861 nblks = del->br_blockcount;
4862 qfield = XFS_TRANS_DQ_BCOUNT;
4863 }
2bd0ea18 4864 /*
49f693fa 4865 * Set up del_endblock and cur for later.
2bd0ea18 4866 */
49f693fa
DC
4867 del_endblock = del->br_startblock + del->br_blockcount;
4868 if (cur) {
4869 if ((error = xfs_bmbt_lookup_eq(cur, got.br_startoff,
4870 got.br_startblock, got.br_blockcount,
4871 &i)))
4872 goto done;
19ebedcf 4873 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2bd0ea18 4874 }
49f693fa
DC
4875 da_old = da_new = 0;
4876 } else {
4877 da_old = startblockval(got.br_startblock);
4878 da_new = 0;
4879 nblks = 0;
4880 do_fx = 0;
4881 }
4882 /*
4883 * Set flag value to use in switch statement.
4884 * Left-contig is 2, right-contig is 1.
4885 */
4886 switch (((got.br_startoff == del->br_startoff) << 1) |
4887 (got_endoff == del_endoff)) {
4888 case 3:
4889 /*
4890 * Matches the whole extent. Delete the entry.
4891 */
4892 xfs_iext_remove(ip, *idx, 1,
4893 whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0);
4894 --*idx;
4895 if (delay)
4896 break;
4897
4898 XFS_IFORK_NEXT_SET(ip, whichfork,
4899 XFS_IFORK_NEXTENTS(ip, whichfork) - 1);
4900 flags |= XFS_ILOG_CORE;
4901 if (!cur) {
4902 flags |= xfs_ilog_fext(whichfork);
4903 break;
2bd0ea18 4904 }
49f693fa
DC
4905 if ((error = xfs_btree_delete(cur, &i)))
4906 goto done;
19ebedcf 4907 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa 4908 break;
399ab595 4909
49f693fa 4910 case 2:
2bd0ea18 4911 /*
49f693fa 4912 * Deleting the first part of the extent.
2bd0ea18 4913 */
49f693fa
DC
4914 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
4915 xfs_bmbt_set_startoff(ep, del_endoff);
4916 temp = got.br_blockcount - del->br_blockcount;
4917 xfs_bmbt_set_blockcount(ep, temp);
4918 if (delay) {
4919 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
4920 da_old);
4921 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
4922 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
4923 da_new = temp;
4924 break;
2bd0ea18 4925 }
49f693fa
DC
4926 xfs_bmbt_set_startblock(ep, del_endblock);
4927 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
4928 if (!cur) {
4929 flags |= xfs_ilog_fext(whichfork);
4930 break;
4931 }
4932 if ((error = xfs_bmbt_update(cur, del_endoff, del_endblock,
4933 got.br_blockcount - del->br_blockcount,
4934 got.br_state)))
4935 goto done;
4936 break;
4937
4938 case 1:
2bd0ea18 4939 /*
49f693fa 4940 * Deleting the last part of the extent.
2bd0ea18 4941 */
49f693fa
DC
4942 temp = got.br_blockcount - del->br_blockcount;
4943 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
4944 xfs_bmbt_set_blockcount(ep, temp);
4945 if (delay) {
4946 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
4947 da_old);
4948 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
4949 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
4950 da_new = temp;
4951 break;
4952 }
4953 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
4954 if (!cur) {
4955 flags |= xfs_ilog_fext(whichfork);
4956 break;
4957 }
4958 if ((error = xfs_bmbt_update(cur, got.br_startoff,
4959 got.br_startblock,
4960 got.br_blockcount - del->br_blockcount,
4961 got.br_state)))
4962 goto done;
4963 break;
4964
4965 case 0:
4966 /*
4967 * Deleting the middle of the extent.
4968 */
4969 temp = del->br_startoff - got.br_startoff;
4970 trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
4971 xfs_bmbt_set_blockcount(ep, temp);
4972 new.br_startoff = del_endoff;
4973 temp2 = got_endoff - del_endoff;
4974 new.br_blockcount = temp2;
4975 new.br_state = got.br_state;
4976 if (!delay) {
4977 new.br_startblock = del_endblock;
4978 flags |= XFS_ILOG_CORE;
4979 if (cur) {
4980 if ((error = xfs_bmbt_update(cur,
4981 got.br_startoff,
4982 got.br_startblock, temp,
4983 got.br_state)))
4984 goto done;
4985 if ((error = xfs_btree_increment(cur, 0, &i)))
4986 goto done;
4987 cur->bc_rec.b = new;
4988 error = xfs_btree_insert(cur, &i);
12b53197 4989 if (error && error != -ENOSPC)
49f693fa
DC
4990 goto done;
4991 /*
4992 * If get no-space back from btree insert,
4993 * it tried a split, and we have a zero
4994 * block reservation.
4995 * Fix up our state and return the error.
4996 */
12b53197 4997 if (error == -ENOSPC) {
49f693fa
DC
4998 /*
4999 * Reset the cursor, don't trust
5000 * it after any insert operation.
5001 */
5002 if ((error = xfs_bmbt_lookup_eq(cur,
5003 got.br_startoff,
5004 got.br_startblock,
5005 temp, &i)))
5006 goto done;
19ebedcf
DC
5007 XFS_WANT_CORRUPTED_GOTO(mp,
5008 i == 1, done);
49f693fa
DC
5009 /*
5010 * Update the btree record back
5011 * to the original value.
5012 */
5013 if ((error = xfs_bmbt_update(cur,
5014 got.br_startoff,
5015 got.br_startblock,
5016 got.br_blockcount,
5017 got.br_state)))
5018 goto done;
5019 /*
5020 * Reset the extent record back
5021 * to the original value.
5022 */
5023 xfs_bmbt_set_blockcount(ep,
5024 got.br_blockcount);
5025 flags = 0;
12b53197 5026 error = -ENOSPC;
49f693fa
DC
5027 goto done;
5028 }
19ebedcf 5029 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
49f693fa
DC
5030 } else
5031 flags |= xfs_ilog_fext(whichfork);
5032 XFS_IFORK_NEXT_SET(ip, whichfork,
5033 XFS_IFORK_NEXTENTS(ip, whichfork) + 1);
5034 } else {
731ccdf9 5035 xfs_filblks_t stolen;
49f693fa 5036 ASSERT(whichfork == XFS_DATA_FORK);
01d1b786
BF
5037
5038 /*
5039 * Distribute the original indlen reservation across the
731ccdf9
BF
5040 * two new extents. Steal blocks from the deleted extent
5041 * if necessary. Stealing blocks simply fudges the
5042 * fdblocks accounting in xfs_bunmapi().
01d1b786
BF
5043 */
5044 temp = xfs_bmap_worst_indlen(ip, got.br_blockcount);
5045 temp2 = xfs_bmap_worst_indlen(ip, new.br_blockcount);
731ccdf9
BF
5046 stolen = xfs_bmap_split_indlen(da_old, &temp, &temp2,
5047 del->br_blockcount);
5048 da_new = temp + temp2 - stolen;
5049 del->br_blockcount -= stolen;
01d1b786
BF
5050
5051 /*
731ccdf9
BF
5052 * Set the reservation for each extent. Warn if either
5053 * is zero as this can lead to delalloc problems.
01d1b786 5054 */
731ccdf9 5055 WARN_ON_ONCE(!temp || !temp2);
49f693fa 5056 xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
49f693fa 5057 new.br_startblock = nullstartblock((int)temp2);
2bd0ea18 5058 }
49f693fa
DC
5059 trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
5060 xfs_iext_insert(ip, *idx + 1, 1, &new, state);
5061 ++*idx;
5062 break;
2bd0ea18
NS
5063 }
5064 /*
49f693fa 5065 * If we need to, add to list of extents to delete.
2bd0ea18 5066 */
49f693fa 5067 if (do_fx)
af2e7c6e
DW
5068 xfs_bmap_add_free(mp, flist, del->br_startblock,
5069 del->br_blockcount);
2bd0ea18 5070 /*
49f693fa 5071 * Adjust inode # blocks in the file.
2bd0ea18 5072 */
49f693fa
DC
5073 if (nblks)
5074 ip->i_d.di_nblocks -= nblks;
2bd0ea18 5075 /*
49f693fa 5076 * Adjust quota data.
2bd0ea18 5077 */
49f693fa
DC
5078 if (qfield)
5079 xfs_trans_mod_dquot_byino(tp, ip, qfield, (long)-nblks);
5080
2bd0ea18 5081 /*
49f693fa
DC
5082 * Account for change in delayed indirect blocks.
5083 * Nothing to do for disk quota accounting here.
2bd0ea18 5084 */
49f693fa 5085 ASSERT(da_old >= da_new);
19ebedcf
DC
5086 if (da_old > da_new)
5087 xfs_mod_fdblocks(mp, (int64_t)(da_old - da_new), false);
49f693fa
DC
5088done:
5089 *logflagsp = flags;
2bd0ea18
NS
5090 return error;
5091}
5092
5093/*
49f693fa
DC
5094 * Unmap (remove) blocks from a file.
5095 * If nexts is nonzero then the number of extents to remove is limited to
5096 * that value. If not all extents in the block range can be removed then
5097 * *done is set.
2bd0ea18 5098 */
49f693fa
DC
5099int /* error */
5100xfs_bunmapi(
5101 xfs_trans_t *tp, /* transaction pointer */
5102 struct xfs_inode *ip, /* incore inode */
5103 xfs_fileoff_t bno, /* starting offset to unmap */
5104 xfs_filblks_t len, /* length to unmap in file */
5105 int flags, /* misc flags */
5106 xfs_extnum_t nexts, /* number of extents max */
5107 xfs_fsblock_t *firstblock, /* first allocated block
5108 controls a.g. for allocs */
5109 xfs_bmap_free_t *flist, /* i/o: list extents to free */
5110 int *done) /* set if not done yet */
2bd0ea18 5111{
49f693fa
DC
5112 xfs_btree_cur_t *cur; /* bmap btree cursor */
5113 xfs_bmbt_irec_t del; /* extent being deleted */
5114 int eof; /* is deleting at eof */
5115 xfs_bmbt_rec_host_t *ep; /* extent record pointer */
5116 int error; /* error return value */
5117 xfs_extnum_t extno; /* extent number in list */
5118 xfs_bmbt_irec_t got; /* current extent record */
5119 xfs_ifork_t *ifp; /* inode fork pointer */
5120 int isrt; /* freeing in rt area */
5121 xfs_extnum_t lastx; /* last extent index used */
5122 int logflags; /* transaction logging flags */
5123 xfs_extlen_t mod; /* rt extent offset */
5124 xfs_mount_t *mp; /* mount structure */
5125 xfs_extnum_t nextents; /* number of file extents */
5126 xfs_bmbt_irec_t prev; /* previous extent record */
5127 xfs_fileoff_t start; /* first file offset deleted */
5128 int tmp_logflags; /* partial logging flags */
5129 int wasdel; /* was a delayed alloc extent */
5130 int whichfork; /* data or attribute fork */
5131 xfs_fsblock_t sum;
2bd0ea18 5132
49f693fa 5133 trace_xfs_bunmap(ip, bno, len, flags, _RET_IP_);
a2ceac1f 5134
49f693fa
DC
5135 whichfork = (flags & XFS_BMAPI_ATTRFORK) ?
5136 XFS_ATTR_FORK : XFS_DATA_FORK;
a2ceac1f 5137 ifp = XFS_IFORK_PTR(ip, whichfork);
49f693fa
DC
5138 if (unlikely(
5139 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
5140 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) {
5141 XFS_ERROR_REPORT("xfs_bunmapi", XFS_ERRLEVEL_LOW,
5142 ip->i_mount);
12b53197 5143 return -EFSCORRUPTED;
49f693fa
DC
5144 }
5145 mp = ip->i_mount;
5146 if (XFS_FORCED_SHUTDOWN(mp))
12b53197 5147 return -EIO;
56b2de80 5148
ff105f75 5149 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
49f693fa
DC
5150 ASSERT(len > 0);
5151 ASSERT(nexts >= 0);
56b2de80 5152
49f693fa
DC
5153 if (!(ifp->if_flags & XFS_IFEXTENTS) &&
5154 (error = xfs_iread_extents(tp, ip, whichfork)))
5155 return error;
5156 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
5157 if (nextents == 0) {
5158 *done = 1;
5159 return 0;
56b2de80 5160 }
79896434 5161 XFS_STATS_INC(mp, xs_blk_unmap);
49f693fa
DC
5162 isrt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip);
5163 start = bno;
5164 bno = start + len - 1;
5165 ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got,
5166 &prev);
a2ceac1f
DC
5167
5168 /*
49f693fa
DC
5169 * Check to see if the given block number is past the end of the
5170 * file, back up to the last block if so...
56b2de80 5171 */
49f693fa
DC
5172 if (eof) {
5173 ep = xfs_iext_get_ext(ifp, --lastx);
5174 xfs_bmbt_get_all(ep, &got);
5175 bno = got.br_startoff + got.br_blockcount - 1;
5176 }
5177 logflags = 0;
5178 if (ifp->if_flags & XFS_IFBROOT) {
5179 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE);
5180 cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
5181 cur->bc_private.b.firstblock = *firstblock;
5182 cur->bc_private.b.flist = flist;
5183 cur->bc_private.b.flags = 0;
5184 } else
5185 cur = NULL;
a2ceac1f 5186
49f693fa 5187 if (isrt) {
a2ceac1f 5188 /*
49f693fa 5189 * Synchronize by locking the bitmap inode.
a2ceac1f 5190 */
49f693fa
DC
5191 xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL);
5192 xfs_trans_ijoin(tp, mp->m_rbmip, XFS_ILOCK_EXCL);
5193 }
a2ceac1f 5194
49f693fa
DC
5195 extno = 0;
5196 while (bno != (xfs_fileoff_t)-1 && bno >= start && lastx >= 0 &&
5197 (nexts == 0 || extno < nexts)) {
a2ceac1f 5198 /*
49f693fa
DC
5199 * Is the found extent after a hole in which bno lives?
5200 * Just back up to the previous extent, if so.
a2ceac1f 5201 */
49f693fa
DC
5202 if (got.br_startoff > bno) {
5203 if (--lastx < 0)
5204 break;
5205 ep = xfs_iext_get_ext(ifp, lastx);
5206 xfs_bmbt_get_all(ep, &got);
a2ceac1f 5207 }
49f693fa
DC
5208 /*
5209 * Is the last block of this extent before the range
5210 * we're supposed to delete? If so, we're done.
5211 */
5212 bno = XFS_FILEOFF_MIN(bno,
5213 got.br_startoff + got.br_blockcount - 1);
5214 if (bno < start)
5215 break;
5216 /*
5217 * Then deal with the (possibly delayed) allocated space
5218 * we found.
5219 */
5220 ASSERT(ep != NULL);
5221 del = got;
5222 wasdel = isnullstartblock(del.br_startblock);
5223 if (got.br_startoff < start) {
5224 del.br_startoff = start;
5225 del.br_blockcount -= start - got.br_startoff;
5226 if (!wasdel)
5227 del.br_startblock += start - got.br_startoff;
5228 }
5229 if (del.br_startoff + del.br_blockcount > bno + 1)
5230 del.br_blockcount = bno + 1 - del.br_startoff;
5231 sum = del.br_startblock + del.br_blockcount;
5232 if (isrt &&
5233 (mod = do_mod(sum, mp->m_sb.sb_rextsize))) {
5234 /*
5235 * Realtime extent not lined up at the end.
5236 * The extent could have been split into written
5237 * and unwritten pieces, or we could just be
5238 * unmapping part of it. But we can't really
5239 * get rid of part of a realtime extent.
5240 */
5241 if (del.br_state == XFS_EXT_UNWRITTEN ||
5242 !xfs_sb_version_hasextflgbit(&mp->m_sb)) {
5243 /*
5244 * This piece is unwritten, or we're not
5245 * using unwritten extents. Skip over it.
5246 */
5247 ASSERT(bno >= mod);
5248 bno -= mod > del.br_blockcount ?
5249 del.br_blockcount : mod;
5250 if (bno < got.br_startoff) {
5251 if (--lastx >= 0)
5252 xfs_bmbt_get_all(xfs_iext_get_ext(
5253 ifp, lastx), &got);
5254 }
5255 continue;
5256 }
5257 /*
5258 * It's written, turn it unwritten.
5259 * This is better than zeroing it.
5260 */
5261 ASSERT(del.br_state == XFS_EXT_NORM);
0268fdc3 5262 ASSERT(tp->t_blk_res > 0);
49f693fa
DC
5263 /*
5264 * If this spans a realtime extent boundary,
5265 * chop it back to the start of the one we end at.
5266 */
5267 if (del.br_blockcount > mod) {
5268 del.br_startoff += del.br_blockcount - mod;
5269 del.br_startblock += del.br_blockcount - mod;
5270 del.br_blockcount = mod;
5271 }
5272 del.br_state = XFS_EXT_UNWRITTEN;
5273 error = xfs_bmap_add_extent_unwritten_real(tp, ip,
5274 &lastx, &cur, &del, firstblock, flist,
5275 &logflags);
5276 if (error)
5277 goto error0;
5278 goto nodelete;
a2ceac1f 5279 }
49f693fa
DC
5280 if (isrt && (mod = do_mod(del.br_startblock, mp->m_sb.sb_rextsize))) {
5281 /*
5282 * Realtime extent is lined up at the end but not
5283 * at the front. We'll get rid of full extents if
5284 * we can.
5285 */
5286 mod = mp->m_sb.sb_rextsize - mod;
5287 if (del.br_blockcount > mod) {
5288 del.br_blockcount -= mod;
5289 del.br_startoff += mod;
5290 del.br_startblock += mod;
5291 } else if ((del.br_startoff == start &&
5292 (del.br_state == XFS_EXT_UNWRITTEN ||
0268fdc3 5293 tp->t_blk_res == 0)) ||
49f693fa
DC
5294 !xfs_sb_version_hasextflgbit(&mp->m_sb)) {
5295 /*
5296 * Can't make it unwritten. There isn't
5297 * a full extent here so just skip it.
5298 */
5299 ASSERT(bno >= del.br_blockcount);
5300 bno -= del.br_blockcount;
5301 if (got.br_startoff > bno) {
5302 if (--lastx >= 0) {
5303 ep = xfs_iext_get_ext(ifp,
5304 lastx);
5305 xfs_bmbt_get_all(ep, &got);
5306 }
5307 }
5308 continue;
5309 } else if (del.br_state == XFS_EXT_UNWRITTEN) {
5310 /*
5311 * This one is already unwritten.
5312 * It must have a written left neighbor.
5313 * Unwrite the killed part of that one and
5314 * try again.
5315 */
5316 ASSERT(lastx > 0);
5317 xfs_bmbt_get_all(xfs_iext_get_ext(ifp,
5318 lastx - 1), &prev);
5319 ASSERT(prev.br_state == XFS_EXT_NORM);
5320 ASSERT(!isnullstartblock(prev.br_startblock));
5321 ASSERT(del.br_startblock ==
5322 prev.br_startblock + prev.br_blockcount);
5323 if (prev.br_startoff < start) {
5324 mod = start - prev.br_startoff;
5325 prev.br_blockcount -= mod;
5326 prev.br_startblock += mod;
5327 prev.br_startoff = start;
5328 }
5329 prev.br_state = XFS_EXT_UNWRITTEN;
5330 lastx--;
5331 error = xfs_bmap_add_extent_unwritten_real(tp,
5332 ip, &lastx, &cur, &prev,
5333 firstblock, flist, &logflags);
5334 if (error)
5335 goto error0;
5336 goto nodelete;
5337 } else {
5338 ASSERT(del.br_state == XFS_EXT_NORM);
5339 del.br_state = XFS_EXT_UNWRITTEN;
5340 error = xfs_bmap_add_extent_unwritten_real(tp,
5341 ip, &lastx, &cur, &del,
5342 firstblock, flist, &logflags);
5343 if (error)
5344 goto error0;
5345 goto nodelete;
5346 }
5347 }
a2ceac1f 5348
49f693fa
DC
5349 /*
5350 * If it's the case where the directory code is running
5351 * with no block reservation, and the deleted block is in
5352 * the middle of its extent, and the resulting insert
5353 * of an extent would cause transformation to btree format,
5354 * then reject it. The calling code will then swap
5355 * blocks around instead.
5356 * We have to do this now, rather than waiting for the
5357 * conversion to btree format, since the transaction
5358 * will be dirty.
5359 */
0268fdc3 5360 if (!wasdel && tp->t_blk_res == 0 &&
49f693fa
DC
5361 XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS &&
5362 XFS_IFORK_NEXTENTS(ip, whichfork) >= /* Note the >= */
5363 XFS_IFORK_MAXEXT(ip, whichfork) &&
5364 del.br_startoff > got.br_startoff &&
5365 del.br_startoff + del.br_blockcount <
5366 got.br_startoff + got.br_blockcount) {
12b53197 5367 error = -ENOSPC;
49f693fa 5368 goto error0;
a2ceac1f 5369 }
8359e0b9
BF
5370
5371 /*
5372 * Unreserve quota and update realtime free space, if
5373 * appropriate. If delayed allocation, update the inode delalloc
5374 * counter now and wait to update the sb counters as
5375 * xfs_bmap_del_extent() might need to borrow some blocks.
5376 */
5377 if (wasdel) {
5378 ASSERT(startblockval(del.br_startblock) > 0);
5379 if (isrt) {
5380 xfs_filblks_t rtexts;
5381
5382 rtexts = XFS_FSB_TO_B(mp, del.br_blockcount);
5383 do_div(rtexts, mp->m_sb.sb_rextsize);
5384 xfs_mod_frextents(mp, (int64_t)rtexts);
5385 (void)xfs_trans_reserve_quota_nblks(NULL,
5386 ip, -((long)del.br_blockcount), 0,
5387 XFS_QMOPT_RES_RTBLKS);
5388 } else {
5389 (void)xfs_trans_reserve_quota_nblks(NULL,
5390 ip, -((long)del.br_blockcount), 0,
5391 XFS_QMOPT_RES_REGBLKS);
5392 }
5393 ip->i_delayed_blks -= del.br_blockcount;
5394 if (cur)
5395 cur->bc_private.b.flags |=
5396 XFS_BTCUR_BPRV_WASDEL;
5397 } else if (cur)
5398 cur->bc_private.b.flags &= ~XFS_BTCUR_BPRV_WASDEL;
5399
49f693fa
DC
5400 error = xfs_bmap_del_extent(ip, tp, &lastx, flist, cur, &del,
5401 &tmp_logflags, whichfork);
5402 logflags |= tmp_logflags;
5403 if (error)
5404 goto error0;
8359e0b9
BF
5405
5406 if (!isrt && wasdel)
5407 xfs_mod_fdblocks(mp, (int64_t)del.br_blockcount, false);
5408
49f693fa
DC
5409 bno = del.br_startoff - 1;
5410nodelete:
a2ceac1f 5411 /*
49f693fa 5412 * If not done go on to the next (previous) record.
a2ceac1f 5413 */
49f693fa
DC
5414 if (bno != (xfs_fileoff_t)-1 && bno >= start) {
5415 if (lastx >= 0) {
5416 ep = xfs_iext_get_ext(ifp, lastx);
5417 if (xfs_bmbt_get_startoff(ep) > bno) {
5418 if (--lastx >= 0)
5419 ep = xfs_iext_get_ext(ifp,
5420 lastx);
5421 }
5422 xfs_bmbt_get_all(ep, &got);
5423 }
5424 extno++;
a2ceac1f 5425 }
a2ceac1f 5426 }
49f693fa 5427 *done = bno == (xfs_fileoff_t)-1 || bno < start || lastx < 0;
56b2de80 5428
49f693fa
DC
5429 /*
5430 * Convert to a btree if necessary.
5431 */
5432 if (xfs_bmap_needs_btree(ip, whichfork)) {
5433 ASSERT(cur == NULL);
5434 error = xfs_bmap_extents_to_btree(tp, ip, firstblock, flist,
5435 &cur, 0, &tmp_logflags, whichfork);
5436 logflags |= tmp_logflags;
5437 if (error)
5438 goto error0;
56b2de80 5439 }
56b2de80 5440 /*
49f693fa 5441 * transform from btree to extents, give it cur
56b2de80 5442 */
49f693fa
DC
5443 else if (xfs_bmap_wants_extents(ip, whichfork)) {
5444 ASSERT(cur != NULL);
5445 error = xfs_bmap_btree_to_extents(tp, ip, cur, &tmp_logflags,
5446 whichfork);
5447 logflags |= tmp_logflags;
5448 if (error)
5449 goto error0;
56b2de80 5450 }
49f693fa
DC
5451 /*
5452 * transform from extents to local?
5453 */
5454 error = 0;
5455error0:
5456 /*
5457 * Log everything. Do this after conversion, there's no point in
5458 * logging the extent records if we've converted to btree format.
5459 */
5460 if ((logflags & xfs_ilog_fext(whichfork)) &&
5461 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)
5462 logflags &= ~xfs_ilog_fext(whichfork);
5463 else if ((logflags & xfs_ilog_fbroot(whichfork)) &&
5464 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)
5465 logflags &= ~xfs_ilog_fbroot(whichfork);
5466 /*
5467 * Log inode even in the error case, if the transaction
5468 * is dirty we'll need to shut down the filesystem.
5469 */
5470 if (logflags)
5471 xfs_trans_log_inode(tp, ip, logflags);
5472 if (cur) {
5473 if (!error) {
5474 *firstblock = cur->bc_private.b.firstblock;
5475 cur->bc_private.b.allocated = 0;
56b2de80 5476 }
49f693fa
DC
5477 xfs_btree_del_cursor(cur,
5478 error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR);
56b2de80 5479 }
49f693fa 5480 return error;
a2ceac1f 5481}
ff105f75 5482
5a35bf2c
DC
5483/*
5484 * Determine whether an extent shift can be accomplished by a merge with the
5485 * extent that precedes the target hole of the shift.
5486 */
5487STATIC bool
5488xfs_bmse_can_merge(
5489 struct xfs_bmbt_irec *left, /* preceding extent */
5490 struct xfs_bmbt_irec *got, /* current extent to shift */
5491 xfs_fileoff_t shift) /* shift fsb */
5492{
5493 xfs_fileoff_t startoff;
5494
5495 startoff = got->br_startoff - shift;
5496
5497 /*
5498 * The extent, once shifted, must be adjacent in-file and on-disk with
5499 * the preceding extent.
5500 */
5501 if ((left->br_startoff + left->br_blockcount != startoff) ||
5502 (left->br_startblock + left->br_blockcount != got->br_startblock) ||
5503 (left->br_state != got->br_state) ||
5504 (left->br_blockcount + got->br_blockcount > MAXEXTLEN))
5505 return false;
5506
5507 return true;
5508}
5509
5510/*
5511 * A bmap extent shift adjusts the file offset of an extent to fill a preceding
5512 * hole in the file. If an extent shift would result in the extent being fully
5513 * adjacent to the extent that currently precedes the hole, we can merge with
5514 * the preceding extent rather than do the shift.
5515 *
5516 * This function assumes the caller has verified a shift-by-merge is possible
5517 * with the provided extents via xfs_bmse_can_merge().
5518 */
5519STATIC int
5520xfs_bmse_merge(
5521 struct xfs_inode *ip,
5522 int whichfork,
5523 xfs_fileoff_t shift, /* shift fsb */
5524 int current_ext, /* idx of gotp */
5525 struct xfs_bmbt_rec_host *gotp, /* extent to shift */
5526 struct xfs_bmbt_rec_host *leftp, /* preceding extent */
5527 struct xfs_btree_cur *cur,
5528 int *logflags) /* output */
5529{
5530 struct xfs_bmbt_irec got;
5531 struct xfs_bmbt_irec left;
5532 xfs_filblks_t blockcount;
5533 int error, i;
19ebedcf 5534 struct xfs_mount *mp = ip->i_mount;
5a35bf2c
DC
5535
5536 xfs_bmbt_get_all(gotp, &got);
5537 xfs_bmbt_get_all(leftp, &left);
5538 blockcount = left.br_blockcount + got.br_blockcount;
5539
5540 ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL));
5541 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
5542 ASSERT(xfs_bmse_can_merge(&left, &got, shift));
5543
5544 /*
5545 * Merge the in-core extents. Note that the host record pointers and
5546 * current_ext index are invalid once the extent has been removed via
5547 * xfs_iext_remove().
5548 */
5549 xfs_bmbt_set_blockcount(leftp, blockcount);
5550 xfs_iext_remove(ip, current_ext, 1, 0);
5551
5552 /*
5553 * Update the on-disk extent count, the btree if necessary and log the
5554 * inode.
5555 */
5556 XFS_IFORK_NEXT_SET(ip, whichfork,
5557 XFS_IFORK_NEXTENTS(ip, whichfork) - 1);
5558 *logflags |= XFS_ILOG_CORE;
5559 if (!cur) {
5560 *logflags |= XFS_ILOG_DEXT;
5561 return 0;
5562 }
5563
5564 /* lookup and remove the extent to merge */
5565 error = xfs_bmbt_lookup_eq(cur, got.br_startoff, got.br_startblock,
5566 got.br_blockcount, &i);
5567 if (error)
5568 return error;
19ebedcf 5569 XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
5a35bf2c
DC
5570
5571 error = xfs_btree_delete(cur, &i);
5572 if (error)
5573 return error;
19ebedcf 5574 XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
5a35bf2c
DC
5575
5576 /* lookup and update size of the previous extent */
5577 error = xfs_bmbt_lookup_eq(cur, left.br_startoff, left.br_startblock,
5578 left.br_blockcount, &i);
5579 if (error)
5580 return error;
19ebedcf 5581 XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
5a35bf2c
DC
5582
5583 left.br_blockcount = blockcount;
5584
5585 return xfs_bmbt_update(cur, left.br_startoff, left.br_startblock,
5586 left.br_blockcount, left.br_state);
5587}
5588
5589/*
5590 * Shift a single extent.
5591 */
5592STATIC int
5593xfs_bmse_shift_one(
5594 struct xfs_inode *ip,
5595 int whichfork,
5596 xfs_fileoff_t offset_shift_fsb,
5597 int *current_ext,
5598 struct xfs_bmbt_rec_host *gotp,
5599 struct xfs_btree_cur *cur,
19ebedcf
DC
5600 int *logflags,
5601 enum shift_direction direction)
5a35bf2c
DC
5602{
5603 struct xfs_ifork *ifp;
19ebedcf 5604 struct xfs_mount *mp;
5a35bf2c 5605 xfs_fileoff_t startoff;
19ebedcf 5606 struct xfs_bmbt_rec_host *adj_irecp;
5a35bf2c 5607 struct xfs_bmbt_irec got;
19ebedcf 5608 struct xfs_bmbt_irec adj_irec;
5a35bf2c
DC
5609 int error;
5610 int i;
19ebedcf 5611 int total_extents;
5a35bf2c 5612
19ebedcf 5613 mp = ip->i_mount;
5a35bf2c 5614 ifp = XFS_IFORK_PTR(ip, whichfork);
19ebedcf 5615 total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t);
5a35bf2c
DC
5616
5617 xfs_bmbt_get_all(gotp, &got);
5a35bf2c
DC
5618
5619 /* delalloc extents should be prevented by caller */
19ebedcf 5620 XFS_WANT_CORRUPTED_RETURN(mp, !isnullstartblock(got.br_startblock));
5a35bf2c 5621
19ebedcf
DC
5622 if (direction == SHIFT_LEFT) {
5623 startoff = got.br_startoff - offset_shift_fsb;
5624
5625 /*
5626 * Check for merge if we've got an extent to the left,
5627 * otherwise make sure there's enough room at the start
5628 * of the file for the shift.
5629 */
5630 if (!*current_ext) {
5631 if (got.br_startoff < offset_shift_fsb)
5632 return -EINVAL;
5633 goto update_current_ext;
5634 }
5635 /*
5636 * grab the left extent and check for a large
5637 * enough hole.
5638 */
5639 adj_irecp = xfs_iext_get_ext(ifp, *current_ext - 1);
5640 xfs_bmbt_get_all(adj_irecp, &adj_irec);
5a35bf2c 5641
19ebedcf
DC
5642 if (startoff <
5643 adj_irec.br_startoff + adj_irec.br_blockcount)
5a35bf2c
DC
5644 return -EINVAL;
5645
5646 /* check whether to merge the extent or shift it down */
19ebedcf
DC
5647 if (xfs_bmse_can_merge(&adj_irec, &got,
5648 offset_shift_fsb)) {
5a35bf2c 5649 return xfs_bmse_merge(ip, whichfork, offset_shift_fsb,
19ebedcf
DC
5650 *current_ext, gotp, adj_irecp,
5651 cur, logflags);
5a35bf2c 5652 }
19ebedcf
DC
5653 } else {
5654 startoff = got.br_startoff + offset_shift_fsb;
5655 /* nothing to move if this is the last extent */
5656 if (*current_ext >= (total_extents - 1))
5657 goto update_current_ext;
5658 /*
5659 * If this is not the last extent in the file, make sure there
5660 * is enough room between current extent and next extent for
5661 * accommodating the shift.
5662 */
5663 adj_irecp = xfs_iext_get_ext(ifp, *current_ext + 1);
5664 xfs_bmbt_get_all(adj_irecp, &adj_irec);
5665 if (startoff + got.br_blockcount > adj_irec.br_startoff)
5666 return -EINVAL;
5667 /*
5668 * Unlike a left shift (which involves a hole punch),
5669 * a right shift does not modify extent neighbors
5670 * in any way. We should never find mergeable extents
5671 * in this scenario. Check anyways and warn if we
5672 * encounter two extents that could be one.
5673 */
5674 if (xfs_bmse_can_merge(&got, &adj_irec, offset_shift_fsb))
5675 WARN_ON_ONCE(1);
5676 }
5a35bf2c
DC
5677 /*
5678 * Increment the extent index for the next iteration, update the start
5679 * offset of the in-core extent and update the btree if applicable.
5680 */
19ebedcf
DC
5681update_current_ext:
5682 if (direction == SHIFT_LEFT)
5683 (*current_ext)++;
5684 else
5685 (*current_ext)--;
5a35bf2c
DC
5686 xfs_bmbt_set_startoff(gotp, startoff);
5687 *logflags |= XFS_ILOG_CORE;
5688 if (!cur) {
5689 *logflags |= XFS_ILOG_DEXT;
5690 return 0;
5691 }
5692
5693 error = xfs_bmbt_lookup_eq(cur, got.br_startoff, got.br_startblock,
5694 got.br_blockcount, &i);
5695 if (error)
5696 return error;
19ebedcf 5697 XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
5a35bf2c
DC
5698
5699 got.br_startoff = startoff;
5700 return xfs_bmbt_update(cur, got.br_startoff, got.br_startblock,
19ebedcf 5701 got.br_blockcount, got.br_state);
5a35bf2c
DC
5702}
5703
ff105f75 5704/*
19ebedcf 5705 * Shift extent records to the left/right to cover/create a hole.
ff105f75 5706 *
5a35bf2c 5707 * The maximum number of extents to be shifted in a single operation is
19ebedcf 5708 * @num_exts. @stop_fsb specifies the file offset at which to stop shift and the
5a35bf2c
DC
5709 * file offset where we've left off is returned in @next_fsb. @offset_shift_fsb
5710 * is the length by which each extent is shifted. If there is no hole to shift
5711 * the extents into, this will be considered invalid operation and we abort
5712 * immediately.
ff105f75
DC
5713 */
5714int
5715xfs_bmap_shift_extents(
5716 struct xfs_trans *tp,
5717 struct xfs_inode *ip,
19ebedcf 5718 xfs_fileoff_t *next_fsb,
ff105f75 5719 xfs_fileoff_t offset_shift_fsb,
5a35bf2c 5720 int *done,
19ebedcf 5721 xfs_fileoff_t stop_fsb,
ff105f75
DC
5722 xfs_fsblock_t *firstblock,
5723 struct xfs_bmap_free *flist,
19ebedcf 5724 enum shift_direction direction,
ff105f75
DC
5725 int num_exts)
5726{
5a35bf2c 5727 struct xfs_btree_cur *cur = NULL;
ff105f75
DC
5728 struct xfs_bmbt_rec_host *gotp;
5729 struct xfs_bmbt_irec got;
ff105f75
DC
5730 struct xfs_mount *mp = ip->i_mount;
5731 struct xfs_ifork *ifp;
5732 xfs_extnum_t nexts = 0;
5a35bf2c 5733 xfs_extnum_t current_ext;
19ebedcf
DC
5734 xfs_extnum_t total_extents;
5735 xfs_extnum_t stop_extent;
ff105f75 5736 int error = 0;
ff105f75 5737 int whichfork = XFS_DATA_FORK;
5a35bf2c 5738 int logflags = 0;
ff105f75
DC
5739
5740 if (unlikely(XFS_TEST_ERROR(
5741 (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
5742 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE),
5743 mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) {
5744 XFS_ERROR_REPORT("xfs_bmap_shift_extents",
5745 XFS_ERRLEVEL_LOW, mp);
12b53197 5746 return -EFSCORRUPTED;
ff105f75
DC
5747 }
5748
5749 if (XFS_FORCED_SHUTDOWN(mp))
12b53197 5750 return -EIO;
ff105f75 5751
5a35bf2c
DC
5752 ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL));
5753 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
19ebedcf
DC
5754 ASSERT(direction == SHIFT_LEFT || direction == SHIFT_RIGHT);
5755 ASSERT(*next_fsb != NULLFSBLOCK || direction == SHIFT_RIGHT);
ff105f75
DC
5756
5757 ifp = XFS_IFORK_PTR(ip, whichfork);
5758 if (!(ifp->if_flags & XFS_IFEXTENTS)) {
5759 /* Read in all the extents */
5760 error = xfs_iread_extents(tp, ip, whichfork);
5761 if (error)
5762 return error;
5763 }
5764
ff105f75
DC
5765 if (ifp->if_flags & XFS_IFBROOT) {
5766 cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
5767 cur->bc_private.b.firstblock = *firstblock;
5768 cur->bc_private.b.flist = flist;
5769 cur->bc_private.b.flags = 0;
5a35bf2c
DC
5770 }
5771
19ebedcf
DC
5772 /*
5773 * There may be delalloc extents in the data fork before the range we
5774 * are collapsing out, so we cannot use the count of real extents here.
5775 * Instead we have to calculate it from the incore fork.
5776 */
5777 total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t);
5778 if (total_extents == 0) {
5779 *done = 1;
5780 goto del_cursor;
5781 }
5782
5783 /*
5784 * In case of first right shift, we need to initialize next_fsb
5785 */
5786 if (*next_fsb == NULLFSBLOCK) {
5787 gotp = xfs_iext_get_ext(ifp, total_extents - 1);
5788 xfs_bmbt_get_all(gotp, &got);
5789 *next_fsb = got.br_startoff;
5790 if (stop_fsb > *next_fsb) {
5791 *done = 1;
5792 goto del_cursor;
5793 }
5794 }
5795
5796 /* Lookup the extent index at which we have to stop */
5797 if (direction == SHIFT_RIGHT) {
5798 gotp = xfs_iext_bno_to_ext(ifp, stop_fsb, &stop_extent);
5799 /* Make stop_extent exclusive of shift range */
5800 stop_extent--;
5801 } else
5802 stop_extent = total_extents;
5803
5a35bf2c
DC
5804 /*
5805 * Look up the extent index for the fsb where we start shifting. We can
5806 * henceforth iterate with current_ext as extent list changes are locked
5807 * out via ilock.
5808 *
5809 * gotp can be null in 2 cases: 1) if there are no extents or 2)
19ebedcf 5810 * *next_fsb lies in a hole beyond which there are no extents. Either
5a35bf2c
DC
5811 * way, we are done.
5812 */
19ebedcf 5813 gotp = xfs_iext_bno_to_ext(ifp, *next_fsb, &current_ext);
5a35bf2c
DC
5814 if (!gotp) {
5815 *done = 1;
5816 goto del_cursor;
ff105f75
DC
5817 }
5818
19ebedcf
DC
5819 /* some sanity checking before we finally start shifting extents */
5820 if ((direction == SHIFT_LEFT && current_ext >= stop_extent) ||
5821 (direction == SHIFT_RIGHT && current_ext <= stop_extent)) {
5822 error = -EIO;
5823 goto del_cursor;
5824 }
5825
5826 while (nexts++ < num_exts) {
5a35bf2c 5827 error = xfs_bmse_shift_one(ip, whichfork, offset_shift_fsb,
19ebedcf
DC
5828 &current_ext, gotp, cur, &logflags,
5829 direction);
ff105f75
DC
5830 if (error)
5831 goto del_cursor;
19ebedcf
DC
5832 /*
5833 * If there was an extent merge during the shift, the extent
5834 * count can change. Update the total and grade the next record.
5835 */
5836 if (direction == SHIFT_LEFT) {
5837 total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t);
5838 stop_extent = total_extents;
5839 }
ff105f75 5840
19ebedcf
DC
5841 if (current_ext == stop_extent) {
5842 *done = 1;
5843 *next_fsb = NULLFSBLOCK;
5a35bf2c 5844 break;
19ebedcf 5845 }
5a35bf2c 5846 gotp = xfs_iext_get_ext(ifp, current_ext);
ff105f75
DC
5847 }
5848
19ebedcf 5849 if (!*done) {
5a35bf2c
DC
5850 xfs_bmbt_get_all(gotp, &got);
5851 *next_fsb = got.br_startoff;
5852 }
ff105f75
DC
5853
5854del_cursor:
5855 if (cur)
5856 xfs_btree_del_cursor(cur,
5857 error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR);
5858
5a35bf2c
DC
5859 if (logflags)
5860 xfs_trans_log_inode(tp, ip, logflags);
5861
ff105f75
DC
5862 return error;
5863}
19ebedcf
DC
5864
5865/*
5866 * Splits an extent into two extents at split_fsb block such that it is
5867 * the first block of the current_ext. @current_ext is a target extent
5868 * to be split. @split_fsb is a block where the extents is split.
5869 * If split_fsb lies in a hole or the first block of extents, just return 0.
5870 */
5871STATIC int
5872xfs_bmap_split_extent_at(
5873 struct xfs_trans *tp,
5874 struct xfs_inode *ip,
5875 xfs_fileoff_t split_fsb,
5876 xfs_fsblock_t *firstfsb,
5877 struct xfs_bmap_free *free_list)
5878{
5879 int whichfork = XFS_DATA_FORK;
5880 struct xfs_btree_cur *cur = NULL;
5881 struct xfs_bmbt_rec_host *gotp;
5882 struct xfs_bmbt_irec got;
5883 struct xfs_bmbt_irec new; /* split extent */
5884 struct xfs_mount *mp = ip->i_mount;
5885 struct xfs_ifork *ifp;
5886 xfs_fsblock_t gotblkcnt; /* new block count for got */
5887 xfs_extnum_t current_ext;
5888 int error = 0;
5889 int logflags = 0;
5890 int i = 0;
5891
5892 if (unlikely(XFS_TEST_ERROR(
5893 (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
5894 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE),
5895 mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) {
5896 XFS_ERROR_REPORT("xfs_bmap_split_extent_at",
5897 XFS_ERRLEVEL_LOW, mp);
5898 return -EFSCORRUPTED;
5899 }
5900
5901 if (XFS_FORCED_SHUTDOWN(mp))
5902 return -EIO;
5903
5904 ifp = XFS_IFORK_PTR(ip, whichfork);
5905 if (!(ifp->if_flags & XFS_IFEXTENTS)) {
5906 /* Read in all the extents */
5907 error = xfs_iread_extents(tp, ip, whichfork);
5908 if (error)
5909 return error;
5910 }
5911
5912 /*
5913 * gotp can be null in 2 cases: 1) if there are no extents
5914 * or 2) split_fsb lies in a hole beyond which there are
5915 * no extents. Either way, we are done.
5916 */
5917 gotp = xfs_iext_bno_to_ext(ifp, split_fsb, &current_ext);
5918 if (!gotp)
5919 return 0;
5920
5921 xfs_bmbt_get_all(gotp, &got);
5922
5923 /*
5924 * Check split_fsb lies in a hole or the start boundary offset
5925 * of the extent.
5926 */
5927 if (got.br_startoff >= split_fsb)
5928 return 0;
5929
5930 gotblkcnt = split_fsb - got.br_startoff;
5931 new.br_startoff = split_fsb;
5932 new.br_startblock = got.br_startblock + gotblkcnt;
5933 new.br_blockcount = got.br_blockcount - gotblkcnt;
5934 new.br_state = got.br_state;
5935
5936 if (ifp->if_flags & XFS_IFBROOT) {
5937 cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
5938 cur->bc_private.b.firstblock = *firstfsb;
5939 cur->bc_private.b.flist = free_list;
5940 cur->bc_private.b.flags = 0;
5941 error = xfs_bmbt_lookup_eq(cur, got.br_startoff,
5942 got.br_startblock,
5943 got.br_blockcount,
5944 &i);
5945 if (error)
5946 goto del_cursor;
5947 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, del_cursor);
5948 }
5949
5950 xfs_bmbt_set_blockcount(gotp, gotblkcnt);
5951 got.br_blockcount = gotblkcnt;
5952
5953 logflags = XFS_ILOG_CORE;
5954 if (cur) {
5955 error = xfs_bmbt_update(cur, got.br_startoff,
5956 got.br_startblock,
5957 got.br_blockcount,
5958 got.br_state);
5959 if (error)
5960 goto del_cursor;
5961 } else
5962 logflags |= XFS_ILOG_DEXT;
5963
5964 /* Add new extent */
5965 current_ext++;
5966 xfs_iext_insert(ip, current_ext, 1, &new, 0);
5967 XFS_IFORK_NEXT_SET(ip, whichfork,
5968 XFS_IFORK_NEXTENTS(ip, whichfork) + 1);
5969
5970 if (cur) {
5971 error = xfs_bmbt_lookup_eq(cur, new.br_startoff,
5972 new.br_startblock, new.br_blockcount,
5973 &i);
5974 if (error)
5975 goto del_cursor;
5976 XFS_WANT_CORRUPTED_GOTO(mp, i == 0, del_cursor);
5977 cur->bc_rec.b.br_state = new.br_state;
5978
5979 error = xfs_btree_insert(cur, &i);
5980 if (error)
5981 goto del_cursor;
5982 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, del_cursor);
5983 }
5984
5985 /*
5986 * Convert to a btree if necessary.
5987 */
5988 if (xfs_bmap_needs_btree(ip, whichfork)) {
5989 int tmp_logflags; /* partial log flag return val */
5990
5991 ASSERT(cur == NULL);
5992 error = xfs_bmap_extents_to_btree(tp, ip, firstfsb, free_list,
5993 &cur, 0, &tmp_logflags, whichfork);
5994 logflags |= tmp_logflags;
5995 }
5996
5997del_cursor:
5998 if (cur) {
5999 cur->bc_private.b.allocated = 0;
6000 xfs_btree_del_cursor(cur,
6001 error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR);
6002 }
6003
6004 if (logflags)
6005 xfs_trans_log_inode(tp, ip, logflags);
6006 return error;
6007}
6008
6009int
6010xfs_bmap_split_extent(
6011 struct xfs_inode *ip,
6012 xfs_fileoff_t split_fsb)
6013{
6014 struct xfs_mount *mp = ip->i_mount;
6015 struct xfs_trans *tp;
6016 struct xfs_bmap_free free_list;
6017 xfs_fsblock_t firstfsb;
19ebedcf
DC
6018 int error;
6019
9074815c
CH
6020 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write,
6021 XFS_DIOSTRAT_SPACE_RES(mp, 0), 0, 0, &tp);
6022 if (error)
19ebedcf 6023 return error;
19ebedcf
DC
6024
6025 xfs_ilock(ip, XFS_ILOCK_EXCL);
6026 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
6027
6028 xfs_bmap_init(&free_list, &firstfsb);
6029
6030 error = xfs_bmap_split_extent_at(tp, ip, split_fsb,
6031 &firstfsb, &free_list);
6032 if (error)
6033 goto out;
6034
0b66d459 6035 error = xfs_bmap_finish(&tp, &free_list, NULL);
19ebedcf
DC
6036 if (error)
6037 goto out;
6038
de5a3f46 6039 return xfs_trans_commit(tp);
19ebedcf
DC
6040
6041out:
5769a376 6042 xfs_bmap_cancel(&free_list);
3d7434fe 6043 xfs_trans_cancel(tp);
19ebedcf
DC
6044 return error;
6045}