When using the mapped-file security model, we also have to rename the metadata file if it exists. In case of failure, we should rollback.
To achieve that, this patch moves the renaming of the main file before the renaming of the metadata file. Signed-off-by: Greg Kurz <[email protected]> --- hw/9pfs/9p-local.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c index ebc3e208efa0..df453414c902 100644 --- a/hw/9pfs/9p-local.c +++ b/hw/9pfs/9p-local.c @@ -1192,26 +1192,39 @@ static int local_rename(FsContext *ctx, const char *oldpath, { int err; char *buffer, *buffer1; + int serrno; + + buffer = rpath(ctx, oldpath); + buffer1 = rpath(ctx, newpath); + err = rename(buffer, buffer1); + if (err < 0) { + goto out; + } if (ctx->export_flags & V9FS_SM_MAPPED_FILE) { + char *vbuffer, *vbuffer1; + err = local_create_mapped_attr_dir(ctx, newpath); if (err < 0) { - return err; + goto out_err; } /* rename the .virtfs_metadata files */ - buffer = local_mapped_attr_path(ctx, oldpath); - buffer1 = local_mapped_attr_path(ctx, newpath); - err = rename(buffer, buffer1); - g_free(buffer); - g_free(buffer1); + vbuffer = local_mapped_attr_path(ctx, oldpath); + vbuffer1 = local_mapped_attr_path(ctx, newpath); + err = rename(vbuffer, vbuffer1); + g_free(vbuffer); + g_free(vbuffer1); if (err < 0 && errno != ENOENT) { - return err; + goto err_out; } } + goto out; - buffer = rpath(ctx, oldpath); - buffer1 = rpath(ctx, newpath); - err = rename(buffer, buffer1); +err_out: + serrno = errno; + rename(buffer1, buffer); + errno = serrno; +out: g_free(buffer); g_free(buffer1); return err;
