Пример #1
0
/*ARGSUSED*/
static int
ntfs_fhtovp(
	struct mount *mp,
	struct fid *fhp,
	struct vnode **vpp)
{
	struct ntfid ntfh;
	int error;

	if (fhp->fid_len != sizeof(struct ntfid))
		return EINVAL;
	memcpy(&ntfh, fhp, sizeof(ntfh));
	ddprintf(("ntfs_fhtovp(): %s: %llu\n", mp->mnt_stat.f_mntonname,
	    (unsigned long long)ntfh.ntfid_ino));

	error = ntfs_vgetex(mp, ntfh.ntfid_ino, ntfh.ntfid_attr, NULL,
			LK_EXCLUSIVE, 0, vpp);
	if (error != 0) {
		*vpp = NULLVP;
		return (error);
	}

	/* XXX as unlink/rmdir/mkdir/creat are not currently possible
	 * with NTFS, we don't need to check anything else for now */
	return (0);
}
Пример #2
0
static int
ntfs_vget(
	struct mount *mp,
	ino_t ino,
	struct vnode **vpp)
{
	return ntfs_vgetex(mp, ino, NTFS_A_DATA, NULL, LK_EXCLUSIVE, 0, vpp);
}
static int
ntfs_vget(struct mount *mp, struct vnode *dvp, ino_t ino, struct vnode **vpp)
{
	return ntfs_vgetex(mp, ino, NTFS_A_DATA, NULL,
			LK_EXCLUSIVE | LK_RETRY, 0, curthread, vpp);
}
Пример #4
0
int
ntfs_lookup(void *v)
{
	struct vop_lookup_v2_args /* {
		struct vnode *a_dvp;
		struct vnode **a_vpp;
		struct componentname *a_cnp;
	} */ *ap = v;
	struct vnode *dvp = ap->a_dvp;
	struct ntnode *dip = VTONT(dvp);
	struct ntfsmount *ntmp = dip->i_mp;
	struct componentname *cnp = ap->a_cnp;
	kauth_cred_t cred = cnp->cn_cred;
	int error;

	dprintf(("ntfs_lookup: \"%.*s\" (%lld bytes) in %llu\n",
	    (int)cnp->cn_namelen, cnp->cn_nameptr, (long long)cnp->cn_namelen,
	    (unsigned long long)dip->i_number));

	error = VOP_ACCESS(dvp, VEXEC, cred);
	if(error)
		return (error);

	if ((cnp->cn_flags & ISLASTCN) &&
	    (dvp->v_mount->mnt_flag & MNT_RDONLY) &&
	    (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
		return (EROFS);

	/*
	 * We now have a segment name to search for, and a directory
	 * to search.
	 *
	 * Before tediously performing a linear scan of the directory,
	 * check the name cache to see if the directory/name pair
	 * we are looking for is known already.
	 */
	if (cache_lookup(ap->a_dvp, cnp->cn_nameptr, cnp->cn_namelen,
			 cnp->cn_nameiop, cnp->cn_flags, NULL, ap->a_vpp)) {
		return *ap->a_vpp == NULLVP ? ENOENT : 0;
	}

	if(cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') {
		dprintf(("ntfs_lookup: faking . directory in %llu\n",
		    (unsigned long long)dip->i_number));

		vref(dvp);
		*ap->a_vpp = dvp;
		error = 0;
	} else if (cnp->cn_flags & ISDOTDOT) {
		struct ntvattr *vap;

		dprintf(("ntfs_lookup: faking .. directory in %llu\n",
		    (unsigned long long)dip->i_number));

		error = ntfs_ntvattrget(ntmp, dip, NTFS_A_NAME, NULL, 0, &vap);
		if (error) {
			return (error);
		}

		dprintf(("ntfs_lookup: parentdir: %d\n",
			 vap->va_a_name->n_pnumber));
		error = ntfs_vgetex(ntmp->ntm_mountp,
				 vap->va_a_name->n_pnumber,
				 NTFS_A_DATA, "", 0, ap->a_vpp);
		ntfs_ntvattrrele(vap);
		if (error) {
			return (error);
		}
	} else {
		error = ntfs_ntlookupfile(ntmp, dvp, cnp, ap->a_vpp);
		if (error) {
			dprintf(("ntfs_ntlookupfile: returned %d\n", error));
			return (error);
		}

		dprintf(("ntfs_lookup: found ino: %llu\n",
		    (unsigned long long)VTONT(*ap->a_vpp)->i_number));
	}

	cache_enter(dvp, *ap->a_vpp, cnp->cn_nameptr, cnp->cn_namelen,
		    cnp->cn_flags);

	return error;
}