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