libzfs_jni_property.c revision 1356:e021b5e4aa0e
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22/* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27#pragma ident "%Z%%M% %I% %E% SMI" 28 29#include "libzfs_jni_property.h" 30#include "libzfs_jni_util.h" 31#include <strings.h> 32 33/* 34 * Types 35 */ 36 37/* Signature for function to convert string to a specific Java object */ 38typedef jobject (*str_to_obj_f)(JNIEnv *, char *); 39 40/* Signature for function to convert uint64_t to a specific Java object */ 41typedef jobject (*uint64_to_obj_f)(JNIEnv *, uint64_t); 42 43/* 44 * Describes a property and the parameters needed to create a Java 45 * Property object for it 46 */ 47typedef struct custom_prop_desct { 48 zfs_prop_t prop; 49 str_to_obj_f convert_str; 50 uint64_to_obj_f convert_uint64; 51 char *propClass; 52 char *valueClass; 53} custom_prop_desct_t; 54 55/* 56 * Function prototypes 57 */ 58 59static jobject create_BasicProperty(JNIEnv *, zfs_handle_t *, 60 zfs_prop_t, str_to_obj_f, uint64_to_obj_f, char *, char *); 61static jobject create_BooleanProperty(JNIEnv *, zfs_handle_t *, zfs_prop_t); 62static jobject create_LongProperty(JNIEnv *, zfs_handle_t *, zfs_prop_t); 63static jobject create_StringProperty(JNIEnv *, zfs_handle_t *, zfs_prop_t); 64static jobject create_ObjectProperty(JNIEnv *, zfs_handle_t *, 65 zfs_prop_t, str_to_obj_f, uint64_to_obj_f, char *, char *); 66static jobject create_default_BasicProperty(JNIEnv *, zfs_prop_t, 67 str_to_obj_f, uint64_to_obj_f, char *, char *); 68static jobject create_default_BooleanProperty(JNIEnv *, zfs_prop_t); 69static jobject create_default_LongProperty(JNIEnv *, zfs_prop_t); 70static jobject create_default_StringProperty(JNIEnv *, zfs_prop_t); 71static jobject create_default_ObjectProperty( 72 JNIEnv *, zfs_prop_t, str_to_obj_f, uint64_to_obj_f, char *, char *); 73static jobject str_to_enum_element(JNIEnv *, char *, char *); 74static jobject str_to_aclinherit(JNIEnv *, char *); 75static jobject str_to_aclmode(JNIEnv *, char *); 76static jobject str_to_checksum(JNIEnv *, char *); 77static jobject str_to_compression(JNIEnv *, char *); 78static jobject str_to_snapdir(JNIEnv *, char *); 79static jobject str_to_string(JNIEnv *, char *); 80 81/* 82 * Static data 83 */ 84 85zfs_prop_t props_boolean[] = { 86 ZFS_PROP_ATIME, 87 ZFS_PROP_DEVICES, 88 ZFS_PROP_EXEC, 89 ZFS_PROP_MOUNTED, 90 ZFS_PROP_READONLY, 91 ZFS_PROP_SETUID, 92 ZFS_PROP_ZONED, 93 ZFS_PROP_INVAL 94}; 95 96zfs_prop_t props_long[] = { 97 ZFS_PROP_AVAILABLE, 98 ZFS_PROP_CREATETXG, 99 ZFS_PROP_QUOTA, 100 ZFS_PROP_REFERENCED, 101 ZFS_PROP_RESERVATION, 102 ZFS_PROP_USED, 103 ZFS_PROP_VOLSIZE, 104 ZFS_PROP_INVAL 105}; 106 107zfs_prop_t props_string[] = { 108 ZFS_PROP_ORIGIN, 109 /* ZFS_PROP_TYPE, */ 110 ZFS_PROP_INVAL 111}; 112 113custom_prop_desct_t props_custom[] = { 114 { ZFS_PROP_ACLINHERIT, str_to_aclinherit, NULL, 115 ZFSJNI_PACKAGE_DATA "AclInheritProperty", 116 ZFSJNI_PACKAGE_DATA "AclInheritProperty$AclInherit" }, 117 118 { ZFS_PROP_ACLMODE, str_to_aclmode, NULL, 119 ZFSJNI_PACKAGE_DATA "AclModeProperty", 120 ZFSJNI_PACKAGE_DATA "AclModeProperty$AclMode" }, 121 122 { ZFS_PROP_CHECKSUM, str_to_checksum, NULL, 123 ZFSJNI_PACKAGE_DATA "ChecksumProperty", 124 ZFSJNI_PACKAGE_DATA "ChecksumProperty$Checksum" }, 125 126 { ZFS_PROP_COMPRESSION, str_to_compression, NULL, 127 ZFSJNI_PACKAGE_DATA "CompressionProperty", 128 ZFSJNI_PACKAGE_DATA "CompressionProperty$Compression" }, 129 130 { ZFS_PROP_COMPRESSRATIO, NULL, zjni_long_to_Long, 131 ZFSJNI_PACKAGE_DATA "CompressRatioProperty", 132 "java/lang/Long" }, 133 134 { ZFS_PROP_CREATION, zjni_str_to_date, NULL, 135 ZFSJNI_PACKAGE_DATA "CreationProperty", 136 "java/util/Date" }, 137 138 { ZFS_PROP_MOUNTPOINT, str_to_string, NULL, 139 ZFSJNI_PACKAGE_DATA "MountPointProperty", 140 "java/lang/String" }, 141 142 { ZFS_PROP_RECORDSIZE, NULL, zjni_long_to_Long, 143 ZFSJNI_PACKAGE_DATA "RecordSizeProperty", 144 "java/lang/Long" }, 145 146 { ZFS_PROP_SHARENFS, str_to_string, NULL, 147 ZFSJNI_PACKAGE_DATA "ShareNFSProperty", 148 "java/lang/String" }, 149 150 { ZFS_PROP_SNAPDIR, str_to_snapdir, NULL, 151 ZFSJNI_PACKAGE_DATA "SnapDirProperty", 152 ZFSJNI_PACKAGE_DATA "SnapDirProperty$SnapDir" }, 153 154 { ZFS_PROP_VOLBLOCKSIZE, NULL, zjni_long_to_Long, 155 ZFSJNI_PACKAGE_DATA "VolBlockSizeProperty", 156 "java/lang/Long" }, 157 158 { ZFS_PROP_INVAL, NULL, NULL, NULL, NULL }, 159}; 160 161/* 162 * Static functions 163 */ 164 165static jobject 166create_BasicProperty(JNIEnv *env, zfs_handle_t *zhp, zfs_prop_t prop, 167 str_to_obj_f convert_str, uint64_to_obj_f convert_uint64, 168 char *propClass, char *valueClass) 169{ 170 jobject propertyObject = NULL; 171 char source[ZFS_MAXNAMELEN]; 172 zfs_source_t srctype; 173 jobject propValue = NULL; 174 175 if (convert_str != NULL) { 176 char propbuf[ZFS_MAXPROPLEN]; 177 int result = zfs_prop_get(zhp, prop, propbuf, 178 sizeof (propbuf), &srctype, source, sizeof (source), 1); 179 180 if (result == 0) { 181 propValue = convert_str(env, propbuf); 182 } 183 } else { 184 uint64_t value; 185 int result = zfs_prop_get_numeric( 186 zhp, prop, &value, &srctype, source, sizeof (source)); 187 188 if (result == 0) { 189 propValue = convert_uint64(env, value); 190 } 191 } 192 193 if (propValue != NULL) { 194 195 jmethodID constructor; 196 char signature[1024]; 197 jclass class = (*env)->FindClass(env, propClass); 198 199 jstring propName = (*env)->NewStringUTF( 200 env, zfs_prop_to_name(prop)); 201 202 jboolean readOnly = zfs_prop_readonly(prop) ? 203 JNI_TRUE : JNI_FALSE; 204 205 if (srctype == ZFS_SRC_INHERITED) { 206 207 jstring propSource = (*env)->NewStringUTF(env, source); 208 209 (void) snprintf(signature, sizeof (signature), 210 "(Ljava/lang/String;L%s;ZLjava/lang/String;)V", 211 valueClass); 212 213 constructor = (*env)->GetMethodID( 214 env, class, "<init>", signature); 215 216 propertyObject = (*env)->NewObject( 217 env, class, constructor, propName, propValue, 218 readOnly, propSource); 219 } else { 220 jobject lineage = zjni_int_to_Lineage(env, srctype); 221 222 (void) snprintf(signature, sizeof (signature), 223 "(Ljava/lang/String;L%s;ZL" 224 ZFSJNI_PACKAGE_DATA "Property$Lineage;)V", 225 valueClass); 226 227 constructor = (*env)->GetMethodID( 228 env, class, "<init>", signature); 229 230 propertyObject = (*env)->NewObject( 231 env, class, constructor, propName, propValue, 232 readOnly, lineage); 233 } 234 } 235 236 return (propertyObject); 237} 238 239static jobject 240create_BooleanProperty(JNIEnv *env, zfs_handle_t *zhp, zfs_prop_t prop) 241{ 242 return (create_BasicProperty(env, zhp, prop, NULL, zjni_int_to_boolean, 243 ZFSJNI_PACKAGE_DATA "BooleanProperty", "java/lang/Boolean")); 244} 245 246static jobject 247create_LongProperty(JNIEnv *env, zfs_handle_t *zhp, zfs_prop_t prop) 248{ 249 return (create_BasicProperty(env, zhp, prop, NULL, zjni_long_to_Long, 250 ZFSJNI_PACKAGE_DATA "LongProperty", "java/lang/Long")); 251} 252 253static jobject 254create_StringProperty(JNIEnv *env, zfs_handle_t *zhp, zfs_prop_t prop) 255{ 256 return (create_BasicProperty(env, zhp, prop, str_to_string, NULL, 257 ZFSJNI_PACKAGE_DATA "StringProperty", "java/lang/String")); 258} 259 260static jobject 261create_ObjectProperty(JNIEnv *env, zfs_handle_t *zhp, zfs_prop_t prop, 262 str_to_obj_f convert_str, uint64_to_obj_f convert_uint64, 263 char *propClass, char *valueClass) 264{ 265 jobject propertyObject = NULL; 266 char source[ZFS_MAXNAMELEN]; 267 zfs_source_t srctype; 268 jobject propValue = NULL; 269 270 if (convert_str != NULL) { 271 char propbuf[ZFS_MAXPROPLEN]; 272 int result = zfs_prop_get(zhp, prop, propbuf, 273 sizeof (propbuf), &srctype, source, sizeof (source), 1); 274 275 if (result == 0) { 276 propValue = convert_str(env, propbuf); 277 } 278 } else { 279 uint64_t value; 280 int result = zfs_prop_get_numeric( 281 zhp, prop, &value, &srctype, source, sizeof (source)); 282 283 if (result == 0) { 284 propValue = convert_uint64(env, value); 285 } 286 } 287 288 if (propValue != NULL) { 289 290 jmethodID constructor; 291 char signature[1024]; 292 jclass class = (*env)->FindClass(env, propClass); 293 294 if (srctype == ZFS_SRC_INHERITED) { 295 296 jstring propSource = (*env)->NewStringUTF(env, source); 297 298 (void) snprintf(signature, sizeof (signature), 299 "(L%s;Ljava/lang/String;)V", valueClass); 300 301 constructor = (*env)->GetMethodID( 302 env, class, "<init>", signature); 303 304 propertyObject = (*env)->NewObject(env, 305 class, constructor, propValue, propSource); 306 307 } else { 308 jobject lineage = zjni_int_to_Lineage(env, srctype); 309 310 (void) snprintf(signature, sizeof (signature), 311 "(L%s;L" ZFSJNI_PACKAGE_DATA "Property$Lineage;)V", 312 valueClass); 313 314 constructor = (*env)->GetMethodID( 315 env, class, "<init>", signature); 316 317 propertyObject = (*env)->NewObject(env, 318 class, constructor, propValue, lineage); 319 } 320 } 321 322 return (propertyObject); 323} 324 325static jobject 326create_default_BasicProperty(JNIEnv *env, zfs_prop_t prop, 327 str_to_obj_f convert_str, uint64_to_obj_f convert_uint64, 328 char *propClass, char *valueClass) 329{ 330 jobject propertyObject = NULL; 331 332 if (!zfs_prop_readonly(prop)) { 333 jobject propValue; 334 335 if (convert_str != NULL) { 336 char *propbuf = (char *)zfs_prop_default_string(prop); 337 propValue = convert_str(env, propbuf); 338 } else { 339 uint64_t value = zfs_prop_default_numeric(prop); 340 propValue = convert_uint64(env, value); 341 } 342 343 if (propValue != NULL) { 344 char signature[1024]; 345 jmethodID constructor; 346 347 jstring propName = 348 (*env)->NewStringUTF(env, zfs_prop_to_name(prop)); 349 350 jboolean readOnly = zfs_prop_readonly(prop) ? 351 JNI_TRUE : JNI_FALSE; 352 353 jclass class = (*env)->FindClass(env, propClass); 354 jobject lineage = 355 zjni_int_to_Lineage(env, ZFS_SRC_DEFAULT); 356 357 (void) snprintf(signature, sizeof (signature), 358 "(Ljava/lang/String;L%s;ZL" ZFSJNI_PACKAGE_DATA 359 "Property$Lineage;)V", valueClass); 360 361 constructor = (*env)->GetMethodID( 362 env, class, "<init>", signature); 363 364 propertyObject = (*env)->NewObject( 365 env, class, constructor, 366 propName, propValue, readOnly, lineage); 367 } 368 } 369 370 return (propertyObject); 371} 372 373static jobject 374create_default_BooleanProperty(JNIEnv *env, zfs_prop_t prop) 375{ 376 return (create_default_BasicProperty(env, prop, NULL, 377 zjni_int_to_boolean, ZFSJNI_PACKAGE_DATA "BooleanProperty", 378 "java/lang/Boolean")); 379} 380 381static jobject 382create_default_LongProperty(JNIEnv *env, zfs_prop_t prop) 383{ 384 return (create_default_BasicProperty(env, prop, NULL, 385 zjni_long_to_Long, ZFSJNI_PACKAGE_DATA "LongProperty", 386 "java/lang/Long")); 387} 388 389static jobject 390create_default_StringProperty(JNIEnv *env, zfs_prop_t prop) 391{ 392 return (create_default_BasicProperty(env, prop, str_to_string, NULL, 393 ZFSJNI_PACKAGE_DATA "StringProperty", "java/lang/String")); 394} 395 396static jobject 397create_default_ObjectProperty(JNIEnv *env, zfs_prop_t prop, 398 str_to_obj_f convert_str, uint64_to_obj_f convert_uint64, 399 char *propClass, char *valueClass) 400{ 401 jobject propertyObject = NULL; 402 403 if (!zfs_prop_readonly(prop)) { 404 jobject propValue; 405 406 if (convert_str != NULL) { 407 char *propbuf = (char *)zfs_prop_default_string(prop); 408 propValue = convert_str(env, propbuf); 409 } else { 410 uint64_t value = zfs_prop_default_numeric(prop); 411 propValue = convert_uint64(env, value); 412 } 413 414 if (propValue != NULL) { 415 char signature[1024]; 416 jmethodID constructor; 417 418 jclass class = (*env)->FindClass(env, propClass); 419 jobject lineage = 420 zjni_int_to_Lineage(env, ZFS_SRC_DEFAULT); 421 422 (void) snprintf(signature, sizeof (signature), 423 "(L%s;L" ZFSJNI_PACKAGE_DATA "Property$Lineage;)V", 424 valueClass); 425 426 constructor = (*env)->GetMethodID( 427 env, class, "<init>", signature); 428 429 propertyObject = (*env)->NewObject( 430 env, class, constructor, propValue, lineage); 431 } 432 } 433 434 return (propertyObject); 435} 436 437static jobject 438str_to_enum_element(JNIEnv *env, char *str, char *valueClass) 439{ 440 char signature[1024]; 441 jmethodID method_valueOf; 442 443 jstring utf = (*env)->NewStringUTF(env, str); 444 jclass class = (*env)->FindClass(env, valueClass); 445 446 (void) snprintf(signature, sizeof (signature), 447 "(Ljava/lang/String;)L%s;", valueClass); 448 449 method_valueOf = (*env)->GetStaticMethodID( 450 env, class, "valueOf", signature); 451 452 return (*env)->CallStaticObjectMethod(env, class, method_valueOf, utf); 453} 454 455static jobject 456str_to_aclinherit(JNIEnv *env, char *str) 457{ 458 return (str_to_enum_element(env, str, 459 ZFSJNI_PACKAGE_DATA "AclInheritProperty$AclInherit")); 460} 461 462static jobject 463str_to_aclmode(JNIEnv *env, char *str) 464{ 465 return (str_to_enum_element(env, str, 466 ZFSJNI_PACKAGE_DATA "AclModeProperty$AclMode")); 467} 468 469static jobject 470str_to_checksum(JNIEnv *env, char *str) 471{ 472 return (str_to_enum_element(env, str, 473 ZFSJNI_PACKAGE_DATA "ChecksumProperty$Checksum")); 474} 475 476static jobject 477str_to_compression(JNIEnv *env, char *str) 478{ 479 return (str_to_enum_element(env, str, 480 ZFSJNI_PACKAGE_DATA "CompressionProperty$Compression")); 481} 482 483static jobject 484str_to_snapdir(JNIEnv *env, char *str) 485{ 486 return (str_to_enum_element(env, str, 487 ZFSJNI_PACKAGE_DATA "SnapDirProperty$SnapDir")); 488} 489 490static jobject 491str_to_string(JNIEnv *env, char *str) 492{ 493 return (*env)->NewStringUTF(env, str); 494} 495 496/* 497 * Package-private functions 498 */ 499 500jobject 501zjni_get_default_property(JNIEnv *env, zfs_prop_t prop) 502{ 503 int i; 504 for (i = 0; props_boolean[i] != ZFS_PROP_INVAL; i++) { 505 if (prop == props_boolean[i]) { 506 return (create_default_BooleanProperty(env, prop)); 507 } 508 } 509 510 for (i = 0; props_long[i] != ZFS_PROP_INVAL; i++) { 511 if (prop == props_long[i]) { 512 return (create_default_LongProperty(env, prop)); 513 } 514 } 515 516 for (i = 0; props_string[i] != ZFS_PROP_INVAL; i++) { 517 if (prop == props_string[i]) { 518 return (create_default_StringProperty(env, prop)); 519 } 520 } 521 522 for (i = 0; props_custom[i].prop != ZFS_PROP_INVAL; i++) { 523 if (prop == props_custom[i].prop) { 524 return create_default_ObjectProperty(env, 525 props_custom[i].prop, props_custom[i].convert_str, 526 props_custom[i].convert_uint64, 527 props_custom[i].propClass, props_custom[i].valueClass); 528 } 529 } 530 531 return (NULL); 532} 533 534zfs_prop_t 535zjni_get_property_from_name(const char *name) 536{ 537 zfs_prop_t prop; 538 for (prop = 0; prop < ZFS_NPROP_VISIBLE; prop++) { 539 if (strcasecmp(name, zfs_prop_to_name(prop)) == 0) { 540 return (prop); 541 } 542 } 543 544 return (ZFS_PROP_INVAL); 545} 546 547jobject 548zjni_int_to_Lineage(JNIEnv *env, zfs_source_t srctype) 549{ 550 /* zfs_source_t to Property$Lineage map */ 551 static zjni_field_mapping_t lineage_map[] = { 552 { ZFS_SRC_NONE, "ZFS_PROP_LINEAGE_NOTINHERITABLE" }, 553 { ZFS_SRC_DEFAULT, "ZFS_PROP_LINEAGE_DEFAULT" }, 554 { ZFS_SRC_LOCAL, "ZFS_PROP_LINEAGE_LOCAL" }, 555 { ZFS_SRC_TEMPORARY, "ZFS_PROP_LINEAGE_TEMPORARY" }, 556 { ZFS_SRC_INHERITED, "ZFS_PROP_LINEAGE_INHERITED" } 557 }; 558 559 return (zjni_int_to_enum(env, srctype, 560 ZFSJNI_PACKAGE_DATA "Property$Lineage", 561 "ZFS_PROP_LINEAGE_INHERITED", lineage_map)); 562} 563 564jobjectArray 565zjni_get_Dataset_properties(JNIEnv *env, zfs_handle_t *zhp) 566{ 567 jobject prop; 568 int i; 569 570 /* Create an array list for the properties */ 571 zjni_ArrayList_t proplist_obj = {0}; 572 zjni_ArrayList_t *proplist = &proplist_obj; 573 zjni_new_ArrayList(env, proplist); 574 575 for (i = 0; props_boolean[i] != ZFS_PROP_INVAL; i++) { 576 /* Create property and add to list */ 577 prop = create_BooleanProperty(env, zhp, props_boolean[i]); 578 579 /* Does this property apply to this object? */ 580 if (prop != NULL) { 581 582 (*env)->CallBooleanMethod( 583 env, ((zjni_Object_t *)proplist)->object, 584 ((zjni_Collection_t *)proplist)->method_add, prop); 585 } else { 586 587 if ((*env)->ExceptionOccurred(env) != NULL) { 588 return (NULL); 589 } 590#ifdef DEBUG 591 (void) fprintf(stderr, "Property %s is not appropriate " 592 "for %s\n", zfs_prop_to_name(props_boolean[i]), 593 zfs_get_name(zhp)); 594#endif 595 } 596 } 597 598 for (i = 0; props_long[i] != ZFS_PROP_INVAL; i++) { 599 /* Create property and add to list */ 600 prop = create_LongProperty(env, zhp, props_long[i]); 601 602 /* Does this property apply to this object? */ 603 if (prop != NULL) { 604 605 (*env)->CallBooleanMethod( 606 env, ((zjni_Object_t *)proplist)->object, 607 ((zjni_Collection_t *)proplist)->method_add, prop); 608 } else { 609 if ((*env)->ExceptionOccurred(env) != NULL) { 610 return (NULL); 611 } 612#ifdef DEBUG 613 (void) fprintf(stderr, "Property %s is not appropriate " 614 "for %s\n", zfs_prop_to_name(props_long[i]), 615 zfs_get_name(zhp)); 616#endif 617 } 618 } 619 620 for (i = 0; props_string[i] != ZFS_PROP_INVAL; i++) { 621 /* Create property and add to list */ 622 prop = create_StringProperty(env, zhp, props_string[i]); 623 624 /* Does this property apply to this object? */ 625 if (prop != NULL) { 626 627 (*env)->CallBooleanMethod( 628 env, ((zjni_Object_t *)proplist)->object, 629 ((zjni_Collection_t *)proplist)->method_add, prop); 630 } else { 631 if ((*env)->ExceptionOccurred(env) != NULL) { 632 return (NULL); 633 } 634#ifdef DEBUG 635 (void) fprintf(stderr, "Property %s is not appropriate " 636 "for %s\n", zfs_prop_to_name(props_string[i]), 637 zfs_get_name(zhp)); 638#endif 639 } 640 } 641 642 for (i = 0; props_custom[i].prop != ZFS_PROP_INVAL; i++) { 643 /* Create property and add to list */ 644 prop = create_ObjectProperty(env, zhp, props_custom[i].prop, 645 props_custom[i].convert_str, props_custom[i].convert_uint64, 646 props_custom[i].propClass, props_custom[i].valueClass); 647 648 /* Does this property apply to this object? */ 649 if (prop != NULL) { 650 651 (*env)->CallBooleanMethod( 652 env, ((zjni_Object_t *)proplist)->object, 653 ((zjni_Collection_t *)proplist)->method_add, prop); 654 } else { 655 if ((*env)->ExceptionOccurred(env) != NULL) { 656 return (NULL); 657 } 658#ifdef DEBUG 659 (void) fprintf(stderr, "Property %s is not appropriate " 660 "for %s\n", zfs_prop_to_name(props_custom[i].prop), 661 zfs_get_name(zhp)); 662#endif 663 } 664 } 665 666 return (zjni_Collection_to_array(env, 667 (zjni_Collection_t *)proplist, ZFSJNI_PACKAGE_DATA "Property")); 668} 669