|
@@ -42,18 +42,18 @@
|
|
|
|
|
|
#define VIRTFS_META_DIR ".virtfs_metadata"
|
|
|
|
|
|
-static const char *local_mapped_attr_path(FsContext *ctx,
|
|
|
- const char *path, char *buffer)
|
|
|
+static char *local_mapped_attr_path(FsContext *ctx, const char *path)
|
|
|
{
|
|
|
char *dir_name;
|
|
|
char *tmp_path = g_strdup(path);
|
|
|
char *base_name = basename(tmp_path);
|
|
|
+ char *buffer;
|
|
|
|
|
|
/* NULL terminate the directory */
|
|
|
dir_name = tmp_path;
|
|
|
*(base_name - 1) = '\0';
|
|
|
|
|
|
- snprintf(buffer, PATH_MAX, "%s/%s/%s/%s",
|
|
|
+ buffer = g_strdup_printf("%s/%s/%s/%s",
|
|
|
ctx->fs_root, dir_name, VIRTFS_META_DIR, base_name);
|
|
|
g_free(tmp_path);
|
|
|
return buffer;
|
|
@@ -92,10 +92,11 @@ static void local_mapped_file_attr(FsContext *ctx, const char *path,
|
|
|
{
|
|
|
FILE *fp;
|
|
|
char buf[ATTR_MAX];
|
|
|
- char attr_path[PATH_MAX];
|
|
|
+ char *attr_path;
|
|
|
|
|
|
- local_mapped_attr_path(ctx, path, attr_path);
|
|
|
+ attr_path = local_mapped_attr_path(ctx, path);
|
|
|
fp = local_fopen(attr_path, "r");
|
|
|
+ g_free(attr_path);
|
|
|
if (!fp) {
|
|
|
return;
|
|
|
}
|
|
@@ -118,12 +119,13 @@ static void local_mapped_file_attr(FsContext *ctx, const char *path,
|
|
|
static int local_lstat(FsContext *fs_ctx, V9fsPath *fs_path, struct stat *stbuf)
|
|
|
{
|
|
|
int err;
|
|
|
- char buffer[PATH_MAX];
|
|
|
+ char *buffer;
|
|
|
char *path = fs_path->data;
|
|
|
|
|
|
- err = lstat(rpath(fs_ctx, path, buffer), stbuf);
|
|
|
+ buffer = rpath(fs_ctx, path);
|
|
|
+ err = lstat(buffer, stbuf);
|
|
|
if (err) {
|
|
|
- return err;
|
|
|
+ goto err_out;
|
|
|
}
|
|
|
if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
|
|
|
/* Actual credentials are part of extended attrs */
|
|
@@ -131,41 +133,42 @@ static int local_lstat(FsContext *fs_ctx, V9fsPath *fs_path, struct stat *stbuf)
|
|
|
gid_t tmp_gid;
|
|
|
mode_t tmp_mode;
|
|
|
dev_t tmp_dev;
|
|
|
- if (getxattr(rpath(fs_ctx, path, buffer), "user.virtfs.uid", &tmp_uid,
|
|
|
- sizeof(uid_t)) > 0) {
|
|
|
+ if (getxattr(buffer, "user.virtfs.uid", &tmp_uid, sizeof(uid_t)) > 0) {
|
|
|
stbuf->st_uid = tmp_uid;
|
|
|
}
|
|
|
- if (getxattr(rpath(fs_ctx, path, buffer), "user.virtfs.gid", &tmp_gid,
|
|
|
- sizeof(gid_t)) > 0) {
|
|
|
+ if (getxattr(buffer, "user.virtfs.gid", &tmp_gid, sizeof(gid_t)) > 0) {
|
|
|
stbuf->st_gid = tmp_gid;
|
|
|
}
|
|
|
- if (getxattr(rpath(fs_ctx, path, buffer), "user.virtfs.mode",
|
|
|
+ if (getxattr(buffer, "user.virtfs.mode",
|
|
|
&tmp_mode, sizeof(mode_t)) > 0) {
|
|
|
stbuf->st_mode = tmp_mode;
|
|
|
}
|
|
|
- if (getxattr(rpath(fs_ctx, path, buffer), "user.virtfs.rdev", &tmp_dev,
|
|
|
- sizeof(dev_t)) > 0) {
|
|
|
+ if (getxattr(buffer, "user.virtfs.rdev", &tmp_dev, sizeof(dev_t)) > 0) {
|
|
|
stbuf->st_rdev = tmp_dev;
|
|
|
}
|
|
|
} else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
|
|
|
local_mapped_file_attr(fs_ctx, path, stbuf);
|
|
|
}
|
|
|
+
|
|
|
+err_out:
|
|
|
+ g_free(buffer);
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
static int local_create_mapped_attr_dir(FsContext *ctx, const char *path)
|
|
|
{
|
|
|
int err;
|
|
|
- char attr_dir[PATH_MAX];
|
|
|
+ char *attr_dir;
|
|
|
char *tmp_path = g_strdup(path);
|
|
|
|
|
|
- snprintf(attr_dir, PATH_MAX, "%s/%s/%s",
|
|
|
+ attr_dir = g_strdup_printf("%s/%s/%s",
|
|
|
ctx->fs_root, dirname(tmp_path), VIRTFS_META_DIR);
|
|
|
|
|
|
err = mkdir(attr_dir, 0700);
|
|
|
if (err < 0 && errno == EEXIST) {
|
|
|
err = 0;
|
|
|
}
|
|
|
+ g_free(attr_dir);
|
|
|
g_free(tmp_path);
|
|
|
return err;
|
|
|
}
|
|
@@ -176,10 +179,11 @@ static int local_set_mapped_file_attr(FsContext *ctx,
|
|
|
FILE *fp;
|
|
|
int ret = 0;
|
|
|
char buf[ATTR_MAX];
|
|
|
- char attr_path[PATH_MAX];
|
|
|
+ char *attr_path;
|
|
|
int uid = -1, gid = -1, mode = -1, rdev = -1;
|
|
|
|
|
|
- fp = local_fopen(local_mapped_attr_path(ctx, path, attr_path), "r");
|
|
|
+ attr_path = local_mapped_attr_path(ctx, path);
|
|
|
+ fp = local_fopen(attr_path, "r");
|
|
|
if (!fp) {
|
|
|
goto create_map_file;
|
|
|
}
|
|
@@ -241,6 +245,7 @@ update_map_file:
|
|
|
fclose(fp);
|
|
|
|
|
|
err_out:
|
|
|
+ g_free(attr_path);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -282,36 +287,43 @@ static int local_set_xattr(const char *path, FsCred *credp)
|
|
|
static int local_post_create_passthrough(FsContext *fs_ctx, const char *path,
|
|
|
FsCred *credp)
|
|
|
{
|
|
|
- char buffer[PATH_MAX];
|
|
|
+ char *buffer;
|
|
|
|
|
|
- if (lchown(rpath(fs_ctx, path, buffer), credp->fc_uid,
|
|
|
- credp->fc_gid) < 0) {
|
|
|
+ buffer = rpath(fs_ctx, path);
|
|
|
+ if (lchown(buffer, credp->fc_uid, credp->fc_gid) < 0) {
|
|
|
/*
|
|
|
* If we fail to change ownership and if we are
|
|
|
* using security model none. Ignore the error
|
|
|
*/
|
|
|
if ((fs_ctx->export_flags & V9FS_SEC_MASK) != V9FS_SM_NONE) {
|
|
|
- return -1;
|
|
|
+ goto err;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (chmod(rpath(fs_ctx, path, buffer), credp->fc_mode & 07777) < 0) {
|
|
|
- return -1;
|
|
|
+ if (chmod(buffer, credp->fc_mode & 07777) < 0) {
|
|
|
+ goto err;
|
|
|
}
|
|
|
+
|
|
|
+ g_free(buffer);
|
|
|
return 0;
|
|
|
+err:
|
|
|
+ g_free(buffer);
|
|
|
+ return -1;
|
|
|
}
|
|
|
|
|
|
static ssize_t local_readlink(FsContext *fs_ctx, V9fsPath *fs_path,
|
|
|
char *buf, size_t bufsz)
|
|
|
{
|
|
|
ssize_t tsize = -1;
|
|
|
- char buffer[PATH_MAX];
|
|
|
+ char *buffer;
|
|
|
char *path = fs_path->data;
|
|
|
|
|
|
if ((fs_ctx->export_flags & V9FS_SM_MAPPED) ||
|
|
|
(fs_ctx->export_flags & V9FS_SM_MAPPED_FILE)) {
|
|
|
int fd;
|
|
|
- fd = open(rpath(fs_ctx, path, buffer), O_RDONLY | O_NOFOLLOW);
|
|
|
+ buffer = rpath(fs_ctx, path);
|
|
|
+ fd = open(buffer, O_RDONLY | O_NOFOLLOW);
|
|
|
+ g_free(buffer);
|
|
|
if (fd == -1) {
|
|
|
return -1;
|
|
|
}
|
|
@@ -322,7 +334,9 @@ static ssize_t local_readlink(FsContext *fs_ctx, V9fsPath *fs_path,
|
|
|
return tsize;
|
|
|
} else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
|
|
|
(fs_ctx->export_flags & V9FS_SM_NONE)) {
|
|
|
- tsize = readlink(rpath(fs_ctx, path, buffer), buf, bufsz);
|
|
|
+ buffer = rpath(fs_ctx, path);
|
|
|
+ tsize = readlink(buffer, buf, bufsz);
|
|
|
+ g_free(buffer);
|
|
|
}
|
|
|
return tsize;
|
|
|
}
|
|
@@ -340,20 +354,24 @@ static int local_closedir(FsContext *ctx, V9fsFidOpenState *fs)
|
|
|
static int local_open(FsContext *ctx, V9fsPath *fs_path,
|
|
|
int flags, V9fsFidOpenState *fs)
|
|
|
{
|
|
|
- char buffer[PATH_MAX];
|
|
|
+ char *buffer;
|
|
|
char *path = fs_path->data;
|
|
|
|
|
|
- fs->fd = open(rpath(ctx, path, buffer), flags | O_NOFOLLOW);
|
|
|
+ buffer = rpath(ctx, path);
|
|
|
+ fs->fd = open(buffer, flags | O_NOFOLLOW);
|
|
|
+ g_free(buffer);
|
|
|
return fs->fd;
|
|
|
}
|
|
|
|
|
|
static int local_opendir(FsContext *ctx,
|
|
|
V9fsPath *fs_path, V9fsFidOpenState *fs)
|
|
|
{
|
|
|
- char buffer[PATH_MAX];
|
|
|
+ char *buffer;
|
|
|
char *path = fs_path->data;
|
|
|
|
|
|
- fs->dir = opendir(rpath(ctx, path, buffer));
|
|
|
+ buffer = rpath(ctx, path);
|
|
|
+ fs->dir = opendir(buffer);
|
|
|
+ g_free(buffer);
|
|
|
if (!fs->dir) {
|
|
|
return -1;
|
|
|
}
|
|
@@ -441,18 +459,23 @@ static ssize_t local_pwritev(FsContext *ctx, V9fsFidOpenState *fs,
|
|
|
|
|
|
static int local_chmod(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp)
|
|
|
{
|
|
|
- char buffer[PATH_MAX];
|
|
|
+ char *buffer;
|
|
|
+ int ret = -1;
|
|
|
char *path = fs_path->data;
|
|
|
|
|
|
if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
|
|
|
- return local_set_xattr(rpath(fs_ctx, path, buffer), credp);
|
|
|
+ buffer = rpath(fs_ctx, path);
|
|
|
+ ret = local_set_xattr(buffer, credp);
|
|
|
+ g_free(buffer);
|
|
|
} else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
|
|
|
return local_set_mapped_file_attr(fs_ctx, path, credp);
|
|
|
} else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
|
|
|
(fs_ctx->export_flags & V9FS_SM_NONE)) {
|
|
|
- return chmod(rpath(fs_ctx, path, buffer), credp->fc_mode);
|
|
|
+ buffer = rpath(fs_ctx, path);
|
|
|
+ ret = chmod(buffer, credp->fc_mode);
|
|
|
+ g_free(buffer);
|
|
|
}
|
|
|
- return -1;
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path,
|
|
@@ -462,7 +485,7 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path,
|
|
|
int err = -1;
|
|
|
int serrno = 0;
|
|
|
V9fsString fullname;
|
|
|
- char buffer[PATH_MAX];
|
|
|
+ char *buffer;
|
|
|
|
|
|
v9fs_string_init(&fullname);
|
|
|
v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name);
|
|
@@ -470,21 +493,23 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path,
|
|
|
|
|
|
/* Determine the security model */
|
|
|
if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
|
|
|
- err = mknod(rpath(fs_ctx, path, buffer),
|
|
|
- SM_LOCAL_MODE_BITS|S_IFREG, 0);
|
|
|
+ buffer = rpath(fs_ctx, path);
|
|
|
+ err = mknod(buffer, SM_LOCAL_MODE_BITS|S_IFREG, 0);
|
|
|
if (err == -1) {
|
|
|
+ g_free(buffer);
|
|
|
goto out;
|
|
|
}
|
|
|
- err = local_set_xattr(rpath(fs_ctx, path, buffer), credp);
|
|
|
+ err = local_set_xattr(buffer, credp);
|
|
|
if (err == -1) {
|
|
|
serrno = errno;
|
|
|
goto err_end;
|
|
|
}
|
|
|
} else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
|
|
|
|
|
|
- err = mknod(rpath(fs_ctx, path, buffer),
|
|
|
- SM_LOCAL_MODE_BITS|S_IFREG, 0);
|
|
|
+ buffer = rpath(fs_ctx, path);
|
|
|
+ err = mknod(buffer, SM_LOCAL_MODE_BITS|S_IFREG, 0);
|
|
|
if (err == -1) {
|
|
|
+ g_free(buffer);
|
|
|
goto out;
|
|
|
}
|
|
|
err = local_set_mapped_file_attr(fs_ctx, path, credp);
|
|
@@ -494,9 +519,10 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path,
|
|
|
}
|
|
|
} else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
|
|
|
(fs_ctx->export_flags & V9FS_SM_NONE)) {
|
|
|
- err = mknod(rpath(fs_ctx, path, buffer), credp->fc_mode,
|
|
|
- credp->fc_rdev);
|
|
|
+ buffer = rpath(fs_ctx, path);
|
|
|
+ err = mknod(buffer, credp->fc_mode, credp->fc_rdev);
|
|
|
if (err == -1) {
|
|
|
+ g_free(buffer);
|
|
|
goto out;
|
|
|
}
|
|
|
err = local_post_create_passthrough(fs_ctx, path, credp);
|
|
@@ -508,8 +534,9 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path,
|
|
|
goto out;
|
|
|
|
|
|
err_end:
|
|
|
- remove(rpath(fs_ctx, path, buffer));
|
|
|
+ remove(buffer);
|
|
|
errno = serrno;
|
|
|
+ g_free(buffer);
|
|
|
out:
|
|
|
v9fs_string_free(&fullname);
|
|
|
return err;
|
|
@@ -522,7 +549,7 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
|
|
|
int err = -1;
|
|
|
int serrno = 0;
|
|
|
V9fsString fullname;
|
|
|
- char buffer[PATH_MAX];
|
|
|
+ char *buffer;
|
|
|
|
|
|
v9fs_string_init(&fullname);
|
|
|
v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name);
|
|
@@ -530,19 +557,23 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
|
|
|
|
|
|
/* Determine the security model */
|
|
|
if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
|
|
|
- err = mkdir(rpath(fs_ctx, path, buffer), SM_LOCAL_DIR_MODE_BITS);
|
|
|
+ buffer = rpath(fs_ctx, path);
|
|
|
+ err = mkdir(buffer, SM_LOCAL_DIR_MODE_BITS);
|
|
|
if (err == -1) {
|
|
|
+ g_free(buffer);
|
|
|
goto out;
|
|
|
}
|
|
|
credp->fc_mode = credp->fc_mode|S_IFDIR;
|
|
|
- err = local_set_xattr(rpath(fs_ctx, path, buffer), credp);
|
|
|
+ err = local_set_xattr(buffer, credp);
|
|
|
if (err == -1) {
|
|
|
serrno = errno;
|
|
|
goto err_end;
|
|
|
}
|
|
|
} else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
|
|
|
- err = mkdir(rpath(fs_ctx, path, buffer), SM_LOCAL_DIR_MODE_BITS);
|
|
|
+ buffer = rpath(fs_ctx, path);
|
|
|
+ err = mkdir(buffer, SM_LOCAL_DIR_MODE_BITS);
|
|
|
if (err == -1) {
|
|
|
+ g_free(buffer);
|
|
|
goto out;
|
|
|
}
|
|
|
credp->fc_mode = credp->fc_mode|S_IFDIR;
|
|
@@ -553,8 +584,10 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
|
|
|
}
|
|
|
} else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
|
|
|
(fs_ctx->export_flags & V9FS_SM_NONE)) {
|
|
|
- err = mkdir(rpath(fs_ctx, path, buffer), credp->fc_mode);
|
|
|
+ buffer = rpath(fs_ctx, path);
|
|
|
+ err = mkdir(buffer, credp->fc_mode);
|
|
|
if (err == -1) {
|
|
|
+ g_free(buffer);
|
|
|
goto out;
|
|
|
}
|
|
|
err = local_post_create_passthrough(fs_ctx, path, credp);
|
|
@@ -566,8 +599,9 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
|
|
|
goto out;
|
|
|
|
|
|
err_end:
|
|
|
- remove(rpath(fs_ctx, path, buffer));
|
|
|
+ remove(buffer);
|
|
|
errno = serrno;
|
|
|
+ g_free(buffer);
|
|
|
out:
|
|
|
v9fs_string_free(&fullname);
|
|
|
return err;
|
|
@@ -626,7 +660,7 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
|
|
|
int err = -1;
|
|
|
int serrno = 0;
|
|
|
V9fsString fullname;
|
|
|
- char buffer[PATH_MAX];
|
|
|
+ char *buffer;
|
|
|
|
|
|
/*
|
|
|
* Mark all the open to not follow symlinks
|
|
@@ -639,21 +673,25 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
|
|
|
|
|
|
/* Determine the security model */
|
|
|
if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
|
|
|
- fd = open(rpath(fs_ctx, path, buffer), flags, SM_LOCAL_MODE_BITS);
|
|
|
+ buffer = rpath(fs_ctx, path);
|
|
|
+ fd = open(buffer, flags, SM_LOCAL_MODE_BITS);
|
|
|
if (fd == -1) {
|
|
|
+ g_free(buffer);
|
|
|
err = fd;
|
|
|
goto out;
|
|
|
}
|
|
|
credp->fc_mode = credp->fc_mode|S_IFREG;
|
|
|
/* Set cleint credentials in xattr */
|
|
|
- err = local_set_xattr(rpath(fs_ctx, path, buffer), credp);
|
|
|
+ err = local_set_xattr(buffer, credp);
|
|
|
if (err == -1) {
|
|
|
serrno = errno;
|
|
|
goto err_end;
|
|
|
}
|
|
|
} else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
|
|
|
- fd = open(rpath(fs_ctx, path, buffer), flags, SM_LOCAL_MODE_BITS);
|
|
|
+ buffer = rpath(fs_ctx, path);
|
|
|
+ fd = open(buffer, flags, SM_LOCAL_MODE_BITS);
|
|
|
if (fd == -1) {
|
|
|
+ g_free(buffer);
|
|
|
err = fd;
|
|
|
goto out;
|
|
|
}
|
|
@@ -666,8 +704,10 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
|
|
|
}
|
|
|
} else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
|
|
|
(fs_ctx->export_flags & V9FS_SM_NONE)) {
|
|
|
- fd = open(rpath(fs_ctx, path, buffer), flags, credp->fc_mode);
|
|
|
+ buffer = rpath(fs_ctx, path);
|
|
|
+ fd = open(buffer, flags, credp->fc_mode);
|
|
|
if (fd == -1) {
|
|
|
+ g_free(buffer);
|
|
|
err = fd;
|
|
|
goto out;
|
|
|
}
|
|
@@ -683,8 +723,9 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
|
|
|
|
|
|
err_end:
|
|
|
close(fd);
|
|
|
- remove(rpath(fs_ctx, path, buffer));
|
|
|
+ remove(buffer);
|
|
|
errno = serrno;
|
|
|
+ g_free(buffer);
|
|
|
out:
|
|
|
v9fs_string_free(&fullname);
|
|
|
return err;
|
|
@@ -698,7 +739,7 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
|
|
|
int serrno = 0;
|
|
|
char *newpath;
|
|
|
V9fsString fullname;
|
|
|
- char buffer[PATH_MAX];
|
|
|
+ char *buffer;
|
|
|
|
|
|
v9fs_string_init(&fullname);
|
|
|
v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name);
|
|
@@ -708,10 +749,10 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
|
|
|
if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
|
|
|
int fd;
|
|
|
ssize_t oldpath_size, write_size;
|
|
|
- fd = open(rpath(fs_ctx, newpath, buffer),
|
|
|
- O_CREAT|O_EXCL|O_RDWR|O_NOFOLLOW,
|
|
|
- SM_LOCAL_MODE_BITS);
|
|
|
+ buffer = rpath(fs_ctx, newpath);
|
|
|
+ fd = open(buffer, O_CREAT|O_EXCL|O_RDWR|O_NOFOLLOW, SM_LOCAL_MODE_BITS);
|
|
|
if (fd == -1) {
|
|
|
+ g_free(buffer);
|
|
|
err = fd;
|
|
|
goto out;
|
|
|
}
|
|
@@ -730,7 +771,7 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
|
|
|
close(fd);
|
|
|
/* Set cleint credentials in symlink's xattr */
|
|
|
credp->fc_mode = credp->fc_mode|S_IFLNK;
|
|
|
- err = local_set_xattr(rpath(fs_ctx, newpath, buffer), credp);
|
|
|
+ err = local_set_xattr(buffer, credp);
|
|
|
if (err == -1) {
|
|
|
serrno = errno;
|
|
|
goto err_end;
|
|
@@ -738,10 +779,10 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
|
|
|
} else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
|
|
|
int fd;
|
|
|
ssize_t oldpath_size, write_size;
|
|
|
- fd = open(rpath(fs_ctx, newpath, buffer),
|
|
|
- O_CREAT|O_EXCL|O_RDWR|O_NOFOLLOW,
|
|
|
- SM_LOCAL_MODE_BITS);
|
|
|
+ buffer = rpath(fs_ctx, newpath);
|
|
|
+ fd = open(buffer, O_CREAT|O_EXCL|O_RDWR|O_NOFOLLOW, SM_LOCAL_MODE_BITS);
|
|
|
if (fd == -1) {
|
|
|
+ g_free(buffer);
|
|
|
err = fd;
|
|
|
goto out;
|
|
|
}
|
|
@@ -767,12 +808,13 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
|
|
|
}
|
|
|
} else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
|
|
|
(fs_ctx->export_flags & V9FS_SM_NONE)) {
|
|
|
- err = symlink(oldpath, rpath(fs_ctx, newpath, buffer));
|
|
|
+ buffer = rpath(fs_ctx, newpath);
|
|
|
+ err = symlink(oldpath, buffer);
|
|
|
if (err) {
|
|
|
+ g_free(buffer);
|
|
|
goto out;
|
|
|
}
|
|
|
- err = lchown(rpath(fs_ctx, newpath, buffer), credp->fc_uid,
|
|
|
- credp->fc_gid);
|
|
|
+ err = lchown(buffer, credp->fc_uid, credp->fc_gid);
|
|
|
if (err == -1) {
|
|
|
/*
|
|
|
* If we fail to change ownership and if we are
|
|
@@ -788,8 +830,9 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
|
|
|
goto out;
|
|
|
|
|
|
err_end:
|
|
|
- remove(rpath(fs_ctx, newpath, buffer));
|
|
|
+ remove(buffer);
|
|
|
errno = serrno;
|
|
|
+ g_free(buffer);
|
|
|
out:
|
|
|
v9fs_string_free(&fullname);
|
|
|
return err;
|
|
@@ -800,13 +843,16 @@ static int local_link(FsContext *ctx, V9fsPath *oldpath,
|
|
|
{
|
|
|
int ret;
|
|
|
V9fsString newpath;
|
|
|
- char buffer[PATH_MAX], buffer1[PATH_MAX];
|
|
|
+ char *buffer, *buffer1;
|
|
|
|
|
|
v9fs_string_init(&newpath);
|
|
|
v9fs_string_sprintf(&newpath, "%s/%s", dirpath->data, name);
|
|
|
|
|
|
- ret = link(rpath(ctx, oldpath->data, buffer),
|
|
|
- rpath(ctx, newpath.data, buffer1));
|
|
|
+ buffer = rpath(ctx, oldpath->data);
|
|
|
+ buffer1 = rpath(ctx, newpath.data);
|
|
|
+ ret = link(buffer, buffer1);
|
|
|
+ g_free(buffer);
|
|
|
+ g_free(buffer1);
|
|
|
|
|
|
/* now link the virtfs_metadata files */
|
|
|
if (!ret && (ctx->export_flags & V9FS_SM_MAPPED_FILE)) {
|
|
@@ -815,8 +861,11 @@ static int local_link(FsContext *ctx, V9fsPath *oldpath,
|
|
|
if (ret < 0) {
|
|
|
goto err_out;
|
|
|
}
|
|
|
- ret = link(local_mapped_attr_path(ctx, oldpath->data, buffer),
|
|
|
- local_mapped_attr_path(ctx, newpath.data, buffer1));
|
|
|
+ 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);
|
|
|
if (ret < 0 && errno != ENOENT) {
|
|
|
goto err_out;
|
|
|
}
|
|
@@ -828,17 +877,21 @@ err_out:
|
|
|
|
|
|
static int local_truncate(FsContext *ctx, V9fsPath *fs_path, off_t size)
|
|
|
{
|
|
|
- char buffer[PATH_MAX];
|
|
|
+ char *buffer;
|
|
|
+ int ret;
|
|
|
char *path = fs_path->data;
|
|
|
|
|
|
- return truncate(rpath(ctx, path, buffer), size);
|
|
|
+ buffer = rpath(ctx, path);
|
|
|
+ ret = truncate(buffer, size);
|
|
|
+ g_free(buffer);
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static int local_rename(FsContext *ctx, const char *oldpath,
|
|
|
const char *newpath)
|
|
|
{
|
|
|
int err;
|
|
|
- char buffer[PATH_MAX], buffer1[PATH_MAX];
|
|
|
+ char *buffer, *buffer1;
|
|
|
|
|
|
if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
|
|
|
err = local_create_mapped_attr_dir(ctx, newpath);
|
|
@@ -846,50 +899,69 @@ static int local_rename(FsContext *ctx, const char *oldpath,
|
|
|
return err;
|
|
|
}
|
|
|
/* rename the .virtfs_metadata files */
|
|
|
- err = rename(local_mapped_attr_path(ctx, oldpath, buffer),
|
|
|
- local_mapped_attr_path(ctx, newpath, buffer1));
|
|
|
+ buffer = local_mapped_attr_path(ctx, oldpath);
|
|
|
+ buffer1 = local_mapped_attr_path(ctx, newpath);
|
|
|
+ err = rename(buffer, buffer1);
|
|
|
+ g_free(buffer);
|
|
|
+ g_free(buffer1);
|
|
|
if (err < 0 && errno != ENOENT) {
|
|
|
return err;
|
|
|
}
|
|
|
}
|
|
|
- return rename(rpath(ctx, oldpath, buffer), rpath(ctx, newpath, buffer1));
|
|
|
+
|
|
|
+ buffer = rpath(ctx, oldpath);
|
|
|
+ buffer1 = rpath(ctx, newpath);
|
|
|
+ err = rename(buffer, buffer1);
|
|
|
+ g_free(buffer);
|
|
|
+ g_free(buffer1);
|
|
|
+ return err;
|
|
|
}
|
|
|
|
|
|
static int local_chown(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp)
|
|
|
{
|
|
|
- char buffer[PATH_MAX];
|
|
|
+ char *buffer;
|
|
|
+ int ret = -1;
|
|
|
char *path = fs_path->data;
|
|
|
|
|
|
if ((credp->fc_uid == -1 && credp->fc_gid == -1) ||
|
|
|
(fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
|
|
|
(fs_ctx->export_flags & V9FS_SM_NONE)) {
|
|
|
- return lchown(rpath(fs_ctx, path, buffer),
|
|
|
- credp->fc_uid, credp->fc_gid);
|
|
|
+ buffer = rpath(fs_ctx, path);
|
|
|
+ ret = lchown(buffer, credp->fc_uid, credp->fc_gid);
|
|
|
+ g_free(buffer);
|
|
|
} else if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
|
|
|
- return local_set_xattr(rpath(fs_ctx, path, buffer), credp);
|
|
|
+ buffer = rpath(fs_ctx, path);
|
|
|
+ ret = local_set_xattr(buffer, credp);
|
|
|
+ g_free(buffer);
|
|
|
} else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
|
|
|
return local_set_mapped_file_attr(fs_ctx, path, credp);
|
|
|
}
|
|
|
- return -1;
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static int local_utimensat(FsContext *s, V9fsPath *fs_path,
|
|
|
const struct timespec *buf)
|
|
|
{
|
|
|
- char buffer[PATH_MAX];
|
|
|
+ char *buffer;
|
|
|
+ int ret;
|
|
|
char *path = fs_path->data;
|
|
|
|
|
|
- return qemu_utimens(rpath(s, path, buffer), buf);
|
|
|
+ buffer = rpath(s, path);
|
|
|
+ ret = qemu_utimens(buffer, buf);
|
|
|
+ g_free(buffer);
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static int local_remove(FsContext *ctx, const char *path)
|
|
|
{
|
|
|
int err;
|
|
|
struct stat stbuf;
|
|
|
- char buffer[PATH_MAX];
|
|
|
+ char *buffer;
|
|
|
|
|
|
if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
|
|
|
- err = lstat(rpath(ctx, path, buffer), &stbuf);
|
|
|
+ buffer = rpath(ctx, path);
|
|
|
+ err = lstat(buffer, &stbuf);
|
|
|
+ g_free(buffer);
|
|
|
if (err) {
|
|
|
goto err_out;
|
|
|
}
|
|
@@ -898,8 +970,10 @@ static int local_remove(FsContext *ctx, const char *path)
|
|
|
* directory
|
|
|
*/
|
|
|
if (S_ISDIR(stbuf.st_mode)) {
|
|
|
- sprintf(buffer, "%s/%s/%s", ctx->fs_root, path, VIRTFS_META_DIR);
|
|
|
+ buffer = g_strdup_printf("%s/%s/%s", ctx->fs_root,
|
|
|
+ path, VIRTFS_META_DIR);
|
|
|
err = remove(buffer);
|
|
|
+ g_free(buffer);
|
|
|
if (err < 0 && errno != ENOENT) {
|
|
|
/*
|
|
|
* We didn't had the .virtfs_metadata file. May be file created
|
|
@@ -912,7 +986,9 @@ static int local_remove(FsContext *ctx, const char *path)
|
|
|
* Now remove the name from parent directory
|
|
|
* .virtfs_metadata directory
|
|
|
*/
|
|
|
- err = remove(local_mapped_attr_path(ctx, path, buffer));
|
|
|
+ buffer = local_mapped_attr_path(ctx, path);
|
|
|
+ err = remove(buffer);
|
|
|
+ g_free(buffer);
|
|
|
if (err < 0 && errno != ENOENT) {
|
|
|
/*
|
|
|
* We didn't had the .virtfs_metadata file. May be file created
|
|
@@ -921,7 +997,10 @@ static int local_remove(FsContext *ctx, const char *path)
|
|
|
goto err_out;
|
|
|
}
|
|
|
}
|
|
|
- return remove(rpath(ctx, path, buffer));
|
|
|
+
|
|
|
+ buffer = rpath(ctx, path);
|
|
|
+ err = remove(buffer);
|
|
|
+ g_free(buffer);
|
|
|
err_out:
|
|
|
return err;
|
|
|
}
|
|
@@ -946,10 +1025,14 @@ static int local_fsync(FsContext *ctx, int fid_type,
|
|
|
|
|
|
static int local_statfs(FsContext *s, V9fsPath *fs_path, struct statfs *stbuf)
|
|
|
{
|
|
|
- char buffer[PATH_MAX];
|
|
|
+ char *buffer;
|
|
|
+ int ret;
|
|
|
char *path = fs_path->data;
|
|
|
|
|
|
- return statfs(rpath(s, path, buffer), stbuf);
|
|
|
+ buffer = rpath(s, path);
|
|
|
+ ret = statfs(buffer, stbuf);
|
|
|
+ g_free(buffer);
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static ssize_t local_lgetxattr(FsContext *ctx, V9fsPath *fs_path,
|
|
@@ -1022,7 +1105,7 @@ static int local_unlinkat(FsContext *ctx, V9fsPath *dir,
|
|
|
{
|
|
|
int ret;
|
|
|
V9fsString fullname;
|
|
|
- char buffer[PATH_MAX];
|
|
|
+ char *buffer;
|
|
|
|
|
|
v9fs_string_init(&fullname);
|
|
|
|
|
@@ -1033,9 +1116,10 @@ static int local_unlinkat(FsContext *ctx, V9fsPath *dir,
|
|
|
* If directory remove .virtfs_metadata contained in the
|
|
|
* directory
|
|
|
*/
|
|
|
- sprintf(buffer, "%s/%s/%s", ctx->fs_root,
|
|
|
- fullname.data, VIRTFS_META_DIR);
|
|
|
+ buffer = g_strdup_printf("%s/%s/%s", ctx->fs_root,
|
|
|
+ fullname.data, VIRTFS_META_DIR);
|
|
|
ret = remove(buffer);
|
|
|
+ g_free(buffer);
|
|
|
if (ret < 0 && errno != ENOENT) {
|
|
|
/*
|
|
|
* We didn't had the .virtfs_metadata file. May be file created
|
|
@@ -1048,7 +1132,9 @@ static int local_unlinkat(FsContext *ctx, V9fsPath *dir,
|
|
|
* Now remove the name from parent directory
|
|
|
* .virtfs_metadata directory.
|
|
|
*/
|
|
|
- ret = remove(local_mapped_attr_path(ctx, fullname.data, buffer));
|
|
|
+ buffer = local_mapped_attr_path(ctx, fullname.data);
|
|
|
+ ret = remove(buffer);
|
|
|
+ g_free(buffer);
|
|
|
if (ret < 0 && errno != ENOENT) {
|
|
|
/*
|
|
|
* We didn't had the .virtfs_metadata file. May be file created
|
|
@@ -1058,10 +1144,12 @@ static int local_unlinkat(FsContext *ctx, V9fsPath *dir,
|
|
|
}
|
|
|
}
|
|
|
/* Remove the name finally */
|
|
|
- ret = remove(rpath(ctx, fullname.data, buffer));
|
|
|
- v9fs_string_free(&fullname);
|
|
|
+ buffer = rpath(ctx, fullname.data);
|
|
|
+ ret = remove(buffer);
|
|
|
+ g_free(buffer);
|
|
|
|
|
|
err_out:
|
|
|
+ v9fs_string_free(&fullname);
|
|
|
return ret;
|
|
|
}
|
|
|
|