Mercurial > illumos > illumos-gate
changeset 10951:56fd5475e8fe
6896756 assertion failed: 0 == dsl_pool_user_hold(dp, ds->ds_object, htag, &now, tx)
6897005 zfs holds broken on 32-bit i86pc
author | Chris Kirby <Chris.Kirby@sun.com> |
---|---|
date | Wed, 04 Nov 2009 09:10:12 -0700 |
parents | 588ee15c1f19 |
children | b08b5e896bbd |
files | usr/src/lib/libzfs/common/libzfs_dataset.c usr/src/uts/common/fs/zfs/dsl_dataset.c usr/src/uts/common/fs/zfs/dsl_pool.c usr/src/uts/common/fs/zfs/sys/dsl_pool.h |
diffstat | 4 files changed, 24 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/lib/libzfs/common/libzfs_dataset.c Wed Nov 04 07:57:07 2009 -0700 +++ b/usr/src/lib/libzfs/common/libzfs_dataset.c Wed Nov 04 09:10:12 2009 -0700 @@ -3714,6 +3714,14 @@ (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, "cannot hold '%s@%s'"), zc.zc_name, snapname); switch (errno) { + case E2BIG: + /* + * Temporary tags wind up having the ds object id + * prepended. So even if we passed the length check + * above, it's still possible for the tag to wind + * up being slightly too long. + */ + return (zfs_error(hdl, EZFS_TAGTOOLONG, errbuf)); case ENOTSUP: zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be upgraded"));
--- a/usr/src/uts/common/fs/zfs/dsl_dataset.c Wed Nov 04 07:57:07 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/dsl_dataset.c Wed Nov 04 09:10:12 2009 -0700 @@ -3239,6 +3239,12 @@ char failed[MAXPATHLEN]; }; +/* + * The max length of a temporary tag prefix is the number of hex digits + * required to express UINT64_MAX plus one for the hyphen. + */ +#define MAX_TAG_PREFIX_LEN 17 + static int dsl_dataset_user_hold_check(void *arg1, void *arg2, dmu_tx_t *tx) { @@ -3266,6 +3272,10 @@ } mutex_exit(&ds->ds_lock); + if (error == 0 && ha->temphold && + strlen(htag) + MAX_TAG_PREFIX_LEN >= MAXNAMELEN) + error = E2BIG; + return (error); } @@ -3277,7 +3287,7 @@ char *htag = ha->htag; dsl_pool_t *dp = ds->ds_dir->dd_pool; objset_t *mos = dp->dp_meta_objset; - time_t now = gethrestime_sec(); + uint64_t now = gethrestime_sec(); uint64_t zapobj; mutex_enter(&ds->ds_lock);
--- a/usr/src/uts/common/fs/zfs/dsl_pool.c Wed Nov 04 07:57:07 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/dsl_pool.c Wed Nov 04 09:10:12 2009 -0700 @@ -722,7 +722,7 @@ static int dsl_pool_user_hold_rele_impl(dsl_pool_t *dp, uint64_t dsobj, - const char *tag, time_t *t, dmu_tx_t *tx, boolean_t holding) + const char *tag, uint64_t *now, dmu_tx_t *tx, boolean_t holding) { objset_t *mos = dp->dp_meta_objset; uint64_t zapobj = dp->dp_tmp_userrefs_obj; @@ -747,7 +747,7 @@ name = kmem_asprintf("%llx-%s", (u_longlong_t)dsobj, tag); if (holding) - error = zap_add(mos, zapobj, name, 8, 1, t, tx); + error = zap_add(mos, zapobj, name, 8, 1, now, tx); else error = zap_remove(mos, zapobj, name, tx); strfree(name); @@ -760,9 +760,9 @@ */ int dsl_pool_user_hold(dsl_pool_t *dp, uint64_t dsobj, const char *tag, - time_t *t, dmu_tx_t *tx) + uint64_t *now, dmu_tx_t *tx) { - return (dsl_pool_user_hold_rele_impl(dp, dsobj, tag, t, tx, B_TRUE)); + return (dsl_pool_user_hold_rele_impl(dp, dsobj, tag, now, tx, B_TRUE)); } /*
--- a/usr/src/uts/common/fs/zfs/sys/dsl_pool.h Wed Nov 04 07:57:07 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/sys/dsl_pool.h Wed Nov 04 09:10:12 2009 -0700 @@ -149,7 +149,7 @@ taskq_t *dsl_pool_vnrele_taskq(dsl_pool_t *dp); extern int dsl_pool_user_hold(dsl_pool_t *dp, uint64_t dsobj, - const char *tag, time_t *t, dmu_tx_t *tx); + const char *tag, uint64_t *now, dmu_tx_t *tx); extern int dsl_pool_user_release(dsl_pool_t *dp, uint64_t dsobj, const char *tag, dmu_tx_t *tx); extern void dsl_pool_clean_tmp_userrefs(dsl_pool_t *dp);