diff options
Diffstat (limited to 'xlators/encryption/crypt/src/atom.c')
| -rw-r--r-- | xlators/encryption/crypt/src/atom.c | 1210 | 
1 files changed, 557 insertions, 653 deletions
diff --git a/xlators/encryption/crypt/src/atom.c b/xlators/encryption/crypt/src/atom.c index fc90892fae8..8e9c4940abd 100644 --- a/xlators/encryption/crypt/src/atom.c +++ b/xlators/encryption/crypt/src/atom.c @@ -71,182 +71,182 @@  /*   * atom->offset_at()   */ -static off_t offset_at_head(struct avec_config *conf) +static off_t +offset_at_head(struct avec_config *conf)  { -	return conf->aligned_offset; +    return conf->aligned_offset;  } -static off_t offset_at_hole_head(call_frame_t *frame, -					 struct object_cipher_info *object) +static off_t +offset_at_hole_head(call_frame_t *frame, struct object_cipher_info *object)  { -	return offset_at_head(get_hole_conf(frame)); +    return offset_at_head(get_hole_conf(frame));  } -static off_t offset_at_data_head(call_frame_t *frame, -					 struct object_cipher_info *object) +static off_t +offset_at_data_head(call_frame_t *frame, struct object_cipher_info *object)  { -	return offset_at_head(get_data_conf(frame)); +    return offset_at_head(get_data_conf(frame));  } - -static off_t offset_at_tail(struct avec_config *conf, -				    struct object_cipher_info *object) +static off_t +offset_at_tail(struct avec_config *conf, struct object_cipher_info *object)  { -	return conf->aligned_offset + -		(conf->off_in_head ? get_atom_size(object) : 0) + -		(conf->nr_full_blocks << get_atom_bits(object)); +    return conf->aligned_offset + +           (conf->off_in_head ? get_atom_size(object) : 0) + +           (conf->nr_full_blocks << get_atom_bits(object));  } -static off_t offset_at_hole_tail(call_frame_t *frame, -					 struct object_cipher_info *object) +static off_t +offset_at_hole_tail(call_frame_t *frame, struct object_cipher_info *object)  { -	return offset_at_tail(get_hole_conf(frame), object); +    return offset_at_tail(get_hole_conf(frame), object);  } - -static off_t offset_at_data_tail(call_frame_t *frame, -					 struct object_cipher_info *object) +static off_t +offset_at_data_tail(call_frame_t *frame, struct object_cipher_info *object)  { -	return offset_at_tail(get_data_conf(frame), object); +    return offset_at_tail(get_data_conf(frame), object);  } -static off_t offset_at_full(struct avec_config *conf, -				    struct object_cipher_info *object) +static off_t +offset_at_full(struct avec_config *conf, struct object_cipher_info *object)  { -	return conf->aligned_offset + -		(conf->off_in_head ? get_atom_size(object) : 0); +    return conf->aligned_offset + +           (conf->off_in_head ? get_atom_size(object) : 0);  } -static off_t offset_at_data_full(call_frame_t *frame, -					 struct object_cipher_info *object) +static off_t +offset_at_data_full(call_frame_t *frame, struct object_cipher_info *object)  { -	return offset_at_full(get_data_conf(frame), object); +    return offset_at_full(get_data_conf(frame), object);  } -static off_t offset_at_hole_full(call_frame_t *frame, -					 struct object_cipher_info *object) +static off_t +offset_at_hole_full(call_frame_t *frame, struct object_cipher_info *object)  { -	return offset_at_full(get_hole_conf(frame), object); +    return offset_at_full(get_hole_conf(frame), object);  }  /*   * atom->io_size_nopad()   */ -static uint32_t io_size_nopad_head(struct avec_config *conf, -				   struct object_cipher_info *object) +static uint32_t +io_size_nopad_head(struct avec_config *conf, struct object_cipher_info *object)  { -	uint32_t gap_at_beg; -	uint32_t gap_at_end; +    uint32_t gap_at_beg; +    uint32_t gap_at_end; -	check_head_block(conf); +    check_head_block(conf); -	gap_at_beg = conf->off_in_head; +    gap_at_beg = conf->off_in_head; -	if (has_tail_block(conf) || has_full_blocks(conf) || conf->off_in_tail == 0 ) -		gap_at_end = 0; -	else -		gap_at_end = get_atom_size(object) - conf->off_in_tail; +    if (has_tail_block(conf) || has_full_blocks(conf) || conf->off_in_tail == 0) +        gap_at_end = 0; +    else +        gap_at_end = get_atom_size(object) - conf->off_in_tail; -	return get_atom_size(object) - (gap_at_beg + gap_at_end); +    return get_atom_size(object) - (gap_at_beg + gap_at_end);  } -static uint32_t io_size_nopad_tail(struct avec_config *conf, -				   struct object_cipher_info *object) +static uint32_t +io_size_nopad_tail(struct avec_config *conf, struct object_cipher_info *object)  { -	check_tail_block(conf); -	return conf->off_in_tail; +    check_tail_block(conf); +    return conf->off_in_tail;  } -static uint32_t io_size_nopad_full(struct avec_config *conf, -				   struct object_cipher_info *object) +static uint32_t +io_size_nopad_full(struct avec_config *conf, struct object_cipher_info *object)  { -	check_full_block(conf); -	return get_atom_size(object); +    check_full_block(conf); +    return get_atom_size(object);  } -static uint32_t io_size_nopad_data_head(call_frame_t *frame, -					struct object_cipher_info *object) +static uint32_t +io_size_nopad_data_head(call_frame_t *frame, struct object_cipher_info *object)  { -	return io_size_nopad_head(get_data_conf(frame), object); +    return io_size_nopad_head(get_data_conf(frame), object);  } -static uint32_t io_size_nopad_hole_head(call_frame_t *frame, -					struct object_cipher_info *object) +static uint32_t +io_size_nopad_hole_head(call_frame_t *frame, struct object_cipher_info *object)  { -	return io_size_nopad_head(get_hole_conf(frame), object); +    return io_size_nopad_head(get_hole_conf(frame), object);  } -static uint32_t io_size_nopad_data_tail(call_frame_t *frame, -					struct object_cipher_info *object) +static uint32_t +io_size_nopad_data_tail(call_frame_t *frame, struct object_cipher_info *object)  { -	return io_size_nopad_tail(get_data_conf(frame), object); +    return io_size_nopad_tail(get_data_conf(frame), object);  } -static uint32_t io_size_nopad_hole_tail(call_frame_t *frame, -					struct object_cipher_info *object) +static uint32_t +io_size_nopad_hole_tail(call_frame_t *frame, struct object_cipher_info *object)  { -	return io_size_nopad_tail(get_hole_conf(frame), object); +    return io_size_nopad_tail(get_hole_conf(frame), object);  } -static uint32_t io_size_nopad_data_full(call_frame_t *frame, -					struct object_cipher_info *object) +static uint32_t +io_size_nopad_data_full(call_frame_t *frame, struct object_cipher_info *object)  { -	return io_size_nopad_full(get_data_conf(frame), object); +    return io_size_nopad_full(get_data_conf(frame), object);  } -static uint32_t io_size_nopad_hole_full(call_frame_t *frame, -					struct object_cipher_info *object) +static uint32_t +io_size_nopad_hole_full(call_frame_t *frame, struct object_cipher_info *object)  { -	return io_size_nopad_full(get_hole_conf(frame), object); +    return io_size_nopad_full(get_hole_conf(frame), object);  } -static uint32_t offset_in_head(struct avec_config *conf) +static uint32_t +offset_in_head(struct avec_config *conf)  { -	check_cursor_head(conf); +    check_cursor_head(conf); -	return conf->off_in_head; +    return conf->off_in_head;  } -static uint32_t offset_in_tail(call_frame_t *frame, -			       struct object_cipher_info *object) +static uint32_t +offset_in_tail(call_frame_t *frame, struct object_cipher_info *object)  { -	return 0; +    return 0;  } -static uint32_t offset_in_full(struct avec_config *conf, -			       struct object_cipher_info *object) +static uint32_t +offset_in_full(struct avec_config *conf, struct object_cipher_info *object)  { -	check_cursor_full(conf); +    check_cursor_full(conf); -	if (has_head_block(conf)) -		return (conf->cursor - 1) << get_atom_bits(object); -	else -		return conf->cursor << get_atom_bits(object); +    if (has_head_block(conf)) +        return (conf->cursor - 1) << get_atom_bits(object); +    else +        return conf->cursor << get_atom_bits(object);  } -static uint32_t offset_in_data_head(call_frame_t *frame, -				    struct object_cipher_info *object) +static uint32_t +offset_in_data_head(call_frame_t *frame, struct object_cipher_info *object)  { -	return offset_in_head(get_data_conf(frame)); +    return offset_in_head(get_data_conf(frame));  } -static uint32_t offset_in_hole_head(call_frame_t *frame, -				    struct object_cipher_info *object) +static uint32_t +offset_in_hole_head(call_frame_t *frame, struct object_cipher_info *object)  { -	return offset_in_head(get_hole_conf(frame)); +    return offset_in_head(get_hole_conf(frame));  } -static uint32_t offset_in_data_full(call_frame_t *frame, -				    struct object_cipher_info *object) +static uint32_t +offset_in_data_full(call_frame_t *frame, struct object_cipher_info *object)  { -	return offset_in_full(get_data_conf(frame), object); +    return offset_in_full(get_data_conf(frame), object);  } -static uint32_t offset_in_hole_full(call_frame_t *frame, -				    struct object_cipher_info *object) +static uint32_t +offset_in_hole_full(call_frame_t *frame, struct object_cipher_info *object)  { -	return offset_in_full(get_hole_conf(frame), object); +    return offset_in_full(get_hole_conf(frame), object);  }  /* @@ -261,94 +261,88 @@ static uint32_t offset_in_hole_full(call_frame_t *frame,   * this plain text, encrypt the whole block   * and write the result to disk.   */ -static int32_t rmw_partial_block(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, -				 struct rmw_atom *atom) -{ -	size_t was_read = 0; -	uint64_t file_size; -	crypt_local_t *local = frame->local; -	struct object_cipher_info *object = &local->info->cinfo; - -	struct iovec *partial = atom->get_iovec(frame, 0); -	struct avec_config *conf = atom->get_config(frame); -	end_writeback_handler_t end_writeback_partial_block; +static int32_t +rmw_partial_block(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, +                  struct rmw_atom *atom) +{ +    size_t was_read = 0; +    uint64_t file_size; +    crypt_local_t *local = frame->local; +    struct object_cipher_info *object = &local->info->cinfo; + +    struct iovec *partial = atom->get_iovec(frame, 0); +    struct avec_config *conf = atom->get_config(frame); +    end_writeback_handler_t end_writeback_partial_block;  #if DEBUG_CRYPT -	gf_boolean_t check_last_cblock = _gf_false; +    gf_boolean_t check_last_cblock = _gf_false;  #endif -	local->op_ret = op_ret; -	local->op_errno = op_errno; - -	if (op_ret < 0) -		goto exit; - -	file_size = local->cur_file_size; -	was_read = op_ret; - -	if (atom->locality == HEAD_ATOM && conf->off_in_head) { -		/* -		 * head atom with a non-uptodate gap -		 * at the beginning -		 * -		 * fill the gap with plain text of the -		 * latest version. Convert a part of hole -		 * (if any) to zeros. -		 */ -		int32_t i; -		int32_t copied = 0; -		int32_t to_gap; /* amount of data needed to uptodate -				   the gap at the beginning */ +    local->op_ret = op_ret; +    local->op_errno = op_errno; + +    if (op_ret < 0) +        goto exit; + +    file_size = local->cur_file_size; +    was_read = op_ret; + +    if (atom->locality == HEAD_ATOM && conf->off_in_head) { +        /* +         * head atom with a non-uptodate gap +         * at the beginning +         * +         * fill the gap with plain text of the +         * latest version. Convert a part of hole +         * (if any) to zeros. +         */ +        int32_t i; +        int32_t copied = 0; +        int32_t to_gap; /* amount of data needed to uptodate +                           the gap at the beginning */  #if 0  		int32_t hole = 0; /* The part of the hole which  				   * got in the head block */  #endif /* 0 */ -		to_gap = conf->off_in_head; - -		if (was_read < to_gap) { -			if (file_size > -			    offset_at_head(conf) + was_read) { -				/* -				 * It is impossible to uptodate -				 * head block: too few bytes have -				 * been read from disk, so that -				 * partial write is impossible. -				 * -				 * It could happen because of many -				 * reasons: IO errors, (meta)data -				 * corruption in the local file system, -				 * etc. -				 */ -				gf_log(this->name, GF_LOG_WARNING, -				     "Can not uptodate a gap at the beginning"); -				local->op_ret = -1; -				local->op_errno = EIO; -				goto exit; -			} +        to_gap = conf->off_in_head; + +        if (was_read < to_gap) { +            if (file_size > offset_at_head(conf) + was_read) { +                /* +                 * It is impossible to uptodate +                 * head block: too few bytes have +                 * been read from disk, so that +                 * partial write is impossible. +                 * +                 * It could happen because of many +                 * reasons: IO errors, (meta)data +                 * corruption in the local file system, +                 * etc. +                 */ +                gf_log(this->name, GF_LOG_WARNING, +                       "Can not uptodate a gap at the beginning"); +                local->op_ret = -1; +                local->op_errno = EIO; +                goto exit; +            }  #if 0  			hole = to_gap - was_read;  #endif /* 0 */ -			to_gap = was_read; -		} -		/* -		 * uptodate the gap at the beginning -		 */ -		for (i = 0; i < count && copied < to_gap; i++) { -			int32_t to_copy; - -			to_copy = vec[i].iov_len; -			if (to_copy > to_gap - copied) -				to_copy = to_gap - copied; - -			memcpy(partial->iov_base, vec[i].iov_base, to_copy); -			copied += to_copy; -		} +            to_gap = was_read; +        } +        /* +         * uptodate the gap at the beginning +         */ +        for (i = 0; i < count && copied < to_gap; i++) { +            int32_t to_copy; + +            to_copy = vec[i].iov_len; +            if (to_copy > to_gap - copied) +                to_copy = to_gap - copied; + +            memcpy(partial->iov_base, vec[i].iov_base, to_copy); +            copied += to_copy; +        }  #if 0  		/*  		 * If possible, convert part of the @@ -386,146 +380,128 @@ static int32_t rmw_partial_block(call_frame_t *frame,  		      */  			;  #endif /* 0 */ -	} -	if (atom->locality == TAIL_ATOM || -	    (!has_tail_block(conf) && conf->off_in_tail)) { -		/* -		 * tail atom, or head atom with a non-uptodate -		 * gap at the end. -		 * -		 * fill the gap at the end of the block -		 * with plain text of the latest version. -		 * Pad the result, (if needed) -		 */ -		int32_t i; -		int32_t to_gap; -		int copied; -		off_t off_in_tail; -		int32_t to_copy; - -		off_in_tail = conf->off_in_tail; -		to_gap = conf->gap_in_tail; - -		if (to_gap && was_read < off_in_tail + to_gap) { -			/* -			 * It is impossible to uptodate -			 * the gap at the end: too few bytes -			 * have been read from disk, so that -			 * partial write is impossible. -			 * -			 * It could happen because of many -			 * reasons: IO errors, (meta)data -			 * corruption in the local file system, -			 * etc. -			 */ -			gf_log(this->name, GF_LOG_WARNING, -			       "Can not uptodate a gap at the end"); -			local->op_ret = -1; -			local->op_errno = EIO; -			goto exit; -		} -		/* -		 * uptodate the gap at the end -		 */ -		copied = 0; -		to_copy = to_gap; -		for(i = count - 1; i >= 0 && to_copy > 0; i--) { -			uint32_t from_vec, off_in_vec; - -			off_in_vec = 0; -			from_vec = vec[i].iov_len; -			if (from_vec > to_copy) { -				off_in_vec = from_vec - to_copy; -				from_vec = to_copy; -			} -			memcpy(partial->iov_base + -			       off_in_tail + to_gap - copied - from_vec, -			       vec[i].iov_base + off_in_vec, -			       from_vec); - -			gf_log(this->name, GF_LOG_DEBUG, -			       "uptodate %d bytes at tail. Offset at target(source): %d(%d)", -			       (int)from_vec, -			       (int)off_in_tail + to_gap - copied - from_vec, -			       (int)off_in_vec); - -			copied += from_vec; -			to_copy -= from_vec; -		} -		partial->iov_len = off_in_tail + to_gap; - -		if (object_alg_should_pad(object)) { -			int32_t resid = 0; -			resid = partial->iov_len & (object_alg_blksize(object) - 1); -			if (resid) { -				/* -				 * append a new EOF padding -				 */ -				local->eof_padding_size = -					object_alg_blksize(object) - resid; - -				gf_log(this->name, GF_LOG_DEBUG, -				       "set padding size %d", -				       local->eof_padding_size); - -				memset(partial->iov_base + partial->iov_len, -				       1, -				       local->eof_padding_size); -				partial->iov_len += local->eof_padding_size; +    } +    if (atom->locality == TAIL_ATOM || +        (!has_tail_block(conf) && conf->off_in_tail)) { +        /* +         * tail atom, or head atom with a non-uptodate +         * gap at the end. +         * +         * fill the gap at the end of the block +         * with plain text of the latest version. +         * Pad the result, (if needed) +         */ +        int32_t i; +        int32_t to_gap; +        int copied; +        off_t off_in_tail; +        int32_t to_copy; + +        off_in_tail = conf->off_in_tail; +        to_gap = conf->gap_in_tail; + +        if (to_gap && was_read < off_in_tail + to_gap) { +            /* +             * It is impossible to uptodate +             * the gap at the end: too few bytes +             * have been read from disk, so that +             * partial write is impossible. +             * +             * It could happen because of many +             * reasons: IO errors, (meta)data +             * corruption in the local file system, +             * etc. +             */ +            gf_log(this->name, GF_LOG_WARNING, +                   "Can not uptodate a gap at the end"); +            local->op_ret = -1; +            local->op_errno = EIO; +            goto exit; +        } +        /* +         * uptodate the gap at the end +         */ +        copied = 0; +        to_copy = to_gap; +        for (i = count - 1; i >= 0 && to_copy > 0; i--) { +            uint32_t from_vec, off_in_vec; + +            off_in_vec = 0; +            from_vec = vec[i].iov_len; +            if (from_vec > to_copy) { +                off_in_vec = from_vec - to_copy; +                from_vec = to_copy; +            } +            memcpy(partial->iov_base + off_in_tail + to_gap - copied - from_vec, +                   vec[i].iov_base + off_in_vec, from_vec); + +            gf_log( +                this->name, GF_LOG_DEBUG, +                "uptodate %d bytes at tail. Offset at target(source): %d(%d)", +                (int)from_vec, (int)off_in_tail + to_gap - copied - from_vec, +                (int)off_in_vec); + +            copied += from_vec; +            to_copy -= from_vec; +        } +        partial->iov_len = off_in_tail + to_gap; + +        if (object_alg_should_pad(object)) { +            int32_t resid = 0; +            resid = partial->iov_len & (object_alg_blksize(object) - 1); +            if (resid) { +                /* +                 * append a new EOF padding +                 */ +                local->eof_padding_size = object_alg_blksize(object) - resid; + +                gf_log(this->name, GF_LOG_DEBUG, "set padding size %d", +                       local->eof_padding_size); + +                memset(partial->iov_base + partial->iov_len, 1, +                       local->eof_padding_size); +                partial->iov_len += local->eof_padding_size;  #if DEBUG_CRYPT -				gf_log(this->name, GF_LOG_DEBUG, -				       "pad cblock with %d zeros:", -				       local->eof_padding_size); -				dump_cblock(this, -					    (unsigned char *)partial->iov_base + -					    partial->iov_len - object_alg_blksize(object)); -				check_last_cblock = _gf_true; +                gf_log(this->name, GF_LOG_DEBUG, +                       "pad cblock with %d zeros:", local->eof_padding_size); +                dump_cblock(this, (unsigned char *)partial->iov_base + +                                      partial->iov_len - +                                      object_alg_blksize(object)); +                check_last_cblock = _gf_true;  #endif -			} -		} -	} -	/* -	 * encrypt the whole block -	 */ -	encrypt_aligned_iov(object, -			    partial, -			    1, -			    atom->offset_at(frame, object)); +            } +        } +    } +    /* +     * encrypt the whole block +     */ +    encrypt_aligned_iov(object, partial, 1, atom->offset_at(frame, object));  #if DEBUG_CRYPT -	if (check_last_cblock == _gf_true) { -		gf_log(this->name, GF_LOG_DEBUG, -		       "encrypt last cblock with offset %llu", -		       (unsigned long long)atom->offset_at(frame, object)); -		dump_cblock(this, (unsigned char *)partial->iov_base + -			    partial->iov_len - object_alg_blksize(object)); -	} +    if (check_last_cblock == _gf_true) { +        gf_log(this->name, GF_LOG_DEBUG, "encrypt last cblock with offset %llu", +               (unsigned long long)atom->offset_at(frame, object)); +        dump_cblock(this, (unsigned char *)partial->iov_base + +                              partial->iov_len - object_alg_blksize(object)); +    }  #endif -	set_local_io_params_writev(frame, object, atom, -				   atom->offset_at(frame, object), -				   iov_length(partial, 1)); -	/* -	 * write the whole block to disk -	 */ -	end_writeback_partial_block = dispatch_end_writeback(local->fop); -	conf->cursor ++; -	STACK_WIND(frame, -		   end_writeback_partial_block, -		   FIRST_CHILD(this), -		   FIRST_CHILD(this)->fops->writev, -		   local->fd, -		   partial, -		   1, -		   atom->offset_at(frame, object), -		   local->flags, -		   local->iobref_data, -		   local->xdata); - -	gf_log("crypt", GF_LOG_DEBUG, -	       "submit partial block: %d bytes from %d offset", -	       (int)iov_length(partial, 1), -	       (int)atom->offset_at(frame, object)); - exit: -	return 0; +    set_local_io_params_writev(frame, object, atom, +                               atom->offset_at(frame, object), +                               iov_length(partial, 1)); +    /* +     * write the whole block to disk +     */ +    end_writeback_partial_block = dispatch_end_writeback(local->fop); +    conf->cursor++; +    STACK_WIND(frame, end_writeback_partial_block, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->writev, local->fd, partial, 1, +               atom->offset_at(frame, object), local->flags, local->iobref_data, +               local->xdata); + +    gf_log("crypt", GF_LOG_DEBUG, +           "submit partial block: %d bytes from %d offset", +           (int)iov_length(partial, 1), (int)atom->offset_at(frame, object)); +exit: +    return 0;  }  /* @@ -534,415 +510,343 @@ static int32_t rmw_partial_block(call_frame_t *frame,   * of upper server-side manager, i.e. the caller   * needs to make sure this is his turn to rmw.   */ -void submit_partial(call_frame_t *frame, -		    xlator_t *this, -		    fd_t *fd, -		    atom_locality_type ltype) -{ -	int32_t ret; -	dict_t *dict; -	struct rmw_atom *atom; -	crypt_local_t *local = frame->local; -	struct object_cipher_info *object = &local->info->cinfo; - -	atom = atom_by_types(local->active_setup, ltype); -	/* -	 * To perform the "read" component of the read-modify-write -	 * sequence the crypt translator does stack_wind to itself. -	 * -	 * Pass current file size to crypt_readv() -	 */ -	dict = dict_new(); -	if (!dict) { -		/* -		 * FIXME: Handle the error -		 */ -		gf_log("crypt", GF_LOG_WARNING, "Can not alloc dict"); -		return; -	} -	ret = dict_set(dict, -		       FSIZE_XATTR_PREFIX, -		       data_from_uint64(local->cur_file_size)); -	if (ret) { -		/* -		 * FIXME: Handle the error -		 */ -		dict_unref(dict); -		gf_log("crypt", GF_LOG_WARNING, "Can not set dict"); -		goto exit; -	} -	STACK_WIND(frame, -		   atom->rmw, -		   this, -		   this->fops->readv, /* crypt_readv */ -		   fd, -		   atom->count_to_uptodate(frame, object), /* count */ -		   atom->offset_at(frame, object), /* offset to read from */ -		   0, -		   dict); - exit: -	dict_unref(dict); +void +submit_partial(call_frame_t *frame, xlator_t *this, fd_t *fd, +               atom_locality_type ltype) +{ +    int32_t ret; +    dict_t *dict; +    struct rmw_atom *atom; +    crypt_local_t *local = frame->local; +    struct object_cipher_info *object = &local->info->cinfo; + +    atom = atom_by_types(local->active_setup, ltype); +    /* +     * To perform the "read" component of the read-modify-write +     * sequence the crypt translator does stack_wind to itself. +     * +     * Pass current file size to crypt_readv() +     */ +    dict = dict_new(); +    if (!dict) { +        /* +         * FIXME: Handle the error +         */ +        gf_log("crypt", GF_LOG_WARNING, "Can not alloc dict"); +        return; +    } +    ret = dict_set(dict, FSIZE_XATTR_PREFIX, +                   data_from_uint64(local->cur_file_size)); +    if (ret) { +        /* +         * FIXME: Handle the error +         */ +        dict_unref(dict); +        gf_log("crypt", GF_LOG_WARNING, "Can not set dict"); +        goto exit; +    } +    STACK_WIND(frame, atom->rmw, this, this->fops->readv,  /* crypt_readv */ +               fd, atom->count_to_uptodate(frame, object), /* count */ +               atom->offset_at(frame, object), /* offset to read from */ +               0, dict); +exit: +    dict_unref(dict);  }  /*   * submit blocks of FULL_ATOM type   */ -void submit_full(call_frame_t *frame, xlator_t *this) -{ -	crypt_local_t *local = frame->local; -	struct object_cipher_info *object = &local->info->cinfo; -	struct rmw_atom *atom = atom_by_types(local->active_setup, FULL_ATOM); -	uint32_t count; /* total number of full blocks to submit */ -	uint32_t granularity; /* number of blocks to submit in one iteration */ - -	uint64_t off_in_file; /* start offset in the file, bytes */ -	uint32_t off_in_atom; /* start offset in the atom, blocks */ -	uint32_t blocks_written = 0; /* blocks written for this submit */ - -	struct avec_config *conf = atom->get_config(frame); -	end_writeback_handler_t end_writeback_full_block; -	/* -	 * Write full blocks by groups of granularity size. -	 */ -	end_writeback_full_block = dispatch_end_writeback(local->fop); - -	if (is_ordered_mode(frame)) { -		uint32_t skip = has_head_block(conf) ? 1 : 0; -		count = 1; -		granularity = 1; -		/* -		 * calculate start offset using cursor value; -		 * here we should take into account head block, -		 * which corresponds to cursor value 0. -		 */ -		off_in_file = atom->offset_at(frame, object) + -			((conf->cursor - skip) << get_atom_bits(object)); -		off_in_atom = conf->cursor - skip; -	} -	else { -		/* -		 * in parallel mode -		 */ -		count = conf->nr_full_blocks; -		granularity = MAX_IOVEC; -		off_in_file = atom->offset_at(frame, object); -		off_in_atom = 0; -	} -	while (count) { -		uint32_t blocks_to_write = count; - -		if (blocks_to_write > granularity) -			blocks_to_write = granularity; -		if (conf->type == HOLE_ATOM) -			/* -			 * reset iovec before encryption -			 */ -			memset(atom->get_iovec(frame, 0)->iov_base, -			       0, -			       get_atom_size(object)); -		/* -		 * encrypt the group -		 */ -		encrypt_aligned_iov(object, -				    atom->get_iovec(frame, -						    off_in_atom + -						    blocks_written), -				    blocks_to_write, -				    off_in_file + (blocks_written << -						   get_atom_bits(object))); - -		set_local_io_params_writev(frame, object, atom, -		        off_in_file + (blocks_written << get_atom_bits(object)), -			blocks_to_write <<  get_atom_bits(object)); - -		conf->cursor += blocks_to_write; - -		STACK_WIND(frame, -			   end_writeback_full_block, -			   FIRST_CHILD(this), -			   FIRST_CHILD(this)->fops->writev, -			   local->fd, -			   atom->get_iovec(frame, off_in_atom + blocks_written), -			   blocks_to_write, -			   off_in_file + (blocks_written << get_atom_bits(object)), -			   local->flags, -			   local->iobref_data ? local->iobref_data : local->iobref, -			   local->xdata); - -		gf_log("crypt", GF_LOG_DEBUG, "submit %d full blocks from %d offset", -		       blocks_to_write, -		       (int)(off_in_file + (blocks_written << get_atom_bits(object)))); - -		count -= blocks_to_write; -		blocks_written += blocks_to_write; -	} -	return; -} - -static int32_t rmw_data_head(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) -{ -	return rmw_partial_block(frame, -				 cookie, -				 this, -				 op_ret, -				 op_errno, -				 vec, -				 count, -				 stbuf, -				 iobref, -				 atom_by_types(DATA_ATOM, HEAD_ATOM)); -} - -static int32_t rmw_data_tail(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) -{ -	return rmw_partial_block(frame, -				 cookie, -				 this, -				 op_ret, -				 op_errno, -				 vec, -				 count, -				 stbuf, -				 iobref, -				 atom_by_types(DATA_ATOM, TAIL_ATOM)); -} - -static int32_t rmw_hole_head(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) -{ -	return rmw_partial_block(frame, -				 cookie, -				 this, -				 op_ret, -				 op_errno, -				 vec, -				 count, -				 stbuf, -				 iobref, -				 atom_by_types(HOLE_ATOM, HEAD_ATOM)); -} - -static int32_t rmw_hole_tail(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) -{ -	return rmw_partial_block(frame, -				 cookie, -				 this, -				 op_ret, -				 op_errno, -				 vec, -				 count, -				 stbuf, -				 iobref, -				 atom_by_types(HOLE_ATOM, TAIL_ATOM)); +void +submit_full(call_frame_t *frame, xlator_t *this) +{ +    crypt_local_t *local = frame->local; +    struct object_cipher_info *object = &local->info->cinfo; +    struct rmw_atom *atom = atom_by_types(local->active_setup, FULL_ATOM); +    uint32_t count;       /* total number of full blocks to submit */ +    uint32_t granularity; /* number of blocks to submit in one iteration */ + +    uint64_t off_in_file;        /* start offset in the file, bytes */ +    uint32_t off_in_atom;        /* start offset in the atom, blocks */ +    uint32_t blocks_written = 0; /* blocks written for this submit */ + +    struct avec_config *conf = atom->get_config(frame); +    end_writeback_handler_t end_writeback_full_block; +    /* +     * Write full blocks by groups of granularity size. +     */ +    end_writeback_full_block = dispatch_end_writeback(local->fop); + +    if (is_ordered_mode(frame)) { +        uint32_t skip = has_head_block(conf) ? 1 : 0; +        count = 1; +        granularity = 1; +        /* +         * calculate start offset using cursor value; +         * here we should take into account head block, +         * which corresponds to cursor value 0. +         */ +        off_in_file = atom->offset_at(frame, object) + +                      ((conf->cursor - skip) << get_atom_bits(object)); +        off_in_atom = conf->cursor - skip; +    } else { +        /* +         * in parallel mode +         */ +        count = conf->nr_full_blocks; +        granularity = MAX_IOVEC; +        off_in_file = atom->offset_at(frame, object); +        off_in_atom = 0; +    } +    while (count) { +        uint32_t blocks_to_write = count; + +        if (blocks_to_write > granularity) +            blocks_to_write = granularity; +        if (conf->type == HOLE_ATOM) +            /* +             * reset iovec before encryption +             */ +            memset(atom->get_iovec(frame, 0)->iov_base, 0, +                   get_atom_size(object)); +        /* +         * encrypt the group +         */ +        encrypt_aligned_iov( +            object, atom->get_iovec(frame, off_in_atom + blocks_written), +            blocks_to_write, +            off_in_file + (blocks_written << get_atom_bits(object))); + +        set_local_io_params_writev( +            frame, object, atom, +            off_in_file + (blocks_written << get_atom_bits(object)), +            blocks_to_write << get_atom_bits(object)); + +        conf->cursor += blocks_to_write; + +        STACK_WIND(frame, end_writeback_full_block, FIRST_CHILD(this), +                   FIRST_CHILD(this)->fops->writev, local->fd, +                   atom->get_iovec(frame, off_in_atom + blocks_written), +                   blocks_to_write, +                   off_in_file + (blocks_written << get_atom_bits(object)), +                   local->flags, +                   local->iobref_data ? local->iobref_data : local->iobref, +                   local->xdata); + +        gf_log("crypt", GF_LOG_DEBUG, "submit %d full blocks from %d offset", +               blocks_to_write, +               (int)(off_in_file + (blocks_written << get_atom_bits(object)))); + +        count -= blocks_to_write; +        blocks_written += blocks_to_write; +    } +    return; +} + +static int32_t +rmw_data_head(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) +{ +    return rmw_partial_block(frame, cookie, this, op_ret, op_errno, vec, count, +                             stbuf, iobref, +                             atom_by_types(DATA_ATOM, HEAD_ATOM)); +} + +static int32_t +rmw_data_tail(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) +{ +    return rmw_partial_block(frame, cookie, this, op_ret, op_errno, vec, count, +                             stbuf, iobref, +                             atom_by_types(DATA_ATOM, TAIL_ATOM)); +} + +static int32_t +rmw_hole_head(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) +{ +    return rmw_partial_block(frame, cookie, this, op_ret, op_errno, vec, count, +                             stbuf, iobref, +                             atom_by_types(HOLE_ATOM, HEAD_ATOM)); +} + +static int32_t +rmw_hole_tail(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) +{ +    return rmw_partial_block(frame, cookie, this, op_ret, op_errno, vec, count, +                             stbuf, iobref, +                             atom_by_types(HOLE_ATOM, TAIL_ATOM));  }  /*   * atom->count_to_uptodate()   */ -static uint32_t count_to_uptodate_head(struct avec_config *conf, -				       struct object_cipher_info *object) +static uint32_t +count_to_uptodate_head(struct avec_config *conf, +                       struct object_cipher_info *object)  { -	if (conf->acount == 1 && conf->off_in_tail) -		return get_atom_size(object); -	else -		/* there is no need to read the whole head block */ -		return conf->off_in_head; +    if (conf->acount == 1 && conf->off_in_tail) +        return get_atom_size(object); +    else +        /* there is no need to read the whole head block */ +        return conf->off_in_head;  } -static uint32_t count_to_uptodate_tail(struct avec_config *conf, -				       struct object_cipher_info *object) +static uint32_t +count_to_uptodate_tail(struct avec_config *conf, +                       struct object_cipher_info *object)  { -	/* we need to read the whole tail block */ -	return get_atom_size(object); +    /* we need to read the whole tail block */ +    return get_atom_size(object);  } -static uint32_t count_to_uptodate_data_head(call_frame_t *frame, -					    struct object_cipher_info *object) +static uint32_t +count_to_uptodate_data_head(call_frame_t *frame, +                            struct object_cipher_info *object)  { -	return count_to_uptodate_head(get_data_conf(frame), object); +    return count_to_uptodate_head(get_data_conf(frame), object);  } -static uint32_t count_to_uptodate_data_tail(call_frame_t *frame, -					    struct object_cipher_info *object) +static uint32_t +count_to_uptodate_data_tail(call_frame_t *frame, +                            struct object_cipher_info *object)  { -	return count_to_uptodate_tail(get_data_conf(frame), object); +    return count_to_uptodate_tail(get_data_conf(frame), object);  } -static uint32_t count_to_uptodate_hole_head(call_frame_t *frame, -					    struct object_cipher_info *object) +static uint32_t +count_to_uptodate_hole_head(call_frame_t *frame, +                            struct object_cipher_info *object)  { -	return count_to_uptodate_head(get_hole_conf(frame), object); +    return count_to_uptodate_head(get_hole_conf(frame), object);  } -static uint32_t count_to_uptodate_hole_tail(call_frame_t *frame, -					    struct object_cipher_info *object) +static uint32_t +count_to_uptodate_hole_tail(call_frame_t *frame, +                            struct object_cipher_info *object)  { -	return count_to_uptodate_tail(get_hole_conf(frame), object); +    return count_to_uptodate_tail(get_hole_conf(frame), object);  }  /* atom->get_config() */ -static struct avec_config *get_config_data(call_frame_t *frame) +static struct avec_config * +get_config_data(call_frame_t *frame)  { -	return &((crypt_local_t *)frame->local)->data_conf; +    return &((crypt_local_t *)frame->local)->data_conf;  } -static struct avec_config *get_config_hole(call_frame_t *frame) +static struct avec_config * +get_config_hole(call_frame_t *frame)  { -	return &((crypt_local_t *)frame->local)->hole_conf; +    return &((crypt_local_t *)frame->local)->hole_conf;  }  /*   * atom->get_iovec()   */ -static struct iovec *get_iovec_hole_head(call_frame_t *frame, -					 uint32_t count) +static struct iovec * +get_iovec_hole_head(call_frame_t *frame, uint32_t count)  { -	struct avec_config *conf = get_hole_conf(frame); +    struct avec_config *conf = get_hole_conf(frame); -	return conf->avec; +    return conf->avec;  } -static struct iovec *get_iovec_hole_full(call_frame_t *frame, -					 uint32_t count) +static struct iovec * +get_iovec_hole_full(call_frame_t *frame, uint32_t count)  { -	struct avec_config *conf = get_hole_conf(frame); +    struct avec_config *conf = get_hole_conf(frame); -	return conf->avec + (conf->off_in_head ? 1 : 0); +    return conf->avec + (conf->off_in_head ? 1 : 0);  } -static struct iovec *get_iovec_hole_tail(call_frame_t *frame, -						uint32_t count) +static struct iovec * +get_iovec_hole_tail(call_frame_t *frame, uint32_t count)  { -	struct avec_config *conf = get_hole_conf(frame); +    struct avec_config *conf = get_hole_conf(frame); -	return conf->avec + (conf->blocks_in_pool - 1); +    return conf->avec + (conf->blocks_in_pool - 1);  } -static struct iovec *get_iovec_data_head(call_frame_t *frame, -						uint32_t count) +static struct iovec * +get_iovec_data_head(call_frame_t *frame, uint32_t count)  { -	struct avec_config *conf = get_data_conf(frame); +    struct avec_config *conf = get_data_conf(frame); -	return conf->avec; +    return conf->avec;  } -static struct iovec *get_iovec_data_full(call_frame_t *frame, -						uint32_t count) +static struct iovec * +get_iovec_data_full(call_frame_t *frame, uint32_t count)  { -	struct avec_config *conf = get_data_conf(frame); +    struct avec_config *conf = get_data_conf(frame); -	return conf->avec + (conf->off_in_head ? 1 : 0) + count; +    return conf->avec + (conf->off_in_head ? 1 : 0) + count;  } -static struct iovec *get_iovec_data_tail(call_frame_t *frame, -						uint32_t count) +static struct iovec * +get_iovec_data_tail(call_frame_t *frame, uint32_t count)  { -	struct avec_config *conf = get_data_conf(frame); +    struct avec_config *conf = get_data_conf(frame); -	return conf->avec + -		(conf->off_in_head ? 1 : 0) + -		conf->nr_full_blocks; +    return conf->avec + (conf->off_in_head ? 1 : 0) + conf->nr_full_blocks;  }  static struct rmw_atom atoms[LAST_DATA_TYPE][LAST_LOCALITY_TYPE] = { -	[DATA_ATOM][HEAD_ATOM] = -	{ .locality = HEAD_ATOM, -	  .rmw = rmw_data_head, -	  .offset_at = offset_at_data_head, -	  .offset_in = offset_in_data_head, -	  .get_iovec = get_iovec_data_head, -	  .io_size_nopad = io_size_nopad_data_head, -	  .count_to_uptodate = count_to_uptodate_data_head, -	  .get_config = get_config_data -	}, -	[DATA_ATOM][TAIL_ATOM] = -	{ .locality = TAIL_ATOM, -	  .rmw = rmw_data_tail, -	  .offset_at = offset_at_data_tail, -	  .offset_in = offset_in_tail, -	  .get_iovec = get_iovec_data_tail, -	  .io_size_nopad = io_size_nopad_data_tail, -	  .count_to_uptodate = count_to_uptodate_data_tail, -	  .get_config = get_config_data -	}, -	[DATA_ATOM][FULL_ATOM] = -	{ .locality = FULL_ATOM, -	  .offset_at = offset_at_data_full, -	  .offset_in = offset_in_data_full, -	  .get_iovec = get_iovec_data_full, -	  .io_size_nopad = io_size_nopad_data_full, -	  .get_config = get_config_data -	}, -	[HOLE_ATOM][HEAD_ATOM] = -	{ .locality = HEAD_ATOM, -	  .rmw = rmw_hole_head, -	  .offset_at = offset_at_hole_head, -	  .offset_in = offset_in_hole_head, -	  .get_iovec = get_iovec_hole_head, -	  .io_size_nopad = io_size_nopad_hole_head, -	  .count_to_uptodate = count_to_uptodate_hole_head, -	  .get_config = get_config_hole -	}, -	[HOLE_ATOM][TAIL_ATOM] = -	{ .locality = TAIL_ATOM, -	  .rmw = rmw_hole_tail, -	  .offset_at = offset_at_hole_tail, -	  .offset_in = offset_in_tail, -	  .get_iovec = get_iovec_hole_tail, -	  .io_size_nopad = io_size_nopad_hole_tail, -	  .count_to_uptodate = count_to_uptodate_hole_tail, -	  .get_config = get_config_hole -	}, -	[HOLE_ATOM][FULL_ATOM] = -	{ .locality = FULL_ATOM, -	  .offset_at = offset_at_hole_full, -	  .offset_in = offset_in_hole_full, -	  .get_iovec = get_iovec_hole_full, -	  .io_size_nopad = io_size_nopad_hole_full, -	  .get_config = get_config_hole -	} -}; - -struct rmw_atom *atom_by_types(atom_data_type data, -			       atom_locality_type locality) -{ -	return &atoms[data][locality]; +    [DATA_ATOM][HEAD_ATOM] = {.locality = HEAD_ATOM, +                              .rmw = rmw_data_head, +                              .offset_at = offset_at_data_head, +                              .offset_in = offset_in_data_head, +                              .get_iovec = get_iovec_data_head, +                              .io_size_nopad = io_size_nopad_data_head, +                              .count_to_uptodate = count_to_uptodate_data_head, +                              .get_config = get_config_data}, +    [DATA_ATOM][TAIL_ATOM] = {.locality = TAIL_ATOM, +                              .rmw = rmw_data_tail, +                              .offset_at = offset_at_data_tail, +                              .offset_in = offset_in_tail, +                              .get_iovec = get_iovec_data_tail, +                              .io_size_nopad = io_size_nopad_data_tail, +                              .count_to_uptodate = count_to_uptodate_data_tail, +                              .get_config = get_config_data}, +    [DATA_ATOM][FULL_ATOM] = {.locality = FULL_ATOM, +                              .offset_at = offset_at_data_full, +                              .offset_in = offset_in_data_full, +                              .get_iovec = get_iovec_data_full, +                              .io_size_nopad = io_size_nopad_data_full, +                              .get_config = get_config_data}, +    [HOLE_ATOM][HEAD_ATOM] = {.locality = HEAD_ATOM, +                              .rmw = rmw_hole_head, +                              .offset_at = offset_at_hole_head, +                              .offset_in = offset_in_hole_head, +                              .get_iovec = get_iovec_hole_head, +                              .io_size_nopad = io_size_nopad_hole_head, +                              .count_to_uptodate = count_to_uptodate_hole_head, +                              .get_config = get_config_hole}, +    [HOLE_ATOM][TAIL_ATOM] = {.locality = TAIL_ATOM, +                              .rmw = rmw_hole_tail, +                              .offset_at = offset_at_hole_tail, +                              .offset_in = offset_in_tail, +                              .get_iovec = get_iovec_hole_tail, +                              .io_size_nopad = io_size_nopad_hole_tail, +                              .count_to_uptodate = count_to_uptodate_hole_tail, +                              .get_config = get_config_hole}, +    [HOLE_ATOM][FULL_ATOM] = {.locality = FULL_ATOM, +                              .offset_at = offset_at_hole_full, +                              .offset_in = offset_in_hole_full, +                              .get_iovec = get_iovec_hole_full, +                              .io_size_nopad = io_size_nopad_hole_full, +                              .get_config = get_config_hole}}; + +struct rmw_atom * +atom_by_types(atom_data_type data, atom_locality_type locality) +{ +    return &atoms[data][locality];  }  /*  | 
