diff options
Diffstat (limited to 'xlators/encryption/crypt/src/data.c')
| -rw-r--r-- | xlators/encryption/crypt/src/data.c | 1131 | 
1 files changed, 541 insertions, 590 deletions
diff --git a/xlators/encryption/crypt/src/data.c b/xlators/encryption/crypt/src/data.c index 0aae60d7139..8e8701b6bf2 100644 --- a/xlators/encryption/crypt/src/data.c +++ b/xlators/encryption/crypt/src/data.c @@ -12,136 +12,130 @@  #include "crypt-common.h"  #include "crypt.h" -static void set_iv_aes_xts(off_t offset, struct object_cipher_info *object) +static void +set_iv_aes_xts(off_t offset, struct object_cipher_info *object)  { -	unsigned char *ivec; +    unsigned char *ivec; -	ivec = object->u.aes_xts.ivec; +    ivec = object->u.aes_xts.ivec; -	/* convert the tweak into a little-endian byte -	 * array (IEEE P1619/D16, May 2007, section 5.1) -	 */ +    /* convert the tweak into a little-endian byte +     * array (IEEE P1619/D16, May 2007, section 5.1) +     */ -	*((uint64_t *)ivec) = htole64(offset); +    *((uint64_t *)ivec) = htole64(offset); -	/* ivec is padded with zeroes */ +    /* ivec is padded with zeroes */  } -static int32_t aes_set_keys_common(unsigned char *raw_key, uint32_t key_size, -				   AES_KEY *keys) +static int32_t +aes_set_keys_common(unsigned char *raw_key, uint32_t key_size, AES_KEY *keys)  { -	int32_t ret; - -	ret = AES_set_encrypt_key(raw_key, -				  key_size, -				  &keys[AES_ENCRYPT]); -	if (ret) { -		gf_log("crypt", GF_LOG_ERROR, "Set encrypt key failed"); -		return ret; -	} -	ret = AES_set_decrypt_key(raw_key, -				  key_size, -				  &keys[AES_DECRYPT]); -	if (ret) { -		gf_log("crypt", GF_LOG_ERROR, "Set decrypt key failed"); -		return ret; -	} -	return 0; +    int32_t ret; + +    ret = AES_set_encrypt_key(raw_key, key_size, &keys[AES_ENCRYPT]); +    if (ret) { +        gf_log("crypt", GF_LOG_ERROR, "Set encrypt key failed"); +        return ret; +    } +    ret = AES_set_decrypt_key(raw_key, key_size, &keys[AES_DECRYPT]); +    if (ret) { +        gf_log("crypt", GF_LOG_ERROR, "Set decrypt key failed"); +        return ret; +    } +    return 0;  }  /*   * set private cipher info for xts mode   */ -static int32_t set_private_aes_xts(struct crypt_inode_info *info, -				   struct master_cipher_info *master) +static int32_t +set_private_aes_xts(struct crypt_inode_info *info, +                    struct master_cipher_info *master)  { -	int ret; -	struct object_cipher_info *object = get_object_cinfo(info); -	unsigned char *data_key; -	uint32_t subkey_size; - -	/* init tweak value */ -	memset(object->u.aes_xts.ivec, 0, 16); - -	data_key = GF_CALLOC(1, object->o_dkey_size, gf_crypt_mt_key); -	if (!data_key) -		return ENOMEM; - -	/* -	 * retrieve data keying material -	 */ -	ret = get_data_file_key(info, master, object->o_dkey_size, data_key); -	if (ret) { -		gf_log("crypt", GF_LOG_ERROR, "Failed to retrieve data key"); -		GF_FREE(data_key); -		return ret; -	} -	/* -	 * parse compound xts key -	 */ -	subkey_size = object->o_dkey_size >> 4; /* (xts-key-size-in-bytes / 2) */ -	/* -	 * install key for data encryption -	 */ -	ret = aes_set_keys_common(data_key, -				  subkey_size << 3, object->u.aes_xts.dkey); -	if (ret) { -		GF_FREE(data_key); -		return ret; -	} -	/* -	 * set up key used to encrypt tweaks -	 */ -	ret = AES_set_encrypt_key(data_key + subkey_size, -				  object->o_dkey_size / 2, -				  &object->u.aes_xts.tkey); -	if (ret < 0) -		gf_log("crypt", GF_LOG_ERROR, "Set tweak key failed"); - -	GF_FREE(data_key); -	return ret; +    int ret; +    struct object_cipher_info *object = get_object_cinfo(info); +    unsigned char *data_key; +    uint32_t subkey_size; + +    /* init tweak value */ +    memset(object->u.aes_xts.ivec, 0, 16); + +    data_key = GF_CALLOC(1, object->o_dkey_size, gf_crypt_mt_key); +    if (!data_key) +        return ENOMEM; + +    /* +     * retrieve data keying material +     */ +    ret = get_data_file_key(info, master, object->o_dkey_size, data_key); +    if (ret) { +        gf_log("crypt", GF_LOG_ERROR, "Failed to retrieve data key"); +        GF_FREE(data_key); +        return ret; +    } +    /* +     * parse compound xts key +     */ +    subkey_size = object->o_dkey_size >> 4; /* (xts-key-size-in-bytes / 2) */ +    /* +     * install key for data encryption +     */ +    ret = aes_set_keys_common(data_key, subkey_size << 3, +                              object->u.aes_xts.dkey); +    if (ret) { +        GF_FREE(data_key); +        return ret; +    } +    /* +     * set up key used to encrypt tweaks +     */ +    ret = AES_set_encrypt_key(data_key + subkey_size, object->o_dkey_size / 2, +                              &object->u.aes_xts.tkey); +    if (ret < 0) +        gf_log("crypt", GF_LOG_ERROR, "Set tweak key failed"); + +    GF_FREE(data_key); +    return ret;  } -static int32_t aes_xts_init(void) +static int32_t +aes_xts_init(void)  { -	cassert(AES_BLOCK_SIZE == (1 << AES_BLOCK_BITS)); -	return 0; +    cassert(AES_BLOCK_SIZE == (1 << AES_BLOCK_BITS)); +    return 0;  } -static int32_t check_key_aes_xts(uint32_t keysize) +static int32_t +check_key_aes_xts(uint32_t keysize)  { -	switch(keysize) { -	case 256: -	case 512: -		return 0; -	default: -		break; -	} -	return -1; +    switch (keysize) { +        case 256: +        case 512: +            return 0; +        default: +            break; +    } +    return -1;  } -static int32_t encrypt_aes_xts(const unsigned char *from, -			       unsigned char *to, size_t length, -			       off_t offset, const int enc, -			       struct object_cipher_info *object) +static int32_t +encrypt_aes_xts(const unsigned char *from, unsigned char *to, size_t length, +                off_t offset, const int enc, struct object_cipher_info *object)  { -	XTS128_CONTEXT ctx; -	if (enc) { -		ctx.key1 = &object->u.aes_xts.dkey[AES_ENCRYPT]; -		ctx.block1 = (block128_f)AES_encrypt; -	} -	else { -		ctx.key1 = &object->u.aes_xts.dkey[AES_DECRYPT]; -		ctx.block1 = (block128_f)AES_decrypt; -	} -	ctx.key2 = &object->u.aes_xts.tkey; -	ctx.block2 = (block128_f)AES_encrypt; - -	return CRYPTO_xts128_encrypt(&ctx, -				     object->u.aes_xts.ivec, -				     from, -				     to, -				     length, enc); +    XTS128_CONTEXT ctx; +    if (enc) { +        ctx.key1 = &object->u.aes_xts.dkey[AES_ENCRYPT]; +        ctx.block1 = (block128_f)AES_encrypt; +    } else { +        ctx.key1 = &object->u.aes_xts.dkey[AES_DECRYPT]; +        ctx.block1 = (block128_f)AES_decrypt; +    } +    ctx.key2 = &object->u.aes_xts.tkey; +    ctx.block2 = (block128_f)AES_encrypt; + +    return CRYPTO_xts128_encrypt(&ctx, object->u.aes_xts.ivec, from, to, length, +                                 enc);  }  /* @@ -149,26 +143,19 @@ static int32_t encrypt_aes_xts(const unsigned char *from,   * @to: result of cipher transform;   * @off: offset in a file (must be cblock-aligned);   */ -static void cipher_data(struct object_cipher_info *object, -			char *from, -			char *to, -			off_t off, -			size_t len, -			const int enc) +static void +cipher_data(struct object_cipher_info *object, char *from, char *to, off_t off, +            size_t len, const int enc)  { -	crypt_check_input_len(len, object); +    crypt_check_input_len(len, object);  #if TRIVIAL_TFM && DEBUG_CRYPT -	return; +    return;  #endif -	data_cipher_algs[object->o_alg][object->o_mode].set_iv(off, object); -	data_cipher_algs[object->o_alg][object->o_mode].encrypt -		((const unsigned char *)from, -		 (unsigned char *)to, -		 len, -		 off, -		 enc, -		 object); +    data_cipher_algs[object->o_alg][object->o_mode].set_iv(off, object); +    data_cipher_algs[object->o_alg][object->o_mode].encrypt( +        (const unsigned char *)from, (unsigned char *)to, len, off, enc, +        object);  }  #define MAX_CIPHER_CHUNK (1 << 30) @@ -184,32 +171,24 @@ static void cipher_data(struct object_cipher_info *object,   *       for other modes).   * @dir: direction of transform (encrypt/decrypt).   */ -static void cipher_region(struct object_cipher_info *object, -			  char *from, -			  char *to, -			  off_t off, -			  size_t len, -			  int dir) +static void +cipher_region(struct object_cipher_info *object, char *from, char *to, +              off_t off, size_t len, int dir)  { -	while (len > 0) { -		size_t to_cipher; - -		to_cipher = len; -		if (to_cipher > MAX_CIPHER_CHUNK) -			to_cipher = MAX_CIPHER_CHUNK; - -		/* this will reset IV */ -		cipher_data(object, -			    from, -			    to, -			    off, -			    to_cipher, -			    dir); -		from += to_cipher; -		to   += to_cipher; -		off  += to_cipher; -		len  -= to_cipher; -	} +    while (len > 0) { +        size_t to_cipher; + +        to_cipher = len; +        if (to_cipher > MAX_CIPHER_CHUNK) +            to_cipher = MAX_CIPHER_CHUNK; + +        /* this will reset IV */ +        cipher_data(object, from, to, off, to_cipher, dir); +        from += to_cipher; +        to += to_cipher; +        off += to_cipher; +        len -= to_cipher; +    }  }  /* @@ -224,115 +203,105 @@ static void cipher_region(struct object_cipher_info *object,   * responsible for this. @dir is "direction" of   * transform (encrypt/decrypt).   */ -static void cipher_aligned_iov(struct object_cipher_info *object, -			       struct iovec *vec, -			       int count, -			       off_t off, -			       int32_t dir) +static void +cipher_aligned_iov(struct object_cipher_info *object, struct iovec *vec, +                   int count, off_t off, int32_t dir)  { -	int i; -	int len = 0; - -	for (i = 0; i < count; i++) { -		cipher_region(object, -			      vec[i].iov_base, -			      vec[i].iov_base, -			      off + len, -			      vec[i].iov_len, -			      dir); -		len += vec[i].iov_len; -	} +    int i; +    int len = 0; + +    for (i = 0; i < count; i++) { +        cipher_region(object, vec[i].iov_base, vec[i].iov_base, off + len, +                      vec[i].iov_len, dir); +        len += vec[i].iov_len; +    }  } -void encrypt_aligned_iov(struct object_cipher_info *object, -			 struct iovec *vec, -			 int count, -			 off_t off) +void +encrypt_aligned_iov(struct object_cipher_info *object, struct iovec *vec, +                    int count, off_t off)  { -	cipher_aligned_iov(object, vec, count, off, 1); +    cipher_aligned_iov(object, vec, count, off, 1);  } -void decrypt_aligned_iov(struct object_cipher_info *object, -			 struct iovec *vec, -			 int count, -			 off_t off) +void +decrypt_aligned_iov(struct object_cipher_info *object, struct iovec *vec, +                    int count, off_t off)  { -	cipher_aligned_iov(object, vec, count, off, 0); +    cipher_aligned_iov(object, vec, count, off, 0);  }  #if DEBUG_CRYPT -static void compound_stream(struct iovec *vec, int count, char *buf, off_t skip) +static void +compound_stream(struct iovec *vec, int count, char *buf, off_t skip)  { -	int i; -	int off = 0; -	for (i = 0; i < count; i++) { -		memcpy(buf + off, -		       vec[i].iov_base + skip, -		       vec[i].iov_len - skip); - -		off += (vec[i].iov_len - skip); -		skip = 0; -	} +    int i; +    int off = 0; +    for (i = 0; i < count; i++) { +        memcpy(buf + off, vec[i].iov_base + skip, vec[i].iov_len - skip); + +        off += (vec[i].iov_len - skip); +        skip = 0; +    }  } -static void check_iovecs(struct iovec *vec, int cnt, -			 struct iovec *avec, int acnt, uint32_t off_in_head) +static void +check_iovecs(struct iovec *vec, int cnt, struct iovec *avec, int acnt, +             uint32_t off_in_head)  { -	char *s1, *s2; -	uint32_t size, asize; - -	size = iov_length(vec, cnt); -	asize = iov_length(avec, acnt) - off_in_head; -	if (size != asize) { -		gf_log("crypt", GF_LOG_DEBUG, "size %d is not eq asize %d", -		       size, asize); -		return; -	} -	s1 = GF_CALLOC(1, size, gf_crypt_mt_data); -	if (!s1) { -		gf_log("crypt", GF_LOG_DEBUG, "Can not allocate stream "); -		return; -	} -	s2 = GF_CALLOC(1, asize, gf_crypt_mt_data); -	if (!s2) { -		GF_FREE(s1); -		gf_log("crypt", GF_LOG_DEBUG, "Can not allocate stream "); -		return; -	} -	compound_stream(vec, cnt, s1, 0); -	compound_stream(avec, acnt, s2, off_in_head); -	if (memcmp(s1, s2, size)) -		gf_log("crypt", GF_LOG_DEBUG, "chunks of different data"); -	GF_FREE(s1); -	GF_FREE(s2); +    char *s1, *s2; +    uint32_t size, asize; + +    size = iov_length(vec, cnt); +    asize = iov_length(avec, acnt) - off_in_head; +    if (size != asize) { +        gf_log("crypt", GF_LOG_DEBUG, "size %d is not eq asize %d", size, +               asize); +        return; +    } +    s1 = GF_CALLOC(1, size, gf_crypt_mt_data); +    if (!s1) { +        gf_log("crypt", GF_LOG_DEBUG, "Can not allocate stream "); +        return; +    } +    s2 = GF_CALLOC(1, asize, gf_crypt_mt_data); +    if (!s2) { +        GF_FREE(s1); +        gf_log("crypt", GF_LOG_DEBUG, "Can not allocate stream "); +        return; +    } +    compound_stream(vec, cnt, s1, 0); +    compound_stream(avec, acnt, s2, off_in_head); +    if (memcmp(s1, s2, size)) +        gf_log("crypt", GF_LOG_DEBUG, "chunks of different data"); +    GF_FREE(s1); +    GF_FREE(s2);  }  #else  #define check_iovecs(vec, count, avec, avecn, off) noop  #endif /* DEBUG_CRYPT */ -static char *data_alloc_block(xlator_t *this, crypt_local_t *local, -			      int32_t block_size) +static char * +data_alloc_block(xlator_t *this, crypt_local_t *local, int32_t block_size)  { -	struct iobuf *iobuf = NULL; - -	iobuf = iobuf_get2(this->ctx->iobuf_pool, block_size); -	if (!iobuf) { -		gf_log("crypt", GF_LOG_ERROR, -		       "Failed to get iobuf"); -		return NULL; -	} -	if (!local->iobref_data) { -		local->iobref_data = iobref_new(); -		if (!local->iobref_data) { -			gf_log("crypt", GF_LOG_ERROR, -			       "Failed to get iobref"); -			iobuf_unref(iobuf); -			return NULL; -		} -	} -	iobref_add(local->iobref_data, iobuf); -	return iobuf->ptr; +    struct iobuf *iobuf = NULL; + +    iobuf = iobuf_get2(this->ctx->iobuf_pool, block_size); +    if (!iobuf) { +        gf_log("crypt", GF_LOG_ERROR, "Failed to get iobuf"); +        return NULL; +    } +    if (!local->iobref_data) { +        local->iobref_data = iobref_new(); +        if (!local->iobref_data) { +            gf_log("crypt", GF_LOG_ERROR, "Failed to get iobref"); +            iobuf_unref(iobuf); +            return NULL; +        } +    } +    iobref_add(local->iobref_data, iobuf); +    return iobuf->ptr;  }  /* @@ -360,250 +329,239 @@ static char *data_alloc_block(xlator_t *this, crypt_local_t *local,   * 3 - full non-compound (the case of reuse);   * 4 - incomplete non-compound (tail).   */ -int32_t align_iov_by_atoms(xlator_t *this, -			   crypt_local_t *local, -			   struct object_cipher_info *object, -			   struct iovec *vec /* input vector */, -			   int32_t count /* number of vec components */, -			   struct iovec *avec /* aligned vector */, -			   char **blocks /* pool of blocks */, -			   uint32_t *blocks_allocated, -			   struct avec_config *conf) +int32_t +align_iov_by_atoms(xlator_t *this, crypt_local_t *local, +                   struct object_cipher_info *object, +                   struct iovec *vec /* input vector */, +                   int32_t count /* number of vec components */, +                   struct iovec *avec /* aligned vector */, +                   char **blocks /* pool of blocks */, +                   uint32_t *blocks_allocated, struct avec_config *conf)  { -	int vecn = 0;      /* number of the current component in vec */ -	int avecn = 0;     /* number of the current component in avec */ -	off_t vec_off = 0; /* offset in the current vec component, -			    * i.e. the number of bytes have already -			    * been copied */ -	int32_t block_size = get_atom_size(object); -	size_t to_process; /* number of vec's bytes to copy and(or) re-use */ -	int32_t off_in_head = conf->off_in_head; - -	to_process = iov_length(vec, count); - -	while (to_process > 0) { -		if (off_in_head || -		    vec[vecn].iov_len - vec_off < block_size) { -			/* -			 * less than block_size: -			 * the case of incomplete (head or tail), -			 * or compound block -			 */ -			size_t copied = 0; -			/* -			 * populate the pool with a new block -			 */ -			blocks[*blocks_allocated] = data_alloc_block(this, -								    local, -								    block_size); -			if (!blocks[*blocks_allocated]) -				return -ENOMEM; -			memset(blocks[*blocks_allocated], 0, off_in_head); -			/* -			 * fill the block with vec components -			 */ -			do { -				size_t to_copy; - -				to_copy = vec[vecn].iov_len - vec_off; -				if (to_copy > block_size - off_in_head) -					to_copy = block_size - off_in_head; - -				memcpy(blocks[*blocks_allocated] + off_in_head + copied, -				       vec[vecn].iov_base + vec_off, -				       to_copy); - -				copied += to_copy; -				to_process -= to_copy; - -				vec_off += to_copy; -				if (vec_off == vec[vecn].iov_len) { -					/* finished with this vecn */ -					vec_off = 0; -					vecn++; -				} -			} while (copied < (block_size - off_in_head) && to_process > 0); -			/* -			 * update avec -			 */ -			avec[avecn].iov_len = off_in_head + copied; -			avec[avecn].iov_base = blocks[*blocks_allocated]; - -			(*blocks_allocated)++; -			off_in_head = 0; -		} else { -			/* -			 * the rest of the current vec component -			 * is not less than block_size, so reuse -			 * the memory buffer of the component. -			 */ -			size_t to_reuse; -			to_reuse = (to_process > block_size ? -				    block_size : -				    to_process); -			avec[avecn].iov_len = to_reuse; -			avec[avecn].iov_base = vec[vecn].iov_base + vec_off; - -			vec_off += to_reuse; -			if (vec_off == vec[vecn].iov_len) { -				/* finished with this vecn */ -				vec_off = 0; -				vecn++; -			} -			to_process -= to_reuse; -		} -		avecn++; -	} -	check_iovecs(vec, count, avec, avecn, conf->off_in_head); -	return 0; +    int vecn = 0;      /* number of the current component in vec */ +    int avecn = 0;     /* number of the current component in avec */ +    off_t vec_off = 0; /* offset in the current vec component, +                        * i.e. the number of bytes have already +                        * been copied */ +    int32_t block_size = get_atom_size(object); +    size_t to_process; /* number of vec's bytes to copy and(or) re-use */ +    int32_t off_in_head = conf->off_in_head; + +    to_process = iov_length(vec, count); + +    while (to_process > 0) { +        if (off_in_head || vec[vecn].iov_len - vec_off < block_size) { +            /* +             * less than block_size: +             * the case of incomplete (head or tail), +             * or compound block +             */ +            size_t copied = 0; +            /* +             * populate the pool with a new block +             */ +            blocks[*blocks_allocated] = data_alloc_block(this, local, +                                                         block_size); +            if (!blocks[*blocks_allocated]) +                return -ENOMEM; +            memset(blocks[*blocks_allocated], 0, off_in_head); +            /* +             * fill the block with vec components +             */ +            do { +                size_t to_copy; + +                to_copy = vec[vecn].iov_len - vec_off; +                if (to_copy > block_size - off_in_head) +                    to_copy = block_size - off_in_head; + +                memcpy(blocks[*blocks_allocated] + off_in_head + copied, +                       vec[vecn].iov_base + vec_off, to_copy); + +                copied += to_copy; +                to_process -= to_copy; + +                vec_off += to_copy; +                if (vec_off == vec[vecn].iov_len) { +                    /* finished with this vecn */ +                    vec_off = 0; +                    vecn++; +                } +            } while (copied < (block_size - off_in_head) && to_process > 0); +            /* +             * update avec +             */ +            avec[avecn].iov_len = off_in_head + copied; +            avec[avecn].iov_base = blocks[*blocks_allocated]; + +            (*blocks_allocated)++; +            off_in_head = 0; +        } else { +            /* +             * the rest of the current vec component +             * is not less than block_size, so reuse +             * the memory buffer of the component. +             */ +            size_t to_reuse; +            to_reuse = (to_process > block_size ? block_size : to_process); +            avec[avecn].iov_len = to_reuse; +            avec[avecn].iov_base = vec[vecn].iov_base + vec_off; + +            vec_off += to_reuse; +            if (vec_off == vec[vecn].iov_len) { +                /* finished with this vecn */ +                vec_off = 0; +                vecn++; +            } +            to_process -= to_reuse; +        } +        avecn++; +    } +    check_iovecs(vec, count, avec, avecn, conf->off_in_head); +    return 0;  }  /*   * allocate and setup aligned vector for data submission   * Pre-condition: @conf is set.   */ -int32_t set_config_avec_data(xlator_t *this, -			     crypt_local_t *local, -			     struct avec_config *conf, -			     struct object_cipher_info *object, -			     struct iovec *vec, -			     int32_t vec_count) +int32_t +set_config_avec_data(xlator_t *this, crypt_local_t *local, +                     struct avec_config *conf, +                     struct object_cipher_info *object, struct iovec *vec, +                     int32_t vec_count)  { -	int32_t ret = ENOMEM; -	struct iovec *avec; -	char **pool; -	uint32_t blocks_in_pool = 0; - -	conf->type = DATA_ATOM; - -	avec = GF_CALLOC(conf->acount, sizeof(*avec), gf_crypt_mt_iovec); -	if (!avec) -		return ret; -	pool = GF_CALLOC(conf->acount, sizeof(*pool), gf_crypt_mt_char); -	if (!pool) { -		GF_FREE(avec); -		return ret; -	} -	if (!vec) { -		/* -		 * degenerated case: no data -		 */ -		pool[0] = data_alloc_block(this, local, get_atom_size(object)); -		if (!pool[0]) -			goto free; -		blocks_in_pool = 1; -		avec->iov_base = pool[0]; -		avec->iov_len = conf->off_in_tail; -	} -	else { -		ret = align_iov_by_atoms(this, local, object, vec, vec_count, -					 avec, pool, &blocks_in_pool, conf); -		if (ret) -			goto free; -	} -	conf->avec = avec; -	conf->pool = pool; -	conf->blocks_in_pool = blocks_in_pool; -	return 0; - free: -	GF_FREE(avec); -	GF_FREE(pool); -	return ret; +    int32_t ret = ENOMEM; +    struct iovec *avec; +    char **pool; +    uint32_t blocks_in_pool = 0; + +    conf->type = DATA_ATOM; + +    avec = GF_CALLOC(conf->acount, sizeof(*avec), gf_crypt_mt_iovec); +    if (!avec) +        return ret; +    pool = GF_CALLOC(conf->acount, sizeof(*pool), gf_crypt_mt_char); +    if (!pool) { +        GF_FREE(avec); +        return ret; +    } +    if (!vec) { +        /* +         * degenerated case: no data +         */ +        pool[0] = data_alloc_block(this, local, get_atom_size(object)); +        if (!pool[0]) +            goto free; +        blocks_in_pool = 1; +        avec->iov_base = pool[0]; +        avec->iov_len = conf->off_in_tail; +    } else { +        ret = align_iov_by_atoms(this, local, object, vec, vec_count, avec, +                                 pool, &blocks_in_pool, conf); +        if (ret) +            goto free; +    } +    conf->avec = avec; +    conf->pool = pool; +    conf->blocks_in_pool = blocks_in_pool; +    return 0; +free: +    GF_FREE(avec); +    GF_FREE(pool); +    return ret;  }  /*   * allocate and setup aligned vector for hole submission   */ -int32_t set_config_avec_hole(xlator_t *this, -			     crypt_local_t *local, -			     struct avec_config *conf, -			     struct object_cipher_info *object, -			     glusterfs_fop_t fop) +int32_t +set_config_avec_hole(xlator_t *this, crypt_local_t *local, +                     struct avec_config *conf, +                     struct object_cipher_info *object, glusterfs_fop_t fop)  { -	uint32_t i, idx; -	struct iovec *avec; -	char **pool; -	uint32_t num_blocks; -	uint32_t blocks_in_pool = 0; - -	conf->type = HOLE_ATOM; - -	num_blocks = conf->acount - -		(conf->nr_full_blocks ? conf->nr_full_blocks - 1 : 0); - -	switch (fop) { -	case GF_FOP_WRITE: -		/* -		 * hole goes before data -		 */ -		if (num_blocks == 1 && conf->off_in_tail != 0) -		/* -		 * we won't submit a hole which fits into -		 * a data atom: this part of hole will be -		 * submitted with data write -		 */ -			return 0; -		break; -	case GF_FOP_FTRUNCATE: -		/* -		 * expanding truncate, hole goes after data, -		 * and will be submitted in any case. - 		 */ -		break; -	default: -		gf_log("crypt", GF_LOG_WARNING, -		       "bad file operation %d", fop); -		return 0; -	} -	avec = GF_CALLOC(num_blocks, sizeof(*avec), gf_crypt_mt_iovec); -	if (!avec) -		return ENOMEM; -	pool = GF_CALLOC(num_blocks, sizeof(*pool), gf_crypt_mt_char); -	if (!pool) { -		GF_FREE(avec); -		return ENOMEM; -	} -	for (i = 0; i < num_blocks; i++) { -		pool[i] = data_alloc_block(this, local, get_atom_size(object)); -		if (pool[i] == NULL) -			goto free; -		blocks_in_pool++; -	} -	if (has_head_block(conf)) { -		/* set head block */ -		idx = 0; -		avec[idx].iov_base = pool[idx]; -		avec[idx].iov_len = get_atom_size(object); -		memset(avec[idx].iov_base + conf->off_in_head, -		       0, -		       get_atom_size(object) - conf->off_in_head); -	} -	if (has_tail_block(conf)) { -		/* set tail block */ -		idx = num_blocks - 1; -		avec[idx].iov_base = pool[idx]; -		avec[idx].iov_len = get_atom_size(object); -		memset(avec[idx].iov_base, 0, conf->off_in_tail); -	} -	if (has_full_blocks(conf)) { -		/* set full block */ -		idx = conf->off_in_head ? 1 : 0; -		avec[idx].iov_base = pool[idx]; -		avec[idx].iov_len = get_atom_size(object); -		/* -		 * since we re-use the buffer, -		 * zeroes will be set every time -		 * before encryption, see submit_full() -		 */ -	} -	conf->avec = avec; -	conf->pool = pool; -	conf->blocks_in_pool = blocks_in_pool; -	return 0; - free: -	GF_FREE(avec); -	GF_FREE(pool); -	return ENOMEM; +    uint32_t i, idx; +    struct iovec *avec; +    char **pool; +    uint32_t num_blocks; +    uint32_t blocks_in_pool = 0; + +    conf->type = HOLE_ATOM; + +    num_blocks = conf->acount - +                 (conf->nr_full_blocks ? conf->nr_full_blocks - 1 : 0); + +    switch (fop) { +        case GF_FOP_WRITE: +            /* +             * hole goes before data +             */ +            if (num_blocks == 1 && conf->off_in_tail != 0) +                /* +                 * we won't submit a hole which fits into +                 * a data atom: this part of hole will be +                 * submitted with data write +                 */ +                return 0; +            break; +        case GF_FOP_FTRUNCATE: +            /* +             * expanding truncate, hole goes after data, +             * and will be submitted in any case. +             */ +            break; +        default: +            gf_log("crypt", GF_LOG_WARNING, "bad file operation %d", fop); +            return 0; +    } +    avec = GF_CALLOC(num_blocks, sizeof(*avec), gf_crypt_mt_iovec); +    if (!avec) +        return ENOMEM; +    pool = GF_CALLOC(num_blocks, sizeof(*pool), gf_crypt_mt_char); +    if (!pool) { +        GF_FREE(avec); +        return ENOMEM; +    } +    for (i = 0; i < num_blocks; i++) { +        pool[i] = data_alloc_block(this, local, get_atom_size(object)); +        if (pool[i] == NULL) +            goto free; +        blocks_in_pool++; +    } +    if (has_head_block(conf)) { +        /* set head block */ +        idx = 0; +        avec[idx].iov_base = pool[idx]; +        avec[idx].iov_len = get_atom_size(object); +        memset(avec[idx].iov_base + conf->off_in_head, 0, +               get_atom_size(object) - conf->off_in_head); +    } +    if (has_tail_block(conf)) { +        /* set tail block */ +        idx = num_blocks - 1; +        avec[idx].iov_base = pool[idx]; +        avec[idx].iov_len = get_atom_size(object); +        memset(avec[idx].iov_base, 0, conf->off_in_tail); +    } +    if (has_full_blocks(conf)) { +        /* set full block */ +        idx = conf->off_in_head ? 1 : 0; +        avec[idx].iov_base = pool[idx]; +        avec[idx].iov_len = get_atom_size(object); +        /* +         * since we re-use the buffer, +         * zeroes will be set every time +         * before encryption, see submit_full() +         */ +    } +    conf->avec = avec; +    conf->pool = pool; +    conf->blocks_in_pool = blocks_in_pool; +    return 0; +free: +    GF_FREE(avec); +    GF_FREE(pool); +    return ENOMEM;  }  /* A helper for setting up config of partial atoms (which @@ -617,140 +575,133 @@ int32_t set_config_avec_hole(xlator_t *this,   * @conf contains setup, which is enough for correct calculation   * of has_tail_block(), ->get_offset().   */ -void set_gap_at_end(call_frame_t *frame, struct object_cipher_info *object, -		    struct avec_config *conf, atom_data_type dtype) +void +set_gap_at_end(call_frame_t *frame, struct object_cipher_info *object, +               struct avec_config *conf, atom_data_type dtype)  { -	uint32_t to_block; -	crypt_local_t *local = frame->local; -	uint64_t old_file_size = local->old_file_size; -	struct rmw_atom *partial = atom_by_types(dtype, -						 has_tail_block(conf) ? -						 TAIL_ATOM : HEAD_ATOM); - -	if (old_file_size <= partial->offset_at(frame, object)) -		to_block = 0; -	else { -		to_block = old_file_size - partial->offset_at(frame, object); -		if (to_block > get_atom_size(object)) -			to_block = get_atom_size(object); -	} -	if (to_block > conf->off_in_tail) -		conf->gap_in_tail = to_block - conf->off_in_tail; -	else -		/* -		 * nothing to uptodate -		 */ -		conf->gap_in_tail = 0; +    uint32_t to_block; +    crypt_local_t *local = frame->local; +    uint64_t old_file_size = local->old_file_size; +    struct rmw_atom *partial = atom_by_types( +        dtype, has_tail_block(conf) ? TAIL_ATOM : HEAD_ATOM); + +    if (old_file_size <= partial->offset_at(frame, object)) +        to_block = 0; +    else { +        to_block = old_file_size - partial->offset_at(frame, object); +        if (to_block > get_atom_size(object)) +            to_block = get_atom_size(object); +    } +    if (to_block > conf->off_in_tail) +        conf->gap_in_tail = to_block - conf->off_in_tail; +    else +        /* +         * nothing to uptodate +         */ +        conf->gap_in_tail = 0;  }  /*   * fill struct avec_config with offsets layouts   */ -void set_config_offsets(call_frame_t *frame, -			xlator_t *this, -			uint64_t offset, -			uint64_t count, -			atom_data_type dtype, -			int32_t set_gap) +void +set_config_offsets(call_frame_t *frame, xlator_t *this, uint64_t offset, +                   uint64_t count, atom_data_type dtype, int32_t set_gap)  { -	crypt_local_t *local; -	struct object_cipher_info *object; -	struct avec_config *conf; -	uint32_t resid; - -	uint32_t atom_size; -	uint32_t atom_bits; - -	size_t orig_size; -	off_t orig_offset; -	size_t expanded_size; -	off_t aligned_offset; - -	uint32_t off_in_head = 0; -	uint32_t off_in_tail = 0; -	uint32_t nr_full_blocks; -	int32_t size_full_blocks; - -	uint32_t acount; /* number of aligned components to write. -			  * The same as number of occupied logical -			  * blocks (atoms) -			  */ -	local = frame->local; -	object = &local->info->cinfo; -	conf = (dtype == DATA_ATOM ? -		get_data_conf(frame) : get_hole_conf(frame)); - -	orig_offset = offset; -	orig_size = count; - -	atom_size = get_atom_size(object); -	atom_bits = get_atom_bits(object); - -	/* -	 * Round-down the start, -	 * round-up the end. -	 */ -	resid = offset & (uint64_t)(atom_size - 1); - -	if (resid) -		off_in_head = resid; -	aligned_offset = offset - off_in_head; -	expanded_size = orig_size + off_in_head; - -	/* calculate tail, -	   expand size forward  */ -	resid = (offset + orig_size) & (uint64_t)(atom_size - 1); - -	if (resid) { -		off_in_tail = resid; -		expanded_size += (atom_size - off_in_tail); -	} -	/* -	 * calculate number of occupied blocks -	 */ -	acount = expanded_size >> atom_bits; -	/* -	 * calculate number of full blocks -	 */ -	size_full_blocks = expanded_size; -	if (off_in_head) -		size_full_blocks -= atom_size; -	if (off_in_tail && size_full_blocks > 0) -		size_full_blocks -= atom_size; -	nr_full_blocks = size_full_blocks >> atom_bits; - -	conf->atom_size = atom_size; -	conf->orig_size = orig_size; -	conf->orig_offset = orig_offset; -	conf->expanded_size = expanded_size; -	conf->aligned_offset = aligned_offset; - -	conf->off_in_head = off_in_head; -	conf->off_in_tail = off_in_tail; -	conf->nr_full_blocks = nr_full_blocks; -	conf->acount = acount; -	/* -	 * Finally, calculate precise amount of -	 * "extra-bytes" that should be uptodated -	 * at the end. -	 * Only if RMW is expected. -	 */ -	if (off_in_tail && set_gap) -		set_gap_at_end(frame, object, conf, dtype); +    crypt_local_t *local; +    struct object_cipher_info *object; +    struct avec_config *conf; +    uint32_t resid; + +    uint32_t atom_size; +    uint32_t atom_bits; + +    size_t orig_size; +    off_t orig_offset; +    size_t expanded_size; +    off_t aligned_offset; + +    uint32_t off_in_head = 0; +    uint32_t off_in_tail = 0; +    uint32_t nr_full_blocks; +    int32_t size_full_blocks; + +    uint32_t acount; /* number of aligned components to write. +                      * The same as number of occupied logical +                      * blocks (atoms) +                      */ +    local = frame->local; +    object = &local->info->cinfo; +    conf = (dtype == DATA_ATOM ? get_data_conf(frame) : get_hole_conf(frame)); + +    orig_offset = offset; +    orig_size = count; + +    atom_size = get_atom_size(object); +    atom_bits = get_atom_bits(object); + +    /* +     * Round-down the start, +     * round-up the end. +     */ +    resid = offset & (uint64_t)(atom_size - 1); + +    if (resid) +        off_in_head = resid; +    aligned_offset = offset - off_in_head; +    expanded_size = orig_size + off_in_head; + +    /* calculate tail, +       expand size forward  */ +    resid = (offset + orig_size) & (uint64_t)(atom_size - 1); + +    if (resid) { +        off_in_tail = resid; +        expanded_size += (atom_size - off_in_tail); +    } +    /* +     * calculate number of occupied blocks +     */ +    acount = expanded_size >> atom_bits; +    /* +     * calculate number of full blocks +     */ +    size_full_blocks = expanded_size; +    if (off_in_head) +        size_full_blocks -= atom_size; +    if (off_in_tail && size_full_blocks > 0) +        size_full_blocks -= atom_size; +    nr_full_blocks = size_full_blocks >> atom_bits; + +    conf->atom_size = atom_size; +    conf->orig_size = orig_size; +    conf->orig_offset = orig_offset; +    conf->expanded_size = expanded_size; +    conf->aligned_offset = aligned_offset; + +    conf->off_in_head = off_in_head; +    conf->off_in_tail = off_in_tail; +    conf->nr_full_blocks = nr_full_blocks; +    conf->acount = acount; +    /* +     * Finally, calculate precise amount of +     * "extra-bytes" that should be uptodated +     * at the end. +     * Only if RMW is expected. +     */ +    if (off_in_tail && set_gap) +        set_gap_at_end(frame, object, conf, dtype);  }  struct data_cipher_alg data_cipher_algs[LAST_CIPHER_ALG][LAST_CIPHER_MODE] = { -	[AES_CIPHER_ALG][XTS_CIPHER_MODE] = -	{ .atomic = _gf_true, -	  .should_pad = _gf_true, -	  .blkbits = AES_BLOCK_BITS, -	  .init = aes_xts_init, -	  .set_private = set_private_aes_xts, -	  .check_key = check_key_aes_xts, -	  .set_iv = set_iv_aes_xts, -	  .encrypt = encrypt_aes_xts -	} -}; +    [AES_CIPHER_ALG][XTS_CIPHER_MODE] = {.atomic = _gf_true, +                                         .should_pad = _gf_true, +                                         .blkbits = AES_BLOCK_BITS, +                                         .init = aes_xts_init, +                                         .set_private = set_private_aes_xts, +                                         .check_key = check_key_aes_xts, +                                         .set_iv = set_iv_aes_xts, +                                         .encrypt = encrypt_aes_xts}};  /*    Local variables:  | 
