25
25
* Copyright (c) 2014 RackTop Systems.
26
26
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
27
27
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
28
+ * Copyright 2016, OmniTI Computer Consulting, Inc. All rights reserved.
28
29
*/
29
30
30
31
#include <sys/dmu_objset.h>
@@ -78,6 +79,8 @@ int zfs_max_recordsize = 1 * 1024 * 1024;
78
79
79
80
extern inline dsl_dataset_phys_t * dsl_dataset_phys (dsl_dataset_t * ds );
80
81
82
+ extern int spa_asize_inflation ;
83
+
81
84
/*
82
85
* Figure out how much of this delta should be propogated to the dsl_dir
83
86
* layer. If there's a refreservation, that space has already been
@@ -2810,6 +2813,11 @@ int
2810
2813
dsl_dataset_clone_swap_check_impl (dsl_dataset_t * clone ,
2811
2814
dsl_dataset_t * origin_head , boolean_t force , void * owner , dmu_tx_t * tx )
2812
2815
{
2816
+ /*
2817
+ * "slack" factor for received datasets with refquota set on them.
2818
+ * See the bottom of this function for details on its use.
2819
+ */
2820
+ uint64_t refquota_slack = DMU_MAX_ACCESS * spa_asize_inflation ;
2813
2821
int64_t unused_refres_delta ;
2814
2822
2815
2823
/* they should both be heads */
@@ -2852,10 +2860,22 @@ dsl_dataset_clone_swap_check_impl(dsl_dataset_t *clone,
2852
2860
dsl_dir_space_available (origin_head -> ds_dir , NULL , 0 , TRUE))
2853
2861
return (SET_ERROR (ENOSPC ));
2854
2862
2855
- /* clone can't be over the head's refquota */
2863
+ /*
2864
+ * The clone can't be too much over the head's refquota.
2865
+ *
2866
+ * To ensure that the entire refquota can be used, we allow one
2867
+ * transaction to exceed the the refquota. Therefore, this check
2868
+ * needs to also allow for the space referenced to be more than the
2869
+ * refquota. The maximum amount of space that one transaction can use
2870
+ * on disk is DMU_MAX_ACCESS * spa_asize_inflation. Allowing this
2871
+ * overage ensures that we are able to receive a filesystem that
2872
+ * exceeds the refquota on the source system.
2873
+ *
2874
+ * So that overage is the refquota_slack we use below.
2875
+ */
2856
2876
if (origin_head -> ds_quota != 0 &&
2857
2877
dsl_dataset_phys (clone )-> ds_referenced_bytes >
2858
- origin_head -> ds_quota )
2878
+ origin_head -> ds_quota + refquota_slack )
2859
2879
return (SET_ERROR (EDQUOT ));
2860
2880
2861
2881
return (0 );
@@ -2870,8 +2890,13 @@ dsl_dataset_clone_swap_sync_impl(dsl_dataset_t *clone,
2870
2890
int64_t unused_refres_delta ;
2871
2891
2872
2892
ASSERT (clone -> ds_reserved == 0 );
2893
+ /*
2894
+ * NOTE: On DEBUG kernels there could be a race between this and
2895
+ * the check function if spa_asize_inflation is adjusted...
2896
+ */
2873
2897
ASSERT (origin_head -> ds_quota == 0 ||
2874
- dsl_dataset_phys (clone )-> ds_unique_bytes <= origin_head -> ds_quota );
2898
+ dsl_dataset_phys (clone )-> ds_unique_bytes <= origin_head -> ds_quota +
2899
+ DMU_MAX_ACCESS * spa_asize_inflation );
2875
2900
ASSERT3P (clone -> ds_prev , = = , origin_head -> ds_prev );
2876
2901
2877
2902
/*
0 commit comments