Esempio n. 1
0
void
vnclear(struct vn_softc *vn, vfs_context_t ctx)
{
	if (vn->sc_vp != NULL) {
		/* release long-term reference */
		(void)vn_close(vn->sc_vp, vn->sc_open_flags, ctx);
		vn->sc_vp = NULL;
	}
	if (vn->sc_shadow_vp != NULL) {
		/* release long-term reference */
		(void)vn_close(vn->sc_shadow_vp, FREAD | FWRITE, ctx);
		vn->sc_shadow_vp = NULL;
	}
	if (vn->sc_shadow_map != NULL) {
		shadow_map_free(vn->sc_shadow_map);
		vn->sc_shadow_map = NULL;
	}
	vn->sc_flags &= ~(VNF_INITED | VNF_READONLY);
	if (vn->sc_cred) {
		kauth_cred_unref(&vn->sc_cred);
	}
	vn->sc_size = 0;
	vn->sc_fsize = 0;
	if (vn->sc_cdev) {
		devfs_remove(vn->sc_cdev);
		vn->sc_cdev = NULL;
	}
}
Esempio n. 2
0
/*
 * Accounting system call.  Written based on the specification and
 * previous implementation done by Mark Tinguely.
 */
int
sys_acct(struct proc *p, void *v, register_t *retval)
{
	struct sys_acct_args /* {
		syscallarg(const char *) path;
	} */ *uap = v;
	struct nameidata nd;
	int error;

	/* Make sure that the caller is root. */
	if ((error = suser(p, 0)) != 0)
		return (error);

	/*
	 * If accounting is to be started to a file, open that file for
	 * writing and make sure it's 'normal'.
	 */
	if (SCARG(uap, path) != NULL) {
		NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path),
		    p);
		if ((error = vn_open(&nd, FWRITE|O_APPEND, 0)) != 0)
			return (error);
		VOP_UNLOCK(nd.ni_vp, 0);
		if (nd.ni_vp->v_type != VREG) {
			vn_close(nd.ni_vp, FWRITE, p->p_ucred, p);
			return (EACCES);
		}
	}

	/*
	 * If accounting was previously enabled, kill the old space-watcher,
	 * close the file, and (if no new file was specified, leave).
	 */
	if (acctp != NULL || savacctp != NULL) {
		wakeup(&acct_proc);
		error = vn_close((acctp != NULL ? acctp : savacctp), FWRITE,
		    p->p_ucred, p);
		acctp = savacctp = NULL;
	}
	if (SCARG(uap, path) == NULL)
		return (0);

	/*
	 * Save the new accounting file vnode, and schedule the new
	 * free space watcher.
	 */
	acctp = nd.ni_vp;
	if ((error = acct_start()) != 0) {
		acctp = NULL;
		(void)vn_close(nd.ni_vp, FWRITE, p->p_ucred, p);
		return (error);
	}
	return (0);
}
Esempio n. 3
0
static int
vniocattach_shadow(struct vn_softc *vn, struct vn_ioctl_64 *vniop, 
				   __unused dev_t dev, int in_kernel, proc_t p)
{
	vfs_context_t ctx = vfs_context_current();
	struct nameidata nd;
	int error, flags;
	shadow_map_t *	map;
	off_t file_size;

	flags = FREAD|FWRITE;
	if (in_kernel) {
		NDINIT(&nd, LOOKUP, OP_OPEN, FOLLOW, UIO_SYSSPACE, vniop->vn_file, ctx);
	}
	else {
		NDINIT(&nd, LOOKUP, OP_OPEN, FOLLOW, 
			   (IS_64BIT_PROCESS(p) ? UIO_USERSPACE64 : UIO_USERSPACE32), 
			   vniop->vn_file, ctx);
	}
	/* vn_open gives both long- and short-term references */
	error = vn_open(&nd, flags, 0);
	if (error) {
		/* shadow MUST be writable! */
		return (error);
	}
	if (nd.ni_vp->v_type != VREG 
	    || (error = vnode_size(nd.ni_vp, &file_size, ctx))) {
		(void)vn_close(nd.ni_vp, flags, ctx);
		vnode_put(nd.ni_vp);
		return (error ? error : EINVAL);
	}
	map = shadow_map_create(vn->sc_fsize, file_size,
				0, vn->sc_secsize);
	if (map == NULL) {
		(void)vn_close(nd.ni_vp, flags, ctx);
		vnode_put(nd.ni_vp);
		vn->sc_shadow_vp = NULL;
		return (ENOMEM);
	}
	vn->sc_shadow_vp = nd.ni_vp;
	vn->sc_shadow_vid = vnode_vid(nd.ni_vp);
	vn->sc_shadow_vp->v_flag |= VNOCACHE_DATA;
	vn->sc_shadow_map = map;
	vn->sc_flags &= ~VNF_READONLY; /* we're now read/write */

	/* lose the short-term reference */
	vnode_put(nd.ni_vp);
	return(0);
}
Esempio n. 4
0
void
vdsp_close(void *arg1)
{
	struct vdsp_softc *sc = arg1;
	struct proc *p = curproc;

	sc->sc_seq_no = 0;

	if (sc->sc_vd) {
		free(sc->sc_vd, M_DEVBUF, 0);
		sc->sc_vd = NULL;
	}
	if (sc->sc_vd_ring != NULL) {
		free(sc->sc_vd_ring, M_DEVBUF,
		    sc->sc_num_descriptors * sizeof(*sc->sc_vd_ring));
		sc->sc_vd_ring = NULL;
	}
	if (sc->sc_label) {
		free(sc->sc_label, M_DEVBUF, 0);
		sc->sc_label = NULL;
	}
	if (sc->sc_vp) {
		vn_close(sc->sc_vp, FREAD | FWRITE, p->p_ucred, p);
		sc->sc_vp = NULL;
	}
}
Esempio n. 5
0
/* ARGSUSED */
static int
cgd_ioctl_clr(struct cgd_softc *cs, struct lwp *l)
{
	struct	dk_softc *dksc = &cs->sc_dksc;

	if (!DK_ATTACHED(dksc))
		return ENXIO;

	/* Delete all of our wedges. */
	dkwedge_delall(&dksc->sc_dkdev);

	/* Kill off any queued buffers. */
	dk_drain(dksc);
	bufq_free(dksc->sc_bufq);

	(void)vn_close(cs->sc_tvn, FREAD|FWRITE, l->l_cred);
	cs->sc_cfuncs->cf_destroy(cs->sc_cdata.cf_priv);
	free(cs->sc_tpath, M_DEVBUF);
	free(cs->sc_data, M_DEVBUF);
	cs->sc_data_used = 0;
	dk_detach(dksc);
	disk_detach(&dksc->sc_dkdev);

	return 0;
}
static void
kobj_close_vfs(kobj_t ko)
{

	VOP_UNLOCK(ko->ko_source);
	vn_close(ko->ko_source, FREAD, kauth_cred_get());
}
Esempio n. 7
0
/*
 * Enable an EA using the passed filesystem, backing vnode, attribute name,
 * namespace, and proc.  Will perform a VOP_OPEN() on the vp, so expects vp
 * to be locked when passed in.  The vnode will be returned unlocked,
 * regardless of success/failure of the function.  As a result, the caller
 * will always need to vrele(), but not vput().
 */
