On Mon, 2018-01-22 at 16:14 -0700, Jens Axboe wrote:
> On 1/22/18 3:25 PM, Elliott, Robert (Persistent Memory) wrote:
> > fio engines/sg.c fio_sgio_rw_doio() has that pattern:
> > 
> >     ret = write(f->fd, hdr, sizeof(*hdr));
> >     if (ret < 0)
> >             return ret;
> >     ...
> >     return FIO_Q_QUEUED;   [which is 1]
> > 
> > although there might be special circumstances for the sg interface
> > making that safe.
> 
> That's for SG scsi direct IO, I don't think that supports partial
> IO since it's sending raw SCSI commands.
> 
> For the regular libaio or sync IO system calls, fio of course checks
> and handles short IOs correctly. It even logs if it got any.

The entire fio_sgio_rw_doio() function is as follows:

static int fio_sgio_rw_doio(struct fio_file *f, struct io_u *io_u, int do_sync)
{
        struct sg_io_hdr *hdr = &io_u->hdr;
        int ret;

        ret = write(f->fd, hdr, sizeof(*hdr));
        if (ret < 0)
                return ret;

        if (do_sync) {
                ret = read(f->fd, hdr, sizeof(*hdr));
                if (ret < 0)
                        return ret;

                /* record if an io error occurred */
                if (hdr->info & SG_INFO_CHECK)
                        io_u->error = EIO;

                return FIO_Q_COMPLETED;
        }

        return FIO_Q_QUEUED;
}

I think the 'resid' member of the struct sg_io_hdr that is provided by the
sg_io kernel driver as a response represents the number of bytes that has not
been written. So it should be possible to recognize and handle short I/Os in
that function. From include/scsi/sg.h:

    int resid;                  /* [o] dxfer_len - actual_transferred */

Bart.

Reply via email to