]> git.proxmox.com Git - mirror_qemu.git/blobdiff - hw/9pfs/virtio-9p-handle.c
s390x: Migrate guest storage keys (initial memory only)
[mirror_qemu.git] / hw / 9pfs / virtio-9p-handle.c
index 7644ae5ab9ba657568006ade05593ab6e4e65bc4..13eabb98a401d545d38279818839448a509db742 100644 (file)
@@ -11,7 +11,7 @@
  *
  */
 
-#include "hw/virtio.h"
+#include "hw/virtio/virtio.h"
 #include "virtio-9p.h"
 #include "virtio-9p-xattr.h"
 #include <arpa/inet.h>
@@ -19,7 +19,7 @@
 #include <grp.h>
 #include <sys/socket.h>
 #include <sys/un.h>
-#include "qemu-xattr.h"
+#include "qemu/xattr.h"
 #include <unistd.h>
 #include <linux/fs.h>
 #ifdef CONFIG_LINUX_MAGIC_H
@@ -45,7 +45,6 @@ struct handle_data {
     int handle_bytes;
 };
 
-#ifdef CONFIG_OPEN_BY_HANDLE
 static inline int name_to_handle(int dirfd, const char *name,
                                  struct file_handle *fh, int *mnt_id, int flags)
 {
@@ -56,51 +55,19 @@ static inline int open_by_handle(int mountfd, const char *fh, int flags)
 {
     return open_by_handle_at(mountfd, (struct file_handle *)fh, flags);
 }
-#else
-
-struct rpl_file_handle {
-    unsigned int handle_bytes;
-    int handle_type;
-    unsigned char handle[0];
-};
-#define file_handle rpl_file_handle
-
-#ifndef AT_REMOVEDIR
-#define AT_REMOVEDIR    0x200
-#endif
-#ifndef AT_EMPTY_PATH
-#define AT_EMPTY_PATH   0x1000  /* Allow empty relative pathname */
-#endif
-#ifndef O_PATH
-#define O_PATH    010000000
-#endif
-
-static inline int name_to_handle(int dirfd, const char *name,
-                                 struct file_handle *fh, int *mnt_id, int flags)
-{
-    errno = ENOSYS;
-    return -1;
-}
-
-static inline int open_by_handle(int mountfd, const char *fh, int flags)
-{
-    errno = ENOSYS;
-    return -1;
-}
-#endif
 
 static int handle_update_file_cred(int dirfd, const char *name, FsCred *credp)
 {
     int fd, ret;
-    fd = openat(dirfd, name, O_NONBLOCK | O_NOFOLLOW);;
+    fd = openat(dirfd, name, O_NONBLOCK | O_NOFOLLOW);
     if (fd < 0) {
         return fd;
     }
-    ret = fchmod(fd, credp->fc_mode & 07777);
+    ret = fchownat(fd, "", credp->fc_uid, credp->fc_gid, AT_EMPTY_PATH);
     if (ret < 0) {
         goto err_out;
     }
-    ret = fchownat(fd, "", credp->fc_uid, credp->fc_gid, AT_EMPTY_PATH);
+    ret = fchmod(fd, credp->fc_mode & 07777);
 err_out:
     close(fd);
     return ret;
@@ -173,7 +140,7 @@ static int handle_opendir(FsContext *ctx,
 
 static void handle_rewinddir(FsContext *ctx, V9fsFidOpenState *fs)
 {
-    return rewinddir(fs->dir);
+    rewinddir(fs->dir);
 }
 
 static off_t handle_telldir(FsContext *ctx, V9fsFidOpenState *fs)
@@ -190,7 +157,7 @@ static int handle_readdir_r(FsContext *ctx, V9fsFidOpenState *fs,
 
 static void handle_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off)
 {
-    return seekdir(fs->dir, off);
+    seekdir(fs->dir, off);
 }
 
 static ssize_t handle_preadv(FsContext *ctx, V9fsFidOpenState *fs,
@@ -288,10 +255,17 @@ static int handle_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
     return ret;
 }
 
-static int handle_fstat(FsContext *fs_ctx, V9fsFidOpenState *fs,
-                        struct stat *stbuf)
+static int handle_fstat(FsContext *fs_ctx, int fid_type,
+                        V9fsFidOpenState *fs, struct stat *stbuf)
 {
-    return fstat(fs->fd, stbuf);
+    int fd;
+
+    if (fid_type == P9_FID_DIR) {
+        fd = dirfd(fs->dir);
+    } else {
+        fd = fs->fd;
+    }
+    return fstat(fd, stbuf);
 }
 
 static int handle_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
@@ -428,12 +402,21 @@ static int handle_remove(FsContext *ctx, const char *path)
     return -1;
 }
 
-static int handle_fsync(FsContext *ctx, V9fsFidOpenState *fs, int datasync)
+static int handle_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);
     }
 }
 
