/* Copyright (c) 2013 Red Hat, Inc. 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 _CONFIG_H #define _CONFIG_H #include "config.h" #endif #include "call-stub.h" #include "defaults.h" #include "timer.h" #include "xlator.h" #define SCAR_LIMIT 20 #define HILITE(x) (""x"") /* * The fops are actually generated by gen-fops.py; the rest was mostly copied * from defaults.c (commit cd253754 on 27 August 2013). */ enum gf_dht_mem_types_ { gf_mt_nsrc_private_t = gf_common_mt_end + 1, }; typedef struct { xlator_t *active; } nsrc_private_t; typedef struct { call_stub_t *stub; xlator_t *curr_xl; uint16_t scars; } nsrc_local_t; char *NSRC_XATTR = "user.nsr.active"; static inline xlator_t * ACTIVE_CHILD (xlator_t *parent) { nsrc_private_t *priv = parent->private; return priv ? priv->active : FIRST_CHILD(parent); } xlator_t * next_xlator (xlator_t *this, xlator_t *prev) { xlator_list_t *trav; for (trav = this->children; trav; trav = trav->next) { if (trav->xlator == prev) { return trav->next ? trav->next->xlator : this->children->xlator; } } return NULL; } void nsrc_retry_cb (void *cb_arg) { nsrc_local_t *local = cb_arg; gf_log (__func__, GF_LOG_INFO, HILITE("retrying %p"), local); call_resume_wind(local->stub); } #include "nsrc-cg.c" int32_t nsrc_forget (xlator_t *this, inode_t *inode) { gf_log_callingfn (this->name, GF_LOG_WARNING, "xlator does not " "implement forget_cbk"); return 0; } int32_t nsrc_releasedir (xlator_t *this, fd_t *fd) { gf_log_callingfn (this->name, GF_LOG_WARNING, "xlator does not " "implement releasedir_cbk"); return 0; } int32_t nsrc_release (xlator_t *this, fd_t *fd) { gf_log_callingfn (this->name, GF_LOG_WARNING, "xlator does not " "implement release_cbk"); return 0; } struct xlator_fops fops = { .lookup = nsrc_lookup, .stat = nsrc_stat, .fstat = nsrc_fstat, .truncate = nsrc_truncate, .ftruncate = nsrc_ftruncate, .access = nsrc_access, .readlink = nsrc_readlink, .mknod = nsrc_mknod, .mkdir = nsrc_mkdir, .unlink = nsrc_unlink, .rmdir = nsrc_rmdir, .symlink = nsrc_symlink, .rename = nsrc_rename, .link = nsrc_link, .create = nsrc_create, .open = nsrc_open, .readv = nsrc_readv, .writev = nsrc_writev, .flush = nsrc_flush, .fsync = nsrc_fsync, .opendir = nsrc_opendir, .readdir = nsrc_readdir, .readdirp = nsrc_readdirp, .fsyncdir = nsrc_fsyncdir, .statfs = nsrc_statfs, .setxattr = nsrc_setxattr, .getxattr = nsrc_getxattr, .fsetxattr = nsrc_fsetxattr, .fgetxattr = nsrc_fgetxattr, .removexattr = nsrc_removexattr, .fremovexattr = nsrc_fremovexattr, .lk = nsrc_lk, .inodelk = nsrc_inodelk, .finodelk = nsrc_finodelk, .entrylk = nsrc_entrylk, .fentrylk = nsrc_fentrylk, .rchecksum = nsrc_rchecksum, .xattrop = nsrc_xattrop, .fxattrop = nsrc_fxattrop, .setattr = nsrc_setattr, .fsetattr = nsrc_fsetattr, .fallocate = nsrc_fallocate, .discard = nsrc_discard, }; struct xlator_cbks cbks = { }; int32_t nsrc_init (xlator_t *this) { nsrc_private_t *priv = NULL; this->local_pool = mem_pool_new (nsrc_local_t, 128); if (!this->local_pool) { gf_log (this->name, GF_LOG_ERROR, "failed to create nsrc_local_t pool"); goto err; } priv = GF_CALLOC (1, sizeof (*priv), gf_mt_nsrc_private_t); if (!priv) { goto err; } priv->active = FIRST_CHILD(this); this->private = priv; return 0; err: if (priv) { GF_FREE(priv); } return -1; } void nsrc_fini (xlator_t *this) { GF_FREE(this->private); } int32_t nsrc_notify (xlator_t *this, int32_t event, void *data, void *data2) { int32_t ret = 0; switch (event) { case GF_EVENT_CHILD_DOWN: /* * TBD: handle this properly * * What we really should do is propagate this only if it caused * us to lose quorum, and likewise for GF_EVENT_CHILD_UP only * if it caused us to gain quorum. However, that requires * tracking child states and for now it's easier to swallow * these unconditionally. The consequence of failing to do * this is that DHT sees the first GF_EVENT_CHILD_DOWN and gets * confused, so it doesn't call us and doesn't get up-to-date * directory listings etc. */ break; default: ret = default_notify (this, event, data); } return ret; } class_methods_t class_methods = { .init = nsrc_init, .fini = nsrc_fini, .notify = nsrc_notify, }; struct volume_options options[] = { { .key = {NULL} }, };