コード例 #1
0
ファイル: nwfs_vnops.c プロジェクト: mihaicarabas/dragonfly
/*
 * nwfs_create call
 * Create a regular file. On entry the directory to contain the file being
 * created is locked.  We must release before we return. 
 *
 * nwfs_create(struct vnode *a_dvp, struct vnode **a_vpp,
 *		struct componentname *a_cnpl, struct vattr *a_vap)
 */
static int
nwfs_create(struct vop_old_create_args *ap)
{
	struct vnode *dvp = ap->a_dvp;
	struct vattr *vap = ap->a_vap;
	struct vnode **vpp=ap->a_vpp;
	struct componentname *cnp = ap->a_cnp;
	struct vnode *vp = NULL;
	int error = 0, fmode;
	struct vattr vattr;
	struct nwnode *np;
	struct ncp_open_info no;
	struct nwmount *nmp=VTONWFS(dvp);
	ncpfid fid;
	

	NCPVNDEBUG("\n");
	*vpp = NULL;
	if (vap->va_type == VSOCK)
		return (EOPNOTSUPP);
	if ((error = VOP_GETATTR(dvp, &vattr))) {
		return (error);
	}
	fmode = AR_READ | AR_WRITE;
/*	if (vap->va_vaflags & VA_EXCLUSIVE)
		fmode |= AR_DENY_READ | AR_DENY_WRITE;*/
	
	error = ncp_open_create_file_or_subdir(nmp,dvp,cnp->cn_namelen,cnp->cn_nameptr, 
			   OC_MODE_CREATE | OC_MODE_OPEN | OC_MODE_REPLACE,
			   0, fmode, &no, cnp->cn_td, cnp->cn_cred);
	if (!error) {
		error = ncp_close_file(NWFSTOCONN(nmp), &no.fh, cnp->cn_td,cnp->cn_cred);
		fid.f_parent = VTONW(dvp)->n_fid.f_id;
		fid.f_id = no.fattr.dirEntNum;
		error = nwfs_nget(VTOVFS(dvp), fid, &no.fattr, dvp, &vp);
		if (!error) {
			np = VTONW(vp);
			np->opened = 0;
			*vpp = vp;
		}
	}
	return (error);
}
コード例 #2
0
ファイル: nwfs_vnops.c プロジェクト: mihaicarabas/dragonfly
/*
 * nwfs_mkdir call
 *
 * nwfs_mkdir(struct vnode *a_dvp, struct vnode **a_vpp,
 *		struct componentname *a_cnp, struct vattr *a_vap)
 */
