Accidentally left behind: these live in src/lib now.

This commit is contained in:
pooka 2008-07-29 13:50:24 +00:00
parent 727a7567f1
commit cd56ab5fbf
6 changed files with 0 additions and 1488 deletions

View File

@ -1,16 +0,0 @@
# $NetBSD: Makefile,v 1.4 2007/09/02 12:00:12 pooka Exp $
#
.include <bsd.own.mk>
LIB= p2k
SRCS= p2k.c
RUMPKERNEL= no
CPPFLAGS+= -I${NETBSDSRCDIR}/sys/rump/librump/rumpkern \
-I${NETBSDSRCDIR}/sys/rump/fs/lib/libukfs \
-I${LIBRUMPDIR}
.include "${NETBSDSRCDIR}/sys/rump/Makefile.rump"
.include <bsd.lib.mk>

View File

@ -1,763 +0,0 @@
/* $NetBSD: p2k.c,v 1.42 2008/03/11 10:50:16 pooka Exp $ */
/*
* Copyright (c) 2007 Antti Kantee. All Rights Reserved.
*
* Development of this software was supported by Google Summer of Code.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* puffs 2k, i.e. puffs 2 kernel. Converts the puffs protocol to
* the kernel vfs protocol and vice versa.
*
* A word about reference counting: puffs in the kernel is the king of
* reference counting. We must maintain a vnode alive and kicking
* until the kernel tells us to reclaim it. Therefore we make sure
* we never accidentally lose a vnode. Before calling operations which
* decrease the refcount we always bump the refcount up to compensate.
* Come inactive, if the file system thinks that the vnode should be
* put out of its misery, it will set the recycle flag. We use this
* to tell the kernel to reclaim the vnode. Only in reclaim do we
* really nuke the last reference.
*/
#define __VFSOPS_EXPOSE
#include <sys/mount.h>
#include <sys/param.h>
#include <sys/vnode.h>
#include <sys/lock.h>
#include <sys/namei.h>
#include <sys/dirent.h>
#include <assert.h>
#include <errno.h>
#include <puffs.h>
#include <stdlib.h>
#include "rump.h"
#include "p2k.h"
#include "ukfs.h"
PUFFSOP_PROTOS(p2k)
static kauth_cred_t
cred_create(const struct puffs_cred *pcr)
{
gid_t groups[NGROUPS];
uid_t uid;
gid_t gid;
short ngroups = 0;
if (puffs_cred_getuid(pcr, &uid) == -1)
uid = 0;
if (puffs_cred_getgid(pcr, &gid) == -1)
gid = 0;
puffs_cred_getgroups(pcr, groups, &ngroups);
return rump_cred_create(uid, gid, ngroups, groups);
}
static __inline void
cred_destroy(kauth_cred_t cred)
{
rump_cred_destroy(cred);
}
static struct componentname *
makecn(const struct puffs_cn *pcn)
{
kauth_cred_t cred;
cred = cred_create(pcn->pcn_cred);
return rump_makecn(pcn->pcn_nameiop, pcn->pcn_flags, pcn->pcn_name,
pcn->pcn_namelen, cred, curlwp);
}
static __inline void
freecn(struct componentname *cnp, int flags)
{
rump_freecn(cnp, flags | RUMPCN_FREECRED);
}
static void
makelwp(struct puffs_usermount *pu)
{
pid_t pid;
lwpid_t lid;
puffs_cc_getcaller(puffs_cc_getcc(pu), &pid, &lid);
rump_setup_curlwp(pid, lid, 1);
}
static void
clearlwp(struct puffs_usermount *pu)
{
rump_clear_curlwp();
}
int
p2k_run_fs(const char *vfsname, const char *devpath, const char *mountpath,
int mntflags, void *arg, size_t alen, uint32_t puffs_flags)
{
char typebuf[PUFFS_TYPELEN];
struct puffs_ops *pops;
struct puffs_usermount *pu;
struct puffs_node *pn_root;
struct vnode *rvp;
struct ukfs *ukfs;
extern int puffs_fakecc;
int rv, sverrno;
rv = -1;
ukfs_init();
ukfs = ukfs_mount(vfsname, devpath, mountpath, mntflags, arg, alen);
if (ukfs == NULL)
return -1;
PUFFSOP_INIT(pops);
PUFFSOP_SET(pops, p2k, fs, statvfs);
PUFFSOP_SET(pops, p2k, fs, unmount);
PUFFSOP_SET(pops, p2k, fs, sync);
PUFFSOP_SET(pops, p2k, fs, fhtonode);
PUFFSOP_SET(pops, p2k, fs, nodetofh);
PUFFSOP_SET(pops, p2k, node, lookup);
PUFFSOP_SET(pops, p2k, node, create);
PUFFSOP_SET(pops, p2k, node, mknod);
PUFFSOP_SET(pops, p2k, node, open);
PUFFSOP_SET(pops, p2k, node, close);
PUFFSOP_SET(pops, p2k, node, access);
PUFFSOP_SET(pops, p2k, node, getattr);
PUFFSOP_SET(pops, p2k, node, setattr);
#if 0
PUFFSOP_SET(pops, p2k, node, poll);
#endif
PUFFSOP_SET(pops, p2k, node, mmap);
PUFFSOP_SET(pops, p2k, node, fsync);
PUFFSOP_SET(pops, p2k, node, seek);
PUFFSOP_SET(pops, p2k, node, remove);
PUFFSOP_SET(pops, p2k, node, link);
PUFFSOP_SET(pops, p2k, node, rename);
PUFFSOP_SET(pops, p2k, node, mkdir);
PUFFSOP_SET(pops, p2k, node, rmdir);
PUFFSOP_SET(pops, p2k, node, symlink);
PUFFSOP_SET(pops, p2k, node, readdir);
PUFFSOP_SET(pops, p2k, node, readlink);
PUFFSOP_SET(pops, p2k, node, read);
PUFFSOP_SET(pops, p2k, node, write);
PUFFSOP_SET(pops, p2k, node, inactive);
PUFFSOP_SET(pops, p2k, node, reclaim);
strcpy(typebuf, "p2k|");
if (strcmp(vfsname, "puffs") == 0) { /* XXX */
struct puffs_kargs *args = arg;
strlcat(typebuf, args->pa_typename, sizeof(typebuf));
} else {
strlcat(typebuf, vfsname, sizeof(typebuf));
}
pu = puffs_init(pops, devpath, typebuf, ukfs_getmp(ukfs), puffs_flags);
if (pu == NULL)
goto out;
rvp = ukfs_getrvp(ukfs);
pn_root = puffs_pn_new(pu, rvp);
puffs_setroot(pu, pn_root);
puffs_setfhsize(pu, 0, PUFFS_FHFLAG_PASSTHROUGH);
puffs_setstacksize(pu, PUFFS_STACKSIZE_MIN);
puffs_fakecc = 1;
puffs_set_prepost(pu, makelwp, clearlwp);
if ((rv = puffs_mount(pu, mountpath, mntflags, rvp))== -1)
goto out;
rv = puffs_mainloop(pu);
out:
sverrno = errno;
ukfs_release(ukfs, 0);
if (rv) {
errno = sverrno;
rv = -1;
}
return rv;
}
/* XXX: vn_lock() */
#define VLE(a) RUMP_VOP_LOCK(a, LK_EXCLUSIVE)
#define VLS(a) RUMP_VOP_LOCK(a, LK_SHARED)
#define VUL(a) RUMP_VOP_UNLOCK(a, 0);
#define AUL(a) assert(RUMP_VOP_ISLOCKED(a) == 0)
int
p2k_fs_statvfs(struct puffs_usermount *pu, struct statvfs *sbp)
{
struct mount *mp = puffs_getspecific(pu);
return rump_vfs_statvfs(mp, sbp);
}
int
p2k_fs_unmount(struct puffs_usermount *pu, int flags)
{
struct mount *mp = puffs_getspecific(pu);
struct puffs_node *pn_root = puffs_getroot(pu);
struct vnode *rvp = pn_root->pn_data, *rvp2;
int rv;
/*
* We recycle the root node already here (god knows how
* many references it has due to lookup). This is good
* because VFS_UNMOUNT would do it anyway. But it is
* very bad if VFS_UNMOUNT fails for a reason or another
* (puffs guards against busy fs, but there might be other
* reasons).
*
* Theoretically we're going south, sinking fast & dying
* out here because the old vnode will be freed and we are
* unlikely to get a vnode at the same address. But try
* anyway.
*
* XXX: reallyfixmesomeday. either introduce VFS_ROOT to
* puffs (blah) or check the cookie in every routine
* against the root cookie, which might change (blah2).
*/
rump_vp_recycle_nokidding(rvp);
rv = rump_vfs_unmount(mp, flags);
if (rv) {
int rv2;
rv2 = rump_vfs_root(mp, &rvp2, 0);
assert(rv2 == 0 && rvp == rvp2);
}
return rv;
}
int
p2k_fs_sync(struct puffs_usermount *pu, int waitfor,
const struct puffs_cred *pcr)
{
struct mount *mp = puffs_getspecific(pu);
kauth_cred_t cred;
int rv;
cred = cred_create(pcr);
rv = rump_vfs_sync(mp, waitfor, (kauth_cred_t)cred);
cred_destroy(cred);
rump_bioops_sync();
return rv;
}
int
p2k_fs_fhtonode(struct puffs_usermount *pu, void *fid, size_t fidsize,
struct puffs_newinfo *pni)
{
struct mount *mp = puffs_getspecific(pu);
struct vnode *vp;
enum vtype vtype;
voff_t vsize;
dev_t rdev;
int rv;
rv = rump_vfs_fhtovp(mp, fid, &vp);
if (rv)
return rv;
puffs_newinfo_setcookie(pni, vp);
rump_getvninfo(vp, &vtype, &vsize, &rdev);
puffs_newinfo_setvtype(pni, vtype);
puffs_newinfo_setsize(pni, vsize);
puffs_newinfo_setrdev(pni, rdev);
return 0;
}
int
p2k_fs_nodetofh(struct puffs_usermount *pu, void *cookie, void *fid,
size_t *fidsize)
{
struct vnode *vp = cookie;
return rump_vfs_vptofh(vp, fid, fidsize);
}
int
p2k_node_lookup(struct puffs_usermount *pu, void *opc,
struct puffs_newinfo *pni, const struct puffs_cn *pcn)
{
struct componentname *cn;
struct vnode *vp;
enum vtype vtype;
voff_t vsize;
dev_t rdev;
int rv;
cn = makecn(pcn);
VLE(opc);
rv = RUMP_VOP_LOOKUP(opc, &vp, cn);
VUL(opc);
freecn(cn, RUMPCN_ISLOOKUP);
if (rv) {
if (rv == EJUSTRETURN)
rv = ENOENT;
return rv;
}
VUL(vp);
puffs_newinfo_setcookie(pni, vp);
rump_getvninfo(vp, &vtype, &vsize, &rdev);
puffs_newinfo_setvtype(pni, vtype);
puffs_newinfo_setsize(pni, vsize);
puffs_newinfo_setrdev(pni, rdev);
return 0;
}
int
p2k_node_create(struct puffs_usermount *pu, void *opc,
struct puffs_newinfo *pni, const struct puffs_cn *pcn,
const struct vattr *vap)
{
struct componentname *cn;
struct vnode *vp;
int rv;
cn = makecn(pcn);
VLE(opc);
rump_vp_incref(opc);
rv = RUMP_VOP_CREATE(opc, &vp, cn, __UNCONST(vap));
AUL(opc);
freecn(cn, 0);
if (rv == 0) {
VUL(vp);
puffs_newinfo_setcookie(pni, vp);
}
return rv;
}
int
p2k_node_mknod(struct puffs_usermount *pu, void *opc, struct puffs_newinfo *pni,
const struct puffs_cn *pcn, const struct vattr *vap)
{
struct componentname *cn;
struct vnode *vp;
int rv;
cn = makecn(pcn);
VLE(opc);
rump_vp_incref(opc);
rv = RUMP_VOP_MKNOD(opc, &vp, cn, __UNCONST(vap));
AUL(opc);
freecn(cn, 0);
if (rv == 0) {
VUL(vp);
puffs_newinfo_setcookie(pni, vp);
}
return rv;
}
int
p2k_node_open(struct puffs_usermount *pu, void *opc, int mode,
const struct puffs_cred *pcr)
{
kauth_cred_t cred;
int rv;
cred = cred_create(pcr);
VLE(opc);
rv = RUMP_VOP_OPEN(opc, mode, cred);
VUL(opc);
cred_destroy(cred);
return rv;
}
int
p2k_node_close(struct puffs_usermount *pu, void *opc, int flags,
const struct puffs_cred *pcr)
{
kauth_cred_t cred;
int rv;
cred = cred_create(pcr);
VLE(opc);
rv = RUMP_VOP_CLOSE(opc, flags, cred);
VUL(opc);
cred_destroy(cred);
return 0;
}
int
p2k_node_access(struct puffs_usermount *pu, void *opc, int mode,
const struct puffs_cred *pcr)
{
kauth_cred_t cred;
int rv;
cred = cred_create(pcr);
VLE(opc);
rv = RUMP_VOP_ACCESS(opc, mode, cred);
VUL(opc);
cred_destroy(cred);
return rv;
}
int
p2k_node_getattr(struct puffs_usermount *pu, void *opc, struct vattr *vap,
const struct puffs_cred *pcr)
{
kauth_cred_t cred;
int rv;
cred = cred_create(pcr);
VLE(opc);
rv = RUMP_VOP_GETATTR(opc, vap, cred);
VUL(opc);
cred_destroy(cred);
return rv;
}
int
p2k_node_setattr(struct puffs_usermount *pu, void *opc, const struct vattr *vap,
const struct puffs_cred *pcr)
{
kauth_cred_t cred;
int rv;
cred = cred_create(pcr);
VLE(opc);
rv = RUMP_VOP_SETATTR(opc, __UNCONST(vap), cred);
VUL(opc);
cred_destroy(cred);
return rv;
}
int
p2k_node_fsync(struct puffs_usermount *pu, void *opc,
const struct puffs_cred *pcr, int flags, off_t offlo, off_t offhi)
{
kauth_cred_t cred;
int rv;
cred = cred_create(pcr);
VLE(opc);
rv = RUMP_VOP_FSYNC(opc, cred, flags, offlo, offhi);
VUL(opc);
cred_destroy(cred);
return rv;
}
int
p2k_node_mmap(struct puffs_usermount *pu, void *opc, vm_prot_t flags,
const struct puffs_cred *pcr)
{
kauth_cred_t cred;
int rv;
cred = cred_create(pcr);
rv = RUMP_VOP_MMAP(opc, flags, cred);
cred_destroy(cred);
return rv;
}
int
p2k_node_seek(struct puffs_usermount *pu, void *opc, off_t oldoff, off_t newoff,
const struct puffs_cred *pcr)
{
kauth_cred_t cred;
int rv;
cred = cred_create(pcr);
VLE(opc);
rv = RUMP_VOP_SEEK(opc, oldoff, newoff, cred);
VUL(opc);
cred_destroy(cred);
return rv;
}
int
p2k_node_remove(struct puffs_usermount *pu, void *opc, void *targ,
const struct puffs_cn *pcn)
{
struct componentname *cn;
int rv;
cn = makecn(pcn);
VLE(opc);
rump_vp_incref(opc);
VLE(targ);
rump_vp_incref(targ);
rv = RUMP_VOP_REMOVE(opc, targ, cn);
AUL(opc);
AUL(targ);
freecn(cn, 0);
return rv;
}
int
p2k_node_link(struct puffs_usermount *pu, void *opc, void *targ,
const struct puffs_cn *pcn)
{
struct componentname *cn;
int rv;
cn = makecn(pcn);
VLE(opc);
rump_vp_incref(opc);
rv = RUMP_VOP_LINK(opc, targ, cn);
freecn(cn, 0);
return rv;
}
int
p2k_node_rename(struct puffs_usermount *pu, void *src_dir, void *src,
const struct puffs_cn *pcn_src, void *targ_dir, void *targ,
const struct puffs_cn *pcn_targ)
{
struct componentname *cn_src, *cn_targ;
int rv;
cn_src = makecn(pcn_src);
cn_targ = makecn(pcn_targ);
rump_vp_incref(src_dir);
rump_vp_incref(src);
VLE(targ_dir);
rump_vp_incref(targ_dir);
if (targ) {
VLE(targ);
rump_vp_incref(targ);
}
rv = RUMP_VOP_RENAME(src_dir, src, cn_src, targ_dir, targ, cn_targ);
AUL(targ_dir);
if (targ)
AUL(targ);
freecn(cn_src, 0);
freecn(cn_targ, 0);
return rv;
}
int
p2k_node_mkdir(struct puffs_usermount *pu, void *opc, struct puffs_newinfo *pni,
const struct puffs_cn *pcn, const struct vattr *vap)
{
struct componentname *cn;
struct vnode *vp;
int rv;
cn = makecn(pcn);
VLE(opc);
rump_vp_incref(opc);
rv = RUMP_VOP_MKDIR(opc, &vp, cn, __UNCONST(vap));
AUL(opc);
freecn(cn, 0);
if (rv == 0) {
VUL(vp);
puffs_newinfo_setcookie(pni, vp);
}
return rv;
}
int
p2k_node_rmdir(struct puffs_usermount *pu, void *opc, void *targ,
const struct puffs_cn *pcn)
{
struct componentname *cn;
int rv;
cn = makecn(pcn);
VLE(opc);
rump_vp_incref(opc);
VLE(targ);
rump_vp_incref(targ);
rv = RUMP_VOP_RMDIR(opc, targ, cn);
AUL(targ);
AUL(opc);
freecn(cn, 0);
return rv;
}
int
p2k_node_symlink(struct puffs_usermount *pu, void *opc,
struct puffs_newinfo *pni, const struct puffs_cn *pcn_src,
const struct vattr *vap, const char *link_target)
{
struct componentname *cn;
struct vnode *vp;
int rv;
cn = makecn(pcn_src);
VLE(opc);
rump_vp_incref(opc);
rv = RUMP_VOP_SYMLINK(opc, &vp, cn,
__UNCONST(vap), __UNCONST(link_target));
AUL(opc);
freecn(cn, 0);
if (rv == 0) {
VUL(vp);
puffs_newinfo_setcookie(pni, vp);
}
return rv;
}
int
p2k_node_readdir(struct puffs_usermount *pu, void *opc, struct dirent *dent,
off_t *readoff, size_t *reslen, const struct puffs_cred *pcr,
int *eofflag, off_t *cookies, size_t *ncookies)
{
kauth_cred_t cred;
struct uio *uio;
off_t *vop_cookies;
int vop_ncookies;
int rv;
cred = cred_create(pcr);
uio = rump_uio_setup(dent, *reslen, *readoff, RUMPUIO_READ);
VLS(opc);
if (cookies) {
rv = RUMP_VOP_READDIR(opc, uio, cred, eofflag,
&vop_cookies, &vop_ncookies);
memcpy(cookies, vop_cookies, vop_ncookies * sizeof(*cookies));
*ncookies = vop_ncookies;
free(vop_cookies);
} else {
rv = RUMP_VOP_READDIR(opc, uio, cred, eofflag, NULL, NULL);
}
VUL(opc);
if (rv == 0) {
*reslen = rump_uio_getresid(uio);
*readoff = rump_uio_getoff(uio);
}
rump_uio_free(uio);
cred_destroy(cred);
return rv;
}
int
p2k_node_readlink(struct puffs_usermount *pu, void *opc,
const struct puffs_cred *pcr, char *linkname, size_t *linklen)
{
kauth_cred_t cred;
struct uio *uio;
int rv;
cred = cred_create(pcr);
uio = rump_uio_setup(linkname, *linklen, 0, RUMPUIO_READ);
VLE(opc);
rv = RUMP_VOP_READLINK(opc, uio, cred);
VUL(opc);
*linklen -= rump_uio_free(uio);
cred_destroy(cred);
return rv;
}
int
p2k_node_read(struct puffs_usermount *pu, void *opc,
uint8_t *buf, off_t offset, size_t *resid,
const struct puffs_cred *pcr, int ioflag)
{
kauth_cred_t cred;
struct uio *uio;
int rv;
cred = cred_create(pcr);
uio = rump_uio_setup(buf, *resid, offset, RUMPUIO_READ);
VLS(opc);
rv = RUMP_VOP_READ(opc, uio, ioflag, cred);
VUL(opc);
*resid = rump_uio_free(uio);
cred_destroy(cred);
return rv;
}
int
p2k_node_write(struct puffs_usermount *pu, void *opc,
uint8_t *buf, off_t offset, size_t *resid,
const struct puffs_cred *pcr, int ioflag)
{
kauth_cred_t cred;
struct uio *uio;
int rv;
cred = cred_create(pcr);
uio = rump_uio_setup(buf, *resid, offset, RUMPUIO_WRITE);
VLE(opc);
rv = RUMP_VOP_WRITE(opc, uio, ioflag, cred);
VUL(opc);
*resid = rump_uio_free(uio);
cred_destroy(cred);
return rv;
}
int
p2k_node_inactive(struct puffs_usermount *pu, void *opc)
{
struct vnode *vp = opc;
bool recycle;
int rv;
rump_vp_interlock(vp);
(void) RUMP_VOP_PUTPAGES(vp, 0, 0, PGO_ALLPAGES);
VLE(vp);
rv = RUMP_VOP_INACTIVE(vp, &recycle);
if (recycle)
puffs_setback(puffs_cc_getcc(pu), PUFFS_SETBACK_NOREF_N1);
return rv;
}
int
p2k_node_reclaim(struct puffs_usermount *pu, void *opc)
{
rump_vp_recycle_nokidding(opc);
return 0;
}

