Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F160814450
D45305.id139105.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
28 KB
Referenced Files
None
Subscribers
None
D45305.id139105.diff
View Options
diff --git a/sys/kern/uipc_mqueue.c b/sys/kern/uipc_mqueue.c
--- a/sys/kern/uipc_mqueue.c
+++ b/sys/kern/uipc_mqueue.c
@@ -33,23 +33,6 @@
*
*/
-/*
- * POSIX message queue implementation.
- *
- * 1) A mqueue filesystem can be mounted, each message queue appears
- * in mounted directory, user can change queue's permission and
- * ownership, or remove a queue. Manually creating a file in the
- * directory causes a message queue to be created in the kernel with
- * default message queue attributes applied and same name used, this
- * method is not advocated since mq_open syscall allows user to specify
- * different attributes. Also the file system can be mounted multiple
- * times at different mount points but shows same contents.
- *
- * 2) Standard POSIX message queue API. The syscalls do not use vfs layer,
- * but directly operate on internal data structure, this allows user to
- * use the IPC facility without having to mount mqueue file system.
- */
-
#include "opt_capsicum.h"
#include <sys/param.h>
@@ -57,9 +40,7 @@
#include <sys/systm.h>
#include <sys/limits.h>
#include <sys/malloc.h>
-#include <sys/buf.h>
#include <sys/capsicum.h>
-#include <sys/dirent.h>
#include <sys/event.h>
#include <sys/eventhandler.h>
#include <sys/fcntl.h>
@@ -68,26 +49,25 @@
#include <sys/jail.h>
#include <sys/lock.h>
#include <sys/module.h>
-#include <sys/mount.h>
#include <sys/mqueue.h>
#include <sys/mutex.h>
-#include <sys/namei.h>
+#include <sys/proc.h>
#include <sys/posix4.h>
#include <sys/poll.h>
#include <sys/priv.h>
-#include <sys/proc.h>
#include <sys/queue.h>
-#include <sys/sysproto.h>
+#include <sys/selinfo.h>
#include <sys/stat.h>
+#include <sys/sysproto.h>
#include <sys/syscall.h>
#include <sys/syscallsubr.h>
#include <sys/sysent.h>
-#include <sys/sx.h>
#include <sys/sysctl.h>
-#include <sys/taskqueue.h>
#include <sys/unistd.h>
#include <sys/user.h>
#include <sys/vnode.h>
+#include <vm/vm.h>
+#include <vm/uma.h>
#include <machine/atomic.h>
#include <security/audit/audit.h>
@@ -122,13 +102,6 @@
struct unrhdr *mi_unrhdr;
};
-struct mqfs_vdata {
- LIST_ENTRY(mqfs_vdata) mv_link;
- struct mqfs_node *mv_node;
- struct vnode *mv_vnode;
- struct task mv_task;
-};
-
/*
* mqfs_node: describes a node (file or directory) within a mqfs
*/
@@ -197,7 +170,7 @@
};
static SYSCTL_NODE(_kern, OID_AUTO, mqueue, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
- "POSIX real time message queue");
+ "POSIX real time message queue");
static int default_maxmsg = 10;
SYSCTL_INT(_kern_mqueue, OID_AUTO, default_maxmsg, CTLFLAG_RD,
@@ -227,28 +200,15 @@
static struct mqfs_info mqfs_data;
static uma_zone_t mqnode_zone;
static uma_zone_t mqueue_zone;
-static uma_zone_t mvdata_zone;
static uma_zone_t mqnoti_zone;
-static struct vop_vector mqfs_vnodeops;
static struct fileops mqueueops;
static unsigned mqfs_osd_jail_slot;
-/*
- * Directory structure construction and manipulation
- */
-#ifdef notyet
-static struct mqfs_node *mqfs_create_dir(struct mqfs_node *parent,
- const char *name, int namelen, struct ucred *cred, int mode);
-static struct mqfs_node *mqfs_create_link(struct mqfs_node *parent,
- const char *name, int namelen, struct ucred *cred, int mode);
-#endif
-
static struct mqfs_node *mqfs_create_file(struct mqfs_node *parent,
const char *name, int namelen, struct ucred *cred, int mode);
static int mqfs_destroy(struct mqfs_node *mn);
static void mqfs_fileno_alloc(struct mqfs_info *mi, struct mqfs_node *mn);
static void mqfs_fileno_free(struct mqfs_info *mi, struct mqfs_node *mn);
-static int mqfs_allocv(struct mount *mp, struct vnode **vpp, struct mqfs_node *pn);
static int mqfs_prison_remove(void *obj, void *data);
/*
@@ -442,6 +402,27 @@
return (0);
}
+/*
+ * Search a directory entry
+ */
+static struct mqfs_node *
+mqfs_search(struct mqfs_node *pd, const char *name, int len, struct ucred *cred)
+{
+ struct mqfs_node *pn;
+ const void *pr_root;
+
+ sx_assert(&pd->mn_info->mi_lock, SX_LOCKED);
+ pr_root = cred->cr_prison->pr_root;
+ LIST_FOREACH(pn, &pd->mn_children, mn_sibling) {
+ /* Only match names within the same prison root directory */
+ if ((pn->mn_pr_root == NULL || pn->mn_pr_root == pr_root) &&
+ strncmp(pn->mn_name, name, len) == 0 &&
+ pn->mn_name[len] == '\0')
+ return (pn);
+ }
+ return (NULL);
+}
+
static struct mqfs_node *
mqfs_create_node(const char *name, int namelen, struct ucred *cred, int mode,
int nodetype)
@@ -479,79 +460,6 @@
return (node);
}
-/*
- * Add . and .. to a directory
- */
-static int
-mqfs_fixup_dir(struct mqfs_node *parent)
-{
- struct mqfs_node *dir;
-
- dir = mqnode_alloc();
- dir->mn_name[0] = '.';
- dir->mn_type = mqfstype_this;
- dir->mn_refcount = 1;
- if (mqfs_add_node(parent, dir) != 0) {
- mqnode_free(dir);
- return (-1);
- }
-
- dir = mqnode_alloc();
- dir->mn_name[0] = dir->mn_name[1] = '.';
- dir->mn_type = mqfstype_parent;
- dir->mn_refcount = 1;
-
- if (mqfs_add_node(parent, dir) != 0) {
- mqnode_free(dir);
- return (-1);
- }
-
- return (0);
-}
-
-#ifdef notyet
-
-/*
- * Create a directory
- */
-static struct mqfs_node *
-mqfs_create_dir(struct mqfs_node *parent, const char *name, int namelen,
- struct ucred *cred, int mode)
-{
- struct mqfs_node *node;
-
- node = mqfs_create_node(name, namelen, cred, mode, mqfstype_dir);
- if (mqfs_add_node(parent, node) != 0) {
- mqnode_free(node);
- return (NULL);
- }
-
- if (mqfs_fixup_dir(node) != 0) {
- mqfs_destroy(node);
- return (NULL);
- }
- return (node);
-}
-
-/*
- * Create a symlink
- */
-static struct mqfs_node *
-mqfs_create_link(struct mqfs_node *parent, const char *name, int namelen,
- struct ucred *cred, int mode)
-{
- struct mqfs_node *node;
-
- node = mqfs_create_node(name, namelen, cred, mode, mqfstype_symlink);
- if (mqfs_add_node(parent, node) != 0) {
- mqnode_free(node);
- return (NULL);
- }
- return (node);
-}
-
-#endif
-
/*
* Destroy a node or a tree of nodes
*/
@@ -585,77 +493,11 @@
return (0);
}
-/*
- * Mount a mqfs instance
- */
-static int
-mqfs_mount(struct mount *mp)
-{
- struct statfs *sbp;
-
- if (mp->mnt_flag & MNT_UPDATE)
- return (EOPNOTSUPP);
-
- mp->mnt_data = &mqfs_data;
- MNT_ILOCK(mp);
- mp->mnt_flag |= MNT_LOCAL;
- MNT_IUNLOCK(mp);
- vfs_getnewfsid(mp);
-
- sbp = &mp->mnt_stat;
- vfs_mountedfrom(mp, "mqueue");
- sbp->f_bsize = PAGE_SIZE;
- sbp->f_iosize = PAGE_SIZE;
- sbp->f_blocks = 1;
- sbp->f_bfree = 1;
- sbp->f_bavail = 0;
- sbp->f_files = 0;
- sbp->f_ffree = 0;
- return (0);
-}
-
-/*
- * Unmount a mqfs instance
- */
-static int
-mqfs_unmount(struct mount *mp, int mntflags)
-{
- int error;
-
- error = vflush(mp, 0, (mntflags & MNT_FORCE) ? FORCECLOSE : 0,
- curthread);
- return (error);
-}
-
-/*
- * Return a root vnode
- */
-static int
-mqfs_root(struct mount *mp, int flags, struct vnode **vpp)
-{
- struct mqfs_info *mqfs;
- int ret;
-
- mqfs = VFSTOMQFS(mp);
- ret = mqfs_allocv(mp, vpp, mqfs->mi_root);
- return (ret);
-}
-
-/*
- * Return filesystem stats
- */
-static int
-mqfs_statfs(struct mount *mp, struct statfs *sbp)
-{
- /* XXX update statistics */
- return (0);
-}
-
/*
* Initialize a mqfs instance
*/
-static int
-mqfs_init(struct vfsconf *vfc)
+static void
+mqfs_init(void)
{
struct mqfs_node *root;
struct mqfs_info *mi;
@@ -664,44 +506,36 @@
};
mqnode_zone = uma_zcreate("mqnode", sizeof(struct mqfs_node),
- NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
+ NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
mqueue_zone = uma_zcreate("mqueue", sizeof(struct mqueue),
- NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
- mvdata_zone = uma_zcreate("mvdata",
- sizeof(struct mqfs_vdata), NULL, NULL, NULL,
- NULL, UMA_ALIGN_PTR, 0);
+ NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
mqnoti_zone = uma_zcreate("mqnotifier", sizeof(struct mqueue_notifier),
- NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
+ NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
mi = &mqfs_data;
sx_init(&mi->mi_lock, "mqfs lock");
/* set up the root diretory */
root = mqfs_create_node("/", 1, curthread->td_ucred, 01777,
- mqfstype_root);
+ mqfstype_root);
root->mn_info = mi;
LIST_INIT(&root->mn_children);
- LIST_INIT(&root->mn_vnodes);
mi->mi_root = root;
mqfs_fileno_init(mi);
mqfs_fileno_alloc(mi, root);
- mqfs_fixup_dir(root);
exit_tag = EVENTHANDLER_REGISTER(process_exit, mq_proc_exit, NULL,
EVENTHANDLER_PRI_ANY);
mq_fdclose = mqueue_fdclose;
p31b_setcfg(CTL_P1003_1B_MESSAGE_PASSING, _POSIX_MESSAGE_PASSING);
mqfs_osd_jail_slot = osd_jail_register(NULL, methods);
- return (0);
}
/*
* Destroy a mqfs instance
*/
static int
-mqfs_uninit(struct vfsconf *vfc)
+mqfs_uninit(void)
{
struct mqfs_info *mi;
- if (!unloadable)
- return (EOPNOTSUPP);
osd_jail_deregister(mqfs_osd_jail_slot);
EVENTHANDLER_DEREGISTER(process_exit, exit_tag);
mi = &mqfs_data;
@@ -711,313 +545,10 @@
sx_destroy(&mi->mi_lock);
uma_zdestroy(mqnode_zone);
uma_zdestroy(mqueue_zone);
- uma_zdestroy(mvdata_zone);
uma_zdestroy(mqnoti_zone);
return (0);
}
-/*
- * task routine
- */
-static void
-do_recycle(void *context, int pending __unused)
-{
- struct vnode *vp = (struct vnode *)context;
-
- vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
- vrecycle(vp);
- VOP_UNLOCK(vp);
- vdrop(vp);
-}
-
-/*
- * Allocate a vnode
- */
-static int
-mqfs_allocv(struct mount *mp, struct vnode **vpp, struct mqfs_node *pn)
-{
- struct mqfs_vdata *vd;
- struct mqfs_info *mqfs;
- struct vnode *newvpp;
- int error;
-
- mqfs = pn->mn_info;
- *vpp = NULL;
- sx_xlock(&mqfs->mi_lock);
- LIST_FOREACH(vd, &pn->mn_vnodes, mv_link) {
- if (vd->mv_vnode->v_mount == mp) {
- vhold(vd->mv_vnode);
- break;
- }
- }
-
- if (vd != NULL) {
-found:
- *vpp = vd->mv_vnode;
- sx_xunlock(&mqfs->mi_lock);
- error = vget(*vpp, LK_RETRY | LK_EXCLUSIVE);
- vdrop(*vpp);
- return (error);
- }
- sx_xunlock(&mqfs->mi_lock);
-
- error = getnewvnode("mqueue", mp, &mqfs_vnodeops, &newvpp);
- if (error)
- return (error);
- vn_lock(newvpp, LK_EXCLUSIVE | LK_RETRY);
- error = insmntque(newvpp, mp);
- if (error != 0)
- return (error);
-
- sx_xlock(&mqfs->mi_lock);
- /*
- * Check if it has already been allocated
- * while we were blocked.
- */
- LIST_FOREACH(vd, &pn->mn_vnodes, mv_link) {
- if (vd->mv_vnode->v_mount == mp) {
- vhold(vd->mv_vnode);
- sx_xunlock(&mqfs->mi_lock);
-
- vgone(newvpp);
- vput(newvpp);
- goto found;
- }
- }
-
- *vpp = newvpp;
-
- vd = uma_zalloc(mvdata_zone, M_WAITOK);
- (*vpp)->v_data = vd;
- vd->mv_vnode = *vpp;
- vd->mv_node = pn;
- TASK_INIT(&vd->mv_task, 0, do_recycle, *vpp);
- LIST_INSERT_HEAD(&pn->mn_vnodes, vd, mv_link);
- mqnode_addref(pn);
- switch (pn->mn_type) {
- case mqfstype_root:
- (*vpp)->v_vflag = VV_ROOT;
- /* fall through */
- case mqfstype_dir:
- case mqfstype_this:
- case mqfstype_parent:
- (*vpp)->v_type = VDIR;
- break;
- case mqfstype_file:
- (*vpp)->v_type = VREG;
- break;
- case mqfstype_symlink:
- (*vpp)->v_type = VLNK;
- break;
- case mqfstype_none:
- KASSERT(0, ("mqfs_allocf called for null node\n"));
- default:
- panic("%s has unexpected type: %d", pn->mn_name, pn->mn_type);
- }
- sx_xunlock(&mqfs->mi_lock);
- vn_set_state(*vpp, VSTATE_CONSTRUCTED);
- return (0);
-}
-
-/*
- * Search a directory entry
- */
-static struct mqfs_node *
-mqfs_search(struct mqfs_node *pd, const char *name, int len, struct ucred *cred)
-{
- struct mqfs_node *pn;
- const void *pr_root;
-
- sx_assert(&pd->mn_info->mi_lock, SX_LOCKED);
- pr_root = cred->cr_prison->pr_root;
- LIST_FOREACH(pn, &pd->mn_children, mn_sibling) {
- /* Only match names within the same prison root directory */
- if ((pn->mn_pr_root == NULL || pn->mn_pr_root == pr_root) &&
- strncmp(pn->mn_name, name, len) == 0 &&
- pn->mn_name[len] == '\0')
- return (pn);
- }
- return (NULL);
-}
-
-/*
- * Look up a file or directory.
- */
-static int
-mqfs_lookupx(struct vop_cachedlookup_args *ap)
-{
- struct componentname *cnp;
- struct vnode *dvp, **vpp;
- struct mqfs_node *pd;
- struct mqfs_node *pn;
- struct mqfs_info *mqfs;
- int nameiop, flags, error, namelen;
- char *pname;
- struct thread *td;
-
- td = curthread;
- cnp = ap->a_cnp;
- vpp = ap->a_vpp;
- dvp = ap->a_dvp;
- pname = cnp->cn_nameptr;
- namelen = cnp->cn_namelen;
- flags = cnp->cn_flags;
- nameiop = cnp->cn_nameiop;
- pd = VTON(dvp);
- pn = NULL;
- mqfs = pd->mn_info;
- *vpp = NULLVP;
-
- if (dvp->v_type != VDIR)
- return (ENOTDIR);
-
- error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, td);
- if (error)
- return (error);
-
- /* shortcut: check if the name is too long */
- if (cnp->cn_namelen >= MQFS_NAMELEN)
- return (ENOENT);
-
- /* self */
- if (namelen == 1 && pname[0] == '.') {
- if ((flags & ISLASTCN) && nameiop != LOOKUP)
- return (EINVAL);
- pn = pd;
- *vpp = dvp;
- VREF(dvp);
- return (0);
- }
-
- /* parent */
- if (cnp->cn_flags & ISDOTDOT) {
- if (dvp->v_vflag & VV_ROOT)
- return (EIO);
- if ((flags & ISLASTCN) && nameiop != LOOKUP)
- return (EINVAL);
- VOP_UNLOCK(dvp);
- KASSERT(pd->mn_parent, ("non-root directory has no parent"));
- pn = pd->mn_parent;
- error = mqfs_allocv(dvp->v_mount, vpp, pn);
- vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
- return (error);
- }
-
- /* named node */
- sx_xlock(&mqfs->mi_lock);
- pn = mqfs_search(pd, pname, namelen, cnp->cn_cred);
- if (pn != NULL)
- mqnode_addref(pn);
- sx_xunlock(&mqfs->mi_lock);
-
- /* found */
- if (pn != NULL) {
- /* DELETE */
- if (nameiop == DELETE && (flags & ISLASTCN)) {
- error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td);
- if (error) {
- mqnode_release(pn);
- return (error);
- }
- if (*vpp == dvp) {
- VREF(dvp);
- *vpp = dvp;
- mqnode_release(pn);
- return (0);
- }
- }
-
- /* allocate vnode */
- error = mqfs_allocv(dvp->v_mount, vpp, pn);
- mqnode_release(pn);
- if (error == 0 && cnp->cn_flags & MAKEENTRY)
- cache_enter(dvp, *vpp, cnp);
- return (error);
- }
-
- /* not found */
-
- /* will create a new entry in the directory ? */
- if ((nameiop == CREATE || nameiop == RENAME) && (flags & LOCKPARENT)
- && (flags & ISLASTCN)) {
- error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td);
- if (error)
- return (error);
- return (EJUSTRETURN);
- }
- return (ENOENT);
-}
-
-#if 0
-struct vop_lookup_args {
- struct vop_generic_args a_gen;
- struct vnode *a_dvp;
- struct vnode **a_vpp;
- struct componentname *a_cnp;
-};
-#endif
-
-/*
- * vnode lookup operation
- */
-static int
-mqfs_lookup(struct vop_cachedlookup_args *ap)
-{
- int rc;
-
- rc = mqfs_lookupx(ap);
- return (rc);
-}
-
-#if 0
-struct vop_create_args {
- struct vnode *a_dvp;
- struct vnode **a_vpp;
- struct componentname *a_cnp;
- struct vattr *a_vap;
-};
-#endif
-
-/*
- * vnode creation operation
- */
-static int
-mqfs_create(struct vop_create_args *ap)
-{
- struct mqfs_info *mqfs = VFSTOMQFS(ap->a_dvp->v_mount);
- struct componentname *cnp = ap->a_cnp;
- struct mqfs_node *pd;
- struct mqfs_node *pn;
- struct mqueue *mq;
- int error;
-
- pd = VTON(ap->a_dvp);
- if (pd->mn_type != mqfstype_root && pd->mn_type != mqfstype_dir)
- return (ENOTDIR);
- mq = mqueue_alloc(NULL);
- if (mq == NULL)
- return (EAGAIN);
- sx_xlock(&mqfs->mi_lock);
- pn = mqfs_create_file(pd, cnp->cn_nameptr, cnp->cn_namelen,
- cnp->cn_cred, ap->a_vap->va_mode);
- if (pn == NULL) {
- sx_xunlock(&mqfs->mi_lock);
- error = ENOSPC;
- } else {
- mqnode_addref(pn);
- sx_xunlock(&mqfs->mi_lock);
- error = mqfs_allocv(ap->a_dvp->v_mount, ap->a_vpp, pn);
- mqnode_release(pn);
- if (error)
- mqfs_destroy(pn);
- else
- pn->mn_data = mq;
- }
- if (error)
- mqueue_free(mq);
- return (error);
-}
-
/*
* Remove an entry
*/
@@ -1025,7 +556,6 @@
do_unlink(struct mqfs_node *pn, struct ucred *ucred)
{
struct mqfs_node *parent;
- struct mqfs_vdata *vd;
int error = 0;
sx_assert(&pn->mn_info->mi_lock, SX_LOCKED);
@@ -1038,11 +568,6 @@
pn->mn_parent = NULL;
pn->mn_deleted = 1;
LIST_REMOVE(pn, mn_sibling);
- LIST_FOREACH(vd, &pn->mn_vnodes, mv_link) {
- cache_purge(vd->mv_vnode);
- vhold(vd->mv_vnode);
- taskqueue_enqueue(taskqueue_thread, &vd->mv_task);
- }
mqnode_release(pn);
mqnode_release(parent);
} else
@@ -1050,508 +575,6 @@
return (error);
}
-#if 0
-struct vop_remove_args {
- struct vnode *a_dvp;
- struct vnode *a_vp;
- struct componentname *a_cnp;
-};
-#endif
-
-/*
- * vnode removal operation
- */
-static int
-mqfs_remove(struct vop_remove_args *ap)
-{
- struct mqfs_info *mqfs = VFSTOMQFS(ap->a_dvp->v_mount);
- struct mqfs_node *pn;
- int error;
-
- if (ap->a_vp->v_type == VDIR)
- return (EPERM);
- pn = VTON(ap->a_vp);
- sx_xlock(&mqfs->mi_lock);
- error = do_unlink(pn, ap->a_cnp->cn_cred);
- sx_xunlock(&mqfs->mi_lock);
- return (error);
-}
-
-#if 0
-struct vop_inactive_args {
- struct vnode *a_vp;
- struct thread *a_td;
-};
-#endif
-
-static int
-mqfs_inactive(struct vop_inactive_args *ap)
-{
- struct mqfs_node *pn = VTON(ap->a_vp);
-
- if (pn->mn_deleted)
- vrecycle(ap->a_vp);
- return (0);
-}
-
-#if 0
-struct vop_reclaim_args {
- struct vop_generic_args a_gen;
- struct vnode *a_vp;
-};
-#endif
-
-static int
-mqfs_reclaim(struct vop_reclaim_args *ap)
-{
- struct mqfs_info *mqfs = VFSTOMQFS(ap->a_vp->v_mount);
- struct vnode *vp = ap->a_vp;
- struct mqfs_node *pn;
- struct mqfs_vdata *vd;
-
- vd = vp->v_data;
- pn = vd->mv_node;
- sx_xlock(&mqfs->mi_lock);
- vp->v_data = NULL;
- LIST_REMOVE(vd, mv_link);
- mqnode_release(pn);
- sx_xunlock(&mqfs->mi_lock);
- uma_zfree(mvdata_zone, vd);
- return (0);
-}
-
-#if 0
-struct vop_open_args {
- struct vop_generic_args a_gen;
- struct vnode *a_vp;
- int a_mode;
- struct ucred *a_cred;
- struct thread *a_td;
- struct file *a_fp;
-};
-#endif
-
-static int
-mqfs_open(struct vop_open_args *ap)
-{
- return (0);
-}
-
-#if 0
-struct vop_close_args {
- struct vop_generic_args a_gen;
- struct vnode *a_vp;
- int a_fflag;
- struct ucred *a_cred;
- struct thread *a_td;
-};
-#endif
-
-static int
-mqfs_close(struct vop_close_args *ap)
-{
- return (0);
-}
-
-#if 0
-struct vop_access_args {
- struct vop_generic_args a_gen;
- struct vnode *a_vp;
- accmode_t a_accmode;
- struct ucred *a_cred;
- struct thread *a_td;
-};
-#endif
-
-/*
- * Verify permissions
- */
-static int
-mqfs_access(struct vop_access_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct vattr vattr;
- int error;
-
- error = VOP_GETATTR(vp, &vattr, ap->a_cred);
- if (error)
- return (error);
- error = vaccess(vp->v_type, vattr.va_mode, vattr.va_uid, vattr.va_gid,
- ap->a_accmode, ap->a_cred);
- return (error);
-}
-
-#if 0
-struct vop_getattr_args {
- struct vop_generic_args a_gen;
- struct vnode *a_vp;
- struct vattr *a_vap;
- struct ucred *a_cred;
-};
-#endif
-
-/*
- * Get file attributes
- */
-static int
-mqfs_getattr(struct vop_getattr_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct mqfs_node *pn = VTON(vp);
- struct vattr *vap = ap->a_vap;
- int error = 0;
-
- vap->va_type = vp->v_type;
- vap->va_mode = pn->mn_mode;
- vap->va_nlink = 1;
- vap->va_uid = pn->mn_uid;
- vap->va_gid = pn->mn_gid;
- vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
- vap->va_fileid = pn->mn_fileno;
- vap->va_size = 0;
- vap->va_blocksize = PAGE_SIZE;
- vap->va_bytes = vap->va_size = 0;
- vap->va_atime = pn->mn_atime;
- vap->va_mtime = pn->mn_mtime;
- vap->va_ctime = pn->mn_ctime;
- vap->va_birthtime = pn->mn_birth;
- vap->va_gen = 0;
- vap->va_flags = 0;
- vap->va_rdev = NODEV;
- vap->va_bytes = 0;
- vap->va_filerev = 0;
- return (error);
-}
-
-#if 0
-struct vop_setattr_args {
- struct vop_generic_args a_gen;
- struct vnode *a_vp;
- struct vattr *a_vap;
- struct ucred *a_cred;
-};
-#endif
-/*
- * Set attributes
- */
-static int
-mqfs_setattr(struct vop_setattr_args *ap)
-{
- struct mqfs_node *pn;
- struct vattr *vap;
- struct vnode *vp;
- struct thread *td;
- int c, error;
- uid_t uid;
- gid_t gid;
-
- td = curthread;
- vap = ap->a_vap;
- vp = ap->a_vp;
- if (vap->va_type != VNON ||
- vap->va_nlink != VNOVAL ||
- vap->va_fsid != VNOVAL ||
- vap->va_fileid != VNOVAL ||
- vap->va_blocksize != VNOVAL ||
- (vap->va_flags != VNOVAL && vap->va_flags != 0) ||
- vap->va_rdev != VNOVAL ||
- (int)vap->va_bytes != VNOVAL ||
- vap->va_gen != VNOVAL) {
- return (EINVAL);
- }
-
- pn = VTON(vp);
-
- error = c = 0;
- if (vap->va_uid == (uid_t)VNOVAL)
- uid = pn->mn_uid;
- else
- uid = vap->va_uid;
- if (vap->va_gid == (gid_t)VNOVAL)
- gid = pn->mn_gid;
- else
- gid = vap->va_gid;
-
- if (uid != pn->mn_uid || gid != pn->mn_gid) {
- /*
- * To modify the ownership of a file, must possess VADMIN
- * for that file.
- */
- if ((error = VOP_ACCESS(vp, VADMIN, ap->a_cred, td)))
- return (error);
-
- /*
- * XXXRW: Why is there a privilege check here: shouldn't the
- * check in VOP_ACCESS() be enough? Also, are the group bits
- * below definitely right?
- */
- if ((ap->a_cred->cr_uid != pn->mn_uid || uid != pn->mn_uid ||
- (gid != pn->mn_gid && !groupmember(gid, ap->a_cred))) &&
- (error = priv_check(td, PRIV_MQ_ADMIN)) != 0)
- return (error);
- pn->mn_uid = uid;
- pn->mn_gid = gid;
- c = 1;
- }
-
- if (vap->va_mode != (mode_t)VNOVAL) {
- if (ap->a_cred->cr_uid != pn->mn_uid &&
- (error = priv_check(td, PRIV_MQ_ADMIN)))
- return (error);
- pn->mn_mode = vap->va_mode;
- c = 1;
- }
-
- if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
- /* See the comment in ufs_vnops::ufs_setattr(). */
- if ((error = VOP_ACCESS(vp, VADMIN, ap->a_cred, td)) &&
- ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
- (error = VOP_ACCESS(vp, VWRITE, ap->a_cred, td))))
- return (error);
- if (vap->va_atime.tv_sec != VNOVAL) {
- pn->mn_atime = vap->va_atime;
- }
- if (vap->va_mtime.tv_sec != VNOVAL) {
- pn->mn_mtime = vap->va_mtime;
- }
- c = 1;
- }
- if (c) {
- vfs_timestamp(&pn->mn_ctime);
- }
- return (0);
-}
-
-#if 0
-struct vop_read_args {
- struct vop_generic_args a_gen;
- struct vnode *a_vp;
- struct uio *a_uio;
- int a_ioflag;
- struct ucred *a_cred;
-};
-#endif
-
-/*
- * Read from a file
- */
-static int
-mqfs_read(struct vop_read_args *ap)
-{
- char buf[80];
- struct vnode *vp = ap->a_vp;
- struct uio *uio = ap->a_uio;
- struct mqueue *mq;
- int len, error;
-
- if (vp->v_type != VREG)
- return (EINVAL);
-
- mq = VTOMQ(vp);
- snprintf(buf, sizeof(buf),
- "QSIZE:%-10ld MAXMSG:%-10ld CURMSG:%-10ld MSGSIZE:%-10ld\n",
- mq->mq_totalbytes,
- mq->mq_maxmsg,
- mq->mq_curmsgs,
- mq->mq_msgsize);
- buf[sizeof(buf)-1] = '\0';
- len = strlen(buf);
- error = uiomove_frombuf(buf, len, uio);
- return (error);
-}
-
-#if 0
-struct vop_readdir_args {
- struct vop_generic_args a_gen;
- struct vnode *a_vp;
- struct uio *a_uio;
- struct ucred *a_cred;
- int *a_eofflag;
- int *a_ncookies;
- uint64_t **a_cookies;
-};
-#endif
-
-/*
- * Return directory entries.
- */
-static int
-mqfs_readdir(struct vop_readdir_args *ap)
-{
- struct vnode *vp;
- struct mqfs_info *mi;
- struct mqfs_node *pd;
- struct mqfs_node *pn;
- struct dirent entry;
- struct uio *uio;
- const void *pr_root;
- int *tmp_ncookies = NULL;
- off_t offset;
- int error, i;
-
- vp = ap->a_vp;
- mi = VFSTOMQFS(vp->v_mount);
- pd = VTON(vp);
- uio = ap->a_uio;
-
- if (vp->v_type != VDIR)
- return (ENOTDIR);
-
- if (uio->uio_offset < 0)
- return (EINVAL);
-
- if (ap->a_ncookies != NULL) {
- tmp_ncookies = ap->a_ncookies;
- *ap->a_ncookies = 0;
- ap->a_ncookies = NULL;
- }
-
- error = 0;
- offset = 0;
-
- pr_root = ap->a_cred->cr_prison->pr_root;
- sx_xlock(&mi->mi_lock);
-
- LIST_FOREACH(pn, &pd->mn_children, mn_sibling) {
- entry.d_reclen = sizeof(entry);
-
- /*
- * Only show names within the same prison root directory
- * (or not associated with a prison, e.g. "." and "..").
- */
- if (pn->mn_pr_root != NULL && pn->mn_pr_root != pr_root)
- continue;
- if (!pn->mn_fileno)
- mqfs_fileno_alloc(mi, pn);
- entry.d_fileno = pn->mn_fileno;
- entry.d_off = offset + entry.d_reclen;
- for (i = 0; i < MQFS_NAMELEN - 1 && pn->mn_name[i] != '\0'; ++i)
- entry.d_name[i] = pn->mn_name[i];
- entry.d_namlen = i;
- switch (pn->mn_type) {
- case mqfstype_root:
- case mqfstype_dir:
- case mqfstype_this:
- case mqfstype_parent:
- entry.d_type = DT_DIR;
- break;
- case mqfstype_file:
- entry.d_type = DT_REG;
- break;
- case mqfstype_symlink:
- entry.d_type = DT_LNK;
- break;
- default:
- panic("%s has unexpected node type: %d", pn->mn_name,
- pn->mn_type);
- }
- dirent_terminate(&entry);
- if (entry.d_reclen > uio->uio_resid)
- break;
- if (offset >= uio->uio_offset) {
- error = vfs_read_dirent(ap, &entry, offset);
- if (error)
- break;
- }
- offset += entry.d_reclen;
- }
- sx_xunlock(&mi->mi_lock);
-
- uio->uio_offset = offset;
-
- if (tmp_ncookies != NULL)
- ap->a_ncookies = tmp_ncookies;
-
- return (error);
-}
-
-#ifdef notyet
-
-#if 0
-struct vop_mkdir_args {
- struct vnode *a_dvp;
- struvt vnode **a_vpp;
- struvt componentname *a_cnp;
- struct vattr *a_vap;
-};
-#endif
-
-/*
- * Create a directory.
- */
-static int
-mqfs_mkdir(struct vop_mkdir_args *ap)
-{
- struct mqfs_info *mqfs = VFSTOMQFS(ap->a_dvp->v_mount);
- struct componentname *cnp = ap->a_cnp;
- struct mqfs_node *pd = VTON(ap->a_dvp);
- struct mqfs_node *pn;
- int error;
-
- if (pd->mn_type != mqfstype_root && pd->mn_type != mqfstype_dir)
- return (ENOTDIR);
- sx_xlock(&mqfs->mi_lock);
- pn = mqfs_create_dir(pd, cnp->cn_nameptr, cnp->cn_namelen,
- ap->a_vap->cn_cred, ap->a_vap->va_mode);
- if (pn != NULL)
- mqnode_addref(pn);
- sx_xunlock(&mqfs->mi_lock);
- if (pn == NULL) {
- error = ENOSPC;
- } else {
- error = mqfs_allocv(ap->a_dvp->v_mount, ap->a_vpp, pn);
- mqnode_release(pn);
- }
- return (error);
-}
-
-#if 0
-struct vop_rmdir_args {
- struct vnode *a_dvp;
- struct vnode *a_vp;
- struct componentname *a_cnp;
-};
-#endif
-
-/*
- * Remove a directory.
- */
-static int
-mqfs_rmdir(struct vop_rmdir_args *ap)
-{
- struct mqfs_info *mqfs = VFSTOMQFS(ap->a_dvp->v_mount);
- struct mqfs_node *pn = VTON(ap->a_vp);
- struct mqfs_node *pt;
-
- if (pn->mn_type != mqfstype_dir)
- return (ENOTDIR);
-
- sx_xlock(&mqfs->mi_lock);
- if (pn->mn_deleted) {
- sx_xunlock(&mqfs->mi_lock);
- return (ENOENT);
- }
-
- pt = LIST_FIRST(&pn->mn_children);
- pt = LIST_NEXT(pt, mn_sibling);
- pt = LIST_NEXT(pt, mn_sibling);
- if (pt != NULL) {
- sx_xunlock(&mqfs->mi_lock);
- return (ENOTEMPTY);
- }
- pt = pn->mn_parent;
- pn->mn_parent = NULL;
- pn->mn_deleted = 1;
- LIST_REMOVE(pn, mn_sibling);
- mqnode_release(pn);
- mqnode_release(pt);
- sx_xunlock(&mqfs->mi_lock);
- cache_purge(ap->a_vp);
- return (0);
-}
-
-#endif /* notyet */
-
/*
* See if this prison root is obsolete, and clean up associated queues if it is.
*/
@@ -1665,7 +688,7 @@
int error;
error = copyout(((char *)msg) + sizeof(*msg), msg_ptr,
- msg->msg_size);
+ msg->msg_size);
if (error == 0 && msg_prio != NULL)
error = copyout(&msg->msg_prio, msg_prio, sizeof(int));
return (error);
@@ -2698,44 +1721,6 @@
.fo_flags = DFLAG_PASSABLE,
};
-static struct vop_vector mqfs_vnodeops = {
- .vop_default = &default_vnodeops,
- .vop_access = mqfs_access,
- .vop_cachedlookup = mqfs_lookup,
- .vop_lookup = vfs_cache_lookup,
- .vop_reclaim = mqfs_reclaim,
- .vop_create = mqfs_create,
- .vop_remove = mqfs_remove,
- .vop_inactive = mqfs_inactive,
- .vop_open = mqfs_open,
- .vop_close = mqfs_close,
- .vop_getattr = mqfs_getattr,
- .vop_setattr = mqfs_setattr,
- .vop_read = mqfs_read,
- .vop_write = VOP_EOPNOTSUPP,
- .vop_readdir = mqfs_readdir,
- .vop_mkdir = VOP_EOPNOTSUPP,
- .vop_rmdir = VOP_EOPNOTSUPP
-};
-VFS_VOP_VECTOR_REGISTER(mqfs_vnodeops);
-
-static struct vfsops mqfs_vfsops = {
- .vfs_init = mqfs_init,
- .vfs_uninit = mqfs_uninit,
- .vfs_mount = mqfs_mount,
- .vfs_unmount = mqfs_unmount,
- .vfs_root = mqfs_root,
- .vfs_statfs = mqfs_statfs,
-};
-
-static struct vfsconf mqueuefs_vfsconf = {
- .vfc_version = VFS_VERSION,
- .vfc_name = "mqueuefs",
- .vfc_vfsops = &mqfs_vfsops,
- .vfc_typenum = -1,
- .vfc_flags = VFCF_SYNTHETIC
-};
-
static struct syscall_helper_data mq_syscalls[] = {
SYSCALL_INIT_HELPER(kmq_open),
SYSCALL_INIT_HELPER_F(kmq_setattr, SYF_CAPENABLED),
@@ -2897,6 +1882,7 @@
{
int error;
+ mqfs_init();
error = syscall_helper_register(mq_syscalls, SY_THR_STATIC_KLD);
if (error != 0)
return (error);
@@ -2912,10 +1898,15 @@
mqunload(void)
{
+ if (!unloadable)
+ return (EOPNOTSUPP);
+
#ifdef COMPAT_FREEBSD32
syscall32_helper_unregister(mq32_syscalls);
#endif
syscall_helper_unregister(mq_syscalls);
+
+ mqfs_uninit();
return (0);
}
@@ -2924,10 +1915,6 @@
{
int error = 0;
- error = vfs_modevent(module, cmd, arg);
- if (error != 0)
- return (error);
-
switch (cmd) {
case MOD_LOAD:
error = mqinit();
@@ -2946,7 +1933,7 @@
static moduledata_t mqueuefs_mod = {
"mqueuefs",
mq_modload,
- &mqueuefs_vfsconf
+ NULL
};
DECLARE_MODULE(mqueuefs, mqueuefs_mod, SI_SUB_VFS, SI_ORDER_MIDDLE);
MODULE_VERSION(mqueuefs, 1);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Jun 29, 4:08 AM (15 h, 12 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34452264
Default Alt Text
D45305.id139105.diff (28 KB)
Attached To
Mode
D45305: mqueuefs: remove
Attached
Detach File
Event Timeline
Log In to Comment