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