static int
ufs_extattr_enable_with_open(struct ufsmount *ump, struct vnode *vp,
    int attrnamespace, const char *attrname, struct thread *td)
{
	int error;

	error = VOP_OPEN(vp, FREAD|FWRITE, td->td_ucred, td, NULL);
	if (error) {
		printf("ufs_extattr_enable_with_open.VOP_OPEN(): failed "
		    "with %d\n", error);
		VOP_UNLOCK(vp, 0);
		return (error);
	}

	error = VOP_ADD_WRITECOUNT(vp, 1);
	if (error != 0) {
		VOP_CLOSE(vp, FREAD | FWRITE, td->td_ucred, td);
		VOP_UNLOCK(vp, 0);
		return (error);
	}
	CTR3(KTR_VFS, "%s: vp %p v_writecount increased to %d", __func__, vp,
	    vp->v_writecount);

	vref(vp);

	VOP_UNLOCK(vp, 0);

	error = ufs_extattr_enable(ump, attrnamespace, attrname, vp, td);
	if (error != 0)
		vn_close(vp, FREAD|FWRITE, td->td_ucred, td);
	return (error);
}
Esempio n. 8
0
static void
alq_shutdown(struct alq *alq)
{
    ALQ_LOCK(alq);

    /* Stop any new writers. */
    alq->aq_flags |= AQ_SHUTDOWN;

    /*
     * If the ALQ isn't active but has unwritten data (possible if
     * the ALQ_NOACTIVATE flag has been used), explicitly activate the
     * ALQ here so that the pending data gets flushed by the ald_daemon.
     */
    if (!(alq->aq_flags & AQ_ACTIVE) && HAS_PENDING_DATA(alq)) {
        alq->aq_flags |= AQ_ACTIVE;
        ALQ_UNLOCK(alq);
        ALD_LOCK();
        ald_activate(alq);
        ALD_UNLOCK();
        ALQ_LOCK(alq);
    }

    /* Drain IO */
    while (alq->aq_flags & AQ_ACTIVE) {
        alq->aq_flags |= AQ_WANTED;
        msleep_spin(alq, &alq->aq_mtx, "aldclose", 0);
    }
    ALQ_UNLOCK(alq);

    vn_close(alq->aq_vp, FWRITE, alq->aq_cred,
             curthread);
    crfree(alq->aq_cred);
}
/*
 * Enable an EA using the passed filesystem, backing vnode, attribute name,
 * namespace, and proc.  Will perform a VOP_OPEN() on the vp, so expects vp
 * to be locked when passed in.  The vnode will be returned unlocked,
 * regardless of success/failure of the function.  As a result, the caller
 * will always need to vrele(), but not vput().
 */