@@ -515,7 +498,7 @@ static int handle_lremovexattr(FsContext *ctx, V9fsPath *fs_path,
 static int handle_name_to_path(FsContext *ctx, V9fsPath *dir_path,
                               const char *name, V9fsPath *target)
 {
-    char buffer[PATH_MAX];
+    char *buffer;
     struct file_handle *fh;
     int dirfd, ret, mnt_id;
     struct handle_data *data = (struct handle_data *)ctx->private;
@@ -530,15 +513,17 @@ static int handle_name_to_path(FsContext *ctx, V9fsPath *dir_path,
         dirfd = open_by_handle(data->mountfd, dir_path->data, O_PATH);
     } else {
         /* relative to export root */
-        dirfd = open(rpath(ctx, ".", buffer), O_DIRECTORY);
+        buffer = rpath(ctx, ".");
+        dirfd = open(buffer, O_DIRECTORY);
+        g_free(buffer);
     }
     if (dirfd < 0) {
         return dirfd;
     }
     fh = g_malloc(sizeof(struct file_handle) + data->handle_bytes);
     fh->handle_bytes = data->handle_bytes;
-    /* add a "./" at the begining of the path */
-    snprintf(buffer, PATH_MAX, "./%s", name);
+    /* add a "./" at the beginning of the path */
+    buffer = g_strdup_printf("./%s", name);
     /* flag = 0 imply don't follow symlink */
     ret = name_to_handle(dirfd, buffer, fh, &mnt_id, 0);
     if (!ret) {
@@ -548,6 +533,7 @@ static int handle_name_to_path(FsContext *ctx, V9fsPath *dir_path,
         g_free(fh);
     }
     close(dirfd);
+    g_free(buffer);
     return ret;
 }
 
@@ -599,6 +585,7 @@ static int handle_unlinkat(FsContext *ctx, V9fsPath *dir,
 static int handle_ioc_getversion(FsContext *ctx, V9fsPath *path,
                                  mode_t st_mode, uint64_t *st_gen)
 {
+#ifdef FS_IOC_GETVERSION
     int err;
     V9fsFidOpenState fid_open;
 
@@ -607,7 +594,8 @@ static int handle_ioc_getversion(FsContext *ctx, V9fsPath *path,
      * We can get fd for regular files and directories only
      */
     if (!S_ISREG(st_mode) && !S_ISDIR(st_mode)) {
-            return 0;
+        errno = ENOTTY;
+        return -1;
     }
     err = handle_open(ctx, path, O_RDONLY, &fid_open);
     if (err < 0) {
@@ -616,6 +604,10 @@ static int handle_ioc_getversion(FsContext *ctx, V9fsPath *path,
     err = ioctl(fid_open.fd, FS_IOC_GETVERSION, st_gen);
     handle_close(ctx, &fid_open);
     return err;
+#else
+    errno = ENOTTY;
+    return -1;
+#endif
 }
 
 static int handle_init(FsContext *ctx)
@@ -658,7 +650,27 @@ out:
     return ret;
 }
 
+static int handle_parse_opts(QemuOpts *opts, struct FsDriverEntry *fse)
+{
+    const char *sec_model = qemu_opt_get(opts, "security_model");
+    const char *path = qemu_opt_get(opts, "path");
+
+    if (sec_model) {
+        fprintf(stderr, "Invalid argument security_model specified with handle fsdriver\n");
+        return -1;
+    }
+
+    if (!path) {
+        fprintf(stderr, "fsdev: No path specified.\n");
+        return -1;
+    }
+    fse->path = g_strdup(path);
+    return 0;
+
+}
+
 FileOperations handle_ops = {
+    .parse_opts   = handle_parse_opts,
     .init         = handle_init,
     .lstat        = handle_lstat,
     .readlink     = handle_readlink,