qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PULL 20/28] 9pfs: local: improve error handling in link op


From: Greg Kurz
Subject: [Qemu-devel] [PULL 20/28] 9pfs: local: improve error handling in link op
Date: Tue, 28 Feb 2017 11:30:32 +0100

When using the mapped-file security model, we also have to create a link
for the metadata file if it exists. In case of failure, we should rollback.

That's what this patch does.

Signed-off-by: Greg Kurz <address@hidden>
Reviewed-by: Stefan Hajnoczi <address@hidden>
---
 hw/9pfs/9p-local.c | 32 +++++++++++++++++++++-----------
 1 file changed, 21 insertions(+), 11 deletions(-)

diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
index 77f79b60aefa..2538bd317d7e 100644
--- a/hw/9pfs/9p-local.c
+++ b/hw/9pfs/9p-local.c
@@ -920,6 +920,7 @@ static int local_link(FsContext *ctx, V9fsPath *oldpath,
     int ret;
     V9fsString newpath;
     char *buffer, *buffer1;
+    int serrno;
 
     v9fs_string_init(&newpath);
     v9fs_string_sprintf(&newpath, "%s/%s", dirpath->data, name);
@@ -928,25 +929,36 @@ static int local_link(FsContext *ctx, V9fsPath *oldpath,
     buffer1 = rpath(ctx, newpath.data);
     ret = link(buffer, buffer1);
     g_free(buffer);
-    g_free(buffer1);
+    if (ret < 0) {
+        goto out;
+    }
 
     /* now link the virtfs_metadata files */
-    if (!ret && (ctx->export_flags & V9FS_SM_MAPPED_FILE)) {
+    if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
+        char *vbuffer, *vbuffer1;
+
         /* Link the .virtfs_metadata files. Create the metada directory */
         ret = local_create_mapped_attr_dir(ctx, newpath.data);
         if (ret < 0) {
             goto err_out;
         }
-        buffer = local_mapped_attr_path(ctx, oldpath->data);
-        buffer1 = local_mapped_attr_path(ctx, newpath.data);
-        ret = link(buffer, buffer1);
-        g_free(buffer);
-        g_free(buffer1);
+        vbuffer = local_mapped_attr_path(ctx, oldpath->data);
+        vbuffer1 = local_mapped_attr_path(ctx, newpath.data);
+        ret = link(vbuffer, vbuffer1);
+        g_free(vbuffer);
+        g_free(vbuffer1);
         if (ret < 0 && errno != ENOENT) {
             goto err_out;
         }
     }
+    goto out;
+
 err_out:
+    serrno = errno;
+    remove(buffer1);
+    errno = serrno;
+out:
+    g_free(buffer1);
     v9fs_string_free(&newpath);
     return ret;
 }
@@ -1189,14 +1201,12 @@ static int local_renameat(FsContext *ctx, V9fsPath 
*olddir,
             goto err_undo_rename;
         }
 
-        omap_dirfd = openat(odirfd, VIRTFS_META_DIR,
-                            O_RDONLY | O_DIRECTORY | O_NOFOLLOW);
+        omap_dirfd = openat_dir(odirfd, VIRTFS_META_DIR);
         if (omap_dirfd == -1) {
             goto err;
         }
 
-        nmap_dirfd = openat(ndirfd, VIRTFS_META_DIR,
-                            O_RDONLY | O_DIRECTORY | O_NOFOLLOW);
+        nmap_dirfd = openat_dir(ndirfd, VIRTFS_META_DIR);
         if (nmap_dirfd == -1) {
             close_preserve_errno(omap_dirfd);
             goto err;
-- 
2.7.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]