block: Add bdrv_(p)write_sync
Add new functions that write and flush the written data to disk immediately.
This is what needs to be used for image format metadata to maintain integrity
for cache=... modes that don't use O_DSYNC. (Actually, we only need barriers,
and therefore the functions are defined as such, but flushes is what is
implemented in this patch - we can try to change that later)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit f08145fe16
)
This commit is contained in:
parent
dfe0bb55ee
commit
ceef722d01
39
block.c
39
block.c
|
@ -452,6 +452,8 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
|
||||||
(flags & (BDRV_O_CACHE_MASK|BDRV_O_NATIVE_AIO));
|
(flags & (BDRV_O_CACHE_MASK|BDRV_O_NATIVE_AIO));
|
||||||
else
|
else
|
||||||
open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
|
open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
|
||||||
|
|
||||||
|
bs->open_flags = open_flags;
|
||||||
if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv))
|
if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv))
|
||||||
ret = -ENOTSUP;
|
ret = -ENOTSUP;
|
||||||
else
|
else
|
||||||
|
@ -779,6 +781,43 @@ int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
|
||||||
return count1;
|
return count1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Writes to the file and ensures that no writes are reordered across this
|
||||||
|
* request (acts as a barrier)
|
||||||
|
*
|
||||||
|
* Returns 0 on success, -errno in error cases.
|
||||||
|
*/
|
||||||
|
int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
|
||||||
|
const void *buf, int count)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = bdrv_pwrite(bs, offset, buf, count);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No flush needed for cache=writethrough, it uses O_DSYNC */
|
||||||
|
if ((bs->open_flags & BDRV_O_CACHE_MASK) != 0) {
|
||||||
|
bdrv_flush(bs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Writes to the file and ensures that no writes are reordered across this
|
||||||
|
* request (acts as a barrier)
|
||||||
|
*
|
||||||
|
* Returns 0 on success, -errno in error cases.
|
||||||
|
*/
|
||||||
|
int bdrv_write_sync(BlockDriverState *bs, int64_t sector_num,
|
||||||
|
const uint8_t *buf, int nb_sectors)
|
||||||
|
{
|
||||||
|
return bdrv_pwrite_sync(bs, BDRV_SECTOR_SIZE * sector_num,
|
||||||
|
buf, BDRV_SECTOR_SIZE * nb_sectors);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Truncate file to 'offset' bytes (needed only for file protocols)
|
* Truncate file to 'offset' bytes (needed only for file protocols)
|
||||||
*/
|
*/
|
||||||
|
|
4
block.h
4
block.h
|
@ -77,6 +77,10 @@ int bdrv_pread(BlockDriverState *bs, int64_t offset,
|
||||||
void *buf, int count);
|
void *buf, int count);
|
||||||
int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
|
int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
|
||||||
const void *buf, int count);
|
const void *buf, int count);
|
||||||
|
int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
|
||||||
|
const void *buf, int count);
|
||||||
|
int bdrv_write_sync(BlockDriverState *bs, int64_t sector_num,
|
||||||
|
const uint8_t *buf, int nb_sectors);
|
||||||
int bdrv_truncate(BlockDriverState *bs, int64_t offset);
|
int bdrv_truncate(BlockDriverState *bs, int64_t offset);
|
||||||
int64_t bdrv_getlength(BlockDriverState *bs);
|
int64_t bdrv_getlength(BlockDriverState *bs);
|
||||||
void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
|
void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
|
||||||
|
|
|
@ -127,6 +127,7 @@ struct BlockDriverState {
|
||||||
int64_t total_sectors; /* if we are reading a disk image, give its
|
int64_t total_sectors; /* if we are reading a disk image, give its
|
||||||
size in sectors */
|
size in sectors */
|
||||||
int read_only; /* if true, the media is read only */
|
int read_only; /* if true, the media is read only */
|
||||||
|
int open_flags; /* flags used to open the file, re-used for re-open */
|
||||||
int removable; /* if true, the media can be removed */
|
int removable; /* if true, the media can be removed */
|
||||||
int locked; /* if true, the media cannot temporarily be ejected */
|
int locked; /* if true, the media cannot temporarily be ejected */
|
||||||
int encrypted; /* if true, the media is encrypted */
|
int encrypted; /* if true, the media is encrypted */
|
||||||
|
|
Loading…
Reference in New Issue