Print this page
*** NO COMMENTS ***

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/zfs/dsl_dataset.c
          +++ new/usr/src/uts/common/fs/zfs/dsl_dataset.c
↓ open down ↓ 281 lines elided ↑ open up ↑
 282  282          } else {
 283  283                  ASSERT(ds->ds_deadlist.dl_dbuf == NULL);
 284  284                  ASSERT(!ds->ds_deadlist.dl_oldfmt);
 285  285          }
 286  286          if (ds->ds_dir)
 287  287                  dsl_dir_close(ds->ds_dir, ds);
 288  288  
 289  289          ASSERT(!list_link_active(&ds->ds_synced_link));
 290  290  
 291  291          mutex_destroy(&ds->ds_lock);
 292      -        mutex_destroy(&ds->ds_recvlock);
 293  292          mutex_destroy(&ds->ds_opening_lock);
 294  293          rw_destroy(&ds->ds_rwlock);
 295  294          cv_destroy(&ds->ds_exclusive_cv);
 296  295  
 297  296          kmem_free(ds, sizeof (dsl_dataset_t));
 298  297  }
 299  298  
 300  299  static int
 301  300  dsl_dataset_get_snapname(dsl_dataset_t *ds)
 302  301  {
↓ open down ↓ 85 lines elided ↑ open up ↑
 388  387          ds = dmu_buf_get_user(dbuf);
 389  388          if (ds == NULL) {
 390  389                  dsl_dataset_t *winner;
 391  390  
 392  391                  ds = kmem_zalloc(sizeof (dsl_dataset_t), KM_SLEEP);
 393  392                  ds->ds_dbuf = dbuf;
 394  393                  ds->ds_object = dsobj;
 395  394                  ds->ds_phys = dbuf->db_data;
 396  395  
 397  396                  mutex_init(&ds->ds_lock, NULL, MUTEX_DEFAULT, NULL);
 398      -                mutex_init(&ds->ds_recvlock, NULL, MUTEX_DEFAULT, NULL);
 399  397                  mutex_init(&ds->ds_opening_lock, NULL, MUTEX_DEFAULT, NULL);
 400  398                  mutex_init(&ds->ds_sendstream_lock, NULL, MUTEX_DEFAULT, NULL);
 401  399  
 402  400                  rw_init(&ds->ds_rwlock, 0, 0, 0);
 403  401                  cv_init(&ds->ds_exclusive_cv, NULL, CV_DEFAULT, NULL);
 404  402  
 405  403                  bplist_create(&ds->ds_pending_deadlist);
 406  404                  dsl_deadlist_open(&ds->ds_deadlist,
 407  405                      mos, ds->ds_phys->ds_deadlist_obj);
 408  406  
 409  407                  list_create(&ds->ds_sendstreams, sizeof (dmu_sendarg_t),
 410  408                      offsetof(dmu_sendarg_t, dsa_link));
 411  409  
 412  410                  if (err == 0) {
 413  411                          err = dsl_dir_open_obj(dp,
 414  412                              ds->ds_phys->ds_dir_obj, NULL, ds, &ds->ds_dir);
 415  413                  }
 416  414                  if (err) {
 417  415                          mutex_destroy(&ds->ds_lock);
 418      -                        mutex_destroy(&ds->ds_recvlock);
 419  416                          mutex_destroy(&ds->ds_opening_lock);
 420  417                          rw_destroy(&ds->ds_rwlock);
 421  418                          cv_destroy(&ds->ds_exclusive_cv);
 422  419                          bplist_destroy(&ds->ds_pending_deadlist);
 423  420                          dsl_deadlist_close(&ds->ds_deadlist);
 424  421                          kmem_free(ds, sizeof (dsl_dataset_t));
 425  422                          dmu_buf_rele(dbuf, tag);
 426  423                          return (err);
 427  424                  }
 428  425  
↓ open down ↓ 47 lines elided ↑ open up ↑
 476  473                          winner = dmu_buf_set_user_ie(dbuf, ds, &ds->ds_phys,
 477  474                              dsl_dataset_evict);
 478  475                  }
 479  476                  if (err || winner) {
 480  477                          bplist_destroy(&ds->ds_pending_deadlist);
 481  478                          dsl_deadlist_close(&ds->ds_deadlist);
 482  479                          if (ds->ds_prev)
 483  480                                  dsl_dataset_drop_ref(ds->ds_prev, ds);
 484  481                          dsl_dir_close(ds->ds_dir, ds);
 485  482                          mutex_destroy(&ds->ds_lock);
 486      -                        mutex_destroy(&ds->ds_recvlock);
 487  483                          mutex_destroy(&ds->ds_opening_lock);
 488  484                          rw_destroy(&ds->ds_rwlock);
 489  485                          cv_destroy(&ds->ds_exclusive_cv);
 490  486                          kmem_free(ds, sizeof (dsl_dataset_t));
 491  487                          if (err) {
 492  488                                  dmu_buf_rele(dbuf, tag);
 493  489                                  return (err);
 494  490                          }
 495  491                          ds = winner;
 496  492                  } else {
↓ open down ↓ 42 lines elided ↑ open up ↑
 539  535           * If the dataset is being destroyed, the destroy thread will
 540  536           * obtain a WRITER lock for exclusive access after it's done its
 541  537           * open-context work and then change the ds_owner to
 542  538           * dsl_reaper once destruction is assured.  So threads
 543  539           * may block here temporarily, until the "destructability" of
 544  540           * the dataset is determined.
 545  541           */
 546  542          ASSERT(!RW_WRITE_HELD(&dp->dp_config_rwlock));
 547  543          mutex_enter(&ds->ds_lock);
 548  544          while (!rw_tryenter(&ds->ds_rwlock, RW_READER)) {
      545 +                int rc;
      546 +
 549  547                  rw_exit(&dp->dp_config_rwlock);
 550      -                cv_wait(&ds->ds_exclusive_cv, &ds->ds_lock);
 551      -                if (DSL_DATASET_IS_DESTROYED(ds)) {
      548 +                rc = cv_wait_sig(&ds->ds_exclusive_cv, &ds->ds_lock);
      549 +                if (!rc || DSL_DATASET_IS_DESTROYED(ds)) {
 552  550                          mutex_exit(&ds->ds_lock);
 553  551                          dsl_dataset_drop_ref(ds, tag);
 554  552                          rw_enter(&dp->dp_config_rwlock, RW_READER);
 555      -                        return (ENOENT);
      553 +                        return (rc ? ENOENT : EINTR);
 556  554                  }
 557  555                  /*
 558  556                   * The dp_config_rwlock lives above the ds_lock. And
 559  557                   * we need to check DSL_DATASET_IS_DESTROYED() while
 560  558                   * holding the ds_lock, so we have to drop and reacquire
 561  559                   * the ds_lock here.
 562  560                   */
 563  561                  mutex_exit(&ds->ds_lock);
 564  562                  rw_enter(&dp->dp_config_rwlock, RW_READER);
 565  563                  mutex_enter(&ds->ds_lock);
↓ open down ↓ 3748 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX