/*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); }
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); }
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; }