diff options
-rw-r--r-- | cmd/zdb/zdb.c | 19 | ||||
-rw-r--r-- | lib/libzfs/libzfs_diff.c | 7 | ||||
-rw-r--r-- | module/zfs/zfs_znode.c | 11 |
3 files changed, 30 insertions, 7 deletions
diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c index 852f85355..5f56b10e2 100644 --- a/cmd/zdb/zdb.c +++ b/cmd/zdb/zdb.c @@ -106,6 +106,7 @@ uint64_t *zopt_object = NULL; static unsigned zopt_objects = 0; libzfs_handle_t *g_zfs; uint64_t max_inflight = 1000; +static int leaked_objects = 0; static void snprintf_blkptr_compact(char *, size_t, const blkptr_t *); @@ -1983,9 +1984,12 @@ dump_znode(objset_t *os, uint64_t object, void *data, size_t size) if (dump_opt['d'] > 4) { error = zfs_obj_to_path(os, object, path, sizeof (path)); - if (error != 0) { + if (error == ESTALE) { + (void) snprintf(path, sizeof (path), "on delete queue"); + } else if (error != 0) { + leaked_objects++; (void) snprintf(path, sizeof (path), - "\?\?\?<object#%llu>", (u_longlong_t)object); + "path not found, possibly leaked"); } (void) printf("\tpath %s\n", path); } @@ -2376,14 +2380,19 @@ dump_dir(objset_t *os) (double)(max_slot_used - total_slots_used)*100 / (double)max_slot_used); + ASSERT3U(object_count, ==, usedobjs); + (void) printf("\n"); if (error != ESRCH) { (void) fprintf(stderr, "dmu_object_next() = %d\n", error); abort(); } - - ASSERT3U(object_count, ==, usedobjs); + if (leaked_objects != 0) { + (void) printf("%d potentially leaked objects detected\n", + leaked_objects); + leaked_objects = 0; + } } static void @@ -5209,5 +5218,5 @@ main(int argc, char **argv) libzfs_fini(g_zfs); kernel_fini(); - return (0); + return (error); } diff --git a/lib/libzfs/libzfs_diff.c b/lib/libzfs/libzfs_diff.c index 3e0005048..249334acd 100644 --- a/lib/libzfs/libzfs_diff.c +++ b/lib/libzfs/libzfs_diff.c @@ -22,7 +22,7 @@ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2015 Nexenta Systems, Inc. All rights reserved. - * Copyright (c) 2015 by Delphix. All rights reserved. + * Copyright (c) 2015, 2017 by Delphix. All rights reserved. * Copyright 2016 Joyent, Inc. * Copyright 2016 Igor Kozhukhov <[email protected]> */ @@ -103,7 +103,10 @@ get_stats_for_obj(differ_info_t *di, const char *dsname, uint64_t obj, return (0); } - if (di->zerr == EPERM) { + if (di->zerr == ESTALE) { + (void) snprintf(pn, maxlen, "(on_delete_queue)"); + return (0); + } else if (di->zerr == EPERM) { (void) snprintf(di->errbuf, sizeof (di->errbuf), dgettext(TEXT_DOMAIN, "The sys_config privilege or diff delegated permission " diff --git a/module/zfs/zfs_znode.c b/module/zfs/zfs_znode.c index 5288c9c68..c8a613f14 100644 --- a/module/zfs/zfs_znode.c +++ b/module/zfs/zfs_znode.c @@ -2120,6 +2120,17 @@ zfs_obj_to_path_impl(objset_t *osp, uint64_t obj, sa_handle_t *hdl, *path = '\0'; sa_hdl = hdl; + uint64_t deleteq_obj; + VERIFY0(zap_lookup(osp, MASTER_NODE_OBJ, + ZFS_UNLINKED_SET, sizeof (uint64_t), 1, &deleteq_obj)); + error = zap_lookup_int(osp, deleteq_obj, obj); + if (error == 0) { + return (ESTALE); + } else if (error != ENOENT) { + return (error); + } + error = 0; + for (;;) { uint64_t pobj = 0; char component[MAXNAMELEN + 2]; |