Merge f54bcc9c40
into bdf4d6be1d
This commit is contained in:
commit
f92a105c92
129
cmd/zdb/zdb.c
129
cmd/zdb/zdb.c
|
@ -1117,7 +1117,7 @@ dump_zap(objset_t *os, uint64_t object, void *data, size_t size)
|
|||
{
|
||||
(void) data, (void) size;
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t attr;
|
||||
zap_attribute_t *attrp = zap_attribute_long_alloc();
|
||||
void *prop;
|
||||
unsigned i;
|
||||
|
||||
|
@ -1125,53 +1125,54 @@ dump_zap(objset_t *os, uint64_t object, void *data, size_t size)
|
|||
(void) printf("\n");
|
||||
|
||||
for (zap_cursor_init(&zc, os, object);
|
||||
zap_cursor_retrieve(&zc, &attr) == 0;
|
||||
zap_cursor_retrieve(&zc, attrp) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
boolean_t key64 =
|
||||
!!(zap_getflags(zc.zc_zap) & ZAP_FLAG_UINT64_KEY);
|
||||
|
||||
if (key64)
|
||||
(void) printf("\t\t0x%010lx = ",
|
||||
*(uint64_t *)attr.za_name);
|
||||
*(uint64_t *)attrp->za_name);
|
||||
else
|
||||
(void) printf("\t\t%s = ", attr.za_name);
|
||||
(void) printf("\t\t%s = ", attrp->za_name);
|
||||
|
||||
if (attr.za_num_integers == 0) {
|
||||
if (attrp->za_num_integers == 0) {
|
||||
(void) printf("\n");
|
||||
continue;
|
||||
}
|
||||
prop = umem_zalloc(attr.za_num_integers *
|
||||
attr.za_integer_length, UMEM_NOFAIL);
|
||||
prop = umem_zalloc(attrp->za_num_integers *
|
||||
attrp->za_integer_length, UMEM_NOFAIL);
|
||||
|
||||
if (key64)
|
||||
(void) zap_lookup_uint64(os, object,
|
||||
(const uint64_t *)attr.za_name, 1,
|
||||
attr.za_integer_length, attr.za_num_integers,
|
||||
(const uint64_t *)attrp->za_name, 1,
|
||||
attrp->za_integer_length, attrp->za_num_integers,
|
||||
prop);
|
||||
else
|
||||
(void) zap_lookup(os, object, attr.za_name,
|
||||
attr.za_integer_length, attr.za_num_integers,
|
||||
(void) zap_lookup(os, object, attrp->za_name,
|
||||
attrp->za_integer_length, attrp->za_num_integers,
|
||||
prop);
|
||||
|
||||
if (attr.za_integer_length == 1 && !key64) {
|
||||
if (strcmp(attr.za_name,
|
||||
if (attrp->za_integer_length == 1 && !key64) {
|
||||
if (strcmp(attrp->za_name,
|
||||
DSL_CRYPTO_KEY_MASTER_KEY) == 0 ||
|
||||
strcmp(attr.za_name,
|
||||
strcmp(attrp->za_name,
|
||||
DSL_CRYPTO_KEY_HMAC_KEY) == 0 ||
|
||||
strcmp(attr.za_name, DSL_CRYPTO_KEY_IV) == 0 ||
|
||||
strcmp(attr.za_name, DSL_CRYPTO_KEY_MAC) == 0 ||
|
||||
strcmp(attr.za_name, DMU_POOL_CHECKSUM_SALT) == 0) {
|
||||
strcmp(attrp->za_name, DSL_CRYPTO_KEY_IV) == 0 ||
|
||||
strcmp(attrp->za_name, DSL_CRYPTO_KEY_MAC) == 0 ||
|
||||
strcmp(attrp->za_name,
|
||||
DMU_POOL_CHECKSUM_SALT) == 0) {
|
||||
uint8_t *u8 = prop;
|
||||
|
||||
for (i = 0; i < attr.za_num_integers; i++) {
|
||||
for (i = 0; i < attrp->za_num_integers; i++) {
|
||||
(void) printf("%02x", u8[i]);
|
||||
}
|
||||
} else {
|
||||
(void) printf("%s", (char *)prop);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < attr.za_num_integers; i++) {
|
||||
switch (attr.za_integer_length) {
|
||||
for (i = 0; i < attrp->za_num_integers; i++) {
|
||||
switch (attrp->za_integer_length) {
|
||||
case 1:
|
||||
(void) printf("%u ",
|
||||
((uint8_t *)prop)[i]);
|
||||
|
@ -1192,9 +1193,11 @@ dump_zap(objset_t *os, uint64_t object, void *data, size_t size)
|
|||
}
|
||||
}
|
||||
(void) printf("\n");
|
||||
umem_free(prop, attr.za_num_integers * attr.za_integer_length);
|
||||
umem_free(prop,
|
||||
attrp->za_num_integers * attrp->za_integer_length);
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(attrp);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1295,26 +1298,27 @@ dump_sa_attrs(objset_t *os, uint64_t object, void *data, size_t size)
|
|||
{
|
||||
(void) data, (void) size;
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t attr;
|
||||
zap_attribute_t *attrp = zap_attribute_alloc();
|
||||
|
||||
dump_zap_stats(os, object);
|
||||
(void) printf("\n");
|
||||
|
||||
for (zap_cursor_init(&zc, os, object);
|
||||
zap_cursor_retrieve(&zc, &attr) == 0;
|
||||
zap_cursor_retrieve(&zc, attrp) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
(void) printf("\t\t%s = ", attr.za_name);
|
||||
if (attr.za_num_integers == 0) {
|
||||
(void) printf("\t\t%s = ", attrp->za_name);
|
||||
if (attrp->za_num_integers == 0) {
|
||||
(void) printf("\n");
|
||||
continue;
|
||||
}
|
||||
(void) printf(" %llx : [%d:%d:%d]\n",
|
||||
(u_longlong_t)attr.za_first_integer,
|
||||
(int)ATTR_LENGTH(attr.za_first_integer),
|
||||
(int)ATTR_BSWAP(attr.za_first_integer),
|
||||
(int)ATTR_NUM(attr.za_first_integer));
|
||||
(u_longlong_t)attrp->za_first_integer,
|
||||
(int)ATTR_LENGTH(attrp->za_first_integer),
|
||||
(int)ATTR_BSWAP(attrp->za_first_integer),
|
||||
(int)ATTR_NUM(attrp->za_first_integer));
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(attrp);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1322,7 +1326,7 @@ dump_sa_layouts(objset_t *os, uint64_t object, void *data, size_t size)
|
|||
{
|
||||
(void) data, (void) size;
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t attr;
|
||||
zap_attribute_t *attrp = zap_attribute_alloc();
|
||||
uint16_t *layout_attrs;
|
||||
unsigned i;
|
||||
|
||||
|
@ -1330,29 +1334,30 @@ dump_sa_layouts(objset_t *os, uint64_t object, void *data, size_t size)
|
|||
(void) printf("\n");
|
||||
|
||||
for (zap_cursor_init(&zc, os, object);
|
||||
zap_cursor_retrieve(&zc, &attr) == 0;
|
||||
zap_cursor_retrieve(&zc, attrp) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
(void) printf("\t\t%s = [", attr.za_name);
|
||||
if (attr.za_num_integers == 0) {
|
||||
(void) printf("\t\t%s = [", attrp->za_name);
|
||||
if (attrp->za_num_integers == 0) {
|
||||
(void) printf("\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
VERIFY(attr.za_integer_length == 2);
|
||||
layout_attrs = umem_zalloc(attr.za_num_integers *
|
||||
attr.za_integer_length, UMEM_NOFAIL);
|
||||
VERIFY(attrp->za_integer_length == 2);
|
||||
layout_attrs = umem_zalloc(attrp->za_num_integers *
|
||||
attrp->za_integer_length, UMEM_NOFAIL);
|
||||
|
||||
VERIFY(zap_lookup(os, object, attr.za_name,
|
||||
attr.za_integer_length,
|
||||
attr.za_num_integers, layout_attrs) == 0);
|
||||
VERIFY(zap_lookup(os, object, attrp->za_name,
|
||||
attrp->za_integer_length,
|
||||
attrp->za_num_integers, layout_attrs) == 0);
|
||||
|
||||
for (i = 0; i != attr.za_num_integers; i++)
|
||||
for (i = 0; i != attrp->za_num_integers; i++)
|
||||
(void) printf(" %d ", (int)layout_attrs[i]);
|
||||
(void) printf("]\n");
|
||||
umem_free(layout_attrs,
|
||||
attr.za_num_integers * attr.za_integer_length);
|
||||
attrp->za_num_integers * attrp->za_integer_length);
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(attrp);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1360,7 +1365,7 @@ dump_zpldir(objset_t *os, uint64_t object, void *data, size_t size)
|
|||
{
|
||||
(void) data, (void) size;
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t attr;
|
||||
zap_attribute_t *attrp = zap_attribute_long_alloc();
|
||||
const char *typenames[] = {
|
||||
/* 0 */ "not specified",
|
||||
/* 1 */ "FIFO",
|
||||
|
@ -1384,13 +1389,14 @@ dump_zpldir(objset_t *os, uint64_t object, void *data, size_t size)
|
|||
(void) printf("\n");
|
||||
|
||||
for (zap_cursor_init(&zc, os, object);
|
||||
zap_cursor_retrieve(&zc, &attr) == 0;
|
||||
zap_cursor_retrieve(&zc, attrp) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
(void) printf("\t\t%s = %lld (type: %s)\n",
|
||||
attr.za_name, ZFS_DIRENT_OBJ(attr.za_first_integer),
|
||||
typenames[ZFS_DIRENT_TYPE(attr.za_first_integer)]);
|
||||
attrp->za_name, ZFS_DIRENT_OBJ(attrp->za_first_integer),
|
||||
typenames[ZFS_DIRENT_TYPE(attrp->za_first_integer)]);
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(attrp);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -2100,23 +2106,24 @@ dump_brt(spa_t *spa)
|
|||
continue;
|
||||
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za = zap_attribute_alloc();
|
||||
for (zap_cursor_init(&zc, brt->brt_mos, brtvd->bv_mos_entries);
|
||||
zap_cursor_retrieve(&zc, &za) == 0;
|
||||
zap_cursor_retrieve(&zc, za) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
uint64_t refcnt;
|
||||
VERIFY0(zap_lookup_uint64(brt->brt_mos,
|
||||
brtvd->bv_mos_entries,
|
||||
(const uint64_t *)za.za_name, 1,
|
||||
za.za_integer_length, za.za_num_integers, &refcnt));
|
||||
(const uint64_t *)za->za_name, 1,
|
||||
za->za_integer_length, za->za_num_integers, &refcnt));
|
||||
|
||||
uint64_t offset = *(const uint64_t *)za.za_name;
|
||||
uint64_t offset = *(const uint64_t *)za->za_name;
|
||||
|
||||
snprintf(dva, sizeof (dva), "%" PRIu64 ":%llx", vdevid,
|
||||
(u_longlong_t)offset);
|
||||
printf("%-16s %-10llu\n", dva, (u_longlong_t)refcnt);
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2898,28 +2905,30 @@ static void
|
|||
dump_bookmarks(objset_t *os, int verbosity)
|
||||
{
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t attr;
|
||||
zap_attribute_t *attrp;
|
||||
dsl_dataset_t *ds = dmu_objset_ds(os);
|
||||
dsl_pool_t *dp = spa_get_dsl(os->os_spa);
|
||||
objset_t *mos = os->os_spa->spa_meta_objset;
|
||||
if (verbosity < 4)
|
||||
return;
|
||||
attrp = zap_attribute_alloc();
|
||||
dsl_pool_config_enter(dp, FTAG);
|
||||
|
||||
for (zap_cursor_init(&zc, mos, ds->ds_bookmarks_obj);
|
||||
zap_cursor_retrieve(&zc, &attr) == 0;
|
||||
zap_cursor_retrieve(&zc, attrp) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
char osname[ZFS_MAX_DATASET_NAME_LEN];
|
||||
char buf[ZFS_MAX_DATASET_NAME_LEN];
|
||||
int len;
|
||||
dmu_objset_name(os, osname);
|
||||
len = snprintf(buf, sizeof (buf), "%s#%s", osname,
|
||||
attr.za_name);
|
||||
attrp->za_name);
|
||||
VERIFY3S(len, <, ZFS_MAX_DATASET_NAME_LEN);
|
||||
(void) dump_bookmark(dp, buf, verbosity >= 5, verbosity >= 6);
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
dsl_pool_config_exit(dp, FTAG);
|
||||
zap_attribute_free(attrp);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -6710,18 +6719,19 @@ iterate_deleted_livelists(spa_t *spa, ll_iter_t func, void *arg)
|
|||
ASSERT0(err);
|
||||
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t attr;
|
||||
zap_attribute_t *attrp = zap_attribute_alloc();
|
||||
dsl_deadlist_t ll;
|
||||
/* NULL out os prior to dsl_deadlist_open in case it's garbage */
|
||||
ll.dl_os = NULL;
|
||||
for (zap_cursor_init(&zc, mos, zap_obj);
|
||||
zap_cursor_retrieve(&zc, &attr) == 0;
|
||||
zap_cursor_retrieve(&zc, attrp) == 0;
|
||||
(void) zap_cursor_advance(&zc)) {
|
||||
dsl_deadlist_open(&ll, mos, attr.za_first_integer);
|
||||
dsl_deadlist_open(&ll, mos, attrp->za_first_integer);
|
||||
func(&ll, arg);
|
||||
dsl_deadlist_close(&ll);
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(attrp);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -7936,13 +7946,14 @@ static void
|
|||
errorlog_count_refd(objset_t *mos, uint64_t errlog)
|
||||
{
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za = zap_attribute_alloc();
|
||||
for (zap_cursor_init(&zc, mos, errlog);
|
||||
zap_cursor_retrieve(&zc, &za) == 0;
|
||||
zap_cursor_retrieve(&zc, za) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
mos_obj_refd(za.za_first_integer);
|
||||
mos_obj_refd(za->za_first_integer);
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
17
cmd/zhack.c
17
cmd/zhack.c
|
@ -203,26 +203,27 @@ static void
|
|||
dump_obj(objset_t *os, uint64_t obj, const char *name)
|
||||
{
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za = zap_attribute_long_alloc();
|
||||
|
||||
(void) printf("%s_obj:\n", name);
|
||||
|
||||
for (zap_cursor_init(&zc, os, obj);
|
||||
zap_cursor_retrieve(&zc, &za) == 0;
|
||||
zap_cursor_retrieve(&zc, za) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
if (za.za_integer_length == 8) {
|
||||
ASSERT(za.za_num_integers == 1);
|
||||
if (za->za_integer_length == 8) {
|
||||
ASSERT(za->za_num_integers == 1);
|
||||
(void) printf("\t%s = %llu\n",
|
||||
za.za_name, (u_longlong_t)za.za_first_integer);
|
||||
za->za_name, (u_longlong_t)za->za_first_integer);
|
||||
} else {
|
||||
ASSERT(za.za_integer_length == 1);
|
||||
ASSERT(za->za_integer_length == 1);
|
||||
char val[1024];
|
||||
VERIFY(zap_lookup(os, obj, za.za_name,
|
||||
VERIFY(zap_lookup(os, obj, za->za_name,
|
||||
1, sizeof (val), val) == 0);
|
||||
(void) printf("\t%s = %s\n", za.za_name, val);
|
||||
(void) printf("\t%s = %s\n", za->za_name, val);
|
||||
}
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -118,6 +118,7 @@ struct zfsvfs {
|
|||
boolean_t z_xattr_sa; /* allow xattrs to be stores as SA */
|
||||
boolean_t z_draining; /* is true when drain is active */
|
||||
boolean_t z_drain_cancel; /* signal the unlinked drain to stop */
|
||||
boolean_t z_longname; /* Dataset supports long names */
|
||||
uint64_t z_version; /* ZPL version */
|
||||
uint64_t z_shares_dir; /* hidden shares dir */
|
||||
dataset_kstats_t z_kstat; /* fs kstats */
|
||||
|
|
|
@ -44,6 +44,7 @@ extern int zfs_write_simple(znode_t *zp, const void *data, size_t len,
|
|||
loff_t pos, size_t *resid);
|
||||
extern int zfs_lookup(znode_t *dzp, char *nm, znode_t **zpp, int flags,
|
||||
cred_t *cr, int *direntflags, pathname_t *realpnp);
|
||||
extern int zfs_get_name(znode_t *dzp, char *name, znode_t *zp);
|
||||
extern int zfs_create(znode_t *dzp, char *name, vattr_t *vap, int excl,
|
||||
int mode, znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp,
|
||||
zidmap_t *mnt_ns);
|
||||
|
|
|
@ -81,6 +81,7 @@ typedef enum dmu_objset_type {
|
|||
* All of these include the terminating NUL byte.
|
||||
*/
|
||||
#define ZAP_MAXNAMELEN 256
|
||||
#define ZAP_MAXNAMELEN_NEW 1024
|
||||
#define ZAP_MAXVALUELEN (1024 * 8)
|
||||
#define ZAP_OLDMAXVALUELEN 1024
|
||||
#define ZFS_MAX_DATASET_NAME_LEN 256
|
||||
|
@ -193,6 +194,7 @@ typedef enum {
|
|||
ZFS_PROP_SNAPSHOTS_CHANGED,
|
||||
ZFS_PROP_PREFETCH,
|
||||
ZFS_PROP_VOLTHREADING,
|
||||
ZFS_PROP_LONGNAME,
|
||||
ZFS_NUM_PROPS
|
||||
} zfs_prop_t;
|
||||
|
||||
|
|
|
@ -315,7 +315,7 @@ int zap_count(objset_t *ds, uint64_t zapobj, uint64_t *count);
|
|||
* match must be exact (ie, same as mask=-1ULL).
|
||||
*/
|
||||
int zap_value_search(objset_t *os, uint64_t zapobj,
|
||||
uint64_t value, uint64_t mask, char *name);
|
||||
uint64_t value, uint64_t mask, char *name, uint64_t namelen);
|
||||
|
||||
/*
|
||||
* Transfer all the entries from fromobj into intoobj. Only works on
|
||||
|
@ -376,9 +376,20 @@ typedef struct {
|
|||
boolean_t za_normalization_conflict;
|
||||
uint64_t za_num_integers;
|
||||
uint64_t za_first_integer; /* no sign extension for <8byte ints */
|
||||
char za_name[ZAP_MAXNAMELEN];
|
||||
uint32_t za_name_len;
|
||||
char za_name[];
|
||||
} zap_attribute_t;
|
||||
|
||||
void zap_init(void);
|
||||
void zap_fini(void);
|
||||
|
||||
/*
|
||||
* Alloc and free zap_attribute_t.
|
||||
*/
|
||||
zap_attribute_t *zap_attribute_alloc(void);
|
||||
zap_attribute_t *zap_attribute_long_alloc(void);
|
||||
void zap_attribute_free(zap_attribute_t *attrp);
|
||||
|
||||
/*
|
||||
* The interface for listing all the attributes of a zapobj can be
|
||||
* thought of as cursor moving down a list of the attributes one by
|
||||
|
|
|
@ -191,7 +191,8 @@ typedef struct zap_name {
|
|||
uint64_t zn_hash;
|
||||
matchtype_t zn_matchtype;
|
||||
int zn_normflags;
|
||||
char zn_normbuf[ZAP_MAXNAMELEN];
|
||||
int zn_normbuf_len;
|
||||
char zn_normbuf[];
|
||||
} zap_name_t;
|
||||
|
||||
#define zap_f zap_u.zap_fat
|
||||
|
|
|
@ -124,7 +124,7 @@ typedef enum drr_headertype {
|
|||
* default use of "zfs send" won't encounter the bug mentioned above.
|
||||
*/
|
||||
#define DMU_BACKUP_FEATURE_SWITCH_TO_LARGE_BLOCKS (1 << 27)
|
||||
/* flag #28 is reserved for a Nutanix feature */
|
||||
#define DMU_BACKUP_FEATURE_LONGNAME (1 << 28)
|
||||
/*
|
||||
* flag #29 is the last unused bit. It is reserved to indicate a to-be-designed
|
||||
* extension to the stream format which will accomodate more feature flags.
|
||||
|
@ -141,7 +141,7 @@ typedef enum drr_headertype {
|
|||
DMU_BACKUP_FEATURE_COMPRESSED | DMU_BACKUP_FEATURE_LARGE_DNODE | \
|
||||
DMU_BACKUP_FEATURE_RAW | DMU_BACKUP_FEATURE_HOLDS | \
|
||||
DMU_BACKUP_FEATURE_REDACTED | DMU_BACKUP_FEATURE_SWITCH_TO_LARGE_BLOCKS | \
|
||||
DMU_BACKUP_FEATURE_ZSTD)
|
||||
DMU_BACKUP_FEATURE_ZSTD | DMU_BACKUP_FEATURE_LONGNAME)
|
||||
|
||||
/* Are all features in the given flag word currently supported? */
|
||||
#define DMU_STREAM_SUPPORTED(x) (!((x) & ~DMU_BACKUP_FEATURE_MASK))
|
||||
|
|
|
@ -82,6 +82,7 @@ typedef enum spa_feature {
|
|||
SPA_FEATURE_AVZ_V2,
|
||||
SPA_FEATURE_REDACTION_LIST_SPILL,
|
||||
SPA_FEATURE_RAIDZ_EXPANSION,
|
||||
SPA_FEATURE_LONGNAME,
|
||||
SPA_FEATURES
|
||||
} spa_feature_t;
|
||||
|
||||
|
|
|
@ -616,7 +616,7 @@
|
|||
<elf-symbol name='fletcher_4_superscalar_ops' size='128' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='libzfs_config_ops' size='16' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='sa_protocol_names' size='16' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='spa_feature_table' size='2296' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='spa_feature_table' size='2352' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfeature_checks_disable' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfs_deleg_perm_tab' size='512' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zfs_history_event_names' size='328' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
|
@ -664,6 +664,10 @@
|
|||
<parameter type-id='b59d7dce'/>
|
||||
<return type-id='eaa32e2f'/>
|
||||
</function-decl>
|
||||
<function-decl name='unlink' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='80f4b756'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='flock' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
|
@ -1871,7 +1875,8 @@
|
|||
<enumerator name='ZFS_PROP_SNAPSHOTS_CHANGED' value='95'/>
|
||||
<enumerator name='ZFS_PROP_PREFETCH' value='96'/>
|
||||
<enumerator name='ZFS_PROP_VOLTHREADING' value='97'/>
|
||||
<enumerator name='ZFS_NUM_PROPS' value='98'/>
|
||||
<enumerator name='ZFS_PROP_LONGNAME' value='98'/>
|
||||
<enumerator name='ZFS_NUM_PROPS' value='99'/>
|
||||
</enum-decl>
|
||||
<typedef-decl name='zfs_prop_t' type-id='4b000d60' id='58603c44'/>
|
||||
<enum-decl name='zprop_source_t' naming-typedef-id='a2256d42' id='5903f80e'>
|
||||
|
@ -3427,18 +3432,9 @@
|
|||
<function-decl name='__ctype_b_loc' visibility='default' binding='global' size-in-bits='64'>
|
||||
<return type-id='c59e1ef0'/>
|
||||
</function-decl>
|
||||
<function-decl name='dlopen' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='80f4b756'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<return type-id='eaa32e2f'/>
|
||||
</function-decl>
|
||||
<function-decl name='dlsym' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='1b7446cd'/>
|
||||
<parameter type-id='9d26089a'/>
|
||||
<return type-id='eaa32e2f'/>
|
||||
</function-decl>
|
||||
<function-decl name='dlerror' visibility='default' binding='global' size-in-bits='64'>
|
||||
<return type-id='26a90f95'/>
|
||||
<function-decl name='uselocale' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='973a4f8d'/>
|
||||
<return type-id='973a4f8d'/>
|
||||
</function-decl>
|
||||
<function-decl name='uselocale' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='973a4f8d'/>
|
||||
|
@ -3485,11 +3481,6 @@
|
|||
<parameter type-id='822cd80b'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='fdopen' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='80f4b756'/>
|
||||
<return type-id='822cd80b'/>
|
||||
</function-decl>
|
||||
<function-decl name='fputc' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='822cd80b'/>
|
||||
|
@ -3502,10 +3493,6 @@
|
|||
<parameter type-id='e75a27e9'/>
|
||||
<return type-id='41060289'/>
|
||||
</function-decl>
|
||||
<function-decl name='rewind' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='822cd80b'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='ferror' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='822cd80b'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
|
@ -3554,10 +3541,6 @@
|
|||
<parameter type-id='95e97e5e'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='unlink' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='80f4b756'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='__open_too_many_args' visibility='default' binding='global' size-in-bits='64'>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
|
@ -3570,13 +3553,6 @@
|
|||
<parameter is-variadic='yes'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='__asprintf_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='8c85230f'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='9d26089a'/>
|
||||
<parameter is-variadic='yes'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='__fread_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='1b7446cd'/>
|
||||
<parameter type-id='b59d7dce'/>
|
||||
|
@ -4383,6 +4359,10 @@
|
|||
<function-decl name='abort' visibility='default' binding='global' size-in-bits='64'>
|
||||
<return type-id='48b5725f'/>
|
||||
</function-decl>
|
||||
<function-decl name='strdup' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='80f4b756'/>
|
||||
<return type-id='26a90f95'/>
|
||||
</function-decl>
|
||||
<function-decl name='strrchr' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='80f4b756'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
|
@ -4422,6 +4402,13 @@
|
|||
<parameter is-variadic='yes'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='__asprintf_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='8c85230f'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='9d26089a'/>
|
||||
<parameter is-variadic='yes'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='ioctl' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='7359adad'/>
|
||||
|
@ -4952,6 +4939,11 @@
|
|||
<parameter type-id='4051f5e7'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='fdopen' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='80f4b756'/>
|
||||
<return type-id='822cd80b'/>
|
||||
</function-decl>
|
||||
<function-decl name='fputs' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='9d26089a'/>
|
||||
<parameter type-id='e75a27e9'/>
|
||||
|
@ -6006,7 +5998,8 @@
|
|||
<enumerator name='SPA_FEATURE_AVZ_V2' value='38'/>
|
||||
<enumerator name='SPA_FEATURE_REDACTION_LIST_SPILL' value='39'/>
|
||||
<enumerator name='SPA_FEATURE_RAIDZ_EXPANSION' value='40'/>
|
||||
<enumerator name='SPA_FEATURES' value='41'/>
|
||||
<enumerator name='SPA_FEATURE_LONGNAME' value='41'/>
|
||||
<enumerator name='SPA_FEATURES' value='42'/>
|
||||
</enum-decl>
|
||||
<typedef-decl name='spa_feature_t' type-id='33ecb627' id='d6618c78'/>
|
||||
<qualified-type-def type-id='80f4b756' const='yes' id='b99c00c9'/>
|
||||
|
@ -8054,10 +8047,6 @@
|
|||
<function-decl name='__ctype_toupper_loc' visibility='default' binding='global' size-in-bits='64'>
|
||||
<return type-id='24f95ba5'/>
|
||||
</function-decl>
|
||||
<function-decl name='dlclose' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='eaa32e2f'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='regcomp' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='5c53ba29'/>
|
||||
<parameter type-id='9d26089a'/>
|
||||
|
@ -9131,8 +9120,8 @@
|
|||
</function-decl>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='module/zcommon/zfeature_common.c' language='LANG_C99'>
|
||||
<array-type-def dimensions='1' type-id='83f29ca2' size-in-bits='18368' id='b93e4d14'>
|
||||
<subrange length='41' type-id='7359adad' id='cb834f44'/>
|
||||
<array-type-def dimensions='1' type-id='83f29ca2' size-in-bits='18816' id='b937914f'>
|
||||
<subrange length='42' type-id='7359adad' id='cb7c937f'/>
|
||||
</array-type-def>
|
||||
<enum-decl name='zfeature_flags' id='6db816a4'>
|
||||
<underlying-type type-id='9cac1fee'/>
|
||||
|
@ -9209,7 +9198,7 @@
|
|||
<pointer-type-def type-id='611586a1' size-in-bits='64' id='2e243169'/>
|
||||
<qualified-type-def type-id='eaa32e2f' const='yes' id='83be723c'/>
|
||||
<pointer-type-def type-id='83be723c' size-in-bits='64' id='7acd98a2'/>
|
||||
<var-decl name='spa_feature_table' type-id='b93e4d14' mangled-name='spa_feature_table' visibility='default' elf-symbol-id='spa_feature_table'/>
|
||||
<var-decl name='spa_feature_table' type-id='b937914f' mangled-name='spa_feature_table' visibility='default' elf-symbol-id='spa_feature_table'/>
|
||||
<var-decl name='zfeature_checks_disable' type-id='c19b74c3' mangled-name='zfeature_checks_disable' visibility='default' elf-symbol-id='zfeature_checks_disable'/>
|
||||
<function-decl name='opendir' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='80f4b756'/>
|
||||
|
|
|
@ -287,7 +287,7 @@ void
|
|||
zfs_unlinked_drain(zfsvfs_t *zfsvfs)
|
||||
{
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t zap;
|
||||
zap_attribute_t *zap;
|
||||
dmu_object_info_t doi;
|
||||
znode_t *zp;
|
||||
dmu_tx_t *tx;
|
||||
|
@ -296,8 +296,9 @@ zfs_unlinked_drain(zfsvfs_t *zfsvfs)
|
|||
/*
|
||||
* Iterate over the contents of the unlinked set.
|
||||
*/
|
||||
zap = zap_attribute_alloc();
|
||||
for (zap_cursor_init(&zc, zfsvfs->z_os, zfsvfs->z_unlinkedobj);
|
||||
zap_cursor_retrieve(&zc, &zap) == 0;
|
||||
zap_cursor_retrieve(&zc, zap) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
|
||||
/*
|
||||
|
@ -305,7 +306,7 @@ zfs_unlinked_drain(zfsvfs_t *zfsvfs)
|
|||
*/
|
||||
|
||||
error = dmu_object_info(zfsvfs->z_os,
|
||||
zap.za_first_integer, &doi);
|
||||
zap->za_first_integer, &doi);
|
||||
if (error != 0)
|
||||
continue;
|
||||
|
||||
|
@ -315,7 +316,7 @@ zfs_unlinked_drain(zfsvfs_t *zfsvfs)
|
|||
* We need to re-mark these list entries for deletion,
|
||||
* so we pull them back into core and set zp->z_unlinked.
|
||||
*/
|
||||
error = zfs_zget(zfsvfs, zap.za_first_integer, &zp);
|
||||
error = zfs_zget(zfsvfs, zap->za_first_integer, &zp);
|
||||
|
||||
/*
|
||||
* We may pick up znodes that are already marked for deletion.
|
||||
|
@ -351,6 +352,7 @@ zfs_unlinked_drain(zfsvfs_t *zfsvfs)
|
|||
vput(ZTOV(zp));
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(zap);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -368,18 +370,19 @@ static int
|
|||
zfs_purgedir(znode_t *dzp)
|
||||
{
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t zap;
|
||||
zap_attribute_t *zap;
|
||||
znode_t *xzp;
|
||||
dmu_tx_t *tx;
|
||||
zfsvfs_t *zfsvfs = dzp->z_zfsvfs;
|
||||
int skipped = 0;
|
||||
int error;
|
||||
|
||||
zap = zap_attribute_alloc();
|
||||
for (zap_cursor_init(&zc, zfsvfs->z_os, dzp->z_id);
|
||||
(error = zap_cursor_retrieve(&zc, &zap)) == 0;
|
||||
(error = zap_cursor_retrieve(&zc, zap)) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
error = zfs_zget(zfsvfs,
|
||||
ZFS_DIRENT_OBJ(zap.za_first_integer), &xzp);
|
||||
ZFS_DIRENT_OBJ(zap->za_first_integer), &xzp);
|
||||
if (error) {
|
||||
skipped += 1;
|
||||
continue;
|
||||
|
@ -391,7 +394,7 @@ zfs_purgedir(znode_t *dzp)
|
|||
|
||||
tx = dmu_tx_create(zfsvfs->z_os);
|
||||
dmu_tx_hold_sa(tx, dzp->z_sa_hdl, B_FALSE);
|
||||
dmu_tx_hold_zap(tx, dzp->z_id, FALSE, zap.za_name);
|
||||
dmu_tx_hold_zap(tx, dzp->z_id, FALSE, zap->za_name);
|
||||
dmu_tx_hold_sa(tx, xzp->z_sa_hdl, B_FALSE);
|
||||
dmu_tx_hold_zap(tx, zfsvfs->z_unlinkedobj, FALSE, NULL);
|
||||
/* Is this really needed ? */
|
||||
|
@ -405,7 +408,7 @@ zfs_purgedir(znode_t *dzp)
|
|||
continue;
|
||||
}
|
||||
|
||||
error = zfs_link_destroy(dzp, zap.za_name, xzp, tx, 0, NULL);
|
||||
error = zfs_link_destroy(dzp, zap->za_name, xzp, tx, 0, NULL);
|
||||
if (error)
|
||||
skipped += 1;
|
||||
dmu_tx_commit(tx);
|
||||
|
@ -413,6 +416,7 @@ zfs_purgedir(znode_t *dzp)
|
|||
vput(ZTOV(xzp));
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(zap);
|
||||
if (error != ENOENT)
|
||||
skipped += 1;
|
||||
return (skipped);
|
||||
|
|
|
@ -1568,7 +1568,7 @@ zfs_readdir(vnode_t *vp, zfs_uio_t *uio, cred_t *cr, int *eofp,
|
|||
caddr_t outbuf;
|
||||
size_t bufsize;
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t zap;
|
||||
zap_attribute_t *zap;
|
||||
uint_t bytes_wanted;
|
||||
uint64_t offset; /* must be unsigned; checks for < 1 */
|
||||
uint64_t parent;
|
||||
|
@ -1616,6 +1616,7 @@ zfs_readdir(vnode_t *vp, zfs_uio_t *uio, cred_t *cr, int *eofp,
|
|||
os = zfsvfs->z_os;
|
||||
offset = zfs_uio_offset(uio);
|
||||
prefetch = zp->z_zn_prefetch;
|
||||
zap = zap_attribute_alloc();
|
||||
|
||||
/*
|
||||
* Initialize the iterator cursor.
|
||||
|
@ -1671,33 +1672,33 @@ zfs_readdir(vnode_t *vp, zfs_uio_t *uio, cred_t *cr, int *eofp,
|
|||
* Special case `.', `..', and `.zfs'.
|
||||
*/
|
||||
if (offset == 0) {
|
||||
(void) strcpy(zap.za_name, ".");
|
||||
zap.za_normalization_conflict = 0;
|
||||
(void) strcpy(zap->za_name, ".");
|
||||
zap->za_normalization_conflict = 0;
|
||||
objnum = zp->z_id;
|
||||
type = DT_DIR;
|
||||
} else if (offset == 1) {
|
||||
(void) strcpy(zap.za_name, "..");
|
||||
zap.za_normalization_conflict = 0;
|
||||
(void) strcpy(zap->za_name, "..");
|
||||
zap->za_normalization_conflict = 0;
|
||||
objnum = parent;
|
||||
type = DT_DIR;
|
||||
} else if (offset == 2 && zfs_show_ctldir(zp)) {
|
||||
(void) strcpy(zap.za_name, ZFS_CTLDIR_NAME);
|
||||
zap.za_normalization_conflict = 0;
|
||||
(void) strcpy(zap->za_name, ZFS_CTLDIR_NAME);
|
||||
zap->za_normalization_conflict = 0;
|
||||
objnum = ZFSCTL_INO_ROOT;
|
||||
type = DT_DIR;
|
||||
} else {
|
||||
/*
|
||||
* Grab next entry.
|
||||
*/
|
||||
if ((error = zap_cursor_retrieve(&zc, &zap))) {
|
||||
if ((error = zap_cursor_retrieve(&zc, zap))) {
|
||||
if ((*eofp = (error == ENOENT)) != 0)
|
||||
break;
|
||||
else
|
||||
goto update;
|
||||
}
|
||||
|
||||
if (zap.za_integer_length != 8 ||
|
||||
zap.za_num_integers != 1) {
|
||||
if (zap->za_integer_length != 8 ||
|
||||
zap->za_num_integers != 1) {
|
||||
cmn_err(CE_WARN, "zap_readdir: bad directory "
|
||||
"entry, obj = %lld, offset = %lld\n",
|
||||
(u_longlong_t)zp->z_id,
|
||||
|
@ -1706,15 +1707,15 @@ zfs_readdir(vnode_t *vp, zfs_uio_t *uio, cred_t *cr, int *eofp,
|
|||
goto update;
|
||||
}
|
||||
|
||||
objnum = ZFS_DIRENT_OBJ(zap.za_first_integer);
|
||||
objnum = ZFS_DIRENT_OBJ(zap->za_first_integer);
|
||||
/*
|
||||
* MacOS X can extract the object type here such as:
|
||||
* uint8_t type = ZFS_DIRENT_TYPE(zap.za_first_integer);
|
||||
*/
|
||||
type = ZFS_DIRENT_TYPE(zap.za_first_integer);
|
||||
type = ZFS_DIRENT_TYPE(zap->za_first_integer);
|
||||
}
|
||||
|
||||
reclen = DIRENT64_RECLEN(strlen(zap.za_name));
|
||||
reclen = DIRENT64_RECLEN(strlen(zap->za_name));
|
||||
|
||||
/*
|
||||
* Will this entry fit in the buffer?
|
||||
|
@ -1734,10 +1735,10 @@ zfs_readdir(vnode_t *vp, zfs_uio_t *uio, cred_t *cr, int *eofp,
|
|||
*/
|
||||
odp->d_ino = objnum;
|
||||
odp->d_reclen = reclen;
|
||||
odp->d_namlen = strlen(zap.za_name);
|
||||
odp->d_namlen = strlen(zap->za_name);
|
||||
/* NOTE: d_off is the offset for the *next* entry. */
|
||||
next = &odp->d_off;
|
||||
strlcpy(odp->d_name, zap.za_name, odp->d_namlen + 1);
|
||||
strlcpy(odp->d_name, zap->za_name, odp->d_namlen + 1);
|
||||
odp->d_type = type;
|
||||
dirent_terminate(odp);
|
||||
odp = (dirent64_t *)((intptr_t)odp + reclen);
|
||||
|
@ -1788,6 +1789,7 @@ zfs_readdir(vnode_t *vp, zfs_uio_t *uio, cred_t *cr, int *eofp,
|
|||
|
||||
update:
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(zap);
|
||||
if (zfs_uio_segflg(uio) != UIO_SYSSPACE || zfs_uio_iovcnt(uio) != 1)
|
||||
kmem_free(outbuf, bufsize);
|
||||
|
||||
|
|
|
@ -1967,7 +1967,7 @@ zfs_obj_to_path_impl(objset_t *osp, uint64_t obj, sa_handle_t *hdl,
|
|||
(void) sprintf(component + 1, "<xattrdir>");
|
||||
} else {
|
||||
error = zap_value_search(osp, pobj, obj,
|
||||
ZFS_DIRENT_OBJ(-1ULL), component + 1);
|
||||
ZFS_DIRENT_OBJ(-1ULL), component + 1, MAXNAMELEN);
|
||||
if (error != 0)
|
||||
break;
|
||||
}
|
||||
|
@ -2180,7 +2180,7 @@ zfs_znode_parent_and_name(znode_t *zp, znode_t **dzpp, char *buf)
|
|||
return (SET_ERROR(EINVAL));
|
||||
|
||||
err = zap_value_search(zfsvfs->z_os, parent, zp->z_id,
|
||||
ZFS_DIRENT_OBJ(-1ULL), buf);
|
||||
ZFS_DIRENT_OBJ(-1ULL), buf, MAXNAMELEN);
|
||||
if (err != 0)
|
||||
return (err);
|
||||
err = zfs_zget(zfsvfs, parent, dzpp);
|
||||
|
|
|
@ -476,7 +476,7 @@ zfs_unlinked_drain_task(void *arg)
|
|||
{
|
||||
zfsvfs_t *zfsvfs = arg;
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t zap;
|
||||
zap_attribute_t *zap = zap_attribute_alloc();
|
||||
dmu_object_info_t doi;
|
||||
znode_t *zp;
|
||||
int error;
|
||||
|
@ -487,7 +487,7 @@ zfs_unlinked_drain_task(void *arg)
|
|||
* Iterate over the contents of the unlinked set.
|
||||
*/
|
||||
for (zap_cursor_init(&zc, zfsvfs->z_os, zfsvfs->z_unlinkedobj);
|
||||
zap_cursor_retrieve(&zc, &zap) == 0 && !zfsvfs->z_drain_cancel;
|
||||
zap_cursor_retrieve(&zc, zap) == 0 && !zfsvfs->z_drain_cancel;
|
||||
zap_cursor_advance(&zc)) {
|
||||
|
||||
/*
|
||||
|
@ -495,7 +495,7 @@ zfs_unlinked_drain_task(void *arg)
|
|||
*/
|
||||
|
||||
error = dmu_object_info(zfsvfs->z_os,
|
||||
zap.za_first_integer, &doi);
|
||||
zap->za_first_integer, &doi);
|
||||
if (error != 0)
|
||||
continue;
|
||||
|
||||
|
@ -505,7 +505,7 @@ zfs_unlinked_drain_task(void *arg)
|
|||
* We need to re-mark these list entries for deletion,
|
||||
* so we pull them back into core and set zp->z_unlinked.
|
||||
*/
|
||||
error = zfs_zget(zfsvfs, zap.za_first_integer, &zp);
|
||||
error = zfs_zget(zfsvfs, zap->za_first_integer, &zp);
|
||||
|
||||
/*
|
||||
* We may pick up znodes that are already marked for deletion.
|
||||
|
@ -532,6 +532,7 @@ zfs_unlinked_drain_task(void *arg)
|
|||
|
||||
zfsvfs->z_draining = B_FALSE;
|
||||
zfsvfs->z_drain_task = TASKQID_INVALID;
|
||||
zap_attribute_free(zap);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -589,7 +590,7 @@ static int
|
|||
zfs_purgedir(znode_t *dzp)
|
||||
{
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t zap;
|
||||
zap_attribute_t *zap = zap_attribute_alloc();
|
||||
znode_t *xzp;
|
||||
dmu_tx_t *tx;
|
||||
zfsvfs_t *zfsvfs = ZTOZSB(dzp);
|
||||
|
@ -598,10 +599,10 @@ zfs_purgedir(znode_t *dzp)
|
|||
int error;
|
||||
|
||||
for (zap_cursor_init(&zc, zfsvfs->z_os, dzp->z_id);
|
||||
(error = zap_cursor_retrieve(&zc, &zap)) == 0;
|
||||
(error = zap_cursor_retrieve(&zc, zap)) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
error = zfs_zget(zfsvfs,
|
||||
ZFS_DIRENT_OBJ(zap.za_first_integer), &xzp);
|
||||
ZFS_DIRENT_OBJ(zap->za_first_integer), &xzp);
|
||||
if (error) {
|
||||
skipped += 1;
|
||||
continue;
|
||||
|
@ -612,7 +613,7 @@ zfs_purgedir(znode_t *dzp)
|
|||
|
||||
tx = dmu_tx_create(zfsvfs->z_os);
|
||||
dmu_tx_hold_sa(tx, dzp->z_sa_hdl, B_FALSE);
|
||||
dmu_tx_hold_zap(tx, dzp->z_id, FALSE, zap.za_name);
|
||||
dmu_tx_hold_zap(tx, dzp->z_id, FALSE, zap->za_name);
|
||||
dmu_tx_hold_sa(tx, xzp->z_sa_hdl, B_FALSE);
|
||||
dmu_tx_hold_zap(tx, zfsvfs->z_unlinkedobj, FALSE, NULL);
|
||||
/* Is this really needed ? */
|
||||
|
@ -627,7 +628,7 @@ zfs_purgedir(znode_t *dzp)
|
|||
}
|
||||
memset(&dl, 0, sizeof (dl));
|
||||
dl.dl_dzp = dzp;
|
||||
dl.dl_name = zap.za_name;
|
||||
dl.dl_name = zap->za_name;
|
||||
|
||||
error = zfs_link_destroy(&dl, xzp, tx, 0, NULL);
|
||||
if (error)
|
||||
|
@ -637,6 +638,7 @@ zfs_purgedir(znode_t *dzp)
|
|||
zfs_zrele_async(xzp);
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(zap);
|
||||
if (error != ENOENT)
|
||||
skipped += 1;
|
||||
return (skipped);
|
||||
|
@ -800,6 +802,7 @@ zfs_link_create(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag)
|
|||
{
|
||||
znode_t *dzp = dl->dl_dzp;
|
||||
zfsvfs_t *zfsvfs = ZTOZSB(zp);
|
||||
dsl_dataset_t *ds = dmu_objset_ds(zfsvfs->z_os);
|
||||
uint64_t value;
|
||||
int zp_is_dir = S_ISDIR(ZTOI(zp)->i_mode);
|
||||
sa_bulk_attr_t bulk[5];
|
||||
|
@ -845,6 +848,14 @@ zfs_link_create(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag)
|
|||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we added a longname activate the SPA_FEATURE_LONGNAME.
|
||||
*/
|
||||
if (strlen(dl->dl_name) >= ZAP_MAXNAMELEN) {
|
||||
ds->ds_feature_activation[SPA_FEATURE_LONGNAME] =
|
||||
(void *)B_TRUE;
|
||||
}
|
||||
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zfsvfs), NULL,
|
||||
&dzp->z_id, sizeof (dzp->z_id));
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), NULL,
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
#include <sys/dmu_objset.h>
|
||||
#include <sys/dsl_dir.h>
|
||||
#include <sys/objlist.h>
|
||||
#include <sys/zfeature.h>
|
||||
#include <sys/zpl.h>
|
||||
#include <linux/vfs_compat.h>
|
||||
#include "zfs_comutil.h"
|
||||
|
@ -448,6 +449,12 @@ acl_inherit_changed_cb(void *arg, uint64_t newval)
|
|||
((zfsvfs_t *)arg)->z_acl_inherit = newval;
|
||||
}
|
||||
|
||||
static void
|
||||
longname_changed_cb(void *arg, uint64_t newval)
|
||||
{
|
||||
((zfsvfs_t *)arg)->z_longname = newval;
|
||||
}
|
||||
|
||||
static int
|
||||
zfs_register_callbacks(vfs_t *vfsp)
|
||||
{
|
||||
|
@ -508,6 +515,8 @@ zfs_register_callbacks(vfs_t *vfsp)
|
|||
zfsvfs);
|
||||
error = error ? error : dsl_prop_register(ds,
|
||||
zfs_prop_to_name(ZFS_PROP_NBMAND), nbmand_changed_cb, zfsvfs);
|
||||
error = error ? error : dsl_prop_register(ds,
|
||||
zfs_prop_to_name(ZFS_PROP_LONGNAME), longname_changed_cb, zfsvfs);
|
||||
dsl_pool_config_exit(dmu_objset_pool(os), FTAG);
|
||||
if (error)
|
||||
goto unregister;
|
||||
|
@ -1139,7 +1148,8 @@ zfs_statvfs(struct inode *ip, struct kstatfs *statp)
|
|||
statp->f_fsid.val[0] = (uint32_t)fsid;
|
||||
statp->f_fsid.val[1] = (uint32_t)(fsid >> 32);
|
||||
statp->f_type = ZFS_SUPER_MAGIC;
|
||||
statp->f_namelen = MAXNAMELEN - 1;
|
||||
statp->f_namelen =
|
||||
zfsvfs->z_longname ? (ZAP_MAXNAMELEN_NEW - 1) : (MAXNAMELEN - 1);
|
||||
|
||||
/*
|
||||
* We have all of 40 characters to stuff a string here.
|
||||
|
|
|
@ -532,6 +532,46 @@ zfs_lookup(znode_t *zdp, char *nm, znode_t **zpp, int flags, cred_t *cr,
|
|||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a linear search in directory for the name of specific inode.
|
||||
* Note we don't pass in the buffer size of name because it's hardcoded to
|
||||
* NAME_MAX+1(256) in Linux.
|
||||
*
|
||||
* IN: dzp - znode of directory to search.
|
||||
* zp - znode of the target
|
||||
*
|
||||
* OUT: name - dentry name of the target
|
||||
*
|
||||
* RETURN: 0 on success, error code on failure.
|
||||
*/
|
||||
int
|
||||
zfs_get_name(znode_t *dzp, char *name, znode_t *zp)
|
||||
{
|
||||
zfsvfs_t *zfsvfs = ZTOZSB(dzp);
|
||||
int error = 0;
|
||||
|
||||
if ((error = zfs_enter_verify_zp(zfsvfs, dzp, FTAG)) != 0)
|
||||
return (error);
|
||||
|
||||
if ((error = zfs_verify_zp(zp)) != 0) {
|
||||
zfs_exit(zfsvfs, FTAG);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/* ctldir should have got their name in zfs_vget */
|
||||
if (dzp->z_is_ctldir || zp->z_is_ctldir) {
|
||||
zfs_exit(zfsvfs, FTAG);
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
/* buffer len is hardcoded to 256 in Linux kernel */
|
||||
error = zap_value_search(zfsvfs->z_os, dzp->z_id, zp->z_id,
|
||||
ZFS_DIRENT_OBJ(-1ULL), name, ZAP_MAXNAMELEN);
|
||||
|
||||
zfs_exit(zfsvfs, FTAG);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to create a new entry in a directory. If the entry
|
||||
* already exists, truncate the file if permissible, else return
|
||||
|
@ -1513,7 +1553,7 @@ zfs_readdir(struct inode *ip, zpl_dir_context_t *ctx, cred_t *cr)
|
|||
zfsvfs_t *zfsvfs = ITOZSB(ip);
|
||||
objset_t *os;
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t zap;
|
||||
zap_attribute_t *zap;
|
||||
int error;
|
||||
uint8_t prefetch;
|
||||
uint8_t type;
|
||||
|
@ -1538,6 +1578,7 @@ zfs_readdir(struct inode *ip, zpl_dir_context_t *ctx, cred_t *cr)
|
|||
os = zfsvfs->z_os;
|
||||
offset = ctx->pos;
|
||||
prefetch = zp->z_zn_prefetch;
|
||||
zap = zap_attribute_long_alloc();
|
||||
|
||||
/*
|
||||
* Initialize the iterator cursor.
|
||||
|
@ -1563,25 +1604,25 @@ zfs_readdir(struct inode *ip, zpl_dir_context_t *ctx, cred_t *cr)
|
|||
* Special case `.', `..', and `.zfs'.
|
||||
*/
|
||||
if (offset == 0) {
|
||||
(void) strcpy(zap.za_name, ".");
|
||||
zap.za_normalization_conflict = 0;
|
||||
(void) strcpy(zap->za_name, ".");
|
||||
zap->za_normalization_conflict = 0;
|
||||
objnum = zp->z_id;
|
||||
type = DT_DIR;
|
||||
} else if (offset == 1) {
|
||||
(void) strcpy(zap.za_name, "..");
|
||||
zap.za_normalization_conflict = 0;
|
||||
(void) strcpy(zap->za_name, "..");
|
||||
zap->za_normalization_conflict = 0;
|
||||
objnum = parent;
|
||||
type = DT_DIR;
|
||||
} else if (offset == 2 && zfs_show_ctldir(zp)) {
|
||||
(void) strcpy(zap.za_name, ZFS_CTLDIR_NAME);
|
||||
zap.za_normalization_conflict = 0;
|
||||
(void) strcpy(zap->za_name, ZFS_CTLDIR_NAME);
|
||||
zap->za_normalization_conflict = 0;
|
||||
objnum = ZFSCTL_INO_ROOT;
|
||||
type = DT_DIR;
|
||||
} else {
|
||||
/*
|
||||
* Grab next entry.
|
||||
*/
|
||||
if ((error = zap_cursor_retrieve(&zc, &zap))) {
|
||||
if ((error = zap_cursor_retrieve(&zc, zap))) {
|
||||
if (error == ENOENT)
|
||||
break;
|
||||
else
|
||||
|
@ -1595,24 +1636,24 @@ zfs_readdir(struct inode *ip, zpl_dir_context_t *ctx, cred_t *cr)
|
|||
*
|
||||
* XXX: This should be a feature flag for compatibility
|
||||
*/
|
||||
if (zap.za_integer_length != 8 ||
|
||||
zap.za_num_integers == 0) {
|
||||
if (zap->za_integer_length != 8 ||
|
||||
zap->za_num_integers == 0) {
|
||||
cmn_err(CE_WARN, "zap_readdir: bad directory "
|
||||
"entry, obj = %lld, offset = %lld, "
|
||||
"length = %d, num = %lld\n",
|
||||
(u_longlong_t)zp->z_id,
|
||||
(u_longlong_t)offset,
|
||||
zap.za_integer_length,
|
||||
(u_longlong_t)zap.za_num_integers);
|
||||
zap->za_integer_length,
|
||||
(u_longlong_t)zap->za_num_integers);
|
||||
error = SET_ERROR(ENXIO);
|
||||
goto update;
|
||||
}
|
||||
|
||||
objnum = ZFS_DIRENT_OBJ(zap.za_first_integer);
|
||||
type = ZFS_DIRENT_TYPE(zap.za_first_integer);
|
||||
objnum = ZFS_DIRENT_OBJ(zap->za_first_integer);
|
||||
type = ZFS_DIRENT_TYPE(zap->za_first_integer);
|
||||
}
|
||||
|
||||
done = !zpl_dir_emit(ctx, zap.za_name, strlen(zap.za_name),
|
||||
done = !zpl_dir_emit(ctx, zap->za_name, strlen(zap->za_name),
|
||||
objnum, type);
|
||||
if (done)
|
||||
break;
|
||||
|
@ -1635,6 +1676,7 @@ zfs_readdir(struct inode *ip, zpl_dir_context_t *ctx, cred_t *cr)
|
|||
|
||||
update:
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(zap);
|
||||
if (error == ENOENT)
|
||||
error = 0;
|
||||
out:
|
||||
|
@ -1733,7 +1775,7 @@ zfs_setattr_dir(znode_t *dzp)
|
|||
zfsvfs_t *zfsvfs = ZTOZSB(dzp);
|
||||
objset_t *os = zfsvfs->z_os;
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t zap;
|
||||
zap_attribute_t *zap;
|
||||
zfs_dirlock_t *dl;
|
||||
znode_t *zp = NULL;
|
||||
dmu_tx_t *tx = NULL;
|
||||
|
@ -1742,15 +1784,16 @@ zfs_setattr_dir(znode_t *dzp)
|
|||
int count;
|
||||
int err;
|
||||
|
||||
zap = zap_attribute_alloc();
|
||||
zap_cursor_init(&zc, os, dzp->z_id);
|
||||
while ((err = zap_cursor_retrieve(&zc, &zap)) == 0) {
|
||||
while ((err = zap_cursor_retrieve(&zc, zap)) == 0) {
|
||||
count = 0;
|
||||
if (zap.za_integer_length != 8 || zap.za_num_integers != 1) {
|
||||
if (zap->za_integer_length != 8 || zap->za_num_integers != 1) {
|
||||
err = ENXIO;
|
||||
break;
|
||||
}
|
||||
|
||||
err = zfs_dirent_lock(&dl, dzp, (char *)zap.za_name, &zp,
|
||||
err = zfs_dirent_lock(&dl, dzp, (char *)zap->za_name, &zp,
|
||||
ZEXISTS, NULL, NULL);
|
||||
if (err == ENOENT)
|
||||
goto next;
|
||||
|
@ -1842,6 +1885,7 @@ next:
|
|||
zfs_dirent_unlock(dl);
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(zap);
|
||||
|
||||
return (err == ENOENT ? 0 : err);
|
||||
}
|
||||
|
|
|
@ -2145,6 +2145,7 @@ zfs_obj_to_path_impl(objset_t *osp, uint64_t obj, sa_handle_t *hdl,
|
|||
dmu_buf_t *prevdb = NULL;
|
||||
dmu_buf_t *sa_db = NULL;
|
||||
char *path = buf + len - 1;
|
||||
char *comp_buf;
|
||||
int error;
|
||||
|
||||
*path = '\0';
|
||||
|
@ -2160,9 +2161,10 @@ zfs_obj_to_path_impl(objset_t *osp, uint64_t obj, sa_handle_t *hdl,
|
|||
return (error);
|
||||
}
|
||||
|
||||
comp_buf = kmem_alloc(ZAP_MAXNAMELEN_NEW + 2, KM_SLEEP);
|
||||
for (;;) {
|
||||
uint64_t pobj = 0;
|
||||
char component[MAXNAMELEN + 2];
|
||||
char *component = comp_buf;
|
||||
size_t complen;
|
||||
int is_xattrdir = 0;
|
||||
|
||||
|
@ -2186,7 +2188,8 @@ zfs_obj_to_path_impl(objset_t *osp, uint64_t obj, sa_handle_t *hdl,
|
|||
strcpy(component + 1, "<xattrdir>");
|
||||
} else {
|
||||
error = zap_value_search(osp, pobj, obj,
|
||||
ZFS_DIRENT_OBJ(-1ULL), component + 1);
|
||||
ZFS_DIRENT_OBJ(-1ULL), component + 1,
|
||||
ZAP_MAXNAMELEN_NEW);
|
||||
if (error != 0)
|
||||
break;
|
||||
}
|
||||
|
@ -2217,6 +2220,7 @@ zfs_obj_to_path_impl(objset_t *osp, uint64_t obj, sa_handle_t *hdl,
|
|||
if (error == 0)
|
||||
(void) memmove(buf, path, buf + len - path);
|
||||
|
||||
kmem_free(comp_buf, ZAP_MAXNAMELEN_NEW +2);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
*/
|
||||
|
||||
|
||||
#include <sys/file.h>
|
||||
#include <sys/zfs_znode.h>
|
||||
#include <sys/zfs_vnops.h>
|
||||
#include <sys/zfs_ctldir.h>
|
||||
|
@ -109,6 +110,35 @@ zpl_fh_to_dentry(struct super_block *sb, struct fid *fh,
|
|||
return (d_obtain_alias(ip));
|
||||
}
|
||||
|
||||
/*
|
||||
* In case the filesystem contains name longer than 255, we need to override
|
||||
* the default get_name so we don't get buffer overflow. Unfortunately, since
|
||||
* the buffer size is hardcoded in Linux, we will get ESTALE error in this
|
||||
* case.
|
||||
*/
|
||||
static int
|
||||
zpl_get_name(struct dentry *parent, char *name, struct dentry *child)
|
||||
{
|
||||
cred_t *cr = CRED();
|
||||
fstrans_cookie_t cookie;
|
||||
struct inode *dir = parent->d_inode;
|
||||
struct inode *ip = child->d_inode;
|
||||
int error;
|
||||
|
||||
if (!dir || !S_ISDIR(dir->i_mode))
|
||||
return (-ENOTDIR);
|
||||
|
||||
crhold(cr);
|
||||
cookie = spl_fstrans_mark();
|
||||
spl_inode_lock_shared(dir);
|
||||
error = -zfs_get_name(ITOZ(dir), name, ITOZ(ip));
|
||||
spl_inode_unlock_shared(dir);
|
||||
spl_fstrans_unmark(cookie);
|
||||
crfree(cr);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static struct dentry *
|
||||
zpl_get_parent(struct dentry *child)
|
||||
{
|
||||
|
@ -153,6 +183,7 @@ zpl_commit_metadata(struct inode *inode)
|
|||
const struct export_operations zpl_export_operations = {
|
||||
.encode_fh = zpl_encode_fh,
|
||||
.fh_to_dentry = zpl_fh_to_dentry,
|
||||
.get_name = zpl_get_name,
|
||||
.get_parent = zpl_get_parent,
|
||||
.commit_metadata = zpl_commit_metadata,
|
||||
};
|
||||
|
|
|
@ -46,9 +46,29 @@ zpl_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
|
|||
pathname_t pn;
|
||||
int zfs_flags = 0;
|
||||
zfsvfs_t *zfsvfs = dentry->d_sb->s_fs_info;
|
||||
dsl_dataset_t *ds = dmu_objset_ds(zfsvfs->z_os);
|
||||
size_t dlen = dlen(dentry);
|
||||
|
||||
if (dlen(dentry) >= ZAP_MAXNAMELEN)
|
||||
/*
|
||||
* If z_longname is disabled, disallow create or rename of names
|
||||
* longer than ZAP_MAXNAMELEN.
|
||||
*
|
||||
* This is needed in cases where longname was enabled first and some
|
||||
* files/dirs with names > ZAP_MAXNAMELEN were created. And later
|
||||
* longname was disabled. In such a case allow access to existing
|
||||
* longnames. But disallow creation newer longnamed entities.
|
||||
*/
|
||||
if (!zfsvfs->z_longname && (dlen >= ZAP_MAXNAMELEN)) {
|
||||
/*
|
||||
* If this is for create or rename fail it.
|
||||
*/
|
||||
if (!dsl_dataset_feature_is_active(ds, SPA_FEATURE_LONGNAME) ||
|
||||
(flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET)))
|
||||
return (ERR_PTR(-ENAMETOOLONG));
|
||||
}
|
||||
if (dlen >= ZAP_MAXNAMELEN_NEW) {
|
||||
return (ERR_PTR(-ENAMETOOLONG));
|
||||
}
|
||||
|
||||
crhold(cr);
|
||||
cookie = spl_fstrans_mark();
|
||||
|
@ -131,6 +151,16 @@ zpl_vap_init(vattr_t *vap, struct inode *dir, umode_t mode, cred_t *cr,
|
|||
}
|
||||
}
|
||||
|
||||
static inline bool
|
||||
is_nametoolong(struct dentry *dentry)
|
||||
{
|
||||
zfsvfs_t *zfsvfs = dentry->d_sb->s_fs_info;
|
||||
size_t dlen = dlen(dentry);
|
||||
|
||||
return ((!zfsvfs->z_longname && dlen >= ZAP_MAXNAMELEN) ||
|
||||
dlen >= ZAP_MAXNAMELEN_NEW);
|
||||
}
|
||||
|
||||
static int
|
||||
#ifdef HAVE_IOPS_CREATE_USERNS
|
||||
zpl_create(struct user_namespace *user_ns, struct inode *dir,
|
||||
|
@ -151,6 +181,10 @@ zpl_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool flag)
|
|||
zidmap_t *user_ns = kcred->user_ns;
|
||||
#endif
|
||||
|
||||
if (is_nametoolong(dentry)) {
|
||||
return (-ENAMETOOLONG);
|
||||
}
|
||||
|
||||
crhold(cr);
|
||||
vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
|
||||
zpl_vap_init(vap, dir, mode, cr, user_ns);
|
||||
|
@ -201,6 +235,10 @@ zpl_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
|
|||
zidmap_t *user_ns = kcred->user_ns;
|
||||
#endif
|
||||
|
||||
if (is_nametoolong(dentry)) {
|
||||
return (-ENAMETOOLONG);
|
||||
}
|
||||
|
||||
/*
|
||||
* We currently expect Linux to supply rdev=0 for all sockets
|
||||
* and fifos, but we want to know if this behavior ever changes.
|
||||
|
@ -355,6 +393,10 @@ zpl_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
|
|||
zidmap_t *user_ns = kcred->user_ns;
|
||||
#endif
|
||||
|
||||
if (is_nametoolong(dentry)) {
|
||||
return (-ENAMETOOLONG);
|
||||
}
|
||||
|
||||
crhold(cr);
|
||||
vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
|
||||
zpl_vap_init(vap, dir, mode | S_IFDIR, cr, user_ns);
|
||||
|
@ -570,6 +612,10 @@ zpl_rename2(struct inode *sdip, struct dentry *sdentry,
|
|||
zidmap_t *user_ns = kcred->user_ns;
|
||||
#endif
|
||||
|
||||
if (is_nametoolong(tdentry)) {
|
||||
return (-ENAMETOOLONG);
|
||||
}
|
||||
|
||||
crhold(cr);
|
||||
if (rflags & RENAME_WHITEOUT) {
|
||||
wo_vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
|
||||
|
@ -621,6 +667,10 @@ zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)
|
|||
zidmap_t *user_ns = kcred->user_ns;
|
||||
#endif
|
||||
|
||||
if (is_nametoolong(dentry)) {
|
||||
return (-ENAMETOOLONG);
|
||||
}
|
||||
|
||||
crhold(cr);
|
||||
vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
|
||||
zpl_vap_init(vap, dir, S_IFLNK | S_IRWXUGO, cr, user_ns);
|
||||
|
@ -773,6 +823,10 @@ zpl_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
|
|||
int error;
|
||||
fstrans_cookie_t cookie;
|
||||
|
||||
if (is_nametoolong(dentry)) {
|
||||
return (-ENAMETOOLONG);
|
||||
}
|
||||
|
||||
if (ip->i_nlink >= ZFS_LINK_MAX)
|
||||
return (-EMLINK);
|
||||
|
||||
|
|
|
@ -153,19 +153,20 @@ static int
|
|||
zpl_xattr_readdir(struct inode *dxip, xattr_filldir_t *xf)
|
||||
{
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t zap;
|
||||
zap_attribute_t *zap = zap_attribute_alloc();
|
||||
int error;
|
||||
|
||||
zap_cursor_init(&zc, ITOZSB(dxip)->z_os, ITOZ(dxip)->z_id);
|
||||
|
||||
while ((error = -zap_cursor_retrieve(&zc, &zap)) == 0) {
|
||||
while ((error = -zap_cursor_retrieve(&zc, zap)) == 0) {
|
||||
|
||||
if (zap.za_integer_length != 8 || zap.za_num_integers != 1) {
|
||||
if (zap->za_integer_length != 8 || zap->za_num_integers != 1) {
|
||||
error = -ENXIO;
|
||||
break;
|
||||
}
|
||||
|
||||
error = zpl_xattr_filldir(xf, zap.za_name, strlen(zap.za_name));
|
||||
error = zpl_xattr_filldir(xf, zap->za_name,
|
||||
strlen(zap->za_name));
|
||||
if (error)
|
||||
break;
|
||||
|
||||
|
@ -173,6 +174,7 @@ zpl_xattr_readdir(struct inode *dxip, xattr_filldir_t *xf)
|
|||
}
|
||||
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(zap);
|
||||
|
||||
if (error == -ENOENT)
|
||||
error = 0;
|
||||
|
|
|
@ -754,6 +754,19 @@ zpool_feature_init(void)
|
|||
"Support for raidz expansion",
|
||||
ZFEATURE_FLAG_MOS, ZFEATURE_TYPE_BOOLEAN, NULL, sfeatures);
|
||||
|
||||
{
|
||||
static const spa_feature_t longname_deps[] = {
|
||||
SPA_FEATURE_EXTENSIBLE_DATASET,
|
||||
SPA_FEATURE_ENABLED_TXG,
|
||||
SPA_FEATURE_NONE
|
||||
};
|
||||
zfeature_register(SPA_FEATURE_LONGNAME,
|
||||
"org.zfsonlinux:longname", "longname",
|
||||
"support filename upto 1024 bytes",
|
||||
ZFEATURE_FLAG_READONLY_COMPAT | ZFEATURE_FLAG_PER_DATASET,
|
||||
ZFEATURE_TYPE_BOOLEAN, longname_deps, sfeatures);
|
||||
}
|
||||
|
||||
zfs_mod_list_supported_free(sfeatures);
|
||||
}
|
||||
|
||||
|
|
|
@ -760,6 +760,10 @@ zfs_prop_init(void)
|
|||
ZFS_TYPE_VOLUME, "<date>", "SNAPSHOTS_CHANGED", B_FALSE, B_TRUE,
|
||||
B_TRUE, NULL, sfeatures);
|
||||
|
||||
zprop_register_index(ZFS_PROP_LONGNAME, "longname", 0, PROP_INHERIT,
|
||||
ZFS_TYPE_FILESYSTEM, "on | off", "LONGNAME", boolean_table,
|
||||
sfeatures);
|
||||
|
||||
zfs_mod_list_supported_free(sfeatures);
|
||||
}
|
||||
|
||||
|
|
|
@ -184,9 +184,10 @@ ddt_zap_walk(objset_t *os, uint64_t object, uint64_t *walk, ddt_key_t *ddk,
|
|||
ddt_phys_t *phys, size_t psize)
|
||||
{
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za;
|
||||
int error;
|
||||
|
||||
za = zap_attribute_alloc();
|
||||
if (*walk == 0) {
|
||||
/*
|
||||
* We don't want to prefetch the entire ZAP object, because
|
||||
|
@ -199,20 +200,20 @@ ddt_zap_walk(objset_t *os, uint64_t object, uint64_t *walk, ddt_key_t *ddk,
|
|||
} else {
|
||||
zap_cursor_init_serialized(&zc, os, object, *walk);
|
||||
}
|
||||
if ((error = zap_cursor_retrieve(&zc, &za)) == 0) {
|
||||
uint64_t csize = za.za_num_integers;
|
||||
if ((error = zap_cursor_retrieve(&zc, za)) == 0) {
|
||||
uint64_t csize = za->za_num_integers;
|
||||
|
||||
ASSERT3U(za.za_integer_length, ==, 1);
|
||||
ASSERT3U(za->za_integer_length, ==, 1);
|
||||
ASSERT3U(csize, <=, psize + 1);
|
||||
|
||||
uchar_t *cbuf = kmem_alloc(csize, KM_SLEEP);
|
||||
|
||||
error = zap_lookup_uint64(os, object, (uint64_t *)za.za_name,
|
||||
error = zap_lookup_uint64(os, object, (uint64_t *)za->za_name,
|
||||
DDT_KEY_WORDS, 1, csize, cbuf);
|
||||
ASSERT0(error);
|
||||
if (error == 0) {
|
||||
ddt_zap_decompress(cbuf, phys, csize, psize);
|
||||
*ddk = *(ddt_key_t *)za.za_name;
|
||||
*ddk = *(ddt_key_t *)za->za_name;
|
||||
}
|
||||
|
||||
kmem_free(cbuf, csize);
|
||||
|
@ -221,6 +222,7 @@ ddt_zap_walk(objset_t *os, uint64_t object, uint64_t *walk, ddt_key_t *ddk,
|
|||
*walk = zap_cursor_serialize(&zc);
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
|
@ -2615,35 +2615,39 @@ dmu_snapshot_list_next(objset_t *os, int namelen, char *name,
|
|||
{
|
||||
dsl_dataset_t *ds = os->os_dsl_dataset;
|
||||
zap_cursor_t cursor;
|
||||
zap_attribute_t attr;
|
||||
zap_attribute_t *attr;
|
||||
|
||||
ASSERT(dsl_pool_config_held(dmu_objset_pool(os)));
|
||||
|
||||
if (dsl_dataset_phys(ds)->ds_snapnames_zapobj == 0)
|
||||
return (SET_ERROR(ENOENT));
|
||||
|
||||
attr = zap_attribute_alloc();
|
||||
zap_cursor_init_serialized(&cursor,
|
||||
ds->ds_dir->dd_pool->dp_meta_objset,
|
||||
dsl_dataset_phys(ds)->ds_snapnames_zapobj, *offp);
|
||||
|
||||
if (zap_cursor_retrieve(&cursor, &attr) != 0) {
|
||||
if (zap_cursor_retrieve(&cursor, attr) != 0) {
|
||||
zap_cursor_fini(&cursor);
|
||||
zap_attribute_free(attr);
|
||||
return (SET_ERROR(ENOENT));
|
||||
}
|
||||
|
||||
if (strlen(attr.za_name) + 1 > namelen) {
|
||||
if (strlen(attr->za_name) + 1 > namelen) {
|
||||
zap_cursor_fini(&cursor);
|
||||
zap_attribute_free(attr);
|
||||
return (SET_ERROR(ENAMETOOLONG));
|
||||
}
|
||||
|
||||
(void) strlcpy(name, attr.za_name, namelen);
|
||||
(void) strlcpy(name, attr->za_name, namelen);
|
||||
if (idp)
|
||||
*idp = attr.za_first_integer;
|
||||
*idp = attr->za_first_integer;
|
||||
if (case_conflict)
|
||||
*case_conflict = attr.za_normalization_conflict;
|
||||
*case_conflict = attr->za_normalization_conflict;
|
||||
zap_cursor_advance(&cursor);
|
||||
*offp = zap_cursor_serialize(&cursor);
|
||||
zap_cursor_fini(&cursor);
|
||||
zap_attribute_free(attr);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -2660,33 +2664,37 @@ dmu_dir_list_next(objset_t *os, int namelen, char *name,
|
|||
{
|
||||
dsl_dir_t *dd = os->os_dsl_dataset->ds_dir;
|
||||
zap_cursor_t cursor;
|
||||
zap_attribute_t attr;
|
||||
zap_attribute_t *attr;
|
||||
|
||||
/* there is no next dir on a snapshot! */
|
||||
if (os->os_dsl_dataset->ds_object !=
|
||||
dsl_dir_phys(dd)->dd_head_dataset_obj)
|
||||
return (SET_ERROR(ENOENT));
|
||||
|
||||
attr = zap_attribute_alloc();
|
||||
zap_cursor_init_serialized(&cursor,
|
||||
dd->dd_pool->dp_meta_objset,
|
||||
dsl_dir_phys(dd)->dd_child_dir_zapobj, *offp);
|
||||
|
||||
if (zap_cursor_retrieve(&cursor, &attr) != 0) {
|
||||
if (zap_cursor_retrieve(&cursor, attr) != 0) {
|
||||
zap_cursor_fini(&cursor);
|
||||
zap_attribute_free(attr);
|
||||
return (SET_ERROR(ENOENT));
|
||||
}
|
||||
|
||||
if (strlen(attr.za_name) + 1 > namelen) {
|
||||
if (strlen(attr->za_name) + 1 > namelen) {
|
||||
zap_cursor_fini(&cursor);
|
||||
zap_attribute_free(attr);
|
||||
return (SET_ERROR(ENAMETOOLONG));
|
||||
}
|
||||
|
||||
(void) strlcpy(name, attr.za_name, namelen);
|
||||
(void) strlcpy(name, attr->za_name, namelen);
|
||||
if (idp)
|
||||
*idp = attr.za_first_integer;
|
||||
*idp = attr->za_first_integer;
|
||||
zap_cursor_advance(&cursor);
|
||||
*offp = zap_cursor_serialize(&cursor);
|
||||
zap_cursor_fini(&cursor);
|
||||
zap_attribute_free(attr);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -2734,7 +2742,7 @@ dmu_objset_find_dp_impl(dmu_objset_find_ctx_t *dcp)
|
|||
}
|
||||
|
||||
thisobj = dsl_dir_phys(dd)->dd_head_dataset_obj;
|
||||
attr = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
|
||||
attr = zap_attribute_alloc();
|
||||
|
||||
/*
|
||||
* Iterate over all children.
|
||||
|
@ -2795,7 +2803,7 @@ dmu_objset_find_dp_impl(dmu_objset_find_ctx_t *dcp)
|
|||
}
|
||||
}
|
||||
|
||||
kmem_free(attr, sizeof (zap_attribute_t));
|
||||
zap_attribute_free(attr);
|
||||
|
||||
if (err != 0) {
|
||||
dsl_dir_rele(dd, FTAG);
|
||||
|
@ -2969,7 +2977,7 @@ dmu_objset_find_impl(spa_t *spa, const char *name,
|
|||
}
|
||||
|
||||
thisobj = dsl_dir_phys(dd)->dd_head_dataset_obj;
|
||||
attr = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
|
||||
attr = zap_attribute_alloc();
|
||||
|
||||
/*
|
||||
* Iterate over all children.
|
||||
|
@ -2997,7 +3005,7 @@ dmu_objset_find_impl(spa_t *spa, const char *name,
|
|||
if (err != 0) {
|
||||
dsl_dir_rele(dd, FTAG);
|
||||
dsl_pool_config_exit(dp, FTAG);
|
||||
kmem_free(attr, sizeof (zap_attribute_t));
|
||||
zap_attribute_free(attr);
|
||||
return (err);
|
||||
}
|
||||
}
|
||||
|
@ -3035,7 +3043,7 @@ dmu_objset_find_impl(spa_t *spa, const char *name,
|
|||
}
|
||||
|
||||
dsl_dir_rele(dd, FTAG);
|
||||
kmem_free(attr, sizeof (zap_attribute_t));
|
||||
zap_attribute_free(attr);
|
||||
dsl_pool_config_exit(dp, FTAG);
|
||||
|
||||
if (err != 0)
|
||||
|
|
|
@ -602,6 +602,13 @@ recv_begin_check_feature_flags_impl(uint64_t featureflags, spa_t *spa)
|
|||
!spa_feature_is_enabled(spa, SPA_FEATURE_REDACTED_DATASETS))
|
||||
return (SET_ERROR(ENOTSUP));
|
||||
|
||||
/*
|
||||
* If the LONGNAME is not enabled on the target, fail that request.
|
||||
*/
|
||||
if ((featureflags & DMU_BACKUP_FEATURE_LONGNAME) &&
|
||||
!spa_feature_is_enabled(spa, SPA_FEATURE_LONGNAME))
|
||||
return (SET_ERROR(ENOTSUP));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -990,6 +997,16 @@ dmu_recv_begin_sync(void *arg, dmu_tx_t *tx)
|
|||
dmu_buf_will_dirty(newds->ds_dbuf, tx);
|
||||
dsl_dataset_phys(newds)->ds_flags |= DS_FLAG_INCONSISTENT;
|
||||
|
||||
/*
|
||||
* Activate longname feature if received
|
||||
*/
|
||||
if (featureflags & DMU_BACKUP_FEATURE_LONGNAME &&
|
||||
!dsl_dataset_feature_is_active(newds, SPA_FEATURE_LONGNAME)) {
|
||||
dsl_dataset_activate_feature(newds->ds_object,
|
||||
SPA_FEATURE_LONGNAME, (void *)B_TRUE, tx);
|
||||
newds->ds_feature[SPA_FEATURE_LONGNAME] = (void *)B_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we actually created a non-clone, we need to create the objset
|
||||
* in our new dataset. If this is a raw send we postpone this until
|
||||
|
|
|
@ -189,7 +189,7 @@ zfs_get_deleteq(objset_t *os)
|
|||
objlist_t *deleteq_objlist = objlist_create();
|
||||
uint64_t deleteq_obj;
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za;
|
||||
dmu_object_info_t doi;
|
||||
|
||||
ASSERT3U(os->os_phys->os_type, ==, DMU_OST_ZFS);
|
||||
|
@ -208,13 +208,15 @@ zfs_get_deleteq(objset_t *os)
|
|||
avl_create(&at, objnode_compare, sizeof (struct objnode),
|
||||
offsetof(struct objnode, node));
|
||||
|
||||
za = zap_attribute_alloc();
|
||||
for (zap_cursor_init(&zc, os, deleteq_obj);
|
||||
zap_cursor_retrieve(&zc, &za) == 0; zap_cursor_advance(&zc)) {
|
||||
zap_cursor_retrieve(&zc, za) == 0; zap_cursor_advance(&zc)) {
|
||||
struct objnode *obj = kmem_zalloc(sizeof (*obj), KM_SLEEP);
|
||||
obj->obj = za.za_first_integer;
|
||||
obj->obj = za->za_first_integer;
|
||||
avl_add(&at, obj);
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
|
||||
struct objnode *next, *found = avl_first(&at);
|
||||
while (found != NULL) {
|
||||
|
|
|
@ -2011,6 +2011,10 @@ setup_featureflags(struct dmu_send_params *dspp, objset_t *os,
|
|||
if (dsl_dataset_feature_is_active(to_ds, SPA_FEATURE_LARGE_DNODE)) {
|
||||
*featureflags |= DMU_BACKUP_FEATURE_LARGE_DNODE;
|
||||
}
|
||||
|
||||
if (dsl_dataset_feature_is_active(to_ds, SPA_FEATURE_LONGNAME)) {
|
||||
*featureflags |= DMU_BACKUP_FEATURE_LONGNAME;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
|
@ -870,13 +870,14 @@ dsl_bookmark_init_ds(dsl_dataset_t *ds)
|
|||
|
||||
int err = 0;
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t attr;
|
||||
zap_attribute_t *attr;
|
||||
|
||||
attr = zap_attribute_alloc();
|
||||
for (zap_cursor_init(&zc, mos, ds->ds_bookmarks_obj);
|
||||
(err = zap_cursor_retrieve(&zc, &attr)) == 0;
|
||||
(err = zap_cursor_retrieve(&zc, attr)) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
dsl_bookmark_node_t *dbn =
|
||||
dsl_bookmark_node_alloc(attr.za_name);
|
||||
dsl_bookmark_node_alloc(attr->za_name);
|
||||
|
||||
err = dsl_bookmark_lookup_impl(ds,
|
||||
dbn->dbn_name, &dbn->dbn_phys);
|
||||
|
@ -888,6 +889,7 @@ dsl_bookmark_init_ds(dsl_dataset_t *ds)
|
|||
avl_add(&ds->ds_bookmarks, dbn);
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(attr);
|
||||
if (err == ENOENT)
|
||||
err = 0;
|
||||
return (err);
|
||||
|
|
|
@ -1497,7 +1497,7 @@ spa_keystore_change_key_sync_impl(uint64_t rddobj, uint64_t ddobj,
|
|||
}
|
||||
|
||||
zc = kmem_alloc(sizeof (zap_cursor_t), KM_SLEEP);
|
||||
za = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
|
||||
za = zap_attribute_alloc();
|
||||
|
||||
/* Recurse into all child dsl dirs. */
|
||||
for (zap_cursor_init(zc, dp->dp_meta_objset,
|
||||
|
@ -1529,7 +1529,7 @@ spa_keystore_change_key_sync_impl(uint64_t rddobj, uint64_t ddobj,
|
|||
}
|
||||
zap_cursor_fini(zc);
|
||||
|
||||
kmem_free(za, sizeof (zap_attribute_t));
|
||||
zap_attribute_free(za);
|
||||
kmem_free(zc, sizeof (zap_cursor_t));
|
||||
|
||||
dsl_dir_rele(dd, FTAG);
|
||||
|
|
|
@ -494,7 +494,8 @@ dsl_dataset_get_snapname(dsl_dataset_t *ds)
|
|||
return (err);
|
||||
headphys = headdbuf->db_data;
|
||||
err = zap_value_search(dp->dp_meta_objset,
|
||||
headphys->ds_snapnames_zapobj, ds->ds_object, 0, ds->ds_snapname);
|
||||
headphys->ds_snapnames_zapobj, ds->ds_object, 0, ds->ds_snapname,
|
||||
sizeof (ds->ds_snapname));
|
||||
if (err != 0 && zfs_recover == B_TRUE) {
|
||||
err = 0;
|
||||
(void) snprintf(ds->ds_snapname, sizeof (ds->ds_snapname),
|
||||
|
@ -2290,7 +2291,7 @@ get_clones_stat_impl(dsl_dataset_t *ds, nvlist_t *val)
|
|||
uint64_t count = 0;
|
||||
objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za;
|
||||
|
||||
ASSERT(dsl_pool_config_held(ds->ds_dir->dd_pool));
|
||||
|
||||
|
@ -2306,19 +2307,22 @@ get_clones_stat_impl(dsl_dataset_t *ds, nvlist_t *val)
|
|||
if (count != dsl_dataset_phys(ds)->ds_num_children - 1) {
|
||||
return (SET_ERROR(ENOENT));
|
||||
}
|
||||
|
||||
za = zap_attribute_alloc();
|
||||
for (zap_cursor_init(&zc, mos,
|
||||
dsl_dataset_phys(ds)->ds_next_clones_obj);
|
||||
zap_cursor_retrieve(&zc, &za) == 0;
|
||||
zap_cursor_retrieve(&zc, za) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
dsl_dataset_t *clone;
|
||||
char buf[ZFS_MAX_DATASET_NAME_LEN];
|
||||
VERIFY0(dsl_dataset_hold_obj(ds->ds_dir->dd_pool,
|
||||
za.za_first_integer, FTAG, &clone));
|
||||
za->za_first_integer, FTAG, &clone));
|
||||
dsl_dir_name(clone->ds_dir, buf);
|
||||
fnvlist_add_boolean(val, buf);
|
||||
dsl_dataset_rele(clone, FTAG);
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -3640,16 +3644,16 @@ dsl_dataset_promote_sync(void *arg, dmu_tx_t *tx)
|
|||
if (dsl_dataset_phys(ds)->ds_next_clones_obj &&
|
||||
spa_version(dp->dp_spa) >= SPA_VERSION_DIR_CLONES) {
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za = zap_attribute_alloc();
|
||||
|
||||
for (zap_cursor_init(&zc, dp->dp_meta_objset,
|
||||
dsl_dataset_phys(ds)->ds_next_clones_obj);
|
||||
zap_cursor_retrieve(&zc, &za) == 0;
|
||||
zap_cursor_retrieve(&zc, za) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
dsl_dataset_t *cnds;
|
||||
uint64_t o;
|
||||
|
||||
if (za.za_first_integer == oldnext_obj) {
|
||||
if (za->za_first_integer == oldnext_obj) {
|
||||
/*
|
||||
* We've already moved the
|
||||
* origin's reference.
|
||||
|
@ -3658,7 +3662,7 @@ dsl_dataset_promote_sync(void *arg, dmu_tx_t *tx)
|
|||
}
|
||||
|
||||
VERIFY0(dsl_dataset_hold_obj(dp,
|
||||
za.za_first_integer, FTAG, &cnds));
|
||||
za->za_first_integer, FTAG, &cnds));
|
||||
o = dsl_dir_phys(cnds->ds_dir)->
|
||||
dd_head_dataset_obj;
|
||||
|
||||
|
@ -3669,6 +3673,7 @@ dsl_dataset_promote_sync(void *arg, dmu_tx_t *tx)
|
|||
dsl_dataset_rele(cnds, FTAG);
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
}
|
||||
|
||||
ASSERT(!dsl_prop_hascb(ds));
|
||||
|
|
|
@ -133,7 +133,7 @@ static void
|
|||
dsl_deadlist_load_tree(dsl_deadlist_t *dl)
|
||||
{
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za;
|
||||
int error;
|
||||
|
||||
ASSERT(MUTEX_HELD(&dl->dl_lock));
|
||||
|
@ -159,20 +159,21 @@ dsl_deadlist_load_tree(dsl_deadlist_t *dl)
|
|||
if (dl->dl_havetree)
|
||||
return;
|
||||
|
||||
za = zap_attribute_alloc();
|
||||
avl_create(&dl->dl_tree, dsl_deadlist_compare,
|
||||
sizeof (dsl_deadlist_entry_t),
|
||||
offsetof(dsl_deadlist_entry_t, dle_node));
|
||||
for (zap_cursor_init(&zc, dl->dl_os, dl->dl_object);
|
||||
(error = zap_cursor_retrieve(&zc, &za)) == 0;
|
||||
(error = zap_cursor_retrieve(&zc, za)) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
dsl_deadlist_entry_t *dle = kmem_alloc(sizeof (*dle), KM_SLEEP);
|
||||
dle->dle_mintxg = zfs_strtonum(za.za_name, NULL);
|
||||
dle->dle_mintxg = zfs_strtonum(za->za_name, NULL);
|
||||
|
||||
/*
|
||||
* Prefetch all the bpobj's so that we do that i/o
|
||||
* in parallel. Then open them all in a second pass.
|
||||
*/
|
||||
dle->dle_bpobj.bpo_object = za.za_first_integer;
|
||||
dle->dle_bpobj.bpo_object = za->za_first_integer;
|
||||
dmu_prefetch_dnode(dl->dl_os, dle->dle_bpobj.bpo_object,
|
||||
ZIO_PRIORITY_SYNC_READ);
|
||||
|
||||
|
@ -180,6 +181,7 @@ dsl_deadlist_load_tree(dsl_deadlist_t *dl)
|
|||
}
|
||||
VERIFY3U(error, ==, ENOENT);
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
|
||||
for (dsl_deadlist_entry_t *dle = avl_first(&dl->dl_tree);
|
||||
dle != NULL; dle = AVL_NEXT(&dl->dl_tree, dle)) {
|
||||
|
@ -207,7 +209,7 @@ static void
|
|||
dsl_deadlist_load_cache(dsl_deadlist_t *dl)
|
||||
{
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za;
|
||||
int error;
|
||||
|
||||
ASSERT(MUTEX_HELD(&dl->dl_lock));
|
||||
|
@ -221,26 +223,28 @@ dsl_deadlist_load_cache(dsl_deadlist_t *dl)
|
|||
avl_create(&dl->dl_cache, dsl_deadlist_cache_compare,
|
||||
sizeof (dsl_deadlist_cache_entry_t),
|
||||
offsetof(dsl_deadlist_cache_entry_t, dlce_node));
|
||||
za = zap_attribute_alloc();
|
||||
for (zap_cursor_init(&zc, dl->dl_os, dl->dl_object);
|
||||
(error = zap_cursor_retrieve(&zc, &za)) == 0;
|
||||
(error = zap_cursor_retrieve(&zc, za)) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
if (za.za_first_integer == empty_bpobj)
|
||||
if (za->za_first_integer == empty_bpobj)
|
||||
continue;
|
||||
dsl_deadlist_cache_entry_t *dlce =
|
||||
kmem_zalloc(sizeof (*dlce), KM_SLEEP);
|
||||
dlce->dlce_mintxg = zfs_strtonum(za.za_name, NULL);
|
||||
dlce->dlce_mintxg = zfs_strtonum(za->za_name, NULL);
|
||||
|
||||
/*
|
||||
* Prefetch all the bpobj's so that we do that i/o
|
||||
* in parallel. Then open them all in a second pass.
|
||||
*/
|
||||
dlce->dlce_bpobj = za.za_first_integer;
|
||||
dlce->dlce_bpobj = za->za_first_integer;
|
||||
dmu_prefetch_dnode(dl->dl_os, dlce->dlce_bpobj,
|
||||
ZIO_PRIORITY_SYNC_READ);
|
||||
avl_add(&dl->dl_cache, dlce);
|
||||
}
|
||||
VERIFY3U(error, ==, ENOENT);
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
|
||||
for (dsl_deadlist_cache_entry_t *dlce = avl_first(&dl->dl_cache);
|
||||
dlce != NULL; dlce = AVL_NEXT(&dl->dl_cache, dlce)) {
|
||||
|
@ -381,7 +385,7 @@ dsl_deadlist_free(objset_t *os, uint64_t dlobj, dmu_tx_t *tx)
|
|||
{
|
||||
dmu_object_info_t doi;
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za;
|
||||
int error;
|
||||
|
||||
VERIFY0(dmu_object_info(os, dlobj, &doi));
|
||||
|
@ -390,10 +394,11 @@ dsl_deadlist_free(objset_t *os, uint64_t dlobj, dmu_tx_t *tx)
|
|||
return;
|
||||
}
|
||||
|
||||
za = zap_attribute_alloc();
|
||||
for (zap_cursor_init(&zc, os, dlobj);
|
||||
(error = zap_cursor_retrieve(&zc, &za)) == 0;
|
||||
(error = zap_cursor_retrieve(&zc, za)) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
uint64_t obj = za.za_first_integer;
|
||||
uint64_t obj = za->za_first_integer;
|
||||
if (obj == dmu_objset_pool(os)->dp_empty_bpobj)
|
||||
bpobj_decr_empty(os, tx);
|
||||
else
|
||||
|
@ -401,6 +406,7 @@ dsl_deadlist_free(objset_t *os, uint64_t dlobj, dmu_tx_t *tx)
|
|||
}
|
||||
VERIFY3U(error, ==, ENOENT);
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
VERIFY0(dmu_object_free(os, dlobj, tx));
|
||||
}
|
||||
|
||||
|
@ -875,8 +881,8 @@ dsl_deadlist_merge(dsl_deadlist_t *dl, uint64_t obj, dmu_tx_t *tx)
|
|||
return;
|
||||
}
|
||||
|
||||
za = kmem_alloc(sizeof (*za), KM_SLEEP);
|
||||
pza = kmem_alloc(sizeof (*pza), KM_SLEEP);
|
||||
za = zap_attribute_alloc();
|
||||
pza = zap_attribute_alloc();
|
||||
|
||||
mutex_enter(&dl->dl_lock);
|
||||
/*
|
||||
|
@ -913,8 +919,8 @@ dsl_deadlist_merge(dsl_deadlist_t *dl, uint64_t obj, dmu_tx_t *tx)
|
|||
dmu_buf_rele(bonus, FTAG);
|
||||
mutex_exit(&dl->dl_lock);
|
||||
|
||||
kmem_free(za, sizeof (*za));
|
||||
kmem_free(pza, sizeof (*pza));
|
||||
zap_attribute_free(za);
|
||||
zap_attribute_free(pza);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -327,9 +327,9 @@ dsl_deleg_get(const char *ddname, nvlist_t **nvp)
|
|||
mos = dp->dp_meta_objset;
|
||||
|
||||
zc = kmem_alloc(sizeof (zap_cursor_t), KM_SLEEP);
|
||||
za = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
|
||||
za = zap_attribute_alloc();
|
||||
basezc = kmem_alloc(sizeof (zap_cursor_t), KM_SLEEP);
|
||||
baseza = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
|
||||
baseza = zap_attribute_alloc();
|
||||
source = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
|
||||
VERIFY(nvlist_alloc(nvp, NV_UNIQUE_NAME, KM_SLEEP) == 0);
|
||||
|
||||
|
@ -371,9 +371,9 @@ dsl_deleg_get(const char *ddname, nvlist_t **nvp)
|
|||
}
|
||||
|
||||
kmem_free(source, ZFS_MAX_DATASET_NAME_LEN);
|
||||
kmem_free(baseza, sizeof (zap_attribute_t));
|
||||
zap_attribute_free(baseza);
|
||||
kmem_free(basezc, sizeof (zap_cursor_t));
|
||||
kmem_free(za, sizeof (zap_attribute_t));
|
||||
zap_attribute_free(za);
|
||||
kmem_free(zc, sizeof (zap_cursor_t));
|
||||
|
||||
dsl_dir_rele(startdd, FTAG);
|
||||
|
@ -482,7 +482,7 @@ dsl_load_sets(objset_t *mos, uint64_t zapobj,
|
|||
char type, char checkflag, void *valp, avl_tree_t *avl)
|
||||
{
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za;
|
||||
perm_set_t *permnode;
|
||||
avl_index_t idx;
|
||||
uint64_t jumpobj;
|
||||
|
@ -495,11 +495,12 @@ dsl_load_sets(objset_t *mos, uint64_t zapobj,
|
|||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
za = zap_attribute_alloc();
|
||||
for (zap_cursor_init(&zc, mos, jumpobj);
|
||||
zap_cursor_retrieve(&zc, &za) == 0;
|
||||
zap_cursor_retrieve(&zc, za) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
permnode = kmem_alloc(sizeof (perm_set_t), KM_SLEEP);
|
||||
(void) strlcpy(permnode->p_setname, za.za_name,
|
||||
(void) strlcpy(permnode->p_setname, za->za_name,
|
||||
sizeof (permnode->p_setname));
|
||||
permnode->p_matched = B_FALSE;
|
||||
|
||||
|
@ -510,6 +511,7 @@ dsl_load_sets(objset_t *mos, uint64_t zapobj,
|
|||
}
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -683,7 +685,7 @@ copy_create_perms(dsl_dir_t *dd, uint64_t pzapobj,
|
|||
uint64_t jumpobj, pjumpobj;
|
||||
uint64_t zapobj = dsl_dir_phys(dd)->dd_deleg_zapobj;
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za;
|
||||
char whokey[ZFS_MAX_DELEG_NAME];
|
||||
|
||||
zfs_deleg_whokey(whokey,
|
||||
|
@ -706,16 +708,18 @@ copy_create_perms(dsl_dir_t *dd, uint64_t pzapobj,
|
|||
VERIFY(zap_add(mos, zapobj, whokey, 8, 1, &jumpobj, tx) == 0);
|
||||
}
|
||||
|
||||
za = zap_attribute_alloc();
|
||||
for (zap_cursor_init(&zc, mos, pjumpobj);
|
||||
zap_cursor_retrieve(&zc, &za) == 0;
|
||||
zap_cursor_retrieve(&zc, za) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
uint64_t zero = 0;
|
||||
ASSERT(za.za_integer_length == 8 && za.za_num_integers == 1);
|
||||
ASSERT(za->za_integer_length == 8 && za->za_num_integers == 1);
|
||||
|
||||
VERIFY(zap_update(mos, jumpobj, za.za_name,
|
||||
VERIFY(zap_update(mos, jumpobj, za->za_name,
|
||||
8, 1, &zero, tx) == 0);
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -746,19 +750,21 @@ int
|
|||
dsl_deleg_destroy(objset_t *mos, uint64_t zapobj, dmu_tx_t *tx)
|
||||
{
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za;
|
||||
|
||||
if (zapobj == 0)
|
||||
return (0);
|
||||
|
||||
za = zap_attribute_alloc();
|
||||
for (zap_cursor_init(&zc, mos, zapobj);
|
||||
zap_cursor_retrieve(&zc, &za) == 0;
|
||||
zap_cursor_retrieve(&zc, za) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
ASSERT(za.za_integer_length == 8 && za.za_num_integers == 1);
|
||||
VERIFY(0 == zap_destroy(mos, za.za_first_integer, tx));
|
||||
ASSERT(za->za_integer_length == 8 && za->za_num_integers == 1);
|
||||
VERIFY(0 == zap_destroy(mos, za->za_first_integer, tx));
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
VERIFY(0 == zap_destroy(mos, zapobj, tx));
|
||||
zap_attribute_free(za);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
|
@ -216,7 +216,7 @@ dsl_dir_remove_clones_key_impl(dsl_dir_t *dd, uint64_t mintxg, dmu_tx_t *tx,
|
|||
return;
|
||||
|
||||
zap_cursor_t *zc = kmem_alloc(sizeof (zap_cursor_t), KM_SLEEP);
|
||||
zap_attribute_t *za = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
|
||||
zap_attribute_t *za = zap_attribute_alloc();
|
||||
|
||||
for (zap_cursor_init(zc, mos, dsl_dir_phys(dd)->dd_clones);
|
||||
zap_cursor_retrieve(zc, za) == 0;
|
||||
|
@ -242,7 +242,7 @@ dsl_dir_remove_clones_key_impl(dsl_dir_t *dd, uint64_t mintxg, dmu_tx_t *tx,
|
|||
}
|
||||
zap_cursor_fini(zc);
|
||||
|
||||
kmem_free(za, sizeof (zap_attribute_t));
|
||||
zap_attribute_free(za);
|
||||
kmem_free(zc, sizeof (zap_cursor_t));
|
||||
}
|
||||
|
||||
|
|
|
@ -239,7 +239,8 @@ dsl_dir_hold_obj(dsl_pool_t *dp, uint64_t ddobj,
|
|||
err = zap_value_search(dp->dp_meta_objset,
|
||||
dsl_dir_phys(dd->dd_parent)->
|
||||
dd_child_dir_zapobj,
|
||||
ddobj, 0, dd->dd_myname);
|
||||
ddobj, 0, dd->dd_myname,
|
||||
sizeof (dd->dd_myname));
|
||||
}
|
||||
if (err != 0)
|
||||
goto errout;
|
||||
|
@ -586,7 +587,7 @@ dsl_dir_init_fs_ss_count(dsl_dir_t *dd, dmu_tx_t *tx)
|
|||
return;
|
||||
|
||||
zc = kmem_alloc(sizeof (zap_cursor_t), KM_SLEEP);
|
||||
za = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
|
||||
za = zap_attribute_alloc();
|
||||
|
||||
/* Iterate my child dirs */
|
||||
for (zap_cursor_init(zc, os, dsl_dir_phys(dd)->dd_child_dir_zapobj);
|
||||
|
@ -635,7 +636,7 @@ dsl_dir_init_fs_ss_count(dsl_dir_t *dd, dmu_tx_t *tx)
|
|||
dsl_dataset_rele(ds, FTAG);
|
||||
|
||||
kmem_free(zc, sizeof (zap_cursor_t));
|
||||
kmem_free(za, sizeof (zap_attribute_t));
|
||||
zap_attribute_free(za);
|
||||
|
||||
/* we're in a sync task, update counts */
|
||||
dmu_buf_will_dirty(dd->dd_dbuf, tx);
|
||||
|
|
|
@ -1196,7 +1196,7 @@ dsl_pool_unlinked_drain_taskq(dsl_pool_t *dp)
|
|||
void
|
||||
dsl_pool_clean_tmp_userrefs(dsl_pool_t *dp)
|
||||
{
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za;
|
||||
zap_cursor_t zc;
|
||||
objset_t *mos = dp->dp_meta_objset;
|
||||
uint64_t zapobj = dp->dp_tmp_userrefs_obj;
|
||||
|
@ -1208,19 +1208,20 @@ dsl_pool_clean_tmp_userrefs(dsl_pool_t *dp)
|
|||
|
||||
holds = fnvlist_alloc();
|
||||
|
||||
za = zap_attribute_alloc();
|
||||
for (zap_cursor_init(&zc, mos, zapobj);
|
||||
zap_cursor_retrieve(&zc, &za) == 0;
|
||||
zap_cursor_retrieve(&zc, za) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
char *htag;
|
||||
nvlist_t *tags;
|
||||
|
||||
htag = strchr(za.za_name, '-');
|
||||
htag = strchr(za->za_name, '-');
|
||||
*htag = '\0';
|
||||
++htag;
|
||||
if (nvlist_lookup_nvlist(holds, za.za_name, &tags) != 0) {
|
||||
if (nvlist_lookup_nvlist(holds, za->za_name, &tags) != 0) {
|
||||
tags = fnvlist_alloc();
|
||||
fnvlist_add_boolean(tags, htag);
|
||||
fnvlist_add_nvlist(holds, za.za_name, tags);
|
||||
fnvlist_add_nvlist(holds, za->za_name, tags);
|
||||
fnvlist_free(tags);
|
||||
} else {
|
||||
fnvlist_add_boolean(tags, htag);
|
||||
|
@ -1229,6 +1230,7 @@ dsl_pool_clean_tmp_userrefs(dsl_pool_t *dp)
|
|||
dsl_dataset_user_release_tmp(dp, holds);
|
||||
fnvlist_free(holds);
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -662,7 +662,7 @@ dsl_prop_changed_notify(dsl_pool_t *dp, uint64_t ddobj,
|
|||
}
|
||||
mutex_exit(&dd->dd_lock);
|
||||
|
||||
za = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
|
||||
za = zap_attribute_alloc();
|
||||
for (zap_cursor_init(&zc, mos,
|
||||
dsl_dir_phys(dd)->dd_child_dir_zapobj);
|
||||
zap_cursor_retrieve(&zc, za) == 0;
|
||||
|
@ -670,7 +670,7 @@ dsl_prop_changed_notify(dsl_pool_t *dp, uint64_t ddobj,
|
|||
dsl_prop_changed_notify(dp, za->za_first_integer,
|
||||
propname, value, FALSE);
|
||||
}
|
||||
kmem_free(za, sizeof (zap_attribute_t));
|
||||
zap_attribute_free(za);
|
||||
zap_cursor_fini(&zc);
|
||||
dsl_dir_rele(dd, FTAG);
|
||||
}
|
||||
|
@ -1061,11 +1061,11 @@ dsl_prop_get_all_impl(objset_t *mos, uint64_t propobj,
|
|||
const char *setpoint, dsl_prop_getflags_t flags, nvlist_t *nv)
|
||||
{
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za = zap_attribute_alloc();
|
||||
int err = 0;
|
||||
|
||||
for (zap_cursor_init(&zc, mos, propobj);
|
||||
(err = zap_cursor_retrieve(&zc, &za)) == 0;
|
||||
(err = zap_cursor_retrieve(&zc, za)) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
nvlist_t *propval;
|
||||
zfs_prop_t prop;
|
||||
|
@ -1075,7 +1075,7 @@ dsl_prop_get_all_impl(objset_t *mos, uint64_t propobj,
|
|||
const char *propname;
|
||||
const char *source;
|
||||
|
||||
suffix = strchr(za.za_name, '$');
|
||||
suffix = strchr(za->za_name, '$');
|
||||
|
||||
if (suffix == NULL) {
|
||||
/*
|
||||
|
@ -1085,7 +1085,7 @@ dsl_prop_get_all_impl(objset_t *mos, uint64_t propobj,
|
|||
if (flags & DSL_PROP_GET_RECEIVED)
|
||||
continue;
|
||||
|
||||
propname = za.za_name;
|
||||
propname = za->za_name;
|
||||
source = setpoint;
|
||||
|
||||
/* Skip if iuv entries are preset. */
|
||||
|
@ -1102,8 +1102,8 @@ dsl_prop_get_all_impl(objset_t *mos, uint64_t propobj,
|
|||
if (flags & DSL_PROP_GET_LOCAL)
|
||||
continue;
|
||||
|
||||
(void) strlcpy(buf, za.za_name,
|
||||
MIN(sizeof (buf), suffix - za.za_name + 1));
|
||||
(void) strlcpy(buf, za->za_name,
|
||||
MIN(sizeof (buf), suffix - za->za_name + 1));
|
||||
propname = buf;
|
||||
|
||||
if (!(flags & DSL_PROP_GET_RECEIVED)) {
|
||||
|
@ -1128,14 +1128,14 @@ dsl_prop_get_all_impl(objset_t *mos, uint64_t propobj,
|
|||
source = ((flags & DSL_PROP_GET_INHERITING) ?
|
||||
setpoint : ZPROP_SOURCE_VAL_RECVD);
|
||||
} else if (strcmp(suffix, ZPROP_IUV_SUFFIX) == 0) {
|
||||
(void) strlcpy(buf, za.za_name,
|
||||
MIN(sizeof (buf), suffix - za.za_name + 1));
|
||||
(void) strlcpy(buf, za->za_name,
|
||||
MIN(sizeof (buf), suffix - za->za_name + 1));
|
||||
propname = buf;
|
||||
source = setpoint;
|
||||
prop = zfs_name_to_prop(propname);
|
||||
|
||||
if (dsl_prop_known_index(prop,
|
||||
za.za_first_integer) != 1)
|
||||
za->za_first_integer) != 1)
|
||||
continue;
|
||||
} else {
|
||||
/*
|
||||
|
@ -1162,28 +1162,28 @@ dsl_prop_get_all_impl(objset_t *mos, uint64_t propobj,
|
|||
continue;
|
||||
|
||||
VERIFY(nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP) == 0);
|
||||
if (za.za_integer_length == 1) {
|
||||
if (za->za_integer_length == 1) {
|
||||
/*
|
||||
* String property
|
||||
*/
|
||||
char *tmp = kmem_alloc(za.za_num_integers,
|
||||
char *tmp = kmem_alloc(za->za_num_integers,
|
||||
KM_SLEEP);
|
||||
err = zap_lookup(mos, propobj,
|
||||
za.za_name, 1, za.za_num_integers, tmp);
|
||||
za->za_name, 1, za->za_num_integers, tmp);
|
||||
if (err != 0) {
|
||||
kmem_free(tmp, za.za_num_integers);
|
||||
kmem_free(tmp, za->za_num_integers);
|
||||
break;
|
||||
}
|
||||
VERIFY(nvlist_add_string(propval, ZPROP_VALUE,
|
||||
tmp) == 0);
|
||||
kmem_free(tmp, za.za_num_integers);
|
||||
kmem_free(tmp, za->za_num_integers);
|
||||
} else {
|
||||
/*
|
||||
* Integer property
|
||||
*/
|
||||
ASSERT(za.za_integer_length == 8);
|
||||
ASSERT(za->za_integer_length == 8);
|
||||
(void) nvlist_add_uint64(propval, ZPROP_VALUE,
|
||||
za.za_first_integer);
|
||||
za->za_first_integer);
|
||||
}
|
||||
|
||||
VERIFY(nvlist_add_string(propval, ZPROP_SOURCE, source) == 0);
|
||||
|
@ -1191,6 +1191,7 @@ dsl_prop_get_all_impl(objset_t *mos, uint64_t propobj,
|
|||
nvlist_free(propval);
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
if (err == ENOENT)
|
||||
err = 0;
|
||||
return (err);
|
||||
|
|
|
@ -617,17 +617,18 @@ dsl_scan_init(dsl_pool_t *dp, uint64_t txg)
|
|||
/* reload the queue into the in-core state */
|
||||
if (scn->scn_phys.scn_queue_obj != 0) {
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za = zap_attribute_alloc();
|
||||
|
||||
for (zap_cursor_init(&zc, dp->dp_meta_objset,
|
||||
scn->scn_phys.scn_queue_obj);
|
||||
zap_cursor_retrieve(&zc, &za) == 0;
|
||||
zap_cursor_retrieve(&zc, za) == 0;
|
||||
(void) zap_cursor_advance(&zc)) {
|
||||
scan_ds_queue_insert(scn,
|
||||
zfs_strtonum(za.za_name, NULL),
|
||||
za.za_first_integer);
|
||||
zfs_strtonum(za->za_name, NULL),
|
||||
za->za_first_integer);
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
}
|
||||
|
||||
spa_scan_stat_init(spa);
|
||||
|
@ -2865,16 +2866,17 @@ dsl_scan_visitds(dsl_scan_t *scn, uint64_t dsobj, dmu_tx_t *tx)
|
|||
|
||||
if (usenext) {
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za = zap_attribute_alloc();
|
||||
for (zap_cursor_init(&zc, dp->dp_meta_objset,
|
||||
dsl_dataset_phys(ds)->ds_next_clones_obj);
|
||||
zap_cursor_retrieve(&zc, &za) == 0;
|
||||
zap_cursor_retrieve(&zc, za) == 0;
|
||||
(void) zap_cursor_advance(&zc)) {
|
||||
scan_ds_queue_insert(scn,
|
||||
zfs_strtonum(za.za_name, NULL),
|
||||
zfs_strtonum(za->za_name, NULL),
|
||||
dsl_dataset_phys(ds)->ds_creation_txg);
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
} else {
|
||||
VERIFY0(dmu_objset_find_dp(dp, dp->dp_root_dir_obj,
|
||||
enqueue_clones_cb, &ds->ds_object,
|
||||
|
@ -4156,7 +4158,7 @@ dsl_errorscrub_sync(dsl_pool_t *dp, dmu_tx_t *tx)
|
|||
zbookmark_phys_t *zb;
|
||||
boolean_t limit_exceeded = B_FALSE;
|
||||
|
||||
za = kmem_zalloc(sizeof (zap_attribute_t), KM_SLEEP);
|
||||
za = zap_attribute_alloc();
|
||||
zb = kmem_zalloc(sizeof (zbookmark_phys_t), KM_SLEEP);
|
||||
|
||||
if (!spa_feature_is_enabled(spa, SPA_FEATURE_HEAD_ERRLOG)) {
|
||||
|
@ -4187,7 +4189,7 @@ dsl_errorscrub_sync(dsl_pool_t *dp, dmu_tx_t *tx)
|
|||
dsl_errorscrub_done(scn, B_TRUE, tx);
|
||||
|
||||
dsl_errorscrub_sync_state(scn, tx);
|
||||
kmem_free(za, sizeof (*za));
|
||||
zap_attribute_free(za);
|
||||
kmem_free(zb, sizeof (*zb));
|
||||
return;
|
||||
}
|
||||
|
@ -4201,7 +4203,7 @@ dsl_errorscrub_sync(dsl_pool_t *dp, dmu_tx_t *tx)
|
|||
zbookmark_err_phys_t head_ds_block;
|
||||
|
||||
head_ds_cursor = kmem_zalloc(sizeof (zap_cursor_t), KM_SLEEP);
|
||||
head_ds_attr = kmem_zalloc(sizeof (zap_attribute_t), KM_SLEEP);
|
||||
head_ds_attr = zap_attribute_alloc();
|
||||
|
||||
uint64_t head_ds_err_obj = za->za_first_integer;
|
||||
uint64_t head_ds;
|
||||
|
@ -4240,13 +4242,13 @@ dsl_errorscrub_sync(dsl_pool_t *dp, dmu_tx_t *tx)
|
|||
|
||||
zap_cursor_fini(head_ds_cursor);
|
||||
kmem_free(head_ds_cursor, sizeof (*head_ds_cursor));
|
||||
kmem_free(head_ds_attr, sizeof (*head_ds_attr));
|
||||
zap_attribute_free(head_ds_attr);
|
||||
|
||||
if (config_held)
|
||||
dsl_pool_config_exit(dp, FTAG);
|
||||
}
|
||||
|
||||
kmem_free(za, sizeof (*za));
|
||||
zap_attribute_free(za);
|
||||
kmem_free(zb, sizeof (*zb));
|
||||
if (!limit_exceeded)
|
||||
dsl_errorscrub_done(scn, B_TRUE, tx);
|
||||
|
|
|
@ -674,7 +674,7 @@ dsl_dataset_get_holds(const char *dsname, nvlist_t *nvl)
|
|||
zap_attribute_t *za;
|
||||
zap_cursor_t zc;
|
||||
|
||||
za = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
|
||||
za = zap_attribute_alloc();
|
||||
for (zap_cursor_init(&zc, ds->ds_dir->dd_pool->dp_meta_objset,
|
||||
dsl_dataset_phys(ds)->ds_userrefs_obj);
|
||||
zap_cursor_retrieve(&zc, za) == 0;
|
||||
|
@ -683,7 +683,7 @@ dsl_dataset_get_holds(const char *dsname, nvlist_t *nvl)
|
|||
za->za_first_integer);
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
kmem_free(za, sizeof (zap_attribute_t));
|
||||
zap_attribute_free(za);
|
||||
}
|
||||
dsl_dataset_rele(ds, FTAG);
|
||||
dsl_pool_rele(dp, FTAG);
|
||||
|
|
|
@ -840,7 +840,7 @@ sa_attr_table_setup(objset_t *os, const sa_attr_reg_t *reg_attrs, int count)
|
|||
uint64_t attr_value;
|
||||
sa_attr_table_t *tb;
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za;
|
||||
int registered_count = 0;
|
||||
int i;
|
||||
dmu_objset_type_t ostype = dmu_objset_type(os);
|
||||
|
@ -914,11 +914,12 @@ sa_attr_table_setup(objset_t *os, const sa_attr_reg_t *reg_attrs, int count)
|
|||
*/
|
||||
|
||||
if (sa->sa_reg_attr_obj) {
|
||||
za = zap_attribute_alloc();
|
||||
for (zap_cursor_init(&zc, os, sa->sa_reg_attr_obj);
|
||||
(error = zap_cursor_retrieve(&zc, &za)) == 0;
|
||||
(error = zap_cursor_retrieve(&zc, za)) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
uint64_t value;
|
||||
value = za.za_first_integer;
|
||||
value = za->za_first_integer;
|
||||
|
||||
registered_count++;
|
||||
tb[ATTR_NUM(value)].sa_attr = ATTR_NUM(value);
|
||||
|
@ -930,11 +931,12 @@ sa_attr_table_setup(objset_t *os, const sa_attr_reg_t *reg_attrs, int count)
|
|||
continue;
|
||||
}
|
||||
tb[ATTR_NUM(value)].sa_name =
|
||||
kmem_zalloc(strlen(za.za_name) +1, KM_SLEEP);
|
||||
(void) strlcpy(tb[ATTR_NUM(value)].sa_name, za.za_name,
|
||||
strlen(za.za_name) +1);
|
||||
kmem_zalloc(strlen(za->za_name) +1, KM_SLEEP);
|
||||
(void) strlcpy(tb[ATTR_NUM(value)].sa_name, za->za_name,
|
||||
strlen(za->za_name) +1);
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
/*
|
||||
* Make sure we processed the correct number of registered
|
||||
* attributes
|
||||
|
@ -996,7 +998,7 @@ sa_setup(objset_t *os, uint64_t sa_obj, const sa_attr_reg_t *reg_attrs,
|
|||
int count, sa_attr_type_t **user_table)
|
||||
{
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za;
|
||||
sa_os_t *sa;
|
||||
dmu_objset_type_t ostype = dmu_objset_type(os);
|
||||
sa_attr_type_t *tb;
|
||||
|
@ -1053,33 +1055,35 @@ sa_setup(objset_t *os, uint64_t sa_obj, const sa_attr_reg_t *reg_attrs,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
za = zap_attribute_alloc();
|
||||
for (zap_cursor_init(&zc, os, sa->sa_layout_attr_obj);
|
||||
(error = zap_cursor_retrieve(&zc, &za)) == 0;
|
||||
(error = zap_cursor_retrieve(&zc, za)) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
sa_attr_type_t *lot_attrs;
|
||||
uint64_t lot_num;
|
||||
|
||||
lot_attrs = kmem_zalloc(sizeof (sa_attr_type_t) *
|
||||
za.za_num_integers, KM_SLEEP);
|
||||
za->za_num_integers, KM_SLEEP);
|
||||
|
||||
if ((error = (zap_lookup(os, sa->sa_layout_attr_obj,
|
||||
za.za_name, 2, za.za_num_integers,
|
||||
za->za_name, 2, za->za_num_integers,
|
||||
lot_attrs))) != 0) {
|
||||
kmem_free(lot_attrs, sizeof (sa_attr_type_t) *
|
||||
za.za_num_integers);
|
||||
za->za_num_integers);
|
||||
break;
|
||||
}
|
||||
VERIFY0(ddi_strtoull(za.za_name, NULL, 10,
|
||||
VERIFY0(ddi_strtoull(za->za_name, NULL, 10,
|
||||
(unsigned long long *)&lot_num));
|
||||
|
||||
(void) sa_add_layout_entry(os, lot_attrs,
|
||||
za.za_num_integers, lot_num,
|
||||
za->za_num_integers, lot_num,
|
||||
sa_layout_info_hash(lot_attrs,
|
||||
za.za_num_integers), B_FALSE, NULL);
|
||||
za->za_num_integers), B_FALSE, NULL);
|
||||
kmem_free(lot_attrs, sizeof (sa_attr_type_t) *
|
||||
za.za_num_integers);
|
||||
za->za_num_integers);
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
|
||||
/*
|
||||
* Make sure layout count matches number of entries added
|
||||
|
|
|
@ -548,7 +548,7 @@ spa_prop_get(spa_t *spa, nvlist_t **nvp)
|
|||
{
|
||||
objset_t *mos = spa->spa_meta_objset;
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za;
|
||||
dsl_pool_t *dp;
|
||||
int err;
|
||||
|
||||
|
@ -560,6 +560,7 @@ spa_prop_get(spa_t *spa, nvlist_t **nvp)
|
|||
|
||||
dp = spa_get_dsl(spa);
|
||||
dsl_pool_config_enter(dp, FTAG);
|
||||
za = zap_attribute_alloc();
|
||||
mutex_enter(&spa->spa_props_lock);
|
||||
|
||||
/*
|
||||
|
@ -575,21 +576,21 @@ spa_prop_get(spa_t *spa, nvlist_t **nvp)
|
|||
* Get properties from the MOS pool property object.
|
||||
*/
|
||||
for (zap_cursor_init(&zc, mos, spa->spa_pool_props_object);
|
||||
(err = zap_cursor_retrieve(&zc, &za)) == 0;
|
||||
(err = zap_cursor_retrieve(&zc, za)) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
uint64_t intval = 0;
|
||||
char *strval = NULL;
|
||||
zprop_source_t src = ZPROP_SRC_DEFAULT;
|
||||
zpool_prop_t prop;
|
||||
|
||||
if ((prop = zpool_name_to_prop(za.za_name)) ==
|
||||
ZPOOL_PROP_INVAL && !zfs_prop_user(za.za_name))
|
||||
if ((prop = zpool_name_to_prop(za->za_name)) ==
|
||||
ZPOOL_PROP_INVAL && !zfs_prop_user(za->za_name))
|
||||
continue;
|
||||
|
||||
switch (za.za_integer_length) {
|
||||
switch (za->za_integer_length) {
|
||||
case 8:
|
||||
/* integer property */
|
||||
if (za.za_first_integer !=
|
||||
if (za->za_first_integer !=
|
||||
zpool_prop_default_numeric(prop))
|
||||
src = ZPROP_SRC_LOCAL;
|
||||
|
||||
|
@ -597,7 +598,7 @@ spa_prop_get(spa_t *spa, nvlist_t **nvp)
|
|||
dsl_dataset_t *ds = NULL;
|
||||
|
||||
err = dsl_dataset_hold_obj(dp,
|
||||
za.za_first_integer, FTAG, &ds);
|
||||
za->za_first_integer, FTAG, &ds);
|
||||
if (err != 0)
|
||||
break;
|
||||
|
||||
|
@ -607,7 +608,7 @@ spa_prop_get(spa_t *spa, nvlist_t **nvp)
|
|||
dsl_dataset_rele(ds, FTAG);
|
||||
} else {
|
||||
strval = NULL;
|
||||
intval = za.za_first_integer;
|
||||
intval = za->za_first_integer;
|
||||
}
|
||||
|
||||
spa_prop_add_list(*nvp, prop, strval, intval, src);
|
||||
|
@ -619,21 +620,21 @@ spa_prop_get(spa_t *spa, nvlist_t **nvp)
|
|||
|
||||
case 1:
|
||||
/* string property */
|
||||
strval = kmem_alloc(za.za_num_integers, KM_SLEEP);
|
||||
strval = kmem_alloc(za->za_num_integers, KM_SLEEP);
|
||||
err = zap_lookup(mos, spa->spa_pool_props_object,
|
||||
za.za_name, 1, za.za_num_integers, strval);
|
||||
za->za_name, 1, za->za_num_integers, strval);
|
||||
if (err) {
|
||||
kmem_free(strval, za.za_num_integers);
|
||||
kmem_free(strval, za->za_num_integers);
|
||||
break;
|
||||
}
|
||||
if (prop != ZPOOL_PROP_INVAL) {
|
||||
spa_prop_add_list(*nvp, prop, strval, 0, src);
|
||||
} else {
|
||||
src = ZPROP_SRC_LOCAL;
|
||||
spa_prop_add_user(*nvp, za.za_name, strval,
|
||||
spa_prop_add_user(*nvp, za->za_name, strval,
|
||||
src);
|
||||
}
|
||||
kmem_free(strval, za.za_num_integers);
|
||||
kmem_free(strval, za->za_num_integers);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -644,6 +645,7 @@ spa_prop_get(spa_t *spa, nvlist_t **nvp)
|
|||
out:
|
||||
mutex_exit(&spa->spa_props_lock);
|
||||
dsl_pool_config_exit(dp, FTAG);
|
||||
zap_attribute_free(za);
|
||||
if (err && err != ENOENT) {
|
||||
nvlist_free(*nvp);
|
||||
*nvp = NULL;
|
||||
|
@ -2967,12 +2969,13 @@ dsl_get_next_livelist_obj(objset_t *os, uint64_t zap_obj, uint64_t *llp)
|
|||
{
|
||||
int err;
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za = zap_attribute_alloc();
|
||||
zap_cursor_init(&zc, os, zap_obj);
|
||||
err = zap_cursor_retrieve(&zc, &za);
|
||||
err = zap_cursor_retrieve(&zc, za);
|
||||
zap_cursor_fini(&zc);
|
||||
if (err == 0)
|
||||
*llp = za.za_first_integer;
|
||||
*llp = za->za_first_integer;
|
||||
zap_attribute_free(za);
|
||||
return (err);
|
||||
}
|
||||
|
||||
|
@ -6043,17 +6046,17 @@ static void
|
|||
spa_feature_stats_from_disk(spa_t *spa, nvlist_t *features)
|
||||
{
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za = zap_attribute_alloc();
|
||||
|
||||
if (spa->spa_feat_for_read_obj != 0) {
|
||||
for (zap_cursor_init(&zc, spa->spa_meta_objset,
|
||||
spa->spa_feat_for_read_obj);
|
||||
zap_cursor_retrieve(&zc, &za) == 0;
|
||||
zap_cursor_retrieve(&zc, za) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
ASSERT(za.za_integer_length == sizeof (uint64_t) &&
|
||||
za.za_num_integers == 1);
|
||||
VERIFY0(nvlist_add_uint64(features, za.za_name,
|
||||
za.za_first_integer));
|
||||
ASSERT(za->za_integer_length == sizeof (uint64_t) &&
|
||||
za->za_num_integers == 1);
|
||||
VERIFY0(nvlist_add_uint64(features, za->za_name,
|
||||
za->za_first_integer));
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
}
|
||||
|
@ -6061,15 +6064,16 @@ spa_feature_stats_from_disk(spa_t *spa, nvlist_t *features)
|
|||
if (spa->spa_feat_for_write_obj != 0) {
|
||||
for (zap_cursor_init(&zc, spa->spa_meta_objset,
|
||||
spa->spa_feat_for_write_obj);
|
||||
zap_cursor_retrieve(&zc, &za) == 0;
|
||||
zap_cursor_retrieve(&zc, za) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
ASSERT(za.za_integer_length == sizeof (uint64_t) &&
|
||||
za.za_num_integers == 1);
|
||||
VERIFY0(nvlist_add_uint64(features, za.za_name,
|
||||
za.za_first_integer));
|
||||
ASSERT(za->za_integer_length == sizeof (uint64_t) &&
|
||||
za->za_num_integers == 1);
|
||||
VERIFY0(nvlist_add_uint64(features, za->za_name,
|
||||
za->za_first_integer));
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
}
|
||||
zap_attribute_free(za);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -9429,13 +9433,13 @@ spa_sync_config_object(spa_t *spa, dmu_tx_t *tx)
|
|||
|
||||
/* Diff old AVZ with new one */
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za = zap_attribute_alloc();
|
||||
|
||||
for (zap_cursor_init(&zc, spa->spa_meta_objset,
|
||||
spa->spa_all_vdev_zaps);
|
||||
zap_cursor_retrieve(&zc, &za) == 0;
|
||||
zap_cursor_retrieve(&zc, za) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
uint64_t vdzap = za.za_first_integer;
|
||||
uint64_t vdzap = za->za_first_integer;
|
||||
if (zap_lookup_int(spa->spa_meta_objset, new_avz,
|
||||
vdzap) == ENOENT) {
|
||||
/*
|
||||
|
@ -9448,6 +9452,7 @@ spa_sync_config_object(spa_t *spa, dmu_tx_t *tx)
|
|||
}
|
||||
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
|
||||
/* Destroy the old AVZ */
|
||||
VERIFY0(zap_destroy(spa->spa_meta_objset,
|
||||
|
@ -9461,18 +9466,19 @@ spa_sync_config_object(spa_t *spa, dmu_tx_t *tx)
|
|||
spa->spa_all_vdev_zaps = new_avz;
|
||||
} else if (spa->spa_avz_action == AVZ_ACTION_DESTROY) {
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za = zap_attribute_alloc();
|
||||
|
||||
/* Walk through the AVZ and destroy all listed ZAPs */
|
||||
for (zap_cursor_init(&zc, spa->spa_meta_objset,
|
||||
spa->spa_all_vdev_zaps);
|
||||
zap_cursor_retrieve(&zc, &za) == 0;
|
||||
zap_cursor_retrieve(&zc, za) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
uint64_t zap = za.za_first_integer;
|
||||
uint64_t zap = za->za_first_integer;
|
||||
VERIFY0(zap_destroy(spa->spa_meta_objset, zap, tx));
|
||||
}
|
||||
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
|
||||
/* Destroy and unlink the AVZ itself */
|
||||
VERIFY0(zap_destroy(spa->spa_meta_objset,
|
||||
|
|
|
@ -429,7 +429,7 @@ check_filesystem(spa_t *spa, uint64_t head_ds, zbookmark_err_phys_t *zep,
|
|||
zap_attribute_t *za;
|
||||
|
||||
zc = kmem_zalloc(sizeof (zap_cursor_t), KM_SLEEP);
|
||||
za = kmem_zalloc(sizeof (zap_attribute_t), KM_SLEEP);
|
||||
za = zap_attribute_alloc();
|
||||
|
||||
for (zap_cursor_init(zc, spa->spa_meta_objset, zap_clone);
|
||||
zap_cursor_retrieve(zc, za) == 0;
|
||||
|
@ -463,7 +463,7 @@ check_filesystem(spa_t *spa, uint64_t head_ds, zbookmark_err_phys_t *zep,
|
|||
}
|
||||
|
||||
zap_cursor_fini(zc);
|
||||
kmem_free(za, sizeof (*za));
|
||||
zap_attribute_free(za);
|
||||
kmem_free(zc, sizeof (*zc));
|
||||
|
||||
out:
|
||||
|
@ -617,10 +617,10 @@ spa_add_healed_error(spa_t *spa, uint64_t obj, zbookmark_phys_t *healed_zb,
|
|||
errphys_to_name(&healed_zep, name, sizeof (name));
|
||||
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za = zap_attribute_alloc();
|
||||
for (zap_cursor_init(&zc, spa->spa_meta_objset, spa->spa_errlog_last);
|
||||
zap_cursor_retrieve(&zc, &za) == 0; zap_cursor_advance(&zc)) {
|
||||
if (zap_contains(spa->spa_meta_objset, za.za_first_integer,
|
||||
zap_cursor_retrieve(&zc, za) == 0; zap_cursor_advance(&zc)) {
|
||||
if (zap_contains(spa->spa_meta_objset, za->za_first_integer,
|
||||
name) == 0) {
|
||||
if (!MUTEX_HELD(&spa->spa_errlog_lock)) {
|
||||
mutex_enter(&spa->spa_errlog_lock);
|
||||
|
@ -657,6 +657,7 @@ spa_add_healed_error(spa_t *spa, uint64_t obj, zbookmark_phys_t *healed_zb,
|
|||
}
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -704,24 +705,25 @@ spa_remove_healed_errors(spa_t *spa, avl_tree_t *s, avl_tree_t *l, dmu_tx_t *tx)
|
|||
} else {
|
||||
errphys_to_name(&se->se_zep, name, sizeof (name));
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za = zap_attribute_alloc();
|
||||
for (zap_cursor_init(&zc, spa->spa_meta_objset,
|
||||
spa->spa_errlog_last);
|
||||
zap_cursor_retrieve(&zc, &za) == 0;
|
||||
zap_cursor_retrieve(&zc, za) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
zap_remove(spa->spa_meta_objset,
|
||||
za.za_first_integer, name, tx);
|
||||
za->za_first_integer, name, tx);
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
|
||||
for (zap_cursor_init(&zc, spa->spa_meta_objset,
|
||||
spa->spa_errlog_scrub);
|
||||
zap_cursor_retrieve(&zc, &za) == 0;
|
||||
zap_cursor_retrieve(&zc, za) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
zap_remove(spa->spa_meta_objset,
|
||||
za.za_first_integer, name, tx);
|
||||
za->za_first_integer, name, tx);
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
}
|
||||
kmem_free(se, sizeof (spa_error_entry_t));
|
||||
}
|
||||
|
@ -746,15 +748,16 @@ approx_errlog_size_impl(spa_t *spa, uint64_t spa_err_obj)
|
|||
uint64_t total = 0;
|
||||
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za = zap_attribute_alloc();
|
||||
for (zap_cursor_init(&zc, spa->spa_meta_objset, spa_err_obj);
|
||||
zap_cursor_retrieve(&zc, &za) == 0; zap_cursor_advance(&zc)) {
|
||||
zap_cursor_retrieve(&zc, za) == 0; zap_cursor_advance(&zc)) {
|
||||
uint64_t count;
|
||||
if (zap_count(spa->spa_meta_objset, za.za_first_integer,
|
||||
if (zap_count(spa->spa_meta_objset, za->za_first_integer,
|
||||
&count) == 0)
|
||||
total += count;
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
return (total);
|
||||
}
|
||||
|
||||
|
@ -806,7 +809,7 @@ sync_upgrade_errlog(spa_t *spa, uint64_t spa_err_obj, uint64_t *newobj,
|
|||
dmu_tx_t *tx)
|
||||
{
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za;
|
||||
zbookmark_phys_t zb;
|
||||
uint64_t count;
|
||||
|
||||
|
@ -822,14 +825,15 @@ sync_upgrade_errlog(spa_t *spa, uint64_t spa_err_obj, uint64_t *newobj,
|
|||
return;
|
||||
}
|
||||
|
||||
za = zap_attribute_alloc();
|
||||
for (zap_cursor_init(&zc, spa->spa_meta_objset, spa_err_obj);
|
||||
zap_cursor_retrieve(&zc, &za) == 0;
|
||||
zap_cursor_retrieve(&zc, za) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
if (spa_upgrade_errlog_limit != 0 &&
|
||||
zc.zc_cd == spa_upgrade_errlog_limit)
|
||||
break;
|
||||
|
||||
name_to_bookmark(za.za_name, &zb);
|
||||
name_to_bookmark(za->za_name, &zb);
|
||||
|
||||
zbookmark_err_phys_t zep;
|
||||
zep.zb_object = zb.zb_object;
|
||||
|
@ -909,6 +913,7 @@ sync_upgrade_errlog(spa_t *spa, uint64_t spa_err_obj, uint64_t *newobj,
|
|||
buf, 1, strlen(name) + 1, name, tx);
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
|
||||
VERIFY0(dmu_object_free(spa->spa_meta_objset, spa_err_obj, tx));
|
||||
}
|
||||
|
@ -954,7 +959,7 @@ process_error_log(spa_t *spa, uint64_t obj, void *uaddr, uint64_t *count)
|
|||
zap_attribute_t *za;
|
||||
|
||||
zc = kmem_zalloc(sizeof (zap_cursor_t), KM_SLEEP);
|
||||
za = kmem_zalloc(sizeof (zap_attribute_t), KM_SLEEP);
|
||||
za = zap_attribute_alloc();
|
||||
|
||||
if (!spa_feature_is_enabled(spa, SPA_FEATURE_HEAD_ERRLOG)) {
|
||||
for (zap_cursor_init(zc, spa->spa_meta_objset, obj);
|
||||
|
@ -963,7 +968,7 @@ process_error_log(spa_t *spa, uint64_t obj, void *uaddr, uint64_t *count)
|
|||
if (*count == 0) {
|
||||
zap_cursor_fini(zc);
|
||||
kmem_free(zc, sizeof (*zc));
|
||||
kmem_free(za, sizeof (*za));
|
||||
zap_attribute_free(za);
|
||||
return (SET_ERROR(ENOMEM));
|
||||
}
|
||||
|
||||
|
@ -974,13 +979,13 @@ process_error_log(spa_t *spa, uint64_t obj, void *uaddr, uint64_t *count)
|
|||
if (error != 0) {
|
||||
zap_cursor_fini(zc);
|
||||
kmem_free(zc, sizeof (*zc));
|
||||
kmem_free(za, sizeof (*za));
|
||||
zap_attribute_free(za);
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
zap_cursor_fini(zc);
|
||||
kmem_free(zc, sizeof (*zc));
|
||||
kmem_free(za, sizeof (*za));
|
||||
zap_attribute_free(za);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -992,7 +997,7 @@ process_error_log(spa_t *spa, uint64_t obj, void *uaddr, uint64_t *count)
|
|||
zap_attribute_t *head_ds_attr;
|
||||
|
||||
head_ds_cursor = kmem_zalloc(sizeof (zap_cursor_t), KM_SLEEP);
|
||||
head_ds_attr = kmem_zalloc(sizeof (zap_attribute_t), KM_SLEEP);
|
||||
head_ds_attr = zap_attribute_alloc();
|
||||
|
||||
uint64_t head_ds_err_obj = za->za_first_integer;
|
||||
uint64_t head_ds;
|
||||
|
@ -1010,20 +1015,20 @@ process_error_log(spa_t *spa, uint64_t obj, void *uaddr, uint64_t *count)
|
|||
zap_cursor_fini(head_ds_cursor);
|
||||
kmem_free(head_ds_cursor,
|
||||
sizeof (*head_ds_cursor));
|
||||
kmem_free(head_ds_attr, sizeof (*head_ds_attr));
|
||||
zap_attribute_free(head_ds_attr);
|
||||
|
||||
zap_cursor_fini(zc);
|
||||
kmem_free(za, sizeof (*za));
|
||||
zap_attribute_free(za);
|
||||
kmem_free(zc, sizeof (*zc));
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
zap_cursor_fini(head_ds_cursor);
|
||||
kmem_free(head_ds_cursor, sizeof (*head_ds_cursor));
|
||||
kmem_free(head_ds_attr, sizeof (*head_ds_attr));
|
||||
zap_attribute_free(head_ds_attr);
|
||||
}
|
||||
zap_cursor_fini(zc);
|
||||
kmem_free(za, sizeof (*za));
|
||||
zap_attribute_free(za);
|
||||
kmem_free(zc, sizeof (*zc));
|
||||
return (0);
|
||||
}
|
||||
|
@ -1230,14 +1235,15 @@ delete_errlog(spa_t *spa, uint64_t spa_err_obj, dmu_tx_t *tx)
|
|||
{
|
||||
if (spa_feature_is_enabled(spa, SPA_FEATURE_HEAD_ERRLOG)) {
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za = zap_attribute_alloc();
|
||||
for (zap_cursor_init(&zc, spa->spa_meta_objset, spa_err_obj);
|
||||
zap_cursor_retrieve(&zc, &za) == 0;
|
||||
zap_cursor_retrieve(&zc, za) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
VERIFY0(dmu_object_free(spa->spa_meta_objset,
|
||||
za.za_first_integer, tx));
|
||||
za->za_first_integer, tx));
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
}
|
||||
VERIFY0(dmu_object_free(spa->spa_meta_objset, spa_err_obj, tx));
|
||||
}
|
||||
|
@ -1339,20 +1345,21 @@ delete_dataset_errlog(spa_t *spa, uint64_t spa_err_obj, uint64_t ds,
|
|||
return;
|
||||
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za = zap_attribute_alloc();
|
||||
for (zap_cursor_init(&zc, spa->spa_meta_objset, spa_err_obj);
|
||||
zap_cursor_retrieve(&zc, &za) == 0; zap_cursor_advance(&zc)) {
|
||||
zap_cursor_retrieve(&zc, za) == 0; zap_cursor_advance(&zc)) {
|
||||
uint64_t head_ds;
|
||||
name_to_object(za.za_name, &head_ds);
|
||||
name_to_object(za->za_name, &head_ds);
|
||||
if (head_ds == ds) {
|
||||
(void) zap_remove(spa->spa_meta_objset, spa_err_obj,
|
||||
za.za_name, tx);
|
||||
za->za_name, tx);
|
||||
VERIFY0(dmu_object_free(spa->spa_meta_objset,
|
||||
za.za_first_integer, tx));
|
||||
za->za_first_integer, tx));
|
||||
break;
|
||||
}
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1435,22 +1442,23 @@ swap_errlog(spa_t *spa, uint64_t spa_err_obj, uint64_t new_head, uint64_t
|
|||
}
|
||||
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za = zap_attribute_alloc();
|
||||
zbookmark_err_phys_t err_block;
|
||||
for (zap_cursor_init(&zc, spa->spa_meta_objset, old_head_errlog);
|
||||
zap_cursor_retrieve(&zc, &za) == 0; zap_cursor_advance(&zc)) {
|
||||
zap_cursor_retrieve(&zc, za) == 0; zap_cursor_advance(&zc)) {
|
||||
|
||||
const char *name = "";
|
||||
name_to_errphys(za.za_name, &err_block);
|
||||
name_to_errphys(za->za_name, &err_block);
|
||||
if (err_block.zb_birth < txg) {
|
||||
(void) zap_update(spa->spa_meta_objset, new_head_errlog,
|
||||
za.za_name, 1, strlen(name) + 1, name, tx);
|
||||
za->za_name, 1, strlen(name) + 1, name, tx);
|
||||
|
||||
(void) zap_remove(spa->spa_meta_objset, old_head_errlog,
|
||||
za.za_name, tx);
|
||||
za->za_name, tx);
|
||||
}
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1020,16 +1020,17 @@ spa_ld_log_sm_metadata(spa_t *spa)
|
|||
}
|
||||
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za = zap_attribute_alloc();
|
||||
for (zap_cursor_init(&zc, spa_meta_objset(spa), spacemap_zap);
|
||||
(error = zap_cursor_retrieve(&zc, &za)) == 0;
|
||||
(error = zap_cursor_retrieve(&zc, za)) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
uint64_t log_txg = zfs_strtonum(za.za_name, NULL);
|
||||
uint64_t log_txg = zfs_strtonum(za->za_name, NULL);
|
||||
spa_log_sm_t *sls =
|
||||
spa_log_sm_alloc(za.za_first_integer, log_txg);
|
||||
spa_log_sm_alloc(za->za_first_integer, log_txg);
|
||||
avl_add(&spa->spa_sm_logs_by_txg, sls);
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
if (error != ENOENT) {
|
||||
spa_load_failed(spa, "spa_ld_log_sm_metadata(): failed at "
|
||||
"zap_cursor_retrieve(spacemap_zap) [error %d]",
|
||||
|
|
|
@ -2590,6 +2590,7 @@ spa_init(spa_mode_t mode)
|
|||
scan_init();
|
||||
qat_init();
|
||||
spa_import_progress_init();
|
||||
zap_init();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2616,6 +2617,7 @@ spa_fini(void)
|
|||
scan_fini();
|
||||
qat_fini();
|
||||
spa_import_progress_destroy();
|
||||
zap_fini();
|
||||
|
||||
avl_destroy(&spa_namespace_avl);
|
||||
avl_destroy(&spa_spare_avl);
|
||||
|
|
|
@ -6432,33 +6432,33 @@ vdev_prop_get(vdev_t *vd, nvlist_t *innvl, nvlist_t *outnvl)
|
|||
* Get all properties from the MOS vdev property object.
|
||||
*/
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za = zap_attribute_alloc();
|
||||
for (zap_cursor_init(&zc, mos, objid);
|
||||
(err = zap_cursor_retrieve(&zc, &za)) == 0;
|
||||
(err = zap_cursor_retrieve(&zc, za)) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
intval = 0;
|
||||
strval = NULL;
|
||||
zprop_source_t src = ZPROP_SRC_DEFAULT;
|
||||
propname = za.za_name;
|
||||
propname = za->za_name;
|
||||
|
||||
switch (za.za_integer_length) {
|
||||
switch (za->za_integer_length) {
|
||||
case 8:
|
||||
/* We do not allow integer user properties */
|
||||
/* This is likely an internal value */
|
||||
break;
|
||||
case 1:
|
||||
/* string property */
|
||||
strval = kmem_alloc(za.za_num_integers,
|
||||
strval = kmem_alloc(za->za_num_integers,
|
||||
KM_SLEEP);
|
||||
err = zap_lookup(mos, objid, za.za_name, 1,
|
||||
za.za_num_integers, strval);
|
||||
err = zap_lookup(mos, objid, za->za_name, 1,
|
||||
za->za_num_integers, strval);
|
||||
if (err) {
|
||||
kmem_free(strval, za.za_num_integers);
|
||||
kmem_free(strval, za->za_num_integers);
|
||||
break;
|
||||
}
|
||||
vdev_prop_add_list(outnvl, propname, strval, 0,
|
||||
src);
|
||||
kmem_free(strval, za.za_num_integers);
|
||||
kmem_free(strval, za->za_num_integers);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -6466,6 +6466,7 @@ vdev_prop_get(vdev_t *vd, nvlist_t *innvl, nvlist_t *outnvl)
|
|||
}
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
}
|
||||
|
||||
mutex_exit(&spa->spa_props_lock);
|
||||
|
|
|
@ -832,7 +832,8 @@ zap_put_leaf_maybe_grow_ptrtbl(zap_name_t *zn, zap_leaf_t *l,
|
|||
static int
|
||||
fzap_checkname(zap_name_t *zn)
|
||||
{
|
||||
if (zn->zn_key_orig_numints * zn->zn_key_intlen > ZAP_MAXNAMELEN)
|
||||
uint32_t maxnamelen = zn->zn_normbuf_len;
|
||||
if (zn->zn_key_orig_numints * zn->zn_key_intlen > maxnamelen)
|
||||
return (SET_ERROR(ENAMETOOLONG));
|
||||
return (0);
|
||||
}
|
||||
|
@ -1102,7 +1103,7 @@ zap_create_link_dnsize(objset_t *os, dmu_object_type_t ot, uint64_t parent_obj,
|
|||
|
||||
int
|
||||
zap_value_search(objset_t *os, uint64_t zapobj, uint64_t value, uint64_t mask,
|
||||
char *name)
|
||||
char *name, uint64_t namelen)
|
||||
{
|
||||
zap_cursor_t zc;
|
||||
int err;
|
||||
|
@ -1110,17 +1111,18 @@ zap_value_search(objset_t *os, uint64_t zapobj, uint64_t value, uint64_t mask,
|
|||
if (mask == 0)
|
||||
mask = -1ULL;
|
||||
|
||||
zap_attribute_t *za = kmem_alloc(sizeof (*za), KM_SLEEP);
|
||||
zap_attribute_t *za = zap_attribute_long_alloc();
|
||||
for (zap_cursor_init(&zc, os, zapobj);
|
||||
(err = zap_cursor_retrieve(&zc, za)) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
if ((za->za_first_integer & mask) == (value & mask)) {
|
||||
(void) strlcpy(name, za->za_name, MAXNAMELEN);
|
||||
if (strlcpy(name, za->za_name, namelen) >= namelen)
|
||||
err = SET_ERROR(ENAMETOOLONG);
|
||||
break;
|
||||
}
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
kmem_free(za, sizeof (*za));
|
||||
zap_attribute_free(za);
|
||||
return (err);
|
||||
}
|
||||
|
||||
|
@ -1130,7 +1132,7 @@ zap_join(objset_t *os, uint64_t fromobj, uint64_t intoobj, dmu_tx_t *tx)
|
|||
zap_cursor_t zc;
|
||||
int err = 0;
|
||||
|
||||
zap_attribute_t *za = kmem_alloc(sizeof (*za), KM_SLEEP);
|
||||
zap_attribute_t *za = zap_attribute_long_alloc();
|
||||
for (zap_cursor_init(&zc, os, fromobj);
|
||||
zap_cursor_retrieve(&zc, za) == 0;
|
||||
(void) zap_cursor_advance(&zc)) {
|
||||
|
@ -1144,7 +1146,7 @@ zap_join(objset_t *os, uint64_t fromobj, uint64_t intoobj, dmu_tx_t *tx)
|
|||
break;
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
kmem_free(za, sizeof (*za));
|
||||
zap_attribute_free(za);
|
||||
return (err);
|
||||
}
|
||||
|
||||
|
@ -1155,7 +1157,7 @@ zap_join_key(objset_t *os, uint64_t fromobj, uint64_t intoobj,
|
|||
zap_cursor_t zc;
|
||||
int err = 0;
|
||||
|
||||
zap_attribute_t *za = kmem_alloc(sizeof (*za), KM_SLEEP);
|
||||
zap_attribute_t *za = zap_attribute_long_alloc();
|
||||
for (zap_cursor_init(&zc, os, fromobj);
|
||||
zap_cursor_retrieve(&zc, za) == 0;
|
||||
(void) zap_cursor_advance(&zc)) {
|
||||
|
@ -1169,7 +1171,7 @@ zap_join_key(objset_t *os, uint64_t fromobj, uint64_t intoobj,
|
|||
break;
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
kmem_free(za, sizeof (*za));
|
||||
zap_attribute_free(za);
|
||||
return (err);
|
||||
}
|
||||
|
||||
|
@ -1180,7 +1182,7 @@ zap_join_increment(objset_t *os, uint64_t fromobj, uint64_t intoobj,
|
|||
zap_cursor_t zc;
|
||||
int err = 0;
|
||||
|
||||
zap_attribute_t *za = kmem_alloc(sizeof (*za), KM_SLEEP);
|
||||
zap_attribute_t *za = zap_attribute_long_alloc();
|
||||
for (zap_cursor_init(&zc, os, fromobj);
|
||||
zap_cursor_retrieve(&zc, za) == 0;
|
||||
(void) zap_cursor_advance(&zc)) {
|
||||
|
@ -1200,7 +1202,7 @@ zap_join_increment(objset_t *os, uint64_t fromobj, uint64_t intoobj,
|
|||
break;
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
kmem_free(za, sizeof (*za));
|
||||
zap_attribute_free(za);
|
||||
return (err);
|
||||
}
|
||||
|
||||
|
@ -1378,7 +1380,7 @@ again:
|
|||
ASSERT(err == 0 || err == EOVERFLOW);
|
||||
}
|
||||
err = zap_entry_read_name(zap, &zeh,
|
||||
sizeof (za->za_name), za->za_name);
|
||||
za->za_name_len, za->za_name);
|
||||
ASSERT(err == 0);
|
||||
|
||||
za->za_normalization_conflict =
|
||||
|
|
|
@ -131,12 +131,12 @@ zap_hash(zap_name_t *zn)
|
|||
}
|
||||
|
||||
static int
|
||||
zap_normalize(zap_t *zap, const char *name, char *namenorm, int normflags)
|
||||
zap_normalize(zap_t *zap, const char *name, char *namenorm, int normflags,
|
||||
size_t outlen)
|
||||
{
|
||||
ASSERT(!(zap_getflags(zap) & ZAP_FLAG_UINT64_KEY));
|
||||
|
||||
size_t inlen = strlen(name) + 1;
|
||||
size_t outlen = ZAP_MAXNAMELEN;
|
||||
|
||||
int err = 0;
|
||||
(void) u8_textprep_str((char *)name, &inlen, namenorm, &outlen,
|
||||
|
@ -149,43 +149,104 @@ zap_normalize(zap_t *zap, const char *name, char *namenorm, int normflags)
|
|||
boolean_t
|
||||
zap_match(zap_name_t *zn, const char *matchname)
|
||||
{
|
||||
boolean_t res = B_FALSE;
|
||||
ASSERT(!(zap_getflags(zn->zn_zap) & ZAP_FLAG_UINT64_KEY));
|
||||
|
||||
if (zn->zn_matchtype & MT_NORMALIZE) {
|
||||
char norm[ZAP_MAXNAMELEN];
|
||||
size_t namelen = zn->zn_normbuf_len;
|
||||
char normbuf[ZAP_MAXNAMELEN];
|
||||
char *norm = normbuf;
|
||||
|
||||
/*
|
||||
* Cannot allocate this on-stack as it exceed the stack-limit of
|
||||
* 1024.
|
||||
*/
|
||||
if (namelen > ZAP_MAXNAMELEN)
|
||||
norm = kmem_alloc(namelen, KM_SLEEP);
|
||||
|
||||
if (zap_normalize(zn->zn_zap, matchname, norm,
|
||||
zn->zn_normflags) != 0)
|
||||
return (B_FALSE);
|
||||
|
||||
return (strcmp(zn->zn_key_norm, norm) == 0);
|
||||
zn->zn_normflags, namelen) != 0) {
|
||||
res = B_FALSE;
|
||||
} else {
|
||||
res = (strcmp(zn->zn_key_norm, norm) == 0);
|
||||
}
|
||||
if (norm != normbuf)
|
||||
kmem_free(norm, namelen);
|
||||
} else {
|
||||
return (strcmp(zn->zn_key_orig, matchname) == 0);
|
||||
res = (strcmp(zn->zn_key_orig, matchname) == 0);
|
||||
}
|
||||
return (res);
|
||||
}
|
||||
|
||||
static kmem_cache_t *zap_name_cache;
|
||||
static kmem_cache_t *zap_attr_cache;
|
||||
static kmem_cache_t *zap_name_long_cache;
|
||||
static kmem_cache_t *zap_attr_long_cache;
|
||||
|
||||
void
|
||||
zap_init(void)
|
||||
{
|
||||
zap_name_cache = kmem_cache_create("zap_name",
|
||||
sizeof (zap_name_t) + ZAP_MAXNAMELEN, 0, NULL, NULL,
|
||||
NULL, NULL, NULL, 0);
|
||||
|
||||
zap_attr_cache = kmem_cache_create("zap_attr_cache",
|
||||
sizeof (zap_attribute_t) + ZAP_MAXNAMELEN, 0, NULL,
|
||||
NULL, NULL, NULL, NULL, 0);
|
||||
|
||||
zap_name_long_cache = kmem_cache_create("zap_name_long",
|
||||
sizeof (zap_name_t) + ZAP_MAXNAMELEN_NEW, 0, NULL, NULL,
|
||||
NULL, NULL, NULL, 0);
|
||||
|
||||
zap_attr_long_cache = kmem_cache_create("zap_attr_long_cache",
|
||||
sizeof (zap_attribute_t) + ZAP_MAXNAMELEN_NEW, 0, NULL,
|
||||
NULL, NULL, NULL, NULL, 0);
|
||||
}
|
||||
|
||||
void
|
||||
zap_fini(void)
|
||||
{
|
||||
kmem_cache_destroy(zap_name_cache);
|
||||
kmem_cache_destroy(zap_attr_cache);
|
||||
kmem_cache_destroy(zap_name_long_cache);
|
||||
kmem_cache_destroy(zap_attr_long_cache);
|
||||
}
|
||||
|
||||
static zap_name_t *
|
||||
zap_name_alloc(zap_t *zap)
|
||||
zap_name_alloc(zap_t *zap, boolean_t longname)
|
||||
{
|
||||
zap_name_t *zn = kmem_alloc(sizeof (zap_name_t), KM_SLEEP);
|
||||
kmem_cache_t *cache = longname ? zap_name_long_cache : zap_name_cache;
|
||||
zap_name_t *zn = kmem_cache_alloc(cache, KM_SLEEP);
|
||||
|
||||
zn->zn_zap = zap;
|
||||
zn->zn_normbuf_len = longname ? ZAP_MAXNAMELEN_NEW : ZAP_MAXNAMELEN;
|
||||
return (zn);
|
||||
}
|
||||
|
||||
void
|
||||
zap_name_free(zap_name_t *zn)
|
||||
{
|
||||
kmem_free(zn, sizeof (zap_name_t));
|
||||
if (zn->zn_normbuf_len == ZAP_MAXNAMELEN) {
|
||||
kmem_cache_free(zap_name_cache, zn);
|
||||
} else {
|
||||
ASSERT3U(zn->zn_normbuf_len, ==, ZAP_MAXNAMELEN_NEW);
|
||||
kmem_cache_free(zap_name_long_cache, zn);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
zap_name_init_str(zap_name_t *zn, const char *key, matchtype_t mt)
|
||||
{
|
||||
zap_t *zap = zn->zn_zap;
|
||||
size_t key_len = strlen(key) + 1;
|
||||
|
||||
/* Make sure zn is allocated for longname if key is long */
|
||||
IMPLY(key_len > ZAP_MAXNAMELEN,
|
||||
zn->zn_normbuf_len == ZAP_MAXNAMELEN_NEW);
|
||||
|
||||
zn->zn_key_intlen = sizeof (*key);
|
||||
zn->zn_key_orig = key;
|
||||
zn->zn_key_orig_numints = strlen(zn->zn_key_orig) + 1;
|
||||
zn->zn_key_orig_numints = key_len;
|
||||
zn->zn_matchtype = mt;
|
||||
zn->zn_normflags = zap->zap_normflags;
|
||||
|
||||
|
@ -203,7 +264,7 @@ zap_name_init_str(zap_name_t *zn, const char *key, matchtype_t mt)
|
|||
* what the hash is computed from.
|
||||
*/
|
||||
if (zap_normalize(zap, key, zn->zn_normbuf,
|
||||
zap->zap_normflags) != 0)
|
||||
zap->zap_normflags, zn->zn_normbuf_len) != 0)
|
||||
return (SET_ERROR(ENOTSUP));
|
||||
zn->zn_key_norm = zn->zn_normbuf;
|
||||
zn->zn_key_norm_numints = strlen(zn->zn_key_norm) + 1;
|
||||
|
@ -222,7 +283,7 @@ zap_name_init_str(zap_name_t *zn, const char *key, matchtype_t mt)
|
|||
* what the matching is based on. (Not the hash!)
|
||||
*/
|
||||
if (zap_normalize(zap, key, zn->zn_normbuf,
|
||||
zn->zn_normflags) != 0)
|
||||
zn->zn_normflags, zn->zn_normbuf_len) != 0)
|
||||
return (SET_ERROR(ENOTSUP));
|
||||
zn->zn_key_norm_numints = strlen(zn->zn_key_norm) + 1;
|
||||
}
|
||||
|
@ -233,7 +294,8 @@ zap_name_init_str(zap_name_t *zn, const char *key, matchtype_t mt)
|
|||
zap_name_t *
|
||||
zap_name_alloc_str(zap_t *zap, const char *key, matchtype_t mt)
|
||||
{
|
||||
zap_name_t *zn = zap_name_alloc(zap);
|
||||
size_t key_len = strlen(key) + 1;
|
||||
zap_name_t *zn = zap_name_alloc(zap, (key_len > ZAP_MAXNAMELEN));
|
||||
if (zap_name_init_str(zn, key, mt) != 0) {
|
||||
zap_name_free(zn);
|
||||
return (NULL);
|
||||
|
@ -244,7 +306,7 @@ zap_name_alloc_str(zap_t *zap, const char *key, matchtype_t mt)
|
|||
static zap_name_t *
|
||||
zap_name_alloc_uint64(zap_t *zap, const uint64_t *key, int numints)
|
||||
{
|
||||
zap_name_t *zn = kmem_alloc(sizeof (zap_name_t), KM_SLEEP);
|
||||
zap_name_t *zn = kmem_cache_alloc(zap_name_cache, KM_SLEEP);
|
||||
|
||||
ASSERT(zap->zap_normflags == 0);
|
||||
zn->zn_zap = zap;
|
||||
|
@ -252,6 +314,7 @@ zap_name_alloc_uint64(zap_t *zap, const uint64_t *key, int numints)
|
|||
zn->zn_key_orig = zn->zn_key_norm = key;
|
||||
zn->zn_key_orig_numints = zn->zn_key_norm_numints = numints;
|
||||
zn->zn_matchtype = 0;
|
||||
zn->zn_normbuf_len = ZAP_MAXNAMELEN;
|
||||
|
||||
zn->zn_hash = zap_hash(zn);
|
||||
return (zn);
|
||||
|
@ -467,7 +530,7 @@ mzap_open(dmu_buf_t *db)
|
|||
zfs_btree_create_custom(&zap->zap_m.zap_tree, mze_compare,
|
||||
mze_find_in_buf, sizeof (mzap_ent_t), 512);
|
||||
|
||||
zap_name_t *zn = zap_name_alloc(zap);
|
||||
zap_name_t *zn = zap_name_alloc(zap, B_FALSE);
|
||||
for (uint16_t i = 0; i < zap->zap_m.zap_num_chunks; i++) {
|
||||
mzap_ent_phys_t *mze =
|
||||
&zap_m_phys(zap)->mz_chunk[i];
|
||||
|
@ -674,7 +737,7 @@ mzap_upgrade(zap_t **zapp, const void *tag, dmu_tx_t *tx, zap_flags_t flags)
|
|||
|
||||
fzap_upgrade(zap, tx, flags);
|
||||
|
||||
zap_name_t *zn = zap_name_alloc(zap);
|
||||
zap_name_t *zn = zap_name_alloc(zap, B_FALSE);
|
||||
for (int i = 0; i < nchunks; i++) {
|
||||
mzap_ent_phys_t *mze = &mzp->mz_chunk[i];
|
||||
if (mze->mze_name[0] == 0)
|
||||
|
@ -1600,6 +1663,41 @@ zap_remove_uint64_by_dnode(dnode_t *dn, const uint64_t *key, int key_numints,
|
|||
return (err);
|
||||
}
|
||||
|
||||
|
||||
static zap_attribute_t *
|
||||
zap_attribute_alloc_impl(boolean_t longname)
|
||||
{
|
||||
zap_attribute_t *za;
|
||||
|
||||
za = kmem_cache_alloc((longname)? zap_attr_long_cache : zap_attr_cache,
|
||||
KM_SLEEP);
|
||||
za->za_name_len = (longname)? ZAP_MAXNAMELEN_NEW : ZAP_MAXNAMELEN;
|
||||
return (za);
|
||||
}
|
||||
|
||||
zap_attribute_t *
|
||||
zap_attribute_alloc(void)
|
||||
{
|
||||
return (zap_attribute_alloc_impl(B_FALSE));
|
||||
}
|
||||
|
||||
zap_attribute_t *
|
||||
zap_attribute_long_alloc(void)
|
||||
{
|
||||
return (zap_attribute_alloc_impl(B_TRUE));
|
||||
}
|
||||
|
||||
void
|
||||
zap_attribute_free(zap_attribute_t *za)
|
||||
{
|
||||
if (za->za_name_len == ZAP_MAXNAMELEN) {
|
||||
kmem_cache_free(zap_attr_cache, za);
|
||||
} else {
|
||||
ASSERT3U(za->za_name_len, ==, ZAP_MAXNAMELEN_NEW);
|
||||
kmem_cache_free(zap_attr_long_cache, za);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Routines for iterating over the attributes.
|
||||
*/
|
||||
|
@ -1736,7 +1834,7 @@ zap_cursor_retrieve(zap_cursor_t *zc, zap_attribute_t *za)
|
|||
za->za_num_integers = 1;
|
||||
za->za_first_integer = mzep->mze_value;
|
||||
(void) strlcpy(za->za_name, mzep->mze_name,
|
||||
sizeof (za->za_name));
|
||||
za->za_name_len);
|
||||
zc->zc_hash = (uint64_t)mze->mze_hash << 32;
|
||||
zc->zc_cd = mze->mze_cd;
|
||||
err = 0;
|
||||
|
|
|
@ -54,7 +54,7 @@ zcp_clones_iter(lua_State *state)
|
|||
uint64_t cursor = lua_tonumber(state, lua_upvalueindex(2));
|
||||
dsl_pool_t *dp = zcp_run_info(state)->zri_pool;
|
||||
dsl_dataset_t *ds, *clone;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za;
|
||||
zap_cursor_t zc;
|
||||
|
||||
err = dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds);
|
||||
|
@ -75,9 +75,11 @@ zcp_clones_iter(lua_State *state)
|
|||
dsl_dataset_phys(ds)->ds_next_clones_obj, cursor);
|
||||
dsl_dataset_rele(ds, FTAG);
|
||||
|
||||
err = zap_cursor_retrieve(&zc, &za);
|
||||
za = zap_attribute_alloc();
|
||||
err = zap_cursor_retrieve(&zc, za);
|
||||
if (err != 0) {
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
if (err != ENOENT) {
|
||||
return (luaL_error(state,
|
||||
"unexpected error %d from zap_cursor_retrieve()",
|
||||
|
@ -89,7 +91,8 @@ zcp_clones_iter(lua_State *state)
|
|||
cursor = zap_cursor_serialize(&zc);
|
||||
zap_cursor_fini(&zc);
|
||||
|
||||
err = dsl_dataset_hold_obj(dp, za.za_first_integer, FTAG, &clone);
|
||||
err = dsl_dataset_hold_obj(dp, za->za_first_integer, FTAG, &clone);
|
||||
zap_attribute_free(za);
|
||||
if (err != 0) {
|
||||
return (luaL_error(state,
|
||||
"unexpected error %d from "
|
||||
|
@ -499,7 +502,7 @@ zcp_bookmarks_iter(lua_State *state)
|
|||
uint64_t cursor = lua_tonumber(state, lua_upvalueindex(2));
|
||||
dsl_pool_t *dp = zcp_run_info(state)->zri_pool;
|
||||
dsl_dataset_t *ds;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za;
|
||||
zap_cursor_t zc;
|
||||
|
||||
int err = dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds);
|
||||
|
@ -536,9 +539,11 @@ zcp_bookmarks_iter(lua_State *state)
|
|||
ds->ds_bookmarks_obj, cursor);
|
||||
dsl_dataset_rele(ds, FTAG);
|
||||
|
||||
err = zap_cursor_retrieve(&zc, &za);
|
||||
za = zap_attribute_alloc();
|
||||
err = zap_cursor_retrieve(&zc, za);
|
||||
if (err != 0) {
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
if (err != ENOENT) {
|
||||
return (luaL_error(state,
|
||||
"unexpected error %d from zap_cursor_retrieve()",
|
||||
|
@ -552,7 +557,8 @@ zcp_bookmarks_iter(lua_State *state)
|
|||
|
||||
/* Create the full "pool/fs#bookmark" string to return */
|
||||
int n = snprintf(bookmark_name, ZFS_MAX_DATASET_NAME_LEN, "%s#%s",
|
||||
ds_name, za.za_name);
|
||||
ds_name, za->za_name);
|
||||
zap_attribute_free(za);
|
||||
if (n >= ZFS_MAX_DATASET_NAME_LEN) {
|
||||
return (luaL_error(state,
|
||||
"unexpected error %d from snprintf()", ENAMETOOLONG));
|
||||
|
@ -610,7 +616,7 @@ zcp_holds_iter(lua_State *state)
|
|||
uint64_t cursor = lua_tonumber(state, lua_upvalueindex(2));
|
||||
dsl_pool_t *dp = zcp_run_info(state)->zri_pool;
|
||||
dsl_dataset_t *ds;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za;
|
||||
zap_cursor_t zc;
|
||||
|
||||
int err = dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds);
|
||||
|
@ -631,9 +637,11 @@ zcp_holds_iter(lua_State *state)
|
|||
dsl_dataset_phys(ds)->ds_userrefs_obj, cursor);
|
||||
dsl_dataset_rele(ds, FTAG);
|
||||
|
||||
err = zap_cursor_retrieve(&zc, &za);
|
||||
za = zap_attribute_alloc();
|
||||
err = zap_cursor_retrieve(&zc, za);
|
||||
if (err != 0) {
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
if (err != ENOENT) {
|
||||
return (luaL_error(state,
|
||||
"unexpected error %d from zap_cursor_retrieve()",
|
||||
|
@ -648,8 +656,9 @@ zcp_holds_iter(lua_State *state)
|
|||
lua_pushnumber(state, cursor);
|
||||
lua_replace(state, lua_upvalueindex(2));
|
||||
|
||||
(void) lua_pushstring(state, za.za_name);
|
||||
(void) lua_pushnumber(state, za.za_first_integer);
|
||||
(void) lua_pushstring(state, za->za_name);
|
||||
(void) lua_pushnumber(state, za->za_first_integer);
|
||||
zap_attribute_free(za);
|
||||
return (2);
|
||||
}
|
||||
|
||||
|
|
|
@ -183,7 +183,7 @@ spa_features_check(spa_t *spa, boolean_t for_write,
|
|||
char *buf;
|
||||
|
||||
zc = kmem_alloc(sizeof (zap_cursor_t), KM_SLEEP);
|
||||
za = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
|
||||
za = zap_attribute_alloc();
|
||||
buf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
|
||||
|
||||
supported = B_TRUE;
|
||||
|
@ -217,7 +217,7 @@ spa_features_check(spa_t *spa, boolean_t for_write,
|
|||
zap_cursor_fini(zc);
|
||||
|
||||
kmem_free(buf, MAXPATHLEN);
|
||||
kmem_free(za, sizeof (zap_attribute_t));
|
||||
zap_attribute_free(za);
|
||||
kmem_free(zc, sizeof (zap_cursor_t));
|
||||
|
||||
return (supported);
|
||||
|
|
|
@ -2567,6 +2567,44 @@ zfs_prop_set_special(const char *dsname, zprop_source_t source,
|
|||
}
|
||||
break;
|
||||
}
|
||||
case ZFS_PROP_LONGNAME:
|
||||
{
|
||||
zfsvfs_t *zfsvfs;
|
||||
dsl_dataset_t *ds;
|
||||
|
||||
/*
|
||||
* Ignore the checks if the property is being applied as part of
|
||||
* 'zfs receive'. Because, we already check if the local pool
|
||||
* has SPA_FEATURE_LONGNAME enabled in dmu_recv_begin_check().
|
||||
*/
|
||||
if (source == ZPROP_SRC_RECEIVED) {
|
||||
cmn_err(CE_NOTE, "Skipping ZFS_PROP_LONGNAME checks "
|
||||
"for dsname=%s\n", dsname);
|
||||
err = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((err = zfsvfs_hold(dsname, FTAG, &zfsvfs, B_FALSE)) != 0) {
|
||||
cmn_err(CE_WARN, "%s:%d Failed to hold for dsname=%s "
|
||||
"err=%d\n", __FILE__, __LINE__, dsname, err);
|
||||
break;
|
||||
}
|
||||
|
||||
ds = dmu_objset_ds(zfsvfs->z_os);
|
||||
|
||||
if (!spa_feature_is_enabled(zfsvfs->z_os->os_spa,
|
||||
SPA_FEATURE_LONGNAME)) {
|
||||
err = ENOTSUP;
|
||||
} else {
|
||||
/*
|
||||
* Set err to -1 to force the zfs_set_prop_nvlist code
|
||||
* down the default path to set the value in the nvlist.
|
||||
*/
|
||||
err = -1;
|
||||
}
|
||||
zfsvfs_rele(zfsvfs, FTAG);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
err = -1;
|
||||
}
|
||||
|
|
|
@ -165,7 +165,7 @@ zfs_userspace_many(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type,
|
|||
{
|
||||
int error;
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t za;
|
||||
zap_attribute_t *za;
|
||||
zfs_useracct_t *buf = vbuf;
|
||||
uint64_t obj;
|
||||
int offset = 0;
|
||||
|
@ -196,8 +196,9 @@ zfs_userspace_many(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type,
|
|||
type == ZFS_PROP_PROJECTOBJUSED)
|
||||
offset = DMU_OBJACCT_PREFIX_LEN;
|
||||
|
||||
za = zap_attribute_alloc();
|
||||
for (zap_cursor_init_serialized(&zc, zfsvfs->z_os, obj, *cookiep);
|
||||
(error = zap_cursor_retrieve(&zc, &za)) == 0;
|
||||
(error = zap_cursor_retrieve(&zc, za)) == 0;
|
||||
zap_cursor_advance(&zc)) {
|
||||
if ((uintptr_t)buf - (uintptr_t)vbuf + sizeof (zfs_useracct_t) >
|
||||
*bufsizep)
|
||||
|
@ -207,14 +208,14 @@ zfs_userspace_many(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type,
|
|||
* skip object quota (with zap name prefix DMU_OBJACCT_PREFIX)
|
||||
* when dealing with block quota and vice versa.
|
||||
*/
|
||||
if ((offset > 0) != (strncmp(za.za_name, DMU_OBJACCT_PREFIX,
|
||||
if ((offset > 0) != (strncmp(za->za_name, DMU_OBJACCT_PREFIX,
|
||||
DMU_OBJACCT_PREFIX_LEN) == 0))
|
||||
continue;
|
||||
|
||||
fuidstr_to_sid(zfsvfs, za.za_name + offset,
|
||||
fuidstr_to_sid(zfsvfs, za->za_name + offset,
|
||||
buf->zu_domain, sizeof (buf->zu_domain), &buf->zu_rid);
|
||||
|
||||
buf->zu_space = za.za_first_integer;
|
||||
buf->zu_space = za->za_first_integer;
|
||||
buf++;
|
||||
}
|
||||
if (error == ENOENT)
|
||||
|
@ -224,6 +225,7 @@ zfs_userspace_many(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type,
|
|||
*bufsizep = (uintptr_t)buf - (uintptr_t)vbuf;
|
||||
*cookiep = zap_cursor_serialize(&zc);
|
||||
zap_cursor_fini(&zc);
|
||||
zap_attribute_free(za);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
|
@ -1034,7 +1034,7 @@ zvol_add_clones(const char *dsname, list_t *minors_list)
|
|||
goto out;
|
||||
|
||||
zap_cursor_t *zc = kmem_alloc(sizeof (zap_cursor_t), KM_SLEEP);
|
||||
zap_attribute_t *za = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
|
||||
zap_attribute_t *za = zap_attribute_alloc();
|
||||
objset_t *mos = dd->dd_pool->dp_meta_objset;
|
||||
|
||||
for (zap_cursor_init(zc, mos, dsl_dir_phys(dd)->dd_clones);
|
||||
|
@ -1060,7 +1060,7 @@ zvol_add_clones(const char *dsname, list_t *minors_list)
|
|||
}
|
||||
}
|
||||
zap_cursor_fini(zc);
|
||||
kmem_free(za, sizeof (zap_attribute_t));
|
||||
zap_attribute_free(za);
|
||||
kmem_free(zc, sizeof (zap_cursor_t));
|
||||
|
||||
out:
|
||||
|
|
|
@ -138,6 +138,10 @@ pre =
|
|||
post =
|
||||
tags = ['functional', 'largest_pool']
|
||||
|
||||
[tests/functional/longname:Linux]
|
||||
tests = ['longname_001_pos', 'longname_002_pos', 'longname_003_pos']
|
||||
tags = ['functional', 'longname']
|
||||
|
||||
[tests/functional/mmap:Linux]
|
||||
tests = ['mmap_libaio_001_pos', 'mmap_sync_001_pos']
|
||||
tags = ['functional', 'mmap']
|
||||
|
@ -182,7 +186,7 @@ tests = ['renameat2_noreplace', 'renameat2_exchange', 'renameat2_whiteout']
|
|||
tags = ['functional', 'renameat2']
|
||||
|
||||
[tests/functional/rsend:Linux]
|
||||
tests = ['send_realloc_dnode_size', 'send_encrypted_files']
|
||||
tests = ['send_realloc_dnode_size', 'send_encrypted_files', 'send-c_longname']
|
||||
tags = ['functional', 'rsend']
|
||||
|
||||
[tests/functional/simd:Linux]
|
||||
|
|
|
@ -1571,6 +1571,11 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
|
|||
functional/link_count/link_count_001.ksh \
|
||||
functional/link_count/link_count_root_inode.ksh \
|
||||
functional/link_count/setup.ksh \
|
||||
functional/longname/cleanup.ksh \
|
||||
functional/longname/longname_001_pos.ksh \
|
||||
functional/longname/longname_002_pos.ksh \
|
||||
functional/longname/longname_003_pos.ksh \
|
||||
functional/longname/setup.ksh \
|
||||
functional/log_spacemap/log_spacemap_import_logs.ksh \
|
||||
functional/migration/cleanup.ksh \
|
||||
functional/migration/migration_001_pos.ksh \
|
||||
|
@ -1904,6 +1909,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
|
|||
functional/rsend/rsend_031_pos.ksh \
|
||||
functional/rsend/send-c_embedded_blocks.ksh \
|
||||
functional/rsend/send-c_incremental.ksh \
|
||||
functional/rsend/send-c_longname.ksh \
|
||||
functional/rsend/send-c_lz4_disabled.ksh \
|
||||
functional/rsend/send-c_mixed_compression.ksh \
|
||||
functional/rsend/send-c_props.ksh \
|
||||
|
|
|
@ -109,5 +109,6 @@ if is_linux || is_freebsd; then
|
|||
"feature@block_cloning"
|
||||
"feature@vdev_zaps_v2"
|
||||
"feature@raidz_expansion"
|
||||
"feature@longname"
|
||||
)
|
||||
fi
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
#!/bin/ksh -p
|
||||
#
|
||||
# CDDL HEADER START
|
||||
#
|
||||
# The contents of this file are subject to the terms of the
|
||||
# Common Development and Distribution License (the "License").
|
||||
# You may not use this file except in compliance with the License.
|
||||
#
|
||||
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
# or http://www.opensolaris.org/os/licensing.
|
||||
# See the License for the specific language governing permissions
|
||||
# and limitations under the License.
|
||||
#
|
||||
# When distributing Covered Code, include this CDDL HEADER in each
|
||||
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
# If applicable, add the following below this CDDL HEADER, with the
|
||||
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
#
|
||||
# CDDL HEADER END
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
# Use is subject to license terms.
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2021 by Nutanix. All rights reserved.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
|
||||
default_cleanup
|
|
@ -0,0 +1,139 @@
|
|||
#! /bin/ksh -p
|
||||
#
|
||||
# CDDL HEADER START
|
||||
#
|
||||
# The contents of this file are subject to the terms of the
|
||||
# Common Development and Distribution License (the "License").
|
||||
# You may not use this file except in compliance with the License.
|
||||
#
|
||||
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
# or http://www.opensolaris.org/os/licensing.
|
||||
# See the License for the specific language governing permissions
|
||||
# and limitations under the License.
|
||||
#
|
||||
# When distributing Covered Code, include this CDDL HEADER in each
|
||||
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
# If applicable, add the following below this CDDL HEADER, with the
|
||||
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
#
|
||||
# CDDL HEADER END
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2021 by Nutanix. All rights reserved.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# Verify the support for long filenames.
|
||||
#
|
||||
# STRATEGY:
|
||||
# 0. On a fresh dataset ensure property "longname" is enabled by default.
|
||||
# 1. Disable the longname.
|
||||
# 2. Try to create a filename whose length is > 256 bytes. This should fail.
|
||||
# 3. Enable "longname" property on the dataset.
|
||||
# 4. Try to create files and dirs whose names are > 256 bytes.
|
||||
# 5. Ensure that "ls" is able to list the file.
|
||||
# 6. Ensure stat(1) is able to stat the file/directory.
|
||||
# 7. Try to rename the files and directories
|
||||
# 8. Try to delete the files and directories
|
||||
|
||||
verify_runnable "global"
|
||||
|
||||
WORKDIR=$TESTDIR/workdir
|
||||
MOVEDIR=$TESTDIR/movedir/level2/level3/level4/level5/level6
|
||||
|
||||
function cleanup
|
||||
{
|
||||
log_must rm -rf $WORKDIR
|
||||
log_must rm -rf $TESTDIR/movedir
|
||||
}
|
||||
|
||||
LONGNAME=$(printf 'a%.0s' {1..512})
|
||||
LONGFNAME="file-$LONGNAME"
|
||||
LONGDNAME="dir-$LONGNAME"
|
||||
LONGPNAME="mypipe-$LONGNAME"
|
||||
LONGCNAME="char_dev-$LONGNAME"
|
||||
LONGLNAME="link-$LONGNAME"
|
||||
LONGNAME_255=$(printf 'a%.0s' {1..255})
|
||||
LONGNAME_1023=$(printf 'a%.0s' {1..1023})
|
||||
|
||||
|
||||
log_assert "Check longname support for directories/files"
|
||||
|
||||
log_onexit cleanup
|
||||
|
||||
log_must mkdir $WORKDIR
|
||||
log_must mkdir -p $MOVEDIR
|
||||
|
||||
# Disable longname support
|
||||
log_must zfs set longname=off $TESTPOOL/$TESTFS
|
||||
|
||||
#Ensure a file of length 255bytes can be created
|
||||
log_must touch $WORKDIR/$LONGNAME_255
|
||||
|
||||
#Where as file of length 256bytes should fail
|
||||
long_mustnot touch $WORKDIR/${LONGNAME_255}b
|
||||
|
||||
# Try to create a file with long name with property "longname=off"
|
||||
log_mustnot touch $WORKDIR/$LONGFNAME
|
||||
log_mustnot mkdir $WORKDIR/$LONGDNAME
|
||||
|
||||
# Enable longname support
|
||||
log_must zfs set longname=on $TESTPOOL/$TESTFS
|
||||
|
||||
# Retry the longname creates and that should succeed
|
||||
log_must mkdir $WORKDIR/$LONGDNAME
|
||||
log_must touch $WORKDIR/$LONGFNAME
|
||||
|
||||
# Should be able to create a file with name of 1023 chars
|
||||
log_must touch $WORKDIR/$LONGNAME_1023
|
||||
|
||||
# And names longer that 1023 should fail
|
||||
log_mustnot touch $WORKDIR/${LONGNAME_1023}b
|
||||
|
||||
# Ensure the longnamed dir/file can be listed.
|
||||
name=$(ls $WORKDIR/$LONGFNAME)
|
||||
if [[ "${name}" != "$WORKDIR/$LONGFNAME" ]]; then
|
||||
log_fail "Unable to list: $WORKDIR/$LONGFNAME ret:$name"
|
||||
fi
|
||||
|
||||
name=$(ls -d $WORKDIR/$LONGDNAME)
|
||||
if [[ "${name}" != "$WORKDIR/$LONGDNAME" ]]; then
|
||||
log_fail "Unable to list: $WORKDIR/$LONGDNAME ret:$name"
|
||||
fi
|
||||
|
||||
# Ensure stat works
|
||||
log_must stat $WORKDIR/$LONGFNAME
|
||||
log_must stat $WORKDIR/$LONGDNAME
|
||||
|
||||
# Ensure softlinks can be created from a longname to
|
||||
# another longnamed file.
|
||||
log_must ln -s $WORKDIR/$LONGFNAME $WORKDIR/$LONGLNAME
|
||||
|
||||
# Ensure a longnamed pipe and character device file
|
||||
# can be created
|
||||
log_must mknod $WORKDIR/$LONGPNAME p
|
||||
log_must mknod $WORKDIR/$LONGCNAME c 92 1
|
||||
|
||||
# Fetch the inode numbers of the objects created.
|
||||
INODE_NO_FILE=$(stat -c %i $WORKDIR/$LONGFNAME)
|
||||
INODE_NO_DIR=$(stat -c %i $WORKDIR/$LONGDNAME)
|
||||
INODE_NO_LINK=$(stat -c %i $WORKDIR/$LONGLNAME)
|
||||
INODE_NO_PIPE=$(stat -c %i $WORKDIR/$LONGPNAME)
|
||||
INODE_NO_CHAR=$(stat -c %i $WORKDIR/$LONGCNAME)
|
||||
|
||||
# Ensure we can rename the longname file
|
||||
log_must mv $WORKDIR/$LONGFNAME $WORKDIR/file2
|
||||
|
||||
# Delete the long named dir/file
|
||||
log_must rmdir $WORKDIR/$LONGDNAME
|
||||
log_must rm $WORKDIR/file2
|
||||
log_must rm $WORKDIR/$LONGPNAME
|
||||
log_must rm $WORKDIR/$LONGCNAME
|
||||
log_must rm $WORKDIR/$LONGLNAME
|
||||
|
||||
log_pass
|
|
@ -0,0 +1,115 @@
|
|||
#! /bin/ksh -p
|
||||
#
|
||||
# CDDL HEADER START
|
||||
#
|
||||
# The contents of this file are subject to the terms of the
|
||||
# Common Development and Distribution License (the "License").
|
||||
# You may not use this file except in compliance with the License.
|
||||
#
|
||||
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
# or http://www.opensolaris.org/os/licensing.
|
||||
# See the License for the specific language governing permissions
|
||||
# and limitations under the License.
|
||||
#
|
||||
# When distributing Covered Code, include this CDDL HEADER in each
|
||||
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
# If applicable, add the following below this CDDL HEADER, with the
|
||||
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
#
|
||||
# CDDL HEADER END
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2021 by Nutanix. All rights reserved.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# Check if longname feature is disabled by default and can be enabled.
|
||||
#
|
||||
# STRATEGY:
|
||||
# 1. Create a zpool with longname feature disabled
|
||||
# 2. Attempt to enable 'longname' property should fail.
|
||||
# 3. Attempt to create a longnamed (>255) file should fail.
|
||||
# 4. Enable the feature@longname
|
||||
# 5. Enable 'longname' property on the dataset.
|
||||
# 6. Should be able to create long named files and directories.
|
||||
# 7. Should be able to disable longname property.
|
||||
# 8. This should disallow creating new longnamed file/dirs. But, should be
|
||||
# able to access existing longnamed files/dirs.
|
||||
verify_runnable "global"
|
||||
|
||||
function cleanup
|
||||
{
|
||||
log_must rm -rf $WORKDIR
|
||||
poolexists $TESTPOOL && zpool destroy $TESTPOOL
|
||||
}
|
||||
|
||||
log_assert "Check feature@longname and 'longname' dataset propery work correctly"
|
||||
|
||||
log_onexit cleanup
|
||||
|
||||
log_must zpool destroy $TESTPOOL
|
||||
|
||||
log_must zpool create -o feature@longname=disabled $TESTPOOL $DISKS
|
||||
|
||||
log_must zfs create $TESTPOOL/$TESTFS2
|
||||
|
||||
log_must zfs set mountpoint=$TESTDIR2 $TESTPOOL/$TESTFS2
|
||||
|
||||
log_mustnot zfs set longname=on $TESTPOOL/$TESTFS2
|
||||
|
||||
LONGNAME=$(printf 'a%.0s' {1..512})
|
||||
LONGFNAME="file-$LONGNAME"
|
||||
LONGDNAME="dir-$LONGNAME"
|
||||
SHORTDNAME="dir-short"
|
||||
SHORTFNAME="file-short"
|
||||
WORKDIR=$TESTDIR2/workdir
|
||||
|
||||
log_must mkdir $WORKDIR
|
||||
log_mustnot touch $WORKDIR/$LONGFNAME
|
||||
log_mustnot mkdir $WORKDIR/$LONGDNAME
|
||||
|
||||
log_must zpool set feature@longname=enabled $TESTPOOL
|
||||
log_must zfs set longname=on $TESTPOOL/$TESTFS2
|
||||
|
||||
log_must mkdir $WORKDIR/$LONGDNAME
|
||||
log_must touch $WORKDIR/$LONGFNAME
|
||||
|
||||
# Ensure the above changes are synced out.
|
||||
log_must zpool sync $TESTPOOL
|
||||
|
||||
# Ensure that the feature is activated once longnamed files are created.
|
||||
state=$(zpool get feature@longname -H -o value $TESTPOOL)
|
||||
log_note "feature@longname on pool: $TESTPOOL : $state"
|
||||
|
||||
if [[ "$state" != "active" ]]; then
|
||||
log_fail "feature@longname has state $state (expected active)"
|
||||
fi
|
||||
|
||||
# Set longname=off.
|
||||
log_must zfs set longname=off $TESTPOOL/$TESTFS2
|
||||
|
||||
# Ensure no new file/directory with longnames can be created or can be renamed
|
||||
# to.
|
||||
log_mustnot mkdir $WORKDIR/${LONGDNAME}.1
|
||||
log_mustnot touch $WORKDIR/${LONGFNAME}.1
|
||||
log_must mkdir $WORKDIR/$SHORTDNAME
|
||||
log_mustnot mv $WORKDIR/$SHORTDNAME $WORKDIR/${LONGDNAME}.1
|
||||
log_must touch $WORKDIR/$SHORTFNAME
|
||||
log_mustnot mv $WORKDIR/$SHORTFNAME $WORKDIR/${LONGFNAME}.1
|
||||
|
||||
#Cleanup shortnames
|
||||
log_must rmdir $WORKDIR/$SHORTDNAME
|
||||
log_must rm $WORKDIR/$SHORTFNAME
|
||||
|
||||
# But, should be able to stat and rename existing files
|
||||
log_must stat $WORKDIR/$LONGDNAME
|
||||
log_must stat $WORKDIR/$LONGFNAME
|
||||
log_must mv $WORKDIR/$LONGDNAME $WORKDIR/$SHORTDNAME
|
||||
log_must mv $WORKDIR/$LONGFNAME $WORKDIR/$SHORTFNAME
|
||||
|
||||
log_pass
|
|
@ -0,0 +1,113 @@
|
|||
#! /bin/ksh -p
|
||||
#
|
||||
# CDDL HEADER START
|
||||
#
|
||||
# The contents of this file are subject to the terms of the
|
||||
# Common Development and Distribution License (the "License").
|
||||
# You may not use this file except in compliance with the License.
|
||||
#
|
||||
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
# or http://www.opensolaris.org/os/licensing.
|
||||
# See the License for the specific language governing permissions
|
||||
# and limitations under the License.
|
||||
#
|
||||
# When distributing Covered Code, include this CDDL HEADER in each
|
||||
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
# If applicable, add the following below this CDDL HEADER, with the
|
||||
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
#
|
||||
# CDDL HEADER END
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2021 by Nutanix. All rights reserved.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# Check if longnames are handled correctly by ZIL replay and feature is activated.
|
||||
#
|
||||
# STRATEGY:
|
||||
# 1. Create a zpool with longname feature disabled
|
||||
# 2. Enable the feature@longname
|
||||
# 3. Enable 'longname' property on the dataset.
|
||||
# 4. Freeze the zpool
|
||||
# 5. Create a longname
|
||||
# 6. Export and import the zpool.
|
||||
# 7. Replaying of longname create should activate the feature@longname
|
||||
verify_runnable "global"
|
||||
|
||||
function cleanup
|
||||
{
|
||||
log_must rm -rf $WORKDIR
|
||||
poolexists $TESTPOOL && zpool destroy $TESTPOOL
|
||||
}
|
||||
|
||||
log_assert "Check feature@longname and 'longname' dataset propery work correctly"
|
||||
|
||||
log_onexit cleanup
|
||||
|
||||
poolexists $TESTPOOL && zpool destroy $TESTPOOL
|
||||
|
||||
log_must zpool create -o feature@longname=disabled $TESTPOOL $DISKS
|
||||
|
||||
log_must zfs create $TESTPOOL/$TESTFS
|
||||
|
||||
log_must zfs set mountpoint=$TESTDIR $TESTPOOL/$TESTFS
|
||||
|
||||
LONGNAME=$(printf 'a%.0s' {1..512})
|
||||
LONGFNAME="file-$LONGNAME"
|
||||
LONGDNAME="dir-$LONGNAME"
|
||||
SHORTDNAME="dir-short"
|
||||
SHORTFNAME="file-short"
|
||||
WORKDIR=$TESTDIR/workdir
|
||||
|
||||
log_must mkdir $WORKDIR
|
||||
|
||||
log_must zpool set feature@longname=enabled $TESTPOOL
|
||||
log_must zfs set longname=on $TESTPOOL/$TESTFS
|
||||
|
||||
# Ensure that the feature is NOT activated yet as no longnamed file is created.
|
||||
state=$(zpool get feature@longname -H -o value $TESTPOOL)
|
||||
log_note "feature@longname on pool: $TESTPOOL : $state"
|
||||
|
||||
if [[ "$state" != "enabled" ]]; then
|
||||
log_fail "feature@longname has state $state (expected enabled)"
|
||||
fi
|
||||
|
||||
#
|
||||
# This dd command works around an issue where ZIL records aren't created
|
||||
# after freezing the pool unless a ZIL header already exists. Create a file
|
||||
# synchronously to force ZFS to write one out.
|
||||
#
|
||||
log_must dd if=/dev/zero of=/$WORKDIR/sync conv=fdatasync,fsync bs=1 count=1
|
||||
|
||||
log_must zpool freeze $TESTPOOL
|
||||
|
||||
log_must mkdir $WORKDIR/$LONGDNAME
|
||||
log_must touch $WORKDIR/$LONGFNAME
|
||||
|
||||
# Export and re-import the zpool
|
||||
log_must zpool export $TESTPOOL
|
||||
log_must zpool import $TESTPOOL
|
||||
|
||||
# Ensure that the feature is activated once longnamed files are created.
|
||||
state=$(zpool get feature@longname -H -o value $TESTPOOL)
|
||||
log_note "feature@longname on pool: $TESTPOOL : $state"
|
||||
if [[ "$state" != "active" ]]; then
|
||||
log_fail "feature@longname has state $state (expected active)"
|
||||
fi
|
||||
|
||||
# Destroying the dataset where the feature is activated should put the feature
|
||||
# back to 'enabled' state
|
||||
log_must zfs destroy -r $TESTPOOL/$TESTFS
|
||||
state=$(zpool get feature@longname -H -o value $TESTPOOL)
|
||||
log_note "feature@longname on pool: $TESTPOOL : $state"
|
||||
if [[ "$state" != "enabled" ]]; then
|
||||
log_fail "feature@longname has state $state (expected active)"
|
||||
fi
|
||||
|
||||
log_pass
|
|
@ -0,0 +1,35 @@
|
|||
#!/bin/ksh -p
|
||||
#
|
||||
# CDDL HEADER START
|
||||
#
|
||||
# The contents of this file are subject to the terms of the
|
||||
# Common Development and Distribution License (the "License").
|
||||
# You may not use this file except in compliance with the License.
|
||||
#
|
||||
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
# or http://www.opensolaris.org/os/licensing.
|
||||
# See the License for the specific language governing permissions
|
||||
# and limitations under the License.
|
||||
#
|
||||
# When distributing Covered Code, include this CDDL HEADER in each
|
||||
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
# If applicable, add the following below this CDDL HEADER, with the
|
||||
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
#
|
||||
# CDDL HEADER END
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
# Use is subject to license terms.
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2021 by Nutanix. All rights reserved.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
|
||||
DISK=${DISKS%% *}
|
||||
default_setup $DISK
|
|
@ -720,6 +720,7 @@ function stream_has_features
|
|||
feature[resuming]="100000"
|
||||
feature[redacted]="200000"
|
||||
feature[compressed]="400000"
|
||||
feature[longname]="10000000"
|
||||
|
||||
typeset flag known derived=0
|
||||
for flag in "$@"; do
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
#!/bin/ksh -p
|
||||
|
||||
#
|
||||
# This file and its contents are supplied under the terms of the
|
||||
# Common Development and Distribution License ("CDDL"), version 1.0.
|
||||
# You may only use this file in accordance with the terms of version
|
||||
# 1.0 of the CDDL.
|
||||
#
|
||||
# A full copy of the text of the CDDL should have accompanied this
|
||||
# source. A copy of the CDDL is also available via the Internet at
|
||||
# http://www.illumos.org/license/CDDL.
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2021 by Nutanix. All rights reserved.
|
||||
#
|
||||
|
||||
. $STF_SUITE/tests/functional/rsend/rsend.kshlib
|
||||
. $STF_SUITE/include/properties.shlib
|
||||
|
||||
#
|
||||
# Description:
|
||||
# Verify that longname featureflag is present in the stream.
|
||||
#
|
||||
# Strategy:
|
||||
# 1. Create a filesystem with longnamed files/directories.
|
||||
# 2. Verify that the sendstream has the longname featureflag is present in the
|
||||
# send stream.
|
||||
# 3. Verify the created streams can be received correctly.
|
||||
# 4. Verify that the longnamed files/directories are present in the received
|
||||
# filesystem.
|
||||
#
|
||||
|
||||
verify_runnable "both"
|
||||
|
||||
log_assert "Verify that longnames are handled correctly in send stream."
|
||||
log_onexit cleanup_pool $POOL $POOL2 $POOL3
|
||||
|
||||
typeset sendfs=$POOL/sendfs
|
||||
typeset recvfs=$POOL2/recvfs
|
||||
typeset recvfs3=$POOL3/recvfs
|
||||
typeset stream=$BACKDIR/stream
|
||||
typeset dump=$BACKDIR/dump
|
||||
|
||||
log_must zfs create -o longname=on $sendfs
|
||||
typeset dir=$(get_prop mountpoint $sendfs)
|
||||
|
||||
# Create a longnamed dir and a file in the send dataset
|
||||
LONGNAME=$(printf 'a%.0s' {1..512})
|
||||
LONGFNAME="file-$LONGNAME"
|
||||
LONGDNAME="dir-$LONGNAME"
|
||||
log_must mkdir $dir/$LONGDNAME
|
||||
log_must touch $dir/$LONGFNAME
|
||||
|
||||
# When POOL3 is created by rsend.kshlib feature@longname is 'enabled'.
|
||||
# Recreate the POOL3 with feature@longname disabled.
|
||||
datasetexists $POOL3 && log_must zpool destroy $POOL3
|
||||
log_must zpool create -o feature@longname=disabled $POOL3 $DISK3
|
||||
|
||||
# Generate the streams and zstreamdump output.
|
||||
log_must zfs snapshot $sendfs@now
|
||||
log_must eval "zfs send -p $sendfs@now >$stream"
|
||||
log_must eval "zstream dump -v <$stream >$dump"
|
||||
log_must eval "zfs recv $recvfs <$stream"
|
||||
cmp_ds_cont $sendfs $recvfs
|
||||
log_must stream_has_features $stream longname
|
||||
|
||||
# Ensure the the receiving pool has feature@longname activated after receiving.
|
||||
feat_val=$(zpool get -H -o value feature@longname $POOL2)
|
||||
log_note "Zpool $POOL2 feature@longname=$feat_val"
|
||||
if [[ "$feat_val" != "active" ]]; then
|
||||
log_fail "pool $POOL2 feature@longname=$feat_val (expected 'active')"
|
||||
fi
|
||||
|
||||
# Receiving of the stream on $POOL3 should fail as longname is not enabled
|
||||
log_mustnot eval "zfs recv $recvfs3 <$stream"
|
||||
|
||||
# Enable feature@longname and retry the receiving the stream.
|
||||
# It should succeed this time.
|
||||
log_must eval "zpool set feature@longname=enabled $POOL3"
|
||||
log_must eval "zfs recv $recvfs3 <$stream"
|
||||
|
||||
log_must zfs get longname $recvfs3
|
||||
prop_val=$(zfs get -H -o value longname $recvfs3)
|
||||
log_note "dataset $recvfs3 has longname=$prop_val"
|
||||
if [[ "$prop_val" != "on" ]]; then
|
||||
log_fail "$recvfs3 has longname=$prop_val (expected 'on')"
|
||||
fi
|
||||
|
||||
#
|
||||
# TODO:
|
||||
# - Add a testcase to cover the case where send-stream does not contain
|
||||
# properties (generated without "-p").
|
||||
# In this case the target dataset would have longname files/directories which
|
||||
# cannot be accessed if the dataset property 'longname=off'.
|
||||
#
|
||||
|
||||
log_pass "Longnames are handled correctly in send/recv"
|
Loading…
Reference in New Issue