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