Author: mav
Date: Mon Jun  3 17:01:16 2019
New Revision: 348550
URL: https://svnweb.freebsd.org/changeset/base/348550

Log:
  1700 Add SCSI UNMAP support
  
  illumos/illumos-gate@047c81d31d0f571d6652e97143cd15281de61e84
  
  Reviewed by: Jerry Jelinek <jerry.jeli...@joyent.com>
  Reviewed by: Garrett D'Amore <garr...@damore.org>
  Reviewed by: Igor Kozhukhov <i...@dilos.org>
  Approved by: Dan McDonald <dan...@joyent.com>
  Author:     Saso Kiselkov <saso.kisel...@nexenta.com>

Modified:
  vendor-sys/illumos/dist/uts/common/fs/zfs/zvol.c

Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/zvol.c
==============================================================================
--- vendor-sys/illumos/dist/uts/common/fs/zfs/zvol.c    Mon Jun  3 16:59:56 
2019        (r348549)
+++ vendor-sys/illumos/dist/uts/common/fs/zfs/zvol.c    Mon Jun  3 17:01:16 
2019        (r348550)
@@ -23,7 +23,7 @@
  *
  * Portions Copyright 2010 Robert Milkowski
  *
- * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
  * Copyright (c) 2012, 2017 by Delphix. All rights reserved.
  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  * Copyright (c) 2014 Integros [integros.com]
@@ -89,6 +89,7 @@
 #include <sys/zfeature.h>
 #include <sys/zio_checksum.h>
 #include <sys/zil_impl.h>
+#include <sys/dkioc_free_util.h>
 
 #include "zfs_namecheck.h"
 
@@ -1778,44 +1779,64 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag,
 
        case DKIOCFREE:
        {
-               dkioc_free_t df;
+               dkioc_free_list_t *dfl;
                dmu_tx_t *tx;
 
                if (!zvol_unmap_enabled)
                        break;
 
-               if (ddi_copyin((void *)arg, &df, sizeof (df), flag)) {
-                       error = SET_ERROR(EFAULT);
-                       break;
+               if (!(flag & FKIOCTL)) {
+                       error = dfl_copyin((void *)arg, &dfl, flag, KM_SLEEP);
+                       if (error != 0)
+                               break;
+               } else {
+                       dfl = (dkioc_free_list_t *)arg;
+                       ASSERT3U(dfl->dfl_num_exts, <=, DFL_COPYIN_MAX_EXTS);
+                       if (dfl->dfl_num_exts > DFL_COPYIN_MAX_EXTS) {
+                               error = SET_ERROR(EINVAL);
+                               break;
+                       }
                }
 
-               /*
-                * Apply Postel's Law to length-checking.  If they overshoot,
-                * just blank out until the end, if there's a need to blank
-                * out anything.
-                */
-               if (df.df_start >= zv->zv_volsize)
-                       break;  /* No need to do anything... */
-
                mutex_exit(&zfsdev_state_lock);
 
-               rl = zfs_range_lock(&zv->zv_znode, df.df_start, df.df_length,
-                   RL_WRITER);
-               tx = dmu_tx_create(zv->zv_objset);
-               dmu_tx_mark_netfree(tx);
-               error = dmu_tx_assign(tx, TXG_WAIT);
-               if (error != 0) {
-                       dmu_tx_abort(tx);
-               } else {
-                       zvol_log_truncate(zv, tx, df.df_start,
-                           df.df_length, B_TRUE);
-                       dmu_tx_commit(tx);
-                       error = dmu_free_long_range(zv->zv_objset, ZVOL_OBJ,
-                           df.df_start, df.df_length);
-               }
+               for (int i = 0; i < dfl->dfl_num_exts; i++) {
+                       uint64_t start = dfl->dfl_exts[i].dfle_start,
+                           length = dfl->dfl_exts[i].dfle_length,
+                           end = start + length;
 
-               zfs_range_unlock(rl);
+                       /*
+                        * Apply Postel's Law to length-checking.  If they
+                        * overshoot, just blank out until the end, if there's
+                        * a need to blank out anything.
+                        */
+                       if (start >= zv->zv_volsize)
+                               continue;       /* No need to do anything... */
+                       if (end > zv->zv_volsize) {
+                               end = DMU_OBJECT_END;
+                               length = end - start;
+                       }
 
+                       rl = zfs_range_lock(&zv->zv_znode, start, length,
+                           RL_WRITER);
+                       tx = dmu_tx_create(zv->zv_objset);
+                       error = dmu_tx_assign(tx, TXG_WAIT);
+                       if (error != 0) {
+                               dmu_tx_abort(tx);
+                       } else {
+                               zvol_log_truncate(zv, tx, start, length,
+                                   B_TRUE);
+                               dmu_tx_commit(tx);
+                               error = dmu_free_long_range(zv->zv_objset,
+                                   ZVOL_OBJ, start, length);
+                       }
+
+                       zfs_range_unlock(rl);
+
+                       if (error != 0)
+                               break;
+               }
+
                /*
                 * If the write-cache is disabled, 'sync' property
                 * is set to 'always', or if the caller is asking for
@@ -1827,9 +1848,12 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag,
                if ((error == 0) && zvol_unmap_sync_enabled &&
                    (!(zv->zv_flags & ZVOL_WCE) ||
                    (zv->zv_objset->os_sync == ZFS_SYNC_ALWAYS) ||
-                   (df.df_flags & DF_WAIT_SYNC))) {
+                   (dfl->dfl_flags & DF_WAIT_SYNC))) {
                        zil_commit(zv->zv_zilog, ZVOL_OBJ);
                }
+
+               if (!(flag & FKIOCTL))
+                       dfl_free(dfl);
 
                return (error);
        }
_______________________________________________
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