FreeBSD/sys/fs/fdescfs/fdesc_vnops.c
/*
 * vp is the current namei directory
 * ndp is the name to locate in that directory...
 */
vp is the current namei directory
ndp is the name to locate in that directory
vp is the current namei directory ndp is the name to locate in that directory
static int
fdesc_lookup(struct vop_lookup_args *ap)
{
	struct vnode **vpp = ap->a_vpp;
	struct vnode *dvp = ap->a_dvp;
	struct componentname *cnp = ap->a_cnp;
	char *pname = cnp->cn_nameptr;
	struct thread *td = cnp->cn_thread;
	struct file *fp;
	struct fdesc_get_ino_args arg;
	cap_rights_t rights;
	int nlen = cnp->cn_namelen;
	u_int fd, fd1;
	int error;
	struct vnode *fvp;
	if ((cnp->cn_flags & ISLASTCN) &&
	    (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) {
		error = EROFS;
		goto bad;
	}
	if (cnp->cn_namelen == 1 && *pname == '.') {
		*vpp = dvp;
		VREF(dvp);
		return (0);
	}
	if (VTOFDESC(dvp)->fd_type != Froot) {
		error = ENOTDIR;
		goto bad;
	}
	fd = 0;
	if (*pname == '0' && nlen != 1) {
		error = ENOENT;
		goto bad;
	}
	while (nlen--) {
		if (*pname < '0' || *pname > '9') {
			error = ENOENT;
			goto bad;
		}
		fd1 = 10 * fd + *pname++ - '0';
		if (fd1 < fd) {
			error = ENOENT;
			goto bad;
		}
		fd = fd1;
	}
	if ((error = fget(td, fd, cap_rights_init(&rights), &fp)) != 0)
		goto bad;
	if (VTOFDESC(dvp)->fd_ix == FD_DESC + fd) {
		vhold(dvp);
		VOP_UNLOCK(dvp, 0);
		fdrop(fp, td);
		vn_lock(dvp, LK_RETRY | LK_EXCLUSIVE);
		vdrop(dvp);
		fvp = dvp;
		if ((dvp->v_iflag & VI_DOOMED) != 0)
			error = ENOENT;
	} else {
		arg.ftype = Fdesc;
		arg.fd_fd = fd;
		arg.ix = FD_DESC + fd;
		arg.fp = fp;
		arg.td = td;
		error = vn_vget_ino_gen(dvp, fdesc_get_ino_alloc, &arg,
		    LK_EXCLUSIVE, &fvp);
	}
	if (error)
		goto bad;
	*vpp = fvp;
	return (0);
bad:
	*vpp = NULL;
	return (error);
}
static int fdesc_lookup ( struct vop_lookup_args * ap ) { struct vnode * * vpp = ap -> a_vpp ; struct vnode * dvp = ap -> a_dvp ; struct componentname * cnp = ap -> a_cnp ; char * pname = cnp -> cn_nameptr ; struct thread * td = cnp -> cn_thread ; struct file * fp ; struct fdesc_get_ino_args arg ; cap_rights_t rights ; int nlen = cnp -> cn_namelen ; u_int fd , fd1 ; int error ; struct vnode * fvp ; if ( ( cnp -> cn_flags & ISLASTCN ) && ( cnp -> cn_nameiop == DELETE || cnp -> cn_nameiop == RENAME ) ) { error = EROFS ; goto bad ; } if ( cnp -> cn_namelen == 1 && * pname == ' ' ) { * vpp = dvp ; VREF ( dvp ) ; return ( 0 ) ; } if ( VTOFDESC ( dvp ) -> fd_type != Froot ) { error = ENOTDIR ; goto bad ; } fd = 0 ; if ( * pname == ' ' && nlen != 1 ) { error = ENOENT ; goto bad ; } while ( nlen -- ) { if ( * pname < ' ' || * pname > ' ' ) { error = ENOENT ; goto bad ; } fd1 = 10 * fd + * pname ++ - ' ' ; if ( fd1 < fd ) { error = ENOENT ; goto bad ; } fd = fd1 ; } if ( ( error = fget ( td , fd , cap_rights_init ( & rights ) , & fp ) ) != 0 ) goto bad ; if ( VTOFDESC ( dvp ) -> fd_ix == FD_DESC + fd ) { vhold ( dvp ) ; VOP_UNLOCK ( dvp , 0 ) ; fdrop ( fp , td ) ; vn_lock ( dvp , LK_RETRY | LK_EXCLUSIVE ) ; vdrop ( dvp ) ; fvp = dvp ; if ( ( dvp -> v_iflag & VI_DOOMED ) != 0 ) error = ENOENT ; } else { arg . ftype = Fdesc ; arg . fd_fd = fd ; arg . ix = FD_DESC + fd ; arg . fp = fp ; arg . td = td ; error = vn_vget_ino_gen ( dvp , fdesc_get_ino_alloc , & arg , LK_EXCLUSIVE , & fvp ) ; } if ( error ) goto bad ; * vpp = fvp ; return ( 0 ) ; bad : * vpp = NULL ; return ( error ) ; }
vp is the current namei directory
 ndp is the name to locate in that directory...
vp is the current namei directory ndp is the name to locate in that directory ...
/* the only time a leading 0 is acceptable is if it's "0" */ /*
	 * No rights to check since 'fp' isn't actually used.
	 */ /* Check if we're looking up ourselves. */ /*
		 * In case we're holding the last reference to the file, the dvp
		 * will be re-acquired.
		 */ /* Re-aquire the lock afterwards. */ /*
		 * Unlock our root node (dvp) when doing this, since we might
		 * deadlock since the vnode might be locked by another thread
		 * and the root vnode lock will be obtained afterwards (in case
		 * we're looking up the fd of the root vnode), which will be the
		 * opposite lock order. Vhold the root vnode first so we don't
		 * lose it.
		 */