@@ -61,6 +61,8 @@ typedef struct BlockDevOps {
#define BDRV_O_NATIVE_AIO 0x0080 /* use native AIO instead of the thread pool */
#define BDRV_O_NO_BACKING 0x0100 /* don't open the backing file */
#define BDRV_O_NO_FLUSH 0x0200 /* disable flushing on this disk */
+#define BDRV_O_INVALIDATE 0x0400 /* invalidate buffer cache for this device.
+ re-read things from server */
#define BDRV_O_CACHE_MASK (BDRV_O_NOCACHE | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH)
@@ -52,6 +52,7 @@
#include <sys/param.h>
#include <linux/cdrom.h>
#include <linux/fd.h>
+#include <linux/fs.h>
#endif
#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
#include <sys/disk.h>
@@ -218,6 +219,29 @@ static int raw_open_common(BlockDriverState *bs, const char *filename,
s->fd = fd;
s->aligned_buf = NULL;
+#ifdef __linux__
+ if ((bdrv_flags & BDRV_O_INVALIDATE)) {
+ struct stat buf;
+ int res;
+
+ res = fstat(fd, &buf);
+
+ if (res < 0) {
+ return -errno;
+ }
+
+ if (S_ISBLK(buf.st_mode)) {
+ printf("we are in a block device: %s\n", filename);
+ res = ioctl(fd, BLKFLSBUF, 0);
+ if (res < 0) {
+ fprintf(stderr, "qemu: buffer invalidation of %s"
+ " failed with error %d\n", filename, errno);
+ return -errno;
+ }
+ }
+ }
+#endif /* __linux__ */
+
if ((bdrv_flags & BDRV_O_NOCACHE)) {
/*
* Allocate a buffer for read/modify/write cycles. Chose the size
@@ -217,10 +217,10 @@ static int parse_block_error_action(const char *buf, int is_read)
}
}
-static int drive_open(DriveInfo *dinfo)
+static int drive_open(DriveInfo *dinfo, int extra_flags)
{
int res = bdrv_open(dinfo->bdrv, dinfo->file,
- dinfo->bdrv_flags, dinfo->drv);
+ dinfo->bdrv_flags | extra_flags, dinfo->drv);
if (res < 0) {
fprintf(stderr, "qemu: could not open disk image %s: %s\n",
@@ -237,7 +237,7 @@ int drives_reinit(void)
if (dinfo->opened && !bdrv_is_read_only(dinfo->bdrv)) {
int res;
bdrv_close(dinfo->bdrv);
- res = drive_open(dinfo);
+ res = drive_open(dinfo, BDRV_O_INVALIDATE);
if (res) {
fprintf(stderr, "qemu: re-open of %s failed with error %d\n",
dinfo->file, res);
@@ -550,7 +550,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
dinfo->drv = drv;
dinfo->opened = 1;
- if (drive_open(dinfo) < 0) {
+ if (drive_open(dinfo, 0) < 0) {
goto err;
}
Linux allows to invalidate block devices. This is needed for the incoming migration part. Signed-off-by: Juan Quintela <quintela@redhat.com> --- block.h | 2 ++ block/raw-posix.c | 24 ++++++++++++++++++++++++ blockdev.c | 8 ++++---- 3 files changed, 30 insertions(+), 4 deletions(-)