Print this page
5056 ZFS deadlock on db_mtx and dn_holds
Reviewed by: Will Andrews <willa@spectralogic.com>
Reviewed by: Matt Ahrens <mahrens@delphix.com>
Reviewed by: George Wilson <george.wilson@delphix.com>
Approved by: Dan McDonald <danmcd@omniti.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 ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23   23   * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
       24 + * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
  24   25   */
  25   26  
  26   27  #include <sys/zio.h>
  27   28  #include <sys/spa.h>
  28   29  #include <sys/dmu.h>
  29   30  #include <sys/zfs_context.h>
  30   31  #include <sys/zap.h>
  31   32  #include <sys/refcount.h>
  32   33  #include <sys/zap_impl.h>
  33   34  #include <sys/zap_leaf.h>
↓ open down ↓ 346 lines elided ↑ open up ↑
 380  381                  zap->zap_f.zap_block_shift = highbit64(db->db_size) - 1;
 381  382          } else {
 382  383                  zap->zap_ismicro = TRUE;
 383  384          }
 384  385  
 385  386          /*
 386  387           * Make sure that zap_ismicro is set before we let others see
 387  388           * it, because zap_lockdir() checks zap_ismicro without the lock
 388  389           * held.
 389  390           */
 390      -        winner = dmu_buf_set_user(db, zap, zap_evict);
      391 +        dmu_buf_init_user(&zap->zap_dbu, zap_evict, &zap->zap_dbuf);
      392 +        winner = dmu_buf_set_user(db, &zap->zap_dbu);
 391  393  
 392  394          if (winner != NULL) {
 393  395                  rw_exit(&zap->zap_rwlock);
 394  396                  rw_destroy(&zap->zap_rwlock);
 395  397                  if (!zap->zap_ismicro)
 396  398                          mutex_destroy(&zap->zap_f.zap_num_entries_mtx);
 397  399                  kmem_free(zap, sizeof (zap_t));
 398  400                  return (winner);
 399  401          }
 400  402  
↓ open down ↓ 271 lines elided ↑ open up ↑
 672  674  {
 673  675          /*
 674  676           * dmu_object_free will free the object number and free the
 675  677           * data.  Freeing the data will cause our pageout function to be
 676  678           * called, which will destroy our data (zap_leaf_t's and zap_t).
 677  679           */
 678  680  
 679  681          return (dmu_object_free(os, zapobj, tx));
 680  682  }
 681  683  
 682      -_NOTE(ARGSUSED(0))
 683  684  void
 684      -zap_evict(dmu_buf_t *db, void *vzap)
      685 +zap_evict(void *dbu)
 685  686  {
 686      -        zap_t *zap = vzap;
      687 +        zap_t *zap = dbu;
 687  688  
 688  689          rw_destroy(&zap->zap_rwlock);
 689  690  
 690  691          if (zap->zap_ismicro)
 691  692                  mze_destroy(zap);
 692  693          else
 693  694                  mutex_destroy(&zap->zap_f.zap_num_entries_mtx);
 694  695  
 695  696          kmem_free(zap, sizeof (zap_t));
 696  697  }
↓ open down ↓ 721 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX