Exemplo n.º 1
0
/*
 * Some commonality here with sdev_mknode(), could be simplified.
 * NOTE: prof_mknode returns with *newdv held once, if success.
 */
static int
prof_mknode(struct sdev_node *dir, char *name, struct sdev_node **newdv,
    vattr_t *vap, vnode_t *avp, void *arg, cred_t *cred)
{
	struct sdev_node *dv;
	int rv;

	ASSERT(RW_WRITE_HELD(&dir->sdev_contents));

	/* check cache first */
	if (dv = sdev_cache_lookup(dir, name)) {
		*newdv = dv;
		return (0);
	}

	/* allocate node and insert into cache */
	rv = sdev_nodeinit(dir, name, &dv, NULL);
	if (rv != 0) {
		*newdv = NULL;
		return (rv);
	}

	sdev_cache_update(dir, &dv, name, SDEV_CACHE_ADD);
	*newdv = dv;

	/* put it in ready state */
	rv = sdev_nodeready(*newdv, vap, avp, arg, cred);

	/* handle glob pattern in the middle of a path */
	if (rv == 0) {
		if (SDEVTOV(*newdv)->v_type == VDIR)
			sdcmn_err10(("sdev_origin for %s set to 0x%p\n",
			    name, arg));
		apply_glob_pattern(dir, *newdv);
	} else {
		sdev_cache_update(dir, &dv, name, SDEV_CACHE_DELETE);
		SDEV_RELE(dv);
	}
	return (rv);
}
Exemplo n.º 2
0
/*
 * Clean pts sdev_nodes that are no longer valid.
 */
static void
devpts_prunedir(struct sdev_node *ddv)
{
	struct vnode *vp;
	struct sdev_node *dv, *next = NULL;
	int (*vtor)(struct sdev_node *) = NULL;

	ASSERT(ddv->sdev_flags & SDEV_VTOR);

	vtor = (int (*)(struct sdev_node *))sdev_get_vtor(ddv);
	ASSERT(vtor);

	if (rw_tryupgrade(&ddv->sdev_contents) == NULL) {
		rw_exit(&ddv->sdev_contents);
		rw_enter(&ddv->sdev_contents, RW_WRITER);
	}

	for (dv = ddv->sdev_dot; dv; dv = next) {
		next = dv->sdev_next;

		/* skip stale nodes */
		if (dv->sdev_flags & SDEV_STALE)
			continue;

		/* validate and prune only ready nodes */
		if (dv->sdev_state != SDEV_READY)
			continue;

		switch (vtor(dv)) {
		case SDEV_VTOR_VALID:
		case SDEV_VTOR_SKIP:
			continue;
		case SDEV_VTOR_INVALID:
			sdcmn_err7(("prunedir: destroy invalid "
			    "node: %s(%p)\n", dv->sdev_name, (void *)dv));
			break;
		}
		vp = SDEVTOV(dv);
		if (vp->v_count > 0)
			continue;
		SDEV_HOLD(dv);
		/* remove the cache node */
		(void) sdev_cache_update(ddv, &dv, dv->sdev_name,
		    SDEV_CACHE_DELETE);
	}
	rw_downgrade(&ddv->sdev_contents);
}
Exemplo n.º 3
0
/*
 * First step in refreshing directory contents.
 * Remove each invalid entry and rebuild the link
 * reference for each stale entry.
 */
static void
devvt_prunedir(struct sdev_node *ddv)
{
	struct vnode *vp;
	struct sdev_node *dv, *next = NULL;
	int (*vtor)(struct sdev_node *) = NULL;

	ASSERT(ddv->sdev_flags & SDEV_VTOR);

	vtor = (int (*)(struct sdev_node *))sdev_get_vtor(ddv);
	ASSERT(vtor);

	for (dv = SDEV_FIRST_ENTRY(ddv); dv; dv = next) {
		next = SDEV_NEXT_ENTRY(ddv, dv);

		switch (vtor(dv)) {
		case SDEV_VTOR_VALID:
			break;
		case SDEV_VTOR_SKIP:
			break;
		case SDEV_VTOR_INVALID:
			vp = SDEVTOV(dv);
			if (vp->v_count != 0)
				break;
			/* remove the cached node */
			SDEV_HOLD(dv);
			(void) sdev_cache_update(ddv, &dv,
			    dv->sdev_name, SDEV_CACHE_DELETE);
			SDEV_RELE(dv);
			break;
		case SDEV_VTOR_STALE:
			devvt_rebuild_stale_link(ddv, dv);
			break;
		}
	}
}