server/connections.c
/* This is called with the request lock held to actually execute the
 * request (by calling the plugin).  Note that the request fields have
 * been validated already in 'validate_request' so we don't have to
 * check them again.  'buf' is either the data to be written or the
 * data to be returned, and points to a buffer of size 'count' bytes.
 *
 * In all cases, the return value is the system errno value that will
 * later be converted to the nbd error to send back to the client (0
 * for success).
 */
This is called with the request lock held to actually execute the
request (by calling the plugin).  Note that the request fields have
been validated already in 'validate_request' so we don't have to
check them again.  'buf' is either the data to be written or the
data to be returned, and points to a buffer of size 'count' bytes.

In all cases, the return value is the system errno value that will
later be converted to the nbd error to send back to the client (0
for success).
This is called with the request lock held to actually execute the request ( by calling the plugin ) . Note that the request fields have been validated already in ' validate_request ' so we don ' t have to check them again . ' buf ' is either the data to be written or the data to be returned and points to a buffer of size ' count ' bytes . In all cases the return value is the system errno value that will later be converted to the nbd error to send back to the client ( 0 for success ) .
static uint32_t
handle_request (struct connection *conn,
                uint16_t cmd, uint16_t flags, uint64_t offset, uint32_t count,
                void *buf)
{
  uint32_t f = 0;
  bool fua = conn->can_fua && (flags & NBD_CMD_FLAG_FUA);
  int err = 0;
  threadlocal_set_error (0);
  switch (cmd) {
  case NBD_CMD_READ:
    if (backend->pread (backend, conn, buf, count, offset, 0, &err) == -1)
      return err;
    break;
  case NBD_CMD_WRITE:
    if (fua)
      f |= NBDKIT_FLAG_FUA;
    if (backend->pwrite (backend, conn, buf, count, offset, f, &err) == -1)
      return err;
    break;
  case NBD_CMD_FLUSH:
    if (backend->flush (backend, conn, 0, &err) == -1)
      return err;
    break;
  case NBD_CMD_TRIM:
    if (fua)
      f |= NBDKIT_FLAG_FUA;
    if (backend->trim (backend, conn, count, offset, f, &err) == -1)
      return err;
    break;
  case NBD_CMD_WRITE_ZEROES:
    if (!(flags & NBD_CMD_FLAG_NO_HOLE))
      f |= NBDKIT_FLAG_MAY_TRIM;
    if (fua)
      f |= NBDKIT_FLAG_FUA;
    if (backend->zero (backend, conn, count, offset, f, &err) == -1)
      return err;
    break;
  default:
    abort ();
  }
  return 0;
}
static uint32_t handle_request ( struct connection * conn , uint16_t cmd , uint16_t flags , uint64_t offset , uint32_t count , void * buf ) { uint32_t f = 0 ; bool fua = conn -> can_fua && ( flags & NBD_CMD_FLAG_FUA ) ; int err = 0 ; threadlocal_set_error ( 0 ) ; switch ( cmd ) { case NBD_CMD_READ : if ( backend -> pread ( backend , conn , buf , count , offset , 0 , & err ) == -1 ) return err ; break ; case NBD_CMD_WRITE : if ( fua ) f |= NBDKIT_FLAG_FUA ; if ( backend -> pwrite ( backend , conn , buf , count , offset , f , & err ) == -1 ) return err ; break ; case NBD_CMD_FLUSH : if ( backend -> flush ( backend , conn , 0 , & err ) == -1 ) return err ; break ; case NBD_CMD_TRIM : if ( fua ) f |= NBDKIT_FLAG_FUA ; if ( backend -> trim ( backend , conn , count , offset , f , & err ) == -1 ) return err ; break ; case NBD_CMD_WRITE_ZEROES : if ( ! ( flags & NBD_CMD_FLAG_NO_HOLE ) ) f |= NBDKIT_FLAG_MAY_TRIM ; if ( fua ) f |= NBDKIT_FLAG_FUA ; if ( backend -> zero ( backend , conn , count , offset , f , & err ) == -1 ) return err ; break ; default : abort ( ) ; } return 0 ; }
This is called with the request lock held to actually execute the
 request (by calling the plugin).
This is called with the request lock held to actually execute the request ( by calling the plugin ) .
/* Clear the error, so that we know if the plugin calls
   * nbdkit_set_error() or relied on errno.  */