struct xattr_operations;
+/* FsContext flag values */
+#define PATHNAME_FSCONTEXT 0x1
+
typedef struct FsContext
{
+ int flags;
char *fs_root;
SecModel fs_sm;
uid_t uid;
struct xattr_operations **xops;
+ /* fs driver specific data */
+ void *private;
} FsContext;
typedef struct V9fsPath {
cred.fc_mode = mode;
cred.fc_uid = uid;
cred.fc_gid = gid;
- qemu_co_rwlock_rdlock(&s->rename_lock);
+ v9fs_path_read_lock(s);
v9fs_co_run_in_worker(
{
err = s->ops->mkdir(&s->ctx, &fidp->path, name->data, &cred);
v9fs_path_free(&path);
}
});
- qemu_co_rwlock_unlock(&s->rename_lock);
+ v9fs_path_unlock(s);
return err;
}
{
int err;
- qemu_co_rwlock_rdlock(&s->rename_lock);
+ v9fs_path_read_lock(s);
v9fs_co_run_in_worker(
{
fidp->fs.dir = s->ops->opendir(&s->ctx, &fidp->path);
err = 0;
}
});
- qemu_co_rwlock_unlock(&s->rename_lock);
+ v9fs_path_unlock(s);
if (!err) {
total_open_fd++;
if (total_open_fd > open_fd_hw) {
{
int err;
- qemu_co_rwlock_rdlock(&s->rename_lock);
+ v9fs_path_read_lock(s);
v9fs_co_run_in_worker(
{
err = s->ops->lstat(&s->ctx, path, stbuf);
err = -errno;
}
});
- qemu_co_rwlock_unlock(&s->rename_lock);
+ v9fs_path_unlock(s);
return err;
}
{
int err;
- qemu_co_rwlock_rdlock(&s->rename_lock);
+ v9fs_path_read_lock(s);
v9fs_co_run_in_worker(
{
fidp->fs.fd = s->ops->open(&s->ctx, &fidp->path, flags);
err = 0;
}
});
- qemu_co_rwlock_unlock(&s->rename_lock);
+ v9fs_path_unlock(s);
if (!err) {
total_open_fd++;
if (total_open_fd > open_fd_hw) {
* don't change. Read lock is fine because this fid cannot
* be used by any other operation.
*/
- qemu_co_rwlock_rdlock(&s->rename_lock);
+ v9fs_path_read_lock(s);
v9fs_co_run_in_worker(
{
fidp->fs.fd = s->ops->open2(&s->ctx, &fidp->path,
v9fs_path_free(&path);
}
});
- qemu_co_rwlock_unlock(&s->rename_lock);
+ v9fs_path_unlock(s);
if (!err) {
total_open_fd++;
if (total_open_fd > open_fd_hw) {
{
int err;
- qemu_co_rwlock_rdlock(&s->rename_lock);
+ v9fs_path_read_lock(s);
v9fs_co_run_in_worker(
{
err = s->ops->link(&s->ctx, &oldfid->path,
err = -errno;
}
});
- qemu_co_rwlock_unlock(&s->rename_lock);
+ v9fs_path_unlock(s);
return err;
}
ssize_t len;
buf->data = g_malloc(PATH_MAX);
- qemu_co_rwlock_rdlock(&s->rename_lock);
-
+ v9fs_path_read_lock(s);
v9fs_co_run_in_worker(
{
len = s->ops->readlink(&s->ctx, path,
err = -errno;
}
});
- qemu_co_rwlock_unlock(&s->rename_lock);
+ v9fs_path_unlock(s);
if (err) {
g_free(buf->data);
buf->data = NULL;
{
int err;
- qemu_co_rwlock_rdlock(&s->rename_lock);
+ v9fs_path_read_lock(s);
v9fs_co_run_in_worker(
{
err = s->ops->statfs(&s->ctx, path, stbuf);
err = -errno;
}
});
- qemu_co_rwlock_unlock(&s->rename_lock);
+ v9fs_path_unlock(s);
return err;
}
cred_init(&cred);
cred.fc_mode = mode;
- qemu_co_rwlock_rdlock(&s->rename_lock);
+ v9fs_path_read_lock(s);
v9fs_co_run_in_worker(
{
err = s->ops->chmod(&s->ctx, path, &cred);
err = -errno;
}
});
- qemu_co_rwlock_unlock(&s->rename_lock);
+ v9fs_path_unlock(s);
return err;
}
{
int err;
- qemu_co_rwlock_rdlock(&s->rename_lock);
+ v9fs_path_read_lock(s);
v9fs_co_run_in_worker(
{
err = s->ops->utimensat(&s->ctx, path, times);
err = -errno;
}
});
- qemu_co_rwlock_unlock(&s->rename_lock);
+ v9fs_path_unlock(s);
return err;
}
cred_init(&cred);
cred.fc_uid = uid;
cred.fc_gid = gid;
- qemu_co_rwlock_rdlock(&s->rename_lock);
+ v9fs_path_read_lock(s);
v9fs_co_run_in_worker(
{
err = s->ops->chown(&s->ctx, path, &cred);
err = -errno;
}
});
- qemu_co_rwlock_unlock(&s->rename_lock);
+ v9fs_path_unlock(s);
return err;
}
{
int err;
- qemu_co_rwlock_rdlock(&s->rename_lock);
+ v9fs_path_read_lock(s);
v9fs_co_run_in_worker(
{
err = s->ops->truncate(&s->ctx, path, size);
err = -errno;
}
});
- qemu_co_rwlock_unlock(&s->rename_lock);
+ v9fs_path_unlock(s);
return err;
}
cred.fc_gid = gid;
cred.fc_mode = mode;
cred.fc_rdev = dev;
- qemu_co_rwlock_rdlock(&s->rename_lock);
+ v9fs_path_read_lock(s);
v9fs_co_run_in_worker(
{
err = s->ops->mknod(&s->ctx, &fidp->path, name->data, &cred);
v9fs_path_free(&path);
}
});
- qemu_co_rwlock_unlock(&s->rename_lock);
+ v9fs_path_unlock(s);
return err;
}
{
int err;
- qemu_co_rwlock_rdlock(&s->rename_lock);
+ v9fs_path_read_lock(s);
v9fs_co_run_in_worker(
{
err = s->ops->remove(&s->ctx, path->data);
err = -errno;
}
});
- qemu_co_rwlock_unlock(&s->rename_lock);
+ v9fs_path_unlock(s);
return err;
}
{
int err;
- qemu_co_rwlock_rdlock(&s->rename_lock);
+ v9fs_path_read_lock(s);
v9fs_co_run_in_worker(
{
err = s->ops->unlinkat(&s->ctx, path, name->data, flags);
err = -errno;
}
});
- qemu_co_rwlock_unlock(&s->rename_lock);
+ v9fs_path_unlock(s);
return err;
}
cred.fc_uid = dfidp->uid;
cred.fc_gid = gid;
cred.fc_mode = 0777;
- qemu_co_rwlock_rdlock(&s->rename_lock);
+ v9fs_path_read_lock(s);
v9fs_co_run_in_worker(
{
err = s->ops->symlink(&s->ctx, oldpath, &dfidp->path,
v9fs_path_free(&path);
}
});
- qemu_co_rwlock_unlock(&s->rename_lock);
+ v9fs_path_unlock(s);
return err;
}
const char *name, V9fsPath *path)
{
int err;
- err = s->ops->name_to_path(&s->ctx, dirpath, name, path);
- if (err < 0) {
- err = -errno;
+
+ if (s->ctx.flags & PATHNAME_FSCONTEXT) {
+ err = s->ops->name_to_path(&s->ctx, dirpath, name, path);
+ if (err < 0) {
+ err = -errno;
+ }
+ } else {
+ v9fs_co_run_in_worker(
+ {
+ err = s->ops->name_to_path(&s->ctx, dirpath, name, path);
+ if (err < 0) {
+ err = -errno;
+ }
+ });
}
return err;
}
{
int err;
- qemu_co_rwlock_rdlock(&s->rename_lock);
+ v9fs_path_read_lock(s);
v9fs_co_run_in_worker(
{
err = s->ops->llistxattr(&s->ctx, path, value, size);
err = -errno;
}
});
- qemu_co_rwlock_unlock(&s->rename_lock);
+ v9fs_path_unlock(s);
return err;
}
{
int err;
- qemu_co_rwlock_rdlock(&s->rename_lock);
+ v9fs_path_read_lock(s);
v9fs_co_run_in_worker(
{
err = s->ops->lgetxattr(&s->ctx, path,
err = -errno;
}
});
- qemu_co_rwlock_unlock(&s->rename_lock);
+ v9fs_path_unlock(s);
return err;
}
{
int err;
- qemu_co_rwlock_rdlock(&s->rename_lock);
+ v9fs_path_read_lock(s);
v9fs_co_run_in_worker(
{
err = s->ops->lsetxattr(&s->ctx, path,
err = -errno;
}
});
- qemu_co_rwlock_unlock(&s->rename_lock);
+ v9fs_path_unlock(s);
return err;
}
{
int err;
- qemu_co_rwlock_rdlock(&s->rename_lock);
+ v9fs_path_read_lock(s);
v9fs_co_run_in_worker(
{
err = s->ops->lremovexattr(&s->ctx, path, xattr_name->data);
err = -errno;
}
});
- qemu_co_rwlock_unlock(&s->rename_lock);
+ v9fs_path_unlock(s);
return err;
}
memcpy(s->tag, conf->tag, len);
s->tag_len = len;
s->ctx.uid = -1;
+ s->ctx.flags = 0;
s->ops = fse->ops;
s->vdev.get_features = virtio_9p_get_features;
static int local_init(FsContext *ctx)
{
+ ctx->flags |= PATHNAME_FSCONTEXT;
return 0;
}
complete_pdu(s, pdu, err);
}
+/* Only works with path name based fid */
static void v9fs_remove(void *opaque)
{
int32_t fid;
err = -EINVAL;
goto out_nofid;
}
+ /* if fs driver is not path based, return EOPNOTSUPP */
+ if (!pdu->s->ctx.flags & PATHNAME_FSCONTEXT) {
+ err = -EOPNOTSUPP;
+ goto out_err;
+ }
/*
* IF the file is unlinked, we cannot reopen
* the file later. So don't reclaim fd
return err;
}
+/* Only works with path name based fid */
static void v9fs_rename(void *opaque)
{
int32_t fid;
goto out_nofid;
}
BUG_ON(fidp->fid_type != P9_FID_NONE);
-
- qemu_co_rwlock_wrlock(&s->rename_lock);
+ /* if fs driver is not path based, return EOPNOTSUPP */
+ if (!pdu->s->ctx.flags & PATHNAME_FSCONTEXT) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+ v9fs_path_write_lock(s);
err = v9fs_complete_rename(s, fidp, newdirfid, &name);
- qemu_co_rwlock_unlock(&s->rename_lock);
+ v9fs_path_unlock(s);
if (!err) {
err = offset;
}
+out:
put_fid(s, fidp);
out_nofid:
complete_pdu(s, pdu, err);
if (err < 0) {
goto out;
}
- /* Only for path based fid we need to do the below fixup */
- v9fs_fix_fid_paths(s, &olddirfidp->path, old_name,
- &newdirfidp->path, new_name);
+ if (s->ctx.flags & PATHNAME_FSCONTEXT) {
+ /* Only for path based fid we need to do the below fixup */
+ v9fs_fix_fid_paths(s, &olddirfidp->path, old_name,
+ &newdirfidp->path, new_name);
+ }
out:
if (olddirfidp) {
put_fid(s, olddirfidp);
pdu_unmarshal(pdu, offset, "dsds", &olddirfid,
&old_name, &newdirfid, &new_name);
- qemu_co_rwlock_wrlock(&s->rename_lock);
+ v9fs_path_write_lock(s);
err = v9fs_complete_renameat(s, olddirfid, &old_name, newdirfid, &new_name);
- qemu_co_rwlock_unlock(&s->rename_lock);
+ v9fs_path_unlock(s);
if (!err) {
err = offset;
}
return pdu_packunpack(dst, sg, sg_count, offset, size, 0);
}
+static inline void v9fs_path_write_lock(V9fsState *s)
+{
+ if (s->ctx.flags & PATHNAME_FSCONTEXT) {
+ qemu_co_rwlock_wrlock(&s->rename_lock);
+ }
+}
+
+static inline void v9fs_path_read_lock(V9fsState *s)
+{
+ if (s->ctx.flags & PATHNAME_FSCONTEXT) {
+ qemu_co_rwlock_rdlock(&s->rename_lock);
+ }
+}
+
+static inline void v9fs_path_unlock(V9fsState *s)
+{
+ if (s->ctx.flags & PATHNAME_FSCONTEXT) {
+ qemu_co_rwlock_unlock(&s->rename_lock);
+ }
+}
+
extern void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq);
extern void virtio_9p_set_fd_limit(void);
extern void v9fs_reclaim_fd(V9fsState *s);