static int
nwfs_mkdir(struct vop_old_mkdir_args *ap)
{
	struct vnode *dvp = ap->a_dvp;
/*	struct vattr *vap = ap->a_vap;*/
	struct componentname *cnp = ap->a_cnp;
	int len=cnp->cn_namelen;
	struct ncp_open_info no;
	struct vnode *newvp = NULL;
	ncpfid fid;
	int error = 0;
	struct vattr vattr;
	char *name=cnp->cn_nameptr;

	if ((error = VOP_GETATTR(dvp, &vattr))) {
		return (error);
	}	
	if ((name[0] == '.') && ((len == 1) || ((len == 2) && (name[1] == '.')))) {
		return EEXIST;
	}
	if (ncp_open_create_file_or_subdir(VTONWFS(dvp),dvp, cnp->cn_namelen,
			cnp->cn_nameptr,OC_MODE_CREATE, aDIR, 0xffff,
			&no, cnp->cn_td, cnp->cn_cred) != 0) {
		error = EACCES;
	} else {
		error = 0;
        }
	if (!error) {
		fid.f_parent = VTONW(dvp)->n_fid.f_id;
		fid.f_id = no.fattr.dirEntNum;
		error = nwfs_nget(VTOVFS(dvp), fid, &no.fattr, dvp, &newvp);
		if (!error) {
			newvp->v_type = VDIR;
			*ap->a_vpp = newvp;
		}
	}
	return (error);
}
コード例 #3
0
ファイル: nwfs_io.c プロジェクト: dcui/FreeBSD-9.3_kernel
static int
nwfs_readvdir(struct vnode *vp, struct uio *uio, struct ucred *cred) {
	struct nwmount *nmp = VTONWFS(vp);
	int error, count, i;
	struct dirent dp;
	struct nwnode *np = VTONW(vp);
	struct nw_entry_info fattr;
	struct vnode *newvp;
	struct componentname cn;
	ncpfid fid;

	np = VTONW(vp);
	NCPVNDEBUG("dirname='%s'\n",np->n_name);
	if (uio->uio_resid < DE_SIZE || (uio->uio_offset < 0))
		return (EINVAL);
	error = 0;
	count = 0;
	i = uio->uio_offset / DE_SIZE; /* offset in directory */
	if (i == 0) {
		error = ncp_initsearch(vp, uio->uio_td, cred);
		if (error) {
			NCPVNDEBUG("cannot initialize search, error=%d",error);
			return( error );
		}
	}

	for (; uio->uio_resid >= DE_SIZE; i++) {
		bzero((char *) &dp, DE_SIZE);
		dp.d_reclen = DE_SIZE;
		switch (i) {
		    case 0:		/* `.' */
		    case 1:		/* `..' */
			dp.d_fileno = (i == 0) ? np->n_fid.f_id : np->n_parent.f_id;
			if (!dp.d_fileno) dp.d_fileno = NWFS_ROOT_INO;
			dp.d_namlen = i + 1;
			dp.d_name[0] = '.';
			dp.d_name[1] = '.';
			dp.d_name[i + 1] = '\0';
			dp.d_type = DT_DIR;
			break;
		    default:
			error = ncp_search_for_file_or_subdir(nmp, &np->n_seq, &fattr, uio->uio_td, cred);
			if (error && error < 0x80) break;
			dp.d_fileno = fattr.dirEntNum;
			dp.d_type = (fattr.attributes & aDIR) ? DT_DIR : DT_REG;
			dp.d_namlen = fattr.nameLen;
			bcopy(fattr.entryName, dp.d_name, dp.d_namlen);
			dp.d_name[dp.d_namlen] = '\0';
#if 0
			if (error && eofflag) {
			/*	*eofflag = 1;*/
				break;
			}
#endif
			break;
		}
		if (nwfs_fastlookup && !error && i > 1) {
			fid.f_id = fattr.dirEntNum;
			fid.f_parent = np->n_fid.f_id;
			error = nwfs_nget(vp->v_mount, fid, &fattr, vp, &newvp);
			if (!error) {
				VTONW(newvp)->n_ctime = VTONW(newvp)->n_vattr.va_ctime.tv_sec;
				cn.cn_nameptr = dp.d_name;
				cn.cn_namelen = dp.d_namlen;
				cache_enter(vp, newvp, &cn);
				vput(newvp);
			} else
				error = 0;
		}
		if (error >= 0x80) {
		    error = 0;
		    break;
		}
		if ((error = uiomove(&dp, DE_SIZE, uio)))
			break;
	}

	uio->uio_offset = i * DE_SIZE;
	return (error);
}
コード例 #4
0
ファイル: nwfs_vfsops.c プロジェクト: AhmadTux/DragonFlyBSD
/*  Return locked vnode to root of a filesystem */
static int
nwfs_root(struct mount *mp, struct vnode **vpp)
{
	struct vnode *vp;
	struct nwmount *nmp;
	struct nwnode *np;
	struct ncp_conn *conn;
	struct nw_entry_info fattr;
	struct thread *td = curthread;	/* XXX */
	struct ucred *cred;
	int error, nsf, opt;
	u_char vol;

	KKASSERT(td->td_proc);
	cred = td->td_proc->p_ucred;

	nmp = VFSTONWFS(mp);
	conn = NWFSTOCONN(nmp);
	if (nmp->n_root) {
		*vpp = NWTOV(nmp->n_root);
		while (vget(*vpp, LK_EXCLUSIVE) != 0) /* XXX */
			;
		return 0;
	}
	error = ncp_lookup_volume(conn, nmp->m.mounted_vol, &vol, 
		&nmp->n_rootent.f_id, td, cred);
	if (error)
		return ENOENT;
	nmp->n_volume = vol;
	error = ncp_get_namespaces(conn, vol, &nsf, td, cred);
	if (error)
		return ENOENT;
	if (nsf & NW_NSB_OS2) {
		NCPVODEBUG("volume %s has os2 namespace\n",nmp->m.mounted_vol);
		if ((nmp->m.flags & NWFS_MOUNT_NO_OS2) == 0) {
			nmp->name_space = NW_NS_OS2;
			nmp->m.nls.opt &= ~NWHP_DOS;
		}
	}
	opt = nmp->m.nls.opt;
	nsf = opt & (NWHP_UPPER | NWHP_LOWER);
	if (opt & NWHP_DOS) {
		if (nsf == (NWHP_UPPER | NWHP_LOWER)) {
			nmp->m.nls.opt &= ~(NWHP_LOWER | NWHP_UPPER);
		} else if (nsf == 0) {
			nmp->m.nls.opt |= NWHP_LOWER;
		}
	} else {
		if (nsf == (NWHP_UPPER | NWHP_LOWER)) {
			nmp->m.nls.opt &= ~(NWHP_LOWER | NWHP_UPPER);
		}
	}
	if (nmp->m.root_path[0]) {
		nmp->m.root_path[0]--;
		error = ncp_obtain_info(nmp, nmp->n_rootent.f_id,
		    -nmp->m.root_path[0], nmp->m.root_path, &fattr, td, cred);
		if (error) {
			NCPFATAL("Invalid root path specified\n");
			return ENOENT;
		}
		nmp->n_rootent.f_parent = fattr.dirEntNum;
		nmp->m.root_path[0]++;
		error = ncp_obtain_info(nmp, nmp->n_rootent.f_id,
		    -nmp->m.root_path[0], nmp->m.root_path, &fattr, td, cred);
		if (error) {
			NCPFATAL("Invalid root path specified\n");
			return ENOENT;
		}
		nmp->n_rootent.f_id = fattr.dirEntNum;
	} else {
		error = ncp_obtain_info(nmp, nmp->n_rootent.f_id,
		    0, NULL, &fattr, td, cred);
		if (error) {
			NCPFATAL("Can't obtain volume info\n");
			return ENOENT;
		}
		fattr.nameLen = strlen(strcpy(fattr.entryName, NWFS_ROOTVOL));
		nmp->n_rootent.f_parent = nmp->n_rootent.f_id;
	}
	error = nwfs_nget(mp, nmp->n_rootent, &fattr, NULL, &vp);
	if (error)
		return (error);
	vsetflags(vp, VROOT);
	np = VTONW(vp);
	if (nmp->m.root_path[0] == 0)
		np->n_flag |= NVOLUME;
	nmp->n_root = np;
/*	error = VOP_GETATTR(vp, &vattr);
	if (error) {
		vput(vp);
		NCPFATAL("Can't get root directory entry\n");
		return error;
	}*/
	*vpp = vp;
	return (0);
}
コード例 #5
0
ファイル: nwfs_vnops.c プロジェクト: mihaicarabas/dragonfly
/*
 * How to keep the brain busy ...
 * Currently lookup routine can make two lookup for vnode. This can be
 * avoided by reorg the code.
 *
 * nwfs_lookup(struct vnode *a_dvp, struct vnode **a_vpp,
 *	       struct componentname *a_cnp)
 */
