Author: mav
Date: Mon Mar 21 00:19:42 2016
New Revision: 297113
URL: https://svnweb.freebsd.org/changeset/base/297113

Log:
  MFC r296521: MFV r296520:
  6562 Refquota on receive doesn't account for overage
  
  Reviewed by: Matthew Ahrens <mahr...@delphix.com>
  Reviewed by: Yuri Pankov <yuri.pan...@nexenta.com>
  Reviewed by: Toomas Soome <tso...@me.com>
  Approved by: Gordon Ross <g...@nexenta.com>
  Author: Dan McDonald <dan...@omniti.com>
  
  illumos/illumos-gate@5f7a8e6d750cb070a3347f045201c6206caee6aa

Modified:
  stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
==============================================================================
--- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c      
Mon Mar 21 00:18:38 2016        (r297112)
+++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c      
Mon Mar 21 00:19:42 2016        (r297113)
@@ -26,6 +26,7 @@
  * Copyright (c) 2014 RackTop Systems.
  * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
  * Copyright (c) 2014 Integros [integros.com]
+ * Copyright 2016, OmniTI Computer Consulting, Inc. All rights reserved.
  */
 
 #include <sys/dmu_objset.h>
@@ -85,6 +86,8 @@ SYSCTL_INT(_vfs_zfs, OID_AUTO, max_recor
 
 extern inline dsl_dataset_phys_t *dsl_dataset_phys(dsl_dataset_t *ds);
 
+extern int spa_asize_inflation;
+
 /*
  * Figure out how much of this delta should be propogated to the dsl_dir
  * layer.  If there's a refreservation, that space has already been
@@ -2897,6 +2900,11 @@ int
 dsl_dataset_clone_swap_check_impl(dsl_dataset_t *clone,
     dsl_dataset_t *origin_head, boolean_t force, void *owner, dmu_tx_t *tx)
 {
+       /*
+        * "slack" factor for received datasets with refquota set on them.
+        * See the bottom of this function for details on its use.
+        */
+       uint64_t refquota_slack = DMU_MAX_ACCESS * spa_asize_inflation;
        int64_t unused_refres_delta;
 
        /* they should both be heads */
@@ -2939,10 +2947,22 @@ dsl_dataset_clone_swap_check_impl(dsl_da
            dsl_dir_space_available(origin_head->ds_dir, NULL, 0, TRUE))
                return (SET_ERROR(ENOSPC));
 
-       /* clone can't be over the head's refquota */
+       /*
+        * The clone can't be too much over the head's refquota.
+        *
+        * To ensure that the entire refquota can be used, we allow one
+        * transaction to exceed the the refquota.  Therefore, this check
+        * needs to also allow for the space referenced to be more than the
+        * refquota.  The maximum amount of space that one transaction can use
+        * on disk is DMU_MAX_ACCESS * spa_asize_inflation.  Allowing this
+        * overage ensures that we are able to receive a filesystem that
+        * exceeds the refquota on the source system.
+        *
+        * So that overage is the refquota_slack we use below.
+        */
        if (origin_head->ds_quota != 0 &&
            dsl_dataset_phys(clone)->ds_referenced_bytes >
-           origin_head->ds_quota)
+           origin_head->ds_quota + refquota_slack)
                return (SET_ERROR(EDQUOT));
 
        return (0);
@@ -2956,8 +2976,13 @@ dsl_dataset_clone_swap_sync_impl(dsl_dat
        int64_t unused_refres_delta;
 
        ASSERT(clone->ds_reserved == 0);
+       /*
+        * NOTE: On DEBUG kernels there could be a race between this and
+        * the check function if spa_asize_inflation is adjusted...
+        */
        ASSERT(origin_head->ds_quota == 0 ||
-           dsl_dataset_phys(clone)->ds_unique_bytes <= origin_head->ds_quota);
+           dsl_dataset_phys(clone)->ds_unique_bytes <= origin_head->ds_quota +
+           DMU_MAX_ACCESS * spa_asize_inflation);
        ASSERT3P(clone->ds_prev, ==, origin_head->ds_prev);
 
        /*
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to