diff options
Diffstat (limited to 'xlators/encryption/crypt/src/crypt.h')
| -rw-r--r-- | xlators/encryption/crypt/src/crypt.h | 899 | 
1 files changed, 899 insertions, 0 deletions
diff --git a/xlators/encryption/crypt/src/crypt.h b/xlators/encryption/crypt/src/crypt.h new file mode 100644 index 00000000000..01a8542ab8c --- /dev/null +++ b/xlators/encryption/crypt/src/crypt.h @@ -0,0 +1,899 @@ +/* +  Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> +  This file is part of GlusterFS. + +  This file is licensed to you under your choice of the GNU Lesser +  General Public License, version 3 or any later version (LGPLv3 or +  later), or the GNU General Public License, version 2 (GPLv2), in all +  cases as published by the Free Software Foundation. +*/ + +#ifndef __CRYPT_H__ +#define __CRYPT_H__ + +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif +#include <openssl/aes.h> +#include <openssl/evp.h> +#include <openssl/sha.h> +#include <openssl/hmac.h> +#include <openssl/cmac.h> +#include <openssl/modes.h> +#include "crypt-mem-types.h" + +#define CRYPT_XLATOR_ID  (0) + +#define MAX_IOVEC_BITS (3) +#define MAX_IOVEC (1 << MAX_IOVEC_BITS) +#define KEY_FACTOR_BITS  (6) + +#define DEBUG_CRYPT (0) +#define TRIVIAL_TFM (0) + +#define CRYPT_MIN_BLOCK_BITS (9) +#define CRYPT_MAX_BLOCK_BITS (12) + +#define MASTER_VOL_KEY_SIZE (32) +#define NMTD_VOL_KEY_SIZE (16) + +struct crypt_key { +	uint32_t len; +	const char *label;	 +}; + +/* + * Add new key types to the end of this + * enumeration but before LAST_KEY_TYPE + */ +typedef enum { +	MASTER_VOL_KEY, +	NMTD_VOL_KEY, +	NMTD_LINK_KEY, +	EMTD_FILE_KEY, +	DATA_FILE_KEY_256, +	DATA_FILE_KEY_512, +	LAST_KEY_TYPE +}crypt_key_type; + +struct kderive_context { +	const unsigned char *pkey;/* parent key */ +	uint32_t pkey_len;        /* parent key size, bits */ +	uint32_t ckey_len;        /* child key size, bits */ +	unsigned char *fid;       /* fixed input data, NIST 800-108, 5.1 */ +	uint32_t fid_len;         /* fid len, bytes */ +	unsigned char *out;       /* contains child keying material */ +	uint32_t out_len;         /* out len, bytes */ +}; + +typedef enum { +	DATA_ATOM, +	HOLE_ATOM, +	LAST_DATA_TYPE +}atom_data_type; + +typedef enum { +	HEAD_ATOM, +	TAIL_ATOM, +	FULL_ATOM, +	LAST_LOCALITY_TYPE +}atom_locality_type; + +typedef enum { +	MTD_CREATE, +	MTD_APPEND, +	MTD_OVERWRITE, +	MTD_CUT, +	MTD_LAST_OP +} mtd_op_t; + +struct xts128_context { +	void      *key1, *key2; +	block128_f block1,block2; +}; + +struct object_cipher_info { +	cipher_alg_t  o_alg; +        cipher_mode_t o_mode; +	uint32_t      o_block_bits; +        uint32_t      o_dkey_size; /* raw data key size in bits */ +	union { +		struct { +			unsigned char ivec[16]; +			AES_KEY dkey[2]; +			AES_KEY tkey;    /* key used for tweaking */ +			XTS128_CONTEXT xts; +		} aes_xts; +	} u; +}; + +struct master_cipher_info { +	/* +	 * attributes inherited by newly created regular files +	 */ +	cipher_alg_t  m_alg; +        cipher_mode_t m_mode; +	uint32_t      m_block_bits; +        uint32_t      m_dkey_size; /* raw key size in bits */ +	/* +	 * master key +	 */ +	unsigned char m_key[MASTER_VOL_KEY_SIZE]; +	/*  +	 * volume key for oid authentication +	 */ +	unsigned char m_nmtd_key[NMTD_VOL_KEY_SIZE]; +}; + +/* +* This info is not changed during file's life + */ +struct crypt_inode_info { +#if DEBUG_CRYPT +	loc_t *loc; /* pathname that the file has been +		       opened, or created with */ +#endif +	uint16_t nr_minor; +	uuid_t oid; +	struct object_cipher_info cinfo; +}; + +/* + * this should locate in secure memory + */ +typedef struct { +	struct master_cipher_info master; +} crypt_private_t; + +static inline struct master_cipher_info *get_master_cinfo(crypt_private_t *priv) +{ +	return &priv->master; +} + +static inline struct object_cipher_info *get_object_cinfo(struct crypt_inode_info +							 *info) +{ +	return &info->cinfo; +} + +/* + * this describes layouts and properties + * of atoms in an aligned vector + */ +struct avec_config { +	uint32_t atom_size; +	atom_data_type type; +	size_t orig_size; +	off_t orig_offset; +	size_t expanded_size; +	off_t aligned_offset; + +	uint32_t off_in_head; +	uint32_t off_in_tail; +	uint32_t gap_in_tail; +	uint32_t nr_full_blocks; + +	struct iovec *avec; /* aligned vector */ +	uint32_t acount; /* number of avec components. The same +			  * as number of occupied logical blocks */ +	char **pool; +	uint32_t blocks_in_pool; +	uint32_t cursor; /* makes sense only for ordered writes, +			  * so there is no races on this counter. +			  * +			  * Cursor is per-config object, we don't +			  * reset cursor for atoms of different +			  * localities (head, tail, full) +			  */ +}; + + +typedef struct { +	glusterfs_fop_t fop; /* code of FOP this local info built for */ +	fd_t *fd; +	inode_t *inode; +	loc_t *loc; +	int32_t mac_idx; +	loc_t *newloc; +	int32_t flags; +	int32_t wbflags; +	struct crypt_inode_info *info; +	struct iobref *iobref; +	struct iobref *iobref_data; +	off_t offset; + +	uint64_t old_file_size; /* per FOP, retrieved under lock held */ +	uint64_t cur_file_size; /* per iteration, before issuing IOs */ +	uint64_t new_file_size; /* per iteration, after issuing IOs */ + +	uint64_t io_offset; /* offset of IOs issued per iteration */ +	uint64_t io_offset_nopad; /* offset of user's data in the atom */ +	uint32_t io_size; /* size of IOs issued per iteration */ +	uint32_t io_size_nopad; /* size of user's data in the IOs */ +	uint32_t eof_padding_size; /* size od EOF padding in the IOs */ + +	gf_lock_t call_lock; /* protect nr_calls from many cbks */ +	int32_t nr_calls; + +	atom_data_type active_setup; /* which setup (hole or date) +					is currently active */ +	/* data setup */ +	struct avec_config data_conf; + +	/* hole setup */ +	int hole_conv_in_proggress; +	gf_lock_t hole_lock; /* protect hole config from many cbks */ +	int hole_handled; +	struct avec_config hole_conf; +	struct iatt buf; +	struct iatt prebuf; +	struct iatt postbuf; +	struct iatt *prenewparent; +	struct iatt *postnewparent; +	int32_t op_ret; +	int32_t op_errno; +	int32_t rw_count; /* total read or written */ +	gf_lock_t rw_count_lock; /* protect the counter above */ +	unsigned char *format; /* for create, update format string */ +	uint32_t format_size; +	uint32_t msgflags; /* messages for crypt_open() */ +	dict_t *xdata; +	dict_t *xattr; +	struct iovec vec; /* contains last file's atom for +			     read-prune-write sequence */ +	gf_boolean_t custom_mtd; +	/* +	 * the next 3 fields are used by readdir and friends +	 */ +	gf_dirent_t *de; /* directory entry */ +	char *de_path; /* pathname of directory entry */ +	uint32_t de_prefix_len; /* lenght of the parent's pathname */ +	gf_dirent_t *entries; + +	uint32_t update_disk_file_size:1; +} crypt_local_t; + +/* This represents a (read)modify-write atom */ +struct rmw_atom { +	atom_locality_type locality; +	/* +	 * read-modify-write sequence of the atom +	 */ +	int32_t (*rmw)(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); +	/* +	 * offset of the logical block in a file +	 */ +	loff_t (*offset_at)(call_frame_t *frame, +			    struct object_cipher_info *object); +	/* +	 * IO offset in an atom +	 */ +	uint32_t (*offset_in)(call_frame_t *frame, +			      struct object_cipher_info *object); +	/* +	 * number of bytes of plain text of this atom that user +	 * wants to read/write. +	 * It can be smaller than atom_size in the case of head +	 * or tail atoms. +	 */ +	uint32_t (*io_size_nopad)(call_frame_t *frame, +				  struct object_cipher_info *object); +	/* +	 * which iovec represents the atom +	 */ +	struct iovec *(*get_iovec)(call_frame_t *frame, uint32_t count); +	/* +	 * how many bytes of partial block should be uptodated by +	 * reading from disk. +	 * This is used to perform a read component of RMW (read-modify-write). +	 */ +	uint32_t (*count_to_uptodate)(call_frame_t *frame, struct object_cipher_info *object); +	struct avec_config *(*get_config)(call_frame_t *frame); +}; + +struct data_cipher_alg { +	gf_boolean_t atomic; /* true means that algorithm requires +				to pad data before cipher transform */ +	gf_boolean_t should_pad; /* true means that algorithm requires +				    to pad the end of file with extra-data */ +	uint32_t blkbits; /* blksize = 1 << blkbits */ +	/* +	 * any preliminary sanity checks goes here +	 */ +	int32_t (*init)(void); +	/* +	 * set alg-mode specific inode info +	 */ +	int32_t (*set_private)(struct crypt_inode_info *info, +			       struct master_cipher_info *master); +	/* +	 * check alg-mode specific data key +	 */ +	int32_t (*check_key)(uint32_t key_size); +	void (*set_iv)(off_t offset, struct object_cipher_info *object); +	int32_t (*encrypt)(const unsigned char *from, unsigned char *to, +			   size_t length, off_t offset, const int enc, +			   struct object_cipher_info *object); +}; + +/* + * version-dependent metadata loader + */ +struct crypt_mtd_loader { +	/* +	 * return core format size +	 */ +	size_t (*format_size)(mtd_op_t op, size_t old_size); +	/* +	 * pack version-specific metadata of an object +	 * at ->create() +	 */ +	int32_t (*create_format)(unsigned char *wire, +				 loc_t *loc, +				 struct crypt_inode_info *info, +				 struct master_cipher_info *master); +	/* +	 * extract version-specific metadata of an object +	 * at ->open() time +	 */ +	int32_t (*open_format)(unsigned char *wire, +			       int32_t len, +			       loc_t *loc, +			       struct crypt_inode_info *info, +			       struct master_cipher_info *master, +			       crypt_local_t *local, +			       gf_boolean_t load_info); +	int32_t (*update_format)(unsigned char *new, +				 unsigned char *old, +				 size_t old_len, +				 int32_t mac_idx, +				 mtd_op_t op, +				 loc_t *loc, +				 struct crypt_inode_info *info, +				 struct master_cipher_info *master, +				 crypt_local_t *local); +}; + +typedef int32_t (*end_writeback_handler_t)(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); +typedef void (*linkop_wind_handler_t)(call_frame_t *frame, xlator_t *this); +typedef void (*linkop_unwind_handler_t)(call_frame_t *frame); + + +/* Declarations */ + +/* keys.c */ +extern struct crypt_key crypt_keys[LAST_KEY_TYPE]; +int32_t get_nmtd_vol_key(struct master_cipher_info *master); +int32_t get_nmtd_link_key(loc_t *loc, +			  struct master_cipher_info *master, +			  unsigned char *result); +int32_t get_emtd_file_key(struct crypt_inode_info *info, +			  struct master_cipher_info *master, +			  unsigned char *result); +int32_t get_data_file_key(struct crypt_inode_info *info, +			  struct master_cipher_info *master, +			  uint32_t keysize, +			  unsigned char *key); +/* data.c */ +extern struct data_cipher_alg data_cipher_algs[LAST_CIPHER_ALG][LAST_CIPHER_MODE]; +void encrypt_aligned_iov(struct object_cipher_info *object, +			 struct iovec *vec, +			 int count, +			 off_t off); +void decrypt_aligned_iov(struct object_cipher_info *object, +			 struct iovec *vec, +			 int count, +			 off_t off); +int32_t align_iov_by_atoms(xlator_t *this, +			   crypt_local_t *local, +			   struct object_cipher_info *object, +			   struct iovec *vec /* input vector */, +			   int32_t count /* number of vec components */, +			   struct iovec *avec /* aligned vector */, +			   char **blocks /* pool of blocks */, +			   uint32_t *blocks_allocated, +			   struct avec_config *conf); +int32_t set_config_avec_data(xlator_t *this, +			     crypt_local_t *local, +			     struct avec_config *conf, +			     struct object_cipher_info *object, +			     struct iovec *vec, +			     int32_t vec_count); +int32_t set_config_avec_hole(xlator_t *this, +			     crypt_local_t *local, +			     struct avec_config *conf, +			     struct object_cipher_info *object, +			     glusterfs_fop_t fop); +void set_gap_at_end(call_frame_t *frame, struct object_cipher_info *object, +		    struct avec_config *conf, atom_data_type dtype); +void set_config_offsets(call_frame_t *frame, +			xlator_t *this, +			uint64_t offset, +			uint64_t count, +			atom_data_type dtype, +			int32_t setup_gap_in_tail); + +/* metadata.c */ +extern struct crypt_mtd_loader mtd_loaders [LAST_MTD_LOADER]; + +int32_t alloc_format(crypt_local_t *local, size_t size); +int32_t alloc_format_create(crypt_local_t *local); +void free_format(crypt_local_t *local); +size_t format_size(mtd_op_t op, size_t old_size); +size_t new_format_size(void); +int32_t open_format(unsigned char *str, int32_t len, loc_t *loc, +		    struct crypt_inode_info *info, +		    struct master_cipher_info *master, crypt_local_t *local, +		    gf_boolean_t load_info); +int32_t update_format(unsigned char *new, unsigned char *old, +		      size_t old_len, int32_t mac_idx, mtd_op_t op, loc_t *loc, +		      struct crypt_inode_info *info, +		      struct master_cipher_info *master, +		      crypt_local_t *local); +int32_t create_format(unsigned char *wire, +		      loc_t *loc, +		      struct crypt_inode_info *info, +		      struct master_cipher_info *master); + +/* atom.c */ +struct rmw_atom *atom_by_types(atom_data_type data, +			       atom_locality_type locality); +void submit_partial(call_frame_t *frame, +		    xlator_t *this, +		    fd_t *fd, +		    atom_locality_type ltype); +void submit_full(call_frame_t *frame, xlator_t *this); + +/* crypt.c */ + +end_writeback_handler_t dispatch_end_writeback(glusterfs_fop_t fop); +static size_t iovec_get_size(struct iovec *vec, uint32_t count); +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); +void link_wind(call_frame_t *frame, xlator_t *this); +void unlink_wind(call_frame_t *frame, xlator_t *this); +void link_unwind(call_frame_t *frame); +void unlink_unwind(call_frame_t *frame); +void rename_wind(call_frame_t *frame, xlator_t *this); +void rename_unwind(call_frame_t *frame); + +/* Inline functions */ + +static inline size_t iovec_get_size(struct iovec *vec, uint32_t count) +{ +	int i; +	size_t size = 0; +	for (i = 0; i < count; i++) +		size += vec[i].iov_len; +	return size; +} + +static inline int32_t crypt_xlator_id(void) +{ +	return CRYPT_XLATOR_ID; +} + +static inline mtd_loader_id current_mtd_loader(void) +{ +	return MTD_LOADER_V1; +} + +static inline uint32_t master_key_size (void) +{ +	return crypt_keys[MASTER_VOL_KEY].len >> 3; +} + +static inline uint32_t nmtd_vol_key_size (void) +{ +	return crypt_keys[NMTD_VOL_KEY].len >> 3; +} + +static inline uint32_t alg_mode_blkbits(cipher_alg_t alg, +					cipher_mode_t mode) +{ +	return data_cipher_algs[alg][mode].blkbits; +} + +static inline uint32_t alg_mode_blksize(cipher_alg_t alg, +					cipher_mode_t mode) +{ +	return 1 << alg_mode_blkbits(alg, mode); +} + +static inline gf_boolean_t alg_mode_atomic(cipher_alg_t alg, +					   cipher_mode_t mode) +{ +	return data_cipher_algs[alg][mode].atomic; +} + +static inline gf_boolean_t alg_mode_should_pad(cipher_alg_t alg, +					       cipher_mode_t mode) +{ +	return data_cipher_algs[alg][mode].should_pad; +} + +static inline uint32_t master_alg_blksize(struct master_cipher_info *mr) +{ +	return alg_mode_blksize(mr->m_alg, mr->m_mode); +} + +static inline uint32_t master_alg_blkbits(struct master_cipher_info *mr) +{ +	return alg_mode_blkbits(mr->m_alg, mr->m_mode); +} + +static inline gf_boolean_t master_alg_atomic(struct master_cipher_info *mr) +{ +	return alg_mode_atomic(mr->m_alg, mr->m_mode); +} + +static inline gf_boolean_t master_alg_should_pad(struct master_cipher_info *mr) +{ +	return alg_mode_should_pad(mr->m_alg, mr->m_mode); +} + +static inline uint32_t object_alg_blksize(struct object_cipher_info *ob) +{ +	return alg_mode_blksize(ob->o_alg, ob->o_mode); +} + +static inline uint32_t object_alg_blkbits(struct object_cipher_info *ob) +{ +	return alg_mode_blkbits(ob->o_alg, ob->o_mode); +} + +static inline gf_boolean_t object_alg_atomic(struct object_cipher_info *ob) +{ +	return alg_mode_atomic(ob->o_alg, ob->o_mode); +} + +static inline gf_boolean_t object_alg_should_pad(struct object_cipher_info *ob) +{ +	return alg_mode_should_pad(ob->o_alg, ob->o_mode); +} + +static inline uint32_t aes_raw_key_size(struct master_cipher_info *master) +{ +	return master->m_dkey_size >> 3; +} + +static inline struct avec_config *get_hole_conf(call_frame_t *frame) +{ +	return &(((crypt_local_t *)frame->local)->hole_conf); +} + +static inline struct avec_config *get_data_conf(call_frame_t *frame) +{ +	return &(((crypt_local_t *)frame->local)->data_conf); +} + +static inline int32_t get_atom_bits (struct object_cipher_info *object) +{ +	return object->o_block_bits; +} + +static inline int32_t get_atom_size (struct object_cipher_info *object) +{ +	return 1 << get_atom_bits(object); +} + +static inline int32_t has_head_block(struct avec_config *conf) +{ +	return conf->off_in_head || +		(conf->acount == 1 && conf->off_in_tail); +} + +static inline int32_t has_tail_block(struct avec_config *conf) +{ +	return conf->off_in_tail && conf->acount > 1; +} + +static inline int32_t has_full_blocks(struct avec_config *conf) +{ +	return conf->nr_full_blocks; +} + +static inline int32_t should_submit_head_block(struct avec_config *conf) +{ +	return has_head_block(conf) && (conf->cursor == 0); +} + +static inline int32_t should_submit_tail_block(struct avec_config *conf) +{ +	return has_tail_block(conf) && (conf->cursor == conf->acount - 1); +} + +static inline int32_t should_submit_full_block(struct avec_config *conf) +{ +	uint32_t start = has_head_block(conf) ? 1 : 0; + +	return has_full_blocks(conf) && +		conf->cursor >= start && +		conf->cursor < start + conf->nr_full_blocks; +} + +#if DEBUG_CRYPT +static inline void crypt_check_input_len(size_t len, +					 struct object_cipher_info *object) +{ +	if (object_alg_should_pad(object) && (len & (object_alg_blksize(object) - 1))) +		gf_log ("crypt", GF_LOG_DEBUG, "bad input len: %d", (int)len); +} + +static inline void check_head_block(struct avec_config *conf) +{ +	if (!has_head_block(conf)) +		gf_log("crypt", GF_LOG_DEBUG, "not a head atom"); +} + +static inline void check_tail_block(struct avec_config *conf) +{ +	if (!has_tail_block(conf)) +		gf_log("crypt", GF_LOG_DEBUG, "not a tail atom"); +} + +static inline void check_full_block(struct avec_config *conf) +{ +	if (!has_full_blocks(conf)) +		gf_log("crypt", GF_LOG_DEBUG, "not a full atom"); +} + +static inline void check_cursor_head(struct avec_config *conf) +{ +	if (!has_head_block(conf)) +		gf_log("crypt", +		       GF_LOG_DEBUG, "Illegal call of head atom method"); +	else if (conf->cursor != 0) +		gf_log("crypt", +		       GF_LOG_DEBUG, "Cursor (%d) is not at head atom", +		       conf->cursor); +} + +static inline void check_cursor_full(struct avec_config *conf) +{ +	if (!has_full_blocks(conf)) +		gf_log("crypt", +		       GF_LOG_DEBUG, "Illegal call of full atom method"); +	if (has_head_block(conf) && (conf->cursor == 0)) +		gf_log("crypt", +		       GF_LOG_DEBUG, "Cursor is not at full atom"); +} + +/* + * FIXME: use avec->iov_len to check setup + */ +static inline int data_local_invariant(crypt_local_t *local) +{ +	return 0; +} + +#else +#define crypt_check_input_len(len, object) noop +#define check_head_block(conf) noop +#define check_tail_block(conf) noop +#define check_full_block(conf) noop +#define check_cursor_head(conf) noop +#define check_cursor_full(conf) noop + +#endif /* DEBUG_CRYPT */ + +static inline struct avec_config *conf_by_type(call_frame_t *frame, +					       atom_data_type dtype) +{ +	struct avec_config *conf = NULL; + +	switch (dtype) { +	case HOLE_ATOM: +		conf = get_hole_conf(frame); +		break; +	case DATA_ATOM: +		conf = get_data_conf(frame); +		break; +	default: +		gf_log("crypt", GF_LOG_DEBUG, "bad atom type"); +	} +	return conf; +} + +static inline uint32_t nr_calls_head(struct avec_config *conf) +{ +	return has_head_block(conf) ? 1 : 0; +} + +static inline uint32_t nr_calls_tail(struct avec_config *conf) +{ +	return has_tail_block(conf) ? 1 : 0; +} + +static inline uint32_t nr_calls_full(struct avec_config *conf) +{ +	switch(conf->type) { +	case HOLE_ATOM: +		return has_full_blocks(conf); +	case DATA_ATOM: +		return has_full_blocks(conf) ? +			logical_blocks_occupied(0, +						conf->nr_full_blocks, +						MAX_IOVEC_BITS)	: 0; +	default: +		gf_log("crypt", GF_LOG_DEBUG, "bad atom data type"); +		return 0; +	} +} + +static inline uint32_t nr_calls(struct avec_config *conf) +{ +	return nr_calls_head(conf) + nr_calls_tail(conf) + nr_calls_full(conf); +} + +static inline uint32_t nr_calls_data(call_frame_t *frame) +{ +	return nr_calls(get_data_conf(frame)); +} + +static inline uint32_t nr_calls_hole(call_frame_t *frame) +{ +	return nr_calls(get_hole_conf(frame)); +} + +static inline void get_one_call_nolock(call_frame_t *frame) +{ +	crypt_local_t *local = frame->local; + +	++local->nr_calls; + +	//gf_log("crypt", GF_LOG_DEBUG, "get %d calls", 1); +} + +static inline void get_one_call(call_frame_t *frame) +{ +	crypt_local_t *local = frame->local; + +	LOCK(&local->call_lock); +	get_one_call_nolock(frame); +	UNLOCK(&local->call_lock); +} + +static inline void get_nr_calls_nolock(call_frame_t *frame, int32_t nr) +{ +	crypt_local_t *local = frame->local; + +	local->nr_calls += nr; + +	//gf_log("crypt", GF_LOG_DEBUG, "get %d calls", nr); +} + +static inline void get_nr_calls(call_frame_t *frame, int32_t nr) +{ +	crypt_local_t *local = frame->local; + +	LOCK(&local->call_lock); +	get_nr_calls_nolock(frame, nr); +	UNLOCK(&local->call_lock); +} + +static inline int put_one_call(crypt_local_t *local) +{ +	uint32_t last = 0; + +	LOCK(&local->call_lock); +	if (--local->nr_calls == 0) +		last = 1; + +	//gf_log("crypt", GF_LOG_DEBUG, "put %d calls", 1); + +	UNLOCK(&local->call_lock); +	return last; +} + +static inline int is_appended_write(call_frame_t *frame) +{ +	crypt_local_t *local = frame->local; +	struct avec_config *conf = get_data_conf(frame); + +	return conf->orig_offset + conf->orig_size > local->old_file_size; +} + +static inline int is_ordered_mode(call_frame_t *frame) +{ +#if 0 +	crypt_local_t *local = frame->local; +	return local->fop == GF_FOP_FTRUNCATE || +		(local->fop == GF_FOP_WRITE && is_appended_write(frame)); +#endif +	return 1; +} + +static inline int32_t hole_conv_completed(crypt_local_t *local) +{ +	struct avec_config *conf = &local->hole_conf; +	return conf->cursor == conf->acount; +} + +static inline int32_t data_write_in_progress(crypt_local_t *local) +{ +	return local->active_setup == DATA_ATOM; +} + +static inline int32_t parent_is_crypt_xlator(call_frame_t *frame, +					     xlator_t *this) +{ +	return frame->parent->this == this; +} + +static inline linkop_wind_handler_t linkop_wind_dispatch(glusterfs_fop_t fop) +{ +	switch(fop){ +	case GF_FOP_LINK: +		return link_wind; +	case GF_FOP_UNLINK: +		return unlink_wind; +	case GF_FOP_RENAME: +		return rename_wind; +	default: +		gf_log("crypt", GF_LOG_ERROR, "Bad link operation %d", fop); +		return NULL; +	} +} + +static inline linkop_unwind_handler_t linkop_unwind_dispatch(glusterfs_fop_t fop) +{ +	switch(fop){ +	case GF_FOP_LINK: +		return link_unwind; +	case GF_FOP_UNLINK: +		return unlink_unwind; +	case GF_FOP_RENAME: +		return rename_unwind; +	default: +		gf_log("crypt", GF_LOG_ERROR, "Bad link operation %d", fop); +		return NULL;		 +	}	 +} + +static inline mtd_op_t linkop_mtdop_dispatch(glusterfs_fop_t fop) +{ +	switch (fop) { +	case GF_FOP_LINK: +		return MTD_APPEND; +	case GF_FOP_UNLINK: +		return MTD_CUT; +	case GF_FOP_RENAME: +		return MTD_OVERWRITE; +	default: +		gf_log("crypt", GF_LOG_WARNING, "Bad link operation %d", fop); +		return MTD_LAST_OP; +	} +} + +#endif /* __CRYPT_H__ */ + +/* +  Local variables: +  c-indentation-style: "K&R" +  mode-name: "LC" +  c-basic-offset: 8 +  tab-width: 8 +  fill-column: 80 +  scroll-step: 1 +  End: +*/  | 
