Author: avg
Date: Tue Feb 18 15:18:08 2014
New Revision: 262171
URL: http://svnweb.freebsd.org/changeset/base/262171

Log:
  MFC r254757: MFV r254749: 4046 dsl_dataset_t ds_dir->dd_lock is highly 
contended
  
  MFC slacker:  delphij

Modified:
  stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
  stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/cddl/contrib/opensolaris/   (props changed)

Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c       
Tue Feb 18 15:07:24 2014        (r262170)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c       
Tue Feb 18 15:18:08 2014        (r262171)
@@ -101,9 +101,8 @@ dsl_dataset_block_born(dsl_dataset_t *ds
                    used, compressed, uncompressed);
                return;
        }
-       dmu_buf_will_dirty(ds->ds_dbuf, tx);
 
-       mutex_enter(&ds->ds_dir->dd_lock);
+       dmu_buf_will_dirty(ds->ds_dbuf, tx);
        mutex_enter(&ds->ds_lock);
        delta = parent_delta(ds, used);
        ds->ds_phys->ds_referenced_bytes += used;
@@ -115,7 +114,6 @@ dsl_dataset_block_born(dsl_dataset_t *ds
            compressed, uncompressed, tx);
        dsl_dir_transfer_space(ds->ds_dir, used - delta,
            DD_USED_REFRSRV, DD_USED_HEAD, tx);
-       mutex_exit(&ds->ds_dir->dd_lock);
 }
 
 int
@@ -150,7 +148,6 @@ dsl_dataset_block_kill(dsl_dataset_t *ds
                dprintf_bp(bp, "freeing ds=%llu", ds->ds_object);
                dsl_free(tx->tx_pool, tx->tx_txg, bp);
 
-               mutex_enter(&ds->ds_dir->dd_lock);
                mutex_enter(&ds->ds_lock);
                ASSERT(ds->ds_phys->ds_unique_bytes >= used ||
                    !DS_UNIQUE_IS_ACCURATE(ds));
@@ -161,7 +158,6 @@ dsl_dataset_block_kill(dsl_dataset_t *ds
                    delta, -compressed, -uncompressed, tx);
                dsl_dir_transfer_space(ds->ds_dir, -used - delta,
                    DD_USED_REFRSRV, DD_USED_HEAD, tx);
-               mutex_exit(&ds->ds_dir->dd_lock);
        } else {
                dprintf_bp(bp, "putting on dead list: %s", "");
                if (async) {
@@ -596,31 +592,6 @@ dsl_dataset_name(dsl_dataset_t *ds, char
        }
 }
 
-static int
-dsl_dataset_namelen(dsl_dataset_t *ds)
-{
-       int result;
-
-       if (ds == NULL) {
-               result = 3;     /* "mos" */
-       } else {
-               result = dsl_dir_namelen(ds->ds_dir);
-               VERIFY0(dsl_dataset_get_snapname(ds));
-               if (ds->ds_snapname[0]) {
-                       ++result;       /* adding one for the @-sign */
-                       if (!MUTEX_HELD(&ds->ds_lock)) {
-                               mutex_enter(&ds->ds_lock);
-                               result += strlen(ds->ds_snapname);
-                               mutex_exit(&ds->ds_lock);
-                       } else {
-                               result += strlen(ds->ds_snapname);
-                       }
-               }
-       }
-
-       return (result);
-}
-
 void
 dsl_dataset_rele(dsl_dataset_t *ds, void *tag)
 {

Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c   Tue Feb 
18 15:07:24 2014        (r262170)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c   Tue Feb 
18 15:18:08 2014        (r262171)
@@ -836,11 +836,21 @@ dsl_dir_diduse_space(dsl_dir_t *dd, dd_u
     int64_t used, int64_t compressed, int64_t uncompressed, dmu_tx_t *tx)
 {
        int64_t accounted_delta;
+
+       /*
+        * dsl_dataset_set_refreservation_sync_impl() calls this with
+        * dd_lock held, so that it can atomically update
+        * ds->ds_reserved and the dsl_dir accounting, so that
+        * dsl_dataset_check_quota() can see dataset and dir accounting
+        * consistently.
+        */
        boolean_t needlock = !MUTEX_HELD(&dd->dd_lock);
 
        ASSERT(dmu_tx_is_syncing(tx));
        ASSERT(type < DD_USED_NUM);
 
+       dmu_buf_will_dirty(dd->dd_dbuf, tx);
+
        if (needlock)
                mutex_enter(&dd->dd_lock);
        accounted_delta = parent_delta(dd, dd->dd_phys->dd_used_bytes, used);
@@ -849,7 +859,6 @@ dsl_dir_diduse_space(dsl_dir_t *dd, dd_u
            dd->dd_phys->dd_compressed_bytes >= -compressed);
        ASSERT(uncompressed >= 0 ||
            dd->dd_phys->dd_uncompressed_bytes >= -uncompressed);
-       dmu_buf_will_dirty(dd->dd_dbuf, tx);
        dd->dd_phys->dd_used_bytes += used;
        dd->dd_phys->dd_uncompressed_bytes += uncompressed;
        dd->dd_phys->dd_compressed_bytes += compressed;
@@ -882,8 +891,6 @@ void
 dsl_dir_transfer_space(dsl_dir_t *dd, int64_t delta,
     dd_used_t oldtype, dd_used_t newtype, dmu_tx_t *tx)
 {
-       boolean_t needlock = !MUTEX_HELD(&dd->dd_lock);
-
        ASSERT(dmu_tx_is_syncing(tx));
        ASSERT(oldtype < DD_USED_NUM);
        ASSERT(newtype < DD_USED_NUM);
@@ -891,17 +898,15 @@ dsl_dir_transfer_space(dsl_dir_t *dd, in
        if (delta == 0 || !(dd->dd_phys->dd_flags & DD_FLAG_USED_BREAKDOWN))
                return;
 
-       if (needlock)
-               mutex_enter(&dd->dd_lock);
+       dmu_buf_will_dirty(dd->dd_dbuf, tx);
+       mutex_enter(&dd->dd_lock);
        ASSERT(delta > 0 ?
            dd->dd_phys->dd_used_breakdown[oldtype] >= delta :
            dd->dd_phys->dd_used_breakdown[newtype] >= -delta);
        ASSERT(dd->dd_phys->dd_used_bytes >= ABS(delta));
-       dmu_buf_will_dirty(dd->dd_dbuf, tx);
        dd->dd_phys->dd_used_breakdown[oldtype] -= delta;
        dd->dd_phys->dd_used_breakdown[newtype] += delta;
-       if (needlock)
-               mutex_exit(&dd->dd_lock);
+       mutex_exit(&dd->dd_lock);
 }
 
 typedef struct dsl_dir_set_qr_arg {
_______________________________________________
svn-src-stable-9@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-stable-9
To unsubscribe, send any mail to "svn-src-stable-9-unsubscr...@freebsd.org"

Reply via email to