static int
ufs_extattr_enable_with_open(struct myfs_ufsmount *ump, struct vnode *vp,
    int attrnamespace, const char *attrname, struct thread *td)
{
	int error;

	error = VOP_OPEN(vp, FREAD|FWRITE, td->td_ucred, td, NULL);
	if (error) {
		printf("ufs_extattr_enable_with_open.VOP_OPEN(): failed "
		    "with %d\n", error);
		VOP_UNLOCK(vp, 0);
		return (error);
	}

	vp->v_writecount++;

	vref(vp);

	VOP_UNLOCK(vp, 0);

	error = ufs_extattr_enable(ump, attrnamespace, attrname, vp, td);
	if (error != 0)
		vn_close(vp, FREAD|FWRITE, td->td_ucred, td);
	return (error);
}
Esempio n. 10
0
/*
 * Disable extended attribute support on an FS.
 */
static int
ufs_extattr_disable(struct ufsmount *ump, int attrnamespace,
    const char *attrname, struct thread *td)
{
	struct ufs_extattr_list_entry *uele;
	int error = 0;

	if (!ufs_extattr_valid_attrname(attrnamespace, attrname))
		return (EINVAL);

	uele = ufs_extattr_find_attr(ump, attrnamespace, attrname);
	if (!uele)
		return (ENOATTR);

	LIST_REMOVE(uele, uele_entries);

	vn_lock(uele->uele_backing_vnode, LK_SHARED | LK_RETRY);
	ASSERT_VOP_LOCKED(uele->uele_backing_vnode, "ufs_extattr_disable");
	VOP_UNLOCK(uele->uele_backing_vnode, 0);
	error = vn_close(uele->uele_backing_vnode, FREAD|FWRITE,
	    td->td_ucred, td);

	free(uele, M_UFS_EXTATTR);

	return (error);
}
Esempio n. 11
0
static int
vfs_mountroot_readconf(struct thread *td, struct sbuf *sb)
{
	static char buf[128];
	struct nameidata nd;
	off_t ofs;
	ssize_t resid;
	int error, flags, len;

	NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, "/.mount.conf", td);
	flags = FREAD;
	error = vn_open(&nd, &flags, 0, NULL);
	if (error)
		return (error);

	NDFREE(&nd, NDF_ONLY_PNBUF);
	ofs = 0;
	len = sizeof(buf) - 1;
	while (1) {
		error = vn_rdwr(UIO_READ, nd.ni_vp, buf, len, ofs,
		    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred,
		    NOCRED, &resid, td);
		if (error)
			break;
		if (resid == len)
			break;
		buf[len - resid] = 0;
		sbuf_printf(sb, "%s", buf);
		ofs += len - resid;
	}

	VOP_UNLOCK(nd.ni_vp, 0);
	vn_close(nd.ni_vp, FREAD, td->td_ucred, td);
	return (error);
}
Esempio n. 12
0
int
randomdev_write_file(const char *filename, void *buf, size_t length)
{
	struct nameidata nd;
	struct thread* td = curthread;
	int error;
	ssize_t resid;
	int flags;

	NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, filename, td);
	flags = FWRITE | O_CREAT | O_TRUNC;
	error = vn_open(&nd, &flags, 0, NULL);
	if (error == 0) {
		NDFREE(&nd, NDF_ONLY_PNBUF);
		if (nd.ni_vp->v_type != VREG)
			error = ENOEXEC;
		else
			error = vn_rdwr(UIO_WRITE, nd.ni_vp, buf, length, 0, UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, &resid, td);

		VOP_UNLOCK(nd.ni_vp, 0);
		vn_close(nd.ni_vp, FREAD, td->td_ucred, td);
	}

	return (error);
}
Esempio n. 13
0
/*
 * Lookup the provided name in the filesystem.  If the file exists,
 * is a valid block device, and isn't being used by anyone else,
 * set *vpp to the file's vnode.
 */