int
nwfs_lookup(struct vop_old_lookup_args *ap)
{
	struct componentname *cnp = ap->a_cnp;
	struct vnode *dvp = ap->a_dvp;
	struct vnode **vpp = ap->a_vpp;
	int flags = cnp->cn_flags;
	struct vnode *vp;
	struct nwmount *nmp;
	struct mount *mp = dvp->v_mount;
	struct nwnode *dnp, *npp;
	struct nw_entry_info fattr, *fap;
	ncpfid fid;
	int nameiop=cnp->cn_nameiop;
	int lockparent, wantparent, error = 0, notfound;
	struct thread *td = cnp->cn_td;
	char _name[cnp->cn_namelen+1];
	bcopy(cnp->cn_nameptr,_name,cnp->cn_namelen);
	_name[cnp->cn_namelen]=0;
	
	if (dvp->v_type != VDIR)
		return (ENOTDIR);
	if ((flags & CNP_ISDOTDOT) && (dvp->v_flag & VROOT)) {
		kprintf("nwfs_lookup: invalid '..'\n");
		return EIO;
	}

	NCPVNDEBUG("%d '%s' in '%s' id=d\n", nameiop, _name, 
		VTONW(dvp)->n_name/*, VTONW(dvp)->n_name*/);

	if ((mp->mnt_flag & MNT_RDONLY) && nameiop != NAMEI_LOOKUP)
		return (EROFS);
	if ((error = VOP_EACCESS(dvp, VEXEC, cnp->cn_cred)))
		return (error);
	lockparent = flags & CNP_LOCKPARENT;
	wantparent = flags & (CNP_LOCKPARENT | CNP_WANTPARENT);
	nmp = VFSTONWFS(mp);
	dnp = VTONW(dvp);
/*
kprintf("dvp %d:%d:%d\n", (int)mp, (int)dvp->v_flag & VROOT, (int)flags & CNP_ISDOTDOT);
*/
	error = ncp_pathcheck(cnp->cn_nameptr, cnp->cn_namelen, &nmp->m.nls, 
	    (nameiop == NAMEI_CREATE || nameiop == NAMEI_RENAME) && (nmp->m.nls.opt & NWHP_NOSTRICT) == 0);
	if (error) 
	    return ENOENT;

	error = 0;
	*vpp = NULLVP;
	fap = NULL;
	if (flags & CNP_ISDOTDOT) {
		if (NWCMPF(&dnp->n_parent, &nmp->n_rootent)) {
			fid = nmp->n_rootent;
			fap = NULL;
			notfound = 0;
		} else {
			error = nwfs_lookupnp(nmp, dnp->n_parent, td, &npp);
			if (error) {
				return error;
			}
			fid = dnp->n_parent;
			fap = &fattr;
			/*np = *npp;*/
			notfound = ncp_obtain_info(nmp, npp->n_dosfid,
			    0, NULL, fap, td, cnp->cn_cred);
		}
	} else {
		fap = &fattr;
		notfound = ncp_lookup(dvp, cnp->cn_namelen, cnp->cn_nameptr,
			fap, td, cnp->cn_cred);
		fid.f_id = fap->dirEntNum;
		if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') {
			fid.f_parent = dnp->n_fid.f_parent;
		} else
			fid.f_parent = dnp->n_fid.f_id;
		NCPVNDEBUG("call to ncp_lookup returned=%d\n",notfound);
	}
	if (notfound && notfound < 0x80 )
		return (notfound);	/* hard error */
	if (notfound) { /* entry not found */
		/* Handle RENAME or CREATE case... */
		if ((nameiop == NAMEI_CREATE || nameiop == NAMEI_RENAME) && wantparent) {
			if (!lockparent)
				vn_unlock(dvp);
			return (EJUSTRETURN);
		}
		return ENOENT;
	}/* else {
		NCPVNDEBUG("Found entry %s with id=%d\n", fap->entryName, fap->dirEntNum);
	}*/
	/* handle DELETE case ... */
	if (nameiop == NAMEI_DELETE) { 	/* delete last component */
		error = VOP_EACCESS(dvp, VWRITE, cnp->cn_cred);
		if (error) return (error);
		if (NWCMPF(&dnp->n_fid, &fid)) {	/* we found ourselfs */
			vref(dvp);
			*vpp = dvp;
			return 0;
		}
		error = nwfs_nget(mp, fid, fap, dvp, &vp);
		if (error) return (error);
		*vpp = vp;
		if (!lockparent) vn_unlock(dvp);
		return (0);
	}
	if (nameiop == NAMEI_RENAME && wantparent) {
		error = VOP_EACCESS(dvp, VWRITE, cnp->cn_cred);
		if (error) return (error);
		if (NWCMPF(&dnp->n_fid, &fid)) return EISDIR;
		error = nwfs_nget(mp, fid, fap, dvp, &vp);
		if (error) return (error);
		*vpp = vp;
		if (!lockparent)
			vn_unlock(dvp);
		return (0);
	}
	if (flags & CNP_ISDOTDOT) {
		vn_unlock(dvp);	/* race to get the inode */
		error = nwfs_nget(mp, fid, NULL, NULL, &vp);
		if (error) {
			vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
			return (error);
		}
		if (lockparent) {
			error = vn_lock(dvp, LK_EXCLUSIVE | LK_FAILRECLAIM);
			if (error) {
				vput(vp);
				return (error);
			}
		}
		*vpp = vp;
	} else if (NWCMPF(&dnp->n_fid, &fid)) {
		vref(dvp);
		*vpp = dvp;
	} else {
		error = nwfs_nget(mp, fid, fap, dvp, &vp);
		if (error) return (error);
		*vpp = vp;
		NCPVNDEBUG("lookup: getnewvp!\n");
		if (!lockparent)
			vn_unlock(dvp);
	}
