tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Fullfs file system



Thanks Mouse and Martin. I got past that error. But
now I'm running into another problem - unable to
determine when write op occurs (to be able to return
ENOSPC error).

I'm trying to use the 'bypass routine' by creating a
new `full_bypass` by duplicating `layer_bypass`. In this
`full_bypass` I want to return ENOSPC error whenever
write occurs. Which variable contains this info? I'm
confused which structs contain what information.

-- IC

full_bypass for reference:

int
full_bypass(void *v)
{
	struct vop_generic_args /* {
		struct vnodeop_desc *a_desc;
		<other random data follows, presumably>
	} */ *ap = v;
	int (**our_vnodeop_p)(void *);
	struct vnode **this_vp_p;
	int error;
	struct vnode *old_vps[VDESC_MAX_VPS], *vp0;
	struct vnode **vps_p[VDESC_MAX_VPS];
	struct vnode ***vppp;
	struct mount *mp;
	struct vnodeop_desc *descp = ap->a_desc;
	int reles, i, flags;

#ifdef DIAGNOSTIC
	/*
	 * We require at least one vp.
	 */
	if (descp->vdesc_vp_offsets == NULL ||
	    descp->vdesc_vp_offsets[0] == VDESC_NO_OFFSET)
		panic("%s: no vp's in map.\n", __func__);
#endif

	vps_p[0] =
	    VOPARG_OFFSETTO(struct vnode**, descp->vdesc_vp_offsets[0], ap);
	vp0 = *vps_p[0];
	mp = vp0->v_mount;
	flags = MOUNTTOLAYERMOUNT(mp)->layerm_flags;
	our_vnodeop_p = vp0->v_op;

	if (flags & LAYERFS_MBYPASSDEBUG)
		printf("%s: %s\n", __func__, descp->vdesc_name);

	/*
	 * Map the vnodes going in.
	 * Later, we'll invoke the operation based on
	 * the first mapped vnode's operation vector.
	 */
	reles = descp->vdesc_flags;
	for (i = 0; i < VDESC_MAX_VPS; reles >>= 1, i++) {
		if (descp->vdesc_vp_offsets[i] == VDESC_NO_OFFSET)
			break;   /* bail out at end of list */
		vps_p[i] = this_vp_p =
		    VOPARG_OFFSETTO(struct vnode**, descp->vdesc_vp_offsets[i],
		    ap);
		/*
		 * We're not guaranteed that any but the first vnode
		 * are of our type.  Check for and don't map any
		 * that aren't.  (We must always map first vp or vclean fails.)
		 */
		if (i && (*this_vp_p == NULL ||
		    (*this_vp_p)->v_op != our_vnodeop_p)) {
			old_vps[i] = NULL;
		} else {
			old_vps[i] = *this_vp_p;
			*(vps_p[i]) = LAYERVPTOLOWERVP(*this_vp_p);
			/*
			 * XXX - Several operations have the side effect
			 * of vrele'ing their vp's.  We must account for
			 * that.  (This should go away in the future.)
			 */
			if (reles & VDESC_VP0_WILLRELE)
				vref(*this_vp_p);
		}
	}

///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////

                      I want to return ENOSPC here
                        if there is a write operation

///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////

	/*
	 * Call the operation on the lower layer
	 * with the modified argument structure.
	 */
	error = VCALL(*vps_p[0], descp->vdesc_offset, ap);

	/*
	 * Maintain the illusion of call-by-value
	 * by restoring vnodes in the argument structure
	 * to their original value.
	 */
	reles = descp->vdesc_flags;
	for (i = 0; i < VDESC_MAX_VPS; reles >>= 1, i++) {
		if (descp->vdesc_vp_offsets[i] == VDESC_NO_OFFSET)
			break;   /* bail out at end of list */
		if (old_vps[i]) {
			*(vps_p[i]) = old_vps[i];
			if (reles & VDESC_VP0_WILLRELE)
				vrele(*(vps_p[i]));
		}
	}

	/*
	 * Map the possible out-going vpp
	 * (Assumes that the lower layer always returns
	 * a VREF'ed vpp unless it gets an error.)
	 */
	if (descp->vdesc_vpp_offset != VDESC_NO_OFFSET && !error) {
		vppp = VOPARG_OFFSETTO(struct vnode***,
				 descp->vdesc_vpp_offset, ap);
		/*
		 * Only vop_lookup, vop_create, vop_makedir, vop_mknod
		 * and vop_symlink return vpp's. vop_lookup doesn't call bypass
		 * as a lookup on "." would generate a locking error.
		 * So all the calls which get us here have a unlocked vpp. :-)
		 */
		error = layer_node_create(mp, **vppp, *vppp);
		if (error) {
			vrele(**vppp);
			**vppp = NULL;
		}
	}
	return error;
}


Home | Main Index | Thread Index | Old Index