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
@ -26,7 +26,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]
|
||||
@ -2259,43 +2259,63 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp)
|
||||
|
||||
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
|
||||
@ -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 &&
|
||||
(!(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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user