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