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