int
dk_lookup(struct pathbuf *pb, struct lwp *l, struct vnode **vpp)
{
	struct nameidata nd;
	struct vnode *vp;
	int     error;

	if (l == NULL)
		return ESRCH;	/* Is ESRCH the best choice? */

	NDINIT(&nd, LOOKUP, FOLLOW, pb);
	if ((error = vn_open(&nd, FREAD | FWRITE, 0)) != 0) {
		DPRINTF((DKDB_FOLLOW|DKDB_INIT),
		    ("%s: vn_open error = %d\n", __func__, error));
		return error;
	}

	vp = nd.ni_vp;
	if (vp->v_type != VBLK) {
		error = ENOTBLK;
		goto out;
	}

	/* Reopen as anonymous vnode to protect against forced unmount. */
	if ((error = bdevvp(vp->v_rdev, vpp)) != 0)
		goto out;
	VOP_UNLOCK(vp);
	if ((error = vn_close(vp, FREAD | FWRITE, l->l_cred)) != 0) {
		vrele(*vpp);
		return error;
	}
	if ((error = VOP_OPEN(*vpp, FREAD | FWRITE, l->l_cred)) != 0) {
		vrele(*vpp);
		return error;
	}
	mutex_enter((*vpp)->v_interlock);
	(*vpp)->v_writecount++;
	mutex_exit((*vpp)->v_interlock);

	IFDEBUG(DKDB_VNODE, vprint("dk_lookup: vnode info", *vpp));

	return 0;
out:
	VOP_UNLOCK(vp);
	(void) vn_close(vp, FREAD | FWRITE, l->l_cred);
	return error;
}
Esempio n. 14
0
void
kobj_close_file(struct _buf *file)
{

	if (file->mounted)
		vn_close(file->ptr, FREAD, curthread->td_ucred, curthread);
	kmem_free(file, sizeof(*file));
}
Esempio n. 15
0
/*
 * Lookup the provided name in the filesystem.  If the file exists,
 * is a valid block device, and isn't being used by anyone else,
 * set *vpp to the file's vnode.
 */
int
ccdlookup(char *path, struct proc *p, struct vnode **vpp)
{
	struct nameidata nd;
	struct vnode *vp;
	struct vattr va;
	int error;

	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, path, p);
	if ((error = vn_open(&nd, FREAD|FWRITE, 0)) != 0) {
		CCD_DPRINTF(CCDB_FOLLOW | CCDB_INIT,
		    ("ccdlookup: vn_open error = %d\n", error));
		return (error);
	}
	vp = nd.ni_vp;

	if (vp->v_usecount > 1) {
		VOP_UNLOCK(vp, 0, p);
		(void)vn_close(vp, FREAD|FWRITE, p->p_ucred, p);
		return (EBUSY);
	}

	if ((error = VOP_GETATTR(vp, &va, p->p_ucred, p)) != 0) {
		CCD_DPRINTF(CCDB_FOLLOW | CCDB_INIT,
		    ("ccdlookup: getattr error = %d\n", error));
		VOP_UNLOCK(vp, 0, p);
		(void)vn_close(vp, FREAD|FWRITE, p->p_ucred, p);
		return (error);
	}

	/* XXX: eventually we should handle VREG, too. */
	if (va.va_type != VBLK) {
		VOP_UNLOCK(vp, 0, p);
		(void)vn_close(vp, FREAD|FWRITE, p->p_ucred, p);
		return (ENOTBLK);
	}

