geom: Handle partial I/O in g_{read,write,delete}_data()


geom: Handle partial I/O in g_{read,write,delete}_data()

These routines are used internally by GEOM to dispatch I/O requests to a
provider, typically for tasting or for updating GEOM class metadata

These routines assumed that partial I/O did not occur without setting
BIO_ERROR, but this is possible in at least two cases:

  • Some or all of the I/O range is beyond the provider's mediasize. In this scenario g_io_check() truncates the bounds of the request before it is handed to the target provider.
  • A read from vnode-backed md(4) device returns EOF (the backing vnode is allowed to be smaller than the device itself) or partial vnode I/O occurs.

In these scenarios g_read_data() could return a partially uninitialized
buffer. Many consumers are not affected by the first case, since the
offsets used for provider metadata or tasting are relative to the
provider's mediasize, but in some cases metadata is read at fixed
offsets, such as when searching for a UFS superblock using the offsets
defined by SBLOCKSEARCH.

Thus, modify the routines to explicitly check for a non-zero residual
and return EIO in that case. Remove a related check from the
DIOCGDELETE ioctl handler, it is handled within g_delete_data() now.

Reviewed by: mav, imp, kib
Reported by: KMSAN
MFC after: 2 weeks
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D31293


markjAuthored on Jan 20 2022, 1:25 PM
Differential Revision
D31293: geom: Handle truncated I/O in g_*_data()
rG526ddf174ee9: vtnet: Mark MRG_RXBUF headers as initialized before loading fields