Skip to content

Commit ee8803a

Browse files
authored
vdev_file: make FLUSH and TRIM asynchronous
zfs_file_fsync() and zfs_file_deallocate() are both blocking ops, so the zio_taskq thread is active and blocked both while waiting for the IO call and then while calling zio_execute() for the next stage. This is a particular issue for FLUSH, as the z_flush_iss queue typically only has one thread; multiple flushes arriving at once can cause long delays if the underlying fsync() response is particularly slow. To fix this, we dispatch both FLUSH and TRIM to the z_vdev_file taskq, just as we do for reads and writes. Further, we return all results through zio_interrupt(), so neither the issue nor the file taskqs are blocked. Sponsored-by: Klara, Inc. Sponsored-by: Wasabi Technology, Inc. Reviewed-by: Tony Hutter <[email protected]> Reviewed-by: Alexander Motin <[email protected]> Signed-off-by: Rob Norris <[email protected]> Closes #17064
1 parent 682c5f6 commit ee8803a

File tree

1 file changed

+23
-22
lines changed

1 file changed

+23
-22
lines changed

module/zfs/vdev_file.c

+23-22
Original file line numberDiff line numberDiff line change
@@ -248,11 +248,22 @@ vdev_file_io_fsync(void *arg)
248248
zio_interrupt(zio);
249249
}
250250

251+
static void
252+
vdev_file_io_deallocate(void *arg)
253+
{
254+
zio_t *zio = (zio_t *)arg;
255+
vdev_file_t *vf = zio->io_vd->vdev_tsd;
256+
257+
zio->io_error = zfs_file_deallocate(vf->vf_file,
258+
zio->io_offset, zio->io_size);
259+
260+
zio_interrupt(zio);
261+
}
262+
251263
static void
252264
vdev_file_io_start(zio_t *zio)
253265
{
254266
vdev_t *vd = zio->io_vd;
255-
vdev_file_t *vf = vd->vdev_tsd;
256267

257268
if (zio->io_type == ZIO_TYPE_FLUSH) {
258269
/* XXPOLICY */
@@ -263,33 +274,23 @@ vdev_file_io_start(zio_t *zio)
263274
}
264275

265276
if (zfs_nocacheflush) {
266-
zio_execute(zio);
277+
zio_interrupt(zio);
267278
return;
268279
}
269280

270-
#ifdef __linux__
271-
/*
272-
* We cannot safely call vfs_fsync() when PF_FSTRANS
273-
* is set in the current context. Filesystems like
274-
* XFS include sanity checks to verify it is not
275-
* already set, see xfs_vm_writepage(). Therefore
276-
* the sync must be dispatched to a different context.
277-
*/
278-
if (__spl_pf_fstrans_check()) {
279-
VERIFY3U(taskq_dispatch(vdev_file_taskq,
280-
vdev_file_io_fsync, zio, TQ_SLEEP), !=,
281-
TASKQID_INVALID);
282-
return;
283-
}
284-
#endif
281+
VERIFY3U(taskq_dispatch(vdev_file_taskq,
282+
vdev_file_io_fsync, zio, TQ_SLEEP), !=, TASKQID_INVALID);
285283

286-
vdev_file_io_fsync(zio);
287284
return;
288-
} else if (zio->io_type == ZIO_TYPE_TRIM) {
285+
}
286+
287+
if (zio->io_type == ZIO_TYPE_TRIM) {
289288
ASSERT3U(zio->io_size, !=, 0);
290-
zio->io_error = zfs_file_deallocate(vf->vf_file,
291-
zio->io_offset, zio->io_size);
292-
zio_execute(zio);
289+
290+
VERIFY3U(taskq_dispatch(vdev_file_taskq,
291+
vdev_file_io_deallocate, zio, TQ_SLEEP), !=,
292+
TASKQID_INVALID);
293+
293294
return;
294295
}
295296

0 commit comments

Comments
 (0)