diff options
Diffstat (limited to 'xlators/encryption/crypt/src/crypt.c')
| -rw-r--r-- | xlators/encryption/crypt/src/crypt.c | 7571 | 
1 files changed, 3476 insertions, 4095 deletions
diff --git a/xlators/encryption/crypt/src/crypt.c b/xlators/encryption/crypt/src/crypt.c index 93d64c82a9e..02c4028c087 100644 --- a/xlators/encryption/crypt/src/crypt.c +++ b/xlators/encryption/crypt/src/crypt.c @@ -18,231 +18,242 @@  #include "crypt-common.h"  #include "crypt.h" -static void init_inode_info_head(struct crypt_inode_info *info, fd_t *fd); -static int32_t init_inode_info_tail(struct crypt_inode_info *info, -				    struct master_cipher_info *master); -static int32_t prepare_for_submit_hole(call_frame_t *frame, xlator_t *this, -				       uint64_t from, off_t size); -static int32_t load_file_size(call_frame_t *frame, void *cookie, -			      xlator_t *this, int32_t op_ret, int32_t op_errno, -			      dict_t *dict, dict_t *xdata); -static void do_ordered_submit(call_frame_t *frame, xlator_t *this, -			      atom_data_type dtype); -static void do_parallel_submit(call_frame_t *frame, xlator_t *this, -			       atom_data_type dtype); -static void put_one_call_open(call_frame_t *frame); -static void put_one_call_readv(call_frame_t *frame, xlator_t *this); -static void put_one_call_writev(call_frame_t *frame, xlator_t *this); -static void put_one_call_ftruncate(call_frame_t *frame, xlator_t *this); -static void free_avec(struct iovec *avec, char **pool, int blocks_in_pool); -static void free_avec_data(crypt_local_t *local); -static void free_avec_hole(crypt_local_t *local); - -static crypt_local_t *crypt_alloc_local(call_frame_t *frame, xlator_t *this, -					glusterfs_fop_t fop) -{ -	crypt_local_t *local = NULL; - -	local = GF_CALLOC (1, sizeof (crypt_local_t), gf_crypt_mt_local); -	if (!local) { -		gf_log(this->name, GF_LOG_ERROR, "out of memory"); -		return NULL; -	} -	local->fop = fop; -	LOCK_INIT(&local->hole_lock); -	LOCK_INIT(&local->call_lock); -	LOCK_INIT(&local->rw_count_lock); - -	frame->local = local; -	return local; -} - -struct crypt_inode_info *get_crypt_inode_info(inode_t *inode, xlator_t *this) -{ -	int ret; -	uint64_t value = 0; -	struct crypt_inode_info *info; - -	ret = inode_ctx_get(inode, this, &value); -	if (ret == -1) { -		gf_log (this->name, GF_LOG_WARNING, -			"Can not get inode info"); -		return NULL; -	} -	info = (struct crypt_inode_info *)(long)value; -	if (info == NULL) { -		gf_log (this->name, GF_LOG_WARNING, -			"Can not obtain inode info"); -		return NULL; -	} -	return info; -} - -static struct crypt_inode_info *local_get_inode_info(crypt_local_t *local, -						      xlator_t *this) -{ -	if (local->info) -		return local->info; -	local->info = get_crypt_inode_info(local->fd->inode, this); -	return local->info; -} - -static struct crypt_inode_info *alloc_inode_info(crypt_local_t *local, -						 loc_t *loc) -{ -	struct crypt_inode_info *info; - -	info = GF_CALLOC(1, sizeof(struct crypt_inode_info), gf_crypt_mt_inode); -	if (!info) { -		local->op_ret = -1; -		local->op_errno = ENOMEM; -		gf_log ("crypt", GF_LOG_WARNING, -			"Can not allocate inode info"); -		return NULL; -	} +static void +init_inode_info_head(struct crypt_inode_info *info, fd_t *fd); +static int32_t +init_inode_info_tail(struct crypt_inode_info *info, +                     struct master_cipher_info *master); +static int32_t +prepare_for_submit_hole(call_frame_t *frame, xlator_t *this, uint64_t from, +                        off_t size); +static int32_t +load_file_size(call_frame_t *frame, void *cookie, xlator_t *this, +               int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata); +static void +do_ordered_submit(call_frame_t *frame, xlator_t *this, atom_data_type dtype); +static void +do_parallel_submit(call_frame_t *frame, xlator_t *this, atom_data_type dtype); +static void +put_one_call_open(call_frame_t *frame); +static void +put_one_call_readv(call_frame_t *frame, xlator_t *this); +static void +put_one_call_writev(call_frame_t *frame, xlator_t *this); +static void +put_one_call_ftruncate(call_frame_t *frame, xlator_t *this); +static void +free_avec(struct iovec *avec, char **pool, int blocks_in_pool); +static void +free_avec_data(crypt_local_t *local); +static void +free_avec_hole(crypt_local_t *local); + +static crypt_local_t * +crypt_alloc_local(call_frame_t *frame, xlator_t *this, glusterfs_fop_t fop) +{ +    crypt_local_t *local = NULL; + +    local = GF_CALLOC(1, sizeof(crypt_local_t), gf_crypt_mt_local); +    if (!local) { +        gf_log(this->name, GF_LOG_ERROR, "out of memory"); +        return NULL; +    } +    local->fop = fop; +    LOCK_INIT(&local->hole_lock); +    LOCK_INIT(&local->call_lock); +    LOCK_INIT(&local->rw_count_lock); + +    frame->local = local; +    return local; +} + +struct crypt_inode_info * +get_crypt_inode_info(inode_t *inode, xlator_t *this) +{ +    int ret; +    uint64_t value = 0; +    struct crypt_inode_info *info; + +    ret = inode_ctx_get(inode, this, &value); +    if (ret == -1) { +        gf_log(this->name, GF_LOG_WARNING, "Can not get inode info"); +        return NULL; +    } +    info = (struct crypt_inode_info *)(long)value; +    if (info == NULL) { +        gf_log(this->name, GF_LOG_WARNING, "Can not obtain inode info"); +        return NULL; +    } +    return info; +} + +static struct crypt_inode_info * +local_get_inode_info(crypt_local_t *local, xlator_t *this) +{ +    if (local->info) +        return local->info; +    local->info = get_crypt_inode_info(local->fd->inode, this); +    return local->info; +} + +static struct crypt_inode_info * +alloc_inode_info(crypt_local_t *local, loc_t *loc) +{ +    struct crypt_inode_info *info; + +    info = GF_CALLOC(1, sizeof(struct crypt_inode_info), gf_crypt_mt_inode); +    if (!info) { +        local->op_ret = -1; +        local->op_errno = ENOMEM; +        gf_log("crypt", GF_LOG_WARNING, "Can not allocate inode info"); +        return NULL; +    }  #if DEBUG_CRYPT -	info->loc = GF_CALLOC(1, sizeof(loc_t), gf_crypt_mt_loc); -	if (!info->loc) { -		gf_log("crypt", GF_LOG_WARNING, "Can not allocate loc"); -		GF_FREE(info); -		return NULL; -	} -	if (loc_copy(info->loc, loc)){ -		GF_FREE(info->loc); -		GF_FREE(info); -		return NULL; -	} +    info->loc = GF_CALLOC(1, sizeof(loc_t), gf_crypt_mt_loc); +    if (!info->loc) { +        gf_log("crypt", GF_LOG_WARNING, "Can not allocate loc"); +        GF_FREE(info); +        return NULL; +    } +    if (loc_copy(info->loc, loc)) { +        GF_FREE(info->loc); +        GF_FREE(info); +        return NULL; +    }  #endif /* DEBUG_CRYPT */ -	local->info = info; -	return info; +    local->info = info; +    return info;  } -static void free_inode_info(struct crypt_inode_info *info) +static void +free_inode_info(struct crypt_inode_info *info)  {  #if DEBUG_CRYPT -	loc_wipe(info->loc); -	GF_FREE(info->loc); +    loc_wipe(info->loc); +    GF_FREE(info->loc);  #endif -	memset(info, 0, sizeof(*info)); -	GF_FREE(info); +    memset(info, 0, sizeof(*info)); +    GF_FREE(info);  } -int crypt_forget (xlator_t *this, inode_t *inode) +int +crypt_forget(xlator_t *this, inode_t *inode)  { -        uint64_t ctx_addr = 0; -        if (!inode_ctx_del (inode, this, &ctx_addr)) -                free_inode_info((struct crypt_inode_info *)(long)ctx_addr); -        return 0; +    uint64_t ctx_addr = 0; +    if (!inode_ctx_del(inode, this, &ctx_addr)) +        free_inode_info((struct crypt_inode_info *)(long)ctx_addr); +    return 0;  }  #if DEBUG_CRYPT -static void check_read(call_frame_t *frame, xlator_t *this, int32_t read, -		       struct iovec *vec, int32_t count, struct iatt *stbuf) +static void +check_read(call_frame_t *frame, xlator_t *this, int32_t read, struct iovec *vec, +           int32_t count, struct iatt *stbuf)  { -	crypt_local_t *local = frame->local; -	struct object_cipher_info *object = get_object_cinfo(local->info); -	struct avec_config *conf = &local->data_conf; -	uint32_t resid = stbuf->ia_size & (object_alg_blksize(object) - 1); - -	if (read <= 0) -		return; -	if (read != iov_length(vec, count)) -		gf_log ("crypt", GF_LOG_DEBUG, -			"op_ret differs from amount of read bytes"); +    crypt_local_t *local = frame->local; +    struct object_cipher_info *object = get_object_cinfo(local->info); +    struct avec_config *conf = &local->data_conf; +    uint32_t resid = stbuf->ia_size & (object_alg_blksize(object) - 1); -	if (object_alg_should_pad(object) && (read & (object_alg_blksize(object) - 1))) -		gf_log ("crypt", GF_LOG_DEBUG, -			"bad amount of read bytes (!= 0 mod(cblock size))"); +    if (read <= 0) +        return; +    if (read != iov_length(vec, count)) +        gf_log("crypt", GF_LOG_DEBUG, +               "op_ret differs from amount of read bytes"); -	if (conf->aligned_offset + read > -	    stbuf->ia_size + (resid ? object_alg_blksize(object) - resid : 0)) -		gf_log ("crypt", GF_LOG_DEBUG, -			"bad amount of read bytes (too large))"); +    if (object_alg_should_pad(object) && +        (read & (object_alg_blksize(object) - 1))) +        gf_log("crypt", GF_LOG_DEBUG, +               "bad amount of read bytes (!= 0 mod(cblock size))"); +    if (conf->aligned_offset + read > +        stbuf->ia_size + (resid ? object_alg_blksize(object) - resid : 0)) +        gf_log("crypt", GF_LOG_DEBUG, "bad amount of read bytes (too large))");  }  #define PT_BYTES_TO_DUMP (32) -static void dump_plain_text(crypt_local_t *local, struct iovec *avec) -{ -	int32_t to_dump; -	char str[PT_BYTES_TO_DUMP + 1]; - -	if (!avec) -		return; -	to_dump = avec->iov_len; -	if (to_dump > PT_BYTES_TO_DUMP) -		to_dump = PT_BYTES_TO_DUMP; -	memcpy(str, avec->iov_base, to_dump); -	memset(str + to_dump, '0', 1); -	gf_log("crypt", GF_LOG_DEBUG, "Read file: %s", str); -} - -static int32_t data_conf_invariant(struct avec_config *conf) -{ -	return conf->acount == -		!!has_head_block(conf) + -		!!has_tail_block(conf)+ -		conf->nr_full_blocks; -} - -static int32_t hole_conf_invariant(struct avec_config *conf) -{ -	return conf->blocks_in_pool == -		!!has_head_block(conf) + -		!!has_tail_block(conf)+ -		!!has_full_blocks(conf); -} - -static void crypt_check_conf(struct avec_config *conf) -{ -	int32_t ret = 0; -	const char *msg; - -	switch (conf->type) { -	case DATA_ATOM: -		msg = "data"; -		ret = data_conf_invariant(conf); -		break; -	case HOLE_ATOM: -		msg = "hole"; -		ret = hole_conf_invariant(conf); -		break; -	default: -		msg = "unknown"; -	} -	if (!ret) -		gf_log("crypt", GF_LOG_DEBUG, "bad %s conf", msg); -} - -static void check_buf(call_frame_t *frame, xlator_t *this, struct iatt *buf) -{ -	crypt_local_t *local = frame->local; -	struct object_cipher_info *object = &local->info->cinfo; -	uint64_t local_file_size; - -	switch(local->fop) { -	case GF_FOP_FTRUNCATE: -		return; -	case GF_FOP_WRITE: -		local_file_size = local->new_file_size; -		break; -	case GF_FOP_READ: -		if (parent_is_crypt_xlator(frame, this)) -			return; -		local_file_size = local->cur_file_size; -		break; -	default: -		gf_log("crypt", GF_LOG_DEBUG, "bad file operation"); -		return; -	} -	if (buf->ia_size != round_up(local_file_size, -					 object_alg_blksize(object))) -		gf_log("crypt", GF_LOG_DEBUG, -		       "bad ia_size in buf (%llu), should be %llu", -		       (unsigned long long)buf->ia_size, -		       (unsigned long long)round_up(local_file_size, -						    object_alg_blksize(object))); +static void +dump_plain_text(crypt_local_t *local, struct iovec *avec) +{ +    int32_t to_dump; +    char str[PT_BYTES_TO_DUMP + 1]; + +    if (!avec) +        return; +    to_dump = avec->iov_len; +    if (to_dump > PT_BYTES_TO_DUMP) +        to_dump = PT_BYTES_TO_DUMP; +    memcpy(str, avec->iov_base, to_dump); +    memset(str + to_dump, '0', 1); +    gf_log("crypt", GF_LOG_DEBUG, "Read file: %s", str); +} + +static int32_t +data_conf_invariant(struct avec_config *conf) +{ +    return conf->acount == !!has_head_block(conf) + !!has_tail_block(conf) + +                               conf->nr_full_blocks; +} + +static int32_t +hole_conf_invariant(struct avec_config *conf) +{ +    return conf->blocks_in_pool == !!has_head_block(conf) + +                                       !!has_tail_block(conf) + +                                       !!has_full_blocks(conf); +} + +static void +crypt_check_conf(struct avec_config *conf) +{ +    int32_t ret = 0; +    const char *msg; + +    switch (conf->type) { +        case DATA_ATOM: +            msg = "data"; +            ret = data_conf_invariant(conf); +            break; +        case HOLE_ATOM: +            msg = "hole"; +            ret = hole_conf_invariant(conf); +            break; +        default: +            msg = "unknown"; +    } +    if (!ret) +        gf_log("crypt", GF_LOG_DEBUG, "bad %s conf", msg); +} + +static void +check_buf(call_frame_t *frame, xlator_t *this, struct iatt *buf) +{ +    crypt_local_t *local = frame->local; +    struct object_cipher_info *object = &local->info->cinfo; +    uint64_t local_file_size; + +    switch (local->fop) { +        case GF_FOP_FTRUNCATE: +            return; +        case GF_FOP_WRITE: +            local_file_size = local->new_file_size; +            break; +        case GF_FOP_READ: +            if (parent_is_crypt_xlator(frame, this)) +                return; +            local_file_size = local->cur_file_size; +            break; +        default: +            gf_log("crypt", GF_LOG_DEBUG, "bad file operation"); +            return; +    } +    if (buf->ia_size != round_up(local_file_size, object_alg_blksize(object))) +        gf_log("crypt", GF_LOG_DEBUG, +               "bad ia_size in buf (%llu), should be %llu", +               (unsigned long long)buf->ia_size, +               (unsigned long long)round_up(local_file_size, +                                            object_alg_blksize(object)));  }  #else @@ -262,582 +273,509 @@ static void check_buf(call_frame_t *frame, xlator_t *this, struct iatt *buf)   * of data corresponding to the original size and offset.   * Pass the result to the next translator.   */ -int32_t crypt_readv_cbk(call_frame_t *frame, -			void *cookie, -			xlator_t *this, -			int32_t op_ret, -			int32_t op_errno, -			struct iovec *vec, -			int32_t count, -			struct iatt *stbuf, -			struct iobref *iobref, -			dict_t *xdata) -{ -	crypt_local_t *local = frame->local; -	struct avec_config *conf = &local->data_conf; -	struct object_cipher_info *object = &local->info->cinfo; - -	struct iovec *avec; -	uint32_t i; -	uint32_t to_vec; -	uint32_t to_user; - -	check_buf(frame, this, stbuf); -	check_read(frame, this, op_ret, vec, count, stbuf); - -	local->op_ret = op_ret; -	local->op_errno = op_errno; -	local->iobref = iobref_ref(iobref); - -	local->buf = *stbuf; -	local->buf.ia_size = local->cur_file_size; - -	if (op_ret <= 0 || count == 0 || vec[0].iov_len == 0) -		goto put_one_call; - -	if (conf->orig_offset >= local->cur_file_size) { -		local->op_ret = 0; -		goto put_one_call; -	} -	/* -	 * correct config params with real file size -	 * and actual amount of bytes read -	 */ -	set_config_offsets(frame, this, -			   conf->orig_offset, op_ret, DATA_ATOM, 0); - -	if (conf->orig_offset + conf->orig_size > local->cur_file_size) -		conf->orig_size = local->cur_file_size - conf->orig_offset; -	/* -	 * calculate amount of data to be returned -	 * to user. -	 */ -	to_user = op_ret; -	if (conf->aligned_offset + to_user <= conf->orig_offset) { -		gf_log(this->name, GF_LOG_WARNING, "Incomplete read"); -		local->op_ret = -1; -		local->op_errno = EIO; -		goto put_one_call; -	} -	to_user -= (conf->aligned_offset - conf->orig_offset); - -	if (to_user > conf->orig_size) -		to_user = conf->orig_size; -	local->rw_count = to_user; - -	op_errno = set_config_avec_data(this, local, -					conf, object, vec, count); -	if (op_errno) { -		local->op_ret = -1; -		local->op_errno = op_errno; -		goto put_one_call; -	} -	avec = conf->avec; +int32_t +crypt_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                int32_t op_ret, int32_t op_errno, struct iovec *vec, +                int32_t count, struct iatt *stbuf, struct iobref *iobref, +                dict_t *xdata) +{ +    crypt_local_t *local = frame->local; +    struct avec_config *conf = &local->data_conf; +    struct object_cipher_info *object = &local->info->cinfo; + +    struct iovec *avec; +    uint32_t i; +    uint32_t to_vec; +    uint32_t to_user; + +    check_buf(frame, this, stbuf); +    check_read(frame, this, op_ret, vec, count, stbuf); + +    local->op_ret = op_ret; +    local->op_errno = op_errno; +    local->iobref = iobref_ref(iobref); + +    local->buf = *stbuf; +    local->buf.ia_size = local->cur_file_size; + +    if (op_ret <= 0 || count == 0 || vec[0].iov_len == 0) +        goto put_one_call; + +    if (conf->orig_offset >= local->cur_file_size) { +        local->op_ret = 0; +        goto put_one_call; +    } +    /* +     * correct config params with real file size +     * and actual amount of bytes read +     */ +    set_config_offsets(frame, this, conf->orig_offset, op_ret, DATA_ATOM, 0); + +    if (conf->orig_offset + conf->orig_size > local->cur_file_size) +        conf->orig_size = local->cur_file_size - conf->orig_offset; +    /* +     * calculate amount of data to be returned +     * to user. +     */ +    to_user = op_ret; +    if (conf->aligned_offset + to_user <= conf->orig_offset) { +        gf_log(this->name, GF_LOG_WARNING, "Incomplete read"); +        local->op_ret = -1; +        local->op_errno = EIO; +        goto put_one_call; +    } +    to_user -= (conf->aligned_offset - conf->orig_offset); + +    if (to_user > conf->orig_size) +        to_user = conf->orig_size; +    local->rw_count = to_user; + +    op_errno = set_config_avec_data(this, local, conf, object, vec, count); +    if (op_errno) { +        local->op_ret = -1; +        local->op_errno = op_errno; +        goto put_one_call; +    } +    avec = conf->avec;  #if DEBUG_CRYPT -	if (conf->off_in_tail != 0 && -	    conf->off_in_tail < object_alg_blksize(object) && -	    object_alg_should_pad(object)) -		gf_log(this->name, GF_LOG_DEBUG, "Bad offset in tail %d", -		       conf->off_in_tail); -	if (iov_length(vec, count) != 0 && -	    in_same_lblock(conf->orig_offset + iov_length(vec, count) - 1, -			   local->cur_file_size - 1, -			   object_alg_blkbits(object))) { -		gf_log(this->name, GF_LOG_DEBUG, "Compound last cblock"); -		dump_cblock(this, -			    (unsigned char *)(avec[conf->acount - 1].iov_base) + -			    avec[conf->acount - 1].iov_len - object_alg_blksize(object)); -		dump_cblock(this, -			    (unsigned char *)(vec[count - 1].iov_base) + -			    vec[count - 1].iov_len - object_alg_blksize(object)); -	} +    if (conf->off_in_tail != 0 && +        conf->off_in_tail < object_alg_blksize(object) && +        object_alg_should_pad(object)) +        gf_log(this->name, GF_LOG_DEBUG, "Bad offset in tail %d", +               conf->off_in_tail); +    if (iov_length(vec, count) != 0 && +        in_same_lblock(conf->orig_offset + iov_length(vec, count) - 1, +                       local->cur_file_size - 1, object_alg_blkbits(object))) { +        gf_log(this->name, GF_LOG_DEBUG, "Compound last cblock"); +        dump_cblock(this, (unsigned char *)(avec[conf->acount - 1].iov_base) + +                              avec[conf->acount - 1].iov_len - +                              object_alg_blksize(object)); +        dump_cblock(this, (unsigned char *)(vec[count - 1].iov_base) + +                              vec[count - 1].iov_len - +                              object_alg_blksize(object)); +    }  #endif -	decrypt_aligned_iov(object, avec, -			    conf->acount, conf->aligned_offset); -	/* -	 * pass proper plain data to user -	 */ -	avec[0].iov_base += (conf->aligned_offset - conf->orig_offset); -	avec[0].iov_len  -= (conf->aligned_offset - conf->orig_offset); - -	to_vec = to_user; -	for (i = 0; i < conf->acount; i++) { -		if (avec[i].iov_len > to_vec) -			avec[i].iov_len = to_vec; -		to_vec -= avec[i].iov_len; -	} - put_one_call: -	put_one_call_readv(frame, this); -	return 0; -} - -static int32_t do_readv(call_frame_t *frame, -			void *cookie, -			xlator_t *this, -			int32_t op_ret, -			int32_t op_errno, -			dict_t *dict, -			dict_t *xdata) -{ -	data_t *data; -	crypt_local_t *local = frame->local; - -	if (op_ret < 0) -		goto error; -	/* -	 * extract regular file size -	 */ -	data = dict_get(dict, FSIZE_XATTR_PREFIX); -	if (!data) { -		gf_log("crypt", GF_LOG_WARNING, "Regular file size not found"); -		op_errno = EIO; -		goto error; -	} -	local->cur_file_size = data_to_uint64(data); - -	get_one_call(frame); -	STACK_WIND(frame, -		   crypt_readv_cbk, -		   FIRST_CHILD (this), -		   FIRST_CHILD (this)->fops->readv, -		   local->fd, -		   /* -		    * FIXME: read amount can be reduced -		    */ -		   local->data_conf.expanded_size, -		   local->data_conf.aligned_offset, -		   local->flags, -		   local->xdata); -	return 0; - error: -	local->op_ret = -1; -	local->op_errno = op_errno; - -	get_one_call(frame); -	put_one_call_readv(frame, this); -	return 0; -} - -static int32_t crypt_readv_finodelk_cbk(call_frame_t *frame, -					void *cookie, -					xlator_t *this, -					int32_t op_ret, -					int32_t op_errno, -					dict_t *xdata) -{ -	crypt_local_t *local = frame->local; - -	if (op_ret < 0) -		goto error; -	/* -	 * An access has been granted, -	 * retrieve file size -	 */ -	STACK_WIND(frame, -		   do_readv, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->fgetxattr, -		   local->fd, -		   FSIZE_XATTR_PREFIX, -		   NULL); -	return  0; - error: -	fd_unref(local->fd); -	if (local->xdata) -		dict_unref(local->xdata); -	CRYPT_STACK_UNWIND(readv, -			   frame, -			   -1, -			   op_errno, -			   NULL, -			   0, -			   NULL, -			   NULL, -			   NULL); -	return 0; -} - -static int32_t readv_trivial_completion(call_frame_t *frame, -					void *cookie, -					xlator_t *this, -					int32_t op_ret, -					int32_t op_errno, -					struct iatt *buf, -					dict_t *xdata) -{ -	crypt_local_t *local = frame->local; - -	local->op_ret = op_ret; -	local->op_errno = op_errno; - -	if (op_ret < 0) { -		gf_log(this->name, GF_LOG_WARNING, -		       "stat failed (%d)", op_errno); -		goto error; -	} -	local->buf = *buf; -	STACK_WIND(frame, -		   load_file_size, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->getxattr, -		   local->loc, -		   FSIZE_XATTR_PREFIX, -		   NULL); -	return 0; - error: -	CRYPT_STACK_UNWIND(readv, frame, op_ret, op_errno, -			   NULL, 0, NULL, NULL, NULL); -	return 0; -} - -int32_t crypt_readv(call_frame_t *frame, -		    xlator_t *this, -		    fd_t *fd, -		    size_t size, -		    off_t offset, -		    uint32_t flags, dict_t *xdata) -{ -	int32_t ret; -	crypt_local_t *local; -	struct crypt_inode_info *info; -	struct gf_flock lock = {0, }; +    decrypt_aligned_iov(object, avec, conf->acount, conf->aligned_offset); +    /* +     * pass proper plain data to user +     */ +    avec[0].iov_base += (conf->aligned_offset - conf->orig_offset); +    avec[0].iov_len -= (conf->aligned_offset - conf->orig_offset); + +    to_vec = to_user; +    for (i = 0; i < conf->acount; i++) { +        if (avec[i].iov_len > to_vec) +            avec[i].iov_len = to_vec; +        to_vec -= avec[i].iov_len; +    } +put_one_call: +    put_one_call_readv(frame, this); +    return 0; +} + +static int32_t +do_readv(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, +         int32_t op_errno, dict_t *dict, dict_t *xdata) +{ +    data_t *data; +    crypt_local_t *local = frame->local; + +    if (op_ret < 0) +        goto error; +    /* +     * extract regular file size +     */ +    data = dict_get(dict, FSIZE_XATTR_PREFIX); +    if (!data) { +        gf_log("crypt", GF_LOG_WARNING, "Regular file size not found"); +        op_errno = EIO; +        goto error; +    } +    local->cur_file_size = data_to_uint64(data); + +    get_one_call(frame); +    STACK_WIND(frame, crypt_readv_cbk, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->readv, local->fd, +               /* +                * FIXME: read amount can be reduced +                */ +               local->data_conf.expanded_size, local->data_conf.aligned_offset, +               local->flags, local->xdata); +    return 0; +error: +    local->op_ret = -1; +    local->op_errno = op_errno; + +    get_one_call(frame); +    put_one_call_readv(frame, this); +    return 0; +} + +static int32_t +crypt_readv_finodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                         int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ +    crypt_local_t *local = frame->local; + +    if (op_ret < 0) +        goto error; +    /* +     * An access has been granted, +     * retrieve file size +     */ +    STACK_WIND(frame, do_readv, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->fgetxattr, local->fd, +               FSIZE_XATTR_PREFIX, NULL); +    return 0; +error: +    fd_unref(local->fd); +    if (local->xdata) +        dict_unref(local->xdata); +    CRYPT_STACK_UNWIND(readv, frame, -1, op_errno, NULL, 0, NULL, NULL, NULL); +    return 0; +} + +static int32_t +readv_trivial_completion(call_frame_t *frame, void *cookie, xlator_t *this, +                         int32_t op_ret, int32_t op_errno, struct iatt *buf, +                         dict_t *xdata) +{ +    crypt_local_t *local = frame->local; + +    local->op_ret = op_ret; +    local->op_errno = op_errno; + +    if (op_ret < 0) { +        gf_log(this->name, GF_LOG_WARNING, "stat failed (%d)", op_errno); +        goto error; +    } +    local->buf = *buf; +    STACK_WIND(frame, load_file_size, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->getxattr, local->loc, +               FSIZE_XATTR_PREFIX, NULL); +    return 0; +error: +    CRYPT_STACK_UNWIND(readv, frame, op_ret, op_errno, NULL, 0, NULL, NULL, +                       NULL); +    return 0; +} + +int32_t +crypt_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, +            off_t offset, uint32_t flags, dict_t *xdata) +{ +    int32_t ret; +    crypt_local_t *local; +    struct crypt_inode_info *info; +    struct gf_flock lock = { +        0, +    };  #if DEBUG_CRYPT -	gf_log("crypt", GF_LOG_DEBUG, "reading %d bytes from offset %llu", -	       (int)size, (long long)offset); -	if (parent_is_crypt_xlator(frame, this)) -		gf_log("crypt", GF_LOG_DEBUG, "parent is crypt"); +    gf_log("crypt", GF_LOG_DEBUG, "reading %d bytes from offset %llu", +           (int)size, (long long)offset); +    if (parent_is_crypt_xlator(frame, this)) +        gf_log("crypt", GF_LOG_DEBUG, "parent is crypt");  #endif -	local = crypt_alloc_local(frame, this, GF_FOP_READ); -	if (!local) { -		ret = ENOMEM; -		goto error; -	} -	if (size == 0) -		goto trivial; - -	local->fd = fd_ref(fd); -	local->flags = flags; - -	info = local_get_inode_info(local, this); -	if (info == NULL) { -		ret = EINVAL; -		fd_unref(fd); -		goto error; -	} -	if (!object_alg_atomic(&info->cinfo)) { -		ret = EINVAL; -		fd_unref(fd); -		goto error; -	} -	set_config_offsets(frame, this, offset, size, -			   DATA_ATOM, 0); -	if (parent_is_crypt_xlator(frame, this)) { -		data_t *data; -		/* -		 * We are called by crypt_writev (or cypt_ftruncate) -		 * to perform the "read" component of the read-modify-write -		 * (or read-prune-write) sequence for some atom; -		 * -		 * don't ask for access: -		 * it has already been acquired -		 * -		 * Retrieve current file size -		 */ -		if (!xdata) { -			gf_log("crypt", GF_LOG_WARNING, -			       "Regular file size hasn't been passed"); -			ret = EIO; -			goto error; -		} -		data = dict_get(xdata, FSIZE_XATTR_PREFIX); -		if (!data) { -			gf_log("crypt", GF_LOG_WARNING, -			       "Regular file size not found"); -			ret = EIO; -			goto error; -		} -		local->old_file_size = -			local->cur_file_size = data_to_uint64(data); - -		get_one_call(frame); -		STACK_WIND(frame, -			   crypt_readv_cbk, -			   FIRST_CHILD(this), -			   FIRST_CHILD(this)->fops->readv, -			   local->fd, -			   /* -			    * FIXME: read amount can be reduced -			    */ -			   local->data_conf.expanded_size, -			   local->data_conf.aligned_offset, -			   flags, -			   NULL); -		return 0; -	} -	if (xdata) -		local->xdata = dict_ref(xdata); - -	lock.l_len    = 0; -        lock.l_start  = 0; -        lock.l_type   = F_RDLCK; -        lock.l_whence = SEEK_SET; +    local = crypt_alloc_local(frame, this, GF_FOP_READ); +    if (!local) { +        ret = ENOMEM; +        goto error; +    } +    if (size == 0) +        goto trivial; + +    local->fd = fd_ref(fd); +    local->flags = flags; + +    info = local_get_inode_info(local, this); +    if (info == NULL) { +        ret = EINVAL; +        fd_unref(fd); +        goto error; +    } +    if (!object_alg_atomic(&info->cinfo)) { +        ret = EINVAL; +        fd_unref(fd); +        goto error; +    } +    set_config_offsets(frame, this, offset, size, DATA_ATOM, 0); +    if (parent_is_crypt_xlator(frame, this)) { +        data_t *data; +        /* +         * We are called by crypt_writev (or cypt_ftruncate) +         * to perform the "read" component of the read-modify-write +         * (or read-prune-write) sequence for some atom; +         * +         * don't ask for access: +         * it has already been acquired +         * +         * Retrieve current file size +         */ +        if (!xdata) { +            gf_log("crypt", GF_LOG_WARNING, +                   "Regular file size hasn't been passed"); +            ret = EIO; +            goto error; +        } +        data = dict_get(xdata, FSIZE_XATTR_PREFIX); +        if (!data) { +            gf_log("crypt", GF_LOG_WARNING, "Regular file size not found"); +            ret = EIO; +            goto error; +        } +        local->old_file_size = local->cur_file_size = data_to_uint64(data); + +        get_one_call(frame); +        STACK_WIND(frame, crypt_readv_cbk, FIRST_CHILD(this), +                   FIRST_CHILD(this)->fops->readv, local->fd, +                   /* +                    * FIXME: read amount can be reduced +                    */ +                   local->data_conf.expanded_size, +                   local->data_conf.aligned_offset, flags, NULL); +        return 0; +    } +    if (xdata) +        local->xdata = dict_ref(xdata); + +    lock.l_len = 0; +    lock.l_start = 0; +    lock.l_type = F_RDLCK; +    lock.l_whence = SEEK_SET; + +    STACK_WIND(frame, crypt_readv_finodelk_cbk, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->finodelk, this->name, fd, F_SETLKW, +               &lock, NULL); +    return 0; +trivial: +    STACK_WIND(frame, readv_trivial_completion, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->fstat, fd, NULL); +    return 0; +error: +    CRYPT_STACK_UNWIND(readv, frame, -1, ret, NULL, 0, NULL, NULL, NULL); +    return 0; +} + +void +set_local_io_params_writev(call_frame_t *frame, +                           struct object_cipher_info *object, +                           struct rmw_atom *atom, off_t io_offset, +                           uint32_t io_size) +{ +    crypt_local_t *local = frame->local; + +    local->io_offset = io_offset; +    local->io_size = io_size; + +    local->io_offset_nopad = atom->offset_at(frame, object) + +                             atom->offset_in(frame, object); + +    gf_log("crypt", GF_LOG_DEBUG, "set nopad offset to %llu", +           (unsigned long long)local->io_offset_nopad); + +    local->io_size_nopad = atom->io_size_nopad(frame, object); + +    gf_log("crypt", GF_LOG_DEBUG, "set nopad size to %llu", +           (unsigned long long)local->io_size_nopad); + +    local->update_disk_file_size = 0; +    /* +     * NOTE: eof_padding_size is 0 for all full atoms; +     * For head and tail atoms it will be set up at rmw_partial block() +     */ +    local->new_file_size = local->cur_file_size; + +    if (local->io_offset_nopad + local->io_size_nopad > local->cur_file_size) { +        local->new_file_size = local->io_offset_nopad + local->io_size_nopad; + +        gf_log("crypt", GF_LOG_DEBUG, "set new file size to %llu", +               (unsigned long long)local->new_file_size); + +        local->update_disk_file_size = 1; +    } +} + +void +set_local_io_params_ftruncate(call_frame_t *frame, +                              struct object_cipher_info *object) +{ +    uint32_t resid; +    crypt_local_t *local = frame->local; +    struct avec_config *conf = &local->data_conf; + +    resid = conf->orig_offset & (object_alg_blksize(object) - 1); +    if (resid) { +        local->eof_padding_size = object_alg_blksize(object) - resid; +        local->new_file_size = conf->aligned_offset; +        local->update_disk_file_size = 0; +        /* +         * file size will be updated +         * in the ->writev() stack, +         * when submitting file tail +         */ +    } else { +        local->eof_padding_size = 0; +        local->new_file_size = conf->orig_offset; +        local->update_disk_file_size = 1; +        /* +         * file size will be updated +         * in this ->ftruncate stack +         */ +    } +} + +static void +submit_head(call_frame_t *frame, xlator_t *this) +{ +    crypt_local_t *local = frame->local; +    submit_partial(frame, this, local->fd, HEAD_ATOM); +} -	STACK_WIND(frame, -		   crypt_readv_finodelk_cbk, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->finodelk, -		   this->name, -		   fd, -		   F_SETLKW, -		   &lock, -		   NULL); -	return 0; - trivial: -	STACK_WIND(frame, -		   readv_trivial_completion, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->fstat, -		   fd, -		   NULL); -	return 0; - error: -	CRYPT_STACK_UNWIND(readv, -			   frame, -			   -1, -			   ret, -			   NULL, -			   0, -			   NULL, -			   NULL, -			   NULL); -	return 0; -} - -void set_local_io_params_writev(call_frame_t *frame, -				struct object_cipher_info *object, -				struct rmw_atom *atom, -				off_t io_offset, -				uint32_t io_size) -{ -	crypt_local_t *local = frame->local; - -	local->io_offset = io_offset; -	local->io_size = io_size; - -	local->io_offset_nopad = -		atom->offset_at(frame, object) + atom->offset_in(frame, object); - -	gf_log("crypt", GF_LOG_DEBUG, -	       "set nopad offset to %llu", -	       (unsigned long long)local->io_offset_nopad); - -	local->io_size_nopad = atom->io_size_nopad(frame, object); - -	gf_log("crypt", GF_LOG_DEBUG, -	       "set nopad size to %llu", -	       (unsigned long long)local->io_size_nopad); - -	local->update_disk_file_size = 0; -	/* -	 * NOTE: eof_padding_size is 0 for all full atoms; -	 * For head and tail atoms it will be set up at rmw_partial block() -	 */ -	local->new_file_size = local->cur_file_size; - -	if (local->io_offset_nopad + local->io_size_nopad > local->cur_file_size) { - -		local->new_file_size = local->io_offset_nopad + local->io_size_nopad; - -		gf_log("crypt", GF_LOG_DEBUG, -		       "set new file size to %llu", -		       (unsigned long long)local->new_file_size); - -		local->update_disk_file_size = 1; -	} -} - -void set_local_io_params_ftruncate(call_frame_t *frame, -				   struct object_cipher_info *object) -{ -	uint32_t resid; -	crypt_local_t *local = frame->local; -	struct avec_config *conf = &local->data_conf; - -	resid = conf->orig_offset & (object_alg_blksize(object) - 1); -	if (resid) { -		local->eof_padding_size = -			object_alg_blksize(object) - resid; -		local->new_file_size = conf->aligned_offset; -		local->update_disk_file_size = 0; -		/* -		 * file size will be updated -		 * in the ->writev() stack, -		 * when submitting file tail -		 */ -	} else { -		local->eof_padding_size = 0; -		local->new_file_size = conf->orig_offset; -		local->update_disk_file_size = 1; -		/* -		 * file size will be updated -		 * in this ->ftruncate stack -		 */ -	} -} - -static void submit_head(call_frame_t *frame, xlator_t *this) -{ -	crypt_local_t *local = frame->local; -	submit_partial(frame, this, local->fd, HEAD_ATOM); -} - -static void submit_tail(call_frame_t *frame, xlator_t *this) +static void +submit_tail(call_frame_t *frame, xlator_t *this)  { -	crypt_local_t *local = frame->local; -	submit_partial(frame, this, local->fd, TAIL_ATOM); +    crypt_local_t *local = frame->local; +    submit_partial(frame, this, local->fd, TAIL_ATOM);  } -static void submit_hole(call_frame_t *frame, xlator_t *this) +static void +submit_hole(call_frame_t *frame, xlator_t *this)  { -	/* -	 * hole conversion always means -	 * appended write and goes in ordered fashion -	 */ -	do_ordered_submit(frame, this, HOLE_ATOM); +    /* +     * hole conversion always means +     * appended write and goes in ordered fashion +     */ +    do_ordered_submit(frame, this, HOLE_ATOM);  } -static void submit_data(call_frame_t *frame, xlator_t *this) +static void +submit_data(call_frame_t *frame, xlator_t *this)  { -	if (is_ordered_mode(frame)) { -		do_ordered_submit(frame, this, DATA_ATOM); -		return; -	} -	gf_log("crypt", GF_LOG_WARNING, "Bad submit mode"); -	get_nr_calls(frame, nr_calls_data(frame)); -	do_parallel_submit(frame, this, DATA_ATOM); -	return; +    if (is_ordered_mode(frame)) { +        do_ordered_submit(frame, this, DATA_ATOM); +        return; +    } +    gf_log("crypt", GF_LOG_WARNING, "Bad submit mode"); +    get_nr_calls(frame, nr_calls_data(frame)); +    do_parallel_submit(frame, this, DATA_ATOM); +    return;  }  /*   * heplers called by writev_cbk, fruncate_cbk in ordered mode   */ -static int32_t should_submit_hole(crypt_local_t *local) +static int32_t +should_submit_hole(crypt_local_t *local)  { -	struct avec_config *conf = &local->hole_conf; +    struct avec_config *conf = &local->hole_conf; -	return conf->avec != NULL; +    return conf->avec != NULL;  } -static int32_t should_resume_submit_hole(crypt_local_t *local) +static int32_t +should_resume_submit_hole(crypt_local_t *local)  { -	struct avec_config *conf = &local->hole_conf; +    struct avec_config *conf = &local->hole_conf; -	if (local->fop == GF_FOP_WRITE && has_tail_block(conf)) -		/* -		 * Don't submit a part of hole, which -		 * fits into a data block: - 		 * this part of hole will be converted -		 * as a gap filled by zeros in data head -		 * block. -		 */ -		return conf->cursor < conf->acount - 1; -	else -		return conf->cursor < conf->acount; +    if (local->fop == GF_FOP_WRITE && has_tail_block(conf)) +        /* +         * Don't submit a part of hole, which +         * fits into a data block: +         * this part of hole will be converted +         * as a gap filled by zeros in data head +         * block. +         */ +        return conf->cursor < conf->acount - 1; +    else +        return conf->cursor < conf->acount;  } -static int32_t should_resume_submit_data(call_frame_t *frame) +static int32_t +should_resume_submit_data(call_frame_t *frame)  { -	crypt_local_t *local = frame->local; -	struct avec_config *conf = &local->data_conf; +    crypt_local_t *local = frame->local; +    struct avec_config *conf = &local->data_conf; -	if (is_ordered_mode(frame)) -		return conf->cursor < conf->acount; -	/* -	 * parallel writes -	 */ -	return 0; +    if (is_ordered_mode(frame)) +        return conf->cursor < conf->acount; +    /* +     * parallel writes +     */ +    return 0;  } -static int32_t should_submit_data_after_hole(crypt_local_t *local) +static int32_t +should_submit_data_after_hole(crypt_local_t *local)  { -	return local->data_conf.avec != NULL; +    return local->data_conf.avec != NULL;  } -static void update_local_file_params(call_frame_t *frame, -				     xlator_t *this, -				     struct iatt *prebuf, -				     struct iatt *postbuf) +static void +update_local_file_params(call_frame_t *frame, xlator_t *this, +                         struct iatt *prebuf, struct iatt *postbuf)  { -	crypt_local_t *local = frame->local; +    crypt_local_t *local = frame->local; -	check_buf(frame, this, postbuf); +    check_buf(frame, this, postbuf); -	local->prebuf = *prebuf; -	local->postbuf = *postbuf; +    local->prebuf = *prebuf; +    local->postbuf = *postbuf; -	local->prebuf.ia_size  = local->cur_file_size; -	local->postbuf.ia_size = local->new_file_size; +    local->prebuf.ia_size = local->cur_file_size; +    local->postbuf.ia_size = local->new_file_size; -	local->cur_file_size = local->new_file_size; +    local->cur_file_size = local->new_file_size;  } -static int32_t end_writeback_writev(call_frame_t *frame, -				    void *cookie, -				    xlator_t *this, -				    int32_t op_ret, -				    int32_t op_errno, -				    struct iatt *prebuf, -				    struct iatt *postbuf, -				    dict_t *xdata) +static int32_t +end_writeback_writev(call_frame_t *frame, void *cookie, xlator_t *this, +                     int32_t op_ret, int32_t op_errno, struct iatt *prebuf, +                     struct iatt *postbuf, dict_t *xdata)  { -	crypt_local_t *local = frame->local; - -	local->op_ret = op_ret; -	local->op_errno = op_errno; +    crypt_local_t *local = frame->local; -	if (op_ret <= 0) { -		gf_log(this->name, GF_LOG_WARNING, -		       "writev iteration failed"); -		goto put_one_call; -	} -	/* -	 * op_ret includes paddings (atom's head, atom's tail and EOF) -	 */ -	if (op_ret < local->io_size) { -		gf_log(this->name, GF_LOG_WARNING, -		       "Incomplete writev iteration"); -		goto put_one_call; -	} -	op_ret -= local->eof_padding_size; -	local->op_ret = op_ret; +    local->op_ret = op_ret; +    local->op_errno = op_errno; -	update_local_file_params(frame, this, prebuf, postbuf); +    if (op_ret <= 0) { +        gf_log(this->name, GF_LOG_WARNING, "writev iteration failed"); +        goto put_one_call; +    } +    /* +     * op_ret includes paddings (atom's head, atom's tail and EOF) +     */ +    if (op_ret < local->io_size) { +        gf_log(this->name, GF_LOG_WARNING, "Incomplete writev iteration"); +        goto put_one_call; +    } +    op_ret -= local->eof_padding_size; +    local->op_ret = op_ret; -	if (data_write_in_progress(local)) { +    update_local_file_params(frame, this, prebuf, postbuf); -		LOCK(&local->rw_count_lock); -		local->rw_count += op_ret; -		UNLOCK(&local->rw_count_lock); +    if (data_write_in_progress(local)) { +        LOCK(&local->rw_count_lock); +        local->rw_count += op_ret; +        UNLOCK(&local->rw_count_lock); -		if (should_resume_submit_data(frame)) -			submit_data(frame, this); -	} -	else { -		/* -		 * hole conversion is going on; -		 * don't take into account written zeros -		 */ -		if (should_resume_submit_hole(local)) -			submit_hole(frame, this); +        if (should_resume_submit_data(frame)) +            submit_data(frame, this); +    } else { +        /* +         * hole conversion is going on; +         * don't take into account written zeros +         */ +        if (should_resume_submit_hole(local)) +            submit_hole(frame, this); -		else if (should_submit_data_after_hole(local)) -			submit_data(frame, this); -	} - put_one_call: -	put_one_call_writev(frame, this); -	return 0; +        else if (should_submit_data_after_hole(local)) +            submit_data(frame, this); +    } +put_one_call: +    put_one_call_writev(frame, this); +    return 0;  }  #define crypt_writev_cbk end_writeback_writev @@ -853,363 +791,331 @@ static int32_t end_writeback_writev(call_frame_t *frame,   * Pre-conditions:   * @local->file_size is set and valid.   */ -int32_t prepare_for_submit_hole(call_frame_t *frame, xlator_t *this, -				uint64_t off, off_t size) +int32_t +prepare_for_submit_hole(call_frame_t *frame, xlator_t *this, uint64_t off, +                        off_t size)  { -	int32_t ret; -	crypt_local_t *local = frame->local; -	struct object_cipher_info *object = &local->info->cinfo; +    int32_t ret; +    crypt_local_t *local = frame->local; +    struct object_cipher_info *object = &local->info->cinfo; -	set_config_offsets(frame, this, off, size, HOLE_ATOM, 1); +    set_config_offsets(frame, this, off, size, HOLE_ATOM, 1); -	ret = set_config_avec_hole(this, local, -				   &local->hole_conf, object, local->fop); -	crypt_check_conf(&local->hole_conf); +    ret = set_config_avec_hole(this, local, &local->hole_conf, object, +                               local->fop); +    crypt_check_conf(&local->hole_conf); -	return ret; +    return ret;  }  /*   * prepare for submit @count bytes at offset @from   */ -int32_t prepare_for_submit_data(call_frame_t *frame, xlator_t *this, -				off_t from, int32_t size, struct iovec *vec, -				int32_t vec_count, int32_t setup_gap) +int32_t +prepare_for_submit_data(call_frame_t *frame, xlator_t *this, off_t from, +                        int32_t size, struct iovec *vec, int32_t vec_count, +                        int32_t setup_gap)  { -	uint32_t ret; -	crypt_local_t *local = frame->local; -	struct object_cipher_info *object = &local->info->cinfo; +    uint32_t ret; +    crypt_local_t *local = frame->local; +    struct object_cipher_info *object = &local->info->cinfo; -	set_config_offsets(frame, this, from, size, -			   DATA_ATOM, setup_gap); +    set_config_offsets(frame, this, from, size, DATA_ATOM, setup_gap); -	ret = set_config_avec_data(this, local, -				   &local->data_conf, object, vec, vec_count); -	crypt_check_conf(&local->data_conf); +    ret = set_config_avec_data(this, local, &local->data_conf, object, vec, +                               vec_count); +    crypt_check_conf(&local->data_conf); -	return ret; +    return ret; +} + +static void +free_avec(struct iovec *avec, char **pool, int blocks_in_pool) +{ +    if (!avec) +        return; +    GF_FREE(pool); +    GF_FREE(avec); +} + +static void +free_avec_data(crypt_local_t *local) +{ +    return free_avec(local->data_conf.avec, local->data_conf.pool, +                     local->data_conf.blocks_in_pool); +} + +static void +free_avec_hole(crypt_local_t *local) +{ +    return free_avec(local->hole_conf.avec, local->hole_conf.pool, +                     local->hole_conf.blocks_in_pool); +} + +static void +do_parallel_submit(call_frame_t *frame, xlator_t *this, atom_data_type dtype) +{ +    crypt_local_t *local = frame->local; +    struct avec_config *conf; + +    local->active_setup = dtype; +    conf = conf_by_type(frame, dtype); + +    if (has_head_block(conf)) +        submit_head(frame, this); + +    if (has_full_blocks(conf)) +        submit_full(frame, this); + +    if (has_tail_block(conf)) +        submit_tail(frame, this); +    return; +} + +static void +do_ordered_submit(call_frame_t *frame, xlator_t *this, atom_data_type dtype) +{ +    crypt_local_t *local = frame->local; +    struct avec_config *conf; + +    local->active_setup = dtype; +    conf = conf_by_type(frame, dtype); + +    if (should_submit_head_block(conf)) { +        get_one_call_nolock(frame); +        submit_head(frame, this); +    } else if (should_submit_full_block(conf)) { +        get_one_call_nolock(frame); +        submit_full(frame, this); +    } else if (should_submit_tail_block(conf)) { +        get_one_call_nolock(frame); +        submit_tail(frame, this); +    } else +        gf_log("crypt", GF_LOG_DEBUG, +               "nothing has been submitted in ordered mode"); +    return; +} + +static int32_t +do_writev(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, +          int32_t op_errno, dict_t *dict, dict_t *xdata) +{ +    data_t *data; +    crypt_local_t *local = frame->local; +    struct object_cipher_info *object = &local->info->cinfo; +    /* +     * extract regular file size +     */ +    data = dict_get(dict, FSIZE_XATTR_PREFIX); +    if (!data) { +        gf_log("crypt", GF_LOG_WARNING, "Regular file size not found"); +        op_ret = -1; +        op_errno = EIO; +        goto error; +    } +    local->old_file_size = local->cur_file_size = data_to_uint64(data); + +    set_gap_at_end(frame, object, &local->data_conf, DATA_ATOM); + +    if (local->cur_file_size < local->data_conf.orig_offset) { +        /* +         * Set up hole config +         */ +        op_errno = prepare_for_submit_hole( +            frame, this, local->cur_file_size, +            local->data_conf.orig_offset - local->cur_file_size); +        if (op_errno) { +            local->op_ret = -1; +            local->op_errno = op_errno; +            goto error; +        } +    } +    if (should_submit_hole(local)) +        submit_hole(frame, this); +    else +        submit_data(frame, this); +    return 0; +error: +    get_one_call_nolock(frame); +    put_one_call_writev(frame, this); +    return 0; +} + +static int32_t +crypt_writev_finodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                          int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ +    crypt_local_t *local = frame->local; + +    local->op_ret = op_ret; +    local->op_errno = op_errno; + +    if (op_ret < 0) +        goto error; +    /* +     * An access has been granted, +     * retrieve file size first +     */ +    STACK_WIND(frame, do_writev, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->fgetxattr, local->fd, +               FSIZE_XATTR_PREFIX, NULL); +    return 0; +error: +    get_one_call_nolock(frame); +    put_one_call_writev(frame, this); +    return 0;  } -static void free_avec(struct iovec *avec, -		      char **pool, int blocks_in_pool) +static int32_t +writev_trivial_completion(call_frame_t *frame, void *cookie, xlator_t *this, +                          int32_t op_ret, int32_t op_errno, struct iatt *buf, +                          dict_t *dict)  { -	if (!avec) -		return; -	GF_FREE(pool); -	GF_FREE(avec); +    crypt_local_t *local = frame->local; + +    local->op_ret = op_ret; +    local->op_errno = op_errno; +    local->prebuf = *buf; +    local->postbuf = *buf; + +    local->prebuf.ia_size = local->cur_file_size; +    local->postbuf.ia_size = local->cur_file_size; + +    get_one_call(frame); +    put_one_call_writev(frame, this); +    return 0;  } -static void free_avec_data(crypt_local_t *local) -{ -	return free_avec(local->data_conf.avec, -			 local->data_conf.pool, -			 local->data_conf.blocks_in_pool); -} - -static void free_avec_hole(crypt_local_t *local) -{ -	return free_avec(local->hole_conf.avec, -			 local->hole_conf.pool, -			 local->hole_conf.blocks_in_pool); -} - - -static void do_parallel_submit(call_frame_t *frame, xlator_t *this, -			       atom_data_type dtype) -{ -	crypt_local_t *local = frame->local; -	struct avec_config *conf; - -	local->active_setup = dtype; -	conf = conf_by_type(frame, dtype); - -	if (has_head_block(conf)) -		submit_head(frame, this); - -	if (has_full_blocks(conf)) -		submit_full(frame, this); - -	if (has_tail_block(conf)) -		submit_tail(frame, this); -	return; -} - -static void do_ordered_submit(call_frame_t *frame, xlator_t *this, -			      atom_data_type dtype) -{ -	crypt_local_t *local = frame->local; -	struct avec_config *conf; - -	local->active_setup = dtype; -	conf = conf_by_type(frame, dtype); - -	if (should_submit_head_block(conf)) { -		get_one_call_nolock(frame); -		submit_head(frame, this); -	} -	else if (should_submit_full_block(conf)) { -		get_one_call_nolock(frame); -		submit_full(frame, this); -	} -	else if (should_submit_tail_block(conf)) { -		get_one_call_nolock(frame); -		submit_tail(frame, this); -	} -	else -		gf_log("crypt", GF_LOG_DEBUG, -		       "nothing has been submitted in ordered mode"); -	return; -} - -static int32_t do_writev(call_frame_t *frame, -			 void *cookie, -			 xlator_t *this, -			 int32_t op_ret, -			 int32_t op_errno, -			 dict_t *dict, -			 dict_t *xdata) -{ -	data_t *data; -	crypt_local_t *local = frame->local; -	struct object_cipher_info *object = &local->info->cinfo; -	/* -	 * extract regular file size -	 */ -	data = dict_get(dict, FSIZE_XATTR_PREFIX); -	if (!data) { -		gf_log("crypt", GF_LOG_WARNING, "Regular file size not found"); -		op_ret = -1; -		op_errno = EIO; -		goto error; -	} -	local->old_file_size = local->cur_file_size = data_to_uint64(data); - -	set_gap_at_end(frame, object, &local->data_conf, DATA_ATOM); - -	if (local->cur_file_size < local->data_conf.orig_offset) { -		/* -		 * Set up hole config -		 */ -		op_errno = prepare_for_submit_hole(frame, -			       this, -			       local->cur_file_size, -			       local->data_conf.orig_offset - local->cur_file_size); -		if (op_errno) { -			local->op_ret = -1; -			local->op_errno = op_errno; -			goto error; -		} -	} -	if (should_submit_hole(local)) -		submit_hole(frame, this); -	else -		submit_data(frame, this); -	return 0; - error: -	get_one_call_nolock(frame); -	put_one_call_writev(frame, this); -	return 0; -} - -static int32_t crypt_writev_finodelk_cbk(call_frame_t *frame, -					 void *cookie, -					 xlator_t *this, -					 int32_t op_ret, -					 int32_t op_errno, -					 dict_t *xdata) -{ -	crypt_local_t *local = frame->local; - -	local->op_ret = op_ret; -	local->op_errno = op_errno; - -	if (op_ret < 0) -		goto error; -	/* -	 * An access has been granted, -	 * retrieve file size first -	 */ -	STACK_WIND(frame, -		   do_writev, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->fgetxattr, -		   local->fd, -		   FSIZE_XATTR_PREFIX, -		   NULL); -	return 0; - error: -	get_one_call_nolock(frame); -	put_one_call_writev(frame, this); -	return 0; -} - -static int32_t writev_trivial_completion(call_frame_t *frame, -					 void *cookie, -					 xlator_t *this, -					 int32_t op_ret, -					 int32_t op_errno, -					 struct iatt *buf, -					 dict_t *dict) -{ -	crypt_local_t *local = frame->local; - -	local->op_ret = op_ret; -	local->op_errno = op_errno; -	local->prebuf = *buf; -	local->postbuf = *buf; - -	local->prebuf.ia_size = local->cur_file_size; -	local->postbuf.ia_size = local->cur_file_size; - -	get_one_call(frame); -	put_one_call_writev(frame, this); -	return 0; -} - -int crypt_writev(call_frame_t *frame, -		 xlator_t *this, -		 fd_t *fd, -		 struct iovec *vec, -		 int32_t count, -		 off_t offset, -		 uint32_t flags, -		 struct iobref *iobref, -		 dict_t *xdata) -{ -	int32_t ret; -	crypt_local_t *local; -	struct crypt_inode_info *info; -	struct gf_flock lock = {0, }; +int +crypt_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vec, +             int32_t count, off_t offset, uint32_t flags, struct iobref *iobref, +             dict_t *xdata) +{ +    int32_t ret; +    crypt_local_t *local; +    struct crypt_inode_info *info; +    struct gf_flock lock = { +        0, +    };  #if DEBUG_CRYPT -	gf_log ("crypt", GF_LOG_DEBUG, "writing %d bytes from offset %llu", -		(int)iov_length(vec, count), (long long)offset); +    gf_log("crypt", GF_LOG_DEBUG, "writing %d bytes from offset %llu", +           (int)iov_length(vec, count), (long long)offset);  #endif -	local = crypt_alloc_local(frame, this, GF_FOP_WRITE); -	if (!local) { -		ret = ENOMEM; -		goto error; -	} -	local->fd = fd_ref(fd); - -	if (iobref) -		local->iobref = iobref_ref(iobref); -	/* -	 * to update real file size on the server -	 */ -	local->xattr = dict_new(); -	if (!local->xattr) { -		ret = ENOMEM; -		goto error; -	} -	local->flags = flags; - -	info = local_get_inode_info(local, this); -	if (info == NULL) { -		ret = EINVAL; -		goto error; -	} -	if (!object_alg_atomic(&info->cinfo)) { -		ret = EINVAL; -		goto error; -	} -	if (iov_length(vec, count) == 0) -		goto trivial; - -	ret = prepare_for_submit_data(frame, this, offset, +    local = crypt_alloc_local(frame, this, GF_FOP_WRITE); +    if (!local) { +        ret = ENOMEM; +        goto error; +    } +    local->fd = fd_ref(fd); + +    if (iobref) +        local->iobref = iobref_ref(iobref); +    /* +     * to update real file size on the server +     */ +    local->xattr = dict_new(); +    if (!local->xattr) { +        ret = ENOMEM; +        goto error; +    } +    local->flags = flags; + +    info = local_get_inode_info(local, this); +    if (info == NULL) { +        ret = EINVAL; +        goto error; +    } +    if (!object_alg_atomic(&info->cinfo)) { +        ret = EINVAL; +        goto error; +    } +    if (iov_length(vec, count) == 0) +        goto trivial; + +    ret = prepare_for_submit_data(frame, this, offset,  				      iov_length(vec, count),  				      vec, count, 0 /* don't setup gup  						       in tail: we don't  						       know file size yet */); -	if (ret) { -                ret = ENOMEM; -		goto error; +    if (ret) { +        ret = ENOMEM; +        goto error; +    } + +    if (parent_is_crypt_xlator(frame, this)) { +        data_t *data; +        /* +         * we are called by shinking crypt_ftruncate(), +         * which doesn't perform hole conversion; +         * +         * don't ask for access: +         * it has already been acquired +         */ + +        /* +         * extract file size +         */ +        if (!xdata) { +            gf_log("crypt", GF_LOG_WARNING, +                   "Regular file size hasn't been passed"); +            ret = EIO; +            goto error;          } +        data = dict_get(xdata, FSIZE_XATTR_PREFIX); +        if (!data) { +            gf_log("crypt", GF_LOG_WARNING, "Regular file size not found"); +            ret = EIO; +            goto error; +        } +        local->old_file_size = local->cur_file_size = data_to_uint64(data); -	if (parent_is_crypt_xlator(frame, this)) { -		data_t *data; -		/* -		 * we are called by shinking crypt_ftruncate(), -		 * which doesn't perform hole conversion; -		 * -		 * don't ask for access: -		 * it has already been acquired -		 */ - -		/* -		 * extract file size -		 */ -		if (!xdata) { -			gf_log("crypt", GF_LOG_WARNING, -			       "Regular file size hasn't been passed"); -			ret = EIO; -			goto error; -		} -		data = dict_get(xdata, FSIZE_XATTR_PREFIX); -		if (!data) { -			gf_log("crypt", GF_LOG_WARNING, -			       "Regular file size not found"); -			ret = EIO; -			goto error; -		} -		local->old_file_size = -			local->cur_file_size = data_to_uint64(data); - -		submit_data(frame, this); -		return 0; -	} -	if (xdata) -		local->xdata = dict_ref(xdata); -	/* -	 * lock the file and retrieve its size -	 */ -	lock.l_len    = 0; -        lock.l_start  = 0; -        lock.l_type   = F_WRLCK; -        lock.l_whence = SEEK_SET; +        submit_data(frame, this); +        return 0; +    } +    if (xdata) +        local->xdata = dict_ref(xdata); +    /* +     * lock the file and retrieve its size +     */ +    lock.l_len = 0; +    lock.l_start = 0; +    lock.l_type = F_WRLCK; +    lock.l_whence = SEEK_SET; + +    STACK_WIND(frame, crypt_writev_finodelk_cbk, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->finodelk, this->name, fd, F_SETLKW, +               &lock, NULL); +    return 0; +trivial: +    STACK_WIND(frame, writev_trivial_completion, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->fstat, fd, NULL); +    return 0; +error: +    if (local && local->fd) +        fd_unref(fd); +    if (local && local->iobref) +        iobref_unref(iobref); +    if (local && local->xdata) +        dict_unref(xdata); +    if (local && local->xattr) +        dict_unref(local->xattr); +    if (local && local->info) +        free_inode_info(local->info); -	STACK_WIND(frame, -		   crypt_writev_finodelk_cbk, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->finodelk, -		   this->name, -		   fd, -		   F_SETLKW, -		   &lock, -		   NULL); -	return 0; - trivial: -	STACK_WIND(frame, -		   writev_trivial_completion, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->fstat, -		   fd, -		   NULL); -	return 0; - error: -	if (local && local->fd) -		fd_unref(fd); -	if (local && local->iobref) -		iobref_unref(iobref); -	if (local && local->xdata) -		dict_unref(xdata); -	if (local && local->xattr) -		dict_unref(local->xattr); -	if (local && local->info) -		free_inode_info(local->info); - -	CRYPT_STACK_UNWIND(writev, frame, -1, ret, NULL, NULL, NULL); -	return 0; -} - -int32_t prepare_for_prune(call_frame_t *frame, xlator_t *this, uint64_t offset) -{ -	set_config_offsets(frame, this, +    CRYPT_STACK_UNWIND(writev, frame, -1, ret, NULL, NULL, NULL); +    return 0; +} + +int32_t +prepare_for_prune(call_frame_t *frame, xlator_t *this, uint64_t offset) +{ +    set_config_offsets(frame, this,  			   offset,  			   0, /* count */  			   DATA_ATOM,  			   0 /* since we prune, there is no  				gap in tail to uptodate */); -	return 0; +    return 0;  }  /* @@ -1220,24 +1126,20 @@ int32_t prepare_for_prune(call_frame_t *frame, xlator_t *this, uint64_t offset)   * 2) ->writev_cbk() for non-cblock-aligned prune   */ -static int32_t prune_complete(call_frame_t *frame, -			      void *cookie, -			      xlator_t *this, -			      int32_t op_ret, -			      int32_t op_errno, -			      struct iatt *prebuf, -			      struct iatt *postbuf, -			      dict_t *xdata) +static int32_t +prune_complete(call_frame_t *frame, void *cookie, xlator_t *this, +               int32_t op_ret, int32_t op_errno, struct iatt *prebuf, +               struct iatt *postbuf, dict_t *xdata)  { -	crypt_local_t *local = frame->local; +    crypt_local_t *local = frame->local; -	local->op_ret = op_ret; -	local->op_errno = op_errno; +    local->op_ret = op_ret; +    local->op_errno = op_errno; -	update_local_file_params(frame, this, prebuf, postbuf); +    update_local_file_params(frame, this, prebuf, postbuf); -	put_one_call_ftruncate(frame, this); -	return 0; +    put_one_call_ftruncate(frame, this); +    return 0;  }  /* @@ -1248,81 +1150,69 @@ static int32_t prune_complete(call_frame_t *frame,   *   * submuit the rest of the file   */ -static int32_t prune_submit_file_tail(call_frame_t *frame, -				      void *cookie, -				      xlator_t *this, -				      int32_t op_ret, -				      int32_t op_errno, -				      struct iatt *prebuf, -				      struct iatt *postbuf, -				      dict_t *xdata) -{ -	crypt_local_t *local = frame->local; -	struct avec_config *conf = &local->data_conf; -	dict_t *dict; - -	if (op_ret < 0) -		goto put_one_call; - -	if (local->xdata) { -		dict_unref(local->xdata); -		local->xdata = NULL; -	} -	if (xdata) -		local->xdata = dict_ref(xdata); - -	dict = dict_new(); -	if (!dict) { -		op_errno = ENOMEM; -		goto error; -	} - -	update_local_file_params(frame, this, prebuf, postbuf); -	local->new_file_size = conf->orig_offset; - -	/* -	 * The rest of the file is a partial block and, hence, -	 * should be written via RMW sequence, so the crypt xlator -	 * does STACK_WIND to itself. -	 * -	 * Pass current file size to crypt_writev() -	 */ -	op_errno = dict_set(dict, -			    FSIZE_XATTR_PREFIX, -			    data_from_uint64(local->cur_file_size)); -	if (op_errno) { -		gf_log("crypt", GF_LOG_WARNING, -		       "can not set key to update file size"); -		dict_unref(dict); -		goto error; -	} -	gf_log("crypt", GF_LOG_DEBUG, -	       "passing current file size (%llu) to crypt_writev", -	       (unsigned long long)local->cur_file_size); -	/* -	 * Padding will be filled with -	 * zeros by rmw_partial_block() -	 */ -	STACK_WIND(frame, -		   prune_complete, -		   this, -		   this->fops->writev, /* crypt_writev */ -		   local->fd, -		   &local->vec, -		   1, -		   conf->aligned_offset, /* offset to write from */ -		   0, -		   local->iobref, -		   dict); - -	dict_unref(dict); -	return 0; - error: -	local->op_ret = -1; -	local->op_errno = op_errno; - put_one_call: -	put_one_call_ftruncate(frame, this); -	return 0; +static int32_t +prune_submit_file_tail(call_frame_t *frame, void *cookie, xlator_t *this, +                       int32_t op_ret, int32_t op_errno, struct iatt *prebuf, +                       struct iatt *postbuf, dict_t *xdata) +{ +    crypt_local_t *local = frame->local; +    struct avec_config *conf = &local->data_conf; +    dict_t *dict; + +    if (op_ret < 0) +        goto put_one_call; + +    if (local->xdata) { +        dict_unref(local->xdata); +        local->xdata = NULL; +    } +    if (xdata) +        local->xdata = dict_ref(xdata); + +    dict = dict_new(); +    if (!dict) { +        op_errno = ENOMEM; +        goto error; +    } + +    update_local_file_params(frame, this, prebuf, postbuf); +    local->new_file_size = conf->orig_offset; + +    /* +     * The rest of the file is a partial block and, hence, +     * should be written via RMW sequence, so the crypt xlator +     * does STACK_WIND to itself. +     * +     * Pass current file size to crypt_writev() +     */ +    op_errno = dict_set(dict, FSIZE_XATTR_PREFIX, +                        data_from_uint64(local->cur_file_size)); +    if (op_errno) { +        gf_log("crypt", GF_LOG_WARNING, "can not set key to update file size"); +        dict_unref(dict); +        goto error; +    } +    gf_log("crypt", GF_LOG_DEBUG, +           "passing current file size (%llu) to crypt_writev", +           (unsigned long long)local->cur_file_size); +    /* +     * Padding will be filled with +     * zeros by rmw_partial_block() +     */ +    STACK_WIND(frame, prune_complete, this, +               this->fops->writev, /* crypt_writev */ +               local->fd, &local->vec, 1, +               conf->aligned_offset, /* offset to write from */ +               0, local->iobref, dict); + +    dict_unref(dict); +    return 0; +error: +    local->op_ret = -1; +    local->op_errno = op_errno; +put_one_call: +    put_one_call_ftruncate(frame, this); +    return 0;  }  /* @@ -1333,40 +1223,36 @@ static int32_t prune_submit_file_tail(call_frame_t *frame,   * 2) an rmw partial data block issued by non-cblock-aligned   * prune.   */ -int32_t end_writeback_ftruncate(call_frame_t *frame, -				void *cookie, -				xlator_t *this, -				int32_t op_ret, -				int32_t op_errno, -				struct iatt *prebuf, -				struct iatt *postbuf, -				dict_t *xdata) -{ -	crypt_local_t  *local = frame->local; -	/* -	 * if nothing has been written, -	 * then it must be an error -	 */ -	local->op_ret = op_ret; -	local->op_errno = op_errno; - -	if (op_ret < 0) -		goto put_one_call; - -	update_local_file_params(frame, this, prebuf, postbuf); - -	if (data_write_in_progress(local)) -		/* case (2) */ -		goto put_one_call; -	/* case (1) */ -	if (should_resume_submit_hole(local)) -		submit_hole(frame, this); -	/* -	 * case of hole, when we shouldn't resume -	 */ - put_one_call: -	put_one_call_ftruncate(frame, this); -	return 0; +int32_t +end_writeback_ftruncate(call_frame_t *frame, void *cookie, xlator_t *this, +                        int32_t op_ret, int32_t op_errno, struct iatt *prebuf, +                        struct iatt *postbuf, dict_t *xdata) +{ +    crypt_local_t *local = frame->local; +    /* +     * if nothing has been written, +     * then it must be an error +     */ +    local->op_ret = op_ret; +    local->op_errno = op_errno; + +    if (op_ret < 0) +        goto put_one_call; + +    update_local_file_params(frame, this, prebuf, postbuf); + +    if (data_write_in_progress(local)) +        /* case (2) */ +        goto put_one_call; +    /* case (1) */ +    if (should_resume_submit_hole(local)) +        submit_hole(frame, this); +    /* +     * case of hole, when we shouldn't resume +     */ +put_one_call: +    put_one_call_ftruncate(frame, this); +    return 0;  }  /* @@ -1379,150 +1265,126 @@ int32_t end_writeback_ftruncate(call_frame_t *frame,   * @vec contains the latest atom of the file   * (plain text)   */ -static int32_t prune_write(call_frame_t *frame, -			   void *cookie, -			   xlator_t *this, -			   int32_t op_ret, -			   int32_t op_errno, -			   struct iovec *vec, -			   int32_t count, -			   struct iatt *stbuf, -			   struct iobref *iobref, -			   dict_t *xdata) -{ -	int32_t i; -	size_t to_copy; -	size_t copied = 0; -	crypt_local_t *local = frame->local; -	struct avec_config *conf = &local->data_conf; - -	local->op_ret = op_ret; -	local->op_errno = op_errno; -	if (op_ret == -1) -		goto put_one_call; - -	/* -	 * At first, uptodate head block -	 */ -	if (iov_length(vec, count) < conf->off_in_head) { -		gf_log(this->name, GF_LOG_WARNING, -		       "Failed to uptodate head block for prune"); -		local->op_ret = -1; -		local->op_errno = EIO; -		goto put_one_call; -	} -	local->vec.iov_len = conf->off_in_head; -	local->vec.iov_base = GF_CALLOC(1, local->vec.iov_len, -					gf_crypt_mt_data); - -	if (local->vec.iov_base == NULL) { -	        gf_log(this->name, GF_LOG_WARNING, -                       "Failed to calloc head block for prune"); -		local->op_ret = -1; -		local->op_errno = ENOMEM; -	        goto put_one_call; -	} -	for (i = 0; i < count; i++) { -		to_copy = vec[i].iov_len; -		if (to_copy > local->vec.iov_len - copied) -			to_copy = local->vec.iov_len - copied; - -		memcpy((char *)local->vec.iov_base + copied, -		       vec[i].iov_base, -		       to_copy); -		copied += to_copy; -		if (copied == local->vec.iov_len) -			break; -	} -	/* -	 * perform prune with aligned offset -	 * (i.e. at this step we prune a bit -	 * more then it is needed -	 */ -	STACK_WIND(frame, -		   prune_submit_file_tail, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->ftruncate, -		   local->fd, -		   conf->aligned_offset, -		   local->xdata); -	return 0; - put_one_call: -	put_one_call_ftruncate(frame, this); -	return 0; +static int32_t +prune_write(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, +            int32_t op_errno, struct iovec *vec, int32_t count, +            struct iatt *stbuf, struct iobref *iobref, dict_t *xdata) +{ +    int32_t i; +    size_t to_copy; +    size_t copied = 0; +    crypt_local_t *local = frame->local; +    struct avec_config *conf = &local->data_conf; + +    local->op_ret = op_ret; +    local->op_errno = op_errno; +    if (op_ret == -1) +        goto put_one_call; + +    /* +     * At first, uptodate head block +     */ +    if (iov_length(vec, count) < conf->off_in_head) { +        gf_log(this->name, GF_LOG_WARNING, +               "Failed to uptodate head block for prune"); +        local->op_ret = -1; +        local->op_errno = EIO; +        goto put_one_call; +    } +    local->vec.iov_len = conf->off_in_head; +    local->vec.iov_base = GF_CALLOC(1, local->vec.iov_len, gf_crypt_mt_data); + +    if (local->vec.iov_base == NULL) { +        gf_log(this->name, GF_LOG_WARNING, +               "Failed to calloc head block for prune"); +        local->op_ret = -1; +        local->op_errno = ENOMEM; +        goto put_one_call; +    } +    for (i = 0; i < count; i++) { +        to_copy = vec[i].iov_len; +        if (to_copy > local->vec.iov_len - copied) +            to_copy = local->vec.iov_len - copied; + +        memcpy((char *)local->vec.iov_base + copied, vec[i].iov_base, to_copy); +        copied += to_copy; +        if (copied == local->vec.iov_len) +            break; +    } +    /* +     * perform prune with aligned offset +     * (i.e. at this step we prune a bit +     * more then it is needed +     */ +    STACK_WIND(frame, prune_submit_file_tail, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->ftruncate, local->fd, +               conf->aligned_offset, local->xdata); +    return 0; +put_one_call: +    put_one_call_ftruncate(frame, this); +    return 0;  }  /*   * Perform a read-prune-write sequence   */ -int32_t read_prune_write(call_frame_t *frame, xlator_t *this) -{ -	int32_t ret = 0; -	dict_t *dict = NULL; -	crypt_local_t  *local = frame->local; -	struct avec_config *conf = &local->data_conf; -	struct object_cipher_info *object = &local->info->cinfo; - -	set_local_io_params_ftruncate(frame, object); -	get_one_call_nolock(frame); - -	if ((conf->orig_offset & (object_alg_blksize(object) - 1)) == 0) { -		/* -		 * cblock-aligned prune: -		 * we don't need read and write components, -		 * just cut file body -		 */ -		gf_log("crypt", GF_LOG_DEBUG, -		       "prune without RMW (at offset %llu", -		       (unsigned long long)conf->orig_offset); - -		STACK_WIND(frame, -			   prune_complete, -			   FIRST_CHILD(this), -			   FIRST_CHILD(this)->fops->ftruncate, -			   local->fd, -			   conf->orig_offset, -			   local->xdata); -		return 0; -	} -	gf_log("crypt", GF_LOG_DEBUG, -	       "prune with RMW (at offset %llu", -	       (unsigned long long)conf->orig_offset); -	/* -	 * We are about to perform the "read" component of the -	 * read-prune-write sequence. It means that we need to -	 * read encrypted data from disk and decrypt it. -	 * So, the crypt translator does STACK_WIND to itself. -	 * -	 * Pass current file size to crypt_readv() - -	 */ -	dict = dict_new(); -	if (!dict) { -		gf_log("crypt", GF_LOG_WARNING, "Can not alloc dict"); -		ret = ENOMEM; -		goto exit; -	} -	ret = dict_set(dict, -		       FSIZE_XATTR_PREFIX, -		       data_from_uint64(local->cur_file_size)); -	if (ret) { -		gf_log("crypt", GF_LOG_WARNING, "Can not set dict"); -		goto exit; -	} -	STACK_WIND(frame, -		   prune_write, -		   this, -		   this->fops->readv, /* crypt_readv */ -		   local->fd, -		   get_atom_size(object), /* bytes to read */ -		   conf->aligned_offset, /* offset to read from */ -		   0, -		   dict); - exit: -	if (dict) -		dict_unref(dict); -	return ret; +int32_t +read_prune_write(call_frame_t *frame, xlator_t *this) +{ +    int32_t ret = 0; +    dict_t *dict = NULL; +    crypt_local_t *local = frame->local; +    struct avec_config *conf = &local->data_conf; +    struct object_cipher_info *object = &local->info->cinfo; + +    set_local_io_params_ftruncate(frame, object); +    get_one_call_nolock(frame); + +    if ((conf->orig_offset & (object_alg_blksize(object) - 1)) == 0) { +        /* +         * cblock-aligned prune: +         * we don't need read and write components, +         * just cut file body +         */ +        gf_log("crypt", GF_LOG_DEBUG, "prune without RMW (at offset %llu", +               (unsigned long long)conf->orig_offset); + +        STACK_WIND(frame, prune_complete, FIRST_CHILD(this), +                   FIRST_CHILD(this)->fops->ftruncate, local->fd, +                   conf->orig_offset, local->xdata); +        return 0; +    } +    gf_log("crypt", GF_LOG_DEBUG, "prune with RMW (at offset %llu", +           (unsigned long long)conf->orig_offset); +    /* +     * We are about to perform the "read" component of the +     * read-prune-write sequence. It means that we need to +     * read encrypted data from disk and decrypt it. +     * So, the crypt translator does STACK_WIND to itself. +     * +     * Pass current file size to crypt_readv() + +     */ +    dict = dict_new(); +    if (!dict) { +        gf_log("crypt", GF_LOG_WARNING, "Can not alloc dict"); +        ret = ENOMEM; +        goto exit; +    } +    ret = dict_set(dict, FSIZE_XATTR_PREFIX, +                   data_from_uint64(local->cur_file_size)); +    if (ret) { +        gf_log("crypt", GF_LOG_WARNING, "Can not set dict"); +        goto exit; +    } +    STACK_WIND(frame, prune_write, this, this->fops->readv, /* crypt_readv */ +               local->fd, get_atom_size(object),            /* bytes to read */ +               conf->aligned_offset, /* offset to read from */ +               0, dict); +exit: +    if (dict) +        dict_unref(dict); +    return ret;  }  /* @@ -1539,159 +1401,135 @@ int32_t read_prune_write(call_frame_t *frame, xlator_t *this)   * 2) perform cblock-aligned prune   * 3) issue a write request for the end-of-file   */ -int32_t prune_file(call_frame_t *frame, xlator_t *this, uint64_t offset) -{ -	int32_t ret; - -	ret = prepare_for_prune(frame, this, offset); -	if (ret) -		return ret; -	return read_prune_write(frame, this); -} - -int32_t expand_file(call_frame_t *frame, xlator_t *this, -		    uint64_t offset) -{ -	int32_t ret; -	crypt_local_t *local = frame->local; - -	ret = prepare_for_submit_hole(frame, this, -				      local->old_file_size, -				      offset - local->old_file_size); -	if (ret) -		return ret; -	submit_hole(frame, this); -	return 0; -} - -static int32_t ftruncate_trivial_completion(call_frame_t *frame, -					    void *cookie, -					    xlator_t *this, -					    int32_t op_ret, -					    int32_t op_errno, -					    struct iatt *buf, -					    dict_t *dict) -{ -	crypt_local_t *local = frame->local; - -	local->op_ret = op_ret; -	local->op_errno = op_errno; -	local->prebuf = *buf; -	local->postbuf = *buf; - -	local->prebuf.ia_size = local->cur_file_size; -	local->postbuf.ia_size = local->cur_file_size; - -	get_one_call(frame); -	put_one_call_ftruncate(frame, this); -	return 0; -} - -static int32_t do_ftruncate(call_frame_t *frame, -			    void *cookie, -			    xlator_t *this, -			    int32_t op_ret, -			    int32_t op_errno, -			    dict_t *dict, -			    dict_t *xdata) -{ -	data_t *data; -	crypt_local_t *local = frame->local; - -	if (op_ret) -		goto error; -	/* -	 * extract regular file size -	 */ -	data = dict_get(dict, FSIZE_XATTR_PREFIX); -	if (!data) { -		gf_log("crypt", GF_LOG_WARNING, "Regular file size not found"); -		op_errno = EIO; -		goto error; -	} -	local->old_file_size = local->cur_file_size = data_to_uint64(data); - -	if (local->data_conf.orig_offset == local->cur_file_size) { +int32_t +prune_file(call_frame_t *frame, xlator_t *this, uint64_t offset) +{ +    int32_t ret; + +    ret = prepare_for_prune(frame, this, offset); +    if (ret) +        return ret; +    return read_prune_write(frame, this); +} + +int32_t +expand_file(call_frame_t *frame, xlator_t *this, uint64_t offset) +{ +    int32_t ret; +    crypt_local_t *local = frame->local; + +    ret = prepare_for_submit_hole(frame, this, local->old_file_size, +                                  offset - local->old_file_size); +    if (ret) +        return ret; +    submit_hole(frame, this); +    return 0; +} + +static int32_t +ftruncate_trivial_completion(call_frame_t *frame, void *cookie, xlator_t *this, +                             int32_t op_ret, int32_t op_errno, struct iatt *buf, +                             dict_t *dict) +{ +    crypt_local_t *local = frame->local; + +    local->op_ret = op_ret; +    local->op_errno = op_errno; +    local->prebuf = *buf; +    local->postbuf = *buf; + +    local->prebuf.ia_size = local->cur_file_size; +    local->postbuf.ia_size = local->cur_file_size; + +    get_one_call(frame); +    put_one_call_ftruncate(frame, this); +    return 0; +} + +static int32_t +do_ftruncate(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, +             int32_t op_errno, dict_t *dict, dict_t *xdata) +{ +    data_t *data; +    crypt_local_t *local = frame->local; + +    if (op_ret) +        goto error; +    /* +     * extract regular file size +     */ +    data = dict_get(dict, FSIZE_XATTR_PREFIX); +    if (!data) { +        gf_log("crypt", GF_LOG_WARNING, "Regular file size not found"); +        op_errno = EIO; +        goto error; +    } +    local->old_file_size = local->cur_file_size = data_to_uint64(data); + +    if (local->data_conf.orig_offset == local->cur_file_size) {  #if DEBUG_CRYPT -		gf_log("crypt", GF_LOG_DEBUG, -		       "trivial ftruncate (current file size %llu)", -		       (unsigned long long)local->cur_file_size); +        gf_log("crypt", GF_LOG_DEBUG, +               "trivial ftruncate (current file size %llu)", +               (unsigned long long)local->cur_file_size);  #endif -		goto trivial; -	} -	else if (local->data_conf.orig_offset < local->cur_file_size) { +        goto trivial; +    } else if (local->data_conf.orig_offset < local->cur_file_size) {  #if DEBUG_CRYPT -		gf_log("crypt", GF_LOG_DEBUG, "prune from %llu to %llu", -		       (unsigned long long)local->cur_file_size, -		       (unsigned long long)local->data_conf.orig_offset); +        gf_log("crypt", GF_LOG_DEBUG, "prune from %llu to %llu", +               (unsigned long long)local->cur_file_size, +               (unsigned long long)local->data_conf.orig_offset);  #endif -		op_errno = prune_file(frame, -				      this, -				      local->data_conf.orig_offset); -	} -	else { +        op_errno = prune_file(frame, this, local->data_conf.orig_offset); +    } else {  #if DEBUG_CRYPT -		gf_log("crypt", GF_LOG_DEBUG, "expand from %llu to %llu", -		       (unsigned long long)local->cur_file_size, -		       (unsigned long long)local->data_conf.orig_offset); +        gf_log("crypt", GF_LOG_DEBUG, "expand from %llu to %llu", +               (unsigned long long)local->cur_file_size, +               (unsigned long long)local->data_conf.orig_offset);  #endif -		op_errno = expand_file(frame, -				       this, -				       local->data_conf.orig_offset); -	} -	if (op_errno) -		goto error; -	return 0; - trivial: -	STACK_WIND(frame, -		   ftruncate_trivial_completion, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->fstat, -		   local->fd, -		   NULL); -	return 0; - error: -	/* -	 * finish with ftruncate -	 */ -	local->op_ret = -1; -	local->op_errno = op_errno; - -	get_one_call_nolock(frame); -	put_one_call_ftruncate(frame, this); -	return 0; -} - -static int32_t crypt_ftruncate_finodelk_cbk(call_frame_t *frame, -					    void *cookie, -					    xlator_t *this, -					    int32_t op_ret, -					    int32_t op_errno, -					    dict_t *xdata) -{ -	crypt_local_t *local = frame->local; - -	local->op_ret = op_ret; -	local->op_errno = op_errno; - -	if (op_ret < 0) -		goto error; -	/* -	 * An access has been granted, -	 * retrieve file size first -	 */ -	STACK_WIND(frame, -		   do_ftruncate, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->fgetxattr, -		   local->fd, -		   FSIZE_XATTR_PREFIX, -		   NULL); -	return 0; - error: -	get_one_call_nolock(frame); -	put_one_call_ftruncate(frame, this); -	return 0; +        op_errno = expand_file(frame, this, local->data_conf.orig_offset); +    } +    if (op_errno) +        goto error; +    return 0; +trivial: +    STACK_WIND(frame, ftruncate_trivial_completion, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->fstat, local->fd, NULL); +    return 0; +error: +    /* +     * finish with ftruncate +     */ +    local->op_ret = -1; +    local->op_errno = op_errno; + +    get_one_call_nolock(frame); +    put_one_call_ftruncate(frame, this); +    return 0; +} + +static int32_t +crypt_ftruncate_finodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                             int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ +    crypt_local_t *local = frame->local; + +    local->op_ret = op_ret; +    local->op_errno = op_errno; + +    if (op_ret < 0) +        goto error; +    /* +     * An access has been granted, +     * retrieve file size first +     */ +    STACK_WIND(frame, do_ftruncate, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->fgetxattr, local->fd, +               FSIZE_XATTR_PREFIX, NULL); +    return 0; +error: +    get_one_call_nolock(frame); +    put_one_call_ftruncate(frame, this); +    return 0;  }  /* @@ -1699,1612 +1537,1316 @@ static int32_t crypt_ftruncate_finodelk_cbk(call_frame_t *frame,   * . receive file size;   * . expand or prune file.   */ -static int32_t crypt_ftruncate(call_frame_t *frame, -			       xlator_t *this, -			       fd_t *fd, -			       off_t offset, -			       dict_t *xdata) -{ -	int32_t ret; -	crypt_local_t *local; -	struct crypt_inode_info *info; -	struct gf_flock lock = {0, }; - -	local = crypt_alloc_local(frame, this, GF_FOP_FTRUNCATE); -	if (!local) { -		ret = ENOMEM; -		goto error; -	} -	local->xattr = dict_new(); -	if (!local->xattr) { -		ret = ENOMEM; -		goto error; -	} -	local->fd = fd_ref(fd); -	info = local_get_inode_info(local, this); -	if (info == NULL) { -		ret = EINVAL; -		goto error; -	} -	if (!object_alg_atomic(&info->cinfo)) { -		ret = EINVAL; -		goto error; -	} -	local->data_conf.orig_offset = offset; -	if (xdata) -		local->xdata = dict_ref(xdata); - -	lock.l_len    = 0; -        lock.l_start  = 0; -        lock.l_type   = F_WRLCK; -        lock.l_whence = SEEK_SET; +static int32_t +crypt_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, +                dict_t *xdata) +{ +    int32_t ret; +    crypt_local_t *local; +    struct crypt_inode_info *info; +    struct gf_flock lock = { +        0, +    }; + +    local = crypt_alloc_local(frame, this, GF_FOP_FTRUNCATE); +    if (!local) { +        ret = ENOMEM; +        goto error; +    } +    local->xattr = dict_new(); +    if (!local->xattr) { +        ret = ENOMEM; +        goto error; +    } +    local->fd = fd_ref(fd); +    info = local_get_inode_info(local, this); +    if (info == NULL) { +        ret = EINVAL; +        goto error; +    } +    if (!object_alg_atomic(&info->cinfo)) { +        ret = EINVAL; +        goto error; +    } +    local->data_conf.orig_offset = offset; +    if (xdata) +        local->xdata = dict_ref(xdata); + +    lock.l_len = 0; +    lock.l_start = 0; +    lock.l_type = F_WRLCK; +    lock.l_whence = SEEK_SET; + +    STACK_WIND(frame, crypt_ftruncate_finodelk_cbk, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->finodelk, this->name, fd, F_SETLKW, +               &lock, NULL); +    return 0; +error: +    if (local && local->fd) +        fd_unref(fd); +    if (local && local->xdata) +        dict_unref(xdata); +    if (local && local->xattr) +        dict_unref(local->xattr); +    if (local && local->info) +        free_inode_info(local->info); -	STACK_WIND(frame, -		   crypt_ftruncate_finodelk_cbk, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->finodelk, -		   this->name, -		   fd, -		   F_SETLKW, -		   &lock, -		   NULL); -	return 0; - error: -	if (local && local->fd) -		fd_unref(fd); -	if (local && local->xdata) -		dict_unref(xdata); -	if (local && local->xattr) -		dict_unref(local->xattr); -	if (local && local->info) -		free_inode_info(local->info); - -	CRYPT_STACK_UNWIND(ftruncate, frame, -1, ret, NULL, NULL, NULL); -	return 0; +    CRYPT_STACK_UNWIND(ftruncate, frame, -1, ret, NULL, NULL, NULL); +    return 0;  }  /* ->flush_cbk() */ -int32_t truncate_end(call_frame_t *frame, -		     void *cookie, -		     xlator_t *this, -		     int32_t op_ret, -		     int32_t op_errno, -		     dict_t *xdata) +int32_t +truncate_end(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, +             int32_t op_errno, dict_t *xdata)  { -	crypt_local_t *local = frame->local; +    crypt_local_t *local = frame->local; -	CRYPT_STACK_UNWIND(truncate, -			   frame, -			   op_ret, -			   op_errno, -			   &local->prebuf, -			   &local->postbuf, -			   local->xdata); -	return 0; +    CRYPT_STACK_UNWIND(truncate, frame, op_ret, op_errno, &local->prebuf, +                       &local->postbuf, local->xdata); +    return 0;  }  /* ftruncate_cbk() */ -int32_t truncate_flush(call_frame_t *frame, -		       void *cookie, -		       xlator_t *this, -		       int32_t op_ret, -		       int32_t op_errno, -		       struct iatt *prebuf, -		       struct iatt *postbuf, -		       dict_t *xdata) -{ -	crypt_local_t *local = frame->local; -	fd_t *fd = local->fd; -	local->prebuf = *prebuf; -	local->postbuf = *postbuf; - -	STACK_WIND(frame, -		   truncate_end, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->flush, -		   fd, -		   NULL); -	fd_unref(fd); -	return 0; +int32_t +truncate_flush(call_frame_t *frame, void *cookie, xlator_t *this, +               int32_t op_ret, int32_t op_errno, struct iatt *prebuf, +               struct iatt *postbuf, dict_t *xdata) +{ +    crypt_local_t *local = frame->local; +    fd_t *fd = local->fd; +    local->prebuf = *prebuf; +    local->postbuf = *postbuf; + +    STACK_WIND(frame, truncate_end, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->flush, fd, NULL); +    fd_unref(fd); +    return 0;  }  /*   * is called as ->open_cbk()   */ -static int32_t truncate_begin(call_frame_t *frame, -			      void *cookie, -			      xlator_t *this, -			      int32_t op_ret, -			      int32_t op_errno, -			      fd_t *fd, -			      dict_t *xdata) -{ -	crypt_local_t *local = frame->local; - -	if (op_ret < 0) { -		fd_unref(fd); -		CRYPT_STACK_UNWIND(truncate, -				   frame, -				   op_ret, -				   op_errno, NULL, NULL, NULL); -		return 0; -	} else { -	        fd_bind (fd); -        } -	/* -	 * crypt_truncate() is implemented via crypt_ftruncate(), -	 * so the crypt xlator does STACK_WIND to itself here -	 */ -	STACK_WIND(frame, -		   truncate_flush, -		   this, -		   this->fops->ftruncate, /* crypt_ftruncate */ -		   fd, -		   local->offset, -		   NULL); -	return 0; +static int32_t +truncate_begin(call_frame_t *frame, void *cookie, xlator_t *this, +               int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) +{ +    crypt_local_t *local = frame->local; + +    if (op_ret < 0) { +        fd_unref(fd); +        CRYPT_STACK_UNWIND(truncate, frame, op_ret, op_errno, NULL, NULL, NULL); +        return 0; +    } else { +        fd_bind(fd); +    } +    /* +     * crypt_truncate() is implemented via crypt_ftruncate(), +     * so the crypt xlator does STACK_WIND to itself here +     */ +    STACK_WIND(frame, truncate_flush, this, +               this->fops->ftruncate, /* crypt_ftruncate */ +               fd, local->offset, NULL); +    return 0;  }  /*   * crypt_truncate() is implemented via crypt_ftruncate() as a   * sequence crypt_open() - crypt_ftruncate() - truncate_flush()   */ -int32_t crypt_truncate(call_frame_t *frame, -		       xlator_t *this, -		       loc_t *loc, -		       off_t offset, -		       dict_t *xdata) +int32_t +crypt_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, +               dict_t *xdata)  { -	fd_t *fd; -	crypt_local_t *local; +    fd_t *fd; +    crypt_local_t *local;  #if DEBUG_CRYPT -	gf_log(this->name, GF_LOG_DEBUG, -	       "truncate file %s at offset %llu", -	       loc->path, (unsigned long long)offset); +    gf_log(this->name, GF_LOG_DEBUG, "truncate file %s at offset %llu", +           loc->path, (unsigned long long)offset);  #endif -	local = crypt_alloc_local(frame, this, GF_FOP_TRUNCATE); -	if (!local) -		goto error; - -	fd = fd_create(loc->inode, frame->root->pid); -	if (!fd) { -		gf_log(this->name, GF_LOG_ERROR, "Can not create fd"); -		goto error; -	} -	local->fd = fd; -	local->offset = offset; -	local->xdata = xdata; -	STACK_WIND(frame, -		   truncate_begin, -		   this, -		   this->fops->open, /* crypt_open() */ -		   loc, -		   O_RDWR, -		   fd, -		   NULL); -	return 0; - error: -	CRYPT_STACK_UNWIND(truncate, frame, -1, EINVAL, NULL, NULL, NULL); -	return 0; -} - -end_writeback_handler_t dispatch_end_writeback(glusterfs_fop_t fop) -{ -	switch (fop) { -	case GF_FOP_WRITE: -		return end_writeback_writev; -	case GF_FOP_FTRUNCATE: -		return end_writeback_ftruncate; -	default: -		gf_log("crypt", GF_LOG_WARNING, "Bad wb operation %d", fop); -		return NULL; -	} +    local = crypt_alloc_local(frame, this, GF_FOP_TRUNCATE); +    if (!local) +        goto error; + +    fd = fd_create(loc->inode, frame->root->pid); +    if (!fd) { +        gf_log(this->name, GF_LOG_ERROR, "Can not create fd"); +        goto error; +    } +    local->fd = fd; +    local->offset = offset; +    local->xdata = xdata; +    STACK_WIND(frame, truncate_begin, this, this->fops->open, /* crypt_open() */ +               loc, O_RDWR, fd, NULL); +    return 0; +error: +    CRYPT_STACK_UNWIND(truncate, frame, -1, EINVAL, NULL, NULL, NULL); +    return 0; +} + +end_writeback_handler_t +dispatch_end_writeback(glusterfs_fop_t fop) +{ +    switch (fop) { +        case GF_FOP_WRITE: +            return end_writeback_writev; +        case GF_FOP_FTRUNCATE: +            return end_writeback_ftruncate; +        default: +            gf_log("crypt", GF_LOG_WARNING, "Bad wb operation %d", fop); +            return NULL; +    }  }  /*   * true, if the caller needs metadata string   */ -static int32_t is_custom_mtd(dict_t *xdata) +static int32_t +is_custom_mtd(dict_t *xdata)  { -	data_t *data; -	uint32_t flags; +    data_t *data; +    uint32_t flags; -	if (!xdata) -		return 0; +    if (!xdata) +        return 0; -	data = dict_get(xdata, MSGFLAGS_PREFIX); -	if (!data) -		return 0; -	if (data->len != sizeof(uint32_t)) { -		gf_log("crypt", GF_LOG_WARNING, -		       "Bad msgflags size (%d)", data->len); -		return -1; -	} -	flags = *((uint32_t *)data->data); -	return msgflags_check_mtd_lock(&flags); +    data = dict_get(xdata, MSGFLAGS_PREFIX); +    if (!data) +        return 0; +    if (data->len != sizeof(uint32_t)) { +        gf_log("crypt", GF_LOG_WARNING, "Bad msgflags size (%d)", data->len); +        return -1; +    } +    flags = *((uint32_t *)data->data); +    return msgflags_check_mtd_lock(&flags);  } -static int32_t crypt_open_done(call_frame_t *frame, -			       void *cookie, -			       xlator_t *this, -			       int32_t op_ret, -			       int32_t op_errno, dict_t *xdata) +static int32_t +crypt_open_done(call_frame_t *frame, void *cookie, xlator_t *this, +                int32_t op_ret, int32_t op_errno, dict_t *xdata)  { -	crypt_local_t *local = frame->local; +    crypt_local_t *local = frame->local; -	local->op_ret = op_ret; -	local->op_errno = op_errno; -	if (op_ret < 0) -		gf_log(this->name, GF_LOG_WARNING, "mtd unlock failed (%d)", -		       op_errno); -	put_one_call_open(frame); -	return 0; +    local->op_ret = op_ret; +    local->op_errno = op_errno; +    if (op_ret < 0) +        gf_log(this->name, GF_LOG_WARNING, "mtd unlock failed (%d)", op_errno); +    put_one_call_open(frame); +    return 0;  } -static void crypt_open_tail(call_frame_t *frame, xlator_t *this) +static void +crypt_open_tail(call_frame_t *frame, xlator_t *this)  { -	struct gf_flock  lock  = {0, }; -	crypt_local_t *local = frame->local; +    struct gf_flock lock = { +        0, +    }; +    crypt_local_t *local = frame->local; -        lock.l_type   = F_UNLCK; -        lock.l_whence = SEEK_SET; -        lock.l_start  = 0; -        lock.l_len    = 0; -        lock.l_pid    = 0; +    lock.l_type = F_UNLCK; +    lock.l_whence = SEEK_SET; +    lock.l_start = 0; +    lock.l_len = 0; +    lock.l_pid = 0; -	STACK_WIND(frame, -		   crypt_open_done, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->finodelk, -		   this->name, -		   local->fd, -		   F_SETLKW, -		   &lock, -		   NULL); +    STACK_WIND(frame, crypt_open_done, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->finodelk, this->name, local->fd, +               F_SETLKW, &lock, NULL);  }  /*   * load private inode info at open time   * called as ->fgetxattr_cbk()   */ -static int load_mtd_open(call_frame_t *frame, -			 void *cookie, -			 xlator_t *this, -			 int32_t op_ret, -			 int32_t op_errno, -			 dict_t *dict, -			 dict_t *xdata) -{ -	int32_t ret; -	gf_boolean_t upload_info; -	data_t *mtd; -	uint64_t value = 0; -	struct crypt_inode_info *info; -	crypt_local_t *local = frame->local; -	crypt_private_t *priv = this->private; - -	local->op_ret = op_ret; -	local->op_errno = op_errno; - -	if (local->fd->inode->ia_type == IA_IFLNK) -		goto exit; -	if (op_ret < 0) -		goto exit; -	/* -	 * first, check for cached info -	 */ -	ret = inode_ctx_get(local->fd->inode, this, &value); -	if (ret != -1) { -		info = (struct crypt_inode_info *)(long)value; -		if (info == NULL) { -			gf_log(this->name, GF_LOG_WARNING, -			       "Inode info expected, but not found"); -			local->op_ret = -1; -			local->op_errno = EIO; -			goto exit; -		} -		/* -		 * info has been found in the cache -		 */ -		upload_info = _gf_false; -	} -	else { -		/* -		 * info hasn't been found in the cache. -		 */ -		info = alloc_inode_info(local, local->loc); -		if (!info) { -			local->op_ret = -1; -			local->op_errno = ENOMEM; -			goto exit; -		} -		init_inode_info_head(info, local->fd); -		upload_info = _gf_true; -	} -	/* -	 * extract metadata -	 */ -	mtd = dict_get(dict, CRYPTO_FORMAT_PREFIX); -	if (!mtd) { -		local->op_ret = -1; -		local->op_errno = ENOENT; -		gf_log (this->name, GF_LOG_WARNING, -			"Format string wasn't found"); -		goto exit; -	} -	/* -	 * authenticate metadata against the path -	 */ -	ret = open_format((unsigned char *)mtd->data, -			  mtd->len, -			  local->loc, -			  info, -			  get_master_cinfo(priv), -			  local, -			  upload_info); -	if (ret) { -		local->op_ret = -1; -		local->op_errno = ret; -		goto exit; -	} -	if (upload_info) { -		ret = init_inode_info_tail(info, get_master_cinfo(priv)); -		if (ret) { -			local->op_ret = -1; -			local->op_errno = ret; -			goto exit; -		} -		ret = inode_ctx_put(local->fd->inode, -				    this, (uint64_t)(long)info); -		if (ret == -1) { -			local->op_ret = -1; -			local->op_errno = EIO; -			goto exit; -		} -	} -	if (local->custom_mtd) { -		/* -		 * pass the metadata string to the customer -		 */ -		ret = dict_set_static_bin(local->xdata, -					  CRYPTO_FORMAT_PREFIX, -					  mtd->data, -					  mtd->len); -		if (ret) { -			local->op_ret = -1; -			local->op_errno = ret; -			goto exit; -		} -	} - exit: -	if (!local->custom_mtd) -		crypt_open_tail(frame, this); -	else -		put_one_call_open(frame); -	return 0; -} - -static int32_t crypt_open_finodelk_cbk(call_frame_t *frame, -				       void *cookie, -				       xlator_t *this, -				       int32_t op_ret, -				       int32_t op_errno, -				       dict_t *xdata) -{ -	crypt_local_t *local = frame->local; - -	local->op_ret = op_ret; -	local->op_errno = op_errno; - -	if (op_ret < 0) { -		gf_log(this->name, GF_LOG_WARNING, "finodelk (LOCK) failed"); -		goto exit; -	} -	STACK_WIND(frame, -		   load_mtd_open, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->fgetxattr, -		   local->fd, -		   CRYPTO_FORMAT_PREFIX, -		   NULL); -	return 0; - exit: -	put_one_call_open(frame); -	return 0; +static int +load_mtd_open(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, +              int32_t op_errno, dict_t *dict, dict_t *xdata) +{ +    int32_t ret; +    gf_boolean_t upload_info; +    data_t *mtd; +    uint64_t value = 0; +    struct crypt_inode_info *info; +    crypt_local_t *local = frame->local; +    crypt_private_t *priv = this->private; + +    local->op_ret = op_ret; +    local->op_errno = op_errno; + +    if (local->fd->inode->ia_type == IA_IFLNK) +        goto exit; +    if (op_ret < 0) +        goto exit; +    /* +     * first, check for cached info +     */ +    ret = inode_ctx_get(local->fd->inode, this, &value); +    if (ret != -1) { +        info = (struct crypt_inode_info *)(long)value; +        if (info == NULL) { +            gf_log(this->name, GF_LOG_WARNING, +                   "Inode info expected, but not found"); +            local->op_ret = -1; +            local->op_errno = EIO; +            goto exit; +        } +        /* +         * info has been found in the cache +         */ +        upload_info = _gf_false; +    } else { +        /* +         * info hasn't been found in the cache. +         */ +        info = alloc_inode_info(local, local->loc); +        if (!info) { +            local->op_ret = -1; +            local->op_errno = ENOMEM; +            goto exit; +        } +        init_inode_info_head(info, local->fd); +        upload_info = _gf_true; +    } +    /* +     * extract metadata +     */ +    mtd = dict_get(dict, CRYPTO_FORMAT_PREFIX); +    if (!mtd) { +        local->op_ret = -1; +        local->op_errno = ENOENT; +        gf_log(this->name, GF_LOG_WARNING, "Format string wasn't found"); +        goto exit; +    } +    /* +     * authenticate metadata against the path +     */ +    ret = open_format((unsigned char *)mtd->data, mtd->len, local->loc, info, +                      get_master_cinfo(priv), local, upload_info); +    if (ret) { +        local->op_ret = -1; +        local->op_errno = ret; +        goto exit; +    } +    if (upload_info) { +        ret = init_inode_info_tail(info, get_master_cinfo(priv)); +        if (ret) { +            local->op_ret = -1; +            local->op_errno = ret; +            goto exit; +        } +        ret = inode_ctx_put(local->fd->inode, this, (uint64_t)(long)info); +        if (ret == -1) { +            local->op_ret = -1; +            local->op_errno = EIO; +            goto exit; +        } +    } +    if (local->custom_mtd) { +        /* +         * pass the metadata string to the customer +         */ +        ret = dict_set_static_bin(local->xdata, CRYPTO_FORMAT_PREFIX, mtd->data, +                                  mtd->len); +        if (ret) { +            local->op_ret = -1; +            local->op_errno = ret; +            goto exit; +        } +    } +exit: +    if (!local->custom_mtd) +        crypt_open_tail(frame, this); +    else +        put_one_call_open(frame); +    return 0; +} + +static int32_t +crypt_open_finodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                        int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ +    crypt_local_t *local = frame->local; + +    local->op_ret = op_ret; +    local->op_errno = op_errno; + +    if (op_ret < 0) { +        gf_log(this->name, GF_LOG_WARNING, "finodelk (LOCK) failed"); +        goto exit; +    } +    STACK_WIND(frame, load_mtd_open, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->fgetxattr, local->fd, +               CRYPTO_FORMAT_PREFIX, NULL); +    return 0; +exit: +    put_one_call_open(frame); +    return 0;  }  /*   * verify metadata against the specified pathname   */ -static int32_t crypt_open_cbk(call_frame_t *frame, -			      void *cookie, -			      xlator_t *this, -			      int32_t op_ret, -			      int32_t op_errno, -			      fd_t *fd, -			      dict_t *xdata) -{ -	struct gf_flock lock = {0, }; -	crypt_local_t *local = frame->local; - -	local->op_ret = op_ret; -	local->op_errno = op_errno; - -	if (local->fd->inode->ia_type == IA_IFLNK) -		goto exit; -	if (op_ret < 0) -		goto exit; -	if (xdata) -		local->xdata = dict_ref(xdata); -	else if (local->custom_mtd){ -		local->xdata = dict_new(); -		if (!local->xdata) { -			local->op_ret = -1; -			local->op_errno = ENOMEM; -			gf_log ("crypt", GF_LOG_ERROR, -				"Can not get new dict for mtd string"); -			goto exit; -		} -	} -	lock.l_len    = 0; -        lock.l_start  = 0; -        lock.l_type   = local->custom_mtd ? F_WRLCK : F_RDLCK; -        lock.l_whence = SEEK_SET; +static int32_t +crypt_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +               int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) +{ +    struct gf_flock lock = { +        0, +    }; +    crypt_local_t *local = frame->local; + +    local->op_ret = op_ret; +    local->op_errno = op_errno; + +    if (local->fd->inode->ia_type == IA_IFLNK) +        goto exit; +    if (op_ret < 0) +        goto exit; +    if (xdata) +        local->xdata = dict_ref(xdata); +    else if (local->custom_mtd) { +        local->xdata = dict_new(); +        if (!local->xdata) { +            local->op_ret = -1; +            local->op_errno = ENOMEM; +            gf_log("crypt", GF_LOG_ERROR, +                   "Can not get new dict for mtd string"); +            goto exit; +        } +    } +    lock.l_len = 0; +    lock.l_start = 0; +    lock.l_type = local->custom_mtd ? F_WRLCK : F_RDLCK; +    lock.l_whence = SEEK_SET; + +    STACK_WIND(frame, crypt_open_finodelk_cbk, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->finodelk, this->name, fd, F_SETLKW, +               &lock, NULL); +    return 0; +exit: +    put_one_call_open(frame); +    return 0; +} + +static int32_t +crypt_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, +           fd_t *fd, dict_t *xdata) +{ +    int32_t ret = ENOMEM; +    crypt_local_t *local; + +    local = crypt_alloc_local(frame, this, GF_FOP_OPEN); +    if (!local) +        goto error; +    local->loc = GF_CALLOC(1, sizeof(loc_t), gf_crypt_mt_loc); +    if (!local->loc) { +        ret = ENOMEM; +        goto error; +    } +    ret = loc_copy(local->loc, loc); +    if (ret) { +        GF_FREE(local->loc); +        ret = ENOMEM; +        goto error; +    } +    local->fd = fd_ref(fd); + +    ret = is_custom_mtd(xdata); +    if (ret < 0) { +        loc_wipe(local->loc); +        GF_FREE(local->loc); +        ret = EINVAL; +        goto error; +    } +    local->custom_mtd = ret; + +    if ((flags & O_ACCMODE) == O_WRONLY) +        /* +         * we can't open O_WRONLY, because +         * we need to do read-modify-write +         */ +        flags = (flags & ~O_ACCMODE) | O_RDWR; +    /* +     * Make sure that out translated offsets +     * and counts won't be ignored +     */ +    flags &= ~O_APPEND; +    get_one_call_nolock(frame); +    STACK_WIND(frame, crypt_open_cbk, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->open, loc, flags, fd, xdata); +    return 0; +error: +    CRYPT_STACK_UNWIND(open, frame, -1, ret, NULL, NULL); +    return 0; +} -	STACK_WIND(frame, -		   crypt_open_finodelk_cbk, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->finodelk, -		   this->name, -		   fd, -		   F_SETLKW, -		   &lock, -		   NULL); -	return 0; - exit: -	put_one_call_open(frame); -	return 0; -} - -static int32_t crypt_open(call_frame_t *frame, -			  xlator_t *this, -			  loc_t *loc, -			  int32_t flags, -			  fd_t *fd, -			  dict_t *xdata) -{ -	int32_t ret = ENOMEM; -	crypt_local_t *local; - -	local = crypt_alloc_local(frame, this, GF_FOP_OPEN); -	if (!local) -		goto error; -	local->loc = GF_CALLOC(1, sizeof(loc_t), gf_crypt_mt_loc); -	if (!local->loc) { -		ret = ENOMEM; -		goto error; -	} -	ret = loc_copy(local->loc, loc); -	if (ret) { -		GF_FREE(local->loc); -                ret = ENOMEM; -		goto error; -	} -	local->fd = fd_ref(fd); - -	ret = is_custom_mtd(xdata); -	if (ret < 0) { -		loc_wipe(local->loc); -		GF_FREE(local->loc); -		ret = EINVAL; -		goto error; -	} -	local->custom_mtd = ret; - -	if ((flags & O_ACCMODE) == O_WRONLY) -		/* -		 * we can't open O_WRONLY, because -		 * we need to do read-modify-write -		 */ -		flags = (flags & ~O_ACCMODE) | O_RDWR; -	/* -	 * Make sure that out translated offsets -	 * and counts won't be ignored -	 */ -	flags &= ~O_APPEND; -	get_one_call_nolock(frame); -	STACK_WIND(frame, -		   crypt_open_cbk, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->open, -		   loc, -		   flags, -		   fd, -		   xdata); -	return 0; - error: -	CRYPT_STACK_UNWIND(open, -			   frame, -			   -1, -			   ret, -			   NULL, -			   NULL); -	return 0; -} - -static int32_t init_inode_info_tail(struct crypt_inode_info *info, -				    struct master_cipher_info *master) -{ -	int32_t ret; -	struct object_cipher_info *object = &info->cinfo; +static int32_t +init_inode_info_tail(struct crypt_inode_info *info, +                     struct master_cipher_info *master) +{ +    int32_t ret; +    struct object_cipher_info *object = &info->cinfo;  #if DEBUG_CRYPT -	gf_log("crypt", GF_LOG_DEBUG, "Init inode info for object %s", -	       uuid_utoa(info->oid)); +    gf_log("crypt", GF_LOG_DEBUG, "Init inode info for object %s", +           uuid_utoa(info->oid));  #endif -	ret = data_cipher_algs[object->o_alg][object->o_mode].set_private(info, -									master); -	if (ret) { -		gf_log("crypt", GF_LOG_ERROR, "Set private info failed"); -		return ret; -	} -	return 0; +    ret = data_cipher_algs[object->o_alg][object->o_mode].set_private(info, +                                                                      master); +    if (ret) { +        gf_log("crypt", GF_LOG_ERROR, "Set private info failed"); +        return ret; +    } +    return 0;  }  /*   * Init inode info at ->create() time   */ -static void init_inode_info_create(struct crypt_inode_info *info, -				   struct master_cipher_info *master, -				   data_t *data) -{ -	struct object_cipher_info *object; - -	info->nr_minor = CRYPT_XLATOR_ID; -	memcpy(info->oid, data->data, data->len); - -	object = &info->cinfo; - -	object->o_alg        = master->m_alg; -	object->o_mode       = master->m_mode; -	object->o_block_bits = master->m_block_bits; -	object->o_dkey_size  = master->m_dkey_size; -} - -static void init_inode_info_head(struct crypt_inode_info *info, fd_t *fd) -{ -	memcpy(info->oid, fd->inode->gfid, sizeof(uuid_t)); -} - -static int32_t crypt_create_done(call_frame_t *frame, -				 void *cookie, -				 xlator_t *this, -				 int32_t op_ret, -				 int32_t op_errno, dict_t *xdata) -{ -	crypt_private_t *priv = this->private; -	crypt_local_t *local = frame->local; -	struct crypt_inode_info *info = local->info; -	fd_t *local_fd = local->fd; -	dict_t *local_xdata = local->xdata; -	inode_t *local_inode = local->inode; - -	if (op_ret < 0) { -		free_inode_info(info); -		goto unwind; -	} -	op_errno = init_inode_info_tail(info, get_master_cinfo(priv)); -	if (op_errno) { -		op_ret = -1; -		free_inode_info(info); -		goto unwind; -	} -	/* -	 * FIXME: drop major subversion number -	 */ -	op_ret = inode_ctx_put(local->fd->inode, this, (uint64_t)(long)info); -	if (op_ret == -1) { -		op_errno = EIO; -		free_inode_info(info); -		goto unwind; -	} - unwind: -	free_format(local); -	CRYPT_STACK_UNWIND(create, -			   frame, -			   op_ret, -			   op_errno, -			   local_fd, -			   local_inode, -			   &local->buf, -			   &local->prebuf, -			   &local->postbuf, -			   local_xdata); -	fd_unref(local_fd); -	inode_unref(local_inode); -	if (local_xdata) -		dict_unref(local_xdata); -	return 0; -} - -static int crypt_create_tail(call_frame_t *frame, -			     void *cookie, -			     xlator_t *this, -			     int32_t op_ret, -			     int32_t op_errno, -			     dict_t *xdata) -{ -	struct gf_flock  lock  = {0, }; -	crypt_local_t *local = frame->local; -	fd_t *local_fd = local->fd; -	dict_t *local_xdata = local->xdata; -	inode_t *local_inode = local->inode; - -	dict_unref(local->xattr); - -	if (op_ret < 0) -		goto error; - -        lock.l_type   = F_UNLCK; -        lock.l_whence = SEEK_SET; -        lock.l_start  = 0; -        lock.l_len    = 0; -        lock.l_pid    = 0; - -	STACK_WIND(frame, -		   crypt_create_done, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->finodelk, -		   this->name, -		   local->fd, -		   F_SETLKW, -		   &lock, -		   NULL); -	return 0; - error: -	free_inode_info(local->info); -	free_format(local); - -	CRYPT_STACK_UNWIND(create, -			   frame, -			   op_ret, -			   op_errno, -			   local_fd, -			   local_inode, -			   &local->buf, -			   &local->prebuf, -			   &local->postbuf, -			   local_xdata); - -	fd_unref(local_fd); -	inode_unref(local_inode); -	if (local_xdata) -		dict_unref(local_xdata); -	return 0; -} - -static int32_t crypt_create_finodelk_cbk(call_frame_t *frame, -					 void *cookie, -					 xlator_t *this, -					 int32_t op_ret, -					 int32_t op_errno, -					 dict_t *xdata) -{ -	crypt_local_t *local = frame->local; -	struct crypt_inode_info *info = local->info; - -	if (op_ret < 0) -		goto error; - -	STACK_WIND(frame, -		   crypt_create_tail, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->fsetxattr, -		   local->fd, -		   local->xattr, /* CRYPTO_FORMAT_PREFIX */ -		   0, -		   NULL); -	return 0; - error: -	free_inode_info(info); -	free_format(local); -	fd_unref(local->fd); -	dict_unref(local->xattr); -	if (local->xdata) -		dict_unref(local->xdata); - -	CRYPT_STACK_UNWIND(create, -			   frame, -			   op_ret, -			   op_errno, -			   NULL, -			   NULL, -			   NULL, -			   NULL, -			   NULL, -			   NULL); -	return 0; +static void +init_inode_info_create(struct crypt_inode_info *info, +                       struct master_cipher_info *master, data_t *data) +{ +    struct object_cipher_info *object; + +    info->nr_minor = CRYPT_XLATOR_ID; +    memcpy(info->oid, data->data, data->len); + +    object = &info->cinfo; + +    object->o_alg = master->m_alg; +    object->o_mode = master->m_mode; +    object->o_block_bits = master->m_block_bits; +    object->o_dkey_size = master->m_dkey_size; +} + +static void +init_inode_info_head(struct crypt_inode_info *info, fd_t *fd) +{ +    memcpy(info->oid, fd->inode->gfid, sizeof(uuid_t)); +} + +static int32_t +crypt_create_done(call_frame_t *frame, void *cookie, xlator_t *this, +                  int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ +    crypt_private_t *priv = this->private; +    crypt_local_t *local = frame->local; +    struct crypt_inode_info *info = local->info; +    fd_t *local_fd = local->fd; +    dict_t *local_xdata = local->xdata; +    inode_t *local_inode = local->inode; + +    if (op_ret < 0) { +        free_inode_info(info); +        goto unwind; +    } +    op_errno = init_inode_info_tail(info, get_master_cinfo(priv)); +    if (op_errno) { +        op_ret = -1; +        free_inode_info(info); +        goto unwind; +    } +    /* +     * FIXME: drop major subversion number +     */ +    op_ret = inode_ctx_put(local->fd->inode, this, (uint64_t)(long)info); +    if (op_ret == -1) { +        op_errno = EIO; +        free_inode_info(info); +        goto unwind; +    } +unwind: +    free_format(local); +    CRYPT_STACK_UNWIND(create, frame, op_ret, op_errno, local_fd, local_inode, +                       &local->buf, &local->prebuf, &local->postbuf, +                       local_xdata); +    fd_unref(local_fd); +    inode_unref(local_inode); +    if (local_xdata) +        dict_unref(local_xdata); +    return 0; +} + +static int +crypt_create_tail(call_frame_t *frame, void *cookie, xlator_t *this, +                  int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ +    struct gf_flock lock = { +        0, +    }; +    crypt_local_t *local = frame->local; +    fd_t *local_fd = local->fd; +    dict_t *local_xdata = local->xdata; +    inode_t *local_inode = local->inode; + +    dict_unref(local->xattr); + +    if (op_ret < 0) +        goto error; + +    lock.l_type = F_UNLCK; +    lock.l_whence = SEEK_SET; +    lock.l_start = 0; +    lock.l_len = 0; +    lock.l_pid = 0; + +    STACK_WIND(frame, crypt_create_done, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->finodelk, this->name, local->fd, +               F_SETLKW, &lock, NULL); +    return 0; +error: +    free_inode_info(local->info); +    free_format(local); + +    CRYPT_STACK_UNWIND(create, frame, op_ret, op_errno, local_fd, local_inode, +                       &local->buf, &local->prebuf, &local->postbuf, +                       local_xdata); + +    fd_unref(local_fd); +    inode_unref(local_inode); +    if (local_xdata) +        dict_unref(local_xdata); +    return 0; +} + +static int32_t +crypt_create_finodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                          int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ +    crypt_local_t *local = frame->local; +    struct crypt_inode_info *info = local->info; + +    if (op_ret < 0) +        goto error; + +    STACK_WIND(frame, crypt_create_tail, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->fsetxattr, local->fd, +               local->xattr, /* CRYPTO_FORMAT_PREFIX */ +               0, NULL); +    return 0; +error: +    free_inode_info(info); +    free_format(local); +    fd_unref(local->fd); +    dict_unref(local->xattr); +    if (local->xdata) +        dict_unref(local->xdata); + +    CRYPT_STACK_UNWIND(create, frame, op_ret, op_errno, NULL, NULL, NULL, NULL, +                       NULL, NULL); +    return 0;  }  /*   * Create and store crypt-specific format on disk;   * Populate cache with private inode info   */ -static int32_t crypt_create_cbk(call_frame_t *frame, -				void *cookie, -				xlator_t *this, -				int32_t op_ret, -				int32_t op_errno, -				fd_t *fd, -				inode_t *inode, -				struct iatt *buf, -				struct iatt *preparent, -				struct iatt *postparent, -				dict_t *xdata) -{ -	struct gf_flock lock = {0, }; -	crypt_local_t *local = frame->local; -	struct crypt_inode_info *info = local->info; - -	if (op_ret < 0) -		goto error; -	if (xdata) -		local->xdata = dict_ref(xdata); -	local->inode = inode_ref(inode); -	local->buf = *buf; -	local->prebuf = *preparent; -	local->postbuf = *postparent; - -        lock.l_len    = 0; -        lock.l_start  = 0; -        lock.l_type   = F_WRLCK; -        lock.l_whence = SEEK_SET; - -        STACK_WIND(frame, -		   crypt_create_finodelk_cbk, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->finodelk, -		   this->name, -		   local->fd, -		   F_SETLKW, -		   &lock, -		   NULL); -	return 0; - error: -	free_inode_info(info); -	free_format(local); -	fd_unref(local->fd); -	dict_unref(local->xattr); - -	CRYPT_STACK_UNWIND(create, -			   frame, -			   op_ret, -			   op_errno, -			   NULL, NULL, NULL, -			   NULL, NULL, NULL); -	return 0; -} - -static int32_t crypt_create(call_frame_t *frame, -			    xlator_t *this, -			    loc_t *loc, -			    int32_t flags, -			    mode_t mode, -			    mode_t umask, -			    fd_t *fd, -			    dict_t *xdata) -{ -	int ret; -	data_t *data; -	crypt_local_t *local; -	crypt_private_t *priv; -	struct master_cipher_info *master; -	struct crypt_inode_info *info; - -	priv = this->private; -	master = get_master_cinfo(priv); - -	if (master_alg_atomic(master)) { -		/* -		 * We can't open O_WRONLY, because we -		 * need to do read-modify-write. -		 */ -		if ((flags & O_ACCMODE) == O_WRONLY) -			flags = (flags & ~O_ACCMODE) | O_RDWR; -		/* -		 * Make sure that out translated offsets -		 * and counts won't be ignored -		 */ -		flags &= ~O_APPEND; -	} -	local = crypt_alloc_local(frame, this, GF_FOP_CREATE); -	if (!local) { -		ret = ENOMEM; -		goto error; -	} -	data = dict_get(xdata, "gfid-req"); -	if (!data) { -		ret = EINVAL; -		gf_log("crypt", GF_LOG_WARNING, "gfid not found"); -		goto error; -	} -	if (data->len != sizeof(uuid_t)) { -		ret = EINVAL; -		gf_log("crypt", GF_LOG_WARNING, -		       "bad gfid size (%d), should be %d", -		       (int)data->len, (int)sizeof(uuid_t)); -		goto error; -	} -	info = alloc_inode_info(local, loc); -	if (!info){ -		ret = ENOMEM; -		goto error; -	} -	/* -	 * NOTE: -	 * format has to be created BEFORE -	 * proceeding to the untrusted server -	 */ -	ret = alloc_format_create(local); -	if (ret) { -		free_inode_info(info); -		goto error; -	} -	init_inode_info_create(info, master, data); - -	ret = create_format(local->format, -			    loc, -			    info, -			    master); -	if (ret) { -		free_inode_info(info); -		goto error; -	} -	local->xattr = dict_new(); -	if (!local->xattr) { -		free_inode_info(info); -		free_format(local); -		goto error; -	} -	ret = dict_set_static_bin(local->xattr, -				  CRYPTO_FORMAT_PREFIX, -				  local->format, -				  new_format_size()); -	if (ret) { -		dict_unref(local->xattr); -		free_inode_info(info); -		free_format(local); -                ret = EINVAL; -		goto error; -	} -	ret = dict_set(local->xattr, FSIZE_XATTR_PREFIX, data_from_uint64(0)); -	if (ret) { -		dict_unref(local->xattr); -		free_inode_info(info); -		free_format(local); -                ret = ENOMEM; -		goto error; -	} -	local->fd = fd_ref(fd); - -	STACK_WIND(frame, -		   crypt_create_cbk, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->create, -		   loc, -		   flags, -		   mode, -		   umask, -		   fd, -		   xdata); -	return 0; - error: -	gf_log("crypt", GF_LOG_WARNING, "can not create file"); -	CRYPT_STACK_UNWIND(create, -			   frame, -			   -1, -			   ret, -			   NULL, NULL, NULL, -			   NULL, NULL, NULL); -	return 0; +static int32_t +crypt_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                 int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode, +                 struct iatt *buf, struct iatt *preparent, +                 struct iatt *postparent, dict_t *xdata) +{ +    struct gf_flock lock = { +        0, +    }; +    crypt_local_t *local = frame->local; +    struct crypt_inode_info *info = local->info; + +    if (op_ret < 0) +        goto error; +    if (xdata) +        local->xdata = dict_ref(xdata); +    local->inode = inode_ref(inode); +    local->buf = *buf; +    local->prebuf = *preparent; +    local->postbuf = *postparent; + +    lock.l_len = 0; +    lock.l_start = 0; +    lock.l_type = F_WRLCK; +    lock.l_whence = SEEK_SET; + +    STACK_WIND(frame, crypt_create_finodelk_cbk, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->finodelk, this->name, local->fd, +               F_SETLKW, &lock, NULL); +    return 0; +error: +    free_inode_info(info); +    free_format(local); +    fd_unref(local->fd); +    dict_unref(local->xattr); + +    CRYPT_STACK_UNWIND(create, frame, op_ret, op_errno, NULL, NULL, NULL, NULL, +                       NULL, NULL); +    return 0; +} + +static int32_t +crypt_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, +             mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) +{ +    int ret; +    data_t *data; +    crypt_local_t *local; +    crypt_private_t *priv; +    struct master_cipher_info *master; +    struct crypt_inode_info *info; + +    priv = this->private; +    master = get_master_cinfo(priv); + +    if (master_alg_atomic(master)) { +        /* +         * We can't open O_WRONLY, because we +         * need to do read-modify-write. +         */ +        if ((flags & O_ACCMODE) == O_WRONLY) +            flags = (flags & ~O_ACCMODE) | O_RDWR; +        /* +         * Make sure that out translated offsets +         * and counts won't be ignored +         */ +        flags &= ~O_APPEND; +    } +    local = crypt_alloc_local(frame, this, GF_FOP_CREATE); +    if (!local) { +        ret = ENOMEM; +        goto error; +    } +    data = dict_get(xdata, "gfid-req"); +    if (!data) { +        ret = EINVAL; +        gf_log("crypt", GF_LOG_WARNING, "gfid not found"); +        goto error; +    } +    if (data->len != sizeof(uuid_t)) { +        ret = EINVAL; +        gf_log("crypt", GF_LOG_WARNING, "bad gfid size (%d), should be %d", +               (int)data->len, (int)sizeof(uuid_t)); +        goto error; +    } +    info = alloc_inode_info(local, loc); +    if (!info) { +        ret = ENOMEM; +        goto error; +    } +    /* +     * NOTE: +     * format has to be created BEFORE +     * proceeding to the untrusted server +     */ +    ret = alloc_format_create(local); +    if (ret) { +        free_inode_info(info); +        goto error; +    } +    init_inode_info_create(info, master, data); + +    ret = create_format(local->format, loc, info, master); +    if (ret) { +        free_inode_info(info); +        goto error; +    } +    local->xattr = dict_new(); +    if (!local->xattr) { +        free_inode_info(info); +        free_format(local); +        goto error; +    } +    ret = dict_set_static_bin(local->xattr, CRYPTO_FORMAT_PREFIX, local->format, +                              new_format_size()); +    if (ret) { +        dict_unref(local->xattr); +        free_inode_info(info); +        free_format(local); +        ret = EINVAL; +        goto error; +    } +    ret = dict_set(local->xattr, FSIZE_XATTR_PREFIX, data_from_uint64(0)); +    if (ret) { +        dict_unref(local->xattr); +        free_inode_info(info); +        free_format(local); +        ret = ENOMEM; +        goto error; +    } +    local->fd = fd_ref(fd); + +    STACK_WIND(frame, crypt_create_cbk, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->create, loc, flags, mode, umask, fd, +               xdata); +    return 0; +error: +    gf_log("crypt", GF_LOG_WARNING, "can not create file"); +    CRYPT_STACK_UNWIND(create, frame, -1, ret, NULL, NULL, NULL, NULL, NULL, +                       NULL); +    return 0;  }  /*   * FIXME: this should depends on the version of format string   */ -static int32_t filter_crypt_xattr(dict_t *dict, -				  char *key, data_t *value, void *data) +static int32_t +filter_crypt_xattr(dict_t *dict, char *key, data_t *value, void *data)  { -        dict_del(dict, key); -        return 0; +    dict_del(dict, key); +    return 0;  } -static int32_t crypt_fsetxattr(call_frame_t *frame, -			       xlator_t *this, -			       fd_t *fd, -			       dict_t *dict, -			       int32_t flags, dict_t *xdata) +static int32_t +crypt_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, +                int32_t flags, dict_t *xdata)  { -	dict_foreach_fnmatch(dict, "trusted.glusterfs.crypt*", -			     filter_crypt_xattr, NULL); -	STACK_WIND(frame, -		   default_fsetxattr_cbk, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->fsetxattr, -		   fd, -		   dict, -		   flags, -		   xdata); -	return 0; +    dict_foreach_fnmatch(dict, "trusted.glusterfs.crypt*", filter_crypt_xattr, +                         NULL); +    STACK_WIND(frame, default_fsetxattr_cbk, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); +    return 0;  }  /*   * TBD: verify file metadata before wind   */ -static int32_t crypt_setxattr(call_frame_t *frame, -			      xlator_t *this, -			      loc_t *loc, -			      dict_t *dict, -			      int32_t flags, dict_t *xdata) -{ -	dict_foreach_fnmatch(dict, "trusted.glusterfs.crypt*", -			     filter_crypt_xattr, NULL); -	STACK_WIND(frame, -		   default_setxattr_cbk, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->setxattr, -		   loc, -		   dict, -		   flags, -		   xdata); -	return 0; +static int32_t +crypt_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, +               int32_t flags, dict_t *xdata) +{ +    dict_foreach_fnmatch(dict, "trusted.glusterfs.crypt*", filter_crypt_xattr, +                         NULL); +    STACK_WIND(frame, default_setxattr_cbk, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata); +    return 0;  }  /*   * called as flush_cbk()   */ -static int32_t linkop_end(call_frame_t *frame, -			  void *cookie, -			  xlator_t *this, -			  int32_t op_ret, -			  int32_t op_errno, -			  dict_t *xdata) -{ -	crypt_local_t *local = frame->local; -	linkop_unwind_handler_t unwind_fn; -	unwind_fn = linkop_unwind_dispatch(local->fop); - -	local->op_ret = op_ret; -	local->op_errno = op_errno; - -	if (op_ret < 0 && -	    op_errno == ENOENT && -	    local->loc->inode->ia_type == IA_IFLNK) { -		local->op_ret = 0; -		local->op_errno = 0; -	} -	unwind_fn(frame); -	return 0; +static int32_t +linkop_end(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, +           int32_t op_errno, dict_t *xdata) +{ +    crypt_local_t *local = frame->local; +    linkop_unwind_handler_t unwind_fn; +    unwind_fn = linkop_unwind_dispatch(local->fop); + +    local->op_ret = op_ret; +    local->op_errno = op_errno; + +    if (op_ret < 0 && op_errno == ENOENT && +        local->loc->inode->ia_type == IA_IFLNK) { +        local->op_ret = 0; +        local->op_errno = 0; +    } +    unwind_fn(frame); +    return 0;  }  /*   * unpin inode on the server   */ -static int32_t link_flush(call_frame_t *frame, -			  void *cookie, -			  xlator_t *this, -			  int32_t op_ret, -			  int32_t op_errno, -			  inode_t *inode, -			  struct iatt *buf, -			  struct iatt *preparent, -			  struct iatt *postparent, dict_t *xdata) -{ -	crypt_local_t *local = frame->local; - -	if (op_ret < 0) -		goto error; -	if (local->xdata) { -		dict_unref(local->xdata); -		local->xdata = NULL; -	} -	if (xdata) -		local->xdata = dict_ref(xdata); -	local->inode = inode_ref(inode); -	local->buf = *buf; -	local->prebuf = *preparent; -	local->postbuf = *postparent; - -	STACK_WIND(frame, -		   linkop_end, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->flush, -		   local->fd, -		   NULL); -	return 0; - error: -	local->op_ret = -1; -	local->op_errno = op_errno; -	link_unwind(frame); -	return 0; -} - -void link_unwind(call_frame_t *frame) -{ -	crypt_local_t *local = frame->local; -	dict_t *xdata; -	dict_t *xattr; -	inode_t *inode; - -	if (!local) { -		CRYPT_STACK_UNWIND(link, -				   frame, -				   -1, -				   ENOMEM, -				   NULL, -				   NULL, -				   NULL, -				   NULL, -				   NULL); -		return; -	} -	xdata = local->xdata; -	xattr = local->xattr; -	inode = local->inode; - -	if (local->loc){ -		loc_wipe(local->loc); -		GF_FREE(local->loc); -	} -	if (local->newloc) { -		loc_wipe(local->newloc); -		GF_FREE(local->newloc); -	} -	if (local->fd) -		fd_unref(local->fd); -	if (local->format) -		GF_FREE(local->format); - -	CRYPT_STACK_UNWIND(link, -			   frame, -			   local->op_ret, -			   local->op_errno, -			   inode, -			   &local->buf, -			   &local->prebuf, -			   &local->postbuf, -			   xdata); -	if (xdata) -		dict_unref(xdata); -	if (xattr) -		dict_unref(xattr); -	if (inode) -		inode_unref(inode); -} - -void link_wind(call_frame_t *frame, xlator_t *this) -{ -	crypt_local_t *local = frame->local; - -	STACK_WIND(frame, -		   link_flush, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->link, -		   local->loc, -		   local->newloc, -		   local->xdata); +static int32_t +link_flush(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, +           int32_t op_errno, inode_t *inode, struct iatt *buf, +           struct iatt *preparent, struct iatt *postparent, dict_t *xdata) +{ +    crypt_local_t *local = frame->local; + +    if (op_ret < 0) +        goto error; +    if (local->xdata) { +        dict_unref(local->xdata); +        local->xdata = NULL; +    } +    if (xdata) +        local->xdata = dict_ref(xdata); +    local->inode = inode_ref(inode); +    local->buf = *buf; +    local->prebuf = *preparent; +    local->postbuf = *postparent; + +    STACK_WIND(frame, linkop_end, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->flush, local->fd, NULL); +    return 0; +error: +    local->op_ret = -1; +    local->op_errno = op_errno; +    link_unwind(frame); +    return 0; +} + +void +link_unwind(call_frame_t *frame) +{ +    crypt_local_t *local = frame->local; +    dict_t *xdata; +    dict_t *xattr; +    inode_t *inode; + +    if (!local) { +        CRYPT_STACK_UNWIND(link, frame, -1, ENOMEM, NULL, NULL, NULL, NULL, +                           NULL); +        return; +    } +    xdata = local->xdata; +    xattr = local->xattr; +    inode = local->inode; + +    if (local->loc) { +        loc_wipe(local->loc); +        GF_FREE(local->loc); +    } +    if (local->newloc) { +        loc_wipe(local->newloc); +        GF_FREE(local->newloc); +    } +    if (local->fd) +        fd_unref(local->fd); +    if (local->format) +        GF_FREE(local->format); + +    CRYPT_STACK_UNWIND(link, frame, local->op_ret, local->op_errno, inode, +                       &local->buf, &local->prebuf, &local->postbuf, xdata); +    if (xdata) +        dict_unref(xdata); +    if (xattr) +        dict_unref(xattr); +    if (inode) +        inode_unref(inode); +} + +void +link_wind(call_frame_t *frame, xlator_t *this) +{ +    crypt_local_t *local = frame->local; + +    STACK_WIND(frame, link_flush, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->link, local->loc, local->newloc, +               local->xdata);  }  /*   * unlink()   */ -static int32_t unlink_flush(call_frame_t *frame, -			    void *cookie, -			    xlator_t *this, -			    int32_t op_ret, -			    int32_t op_errno, -			    struct iatt *preparent, -			    struct iatt *postparent, dict_t *xdata) -{ -	crypt_local_t *local = frame->local; - -	if (op_ret < 0) -		goto error; -	local->prebuf = *preparent; -	local->postbuf = *postparent; -	if (local->xdata) { -		dict_unref(local->xdata); -		local->xdata = NULL; -	} -	if (xdata) -		local->xdata = dict_ref(xdata); - -	STACK_WIND(frame, -		   linkop_end, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->flush, -		   local->fd, -		   NULL); -	return 0; - error: -	local->op_ret = -1; -	local->op_errno = op_errno; -	unlink_unwind(frame); -	return 0; -} - -void unlink_unwind(call_frame_t *frame) -{ -	crypt_local_t *local = frame->local; -	dict_t *xdata; -	dict_t *xattr; - -	if (!local) { -		CRYPT_STACK_UNWIND(unlink, -				   frame, -				   -1, -				   ENOMEM, -				   NULL, -				   NULL, -				   NULL); -		return; -	} -	xdata = local->xdata; -	xattr = local->xattr; -	if (local->loc){ -		loc_wipe(local->loc); -		GF_FREE(local->loc); -	} -	if (local->fd) -		fd_unref(local->fd); -	if (local->format) -		GF_FREE(local->format); - -	CRYPT_STACK_UNWIND(unlink, -			   frame, -			   local->op_ret, -			   local->op_errno, -			   &local->prebuf, -			   &local->postbuf, -			   xdata); -	if (xdata) -		dict_unref(xdata); -	if (xattr) -		dict_unref(xattr); -} - -void unlink_wind(call_frame_t *frame, xlator_t *this) -{ -	crypt_local_t *local = frame->local; - -	STACK_WIND(frame, -		   unlink_flush, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->unlink, -		   local->loc, -		   local->flags, -		   local->xdata); -} - -void rename_unwind(call_frame_t *frame) -{ -	crypt_local_t *local = frame->local; -	dict_t *xdata; -	dict_t *xattr; -	struct iatt *prenewparent; -	struct iatt *postnewparent; - -	if (!local) { -		CRYPT_STACK_UNWIND(rename, -				   frame, -				   -1, -				   ENOMEM, -				   NULL, -				   NULL, -				   NULL, -				   NULL, -				   NULL, -				   NULL); -		return; -	} -	xdata = local->xdata; -	xattr = local->xattr; -	prenewparent = local->prenewparent; -	postnewparent = local->postnewparent; - -	if (local->loc){ -		loc_wipe(local->loc); -		GF_FREE(local->loc); -	} -	if (local->newloc){ -		loc_wipe(local->newloc); -		GF_FREE(local->newloc); -	} -	if (local->fd) -		fd_unref(local->fd); -	if (local->format) -		GF_FREE(local->format); - -	CRYPT_STACK_UNWIND(rename, -			   frame, -			   local->op_ret, -			   local->op_errno, -			   &local->buf, -			   &local->prebuf, -			   &local->postbuf, -			   prenewparent, -			   postnewparent, -			   xdata); -	if (xdata) -		dict_unref(xdata); -	if (xattr) -		dict_unref(xattr); -	if (prenewparent) -		GF_FREE(prenewparent); -	if (postnewparent) -		GF_FREE(postnewparent); +static int32_t +unlink_flush(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, +             int32_t op_errno, struct iatt *preparent, struct iatt *postparent, +             dict_t *xdata) +{ +    crypt_local_t *local = frame->local; + +    if (op_ret < 0) +        goto error; +    local->prebuf = *preparent; +    local->postbuf = *postparent; +    if (local->xdata) { +        dict_unref(local->xdata); +        local->xdata = NULL; +    } +    if (xdata) +        local->xdata = dict_ref(xdata); + +    STACK_WIND(frame, linkop_end, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->flush, local->fd, NULL); +    return 0; +error: +    local->op_ret = -1; +    local->op_errno = op_errno; +    unlink_unwind(frame); +    return 0; +} + +void +unlink_unwind(call_frame_t *frame) +{ +    crypt_local_t *local = frame->local; +    dict_t *xdata; +    dict_t *xattr; + +    if (!local) { +        CRYPT_STACK_UNWIND(unlink, frame, -1, ENOMEM, NULL, NULL, NULL); +        return; +    } +    xdata = local->xdata; +    xattr = local->xattr; +    if (local->loc) { +        loc_wipe(local->loc); +        GF_FREE(local->loc); +    } +    if (local->fd) +        fd_unref(local->fd); +    if (local->format) +        GF_FREE(local->format); + +    CRYPT_STACK_UNWIND(unlink, frame, local->op_ret, local->op_errno, +                       &local->prebuf, &local->postbuf, xdata); +    if (xdata) +        dict_unref(xdata); +    if (xattr) +        dict_unref(xattr); +} + +void +unlink_wind(call_frame_t *frame, xlator_t *this) +{ +    crypt_local_t *local = frame->local; + +    STACK_WIND(frame, unlink_flush, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->unlink, local->loc, local->flags, +               local->xdata); +} + +void +rename_unwind(call_frame_t *frame) +{ +    crypt_local_t *local = frame->local; +    dict_t *xdata; +    dict_t *xattr; +    struct iatt *prenewparent; +    struct iatt *postnewparent; + +    if (!local) { +        CRYPT_STACK_UNWIND(rename, frame, -1, ENOMEM, NULL, NULL, NULL, NULL, +                           NULL, NULL); +        return; +    } +    xdata = local->xdata; +    xattr = local->xattr; +    prenewparent = local->prenewparent; +    postnewparent = local->postnewparent; + +    if (local->loc) { +        loc_wipe(local->loc); +        GF_FREE(local->loc); +    } +    if (local->newloc) { +        loc_wipe(local->newloc); +        GF_FREE(local->newloc); +    } +    if (local->fd) +        fd_unref(local->fd); +    if (local->format) +        GF_FREE(local->format); + +    CRYPT_STACK_UNWIND(rename, frame, local->op_ret, local->op_errno, +                       &local->buf, &local->prebuf, &local->postbuf, +                       prenewparent, postnewparent, xdata); +    if (xdata) +        dict_unref(xdata); +    if (xattr) +        dict_unref(xattr); +    if (prenewparent) +        GF_FREE(prenewparent); +    if (postnewparent) +        GF_FREE(postnewparent);  }  /*   * called as flush_cbk()   */ -static int32_t rename_end(call_frame_t *frame, -			  void *cookie, -			  xlator_t *this, -			  int32_t op_ret, -			  int32_t op_errno, -			  dict_t *xdata) -{ -	crypt_local_t *local = frame->local; - -	local->op_ret = op_ret; -	local->op_errno = op_errno; - -	rename_unwind(frame); -	return 0; -} - -static int32_t rename_flush(call_frame_t *frame, -			    void *cookie, -			    xlator_t *this, -			    int32_t op_ret, -			    int32_t op_errno, -			    struct iatt *buf, -			    struct iatt *preoldparent, -			    struct iatt *postoldparent, -			    struct iatt *prenewparent, -			    struct iatt *postnewparent, -			    dict_t *xdata) -{ -	crypt_local_t *local = frame->local; - -	if (op_ret < 0) -		goto error; -	dict_unref(local->xdata); -	local->xdata = NULL; -	if (xdata) -		local->xdata = dict_ref(xdata); - -	local->buf = *buf; -	local->prebuf = *preoldparent; -	local->postbuf = *postoldparent; -	if (prenewparent) { -		local->prenewparent = GF_CALLOC(1, sizeof(*prenewparent), -						gf_crypt_mt_iatt); -		if (!local->prenewparent) { -			op_errno = ENOMEM; -			goto error; -		} -		*local->prenewparent = *prenewparent; -	} -	if (postnewparent) { -		local->postnewparent = GF_CALLOC(1, sizeof(*postnewparent), -						 gf_crypt_mt_iatt); -		if (!local->postnewparent) { -			op_errno = ENOMEM; -			goto error; -		} -		*local->postnewparent = *postnewparent; -	} -	STACK_WIND(frame, -		   rename_end, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->flush, -		   local->fd, -		   NULL); -	return 0; - error: -	local->op_ret = -1; -	local->op_errno = op_errno; -	rename_unwind(frame); -	return 0; -} - -void rename_wind(call_frame_t *frame, xlator_t *this) -{ -	crypt_local_t *local = frame->local; - -	STACK_WIND(frame, -		   rename_flush, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->rename, -		   local->loc, -		   local->newloc, -		   local->xdata); -} - -static int32_t __do_linkop(call_frame_t *frame, -			   void *cookie, -			   xlator_t *this, -			   int32_t op_ret, -			   int32_t op_errno, dict_t *xdata) -{ -	crypt_local_t *local = frame->local; -	linkop_wind_handler_t wind_fn; -	linkop_unwind_handler_t unwind_fn; - -	wind_fn = linkop_wind_dispatch(local->fop); -	unwind_fn = linkop_unwind_dispatch(local->fop); - -	local->op_ret = op_ret; -	local->op_errno = op_errno; - -	if (op_ret >= 0) -		wind_fn(frame, this); -	else { -		gf_log(this->name, GF_LOG_WARNING, "mtd unlock failed (%d)", -		       op_errno); -		unwind_fn(frame); -	} -	return 0; -} - -static int32_t do_linkop(call_frame_t *frame, -			 void *cookie, -			 xlator_t *this, -			 int32_t op_ret, -			 int32_t op_errno, -			 dict_t *xdata) -{ -	struct gf_flock  lock  = {0, }; -	crypt_local_t *local = frame->local; -	linkop_unwind_handler_t unwind_fn; - -	unwind_fn = linkop_unwind_dispatch(local->fop); -	local->op_ret = op_ret; -	local->op_errno = op_errno; - -	if(op_ret < 0) -		goto error; - -	lock.l_type   = F_UNLCK; -        lock.l_whence = SEEK_SET; -        lock.l_start  = 0; -        lock.l_len    = 0; -        lock.l_pid    = 0; - -	STACK_WIND(frame, -		   __do_linkop, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->finodelk, -		   this->name, -		   local->fd, -		   F_SETLKW, -		   &lock, -		   NULL); -	return 0; - error: -	unwind_fn(frame); -	return 0; +static int32_t +rename_end(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, +           int32_t op_errno, dict_t *xdata) +{ +    crypt_local_t *local = frame->local; + +    local->op_ret = op_ret; +    local->op_errno = op_errno; + +    rename_unwind(frame); +    return 0; +} + +static int32_t +rename_flush(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, +             int32_t op_errno, struct iatt *buf, struct iatt *preoldparent, +             struct iatt *postoldparent, struct iatt *prenewparent, +             struct iatt *postnewparent, dict_t *xdata) +{ +    crypt_local_t *local = frame->local; + +    if (op_ret < 0) +        goto error; +    dict_unref(local->xdata); +    local->xdata = NULL; +    if (xdata) +        local->xdata = dict_ref(xdata); + +    local->buf = *buf; +    local->prebuf = *preoldparent; +    local->postbuf = *postoldparent; +    if (prenewparent) { +        local->prenewparent = GF_CALLOC(1, sizeof(*prenewparent), +                                        gf_crypt_mt_iatt); +        if (!local->prenewparent) { +            op_errno = ENOMEM; +            goto error; +        } +        *local->prenewparent = *prenewparent; +    } +    if (postnewparent) { +        local->postnewparent = GF_CALLOC(1, sizeof(*postnewparent), +                                         gf_crypt_mt_iatt); +        if (!local->postnewparent) { +            op_errno = ENOMEM; +            goto error; +        } +        *local->postnewparent = *postnewparent; +    } +    STACK_WIND(frame, rename_end, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->flush, local->fd, NULL); +    return 0; +error: +    local->op_ret = -1; +    local->op_errno = op_errno; +    rename_unwind(frame); +    return 0; +} + +void +rename_wind(call_frame_t *frame, xlator_t *this) +{ +    crypt_local_t *local = frame->local; + +    STACK_WIND(frame, rename_flush, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->rename, local->loc, local->newloc, +               local->xdata); +} + +static int32_t +__do_linkop(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, +            int32_t op_errno, dict_t *xdata) +{ +    crypt_local_t *local = frame->local; +    linkop_wind_handler_t wind_fn; +    linkop_unwind_handler_t unwind_fn; + +    wind_fn = linkop_wind_dispatch(local->fop); +    unwind_fn = linkop_unwind_dispatch(local->fop); + +    local->op_ret = op_ret; +    local->op_errno = op_errno; + +    if (op_ret >= 0) +        wind_fn(frame, this); +    else { +        gf_log(this->name, GF_LOG_WARNING, "mtd unlock failed (%d)", op_errno); +        unwind_fn(frame); +    } +    return 0; +} + +static int32_t +do_linkop(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, +          int32_t op_errno, dict_t *xdata) +{ +    struct gf_flock lock = { +        0, +    }; +    crypt_local_t *local = frame->local; +    linkop_unwind_handler_t unwind_fn; + +    unwind_fn = linkop_unwind_dispatch(local->fop); +    local->op_ret = op_ret; +    local->op_errno = op_errno; + +    if (op_ret < 0) +        goto error; + +    lock.l_type = F_UNLCK; +    lock.l_whence = SEEK_SET; +    lock.l_start = 0; +    lock.l_len = 0; +    lock.l_pid = 0; + +    STACK_WIND(frame, __do_linkop, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->finodelk, this->name, local->fd, +               F_SETLKW, &lock, NULL); +    return 0; +error: +    unwind_fn(frame); +    return 0;  }  /*   * Update the metadata string (against the new pathname);   * submit the result   */ -static int32_t linkop_begin(call_frame_t *frame, -			    void *cookie, -			    xlator_t *this, -			    int32_t op_ret, -			    int32_t op_errno, -			    fd_t *fd, -			    dict_t *xdata) -{ -	gf_boolean_t upload_info; -	crypt_local_t *local = frame->local; -	crypt_private_t *priv = this->private; -	struct crypt_inode_info *info; -	data_t *old_mtd; -	uint32_t new_mtd_size; -	uint64_t value = 0; -	void (*unwind_fn)(call_frame_t *frame); -	mtd_op_t mop; - -	unwind_fn = linkop_unwind_dispatch(local->fop); -	mop = linkop_mtdop_dispatch(local->fop); - -	if (op_ret < 0) { -		/* -		 * verification failed -		 */ -		goto error; -        } else { -                fd_bind (fd); +static int32_t +linkop_begin(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, +             int32_t op_errno, fd_t *fd, dict_t *xdata) +{ +    gf_boolean_t upload_info; +    crypt_local_t *local = frame->local; +    crypt_private_t *priv = this->private; +    struct crypt_inode_info *info; +    data_t *old_mtd; +    uint32_t new_mtd_size; +    uint64_t value = 0; +    void (*unwind_fn)(call_frame_t * frame); +    mtd_op_t mop; + +    unwind_fn = linkop_unwind_dispatch(local->fop); +    mop = linkop_mtdop_dispatch(local->fop); + +    if (op_ret < 0) { +        /* +         * verification failed +         */ +        goto error; +    } else { +        fd_bind(fd); +    } + +    old_mtd = dict_get(xdata, CRYPTO_FORMAT_PREFIX); +    if (!old_mtd) { +        op_errno = EIO; +        gf_log(this->name, GF_LOG_DEBUG, "Metadata string wasn't found"); +        goto error; +    } +    new_mtd_size = format_size(mop, old_mtd->len); +    op_errno = alloc_format(local, new_mtd_size); +    if (op_errno) +        goto error; +    /* +     * check for cached info +     */ +    op_ret = inode_ctx_get(fd->inode, this, &value); +    if (op_ret != -1) { +        info = (struct crypt_inode_info *)(long)value; +        if (info == NULL) { +            gf_log(this->name, GF_LOG_WARNING, "Inode info was not found"); +            op_errno = EINVAL; +            goto error;          } - -	old_mtd = dict_get(xdata, CRYPTO_FORMAT_PREFIX); -	if (!old_mtd) { -		op_errno = EIO; -		gf_log (this->name, GF_LOG_DEBUG, -			"Metadata string wasn't found"); -		goto error; -	} -	new_mtd_size = format_size(mop, old_mtd->len); -	op_errno = alloc_format(local, new_mtd_size); -	if (op_errno) -		goto error; -	/* -	 * check for cached info -	 */ -	op_ret = inode_ctx_get(fd->inode, this, &value); -	if (op_ret != -1) { -		info = (struct crypt_inode_info *)(long)value; -		if (info == NULL) { -			gf_log (this->name, GF_LOG_WARNING, -				"Inode info was not found"); -			op_errno = EINVAL; -			goto error; -		} -		/* -		 * info was found in the cache -		 */ -		local->info = info; -		upload_info = _gf_false; -	} -	else { -		/* -		 * info wasn't found in the cache; -		 */ -		info = alloc_inode_info(local, local->loc); -		if (!info) -			goto error; -		init_inode_info_head(info, fd); -		local->info = info; -		upload_info = _gf_true; -	} -	op_errno = open_format((unsigned char *)old_mtd->data, -			       old_mtd->len, -			       local->loc, -			       info, -			       get_master_cinfo(priv), -			       local, -			       upload_info); -	if (op_errno) -		goto error; -	if (upload_info == _gf_true) { -		op_errno = init_inode_info_tail(info, -						get_master_cinfo(priv)); -		if (op_errno) -			goto error; -		op_errno = inode_ctx_put(fd->inode, this, -					 (uint64_t)(long)(info)); -		if (op_errno == -1) { -			op_errno = EIO; -			goto error; -		} -	} -	/* -	 * update the format string (append/update/cup a MAC) -	 */ -	op_errno = update_format(local->format, -				 (unsigned char *)old_mtd->data, -				 old_mtd->len, -				 local->mac_idx, -				 mop, -				 local->newloc, -				 info, -				 get_master_cinfo(priv), -				 local); -	if (op_errno) -		goto error; -	/* -	 * store the new format string on the server -	 */ -	if (new_mtd_size) { -		op_errno = dict_set_static_bin(local->xattr, -					       CRYPTO_FORMAT_PREFIX, -					       local->format, -					       new_mtd_size); -		if (op_errno) -			goto error; -	} -	STACK_WIND(frame, -		   do_linkop, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->setxattr, -		   local->loc, -		   local->xattr, -		   0, -		   NULL); -	return 0; - error: -	local->op_ret = -1; -	local->op_errno = op_errno; -	unwind_fn(frame); -	return 0; -} - -static int32_t linkop_grab_local(call_frame_t *frame, -				 xlator_t *this, -				 loc_t *oldloc, -				 loc_t *newloc, -				 int flags, dict_t *xdata, -				 glusterfs_fop_t op) -{ -	int32_t ret = ENOMEM; -	fd_t *fd; -	crypt_local_t *local; - -	local = crypt_alloc_local(frame, this, op); -	if (!local) -		goto error; -	if (xdata) -		local->xdata = dict_ref(xdata); - -	fd = fd_create(oldloc->inode, frame->root->pid); -	if (!fd) { -		gf_log(this->name, GF_LOG_ERROR, "Can not create fd"); -		goto error; -	} -	local->fd = fd; -	local->flags = flags; -	local->loc = GF_CALLOC(1, sizeof(loc_t), gf_crypt_mt_loc); -	if (!local->loc) -		goto error; -	ret = loc_copy(local->loc, oldloc); -	if (ret) { -		GF_FREE(local->loc); -		local->loc = NULL; -		goto error; -	} -	if (newloc) { -		local->newloc = GF_CALLOC(1, sizeof(loc_t), gf_crypt_mt_loc); -		if (!local->newloc) { -			loc_wipe(local->loc); -			GF_FREE(local->loc); -			goto error; -		} -		ret = loc_copy(local->newloc, newloc); -		if (ret) { -			loc_wipe(local->loc); -			GF_FREE(local->loc); -			GF_FREE(local->newloc); -			goto error; -		} -	} -	local->xattr = dict_new(); -	if (!local->xattr) { -		gf_log(this->name, GF_LOG_ERROR, "Can not create dict"); -		ret = ENOMEM; -		goto error; -	} -	return 0; - +        /* +         * info was found in the cache +         */ +        local->info = info; +        upload_info = _gf_false; +    } else { +        /* +         * info wasn't found in the cache; +         */ +        info = alloc_inode_info(local, local->loc); +        if (!info) +            goto error; +        init_inode_info_head(info, fd); +        local->info = info; +        upload_info = _gf_true; +    } +    op_errno = open_format((unsigned char *)old_mtd->data, old_mtd->len, +                           local->loc, info, get_master_cinfo(priv), local, +                           upload_info); +    if (op_errno) +        goto error; +    if (upload_info == _gf_true) { +        op_errno = init_inode_info_tail(info, get_master_cinfo(priv)); +        if (op_errno) +            goto error; +        op_errno = inode_ctx_put(fd->inode, this, (uint64_t)(long)(info)); +        if (op_errno == -1) { +            op_errno = EIO; +            goto error; +        } +    } +    /* +     * update the format string (append/update/cup a MAC) +     */ +    op_errno = update_format(local->format, (unsigned char *)old_mtd->data, +                             old_mtd->len, local->mac_idx, mop, local->newloc, +                             info, get_master_cinfo(priv), local); +    if (op_errno) +        goto error; +    /* +     * store the new format string on the server +     */ +    if (new_mtd_size) { +        op_errno = dict_set_static_bin(local->xattr, CRYPTO_FORMAT_PREFIX, +                                       local->format, new_mtd_size); +        if (op_errno) +            goto error; +    } +    STACK_WIND(frame, do_linkop, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->setxattr, local->loc, local->xattr, 0, +               NULL); +    return 0;  error: -        if (local) { -                if (local->xdata) -                        dict_unref(local->xdata); -                if (local->fd) -                        fd_unref(local->fd); -                local->fd = 0; -                local->loc = NULL; -                local->newloc = NULL; -                local->op_ret = -1; -                local->op_errno = ret; +    local->op_ret = -1; +    local->op_errno = op_errno; +    unwind_fn(frame); +    return 0; +} + +static int32_t +linkop_grab_local(call_frame_t *frame, xlator_t *this, loc_t *oldloc, +                  loc_t *newloc, int flags, dict_t *xdata, glusterfs_fop_t op) +{ +    int32_t ret = ENOMEM; +    fd_t *fd; +    crypt_local_t *local; + +    local = crypt_alloc_local(frame, this, op); +    if (!local) +        goto error; +    if (xdata) +        local->xdata = dict_ref(xdata); + +    fd = fd_create(oldloc->inode, frame->root->pid); +    if (!fd) { +        gf_log(this->name, GF_LOG_ERROR, "Can not create fd"); +        goto error; +    } +    local->fd = fd; +    local->flags = flags; +    local->loc = GF_CALLOC(1, sizeof(loc_t), gf_crypt_mt_loc); +    if (!local->loc) +        goto error; +    ret = loc_copy(local->loc, oldloc); +    if (ret) { +        GF_FREE(local->loc); +        local->loc = NULL; +        goto error; +    } +    if (newloc) { +        local->newloc = GF_CALLOC(1, sizeof(loc_t), gf_crypt_mt_loc); +        if (!local->newloc) { +            loc_wipe(local->loc); +            GF_FREE(local->loc); +            goto error; +        } +        ret = loc_copy(local->newloc, newloc); +        if (ret) { +            loc_wipe(local->loc); +            GF_FREE(local->loc); +            GF_FREE(local->newloc); +            goto error;          } +    } +    local->xattr = dict_new(); +    if (!local->xattr) { +        gf_log(this->name, GF_LOG_ERROR, "Can not create dict"); +        ret = ENOMEM; +        goto error; +    } +    return 0; -        return ret; +error: +    if (local) { +        if (local->xdata) +            dict_unref(local->xdata); +        if (local->fd) +            fd_unref(local->fd); +        local->fd = 0; +        local->loc = NULL; +        local->newloc = NULL; +        local->op_ret = -1; +        local->op_errno = ret; +    } + +    return ret;  }  /* @@ -3313,802 +2855,650 @@ error:   * submit modified metadata;   * wind;   */ -static int32_t linkop(call_frame_t *frame, -		      xlator_t *this, -		      loc_t *oldloc, -		      loc_t *newloc, -		      int flags, -		      dict_t *xdata, -		      glusterfs_fop_t op) -{ -	int32_t ret; -	dict_t *dict; -	crypt_local_t *local; -	void (*unwind_fn)(call_frame_t *frame); -        void (*wind_fn)(call_frame_t *frame, xlator_t *this); - -        wind_fn = linkop_wind_dispatch(op); -	unwind_fn = linkop_unwind_dispatch(op); - -	ret = linkop_grab_local(frame, this, oldloc, newloc, flags, xdata, op); -	local = frame->local; -	if (ret) -		goto error; - -        if (local->fd->inode->ia_type == IA_IFLNK) -                goto wind; - -	dict = dict_new(); -	if (!dict) { -		gf_log(this->name, GF_LOG_ERROR, "Can not create dict"); -		ret = ENOMEM; -		goto error; -	} -	/* -	 * Set a message to crypt_open() that we need -	 * locked metadata string. -	 * All link operations (link, unlink, rename) -	 * need write lock -	 */ -	msgflags_set_mtd_wlock(&local->msgflags); -	ret = dict_set_static_bin(dict, -				  MSGFLAGS_PREFIX, -				  &local->msgflags, -				  sizeof(local->msgflags)); -	if (ret) { -		gf_log(this->name, GF_LOG_ERROR, "Can not set dict"); -		dict_unref(dict); -		goto error; -	} -	/* -	 * verify metadata against the old pathname -	 * and retrieve locked metadata string -	 */ -	STACK_WIND(frame, -		   linkop_begin, -		   this, -		   this->fops->open, /* crypt_open() */ -		   oldloc, -		   O_RDWR, -		   local->fd, -		   dict); -	dict_unref(dict); -	return 0; +static int32_t +linkop(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, +       int flags, dict_t *xdata, glusterfs_fop_t op) +{ +    int32_t ret; +    dict_t *dict; +    crypt_local_t *local; +    void (*unwind_fn)(call_frame_t * frame); +    void (*wind_fn)(call_frame_t * frame, xlator_t * this); + +    wind_fn = linkop_wind_dispatch(op); +    unwind_fn = linkop_unwind_dispatch(op); + +    ret = linkop_grab_local(frame, this, oldloc, newloc, flags, xdata, op); +    local = frame->local; +    if (ret) +        goto error; + +    if (local->fd->inode->ia_type == IA_IFLNK) +        goto wind; + +    dict = dict_new(); +    if (!dict) { +        gf_log(this->name, GF_LOG_ERROR, "Can not create dict"); +        ret = ENOMEM; +        goto error; +    } +    /* +     * Set a message to crypt_open() that we need +     * locked metadata string. +     * All link operations (link, unlink, rename) +     * need write lock +     */ +    msgflags_set_mtd_wlock(&local->msgflags); +    ret = dict_set_static_bin(dict, MSGFLAGS_PREFIX, &local->msgflags, +                              sizeof(local->msgflags)); +    if (ret) { +        gf_log(this->name, GF_LOG_ERROR, "Can not set dict"); +        dict_unref(dict); +        goto error; +    } +    /* +     * verify metadata against the old pathname +     * and retrieve locked metadata string +     */ +    STACK_WIND(frame, linkop_begin, this, this->fops->open, /* crypt_open() */ +               oldloc, O_RDWR, local->fd, dict); +    dict_unref(dict); +    return 0;  wind: -        wind_fn(frame, this); -        return 0; +    wind_fn(frame, this); +    return 0;  error: -	local->op_ret = -1; -	local->op_errno = ret; -	unwind_fn(frame); -	return 0; -} - -static int32_t crypt_link(call_frame_t *frame, xlator_t *this, -			  loc_t *oldloc, loc_t *newloc, dict_t *xdata) -{ -	return linkop(frame, this, oldloc, newloc, 0, xdata, GF_FOP_LINK); -} - -static int32_t crypt_unlink(call_frame_t *frame, xlator_t *this, -			    loc_t *loc, int flags, dict_t *xdata) -{ -	return linkop(frame, this, loc, NULL, flags, xdata, GF_FOP_UNLINK); -} - -static int32_t crypt_rename(call_frame_t *frame, xlator_t *this, -			    loc_t *oldloc, loc_t *newloc, dict_t *xdata) -{ -	return linkop(frame, this, oldloc, newloc, 0, xdata, GF_FOP_RENAME); -} - -static void put_one_call_open(call_frame_t *frame) -{ -	crypt_local_t *local = frame->local; -	if (put_one_call(local)) { -		fd_t *fd = local->fd; -		loc_t *loc = local->loc; -		dict_t *xdata = local->xdata; - -		CRYPT_STACK_UNWIND(open, -				   frame, -				   local->op_ret, -				   local->op_errno, -				   fd, -				   xdata); -		fd_unref(fd); -		if (xdata) -			dict_unref(xdata); -		loc_wipe(loc); -		GF_FREE(loc); -	} -} - -static int32_t __crypt_readv_done(call_frame_t *frame, -				  void *cookie, -				  xlator_t *this, -				  int32_t op_ret, -				  int32_t op_errno, dict_t *xdata) -{ -	crypt_local_t *local = frame->local; -	fd_t *local_fd = local->fd; -	dict_t *local_xdata = local->xdata; -	/* read deals with data configs only */ -	struct iovec *avec = local->data_conf.avec; -	char **pool = local->data_conf.pool; -	int blocks_in_pool = local->data_conf.blocks_in_pool; -	struct iobref *iobref = local->iobref; -	struct iobref *iobref_data = local->iobref_data; - -	if (op_ret < 0) { -		gf_log(this->name, GF_LOG_WARNING, -		       "readv unlock failed (%d)", op_errno); -		if (local->op_ret >= 0) { -			local->op_ret = op_ret; -			local->op_errno = op_errno; -		} -	} -	dump_plain_text(local, avec); - -	gf_log("crypt", GF_LOG_DEBUG, -	       "readv: ret_to_user: %d, iovec len: %d, ia_size: %llu", -	       (int)(local->rw_count > 0 ? local->rw_count : local->op_ret), -	       (int)(local->rw_count > 0 ? iov_length(avec, local->data_conf.acount) : 0), -	       (unsigned long long)local->buf.ia_size); - -	CRYPT_STACK_UNWIND(readv, -			   frame, -			   local->rw_count > 0 ? local->rw_count : local->op_ret, -			   local->op_errno, -			   avec, -			   avec ? local->data_conf.acount : 0, -			   &local->buf, -			   local->iobref, -			   local_xdata); - -	free_avec(avec, pool, blocks_in_pool); -	fd_unref(local_fd); -	if (local_xdata) -		dict_unref(local_xdata); -	if (iobref) -		iobref_unref(iobref); -	if (iobref_data) -		iobref_unref(iobref_data); -	return 0; -} - -static void crypt_readv_done(call_frame_t *frame, xlator_t *this) -{ -	if (parent_is_crypt_xlator(frame, this)) -		/* -		 *  don't unlock (it will be done by the parent) -		 */ -		__crypt_readv_done(frame, NULL, this, 0, 0, NULL); -	else { -		crypt_local_t *local = frame->local; -		struct gf_flock  lock  = {0, }; - -		lock.l_type   = F_UNLCK; -		lock.l_whence = SEEK_SET; -		lock.l_start  = 0; -		lock.l_len    = 0; -		lock.l_pid    = 0; - -		STACK_WIND(frame, -			   __crypt_readv_done, -			   FIRST_CHILD(this), -			   FIRST_CHILD(this)->fops->finodelk, -			   this->name, -			   local->fd, -			   F_SETLKW, -			   &lock, -			   NULL); -	} -} - -static void put_one_call_readv(call_frame_t *frame, xlator_t *this) -{ -	crypt_local_t *local = frame->local; -	if (put_one_call(local)) -		crypt_readv_done(frame, this); -} - -static int32_t __crypt_writev_done(call_frame_t *frame, -				   void *cookie, -				   xlator_t *this, -				   int32_t op_ret, -				   int32_t op_errno, dict_t *xdata) -{ -	crypt_local_t *local = frame->local; -	fd_t *local_fd = local->fd; -	dict_t *local_xdata = local->xdata; -	int32_t ret_to_user; - -	if (local->xattr) -		dict_unref(local->xattr); -	/* -	 * Calculate amount of butes to be returned -	 * to user. We need to subtract paddings that -	 * have been written as a part of atom. -	 */ -	/* -	 * subtract head padding -	 */ -	if (local->rw_count == 0) -		/* -		 * Nothing has been written, it must be an error -		 */ -		ret_to_user = local->op_ret; -	else if (local->rw_count <= local->data_conf.off_in_head) { -		gf_log("crypt", GF_LOG_WARNING, "Incomplete write"); -		ret_to_user = 0; -	} -	else -		ret_to_user = local->rw_count - -			local->data_conf.off_in_head; -	/* -	 * subtract tail padding -	 */ -	if (ret_to_user > local->data_conf.orig_size) -		ret_to_user = local->data_conf.orig_size; - -	if (local->iobref) -		iobref_unref(local->iobref); -	if (local->iobref_data) -		iobref_unref(local->iobref_data); -	free_avec_data(local); -	free_avec_hole(local); - -	gf_log("crypt", GF_LOG_DEBUG, -	       "writev: ret_to_user: %d", ret_to_user); - -	CRYPT_STACK_UNWIND(writev, -			   frame, -			   ret_to_user, -			   local->op_errno, -			   &local->prebuf, -			   &local->postbuf, -			   local_xdata); -	fd_unref(local_fd); -	if (local_xdata) -		dict_unref(local_xdata); -	return 0; -} - -static int32_t crypt_writev_done(call_frame_t *frame, -				 void *cookie, -				 xlator_t *this, -				 int32_t op_ret, -				 int32_t op_errno, -				 dict_t *xdata) -{ -	crypt_local_t *local = frame->local; - -	if (op_ret < 0) -		gf_log("crypt", GF_LOG_WARNING, "can not update file size"); - -	if (parent_is_crypt_xlator(frame, this)) -		/* -		 * don't unlock (it will be done by the parent) -		 */ -		__crypt_writev_done(frame, NULL, this, 0, 0, NULL); -	else { -		struct gf_flock  lock  = {0, }; - -		lock.l_type   = F_UNLCK; -		lock.l_whence = SEEK_SET; -		lock.l_start  = 0; -		lock.l_len    = 0; -		lock.l_pid    = 0; - -		STACK_WIND(frame, -			   __crypt_writev_done, -			   FIRST_CHILD(this), -			   FIRST_CHILD(this)->fops->finodelk, -			   this->name, -			   local->fd, -			   F_SETLKW, -			   &lock, -			   NULL); -	} -	return 0; -} - -static void put_one_call_writev(call_frame_t *frame, xlator_t *this) -{ -	crypt_local_t *local = frame->local; -	if (put_one_call(local)) { -		if (local->update_disk_file_size) { -			int32_t ret; -			/* -			 * update file size, unlock the file and unwind -			 */ -			ret = dict_set(local->xattr, -				       FSIZE_XATTR_PREFIX, -				       data_from_uint64(local->cur_file_size)); -			if (ret) { -				gf_log("crypt", GF_LOG_WARNING, -				       "can not set key to update file size"); -				crypt_writev_done(frame, NULL, -						  this, 0, 0, NULL); -				return; -			} -			gf_log("crypt", GF_LOG_DEBUG, -			       "Updating disk file size to %llu", -			       (unsigned long long)local->cur_file_size); -			STACK_WIND(frame, -				   crypt_writev_done, -				   FIRST_CHILD(this), -				   FIRST_CHILD(this)->fops->fsetxattr, -				   local->fd, -				   local->xattr, /* CRYPTO_FORMAT_PREFIX */ -				   0, -				   NULL); -		} -		else -			crypt_writev_done(frame, NULL, this, 0, 0, NULL); -	} -} - -static int32_t __crypt_ftruncate_done(call_frame_t *frame, -				      void *cookie, -				      xlator_t *this, -				      int32_t op_ret, -				      int32_t op_errno, dict_t *xdata) -{ -	crypt_local_t *local = frame->local; -	fd_t *local_fd = local->fd; -	dict_t *local_xdata = local->xdata; -	char *iobase = local->vec.iov_base; - -	if (op_ret < 0) { -		gf_log(this->name, GF_LOG_WARNING, -		       "ftruncate unlock failed (%d)", op_errno); -		if (local->op_ret >= 0) { -			local->op_ret = op_ret; -			local->op_errno = op_errno; -		} -	} -	if (local->iobref_data) -		iobref_unref(local->iobref_data); -	free_avec_data(local); -	free_avec_hole(local); - -	gf_log("crypt", GF_LOG_DEBUG, -	       "ftruncate, return to user: presize=%llu, postsize=%llu", -	       (unsigned long long)local->prebuf.ia_size, -	       (unsigned long long)local->postbuf.ia_size); - -	CRYPT_STACK_UNWIND(ftruncate, -			   frame, -			   ((local->op_ret < 0) ? -1 : 0), -			   local->op_errno, -			   &local->prebuf, -			   &local->postbuf, -			   local_xdata); -	fd_unref(local_fd); -	if (local_xdata) -		dict_unref(local_xdata); -	if (iobase) -		GF_FREE(iobase); -	return 0; -} - -static int32_t crypt_ftruncate_done(call_frame_t *frame, -				    void *cookie, -				    xlator_t *this, -				    int32_t op_ret, -				    int32_t op_errno, -				    dict_t *xdata) -{ -	crypt_local_t *local = frame->local; -	struct gf_flock  lock  = {0, }; - -	dict_unref(local->xattr); -	if (op_ret < 0) -		gf_log("crypt", GF_LOG_WARNING, "can not update file size"); - -	lock.l_type   = F_UNLCK; -	lock.l_whence = SEEK_SET; -	lock.l_start  = 0; -	lock.l_len    = 0; -	lock.l_pid    = 0; - -	STACK_WIND(frame, -		   __crypt_ftruncate_done, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->finodelk, -		   this->name, -		   local->fd, -		   F_SETLKW, -		   &lock, -		   NULL); -	return 0; -} - -static void put_one_call_ftruncate(call_frame_t *frame, xlator_t *this) -{ -	crypt_local_t *local = frame->local; -	if (put_one_call(local)) { -		if (local->update_disk_file_size) { -			int32_t ret; -			/* -			 * update file size, unlock the file and unwind -			 */ -			ret = dict_set(local->xattr, -				       FSIZE_XATTR_PREFIX, -				       data_from_uint64(local->cur_file_size)); -			if (ret) { -				gf_log("crypt", GF_LOG_WARNING, -				       "can not set key to update file size"); -				crypt_ftruncate_done(frame, NULL, -						     this, 0, 0, NULL); -				return; -			} -			gf_log("crypt", GF_LOG_DEBUG, -			       "Updating disk file size to %llu", -			       (unsigned long long)local->cur_file_size); -			STACK_WIND(frame, -				   crypt_ftruncate_done, -				   FIRST_CHILD(this), -				   FIRST_CHILD(this)->fops->fsetxattr, -				   local->fd, -				   local->xattr, /* CRYPTO_FORMAT_PREFIX */ -				   0, -				   NULL); -		} -		else -			crypt_ftruncate_done(frame, NULL, this, 0, 0, NULL); -	} +    local->op_ret = -1; +    local->op_errno = ret; +    unwind_fn(frame); +    return 0; +} + +static int32_t +crypt_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, +           dict_t *xdata) +{ +    return linkop(frame, this, oldloc, newloc, 0, xdata, GF_FOP_LINK); +} + +static int32_t +crypt_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, +             dict_t *xdata) +{ +    return linkop(frame, this, loc, NULL, flags, xdata, GF_FOP_UNLINK); +} + +static int32_t +crypt_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, +             dict_t *xdata) +{ +    return linkop(frame, this, oldloc, newloc, 0, xdata, GF_FOP_RENAME); +} + +static void +put_one_call_open(call_frame_t *frame) +{ +    crypt_local_t *local = frame->local; +    if (put_one_call(local)) { +        fd_t *fd = local->fd; +        loc_t *loc = local->loc; +        dict_t *xdata = local->xdata; + +        CRYPT_STACK_UNWIND(open, frame, local->op_ret, local->op_errno, fd, +                           xdata); +        fd_unref(fd); +        if (xdata) +            dict_unref(xdata); +        loc_wipe(loc); +        GF_FREE(loc); +    } +} + +static int32_t +__crypt_readv_done(call_frame_t *frame, void *cookie, xlator_t *this, +                   int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ +    crypt_local_t *local = frame->local; +    fd_t *local_fd = local->fd; +    dict_t *local_xdata = local->xdata; +    /* read deals with data configs only */ +    struct iovec *avec = local->data_conf.avec; +    char **pool = local->data_conf.pool; +    int blocks_in_pool = local->data_conf.blocks_in_pool; +    struct iobref *iobref = local->iobref; +    struct iobref *iobref_data = local->iobref_data; + +    if (op_ret < 0) { +        gf_log(this->name, GF_LOG_WARNING, "readv unlock failed (%d)", +               op_errno); +        if (local->op_ret >= 0) { +            local->op_ret = op_ret; +            local->op_errno = op_errno; +        } +    } +    dump_plain_text(local, avec); + +    gf_log("crypt", GF_LOG_DEBUG, +           "readv: ret_to_user: %d, iovec len: %d, ia_size: %llu", +           (int)(local->rw_count > 0 ? local->rw_count : local->op_ret), +           (int)(local->rw_count > 0 ? iov_length(avec, local->data_conf.acount) +                                     : 0), +           (unsigned long long)local->buf.ia_size); + +    CRYPT_STACK_UNWIND( +        readv, frame, local->rw_count > 0 ? local->rw_count : local->op_ret, +        local->op_errno, avec, avec ? local->data_conf.acount : 0, &local->buf, +        local->iobref, local_xdata); + +    free_avec(avec, pool, blocks_in_pool); +    fd_unref(local_fd); +    if (local_xdata) +        dict_unref(local_xdata); +    if (iobref) +        iobref_unref(iobref); +    if (iobref_data) +        iobref_unref(iobref_data); +    return 0; +} + +static void +crypt_readv_done(call_frame_t *frame, xlator_t *this) +{ +    if (parent_is_crypt_xlator(frame, this)) +        /* +         *  don't unlock (it will be done by the parent) +         */ +        __crypt_readv_done(frame, NULL, this, 0, 0, NULL); +    else { +        crypt_local_t *local = frame->local; +        struct gf_flock lock = { +            0, +        }; + +        lock.l_type = F_UNLCK; +        lock.l_whence = SEEK_SET; +        lock.l_start = 0; +        lock.l_len = 0; +        lock.l_pid = 0; + +        STACK_WIND(frame, __crypt_readv_done, FIRST_CHILD(this), +                   FIRST_CHILD(this)->fops->finodelk, this->name, local->fd, +                   F_SETLKW, &lock, NULL); +    } +} + +static void +put_one_call_readv(call_frame_t *frame, xlator_t *this) +{ +    crypt_local_t *local = frame->local; +    if (put_one_call(local)) +        crypt_readv_done(frame, this); +} + +static int32_t +__crypt_writev_done(call_frame_t *frame, void *cookie, xlator_t *this, +                    int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ +    crypt_local_t *local = frame->local; +    fd_t *local_fd = local->fd; +    dict_t *local_xdata = local->xdata; +    int32_t ret_to_user; + +    if (local->xattr) +        dict_unref(local->xattr); +    /* +     * Calculate amount of butes to be returned +     * to user. We need to subtract paddings that +     * have been written as a part of atom. +     */ +    /* +     * subtract head padding +     */ +    if (local->rw_count == 0) +        /* +         * Nothing has been written, it must be an error +         */ +        ret_to_user = local->op_ret; +    else if (local->rw_count <= local->data_conf.off_in_head) { +        gf_log("crypt", GF_LOG_WARNING, "Incomplete write"); +        ret_to_user = 0; +    } else +        ret_to_user = local->rw_count - local->data_conf.off_in_head; +    /* +     * subtract tail padding +     */ +    if (ret_to_user > local->data_conf.orig_size) +        ret_to_user = local->data_conf.orig_size; + +    if (local->iobref) +        iobref_unref(local->iobref); +    if (local->iobref_data) +        iobref_unref(local->iobref_data); +    free_avec_data(local); +    free_avec_hole(local); + +    gf_log("crypt", GF_LOG_DEBUG, "writev: ret_to_user: %d", ret_to_user); + +    CRYPT_STACK_UNWIND(writev, frame, ret_to_user, local->op_errno, +                       &local->prebuf, &local->postbuf, local_xdata); +    fd_unref(local_fd); +    if (local_xdata) +        dict_unref(local_xdata); +    return 0; +} + +static int32_t +crypt_writev_done(call_frame_t *frame, void *cookie, xlator_t *this, +                  int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ +    crypt_local_t *local = frame->local; + +    if (op_ret < 0) +        gf_log("crypt", GF_LOG_WARNING, "can not update file size"); + +    if (parent_is_crypt_xlator(frame, this)) +        /* +         * don't unlock (it will be done by the parent) +         */ +        __crypt_writev_done(frame, NULL, this, 0, 0, NULL); +    else { +        struct gf_flock lock = { +            0, +        }; + +        lock.l_type = F_UNLCK; +        lock.l_whence = SEEK_SET; +        lock.l_start = 0; +        lock.l_len = 0; +        lock.l_pid = 0; + +        STACK_WIND(frame, __crypt_writev_done, FIRST_CHILD(this), +                   FIRST_CHILD(this)->fops->finodelk, this->name, local->fd, +                   F_SETLKW, &lock, NULL); +    } +    return 0; +} + +static void +put_one_call_writev(call_frame_t *frame, xlator_t *this) +{ +    crypt_local_t *local = frame->local; +    if (put_one_call(local)) { +        if (local->update_disk_file_size) { +            int32_t ret; +            /* +             * update file size, unlock the file and unwind +             */ +            ret = dict_set(local->xattr, FSIZE_XATTR_PREFIX, +                           data_from_uint64(local->cur_file_size)); +            if (ret) { +                gf_log("crypt", GF_LOG_WARNING, +                       "can not set key to update file size"); +                crypt_writev_done(frame, NULL, this, 0, 0, NULL); +                return; +            } +            gf_log("crypt", GF_LOG_DEBUG, "Updating disk file size to %llu", +                   (unsigned long long)local->cur_file_size); +            STACK_WIND(frame, crypt_writev_done, FIRST_CHILD(this), +                       FIRST_CHILD(this)->fops->fsetxattr, local->fd, +                       local->xattr, /* CRYPTO_FORMAT_PREFIX */ +                       0, NULL); +        } else +            crypt_writev_done(frame, NULL, this, 0, 0, NULL); +    } +} + +static int32_t +__crypt_ftruncate_done(call_frame_t *frame, void *cookie, xlator_t *this, +                       int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ +    crypt_local_t *local = frame->local; +    fd_t *local_fd = local->fd; +    dict_t *local_xdata = local->xdata; +    char *iobase = local->vec.iov_base; + +    if (op_ret < 0) { +        gf_log(this->name, GF_LOG_WARNING, "ftruncate unlock failed (%d)", +               op_errno); +        if (local->op_ret >= 0) { +            local->op_ret = op_ret; +            local->op_errno = op_errno; +        } +    } +    if (local->iobref_data) +        iobref_unref(local->iobref_data); +    free_avec_data(local); +    free_avec_hole(local); + +    gf_log("crypt", GF_LOG_DEBUG, +           "ftruncate, return to user: presize=%llu, postsize=%llu", +           (unsigned long long)local->prebuf.ia_size, +           (unsigned long long)local->postbuf.ia_size); + +    CRYPT_STACK_UNWIND(ftruncate, frame, ((local->op_ret < 0) ? -1 : 0), +                       local->op_errno, &local->prebuf, &local->postbuf, +                       local_xdata); +    fd_unref(local_fd); +    if (local_xdata) +        dict_unref(local_xdata); +    if (iobase) +        GF_FREE(iobase); +    return 0; +} + +static int32_t +crypt_ftruncate_done(call_frame_t *frame, void *cookie, xlator_t *this, +                     int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ +    crypt_local_t *local = frame->local; +    struct gf_flock lock = { +        0, +    }; + +    dict_unref(local->xattr); +    if (op_ret < 0) +        gf_log("crypt", GF_LOG_WARNING, "can not update file size"); + +    lock.l_type = F_UNLCK; +    lock.l_whence = SEEK_SET; +    lock.l_start = 0; +    lock.l_len = 0; +    lock.l_pid = 0; + +    STACK_WIND(frame, __crypt_ftruncate_done, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->finodelk, this->name, local->fd, +               F_SETLKW, &lock, NULL); +    return 0; +} + +static void +put_one_call_ftruncate(call_frame_t *frame, xlator_t *this) +{ +    crypt_local_t *local = frame->local; +    if (put_one_call(local)) { +        if (local->update_disk_file_size) { +            int32_t ret; +            /* +             * update file size, unlock the file and unwind +             */ +            ret = dict_set(local->xattr, FSIZE_XATTR_PREFIX, +                           data_from_uint64(local->cur_file_size)); +            if (ret) { +                gf_log("crypt", GF_LOG_WARNING, +                       "can not set key to update file size"); +                crypt_ftruncate_done(frame, NULL, this, 0, 0, NULL); +                return; +            } +            gf_log("crypt", GF_LOG_DEBUG, "Updating disk file size to %llu", +                   (unsigned long long)local->cur_file_size); +            STACK_WIND(frame, crypt_ftruncate_done, FIRST_CHILD(this), +                       FIRST_CHILD(this)->fops->fsetxattr, local->fd, +                       local->xattr, /* CRYPTO_FORMAT_PREFIX */ +                       0, NULL); +        } else +            crypt_ftruncate_done(frame, NULL, this, 0, 0, NULL); +    }  }  /*   * load regular file size for some FOPs   */ -static int32_t load_file_size(call_frame_t *frame, -			      void *cookie, -			      xlator_t *this, -			      int32_t op_ret, -			      int32_t op_errno, -			      dict_t *dict, -			      dict_t *xdata) -{ -	data_t *data; -	crypt_local_t *local = frame->local; - -	dict_t *local_xdata = local->xdata; -	inode_t *local_inode = local->inode; - -	if (op_ret < 0) -		goto unwind; -	/* -	 * load regular file size -	 */ -	data = dict_get(dict, FSIZE_XATTR_PREFIX); -	if (!data) { -		if (local->xdata) -			dict_unref(local->xdata); -		gf_log("crypt", GF_LOG_WARNING, "Regular file size not found"); -		op_ret = -1; -		op_errno = EIO; -		goto unwind; -	} -	local->buf.ia_size = data_to_uint64(data); - -	gf_log(this->name, GF_LOG_DEBUG, -	       "FOP %d: Translate regular file to %llu", -	       local->fop, -	       (unsigned long long)local->buf.ia_size); - unwind: -	if (local->fd) -		fd_unref(local->fd); -	if (local->loc) { -		loc_wipe(local->loc); -		GF_FREE(local->loc); -	} -	switch (local->fop) { -	case GF_FOP_FSTAT: -		CRYPT_STACK_UNWIND(fstat, -				   frame, -				   op_ret, -				   op_errno, -				   op_ret >= 0 ? &local->buf : NULL, -				   local->xdata); -		break; -	case GF_FOP_STAT: -		CRYPT_STACK_UNWIND(stat, -				   frame, -				   op_ret, -				   op_errno, -				   op_ret >= 0 ? &local->buf : NULL, -				   local->xdata); -		break; -	case GF_FOP_LOOKUP: -		CRYPT_STACK_UNWIND(lookup, -				   frame, -				   op_ret, -				   op_errno, -				   op_ret >= 0 ? local->inode : NULL, -				   op_ret >= 0 ? &local->buf : NULL, -				   local->xdata, -				   op_ret >= 0 ? &local->postbuf : NULL); -		break; -	case GF_FOP_READ: -		CRYPT_STACK_UNWIND(readv, -				   frame, -				   op_ret, -				   op_errno, -				   NULL, -				   0, -				   op_ret >= 0 ? &local->buf : NULL, -				   NULL, -				   NULL); -		break; -	default: -		gf_log(this->name, GF_LOG_WARNING, -		       "Improper file operation %d", local->fop); -	} -	if (local_xdata) -		dict_unref(local_xdata); -	if (local_inode) -		inode_unref(local_inode); -	return 0; -} - -static int32_t crypt_stat_common_cbk(call_frame_t *frame, -				     void *cookie, -				     xlator_t *this, -				     int32_t op_ret, -				     int32_t op_errno, -				     struct iatt *buf, dict_t *xdata) -{ -	crypt_local_t *local = frame->local; - -	if (op_ret < 0) -		goto unwind; -	if (!IA_ISREG(buf->ia_type)) -		goto unwind; - -	local->buf = *buf; -	if (xdata) -		local->xdata = dict_ref(xdata); - -	switch (local->fop) { -	case GF_FOP_FSTAT: -		STACK_WIND(frame, -			   load_file_size, -			   FIRST_CHILD(this), -			   FIRST_CHILD(this)->fops->fgetxattr, -			   local->fd, -			   FSIZE_XATTR_PREFIX, -			   NULL); -		break; -	case GF_FOP_STAT: -		STACK_WIND(frame, -			   load_file_size, -			   FIRST_CHILD(this), -			   FIRST_CHILD(this)->fops->getxattr, -			   local->loc, -			   FSIZE_XATTR_PREFIX, -			   NULL); -		break; -	default: -		gf_log (this->name, GF_LOG_WARNING, -			"Improper file operation %d", local->fop); -	} -	return 0; - unwind: -	if (local->fd) -		fd_unref(local->fd); -	if (local->loc) { -		loc_wipe(local->loc); -		GF_FREE(local->loc); -	} -	switch (local->fop) { -	case GF_FOP_FSTAT: -		CRYPT_STACK_UNWIND(fstat, -				   frame, -				   op_ret, -				   op_errno, -				   op_ret >= 0 ? buf : NULL, -				   op_ret >= 0 ? xdata : NULL); -		break; -	case GF_FOP_STAT: -		CRYPT_STACK_UNWIND(stat, -				   frame, -				   op_ret, -				   op_errno, -				   op_ret >= 0 ? buf : NULL, -				   op_ret >= 0 ? xdata : NULL); -		break; -	default: -		gf_log (this->name, GF_LOG_WARNING, -			"Improper file operation %d", local->fop); -	} -	return 0; -} - -static int32_t crypt_fstat(call_frame_t *frame, -			   xlator_t *this, -			   fd_t *fd, dict_t *xdata) -{ -	crypt_local_t *local; - -	local = crypt_alloc_local(frame, this, GF_FOP_FSTAT); -	if (!local) -		goto error; -	local->fd = fd_ref(fd); -	STACK_WIND(frame, -		   crypt_stat_common_cbk, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->fstat, -		   fd, -		   xdata); -	return 0; - error: -	CRYPT_STACK_UNWIND(fstat, -			   frame, -			   -1, -			   ENOMEM, -			   NULL, -			   NULL); -	return 0; -} - -static int32_t crypt_stat(call_frame_t *frame, -			  xlator_t *this, -			  loc_t *loc, dict_t *xdata) -{ -	int32_t ret; -	crypt_local_t *local; - -	local = crypt_alloc_local(frame, this, GF_FOP_STAT); -	if (!local) -		goto error; -	local->loc = GF_CALLOC(1, sizeof(loc_t), gf_crypt_mt_loc); -	if (!local->loc) -		goto error; -	ret = loc_copy(local->loc, loc); -	if (ret) { -		GF_FREE(local->loc); -		goto error; -	} -	STACK_WIND(frame, -		   crypt_stat_common_cbk, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->stat, -		   loc, -		   xdata); -	return 0; - error: -	CRYPT_STACK_UNWIND(stat, -			   frame, -			   -1, -			   ENOMEM, -			   NULL, -			   NULL); -	return 0; -} - -static int32_t crypt_lookup_cbk(call_frame_t *frame, -				void *cookie, -				xlator_t *this, -				int32_t op_ret, -				int32_t op_errno, -				inode_t *inode, -				struct iatt *buf, dict_t *xdata, -				struct iatt *postparent) -{ -	crypt_local_t *local = frame->local; - -	if (op_ret < 0) -		goto unwind; -	if (!IA_ISREG(buf->ia_type)) -		goto unwind; - -	local->inode = inode_ref(inode); -	local->buf = *buf; -	local->postbuf = *postparent; -	if (xdata) -		local->xdata = dict_ref(xdata); -	gf_uuid_copy(local->loc->gfid, buf->ia_gfid); - -	STACK_WIND(frame, -		   load_file_size, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->getxattr, -		   local->loc, -		   FSIZE_XATTR_PREFIX, -		   NULL); -	return 0; - unwind: -	loc_wipe(local->loc); -	GF_FREE(local->loc); -	CRYPT_STACK_UNWIND(lookup, -			   frame, -			   op_ret, -			   op_errno, -			   inode, -			   buf, -			   xdata, -			   postparent); -	return 0; -} - -static int32_t crypt_lookup(call_frame_t *frame, -			    xlator_t *this, -			    loc_t *loc, dict_t *xdata) -{ -	int32_t ret; -	crypt_local_t *local; - -	local = crypt_alloc_local(frame, this, GF_FOP_LOOKUP); -	if (!local) -		goto error; -	local->loc = GF_CALLOC(1, sizeof(loc_t), gf_crypt_mt_loc); -	if (!local->loc) -		goto error; -	ret = loc_copy(local->loc, loc); -	if (ret) { -		GF_FREE(local->loc); -		goto error; -	} -	gf_log(this->name, GF_LOG_DEBUG, "Lookup %s", loc->path); -	STACK_WIND(frame, -		   crypt_lookup_cbk, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->lookup, -		   loc, -		   xdata); -	return 0; - error: -	CRYPT_STACK_UNWIND(lookup, -			   frame, -			   -1, -			   ENOMEM, -			   NULL, -			   NULL, -			   NULL, -			   NULL); -	return 0; +static int32_t +load_file_size(call_frame_t *frame, void *cookie, xlator_t *this, +               int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) +{ +    data_t *data; +    crypt_local_t *local = frame->local; + +    dict_t *local_xdata = local->xdata; +    inode_t *local_inode = local->inode; + +    if (op_ret < 0) +        goto unwind; +    /* +     * load regular file size +     */ +    data = dict_get(dict, FSIZE_XATTR_PREFIX); +    if (!data) { +        if (local->xdata) +            dict_unref(local->xdata); +        gf_log("crypt", GF_LOG_WARNING, "Regular file size not found"); +        op_ret = -1; +        op_errno = EIO; +        goto unwind; +    } +    local->buf.ia_size = data_to_uint64(data); + +    gf_log(this->name, GF_LOG_DEBUG, "FOP %d: Translate regular file to %llu", +           local->fop, (unsigned long long)local->buf.ia_size); +unwind: +    if (local->fd) +        fd_unref(local->fd); +    if (local->loc) { +        loc_wipe(local->loc); +        GF_FREE(local->loc); +    } +    switch (local->fop) { +        case GF_FOP_FSTAT: +            CRYPT_STACK_UNWIND(fstat, frame, op_ret, op_errno, +                               op_ret >= 0 ? &local->buf : NULL, local->xdata); +            break; +        case GF_FOP_STAT: +            CRYPT_STACK_UNWIND(stat, frame, op_ret, op_errno, +                               op_ret >= 0 ? &local->buf : NULL, local->xdata); +            break; +        case GF_FOP_LOOKUP: +            CRYPT_STACK_UNWIND(lookup, frame, op_ret, op_errno, +                               op_ret >= 0 ? local->inode : NULL, +                               op_ret >= 0 ? &local->buf : NULL, local->xdata, +                               op_ret >= 0 ? &local->postbuf : NULL); +            break; +        case GF_FOP_READ: +            CRYPT_STACK_UNWIND(readv, frame, op_ret, op_errno, NULL, 0, +                               op_ret >= 0 ? &local->buf : NULL, NULL, NULL); +            break; +        default: +            gf_log(this->name, GF_LOG_WARNING, "Improper file operation %d", +                   local->fop); +    } +    if (local_xdata) +        dict_unref(local_xdata); +    if (local_inode) +        inode_unref(local_inode); +    return 0; +} + +static int32_t +crypt_stat_common_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                      int32_t op_ret, int32_t op_errno, struct iatt *buf, +                      dict_t *xdata) +{ +    crypt_local_t *local = frame->local; + +    if (op_ret < 0) +        goto unwind; +    if (!IA_ISREG(buf->ia_type)) +        goto unwind; + +    local->buf = *buf; +    if (xdata) +        local->xdata = dict_ref(xdata); + +    switch (local->fop) { +        case GF_FOP_FSTAT: +            STACK_WIND(frame, load_file_size, FIRST_CHILD(this), +                       FIRST_CHILD(this)->fops->fgetxattr, local->fd, +                       FSIZE_XATTR_PREFIX, NULL); +            break; +        case GF_FOP_STAT: +            STACK_WIND(frame, load_file_size, FIRST_CHILD(this), +                       FIRST_CHILD(this)->fops->getxattr, local->loc, +                       FSIZE_XATTR_PREFIX, NULL); +            break; +        default: +            gf_log(this->name, GF_LOG_WARNING, "Improper file operation %d", +                   local->fop); +    } +    return 0; +unwind: +    if (local->fd) +        fd_unref(local->fd); +    if (local->loc) { +        loc_wipe(local->loc); +        GF_FREE(local->loc); +    } +    switch (local->fop) { +        case GF_FOP_FSTAT: +            CRYPT_STACK_UNWIND(fstat, frame, op_ret, op_errno, +                               op_ret >= 0 ? buf : NULL, +                               op_ret >= 0 ? xdata : NULL); +            break; +        case GF_FOP_STAT: +            CRYPT_STACK_UNWIND(stat, frame, op_ret, op_errno, +                               op_ret >= 0 ? buf : NULL, +                               op_ret >= 0 ? xdata : NULL); +            break; +        default: +            gf_log(this->name, GF_LOG_WARNING, "Improper file operation %d", +                   local->fop); +    } +    return 0; +} + +static int32_t +crypt_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) +{ +    crypt_local_t *local; + +    local = crypt_alloc_local(frame, this, GF_FOP_FSTAT); +    if (!local) +        goto error; +    local->fd = fd_ref(fd); +    STACK_WIND(frame, crypt_stat_common_cbk, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->fstat, fd, xdata); +    return 0; +error: +    CRYPT_STACK_UNWIND(fstat, frame, -1, ENOMEM, NULL, NULL); +    return 0; +} + +static int32_t +crypt_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) +{ +    int32_t ret; +    crypt_local_t *local; + +    local = crypt_alloc_local(frame, this, GF_FOP_STAT); +    if (!local) +        goto error; +    local->loc = GF_CALLOC(1, sizeof(loc_t), gf_crypt_mt_loc); +    if (!local->loc) +        goto error; +    ret = loc_copy(local->loc, loc); +    if (ret) { +        GF_FREE(local->loc); +        goto error; +    } +    STACK_WIND(frame, crypt_stat_common_cbk, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->stat, loc, xdata); +    return 0; +error: +    CRYPT_STACK_UNWIND(stat, frame, -1, ENOMEM, NULL, NULL); +    return 0; +} + +static int32_t +crypt_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                 int32_t op_ret, int32_t op_errno, inode_t *inode, +                 struct iatt *buf, dict_t *xdata, struct iatt *postparent) +{ +    crypt_local_t *local = frame->local; + +    if (op_ret < 0) +        goto unwind; +    if (!IA_ISREG(buf->ia_type)) +        goto unwind; + +    local->inode = inode_ref(inode); +    local->buf = *buf; +    local->postbuf = *postparent; +    if (xdata) +        local->xdata = dict_ref(xdata); +    gf_uuid_copy(local->loc->gfid, buf->ia_gfid); + +    STACK_WIND(frame, load_file_size, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->getxattr, local->loc, +               FSIZE_XATTR_PREFIX, NULL); +    return 0; +unwind: +    loc_wipe(local->loc); +    GF_FREE(local->loc); +    CRYPT_STACK_UNWIND(lookup, frame, op_ret, op_errno, inode, buf, xdata, +                       postparent); +    return 0; +} + +static int32_t +crypt_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) +{ +    int32_t ret; +    crypt_local_t *local; + +    local = crypt_alloc_local(frame, this, GF_FOP_LOOKUP); +    if (!local) +        goto error; +    local->loc = GF_CALLOC(1, sizeof(loc_t), gf_crypt_mt_loc); +    if (!local->loc) +        goto error; +    ret = loc_copy(local->loc, loc); +    if (ret) { +        GF_FREE(local->loc); +        goto error; +    } +    gf_log(this->name, GF_LOG_DEBUG, "Lookup %s", loc->path); +    STACK_WIND(frame, crypt_lookup_cbk, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->lookup, loc, xdata); +    return 0; +error: +    CRYPT_STACK_UNWIND(lookup, frame, -1, ENOMEM, NULL, NULL, NULL, NULL); +    return 0;  }  /*   * for every regular directory entry find its real file size   * and update stat's buf properly   */ -static int32_t crypt_readdirp_cbk(call_frame_t *frame, -				  void *cookie, -				  xlator_t *this, -				  int32_t op_ret, -				  int32_t op_errno, -				  gf_dirent_t *entries, dict_t *xdata) -{ -	gf_dirent_t *entry = NULL; - -	if (op_ret < 0) -		goto unwind; - -	list_for_each_entry (entry, (&entries->list), list) { -		data_t *data; - -		if (!IA_ISREG(entry->d_stat.ia_type)) -			continue; -		data = dict_get(entry->dict, FSIZE_XATTR_PREFIX); -		if (!data){ -			gf_log("crypt", GF_LOG_WARNING, -			       "Regular file size of direntry not found"); -			op_errno = EIO; -			op_ret = -1; -			break; -		} -		entry->d_stat.ia_size = data_to_uint64(data); -	} - unwind: -	CRYPT_STACK_UNWIND(readdirp, frame, op_ret, op_errno, entries, xdata); -	return 0; +static int32_t +crypt_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                   int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, +                   dict_t *xdata) +{ +    gf_dirent_t *entry = NULL; + +    if (op_ret < 0) +        goto unwind; + +    list_for_each_entry(entry, (&entries->list), list) +    { +        data_t *data; + +        if (!IA_ISREG(entry->d_stat.ia_type)) +            continue; +        data = dict_get(entry->dict, FSIZE_XATTR_PREFIX); +        if (!data) { +            gf_log("crypt", GF_LOG_WARNING, +                   "Regular file size of direntry not found"); +            op_errno = EIO; +            op_ret = -1; +            break; +        } +        entry->d_stat.ia_size = data_to_uint64(data); +    } +unwind: +    CRYPT_STACK_UNWIND(readdirp, frame, op_ret, op_errno, entries, xdata); +    return 0;  }  /* @@ -4116,401 +3506,392 @@ static int32_t crypt_readdirp_cbk(call_frame_t *frame,   * file sizes for all directory entries of the parent @fd.   * Actual updates take place in ->crypt_readdirp_cbk()   */ -static int32_t crypt_readdirp(call_frame_t *frame, xlator_t *this, -			      fd_t *fd, size_t size, off_t offset, -			      dict_t *xdata) -{ -	int32_t ret = ENOMEM; - -	if (!xdata) { -		xdata = dict_new(); -		if (!xdata) -			goto error; -	} -	else -		dict_ref(xdata); -	/* -	 * make sure that we'll have real file sizes at ->readdirp_cbk() -	 */ -	ret = dict_set(xdata, FSIZE_XATTR_PREFIX, data_from_uint64(0)); -	if (ret) { -		dict_unref(xdata); -                ret = ENOMEM; -		goto error; -	} -	STACK_WIND(frame, -		   crypt_readdirp_cbk, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->readdirp, -		   fd, -		   size, -		   offset, -		   xdata); -	dict_unref(xdata); -	return 0; - error: -	CRYPT_STACK_UNWIND(readdirp, frame, -1, ret, NULL, NULL); -	return 0; -} - -static int32_t crypt_access(call_frame_t *frame, -			    xlator_t *this, -			    loc_t *loc, -			    int32_t mask, dict_t *xdata) -{ -	gf_log(this->name, GF_LOG_WARNING, -	       "NFS mounts of encrypted volumes are unsupported"); -	CRYPT_STACK_UNWIND(access, frame, -1, EPERM, NULL); -	return 0; -} - -int32_t master_set_block_size (xlator_t *this, crypt_private_t *priv, -			       dict_t *options) -{ -	uint64_t block_size = 0; -	struct master_cipher_info *master = get_master_cinfo(priv); - -	if (options != NULL) -		GF_OPTION_RECONF("block-size", block_size, options, -				 size_uint64, error); -	else -		GF_OPTION_INIT("block-size", block_size, size_uint64, error); - -	switch (block_size) { -	case 512: -		master->m_block_bits = 9; -		break; -	case 1024: -		master->m_block_bits = 10; -		break; -	case 2048: -		master->m_block_bits = 11; -		break; -	case 4096: -		master->m_block_bits = 12; -		break; -	default: -		gf_log("crypt", GF_LOG_ERROR, -		       "FATAL: unsupported block size %llu", -		       (unsigned long long)block_size); -		goto error; -	} -	return 0; - error: -	return -1; -} - -int32_t master_set_alg(xlator_t *this, crypt_private_t *priv) -{ -	struct master_cipher_info *master = get_master_cinfo(priv); -	master->m_alg = AES_CIPHER_ALG; -	return 0; -} - -int32_t master_set_mode(xlator_t *this, crypt_private_t *priv) -{ -	struct master_cipher_info *master = get_master_cinfo(priv); -	master->m_mode = XTS_CIPHER_MODE; -	return 0; +static int32_t +crypt_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, +               off_t offset, dict_t *xdata) +{ +    int32_t ret = ENOMEM; + +    if (!xdata) { +        xdata = dict_new(); +        if (!xdata) +            goto error; +    } else +        dict_ref(xdata); +    /* +     * make sure that we'll have real file sizes at ->readdirp_cbk() +     */ +    ret = dict_set(xdata, FSIZE_XATTR_PREFIX, data_from_uint64(0)); +    if (ret) { +        dict_unref(xdata); +        ret = ENOMEM; +        goto error; +    } +    STACK_WIND(frame, crypt_readdirp_cbk, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->readdirp, fd, size, offset, xdata); +    dict_unref(xdata); +    return 0; +error: +    CRYPT_STACK_UNWIND(readdirp, frame, -1, ret, NULL, NULL); +    return 0; +} + +static int32_t +crypt_access(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask, +             dict_t *xdata) +{ +    gf_log(this->name, GF_LOG_WARNING, +           "NFS mounts of encrypted volumes are unsupported"); +    CRYPT_STACK_UNWIND(access, frame, -1, EPERM, NULL); +    return 0; +} + +int32_t +master_set_block_size(xlator_t *this, crypt_private_t *priv, dict_t *options) +{ +    uint64_t block_size = 0; +    struct master_cipher_info *master = get_master_cinfo(priv); + +    if (options != NULL) +        GF_OPTION_RECONF("block-size", block_size, options, size_uint64, error); +    else +        GF_OPTION_INIT("block-size", block_size, size_uint64, error); + +    switch (block_size) { +        case 512: +            master->m_block_bits = 9; +            break; +        case 1024: +            master->m_block_bits = 10; +            break; +        case 2048: +            master->m_block_bits = 11; +            break; +        case 4096: +            master->m_block_bits = 12; +            break; +        default: +            gf_log("crypt", GF_LOG_ERROR, "FATAL: unsupported block size %llu", +                   (unsigned long long)block_size); +            goto error; +    } +    return 0; +error: +    return -1; +} + +int32_t +master_set_alg(xlator_t *this, crypt_private_t *priv) +{ +    struct master_cipher_info *master = get_master_cinfo(priv); +    master->m_alg = AES_CIPHER_ALG; +    return 0; +} + +int32_t +master_set_mode(xlator_t *this, crypt_private_t *priv) +{ +    struct master_cipher_info *master = get_master_cinfo(priv); +    master->m_mode = XTS_CIPHER_MODE; +    return 0;  }  /*   * set key size in bits to the master info   * Pre-conditions: cipher mode in the master info is uptodate.   */ -static int master_set_data_key_size (xlator_t *this, crypt_private_t *priv, -				     dict_t *options) -{ -	int32_t ret; -	uint64_t key_size = 0; -	struct master_cipher_info *master = get_master_cinfo(priv); - -	if (options != NULL) -		GF_OPTION_RECONF("data-key-size", key_size, options, -				 uint64, error); -	else -		GF_OPTION_INIT("data-key-size", key_size, uint64, error); - -	ret = data_cipher_algs[master->m_alg][master->m_mode].check_key(key_size); -	if (ret) { -		gf_log("crypt", GF_LOG_ERROR, -		       "FATAL: wrong bin key size %llu for alg %d mode %d", -		       (unsigned long long)key_size, -		       (int)master->m_alg, -		       (int)master->m_mode); -		goto error; -	} -	master->m_dkey_size = key_size; -	return 0; - error: -	return -1; -} - -static int is_hex(char *s) { -	return  ('0' <= *s && *s <= '9') || ('a' <= *s && *s <= 'f'); -} - -static int parse_hex_buf(xlator_t *this, char *src, unsigned char *dst, -			 int hex_size) -{ -	int i; -	int hex_byte = 0; - -	for (i = 0; i < (hex_size / 2); i++) { -		if (!is_hex(src + i*2) || !is_hex(src + i*2 + 1)) { -			gf_log("crypt", GF_LOG_ERROR, -			       "FATAL: not hex symbol in key"); -			return -1; -		} -		if (sscanf(src + i*2, "%2x", &hex_byte) != 1) { -			gf_log("crypt", GF_LOG_ERROR, -			       "FATAL: can not parse hex key"); -			return -1; -		} -		dst[i] = hex_byte & 0xff; -	} -	return 0; +static int +master_set_data_key_size(xlator_t *this, crypt_private_t *priv, dict_t *options) +{ +    int32_t ret; +    uint64_t key_size = 0; +    struct master_cipher_info *master = get_master_cinfo(priv); + +    if (options != NULL) +        GF_OPTION_RECONF("data-key-size", key_size, options, uint64, error); +    else +        GF_OPTION_INIT("data-key-size", key_size, uint64, error); + +    ret = data_cipher_algs[master->m_alg][master->m_mode].check_key(key_size); +    if (ret) { +        gf_log("crypt", GF_LOG_ERROR, +               "FATAL: wrong bin key size %llu for alg %d mode %d", +               (unsigned long long)key_size, (int)master->m_alg, +               (int)master->m_mode); +        goto error; +    } +    master->m_dkey_size = key_size; +    return 0; +error: +    return -1; +} + +static int +is_hex(char *s) +{ +    return ('0' <= *s && *s <= '9') || ('a' <= *s && *s <= 'f'); +} + +static int +parse_hex_buf(xlator_t *this, char *src, unsigned char *dst, int hex_size) +{ +    int i; +    int hex_byte = 0; + +    for (i = 0; i < (hex_size / 2); i++) { +        if (!is_hex(src + i * 2) || !is_hex(src + i * 2 + 1)) { +            gf_log("crypt", GF_LOG_ERROR, "FATAL: not hex symbol in key"); +            return -1; +        } +        if (sscanf(src + i * 2, "%2x", &hex_byte) != 1) { +            gf_log("crypt", GF_LOG_ERROR, "FATAL: can not parse hex key"); +            return -1; +        } +        dst[i] = hex_byte & 0xff; +    } +    return 0;  }  /*   * Parse options;   * install master volume key   */ -int32_t master_set_master_vol_key(xlator_t *this, crypt_private_t *priv) -{ -	int32_t ret; -	FILE *file = NULL; - -	int32_t key_size; -	char *opt_key_file_pathname = NULL; - -	unsigned char bin_buf[MASTER_VOL_KEY_SIZE]; -	char hex_buf[2 * MASTER_VOL_KEY_SIZE]; - -	struct master_cipher_info *master = get_master_cinfo(priv); -	/* -	 * extract master key passed via option -	 */ -	GF_OPTION_INIT("master-key", opt_key_file_pathname, path, bad_key); - -	if (!opt_key_file_pathname) { -		gf_log(this->name, GF_LOG_ERROR, "FATAL: missing master key"); -		return -1; -	} -	gf_log(this->name, GF_LOG_DEBUG, "handling file key %s", -	       opt_key_file_pathname); - -	file = fopen(opt_key_file_pathname, "r"); -	if (file == NULL) { -		gf_log(this->name, GF_LOG_ERROR, -		       "FATAL: can not open file with master key"); -		return -1; -	} -	/* -	 * extract hex key -	 */ -	key_size = fread(hex_buf, 1, sizeof(hex_buf), file); -	if (key_size < sizeof(hex_buf)) { -		gf_log(this->name, GF_LOG_ERROR, -		       "FATAL: master key is too short"); -		goto bad_key; -	} -	ret = parse_hex_buf(this, hex_buf, bin_buf, key_size); -	if (ret) -		goto bad_key; -	memcpy(master->m_key, bin_buf, MASTER_VOL_KEY_SIZE); -	memset(hex_buf, 0, sizeof(hex_buf)); -	fclose(file); - - 	memset(bin_buf, 0, sizeof(bin_buf)); -	return 0; - bad_key: -	gf_log(this->name, GF_LOG_ERROR, "FATAL: bad master key"); -	if (file) -		fclose(file); -	memset(bin_buf, 0, sizeof(bin_buf)); -	return -1; +int32_t +master_set_master_vol_key(xlator_t *this, crypt_private_t *priv) +{ +    int32_t ret; +    FILE *file = NULL; + +    int32_t key_size; +    char *opt_key_file_pathname = NULL; + +    unsigned char bin_buf[MASTER_VOL_KEY_SIZE]; +    char hex_buf[2 * MASTER_VOL_KEY_SIZE]; + +    struct master_cipher_info *master = get_master_cinfo(priv); +    /* +     * extract master key passed via option +     */ +    GF_OPTION_INIT("master-key", opt_key_file_pathname, path, bad_key); + +    if (!opt_key_file_pathname) { +        gf_log(this->name, GF_LOG_ERROR, "FATAL: missing master key"); +        return -1; +    } +    gf_log(this->name, GF_LOG_DEBUG, "handling file key %s", +           opt_key_file_pathname); + +    file = fopen(opt_key_file_pathname, "r"); +    if (file == NULL) { +        gf_log(this->name, GF_LOG_ERROR, +               "FATAL: can not open file with master key"); +        return -1; +    } +    /* +     * extract hex key +     */ +    key_size = fread(hex_buf, 1, sizeof(hex_buf), file); +    if (key_size < sizeof(hex_buf)) { +        gf_log(this->name, GF_LOG_ERROR, "FATAL: master key is too short"); +        goto bad_key; +    } +    ret = parse_hex_buf(this, hex_buf, bin_buf, key_size); +    if (ret) +        goto bad_key; +    memcpy(master->m_key, bin_buf, MASTER_VOL_KEY_SIZE); +    memset(hex_buf, 0, sizeof(hex_buf)); +    fclose(file); + +    memset(bin_buf, 0, sizeof(bin_buf)); +    return 0; +bad_key: +    gf_log(this->name, GF_LOG_ERROR, "FATAL: bad master key"); +    if (file) +        fclose(file); +    memset(bin_buf, 0, sizeof(bin_buf)); +    return -1;  }  /*   * Derive volume key for object-id authentication   */ -int32_t master_set_nmtd_vol_key(xlator_t *this, crypt_private_t *priv) +int32_t +master_set_nmtd_vol_key(xlator_t *this, crypt_private_t *priv)  { -	return get_nmtd_vol_key(get_master_cinfo(priv)); +    return get_nmtd_vol_key(get_master_cinfo(priv));  } -int32_t crypt_init_xlator(xlator_t *this) +int32_t +crypt_init_xlator(xlator_t *this)  { -	int32_t ret; -	crypt_private_t *priv = this->private; +    int32_t ret; +    crypt_private_t *priv = this->private; -	ret = master_set_alg(this, priv); -	if (ret) -		return ret; -	ret = master_set_mode(this, priv); -	if (ret) -		return ret; -	ret = master_set_block_size(this, priv, NULL); -	if (ret) -		return ret; -	ret = master_set_data_key_size(this, priv, NULL); -	if (ret) -		return ret; -	ret = master_set_master_vol_key(this, priv); -	if (ret) -		return ret; -	return master_set_nmtd_vol_key(this, priv); +    ret = master_set_alg(this, priv); +    if (ret) +        return ret; +    ret = master_set_mode(this, priv); +    if (ret) +        return ret; +    ret = master_set_block_size(this, priv, NULL); +    if (ret) +        return ret; +    ret = master_set_data_key_size(this, priv, NULL); +    if (ret) +        return ret; +    ret = master_set_master_vol_key(this, priv); +    if (ret) +        return ret; +    return master_set_nmtd_vol_key(this, priv);  } -static int32_t crypt_alloc_private(xlator_t *this) +static int32_t +crypt_alloc_private(xlator_t *this)  { -	this->private = GF_CALLOC(1, sizeof(crypt_private_t), gf_crypt_mt_priv); -	if (!this->private) { -		gf_log("crypt", GF_LOG_ERROR, -		       "Can not allocate memory for private data"); -		return ENOMEM; -	} -	return 0; +    this->private = GF_CALLOC(1, sizeof(crypt_private_t), gf_crypt_mt_priv); +    if (!this->private) { +        gf_log("crypt", GF_LOG_ERROR, +               "Can not allocate memory for private data"); +        return ENOMEM; +    } +    return 0;  } -static void crypt_free_private(xlator_t *this) +static void +crypt_free_private(xlator_t *this)  { -	crypt_private_t *priv = this->private; -	if (priv) { -		memset(priv, 0, sizeof(*priv)); -		GF_FREE(priv); -	} +    crypt_private_t *priv = this->private; +    if (priv) { +        memset(priv, 0, sizeof(*priv)); +        GF_FREE(priv); +    }  }  int32_t -mem_acct_init (xlator_t *this) +mem_acct_init(xlator_t *this)  { -        int     ret = -1; +    int ret = -1; + +    if (!this) +        return ret; -        if (!this) -                return ret; +    ret = xlator_mem_acct_init(this, gf_crypt_mt_end); -        ret = xlator_mem_acct_init (this, gf_crypt_mt_end); +    if (ret != 0) { +        gf_log(this->name, GF_LOG_ERROR, +               "Memory accounting init" +               "failed"); +        return ret; +    } -        if (ret != 0) { -                gf_log(this->name, GF_LOG_ERROR, "Memory accounting init" -                       "failed"); -                return ret; -        } +    return ret; +} + +int32_t +reconfigure(xlator_t *this, dict_t *options) +{ +    int32_t ret = -1; +    crypt_private_t *priv = NULL; + +    GF_VALIDATE_OR_GOTO("crypt", this, error); +    GF_VALIDATE_OR_GOTO(this->name, this->private, error); +    GF_VALIDATE_OR_GOTO(this->name, options, error); + +    priv = this->private; + +    ret = master_set_block_size(this, priv, options); +    if (ret) { +        gf_log("this->name", GF_LOG_ERROR, "Failed to reconfure block size"); +        goto error; +    } +    ret = master_set_data_key_size(this, priv, options); +    if (ret) { +        gf_log("this->name", GF_LOG_ERROR, "Failed to reconfure data key size"); +        goto error; +    } +    return 0; +error: +    return ret; +} +int32_t +init(xlator_t *this) +{ +    int32_t ret; + +    if (!this->children || this->children->next) { +        gf_log("crypt", GF_LOG_ERROR, +               "FATAL: crypt should have exactly one child"); +        return EINVAL; +    } +    if (!this->parents) { +        gf_log(this->name, GF_LOG_WARNING, "dangling volume. check volfile "); +    } +    ret = crypt_alloc_private(this); +    if (ret)          return ret; +    ret = crypt_init_xlator(this); +    if (ret) +        goto error; +    this->local_pool = mem_pool_new(crypt_local_t, 64); +    if (!this->local_pool) { +        gf_log(this->name, GF_LOG_ERROR, +               "failed to create local_t's memory pool"); +        ret = ENOMEM; +        goto error; +    } +    gf_log("crypt", GF_LOG_INFO, "crypt xlator loaded"); +    return 0; +error: +    crypt_free_private(this); +    return ret;  } -int32_t reconfigure (xlator_t *this, dict_t *options) -{ -	int32_t ret = -1; -	crypt_private_t *priv = NULL; - -	GF_VALIDATE_OR_GOTO ("crypt", this, error); -	GF_VALIDATE_OR_GOTO (this->name, this->private, error); -	GF_VALIDATE_OR_GOTO (this->name, options, error); - -	priv = this->private; - -	ret = master_set_block_size(this, priv, options); -	if (ret) { -		gf_log("this->name", GF_LOG_ERROR, -		       "Failed to reconfure block size"); -		goto error; -	} -	ret = master_set_data_key_size(this, priv, options); -	if (ret) { -		gf_log("this->name", GF_LOG_ERROR, -		       "Failed to reconfure data key size"); -		goto error; -	} -	return 0; - error: -	return ret; -} - -int32_t init(xlator_t *this) -{ -	int32_t ret; - -	if (!this->children || this->children->next) { -		gf_log ("crypt", GF_LOG_ERROR, -			"FATAL: crypt should have exactly one child"); -		return EINVAL; -	} -	if (!this->parents) { -		gf_log (this->name, GF_LOG_WARNING, -			"dangling volume. check volfile "); -	} -	ret = crypt_alloc_private(this); -	if (ret) -		return ret; -	ret = crypt_init_xlator(this); -	if (ret) -		goto error; -	this->local_pool = mem_pool_new(crypt_local_t, 64); -        if (!this->local_pool) { -		gf_log(this->name, GF_LOG_ERROR, -		       "failed to create local_t's memory pool"); -		ret = ENOMEM; -                goto error; -        } -	gf_log ("crypt", GF_LOG_INFO, "crypt xlator loaded"); -	return 0; - error: -	crypt_free_private(this); -	return ret; -} - -void fini (xlator_t *this) -{ -	crypt_free_private(this); -} - -struct xlator_fops fops = { -	.readv        = crypt_readv, -	.writev       = crypt_writev, -	.truncate     = crypt_truncate, -	.ftruncate    = crypt_ftruncate, -	.setxattr     = crypt_setxattr, -	.fsetxattr    = crypt_fsetxattr, -	.link         = crypt_link, -	.unlink       = crypt_unlink, -	.rename       = crypt_rename, -	.open         = crypt_open, -	.create       = crypt_create, -	.stat         = crypt_stat, -	.fstat        = crypt_fstat, -	.lookup       = crypt_lookup, -	.readdirp     = crypt_readdirp, -	.access       = crypt_access -}; +void +fini(xlator_t *this) +{ +    crypt_free_private(this); +} -struct xlator_cbks cbks = { -	.forget       = crypt_forget -}; +struct xlator_fops fops = {.readv = crypt_readv, +                           .writev = crypt_writev, +                           .truncate = crypt_truncate, +                           .ftruncate = crypt_ftruncate, +                           .setxattr = crypt_setxattr, +                           .fsetxattr = crypt_fsetxattr, +                           .link = crypt_link, +                           .unlink = crypt_unlink, +                           .rename = crypt_rename, +                           .open = crypt_open, +                           .create = crypt_create, +                           .stat = crypt_stat, +                           .fstat = crypt_fstat, +                           .lookup = crypt_lookup, +                           .readdirp = crypt_readdirp, +                           .access = crypt_access}; + +struct xlator_cbks cbks = {.forget = crypt_forget};  struct volume_options options[] = { -	{ .key = {"master-key"}, -	  .type = GF_OPTION_TYPE_PATH, -	  .description = "Pathname of regular file which contains master volume key" -	}, -	{ .key = {"data-key-size"}, -	  .type = GF_OPTION_TYPE_SIZET, -	  .description = "Data key size (bits)", -	  .min = 256, -	  .max = 512, -	  .default_value = "256", -	}, -	{ .key = {"block-size"}, -	  .type = GF_OPTION_TYPE_SIZET, -	  .description = "Atom size (bits)", -	  .min = 512, -	  .max = 4096, -	  .default_value = "4096" -	}, -	{ .key  = {NULL} }, +    {.key = {"master-key"}, +     .type = GF_OPTION_TYPE_PATH, +     .description = +         "Pathname of regular file which contains master volume key"}, +    { +        .key = {"data-key-size"}, +        .type = GF_OPTION_TYPE_SIZET, +        .description = "Data key size (bits)", +        .min = 256, +        .max = 512, +        .default_value = "256", +    }, +    {.key = {"block-size"}, +     .type = GF_OPTION_TYPE_SIZET, +     .description = "Atom size (bits)", +     .min = 512, +     .max = 4096, +     .default_value = "4096"}, +    {.key = {NULL}},  };  /*  | 
