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