linux/fs/xfs/libxfs/xfs_dir2_data.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
   3 * Copyright (c) 2013 Red Hat, Inc.
   4 * All Rights Reserved.
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License as
   8 * published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope that it would be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 *
  15 * You should have received a copy of the GNU General Public License
  16 * along with this program; if not, write the Free Software Foundation,
  17 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  18 */
  19#include "xfs.h"
  20#include "xfs_fs.h"
  21#include "xfs_format.h"
  22#include "xfs_log_format.h"
  23#include "xfs_trans_resv.h"
  24#include "xfs_mount.h"
  25#include "xfs_da_format.h"
  26#include "xfs_da_btree.h"
  27#include "xfs_inode.h"
  28#include "xfs_dir2.h"
  29#include "xfs_dir2_priv.h"
  30#include "xfs_error.h"
  31#include "xfs_trans.h"
  32#include "xfs_buf_item.h"
  33#include "xfs_cksum.h"
  34#include "xfs_log.h"
  35
  36/*
  37 * Check the consistency of the data block.
  38 * The input can also be a block-format directory.
  39 * Return 0 is the buffer is good, otherwise an error.
  40 */
  41int
  42__xfs_dir3_data_check(
  43        struct xfs_inode        *dp,            /* incore inode pointer */
  44        struct xfs_buf          *bp)            /* data block's buffer */
  45{
  46        xfs_dir2_dataptr_t      addr;           /* addr for leaf lookup */
  47        xfs_dir2_data_free_t    *bf;            /* bestfree table */
  48        xfs_dir2_block_tail_t   *btp=NULL;      /* block tail */
  49        int                     count;          /* count of entries found */
  50        xfs_dir2_data_hdr_t     *hdr;           /* data block header */
  51        xfs_dir2_data_entry_t   *dep;           /* data entry */
  52        xfs_dir2_data_free_t    *dfp;           /* bestfree entry */
  53        xfs_dir2_data_unused_t  *dup;           /* unused entry */
  54        char                    *endp;          /* end of useful data */
  55        int                     freeseen;       /* mask of bestfrees seen */
  56        xfs_dahash_t            hash;           /* hash of current name */
  57        int                     i;              /* leaf index */
  58        int                     lastfree;       /* last entry was unused */
  59        xfs_dir2_leaf_entry_t   *lep=NULL;      /* block leaf entries */
  60        xfs_mount_t             *mp;            /* filesystem mount point */
  61        char                    *p;             /* current data position */
  62        int                     stale;          /* count of stale leaves */
  63        struct xfs_name         name;
  64        const struct xfs_dir_ops *ops;
  65        struct xfs_da_geometry  *geo;
  66
  67        mp = bp->b_target->bt_mount;
  68        geo = mp->m_dir_geo;
  69
  70        /*
  71         * We can be passed a null dp here from a verifier, so we need to go the
  72         * hard way to get them.
  73         */
  74        ops = xfs_dir_get_ops(mp, dp);
  75
  76        hdr = bp->b_addr;
  77        p = (char *)ops->data_entry_p(hdr);
  78
  79        switch (hdr->magic) {
  80        case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC):
  81        case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC):
  82                btp = xfs_dir2_block_tail_p(geo, hdr);
  83                lep = xfs_dir2_block_leaf_p(btp);
  84                endp = (char *)lep;
  85
  86                /*
  87                 * The number of leaf entries is limited by the size of the
  88                 * block and the amount of space used by the data entries.
  89                 * We don't know how much space is used by the data entries yet,
  90                 * so just ensure that the count falls somewhere inside the
  91                 * block right now.
  92                 */
  93                XFS_WANT_CORRUPTED_RETURN(mp, be32_to_cpu(btp->count) <
  94                        ((char *)btp - p) / sizeof(struct xfs_dir2_leaf_entry));
  95                break;
  96        case cpu_to_be32(XFS_DIR3_DATA_MAGIC):
  97        case cpu_to_be32(XFS_DIR2_DATA_MAGIC):
  98                endp = (char *)hdr + geo->blksize;
  99                break;
 100        default:
 101                XFS_ERROR_REPORT("Bad Magic", XFS_ERRLEVEL_LOW, mp);
 102                return -EFSCORRUPTED;
 103        }
 104
 105        /*
 106         * Account for zero bestfree entries.
 107         */
 108        bf = ops->data_bestfree_p(hdr);
 109        count = lastfree = freeseen = 0;
 110        if (!bf[0].length) {
 111                XFS_WANT_CORRUPTED_RETURN(mp, !bf[0].offset);
 112                freeseen |= 1 << 0;
 113        }
 114        if (!bf[1].length) {
 115                XFS_WANT_CORRUPTED_RETURN(mp, !bf[1].offset);
 116                freeseen |= 1 << 1;
 117        }
 118        if (!bf[2].length) {
 119                XFS_WANT_CORRUPTED_RETURN(mp, !bf[2].offset);
 120                freeseen |= 1 << 2;
 121        }
 122
 123        XFS_WANT_CORRUPTED_RETURN(mp, be16_to_cpu(bf[0].length) >=
 124                                                be16_to_cpu(bf[1].length));
 125        XFS_WANT_CORRUPTED_RETURN(mp, be16_to_cpu(bf[1].length) >=
 126                                                be16_to_cpu(bf[2].length));
 127        /*
 128         * Loop over the data/unused entries.
 129         */
 130        while (p < endp) {
 131                dup = (xfs_dir2_data_unused_t *)p;
 132                /*
 133                 * If it's unused, look for the space in the bestfree table.
 134                 * If we find it, account for that, else make sure it
 135                 * doesn't need to be there.
 136                 */
 137                if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
 138                        XFS_WANT_CORRUPTED_RETURN(mp, lastfree == 0);
 139                        XFS_WANT_CORRUPTED_RETURN(mp, endp >=
 140                                        p + be16_to_cpu(dup->length));
 141                        XFS_WANT_CORRUPTED_RETURN(mp,
 142                                be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) ==
 143                                               (char *)dup - (char *)hdr);
 144                        dfp = xfs_dir2_data_freefind(hdr, bf, dup);
 145                        if (dfp) {
 146                                i = (int)(dfp - bf);
 147                                XFS_WANT_CORRUPTED_RETURN(mp,
 148                                        (freeseen & (1 << i)) == 0);
 149                                freeseen |= 1 << i;
 150                        } else {
 151                                XFS_WANT_CORRUPTED_RETURN(mp,
 152                                        be16_to_cpu(dup->length) <=
 153                                                be16_to_cpu(bf[2].length));
 154                        }
 155                        p += be16_to_cpu(dup->length);
 156                        lastfree = 1;
 157                        continue;
 158                }
 159                /*
 160                 * It's a real entry.  Validate the fields.
 161                 * If this is a block directory then make sure it's
 162                 * in the leaf section of the block.
 163                 * The linear search is crude but this is DEBUG code.
 164                 */
 165                dep = (xfs_dir2_data_entry_t *)p;
 166                XFS_WANT_CORRUPTED_RETURN(mp, dep->namelen != 0);
 167                XFS_WANT_CORRUPTED_RETURN(mp,
 168                        !xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber)));
 169                XFS_WANT_CORRUPTED_RETURN(mp, endp >=
 170                                p + ops->data_entsize(dep->namelen));
 171                XFS_WANT_CORRUPTED_RETURN(mp,
 172                        be16_to_cpu(*ops->data_entry_tag_p(dep)) ==
 173                                               (char *)dep - (char *)hdr);
 174                XFS_WANT_CORRUPTED_RETURN(mp,
 175                                ops->data_get_ftype(dep) < XFS_DIR3_FT_MAX);
 176                count++;
 177                lastfree = 0;
 178                if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
 179                    hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) {
 180                        addr = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
 181                                                (xfs_dir2_data_aoff_t)
 182                                                ((char *)dep - (char *)hdr));
 183                        name.name = dep->name;
 184                        name.len = dep->namelen;
 185                        hash = mp->m_dirnameops->hashname(&name);
 186                        for (i = 0; i < be32_to_cpu(btp->count); i++) {
 187                                if (be32_to_cpu(lep[i].address) == addr &&
 188                                    be32_to_cpu(lep[i].hashval) == hash)
 189                                        break;
 190                        }
 191                        XFS_WANT_CORRUPTED_RETURN(mp,
 192                                                  i < be32_to_cpu(btp->count));
 193                }
 194                p += ops->data_entsize(dep->namelen);
 195        }
 196        /*
 197         * Need to have seen all the entries and all the bestfree slots.
 198         */
 199        XFS_WANT_CORRUPTED_RETURN(mp, freeseen == 7);
 200        if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
 201            hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) {
 202                for (i = stale = 0; i < be32_to_cpu(btp->count); i++) {
 203                        if (lep[i].address ==
 204                            cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
 205                                stale++;
 206                        if (i > 0)
 207                                XFS_WANT_CORRUPTED_RETURN(mp,
 208                                        be32_to_cpu(lep[i].hashval) >=
 209                                                be32_to_cpu(lep[i - 1].hashval));
 210                }
 211                XFS_WANT_CORRUPTED_RETURN(mp, count ==
 212                        be32_to_cpu(btp->count) - be32_to_cpu(btp->stale));
 213                XFS_WANT_CORRUPTED_RETURN(mp, stale == be32_to_cpu(btp->stale));
 214        }
 215        return 0;
 216}
 217
 218static bool
 219xfs_dir3_data_verify(
 220        struct xfs_buf          *bp)
 221{
 222        struct xfs_mount        *mp = bp->b_target->bt_mount;
 223        struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
 224
 225        if (xfs_sb_version_hascrc(&mp->m_sb)) {
 226                if (hdr3->magic != cpu_to_be32(XFS_DIR3_DATA_MAGIC))
 227                        return false;
 228                if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_meta_uuid))
 229                        return false;
 230                if (be64_to_cpu(hdr3->blkno) != bp->b_bn)
 231                        return false;
 232                if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->lsn)))
 233                        return false;
 234        } else {
 235                if (hdr3->magic != cpu_to_be32(XFS_DIR2_DATA_MAGIC))
 236                        return false;
 237        }
 238        if (__xfs_dir3_data_check(NULL, bp))
 239                return false;
 240        return true;
 241}
 242
 243/*
 244 * Readahead of the first block of the directory when it is opened is completely
 245 * oblivious to the format of the directory. Hence we can either get a block
 246 * format buffer or a data format buffer on readahead.
 247 */
 248static void
 249xfs_dir3_data_reada_verify(
 250        struct xfs_buf          *bp)
 251{
 252        struct xfs_dir2_data_hdr *hdr = bp->b_addr;
 253
 254        switch (hdr->magic) {
 255        case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC):
 256        case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC):
 257                bp->b_ops = &xfs_dir3_block_buf_ops;
 258                bp->b_ops->verify_read(bp);
 259                return;
 260        case cpu_to_be32(XFS_DIR2_DATA_MAGIC):
 261        case cpu_to_be32(XFS_DIR3_DATA_MAGIC):
 262                bp->b_ops = &xfs_dir3_data_buf_ops;
 263                bp->b_ops->verify_read(bp);
 264                return;
 265        default:
 266                xfs_buf_ioerror(bp, -EFSCORRUPTED);
 267                xfs_verifier_error(bp);
 268                break;
 269        }
 270}
 271
 272static void
 273xfs_dir3_data_read_verify(
 274        struct xfs_buf  *bp)
 275{
 276        struct xfs_mount        *mp = bp->b_target->bt_mount;
 277
 278        if (xfs_sb_version_hascrc(&mp->m_sb) &&
 279             !xfs_buf_verify_cksum(bp, XFS_DIR3_DATA_CRC_OFF))
 280                 xfs_buf_ioerror(bp, -EFSBADCRC);
 281        else if (!xfs_dir3_data_verify(bp))
 282                xfs_buf_ioerror(bp, -EFSCORRUPTED);
 283
 284        if (bp->b_error)
 285                xfs_verifier_error(bp);
 286}
 287
 288static void
 289xfs_dir3_data_write_verify(
 290        struct xfs_buf  *bp)
 291{
 292        struct xfs_mount        *mp = bp->b_target->bt_mount;
 293        struct xfs_buf_log_item *bip = bp->b_fspriv;
 294        struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
 295
 296        if (!xfs_dir3_data_verify(bp)) {
 297                xfs_buf_ioerror(bp, -EFSCORRUPTED);
 298                xfs_verifier_error(bp);
 299                return;
 300        }
 301
 302        if (!xfs_sb_version_hascrc(&mp->m_sb))
 303                return;
 304
 305        if (bip)
 306                hdr3->lsn = cpu_to_be64(bip->bli_item.li_lsn);
 307
 308        xfs_buf_update_cksum(bp, XFS_DIR3_DATA_CRC_OFF);
 309}
 310
 311const struct xfs_buf_ops xfs_dir3_data_buf_ops = {
 312        .name = "xfs_dir3_data",
 313        .verify_read = xfs_dir3_data_read_verify,
 314        .verify_write = xfs_dir3_data_write_verify,
 315};
 316
 317static const struct xfs_buf_ops xfs_dir3_data_reada_buf_ops = {
 318        .name = "xfs_dir3_data_reada",
 319        .verify_read = xfs_dir3_data_reada_verify,
 320        .verify_write = xfs_dir3_data_write_verify,
 321};
 322
 323
 324int
 325xfs_dir3_data_read(
 326        struct xfs_trans        *tp,
 327        struct xfs_inode        *dp,
 328        xfs_dablk_t             bno,
 329        xfs_daddr_t             mapped_bno,
 330        struct xfs_buf          **bpp)
 331{
 332        int                     err;
 333
 334        err = xfs_da_read_buf(tp, dp, bno, mapped_bno, bpp,
 335                                XFS_DATA_FORK, &xfs_dir3_data_buf_ops);
 336        if (!err && tp && *bpp)
 337                xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_DATA_BUF);
 338        return err;
 339}
 340
 341int
 342xfs_dir3_data_readahead(
 343        struct xfs_inode        *dp,
 344        xfs_dablk_t             bno,
 345        xfs_daddr_t             mapped_bno)
 346{
 347        return xfs_da_reada_buf(dp, bno, mapped_bno,
 348                                XFS_DATA_FORK, &xfs_dir3_data_reada_buf_ops);
 349}
 350
 351/*
 352 * Given a data block and an unused entry from that block,
 353 * return the bestfree entry if any that corresponds to it.
 354 */
 355xfs_dir2_data_free_t *
 356xfs_dir2_data_freefind(
 357        struct xfs_dir2_data_hdr *hdr,          /* data block header */
 358        struct xfs_dir2_data_free *bf,          /* bestfree table pointer */
 359        struct xfs_dir2_data_unused *dup)       /* unused space */
 360{
 361        xfs_dir2_data_free_t    *dfp;           /* bestfree entry */
 362        xfs_dir2_data_aoff_t    off;            /* offset value needed */
 363#ifdef DEBUG
 364        int                     matched;        /* matched the value */
 365        int                     seenzero;       /* saw a 0 bestfree entry */
 366#endif
 367
 368        off = (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr);
 369
 370#ifdef DEBUG
 371        /*
 372         * Validate some consistency in the bestfree table.
 373         * Check order, non-overlapping entries, and if we find the
 374         * one we're looking for it has to be exact.
 375         */
 376        ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
 377               hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
 378               hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
 379               hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
 380        for (dfp = &bf[0], seenzero = matched = 0;
 381             dfp < &bf[XFS_DIR2_DATA_FD_COUNT];
 382             dfp++) {
 383                if (!dfp->offset) {
 384                        ASSERT(!dfp->length);
 385                        seenzero = 1;
 386                        continue;
 387                }
 388                ASSERT(seenzero == 0);
 389                if (be16_to_cpu(dfp->offset) == off) {
 390                        matched = 1;
 391                        ASSERT(dfp->length == dup->length);
 392                } else if (off < be16_to_cpu(dfp->offset))
 393                        ASSERT(off + be16_to_cpu(dup->length) <= be16_to_cpu(dfp->offset));
 394                else
 395                        ASSERT(be16_to_cpu(dfp->offset) + be16_to_cpu(dfp->length) <= off);
 396                ASSERT(matched || be16_to_cpu(dfp->length) >= be16_to_cpu(dup->length));
 397                if (dfp > &bf[0])
 398                        ASSERT(be16_to_cpu(dfp[-1].length) >= be16_to_cpu(dfp[0].length));
 399        }
 400#endif
 401        /*
 402         * If this is smaller than the smallest bestfree entry,
 403         * it can't be there since they're sorted.
 404         */
 405        if (be16_to_cpu(dup->length) <
 406            be16_to_cpu(bf[XFS_DIR2_DATA_FD_COUNT - 1].length))
 407                return NULL;
 408        /*
 409         * Look at the three bestfree entries for our guy.
 410         */
 411        for (dfp = &bf[0]; dfp < &bf[XFS_DIR2_DATA_FD_COUNT]; dfp++) {
 412                if (!dfp->offset)
 413                        return NULL;
 414                if (be16_to_cpu(dfp->offset) == off)
 415                        return dfp;
 416        }
 417        /*
 418         * Didn't find it.  This only happens if there are duplicate lengths.
 419         */
 420        return NULL;
 421}
 422
 423/*
 424 * Insert an unused-space entry into the bestfree table.
 425 */
 426xfs_dir2_data_free_t *                          /* entry inserted */
 427xfs_dir2_data_freeinsert(
 428        struct xfs_dir2_data_hdr *hdr,          /* data block pointer */
 429        struct xfs_dir2_data_free *dfp,         /* bestfree table pointer */
 430        struct xfs_dir2_data_unused *dup,       /* unused space */
 431        int                     *loghead)       /* log the data header (out) */
 432{
 433        xfs_dir2_data_free_t    new;            /* new bestfree entry */
 434
 435        ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
 436               hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
 437               hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
 438               hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
 439
 440        new.length = dup->length;
 441        new.offset = cpu_to_be16((char *)dup - (char *)hdr);
 442
 443        /*
 444         * Insert at position 0, 1, or 2; or not at all.
 445         */
 446        if (be16_to_cpu(new.length) > be16_to_cpu(dfp[0].length)) {
 447                dfp[2] = dfp[1];
 448                dfp[1] = dfp[0];
 449                dfp[0] = new;
 450                *loghead = 1;
 451                return &dfp[0];
 452        }
 453        if (be16_to_cpu(new.length) > be16_to_cpu(dfp[1].length)) {
 454                dfp[2] = dfp[1];
 455                dfp[1] = new;
 456                *loghead = 1;
 457                return &dfp[1];
 458        }
 459        if (be16_to_cpu(new.length) > be16_to_cpu(dfp[2].length)) {
 460                dfp[2] = new;
 461                *loghead = 1;
 462                return &dfp[2];
 463        }
 464        return NULL;
 465}
 466
 467/*
 468 * Remove a bestfree entry from the table.
 469 */
 470STATIC void
 471xfs_dir2_data_freeremove(
 472        struct xfs_dir2_data_hdr *hdr,          /* data block header */
 473        struct xfs_dir2_data_free *bf,          /* bestfree table pointer */
 474        struct xfs_dir2_data_free *dfp,         /* bestfree entry pointer */
 475        int                     *loghead)       /* out: log data header */
 476{
 477
 478        ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
 479               hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
 480               hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
 481               hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
 482
 483        /*
 484         * It's the first entry, slide the next 2 up.
 485         */
 486        if (dfp == &bf[0]) {
 487                bf[0] = bf[1];
 488                bf[1] = bf[2];
 489        }
 490        /*
 491         * It's the second entry, slide the 3rd entry up.
 492         */
 493        else if (dfp == &bf[1])
 494                bf[1] = bf[2];
 495        /*
 496         * Must be the last entry.
 497         */
 498        else
 499                ASSERT(dfp == &bf[2]);
 500        /*
 501         * Clear the 3rd entry, must be zero now.
 502         */
 503        bf[2].length = 0;
 504        bf[2].offset = 0;
 505        *loghead = 1;
 506}
 507
 508/*
 509 * Given a data block, reconstruct its bestfree map.
 510 */
 511void
 512xfs_dir2_data_freescan_int(
 513        struct xfs_da_geometry  *geo,
 514        const struct xfs_dir_ops *ops,
 515        struct xfs_dir2_data_hdr *hdr,
 516        int                     *loghead)
 517{
 518        xfs_dir2_block_tail_t   *btp;           /* block tail */
 519        xfs_dir2_data_entry_t   *dep;           /* active data entry */
 520        xfs_dir2_data_unused_t  *dup;           /* unused data entry */
 521        struct xfs_dir2_data_free *bf;
 522        char                    *endp;          /* end of block's data */
 523        char                    *p;             /* current entry pointer */
 524
 525        ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
 526               hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
 527               hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
 528               hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
 529
 530        /*
 531         * Start by clearing the table.
 532         */
 533        bf = ops->data_bestfree_p(hdr);
 534        memset(bf, 0, sizeof(*bf) * XFS_DIR2_DATA_FD_COUNT);
 535        *loghead = 1;
 536        /*
 537         * Set up pointers.
 538         */
 539        p = (char *)ops->data_entry_p(hdr);
 540        if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
 541            hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) {
 542                btp = xfs_dir2_block_tail_p(geo, hdr);
 543                endp = (char *)xfs_dir2_block_leaf_p(btp);
 544        } else
 545                endp = (char *)hdr + geo->blksize;
 546        /*
 547         * Loop over the block's entries.
 548         */
 549        while (p < endp) {
 550                dup = (xfs_dir2_data_unused_t *)p;
 551                /*
 552                 * If it's a free entry, insert it.
 553                 */
 554                if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
 555                        ASSERT((char *)dup - (char *)hdr ==
 556                               be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)));
 557                        xfs_dir2_data_freeinsert(hdr, bf, dup, loghead);
 558                        p += be16_to_cpu(dup->length);
 559                }
 560                /*
 561                 * For active entries, check their tags and skip them.
 562                 */
 563                else {
 564                        dep = (xfs_dir2_data_entry_t *)p;
 565                        ASSERT((char *)dep - (char *)hdr ==
 566                               be16_to_cpu(*ops->data_entry_tag_p(dep)));
 567                        p += ops->data_entsize(dep->namelen);
 568                }
 569        }
 570}
 571
 572void
 573xfs_dir2_data_freescan(
 574        struct xfs_inode        *dp,
 575        struct xfs_dir2_data_hdr *hdr,
 576        int                     *loghead)
 577{
 578        return xfs_dir2_data_freescan_int(dp->i_mount->m_dir_geo, dp->d_ops,
 579                        hdr, loghead);
 580}
 581
 582/*
 583 * Initialize a data block at the given block number in the directory.
 584 * Give back the buffer for the created block.
 585 */
 586int                                             /* error */
 587xfs_dir3_data_init(
 588        xfs_da_args_t           *args,          /* directory operation args */
 589        xfs_dir2_db_t           blkno,          /* logical dir block number */
 590        struct xfs_buf          **bpp)          /* output block buffer */
 591{
 592        struct xfs_buf          *bp;            /* block buffer */
 593        xfs_dir2_data_hdr_t     *hdr;           /* data block header */
 594        xfs_inode_t             *dp;            /* incore directory inode */
 595        xfs_dir2_data_unused_t  *dup;           /* unused entry pointer */
 596        struct xfs_dir2_data_free *bf;
 597        int                     error;          /* error return value */
 598        int                     i;              /* bestfree index */
 599        xfs_mount_t             *mp;            /* filesystem mount point */
 600        xfs_trans_t             *tp;            /* transaction pointer */
 601        int                     t;              /* temp */
 602
 603        dp = args->dp;
 604        mp = dp->i_mount;
 605        tp = args->trans;
 606        /*
 607         * Get the buffer set up for the block.
 608         */
 609        error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(args->geo, blkno),
 610                               -1, &bp, XFS_DATA_FORK);
 611        if (error)
 612                return error;
 613        bp->b_ops = &xfs_dir3_data_buf_ops;
 614        xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_DATA_BUF);
 615
 616        /*
 617         * Initialize the header.
 618         */
 619        hdr = bp->b_addr;
 620        if (xfs_sb_version_hascrc(&mp->m_sb)) {
 621                struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
 622
 623                memset(hdr3, 0, sizeof(*hdr3));
 624                hdr3->magic = cpu_to_be32(XFS_DIR3_DATA_MAGIC);
 625                hdr3->blkno = cpu_to_be64(bp->b_bn);
 626                hdr3->owner = cpu_to_be64(dp->i_ino);
 627                uuid_copy(&hdr3->uuid, &mp->m_sb.sb_meta_uuid);
 628
 629        } else
 630                hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
 631
 632        bf = dp->d_ops->data_bestfree_p(hdr);
 633        bf[0].offset = cpu_to_be16(dp->d_ops->data_entry_offset);
 634        for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) {
 635                bf[i].length = 0;
 636                bf[i].offset = 0;
 637        }
 638
 639        /*
 640         * Set up an unused entry for the block's body.
 641         */
 642        dup = dp->d_ops->data_unused_p(hdr);
 643        dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
 644
 645        t = args->geo->blksize - (uint)dp->d_ops->data_entry_offset;
 646        bf[0].length = cpu_to_be16(t);
 647        dup->length = cpu_to_be16(t);
 648        *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)hdr);
 649        /*
 650         * Log it and return it.
 651         */
 652        xfs_dir2_data_log_header(args, bp);
 653        xfs_dir2_data_log_unused(args, bp, dup);
 654        *bpp = bp;
 655        return 0;
 656}
 657
 658/*
 659 * Log an active data entry from the block.
 660 */
 661void
 662xfs_dir2_data_log_entry(
 663        struct xfs_da_args      *args,
 664        struct xfs_buf          *bp,
 665        xfs_dir2_data_entry_t   *dep)           /* data entry pointer */
 666{
 667        struct xfs_dir2_data_hdr *hdr = bp->b_addr;
 668
 669        ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
 670               hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
 671               hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
 672               hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
 673
 674        xfs_trans_log_buf(args->trans, bp, (uint)((char *)dep - (char *)hdr),
 675                (uint)((char *)(args->dp->d_ops->data_entry_tag_p(dep) + 1) -
 676                       (char *)hdr - 1));
 677}
 678
 679/*
 680 * Log a data block header.
 681 */
 682void
 683xfs_dir2_data_log_header(
 684        struct xfs_da_args      *args,
 685        struct xfs_buf          *bp)
 686{
 687#ifdef DEBUG
 688        struct xfs_dir2_data_hdr *hdr = bp->b_addr;
 689
 690        ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
 691               hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
 692               hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
 693               hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
 694#endif
 695
 696        xfs_trans_log_buf(args->trans, bp, 0,
 697                          args->dp->d_ops->data_entry_offset - 1);
 698}
 699
 700/*
 701 * Log a data unused entry.
 702 */
 703void
 704xfs_dir2_data_log_unused(
 705        struct xfs_da_args      *args,
 706        struct xfs_buf          *bp,
 707        xfs_dir2_data_unused_t  *dup)           /* data unused pointer */
 708{
 709        xfs_dir2_data_hdr_t     *hdr = bp->b_addr;
 710
 711        ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
 712               hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
 713               hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
 714               hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
 715
 716        /*
 717         * Log the first part of the unused entry.
 718         */
 719        xfs_trans_log_buf(args->trans, bp, (uint)((char *)dup - (char *)hdr),
 720                (uint)((char *)&dup->length + sizeof(dup->length) -
 721                       1 - (char *)hdr));
 722        /*
 723         * Log the end (tag) of the unused entry.
 724         */
 725        xfs_trans_log_buf(args->trans, bp,
 726                (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr),
 727                (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr +
 728                       sizeof(xfs_dir2_data_off_t) - 1));
 729}
 730
 731/*
 732 * Make a byte range in the data block unused.
 733 * Its current contents are unimportant.
 734 */
 735void
 736xfs_dir2_data_make_free(
 737        struct xfs_da_args      *args,
 738        struct xfs_buf          *bp,
 739        xfs_dir2_data_aoff_t    offset,         /* starting byte offset */
 740        xfs_dir2_data_aoff_t    len,            /* length in bytes */
 741        int                     *needlogp,      /* out: log header */
 742        int                     *needscanp)     /* out: regen bestfree */
 743{
 744        xfs_dir2_data_hdr_t     *hdr;           /* data block pointer */
 745        xfs_dir2_data_free_t    *dfp;           /* bestfree pointer */
 746        char                    *endptr;        /* end of data area */
 747        int                     needscan;       /* need to regen bestfree */
 748        xfs_dir2_data_unused_t  *newdup;        /* new unused entry */
 749        xfs_dir2_data_unused_t  *postdup;       /* unused entry after us */
 750        xfs_dir2_data_unused_t  *prevdup;       /* unused entry before us */
 751        struct xfs_dir2_data_free *bf;
 752
 753        hdr = bp->b_addr;
 754
 755        /*
 756         * Figure out where the end of the data area is.
 757         */
 758        if (hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
 759            hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC))
 760                endptr = (char *)hdr + args->geo->blksize;
 761        else {
 762                xfs_dir2_block_tail_t   *btp;   /* block tail */
 763
 764                ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
 765                        hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
 766                btp = xfs_dir2_block_tail_p(args->geo, hdr);
 767                endptr = (char *)xfs_dir2_block_leaf_p(btp);
 768        }
 769        /*
 770         * If this isn't the start of the block, then back up to
 771         * the previous entry and see if it's free.
 772         */
 773        if (offset > args->dp->d_ops->data_entry_offset) {
 774                __be16                  *tagp;  /* tag just before us */
 775
 776                tagp = (__be16 *)((char *)hdr + offset) - 1;
 777                prevdup = (xfs_dir2_data_unused_t *)((char *)hdr + be16_to_cpu(*tagp));
 778                if (be16_to_cpu(prevdup->freetag) != XFS_DIR2_DATA_FREE_TAG)
 779                        prevdup = NULL;
 780        } else
 781                prevdup = NULL;
 782        /*
 783         * If this isn't the end of the block, see if the entry after
 784         * us is free.
 785         */
 786        if ((char *)hdr + offset + len < endptr) {
 787                postdup =
 788                        (xfs_dir2_data_unused_t *)((char *)hdr + offset + len);
 789                if (be16_to_cpu(postdup->freetag) != XFS_DIR2_DATA_FREE_TAG)
 790                        postdup = NULL;
 791        } else
 792                postdup = NULL;
 793        ASSERT(*needscanp == 0);
 794        needscan = 0;
 795        /*
 796         * Previous and following entries are both free,
 797         * merge everything into a single free entry.
 798         */
 799        bf = args->dp->d_ops->data_bestfree_p(hdr);
 800        if (prevdup && postdup) {
 801                xfs_dir2_data_free_t    *dfp2;  /* another bestfree pointer */
 802
 803                /*
 804                 * See if prevdup and/or postdup are in bestfree table.
 805                 */
 806                dfp = xfs_dir2_data_freefind(hdr, bf, prevdup);
 807                dfp2 = xfs_dir2_data_freefind(hdr, bf, postdup);
 808                /*
 809                 * We need a rescan unless there are exactly 2 free entries
 810                 * namely our two.  Then we know what's happening, otherwise
 811                 * since the third bestfree is there, there might be more
 812                 * entries.
 813                 */
 814                needscan = (bf[2].length != 0);
 815                /*
 816                 * Fix up the new big freespace.
 817                 */
 818                be16_add_cpu(&prevdup->length, len + be16_to_cpu(postdup->length));
 819                *xfs_dir2_data_unused_tag_p(prevdup) =
 820                        cpu_to_be16((char *)prevdup - (char *)hdr);
 821                xfs_dir2_data_log_unused(args, bp, prevdup);
 822                if (!needscan) {
 823                        /*
 824                         * Has to be the case that entries 0 and 1 are
 825                         * dfp and dfp2 (don't know which is which), and
 826                         * entry 2 is empty.
 827                         * Remove entry 1 first then entry 0.
 828                         */
 829                        ASSERT(dfp && dfp2);
 830                        if (dfp == &bf[1]) {
 831                                dfp = &bf[0];
 832                                ASSERT(dfp2 == dfp);
 833                                dfp2 = &bf[1];
 834                        }
 835                        xfs_dir2_data_freeremove(hdr, bf, dfp2, needlogp);
 836                        xfs_dir2_data_freeremove(hdr, bf, dfp, needlogp);
 837                        /*
 838                         * Now insert the new entry.
 839                         */
 840                        dfp = xfs_dir2_data_freeinsert(hdr, bf, prevdup,
 841                                                       needlogp);
 842                        ASSERT(dfp == &bf[0]);
 843                        ASSERT(dfp->length == prevdup->length);
 844                        ASSERT(!dfp[1].length);
 845                        ASSERT(!dfp[2].length);
 846                }
 847        }
 848        /*
 849         * The entry before us is free, merge with it.
 850         */
 851        else if (prevdup) {
 852                dfp = xfs_dir2_data_freefind(hdr, bf, prevdup);
 853                be16_add_cpu(&prevdup->length, len);
 854                *xfs_dir2_data_unused_tag_p(prevdup) =
 855                        cpu_to_be16((char *)prevdup - (char *)hdr);
 856                xfs_dir2_data_log_unused(args, bp, prevdup);
 857                /*
 858                 * If the previous entry was in the table, the new entry
 859                 * is longer, so it will be in the table too.  Remove
 860                 * the old one and add the new one.
 861                 */
 862                if (dfp) {
 863                        xfs_dir2_data_freeremove(hdr, bf, dfp, needlogp);
 864                        xfs_dir2_data_freeinsert(hdr, bf, prevdup, needlogp);
 865                }
 866                /*
 867                 * Otherwise we need a scan if the new entry is big enough.
 868                 */
 869                else {
 870                        needscan = be16_to_cpu(prevdup->length) >
 871                                   be16_to_cpu(bf[2].length);
 872                }
 873        }
 874        /*
 875         * The following entry is free, merge with it.
 876         */
 877        else if (postdup) {
 878                dfp = xfs_dir2_data_freefind(hdr, bf, postdup);
 879                newdup = (xfs_dir2_data_unused_t *)((char *)hdr + offset);
 880                newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
 881                newdup->length = cpu_to_be16(len + be16_to_cpu(postdup->length));
 882                *xfs_dir2_data_unused_tag_p(newdup) =
 883                        cpu_to_be16((char *)newdup - (char *)hdr);
 884                xfs_dir2_data_log_unused(args, bp, newdup);
 885                /*
 886                 * If the following entry was in the table, the new entry
 887                 * is longer, so it will be in the table too.  Remove
 888                 * the old one and add the new one.
 889                 */
 890                if (dfp) {
 891                        xfs_dir2_data_freeremove(hdr, bf, dfp, needlogp);
 892                        xfs_dir2_data_freeinsert(hdr, bf, newdup, needlogp);
 893                }
 894                /*
 895                 * Otherwise we need a scan if the new entry is big enough.
 896                 */
 897                else {
 898                        needscan = be16_to_cpu(newdup->length) >
 899                                   be16_to_cpu(bf[2].length);
 900                }
 901        }
 902        /*
 903         * Neither neighbor is free.  Make a new entry.
 904         */
 905        else {
 906                newdup = (xfs_dir2_data_unused_t *)((char *)hdr + offset);
 907                newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
 908                newdup->length = cpu_to_be16(len);
 909                *xfs_dir2_data_unused_tag_p(newdup) =
 910                        cpu_to_be16((char *)newdup - (char *)hdr);
 911                xfs_dir2_data_log_unused(args, bp, newdup);
 912                xfs_dir2_data_freeinsert(hdr, bf, newdup, needlogp);
 913        }
 914        *needscanp = needscan;
 915}
 916
 917/*
 918 * Take a byte range out of an existing unused space and make it un-free.
 919 */
 920void
 921xfs_dir2_data_use_free(
 922        struct xfs_da_args      *args,
 923        struct xfs_buf          *bp,
 924        xfs_dir2_data_unused_t  *dup,           /* unused entry */
 925        xfs_dir2_data_aoff_t    offset,         /* starting offset to use */
 926        xfs_dir2_data_aoff_t    len,            /* length to use */
 927        int                     *needlogp,      /* out: need to log header */
 928        int                     *needscanp)     /* out: need regen bestfree */
 929{
 930        xfs_dir2_data_hdr_t     *hdr;           /* data block header */
 931        xfs_dir2_data_free_t    *dfp;           /* bestfree pointer */
 932        int                     matchback;      /* matches end of freespace */
 933        int                     matchfront;     /* matches start of freespace */
 934        int                     needscan;       /* need to regen bestfree */
 935        xfs_dir2_data_unused_t  *newdup;        /* new unused entry */
 936        xfs_dir2_data_unused_t  *newdup2;       /* another new unused entry */
 937        int                     oldlen;         /* old unused entry's length */
 938        struct xfs_dir2_data_free *bf;
 939
 940        hdr = bp->b_addr;
 941        ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
 942               hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
 943               hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
 944               hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
 945        ASSERT(be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG);
 946        ASSERT(offset >= (char *)dup - (char *)hdr);
 947        ASSERT(offset + len <= (char *)dup + be16_to_cpu(dup->length) - (char *)hdr);
 948        ASSERT((char *)dup - (char *)hdr == be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)));
 949        /*
 950         * Look up the entry in the bestfree table.
 951         */
 952        oldlen = be16_to_cpu(dup->length);
 953        bf = args->dp->d_ops->data_bestfree_p(hdr);
 954        dfp = xfs_dir2_data_freefind(hdr, bf, dup);
 955        ASSERT(dfp || oldlen <= be16_to_cpu(bf[2].length));
 956        /*
 957         * Check for alignment with front and back of the entry.
 958         */
 959        matchfront = (char *)dup - (char *)hdr == offset;
 960        matchback = (char *)dup + oldlen - (char *)hdr == offset + len;
 961        ASSERT(*needscanp == 0);
 962        needscan = 0;
 963        /*
 964         * If we matched it exactly we just need to get rid of it from
 965         * the bestfree table.
 966         */
 967        if (matchfront && matchback) {
 968                if (dfp) {
 969                        needscan = (bf[2].offset != 0);
 970                        if (!needscan)
 971                                xfs_dir2_data_freeremove(hdr, bf, dfp,
 972                                                         needlogp);
 973                }
 974        }
 975        /*
 976         * We match the first part of the entry.
 977         * Make a new entry with the remaining freespace.
 978         */
 979        else if (matchfront) {
 980                newdup = (xfs_dir2_data_unused_t *)((char *)hdr + offset + len);
 981                newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
 982                newdup->length = cpu_to_be16(oldlen - len);
 983                *xfs_dir2_data_unused_tag_p(newdup) =
 984                        cpu_to_be16((char *)newdup - (char *)hdr);
 985                xfs_dir2_data_log_unused(args, bp, newdup);
 986                /*
 987                 * If it was in the table, remove it and add the new one.
 988                 */
 989                if (dfp) {
 990                        xfs_dir2_data_freeremove(hdr, bf, dfp, needlogp);
 991                        dfp = xfs_dir2_data_freeinsert(hdr, bf, newdup,
 992                                                       needlogp);
 993                        ASSERT(dfp != NULL);
 994                        ASSERT(dfp->length == newdup->length);
 995                        ASSERT(be16_to_cpu(dfp->offset) == (char *)newdup - (char *)hdr);
 996                        /*
 997                         * If we got inserted at the last slot,
 998                         * that means we don't know if there was a better
 999                         * choice for the last slot, or not.  Rescan.
1000                         */
1001                        needscan = dfp == &bf[2];
1002                }
1003        }
1004        /*
1005         * We match the last part of the entry.
1006         * Trim the allocated space off the tail of the entry.
1007         */
1008        else if (matchback) {
1009                newdup = dup;
1010                newdup->length = cpu_to_be16(((char *)hdr + offset) - (char *)newdup);
1011                *xfs_dir2_data_unused_tag_p(newdup) =
1012                        cpu_to_be16((char *)newdup - (char *)hdr);
1013                xfs_dir2_data_log_unused(args, bp, newdup);
1014                /*
1015                 * If it was in the table, remove it and add the new one.
1016                 */
1017                if (dfp) {
1018                        xfs_dir2_data_freeremove(hdr, bf, dfp, needlogp);
1019                        dfp = xfs_dir2_data_freeinsert(hdr, bf, newdup,
1020                                                       needlogp);
1021                        ASSERT(dfp != NULL);
1022                        ASSERT(dfp->length == newdup->length);
1023                        ASSERT(be16_to_cpu(dfp->offset) == (char *)newdup - (char *)hdr);
1024                        /*
1025                         * If we got inserted at the last slot,
1026                         * that means we don't know if there was a better
1027                         * choice for the last slot, or not.  Rescan.
1028                         */
1029                        needscan = dfp == &bf[2];
1030                }
1031        }
1032        /*
1033         * Poking out the middle of an entry.
1034         * Make two new entries.
1035         */
1036        else {
1037                newdup = dup;
1038                newdup->length = cpu_to_be16(((char *)hdr + offset) - (char *)newdup);
1039                *xfs_dir2_data_unused_tag_p(newdup) =
1040                        cpu_to_be16((char *)newdup - (char *)hdr);
1041                xfs_dir2_data_log_unused(args, bp, newdup);
1042                newdup2 = (xfs_dir2_data_unused_t *)((char *)hdr + offset + len);
1043                newdup2->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
1044                newdup2->length = cpu_to_be16(oldlen - len - be16_to_cpu(newdup->length));
1045                *xfs_dir2_data_unused_tag_p(newdup2) =
1046                        cpu_to_be16((char *)newdup2 - (char *)hdr);
1047                xfs_dir2_data_log_unused(args, bp, newdup2);
1048                /*
1049                 * If the old entry was in the table, we need to scan
1050                 * if the 3rd entry was valid, since these entries
1051                 * are smaller than the old one.
1052                 * If we don't need to scan that means there were 1 or 2
1053                 * entries in the table, and removing the old and adding
1054                 * the 2 new will work.
1055                 */
1056                if (dfp) {
1057                        needscan = (bf[2].length != 0);
1058                        if (!needscan) {
1059                                xfs_dir2_data_freeremove(hdr, bf, dfp,
1060                                                         needlogp);
1061                                xfs_dir2_data_freeinsert(hdr, bf, newdup,
1062                                                         needlogp);
1063                                xfs_dir2_data_freeinsert(hdr, bf, newdup2,
1064                                                         needlogp);
1065                        }
1066                }
1067        }
1068        *needscanp = needscan;
1069}
1070