block/ssh: Make ssh_grow_file() blocking

At runtime (that is, during a future ssh_truncate()), the SSH session is
non-blocking.  However, ssh_truncate() (or rather, bdrv_truncate() in
general) is not a coroutine, so this resize operation needs to block.

For ssh_create(), that is fine, too; the session is never set to
non-blocking anyway.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20180214204915.7980-3-mreitz@redhat.com
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
This commit is contained in:
Max Reitz 2018-02-14 21:49:14 +01:00
parent 2b12a756ac
commit bd8e0e32da

View File

@ -803,17 +803,24 @@ static int ssh_file_open(BlockDriverState *bs, QDict *options, int bdrv_flags,
return ret; return ret;
} }
/* Note: This is a blocking operation */
static int ssh_grow_file(BDRVSSHState *s, int64_t offset, Error **errp) static int ssh_grow_file(BDRVSSHState *s, int64_t offset, Error **errp)
{ {
ssize_t ret; ssize_t ret;
char c[1] = { '\0' }; char c[1] = { '\0' };
int was_blocking = libssh2_session_get_blocking(s->session);
/* offset must be strictly greater than the current size so we do /* offset must be strictly greater than the current size so we do
* not overwrite anything */ * not overwrite anything */
assert(offset > 0 && offset > s->attrs.filesize); assert(offset > 0 && offset > s->attrs.filesize);
libssh2_session_set_blocking(s->session, 1);
libssh2_sftp_seek64(s->sftp_handle, offset - 1); libssh2_sftp_seek64(s->sftp_handle, offset - 1);
ret = libssh2_sftp_write(s->sftp_handle, c, 1); ret = libssh2_sftp_write(s->sftp_handle, c, 1);
libssh2_session_set_blocking(s->session, was_blocking);
if (ret < 0) { if (ret < 0) {
sftp_error_setg(errp, s, "Failed to grow file"); sftp_error_setg(errp, s, "Failed to grow file");
return -EIO; return -EIO;