/* Copyright (c) 2013 Red Hat, Inc. 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 _AFR_SELFHEAL_H #define _AFR_SELFHEAL_H /* Perform fop on all UP subvolumes and wait for all callbacks to return */ #define AFR_ONALL(frame, rfn, fop, args...) \ do { \ afr_local_t *__local = frame->local; \ afr_private_t *__priv = frame->this->private; \ int __i = 0, __count = 0; \ unsigned char *__child_up = NULL; \ \ __child_up = alloca0(__priv->child_count); \ memcpy(__child_up, __priv->child_up, \ sizeof(*__child_up) * __priv->child_count); \ __count = AFR_COUNT(__child_up, __priv->child_count); \ \ __local->barrier.waitfor = __count; \ afr_local_replies_wipe(__local, __priv); \ \ for (__i = 0; __i < __priv->child_count; __i++) { \ if (!__child_up[__i]) \ continue; \ STACK_WIND_COOKIE(frame, rfn, (void *)(long)__i, \ __priv->children[__i], \ __priv->children[__i]->fops->fop, args); \ } \ syncbarrier_wait(&__local->barrier, __count); \ } while (0) /* Perform fop on all subvolumes represented by list[] array and wait for all callbacks to return */ #define AFR_ONLIST(list, frame, rfn, fop, args...) \ do { \ afr_local_t *__local = frame->local; \ afr_private_t *__priv = frame->this->private; \ int __i = 0; \ int __count = 0; \ unsigned char *__list = alloca(__priv->child_count); \ \ memcpy(__list, list, sizeof(*__list) * __priv->child_count); \ __count = AFR_COUNT(__list, __priv->child_count); \ __local->barrier.waitfor = __count; \ afr_local_replies_wipe(__local, __priv); \ \ for (__i = 0; __i < __priv->child_count; __i++) { \ if (!__list[__i]) \ continue; \ STACK_WIND_COOKIE(frame, rfn, (void *)(long)__i, \ __priv->children[__i], \ __priv->children[__i]->fops->fop, args); \ } \ syncbarrier_wait(&__local->barrier, __count); \ } while (0) #define AFR_SEQ(frame, rfn, fop, args...) \ do { \ afr_local_t *__local = frame->local; \ afr_private_t *__priv = frame->this->private; \ int __i = 0; \ \ afr_local_replies_wipe(__local, __priv); \ \ for (__i = 0; __i < __priv->child_count; __i++) { \ if (!__priv->child_up[__i]) \ continue; \ STACK_WIND_COOKIE(frame, rfn, (void *)(long)__i, \ __priv->children[__i], \ __priv->children[__i]->fops->fop, args); \ syncbarrier_wait(&__local->barrier, 1); \ } \ } while (0) #define ALLOC_MATRIX(n, type) \ ({ \ type **__ptr = NULL; \ int __i; \ __ptr = alloca0(n * sizeof(type *)); \ for (__i = 0; __i < n; __i++) \ __ptr[__i] = alloca0(n * sizeof(type)); \ __ptr; \ }) #define IA_EQUAL(f, s, field) \ (memcmp(&(f.ia_##field), &(s.ia_##field), sizeof(s.ia_##field)) == 0) #define SBRAIN_HEAL_NO_GO_MSG \ "Failed to obtain replies from all bricks of " \ "the replica (are they up?). Cannot resolve split-brain." #define SFILE_NOT_IN_SPLIT_BRAIN "File not in split-brain" #define SNO_BIGGER_FILE "No bigger file" #define SNO_DIFF_IN_MTIME "No difference in mtime" #define SUSE_SOURCE_BRICK_TO_HEAL \ "Use source-brick option to heal metadata" \ " split-brain" #define SINVALID_BRICK_NAME "Invalid brick name" #define SBRICK_IS_NOT_UP "Brick is not up" #define SBRICK_NOT_CONNECTED "Brick is not connected" #define SLESS_THAN2_BRICKS_in_REP "< 2 bricks in replica are up" #define SBRICK_IS_REMOTE "Brick is remote" #define SSTARTED_SELF_HEAL "Started self-heal" #define SOP_NOT_SUPPORTED "Operation Not Supported" #define SFILE_NOT_UNDER_DATA \ "The file is not under data or metadata " \ "split-brain" #define SFILE_NOT_IN_SPLIT_BRAIN "File not in split-brain" #define SALL_BRICKS_UP_TO_RESOLVE \ "All the bricks should be up to resolve the" \ " gfid split brain" #define SERROR_GETTING_SRC_BRICK "Error getting the source brick" int afr_selfheal(xlator_t *this, uuid_t gfid); gf_boolean_t afr_throttled_selfheal(call_frame_t *frame, xlator_t *this); int afr_selfheal_name(xlator_t *this, uuid_t gfid, const char *name, void *gfid_req, dict_t *xdata); int afr_selfheal_data(call_frame_t *frame, xlator_t *this, fd_t *fd); int afr_selfheal_metadata(call_frame_t *frame, xlator_t *this, inode_t *inode); int afr_selfheal_entry(call_frame_t *frame, xlator_t *this, inode_t *inode); int afr_lookup_and_heal_gfid(xlator_t *this, inode_t *parent, const char *name, inode_t *inode, struct afr_reply *replies, int source, unsigned char *sources, void *gfid, int *gfid_idx); int afr_selfheal_inodelk(call_frame_t *frame, xlator_t *this, inode_t *inode, char *dom, off_t off, size_t size, unsigned char *locked_on); int afr_selfheal_tryinodelk(call_frame_t *frame, xlator_t *this, inode_t *inode, char *dom, off_t off, size_t size, unsigned char *locked_on); int afr_selfheal_tie_breaker_inodelk(call_frame_t *frame, xlator_t *this, inode_t *inode, char *dom, off_t off, size_t size, unsigned char *locked_on); int afr_selfheal_uninodelk(call_frame_t *frame, xlator_t *this, inode_t *inode, char *dom, off_t off, size_t size, const unsigned char *locked_on); int afr_selfheal_entrylk(call_frame_t *frame, xlator_t *this, inode_t *inode, char *dom, const char *name, unsigned char *locked_on); int afr_selfheal_tryentrylk(call_frame_t *frame, xlator_t *this, inode_t *inode, char *dom, const char *name, unsigned char *locked_on); int afr_selfheal_tie_breaker_entrylk(call_frame_t *frame, xlator_t *this, inode_t *inode, char *dom, const char *name, unsigned char *locked_on); int afr_selfheal_unentrylk(call_frame_t *frame, xlator_t *this, inode_t *inode, char *dom, const char *name, unsigned char *locked_on, dict_t *xdata); int afr_selfheal_unlocked_discover(call_frame_t *frame, inode_t *inode, uuid_t gfid, struct afr_reply *replies); int afr_selfheal_unlocked_discover_on(call_frame_t *frame, inode_t *inode, uuid_t gfid, struct afr_reply *replies, unsigned char *discover_on, dict_t *dict); inode_t * afr_selfheal_unlocked_lookup_on(call_frame_t *frame, inode_t *parent, const char *name, struct afr_reply *replies, unsigned char *lookup_on, dict_t *xattr); int afr_selfheal_find_direction(call_frame_t *frame, xlator_t *this, struct afr_reply *replies, afr_transaction_type type, unsigned char *locked_on, unsigned char *sources, unsigned char *sinks, uint64_t *witness, unsigned char *flag); int afr_selfheal_fill_matrix(xlator_t *this, int **matrix, int subvol, int idx, dict_t *xdata); int afr_selfheal_extract_xattr(xlator_t *this, struct afr_reply *replies, afr_transaction_type type, int *dirty, int **matrix); int afr_sh_generic_fop_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *pre, struct iatt *post, dict_t *xdata); int afr_selfheal_restore_time(call_frame_t *frame, xlator_t *this, inode_t *inode, int source, unsigned char *healed_sinks, struct afr_reply *replies); int afr_selfheal_undo_pending(call_frame_t *frame, xlator_t *this, inode_t *inode, unsigned char *sources, unsigned char *sinks, unsigned char *healed_sinks, unsigned char *undid_pending, afr_transaction_type type, struct afr_reply *replies, unsigned char *locked_on); int afr_selfheal_recreate_entry(call_frame_t *frame, int dst, int source, unsigned char *sources, inode_t *dir, const char *name, inode_t *inode, struct afr_reply *replies); int afr_selfheal_post_op(call_frame_t *frame, xlator_t *this, inode_t *inode, int subvol, dict_t *xattr, dict_t *xdata); call_frame_t * afr_frame_create(xlator_t *this, int32_t *op_errno); inode_t * afr_inode_find(xlator_t *this, uuid_t gfid); int afr_selfheal_discover_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *buf, dict_t *xdata, struct iatt *parbuf); void afr_reply_copy(struct afr_reply *dst, struct afr_reply *src); void afr_replies_copy(struct afr_reply *dst, struct afr_reply *src, int count); int afr_selfheal_newentry_mark(call_frame_t *frame, xlator_t *this, inode_t *inode, int source, struct afr_reply *replies, unsigned char *sources, unsigned char *newentry); unsigned int afr_success_count(struct afr_reply *replies, unsigned int count); void afr_log_selfheal(uuid_t gfid, xlator_t *this, int ret, char *type, int source, unsigned char *sources, unsigned char *healed_sinks); void afr_mark_largest_file_as_source(xlator_t *this, unsigned char *sources, struct afr_reply *replies); void afr_mark_active_sinks(xlator_t *this, unsigned char *sources, unsigned char *locked_on, unsigned char *sinks); gf_boolean_t afr_dict_contains_heal_op(call_frame_t *frame); gf_boolean_t afr_can_decide_split_brain_source_sinks(struct afr_reply *replies, int child_count); int afr_mark_split_brain_source_sinks( call_frame_t *frame, xlator_t *this, inode_t *inode, unsigned char *sources, unsigned char *sinks, unsigned char *healed_sinks, unsigned char *locked_on, struct afr_reply *replies, afr_transaction_type type); int afr_sh_get_fav_by_policy(xlator_t *this, struct afr_reply *replies, inode_t *inode, char **policy_str); int _afr_fav_child_reset_sink_xattrs(call_frame_t *frame, xlator_t *this, inode_t *inode, int source, unsigned char *healed_sinks, unsigned char *undid_pending, afr_transaction_type type, unsigned char *locked_on, struct afr_reply *replies); int afr_get_child_index_from_name(xlator_t *this, char *name); gf_boolean_t afr_does_witness_exist(xlator_t *this, uint64_t *witness); int __afr_selfheal_data_prepare(call_frame_t *frame, xlator_t *this, inode_t *inode, unsigned char *locked_on, unsigned char *sources, unsigned char *sinks, unsigned char *healed_sinks, unsigned char *undid_pending, struct afr_reply *replies, unsigned char *flag); int __afr_selfheal_metadata_prepare(call_frame_t *frame, xlator_t *this, inode_t *inode, unsigned char *locked_on, unsigned char *sources, unsigned char *sinks, unsigned char *healed_sinks, unsigned char *undid_pending, struct afr_reply *replies, unsigned char *flag); int __afr_selfheal_entry_prepare(call_frame_t *frame, xlator_t *this, inode_t *inode, unsigned char *locked_on, unsigned char *sources, unsigned char *sinks, unsigned char *healed_sinks, struct afr_reply *replies, int *source_p, unsigned char *flag); int afr_selfheal_unlocked_inspect(call_frame_t *frame, xlator_t *this, uuid_t gfid, inode_t **link_inode, gf_boolean_t *data_selfheal, gf_boolean_t *metadata_selfheal, gf_boolean_t *entry_selfheal); int afr_selfheal_do(call_frame_t *frame, xlator_t *this, uuid_t gfid); int afr_selfheal_lock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata); int afr_locked_fill(call_frame_t *frame, xlator_t *this, unsigned char *locked_on); int afr_choose_source_by_policy(afr_private_t *priv, unsigned char *sources, afr_transaction_type type); int afr_selfheal_metadata_by_stbuf(xlator_t *this, struct iatt *stbuf); int afr_sh_fav_by_size(xlator_t *this, struct afr_reply *replies, inode_t *inode); int afr_sh_fav_by_mtime(xlator_t *this, struct afr_reply *replies, inode_t *inode); int afr_sh_fav_by_ctime(xlator_t *this, struct afr_reply *replies, inode_t *inode); int afr_gfid_split_brain_source(xlator_t *this, struct afr_reply *replies, inode_t *inode, uuid_t pargfid, const char *bname, int src_idx, int child_idx, unsigned char *locked_on, int *src, dict_t *xdata); int afr_mark_source_sinks_if_file_empty(xlator_t *this, unsigned char *sources, unsigned char *sinks, unsigned char *healed_sinks, unsigned char *locked_on, struct afr_reply *replies, afr_transaction_type type); gf_boolean_t afr_is_file_empty_on_all_children(afr_private_t *priv, struct afr_reply *replies); #endif /* !_AFR_SELFHEAL_H */