mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-05-30 10:55:27 +00:00
dm: storage: support writethru and writeback mode
In writethru mode, guest storage write are reported completed only when the data has been written to physical storage. In writeback mode, guest storage write are reported completed when data is placed in SOS page cache. Needs to be flushed to the physical storage. USAGE: -s x,virtio-blk,<filepath>,writeback -s x,virtio-blk,<filepath>,writethru The default mode is *writethru* Signed-off-by: Conghui Chen <conghui.chen@intel.com> Reviewed-by: Shuo Liu <shuo.a.liu@intel.com> Acked-by: Yin Fengwei <fengwei.yin@intel.com>
This commit is contained in:
parent
42cabf6965
commit
2592ea8fa4
@ -118,6 +118,9 @@ struct blockif_ctxt {
|
||||
TAILQ_HEAD(, blockif_elem) pendq;
|
||||
TAILQ_HEAD(, blockif_elem) busyq;
|
||||
struct blockif_elem reqs[BLOCKIF_MAXREQ];
|
||||
|
||||
/* write cache enable */
|
||||
uint8_t wce;
|
||||
};
|
||||
|
||||
static pthread_once_t blockif_once = PTHREAD_ONCE_INIT;
|
||||
@ -131,6 +134,20 @@ struct blockif_sig_elem {
|
||||
|
||||
static struct blockif_sig_elem *blockif_bse_head;
|
||||
|
||||
static int
|
||||
blockif_flush_cache(struct blockif_ctxt *bc)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = 0;
|
||||
assert(bc != NULL);
|
||||
if (!bc->wce) {
|
||||
if (fsync(bc->fd))
|
||||
err = errno;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
blockif_enqueue(struct blockif_ctxt *bc, struct blockif_req *breq,
|
||||
enum blockop op)
|
||||
@ -275,8 +292,10 @@ blockif_proc(struct blockif_ctxt *bc, struct blockif_elem *be, uint8_t *buf)
|
||||
br->offset + bc->sub_file_start_lba);
|
||||
if (len < 0)
|
||||
err = errno;
|
||||
else
|
||||
else {
|
||||
br->resid -= len;
|
||||
err = blockif_flush_cache(bc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
i = 0;
|
||||
@ -305,6 +324,8 @@ blockif_proc(struct blockif_ctxt *bc, struct blockif_elem *be, uint8_t *buf)
|
||||
off += len;
|
||||
br->resid -= len;
|
||||
}
|
||||
err = blockif_flush_cache(bc);
|
||||
|
||||
break;
|
||||
case BOP_FLUSH:
|
||||
if (fsync(bc->fd))
|
||||
@ -464,8 +485,8 @@ blockif_open(const char *optstr, const char *ident)
|
||||
struct stat sbuf;
|
||||
/* struct diocgattr_arg arg; */
|
||||
off_t size, psectsz, psectoff;
|
||||
int extra, fd, i, sectsz;
|
||||
int nocache, sync, ro, candelete, geom, ssopt, pssopt;
|
||||
int fd, i, sectsz;
|
||||
int writeback, ro, candelete, geom, ssopt, pssopt;
|
||||
long sz;
|
||||
long long b;
|
||||
int err_code = -1;
|
||||
@ -476,11 +497,12 @@ blockif_open(const char *optstr, const char *ident)
|
||||
|
||||
fd = -1;
|
||||
ssopt = 0;
|
||||
nocache = 0;
|
||||
sync = 0;
|
||||
ro = 0;
|
||||
sub_file_assign = 0;
|
||||
|
||||
/* writethru is on by default */
|
||||
writeback = 0;
|
||||
|
||||
/*
|
||||
* The first element in the optstring is always a pathname.
|
||||
* Optional elements follow
|
||||
@ -494,10 +516,10 @@ blockif_open(const char *optstr, const char *ident)
|
||||
cp = strsep(&xopts, ",");
|
||||
if (cp == nopt) /* file or device pathname */
|
||||
continue;
|
||||
else if (!strcmp(cp, "nocache"))
|
||||
nocache = 1;
|
||||
else if (!strcmp(cp, "sync") || !strcmp(cp, "direct"))
|
||||
sync = 1;
|
||||
else if (!strcmp(cp, "writeback"))
|
||||
writeback = 1;
|
||||
else if (!strcmp(cp, "writethru"))
|
||||
writeback = 0;
|
||||
else if (!strcmp(cp, "ro"))
|
||||
ro = 1;
|
||||
else if (sscanf(cp, "sectorsize=%d/%d", &ssopt, &pssopt) == 2)
|
||||
@ -513,20 +535,17 @@ blockif_open(const char *optstr, const char *ident)
|
||||
}
|
||||
}
|
||||
|
||||
/* enforce a write-through policy by default */
|
||||
nocache = 1;
|
||||
sync = 1;
|
||||
/*
|
||||
* To support "writeback" and "writethru" mode switch during runtime,
|
||||
* O_SYNC is not used directly, as O_SYNC flag cannot dynamic change
|
||||
* after file is opened. Instead, we call fsync() after each write
|
||||
* operation to emulate it.
|
||||
*/
|
||||
|
||||
extra = 0;
|
||||
if (nocache)
|
||||
extra |= O_DIRECT;
|
||||
if (sync)
|
||||
extra |= O_SYNC;
|
||||
|
||||
fd = open(nopt, (ro ? O_RDONLY : O_RDWR) | extra);
|
||||
fd = open(nopt, ro ? O_RDONLY : O_RDWR);
|
||||
if (fd < 0 && !ro) {
|
||||
/* Attempt a r/w fail with a r/o open */
|
||||
fd = open(nopt, O_RDONLY | extra);
|
||||
fd = open(nopt, O_RDONLY);
|
||||
ro = 1;
|
||||
}
|
||||
|
||||
@ -648,6 +667,7 @@ blockif_open(const char *optstr, const char *ident)
|
||||
bc->sectsz = sectsz;
|
||||
bc->psectsz = psectsz;
|
||||
bc->psectoff = psectoff;
|
||||
bc->wce = writeback;
|
||||
pthread_mutex_init(&bc->mtx, NULL);
|
||||
pthread_cond_init(&bc->cond, NULL);
|
||||
TAILQ_INIT(&bc->freeq);
|
||||
|
Loading…
Reference in New Issue
Block a user