}
int
-vfs_stdvget(struct mount *mp, ino_t ino, struct vnode **vpp)
+vfs_stdvget(struct mount *mp, struct vnode *dvp, ino_t ino, struct vnode **vpp)
{
return (EOPNOTSUPP);
}
typedef int vfs_statvfs_t(struct mount *mp, struct statvfs *sbp,
struct ucred *cred);
typedef int vfs_sync_t(struct mount *mp, int waitfor);
-typedef int vfs_vget_t(struct mount *mp, ino_t ino, struct vnode **vpp);
+typedef int vfs_vget_t(struct mount *mp, struct vnode *dvp,
+ ino_t ino, struct vnode **vpp);
typedef int vfs_fhtovp_t(struct mount *mp, struct vnode *rootvp,
struct fid *fhp, struct vnode **vpp);
typedef int vfs_checkexp_t(struct mount *mp, struct sockaddr *nam,
#define VFS_STATFS(MP, SBP, CRED) (*(MP)->mnt_op->vfs_statfs)(MP, SBP, CRED)
#define VFS_STATVFS(MP, SBP, CRED) (*(MP)->mnt_op->vfs_statvfs)(MP, SBP, CRED)
#define VFS_SYNC(MP, WAIT) (*(MP)->mnt_op->vfs_sync)(MP, WAIT)
-#define VFS_VGET(MP, INO, VPP) (*(MP)->mnt_op->vfs_vget)(MP, INO, VPP)
+#define VFS_VGET(MP, DVP, INO, VPP) (*(MP)->mnt_op->vfs_vget)(MP, DVP, INO, VPP)
#define VFS_FHTOVP(MP, ROOTVP, FIDP, VPP) \
(*(MP)->mnt_op->vfs_fhtovp)(MP, ROOTVP, FIDP, VPP)
#define VFS_VPTOFH(VP, FIDP) (*(VP)->v_mount->mnt_op->vfs_vptofh)(VP, FIDP)
if (ino == 0)
goto noinodes;
- error = VFS_VGET(pvp->v_mount, ino, vpp);
+ error = VFS_VGET(pvp->v_mount, NULL, ino, vpp);
if (error) {
EXT2_VFREE(pvp, ino, mode);
return (error);
*vpp = vdp;
return (0);
}
- if ((error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp)) != 0)
+ if ((error = VFS_VGET(vdp->v_mount, NULL, dp->i_ino, &tdp)) != 0)
return (error);
/*
* If directory is "sticky", then user must own
*/
if (dp->i_number == dp->i_ino)
return (EISDIR);
- if ((error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp)) != 0)
+ if ((error = VFS_VGET(vdp->v_mount, NULL, dp->i_ino, &tdp)) != 0)
return (error);
*vpp = tdp;
if (!lockparent)
pdp = vdp;
if (flags & CNP_ISDOTDOT) {
vn_unlock(pdp); /* race to get the inode */
- if ((error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp)) != 0) {
+ if ((error = VFS_VGET(vdp->v_mount, NULL, dp->i_ino, &tdp)) != 0) {
vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY);
return (error);
}
vref(vdp); /* we want ourself, ie "." */
*vpp = vdp;
} else {
- if ((error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp)) != 0)
+ if ((error = VFS_VGET(vdp->v_mount, NULL, dp->i_ino, &tdp)) != 0)
return (error);
if (!lockparent)
vn_unlock(pdp);
if (dirbuf.dotdot_ino == rootino)
break;
vput(vp);
- if ((error = VFS_VGET(vp->v_mount, dirbuf.dotdot_ino, &vp)) != 0) {
+ if ((error = VFS_VGET(vp->v_mount, NULL, dirbuf.dotdot_ino, &vp)) != 0) {
vp = NULL;
break;
}
static int ext2_statfs (struct mount *, struct statfs *, struct ucred *);
static int ext2_sync (struct mount *, int);
static int ext2_unmount (struct mount *, int);
-static int ext2_vget (struct mount *, ino_t, struct vnode **);
+static int ext2_vget (struct mount *, struct vnode *, ino_t, struct vnode **);
static int ext2_init(struct vfsconf *);
static int ext2_vptofh (struct vnode *, struct fid *);
struct vnode *nvp;
int error;
- error = VFS_VGET(mp, (ino_t)ROOTINO, &nvp);
+ error = VFS_VGET(mp, NULL, (ino_t)ROOTINO, &nvp);
if (error)
return (error);
*vpp = nvp;
* done by the calling routine.
*/
static int
-ext2_vget(struct mount *mp, ino_t ino, struct vnode **vpp)
+ext2_vget(struct mount *mp, struct vnode *dvp, ino_t ino, struct vnode **vpp)
{
struct ext2_sb_info *fs;
struct inode *ip;
ufhp->ufid_ino > fs->s_groups_count * fs->s_es->s_inodes_per_group)
return (ESTALE);
- error = VFS_VGET(mp, ufhp->ufid_ino, &nvp);
+ error = VFS_VGET(mp, rootvp, ufhp->ufid_ino, &nvp);
if (error) {
*vpp = NULLVP;
return (error);
ino = ip->i_number; /* Save this before vgone() invalidates ip. */
vgone_vxlocked(*vpp);
vput(*vpp);
- error = VFS_VGET(ap->a_dvp->v_mount, ino, vpp);
+ error = VFS_VGET(ap->a_dvp->v_mount, NULL, ino, vpp);
if (error) {
*vpp = NULL;
return (error);
static int hammer_vfs_statvfs(struct mount *mp, struct statvfs *sbp,
struct ucred *cred);
static int hammer_vfs_sync(struct mount *mp, int waitfor);
-static int hammer_vfs_vget(struct mount *mp, ino_t ino,
- struct vnode **vpp);
+static int hammer_vfs_vget(struct mount *mp, struct vnode *dvp,
+ ino_t ino, struct vnode **vpp);
static int hammer_vfs_init(struct vfsconf *conf);
static int hammer_vfs_fhtovp(struct mount *mp, struct vnode *rootvp,
struct fid *fhp, struct vnode **vpp);
* FUTURE: Leave the root directory cached referenced but unlocked
* in hmp->rootvp (need to flush it on unmount).
*/
- error = hammer_vfs_vget(mp, 1, &rootvp);
+ error = hammer_vfs_vget(mp, NULL, 1, &rootvp);
if (error)
goto done;
vput(rootvp);
* vnode is returned.
*/
int
-hammer_vfs_vget(struct mount *mp, ino_t ino, struct vnode **vpp)
+hammer_vfs_vget(struct mount *mp, struct vnode *dvp,
+ ino_t ino, struct vnode **vpp)
{
struct hammer_transaction trans;
struct hammer_mount *hmp = (void *)mp->mnt_data;
struct hammer_inode *ip;
int error;
+ u_int32_t localization;
hammer_simple_transaction(&trans, hmp);
/*
+ * If a directory vnode is supplied (mainly NFS) then we can acquire
+ * the PFS domain from it. Otherwise we would only be able to vget
+ * inodes in the root PFS.
+ */
+ if (dvp) {
+ localization = HAMMER_DEF_LOCALIZATION +
+ VTOI(dvp)->obj_localization;
+ } else {
+ localization = HAMMER_DEF_LOCALIZATION;
+ }
+
+ /*
* Lookup the requested HAMMER inode. The structure must be
* left unlocked while we manipulate the related vnode to avoid
* a deadlock.
*/
ip = hammer_get_inode(&trans, NULL, ino,
- hmp->asof, HAMMER_DEF_LOCALIZATION,
+ hmp->asof, localization,
0, &error);
if (ip == NULL) {
*vpp = NULL;
#endif
int error;
- error = hammer_vfs_vget(mp, 1, vpp);
+ error = hammer_vfs_vget(mp, NULL, 1, vpp);
return (error);
}
if (hp->h_no == hp->h_fn.fn_parent) {
dhp = hp;
} else {
- error = VFS_VGET(hpmp->hpm_mp, hp->h_fn.fn_parent, &dvp);
+ error = VFS_VGET(hpmp->hpm_mp, NULL, hp->h_fn.fn_parent, &dvp);
if (error)
return (error);
dhp = VTOHP(dvp);
if (hp->h_no == hp->h_fn.fn_parent) {
dhp = hp;
} else {
- error = VFS_VGET(hp->h_hpmp->hpm_mp, hp->h_fn.fn_parent,
- &dvp);
+ error = VFS_VGET(hp->h_hpmp->hpm_mp, NULL,
+ hp->h_fn.fn_parent, &dvp);
if (error)
return (error);
dhp = VTOHP(dvp);
static int hpfs_root (struct mount *, struct vnode **);
static int hpfs_statfs (struct mount *, struct statfs *, struct ucred *);
static int hpfs_unmount (struct mount *, int);
-static int hpfs_vget (struct mount *mp, ino_t ino,
- struct vnode **vpp);
+static int hpfs_vget (struct mount *mp, struct vnode *,
+ ino_t ino, struct vnode **vpp);
static int hpfs_mountfs (struct vnode *, struct mount *,
struct hpfs_args *);
static int hpfs_vptofh (struct vnode *, struct fid *);
struct hpfsmount *hpmp = VFSTOHPFS(mp);
dprintf(("hpfs_root():\n"));
- error = VFS_VGET(mp, (ino_t)hpmp->hpm_su.su_rootfno, vpp);
+ error = VFS_VGET(mp, NULL, (ino_t)hpmp->hpm_su.su_rootfno, vpp);
if(error) {
kprintf("hpfs_root: VFS_VGET failed: %d\n",error);
return (error);
struct hpfid *hpfhp = (struct hpfid *)fhp;
int error;
- if ((error = VFS_VGET(mp, hpfhp->hpfid_ino, &nvp)) != 0) {
+ if ((error = VFS_VGET(mp, NULL, hpfhp->hpfid_ino, &nvp)) != 0) {
*vpp = NULLVP;
return (error);
}
}
static int
-hpfs_vget(struct mount *mp, ino_t ino, struct vnode **vpp)
+hpfs_vget(struct mount *mp, struct vnode *dvp, ino_t ino, struct vnode **vpp)
{
struct hpfsmount *hpmp = VFSTOHPFS(mp);
struct vnode *vp;
VOP__UNLOCK(dvp, 0);
- error = VFS_VGET(hpmp->hpm_mp,
+ error = VFS_VGET(hpmp->hpm_mp, NULL,
dhp->h_fn.fn_parent, ap->a_vpp);
if (error) {
VOP__LOCK(dvp, 0);
return (0);
}
- error = VFS_VGET(hpmp->hpm_mp, dep->de_fnode, ap->a_vpp);
+ error = VFS_VGET(hpmp->hpm_mp, NULL, dep->de_fnode, ap->a_vpp);
if (error) {
kprintf("hpfs_lookup: VFS_VGET FAILED %d\n", error);
brelse(bp);
static int cd9660_unmount (struct mount *, int);
static int cd9660_root (struct mount *, struct vnode **);
static int cd9660_statfs (struct mount *, struct statfs *, struct ucred *);
-static int cd9660_vget (struct mount *, ino_t, struct vnode **);
+static int cd9660_vget (struct mount *, struct vnode *, ino_t, struct vnode **);
static int cd9660_fhtovp (struct mount *, struct vnode *rootvp,
struct fid *, struct vnode **);
static int cd9660_checkexp (struct mount *, struct sockaddr *,
ifhp->ifid_ino, ifhp->ifid_start);
#endif
- if ((error = VFS_VGET(mp, ifhp->ifid_ino, &nvp)) != 0) {
+ if ((error = VFS_VGET(mp, NULL, ifhp->ifid_ino, &nvp)) != 0) {
*vpp = NULLVP;
return (error);
}
}
int
-cd9660_vget(struct mount *mp, ino_t ino, struct vnode **vpp)
+cd9660_vget(struct mount *mp, struct vnode *dvp, ino_t ino, struct vnode **vpp)
{
/*
* Probe one of the directory entries to see if the filesystem
* supports VGET.
*/
- if (VFS_VGET(vp->v_mount, dp->d_ino, &nvp) == EOPNOTSUPP) {
+ if (VFS_VGET(vp->v_mount, vp, dp->d_ino, &nvp) == EOPNOTSUPP) {
error = NFSERR_NOTSUPP;
vrele(vp);
vp = NULL;
* For readdir_and_lookup get the vnode using
* the file number.
*/
- if (VFS_VGET(vp->v_mount, dp->d_ino, &nvp))
+ if (VFS_VGET(vp->v_mount, vp, dp->d_ino, &nvp))
goto invalid;
bzero((caddr_t)nfhp, NFSX_V3FH);
nfhp->fh_fsid = fhp->fh_fsid;
MALLOC(ntfs_toupper_tab, wchar *, 65536 * sizeof(wchar),
M_NTFSRDATA, M_WAITOK);
- if ((error = VFS_VGET(mp, NTFS_UPCASEINO, &vp)))
+ if ((error = VFS_VGET(mp, NULL, NTFS_UPCASEINO, &vp)))
goto out;
error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL,
0, 65536*sizeof(wchar), (char *) ntfs_toupper_tab, NULL);
static int ntfs_root (struct mount *, struct vnode **);
static int ntfs_statfs (struct mount *, struct statfs *, struct ucred *cred);
static int ntfs_unmount (struct mount *, int);
-static int ntfs_vget (struct mount *mp, ino_t ino, struct vnode **vpp);
+static int ntfs_vget (struct mount *mp, struct vnode *dvp,
+ ino_t ino, struct vnode **vpp);
static int ntfs_mountfs (struct vnode *, struct mount *,
- struct ntfs_args *, struct ucred *);
+ struct ntfs_args *, struct ucred *);
static int ntfs_vptofh (struct vnode *, struct fid *);
static int ntfs_fhtovp (struct mount *, struct vnode *rootvp,
struct fid *, struct vnode **);
{
int pi[3] = { NTFS_MFTINO, NTFS_ROOTINO, NTFS_BITMAPINO };
for (i=0; i<3; i++) {
- error = VFS_VGET(mp, pi[i], &(ntmp->ntm_sysvn[pi[i]]));
+ error = VFS_VGET(mp, NULL,
+ pi[i], &(ntmp->ntm_sysvn[pi[i]]));
if(error)
goto out1;
ntmp->ntm_sysvn[pi[i]]->v_flag |= VSYSTEM;
struct attrdef ad;
/* Open $AttrDef */
- error = VFS_VGET(mp, NTFS_ATTRDEFINO, &vp);
+ error = VFS_VGET(mp, NULL, NTFS_ATTRDEFINO, &vp);
if(error)
goto out1;
dprintf(("ntfs_root(): sysvn: %p\n",
VFSTONTFS(mp)->ntm_sysvn[NTFS_ROOTINO]));
- error = VFS_VGET(mp, (ino_t)NTFS_ROOTINO, &nvp);
+ error = VFS_VGET(mp, NULL, (ino_t)NTFS_ROOTINO, &nvp);
if(error) {
kprintf("ntfs_root: VFS_VGET failed: %d\n",error);
return (error);
ddprintf(("ntfs_fhtovp(): %d\n", ntfhp->ntfid_ino));
- if ((error = VFS_VGET(mp, ntfhp->ntfid_ino, &nvp)) != 0) {
+ if ((error = VFS_VGET(mp, NULL, ntfhp->ntfid_ino, &nvp)) != 0) {
*vpp = NULLVP;
return (error);
}
}
static int
-ntfs_vget(struct mount *mp, ino_t ino, struct vnode **vpp)
+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);
dprintf(("ntfs_lookup: parentdir: %d\n",
vap->va_a_name->n_pnumber));
- error = VFS_VGET(ntmp->ntm_mountp,
+ error = VFS_VGET(ntmp->ntm_mountp, NULL,
vap->va_a_name->n_pnumber,ap->a_vpp);
ntfs_ntvattrrele(vap);
if (error) {
int udf_hashins(struct udf_node *);
int udf_hashrem(struct udf_node *);
int udf_checktag(struct desc_tag *, uint16_t);
-int udf_vget(struct mount *, ino_t, struct vnode **);
+int udf_vget(struct mount *, struct vnode *, ino_t, struct vnode **);
id = udf_getid(&udfmp->root_icb);
- error = udf_vget(mp, id, vpp);
+ error = udf_vget(mp, NULL, id, vpp);
if (error)
return(error);
}
int
-udf_vget(struct mount *mp, ino_t ino, struct vnode **vpp)
+udf_vget(struct mount *mp, struct vnode *dvp, ino_t ino, struct vnode **vpp)
{
struct buf *bp;
struct vnode *devvp;
ifhp = (struct ifid *)fhp;
- if ((error = VFS_VGET(mp, ifhp->ifid_ino, &nvp)) != 0) {
+ if ((error = VFS_VGET(mp, NULL, ifhp->ifid_ino, &nvp)) != 0) {
*vpp = NULLVP;
return(error);
}
/* Did we have a match? */
if (id) {
- error = udf_vget(udfmp->im_mountp, id, &tdp);
+ error = udf_vget(udfmp->im_mountp, NULL, id, &tdp);
if (!error) {
/*
* Remember where this entry was if it's the final
(allocfcn_t *)ffs_nodealloccg);
if (ino == 0)
goto noinodes;
- error = VFS_VGET(pvp->v_mount, ino, vpp);
+ error = VFS_VGET(pvp->v_mount, NULL, ino, vpp);
if (error) {
ffs_vfree(pvp, ino, mode);
return (error);
int ffs_valloc(struct vnode *, int, struct ucred *, struct vnode **);
int ffs_vfree(struct vnode *, ino_t, int);
-int ffs_vget(struct mount *, ino_t, struct vnode **);
+int ffs_vget(struct mount *, struct vnode *, ino_t, struct vnode **);
int ffs_vptofh(struct vnode *, struct fid *);
/*
ino_t oldinum;
int error;
- if ((error = VFS_VGET(dirrem->dm_mnt, dirrem->dm_oldinum, &vp)) != 0) {
+ error = VFS_VGET(dirrem->dm_mnt, NULL, dirrem->dm_oldinum, &vp);
+ if (error) {
softdep_error("handle_workitem_remove: vget", error);
return;
}
*/
FREE_LOCK(&lk);
vn_unlock(vp);
- error = VFS_VGET(mnt, parentino, &pvp);
+ error = VFS_VGET(mnt, NULL, parentino, &pvp);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
if (error != 0)
return (error);
inum = dap->da_newinum;
if (dap->da_state & MKDIR_BODY) {
FREE_LOCK(&lk);
- if ((error = VFS_VGET(mp, inum, &vp)) != 0)
+ if ((error = VFS_VGET(mp, NULL, inum, &vp)) != 0)
break;
if ((error=VOP_FSYNC(vp, MNT_NOWAIT)) ||
(error=VOP_FSYNC(vp, MNT_NOWAIT))) {
mp = pagedep->pd_mnt;
ino = pagedep->pd_ino;
FREE_LOCK(&lk);
- if ((error = VFS_VGET(mp, ino, &vp)) != 0) {
+ if ((error = VFS_VGET(mp, NULL, ino, &vp)) != 0) {
softdep_error("clear_remove: vget", error);
return;
}
if (inodedep_lookup(fs, ino, 0, &inodedep) == 0)
continue;
FREE_LOCK(&lk);
- if ((error = VFS_VGET(info.mp, ino, &vp)) != 0) {
+ if ((error = VFS_VGET(info.mp, NULL, ino, &vp)) != 0) {
softdep_error("clear_inodedeps: vget", error);
return;
}
*/
int
-ffs_vget(struct mount *mp, ino_t ino, struct vnode **vpp)
+ffs_vget(struct mount *mp, struct vnode *dvp, ino_t ino, struct vnode **vpp)
{
struct fs *fs;
struct inode *ip;
}
if (flags & CNP_ISDOTDOT)
vn_unlock(vdp); /* race to get the inode */
- error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp);
+ error = VFS_VGET(vdp->v_mount, NULL, dp->i_ino, &tdp);
if (flags & CNP_ISDOTDOT) {
if (vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY) != 0)
cnp->cn_flags |= CNP_PDIRUNLOCK;
return (EISDIR);
if (flags & CNP_ISDOTDOT)
vn_unlock(vdp); /* race to get the inode */
- error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp);
+ error = VFS_VGET(vdp->v_mount, NULL, dp->i_ino, &tdp);
if (flags & CNP_ISDOTDOT) {
if (vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY) != 0)
cnp->cn_flags |= CNP_PDIRUNLOCK;
if (flags & CNP_ISDOTDOT) {
vn_unlock(pdp); /* race to get the inode */
cnp->cn_flags |= CNP_PDIRUNLOCK;
- if ((error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp)) != 0) {
+ error = VFS_VGET(vdp->v_mount, NULL, dp->i_ino, &tdp);
+ if (error) {
if (vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY) == 0)
cnp->cn_flags &= ~CNP_PDIRUNLOCK;
return (error);
vref(vdp); /* we want ourself, ie "." */
*vpp = vdp;
} else {
- error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp);
+ error = VFS_VGET(vdp->v_mount, NULL, dp->i_ino, &tdp);
if (error)
return (error);
if (!lockparent) {
if (dirbuf.dotdot_ino == rootino)
break;
vput(vp);
- error = VFS_VGET(vp->v_mount, dirbuf.dotdot_ino, &vp);
+ error = VFS_VGET(vp->v_mount, NULL, dirbuf.dotdot_ino, &vp);
if (error) {
vp = NULL;
break;
struct vnode *nvp;
int error;
- error = VFS_VGET(mp, (ino_t)ROOTINO, &nvp);
+ error = VFS_VGET(mp, NULL, (ino_t)ROOTINO, &nvp);
if (error)
return (error);
*vpp = nvp;
struct vnode *nvp;
int error;
- error = VFS_VGET(mp, ufhp->ufid_ino, &nvp);
+ error = VFS_VGET(mp, NULL, ufhp->ufid_ino, &nvp);
if (error) {
*vpp = NULLVP;
return (error);
ino = ip->i_number; /* Save this before vgone() invalidates ip. */
vgone_vxlocked(*vpp);
vput(*vpp);
- error = VFS_VGET(ap->a_dvp->v_mount, ino, vpp);
+ error = VFS_VGET(ap->a_dvp->v_mount, NULL, ino, vpp);
if (error) {
*vpp = NULL;
return (error);
extern struct vop_ops userfs_vnode_vops;
int user_vop_inactive(struct vop_inactive_args *);
int user_vop_reclaim(struct vop_reclaim_args *);
-int user_vfs_vget(struct mount *mp, ino_t ino, struct vnode **vpp);
+int user_vfs_vget(struct mount *mp, struct vnode *dvp,
+ ino_t ino, struct vnode **vpp);
void user_elm_push_vnode(syslink_elm_t par, struct vnode *vp);
void user_elm_push_offset(syslink_elm_t par, off_t offset);
}
int
-user_vfs_vget(struct mount *mp, ino_t ino, struct vnode **vpp)
+user_vfs_vget(struct mount *mp, struct vnode *dvp,
+ ino_t ino, struct vnode **vpp)
{
struct user_mount *ump = (void *)mp->mnt_data;
struct user_inode *ip;