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