View File

@ -1,42 +0,0 @@
/* $NetBSD: p2k.h,v 1.4 2007/08/21 13:57:17 pooka Exp $ */
/*
* Copyright (c) 2007 Antti Kantee. All Rights Reserved.
*
* Development of this software was supported by Google Summer of Code.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _SYS_RUMPFS_P2K_H_
#define _SYS_RUMPFS_P2K_H_
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/vnode.h>
#include <puffs.h>
int p2k_run_fs(const char *, const char *, const char *, int,
void *, size_t, uint32_t);
#endif /* _SYS_RUMPFS_P2K_H_ */

View File

@ -1,15 +0,0 @@
# $NetBSD: Makefile,v 1.3 2007/09/02 12:00:12 pooka Exp $
#
.include <bsd.own.mk>
LIB= ukfs
SRCS= ukfs.c
RUMPKERNEL= no
CPPFLAGS+= -I${NETBSDSRCDIR}/sys/rump/librump/rumpkern \
-I${LIBRUMPDIR}
.include "${NETBSDSRCDIR}/sys/rump/Makefile.rump"
.include <bsd.lib.mk>

View File

@ -1,554 +0,0 @@
/* $NetBSD: ukfs.c,v 1.34 2008/07/22 20:02:16 pooka Exp $ */
/*
* Copyright (c) 2007 Antti Kantee. All Rights Reserved.
*
* Development of this software was supported by the
* Finnish Cultural Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* This library enables access to files systems directly without
* involving system calls.
*/
#ifdef __linux__
#define _XOPEN_SOURCE 500
#define _BSD_SOURCE
#define _FILE_OFFSET_BITS 64
#endif
#include <assert.h>
#include <err.h>
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include "ukfs.h"
#include "rump.h"
#include "rump_syscalls.h"
#define UKFS_MODE_DEFAULT 0555
struct ukfs {
struct mount *ukfs_mp;
struct vnode *ukfs_rvp;
pthread_spinlock_t ukfs_spin;
pid_t ukfs_nextpid;
struct vnode *ukfs_cdir;
};
struct mount *
ukfs_getmp(struct ukfs *ukfs)
{
return ukfs->ukfs_mp;
}
struct vnode *
ukfs_getrvp(struct ukfs *ukfs)
{
struct vnode *rvp;
rvp = ukfs->ukfs_rvp;
rump_vp_incref(rvp);
return rvp;
}
static pid_t
nextpid(struct ukfs *ukfs)
{
pid_t npid;
pthread_spin_lock(&ukfs->ukfs_spin);
npid = ukfs->ukfs_nextpid++;
pthread_spin_unlock(&ukfs->ukfs_spin);
return npid;
}
static void
precall(struct ukfs *ukfs)
{
struct vnode *rvp, *cvp;
rump_setup_curlwp(nextpid(ukfs), 1, 1);
rvp = ukfs_getrvp(ukfs);
pthread_spin_lock(&ukfs->ukfs_spin);
cvp = ukfs->ukfs_cdir;
pthread_spin_unlock(&ukfs->ukfs_spin);
rump_rcvp_set(rvp, cvp); /* takes refs */
ukfs_ll_rele(rvp);
}
static void
postcall(struct ukfs *ukfs)
{
struct vnode *rvp;
rvp = ukfs_getrvp(ukfs);
rump_rcvp_set(NULL, rvp);
ukfs_ll_rele(rvp);
rump_clear_curlwp();
}
int
ukfs_init()
{
rump_init();
return 0;
}
struct ukfs *
ukfs_mount(const char *vfsname, const char *devpath, const char *mountpath,
int mntflags, void *arg, size_t alen)
{
struct ukfs *fs = NULL;
struct vfsops *vfsops;
struct mount *mp;
int rv = 0;
vfsops = rump_vfs_getopsbyname(vfsname);
if (vfsops == NULL) {
rv = ENOENT;
goto out;
}
mp = rump_mnt_init(vfsops, mntflags);
fs = malloc(sizeof(struct ukfs));
if (fs == NULL) {
rv = ENOMEM;
goto out;
}
memset(fs, 0, sizeof(struct ukfs));
pthread_spin_init(&fs->ukfs_spin, PTHREAD_PROCESS_SHARED);
rump_fakeblk_register(devpath);
rv = rump_mnt_mount(mp, mountpath, arg, &alen);
rump_fakeblk_deregister(devpath);
if (rv) {
warnx("VFS_MOUNT %d", rv);
goto out;
}
fs->ukfs_mp = mp;
rv = rump_vfs_root(fs->ukfs_mp, &fs->ukfs_rvp, 0);
fs->ukfs_cdir = ukfs_getrvp(fs);
out:
if (rv) {
if (fs && fs->ukfs_mp)
rump_mnt_destroy(fs->ukfs_mp);
if (fs)
free(fs);
errno = rv;
fs = NULL;
}
return fs;
}
void
ukfs_release(struct ukfs *fs, int dounmount)
{
int rv;
/* XXX: dounmount is the same as !is_p2k, yetch! */
if (dounmount) {
ukfs_ll_rele(fs->ukfs_cdir);
rv = rump_vfs_sync(fs->ukfs_mp, 1, NULL);
rump_vp_recycle_nokidding(ukfs_getrvp(fs));
rv |= rump_vfs_unmount(fs->ukfs_mp, 0);
assert(rv == 0);
}
rump_vfs_syncwait(fs->ukfs_mp);
rump_mnt_destroy(fs->ukfs_mp);
pthread_spin_destroy(&fs->ukfs_spin);
free(fs);
}
/* don't need vn_lock(), since we don't have VXLOCK */
#define VLE(a) rump_vp_lock_exclusive(a)
#define VLS(a) rump_vp_lock_shared(a)
#define VUL(a) rump_vp_unlock(a)
#define AUL(a) assert(rump_vp_islocked(a) == 0)
/* free willy */
void
ukfs_ll_rele(struct vnode *vp)
{
rump_vp_rele(vp);
}
int
ukfs_ll_namei(struct ukfs *ukfs, uint32_t op, uint32_t flags, const char *name,
struct vnode **dvpp, struct vnode **vpp, struct componentname **cnpp)
{
int rv;
precall(ukfs);
rv = rump_namei(op, flags, name, dvpp, vpp, cnpp);
postcall(ukfs);
return rv;
}
#define STDCALL(ukfs, thecall) \
do { \
int rv = 0; \
\
precall(ukfs); \
thecall; \
postcall(ukfs); \
if (rv) { \
errno = rv; \
return -1; \
} \
return 0; \
} while (/*CONSTCOND*/0)
int
ukfs_getdents(struct ukfs *ukfs, const char *dirname, off_t *off,
uint8_t *buf, size_t bufsize)
{
struct uio *uio;
struct vnode *vp;
size_t resid;
int rv, eofflag;
rv = ukfs_ll_namei(ukfs, RUMP_NAMEI_LOOKUP, RUMP_NAMEI_LOCKLEAF,
dirname, NULL, &vp, NULL);
if (rv)
goto out;
uio = rump_uio_setup(buf, bufsize, *off, RUMPUIO_READ);
rv = RUMP_VOP_READDIR(vp, uio, NULL, &eofflag, NULL, NULL);
VUL(vp);
*off = rump_uio_getoff(uio);
resid = rump_uio_free(uio);
rump_vp_rele(vp);
out:
if (rv) {
errno = rv;
return -1;
}
return bufsize - resid;
}
ssize_t
ukfs_read(struct ukfs *ukfs, const char *filename, off_t off,
uint8_t *buf, size_t bufsize)
{
int fd, rv = 0, dummy;
ssize_t xfer = -1; /* XXXgcc */
precall(ukfs);
fd = rump_sys_open(filename, RUMP_O_RDONLY, 0, &rv);
if (rv)
goto out;
xfer = rump_sys_pread(fd, buf, bufsize, 0, off, &rv);
rump_sys_close(fd, &dummy);
out:
postcall(ukfs);
if (rv) {
errno = rv;
return -1;
}
return xfer;
}
ssize_t
ukfs_write(struct ukfs *ukfs, const char *filename, off_t off,
uint8_t *buf, size_t bufsize)
{
int fd, rv = 0, dummy;
ssize_t xfer = -1; /* XXXgcc */
precall(ukfs);
fd = rump_sys_open(filename, RUMP_O_WRONLY, 0, &rv);
if (rv)
goto out;
/* write and commit */
xfer = rump_sys_pwrite(fd, buf, bufsize, 0, off, &rv);
if (rv == 0)
rump_sys_fsync(fd, &dummy);
rump_sys_close(fd, &dummy);
out:
postcall(ukfs);
if (rv) {
errno = rv;
return -1;
}
return xfer;
}
int
ukfs_create(struct ukfs *ukfs, const char *filename, mode_t mode)
{
int rv, fd, dummy;
precall(ukfs);
fd = rump_sys_open(filename, RUMP_O_WRONLY | RUMP_O_CREAT, mode, &rv);
rump_sys_close(fd, &dummy);
postcall(ukfs);
if (rv) {
errno = rv;
return -1;
}
return 0;
}
int
ukfs_mknod(struct ukfs *ukfs, const char *path, mode_t mode, dev_t dev)
{
STDCALL(ukfs, rump_sys_mknod(path, mode, dev, &rv));
}
int
ukfs_mkfifo(struct ukfs *ukfs, const char *path, mode_t mode)
{
STDCALL(ukfs, rump_sys_mkfifo(path, mode, &rv));
}
int
ukfs_mkdir(struct ukfs *ukfs, const char *filename, mode_t mode)
{
STDCALL(ukfs, rump_sys_mkdir(filename, mode, &rv));
}
int
ukfs_remove(struct ukfs *ukfs, const char *filename)
{
STDCALL(ukfs, rump_sys_unlink(filename, &rv));
}
int
ukfs_rmdir(struct ukfs *ukfs, const char *filename)
{
STDCALL(ukfs, rump_sys_rmdir(filename, &rv));
}
int
ukfs_link(struct ukfs *ukfs, const char *filename, const char *f_create)
{
STDCALL(ukfs, rump_sys_link(filename, f_create, &rv));
}
int
ukfs_symlink(struct ukfs *ukfs, const char *filename, const char *linkname)
{
STDCALL(ukfs, rump_sys_symlink(filename, linkname, &rv));
}
ssize_t
ukfs_readlink(struct ukfs *ukfs, const char *filename,
char *linkbuf, size_t buflen)
{
ssize_t rv;
int myerr = 0;
precall(ukfs);
rv = rump_sys_readlink(filename, linkbuf, buflen, &myerr);
postcall(ukfs);
if (myerr) {
errno = rv;
return -1;
}
return rv;
}
int
ukfs_rename(struct ukfs *ukfs, const char *from, const char *to)
{
STDCALL(ukfs, rump_sys_rename(from, to, &rv));
}
int
ukfs_chdir(struct ukfs *ukfs, const char *path)
{
struct vnode *newvp, *oldvp;
int rv;
precall(ukfs);
rump_sys_chdir(path, &rv);
if (rv)
goto out;
newvp = rump_cdir_get();
pthread_spin_lock(&ukfs->ukfs_spin);
oldvp = ukfs->ukfs_cdir;
ukfs->ukfs_cdir = newvp;
pthread_spin_unlock(&ukfs->ukfs_spin);
if (oldvp)
ukfs_ll_rele(oldvp);
out:
postcall(ukfs);
if (rv) {
errno = rv;
return -1;
}
return 0;
}
int
ukfs_stat(struct ukfs *ukfs, const char *filename, struct stat *file_stat)
{
STDCALL(ukfs, rump_sys___stat30(filename, file_stat, &rv));
}
int
ukfs_lstat(struct ukfs *ukfs, const char *filename, struct stat *file_stat)
{
STDCALL(ukfs, rump_sys___lstat30(filename, file_stat, &rv));
}
int
ukfs_chmod(struct ukfs *ukfs, const char *filename, mode_t mode)
{
STDCALL(ukfs, rump_sys_chmod(filename, mode, &rv));
}
int
ukfs_lchmod(struct ukfs *ukfs, const char *filename, mode_t mode)
{
STDCALL(ukfs, rump_sys_lchmod(filename, mode, &rv));
}
int
ukfs_chown(struct ukfs *ukfs, const char *filename, uid_t uid, gid_t gid)
{
STDCALL(ukfs, rump_sys_chown(filename, uid, gid, &rv));
}
int
ukfs_lchown(struct ukfs *ukfs, const char *filename, uid_t uid, gid_t gid)
{
STDCALL(ukfs, rump_sys_lchown(filename, uid, gid, &rv));
}
int
ukfs_chflags(struct ukfs *ukfs, const char *filename, u_long flags)
{
STDCALL(ukfs, rump_sys_chflags(filename, flags, &rv));
}
int
ukfs_lchflags(struct ukfs *ukfs, const char *filename, u_long flags)
{
STDCALL(ukfs, rump_sys_lchflags(filename, flags, &rv));
}
int
ukfs_utimes(struct ukfs *ukfs, const char *filename, const struct timeval *tptr)
{
STDCALL(ukfs, rump_sys_utimes(filename, tptr, &rv));
}
int
ukfs_lutimes(struct ukfs *ukfs, const char *filename,
const struct timeval *tptr)
{
STDCALL(ukfs, rump_sys_lutimes(filename, tptr, &rv));
}
int
ukfs_util_builddirs(struct ukfs *ukfs, const char *filename, mode_t mode)
{
char *f1, *f2;
int rv;
mode_t mask;
bool end;
/*ukfs_umask((mask = ukfs_umask(0)));*/
umask((mask = umask(0)));
f1 = f2 = strdup(filename);
if (f1 == NULL) {
errno = ENOMEM;
return -1;
}
end = false;
for (;;) {
/* find next component */
f2 += strspn(f2, "/");
f2 += strcspn(f2, "/");
if (*f2 == '\0')
end = true;
else
*f2 = '\0';
rv = ukfs_mkdir(ukfs, f1, mode & ~mask);
if (errno == EEXIST)
rv = 0;
if (rv == -1 || *f2 != '\0' || end)
break;
*f2 = '/';
}
free(f1);
return rv;
}

