changeset 10268:cb380b2e9410

6868130 ZFS hold/release "zfs hold -r tag snapshot" failed to check the existence of snapshot
author Chris Kirby <chris.kirby@sun.com>
date Thu, 06 Aug 2009 09:10:03 -0600
parents dd1cf2c420df
children 2788675568fd
files usr/src/lib/pyzfs/common/dataset.py usr/src/lib/pyzfs/common/holds.py usr/src/uts/common/fs/zfs/dsl_dataset.c
diffstat 3 files changed, 20 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/lib/pyzfs/common/dataset.py	Wed Aug 05 23:09:01 2009 -0700
+++ b/usr/src/lib/pyzfs/common/dataset.py	Thu Aug 06 09:10:03 2009 -0600
@@ -213,12 +213,16 @@
 
 def snapshots_fromcmdline(dsnames, recursive):
 	for dsname in dsnames:
-		ds = Dataset(dsname)
 		if not "@" in dsname:
 			raise zfs.util.ZFSError(errno.EINVAL,
 			    _("cannot open %s") % dsname,
 			    _("operation only applies to snapshots"))
-		yield ds
+		try:
+			ds = Dataset(dsname)
+			yield ds
+		except zfs.util.ZFSError, e:
+			if not recursive or e.errno != errno.ENOENT:
+				raise
 		if recursive:
 			(base, snapname) = dsname.split('@')
 			parent = Dataset(base)
--- a/usr/src/lib/pyzfs/common/holds.py	Wed Aug 05 23:09:01 2009 -0700
+++ b/usr/src/lib/pyzfs/common/holds.py	Thu Aug 06 09:10:03 2009 -0600
@@ -61,8 +61,10 @@
 	fields = ("name", "tag", "timestamp")
 	rjustfields = ()
 	printing = False 
+	gotone = False
 	t = zfs.table.Table(fields, rjustfields) 
 	for ds in zfs.dataset.snapshots_fromcmdline(args, options.recursive):
+		gotone = True
 		for tag, tm in ds.get_holds().iteritems():
 			val = {"name": ds.name, "tag": tag,
 			    "timestamp": time.ctime(tm)}
@@ -70,3 +72,5 @@
 			printing = True
 	if printing:
 		t.printme()
+	elif not gotone:
+		raise zfs.util.ZFSError(errno.ENOENT, _("no matching datasets"))
--- a/usr/src/uts/common/fs/zfs/dsl_dataset.c	Wed Aug 05 23:09:01 2009 -0700
+++ b/usr/src/uts/common/fs/zfs/dsl_dataset.c	Thu Aug 06 09:10:03 2009 -0600
@@ -3470,6 +3470,7 @@
 	char *htag;
 	char *snapname;
 	boolean_t recursive;
+	boolean_t gotone;
 	char failed[MAXPATHLEN];
 };
 
@@ -3489,6 +3490,7 @@
 	error = dsl_dataset_hold(name, ha->dstg, &ds);
 	kmem_free(name, buflen);
 	if (error == 0) {
+		ha->gotone = B_TRUE;
 		dsl_sync_task_create(ha->dstg, dsl_dataset_user_hold_check,
 		    dsl_dataset_user_hold_sync, ds, ha->htag, 0);
 	} else if (error == ENOENT && ha->recursive) {
@@ -3542,6 +3544,9 @@
 		dsl_dataset_rele(ds, ha->dstg);
 	}
 
+	if (error == 0 && recursive && !ha->gotone)
+		error = ENOENT;
+
 	if (error)
 		(void) strcpy(dsname, ha->failed);
 
@@ -3692,6 +3697,8 @@
 	if (error)
 		return (error);
 
+	ha->gotone = B_TRUE;
+
 	ASSERT(dsl_dataset_is_snapshot(ds));
 
 	error = dsl_dataset_release_might_destroy(ds, ha->htag, &might_destroy);
@@ -3781,6 +3788,9 @@
 		kmem_free(ra, sizeof (struct dsl_ds_releasearg));
 	}
 
+	if (error == 0 && recursive && !ha->gotone)
+		error = ENOENT;
+
 	if (error)
 		(void) strcpy(dsname, ha->failed);