Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 1 Oct 2009 20:30:50 GMT
From:      Gleb Kurtsou <gk@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 169106 for review
Message-ID:  <200910012030.n91KUofl062894@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=169106

Change 169106 by gk@gk_h1 on 2009/10/01 20:30:32

	remove pefs_bypass
	add pefs_accessx
	pefs_rename: vput vnode after VOP_LOOKUP
	VOP_RENAME is expected to vrele vnodes in error case
	whitespace

Affected files ...

.. //depot/projects/soc2009/gk_pefs/sbin/pefs/Makefile#5 edit
.. //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_ctl.c#10 edit
.. //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_keychain.c#6 edit
.. //depot/projects/soc2009/gk_pefs/sys/crypto/salsa20/salsa20.c#3 edit
.. //depot/projects/soc2009/gk_pefs/sys/crypto/salsa20/salsa20.h#2 edit
.. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs.h#13 edit
.. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_crypto.c#13 edit
.. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_hmac.c#3 edit
.. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_subr.c#13 edit
.. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_vnops.c#19 edit
.. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_xbase64.c#6 edit

Differences ...

==== //depot/projects/soc2009/gk_pefs/sbin/pefs/Makefile#5 (text+ko) ====

@@ -1,6 +1,6 @@
 # $FreeBSD$
 
-MOUNT=	${.CURDIR}/../mount 
+MOUNT=	${.CURDIR}/../mount
 SYS=	${.CURDIR}/../../sys
 .PATH:	${MOUNT} ${SYS}/geom/eli ${SYS}/crypto/sha2
 

==== //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_ctl.c#10 (text+ko) ====

@@ -370,7 +370,7 @@
 		warn("cannot open %s", argv[0]);
 		return (EX_IOERR);
 	}
-	
+
 	if (ioctl(fd, PEFS_SETKEY, &k) == -1) {
 		warn("cannot set key");
 		error = EX_OSERR;
@@ -463,7 +463,7 @@
 		}
 	argc -= optind;
 	argv += optind;
-	
+
 	if (!checkargs_fs(argc, argv)) {
 		pefs_usage();
 	}
@@ -805,7 +805,7 @@
 			    pefs_keyid_as_int(k[1].pxk_keyid));
 		}
 	}
-	
+
 	close(fd);
 
 	return (0);
@@ -882,7 +882,7 @@
 			return (cmd->func(argc, argv));
 		}
 	}
-	
+
 	warnx("unknown command: %s", argv[1]);
 	pefs_usage();
 

==== //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_keychain.c#6 (text+ko) ====

@@ -112,11 +112,11 @@
 		}
 		if (db_data.size != sizeof(struct pefs_xkeyenc))
 			errx(EX_DATAERR, "keychain: db damaged");
-		
+
 		kc = calloc(1, sizeof(struct pefs_keychain));
 		if (kc == NULL)
 			err(EX_OSERR, "calloc");
-		
+
 		memcpy(&ke, db_data.data, sizeof(struct pefs_xkeyenc));
 		error = pefs_key_decrypt(&ke, &kc_parent->kc_key);
 		if (error)
@@ -164,7 +164,7 @@
 		err(EX_OSERR, "calloc");
 	kc->kc_key = *xk;
 	TAILQ_INSERT_HEAD(kch, kc, kc_entry);
-	
+
 	if (flags == 0)
 		return (0);
 
@@ -205,7 +205,7 @@
 	ke.keybits = htole32(xk->pxk_keybits);
 	if (pefs_key_encrypt(&ke, xk) != 0)
 		return (-1);
-	
+
 	db = keychain_dbopen(filesystem, PEFS_KEYCHAIN_USE, O_RDWR | O_CREAT);
 	if (db == NULL)
 		return (-1);

==== //depot/projects/soc2009/gk_pefs/sys/crypto/salsa20/salsa20.c#3 (text+ko) ====

@@ -23,7 +23,7 @@
 static const char sigma[16] = "expand 32-byte k";
 static const char tau[16] = "expand 16-byte k";
 
-void 
+void
 salsa20_keysetup(salsa20_ctx *x, const uint8_t *k, uint32_t kbits)
 {
 	const char *constants;
@@ -48,7 +48,7 @@
 	x->input[15] = U8TO32_LITTLE(constants + 12);
 }
 
-void 
+void
 salsa20_ivsetup(salsa20_ctx *x, const uint8_t *iv, uint64_t offset)
 {
 	x->skip = offset & ((1 << 6) - 1);
@@ -60,10 +60,10 @@
 	x->input[9] = htole32((uint32_t) offset);
 }
 
