From 49594973fb38283e8c469892fe5eac2942d9bd25 Mon Sep 17 00:00:00 2001 From: "Venkateswararao Jujjuri (JV)" Date: Fri, 22 Oct 2010 10:08:45 -0700 Subject: [virtio-9p] Add datasync to server side TFSYNC/RFSYNC for dotl SYNOPSIS size[4] Tfsync tag[2] fid[4] datasync[4] size[4] Rfsync tag[2] DESCRIPTION The Tfsync transaction transfers ("flushes") all modified in-core data of file identified by fid to the disk device (or other permanent storage device) where that file resides. If datasync flag is specified data will be fleshed but does not flush modified metadata unless that metadata is needed in order to allow a subsequent data retrieval to be correctly handled. Signed-off-by: Venkateswararao Jujjuri --- hw/file-op-9p.h | 2 +- hw/virtio-9p-local.c | 8 ++++++-- hw/virtio-9p.c | 11 ++++++----- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/hw/file-op-9p.h b/hw/file-op-9p.h index 21d60b5..c7731c2 100644 --- a/hw/file-op-9p.h +++ b/hw/file-op-9p.h @@ -86,7 +86,7 @@ typedef struct FileOperations int (*fstat)(FsContext *, int, struct stat *); int (*rename)(FsContext *, const char *, const char *); int (*truncate)(FsContext *, const char *, off_t); - int (*fsync)(FsContext *, int); + int (*fsync)(FsContext *, int, int); int (*statfs)(FsContext *s, const char *path, struct statfs *stbuf); ssize_t (*lgetxattr)(FsContext *, const char *, const char *, void *, size_t); diff --git a/hw/virtio-9p-local.c b/hw/virtio-9p-local.c index 0d52020..656bfb3 100644 --- a/hw/virtio-9p-local.c +++ b/hw/virtio-9p-local.c @@ -490,9 +490,13 @@ static int local_remove(FsContext *ctx, const char *path) return remove(rpath(ctx, path)); } -static int local_fsync(FsContext *ctx, int fd) +static int local_fsync(FsContext *ctx, int fd, int datasync) { - return fsync(fd); + if (datasync) { + return qemu_fdatasync(fd); + } else { + return fsync(fd); + } } static int local_statfs(FsContext *s, const char *path, struct statfs *stbuf) diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c index daade77..7c59988 100644 --- a/hw/virtio-9p.c +++ b/hw/virtio-9p.c @@ -248,9 +248,9 @@ static int v9fs_do_remove(V9fsState *s, V9fsString *path) return s->ops->remove(&s->ctx, path->data); } -static int v9fs_do_fsync(V9fsState *s, int fd) +static int v9fs_do_fsync(V9fsState *s, int fd, int datasync) { - return s->ops->fsync(&s->ctx, fd); + return s->ops->fsync(&s->ctx, fd, datasync); } static int v9fs_do_statfs(V9fsState *s, V9fsString *path, struct statfs *stbuf) @@ -1868,16 +1868,17 @@ static void v9fs_fsync(V9fsState *s, V9fsPDU *pdu) int32_t fid; size_t offset = 7; V9fsFidState *fidp; + int datasync; int err; - pdu_unmarshal(pdu, offset, "d", &fid); + pdu_unmarshal(pdu, offset, "dd", &fid, &datasync); fidp = lookup_fid(s, fid); if (fidp == NULL) { err = -ENOENT; v9fs_post_do_fsync(s, pdu, err); return; } - err = v9fs_do_fsync(s, fidp->fs.fd); + err = v9fs_do_fsync(s, fidp->fs.fd, datasync); v9fs_post_do_fsync(s, pdu, err); } @@ -3001,7 +3002,7 @@ static void v9fs_wstat(V9fsState *s, V9fsPDU *pdu) /* do we need to sync the file? */ if (donttouch_stat(&vs->v9stat)) { - err = v9fs_do_fsync(s, vs->fidp->fs.fd); + err = v9fs_do_fsync(s, vs->fidp->fs.fd, 0); v9fs_wstat_post_fsync(s, vs, err); return; } -- cgit v1.1 From d04e2826f5509092c8f0c6c3db7fa3232d912f7e Mon Sep 17 00:00:00 2001 From: Harsh Prateek Bora Date: Sun, 24 Oct 2010 20:54:26 +0530 Subject: hw/virtio9p: Use appropriate debug print functions in TLINK path Running fsstress with debug enabled causes assertion failure because of inappropriate usage of debug print functions. With this patch, fsstress passes without assertion failure. Signed-off-by: Harsh Prateek Bora Signed-off-by: Venkateswararao Jujjuri --- hw/virtio-9p-debug.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/virtio-9p-debug.c b/hw/virtio-9p-debug.c index cff5b07..6b18842 100644 --- a/hw/virtio-9p-debug.c +++ b/hw/virtio-9p-debug.c @@ -552,8 +552,8 @@ void pprint_pdu(V9fsPDU *pdu) break; case P9_TLINK: fprintf(llogfile, "TLINK: ("); - pprint_int32(pdu, 0, &offset, "fid"); - pprint_str(pdu, 0, &offset, ", oldpath"); + pprint_int32(pdu, 0, &offset, "dfid"); + pprint_int32(pdu, 0, &offset, ", fid"); pprint_str(pdu, 0, &offset, ", newpath"); break; case P9_RLINK: -- cgit v1.1 From 0562c67432991d1cee442615d70fd39e638bec71 Mon Sep 17 00:00:00 2001 From: Kusanagi Kouichi Date: Sat, 30 Oct 2010 11:52:39 +0900 Subject: virtio-9p: Check the return value of llistxattr. If llistxattr returned 0, qemu aborts. Signed-off-by: Kusanagi Kouichi Signed-off-by: Venkateswararao Jujjuri --- hw/virtio-9p-xattr.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hw/virtio-9p-xattr.c b/hw/virtio-9p-xattr.c index 175f372..1aab081 100644 --- a/hw/virtio-9p-xattr.c +++ b/hw/virtio-9p-xattr.c @@ -73,6 +73,9 @@ ssize_t v9fs_list_xattr(FsContext *ctx, const char *path, /* Get the actual len */ xattr_len = llistxattr(rpath(ctx, path), value, 0); + if (xattr_len <= 0) { + return xattr_len; + } /* Now fetch the xattr and find the actual size */ orig_value = qemu_malloc(xattr_len); -- cgit v1.1 From 38671423466875ecd848710cc1d7019448a6b145 Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Wed, 24 Nov 2010 11:38:10 +0900 Subject: virtio-9p: fix build on !CONFIG_UTIMENSAT This patch introduce a fallback mechanism for old systems that do not support utimensat(). This fix build failure with following warnings: hw/virtio-9p-local.c: In function 'local_utimensat': hw/virtio-9p-local.c:479: warning: implicit declaration of function 'utimensat' hw/virtio-9p-local.c:479: warning: nested extern declaration of 'utimensat' and: hw/virtio-9p.c: In function 'v9fs_setattr_post_chmod': hw/virtio-9p.c:1410: error: 'UTIME_NOW' undeclared (first use in this function) hw/virtio-9p.c:1410: error: (Each undeclared identifier is reported only once hw/virtio-9p.c:1410: error: for each function it appears in.) hw/virtio-9p.c:1413: error: 'UTIME_OMIT' undeclared (first use in this function) hw/virtio-9p.c: In function 'v9fs_wstat_post_chmod': hw/virtio-9p.c:2905: error: 'UTIME_OMIT' undeclared (first use in this function) [NOTE: At this time virtio-9p is only user of utimensat(), and is available only when host is linux and CONFIG_VIRTFS is defined. So there are no similar warning for win32. Please provide a wrapper for win32 in oslib-win32.c if new user really requires it.] v5: - Allow fallback on runtime - Move qemu_utimensat() to oslib-posix.c - Rebased on latest qemu.git v4: - Use tv_now.tv_usec v3: - Use better alternative handling for UTIME_NOW/OMIT - Move qemu_utimensat() to cutils.c V2: - Introduce qemu_utimensat() Acked-by: Chris Wright Acked-by: M. Mohan Kumar Acked-by: Jes Sorensen Signed-off-by: Hidetoshi Seto Signed-off-by: Venkateswararao Jujjuri --- hw/virtio-9p-local.c | 4 ++-- oslib-posix.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ qemu-os-posix.h | 12 ++++++++++++ 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/hw/virtio-9p-local.c b/hw/virtio-9p-local.c index 656bfb3..a8e7525 100644 --- a/hw/virtio-9p-local.c +++ b/hw/virtio-9p-local.c @@ -480,9 +480,9 @@ static int local_chown(FsContext *fs_ctx, const char *path, FsCred *credp) } static int local_utimensat(FsContext *s, const char *path, - const struct timespec *buf) + const struct timespec *buf) { - return utimensat(AT_FDCWD, rpath(s, path), buf, AT_SYMLINK_NOFOLLOW); + return qemu_utimensat(AT_FDCWD, rpath(s, path), buf, AT_SYMLINK_NOFOLLOW); } static int local_remove(FsContext *ctx, const char *path) diff --git a/oslib-posix.c b/oslib-posix.c index 6e9b0c3..7bc5f7c 100644 --- a/oslib-posix.c +++ b/oslib-posix.c @@ -107,3 +107,51 @@ int qemu_pipe(int pipefd[2]) return ret; } + +int qemu_utimensat(int dirfd, const char *path, const struct timespec *times, + int flags) +{ + struct timeval tv[2], tv_now; + struct stat st; + int i; +#ifdef CONFIG_UTIMENSAT + int ret; + + ret = utimensat(dirfd, path, times, flags); + if (ret != -1 || errno != ENOSYS) { + return ret; + } +#endif + /* Fallback: use utimes() instead of utimensat() */ + + /* happy if special cases */ + if (times[0].tv_nsec == UTIME_OMIT && times[1].tv_nsec == UTIME_OMIT) { + return 0; + } + if (times[0].tv_nsec == UTIME_NOW && times[1].tv_nsec == UTIME_NOW) { + return utimes(path, NULL); + } + + /* prepare for hard cases */ + if (times[0].tv_nsec == UTIME_NOW || times[1].tv_nsec == UTIME_NOW) { + gettimeofday(&tv_now, NULL); + } + if (times[0].tv_nsec == UTIME_OMIT || times[1].tv_nsec == UTIME_OMIT) { + stat(path, &st); + } + + for (i = 0; i < 2; i++) { + if (times[i].tv_nsec == UTIME_NOW) { + tv[i].tv_sec = tv_now.tv_sec; + tv[i].tv_usec = tv_now.tv_usec; + } else if (times[i].tv_nsec == UTIME_OMIT) { + tv[i].tv_sec = (i == 0) ? st.st_atime : st.st_mtime; + tv[i].tv_usec = 0; + } else { + tv[i].tv_sec = times[i].tv_sec; + tv[i].tv_usec = times[i].tv_nsec / 1000; + } + } + + return utimes(path, &tv[0]); +} diff --git a/qemu-os-posix.h b/qemu-os-posix.h index 353f878..81fd9ab 100644 --- a/qemu-os-posix.h +++ b/qemu-os-posix.h @@ -39,4 +39,16 @@ void os_setup_post(void); typedef struct timeval qemu_timeval; #define qemu_gettimeofday(tp) gettimeofday(tp, NULL) +#ifndef CONFIG_UTIMENSAT +#ifndef UTIME_NOW +# define UTIME_NOW ((1l << 30) - 1l) +#endif +#ifndef UTIME_OMIT +# define UTIME_OMIT ((1l << 30) - 2l) +#endif +#endif +typedef struct timespec qemu_timespec; +int qemu_utimensat(int dirfd, const char *path, const qemu_timespec *times, + int flags); + #endif -- cgit v1.1