The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/openzfs/module/zfs/dataset_kstats.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * CDDL HEADER START
    3  *
    4  * The contents of this file are subject to the terms of the
    5  * Common Development and Distribution License (the "License").
    6  * You may not use this file except in compliance with the License.
    7  *
    8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
    9  * or https://opensource.org/licenses/CDDL-1.0.
   10  * See the License for the specific language governing permissions
   11  * and limitations under the License.
   12  *
   13  * When distributing Covered Code, include this CDDL HEADER in each
   14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
   15  * If applicable, add the following below this CDDL HEADER, with the
   16  * fields enclosed by brackets "[]" replaced with your own identifying
   17  * information: Portions Copyright [yyyy] [name of copyright owner]
   18  *
   19  * CDDL HEADER END
   20  */
   21 
   22 /*
   23  * Copyright (c) 2018 by Delphix. All rights reserved.
   24  * Copyright (c) 2018 Datto Inc.
   25  */
   26 
   27 #include <sys/dataset_kstats.h>
   28 #include <sys/dmu_objset.h>
   29 #include <sys/dsl_dataset.h>
   30 #include <sys/spa.h>
   31 
   32 static dataset_kstat_values_t empty_dataset_kstats = {
   33         { "dataset_name",       KSTAT_DATA_STRING },
   34         { "writes",     KSTAT_DATA_UINT64 },
   35         { "nwritten",   KSTAT_DATA_UINT64 },
   36         { "reads",      KSTAT_DATA_UINT64 },
   37         { "nread",      KSTAT_DATA_UINT64 },
   38         { "nunlinks",   KSTAT_DATA_UINT64 },
   39         { "nunlinked",  KSTAT_DATA_UINT64 },
   40         {
   41         { "zil_commit_count",                   KSTAT_DATA_UINT64 },
   42         { "zil_commit_writer_count",            KSTAT_DATA_UINT64 },
   43         { "zil_itx_count",                      KSTAT_DATA_UINT64 },
   44         { "zil_itx_indirect_count",             KSTAT_DATA_UINT64 },
   45         { "zil_itx_indirect_bytes",             KSTAT_DATA_UINT64 },
   46         { "zil_itx_copied_count",               KSTAT_DATA_UINT64 },
   47         { "zil_itx_copied_bytes",               KSTAT_DATA_UINT64 },
   48         { "zil_itx_needcopy_count",             KSTAT_DATA_UINT64 },
   49         { "zil_itx_needcopy_bytes",             KSTAT_DATA_UINT64 },
   50         { "zil_itx_metaslab_normal_count",      KSTAT_DATA_UINT64 },
   51         { "zil_itx_metaslab_normal_bytes",      KSTAT_DATA_UINT64 },
   52         { "zil_itx_metaslab_slog_count",        KSTAT_DATA_UINT64 },
   53         { "zil_itx_metaslab_slog_bytes",        KSTAT_DATA_UINT64 }
   54         }
   55 };
   56 
   57 static int
   58 dataset_kstats_update(kstat_t *ksp, int rw)
   59 {
   60         dataset_kstats_t *dk = ksp->ks_private;
   61         dataset_kstat_values_t *dkv = ksp->ks_data;
   62         ASSERT3P(dk->dk_kstats->ks_data, ==, dkv);
   63 
   64         if (rw == KSTAT_WRITE)
   65                 return (EACCES);
   66 
   67         dkv->dkv_writes.value.ui64 =
   68             wmsum_value(&dk->dk_sums.dss_writes);
   69         dkv->dkv_nwritten.value.ui64 =
   70             wmsum_value(&dk->dk_sums.dss_nwritten);
   71         dkv->dkv_reads.value.ui64 =
   72             wmsum_value(&dk->dk_sums.dss_reads);
   73         dkv->dkv_nread.value.ui64 =
   74             wmsum_value(&dk->dk_sums.dss_nread);
   75         dkv->dkv_nunlinks.value.ui64 =
   76             wmsum_value(&dk->dk_sums.dss_nunlinks);
   77         dkv->dkv_nunlinked.value.ui64 =
   78             wmsum_value(&dk->dk_sums.dss_nunlinked);
   79 
   80         zil_kstat_values_update(&dkv->dkv_zil_stats, &dk->dk_zil_sums);
   81 
   82         return (0);
   83 }
   84 
   85 int
   86 dataset_kstats_create(dataset_kstats_t *dk, objset_t *objset)
   87 {
   88         /*
   89          * There should not be anything wrong with having kstats for
   90          * snapshots. Since we are not sure how useful they would be
   91          * though nor how much their memory overhead would matter in
   92          * a filesystem with many snapshots, we skip them for now.
   93          */
   94         if (dmu_objset_is_snapshot(objset))
   95                 return (0);
   96 
   97         /*
   98          * At the time of this writing, KSTAT_STRLEN is 255 in Linux,
   99          * and the spa_name can theoretically be up to 256 characters.
  100          * In reality though the spa_name can be 240 characters max
  101          * [see origin directory name check in pool_namecheck()]. Thus,
  102          * the naming scheme for the module name below should not cause
  103          * any truncations. In the event that a truncation does happen
  104          * though, due to some future change, we silently skip creating
  105          * the kstat and log the event.
  106          */
  107         char kstat_module_name[KSTAT_STRLEN];
  108         int n = snprintf(kstat_module_name, sizeof (kstat_module_name),
  109             "zfs/%s", spa_name(dmu_objset_spa(objset)));
  110         if (n < 0) {
  111                 zfs_dbgmsg("failed to create dataset kstat for objset %lld: "
  112                     " snprintf() for kstat module name returned %d",
  113                     (unsigned long long)dmu_objset_id(objset), n);
  114                 return (SET_ERROR(EINVAL));
  115         } else if (n >= KSTAT_STRLEN) {
  116                 zfs_dbgmsg("failed to create dataset kstat for objset %lld: "
  117                     "kstat module name length (%d) exceeds limit (%d)",
  118                     (unsigned long long)dmu_objset_id(objset),
  119                     n, KSTAT_STRLEN);
  120                 return (SET_ERROR(ENAMETOOLONG));
  121         }
  122 
  123         char kstat_name[KSTAT_STRLEN];
  124         n = snprintf(kstat_name, sizeof (kstat_name), "objset-0x%llx",
  125             (unsigned long long)dmu_objset_id(objset));
  126         if (n < 0) {
  127                 zfs_dbgmsg("failed to create dataset kstat for objset %lld: "
  128                     " snprintf() for kstat name returned %d",
  129                     (unsigned long long)dmu_objset_id(objset), n);
  130                 return (SET_ERROR(EINVAL));
  131         } else if (n >= KSTAT_STRLEN) {
  132                 zfs_dbgmsg("failed to create dataset kstat for objset %lld: "
  133                     "kstat name length (%d) exceeds limit (%d)",
  134                     (unsigned long long)dmu_objset_id(objset),
  135                     n, KSTAT_STRLEN);
  136                 return (SET_ERROR(ENAMETOOLONG));
  137         }
  138 
  139         kstat_t *kstat = kstat_create(kstat_module_name, 0, kstat_name,
  140             "dataset", KSTAT_TYPE_NAMED,
  141             sizeof (empty_dataset_kstats) / sizeof (kstat_named_t),
  142             KSTAT_FLAG_VIRTUAL);
  143         if (kstat == NULL)
  144                 return (SET_ERROR(ENOMEM));
  145 
  146         dataset_kstat_values_t *dk_kstats =
  147             kmem_alloc(sizeof (empty_dataset_kstats), KM_SLEEP);
  148         memcpy(dk_kstats, &empty_dataset_kstats,
  149             sizeof (empty_dataset_kstats));
  150 
  151         char *ds_name = kmem_zalloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
  152         dsl_dataset_name(objset->os_dsl_dataset, ds_name);
  153         KSTAT_NAMED_STR_PTR(&dk_kstats->dkv_ds_name) = ds_name;
  154         KSTAT_NAMED_STR_BUFLEN(&dk_kstats->dkv_ds_name) =
  155             ZFS_MAX_DATASET_NAME_LEN;
  156 
  157         kstat->ks_data = dk_kstats;
  158         kstat->ks_update = dataset_kstats_update;
  159         kstat->ks_private = dk;
  160         kstat->ks_data_size += ZFS_MAX_DATASET_NAME_LEN;
  161 
  162         wmsum_init(&dk->dk_sums.dss_writes, 0);
  163         wmsum_init(&dk->dk_sums.dss_nwritten, 0);
  164         wmsum_init(&dk->dk_sums.dss_reads, 0);
  165         wmsum_init(&dk->dk_sums.dss_nread, 0);
  166         wmsum_init(&dk->dk_sums.dss_nunlinks, 0);
  167         wmsum_init(&dk->dk_sums.dss_nunlinked, 0);
  168         zil_sums_init(&dk->dk_zil_sums);
  169 
  170         dk->dk_kstats = kstat;
  171         kstat_install(kstat);
  172         return (0);
  173 }
  174 
  175 void
  176 dataset_kstats_destroy(dataset_kstats_t *dk)
  177 {
  178         if (dk->dk_kstats == NULL)
  179                 return;
  180 
  181         dataset_kstat_values_t *dkv = dk->dk_kstats->ks_data;
  182         kstat_delete(dk->dk_kstats);
  183         dk->dk_kstats = NULL;
  184         kmem_free(KSTAT_NAMED_STR_PTR(&dkv->dkv_ds_name),
  185             KSTAT_NAMED_STR_BUFLEN(&dkv->dkv_ds_name));
  186         kmem_free(dkv, sizeof (empty_dataset_kstats));
  187 
  188         wmsum_fini(&dk->dk_sums.dss_writes);
  189         wmsum_fini(&dk->dk_sums.dss_nwritten);
  190         wmsum_fini(&dk->dk_sums.dss_reads);
  191         wmsum_fini(&dk->dk_sums.dss_nread);
  192         wmsum_fini(&dk->dk_sums.dss_nunlinks);
  193         wmsum_fini(&dk->dk_sums.dss_nunlinked);
  194         zil_sums_fini(&dk->dk_zil_sums);
  195 }
  196 
  197 void
  198 dataset_kstats_update_write_kstats(dataset_kstats_t *dk,
  199     int64_t nwritten)
  200 {
  201         ASSERT3S(nwritten, >=, 0);
  202 
  203         if (dk->dk_kstats == NULL)
  204                 return;
  205 
  206         wmsum_add(&dk->dk_sums.dss_writes, 1);
  207         wmsum_add(&dk->dk_sums.dss_nwritten, nwritten);
  208 }
  209 
  210 void
  211 dataset_kstats_update_read_kstats(dataset_kstats_t *dk,
  212     int64_t nread)
  213 {
  214         ASSERT3S(nread, >=, 0);
  215 
  216         if (dk->dk_kstats == NULL)
  217                 return;
  218 
  219         wmsum_add(&dk->dk_sums.dss_reads, 1);
  220         wmsum_add(&dk->dk_sums.dss_nread, nread);
  221 }
  222 
  223 void
  224 dataset_kstats_update_nunlinks_kstat(dataset_kstats_t *dk, int64_t delta)
  225 {
  226         if (dk->dk_kstats == NULL)
  227                 return;
  228 
  229         wmsum_add(&dk->dk_sums.dss_nunlinks, delta);
  230 }
  231 
  232 void
  233 dataset_kstats_update_nunlinked_kstat(dataset_kstats_t *dk, int64_t delta)
  234 {
  235         if (dk->dk_kstats == NULL)
  236                 return;
  237 
  238         wmsum_add(&dk->dk_sums.dss_nunlinked, delta);
  239 }

Cache object: 3a3c9fbc3de7a72a4f384836128790be


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.