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