-void 
+void
 salsa20_crypt(salsa20_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes)
 {
-	uint32_t x0, x1, x2, x3, x4, x5, x6, x7, 
+	uint32_t x0, x1, x2, x3, x4, x5, x6, x7,
 		 x8, x9, x10, x11, x12, x13, x14, x15;
 	uint8_t *ctarget = NULL;
 	const uint8_t *msrc = NULL;

==== //depot/projects/soc2009/gk_pefs/sys/crypto/salsa20/salsa20.h#2 (text+ko) ====

@@ -1,5 +1,5 @@
 /*
- * salsa20-merged.c version 20051118 
+ * salsa20-merged.c version 20051118
  * D. J. Bernstein
  * Public domain.
  */

==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs.h#13 (text+ko) ====

@@ -171,7 +171,7 @@
 void pefs_crypto_init(void);
 void pefs_crypto_uninit(void);
 
-int pefs_node_get_nokey(struct mount *mp, struct vnode *lvp, 
+int pefs_node_get_nokey(struct mount *mp, struct vnode *lvp,
     struct vnode **vpp);
 int pefs_node_get_haskey(struct mount *mp, struct vnode *lvp,
     struct vnode **vpp, struct pefs_tkey *ptk);

==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_crypto.c#13 (text+ko) ====

@@ -50,7 +50,7 @@
 
 #define PEFS_CTR_BLOCK_SIZE		16
 #define PEFS_NAME_BLOCK_SIZE		16
-#define PEFS_BLOCK_ROUND(block, a)	(((a) + (block) - 1) & ~((block) - 1)) 
+#define PEFS_BLOCK_ROUND(block, a)	(((a) + (block) - 1) & ~((block) - 1))
 
 CTASSERT(PEFS_KEY_SIZE <= SHA512_DIGEST_LENGTH);
 CTASSERT(PEFS_TWEAK_SIZE == 64/8);
@@ -98,23 +98,23 @@
 static algop_keysetup_t pefs_camellia_keysetup;
 static algop_crypt_t pefs_camellia_crypt;
 
-static const struct pefs_alg pefs_alg_salsa20 = { 
+static const struct pefs_alg pefs_alg_salsa20 = {
 	PEFS_ALG_SALSA20,
-	pefs_salsa20_keysetup, 
+	pefs_salsa20_keysetup,
 	pefs_salsa20_ivsetup,
 	pefs_salsa20_crypt
 };
 
-static const struct pefs_alg pefs_alg_aes = { 
+static const struct pefs_alg pefs_alg_aes = {
 	PEFS_ALG_AES_CTR,
-	pefs_aes_keysetup, 
+	pefs_aes_keysetup,
 	pefs_ctr_ivsetup,
 	pefs_aes_crypt
 };
 
-static const struct pefs_alg pefs_alg_camellia = { 
+static const struct pefs_alg pefs_alg_camellia = {
 	PEFS_ALG_CAMELLIA_CTR,
-	pefs_camellia_keysetup, 
+	pefs_camellia_keysetup,
 	pefs_ctr_ivsetup,
 	pefs_camellia_crypt
 };
@@ -143,9 +143,9 @@
 void
 pefs_crypto_init(void)
 {
-	pefs_ctx_zone = uma_zcreate("pefs_ctx", sizeof(struct pefs_ctx), 
+	pefs_ctx_zone = uma_zcreate("pefs_ctx", sizeof(struct pefs_ctx),
 	    NULL, NULL, NULL, (uma_fini)bzero, UMA_ALIGN_PTR, 0);
-	pefs_key_zone = uma_zcreate("pefs_key", sizeof(struct pefs_key), 
+	pefs_key_zone = uma_zcreate("pefs_key", sizeof(struct pefs_key),
 	    NULL, NULL, NULL, (uma_fini)bzero, UMA_ALIGN_PTR, 0);
 }
 
@@ -447,7 +447,7 @@
 
 	MPASS(size > PEFS_NAME_CSUM_SIZE && size <= MAXNAMLEN);
 	psize = size - PEFS_NAME_CSUM_SIZE;
-	psize = PEFS_NAME_CSUM_SIZE + 
+	psize = PEFS_NAME_CSUM_SIZE +
 	    PEFS_BLOCK_ROUND(PEFS_NAME_BLOCK_SIZE, psize);
 
 	return (psize);
@@ -479,7 +479,7 @@
 	MPASS(size > PEFS_NAME_CSUM_SIZE &&
 	    size <= MAXNAMLEN &&
 	    (size - PEFS_NAME_CSUM_SIZE) % PEFS_NAME_BLOCK_SIZE == 0);
-	
+
 	pefs_ctx_cpy(ctx, pk->pk_name_csum_ctx);
 	csum_int = vmac(name + PEFS_NAME_CSUM_SIZE,
 	    size - PEFS_NAME_CSUM_SIZE,
@@ -710,13 +710,13 @@
 
 	pos = c->pctr_pos;
 	while (len) {
-		l = pos + len > PEFS_CTR_BLOCK_SIZE ? 
+		l = pos + len > PEFS_CTR_BLOCK_SIZE ?
 		    PEFS_CTR_BLOCK_SIZE - pos : len;
 		le_offset = htole64(c->pctr_offset);
-		memcpy(c->pctr_block + PEFS_TWEAK_SIZE, &le_offset, 
+		memcpy(c->pctr_block + PEFS_TWEAK_SIZE, &le_offset,
 		    sizeof(uint64_t));
 		memcpy(c->pctr_block, c->pctr_tweak, PEFS_TWEAK_SIZE);
-		
+
 		cryptblock(ctx, c->pctr_block);
 		for (i = 0; i < l; i++) {
 			*(ciphertext++) = c->pctr_block[pos + i] ^
@@ -744,10 +744,10 @@
 }
 
 static void
-pefs_camellia_crypt(struct pefs_ctx *ctx, const uint8_t *plaintext, 
+pefs_camellia_crypt(struct pefs_ctx *ctx, const uint8_t *plaintext,
     uint8_t *ciphertext, uint32_t len)
 {
-	pefs_ctr_crypt(ctx, pefs_camellia_cryptblock, 
+	pefs_ctr_crypt(ctx, pefs_camellia_cryptblock,
 	    plaintext, ciphertext, len);
 }
 
@@ -764,10 +764,10 @@
 }
 
 static void
-pefs_aes_crypt(struct pefs_ctx *ctx, const uint8_t *plaintext, 
+pefs_aes_crypt(struct pefs_ctx *ctx, const uint8_t *plaintext,
     uint8_t *ciphertext, uint32_t len)
 {
-	pefs_ctr_crypt(ctx, pefs_aes_cryptblock, 
+	pefs_ctr_crypt(ctx, pefs_aes_cryptblock,
 	    plaintext, ciphertext, len);
 }
 

==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_hmac.c#3 (text+ko) ====

@@ -49,7 +49,7 @@
 	else if (hkeylen <= SHA512_BLOCK_LENGTH)
 		bcopy(hkey, ctx->kpad, hkeylen);
 	else {
-		/* 
+		/*
 		 * If key is longer than SHA512_BLOCK_LENGTH bytes
 		 * reset it to key = SHA512(key).
 		 */
@@ -94,7 +94,7 @@
 	/* mdsize == 0 means "Give me the whole hash!" */
 	if (mdsize == 0)
 		mdsize = SHA512_DIGEST_LENGTH;
-	
+
 	bcopy(digest, md, mdsize);
 }
 

==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_subr.c#13 (text+ko) ====

@@ -127,7 +127,7 @@
 
 	pefs_node_zone = uma_zcreate("pefs_node", sizeof(struct pefs_node),
 	    NULL, NULL, NULL, (uma_fini) bzero, UMA_ALIGN_PTR, 0);
-	
+
 	pefs_node_hashtbl = hashinit(NPENODECACHE, M_PEFSHASH, &pefs_node_hash);
 	mtx_init(&pefs_node_listmtx, "pefs_node_list", NULL, MTX_DEF);
 	pefs_crypto_init();
@@ -240,7 +240,7 @@
 	struct vnode *nldvp;
 	int error, locked, dlocked;
 	int buflen = *encname_len;
- 
+
 	ASSERT_VOP_LOCKED(lvp, "pefs_node_lookup_name");
 	locked = VOP_ISLOCKED(lvp);
 	if (ldvp) {
@@ -250,7 +250,7 @@
 	} else {
 		dlocked = 0;
 	}
- 
+
 	vref(lvp);
 	VOP_UNLOCK(lvp, 0);
 	nldvp = lvp;
@@ -277,34 +277,34 @@
 pefs_node_lookup_key(struct pefs_mount *pm, struct vnode *lvp,
     struct vnode *ldvp, struct ucred *cred, struct pefs_tkey *ptk)
 {
- 	char *namebuf;
+	char *namebuf;
 	char *encname;
 	int error, encname_len, name_len;
- 
+
 	namebuf = malloc((MAXNAMLEN + 1)*2, M_PEFSBUF, M_WAITOK | M_ZERO);
 	encname = namebuf + MAXNAMLEN + 1;
 	encname_len = MAXNAMLEN + 1;
- 
+
 	error = pefs_node_lookup_name(lvp, ldvp, cred, encname, &encname_len);
 	if (error) {
 		free(namebuf, M_PEFSBUF);
 		return (error);
 	}
- 
+
 	PEFSDEBUG("pefs_node_lookup_key: encname=%.*s\n", encname_len, encname);
-	
-	name_len = pefs_name_decrypt(NULL, pefs_rootkey(pm), ptk, 
-			encname, encname_len, 
+
+	name_len = pefs_name_decrypt(NULL, pefs_rootkey(pm), ptk,
+			encname, encname_len,
 			namebuf, MAXNAMLEN + 1);
 
 	if (name_len > 0) {
 		pefs_key_ref(ptk->ptk_key);
- 	} else {
+	} else {
 		PEFSDEBUG("pefs_node_lookup_key: not found: %.*s\n", encname_len, encname);
 	}
-	
- 	free(namebuf, M_PEFSBUF);
-	
+
+	free(namebuf, M_PEFSBUF);
+
 	return (error);
 }
 
@@ -361,7 +361,7 @@
  * the caller's "spare" reference to created pefs vnode.
  */
 static int
-pefs_node_get(struct mount *mp, struct vnode *lvp, struct vnode **vpp, 
+pefs_node_get(struct mount *mp, struct vnode *lvp, struct vnode **vpp,
     pefs_node_init_fn *init_fn, void *context)
 {
 	struct pefs_node *pn;

==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_vnops.c#19 (text+ko) ====

@@ -281,7 +281,7 @@
 		offset = uio->uio_offset;
 
 		pefs_chunk_setsize(&pc, pc.pc_size - uio->uio_resid);
-		de = pefs_enccn_lookup_dirent(dpn_key, &ptk, 
+		de = pefs_enccn_lookup_dirent(dpn_key, &ptk,
 		    pc.pc_base, pc.pc_size,
 		    cnp->cn_nameptr, cnp->cn_namelen);
 		if (de != NULL)
@@ -370,14 +370,14 @@
 			continue;
 		VI_LOCK(vp);
 		pn = VP_TO_PN(vp);
-		if (((pn->pn_flags & PN_HASKEY) && 
+		if (((pn->pn_flags & PN_HASKEY) &&
 		    ((flags & PEFS_FLUSHKEY_ALL) ||
 		    pn->pn_tkey.ptk_key == pk)) ||
 		    ((pn->pn_flags & PN_HASKEY) == 0 && pk == NULL)) {
 			vholdl(vp);
 			MNT_IUNLOCK(mp);
 			error = vn_lock(vp, LK_INTERLOCK | LK_EXCLUSIVE);
-			if (error) {
+			if (error != 0) {
 				vdrop(vp);
 				MNT_ILOCK(mp);
 				MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp);
@@ -398,154 +398,6 @@
 	return (0);
 }
 
-/*
- * This is the 10-Apr-92 bypass routine.
- *    This version has been optimized for speed, throwing away some
- * safety checks.  It should still always work, but it's not as
- * robust to programmer errors.
- *
- * In general, we map all vnodes going down and unmap them on the way back.
- * As an exception to this, vnodes can be marked "unmapped" by setting
- * the Nth bit in operation's vdesc_flags.
- *
- * Also, some BSD vnode operations have the side effect of vrele'ing
- * their arguments.  With stacking, the reference counts are held
- * by the upper node, not the lower one, so we must handle these
- * side-effects here.  This is not of concern in Sun-derived systems
- * since there are no such side-effects.
- *
- * This makes the following assumptions:
- * - only one returned vpp
- * - no INOUT vpp's (Sun's vop_open has one of these)
- * - the vnode operation vector of the first vnode should be used
- *   to determine what implementation of the op should be invoked
- * - all mapped vnodes are of our vnode-type (NEEDSWORK:
- *   problems on rmdir'ing mount points and renaming?)
- */
-static int
-pefs_bypass(struct vop_generic_args *ap, struct pefs_tkey *ptk)
-{
-	struct vnode **this_vp_p;
-	int error;
-	struct vnode *old_vps[VDESC_MAX_VPS];
-	struct vnode **vps_p[VDESC_MAX_VPS];
-	struct vnode ***vppp;
-	struct vnodeop_desc *descp = ap->a_desc;
-	int reles, i;
-
-	if (pefs_bug_bypass)
-		printf ("pefs_bypass: %s\n", descp->vdesc_name);
-
-#ifdef DIAGNOSTIC
-	/*
-	 * We require at least one vp.
-	 */
-	if (descp->vdesc_vp_offsets == NULL ||
-	    descp->vdesc_vp_offsets[0] == VDESC_NO_OFFSET)
-		panic ("pefs_bypass: no vp's in map");
-#endif
-
-	/*
-	 * 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 == NULLVP ||
-		    (*this_vp_p)->v_op != &pefs_vnodeops)) {
-			old_vps[i] = NULLVP;
-		} else {
-			old_vps[i] = *this_vp_p;
-			*(vps_p[i]) = PEFS_LOWERVP(*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);
-		}
-
-	}
-
-	/*
-	 * Call the operation on the lower layer
-	 * with the modified argument structure.
-	 */
-	if (vps_p[0] && *vps_p[0])
-		error = VCALL(ap);
-	else {
-		printf("pefs_bypass: no map for %s\n", descp->vdesc_name);
-		error = EINVAL;
-	}
-
-	/*
-	 * 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 0
-			if (reles & VDESC_VP0_WILLUNLOCK)
-				VOP_UNLOCK(*(vps_p[i]), 0);
-#endif
-			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 &&
-	    !(descp->vdesc_flags & VDESC_NOMAP_VPP) &&
-	    !error) {
-		/* XXX should panic here unconditionally or remove the func */
-		if (ptk == NULL || ptk->ptk_key == NULL) {
-			panic("vop_bypass: map of outgoing vnode without encrypted name: %s", descp->vdesc_name);
-		}
-		/*
-		 * XXX - even though some ops have vpp returned vp's,
-		 * several ops actually vrele this before returning.
-		 * We must avoid these ops.
-		 * (This should go away when these ops are regularized.)
-		 */
-		if (descp->vdesc_flags & VDESC_VPP_WILLRELE)
-			goto out;
-		vppp = VOPARG_OFFSETTO(struct vnode***,
-				 descp->vdesc_vpp_offset,ap);
-		if (*vppp) {
-			error = pefs_node_get_haskey(old_vps[0]->v_mount,
-				**vppp, *vppp, ptk);
-		}
-	}
-
- out:
-	return (error);
-}
-
-/*
- * We have to carry on the locking protocol on the null layer vnodes
- * as we progress through the tree. We also have to enforce read-only
- * if this layer is mounted read-only.
- */
 static int
 pefs_lookup(struct vop_cachedlookup_args *ap)
 {
@@ -565,7 +417,7 @@
 
 	pefs_enccn_init(&enccn);
 
-	if ((flags & ISLASTCN) && 
+	if ((flags & ISLASTCN) &&
 	    ((dvp->v_mount->mnt_flag & MNT_RDONLY) || pefs_no_keys(dvp)) &&
 	    (cnp->cn_nameiop != LOOKUP))
 		return (EROFS);
@@ -589,7 +441,7 @@
 		    (cnp->cn_nameiop == DELETE &&
 		    (cnp->cn_flags & DOWHITEOUT) &&
 		    (cnp->cn_flags & ISWHITEOUT)))) {
-			/* 
+			/*
 			 * Some filesystems (like ufs) update internal inode
 			 * fields during VOP_LOOKUP which are later used by
 			 * VOP_CREATE, VOP_MKDIR, etc. That's why we can't
@@ -640,13 +492,13 @@
 			else
 				error = pefs_node_get_haskey(dvp->v_mount, lvp,
 				    &vp, &enccn.pec_tkey);
-			if (error) {
+			if (error != 0) {
 				vput(lvp);
 			} else {
 				*ap->a_vpp = vp;
 				if ((cnp->cn_flags & MAKEENTRY) &&
 				    cnp->cn_nameiop != CREATE) {
-					PEFSDEBUG("pefs_lookup: cache_enter %.*s\n", 
+					PEFSDEBUG("pefs_lookup: cache_enter %.*s\n",
 					    (int)cnp->cn_namelen,cnp->cn_nameptr);
 					cache_enter(dvp, vp, cnp);
 				}
@@ -669,16 +521,17 @@
 pefs_open(struct vop_open_args *ap)
 {
 	struct vnode *vp = ap->a_vp;
+	struct vnode *lvp = PEFS_LOWERVP(vp);
 	struct pefs_node *pn = VP_TO_PN(vp);
 	int error;
 
 	if (pefs_no_keys(vp) && (ap->a_mode & (FWRITE | O_APPEND)))
 		return (EROFS);
 
-	error = pefs_bypass(&ap->a_gen, NULL);
+	error = VOP_OPEN(lvp, ap->a_mode, ap->a_cred, ap->a_td, ap->a_fp);
 	if (error == 0) {
 		if ((pn->pn_flags & PN_HASKEY) == 0)
-			vp->v_object = PEFS_LOWERVP(vp)->v_object;
+			vp->v_object = lvp->v_object;
 		else
 			vnode_create_vobject(vp, 0, ap->a_td);
 	}
@@ -703,7 +556,7 @@
 	MPASS(pn->pn_flags & PN_HASKEY);
 
 	error = VOP_GETATTR(lvp, &va, cred);
-	if (error)
+	if (error != 0)
 		return (error);
 	osize = va.va_size;
 
@@ -713,7 +566,7 @@
 	if (VOP_ISLOCKED(vp) != LK_EXCLUSIVE) {
 		vn_lock(vp, LK_UPGRADE | LK_RETRY);
 		error = VOP_GETATTR(lvp, &va, cred);
-		if (error)
+		if (error != 0)
 			return (error);
 		osize = va.va_size;
 		if (nsize <= osize)
@@ -739,9 +592,10 @@
 		pefs_chunk_zero(&pc);
 		pefs_data_encrypt_update(ctx, &pn->pn_tkey, &pc);
 		puio = pefs_chunk_uio(&pc, offset, UIO_WRITE);
-		PEFSDEBUG("pefs_tryextend: resizing file; filling with zeros: offset=0x%jx, resid=0x%jx\n", offset, bsize);
+		PEFSDEBUG("pefs_tryextend: resizing file; filling with zeros: offset=0x%jx, resid=0x%jx\n",
+		    offset, bsize);
 		error = VOP_WRITE(lvp, puio, 0, cred);
-		if (error) {
+		if (error != 0) {
 			/* try to reset */
 			VATTR_NULL(&va);
 			va.va_size = osize;
@@ -772,20 +626,20 @@
 	struct vattr *vap = ap->a_vap;
 	int error;
 
-  	if ((vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL ||
+	if ((vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL ||
 	    vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL ||
 	    vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL) &&
 	    (vp->v_mount->mnt_flag & MNT_RDONLY || pefs_no_keys(vp)))
 		return (EROFS);
 
 	if (vap->va_size != VNOVAL) {
- 		switch (vp->v_type) {
- 		case VDIR:
- 			return (EISDIR);
- 		case VCHR:
- 		case VBLK:
- 		case VSOCK:
- 		case VFIFO:
+		switch (vp->v_type) {
+		case VDIR:
+			return (EISDIR);
+		case VCHR:
+		case VBLK:
+		case VSOCK:
+		case VFIFO:
 			if (vap->va_flags != VNOVAL)
 				return (EOPNOTSUPP);
 			return (0);
@@ -805,11 +659,11 @@
 				error = pefs_tryextend(vp, vap->va_size, cred);
 			else
 				error = EOPNOTSUPP; /* TODO */
-			if (error)
+			if (error != 0)
 				return (error);
 			vnode_pager_setsize(vp, vap->va_size);
 			break;
- 		default:
+		default:
 			return (EOPNOTSUPP);
 		}
 	}
@@ -823,13 +677,15 @@
 static int
 pefs_getattr(struct vop_getattr_args *ap)
 {
+	struct vnode *vp = ap->a_vp;
 	struct vattr *vap = ap->a_vap;
 	int error;
 
-	if ((error = pefs_bypass((struct vop_generic_args *)ap, NULL)) != 0)
+	error = VOP_GETATTR(PEFS_LOWERVP(vp), vap, ap->a_cred);
+	if (error != 0)
 		return (error);
 
-	vap->va_fsid = ap->a_vp->v_mount->mnt_stat.f_fsid.val[0];
+	vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
 	if (vap->va_type == VLNK) {
 		vap->va_size = PEFS_NAME_PTON_SIZE(vap->va_size);
 	}
@@ -840,11 +696,8 @@
  * Handle to disallow write access if mounted read-only.
  */
 static int
-pefs_access(struct vop_access_args *ap)
+pefs_access_checkmode(struct vnode *vp, accmode_t accmode)
 {
-	struct vnode *vp = ap->a_vp;
-	accmode_t accmode = ap->a_accmode;
-
 	/*
 	 * Disallow write attempts on read-only layers;
 	 * unless the file is a socket, fifo, or a block or
@@ -855,6 +708,10 @@
 		case VDIR:
 		case VLNK:
 		case VREG:
+			/*
+			 * Do not check pefs_no_keys(vp) here because ioctls
+			 * expect filesystem to be writable right after mount
+			 */
 			if (vp->v_mount->mnt_flag & MNT_RDONLY)
 				return (EROFS);
 			break;
@@ -862,21 +719,49 @@
 			break;
 		}
 	}
-	return (pefs_bypass((struct vop_generic_args *)ap, NULL));
+
+	return (0);
+}
+
+static int
+pefs_access(struct vop_access_args *ap)
+{
+	struct vnode *vp = ap->a_vp;
+	accmode_t accmode = ap->a_accmode;
+	int error;
+
+	error = pefs_access_checkmode(vp, accmode);
+	if (error != 0)
+		return (error);
+	error = VOP_ACCESS(PEFS_LOWERVP(vp), accmode, ap->a_cred, ap->a_td);
+	return (error);
+}
+
+static int
+pefs_accessx(struct vop_accessx_args *ap)
+{
+	struct vnode *vp = ap->a_vp;
+	accmode_t accmode = ap->a_accmode;
+	int error;
+
+	error = pefs_access_checkmode(vp, accmode);
+	if (error != 0)
+		return (error);
+	error = VOP_ACCESSX(PEFS_LOWERVP(vp), accmode, ap->a_cred, ap->a_td);
+	return (error);
 }
 
-/*
- * We handle this to eliminate null FS to lower FS
- * file moving. Don't know why we don't allow this,
- * possibly we should.
- */
 static int
 pefs_rename(struct vop_rename_args *ap)
 {
 	struct vnode *fdvp = ap->a_fdvp;
+	struct vnode *lfdvp = PEFS_LOWERVP(fdvp);
 	struct vnode *fvp = ap->a_fvp;
+	struct vnode *lfvp = PEFS_LOWERVP(fvp);
 	struct vnode *tdvp = ap->a_tdvp;
+	struct vnode *ltdvp = PEFS_LOWERVP(tdvp);
 	struct vnode *tvp = ap->a_tvp;
+	struct vnode *ltvp = (tvp == NULL ? NULL : PEFS_LOWERVP(tvp));
 	struct vnode *tovp = NULL;
 	struct componentname *fcnp = ap->a_fcnp;
 	struct componentname *tcnp = ap->a_tcnp;
@@ -910,9 +795,14 @@
 			PEFSDEBUG("pefs_rename: target dir !HASKEY: %s\n",
 			    tcnp->cn_nameptr);
 			/* Allow unencrypted to unencrypted rename. */
-			error = pefs_bypass((struct vop_generic_args *)ap,
-			    NULL);
-			return (error);
+			vref(lfdvp);
+			vref(lfvp);
+			vref(ltdvp);
+			if (ltvp != NULL)
+				vref(ltvp);
+			error = VOP_RENAME(lfdvp, lfvp, fcnp, ltdvp, ltvp,
+			    tcnp);
+			goto done;
 		}
 		/* Target directory is encrypted. Files should be recreated. */
 		error = EXDEV;
@@ -920,12 +810,12 @@
 	}
 
 	error = pefs_enccn_get(&fenccn, fvp, fcnp);
-	if (error) {
+	if (error != 0) {
 		goto bad;
 	}
 	error = pefs_enccn_create(&tenccn, fenccn.pec_tkey.ptk_key,
 	    fenccn.pec_tkey.ptk_tweak, tcnp);
-	if (error) {
+	if (error != 0) {
 		pefs_enccn_free(&fenccn);
 		goto bad;
 	}
@@ -933,27 +823,31 @@
 		tcnp->cn_nameiop = DELETE;
 		error = VOP_LOOKUP(tdvp, &tovp, tcnp);
 		tcnp->cn_nameiop = RENAME;
-		PEFSDEBUG("pefs_rename: lookup target vnode: %s: error=%d, tovp=%p\n", tcnp->cn_nameptr, error, tovp);
+		PEFSDEBUG("pefs_rename: lookup target vnode: %s: error=%d, tovp=%p\n",
+		    tcnp->cn_nameptr, error, tovp);
 		if (error == ENOENT)
 			error = 0;
 	}
-	if (error) {
+	if (error != 0) {
 		pefs_enccn_free(&fenccn);
 		pefs_enccn_free(&tenccn);
 		goto bad;
 	}
 
-	ap->a_fcnp = &fenccn.pec_cn;
-	ap->a_tcnp = &tenccn.pec_cn;
-	error = pefs_bypass((struct vop_generic_args *)ap, NULL);
-	ap->a_fcnp = fcnp;
-	ap->a_tcnp = tcnp;
+	vref(lfdvp);
+	vref(lfvp);
+	vref(ltdvp);
+	if (ltvp != NULL)
+		vref(ltvp);
+	error = VOP_RENAME(lfdvp, lfvp, &fenccn.pec_cn, ltdvp, ltvp,
+	    &tenccn.pec_cn);
 
 	pefs_enccn_free(&fenccn);
 	pefs_enccn_free(&tenccn);
 
-	if (!error) {
+	if (error == 0) {
 		if (tovp != NULL) {
+			MPASS(tovp->v_type == VREG);
 			vn_lock(tdvp, LK_EXCLUSIVE | LK_RETRY);
 			tcnp->cn_nameiop = DELETE;
 			error = VOP_REMOVE(tdvp, tovp, tcnp);
@@ -964,10 +858,18 @@
 		cache_purge(fdvp);
 		cache_purge(fvp);
 	} else {
-		if (tovp != NULL);
-			VOP_UNLOCK(tovp, 0);
+		if (tovp != NULL)
+			vput(tovp);
 	}
 
+done:
+	ASSERT_VOP_UNLOCKED(tdvp, "pefs_rename");
+	vrele(fdvp);
+	vrele(fvp);
+	vrele(tdvp);
+	if (tvp != NULL)
+		vrele(tvp);
+
 	return (error);
 
 bad:
@@ -975,7 +877,7 @@
 		vrele(tdvp);
 	else
 		vput(tdvp);
-	if (tvp)
+	if (tvp != NULL)
 		vput(tvp);
 	vrele(fdvp);
 	vrele(fvp);
@@ -1264,6 +1166,7 @@
 pefs_readdir(struct vop_readdir_args *ap)
 {
 	struct vnode *vp = ap->a_vp;
+	struct vnode *lvp = PEFS_LOWERVP(vp);
 	struct uio *uio = ap->a_uio;
 	struct ucred *cred = ap->a_cred;
 	int *eofflag = ap->a_eofflag;
@@ -1278,8 +1181,11 @@
 	int *a_ncookies;
 	u_long **a_cookies;
 
-	if (pefs_no_keys(vp))
-		return (pefs_bypass((struct vop_generic_args *)ap, NULL));
+	if (pefs_no_keys(vp)) {
+		error = VOP_READDIR(lvp, uio, cred, eofflag, ap->a_ncookies,
+		    ap->a_cookies);
+		return (error);
+	}
 
 	if (ap->a_ncookies == NULL || ap->a_cookies == NULL) {
 		a_ncookies = NULL;
@@ -1295,9 +1201,9 @@
 		if (uio->uio_resid < pc.pc_size)
 			pefs_chunk_setsize(&pc, uio->uio_resid);
 		puio = pefs_chunk_uio(&pc, uio->uio_offset, uio->uio_rw);
-		error = VOP_READDIR(PEFS_LOWERVP(vp), puio, cred, eofflag,
+		error = VOP_READDIR(lvp, puio, cred, eofflag,
 		    a_ncookies, a_cookies);
-		if (error)
+		if (error != 0)
 			break;
 
 		if (pc.pc_size == puio->uio_resid)
@@ -1364,6 +1270,7 @@
 pefs_mkdir(struct vop_mkdir_args *ap)
 {
 	struct vnode *dvp = ap->a_dvp;
+	struct vnode *lvp;
 	struct componentname *cnp = ap->a_cnp;
 	struct pefs_enccn enccn;
 	int error;
@@ -1374,13 +1281,17 @@
 	pefs_enccn_init(&enccn);
 	PEFS_ENCCN_ASSERT_NOENT(dvp, cnp);
 	error = pefs_enccn_create_node(&enccn, dvp, cnp);
-	if (error) {
+	if (error != 0) {
 		return (error);
 	}
 
-	ap->a_cnp = &enccn.pec_cn;
-	error = pefs_bypass((struct vop_generic_args *)ap, &enccn.pec_tkey);
-	ap->a_cnp = cnp;
+	error = VOP_MKDIR(PEFS_LOWERVP(dvp), &lvp, &enccn.pec_cn, ap->a_vap);
+	if (error == 0 && lvp != NULL) {
+		error = pefs_node_get_haskey(dvp->v_mount, lvp, ap->a_vpp,
+		    &enccn.pec_tkey);
+		if (error != 0)
+			vput(lvp);
+	}
 
 	pefs_enccn_free(&enccn);
 
@@ -1401,20 +1312,17 @@
 		return (EROFS);
 	pefs_enccn_init(&enccn);
 	error = pefs_enccn_get(&enccn, vp, cnp);
-	if (error) {
+	if (error != 0) {
 		PEFSDEBUG("pefs_rmdir: pefs_enccn_get failed: %d\n", error);
 		return (error);
 	}
 
-	ap->a_cnp = &enccn.pec_cn;
-	error = pefs_bypass((struct vop_generic_args *)ap, NULL);
-	ap->a_cnp = cnp;
-
+	error = VOP_RMDIR(PEFS_LOWERVP(dvp), PEFS_LOWERVP(vp), &enccn.pec_cn);
 	VP_TO_PN(vp)->pn_flags |= PN_WANTRECYCLE;
 
 	pefs_enccn_free(&enccn);
 
-	if (!error) {
+	if (error == 0) {
 		cache_purge(dvp);
 		cache_purge(vp);
 	}
@@ -1426,6 +1334,7 @@
 pefs_create(struct vop_create_args *ap)
 {
 	struct vnode *dvp = ap->a_dvp;
+	struct vnode *lvp;
 	struct componentname *cnp = ap->a_cnp;
 	struct pefs_enccn enccn;
 	int error;
@@ -1436,13 +1345,17 @@
 	pefs_enccn_init(&enccn);
 	PEFS_ENCCN_ASSERT_NOENT(dvp, cnp);
 	error = pefs_enccn_create_node(&enccn, dvp, cnp);
-	if (error) {
+	if (error != 0) {

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200910012030.n91KUofl062894>