Ejemplo n.º 1
0
/* afs_root - stat the root of the file system. AFS global held on entry. */
static int
afs_root(struct super_block *afsp)
{
    afs_int32 code = 0;
    struct vcache *tvp = 0;

    AFS_STATCNT(afs_root);
    if (afs_globalVp && (afs_globalVp->f.states & CStatd)) {
	tvp = afs_globalVp;
    } else {
	struct vrequest *treq = NULL;
	cred_t *credp = crref();

	if (afs_globalVp) {
	    afs_PutVCache(afs_globalVp);
	    afs_globalVp = NULL;
	}

	if (!(code = afs_CreateReq(&treq, credp)) && !(code = afs_CheckInit())) {
	    tvp = afs_GetVCache(&afs_rootFid, treq, NULL, NULL);
	    if (tvp) {
		struct inode *ip = AFSTOV(tvp);
		struct vattr *vattr = NULL;

		code = afs_CreateAttr(&vattr);
		if (!code) {
		    afs_getattr(tvp, vattr, credp);
		    afs_fill_inode(ip, vattr);

		    /* setup super_block and mount point inode. */
		    afs_globalVp = tvp;
#if defined(HAVE_LINUX_D_MAKE_ROOT)
		    afsp->s_root = d_make_root(ip);
#else
		    afsp->s_root = d_alloc_root(ip);
#endif
#if !defined(STRUCT_SUPER_BLOCK_HAS_S_D_OP)
		    afsp->s_root->d_op = &afs_dentry_operations;
#endif
		    afs_DestroyAttr(vattr);
		}
	    } else
		code = EIO;
	}
	crfree(credp);
	afs_DestroyReq(treq);
    }

    afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, afs_globalVp,
	       ICL_TYPE_INT32, code);
    return code;
}
Ejemplo n.º 2
0
/* afs_root - stat the root of the file system. AFS global held on entry. */
static int
afs_root(struct super_block *afsp)
{
    afs_int32 code = 0;
    struct vrequest treq;
    struct vcache *tvp = 0;

    AFS_STATCNT(afs_root);
    if (afs_globalVp && (afs_globalVp->f.states & CStatd)) {
	tvp = afs_globalVp;
    } else {
	cred_t *credp = crref();

	if (afs_globalVp) {
	    afs_PutVCache(afs_globalVp);
	    afs_globalVp = NULL;
	}

	if (!(code = afs_InitReq(&treq, credp)) && !(code = afs_CheckInit())) {
	    tvp = afs_GetVCache(&afs_rootFid, &treq, NULL, NULL);
	    if (tvp) {
		struct inode *ip = AFSTOV(tvp);
		struct vattr vattr;

		afs_getattr(tvp, &vattr, credp);
		afs_fill_inode(ip, &vattr);

		/* setup super_block and mount point inode. */
		afs_globalVp = tvp;
#if defined(AFS_LINUX24_ENV)
		afsp->s_root = d_alloc_root(ip);
#else
		afsp->s_root = d_alloc_root(ip, NULL);
#endif
		afsp->s_root->d_op = &afs_dentry_operations;
	    } else
		code = ENOENT;
	}
	crfree(credp);
    }

    afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, afs_globalVp,
	       ICL_TYPE_INT32, code);
    return code;
}
Ejemplo n.º 3
0
int
afs_root(OSI_VFS_DECL(afsp), struct vnode **avpp)
{
    afs_int32 code = 0;
    struct vrequest treq;
    struct vcache *tvp = 0;
    OSI_VFS_CONVERT(afsp);

    AFS_STATCNT(afs_root);
    if (afs_globalVp && (afs_globalVp->f.states & CStatd)) {
	tvp = afs_globalVp;
    } else {
	if (afs_globalVp) {
	    afs_PutVCache(afs_globalVp);
	    afs_globalVp = NULL;
	}

	if (!(code = afs_InitReq(&treq, get_user_struct()->u_cred))
	    && !(code = afs_CheckInit())) {
	    tvp = afs_GetVCache(&afs_rootFid, &treq, NULL, NULL);
	    /* we really want this to stay around */
	    if (tvp) {
		afs_globalVp = tvp;
	    } else
		code = ENOENT;
	}
    }
    if (tvp) {
	VN_HOLD(AFSTOV(tvp));

	AFSTOV(tvp)->v_flag |= VROOT;	/* No-op on Ultrix 2.2 */
	afs_globalVFS = afsp;
	*avpp = AFSTOV(tvp);
    }

    afs_Trace3(afs_iclSetp, CM_TRACE_GOPEN, ICL_TYPE_POINTER, *avpp,
	       ICL_TYPE_INT32, 0, ICL_TYPE_INT32, code);
    return code;
}
Ejemplo n.º 4
0
afs_root(struct mount *mp, struct vnode **vpp)
#endif
{
    int error;
    struct vrequest treq;
    register struct vcache *tvp = 0;
#ifdef AFS_FBSD50_ENV
#ifndef AFS_FBSD53_ENV
    struct thread *td = curthread;
#endif
    struct ucred *cr = td->td_ucred;
#else
    struct proc *p = curproc;
    struct ucred *cr = p->p_cred->pc_ucred;
#endif

    AFS_GLOCK();
    AFS_STATCNT(afs_root);
    crhold(cr);
    if (afs_globalVp && (afs_globalVp->f.states & CStatd)) {
	tvp = afs_globalVp;
	error = 0;
    } else {
tryagain:
#ifndef AFS_FBSD80_ENV
	if (afs_globalVp) {
	    afs_PutVCache(afs_globalVp);
	    /* vrele() needed here or not? */
	    afs_globalVp = NULL;
	}
#endif
	if (!(error = afs_InitReq(&treq, cr)) && !(error = afs_CheckInit())) {
	    tvp = afs_GetVCache(&afs_rootFid, &treq, NULL, NULL);
	    /* we really want this to stay around */
	    if (tvp)
		afs_globalVp = tvp;
	    else
		error = ENOENT;
	}
    }
    if (tvp) {
	struct vnode *vp = AFSTOV(tvp);

#ifdef AFS_FBSD50_ENV
	ASSERT_VI_UNLOCKED(vp, "afs_root");
#endif
	AFS_GUNLOCK();
	/*
	 * I'm uncomfortable about this.  Shouldn't this happen at a
	 * higher level, and shouldn't we busy the top-level directory
	 * to prevent recycling?
	 */
#ifdef AFS_FBSD50_ENV
	error = vget(vp, LK_EXCLUSIVE | LK_RETRY, td);
	vp->v_vflag |= VV_ROOT;
#else
	error = vget(vp, LK_EXCLUSIVE | LK_RETRY, p);
	vp->v_flag |= VROOT;
#endif
	AFS_GLOCK();
	if (error != 0)
		goto tryagain;

	afs_globalVFS = mp;
	*vpp = vp;
    }

    afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, tvp ? AFSTOV(tvp) : NULL,
	       ICL_TYPE_INT32, error);
    AFS_GUNLOCK();
    crfree(cr);
    return error;
}
Ejemplo n.º 5
0
afs_root(struct mount *mp, struct vnode **vpp)
#endif
{
    int error;
    struct vrequest treq;
    struct vcache *tvp = 0;
    struct vcache *gvp;
#if !defined(AFS_FBSD53_ENV) || defined(AFS_FBSD80_ENV)
    struct thread *td = curthread;
#endif
    struct ucred *cr = osi_curcred();

    AFS_GLOCK();
    AFS_STATCNT(afs_root);
    crhold(cr);
tryagain:
    if (afs_globalVp && (afs_globalVp->f.states & CStatd)) {
	tvp = afs_globalVp;
	error = 0;
    } else {
	if (!(error = afs_InitReq(&treq, cr)) && !(error = afs_CheckInit())) {
	    tvp = afs_GetVCache(&afs_rootFid, &treq, NULL, NULL);
	    /* we really want this to stay around */
	    if (tvp) {
		gvp = afs_globalVp;
		afs_globalVp = tvp;
		if (gvp) {
		    afs_PutVCache(gvp);
		    if (tvp != afs_globalVp) {
			/* someone raced us and won */
			afs_PutVCache(tvp);
			goto tryagain;
		    }
		}
	    } else
		error = ENOENT;
	}
    }
    if (tvp) {
	struct vnode *vp = AFSTOV(tvp);

	ASSERT_VI_UNLOCKED(vp, "afs_root");
	AFS_GUNLOCK();
	error = vget(vp, LK_EXCLUSIVE | LK_RETRY, td);
	AFS_GLOCK();
	/* we dropped the glock, so re-check everything it had serialized */
	if (!afs_globalVp || !(afs_globalVp->f.states & CStatd) ||
		tvp != afs_globalVp) {
	    vput(vp);
	    afs_PutVCache(tvp);
	    goto tryagain;
	}
	if (error != 0)
	    goto tryagain;
	/*
	 * I'm uncomfortable about this.  Shouldn't this happen at a
	 * higher level, and shouldn't we busy the top-level directory
	 * to prevent recycling?
	 */
	vp->v_vflag |= VV_ROOT;

	afs_globalVFS = mp;
	*vpp = vp;
    }

    afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, tvp ? AFSTOV(tvp) : NULL,
	       ICL_TYPE_INT32, error);
    AFS_GUNLOCK();
    crfree(cr);
    return error;
}