summary refs log tree commit diff stats
path: root/hw/9pfs/virtio-9p-local.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/9pfs/virtio-9p-local.c')
-rw-r--r--hw/9pfs/virtio-9p-local.c50
1 files changed, 37 insertions, 13 deletions
diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c
index 7f1c0894de..371a94dfff 100644
--- a/hw/9pfs/virtio-9p-local.c
+++ b/hw/9pfs/virtio-9p-local.c
@@ -366,11 +366,18 @@ out:
     return err;
 }
 
-static int local_fstat(FsContext *fs_ctx,
+static int local_fstat(FsContext *fs_ctx, int fid_type,
                        V9fsFidOpenState *fs, struct stat *stbuf)
 {
-    int err;
-    err = fstat(fs->fd, stbuf);
+    int err, fd;
+
+    if (fid_type == P9_FID_DIR) {
+        fd = dirfd(fs->dir);
+    } else {
+        fd = fs->fd;
+    }
+
+    err = fstat(fd, stbuf);
     if (err) {
         return err;
     }
@@ -381,19 +388,19 @@ static int local_fstat(FsContext *fs_ctx,
         mode_t tmp_mode;
         dev_t tmp_dev;
 
-        if (fgetxattr(fs->fd, "user.virtfs.uid",
+        if (fgetxattr(fd, "user.virtfs.uid",
                       &tmp_uid, sizeof(uid_t)) > 0) {
             stbuf->st_uid = tmp_uid;
         }
-        if (fgetxattr(fs->fd, "user.virtfs.gid",
+        if (fgetxattr(fd, "user.virtfs.gid",
                       &tmp_gid, sizeof(gid_t)) > 0) {
             stbuf->st_gid = tmp_gid;
         }
-        if (fgetxattr(fs->fd, "user.virtfs.mode",
+        if (fgetxattr(fd, "user.virtfs.mode",
                       &tmp_mode, sizeof(mode_t)) > 0) {
             stbuf->st_mode = tmp_mode;
         }
-        if (fgetxattr(fs->fd, "user.virtfs.rdev",
+        if (fgetxattr(fd, "user.virtfs.rdev",
                       &tmp_dev, sizeof(dev_t)) > 0) {
                 stbuf->st_rdev = tmp_dev;
         }
@@ -583,8 +590,7 @@ static int local_utimensat(FsContext *s, V9fsPath *fs_path,
     char buffer[PATH_MAX];
     char *path = fs_path->data;
 
-    return qemu_utimensat(AT_FDCWD, rpath(s, path, buffer), buf,
-                          AT_SYMLINK_NOFOLLOW);
+    return qemu_utimens(rpath(s, path, buffer), buf);
 }
 
 static int local_remove(FsContext *ctx, const char *path)
@@ -593,12 +599,21 @@ static int local_remove(FsContext *ctx, const char *path)
     return remove(rpath(ctx, path, buffer));
 }
 
-static int local_fsync(FsContext *ctx, V9fsFidOpenState *fs, int datasync)
+static int local_fsync(FsContext *ctx, int fid_type,
+                       V9fsFidOpenState *fs, int datasync)
 {
+    int fd;
+
+    if (fid_type == P9_FID_DIR) {
+        fd = dirfd(fs->dir);
+    } else {
+        fd = fs->fd;
+    }
+
     if (datasync) {
-        return qemu_fdatasync(fs->fd);
+        return qemu_fdatasync(fd);
     } else {
-        return fsync(fs->fd);
+        return fsync(fd);
     }
 }
 
@@ -694,6 +709,7 @@ static int local_ioc_getversion(FsContext *ctx, V9fsPath *path,
                                 mode_t st_mode, uint64_t *st_gen)
 {
     int err;
+#ifdef FS_IOC_GETVERSION
     V9fsFidOpenState fid_open;
 
     /*
@@ -709,15 +725,22 @@ static int local_ioc_getversion(FsContext *ctx, V9fsPath *path,
     }
     err = ioctl(fid_open.fd, FS_IOC_GETVERSION, st_gen);
     local_close(ctx, &fid_open);
+#else
+    err = -ENOTTY;
+#endif
     return err;
 }
 
 static int local_init(FsContext *ctx)
 {
-    int err;
+    int err = 0;
     struct statfs stbuf;
 
     ctx->export_flags |= V9FS_PATHNAME_FSCONTEXT;
+#ifdef FS_IOC_GETVERSION
+    /*
+     * use ioc_getversion only if the iocl is definied
+     */
     err = statfs(ctx->fs_root, &stbuf);
     if (!err) {
         switch (stbuf.f_type) {
@@ -729,6 +752,7 @@ static int local_init(FsContext *ctx)
             break;
         }
     }
+#endif
     return err;
 }