PERFORCE change 169106 for review
Gleb Kurtsou
gk at FreeBSD.org
Thu Oct 1 20:30:52 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=169106
Change 169106 by gk at 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) <<<
More information about the p4-projects
mailing list