#ifdef DIAGNOSTIC
	CCD_DCALL(CCDB_VNODE, vprint("ccdlookup: vnode info", vp));
#endif

	VOP_UNLOCK(vp, 0, p);
	*vpp = vp;
	return (0);
}
Esempio n. 16
0
/*
 * MPSAFE
 */
static int
vn_closefile(struct file *fp)
{
	int error;

	fp->f_ops = &badfileops;
	error = vn_close(((struct vnode *)fp->f_data), fp->f_flag);
	return (error);
}
Esempio n. 17
0
void
vdsp_close(void *arg1, void *arg2)
{
	struct vdsp_softc *sc = arg1;
	struct proc *p = curproc;

	if (sc->sc_vp) {
		vn_close(sc->sc_vp, FREAD | FWRITE, p->p_ucred, p);
		sc->sc_vp = NULL;
	}
}
Esempio n. 18
0
static int
devfs_fo_close(struct file *fp)
{
	struct vnode *vp = (struct vnode *)fp->f_data;
	int error;

	fp->f_ops = &badfileops;
	error = vn_close(vp, fp->f_flag, fp);
	devfs_clear_cdevpriv(fp);

	return (error);
}
Esempio n. 19
0
static void
swap_file_close(struct chip_swap *swap)
{

	if (swap == NULL)
		return;

	if (swap->swap_vp == NULL)
		return;

	vn_close(swap->swap_vp, FWRITE, swap->swap_cred, curthread);
	crfree(swap->swap_cred);
}
Esempio n. 20
0
void
kobj_close_file(struct _buf *file)
{

	if (file->mounted) {
		struct vnode *vp = file->ptr;
		struct thread *td = curthread;
		int vfslocked;

		vfslocked = VFS_LOCK_GIANT(vp->v_mount);
		vn_close(vp, FREAD, td->td_ucred, td);
		VFS_UNLOCK_GIANT(vfslocked);
	}
	kmem_free(file, sizeof(*file));
}
Esempio n. 21
0
char *
linker_search_path(const char *name)
{
    struct nameidata	nd;
    struct proc		*p = curproc;	/* XXX */
    char		*cp, *ep, *result;
    int			error;
    enum vtype		type;

    /* qualified at all? */
    if (index(name, '/'))
	return(linker_strdup(name));

    /* traverse the linker path */
    cp = linker_path;
    for (;;) {

	/* find the end of this component */
	for (ep = cp; (*ep != 0) && (*ep != ';'); ep++)
	    ;
	result = malloc((strlen(name) + (ep - cp) + 1), M_LINKER, M_WAITOK);
	if (result == NULL)	/* actually ENOMEM */
	    return(NULL);

	strncpy(result, cp, ep - cp);
	strcpy(result + (ep - cp), name);

	/*
	 * Attempt to open the file, and return the path if we succeed and it's
	 * a regular file.
	 */
	NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, result, p);
	error = vn_open(&nd, FREAD, 0);
	if (error == 0) {
	    type = nd.ni_vp->v_type;
	    VOP_UNLOCK(nd.ni_vp, 0, p);
	    vn_close(nd.ni_vp, FREAD, p->p_ucred, p);
	    if (type == VREG)
		return(result);
	}
	free(result, M_LINKER);

	if (*ep == 0)
	    break;
	cp = ep + 1;
    }
    return(NULL);
}
Esempio n. 22
0
/*
 * File table vnode close routine.
 */
