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 (*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);
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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]);
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user