From 1759378307a29ad1f09be636e04b762add9d259c Mon Sep 17 00:00:00 2001 From: Alex Zhuravlev <alexey.zhuravlev@intel.com> Date: Wed, 7 May 2014 17:15:01 +0400 Subject: [PATCH 1/2] dump referenced dnodes at umount --- module/zfs/dnode.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/module/zfs/dnode.c b/module/zfs/dnode.c index 5cb5fcc..8e9a46d 100644 --- a/module/zfs/dnode.c +++ b/module/zfs/dnode.c @@ -931,10 +931,52 @@ dnode_move(void *buf, void *newbuf, size_t size, void *arg) } #endif /* _KERNEL */ +#ifdef __KERNEL__ +static void +dbuf_dump_dnodes(dmu_buf_impl_t *db) +{ + dnode_children_t *children_dnodes; + dnode_handle_t *dnh; +#ifdef __ZFS_DEBUG + reference_t *ref; +#endif + dnode_t *dn; + int i, epb; + + children_dnodes = dmu_buf_get_user(&db->db); + if (children_dnodes == NULL) + return; + + epb = db->db.db_size >> DNODE_SHIFT; + + for (i = 0; i < epb-1; i++) { + dnh = &children_dnodes->dnc_children[i]; + if ((dn = dnh->dnh_dnode) == NULL) + continue; + if (refcount_count(&dn->dn_holds) == 0) + continue; + printk(" dnode %Lu, db %p, refcount %d\n", + dn->dn_object, dn->dn_bonus, + (int)refcount_count(&dn->dn_holds)); +#ifdef ZFS_DEBUG + for (ref = list_head(&dn->dn_holds.rc_list); ref; + ref = list_next(&dn->dn_holds.rc_list, ref)) { + printk(" %d, %s\n", (int)ref->ref_number, + (char *)ref->ref_holder); + } +#endif + } +} +#endif + void dnode_special_close(dnode_handle_t *dnh) { dnode_t *dn = dnh->dnh_dnode; +#ifdef __KERNEL__ + dmu_buf_impl_t *db, *db_next; +#endif + int count = 0; /* * Wait for final references to the dnode to clear. This can @@ -942,8 +984,24 @@ dnode_special_close(dnode_handle_t *dnh) * has a hold on this dnode while we are trying to evict this * dnode. */ - while (refcount_count(&dn->dn_holds) > 0) + while (refcount_count(&dn->dn_holds) > 0) { delay(1); + if (++count != 100) + continue; +#ifdef __KERNEL__ + printk("dnode %Lu\n", dn->dn_object); + for (db = list_head(&dn->dn_dbufs); db; db = db_next) { + db_next = list_next(&dn->dn_dbufs, db); + printk("db %p, blkid %Lu -> objid %Lu-%Lu\n", + db, db->db_blkid, + (db->db_blkid << dn->dn_datablkshift) + / sizeof (dnode_phys_t), + ((db->db_blkid+1) << dn->dn_datablkshift) + / sizeof (dnode_phys_t)); + dbuf_dump_dnodes(db); + } +#endif + } zrl_add(&dnh->dnh_zrlock); dnode_destroy(dn); /* implicit zrl_remove() */ zrl_destroy(&dnh->dnh_zrlock); -- 1.9.3 (Apple Git-50)