int
vn_closefile(struct file *fp, struct proc *p)
{
	struct vnode *vp = fp->f_data;
	struct flock lf;
	
	if ((fp->f_iflags & FIF_HASLOCK)) {
		lf.l_whence = SEEK_SET;
		lf.l_start = 0;
		lf.l_len = 0;
		lf.l_type = F_UNLCK;
		(void) VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK);
	}

	return (vn_close(vp, fp->f_flag, fp->f_cred, p));
}
Esempio n. 23
0
void
vndclear(struct vnd_softc *sc)
{
	struct vnode *vp = sc->sc_vp;
	struct proc *p = curproc;		/* XXX */

	DNPRINTF(VDB_FOLLOW, "vndclear(%p): vp %p\n", sc, vp);

	if (vp == NULL)
		panic("vndioctl: null vp");
	(void) vn_close(vp, VNDRW(sc), sc->sc_cred, p);
	crfree(sc->sc_cred);
	sc->sc_flags = 0;
	sc->sc_vp = NULL;
	sc->sc_cred = NULL;
	sc->sc_size = 0;
	memset(sc->sc_file, 0, sizeof(sc->sc_file));
}
Esempio n. 24
0
static void
alq_shutdown(struct alq *alq)
{
	ALQ_LOCK(alq);

	/* Stop any new writers. */
	alq->aq_flags |= AQ_SHUTDOWN;

	/* Drain IO */
	while (alq->aq_flags & (AQ_FLUSHING|AQ_ACTIVE)) {
		alq->aq_flags |= AQ_WANTED;
		msleep_spin(alq, &alq->aq_mtx, "aldclose", 0);
	}
	ALQ_UNLOCK(alq);

	vn_close(alq->aq_vp, FWRITE, alq->aq_cred,
	    curthread);
	crfree(alq->aq_cred);
}
Esempio n. 25
0
/*
 * Cleanup a nlookupdata structure after we are through with it.  This may
 * be called on any nlookupdata structure initialized with nlookup_init().
 * Calling nlookup_done() is mandatory in all cases except where nlookup_init()
 * returns an error, even if as a consumer you believe you have taken all
 * dynamic elements out of the nlookupdata structure.
 */
void
nlookup_done(struct nlookupdata *nd)
{
    if (nd->nl_nch.ncp) {
	if (nd->nl_flags & NLC_NCPISLOCKED) {
	    nd->nl_flags &= ~NLC_NCPISLOCKED;
	    cache_unlock(&nd->nl_nch);
	}
	if (nd->nl_flags & NLC_NCDIR) {
		cache_drop_ncdir(&nd->nl_nch);
		nd->nl_flags &= ~NLC_NCDIR;
	} else {
		cache_drop(&nd->nl_nch);	/* NULL's out the nch */
	}
    }
    if (nd->nl_rootnch.ncp)
	cache_drop_and_cache(&nd->nl_rootnch);
    if (nd->nl_jailnch.ncp)
	cache_drop_and_cache(&nd->nl_jailnch);
    if ((nd->nl_flags & NLC_HASBUF) && nd->nl_path) {
	objcache_put(namei_oc, nd->nl_path);
	nd->nl_path = NULL;
    }
    if (nd->nl_cred) {
	if ((nd->nl_flags & NLC_BORROWCRED) == 0)
	    crfree(nd->nl_cred);
	nd->nl_cred = NULL;
	nd->nl_flags &= ~NLC_BORROWCRED;
    }
    if (nd->nl_open_vp) {
	if (nd->nl_flags & NLC_LOCKVP) {
		vn_unlock(nd->nl_open_vp);
		nd->nl_flags &= ~NLC_LOCKVP;
	}
	vn_close(nd->nl_open_vp, nd->nl_vp_fmode, NULL);
	nd->nl_open_vp = NULL;
    }
    if (nd->nl_dvp) {
	vrele(nd->nl_dvp);
	nd->nl_dvp = NULL;
    }
    nd->nl_flags = 0;	/* clear remaining flags (just clear everything) */
}
Esempio n. 26
0
/*
 * Lookup the provided name in the filesystem.  If the file exists,
 * is a valid block device, and isn't being used by anyone else,
 * set *vpp to the file's vnode.
 */
int
dk_lookup(const char *path, struct lwp *l, struct vnode **vpp,
    enum uio_seg segflg)
{
	struct nameidata nd;
	struct vnode *vp;
	struct vattr va;
	int     error;

	if (l == NULL)
		return ESRCH;	/* Is ESRCH the best choice? */

	NDINIT(&nd, LOOKUP, FOLLOW, segflg, path);
	if ((error = vn_open(&nd, FREAD | FWRITE, 0)) != 0) {
		DPRINTF((DKDB_FOLLOW|DKDB_INIT),
		    ("dk_lookup: vn_open error = %d\n", error));
		return error;
	}

	vp = nd.ni_vp;
	if ((error = VOP_GETATTR(vp, &va, l->l_cred)) != 0) {
		DPRINTF((DKDB_FOLLOW|DKDB_INIT),
		    ("dk_lookup: getattr error = %d\n", error));
		goto out;
	}

	/* XXX: eventually we should handle VREG, too. */
	if (va.va_type != VBLK) {
		error = ENOTBLK;
		goto out;
	}

	IFDEBUG(DKDB_VNODE, vprint("dk_lookup: vnode info", vp));

