Print this page
6367 spa_config_tryenter incorrectly handles the multiple-lock case
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Prashanth Sreenivasa <prashksp@gmail.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Steven Hartland <steven.hartland@multiplay.co.uk>
Approved by: Matthew Ahrens <mahrens@delphix.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/zfs/spa_misc.c
          +++ new/usr/src/uts/common/fs/zfs/spa_misc.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 2011 Nexenta Systems, Inc.  All rights reserved.
       24 + * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
  25   25   * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
       26 + * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  26   27   */
  27   28  
  28   29  #include <sys/zfs_context.h>
  29   30  #include <sys/spa_impl.h>
  30   31  #include <sys/spa_boot.h>
  31   32  #include <sys/zio.h>
  32   33  #include <sys/zio_checksum.h>
  33   34  #include <sys/zio_compress.h>
  34   35  #include <sys/dmu.h>
  35   36  #include <sys/dmu_tx.h>
↓ open down ↓ 342 lines elided ↑ open up ↑
 378  379  spa_config_tryenter(spa_t *spa, int locks, void *tag, krw_t rw)
 379  380  {
 380  381          for (int i = 0; i < SCL_LOCKS; i++) {
 381  382                  spa_config_lock_t *scl = &spa->spa_config_lock[i];
 382  383                  if (!(locks & (1 << i)))
 383  384                          continue;
 384  385                  mutex_enter(&scl->scl_lock);
 385  386                  if (rw == RW_READER) {
 386  387                          if (scl->scl_writer || scl->scl_write_wanted) {
 387  388                                  mutex_exit(&scl->scl_lock);
 388      -                                spa_config_exit(spa, locks ^ (1 << i), tag);
      389 +                                spa_config_exit(spa, locks & ((1 << i) - 1),
      390 +                                    tag);
 389  391                                  return (0);
 390  392                          }
 391  393                  } else {
 392  394                          ASSERT(scl->scl_writer != curthread);
 393  395                          if (!refcount_is_zero(&scl->scl_count)) {
 394  396                                  mutex_exit(&scl->scl_lock);
 395      -                                spa_config_exit(spa, locks ^ (1 << i), tag);
      397 +                                spa_config_exit(spa, locks & ((1 << i) - 1),
      398 +                                    tag);
 396  399                                  return (0);
 397  400                          }
 398  401                          scl->scl_writer = curthread;
 399  402                  }
 400  403                  (void) refcount_add(&scl->scl_count, tag);
 401  404                  mutex_exit(&scl->scl_lock);
 402  405          }
 403  406          return (1);
 404  407  }
 405  408  
↓ open down ↓ 1617 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX