41
41
42
42
#define ZPROP_INHERIT_SUFFIX "$inherit"
43
43
#define ZPROP_RECVD_SUFFIX "$recvd"
44
+ #define ZPROP_IUV_SUFFIX "$iuv"
44
45
45
46
static int
46
47
dodefault (zfs_prop_t prop , int intsz , int numints , void * buf )
@@ -81,6 +82,7 @@ dsl_prop_get_dd(dsl_dir_t *dd, const char *propname,
81
82
boolean_t inheriting = B_FALSE ;
82
83
char * inheritstr ;
83
84
char * recvdstr ;
85
+ char * iuvstr ;
84
86
85
87
ASSERT (dsl_pool_config_held (dd -> dd_pool ));
86
88
@@ -91,6 +93,7 @@ dsl_prop_get_dd(dsl_dir_t *dd, const char *propname,
91
93
inheritable = (prop == ZPROP_USERPROP || zfs_prop_inheritable (prop ));
92
94
inheritstr = kmem_asprintf ("%s%s" , propname , ZPROP_INHERIT_SUFFIX );
93
95
recvdstr = kmem_asprintf ("%s%s" , propname , ZPROP_RECVD_SUFFIX );
96
+ iuvstr = kmem_asprintf ("%s%s" , propname , ZPROP_IUV_SUFFIX );
94
97
95
98
/*
96
99
* Note: dd may become NULL, therefore we shouldn't dereference it
@@ -105,6 +108,18 @@ dsl_prop_get_dd(dsl_dir_t *dd, const char *propname,
105
108
inheriting = B_TRUE ;
106
109
}
107
110
111
+ /* Check for a IUV value. */
112
+ err = zap_lookup (mos , dsl_dir_phys (dd )-> dd_props_zapobj ,
113
+ iuvstr , intsz , numints , buf );
114
+ if (!dsl_prop_val_understood (zfs_name_to_prop (propname ),
115
+ * (uint64_t * )buf ))
116
+ err = ENOENT ;
117
+ if (err != ENOENT ) {
118
+ if (setpoint != NULL && err == 0 )
119
+ dsl_dir_name (dd , setpoint );
120
+ break ;
121
+ }
122
+
108
123
/* Check for a local value. */
109
124
err = zap_lookup (mos , dsl_dir_phys (dd )-> dd_props_zapobj ,
110
125
propname , intsz , numints , buf );
@@ -155,6 +170,7 @@ dsl_prop_get_dd(dsl_dir_t *dd, const char *propname,
155
170
156
171
kmem_strfree (inheritstr );
157
172
kmem_strfree (recvdstr );
173
+ kmem_strfree (iuvstr );
158
174
159
175
return (err );
160
176
}
@@ -659,6 +675,7 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname,
659
675
const char * valstr = NULL ;
660
676
char * inheritstr ;
661
677
char * recvdstr ;
678
+ char * iuvstr ;
662
679
char * tbuf = NULL ;
663
680
int err ;
664
681
uint64_t version = spa_version (ds -> ds_dir -> dd_pool -> dp_spa );
@@ -692,6 +709,7 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname,
692
709
693
710
inheritstr = kmem_asprintf ("%s%s" , propname , ZPROP_INHERIT_SUFFIX );
694
711
recvdstr = kmem_asprintf ("%s%s" , propname , ZPROP_RECVD_SUFFIX );
712
+ iuvstr = kmem_asprintf ("%s%s" , propname , ZPROP_IUV_SUFFIX );
695
713
696
714
switch ((int )source ) {
697
715
case ZPROP_SRC_NONE :
@@ -709,11 +727,14 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname,
709
727
/*
710
728
* remove propname$inherit
711
729
* set propname -> value
730
+ * set propname$iuv -> new property value
712
731
*/
713
732
err = zap_remove (mos , zapobj , inheritstr , tx );
714
733
ASSERT (err == 0 || err == ENOENT );
715
734
VERIFY0 (zap_update (mos , zapobj , propname ,
716
735
intsz , numints , value , tx ));
736
+ (void ) dsl_prop_set_iuv (mos , zapobj , propname , intsz ,
737
+ numints , value , tx );
717
738
break ;
718
739
case ZPROP_SRC_INHERITED :
719
740
/*
@@ -763,6 +784,7 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname,
763
784
764
785
kmem_strfree (inheritstr );
765
786
kmem_strfree (recvdstr );
787
+ kmem_strfree (iuvstr );
766
788
767
789
/*
768
790
* If we are left with an empty snap zap we can destroy it.
@@ -860,6 +882,49 @@ dsl_prop_inherit(const char *dsname, const char *propname,
860
882
return (error );
861
883
}
862
884
885
+ boolean_t
886
+ dsl_prop_val_understood (zfs_prop_t prop , uint64_t value )
887
+ {
888
+ const char * str ;
889
+ if (zfs_prop_get_type (prop ) == PROP_TYPE_INDEX ) {
890
+ if (!zfs_prop_index_to_string (prop , value , & str ))
891
+ return 1 ;
892
+ else
893
+ return 0 ;
894
+ } else {
895
+ return 1 ;
896
+ }
897
+ }
898
+
899
+ void
900
+ dsl_prop_set_iuv (objset_t * mos , uint64_t zapobj , const char * propname ,
901
+ int intsz , int numints , const void * value , dmu_tx_t * tx )
902
+ {
903
+ char * iuvstr = kmem_asprintf ("%s%s" , propname , ZPROP_IUV_SUFFIX );
904
+ uint64_t val ;
905
+ int iuv_flag = 0 ;
906
+ zfs_prop_t prop = zfs_name_to_prop (propname );
907
+ switch (prop ) {
908
+ case ZFS_PROP_REDUNDANT_METADATA :
909
+ if (* (uint64_t * )value >= ZFS_REDUNDANT_METADATA_NONE )
910
+ iuv_flag = 1 ;
911
+ break ;
912
+ default :
913
+ break ;
914
+ }
915
+
916
+ if (iuv_flag ) {
917
+ VERIFY0 (zap_update (mos , zapobj , iuvstr , intsz , numints ,
918
+ value , tx ));
919
+ val = zfs_prop_default_numeric (prop );
920
+ VERIFY0 (zap_update (mos , zapobj , propname , intsz , numints ,
921
+ & val , tx ));
922
+ } else if (0 == zap_contains (mos , zapobj , iuvstr )) {
923
+ zap_remove (mos , zapobj , iuvstr , tx );
924
+ }
925
+ kmem_strfree (iuvstr );
926
+ }
927
+
863
928
int
864
929
dsl_props_set_check (void * arg , dmu_tx_t * tx )
865
930
{
@@ -1044,6 +1109,15 @@ dsl_prop_get_all_impl(objset_t *mos, uint64_t propobj,
1044
1109
1045
1110
source = ((flags & DSL_PROP_GET_INHERITING ) ?
1046
1111
setpoint : ZPROP_SOURCE_VAL_RECVD );
1112
+ } else if (strcmp (suffix , ZPROP_IUV_SUFFIX ) == 0 ) {
1113
+ (void ) strncpy (buf , za .za_name , (suffix - za .za_name ));
1114
+ buf [suffix - za .za_name ] = '\0' ;
1115
+ propname = buf ;
1116
+ source = setpoint ;
1117
+ prop = zfs_name_to_prop (propname );
1118
+ if (!dsl_prop_val_understood (prop ,
1119
+ za .za_first_integer ))
1120
+ continue ;
1047
1121
} else {
1048
1122
/*
1049
1123
* For backward compatibility, skip suffixes we don't
@@ -1064,6 +1138,10 @@ dsl_prop_get_all_impl(objset_t *mos, uint64_t propobj,
1064
1138
!zfs_prop_valid_for_type (prop , ZFS_TYPE_SNAPSHOT , B_FALSE ))
1065
1139
continue ;
1066
1140
1141
+ /* We only want propname$iuv for new property values */
1142
+ if (suffix && (strcmp (suffix , ZPROP_IUV_SUFFIX ) == 0 ))
1143
+ nvlist_remove_all (nv , propname );
1144
+
1067
1145
/* Skip properties already defined. */
1068
1146
if (nvlist_exists (nv , propname ))
1069
1147
continue ;
0 commit comments