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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user