hw/9pfs: Add fs driver specific details to fscontext

Add a new context flag PATHNAME_FSCONTEXT and indicate whether
the fs driver track fid using path names. Also add a private
pointer that help us to track fs driver specific values in there

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
This commit is contained in:
Aneesh Kumar K.V 2011-08-02 11:35:54 +05:30
parent 0174fe73e6
commit 532decb715
9 changed files with 105 additions and 52 deletions

View File

@ -50,12 +50,18 @@ typedef struct FsCred
struct xattr_operations; struct xattr_operations;
/* FsContext flag values */
#define PATHNAME_FSCONTEXT 0x1
typedef struct FsContext typedef struct FsContext
{ {
int flags;
char *fs_root; char *fs_root;
SecModel fs_sm; SecModel fs_sm;
uid_t uid; uid_t uid;
struct xattr_operations **xops; struct xattr_operations **xops;
/* fs driver specific data */
void *private;
} FsContext; } FsContext;
typedef struct V9fsPath { typedef struct V9fsPath {

View File

@ -76,7 +76,7 @@ int v9fs_co_mkdir(V9fsState *s, V9fsFidState *fidp, V9fsString *name,
cred.fc_mode = mode; cred.fc_mode = mode;
cred.fc_uid = uid; cred.fc_uid = uid;
cred.fc_gid = gid; cred.fc_gid = gid;
qemu_co_rwlock_rdlock(&s->rename_lock); v9fs_path_read_lock(s);
v9fs_co_run_in_worker( v9fs_co_run_in_worker(
{ {
err = s->ops->mkdir(&s->ctx, &fidp->path, name->data, &cred); err = s->ops->mkdir(&s->ctx, &fidp->path, name->data, &cred);
@ -94,7 +94,7 @@ int v9fs_co_mkdir(V9fsState *s, V9fsFidState *fidp, V9fsString *name,
v9fs_path_free(&path); v9fs_path_free(&path);
} }
}); });
qemu_co_rwlock_unlock(&s->rename_lock); v9fs_path_unlock(s);
return err; return err;
} }
@ -102,7 +102,7 @@ int v9fs_co_opendir(V9fsState *s, V9fsFidState *fidp)
{ {
int err; int err;
qemu_co_rwlock_rdlock(&s->rename_lock); v9fs_path_read_lock(s);
v9fs_co_run_in_worker( v9fs_co_run_in_worker(
{ {
fidp->fs.dir = s->ops->opendir(&s->ctx, &fidp->path); fidp->fs.dir = s->ops->opendir(&s->ctx, &fidp->path);
@ -112,7 +112,7 @@ int v9fs_co_opendir(V9fsState *s, V9fsFidState *fidp)
err = 0; err = 0;
} }
}); });
qemu_co_rwlock_unlock(&s->rename_lock); v9fs_path_unlock(s);
if (!err) { if (!err) {
total_open_fd++; total_open_fd++;
if (total_open_fd > open_fd_hw) { if (total_open_fd > open_fd_hw) {

View File

@ -21,7 +21,7 @@ int v9fs_co_lstat(V9fsState *s, V9fsPath *path, struct stat *stbuf)
{ {
int err; int err;
qemu_co_rwlock_rdlock(&s->rename_lock); v9fs_path_read_lock(s);
v9fs_co_run_in_worker( v9fs_co_run_in_worker(
{ {
err = s->ops->lstat(&s->ctx, path, stbuf); err = s->ops->lstat(&s->ctx, path, stbuf);
@ -29,7 +29,7 @@ int v9fs_co_lstat(V9fsState *s, V9fsPath *path, struct stat *stbuf)
err = -errno; err = -errno;
} }
}); });
qemu_co_rwlock_unlock(&s->rename_lock); v9fs_path_unlock(s);
return err; return err;
} }
@ -51,7 +51,7 @@ int v9fs_co_open(V9fsState *s, V9fsFidState *fidp, int flags)
{ {
int err; int err;
qemu_co_rwlock_rdlock(&s->rename_lock); v9fs_path_read_lock(s);
v9fs_co_run_in_worker( v9fs_co_run_in_worker(
{ {
fidp->fs.fd = s->ops->open(&s->ctx, &fidp->path, flags); fidp->fs.fd = s->ops->open(&s->ctx, &fidp->path, flags);
@ -61,7 +61,7 @@ int v9fs_co_open(V9fsState *s, V9fsFidState *fidp, int flags)
err = 0; err = 0;
} }
}); });
qemu_co_rwlock_unlock(&s->rename_lock); v9fs_path_unlock(s);
if (!err) { if (!err) {
total_open_fd++; total_open_fd++;
if (total_open_fd > open_fd_hw) { if (total_open_fd > open_fd_hw) {
@ -88,7 +88,7 @@ int v9fs_co_open2(V9fsState *s, V9fsFidState *fidp, V9fsString *name, gid_t gid,
* don't change. Read lock is fine because this fid cannot * don't change. Read lock is fine because this fid cannot
* be used by any other operation. * be used by any other operation.
*/ */
qemu_co_rwlock_rdlock(&s->rename_lock); v9fs_path_read_lock(s);
v9fs_co_run_in_worker( v9fs_co_run_in_worker(
{ {
fidp->fs.fd = s->ops->open2(&s->ctx, &fidp->path, fidp->fs.fd = s->ops->open2(&s->ctx, &fidp->path,
@ -112,7 +112,7 @@ int v9fs_co_open2(V9fsState *s, V9fsFidState *fidp, V9fsString *name, gid_t gid,
v9fs_path_free(&path); v9fs_path_free(&path);
} }
}); });
qemu_co_rwlock_unlock(&s->rename_lock); v9fs_path_unlock(s);
if (!err) { if (!err) {
total_open_fd++; total_open_fd++;
if (total_open_fd > open_fd_hw) { if (total_open_fd > open_fd_hw) {
@ -160,7 +160,7 @@ int v9fs_co_link(V9fsState *s, V9fsFidState *oldfid,
{ {
int err; int err;
qemu_co_rwlock_rdlock(&s->rename_lock); v9fs_path_read_lock(s);
v9fs_co_run_in_worker( v9fs_co_run_in_worker(
{ {
err = s->ops->link(&s->ctx, &oldfid->path, err = s->ops->link(&s->ctx, &oldfid->path,
@ -169,7 +169,7 @@ int v9fs_co_link(V9fsState *s, V9fsFidState *oldfid,
err = -errno; err = -errno;
} }
}); });
qemu_co_rwlock_unlock(&s->rename_lock); v9fs_path_unlock(s);
return err; return err;
} }

View File

@ -23,8 +23,7 @@ int v9fs_co_readlink(V9fsState *s, V9fsPath *path, V9fsString *buf)
ssize_t len; ssize_t len;
buf->data = g_malloc(PATH_MAX); buf->data = g_malloc(PATH_MAX);
qemu_co_rwlock_rdlock(&s->rename_lock); v9fs_path_read_lock(s);
v9fs_co_run_in_worker( v9fs_co_run_in_worker(
{ {
len = s->ops->readlink(&s->ctx, path, len = s->ops->readlink(&s->ctx, path,
@ -37,7 +36,7 @@ int v9fs_co_readlink(V9fsState *s, V9fsPath *path, V9fsString *buf)
err = -errno; err = -errno;
} }
}); });
qemu_co_rwlock_unlock(&s->rename_lock); v9fs_path_unlock(s);
if (err) { if (err) {
g_free(buf->data); g_free(buf->data);
buf->data = NULL; buf->data = NULL;
@ -50,7 +49,7 @@ int v9fs_co_statfs(V9fsState *s, V9fsPath *path, struct statfs *stbuf)
{ {
int err; int err;
qemu_co_rwlock_rdlock(&s->rename_lock); v9fs_path_read_lock(s);
v9fs_co_run_in_worker( v9fs_co_run_in_worker(
{ {
err = s->ops->statfs(&s->ctx, path, stbuf); err = s->ops->statfs(&s->ctx, path, stbuf);
@ -58,7 +57,7 @@ int v9fs_co_statfs(V9fsState *s, V9fsPath *path, struct statfs *stbuf)
err = -errno; err = -errno;
} }
}); });
qemu_co_rwlock_unlock(&s->rename_lock); v9fs_path_unlock(s);
return err; return err;
} }
@ -69,7 +68,7 @@ int v9fs_co_chmod(V9fsState *s, V9fsPath *path, mode_t mode)
cred_init(&cred); cred_init(&cred);
cred.fc_mode = mode; cred.fc_mode = mode;
qemu_co_rwlock_rdlock(&s->rename_lock); v9fs_path_read_lock(s);
v9fs_co_run_in_worker( v9fs_co_run_in_worker(
{ {
err = s->ops->chmod(&s->ctx, path, &cred); err = s->ops->chmod(&s->ctx, path, &cred);
@ -77,7 +76,7 @@ int v9fs_co_chmod(V9fsState *s, V9fsPath *path, mode_t mode)
err = -errno; err = -errno;
} }
}); });
qemu_co_rwlock_unlock(&s->rename_lock); v9fs_path_unlock(s);
return err; return err;
} }
@ -86,7 +85,7 @@ int v9fs_co_utimensat(V9fsState *s, V9fsPath *path,
{ {
int err; int err;
qemu_co_rwlock_rdlock(&s->rename_lock); v9fs_path_read_lock(s);
v9fs_co_run_in_worker( v9fs_co_run_in_worker(
{ {
err = s->ops->utimensat(&s->ctx, path, times); err = s->ops->utimensat(&s->ctx, path, times);
@ -94,7 +93,7 @@ int v9fs_co_utimensat(V9fsState *s, V9fsPath *path,
err = -errno; err = -errno;
} }
}); });
qemu_co_rwlock_unlock(&s->rename_lock); v9fs_path_unlock(s);
return err; return err;
} }
@ -106,7 +105,7 @@ int v9fs_co_chown(V9fsState *s, V9fsPath *path, uid_t uid, gid_t gid)
cred_init(&cred); cred_init(&cred);
cred.fc_uid = uid; cred.fc_uid = uid;
cred.fc_gid = gid; cred.fc_gid = gid;
qemu_co_rwlock_rdlock(&s->rename_lock); v9fs_path_read_lock(s);
v9fs_co_run_in_worker( v9fs_co_run_in_worker(
{ {
err = s->ops->chown(&s->ctx, path, &cred); err = s->ops->chown(&s->ctx, path, &cred);
@ -114,7 +113,7 @@ int v9fs_co_chown(V9fsState *s, V9fsPath *path, uid_t uid, gid_t gid)
err = -errno; err = -errno;
} }
}); });
qemu_co_rwlock_unlock(&s->rename_lock); v9fs_path_unlock(s);
return err; return err;
} }
@ -122,7 +121,7 @@ int v9fs_co_truncate(V9fsState *s, V9fsPath *path, off_t size)
{ {
int err; int err;
qemu_co_rwlock_rdlock(&s->rename_lock); v9fs_path_read_lock(s);
v9fs_co_run_in_worker( v9fs_co_run_in_worker(
{ {
err = s->ops->truncate(&s->ctx, path, size); err = s->ops->truncate(&s->ctx, path, size);
@ -130,7 +129,7 @@ int v9fs_co_truncate(V9fsState *s, V9fsPath *path, off_t size)
err = -errno; err = -errno;
} }
}); });
qemu_co_rwlock_unlock(&s->rename_lock); v9fs_path_unlock(s);
return err; return err;
} }
@ -146,7 +145,7 @@ int v9fs_co_mknod(V9fsState *s, V9fsFidState *fidp, V9fsString *name, uid_t uid,
cred.fc_gid = gid; cred.fc_gid = gid;
cred.fc_mode = mode; cred.fc_mode = mode;
cred.fc_rdev = dev; cred.fc_rdev = dev;
qemu_co_rwlock_rdlock(&s->rename_lock); v9fs_path_read_lock(s);
v9fs_co_run_in_worker( v9fs_co_run_in_worker(
{ {
err = s->ops->mknod(&s->ctx, &fidp->path, name->data, &cred); err = s->ops->mknod(&s->ctx, &fidp->path, name->data, &cred);
@ -164,7 +163,7 @@ int v9fs_co_mknod(V9fsState *s, V9fsFidState *fidp, V9fsString *name, uid_t uid,
v9fs_path_free(&path); v9fs_path_free(&path);
} }
}); });
qemu_co_rwlock_unlock(&s->rename_lock); v9fs_path_unlock(s);
return err; return err;
} }
@ -173,7 +172,7 @@ int v9fs_co_remove(V9fsState *s, V9fsPath *path)
{ {
int err; int err;
qemu_co_rwlock_rdlock(&s->rename_lock); v9fs_path_read_lock(s);
v9fs_co_run_in_worker( v9fs_co_run_in_worker(
{ {
err = s->ops->remove(&s->ctx, path->data); err = s->ops->remove(&s->ctx, path->data);
@ -181,7 +180,7 @@ int v9fs_co_remove(V9fsState *s, V9fsPath *path)
err = -errno; err = -errno;
} }
}); });
qemu_co_rwlock_unlock(&s->rename_lock); v9fs_path_unlock(s);
return err; return err;
} }
@ -189,7 +188,7 @@ int v9fs_co_unlinkat(V9fsState *s, V9fsPath *path, V9fsString *name, int flags)
{ {
int err; int err;
qemu_co_rwlock_rdlock(&s->rename_lock); v9fs_path_read_lock(s);
v9fs_co_run_in_worker( v9fs_co_run_in_worker(
{ {
err = s->ops->unlinkat(&s->ctx, path, name->data, flags); err = s->ops->unlinkat(&s->ctx, path, name->data, flags);
@ -197,7 +196,7 @@ int v9fs_co_unlinkat(V9fsState *s, V9fsPath *path, V9fsString *name, int flags)
err = -errno; err = -errno;
} }
}); });
qemu_co_rwlock_unlock(&s->rename_lock); v9fs_path_unlock(s);
return err; return err;
} }
@ -244,7 +243,7 @@ int v9fs_co_symlink(V9fsState *s, V9fsFidState *dfidp, V9fsString *name,
cred.fc_uid = dfidp->uid; cred.fc_uid = dfidp->uid;
cred.fc_gid = gid; cred.fc_gid = gid;
cred.fc_mode = 0777; cred.fc_mode = 0777;
qemu_co_rwlock_rdlock(&s->rename_lock); v9fs_path_read_lock(s);
v9fs_co_run_in_worker( v9fs_co_run_in_worker(
{ {
err = s->ops->symlink(&s->ctx, oldpath, &dfidp->path, err = s->ops->symlink(&s->ctx, oldpath, &dfidp->path,
@ -263,7 +262,7 @@ int v9fs_co_symlink(V9fsState *s, V9fsFidState *dfidp, V9fsString *name,
v9fs_path_free(&path); v9fs_path_free(&path);
} }
}); });
qemu_co_rwlock_unlock(&s->rename_lock); v9fs_path_unlock(s);
return err; return err;
} }
@ -275,9 +274,20 @@ int v9fs_co_name_to_path(V9fsState *s, V9fsPath *dirpath,
const char *name, V9fsPath *path) const char *name, V9fsPath *path)
{ {
int err; int err;
err = s->ops->name_to_path(&s->ctx, dirpath, name, path);
if (err < 0) { if (s->ctx.flags & PATHNAME_FSCONTEXT) {
err = -errno; 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; return err;
} }

View File

@ -21,7 +21,7 @@ int v9fs_co_llistxattr(V9fsState *s, V9fsPath *path, void *value, size_t size)
{ {
int err; int err;
qemu_co_rwlock_rdlock(&s->rename_lock); v9fs_path_read_lock(s);
v9fs_co_run_in_worker( v9fs_co_run_in_worker(
{ {
err = s->ops->llistxattr(&s->ctx, path, value, size); err = s->ops->llistxattr(&s->ctx, path, value, size);
@ -29,7 +29,7 @@ int v9fs_co_llistxattr(V9fsState *s, V9fsPath *path, void *value, size_t size)
err = -errno; err = -errno;
} }
}); });
qemu_co_rwlock_unlock(&s->rename_lock); v9fs_path_unlock(s);
return err; return err;
} }
@ -39,7 +39,7 @@ int v9fs_co_lgetxattr(V9fsState *s, V9fsPath *path,
{ {
int err; int err;
qemu_co_rwlock_rdlock(&s->rename_lock); v9fs_path_read_lock(s);
v9fs_co_run_in_worker( v9fs_co_run_in_worker(
{ {
err = s->ops->lgetxattr(&s->ctx, path, err = s->ops->lgetxattr(&s->ctx, path,
@ -49,7 +49,7 @@ int v9fs_co_lgetxattr(V9fsState *s, V9fsPath *path,
err = -errno; err = -errno;
} }
}); });
qemu_co_rwlock_unlock(&s->rename_lock); v9fs_path_unlock(s);
return err; return err;
} }
@ -59,7 +59,7 @@ int v9fs_co_lsetxattr(V9fsState *s, V9fsPath *path,
{ {
int err; int err;
qemu_co_rwlock_rdlock(&s->rename_lock); v9fs_path_read_lock(s);
v9fs_co_run_in_worker( v9fs_co_run_in_worker(
{ {
err = s->ops->lsetxattr(&s->ctx, path, err = s->ops->lsetxattr(&s->ctx, path,
@ -69,7 +69,7 @@ int v9fs_co_lsetxattr(V9fsState *s, V9fsPath *path,
err = -errno; err = -errno;
} }
}); });
qemu_co_rwlock_unlock(&s->rename_lock); v9fs_path_unlock(s);
return err; return err;
} }
@ -78,7 +78,7 @@ int v9fs_co_lremovexattr(V9fsState *s, V9fsPath *path,
{ {
int err; int err;
qemu_co_rwlock_rdlock(&s->rename_lock); v9fs_path_read_lock(s);
v9fs_co_run_in_worker( v9fs_co_run_in_worker(
{ {
err = s->ops->lremovexattr(&s->ctx, path, xattr_name->data); err = s->ops->lremovexattr(&s->ctx, path, xattr_name->data);
@ -86,6 +86,6 @@ int v9fs_co_lremovexattr(V9fsState *s, V9fsPath *path,
err = -errno; err = -errno;
} }
}); });
qemu_co_rwlock_unlock(&s->rename_lock); v9fs_path_unlock(s);
return err; return err;
} }

View File

@ -124,6 +124,7 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
memcpy(s->tag, conf->tag, len); memcpy(s->tag, conf->tag, len);
s->tag_len = len; s->tag_len = len;
s->ctx.uid = -1; s->ctx.uid = -1;
s->ctx.flags = 0;
s->ops = fse->ops; s->ops = fse->ops;
s->vdev.get_features = virtio_9p_get_features; s->vdev.get_features = virtio_9p_get_features;

View File

@ -647,6 +647,7 @@ static int local_unlinkat(FsContext *ctx, V9fsPath *dir,
static int local_init(FsContext *ctx) static int local_init(FsContext *ctx)
{ {
ctx->flags |= PATHNAME_FSCONTEXT;
return 0; return 0;
} }

View File

@ -2332,6 +2332,7 @@ out_nofid:
complete_pdu(s, pdu, err); complete_pdu(s, pdu, err);
} }
/* Only works with path name based fid */
static void v9fs_remove(void *opaque) static void v9fs_remove(void *opaque)
{ {
int32_t fid; int32_t fid;
@ -2347,6 +2348,11 @@ static void v9fs_remove(void *opaque)
err = -EINVAL; err = -EINVAL;
goto out_nofid; 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 * IF the file is unlinked, we cannot reopen
* the file later. So don't reclaim fd * the file later. So don't reclaim fd
@ -2467,6 +2473,7 @@ out_nofid:
return err; return err;
} }
/* Only works with path name based fid */
static void v9fs_rename(void *opaque) static void v9fs_rename(void *opaque)
{ {
int32_t fid; int32_t fid;
@ -2486,13 +2493,18 @@ static void v9fs_rename(void *opaque)
goto out_nofid; goto out_nofid;
} }
BUG_ON(fidp->fid_type != P9_FID_NONE); BUG_ON(fidp->fid_type != P9_FID_NONE);
/* if fs driver is not path based, return EOPNOTSUPP */
qemu_co_rwlock_wrlock(&s->rename_lock); if (!pdu->s->ctx.flags & PATHNAME_FSCONTEXT) {
err = -EOPNOTSUPP;
goto out;
}
v9fs_path_write_lock(s);
err = v9fs_complete_rename(s, fidp, newdirfid, &name); err = v9fs_complete_rename(s, fidp, newdirfid, &name);
qemu_co_rwlock_unlock(&s->rename_lock); v9fs_path_unlock(s);
if (!err) { if (!err) {
err = offset; err = offset;
} }
out:
put_fid(s, fidp); put_fid(s, fidp);
out_nofid: out_nofid:
complete_pdu(s, pdu, err); complete_pdu(s, pdu, err);
@ -2553,9 +2565,11 @@ static int v9fs_complete_renameat(V9fsState *s, int32_t olddirfid,
if (err < 0) { if (err < 0) {
goto out; goto out;
} }
/* Only for path based fid we need to do the below fixup */ if (s->ctx.flags & PATHNAME_FSCONTEXT) {
v9fs_fix_fid_paths(s, &olddirfidp->path, old_name, /* Only for path based fid we need to do the below fixup */
&newdirfidp->path, new_name); v9fs_fix_fid_paths(s, &olddirfidp->path, old_name,
&newdirfidp->path, new_name);
}
out: out:
if (olddirfidp) { if (olddirfidp) {
put_fid(s, olddirfidp); put_fid(s, olddirfidp);
@ -2578,9 +2592,9 @@ static void v9fs_renameat(void *opaque)
pdu_unmarshal(pdu, offset, "dsds", &olddirfid, pdu_unmarshal(pdu, offset, "dsds", &olddirfid,
&old_name, &newdirfid, &new_name); &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); err = v9fs_complete_renameat(s, olddirfid, &old_name, newdirfid, &new_name);
qemu_co_rwlock_unlock(&s->rename_lock); v9fs_path_unlock(s);
if (!err) { if (!err) {
err = offset; err = offset;
} }

View File

@ -388,6 +388,27 @@ static inline size_t do_pdu_unpack(void *dst, struct iovec *sg, int sg_count,
return pdu_packunpack(dst, sg, sg_count, offset, size, 0); 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 handle_9p_output(VirtIODevice *vdev, VirtQueue *vq);
extern void virtio_9p_set_fd_limit(void); extern void virtio_9p_set_fd_limit(void);
extern void v9fs_reclaim_fd(V9fsState *s); extern void v9fs_reclaim_fd(V9fsState *s);