Mercurial > illumos > illumos-gate
diff usr/src/uts/common/fs/zfs/dsl_dataset.c @ 12527:693dd2cad55f
6884007 zfs_send() can leave temporary holds around
6954429 ZFS_IOC_VDEV_SPLIT missing from truss/codes.c
author | Chris Kirby <Chris.Kirby@oracle.com> |
---|---|
date | Tue, 01 Jun 2010 17:04:42 -0600 |
parents | 54258108784b |
children | 16aef3d16470 |
line wrap: on
line diff
--- a/usr/src/uts/common/fs/zfs/dsl_dataset.c Tue Jun 01 17:33:59 2010 -0400 +++ b/usr/src/uts/common/fs/zfs/dsl_dataset.c Tue Jun 01 17:04:42 2010 -0600 @@ -37,6 +37,7 @@ #include <sys/zfs_ioctl.h> #include <sys/spa.h> #include <sys/zfs_znode.h> +#include <sys/zfs_onexit.h> #include <sys/zvol.h> #include <sys/dsl_scan.h> #include <sys/dsl_deadlist.h> @@ -3421,6 +3422,23 @@ char failed[MAXPATHLEN]; }; +typedef struct zfs_hold_cleanup_arg { + char dsname[MAXNAMELEN]; + char snapname[MAXNAMELEN]; + char htag[MAXNAMELEN]; + boolean_t recursive; +} zfs_hold_cleanup_arg_t; + +static void +dsl_dataset_user_release_onexit(void *arg) +{ + zfs_hold_cleanup_arg_t *ca = arg; + + (void) dsl_dataset_user_release(ca->dsname, ca->snapname, + ca->htag, ca->recursive); + kmem_free(ca, sizeof (zfs_hold_cleanup_arg_t)); +} + /* * The max length of a temporary tag prefix is the number of hex digits * required to express UINT64_MAX plus one for the hyphen. @@ -3525,7 +3543,7 @@ int dsl_dataset_user_hold(char *dsname, char *snapname, char *htag, - boolean_t recursive, boolean_t temphold) + boolean_t recursive, boolean_t temphold, int cleanup_fd) { struct dsl_ds_holdarg *ha; dsl_sync_task_t *dst; @@ -3547,6 +3565,7 @@ ha->snapname = snapname; ha->recursive = recursive; ha->temphold = temphold; + if (recursive) { error = dmu_objset_find(dsname, dsl_dataset_user_hold_one, ha, DS_FIND_CHILDREN); @@ -3574,6 +3593,24 @@ (void) strlcpy(dsname, ha->failed, sizeof (ha->failed)); dsl_sync_task_group_destroy(ha->dstg); + + /* + * If this set of temporary holds is to be removed upon process exit, + * register that action now. + */ + if (error == 0 && cleanup_fd != -1 && temphold) { + zfs_hold_cleanup_arg_t *ca; + uint64_t action_handle; + + ca = kmem_alloc(sizeof (zfs_hold_cleanup_arg_t), KM_SLEEP); + (void) strlcpy(ca->dsname, dsname, sizeof (ca->dsname)); + (void) strlcpy(ca->snapname, snapname, sizeof (ca->snapname)); + (void) strlcpy(ca->htag, htag, sizeof (ca->htag)); + ca->recursive = recursive; + ASSERT3U(0, ==, zfs_onexit_add_cb(cleanup_fd, + dsl_dataset_user_release_onexit, ca, &action_handle)); + } + kmem_free(ha, sizeof (struct dsl_ds_holdarg)); spa_close(spa, FTAG); return (error);