diff options
Diffstat (limited to 'sys')
21 files changed, 403 insertions, 24 deletions
diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_misc.c b/sys/cddl/compat/opensolaris/kern/opensolaris_misc.c new file mode 100644 index 0000000..bb51c37 --- /dev/null +++ b/sys/cddl/compat/opensolaris/kern/opensolaris_misc.c @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/libkern.h> +#include <sys/misc.h> + +char hw_serial[11] = "0"; + +struct opensolaris_utsname utsname = { + .nodename = hostname +}; + +int +ddi_strtoul(const char *str, char **nptr, int base, unsigned long *result) +{ + char *end; + + if (str == hw_serial) { + *result = hostid; + return (0); + } + + *result = strtoul(str, &end, base); + if (*result == 0) + return (EINVAL); + return (0); +} diff --git a/sys/cddl/compat/opensolaris/sys/misc.h b/sys/cddl/compat/opensolaris/sys/misc.h new file mode 100644 index 0000000..d18c8c7 --- /dev/null +++ b/sys/cddl/compat/opensolaris/sys/misc.h @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _OPENSOLARIS_SYS_MISC_H_ +#define _OPENSOLARIS_SYS_MISC_H_ + +struct opensolaris_utsname { + char *nodename; +}; + +extern char hw_serial[11]; +extern struct opensolaris_utsname utsname; + +int ddi_strtoul(const char *str, char **nptr, int base, unsigned long *result); +#endif /* _OPENSOLARIS_SYS_MISC_H_ */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c index 07f8c86..378fe8c 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c @@ -948,7 +948,7 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags) objset_t *os; uint64_t snapobj; zap_cursor_t zc; - zap_attribute_t attr; + zap_attribute_t *attr; char *child; int do_self, err; @@ -958,6 +958,7 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags) /* NB: the $MOS dir doesn't have a head dataset */ do_self = (dd->dd_phys->dd_head_dataset_obj != 0); + attr = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP); /* * Iterate over all children. @@ -965,10 +966,10 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags) if (flags & DS_FIND_CHILDREN) { for (zap_cursor_init(&zc, dd->dd_pool->dp_meta_objset, dd->dd_phys->dd_child_dir_zapobj); - zap_cursor_retrieve(&zc, &attr) == 0; + zap_cursor_retrieve(&zc, attr) == 0; (void) zap_cursor_advance(&zc)) { - ASSERT(attr.za_integer_length == sizeof (uint64_t)); - ASSERT(attr.za_num_integers == 1); + ASSERT(attr->za_integer_length == sizeof (uint64_t)); + ASSERT(attr->za_num_integers == 1); /* * No separating '/' because parent's name ends in /. @@ -977,7 +978,7 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags) /* XXX could probably just use name here */ dsl_dir_name(dd, child); (void) strcat(child, "/"); - (void) strcat(child, attr.za_name); + (void) strcat(child, attr->za_name); err = dmu_objset_find(child, func, arg, flags); kmem_free(child, MAXPATHLEN); if (err) @@ -987,6 +988,7 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags) if (err) { dsl_dir_close(dd, FTAG); + kmem_free(attr, sizeof (zap_attribute_t)); return (err); } } @@ -1002,16 +1004,16 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags) dmu_objset_close(os); for (zap_cursor_init(&zc, dd->dd_pool->dp_meta_objset, snapobj); - zap_cursor_retrieve(&zc, &attr) == 0; + zap_cursor_retrieve(&zc, attr) == 0; (void) zap_cursor_advance(&zc)) { - ASSERT(attr.za_integer_length == sizeof (uint64_t)); - ASSERT(attr.za_num_integers == 1); + ASSERT(attr->za_integer_length == sizeof (uint64_t)); + ASSERT(attr->za_num_integers == 1); child = kmem_alloc(MAXPATHLEN, KM_SLEEP); /* XXX could probably just use name here */ dsl_dir_name(dd, child); (void) strcat(child, "@"); - (void) strcat(child, attr.za_name); + (void) strcat(child, attr->za_name); err = func(child, arg); kmem_free(child, MAXPATHLEN); if (err) @@ -1021,6 +1023,7 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags) } dsl_dir_close(dd, FTAG); + kmem_free(attr, sizeof (zap_attribute_t)); if (err) return (err); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c index a9707a0..af06c31 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c @@ -491,6 +491,32 @@ dsl_dataset_name(dsl_dataset_t *ds, char *name) } } +static int +dsl_dataset_namelen(dsl_dataset_t *ds) +{ + int result; + + if (ds == NULL) { + result = 3; /* "mos" */ + } else { + result = dsl_dir_namelen(ds->ds_dir); + VERIFY(0 == dsl_dataset_get_snapname(ds)); + if (ds->ds_snapname[0]) { + ++result; /* adding one for the @-sign */ + if (!MUTEX_HELD(&ds->ds_lock)) { + /* see dsl_datset_name */ + mutex_enter(&ds->ds_lock); + result += strlen(ds->ds_snapname); + mutex_exit(&ds->ds_lock); + } else { + result += strlen(ds->ds_snapname); + } + } + } + + return (result); +} + void dsl_dataset_close(dsl_dataset_t *ds, int mode, void *tag) { @@ -1328,6 +1354,13 @@ dsl_dataset_snapshot_check(void *arg1, void *arg2, dmu_tx_t *tx) if (err != ENOENT) return (err); + /* + * Check that the dataset's name is not too long. Name consists + * of the dataset's length + 1 for the @-sign + snapshot name's length + */ + if (dsl_dataset_namelen(ds) + 1 + strlen(snapname) >= MAXNAMELEN) + return (ENAMETOOLONG); + ds->ds_trysnap_txg = tx->tx_txg; return (0); } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c index 97779a2..5e563b6 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -207,6 +207,29 @@ dsl_dir_name(dsl_dir_t *dd, char *buf) } } +/* Calculate name legnth, avoiding all the strcat calls of dsl_dir_name */ +int +dsl_dir_namelen(dsl_dir_t *dd) +{ + int result = 0; + + if (dd->dd_parent) { + /* parent's name + 1 for the "/" */ + result = dsl_dir_namelen(dd->dd_parent) + 1; + } + + if (!MUTEX_HELD(&dd->dd_lock)) { + /* see dsl_dir_name */ + mutex_enter(&dd->dd_lock); + result += strlen(dd->dd_myname); + mutex_exit(&dd->dd_lock); + } else { + result += strlen(dd->dd_myname); + } + + return (result); +} + int dsl_dir_is_private(dsl_dir_t *dd) { diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c index c218f72..bfaa5e7 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c @@ -579,6 +579,7 @@ spa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig) if (!mosconfig) { nvlist_t *newconfig; + uint64_t hostid; if (load_nvlist(spa, spa->spa_config_object, &newconfig) != 0) { vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN, @@ -587,6 +588,27 @@ spa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig) goto out; } + if (nvlist_lookup_uint64(newconfig, ZPOOL_CONFIG_HOSTID, + &hostid) == 0) { + char *hostname; + unsigned long myhostid = 0; + + VERIFY(nvlist_lookup_string(newconfig, + ZPOOL_CONFIG_HOSTNAME, &hostname) == 0); + + (void) ddi_strtoul(hw_serial, NULL, 10, &myhostid); + if ((unsigned long)hostid != myhostid) { + cmn_err(CE_WARN, "pool '%s' could not be " + "loaded as it was last accessed by " + "another system (host: %s hostid: 0x%lx). " + "See: http://www.sun.com/msg/ZFS-8000-EY", + spa->spa_name, hostname, + (unsigned long)hostid); + error = EBADF; + goto out; + } + } + spa_config_set(spa, newconfig); spa_unload(spa); spa_deactivate(spa); @@ -1366,6 +1388,8 @@ spa_tryimport(nvlist_t *tryconfig) poolname) == 0); VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_STATE, state) == 0); + VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_TIMESTAMP, + spa->spa_uberblock.ub_timestamp) == 0); /* * Add the list of hot spares. diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c index b5d8c38..a7498ff 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c @@ -34,6 +34,7 @@ #include <sys/fs/zfs.h> #include <sys/vdev_impl.h> #include <sys/zfs_ioctl.h> +#include <sys/utsname.h> #ifdef _KERNEL #include <sys/kobj.h> #endif @@ -268,6 +269,7 @@ spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats) { nvlist_t *config, *nvroot; vdev_t *rvd = spa->spa_root_vdev; + unsigned long hostid = 0; ASSERT(spa_config_held(spa, RW_READER)); @@ -292,6 +294,11 @@ spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats) txg) == 0); VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_GUID, spa_guid(spa)) == 0); + (void) ddi_strtoul(hw_serial, NULL, 10, &hostid); + VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_HOSTID, + hostid) == 0); + VERIFY(nvlist_add_string(config, ZPOOL_CONFIG_HOSTNAME, + utsname.nodename) == 0); if (vd != rvd) { VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_TOP_GUID, diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h index f33776a..e0595d3 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -97,6 +97,7 @@ int dsl_dir_open_spa(spa_t *spa, const char *name, void *tag, dsl_dir_t **, int dsl_dir_open_obj(dsl_pool_t *dp, uint64_t ddobj, const char *tail, void *tag, dsl_dir_t **); void dsl_dir_name(dsl_dir_t *dd, char *buf); +int dsl_dir_namelen(dsl_dir_t *dd); int dsl_dir_is_private(dsl_dir_t *dd); uint64_t dsl_dir_create_sync(dsl_dir_t *pds, const char *name, dmu_tx_t *tx); void dsl_dir_create_root(objset_t *mos, uint64_t *ddobjp, dmu_tx_t *tx); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h index c91d807..454126f 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h @@ -46,7 +46,6 @@ extern "C" { #include <sys/kmem.h> #include <sys/taskq.h> #include <sys/systm.h> -#include <sys/kobj.h> #include <sys/conf.h> #include <sys/mutex.h> #include <sys/rwlock.h> @@ -77,6 +76,7 @@ extern "C" { #include <sys/policy.h> #include <sys/zone.h> #include <sys/eventhandler.h> +#include <sys/misc.h> #include <sys/zfs_debug.h> #include <machine/stdarg.h> diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h b/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h index 715537d..4416a5a 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h @@ -208,6 +208,9 @@ extern zpool_prop_t zpool_prop_iter(zpool_prop_f, void *, boolean_t); #define ZPOOL_CONFIG_SPARES "spares" #define ZPOOL_CONFIG_IS_SPARE "is_spare" #define ZPOOL_CONFIG_NPARITY "nparity" +#define ZPOOL_CONFIG_HOSTID "hostid" +#define ZPOOL_CONFIG_HOSTNAME "hostname" +#define ZPOOL_CONFIG_TIMESTAMP "timestamp" /* not stored on disk */ #define VDEV_TYPE_ROOT "root" #define VDEV_TYPE_MIRROR "mirror" diff --git a/sys/compat/opensolaris/kern/opensolaris_misc.c b/sys/compat/opensolaris/kern/opensolaris_misc.c new file mode 100644 index 0000000..bb51c37 --- /dev/null +++ b/sys/compat/opensolaris/kern/opensolaris_misc.c @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/libkern.h> +#include <sys/misc.h> + +char hw_serial[11] = "0"; + +struct opensolaris_utsname utsname = { + .nodename = hostname +}; + +int +ddi_strtoul(const char *str, char **nptr, int base, unsigned long *result) +{ + char *end; + + if (str == hw_serial) { + *result = hostid; + return (0); + } + + *result = strtoul(str, &end, base); + if (*result == 0) + return (EINVAL); + return (0); +} diff --git a/sys/compat/opensolaris/sys/misc.h b/sys/compat/opensolaris/sys/misc.h new file mode 100644 index 0000000..d18c8c7 --- /dev/null +++ b/sys/compat/opensolaris/sys/misc.h @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _OPENSOLARIS_SYS_MISC_H_ +#define _OPENSOLARIS_SYS_MISC_H_ + +struct opensolaris_utsname { + char *nodename; +}; + +extern char hw_serial[11]; +extern struct opensolaris_utsname utsname; + +int ddi_strtoul(const char *str, char **nptr, int base, unsigned long *result); +#endif /* _OPENSOLARIS_SYS_MISC_H_ */ diff --git a/sys/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c b/sys/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c index 07f8c86..378fe8c 100644 --- a/sys/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c +++ b/sys/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c @@ -948,7 +948,7 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags) objset_t *os; uint64_t snapobj; zap_cursor_t zc; - zap_attribute_t attr; + zap_attribute_t *attr; char *child; int do_self, err; @@ -958,6 +958,7 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags) /* NB: the $MOS dir doesn't have a head dataset */ do_self = (dd->dd_phys->dd_head_dataset_obj != 0); + attr = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP); /* * Iterate over all children. @@ -965,10 +966,10 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags) if (flags & DS_FIND_CHILDREN) { for (zap_cursor_init(&zc, dd->dd_pool->dp_meta_objset, dd->dd_phys->dd_child_dir_zapobj); - zap_cursor_retrieve(&zc, &attr) == 0; + zap_cursor_retrieve(&zc, attr) == 0; (void) zap_cursor_advance(&zc)) { - ASSERT(attr.za_integer_length == sizeof (uint64_t)); - ASSERT(attr.za_num_integers == 1); + ASSERT(attr->za_integer_length == sizeof (uint64_t)); + ASSERT(attr->za_num_integers == 1); /* * No separating '/' because parent's name ends in /. @@ -977,7 +978,7 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags) /* XXX could probably just use name here */ dsl_dir_name(dd, child); (void) strcat(child, "/"); - (void) strcat(child, attr.za_name); + (void) strcat(child, attr->za_name); err = dmu_objset_find(child, func, arg, flags); kmem_free(child, MAXPATHLEN); if (err) @@ -987,6 +988,7 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags) if (err) { dsl_dir_close(dd, FTAG); + kmem_free(attr, sizeof (zap_attribute_t)); return (err); } } @@ -1002,16 +1004,16 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags) dmu_objset_close(os); for (zap_cursor_init(&zc, dd->dd_pool->dp_meta_objset, snapobj); - zap_cursor_retrieve(&zc, &attr) == 0; + zap_cursor_retrieve(&zc, attr) == 0; (void) zap_cursor_advance(&zc)) { - ASSERT(attr.za_integer_length == sizeof (uint64_t)); - ASSERT(attr.za_num_integers == 1); + ASSERT(attr->za_integer_length == sizeof (uint64_t)); + ASSERT(attr->za_num_integers == 1); child = kmem_alloc(MAXPATHLEN, KM_SLEEP); /* XXX could probably just use name here */ dsl_dir_name(dd, child); (void) strcat(child, "@"); - (void) strcat(child, attr.za_name); + (void) strcat(child, attr->za_name); err = func(child, arg); kmem_free(child, MAXPATHLEN); if (err) @@ -1021,6 +1023,7 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags) } dsl_dir_close(dd, FTAG); + kmem_free(attr, sizeof (zap_attribute_t)); if (err) return (err); diff --git a/sys/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c b/sys/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c index a9707a0..af06c31 100644 --- a/sys/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c +++ b/sys/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c @@ -491,6 +491,32 @@ dsl_dataset_name(dsl_dataset_t *ds, char *name) } } +static int +dsl_dataset_namelen(dsl_dataset_t *ds) +{ + int result; + + if (ds == NULL) { + result = 3; /* "mos" */ + } else { + result = dsl_dir_namelen(ds->ds_dir); + VERIFY(0 == dsl_dataset_get_snapname(ds)); + if (ds->ds_snapname[0]) { + ++result; /* adding one for the @-sign */ + if (!MUTEX_HELD(&ds->ds_lock)) { + /* see dsl_datset_name */ + mutex_enter(&ds->ds_lock); + result += strlen(ds->ds_snapname); + mutex_exit(&ds->ds_lock); + } else { + result += strlen(ds->ds_snapname); + } + } + } + + return (result); +} + void dsl_dataset_close(dsl_dataset_t *ds, int mode, void *tag) { @@ -1328,6 +1354,13 @@ dsl_dataset_snapshot_check(void *arg1, void *arg2, dmu_tx_t *tx) if (err != ENOENT) return (err); + /* + * Check that the dataset's name is not too long. Name consists + * of the dataset's length + 1 for the @-sign + snapshot name's length + */ + if (dsl_dataset_namelen(ds) + 1 + strlen(snapname) >= MAXNAMELEN) + return (ENAMETOOLONG); + ds->ds_trysnap_txg = tx->tx_txg; return (0); } diff --git a/sys/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c b/sys/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c index 97779a2..5e563b6 100644 --- a/sys/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c +++ b/sys/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -207,6 +207,29 @@ dsl_dir_name(dsl_dir_t *dd, char *buf) } } +/* Calculate name legnth, avoiding all the strcat calls of dsl_dir_name */ +int +dsl_dir_namelen(dsl_dir_t *dd) +{ + int result = 0; + + if (dd->dd_parent) { + /* parent's name + 1 for the "/" */ + result = dsl_dir_namelen(dd->dd_parent) + 1; + } + + if (!MUTEX_HELD(&dd->dd_lock)) { + /* see dsl_dir_name */ + mutex_enter(&dd->dd_lock); + result += strlen(dd->dd_myname); + mutex_exit(&dd->dd_lock); + } else { + result += strlen(dd->dd_myname); + } + + return (result); +} + int dsl_dir_is_private(dsl_dir_t *dd) { diff --git a/sys/contrib/opensolaris/uts/common/fs/zfs/spa.c b/sys/contrib/opensolaris/uts/common/fs/zfs/spa.c index c218f72..bfaa5e7 100644 --- a/sys/contrib/opensolaris/uts/common/fs/zfs/spa.c +++ b/sys/contrib/opensolaris/uts/common/fs/zfs/spa.c @@ -579,6 +579,7 @@ spa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig) if (!mosconfig) { nvlist_t *newconfig; + uint64_t hostid; if (load_nvlist(spa, spa->spa_config_object, &newconfig) != 0) { vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN, @@ -587,6 +588,27 @@ spa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig) goto out; } + if (nvlist_lookup_uint64(newconfig, ZPOOL_CONFIG_HOSTID, + &hostid) == 0) { + char *hostname; + unsigned long myhostid = 0; + + VERIFY(nvlist_lookup_string(newconfig, + ZPOOL_CONFIG_HOSTNAME, &hostname) == 0); + + (void) ddi_strtoul(hw_serial, NULL, 10, &myhostid); + if ((unsigned long)hostid != myhostid) { + cmn_err(CE_WARN, "pool '%s' could not be " + "loaded as it was last accessed by " + "another system (host: %s hostid: 0x%lx). " + "See: http://www.sun.com/msg/ZFS-8000-EY", + spa->spa_name, hostname, + (unsigned long)hostid); + error = EBADF; + goto out; + } + } + spa_config_set(spa, newconfig); spa_unload(spa); spa_deactivate(spa); @@ -1366,6 +1388,8 @@ spa_tryimport(nvlist_t *tryconfig) poolname) == 0); VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_STATE, state) == 0); + VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_TIMESTAMP, + spa->spa_uberblock.ub_timestamp) == 0); /* * Add the list of hot spares. diff --git a/sys/contrib/opensolaris/uts/common/fs/zfs/spa_config.c b/sys/contrib/opensolaris/uts/common/fs/zfs/spa_config.c index b5d8c38..a7498ff 100644 --- a/sys/contrib/opensolaris/uts/common/fs/zfs/spa_config.c +++ b/sys/contrib/opensolaris/uts/common/fs/zfs/spa_config.c @@ -34,6 +34,7 @@ #include <sys/fs/zfs.h> #include <sys/vdev_impl.h> #include <sys/zfs_ioctl.h> +#include <sys/utsname.h> #ifdef _KERNEL #include <sys/kobj.h> #endif @@ -268,6 +269,7 @@ spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats) { nvlist_t *config, *nvroot; vdev_t *rvd = spa->spa_root_vdev; + unsigned long hostid = 0; ASSERT(spa_config_held(spa, RW_READER)); @@ -292,6 +294,11 @@ spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats) txg) == 0); VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_GUID, spa_guid(spa)) == 0); + (void) ddi_strtoul(hw_serial, NULL, 10, &hostid); + VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_HOSTID, + hostid) == 0); + VERIFY(nvlist_add_string(config, ZPOOL_CONFIG_HOSTNAME, + utsname.nodename) == 0); if (vd != rvd) { VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_TOP_GUID, diff --git a/sys/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h b/sys/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h index f33776a..e0595d3 100644 --- a/sys/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h +++ b/sys/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -97,6 +97,7 @@ int dsl_dir_open_spa(spa_t *spa, const char *name, void *tag, dsl_dir_t **, int dsl_dir_open_obj(dsl_pool_t *dp, uint64_t ddobj, const char *tail, void *tag, dsl_dir_t **); void dsl_dir_name(dsl_dir_t *dd, char *buf); +int dsl_dir_namelen(dsl_dir_t *dd); int dsl_dir_is_private(dsl_dir_t *dd); uint64_t dsl_dir_create_sync(dsl_dir_t *pds, const char *name, dmu_tx_t *tx); void dsl_dir_create_root(objset_t *mos, uint64_t *ddobjp, dmu_tx_t *tx); diff --git a/sys/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h b/sys/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h index c91d807..454126f 100644 --- a/sys/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h +++ b/sys/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h @@ -46,7 +46,6 @@ extern "C" { #include <sys/kmem.h> #include <sys/taskq.h> #include <sys/systm.h> -#include <sys/kobj.h> #include <sys/conf.h> #include <sys/mutex.h> #include <sys/rwlock.h> @@ -77,6 +76,7 @@ extern "C" { #include <sys/policy.h> #include <sys/zone.h> #include <sys/eventhandler.h> +#include <sys/misc.h> #include <sys/zfs_debug.h> #include <machine/stdarg.h> diff --git a/sys/contrib/opensolaris/uts/common/sys/fs/zfs.h b/sys/contrib/opensolaris/uts/common/sys/fs/zfs.h index 715537d..4416a5a 100644 --- a/sys/contrib/opensolaris/uts/common/sys/fs/zfs.h +++ b/sys/contrib/opensolaris/uts/common/sys/fs/zfs.h @@ -208,6 +208,9 @@ extern zpool_prop_t zpool_prop_iter(zpool_prop_f, void *, boolean_t); #define ZPOOL_CONFIG_SPARES "spares" #define ZPOOL_CONFIG_IS_SPARE "is_spare" #define ZPOOL_CONFIG_NPARITY "nparity" +#define ZPOOL_CONFIG_HOSTID "hostid" +#define ZPOOL_CONFIG_HOSTNAME "hostname" +#define ZPOOL_CONFIG_TIMESTAMP "timestamp" /* not stored on disk */ #define VDEV_TYPE_ROOT "root" #define VDEV_TYPE_MIRROR "mirror" diff --git a/sys/modules/zfs/Makefile b/sys/modules/zfs/Makefile index 1f3fbbf..80f43a5 100644 --- a/sys/modules/zfs/Makefile +++ b/sys/modules/zfs/Makefile @@ -15,6 +15,7 @@ SRCS+= nvpair.c SRCS+= opensolaris_kmem.c SRCS+= opensolaris_kobj.c SRCS+= opensolaris_kstat.c +SRCS+= opensolaris_misc.c SRCS+= opensolaris_policy.c SRCS+= opensolaris_string.c SRCS+= opensolaris_vfs.c |