Mercurial > illumos > illumos-gate
comparison usr/src/lib/libzfs/common/libzfs_dataset.c @ 14060:aeb4e8fef072
3829 fix for 3740 changed behavior of zfs destroy/hold/release ioctl
Reviewed by: Matt Amdur <matt.amdur@delphix.com>
Reviewed by: Christopher Siden <christopher.siden@delphix.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
author | Matthew Ahrens <mahrens@delphix.com> |
---|---|
date | Thu, 20 Jun 2013 14:43:17 -0800 |
parents | 1a272fe1337b |
children | 520f3adc5d46 |
comparison
equal
deleted
inserted
replaced
14059:1a63e2c4c1b9 | 14060:aeb4e8fef072 |
---|---|
19 * CDDL HEADER END | 19 * CDDL HEADER END |
20 */ | 20 */ |
21 | 21 |
22 /* | 22 /* |
23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. | 23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. |
24 * Copyright (c) 2012 by Delphix. All rights reserved. | 24 * Copyright (c) 2013 by Delphix. All rights reserved. |
25 * Copyright (c) 2012 DEY Storage Systems, Inc. All rights reserved. | 25 * Copyright (c) 2012 DEY Storage Systems, Inc. All rights reserved. |
26 * Copyright 2012 Nexenta Systems, Inc. All rights reserved. | 26 * Copyright 2012 Nexenta Systems, Inc. All rights reserved. |
27 * Copyright (c) 2013 Martin Matuska. All rights reserved. | 27 * Copyright (c) 2013 Martin Matuska. All rights reserved. |
28 * Copyright (c) 2013 Steven Hartland. All rights reserved. | 28 * Copyright (c) 2013 Steven Hartland. All rights reserved. |
29 */ | 29 */ |
4071 struct holdarg { | 4071 struct holdarg { |
4072 nvlist_t *nvl; | 4072 nvlist_t *nvl; |
4073 const char *snapname; | 4073 const char *snapname; |
4074 const char *tag; | 4074 const char *tag; |
4075 boolean_t recursive; | 4075 boolean_t recursive; |
4076 int error; | |
4076 }; | 4077 }; |
4077 | 4078 |
4078 static int | 4079 static int |
4079 zfs_hold_one(zfs_handle_t *zhp, void *arg) | 4080 zfs_hold_one(zfs_handle_t *zhp, void *arg) |
4080 { | 4081 { |
4198 zfs_release_one(zfs_handle_t *zhp, void *arg) | 4199 zfs_release_one(zfs_handle_t *zhp, void *arg) |
4199 { | 4200 { |
4200 struct holdarg *ha = arg; | 4201 struct holdarg *ha = arg; |
4201 char name[ZFS_MAXNAMELEN]; | 4202 char name[ZFS_MAXNAMELEN]; |
4202 int rv = 0; | 4203 int rv = 0; |
4204 nvlist_t *existing_holds; | |
4203 | 4205 |
4204 (void) snprintf(name, sizeof (name), | 4206 (void) snprintf(name, sizeof (name), |
4205 "%s@%s", zhp->zfs_name, ha->snapname); | 4207 "%s@%s", zhp->zfs_name, ha->snapname); |
4206 | 4208 |
4207 if (lzc_exists(name)) { | 4209 if (lzc_get_holds(name, &existing_holds) != 0) { |
4208 nvlist_t *holds = fnvlist_alloc(); | 4210 ha->error = ENOENT; |
4209 fnvlist_add_boolean(holds, ha->tag); | 4211 } else if (!nvlist_exists(existing_holds, ha->tag)) { |
4210 fnvlist_add_nvlist(ha->nvl, name, holds); | 4212 ha->error = ESRCH; |
4211 fnvlist_free(holds); | 4213 } else { |
4214 nvlist_t *torelease = fnvlist_alloc(); | |
4215 fnvlist_add_boolean(torelease, ha->tag); | |
4216 fnvlist_add_nvlist(ha->nvl, name, torelease); | |
4217 fnvlist_free(torelease); | |
4212 } | 4218 } |
4213 | 4219 |
4214 if (ha->recursive) | 4220 if (ha->recursive) |
4215 rv = zfs_iter_filesystems(zhp, zfs_release_one, ha); | 4221 rv = zfs_iter_filesystems(zhp, zfs_release_one, ha); |
4216 zfs_close(zhp); | 4222 zfs_close(zhp); |
4230 | 4236 |
4231 ha.nvl = fnvlist_alloc(); | 4237 ha.nvl = fnvlist_alloc(); |
4232 ha.snapname = snapname; | 4238 ha.snapname = snapname; |
4233 ha.tag = tag; | 4239 ha.tag = tag; |
4234 ha.recursive = recursive; | 4240 ha.recursive = recursive; |
4241 ha.error = 0; | |
4235 (void) zfs_release_one(zfs_handle_dup(zhp), &ha); | 4242 (void) zfs_release_one(zfs_handle_dup(zhp), &ha); |
4236 | 4243 |
4237 if (nvlist_empty(ha.nvl)) { | 4244 if (nvlist_empty(ha.nvl)) { |
4238 fnvlist_free(ha.nvl); | 4245 fnvlist_free(ha.nvl); |
4239 ret = ENOENT; | 4246 ret = ha.error; |
4240 (void) snprintf(errbuf, sizeof (errbuf), | 4247 (void) snprintf(errbuf, sizeof (errbuf), |
4241 dgettext(TEXT_DOMAIN, | 4248 dgettext(TEXT_DOMAIN, |
4242 "cannot release hold from snapshot '%s@%s'"), | 4249 "cannot release hold from snapshot '%s@%s'"), |
4243 zhp->zfs_name, snapname); | 4250 zhp->zfs_name, snapname); |
4244 (void) zfs_standard_error(hdl, ret, errbuf); | 4251 if (ret == ESRCH) { |
4252 (void) zfs_error(hdl, EZFS_REFTAG_RELE, errbuf); | |
4253 } else { | |
4254 (void) zfs_standard_error(hdl, ret, errbuf); | |
4255 } | |
4245 return (ret); | 4256 return (ret); |
4246 } | 4257 } |
4247 | 4258 |
4248 ret = lzc_release(ha.nvl, &errors); | 4259 ret = lzc_release(ha.nvl, &errors); |
4249 fnvlist_free(ha.nvl); | 4260 fnvlist_free(ha.nvl); |