1eda14cbcSMatt Macy /* 2eda14cbcSMatt Macy * CDDL HEADER START 3eda14cbcSMatt Macy * 4eda14cbcSMatt Macy * The contents of this file are subject to the terms of the 5eda14cbcSMatt Macy * Common Development and Distribution License (the "License"). 6eda14cbcSMatt Macy * You may not use this file except in compliance with the License. 7eda14cbcSMatt Macy * 8eda14cbcSMatt Macy * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9271171e0SMartin Matuska * or https://opensource.org/licenses/CDDL-1.0. 10eda14cbcSMatt Macy * See the License for the specific language governing permissions 11eda14cbcSMatt Macy * and limitations under the License. 12eda14cbcSMatt Macy * 13eda14cbcSMatt Macy * When distributing Covered Code, include this CDDL HEADER in each 14eda14cbcSMatt Macy * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15eda14cbcSMatt Macy * If applicable, add the following below this CDDL HEADER, with the 16eda14cbcSMatt Macy * fields enclosed by brackets "[]" replaced with your own identifying 17eda14cbcSMatt Macy * information: Portions Copyright [yyyy] [name of copyright owner] 18eda14cbcSMatt Macy * 19eda14cbcSMatt Macy * CDDL HEADER END 20eda14cbcSMatt Macy */ 21eda14cbcSMatt Macy 22eda14cbcSMatt Macy #include <sys/zfs_context.h> 23eda14cbcSMatt Macy #include <sys/dbuf.h> 24eda14cbcSMatt Macy #include <sys/dmu_objset.h> 25eda14cbcSMatt Macy 26eda14cbcSMatt Macy /* 27eda14cbcSMatt Macy * Calculate the index of the arc header for the state, disabled by default. 28eda14cbcSMatt Macy */ 29eda14cbcSMatt Macy int zfs_dbuf_state_index = 0; 30eda14cbcSMatt Macy 31eda14cbcSMatt Macy /* 32eda14cbcSMatt Macy * ========================================================================== 33eda14cbcSMatt Macy * Dbuf Hash Read Routines 34eda14cbcSMatt Macy * ========================================================================== 35eda14cbcSMatt Macy */ 36eda14cbcSMatt Macy typedef struct dbuf_stats_t { 37eda14cbcSMatt Macy kmutex_t lock; 38eda14cbcSMatt Macy kstat_t *kstat; 39eda14cbcSMatt Macy dbuf_hash_table_t *hash; 40eda14cbcSMatt Macy int idx; 41eda14cbcSMatt Macy } dbuf_stats_t; 42eda14cbcSMatt Macy 43eda14cbcSMatt Macy static dbuf_stats_t dbuf_stats_hash_table; 44eda14cbcSMatt Macy 45eda14cbcSMatt Macy static int 46eda14cbcSMatt Macy dbuf_stats_hash_table_headers(char *buf, size_t size) 47eda14cbcSMatt Macy { 48eda14cbcSMatt Macy (void) snprintf(buf, size, 49*a2b560ccSMartin Matuska "%-105s | %-119s | %s\n" 50*a2b560ccSMartin Matuska "%-16s %-8s %-8s %-8s %-8s %-10s %-8s %-8s %-5s %-5s %-7s %3s | " 51eda14cbcSMatt Macy "%-5s %-5s %-9s %-6s %-8s %-12s " 52eda14cbcSMatt Macy "%-6s %-6s %-6s %-6s %-6s %-8s %-8s %-8s %-6s | " 53eda14cbcSMatt Macy "%-6s %-6s %-8s %-8s %-6s %-6s %-6s %-8s %-8s\n", 54eda14cbcSMatt Macy "dbuf", "arcbuf", "dnode", "pool", "objset", "object", "level", 55*a2b560ccSMartin Matuska "blkid", "offset", "dbsize", "usize", "meta", "state", "dbholds", 56*a2b560ccSMartin Matuska "dbc", "list", "atype", "flags", "count", "asize", "access", 57eda14cbcSMatt Macy "mru", "gmru", "mfu", "gmfu", "l2", "l2_dattr", "l2_asize", 58eda14cbcSMatt Macy "l2_comp", "aholds", "dtype", "btype", "data_bs", "meta_bs", 59eda14cbcSMatt Macy "bsize", "lvls", "dholds", "blocks", "dsize"); 60eda14cbcSMatt Macy 61eda14cbcSMatt Macy return (0); 62eda14cbcSMatt Macy } 63eda14cbcSMatt Macy 64eda14cbcSMatt Macy static int 65eda14cbcSMatt Macy __dbuf_stats_hash_table_data(char *buf, size_t size, dmu_buf_impl_t *db) 66eda14cbcSMatt Macy { 67eda14cbcSMatt Macy arc_buf_info_t abi = { 0 }; 68eda14cbcSMatt Macy dmu_object_info_t doi = { 0 }; 69eda14cbcSMatt Macy dnode_t *dn = DB_DNODE(db); 70eda14cbcSMatt Macy size_t nwritten; 71eda14cbcSMatt Macy 72eda14cbcSMatt Macy if (db->db_buf) 73eda14cbcSMatt Macy arc_buf_info(db->db_buf, &abi, zfs_dbuf_state_index); 74eda14cbcSMatt Macy 75eda14cbcSMatt Macy __dmu_object_info_from_dnode(dn, &doi); 76eda14cbcSMatt Macy 77eda14cbcSMatt Macy nwritten = snprintf(buf, size, 78*a2b560ccSMartin Matuska "%-16s %-8llu %-8lld %-8lld %-8lld %-10llu %-8llu %-8llu " 79*a2b560ccSMartin Matuska "%-5d %-5d %-7lu %-3d | %-5d %-5d 0x%-7x %-6lu %-8llu %-12llu " 80eda14cbcSMatt Macy "%-6lu %-6lu %-6lu %-6lu %-6lu %-8llu %-8llu %-8d %-6lu | " 81eda14cbcSMatt Macy "%-6d %-6d %-8lu %-8lu %-6llu %-6lu %-6lu %-8llu %-8llu\n", 82eda14cbcSMatt Macy /* dmu_buf_impl_t */ 83eda14cbcSMatt Macy spa_name(dn->dn_objset->os_spa), 84eda14cbcSMatt Macy (u_longlong_t)dmu_objset_id(db->db_objset), 85eda14cbcSMatt Macy (longlong_t)db->db.db_object, 86eda14cbcSMatt Macy (longlong_t)db->db_level, 87eda14cbcSMatt Macy (longlong_t)db->db_blkid, 88eda14cbcSMatt Macy (u_longlong_t)db->db.db_offset, 89eda14cbcSMatt Macy (u_longlong_t)db->db.db_size, 90*a2b560ccSMartin Matuska (u_longlong_t)dmu_buf_user_size(&db->db), 91eda14cbcSMatt Macy !!dbuf_is_metadata(db), 92eda14cbcSMatt Macy db->db_state, 93eda14cbcSMatt Macy (ulong_t)zfs_refcount_count(&db->db_holds), 94eda14cbcSMatt Macy multilist_link_active(&db->db_cache_link), 95eda14cbcSMatt Macy /* arc_buf_info_t */ 96eda14cbcSMatt Macy abi.abi_state_type, 97eda14cbcSMatt Macy abi.abi_state_contents, 98eda14cbcSMatt Macy abi.abi_flags, 99eda14cbcSMatt Macy (ulong_t)abi.abi_bufcnt, 100eda14cbcSMatt Macy (u_longlong_t)abi.abi_size, 101eda14cbcSMatt Macy (u_longlong_t)abi.abi_access, 102eda14cbcSMatt Macy (ulong_t)abi.abi_mru_hits, 103eda14cbcSMatt Macy (ulong_t)abi.abi_mru_ghost_hits, 104eda14cbcSMatt Macy (ulong_t)abi.abi_mfu_hits, 105eda14cbcSMatt Macy (ulong_t)abi.abi_mfu_ghost_hits, 106eda14cbcSMatt Macy (ulong_t)abi.abi_l2arc_hits, 107eda14cbcSMatt Macy (u_longlong_t)abi.abi_l2arc_dattr, 108eda14cbcSMatt Macy (u_longlong_t)abi.abi_l2arc_asize, 109eda14cbcSMatt Macy abi.abi_l2arc_compress, 110eda14cbcSMatt Macy (ulong_t)abi.abi_holds, 111eda14cbcSMatt Macy /* dmu_object_info_t */ 112eda14cbcSMatt Macy doi.doi_type, 113eda14cbcSMatt Macy doi.doi_bonus_type, 114eda14cbcSMatt Macy (ulong_t)doi.doi_data_block_size, 115eda14cbcSMatt Macy (ulong_t)doi.doi_metadata_block_size, 116eda14cbcSMatt Macy (u_longlong_t)doi.doi_bonus_size, 117eda14cbcSMatt Macy (ulong_t)doi.doi_indirection, 118eda14cbcSMatt Macy (ulong_t)zfs_refcount_count(&dn->dn_holds), 119eda14cbcSMatt Macy (u_longlong_t)doi.doi_fill_count, 120eda14cbcSMatt Macy (u_longlong_t)doi.doi_max_offset); 121eda14cbcSMatt Macy 122eda14cbcSMatt Macy if (nwritten >= size) 123eda14cbcSMatt Macy return (size); 124eda14cbcSMatt Macy 125eda14cbcSMatt Macy return (nwritten + 1); 126eda14cbcSMatt Macy } 127eda14cbcSMatt Macy 128eda14cbcSMatt Macy static int 129eda14cbcSMatt Macy dbuf_stats_hash_table_data(char *buf, size_t size, void *data) 130eda14cbcSMatt Macy { 131eda14cbcSMatt Macy dbuf_stats_t *dsh = (dbuf_stats_t *)data; 132eda14cbcSMatt Macy dbuf_hash_table_t *h = dsh->hash; 133eda14cbcSMatt Macy dmu_buf_impl_t *db; 134eda14cbcSMatt Macy int length, error = 0; 135eda14cbcSMatt Macy 136eda14cbcSMatt Macy ASSERT3S(dsh->idx, >=, 0); 137eda14cbcSMatt Macy ASSERT3S(dsh->idx, <=, h->hash_table_mask); 138c40487d4SMatt Macy if (size) 139c40487d4SMatt Macy buf[0] = 0; 140eda14cbcSMatt Macy 141be181ee2SMartin Matuska mutex_enter(DBUF_HASH_MUTEX(h, dsh->idx)); 142eda14cbcSMatt Macy for (db = h->hash_table[dsh->idx]; db != NULL; db = db->db_hash_next) { 143eda14cbcSMatt Macy /* 144eda14cbcSMatt Macy * Returning ENOMEM will cause the data and header functions 145eda14cbcSMatt Macy * to be called with a larger scratch buffers. 146eda14cbcSMatt Macy */ 147eda14cbcSMatt Macy if (size < 512) { 148eda14cbcSMatt Macy error = SET_ERROR(ENOMEM); 149eda14cbcSMatt Macy break; 150eda14cbcSMatt Macy } 151eda14cbcSMatt Macy 152eda14cbcSMatt Macy mutex_enter(&db->db_mtx); 153eda14cbcSMatt Macy 154eda14cbcSMatt Macy if (db->db_state != DB_EVICTING) { 155eda14cbcSMatt Macy length = __dbuf_stats_hash_table_data(buf, size, db); 156eda14cbcSMatt Macy buf += length; 157eda14cbcSMatt Macy size -= length; 158eda14cbcSMatt Macy } 159eda14cbcSMatt Macy 160eda14cbcSMatt Macy mutex_exit(&db->db_mtx); 161eda14cbcSMatt Macy } 162be181ee2SMartin Matuska mutex_exit(DBUF_HASH_MUTEX(h, dsh->idx)); 163eda14cbcSMatt Macy 164eda14cbcSMatt Macy return (error); 165eda14cbcSMatt Macy } 166eda14cbcSMatt Macy 167eda14cbcSMatt Macy static void * 168eda14cbcSMatt Macy dbuf_stats_hash_table_addr(kstat_t *ksp, loff_t n) 169eda14cbcSMatt Macy { 170eda14cbcSMatt Macy dbuf_stats_t *dsh = ksp->ks_private; 171eda14cbcSMatt Macy 172eda14cbcSMatt Macy ASSERT(MUTEX_HELD(&dsh->lock)); 173eda14cbcSMatt Macy 174eda14cbcSMatt Macy if (n <= dsh->hash->hash_table_mask) { 175eda14cbcSMatt Macy dsh->idx = n; 176eda14cbcSMatt Macy return (dsh); 177eda14cbcSMatt Macy } 178eda14cbcSMatt Macy 179eda14cbcSMatt Macy return (NULL); 180eda14cbcSMatt Macy } 181eda14cbcSMatt Macy 182eda14cbcSMatt Macy static void 183eda14cbcSMatt Macy dbuf_stats_hash_table_init(dbuf_hash_table_t *hash) 184eda14cbcSMatt Macy { 185eda14cbcSMatt Macy dbuf_stats_t *dsh = &dbuf_stats_hash_table; 186eda14cbcSMatt Macy kstat_t *ksp; 187eda14cbcSMatt Macy 188eda14cbcSMatt Macy mutex_init(&dsh->lock, NULL, MUTEX_DEFAULT, NULL); 189eda14cbcSMatt Macy dsh->hash = hash; 190eda14cbcSMatt Macy 191eda14cbcSMatt Macy ksp = kstat_create("zfs", 0, "dbufs", "misc", 192eda14cbcSMatt Macy KSTAT_TYPE_RAW, 0, KSTAT_FLAG_VIRTUAL); 193eda14cbcSMatt Macy dsh->kstat = ksp; 194eda14cbcSMatt Macy 195eda14cbcSMatt Macy if (ksp) { 196eda14cbcSMatt Macy ksp->ks_lock = &dsh->lock; 197eda14cbcSMatt Macy ksp->ks_ndata = UINT32_MAX; 198eda14cbcSMatt Macy ksp->ks_private = dsh; 199eda14cbcSMatt Macy kstat_set_raw_ops(ksp, dbuf_stats_hash_table_headers, 200eda14cbcSMatt Macy dbuf_stats_hash_table_data, dbuf_stats_hash_table_addr); 201eda14cbcSMatt Macy kstat_install(ksp); 202eda14cbcSMatt Macy } 203eda14cbcSMatt Macy } 204eda14cbcSMatt Macy 205eda14cbcSMatt Macy static void 206eda14cbcSMatt Macy dbuf_stats_hash_table_destroy(void) 207eda14cbcSMatt Macy { 208eda14cbcSMatt Macy dbuf_stats_t *dsh = &dbuf_stats_hash_table; 209eda14cbcSMatt Macy kstat_t *ksp; 210eda14cbcSMatt Macy 211eda14cbcSMatt Macy ksp = dsh->kstat; 212eda14cbcSMatt Macy if (ksp) 213eda14cbcSMatt Macy kstat_delete(ksp); 214eda14cbcSMatt Macy 215eda14cbcSMatt Macy mutex_destroy(&dsh->lock); 216eda14cbcSMatt Macy } 217eda14cbcSMatt Macy 218eda14cbcSMatt Macy void 219eda14cbcSMatt Macy dbuf_stats_init(dbuf_hash_table_t *hash) 220eda14cbcSMatt Macy { 221eda14cbcSMatt Macy dbuf_stats_hash_table_init(hash); 222eda14cbcSMatt Macy } 223eda14cbcSMatt Macy 224eda14cbcSMatt Macy void 225eda14cbcSMatt Macy dbuf_stats_destroy(void) 226eda14cbcSMatt Macy { 227eda14cbcSMatt Macy dbuf_stats_hash_table_destroy(); 228eda14cbcSMatt Macy } 229eda14cbcSMatt Macy 230eda14cbcSMatt Macy ZFS_MODULE_PARAM(zfs, zfs_, dbuf_state_index, INT, ZMOD_RW, 231eda14cbcSMatt Macy "Calculate arc header index"); 232