From patchwork Tue Dec 6 16:20:56 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: RFC: raw device support for block device targets From: Alex Bligh X-Patchwork-Id: 129726 Message-Id: <958CDBC95A3252B592B5E3C9@nimrod.local> To: qemu-devel@nongnu.org Cc: Alex Bligh Date: Tue, 06 Dec 2011 16:20:56 +0000 qemu-img convert appears to support block devices as input, but not as output. That is irritating, as when using qemu-img convert to convert qcow to raw on a block partition, an intermediate file has to be used, which slows things down and pointlessly uses disk space. The problem is that ftruncate() is being called on the output file in order ensure it is sufficiently large, and this fails on block devices. I appreciate there may be other calls that fail depending on the input file format, but these will presumably be error checked at the time. Is it therefore worth skipping the ftruncate() if the block device is large enough, and at least attempting to proceed further? Something like the following (not-even compile tested) patch? diff --git a/block/raw-posix.c b/block/raw-posix.c index 2ee5d69..be9a371 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -573,9 +573,29 @@ static int raw_create(const char *filename, QEMUOptionParameter *options) if (fd < 0) { result = -errno; } else { + + struct stat sb; + + if (-1 == fstat(dest, &sb)) { + result = -errno; + goto close; + } + + /* block devices do not support truncate. If the device is large + enough, then it will do */ + + if (S_ISBLK(sb.st_mode)) { + /* divide to prevent overflow */ + if (sb.st_size / BDRV_SECTOR_SIZE < total_size) + result = -ENOSPC; + goto close; + } + if (ftruncate(fd, total_size * BDRV_SECTOR_SIZE) != 0) { result = -errno; } + + close: if (close(fd) != 0) { result = -errno;