Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tools: hv: report ENOSPC errors in hv_fcopy_daemon

Currently some "Unspecified error 0x80004005" is reported on the Windows
side if something fails. Handle the ENOSPC case and return
ERROR_DISK_FULL, which allows at least Copy-VMFile to report a meaning
full error.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Olaf Hering and committed by
Greg Kroah-Hartman
b4ed5d16 3cace4a6

+18 -3
+1
include/uapi/linux/hyperv.h
··· 313 313 #define HV_INVALIDARG 0x80070057 314 314 #define HV_GUID_NOTFOUND 0x80041002 315 315 #define HV_ERROR_ALREADY_EXISTS 0x80070050 316 + #define HV_ERROR_DISK_FULL 0x80070070 316 317 317 318 #define ADDR_FAMILY_NONE 0x00 318 319 #define ADDR_FAMILY_IPV4 0x01
+17 -3
tools/hv/hv_fcopy_daemon.c
··· 37 37 38 38 static int target_fd; 39 39 static char target_fname[W_MAX_PATH]; 40 + static unsigned long long filesize; 40 41 41 42 static int hv_start_fcopy(struct hv_start_fcopy *smsg) 42 43 { 43 44 int error = HV_E_FAIL; 44 45 char *q, *p; 45 46 47 + filesize = 0; 46 48 p = (char *)smsg->path_name; 47 49 snprintf(target_fname, sizeof(target_fname), "%s/%s", 48 50 (char *)smsg->path_name, (char *)smsg->file_name); ··· 100 98 static int hv_copy_data(struct hv_do_fcopy *cpmsg) 101 99 { 102 100 ssize_t bytes_written; 101 + int ret = 0; 103 102 104 103 bytes_written = pwrite(target_fd, cpmsg->data, cpmsg->size, 105 104 cpmsg->offset); 106 105 107 - if (bytes_written != cpmsg->size) 108 - return HV_E_FAIL; 106 + filesize += cpmsg->size; 107 + if (bytes_written != cpmsg->size) { 108 + switch (errno) { 109 + case ENOSPC: 110 + ret = HV_ERROR_DISK_FULL; 111 + break; 112 + default: 113 + ret = HV_E_FAIL; 114 + break; 115 + } 116 + syslog(LOG_ERR, "pwrite failed to write %llu bytes: %ld (%s)", 117 + filesize, (long)bytes_written, strerror(errno)); 118 + } 109 119 110 - return 0; 120 + return ret; 111 121 } 112 122 113 123 static int hv_copy_finished(void)