Merge remote branch 'jvrao/for-anthony' into staging
This commit is contained in:
commit
2e44928e3c
@ -86,7 +86,7 @@ typedef struct FileOperations
|
|||||||
int (*fstat)(FsContext *, int, struct stat *);
|
int (*fstat)(FsContext *, int, struct stat *);
|
||||||
int (*rename)(FsContext *, const char *, const char *);
|
int (*rename)(FsContext *, const char *, const char *);
|
||||||
int (*truncate)(FsContext *, const char *, off_t);
|
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);
|
int (*statfs)(FsContext *s, const char *path, struct statfs *stbuf);
|
||||||
ssize_t (*lgetxattr)(FsContext *, const char *,
|
ssize_t (*lgetxattr)(FsContext *, const char *,
|
||||||
const char *, void *, size_t);
|
const char *, void *, size_t);
|
||||||
|
@ -552,8 +552,8 @@ void pprint_pdu(V9fsPDU *pdu)
|
|||||||
break;
|
break;
|
||||||
case P9_TLINK:
|
case P9_TLINK:
|
||||||
fprintf(llogfile, "TLINK: (");
|
fprintf(llogfile, "TLINK: (");
|
||||||
pprint_int32(pdu, 0, &offset, "fid");
|
pprint_int32(pdu, 0, &offset, "dfid");
|
||||||
pprint_str(pdu, 0, &offset, ", oldpath");
|
pprint_int32(pdu, 0, &offset, ", fid");
|
||||||
pprint_str(pdu, 0, &offset, ", newpath");
|
pprint_str(pdu, 0, &offset, ", newpath");
|
||||||
break;
|
break;
|
||||||
case P9_RLINK:
|
case P9_RLINK:
|
||||||
|
@ -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,
|
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)
|
static int local_remove(FsContext *ctx, const char *path)
|
||||||
@ -490,9 +490,13 @@ static int local_remove(FsContext *ctx, const char *path)
|
|||||||
return remove(rpath(ctx, 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)
|
static int local_statfs(FsContext *s, const char *path, struct statfs *stbuf)
|
||||||
|
@ -73,6 +73,9 @@ ssize_t v9fs_list_xattr(FsContext *ctx, const char *path,
|
|||||||
|
|
||||||
/* Get the actual len */
|
/* Get the actual len */
|
||||||
xattr_len = llistxattr(rpath(ctx, path), value, 0);
|
xattr_len = llistxattr(rpath(ctx, path), value, 0);
|
||||||
|
if (xattr_len <= 0) {
|
||||||
|
return xattr_len;
|
||||||
|
}
|
||||||
|
|
||||||
/* Now fetch the xattr and find the actual size */
|
/* Now fetch the xattr and find the actual size */
|
||||||
orig_value = qemu_malloc(xattr_len);
|
orig_value = qemu_malloc(xattr_len);
|
||||||
|
@ -248,9 +248,9 @@ static int v9fs_do_remove(V9fsState *s, V9fsString *path)
|
|||||||
return s->ops->remove(&s->ctx, path->data);
|
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)
|
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;
|
int32_t fid;
|
||||||
size_t offset = 7;
|
size_t offset = 7;
|
||||||
V9fsFidState *fidp;
|
V9fsFidState *fidp;
|
||||||
|
int datasync;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
pdu_unmarshal(pdu, offset, "d", &fid);
|
pdu_unmarshal(pdu, offset, "dd", &fid, &datasync);
|
||||||
fidp = lookup_fid(s, fid);
|
fidp = lookup_fid(s, fid);
|
||||||
if (fidp == NULL) {
|
if (fidp == NULL) {
|
||||||
err = -ENOENT;
|
err = -ENOENT;
|
||||||
v9fs_post_do_fsync(s, pdu, err);
|
v9fs_post_do_fsync(s, pdu, err);
|
||||||
return;
|
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);
|
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? */
|
/* do we need to sync the file? */
|
||||||
if (donttouch_stat(&vs->v9stat)) {
|
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);
|
v9fs_wstat_post_fsync(s, vs, err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -107,3 +107,51 @@ int qemu_pipe(int pipefd[2])
|
|||||||
|
|
||||||
return ret;
|
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]);
|
||||||
|
}
|
||||||
|
@ -39,4 +39,16 @@ void os_setup_post(void);
|
|||||||
typedef struct timeval qemu_timeval;
|
typedef struct timeval qemu_timeval;
|
||||||
#define qemu_gettimeofday(tp) gettimeofday(tp, NULL)
|
#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
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user