/* Copyright (c) 2012-2016 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. */ #include #include #include "glfs-internal.h" #include "glfs-mem-types.h" #include "gfapi-messages.h" int graph_setup(struct glfs *fs, glusterfs_graph_t *graph) { xlator_t *new_subvol = NULL; xlator_t *old_subvol = NULL; inode_table_t *itable = NULL; int ret = -1; new_subvol = graph->top; /* This is called in a bottom-up context, it should specifically NOT be glfs_lock() */ pthread_mutex_lock(&fs->mutex); { if (new_subvol->switched || new_subvol == fs->active_subvol || new_subvol == fs->next_subvol || new_subvol == fs->mip_subvol) { /* Spurious CHILD_UP event on old graph */ ret = 0; goto unlock; } if (!new_subvol->itable) { itable = inode_table_new(131072, new_subvol); if (!itable) { errno = ENOMEM; ret = -1; goto unlock; } new_subvol->itable = itable; } old_subvol = fs->next_subvol; fs->next_subvol = new_subvol; fs->next_subvol->winds++; /* first ref */ ret = 0; } unlock: pthread_mutex_unlock(&fs->mutex); if (old_subvol) /* wasn't picked up so far, skip */ glfs_subvol_done(fs, old_subvol); return ret; } int notify(xlator_t *this, int event, void *data, ...) { glusterfs_graph_t *graph = NULL; struct glfs *fs = NULL; graph = data; fs = this->private; switch (event) { case GF_EVENT_GRAPH_NEW: gf_smsg(this->name, GF_LOG_INFO, 0, API_MSG_NEW_GRAPH, "graph-uuid=%s", uuid_utoa((unsigned char *)graph->graph_uuid), "id=%d", graph->id, NULL); break; case GF_EVENT_CHILD_UP: pthread_mutex_lock(&fs->mutex); { graph->used = 1; } pthread_mutex_unlock(&fs->mutex); graph_setup(fs, graph); glfs_init_done(fs, 0); break; case GF_EVENT_CHILD_DOWN: pthread_mutex_lock(&fs->mutex); { graph->used = 0; pthread_cond_broadcast(&fs->child_down_cond); } pthread_mutex_unlock(&fs->mutex); glfs_init_done(fs, 1); break; case GF_EVENT_CHILD_CONNECTING: break; case GF_EVENT_UPCALL: glfs_process_upcall_event(fs, data); break; default: gf_msg_debug(this->name, 0, "got notify event %d", event); break; } return 0; } int mem_acct_init(xlator_t *this) { int ret = -1; if (!this) return ret; ret = xlator_mem_acct_init(this, glfs_mt_end + 1); if (ret) { gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, API_MSG_MEM_ACCT_INIT_FAILED, NULL); return ret; } return 0; } int init(xlator_t *this) { return 0; } void fini(xlator_t *this) { } /* place-holder fops */ int glfs_forget(xlator_t *this, inode_t *inode) { return 0; } int glfs_release(xlator_t *this, fd_t *fd) { return 0; } int glfs_releasedir(xlator_t *this, fd_t *fd) { return 0; } struct xlator_dumpops dumpops; struct xlator_fops fops; struct xlator_cbks cbks = { .forget = glfs_forget, .release = glfs_release, .releasedir = glfs_releasedir, }; xlator_api_t xlator_api = { .init = init, .fini = fini, .notify = notify, .mem_acct_init = mem_acct_init, .op_version = {1}, .dumpops = &dumpops, .fops = &fops, .cbks = &cbks, .identifier = "glfs-api", .category = GF_MAINTAINED, };