Example #1
0
/*
 * Mount the per-process file descriptors (/dev/fd)
 */
int
fdesc_mount(struct mount *mp, const char *path, void *data, size_t *data_len)
{
	struct lwp *l = curlwp;
	int error = 0;
	struct vnode *rvp;

	if (mp->mnt_flag & MNT_GETARGS) {
		*data_len = 0;
		return 0;
	}
	/*
	 * Update is a no-op
	 */
	if (mp->mnt_flag & MNT_UPDATE)
		return (EOPNOTSUPP);

	error = fdesc_allocvp(Froot, FD_ROOT, mp, &rvp);
	if (error)
		return (error);

	rvp->v_type = VDIR;
	rvp->v_vflag |= VV_ROOT;
	mp->mnt_stat.f_namemax = FDESC_MAXNAMLEN;
	mp->mnt_flag |= MNT_LOCAL;
	mp->mnt_data = rvp;
	vfs_getnewfsid(mp);

	error = set_statvfs_info(path, UIO_USERSPACE, "fdesc", UIO_SYSSPACE,
	    mp->mnt_op->vfs_name, mp, l);
	VOP_UNLOCK(rvp);
	return error;
}
Example #2
0
static int
fdesc_get_ino_alloc(struct mount *mp, void *arg, int lkflags,
    struct vnode **rvp)
{
	struct fdesc_get_ino_args *a;
	int error;

	a = arg;
	error = fdesc_allocvp(a->ftype, a->fd_fd, a->ix, mp, rvp);
	fdrop(a->fp, a->td);
	return (error);
}
Example #3
0
/*
 * Mount the per-process file descriptors (/dev/fd)
 */
static int
fdesc_mount(struct mount *mp)
{
	int error = 0;
	struct fdescmount *fmp;
	struct vnode *rvp;

	/*
	 * Update is a no-op
	 */
	if (mp->mnt_flag & (MNT_UPDATE | MNT_ROOTFS))
		return (EOPNOTSUPP);

	fmp = malloc(sizeof(struct fdescmount),
				M_FDESCMNT, M_WAITOK);	/* XXX */

	/*
	 * We need to initialize a few bits of our local mount point struct to
	 * avoid confusion in allocvp.
	 */
	mp->mnt_data = (qaddr_t) fmp;
	fmp->flags = 0;
	error = fdesc_allocvp(Froot, -1, FD_ROOT, mp, &rvp);
	if (error) {
		free(fmp, M_FDESCMNT);
		mp->mnt_data = 0;
		return (error);
	}
	rvp->v_type = VDIR;
	rvp->v_vflag |= VV_ROOT;
	fmp->f_root = rvp;
	VOP_UNLOCK(rvp, 0);
	/* XXX -- don't mark as local to work around fts() problems */
	/*mp->mnt_flag |= MNT_LOCAL;*/
	MNT_ILOCK(mp);
	mp->mnt_kern_flag |= MNTK_MPSAFE;
	MNT_IUNLOCK(mp);
	vfs_getnewfsid(mp);

	vfs_mountedfrom(mp, "fdescfs");
	return (0);
}
Example #4
0
/*
 * Mount the per-process file descriptors (/dev/fd)
 */
static int
fdesc_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
{
	int error = 0;
	struct fdescmount *fmp;
	struct vnode *rvp;

	if (path == NULL)
		panic("fdesc_mount: cannot mount as root");

	/*
	 * Update is a no-op
	 */
	if (mp->mnt_flag & MNT_UPDATE)
		return (EOPNOTSUPP);

	vfs_add_vnodeops(mp, &fdesc_vnode_vops, &mp->mnt_vn_norm_ops);

	error = fdesc_allocvp(Froot, FD_ROOT, mp, &rvp);
	if (error)
		return (error);

	fmp = kmalloc(sizeof(struct fdescmount), M_FDESCMNT, M_WAITOK);	/* XXX */
	rvp->v_type = VDIR;
	vsetflags(rvp, VROOT);
	fmp->f_root = rvp;
	/* XXX -- don't mark as local to work around fts() problems */
	/*mp->mnt_flag |= MNT_LOCAL;*/
	mp->mnt_data = (qaddr_t) fmp;
	vfs_getnewfsid(mp);

	bzero(mp->mnt_stat.f_mntfromname, MNAMELEN);
	bcopy("fdesc", mp->mnt_stat.f_mntfromname, sizeof("fdesc"));
	fdesc_statfs(mp, &mp->mnt_stat, cred);
	return (0);
}
Example #5
0
/*
 * vp is the current namei directory
 * ndp is the name to locate in that directory...
 *
 * fdesc_lookup(struct vnode *a_dvp, struct vnode **a_vpp,
 *		struct componentname *a_cnp)
 */
static int
fdesc_lookup(struct vop_old_lookup_args *ap)
{
	struct componentname *cnp = ap->a_cnp;
	struct thread *td = cnp->cn_td;
	struct proc *p = td->td_proc;
	struct vnode **vpp = ap->a_vpp;
	struct vnode *dvp = ap->a_dvp;
	char *pname = cnp->cn_nameptr;
	int nlen = cnp->cn_namelen;
	int nfiles;
	u_int fd;
	int error;
	struct vnode *fvp;

	KKASSERT(p);
	nfiles = p->p_fd->fd_nfiles;
	if (cnp->cn_nameiop == NAMEI_DELETE || cnp->cn_nameiop == NAMEI_RENAME) {
		error = EROFS;
		goto bad;
	}

	vn_unlock(dvp);
	if (cnp->cn_namelen == 1 && *pname == '.') {
		*vpp = dvp;
		vref(dvp);	
		vn_lock(dvp, LK_SHARED | LK_RETRY);
		return (0);
	}

	if (VTOFDESC(dvp)->fd_type != Froot) {
		error = ENOTDIR;
		goto bad;
	}

	fd = 0;
	/* the only time a leading 0 is acceptable is if it's "0" */
	if (*pname == '0' && nlen != 1) {
		error = ENOENT;
		goto bad;
	}
	while (nlen--) {
		if (*pname < '0' || *pname > '9') {
			error = ENOENT;
			goto bad;
		}
		fd = 10 * fd + *pname++ - '0';
	}

	if (fd >= nfiles || p->p_fd->fd_files[fd].fp == NULL) {
		error = EBADF;
		goto bad;
	}

	error = fdesc_allocvp(Fdesc, FD_DESC+fd, dvp->v_mount, &fvp);
	if (error)
		goto bad;
	VTOFDESC(fvp)->fd_fd = fd;
	vn_lock(fvp, LK_SHARED | LK_RETRY);
	*vpp = fvp;
	return (0);

bad:
	vn_lock(dvp, LK_SHARED | LK_RETRY);
	*vpp = NULL;
	return (error);
}