#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/iov.h"
+#include "qemu/main-loop.h"
#include "qemu/sockets.h"
#include "virtio-9p.h"
#include "fsdev/qemu-fsdev.h"
goto out_nofid;
}
+ trace_v9fs_setattr(pdu->tag, pdu->id, fid,
+ v9iattr.valid, v9iattr.mode, v9iattr.uid, v9iattr.gid,
+ v9iattr.size, v9iattr.atime_sec, v9iattr.mtime_sec);
+
fidp = get_fid(pdu, fid);
if (fidp == NULL) {
err = -EINVAL;
}
}
err = offset;
+ trace_v9fs_setattr_return(pdu->tag, pdu->id);
out:
put_fid(pdu, fidp);
out_nofid:
trace_v9fs_walk(pdu->tag, pdu->id, fid, newfid, nwnames);
if (nwnames && nwnames <= P9_MAXWELEM) {
- wnames = g_malloc0(sizeof(wnames[0]) * nwnames);
- qids = g_malloc0(sizeof(qids[0]) * nwnames);
+ wnames = g_new0(V9fsString, nwnames);
+ qids = g_new0(V9fsQID, nwnames);
for (i = 0; i < nwnames; i++) {
err = pdu_unmarshal(pdu, offset, "s", &wnames[i]);
if (err < 0) {
err = -EINVAL;
goto out;
}
+ v9fs_path_write_lock(s);
v9fs_path_copy(&fidp->path, &path);
+ v9fs_path_unlock(s);
} else {
newfidp = alloc_fid(s, newfid);
if (newfidp == NULL) {
V9fsString extension;
int iounit;
V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
v9fs_path_init(&path);
v9fs_string_init(&name);
if (err < 0) {
goto out;
}
+ v9fs_path_write_lock(s);
v9fs_path_copy(&fidp->path, &path);
+ v9fs_path_unlock(s);
err = v9fs_co_opendir(pdu, fidp);
if (err < 0) {
goto out;
if (err < 0) {
goto out;
}
+ v9fs_path_write_lock(s);
v9fs_path_copy(&fidp->path, &path);
+ v9fs_path_unlock(s);
} else if (perm & P9_STAT_MODE_LINK) {
int32_t ofid = atoi(extension.data);
V9fsFidState *ofidp = get_fid(pdu, ofid);
fidp->fid_type = P9_FID_NONE;
goto out;
}
+ v9fs_path_write_lock(s);
v9fs_path_copy(&fidp->path, &path);
+ v9fs_path_unlock(s);
err = v9fs_co_lstat(pdu, &fidp->path, &stbuf);
if (err < 0) {
fidp->fid_type = P9_FID_NONE;
if (err < 0) {
goto out;
}
+ v9fs_path_write_lock(s);
v9fs_path_copy(&fidp->path, &path);
+ v9fs_path_unlock(s);
} else if (perm & P9_STAT_MODE_NAMED_PIPE) {
err = v9fs_co_mknod(pdu, fidp, &name, fidp->uid, -1,
0, S_IFIFO | (perm & 0777), &stbuf);
if (err < 0) {
goto out;
}
+ v9fs_path_write_lock(s);
v9fs_path_copy(&fidp->path, &path);
+ v9fs_path_unlock(s);
} else if (perm & P9_STAT_MODE_SOCKET) {
err = v9fs_co_mknod(pdu, fidp, &name, fidp->uid, -1,
0, S_IFSOCK | (perm & 0777), &stbuf);
if (err < 0) {
goto out;
}
+ v9fs_path_write_lock(s);
v9fs_path_copy(&fidp->path, &path);
+ v9fs_path_unlock(s);
} else {
err = v9fs_co_open2(pdu, fidp, &name, -1,
omode_to_uflags(mode)|O_CREAT, perm, &stbuf);
{
int err = 0;
V9fsString name;
- int32_t dfid, flags;
+ int32_t dfid, flags, rflags = 0;
size_t offset = 7;
V9fsPath path;
V9fsFidState *dfidp;
goto out_nofid;
}
+ if (flags & ~P9_DOTL_AT_REMOVEDIR) {
+ err = -EINVAL;
+ goto out_nofid;
+ }
+
+ if (flags & P9_DOTL_AT_REMOVEDIR) {
+ rflags |= AT_REMOVEDIR;
+ }
+
dfidp = get_fid(pdu, dfid);
if (dfidp == NULL) {
err = -EINVAL;
if (err < 0) {
goto out_err;
}
- err = v9fs_co_unlinkat(pdu, &dfidp->path, &name, flags);
+ err = v9fs_co_unlinkat(pdu, &dfidp->path, &name, rflags);
if (!err) {
err = offset;
}
struct stat stbuf;
V9fsFidState *fidp;
V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
v9fs_stat_init(&v9stat);
err = pdu_unmarshal(pdu, offset, "dwS", &fid, &unused, &v9stat);
}
}
if (v9stat.name.size != 0) {
+ v9fs_path_write_lock(s);
err = v9fs_complete_rename(pdu, fidp, -1, &v9stat.name);
+ v9fs_path_unlock(s);
if (err < 0) {
goto out;
}
xattr_fidp->fs.xattr.len = size;
xattr_fidp->fid_type = P9_FID_XATTR;
xattr_fidp->fs.xattr.xattrwalk_fid = true;
+ xattr_fidp->fs.xattr.value = g_malloc0(size);
if (size) {
- xattr_fidp->fs.xattr.value = g_malloc0(size);
err = v9fs_co_llistxattr(pdu, &xattr_fidp->path,
xattr_fidp->fs.xattr.value,
xattr_fidp->fs.xattr.len);
xattr_fidp->fs.xattr.len = size;
xattr_fidp->fid_type = P9_FID_XATTR;
xattr_fidp->fs.xattr.xattrwalk_fid = true;
+ xattr_fidp->fs.xattr.value = g_malloc0(size);
if (size) {
- xattr_fidp->fs.xattr.value = g_malloc0(size);
err = v9fs_co_lgetxattr(pdu, &xattr_fidp->path,
&name, xattr_fidp->fs.xattr.value,
xattr_fidp->fs.xattr.len);
static void coroutine_fn v9fs_xattrcreate(void *opaque)
{
- int flags;
+ int flags, rflags = 0;
int32_t fid;
uint64_t size;
ssize_t err = 0;
}
trace_v9fs_xattrcreate(pdu->tag, pdu->id, fid, name.data, size, flags);
+ if (flags & ~(P9_XATTR_CREATE | P9_XATTR_REPLACE)) {
+ err = -EINVAL;
+ goto out_nofid;
+ }
+
+ if (flags & P9_XATTR_CREATE) {
+ rflags |= XATTR_CREATE;
+ }
+
+ if (flags & P9_XATTR_REPLACE) {
+ rflags |= XATTR_REPLACE;
+ }
+
if (size > XATTR_SIZE_MAX) {
err = -E2BIG;
goto out_nofid;
xattr_fidp->fs.xattr.copied_len = 0;
xattr_fidp->fs.xattr.xattrwalk_fid = false;
xattr_fidp->fs.xattr.len = size;
- xattr_fidp->fs.xattr.flags = flags;
+ xattr_fidp->fs.xattr.flags = rflags;
v9fs_string_init(&xattr_fidp->fs.xattr.name);
v9fs_string_copy(&xattr_fidp->fs.xattr.name, &name);
xattr_fidp->fs.xattr.value = g_malloc0(size);