MFV r348550: 1700 Add SCSI UNMAP support
illumos/illumos-gate@047c81d31d Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com> Reviewed by: Garrett D'Amore <garrett@damore.org> Reviewed by: Igor Kozhukhov <igor@dilos.org> Approved by: Dan McDonald <danmcd@joyent.com> Author: Saso Kiselkov <saso.kiselkov@nexenta.com> This is irrelevant to FreeBSD, just a diff reduction.
This commit is contained in:
commit
bd2ae688a4
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=348562
@ -26,7 +26,7 @@
|
|||||||
*
|
*
|
||||||
* Portions Copyright 2010 Robert Milkowski
|
* 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) 2012, 2017 by Delphix. All rights reserved.
|
||||||
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
|
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
|
||||||
* Copyright (c) 2014 Integros [integros.com]
|
* Copyright (c) 2014 Integros [integros.com]
|
||||||
@ -2259,43 +2259,63 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp)
|
|||||||
|
|
||||||
case DKIOCFREE:
|
case DKIOCFREE:
|
||||||
{
|
{
|
||||||
dkioc_free_t df;
|
dkioc_free_list_t *dfl;
|
||||||
dmu_tx_t *tx;
|
dmu_tx_t *tx;
|
||||||
|
|
||||||
if (!zvol_unmap_enabled)
|
if (!zvol_unmap_enabled)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (ddi_copyin((void *)arg, &df, sizeof (df), flag)) {
|
if (!(flag & FKIOCTL)) {
|
||||||
error = SET_ERROR(EFAULT);
|
error = dfl_copyin((void *)arg, &dfl, flag, KM_SLEEP);
|
||||||
break;
|
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);
|
mutex_exit(&zfsdev_state_lock);
|
||||||
|
|
||||||
rl = zfs_range_lock(&zv->zv_znode, df.df_start, df.df_length,
|
for (int i = 0; i < dfl->dfl_num_exts; i++) {
|
||||||
RL_WRITER);
|
uint64_t start = dfl->dfl_exts[i].dfle_start,
|
||||||
tx = dmu_tx_create(zv->zv_objset);
|
length = dfl->dfl_exts[i].dfle_length,
|
||||||
dmu_tx_mark_netfree(tx);
|
end = start + length;
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
* If the write-cache is disabled, 'sync' property
|
||||||
@ -2308,10 +2328,13 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp)
|
|||||||
if ((error == 0) && zvol_unmap_sync_enabled &&
|
if ((error == 0) && zvol_unmap_sync_enabled &&
|
||||||
(!(zv->zv_flags & ZVOL_WCE) ||
|
(!(zv->zv_flags & ZVOL_WCE) ||
|
||||||
(zv->zv_objset->os_sync == ZFS_SYNC_ALWAYS) ||
|
(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);
|
zil_commit(zv->zv_zilog, ZVOL_OBJ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(flag & FKIOCTL))
|
||||||
|
dfl_free(dfl);
|
||||||
|
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user