Merge remote branch 'jvrao/for-anthony' into staging

This commit is contained in:
Anthony Liguori 2010-12-17 08:22:31 -06:00
commit 2e44928e3c
7 changed files with 80 additions and 12 deletions

View File

@ -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);

View File

@ -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:

View File

@ -482,7 +482,7 @@ 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)
{
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,10 +490,14 @@ 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)
{
if (datasync) {
return qemu_fdatasync(fd);
} else {
return fsync(fd);
}
}
static int local_statfs(FsContext *s, const char *path, struct statfs *stbuf)
{

View File

@ -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);

View File

@ -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;
}

View File

@ -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]);
}

View File

@ -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