Print this page
6842 Fix empty xattr dir causing lockup
Reviewed by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/zfs/zap_micro.c
          +++ new/usr/src/uts/common/fs/zfs/zap_micro.c
↓ open down ↓ 359 lines elided ↑ open up ↑
 360  360                  kmem_free(mze, sizeof (mzap_ent_t));
 361  361          avl_destroy(&zap->zap_m.zap_avl);
 362  362  }
 363  363  
 364  364  static zap_t *
 365  365  mzap_open(objset_t *os, uint64_t obj, dmu_buf_t *db)
 366  366  {
 367  367          zap_t *winner;
 368  368          zap_t *zap;
 369  369          int i;
      370 +        uint64_t *zap_hdr = (uint64_t *)db->db_data;
      371 +        uint64_t zap_block_type = zap_hdr[0];
      372 +        uint64_t zap_magic = zap_hdr[1];
 370  373  
 371  374          ASSERT3U(MZAP_ENT_LEN, ==, sizeof (mzap_ent_phys_t));
 372  375  
 373  376          zap = kmem_zalloc(sizeof (zap_t), KM_SLEEP);
 374  377          rw_init(&zap->zap_rwlock, 0, 0, 0);
 375  378          rw_enter(&zap->zap_rwlock, RW_WRITER);
 376  379          zap->zap_objset = os;
 377  380          zap->zap_object = obj;
 378  381          zap->zap_dbuf = db;
 379  382  
 380      -        if (*(uint64_t *)db->db_data != ZBT_MICRO) {
      383 +        if (zap_block_type != ZBT_MICRO) {
 381  384                  mutex_init(&zap->zap_f.zap_num_entries_mtx, 0, 0, 0);
 382  385                  zap->zap_f.zap_block_shift = highbit64(db->db_size) - 1;
      386 +                if (zap_block_type != ZBT_HEADER || zap_magic != ZAP_MAGIC) {
      387 +                        winner = NULL;  /* No actual winner here... */
      388 +                        goto handle_winner;
      389 +                }
 383  390          } else {
 384  391                  zap->zap_ismicro = TRUE;
 385  392          }
 386  393  
 387  394          /*
 388  395           * Make sure that zap_ismicro is set before we let others see
 389  396           * it, because zap_lockdir() checks zap_ismicro without the lock
 390  397           * held.
 391  398           */
 392  399          dmu_buf_init_user(&zap->zap_dbu, zap_evict, &zap->zap_dbuf);
 393  400          winner = dmu_buf_set_user(db, &zap->zap_dbu);
 394  401  
 395      -        if (winner != NULL) {
 396      -                rw_exit(&zap->zap_rwlock);
 397      -                rw_destroy(&zap->zap_rwlock);
 398      -                if (!zap->zap_ismicro)
 399      -                        mutex_destroy(&zap->zap_f.zap_num_entries_mtx);
 400      -                kmem_free(zap, sizeof (zap_t));
 401      -                return (winner);
 402      -        }
      402 +        if (winner != NULL)
      403 +                goto handle_winner;
 403  404  
 404  405          if (zap->zap_ismicro) {
 405  406                  zap->zap_salt = zap_m_phys(zap)->mz_salt;
 406  407                  zap->zap_normflags = zap_m_phys(zap)->mz_normflags;
 407  408                  zap->zap_m.zap_num_chunks = db->db_size / MZAP_ENT_LEN - 1;
 408  409                  avl_create(&zap->zap_m.zap_avl, mze_compare,
 409  410                      sizeof (mzap_ent_t), offsetof(mzap_ent_t, mze_node));
 410  411  
 411  412                  for (i = 0; i < zap->zap_m.zap_num_chunks; i++) {
 412  413                          mzap_ent_phys_t *mze =
↓ open down ↓ 26 lines elided ↑ open up ↑
 439  440                   * The embedded pointer table should end at the end of
 440  441                   * the block
 441  442                   */
 442  443                  ASSERT3U((uintptr_t)&ZAP_EMBEDDED_PTRTBL_ENT(zap,
 443  444                      1<<ZAP_EMBEDDED_PTRTBL_SHIFT(zap)) -
 444  445                      (uintptr_t)zap_f_phys(zap), ==,
 445  446                      zap->zap_dbuf->db_size);
 446  447          }
 447  448          rw_exit(&zap->zap_rwlock);
 448  449          return (zap);
      450 +
      451 +handle_winner:
      452 +        rw_exit(&zap->zap_rwlock);
      453 +        rw_destroy(&zap->zap_rwlock);
      454 +        if (!zap->zap_ismicro)
      455 +                mutex_destroy(&zap->zap_f.zap_num_entries_mtx);
      456 +        kmem_free(zap, sizeof (zap_t));
      457 +        return (winner);
 449  458  }
 450  459  
 451  460  int
 452  461  zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx,
 453  462      krw_t lti, boolean_t fatreader, boolean_t adding, zap_t **zapp)
 454  463  {
 455  464          zap_t *zap;
 456  465          dmu_buf_t *db;
 457  466          krw_t lt;
 458  467          int err;
↓ open down ↓ 6 lines elided ↑ open up ↑
 465  474  
 466  475  #ifdef ZFS_DEBUG
 467  476          {
 468  477                  dmu_object_info_t doi;
 469  478                  dmu_object_info_from_db(db, &doi);
 470  479                  ASSERT3U(DMU_OT_BYTESWAP(doi.doi_type), ==, DMU_BSWAP_ZAP);
 471  480          }
 472  481  #endif
 473  482  
 474  483          zap = dmu_buf_get_user(db);
 475      -        if (zap == NULL)
      484 +        if (zap == NULL) {
 476  485                  zap = mzap_open(os, obj, db);
      486 +                if (zap == NULL) {
      487 +                        /*
      488 +                         * mzap_open() didn't like what it saw on-disk.
      489 +                         * Check for corruption!
      490 +                         */
      491 +                        dmu_buf_rele(db, NULL);
      492 +                        return (SET_ERROR(EIO));
      493 +                }
      494 +        }
 477  495  
 478  496          /*
 479  497           * We're checking zap_ismicro without the lock held, in order to
 480  498           * tell what type of lock we want.  Once we have some sort of
 481  499           * lock, see if it really is the right type.  In practice this
 482  500           * can only be different if it was upgraded from micro to fat,
 483  501           * and micro wanted WRITER but fat only needs READER.
 484  502           */
 485  503          lt = (!zap->zap_ismicro && fatreader) ? RW_READER : lti;
 486  504          rw_enter(&zap->zap_rwlock, lt);
↓ open down ↓ 933 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX