--- a/usr/src/uts/common/fs/zfs/zio_crypt.c Tue Dec 23 02:33:29 2008 +0000
+++ b/usr/src/uts/common/fs/zfs/zio_crypt.c Tue Dec 23 05:06:28 2008 +0000
@@ -1729,7 +1729,8 @@
*/
static int
dnode_setup_crypto_data(void *src, size_t size,
- void *dest, iovec_t **srciovp, iovec_t **dstiovp, size_t *cdlen)
+ void *dest, iovec_t **srciovp, iovec_t **dstiovp, size_t *cdlen,
+ boolean_t encrypting)
{
dnode_phys_t *sdnp = src;
dnode_phys_t *ddnp = dest;
@@ -1765,15 +1766,16 @@
}
/*
- * We have iovcnt bonusbufs that need encrypting so build the uio.
+ * We have iovcnt bonusbufs that need encrypting so build the iov.
+ * Plus one addtional iov for the MAC.
*/
- srciov = kmem_alloc(sizeof (iovec_t) * iovcnt, KM_SLEEP);
-
- /*
- * Add an extra iov entry at the end for the MAC.
- */
- iovcnt++;
- dstiov = kmem_alloc(sizeof (iovec_t) * iovcnt, KM_SLEEP);
+ if (encrypting) {
+ srciov = kmem_alloc(sizeof (iovec_t) * iovcnt, KM_SLEEP);
+ dstiov = kmem_alloc(sizeof (iovec_t) * (iovcnt + 1), KM_SLEEP);
+ } else {
+ srciov = kmem_alloc(sizeof (iovec_t) * (iovcnt + 1), KM_SLEEP);
+ dstiov = kmem_alloc(sizeof (iovec_t) * iovcnt, KM_SLEEP);
+ }
/* From the beginning again build up the iov */
sdnp = src;
@@ -1869,7 +1871,8 @@
*/
int
zil_setup_crypto_data(char *src, size_t size,
- void *dest, iovec_t **srciovp, iovec_t **dstiovp, size_t *cdlen)
+ void *dest, iovec_t **srciovp, iovec_t **dstiovp, size_t *cdlen,
+ boolean_t encrypting)
{
char *slrp, *dlrp;
zil_trailer_t *ztp;
@@ -1893,12 +1896,18 @@
return (0);
}
- /* We have iovcnt log records that need encrypting. */
- srciov = kmem_alloc(sizeof (iovec_t) * iovcnt, KM_SLEEP);
+ /*
+ * We have iovcnt log records that need encrypting.
+ * Plus one more for the MAC
+ */
iovcheck = iovcnt;
-
- /* Add an extra iov in dest for the MAC */
- dstiov = kmem_alloc(sizeof (iovec_t) * (iovcnt + 1), KM_SLEEP);
+ if (encrypting) {
+ srciov = kmem_alloc(sizeof (iovec_t) * iovcnt, KM_SLEEP);
+ dstiov = kmem_alloc(sizeof (iovec_t) * (iovcnt + 1), KM_SLEEP);
+ } else {
+ srciov = kmem_alloc(sizeof (iovec_t) * (iovcnt + 1), KM_SLEEP);
+ dstiov = kmem_alloc(sizeof (iovec_t) * iovcnt, KM_SLEEP);
+ }
iovcnt = 0;
for (slrp = src, dlrp = dest; slrp < src + ztp->zit_nused;
@@ -2013,10 +2022,10 @@
iovec_t *srciov, *dstiov;
if (type == DMU_OT_DNODE) {
iovcnt = dnode_setup_crypto_data(src, srcsize, dest,
- &srciov, &dstiov, &plaintext.cd_length);
+ &srciov, &dstiov, &plaintext.cd_length, B_TRUE);
} else if (type == DMU_OT_INTENT_LOG) {
iovcnt = zil_setup_crypto_data(src, srcsize, dest,
- &srciov, &dstiov, &plaintext.cd_length);
+ &srciov, &dstiov, &plaintext.cd_length, B_TRUE);
}
if (iovcnt == 0) {
zio_crypt_key_release(key, FTAG);
@@ -2129,6 +2138,10 @@
dnode_check_buf(dest, srcsize);
}
#endif /* DEBUG */
+ if (type == DMU_OT_DNODE || type == DMU_OT_INTENT_LOG) {
+ kmem_free(srcuio.uio_iov, sizeof (iovec_t) * srcuio.uio_iovcnt);
+ kmem_free(dstuio.uio_iov, sizeof (iovec_t) * dstuio.uio_iovcnt);
+ }
return (ret);
}
@@ -2184,20 +2197,19 @@
iovec_t *srciov, *dstiov;
if (type == DMU_OT_DNODE) {
iovcnt = dnode_setup_crypto_data(src, srcsize, dest,
- &srciov, &dstiov, &plaintext.cd_length);
- if (iovcnt == 0) {
- zio_crypt_key_release(key, FTAG);
- return (0);
- }
+ &srciov, &dstiov, &plaintext.cd_length, B_FALSE);
} else if (type == DMU_OT_INTENT_LOG) {
iovcnt = zil_setup_crypto_data(src, srcsize, dest,
- &srciov, &dstiov, &plaintext.cd_length);
- ASSERT(iovcnt != 0);
+ &srciov, &dstiov, &plaintext.cd_length, B_FALSE);
+ }
+ if (iovcnt == 0) {
+ zio_crypt_key_release(key, FTAG);
+ return (0);
}
dstuio.uio_iovcnt = iovcnt;
dstuio.uio_iov = dstiov;
+
ciphertext.cd_length = plaintext.cd_length + maclen;
-
srcuio.uio_iov = srciov;
srcuio.uio_iovcnt = iovcnt + 1;
srcuio.uio_iov[iovcnt].iov_base = mac;
@@ -2278,6 +2290,10 @@
dnode_check_buf(dest, srcsize);
}
#endif
+ if (type == DMU_OT_DNODE || type == DMU_OT_INTENT_LOG) {
+ kmem_free(srcuio.uio_iov, sizeof (iovec_t) * srcuio.uio_iovcnt);
+ kmem_free(dstuio.uio_iov, sizeof (iovec_t) * dstuio.uio_iovcnt);
+ }
return (ret);
}