#if 0
	/* XXX MOVE TO NREMOVE */
	if ((cnp->cn_flags & CNP_MAKEENTRY)) {
		VTONW(*vpp)->n_ctime = VTONW(*vpp)->n_vattr.va_ctime.tv_sec;
		/* XXX */
	}
#endif
	return (0);
}
コード例 #6
0
ファイル: nwfs_io.c プロジェクト: mihaicarabas/dragonfly
static int
nwfs_readvdir(struct vnode *vp, struct uio *uio, struct ucred *cred)
{
	struct nwmount *nmp = VTONWFS(vp);
	int error, i;
	struct nwnode *np;
	struct nw_entry_info fattr;
	struct vnode *newvp;
	ncpfid fid;
	ino_t d_ino;
	size_t d_namlen;
	const char *d_name;
	uint8_t d_type;

	np = VTONW(vp);
	NCPVNDEBUG("dirname='%s'\n",np->n_name);
	if (uio->uio_offset < 0 || uio->uio_offset > INT_MAX)
		return (EINVAL);
	error = 0;
	i = (int)uio->uio_offset; /* offset in directory */
	if (i == 0) {
		error = ncp_initsearch(vp, uio->uio_td, cred);
		if (error) {
			NCPVNDEBUG("cannot initialize search, error=%d",error);
			return( error );
		}
	}

	for (; !error && uio->uio_resid > 0; i++) {
		switch (i) {
		    case 0:		/* `.' */
			d_ino = np->n_fid.f_id;
			if (d_ino == 0)
				d_ino = NWFS_ROOT_INO;
			d_namlen = 1;
			d_name = ".";
			d_type = DT_DIR;
			break;
		    case 1:		/* `..' */
			d_ino = np->n_parent.f_id;
			if (d_ino == 0)
				d_ino = NWFS_ROOT_INO;
			d_namlen = 2;
			d_name = "..";
			d_type = DT_DIR;
			break;
		    default:
			error = ncp_search_for_file_or_subdir(nmp, &np->n_seq, &fattr, uio->uio_td, cred);
			if (error && error < 0x80)
				goto done;
			d_ino = fattr.dirEntNum;
			d_type = (fattr.attributes & aDIR) ? DT_DIR : DT_REG;
			d_namlen = fattr.nameLen;
			d_name = fattr.entryName;
#if 0
			if (error && eofflag) {
			/*	*eofflag = 1;*/
			        break;
			}
#endif
			break;
		}
		if (nwfs_fastlookup && !error && i > 1) {
			fid.f_id = fattr.dirEntNum;
			fid.f_parent = np->n_fid.f_id;
			error = nwfs_nget(vp->v_mount, fid, &fattr, vp, &newvp);
			if (!error) {
				VTONW(newvp)->n_ctime = VTONW(newvp)->n_vattr.va_ctime.tv_sec;
				vput(newvp);
			} else
				error = 0;
		}
		if (error >= 0x80) {
		    error = 0;
		    break;
		}
		if (vop_write_dirent(&error, uio, d_ino, d_type, d_namlen, d_name))
			break;
	}
done:
	uio->uio_offset = i;
	return (error);
}