linux/fs/xfs/scrub/dir.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2017 Oracle.  All Rights Reserved.
   4 * Author: Darrick J. Wong <darrick.wong@oracle.com>
   5 */
   6#include "xfs.h"
   7#include "xfs_fs.h"
   8#include "xfs_shared.h"
   9#include "xfs_format.h"
  10#include "xfs_trans_resv.h"
  11#include "xfs_mount.h"
  12#include "xfs_log_format.h"
  13#include "xfs_trans.h"
  14#include "xfs_inode.h"
  15#include "xfs_icache.h"
  16#include "xfs_dir2.h"
  17#include "xfs_dir2_priv.h"
  18#include "scrub/scrub.h"
  19#include "scrub/common.h"
  20#include "scrub/dabtree.h"
  21
  22/* Set us up to scrub directories. */
  23int
  24xchk_setup_directory(
  25        struct xfs_scrub        *sc,
  26        struct xfs_inode        *ip)
  27{
  28        return xchk_setup_inode_contents(sc, ip, 0);
  29}
  30
  31/* Directories */
  32
  33/* Scrub a directory entry. */
  34
  35struct xchk_dir_ctx {
  36        /* VFS fill-directory iterator */
  37        struct dir_context      dir_iter;
  38
  39        struct xfs_scrub        *sc;
  40};
  41
  42/* Check that an inode's mode matches a given DT_ type. */
  43STATIC int
  44xchk_dir_check_ftype(
  45        struct xchk_dir_ctx     *sdc,
  46        xfs_fileoff_t           offset,
  47        xfs_ino_t               inum,
  48        int                     dtype)
  49{
  50        struct xfs_mount        *mp = sdc->sc->mp;
  51        struct xfs_inode        *ip;
  52        int                     ino_dtype;
  53        int                     error = 0;
  54
  55        if (!xfs_sb_version_hasftype(&mp->m_sb)) {
  56                if (dtype != DT_UNKNOWN && dtype != DT_DIR)
  57                        xchk_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK,
  58                                        offset);
  59                goto out;
  60        }
  61
  62        /*
  63         * Grab the inode pointed to by the dirent.  We release the
  64         * inode before we cancel the scrub transaction.  Since we're
  65         * don't know a priori that releasing the inode won't trigger
  66         * eofblocks cleanup (which allocates what would be a nested
  67         * transaction), we can't use DONTCACHE here because DONTCACHE
  68         * inodes can trigger immediate inactive cleanup of the inode.
  69         */
  70        error = xfs_iget(mp, sdc->sc->tp, inum, 0, 0, &ip);
  71        if (!xchk_fblock_xref_process_error(sdc->sc, XFS_DATA_FORK, offset,
  72                        &error))
  73                goto out;
  74
  75        /* Convert mode to the DT_* values that dir_emit uses. */
  76        ino_dtype = xfs_dir3_get_dtype(mp,
  77                        xfs_mode_to_ftype(VFS_I(ip)->i_mode));
  78        if (ino_dtype != dtype)
  79                xchk_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK, offset);
  80        xfs_irele(ip);
  81out:
  82        return error;
  83}
  84
  85/*
  86 * Scrub a single directory entry.
  87 *
  88 * We use the VFS directory iterator (i.e. readdir) to call this
  89 * function for every directory entry in a directory.  Once we're here,
  90 * we check the inode number to make sure it's sane, then we check that
  91 * we can look up this filename.  Finally, we check the ftype.
  92 */
  93STATIC int
  94xchk_dir_actor(
  95        struct dir_context      *dir_iter,
  96        const char              *name,
  97        int                     namelen,
  98        loff_t                  pos,
  99        u64                     ino,
 100        unsigned                type)
 101{
 102        struct xfs_mount        *mp;
 103        struct xfs_inode        *ip;
 104        struct xchk_dir_ctx     *sdc;
 105        struct xfs_name         xname;
 106        xfs_ino_t               lookup_ino;
 107        xfs_dablk_t             offset;
 108        int                     error = 0;
 109
 110        sdc = container_of(dir_iter, struct xchk_dir_ctx, dir_iter);
 111        ip = sdc->sc->ip;
 112        mp = ip->i_mount;
 113        offset = xfs_dir2_db_to_da(mp->m_dir_geo,
 114                        xfs_dir2_dataptr_to_db(mp->m_dir_geo, pos));
 115
 116        if (xchk_should_terminate(sdc->sc, &error))
 117                return error;
 118
 119        /* Does this inode number make sense? */
 120        if (!xfs_verify_dir_ino(mp, ino)) {
 121                xchk_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK, offset);
 122                goto out;
 123        }
 124
 125        /* Does this name make sense? */
 126        if (!xfs_dir2_namecheck(name, namelen)) {
 127                xchk_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK, offset);
 128                goto out;
 129        }
 130
 131        if (!strncmp(".", name, namelen)) {
 132                /* If this is "." then check that the inum matches the dir. */
 133                if (xfs_sb_version_hasftype(&mp->m_sb) && type != DT_DIR)
 134                        xchk_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK,
 135                                        offset);
 136                if (ino != ip->i_ino)
 137                        xchk_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK,
 138                                        offset);
 139        } else if (!strncmp("..", name, namelen)) {
 140                /*
 141                 * If this is ".." in the root inode, check that the inum
 142                 * matches this dir.
 143                 */
 144                if (xfs_sb_version_hasftype(&mp->m_sb) && type != DT_DIR)
 145                        xchk_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK,
 146                                        offset);
 147                if (ip->i_ino == mp->m_sb.sb_rootino && ino != ip->i_ino)
 148                        xchk_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK,
 149                                        offset);
 150        }
 151
 152        /* Verify that we can look up this name by hash. */
 153        xname.name = name;
 154        xname.len = namelen;
 155        xname.type = XFS_DIR3_FT_UNKNOWN;
 156
 157        error = xfs_dir_lookup(sdc->sc->tp, ip, &xname, &lookup_ino, NULL);
 158        /* ENOENT means the hash lookup failed and the dir is corrupt */
 159        if (error == -ENOENT)
 160                error = -EFSCORRUPTED;
 161        if (!xchk_fblock_process_error(sdc->sc, XFS_DATA_FORK, offset,
 162                        &error))
 163                goto out;
 164        if (lookup_ino != ino) {
 165                xchk_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK, offset);
 166                goto out;
 167        }
 168
 169        /* Verify the file type.  This function absorbs error codes. */
 170        error = xchk_dir_check_ftype(sdc, offset, lookup_ino, type);
 171        if (error)
 172                goto out;
 173out:
 174        /*
 175         * A negative error code returned here is supposed to cause the
 176         * dir_emit caller (xfs_readdir) to abort the directory iteration
 177         * and return zero to xchk_directory.
 178         */
 179        if (error == 0 && sdc->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
 180                return -EFSCORRUPTED;
 181        return error;
 182}
 183
 184/* Scrub a directory btree record. */
 185STATIC int
 186xchk_dir_rec(
 187        struct xchk_da_btree            *ds,
 188        int                             level)
 189{
 190        struct xfs_da_state_blk         *blk = &ds->state->path.blk[level];
 191        struct xfs_mount                *mp = ds->state->mp;
 192        struct xfs_inode                *dp = ds->dargs.dp;
 193        struct xfs_da_geometry          *geo = mp->m_dir_geo;
 194        struct xfs_dir2_data_entry      *dent;
 195        struct xfs_buf                  *bp;
 196        struct xfs_dir2_leaf_entry      *ent;
 197        unsigned int                    end;
 198        unsigned int                    iter_off;
 199        xfs_ino_t                       ino;
 200        xfs_dablk_t                     rec_bno;
 201        xfs_dir2_db_t                   db;
 202        xfs_dir2_data_aoff_t            off;
 203        xfs_dir2_dataptr_t              ptr;
 204        xfs_dahash_t                    calc_hash;
 205        xfs_dahash_t                    hash;
 206        struct xfs_dir3_icleaf_hdr      hdr;
 207        unsigned int                    tag;
 208        int                             error;
 209
 210        ASSERT(blk->magic == XFS_DIR2_LEAF1_MAGIC ||
 211               blk->magic == XFS_DIR2_LEAFN_MAGIC);
 212
 213        xfs_dir2_leaf_hdr_from_disk(mp, &hdr, blk->bp->b_addr);
 214        ent = hdr.ents + blk->index;
 215
 216        /* Check the hash of the entry. */
 217        error = xchk_da_btree_hash(ds, level, &ent->hashval);
 218        if (error)
 219                goto out;
 220
 221        /* Valid hash pointer? */
 222        ptr = be32_to_cpu(ent->address);
 223        if (ptr == 0)
 224                return 0;
 225
 226        /* Find the directory entry's location. */
 227        db = xfs_dir2_dataptr_to_db(geo, ptr);
 228        off = xfs_dir2_dataptr_to_off(geo, ptr);
 229        rec_bno = xfs_dir2_db_to_da(geo, db);
 230
 231        if (rec_bno >= geo->leafblk) {
 232                xchk_da_set_corrupt(ds, level);
 233                goto out;
 234        }
 235        error = xfs_dir3_data_read(ds->dargs.trans, dp, rec_bno,
 236                        XFS_DABUF_MAP_HOLE_OK, &bp);
 237        if (!xchk_fblock_process_error(ds->sc, XFS_DATA_FORK, rec_bno,
 238                        &error))
 239                goto out;
 240        if (!bp) {
 241                xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
 242                goto out;
 243        }
 244        xchk_buffer_recheck(ds->sc, bp);
 245
 246        if (ds->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
 247                goto out_relse;
 248
 249        dent = bp->b_addr + off;
 250
 251        /* Make sure we got a real directory entry. */
 252        iter_off = geo->data_entry_offset;
 253        end = xfs_dir3_data_end_offset(geo, bp->b_addr);
 254        if (!end) {
 255                xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
 256                goto out_relse;
 257        }
 258        for (;;) {
 259                struct xfs_dir2_data_entry      *dep = bp->b_addr + iter_off;
 260                struct xfs_dir2_data_unused     *dup = bp->b_addr + iter_off;
 261
 262                if (iter_off >= end) {
 263                        xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
 264                        goto out_relse;
 265                }
 266
 267                if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
 268                        iter_off += be16_to_cpu(dup->length);
 269                        continue;
 270                }
 271                if (dep == dent)
 272                        break;
 273                iter_off += xfs_dir2_data_entsize(mp, dep->namelen);
 274        }
 275
 276        /* Retrieve the entry, sanity check it, and compare hashes. */
 277        ino = be64_to_cpu(dent->inumber);
 278        hash = be32_to_cpu(ent->hashval);
 279        tag = be16_to_cpup(xfs_dir2_data_entry_tag_p(mp, dent));
 280        if (!xfs_verify_dir_ino(mp, ino) || tag != off)
 281                xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
 282        if (dent->namelen == 0) {
 283                xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
 284                goto out_relse;
 285        }
 286        calc_hash = xfs_da_hashname(dent->name, dent->namelen);
 287        if (calc_hash != hash)
 288                xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
 289
 290out_relse:
 291        xfs_trans_brelse(ds->dargs.trans, bp);
 292out:
 293        return error;
 294}
 295
 296/*
 297 * Is this unused entry either in the bestfree or smaller than all of
 298 * them?  We've already checked that the bestfrees are sorted longest to
 299 * shortest, and that there aren't any bogus entries.
 300 */
 301STATIC void
 302xchk_directory_check_free_entry(
 303        struct xfs_scrub                *sc,
 304        xfs_dablk_t                     lblk,
 305        struct xfs_dir2_data_free       *bf,
 306        struct xfs_dir2_data_unused     *dup)
 307{
 308        struct xfs_dir2_data_free       *dfp;
 309        unsigned int                    dup_length;
 310
 311        dup_length = be16_to_cpu(dup->length);
 312
 313        /* Unused entry is shorter than any of the bestfrees */
 314        if (dup_length < be16_to_cpu(bf[XFS_DIR2_DATA_FD_COUNT - 1].length))
 315                return;
 316
 317        for (dfp = &bf[XFS_DIR2_DATA_FD_COUNT - 1]; dfp >= bf; dfp--)
 318                if (dup_length == be16_to_cpu(dfp->length))
 319                        return;
 320
 321        /* Unused entry should be in the bestfrees but wasn't found. */
 322        xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
 323}
 324
 325/* Check free space info in a directory data block. */
 326STATIC int
 327xchk_directory_data_bestfree(
 328        struct xfs_scrub                *sc,
 329        xfs_dablk_t                     lblk,
 330        bool                            is_block)
 331{
 332        struct xfs_dir2_data_unused     *dup;
 333        struct xfs_dir2_data_free       *dfp;
 334        struct xfs_buf                  *bp;
 335        struct xfs_dir2_data_free       *bf;
 336        struct xfs_mount                *mp = sc->mp;
 337        u16                             tag;
 338        unsigned int                    nr_bestfrees = 0;
 339        unsigned int                    nr_frees = 0;
 340        unsigned int                    smallest_bestfree;
 341        int                             newlen;
 342        unsigned int                    offset;
 343        unsigned int                    end;
 344        int                             error;
 345
 346        if (is_block) {
 347                /* dir block format */
 348                if (lblk != XFS_B_TO_FSBT(mp, XFS_DIR2_DATA_OFFSET))
 349                        xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
 350                error = xfs_dir3_block_read(sc->tp, sc->ip, &bp);
 351        } else {
 352                /* dir data format */
 353                error = xfs_dir3_data_read(sc->tp, sc->ip, lblk, 0, &bp);
 354        }
 355        if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, &error))
 356                goto out;
 357        xchk_buffer_recheck(sc, bp);
 358
 359        /* XXX: Check xfs_dir3_data_hdr.pad is zero once we start setting it. */
 360
 361        if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
 362                goto out_buf;
 363
 364        /* Do the bestfrees correspond to actual free space? */
 365        bf = xfs_dir2_data_bestfree_p(mp, bp->b_addr);
 366        smallest_bestfree = UINT_MAX;
 367        for (dfp = &bf[0]; dfp < &bf[XFS_DIR2_DATA_FD_COUNT]; dfp++) {
 368                offset = be16_to_cpu(dfp->offset);
 369                if (offset == 0)
 370                        continue;
 371                if (offset >= mp->m_dir_geo->blksize) {
 372                        xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
 373                        goto out_buf;
 374                }
 375                dup = bp->b_addr + offset;
 376                tag = be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup));
 377
 378                /* bestfree doesn't match the entry it points at? */
 379                if (dup->freetag != cpu_to_be16(XFS_DIR2_DATA_FREE_TAG) ||
 380                    be16_to_cpu(dup->length) != be16_to_cpu(dfp->length) ||
 381                    tag != offset) {
 382                        xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
 383                        goto out_buf;
 384                }
 385
 386                /* bestfree records should be ordered largest to smallest */
 387                if (smallest_bestfree < be16_to_cpu(dfp->length)) {
 388                        xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
 389                        goto out_buf;
 390                }
 391
 392                smallest_bestfree = be16_to_cpu(dfp->length);
 393                nr_bestfrees++;
 394        }
 395
 396        /* Make sure the bestfrees are actually the best free spaces. */
 397        offset = mp->m_dir_geo->data_entry_offset;
 398        end = xfs_dir3_data_end_offset(mp->m_dir_geo, bp->b_addr);
 399
 400        /* Iterate the entries, stopping when we hit or go past the end. */
 401        while (offset < end) {
 402                dup = bp->b_addr + offset;
 403
 404                /* Skip real entries */
 405                if (dup->freetag != cpu_to_be16(XFS_DIR2_DATA_FREE_TAG)) {
 406                        struct xfs_dir2_data_entry *dep = bp->b_addr + offset;
 407
 408                        newlen = xfs_dir2_data_entsize(mp, dep->namelen);
 409                        if (newlen <= 0) {
 410                                xchk_fblock_set_corrupt(sc, XFS_DATA_FORK,
 411                                                lblk);
 412                                goto out_buf;
 413                        }
 414                        offset += newlen;
 415                        continue;
 416                }
 417
 418                /* Spot check this free entry */
 419                tag = be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup));
 420                if (tag != offset) {
 421                        xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
 422                        goto out_buf;
 423                }
 424
 425                /*
 426                 * Either this entry is a bestfree or it's smaller than
 427                 * any of the bestfrees.
 428                 */
 429                xchk_directory_check_free_entry(sc, lblk, bf, dup);
 430                if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
 431                        goto out_buf;
 432
 433                /* Move on. */
 434                newlen = be16_to_cpu(dup->length);
 435                if (newlen <= 0) {
 436                        xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
 437                        goto out_buf;
 438                }
 439                offset += newlen;
 440                if (offset <= end)
 441                        nr_frees++;
 442        }
 443
 444        /* We're required to fill all the space. */
 445        if (offset != end)
 446                xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
 447
 448        /* Did we see at least as many free slots as there are bestfrees? */
 449        if (nr_frees < nr_bestfrees)
 450                xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
 451out_buf:
 452        xfs_trans_brelse(sc->tp, bp);
 453out:
 454        return error;
 455}
 456
 457/*
 458 * Does the free space length in the free space index block ($len) match
 459 * the longest length in the directory data block's bestfree array?
 460 * Assume that we've already checked that the data block's bestfree
 461 * array is in order.
 462 */
 463STATIC void
 464xchk_directory_check_freesp(
 465        struct xfs_scrub                *sc,
 466        xfs_dablk_t                     lblk,
 467        struct xfs_buf                  *dbp,
 468        unsigned int                    len)
 469{
 470        struct xfs_dir2_data_free       *dfp;
 471
 472        dfp = xfs_dir2_data_bestfree_p(sc->mp, dbp->b_addr);
 473
 474        if (len != be16_to_cpu(dfp->length))
 475                xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
 476
 477        if (len > 0 && be16_to_cpu(dfp->offset) == 0)
 478                xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
 479}
 480
 481/* Check free space info in a directory leaf1 block. */
 482STATIC int
 483xchk_directory_leaf1_bestfree(
 484        struct xfs_scrub                *sc,
 485        struct xfs_da_args              *args,
 486        xfs_dablk_t                     lblk)
 487{
 488        struct xfs_dir3_icleaf_hdr      leafhdr;
 489        struct xfs_dir2_leaf_tail       *ltp;
 490        struct xfs_dir2_leaf            *leaf;
 491        struct xfs_buf                  *dbp;
 492        struct xfs_buf                  *bp;
 493        struct xfs_da_geometry          *geo = sc->mp->m_dir_geo;
 494        __be16                          *bestp;
 495        __u16                           best;
 496        __u32                           hash;
 497        __u32                           lasthash = 0;
 498        __u32                           bestcount;
 499        unsigned int                    stale = 0;
 500        int                             i;
 501        int                             error;
 502
 503        /* Read the free space block. */
 504        error = xfs_dir3_leaf_read(sc->tp, sc->ip, lblk, &bp);
 505        if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, &error))
 506                return error;
 507        xchk_buffer_recheck(sc, bp);
 508
 509        leaf = bp->b_addr;
 510        xfs_dir2_leaf_hdr_from_disk(sc->ip->i_mount, &leafhdr, leaf);
 511        ltp = xfs_dir2_leaf_tail_p(geo, leaf);
 512        bestcount = be32_to_cpu(ltp->bestcount);
 513        bestp = xfs_dir2_leaf_bests_p(ltp);
 514
 515        if (xfs_sb_version_hascrc(&sc->mp->m_sb)) {
 516                struct xfs_dir3_leaf_hdr        *hdr3 = bp->b_addr;
 517
 518                if (hdr3->pad != cpu_to_be32(0))
 519                        xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
 520        }
 521
 522        /*
 523         * There should be as many bestfree slots as there are dir data
 524         * blocks that can fit under i_size.
 525         */
 526        if (bestcount != xfs_dir2_byte_to_db(geo, sc->ip->i_d.di_size)) {
 527                xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
 528                goto out;
 529        }
 530
 531        /* Is the leaf count even remotely sane? */
 532        if (leafhdr.count > geo->leaf_max_ents) {
 533                xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
 534                goto out;
 535        }
 536
 537        /* Leaves and bests don't overlap in leaf format. */
 538        if ((char *)&leafhdr.ents[leafhdr.count] > (char *)bestp) {
 539                xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
 540                goto out;
 541        }
 542
 543        /* Check hash value order, count stale entries.  */
 544        for (i = 0; i < leafhdr.count; i++) {
 545                hash = be32_to_cpu(leafhdr.ents[i].hashval);
 546                if (i > 0 && lasthash > hash)
 547                        xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
 548                lasthash = hash;
 549                if (leafhdr.ents[i].address ==
 550                    cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
 551                        stale++;
 552        }
 553        if (leafhdr.stale != stale)
 554                xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
 555        if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
 556                goto out;
 557
 558        /* Check all the bestfree entries. */
 559        for (i = 0; i < bestcount; i++, bestp++) {
 560                best = be16_to_cpu(*bestp);
 561                if (best == NULLDATAOFF)
 562                        continue;
 563                error = xfs_dir3_data_read(sc->tp, sc->ip,
 564                                i * args->geo->fsbcount, 0, &dbp);
 565                if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk,
 566                                &error))
 567                        break;
 568                xchk_directory_check_freesp(sc, lblk, dbp, best);
 569                xfs_trans_brelse(sc->tp, dbp);
 570                if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
 571                        break;
 572        }
 573out:
 574        xfs_trans_brelse(sc->tp, bp);
 575        return error;
 576}
 577
 578/* Check free space info in a directory freespace block. */
 579STATIC int
 580xchk_directory_free_bestfree(
 581        struct xfs_scrub                *sc,
 582        struct xfs_da_args              *args,
 583        xfs_dablk_t                     lblk)
 584{
 585        struct xfs_dir3_icfree_hdr      freehdr;
 586        struct xfs_buf                  *dbp;
 587        struct xfs_buf                  *bp;
 588        __u16                           best;
 589        unsigned int                    stale = 0;
 590        int                             i;
 591        int                             error;
 592
 593        /* Read the free space block */
 594        error = xfs_dir2_free_read(sc->tp, sc->ip, lblk, &bp);
 595        if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, &error))
 596                return error;
 597        xchk_buffer_recheck(sc, bp);
 598
 599        if (xfs_sb_version_hascrc(&sc->mp->m_sb)) {
 600                struct xfs_dir3_free_hdr        *hdr3 = bp->b_addr;
 601
 602                if (hdr3->pad != cpu_to_be32(0))
 603                        xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
 604        }
 605
 606        /* Check all the entries. */
 607        xfs_dir2_free_hdr_from_disk(sc->ip->i_mount, &freehdr, bp->b_addr);
 608        for (i = 0; i < freehdr.nvalid; i++) {
 609                best = be16_to_cpu(freehdr.bests[i]);
 610                if (best == NULLDATAOFF) {
 611                        stale++;
 612                        continue;
 613                }
 614                error = xfs_dir3_data_read(sc->tp, sc->ip,
 615                                (freehdr.firstdb + i) * args->geo->fsbcount,
 616                                0, &dbp);
 617                if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk,
 618                                &error))
 619                        goto out;
 620                xchk_directory_check_freesp(sc, lblk, dbp, best);
 621                xfs_trans_brelse(sc->tp, dbp);
 622        }
 623
 624        if (freehdr.nused + stale != freehdr.nvalid)
 625                xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
 626out:
 627        xfs_trans_brelse(sc->tp, bp);
 628        return error;
 629}
 630
 631/* Check free space information in directories. */
 632STATIC int
 633xchk_directory_blocks(
 634        struct xfs_scrub        *sc)
 635{
 636        struct xfs_bmbt_irec    got;
 637        struct xfs_da_args      args;
 638        struct xfs_ifork        *ifp = XFS_IFORK_PTR(sc->ip, XFS_DATA_FORK);
 639        struct xfs_mount        *mp = sc->mp;
 640        xfs_fileoff_t           leaf_lblk;
 641        xfs_fileoff_t           free_lblk;
 642        xfs_fileoff_t           lblk;
 643        struct xfs_iext_cursor  icur;
 644        xfs_dablk_t             dabno;
 645        bool                    found;
 646        int                     is_block = 0;
 647        int                     error;
 648
 649        /* Ignore local format directories. */
 650        if (ifp->if_format != XFS_DINODE_FMT_EXTENTS &&
 651            ifp->if_format != XFS_DINODE_FMT_BTREE)
 652                return 0;
 653
 654        lblk = XFS_B_TO_FSB(mp, XFS_DIR2_DATA_OFFSET);
 655        leaf_lblk = XFS_B_TO_FSB(mp, XFS_DIR2_LEAF_OFFSET);
 656        free_lblk = XFS_B_TO_FSB(mp, XFS_DIR2_FREE_OFFSET);
 657
 658        /* Is this a block dir? */
 659        args.dp = sc->ip;
 660        args.geo = mp->m_dir_geo;
 661        args.trans = sc->tp;
 662        error = xfs_dir2_isblock(&args, &is_block);
 663        if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, &error))
 664                goto out;
 665
 666        /* Iterate all the data extents in the directory... */
 667        found = xfs_iext_lookup_extent(sc->ip, ifp, lblk, &icur, &got);
 668        while (found && !(sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) {
 669                /* Block directories only have a single block at offset 0. */
 670                if (is_block &&
 671                    (got.br_startoff > 0 ||
 672                     got.br_blockcount != args.geo->fsbcount)) {
 673                        xchk_fblock_set_corrupt(sc, XFS_DATA_FORK,
 674                                        got.br_startoff);
 675                        break;
 676                }
 677
 678                /* No more data blocks... */
 679                if (got.br_startoff >= leaf_lblk)
 680                        break;
 681
 682                /*
 683                 * Check each data block's bestfree data.
 684                 *
 685                 * Iterate all the fsbcount-aligned block offsets in
 686                 * this directory.  The directory block reading code is
 687                 * smart enough to do its own bmap lookups to handle
 688                 * discontiguous directory blocks.  When we're done
 689                 * with the extent record, re-query the bmap at the
 690                 * next fsbcount-aligned offset to avoid redundant
 691                 * block checks.
 692                 */
 693                for (lblk = roundup((xfs_dablk_t)got.br_startoff,
 694                                args.geo->fsbcount);
 695                     lblk < got.br_startoff + got.br_blockcount;
 696                     lblk += args.geo->fsbcount) {
 697                        error = xchk_directory_data_bestfree(sc, lblk,
 698                                        is_block);
 699                        if (error)
 700                                goto out;
 701                }
 702                dabno = got.br_startoff + got.br_blockcount;
 703                lblk = roundup(dabno, args.geo->fsbcount);
 704                found = xfs_iext_lookup_extent(sc->ip, ifp, lblk, &icur, &got);
 705        }
 706
 707        if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
 708                goto out;
 709
 710        /* Look for a leaf1 block, which has free info. */
 711        if (xfs_iext_lookup_extent(sc->ip, ifp, leaf_lblk, &icur, &got) &&
 712            got.br_startoff == leaf_lblk &&
 713            got.br_blockcount == args.geo->fsbcount &&
 714            !xfs_iext_next_extent(ifp, &icur, &got)) {
 715                if (is_block) {
 716                        xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
 717                        goto out;
 718                }
 719                error = xchk_directory_leaf1_bestfree(sc, &args,
 720                                leaf_lblk);
 721                if (error)
 722                        goto out;
 723        }
 724
 725        if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
 726                goto out;
 727
 728        /* Scan for free blocks */
 729        lblk = free_lblk;
 730        found = xfs_iext_lookup_extent(sc->ip, ifp, lblk, &icur, &got);
 731        while (found && !(sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) {
 732                /*
 733                 * Dirs can't have blocks mapped above 2^32.
 734                 * Single-block dirs shouldn't even be here.
 735                 */
 736                lblk = got.br_startoff;
 737                if (lblk & ~0xFFFFFFFFULL) {
 738                        xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
 739                        goto out;
 740                }
 741                if (is_block) {
 742                        xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
 743                        goto out;
 744                }
 745
 746                /*
 747                 * Check each dir free block's bestfree data.
 748                 *
 749                 * Iterate all the fsbcount-aligned block offsets in
 750                 * this directory.  The directory block reading code is
 751                 * smart enough to do its own bmap lookups to handle
 752                 * discontiguous directory blocks.  When we're done
 753                 * with the extent record, re-query the bmap at the
 754                 * next fsbcount-aligned offset to avoid redundant
 755                 * block checks.
 756                 */
 757                for (lblk = roundup((xfs_dablk_t)got.br_startoff,
 758                                args.geo->fsbcount);
 759                     lblk < got.br_startoff + got.br_blockcount;
 760                     lblk += args.geo->fsbcount) {
 761                        error = xchk_directory_free_bestfree(sc, &args,
 762                                        lblk);
 763                        if (error)
 764                                goto out;
 765                }
 766                dabno = got.br_startoff + got.br_blockcount;
 767                lblk = roundup(dabno, args.geo->fsbcount);
 768                found = xfs_iext_lookup_extent(sc->ip, ifp, lblk, &icur, &got);
 769        }
 770out:
 771        return error;
 772}
 773
 774/* Scrub a whole directory. */
 775int
 776xchk_directory(
 777        struct xfs_scrub        *sc)
 778{
 779        struct xchk_dir_ctx     sdc = {
 780                .dir_iter.actor = xchk_dir_actor,
 781                .dir_iter.pos = 0,
 782                .sc = sc,
 783        };
 784        size_t                  bufsize;
 785        loff_t                  oldpos;
 786        int                     error = 0;
 787
 788        if (!S_ISDIR(VFS_I(sc->ip)->i_mode))
 789                return -ENOENT;
 790
 791        /* Plausible size? */
 792        if (sc->ip->i_d.di_size < xfs_dir2_sf_hdr_size(0)) {
 793                xchk_ino_set_corrupt(sc, sc->ip->i_ino);
 794                goto out;
 795        }
 796
 797        /* Check directory tree structure */
 798        error = xchk_da_btree(sc, XFS_DATA_FORK, xchk_dir_rec, NULL);
 799        if (error)
 800                return error;
 801
 802        if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
 803                return error;
 804
 805        /* Check the freespace. */
 806        error = xchk_directory_blocks(sc);
 807        if (error)
 808                return error;
 809
 810        if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
 811                return error;
 812
 813        /*
 814         * Check that every dirent we see can also be looked up by hash.
 815         * Userspace usually asks for a 32k buffer, so we will too.
 816         */
 817        bufsize = (size_t)min_t(loff_t, XFS_READDIR_BUFSIZE,
 818                        sc->ip->i_d.di_size);
 819
 820        /*
 821         * Look up every name in this directory by hash.
 822         *
 823         * Use the xfs_readdir function to call xchk_dir_actor on
 824         * every directory entry in this directory.  In _actor, we check
 825         * the name, inode number, and ftype (if applicable) of the
 826         * entry.  xfs_readdir uses the VFS filldir functions to provide
 827         * iteration context.
 828         *
 829         * The VFS grabs a read or write lock via i_rwsem before it reads
 830         * or writes to a directory.  If we've gotten this far we've
 831         * already obtained IOLOCK_EXCL, which (since 4.10) is the same as
 832         * getting a write lock on i_rwsem.  Therefore, it is safe for us
 833         * to drop the ILOCK here in order to reuse the _readdir and
 834         * _dir_lookup routines, which do their own ILOCK locking.
 835         */
 836        oldpos = 0;
 837        sc->ilock_flags &= ~XFS_ILOCK_EXCL;
 838        xfs_iunlock(sc->ip, XFS_ILOCK_EXCL);
 839        while (true) {
 840                error = xfs_readdir(sc->tp, sc->ip, &sdc.dir_iter, bufsize);
 841                if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0,
 842                                &error))
 843                        goto out;
 844                if (oldpos == sdc.dir_iter.pos)
 845                        break;
 846                oldpos = sdc.dir_iter.pos;
 847        }
 848
 849out:
 850        return error;
 851}
 852