From patchwork Wed Mar 3 19:01:14 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [17/17] Implement sync support in 9p server Date: Wed, 03 Mar 2010 09:01:14 -0000 From: Anthony Liguori X-Patchwork-Id: 46864 Message-Id: <1267642874-15001-19-git-send-email-aliguori@us.ibm.com> To: qemu-devel@nongnu.org Cc: "M. Mohan Kumar" , "Aneesh Kumar K.V" From: M. Mohan Kumar When wstat is called with stat field values set to 'don't touch' pattern, 9p Server interprets it as a request to guarantee that the contents of the associated file are committed to stable storage before the Rwstat message is returned. Implement this feature in the server side. Signed-off-by: M. Mohan Kumar Signed-off-by: Aneesh Kumar K.V --- hw/virtio-9p-local.c | 6 ++++++ hw/virtio-9p.c | 34 ++++++++++++++++++++++++++++++++++ hw/virtio-9p.h | 1 + 3 files changed, 41 insertions(+), 0 deletions(-) diff --git a/hw/virtio-9p-local.c b/hw/virtio-9p-local.c index d89a735..4317ea3 100644 --- a/hw/virtio-9p-local.c +++ b/hw/virtio-9p-local.c @@ -249,6 +249,11 @@ static int local_remove(V9fsState *s, const char *path) } +static int local_fsync(V9fsState *s, int fd) +{ + return fsync(fd); +} + static V9fsPosixFileOperations ops = { .lstat = local_lstat, .setuid = local_setuid, @@ -277,6 +282,7 @@ static V9fsPosixFileOperations ops = { .chown = local_chown, .utime = local_utime, .remove = local_remove, + .fsync = local_fsync, }; V9fsPosixFileOperations *virtio_9p_init_local(const char *path) diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c index 8a96645..94c9c58 100644 --- a/hw/virtio-9p.c +++ b/hw/virtio-9p.c @@ -172,6 +172,11 @@ static int posix_remove(V9fsState *s, V9fsString *path) return s->ops->remove(s, path->data); } +static int posix_fsync(V9fsState *s, int fd) +{ + return s->ops->fsync(s, fd); +} + static void v9fs_string_init(V9fsString *str) { str->data = NULL; @@ -1892,6 +1897,29 @@ out: qemu_free(vs); } +static int donttouch_stat(V9fsStat *stat) +{ + if (stat->type == -1 && + stat->dev == -1 && + stat->qid.type == -1 && + stat->qid.version == -1 && + stat->qid.path == -1 && + stat->mode == -1 && + stat->atime == -1 && + stat->mtime == -1 && + stat->length == -1 && + !stat->name.size && + !stat->uid.size && + !stat->gid.size && + !stat->muid.size && + stat->n_uid == -1 && + stat->n_gid == -1 && + stat->n_muid == -1) + return 1; + else + return 0; +} + static void v9fs_wstat(V9fsState *s, V9fsPDU *pdu) { V9fsWstatState *vs; @@ -1909,6 +1937,12 @@ static void v9fs_wstat(V9fsState *s, V9fsPDU *pdu) goto out; } + /* do we need to sync the file? */ + if (donttouch_stat(&vs->v9stat)) { + posix_fsync(s, vs->fidp->fd); + goto out; + } + if (vs->v9stat.mode != -1) { if (vs->v9stat.mode & P9_STAT_MODE_DIR && vs->fidp->dir == NULL) { err = -EIO; diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h index 42ca887..113b0d5 100644 --- a/hw/virtio-9p.h +++ b/hw/virtio-9p.h @@ -182,6 +182,7 @@ typedef struct V9fsPosixFileOpertions int (*fstat)(V9fsState *, int, struct stat *); int (*rename)(V9fsState *, const char *, const char *); int (*truncate)(V9fsState *, const char *, off_t); + int (*fsync)(V9fsState *, int); void *opaque; } V9fsPosixFileOperations;