aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd/zdb/zdb.c19
-rw-r--r--lib/libzfs/libzfs_diff.c7
-rw-r--r--module/zfs/zfs_znode.c11
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];