	VOP_UNLOCK(vp, 0);
	*vpp = vp;
	return 0;
out:
	VOP_UNLOCK(vp, 0);
	(void) vn_close(vp, FREAD | FWRITE, l->l_cred);
	return error;
}
Esempio n. 27
0
/*
 * Enable an EA using the passed file system, backing vnode, attribute name,
 * namespace, and proc.  Will perform a VOP_OPEN() on the vp, so expects vp
 * to be locked when passed in.  The vnode will be returned unlocked,
 * regardless of success/failure of the function.  As a result, the caller
 * will always need to vrele(), but not vput().
 */
static int
ufs_extattr_enable_with_open(struct ufsmount *ump, struct vnode *vp,
    int attrnamespace, const char *attrname, struct proc *p)
{
	int error;

	error = VOP_OPEN(vp, FREAD|FWRITE, p->p_ucred, p);
	if (error) {
		printf("ufs_extattr_enable_with_open.VOP_OPEN(): failed "
		    "with %d\n", error);
		VOP_UNLOCK(vp, 0, p);
		return (error);
	}

#if 0
	/* - XXX */
	/*
	 * XXX: Note, should VOP_CLOSE() if vfs_object_create() fails, but due
	 * to a similar piece of code in vn_open(), we don't.
	 */
	if (vn_canvmio(vp) == TRUE)
		if ((error = vfs_object_create(vp, p, p->p_ucred)) != 0) {
			/*
			 * XXX: bug replicated from vn_open(): should
			 * VOP_CLOSE() here.
			 */
			VOP_UNLOCK(vp, 0, p);
			return (error);
		}
#endif

	vp->v_writecount++;

	vref(vp);

	VOP_UNLOCK(vp, 0, p);

	error = ufs_extattr_enable(ump, attrnamespace, attrname, vp, p);
	if (error != 0)
		vn_close(vp, FREAD|FWRITE, p->p_ucred, p);
	return (error);
}
Esempio n. 28
0
/*
 * kobj_close:
 *
 *	Close an open ELF object.
 */
static void
kobj_close(kobj_t ko)
{

	if (ko->ko_source == NULL) {
		return;
	}

	switch (ko->ko_type) {
	case KT_VNODE:
		VOP_UNLOCK(ko->ko_source, 0);
		vn_close(ko->ko_source, FREAD, kauth_cred_get());
		break;
	case KT_MEMORY:
		/* nothing */
		break;
	default:
		panic("kobj_close: unknown type");
		break;
	}

	ko->ko_source = NULL;
}
Esempio n. 29
0
/*
 * Disable extended attribute support on an FS.
 */
static int
ufs_extattr_disable(struct ufsmount *ump, int attrnamespace,
    const char *attrname, struct proc *p)
{
	struct ufs_extattr_list_entry	*uele;
	int	error = 0;

	if (!ufs_extattr_valid_attrname(attrnamespace, attrname))
		return (EINVAL);

	uele = ufs_extattr_find_attr(ump, attrnamespace, attrname);
	if (!uele)
		return (ENOENT);

	LIST_REMOVE(uele, uele_entries);

	uele->uele_backing_vnode->v_flag &= ~VSYSTEM;
	error = vn_close(uele->uele_backing_vnode, FREAD|FWRITE, p->p_ucred, p);

	FREE(uele, M_UFS_EXTATTR);

	return (error);
}
Esempio n. 30
0
/*
 * Delete a snapshot.
 */
static int
fss_delete_snapshot(struct fss_softc *sc, struct lwp *l)
{

	if ((sc->sc_flags & FSS_PERSISTENT) == 0)
		fscow_disestablish(sc->sc_mount, fss_copy_on_write, sc);

	mutex_enter(&sc->sc_slock);
	sc->sc_flags &= ~(FSS_ACTIVE|FSS_ERROR);
	sc->sc_mount = NULL;
	sc->sc_bdev = NODEV;
	mutex_exit(&sc->sc_slock);

	fss_softc_free(sc);
	if (sc->sc_flags & FSS_PERSISTENT)
		vrele(sc->sc_bs_vp);
	else
		vn_close(sc->sc_bs_vp, FREAD|FWRITE, l->l_cred);
	sc->sc_bs_vp = NULL;
	sc->sc_flags &= ~FSS_PERSISTENT;

	return 0;
}