View File

@ -1,98 +0,0 @@
/* $NetBSD: ukfs.h,v 1.14 2008/07/27 16:12:23 pooka Exp $ */
/*
* Copyright (c) 2007 Antti Kantee. All Rights Reserved.
*
* Development of this software was supported by the
* Finnish Cultural Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _SYS_RUMPFS_UKFS_H_
#define _SYS_RUMPFS_UKFS_H_
#include <sys/types.h>
#include <sys/stat.h>
#include <stdbool.h>
#include <stdint.h>
struct vnode;
struct ukfs;
#include "rump.h"
int ukfs_init(void);
struct ukfs *ukfs_mount(const char *, const char *, const char *,
int, void *, size_t);
void ukfs_release(struct ukfs *, int);
int ukfs_ll_namei(struct ukfs *, uint32_t, uint32_t, const char *,
struct vnode **, struct vnode **,
struct componentname **);
void ukfs_ll_rele(struct vnode *);
int ukfs_getdents(struct ukfs *, const char *, off_t *,
uint8_t *, size_t);
ssize_t ukfs_read(struct ukfs *, const char *, off_t,
uint8_t *, size_t);
ssize_t ukfs_write(struct ukfs *, const char *, off_t,
uint8_t *, size_t);
ssize_t ukfs_readlink(struct ukfs *, const char *, char *, size_t);
int ukfs_create(struct ukfs *, const char *, mode_t);
int ukfs_mkdir(struct ukfs *, const char *, mode_t);
int ukfs_mknod(struct ukfs *, const char *, mode_t, dev_t);
int ukfs_mkfifo(struct ukfs *, const char *, mode_t);
int ukfs_symlink(struct ukfs *, const char *, const char *);
int ukfs_remove(struct ukfs *, const char *);
int ukfs_rmdir(struct ukfs *, const char *);
int ukfs_link(struct ukfs *, const char *, const char *);
int ukfs_rename(struct ukfs *, const char *, const char *);
int ukfs_chdir(struct ukfs *, const char *);
int ukfs_stat(struct ukfs *, const char *, struct stat *);
int ukfs_lstat(struct ukfs *, const char *, struct stat *);
int ukfs_chmod(struct ukfs *, const char *, mode_t);
int ukfs_lchmod(struct ukfs *, const char *, mode_t);
int ukfs_chown(struct ukfs *, const char *, uid_t, gid_t);
int ukfs_lchown(struct ukfs *, const char *, uid_t, gid_t);
int ukfs_chflags(struct ukfs *, const char *, u_long);
int ukfs_lchflags(struct ukfs *, const char *, u_long);
int ukfs_utimes(struct ukfs *, const char *,
const struct timeval *);
int ukfs_lutimes(struct ukfs *, const char *,
const struct timeval *);
struct mount *ukfs_getmp(struct ukfs *);
struct vnode *ukfs_getrvp(struct ukfs *);
/* Utilities */
int ukfs_util_builddirs(struct ukfs *, const char *, mode_t);
#endif /* _SYS_RUMPFS_UKFS_H_ */