diff options
Diffstat (limited to 'xlators/meta/src')
40 files changed, 2815 insertions, 1758 deletions
diff --git a/xlators/meta/src/Makefile.am b/xlators/meta/src/Makefile.am index f8fa7d4cb13..29b871d7984 100644 --- a/xlators/meta/src/Makefile.am +++ b/xlators/meta/src/Makefile.am @@ -1,11 +1,44 @@ -xlator_PROGRAMS = meta.so -xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/ +xlator_LTLIBRARIES = meta.la +xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator -meta_so_SOURCES = meta.c tree.c misc.c view.c -noinst_HEADERS = meta.h tree.h misc.h view.h +meta_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) -AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src +meta_la_SOURCES = meta.c meta-helpers.c meta-defaults.c \ + root-dir.c \ + graphs-dir.c \ + frames-file.c \ + graph-dir.c \ + active-link.c \ + xlator-dir.c \ + top-link.c \ + logging-dir.c \ + logfile-link.c \ + loglevel-file.c \ + process_uuid-file.c \ + volfile-file.c \ + view-dir.c \ + subvolumes-dir.c \ + subvolume-link.c \ + type-file.c \ + version-file.c \ + options-dir.c \ + option-file.c \ + cmdline-file.c \ + name-file.c \ + private-file.c \ + history-file.c \ + mallinfo-file.c \ + meminfo-file.c \ + measure-file.c \ + profile-file.c -AM_CFLAGS = -Wall +meta_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la -CLEANFILES = +noinst_HEADERS = meta.h meta-hooks.h meta-mem-types.h + +AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ + -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src + +AM_CFLAGS = -Wall $(GF_CFLAGS) + +CLEANFILES = diff --git a/xlators/meta/src/active-link.c b/xlators/meta/src/active-link.c new file mode 100644 index 00000000000..7ee780d89e9 --- /dev/null +++ b/xlators/meta/src/active-link.c @@ -0,0 +1,34 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" + +static int +active_link_fill(xlator_t *this, inode_t *inode, strfd_t *strfd) +{ + strprintf(strfd, "%s", this->ctx->active->graph_uuid); + + return 0; +} + +struct meta_ops active_link_ops = {.link_fill = active_link_fill}; + +int +meta_active_link_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + meta_ops_set(loc->inode, this, &active_link_ops); + + return 0; +} diff --git a/xlators/meta/src/cmdline-file.c b/xlators/meta/src/cmdline-file.c new file mode 100644 index 00000000000..eb24e985af9 --- /dev/null +++ b/xlators/meta/src/cmdline-file.c @@ -0,0 +1,39 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" +#include <glusterfs/strfd.h> +#include <glusterfs/lkowner.h> + +static int +cmdline_file_fill(xlator_t *this, inode_t *file, strfd_t *strfd) +{ + if (this->ctx->cmdlinestr) + strprintf(strfd, "{ \n \"Cmdlinestr\": \"%s\"\n}", + this->ctx->cmdlinestr); + return strfd->size; +} + +static struct meta_ops cmdline_file_ops = { + .file_fill = cmdline_file_fill, +}; + +int +meta_cmdline_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + meta_ops_set(loc->inode, this, &cmdline_file_ops); + + return 0; +} diff --git a/xlators/meta/src/frames-file.c b/xlators/meta/src/frames-file.c new file mode 100644 index 00000000000..9a13db9a934 --- /dev/null +++ b/xlators/meta/src/frames-file.c @@ -0,0 +1,107 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" +#include <glusterfs/strfd.h> +#include <glusterfs/lkowner.h> + +static int +frames_file_fill(xlator_t *this, inode_t *file, strfd_t *strfd) +{ + struct call_pool *pool = NULL; + call_stack_t *stack = NULL; + call_frame_t *frame = NULL; + int i = 0; + int j = 1; + + if (!this || !file || !strfd) + return -1; + + pool = this->ctx->pool; + + strprintf(strfd, "{ \n\t\"Stack\": [\n"); + + LOCK(&pool->lock); + { + list_for_each_entry(stack, &pool->all_frames, all_frames) + { + strprintf(strfd, "\t {\n"); + strprintf(strfd, "\t\t\"Number\": %d,\n", ++i); + strprintf(strfd, "\t\t\"Frame\": [\n"); + j = 1; + list_for_each_entry(frame, &stack->myframes, frames) + { + strprintf(strfd, "\t\t {\n"); + strprintf(strfd, "\t\t\t\"Number\": %d,\n", j++); + strprintf(strfd, "\t\t\t\"Xlator\": \"%s\",\n", + frame->this->name); + if (frame->begin.tv_sec) + strprintf(strfd, "\t\t\t\"Creation_time\": %d.%09d,\n", + (int)frame->begin.tv_sec, + (int)frame->begin.tv_nsec); + strprintf(strfd, " \t\t\t\"Refcount\": %d,\n", + frame->ref_count); + if (frame->parent) + strprintf(strfd, "\t\t\t\"Parent\": \"%s\",\n", + frame->parent->this->name); + if (frame->wind_from) + strprintf(strfd, "\t\t\t\"Wind_from\": \"%s\",\n", + frame->wind_from); + if (frame->wind_to) + strprintf(strfd, "\t\t\t\"Wind_to\": \"%s\",\n", + frame->wind_to); + if (frame->unwind_from) + strprintf(strfd, "\t\t\t\"Unwind_from\": \"%s\",\n", + frame->unwind_from); + if (frame->unwind_to) + strprintf(strfd, "\t\t\t\"Unwind_to\": \"%s\",\n", + frame->unwind_to); + strprintf(strfd, "\t\t\t\"Complete\": %d\n", frame->complete); + if (list_is_last(&frame->frames, &stack->myframes)) + strprintf(strfd, "\t\t }\n"); + else + strprintf(strfd, "\t\t },\n"); + } + strprintf(strfd, "\t\t],\n"); + strprintf(strfd, "\t\t\"Unique\": %" PRId64 ",\n", stack->unique); + strprintf(strfd, "\t\t\"Type\": \"%s\",\n", gf_fop_list[stack->op]); + strprintf(strfd, "\t\t\"UID\": %d,\n", stack->uid); + strprintf(strfd, "\t\t\"GID\": %d,\n", stack->gid); + strprintf(strfd, "\t\t\"LK_owner\": \"%s\"\n", + lkowner_utoa(&stack->lk_owner)); + if (i == (int)pool->cnt) + strprintf(strfd, "\t }\n"); + else + strprintf(strfd, "\t },\n"); + } + strprintf(strfd, "\t],\n"); + strprintf(strfd, "\t\"Call_Count\": %d\n", (int)pool->cnt); + strprintf(strfd, "}"); + } + UNLOCK(&pool->lock); + + return strfd->size; +} + +static struct meta_ops frames_file_ops = { + .file_fill = frames_file_fill, +}; + +int +meta_frames_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + meta_ops_set(loc->inode, this, &frames_file_ops); + return 0; +} diff --git a/xlators/meta/src/graph-dir.c b/xlators/meta/src/graph-dir.c new file mode 100644 index 00000000000..a8f4787880d --- /dev/null +++ b/xlators/meta/src/graph-dir.c @@ -0,0 +1,98 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" +#include "meta-hooks.h" + +static struct meta_dirent graph_dir_dirents[] = { + DOT_DOTDOT, + + { + .name = "top", + .type = IA_IFLNK, + .hook = meta_top_link_hook, + }, + { + .name = "volfile", + .type = IA_IFREG, + .hook = meta_volfile_file_hook, + }, + {.name = NULL}}; + +static int +graph_dir_fill(xlator_t *this, inode_t *inode, struct meta_dirent **dp) +{ + struct meta_dirent *dirents = NULL; + glusterfs_graph_t *graph = NULL; + int i = 0; + int count = 0; + xlator_t *xl = NULL; + + graph = meta_ctx_get(inode, this); + + for (xl = graph->first; xl; xl = xl->next) + count++; + + dirents = GF_MALLOC(sizeof(*dirents) * count, gf_meta_mt_dirents_t); + if (!dirents) + return -1; + + i = 0; + for (xl = graph->first; xl; xl = xl->next) { + dirents[i].name = gf_strdup(xl->name); + dirents[i].type = IA_IFDIR; + dirents[i].hook = meta_xlator_dir_hook; + i++; + } + + *dp = dirents; + return i; +} + +struct meta_ops graph_dir_ops = { + .fixed_dirents = graph_dir_dirents, + .dir_fill = graph_dir_fill, +}; + +static glusterfs_graph_t * +glusterfs_graph_lookup(xlator_t *this, const char *graph_uuid) +{ + glusterfs_graph_t *graph = NULL; + glusterfs_graph_t *tmp = NULL; + + list_for_each_entry(tmp, &this->ctx->graphs, list) + { + if (strcmp(graph_uuid, tmp->graph_uuid) == 0) { + graph = tmp; + break; + } + } + + return graph; +} + +int +meta_graph_dir_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + glusterfs_graph_t *graph = NULL; + + graph = glusterfs_graph_lookup(this, loc->name); + + meta_ops_set(loc->inode, this, &graph_dir_ops); + + meta_ctx_set(loc->inode, this, (void *)graph); + + return 0; +} diff --git a/xlators/meta/src/graphs-dir.c b/xlators/meta/src/graphs-dir.c new file mode 100644 index 00000000000..a1ffbca7d5a --- /dev/null +++ b/xlators/meta/src/graphs-dir.c @@ -0,0 +1,67 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" +#include "meta-hooks.h" + +static struct meta_dirent graphs_dir_dirents[] = { + DOT_DOTDOT, + + { + .name = "active", + .type = IA_IFLNK, + .hook = meta_active_link_hook, + }, + {.name = NULL}}; + +static int +graphs_dir_fill(xlator_t *this, inode_t *dir, struct meta_dirent **dp) +{ + glusterfs_graph_t *graph = NULL; + int graphs_count = 0; + int i = 0; + struct meta_dirent *dirents = NULL; + + list_for_each_entry(graph, &this->ctx->graphs, list) { graphs_count++; } + + dirents = GF_CALLOC(sizeof(*dirents), graphs_count + 3, + gf_meta_mt_dirents_t); + if (!dirents) + return -1; + + i = 0; + list_for_each_entry(graph, &this->ctx->graphs, list) + { + dirents[i].name = gf_strdup(graph->graph_uuid); + dirents[i].type = IA_IFDIR; + dirents[i].hook = meta_graph_dir_hook; + i++; + } + + *dp = dirents; + + return i; +} + +struct meta_ops graphs_dir_ops = {.fixed_dirents = graphs_dir_dirents, + .dir_fill = graphs_dir_fill}; + +int +meta_graphs_dir_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + meta_ops_set(loc->inode, this, &graphs_dir_ops); + + return 0; +} diff --git a/xlators/meta/src/history-file.c b/xlators/meta/src/history-file.c new file mode 100644 index 00000000000..7742a635fed --- /dev/null +++ b/xlators/meta/src/history-file.c @@ -0,0 +1,44 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" +#include <glusterfs/strfd.h> +#include <glusterfs/statedump.h> + +static int +history_file_fill(xlator_t *this, inode_t *file, strfd_t *strfd) +{ + xlator_t *xl = NULL; + + xl = meta_ctx_get(file, this); + + gf_proc_dump_xlator_history(xl, strfd); + + return strfd->size; +} + +static struct meta_ops history_file_ops = { + .file_fill = history_file_fill, +}; + +int +meta_history_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + meta_ops_set(loc->inode, this, &history_file_ops); + + meta_ctx_set(loc->inode, this, meta_ctx_get(loc->parent, this)); + + return 0; +} diff --git a/xlators/meta/src/logfile-link.c b/xlators/meta/src/logfile-link.c new file mode 100644 index 00000000000..616a54518c0 --- /dev/null +++ b/xlators/meta/src/logfile-link.c @@ -0,0 +1,34 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" + +static int +logfile_link_fill(xlator_t *this, inode_t *inode, strfd_t *strfd) +{ + strprintf(strfd, "%s", this->ctx->log.filename); + + return 0; +} + +struct meta_ops logfile_link_ops = {.link_fill = logfile_link_fill}; + +int +meta_logfile_link_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + meta_ops_set(loc->inode, this, &logfile_link_ops); + + return 0; +} diff --git a/xlators/meta/src/logging-dir.c b/xlators/meta/src/logging-dir.c new file mode 100644 index 00000000000..46e6f9e95dd --- /dev/null +++ b/xlators/meta/src/logging-dir.c @@ -0,0 +1,44 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" +#include "meta-hooks.h" + +static struct meta_dirent logging_dir_dirents[] = { + DOT_DOTDOT, + + { + .name = "logfile", + .type = IA_IFLNK, + .hook = meta_logfile_link_hook, + }, + { + .name = "loglevel", + .type = IA_IFREG, + .hook = meta_loglevel_file_hook, + }, + {.name = NULL}}; + +struct meta_ops logging_dir_ops = { + .fixed_dirents = logging_dir_dirents, +}; + +int +meta_logging_dir_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + meta_ops_set(loc->inode, this, &logging_dir_ops); + + return 0; +} diff --git a/xlators/meta/src/loglevel-file.c b/xlators/meta/src/loglevel-file.c new file mode 100644 index 00000000000..eeeeeaa5907 --- /dev/null +++ b/xlators/meta/src/loglevel-file.c @@ -0,0 +1,50 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" +#include <glusterfs/strfd.h> + +static int +loglevel_file_fill(xlator_t *this, inode_t *file, strfd_t *strfd) +{ + strprintf(strfd, "%d\n", this->ctx->log.loglevel); + + return strfd->size; +} + +static int +loglevel_file_write(xlator_t *this, fd_t *fd, struct iovec *iov, int count) +{ + long int level = -1; + + level = strtol(iov[0].iov_base, NULL, 0); + if (level >= GF_LOG_NONE && level <= GF_LOG_TRACE) + gf_log_set_loglevel(this->ctx, level); + + return iov_length(iov, count); +} + +static struct meta_ops loglevel_file_ops = { + .file_fill = loglevel_file_fill, + .file_write = loglevel_file_write, +}; + +int +meta_loglevel_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + meta_ops_set(loc->inode, this, &loglevel_file_ops); + + return 0; +} diff --git a/xlators/meta/src/mallinfo-file.c b/xlators/meta/src/mallinfo-file.c new file mode 100644 index 00000000000..b4396d72189 --- /dev/null +++ b/xlators/meta/src/mallinfo-file.c @@ -0,0 +1,36 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" +#include <glusterfs/statedump.h> + +static int +mallinfo_file_fill(xlator_t *this, inode_t *file, strfd_t *strfd) +{ + gf_proc_dump_mallinfo(strfd); + return strfd->size; +} + +static struct meta_ops mallinfo_file_ops = { + .file_fill = mallinfo_file_fill, +}; + +int +meta_mallinfo_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + meta_ops_set(loc->inode, this, &mallinfo_file_ops); + + return 0; +} diff --git a/xlators/meta/src/measure-file.c b/xlators/meta/src/measure-file.c new file mode 100644 index 00000000000..52e92e48590 --- /dev/null +++ b/xlators/meta/src/measure-file.c @@ -0,0 +1,49 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" +#include <glusterfs/strfd.h> + +static int +measure_file_fill(xlator_t *this, inode_t *file, strfd_t *strfd) +{ + strprintf(strfd, "%d\n", this->ctx->measure_latency); + + return strfd->size; +} + +static int +measure_file_write(xlator_t *this, fd_t *fd, struct iovec *iov, int count) +{ + long int num = -1; + + num = strtol(iov[0].iov_base, NULL, 0); + this->ctx->measure_latency = !!num; + + return iov_length(iov, count); +} + +static struct meta_ops measure_file_ops = { + .file_fill = measure_file_fill, + .file_write = measure_file_write, +}; + +int +meta_measure_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + meta_ops_set(loc->inode, this, &measure_file_ops); + + return 0; +} diff --git a/xlators/meta/src/meminfo-file.c b/xlators/meta/src/meminfo-file.c new file mode 100644 index 00000000000..d889dfb2ae8 --- /dev/null +++ b/xlators/meta/src/meminfo-file.c @@ -0,0 +1,44 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" +#include <glusterfs/strfd.h> +#include <glusterfs/statedump.h> + +static int +meminfo_file_fill(xlator_t *this, inode_t *file, strfd_t *strfd) +{ + xlator_t *xl = NULL; + + xl = meta_ctx_get(file, this); + + gf_proc_dump_xlator_meminfo(xl, strfd); + + return strfd->size; +} + +static struct meta_ops meminfo_file_ops = { + .file_fill = meminfo_file_fill, +}; + +int +meta_meminfo_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + meta_ops_set(loc->inode, this, &meminfo_file_ops); + + meta_ctx_set(loc->inode, this, meta_ctx_get(loc->parent, this)); + + return 0; +} diff --git a/xlators/meta/src/meta-defaults.c b/xlators/meta/src/meta-defaults.c new file mode 100644 index 00000000000..91c328473f8 --- /dev/null +++ b/xlators/meta/src/meta-defaults.c @@ -0,0 +1,655 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" + +#include <glusterfs/compat-errno.h> + +int +meta_default_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, + const char *name, dict_t *xdata) +{ + return default_fgetxattr_failure_cbk(frame, EPERM); +} + +int +meta_default_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, + dict_t *dict, int32_t flags, dict_t *xdata) +{ + return default_fsetxattr_failure_cbk(frame, EPERM); +} + +int +meta_default_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *dict, int32_t flags, dict_t *xdata) +{ + return default_setxattr_failure_cbk(frame, EPERM); +} + +int +meta_default_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + return default_statfs_failure_cbk(frame, EPERM); +} + +int +meta_default_fsyncdir(call_frame_t *frame, xlator_t *this, fd_t *fd, + int32_t flags, dict_t *xdata) +{ + return default_fsyncdir_failure_cbk(frame, EPERM); +} + +int +meta_default_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, + dict_t *xdata) +{ + META_STACK_UNWIND(opendir, frame, 0, 0, fd, xdata); + return 0; +} + +int +meta_default_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) +{ + struct iatt iatt = {}; + + meta_iatt_fill(&iatt, fd->inode, fd->inode->ia_type); + + META_STACK_UNWIND(fstat, frame, 0, 0, &iatt, xdata); + + return 0; +} + +int +meta_default_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, + dict_t *xdata) +{ + return default_fsync_failure_cbk(frame, EPERM); +} + +int +meta_default_flush(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) +{ + META_STACK_UNWIND(flush, frame, 0, 0, xdata); + return 0; +} + +int +meta_default_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, + struct iovec *vector, int32_t count, off_t off, + uint32_t flags, struct iobref *iobref, dict_t *xdata) +{ + struct meta_ops *ops = NULL; + int ret = 0; + struct iatt dummy = {}; + + ops = meta_ops_get(fd->inode, this); + if (!ops) + goto err; + + if (!ops->file_write) + goto err; + + ret = ops->file_write(this, fd, vector, count); + + META_STACK_UNWIND(writev, frame, (ret >= 0 ? ret : -1), + (ret < 0 ? -ret : 0), &dummy, &dummy, xdata); + return 0; +err: + return default_writev_failure_cbk(frame, EPERM); +} + +int +meta_default_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t offset, uint32_t flags, dict_t *xdata) +{ + meta_fd_t *meta_fd = NULL; + struct iovec iov = {}; + struct iobuf *iobuf = NULL; + struct iobref *iobref = NULL; + off_t copy_offset = 0; + int copy_size = 0; + struct iatt iatt = {}; + + meta_fd = meta_fd_get(fd, this); + if (!meta_fd) + return default_readv_failure_cbk(frame, ENODATA); + + if (!meta_fd->size) + meta_file_fill(this, fd); + + iobuf = iobuf_get2(this->ctx->iobuf_pool, size); + if (!iobuf) + return default_readv_failure_cbk(frame, ENOMEM); + + iobref = iobref_new(); + if (!iobref) { + iobuf_unref(iobuf); + return default_readv_failure_cbk(frame, ENOMEM); + } + + if (iobref_add(iobref, iobuf) != 0) { + iobref_unref(iobref); + iobuf_unref(iobuf); + return default_readv_failure_cbk(frame, ENOMEM); + } + + iov.iov_base = iobuf_ptr(iobuf); + + /* iobref would have taken a ref */ + iobuf_unref(iobuf); + + copy_offset = min(meta_fd->size, offset); + copy_size = min(size, (meta_fd->size - copy_offset)); + + if (copy_size) + memcpy(iov.iov_base, meta_fd->data + copy_offset, copy_size); + iov.iov_len = copy_size; + + META_STACK_UNWIND(readv, frame, copy_size, 0, &iov, 1, &iatt, iobref, 0); + + iobref_unref(iobref); + + return 0; +} + +int +meta_default_open(call_frame_t *frame, xlator_t *this, loc_t *loc, + int32_t flags, fd_t *fd, dict_t *xdata) +{ + dict_t *xdata_rsp = NULL; + + xdata_rsp = meta_direct_io_mode(xdata, frame); + + META_STACK_UNWIND(open, frame, 0, 0, fd, xdata_rsp); + + return 0; +} + +int +meta_default_create(call_frame_t *frame, xlator_t *this, loc_t *loc, + int32_t flags, mode_t mode, mode_t umask, fd_t *fd, + dict_t *xdata) +{ + return default_create_failure_cbk(frame, EPERM); +} + +int +meta_default_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, + loc_t *newloc, dict_t *xdata) +{ + return default_link_failure_cbk(frame, EPERM); +} + +int +meta_default_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, + loc_t *newloc, dict_t *xdata) +{ + return default_rename_failure_cbk(frame, EPERM); +} + +int +meta_default_symlink(call_frame_t *frame, xlator_t *this, const char *linkpath, + loc_t *loc, mode_t umask, dict_t *xdata) +{ + return default_symlink_failure_cbk(frame, EPERM); +} + +int +meta_default_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, + dict_t *xdata) +{ + return default_rmdir_failure_cbk(frame, EPERM); +} + +int +meta_default_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, + dict_t *xdata) +{ + return default_unlink_failure_cbk(frame, EPERM); +} + +int +meta_default_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, + mode_t umask, dict_t *xdata) +{ + return default_mkdir_failure_cbk(frame, EPERM); +} + +int +meta_default_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, + dev_t rdev, mode_t umask, dict_t *xdata) +{ + return default_mknod_failure_cbk(frame, EPERM); +} + +int +meta_default_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, + size_t size, dict_t *xdata) +{ + struct meta_ops *ops = NULL; + strfd_t *strfd = NULL; + struct iatt iatt = {}; + int len = -1; + + ops = meta_ops_get(loc->inode, this); + if (!ops || !ops->link_fill) { + META_STACK_UNWIND(readlink, frame, -1, EPERM, 0, 0, 0); + return 0; + } + + strfd = strfd_open(); + if (!strfd) { + META_STACK_UNWIND(readlink, frame, -1, ENOMEM, 0, 0, 0); + return 0; + } + + ops->link_fill(this, loc->inode, strfd); + + meta_iatt_fill(&iatt, loc->inode, IA_IFLNK); + + if (strfd->data) { + len = strlen(strfd->data); + META_STACK_UNWIND(readlink, frame, len, 0, strfd->data, &iatt, xdata); + } else + META_STACK_UNWIND(readlink, frame, -1, ENODATA, 0, 0, 0); + + strfd_close(strfd); + + return 0; +} + +int +meta_default_access(call_frame_t *frame, xlator_t *this, loc_t *loc, + int32_t mask, dict_t *xdata) +{ + return default_access_failure_cbk(frame, EPERM); +} + +int +meta_default_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, + off_t offset, dict_t *xdata) +{ + struct iatt iatt = {}; + + meta_iatt_fill(&iatt, fd->inode, IA_IFREG); + + META_STACK_UNWIND(ftruncate, frame, 0, 0, &iatt, &iatt, xdata); + + return 0; +} + +int +meta_default_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, + const char *name, dict_t *xdata) +{ + return default_getxattr_failure_cbk(frame, EPERM); +} + +int +meta_default_xattrop(call_frame_t *frame, xlator_t *this, loc_t *loc, + gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata) +{ + return default_xattrop_failure_cbk(frame, EPERM); +} + +int +meta_default_fxattrop(call_frame_t *frame, xlator_t *this, fd_t *fd, + gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata) +{ + return default_fxattrop_failure_cbk(frame, EPERM); +} + +int +meta_default_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, + const char *name, dict_t *xdata) +{ + return default_removexattr_failure_cbk(frame, EPERM); +} + +int +meta_default_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, + const char *name, dict_t *xdata) +{ + return default_fremovexattr_failure_cbk(frame, EPERM); +} + +int +meta_default_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, + struct gf_flock *lock, dict_t *xdata) +{ + return default_lk_failure_cbk(frame, EPERM); +} + +int +meta_default_inodelk(call_frame_t *frame, xlator_t *this, const char *volume, + loc_t *loc, int32_t cmd, struct gf_flock *lock, + dict_t *xdata) +{ + return default_inodelk_failure_cbk(frame, EPERM); +} + +int +meta_default_finodelk(call_frame_t *frame, xlator_t *this, const char *volume, + fd_t *fd, int32_t cmd, struct gf_flock *lock, + dict_t *xdata) +{ + return default_finodelk_failure_cbk(frame, EPERM); +} + +int +meta_default_entrylk(call_frame_t *frame, xlator_t *this, const char *volume, + loc_t *loc, const char *basename, entrylk_cmd cmd, + entrylk_type type, dict_t *xdata) +{ + return default_entrylk_failure_cbk(frame, EPERM); +} + +int +meta_default_fentrylk(call_frame_t *frame, xlator_t *this, const char *volume, + fd_t *fd, const char *basename, entrylk_cmd cmd, + entrylk_type type, dict_t *xdata) +{ + return default_fentrylk_failure_cbk(frame, EPERM); +} + +int +meta_default_rchecksum(call_frame_t *frame, xlator_t *this, fd_t *fd, + off_t offset, int32_t len, dict_t *xdata) +{ + return default_rchecksum_failure_cbk(frame, EPERM); +} + +int +meta_default_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t off, dict_t *xdata) +{ + meta_fd_t *meta_fd = NULL; + int i = 0; + gf_dirent_t head; + gf_dirent_t *list = NULL; + int ret = 0; + int this_size = 0; + int filled_size = 0; + int fixed_size = 0; + int dyn_size = 0; + struct meta_dirent *fixed_dirents = NULL; + struct meta_dirent *dyn_dirents = NULL; + struct meta_dirent *dirents = NULL; + struct meta_dirent *end = NULL; + struct meta_ops *ops = NULL; + + INIT_LIST_HEAD(&head.list); + + ops = meta_ops_get(fd->inode, this); + if (!ops) + goto err; + + meta_fd = meta_fd_get(fd, this); + if (!meta_fd) + goto err; + + meta_dir_fill(this, fd); + + fixed_dirents = ops->fixed_dirents; + fixed_size = fixed_dirents_len(fixed_dirents); + + dyn_dirents = meta_fd->dirents; + dyn_size = meta_fd->size; + + for (i = off; i < (fixed_size + dyn_size);) { + if (i >= fixed_size) { + dirents = dyn_dirents + (i - fixed_size); + end = dyn_dirents + dyn_size; + } else { + dirents = fixed_dirents + i; + end = fixed_dirents + fixed_size; + } + + while (dirents < end) { + this_size = sizeof(gf_dirent_t) + strlen(dirents->name) + 1; + if (this_size + filled_size > size) + goto unwind; + + list = gf_dirent_for_name(dirents->name); + if (!list) + break; + + list->d_off = i + 1; + list->d_ino = i + 42; + switch (dirents->type) { + case IA_IFDIR: + list->d_type = DT_DIR; + break; + case IA_IFCHR: + list->d_type = DT_CHR; + break; + case IA_IFBLK: + list->d_type = DT_BLK; + break; + case IA_IFIFO: + list->d_type = DT_FIFO; + break; + case IA_IFLNK: + list->d_type = DT_LNK; + break; + case IA_IFREG: + list->d_type = DT_REG; + break; + case IA_IFSOCK: + list->d_type = DT_SOCK; + break; + case IA_INVAL: + list->d_type = DT_UNKNOWN; + break; + } + + list_add_tail(&list->list, &head.list); + ret++; + i++; + dirents++; + filled_size += this_size; + } + } + +unwind: + META_STACK_UNWIND(readdir, frame, ret, 0, &head, xdata); + + gf_dirent_free(&head); + + return 0; +err: + META_STACK_UNWIND(readdir, frame, -1, ENOMEM, 0, 0); + return 0; +} + +int +meta_default_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, + size_t size, off_t off, dict_t *xdata) +{ + return meta_default_readdir(frame, this, fd, size, off, xdata); +} + +int +meta_default_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, + struct iatt *stbuf, int32_t valid, dict_t *xdata) +{ + return default_setattr_failure_cbk(frame, EPERM); +} + +int +meta_default_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, + off_t offset, dict_t *xdata) +{ + struct iatt iatt = {}; + + meta_iatt_fill(&iatt, loc->inode, IA_IFREG); + + META_STACK_UNWIND(truncate, frame, 0, 0, &iatt, &iatt, xdata); + + return 0; +} + +int +meta_default_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + struct iatt iatt = {}; + + meta_iatt_fill(&iatt, loc->inode, loc->inode->ia_type); + + META_STACK_UNWIND(stat, frame, 0, 0, &iatt, xdata); + + return 0; +} + +int +meta_default_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + struct meta_ops *ops = NULL; + struct meta_dirent *dirent = NULL; + struct meta_dirent *dp = NULL; + int i = 0; + int ret = 0; + + if (!loc->name) + return meta_inode_discover(frame, this, loc, xdata); + + ops = meta_ops_get(loc->parent, this); + if (!ops) + return default_lookup_failure_cbk(frame, EPERM); + + for (dirent = ops->fixed_dirents; dirent && dirent->name; dirent++) { + if (strcmp(dirent->name, loc->name) == 0) + goto hook; + } + + dirent = NULL; + if (ops->dir_fill) + ret = ops->dir_fill(this, loc->parent, &dp); + + for (i = 0; i < ret; i++) { + if (strcmp(dp[i].name, loc->name) == 0) { + dirent = &dp[i]; + goto hook; + } + } +hook: + if (dirent && dirent->hook) { + struct iatt parent = {}; + struct iatt iatt = {}; + + dirent->hook(frame, this, loc, xdata); + + meta_iatt_fill(&iatt, loc->inode, dirent->type); + + META_STACK_UNWIND(lookup, frame, 0, 0, loc->inode, &iatt, xdata, + &parent); + } else { + META_STACK_UNWIND(lookup, frame, -1, ENOENT, 0, 0, 0, 0); + } + + for (i = 0; i < ret; i++) + GF_FREE((void *)dp[i].name); + GF_FREE(dp); + + return 0; +} + +int +meta_default_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, + struct iatt *stbuf, int32_t valid, dict_t *xdata) +{ + return default_fsetattr_failure_cbk(frame, EPERM); +} + +int +meta_default_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, + int32_t keep_size, off_t offset, size_t len, + dict_t *xdata) +{ + return default_fallocate_failure_cbk(frame, EPERM); +} + +int +meta_default_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, + off_t offset, size_t len, dict_t *xdata) +{ + return default_discard_failure_cbk(frame, EPERM); +} + +int +meta_default_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, + off_t offset, off_t len, dict_t *xdata) +{ + return default_zerofill_failure_cbk(frame, EPERM); +} + +#define SET_META_DEFAULT_FOP(f, name) \ + do { \ + if (!f->name) \ + f->name = meta_default_##name; \ + } while (0) + +struct xlator_fops * +meta_defaults_init(struct xlator_fops *fops) +{ + SET_META_DEFAULT_FOP(fops, create); + SET_META_DEFAULT_FOP(fops, open); + SET_META_DEFAULT_FOP(fops, stat); + SET_META_DEFAULT_FOP(fops, readlink); + SET_META_DEFAULT_FOP(fops, mknod); + SET_META_DEFAULT_FOP(fops, mkdir); + SET_META_DEFAULT_FOP(fops, unlink); + SET_META_DEFAULT_FOP(fops, rmdir); + SET_META_DEFAULT_FOP(fops, symlink); + SET_META_DEFAULT_FOP(fops, rename); + SET_META_DEFAULT_FOP(fops, link); + SET_META_DEFAULT_FOP(fops, truncate); + SET_META_DEFAULT_FOP(fops, readv); + SET_META_DEFAULT_FOP(fops, writev); + SET_META_DEFAULT_FOP(fops, statfs); + SET_META_DEFAULT_FOP(fops, flush); + SET_META_DEFAULT_FOP(fops, fsync); + SET_META_DEFAULT_FOP(fops, setxattr); + SET_META_DEFAULT_FOP(fops, getxattr); + SET_META_DEFAULT_FOP(fops, fsetxattr); + SET_META_DEFAULT_FOP(fops, fgetxattr); + SET_META_DEFAULT_FOP(fops, removexattr); + SET_META_DEFAULT_FOP(fops, fremovexattr); + SET_META_DEFAULT_FOP(fops, opendir); + SET_META_DEFAULT_FOP(fops, readdir); + SET_META_DEFAULT_FOP(fops, readdirp); + SET_META_DEFAULT_FOP(fops, fsyncdir); + SET_META_DEFAULT_FOP(fops, access); + SET_META_DEFAULT_FOP(fops, ftruncate); + SET_META_DEFAULT_FOP(fops, fstat); + SET_META_DEFAULT_FOP(fops, lk); + SET_META_DEFAULT_FOP(fops, inodelk); + SET_META_DEFAULT_FOP(fops, finodelk); + SET_META_DEFAULT_FOP(fops, entrylk); + SET_META_DEFAULT_FOP(fops, fentrylk); + SET_META_DEFAULT_FOP(fops, lookup); + SET_META_DEFAULT_FOP(fops, rchecksum); + SET_META_DEFAULT_FOP(fops, xattrop); + SET_META_DEFAULT_FOP(fops, fxattrop); + SET_META_DEFAULT_FOP(fops, setattr); + SET_META_DEFAULT_FOP(fops, fsetattr); + SET_META_DEFAULT_FOP(fops, fallocate); + SET_META_DEFAULT_FOP(fops, discard); + SET_META_DEFAULT_FOP(fops, zerofill); + + return fops; +} diff --git a/xlators/meta/src/meta-helpers.c b/xlators/meta/src/meta-helpers.c new file mode 100644 index 00000000000..cb54f547468 --- /dev/null +++ b/xlators/meta/src/meta-helpers.c @@ -0,0 +1,332 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" + +meta_fd_t * +meta_fd_get(fd_t *fd, xlator_t *this) +{ + uint64_t value = 0; + meta_fd_t *meta_fd = NULL; + + LOCK(&fd->lock); + { + if (__fd_ctx_get(fd, this, &value) < 0) { + if (!value) { + meta_fd = GF_CALLOC(1, sizeof(*meta_fd), gf_meta_mt_fd_t); + if (!meta_fd) + goto unlock; + value = (long)meta_fd; + __fd_ctx_set(fd, this, value); + } + } else { + meta_fd = (void *)(uintptr_t)value; + } + } +unlock: + UNLOCK(&fd->lock); + + return meta_fd; +} + +int +meta_fd_release(fd_t *fd, xlator_t *this) +{ + uint64_t value = 0; + meta_fd_t *meta_fd = NULL; + int i = 0; + + fd_ctx_get(fd, this, &value); + meta_fd = (void *)(uintptr_t)value; + + if (meta_fd && meta_fd->dirents) { + for (i = 0; i < meta_fd->size; i++) + GF_FREE((void *)meta_fd->dirents[i].name); + GF_FREE(meta_fd->dirents); + } + + if (meta_fd) { + GF_FREE(meta_fd->data); + GF_FREE(meta_fd); + } + return 0; +} + +struct meta_ops * +meta_ops_get(inode_t *inode, xlator_t *this) +{ + struct meta_ops *ops = NULL; + uint64_t value = 0; + + inode_ctx_get2(inode, this, NULL, &value); + + ops = (void *)(uintptr_t)value; + + return ops; +} + +struct xlator_fops * +meta_fops_get(inode_t *inode, xlator_t *this) +{ + struct meta_ops *ops = NULL; + + ops = meta_ops_get(inode, this); + if (!ops) + return default_fops; + + return &ops->fops; +} + +int +meta_ops_set(inode_t *inode, xlator_t *this, struct meta_ops *ops) +{ + uint64_t value = 0; + int ret = 0; + + meta_defaults_init(&ops->fops); + + value = (long)ops; + + ret = inode_ctx_set2(inode, this, NULL, &value); + + return ret; +} + +void * +meta_ctx_get(inode_t *inode, xlator_t *this) +{ + void *ctx = NULL; + uint64_t value = 0; + + inode_ctx_get2(inode, this, &value, 0); + + ctx = (void *)(uintptr_t)value; + + return ctx; +} + +int +meta_ctx_set(inode_t *inode, xlator_t *this, void *ctx) +{ + uint64_t value = 0; + int ret = 0; + + value = (long)ctx; + + ret = inode_ctx_set2(inode, this, &value, 0); + + return ret; +} + +void +meta_local_cleanup(meta_local_t *local, xlator_t *this) +{ + if (!local) + return; + + if (local->xdata) + dict_unref(local->xdata); + + GF_FREE(local); + return; +} + +meta_local_t * +meta_local(call_frame_t *frame) +{ + meta_local_t *local = NULL; + + local = frame->local; + if (!local) + local = frame->local = GF_CALLOC(1, sizeof(*local), gf_meta_mt_local_t); + return local; +} + +dict_t * +meta_direct_io_mode(dict_t *xdata, call_frame_t *frame) +{ + meta_local_t *local = NULL; + + if (!xdata) { + local = meta_local(frame); + if (!local) + return NULL; + xdata = local->xdata = dict_new(); + if (!xdata) + return NULL; + } + + if (dict_set_int8(xdata, "direct-io-mode", 1) != 0) + return NULL; + + return xdata; +} + +static void +meta_uuid_copy(uuid_t dst, uuid_t src) +{ + gf_uuid_copy(dst, src); + if (gf_uuid_is_null(dst)) + gf_uuid_generate(dst); +} + +static void +default_meta_iatt_fill(struct iatt *iatt, inode_t *inode, ia_type_t type, + gf_boolean_t is_tunable) +{ + struct timeval tv = {}; + + iatt->ia_type = type; + switch (type) { + case IA_IFDIR: + iatt->ia_prot = ia_prot_from_st_mode(0555); + iatt->ia_nlink = 2; + break; + case IA_IFLNK: + iatt->ia_prot = ia_prot_from_st_mode(0777); + iatt->ia_nlink = 1; + break; + default: + iatt->ia_prot = ia_prot_from_st_mode(is_tunable ? 0644 : 0444); + iatt->ia_nlink = 1; + break; + } + iatt->ia_uid = 0; + iatt->ia_gid = 0; + iatt->ia_size = 0; + + meta_uuid_copy(iatt->ia_gfid, inode->gfid); + iatt->ia_ino = gfid_to_ino(iatt->ia_gfid); + + gettimeofday(&tv, 0); + iatt->ia_mtime = iatt->ia_ctime = iatt->ia_atime = tv.tv_sec; + iatt->ia_mtime_nsec = iatt->ia_ctime_nsec = iatt->ia_atime_nsec = + (tv.tv_usec * 1000); + return; +} + +void +meta_iatt_fill(struct iatt *iatt, inode_t *inode, ia_type_t type) +{ + struct meta_ops *ops = NULL; + + ops = meta_ops_get(inode, THIS); + if (!ops) + return; + + if (!ops->iatt_fill) + default_meta_iatt_fill(iatt, inode, type, !!ops->file_write); + else + ops->iatt_fill(THIS, inode, iatt); + return; +} + +int +meta_inode_discover(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + struct iatt iatt = {}; + struct iatt postparent = {}; + + meta_iatt_fill(&iatt, loc->inode, loc->inode->ia_type); + + META_STACK_UNWIND(lookup, frame, 0, 0, loc->inode, &iatt, xdata, + &postparent); + return 0; +} + +int +meta_file_fill(xlator_t *this, fd_t *fd) +{ + meta_fd_t *meta_fd = NULL; + strfd_t *strfd = NULL; + struct meta_ops *ops = NULL; + int ret = 0; + + meta_fd = meta_fd_get(fd, this); + if (!meta_fd) + return -1; + + if (meta_fd->data) + return meta_fd->size; + + strfd = strfd_open(); + if (!strfd) + return -1; + + ops = meta_ops_get(fd->inode, this); + if (!ops) { + strfd_close(strfd); + return -1; + } + + if (ops->file_fill) + ret = ops->file_fill(this, fd->inode, strfd); + + if (ret >= 0) { + meta_fd->data = strfd->data; + meta_fd->size = strfd->size; + + strfd->data = NULL; + } + + strfd_close(strfd); + + return meta_fd->size; +} + +int +meta_dir_fill(xlator_t *this, fd_t *fd) +{ + meta_fd_t *meta_fd = NULL; + struct meta_ops *ops = NULL; + struct meta_dirent *dp = NULL; + int ret = 0; + + meta_fd = meta_fd_get(fd, this); + if (!meta_fd) + return -1; + + if (meta_fd->dirents) + return meta_fd->size; + + ops = meta_ops_get(fd->inode, this); + if (!ops) + return -1; + + if (ops->dir_fill) + ret = ops->dir_fill(this, fd->inode, &dp); + + if (dp) { + meta_fd->dirents = dp; + meta_fd->size = ret; + } + + return meta_fd->size; +} + +int +fixed_dirents_len(struct meta_dirent *dirents) +{ + int i = 0; + struct meta_dirent *dirent = NULL; + + if (!dirents) + return 0; + + for (dirent = dirents; dirent->name; dirent++) + i++; + + return i; +} diff --git a/xlators/meta/src/meta-hooks.h b/xlators/meta/src/meta-hooks.h new file mode 100644 index 00000000000..7208641398a --- /dev/null +++ b/xlators/meta/src/meta-hooks.h @@ -0,0 +1,48 @@ +/* + Copyright (c) 2014 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 __META_HOOKS_H +#define __META_HOOKS_H +#include <glusterfs/xlator.h> + +#define DECLARE_HOOK(name) \ + int meta_##name##_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, \ + dict_t *xdata) + +DECLARE_HOOK(root_dir); +DECLARE_HOOK(graphs_dir); +DECLARE_HOOK(frames_file); +DECLARE_HOOK(graph_dir); +DECLARE_HOOK(active_link); +DECLARE_HOOK(xlator_dir); +DECLARE_HOOK(top_link); +DECLARE_HOOK(logging_dir); +DECLARE_HOOK(logfile_link); +DECLARE_HOOK(loglevel_file); +DECLARE_HOOK(process_uuid_file); +DECLARE_HOOK(volfile_file); +DECLARE_HOOK(view_dir); +DECLARE_HOOK(subvolumes_dir); +DECLARE_HOOK(subvolume_link); +DECLARE_HOOK(type_file); +DECLARE_HOOK(version_file); +DECLARE_HOOK(options_dir); +DECLARE_HOOK(option_file); +DECLARE_HOOK(cmdline_file); +DECLARE_HOOK(name_file); +DECLARE_HOOK(private_file); +DECLARE_HOOK(mallinfo_file); +DECLARE_HOOK(history_file); +DECLARE_HOOK(master_dir); +DECLARE_HOOK(meminfo_file); +DECLARE_HOOK(measure_file); +DECLARE_HOOK(profile_file); + +#endif diff --git a/xlators/meta/src/meta-mem-types.h b/xlators/meta/src/meta-mem-types.h index 62028b246bf..033c306682f 100644 --- a/xlators/meta/src/meta-mem-types.h +++ b/xlators/meta/src/meta-mem-types.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> + Copyright (c) 2014 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 @@ -11,15 +11,15 @@ #ifndef __META_MEM_TYPES_H__ #define __META_MEM_TYPES_H__ -#include "mem-types.h" +#include <glusterfs/mem-types.h> enum gf_meta_mem_types_ { - gf_meta_mt__open_local = gf_common_mt_end + 1, - gf_meta_mt_dir_entry_t, - gf_meta_mt_meta_dirent_t, - gf_meta_mt_meta_private_t, - gf_meta_mt_stat, - gf_meta_mt_end + gf_meta_mt_priv_t = gf_common_mt_end + 1, + gf_meta_mt_fd_t, + gf_meta_mt_fd_data_t, + gf_meta_mt_strfd_t, + gf_meta_mt_dirents_t, + gf_meta_mt_local_t, + gf_meta_mt_end }; #endif - diff --git a/xlators/meta/src/meta.c b/xlators/meta/src/meta.c index e69719f3cd3..e1b9a2b6581 100644 --- a/xlators/meta/src/meta.c +++ b/xlators/meta/src/meta.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2006-2012 Red Hat, Inc. <http://www.redhat.com> + Copyright (c) 2014 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 @@ -7,1291 +7,270 @@ later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> -#include "glusterfs.h" -#include "dict.h" -#include "xlator.h" - -#include "meta.h" -#include "view.h" #include "meta-mem-types.h" +#include "meta.h" -int32_t -meta_getattr_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - struct stat *buf) -{ - STACK_UNWIND (frame, op_ret, op_errno, buf); - return 0; -} - -int32_t -meta_getattr (call_frame_t *frame, - xlator_t *this, - const char *path) -{ - meta_private_t *priv = (meta_private_t *) this->private; - meta_dirent_t *root = priv->tree; - meta_dirent_t *file = lookup_meta_entry (root, path, NULL); - - if (file) { - if (file->fops && file->fops->getattr) { - STACK_WIND (frame, meta_getattr_cbk, - this, file->fops->getattr, path); - return 0; - } - else { - STACK_UNWIND (frame, 0, 0, file->stbuf); - return 0; - } - } - else { - STACK_WIND (frame, meta_getattr_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->getattr, - path); - return 0; - } -} - -int32_t -meta_chmod_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - struct stat *buf) -{ - STACK_UNWIND (frame, - op_ret, - op_errno, - buf); - return 0; -} - -int32_t -meta_chmod (call_frame_t *frame, - xlator_t *this, - const char *path, - mode_t mode) -{ - STACK_WIND (frame, - meta_chmod_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->chmod, - path, - mode); - return 0; -} - -int32_t -meta_chown_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - struct stat *buf) -{ - STACK_UNWIND (frame, - op_ret, - op_errno, - buf); - return 0; -} - -int32_t -meta_chown (call_frame_t *frame, - xlator_t *this, - const char *path, - uid_t uid, - gid_t gid) -{ - STACK_WIND (frame, - meta_chown_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->chown, - path, - uid, - gid); - return 0; -} - - -int32_t -meta_truncate_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - struct stat *buf) -{ - STACK_UNWIND (frame, - op_ret, - op_errno, - buf); - return 0; -} - -int32_t -meta_truncate (call_frame_t *frame, - xlator_t *this, - const char *path, - off_t offset) -{ - STACK_WIND (frame, - meta_truncate_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->truncate, - path, - offset); - return 0; -} - - -int32_t -meta_ftruncate_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - struct stat *buf) -{ - STACK_UNWIND (frame, - op_ret, - op_errno, - buf); - return 0; -} - -int32_t -meta_ftruncate (call_frame_t *frame, - xlator_t *this, - dict_t *fd, - off_t offset) -{ - STACK_WIND (frame, - meta_ftruncate_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->ftruncate, - fd, - offset); - return 0; -} - - -int32_t -meta_utimes_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - struct stat *buf) -{ - STACK_UNWIND (frame, - op_ret, - op_errno, - buf); - return 0; -} - -int32_t -meta_utimes (call_frame_t *frame, - xlator_t *this, - const char *path, - struct timespec *buf) -{ - STACK_WIND (frame, - meta_utimes_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->utimes, - path, - buf); - return 0; -} - - -int32_t -meta_access_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno) -{ - STACK_UNWIND (frame, - op_ret, - op_errno); - return 0; -} - -int32_t -meta_access (call_frame_t *frame, - xlator_t *this, - const char *path, - mode_t mode) -{ - STACK_WIND (frame, - meta_access_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->access, - path, - mode); - return 0; -} - -int32_t -meta_readlink_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - char *dest) -{ - STACK_UNWIND (frame, - op_ret, - op_errno, - dest); - return 0; -} - -int32_t -meta_readlink (call_frame_t *frame, - xlator_t *this, - const char *path, - size_t size) -{ - STACK_WIND (frame, - meta_readlink_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->readlink, - path, - size); - return 0; -} - -int32_t -meta_mknod_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - struct stat *buf) -{ - STACK_UNWIND (frame, - op_ret, - op_errno, - buf); - return 0; -} - -int32_t -meta_mknod (call_frame_t *frame, - xlator_t *this, - const char *path, - mode_t mode, - dev_t dev) -{ - STACK_WIND (frame, - meta_mknod_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->mknod, - path, - mode, - dev); - return 0; -} - -int32_t -meta_mkdir_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - struct stat *buf) -{ - STACK_UNWIND (frame, - op_ret, - op_errno, - buf); - return 0; -} - -int32_t -meta_mkdir (call_frame_t *frame, - xlator_t *this, - const char *path, - mode_t mode) -{ - STACK_WIND (frame, - meta_mkdir_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->mkdir, - path, - mode); - return 0; -} - -int32_t -meta_unlink_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno) -{ - STACK_UNWIND (frame, - op_ret, - op_errno); - return 0; -} - -int32_t -meta_unlink (call_frame_t *frame, - xlator_t *this, - const char *path) -{ - STACK_WIND (frame, - meta_unlink_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->unlink, - path); - return 0; -} - -int32_t -meta_rmdir_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno) -{ - STACK_UNWIND (frame, - op_ret, - op_errno); - return 0; -} - -int32_t -meta_rmdir (call_frame_t *frame, - xlator_t *this, - const char *path) -{ - STACK_WIND (frame, - meta_rmdir_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->rmdir, - path); - return 0; -} - -int32_t -meta_symlink_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - struct stat *buf) -{ - STACK_UNWIND (frame, - op_ret, - op_errno, - buf); - return 0; -} +#include "meta-hooks.h" -int32_t -meta_symlink (call_frame_t *frame, - xlator_t *this, - const char *oldpath, - const char *newpath) +int +meta_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { - STACK_WIND (frame, - meta_symlink_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->symlink, - oldpath, - newpath); - return 0; -} + inode_t *inode = NULL; -int32_t -meta_rename_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno) -{ - STACK_UNWIND (frame, - op_ret, - op_errno); - return 0; -} + if (META_HOOK(loc) || IS_META_ROOT_GFID(loc->gfid)) { + struct iatt iatt = {}; + struct iatt parent = {}; -int32_t -meta_rename (call_frame_t *frame, - xlator_t *this, - const char *oldpath, - const char *newpath) -{ - STACK_WIND (frame, - meta_rename_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->rename, - oldpath, - newpath); - return 0; -} + meta_root_dir_hook(frame, this, loc, xdata); -int32_t -meta_link_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - struct stat *buf) -{ - STACK_UNWIND (frame, - op_ret, - op_errno, - buf); - return 0; -} + meta_iatt_fill(&iatt, loc->inode, IA_IFDIR); + gf_uuid_parse(META_ROOT_GFID, iatt.ia_gfid); -int32_t -meta_link (call_frame_t *frame, - xlator_t *this, - const char *oldpath, - const char *newpath) -{ - STACK_WIND (frame, - meta_link_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->link, - oldpath, - newpath); - return 0; -} - -struct _open_local { - const char *path; -}; + META_STACK_UNWIND(lookup, frame, 0, 0, loc->inode, &iatt, xdata, + &parent); + return 0; + } -int32_t -meta_open_cbk (call_frame_t *frame, void *cookie, - xlator_t *this, int32_t op_ret, int32_t op_errno, - dict_t *ctx, struct stat *buf) -{ - struct _open_local *local = frame->local; - if (local) - dict_set (ctx, this->name, str_to_data (local->path)); - STACK_UNWIND (frame, op_ret, op_errno, ctx, buf); - return 0; -} + if (loc->parent) + inode = loc->parent; + else + inode = loc->inode; -int32_t -meta_open (call_frame_t *frame, xlator_t *this, - const char *path, int32_t flags, mode_t mode) -{ - meta_private_t *priv = (meta_private_t *) this->private; - meta_dirent_t *root = priv->tree; - meta_dirent_t *file = lookup_meta_entry (root, path, NULL); + META_FOP(inode, lookup, frame, this, loc, xdata); - if (file) { - if (file->fops && file->fops->open) { - struct _open_local *local = GF_CALLOC (1, sizeof (struct _open_local), gf_meta_mt__open_local); - ERR_ABORT (local); - local->path = gf_strdup (path); - frame->local = local; - STACK_WIND (frame, meta_open_cbk, - this, file->fops->open, - path, flags, mode); - return 0; - } - else { - dict_t *ctx = get_new_dict (); - dict_ref (ctx); - dict_set (ctx, this->name, str_to_data (gf_strdup (path))); - STACK_UNWIND (frame, 0, 0, ctx, file->stbuf); - return 0; - } - } - else { - STACK_WIND (frame, meta_open_cbk, - FIRST_CHILD(this), FIRST_CHILD(this)->fops->open, - path, flags, mode); return 0; - } } -int32_t -meta_create (call_frame_t *frame, xlator_t *this, - const char *path, int32_t flags, mode_t mode) +int +meta_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, + dict_t *xdata) { - meta_private_t *priv = (meta_private_t *) this->private; - meta_dirent_t *root = priv->tree; - meta_dirent_t *file = lookup_meta_entry (root, path, NULL); + META_FOP(fd->inode, opendir, frame, this, loc, fd, xdata); - if (file) { - if (file->fops && file->fops->create) { - struct _open_local *local = GF_CALLOC (1, sizeof (struct _open_local), gf_meta_mt__open_local); - ERR_ABORT (local); - local->path = gf_strdup (path); - frame->local = local; - STACK_WIND (frame, meta_open_cbk, - this, file->fops->create, - path, flags, mode); - return 0; - } - else { - STACK_UNWIND (frame, -1, 0, NULL, NULL); - return 0; - } - } - else { - STACK_WIND (frame, meta_open_cbk, - FIRST_CHILD(this), FIRST_CHILD(this)->fops->create, - path, flags, mode); return 0; - } } -int32_t -meta_readv_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - struct iovec *vector, - int32_t count) +int +meta_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, fd_t *fd, + dict_t *xdata) { - STACK_UNWIND (frame, - op_ret, - op_errno, - vector, - count); - return 0; -} + META_FOP(fd->inode, open, frame, this, loc, flags, fd, xdata); -int32_t -meta_readv (call_frame_t *frame, - xlator_t *this, - dict_t *fd, - size_t size, - off_t offset) -{ - meta_private_t *priv = (meta_private_t *) this->private; - meta_dirent_t *root = priv->tree; - data_t *path_data = dict_get (fd, this->name); - - if (path_data) { - const char *path = data_to_str (path_data); - meta_dirent_t *file = lookup_meta_entry (root, path, NULL); - - if (file && file->fops && file->fops->readv) { - STACK_WIND (frame, meta_readv_cbk, - this, file->fops->readv, - fd, size, offset); - return 0; - } - } - else { - STACK_WIND (frame, meta_readv_cbk, - FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv, - fd, size, offset); return 0; - } -} - -int32_t -meta_writev_cbk (call_frame_t *frame, void *cookie, - xlator_t *this, int32_t op_ret, - int32_t op_errno) -{ - STACK_UNWIND (frame, op_ret, op_errno); - return 0; } -int32_t -meta_writev (call_frame_t *frame, xlator_t *this, - dict_t *fd, - struct iovec *vector, int32_t count, off_t offset) +int +meta_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t offset, uint32_t flags, dict_t *xdata) { - meta_private_t *priv = (meta_private_t *) this->private; - meta_dirent_t *root = priv->tree; - data_t *path_data = dict_get (fd, this->name); + META_FOP(fd->inode, readv, frame, this, fd, size, offset, flags, xdata); - if (path_data) { - const char *path = data_to_str (path_data); - meta_dirent_t *file = lookup_meta_entry (root, path, NULL); - - if (file && file->fops && file->fops->writev) { - STACK_WIND (frame, meta_writev_cbk, - this, file->fops->writev, - fd, vector, count, offset); - return 0; - } - } - else { - STACK_WIND (frame, meta_readv_cbk, - FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, - fd, vector, count, offset); return 0; - } } -int32_t -meta_flush_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno) +int +meta_flush(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { - STACK_UNWIND (frame, - op_ret, - op_errno); - return 0; -} + META_FOP(fd->inode, flush, frame, this, fd, xdata); -int32_t -meta_flush (call_frame_t *frame, - xlator_t *this, - dict_t *fd) -{ - meta_private_t *priv = (meta_private_t *) this->private; - meta_dirent_t *root = priv->tree; - data_t *path_data = dict_get (fd, this->name); - - if (path_data) { - const char *path = data_to_str (path_data); - meta_dirent_t *file = lookup_meta_entry (root, path, NULL); - - if (file) { - if (file->fops && file->fops->flush) { - STACK_WIND (frame, meta_flush_cbk, - this, file->fops->flush, - fd); - return 0; - } - else { - STACK_UNWIND (frame, 0, 0); - return 0; - } - } - } - else { - STACK_WIND (frame, meta_flush_cbk, - FIRST_CHILD(this), FIRST_CHILD(this)->fops->flush, - fd); return 0; - } } -int32_t -meta_release_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno) +int +meta_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { - STACK_UNWIND (frame, - op_ret, - op_errno); - return 0; -} - -int32_t -meta_release (call_frame_t *frame, - xlator_t *this, - dict_t *fd) -{ - meta_private_t *priv = (meta_private_t *) this->private; - meta_dirent_t *root = priv->tree; - data_t *path_data = dict_get (fd, this->name); + META_FOP(loc->inode, stat, frame, this, loc, xdata); - if (path_data) { - const char *path = data_to_str (path_data); - meta_dirent_t *file = lookup_meta_entry (root, path, NULL); - - if (file) { - dict_unref (fd); - STACK_UNWIND (frame, 0, 0); - return 0; - } - } - else { - STACK_WIND (frame, meta_release_cbk, - FIRST_CHILD(this), FIRST_CHILD(this)->fops->release, - fd); return 0; - } } -int32_t -meta_fsync_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno) +int +meta_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { - STACK_UNWIND (frame, - op_ret, - op_errno); - return 0; -} + META_FOP(fd->inode, fstat, frame, this, fd, xdata); -int32_t -meta_fsync (call_frame_t *frame, - xlator_t *this, - dict_t *fd, - int32_t flags) -{ - STACK_WIND (frame, - meta_fsync_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->fsync, - fd, - flags); - return 0; + return 0; } -int32_t -meta_fgetattr_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - struct stat *buf) +int +meta_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t offset, dict_t *xdata) { - STACK_UNWIND (frame, - op_ret, - op_errno, - buf); - return 0; -} + META_FOP(fd->inode, readdir, frame, this, fd, size, offset, xdata); -int32_t -meta_fgetattr (call_frame_t *frame, - xlator_t *this, - dict_t *fd) -{ - STACK_WIND (frame, - meta_fgetattr_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->fgetattr, - fd); - return 0; + return 0; } -int32_t -meta_opendir_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - dict_t *fd) +int +meta_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t offset, dict_t *xdata) { - STACK_UNWIND (frame, - op_ret, - op_errno, - fd); - return 0; -} + META_FOP(fd->inode, readdirp, frame, this, fd, size, offset, xdata); -int32_t -meta_opendir (call_frame_t *frame, - xlator_t *this, - const char *path) -{ - meta_private_t *priv = (meta_private_t *) this->private; - meta_dirent_t *root = priv->tree; - meta_dirent_t *dir = lookup_meta_entry (root, path, NULL); - - if (dir) { - dict_t *ctx = get_new_dict (); - dict_set (ctx, this->name, str_to_data (gf_strdup (path))); - STACK_UNWIND (frame, 0, 0, ctx); return 0; - } - else { - STACK_WIND (frame, meta_opendir_cbk, - FIRST_CHILD(this), FIRST_CHILD(this)->fops->opendir, - path); - return 0; - } } -int32_t -meta_readdir_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - dir_entry_t *entries, - int32_t count) +int +meta_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, + dict_t *xdata) { - meta_private_t *priv = (meta_private_t *)this->private; - - if ((int) cookie == 1) { - dir_entry_t *dir = GF_CALLOC (1, sizeof (dir_entry_t), - gf_meta_mt_dir_entry_t); - ERR_ABORT (dir); - - dir->name = gf_strdup (".meta"); - memcpy (&dir->buf, priv->tree->stbuf, sizeof (struct stat)); - dir->next = entries->next; - entries->next = dir; + META_FOP(loc->inode, readlink, frame, this, loc, size, xdata); - STACK_UNWIND (frame, op_ret, op_errno, entries, count+1); return 0; - } - - STACK_UNWIND (frame, op_ret, op_errno, entries, count); - return 0; } -int32_t -meta_readdir (call_frame_t *frame, - xlator_t *this, - const char *path) +int +meta_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *iov, + int count, off_t offset, uint32_t flags, struct iobref *iobref, + dict_t *xdata) { - meta_private_t *priv = (meta_private_t *) this->private; - meta_dirent_t *root = priv->tree; - - meta_dirent_t *dir = lookup_meta_entry (root, path, NULL); - if (dir) { - if (dir->fops && dir->fops->readdir) { - STACK_WIND (frame, meta_readdir_cbk, - this, dir->fops->readdir, path); - return 0; - } - else { - int count = 0; - dir = dir->children; - dir_entry_t *entries = NULL; - - while (dir) { - dir_entry_t *d = GF_CALLOC (1, sizeof (dir_entry_t), - gf_meta_mt_dir_entry_t); - ERR_ABORT (d); - d->name = dir->name; - d->buf = *dir->stbuf; - d->next = entries; - entries = d; - count++; - dir = dir->next; - } - - dir_entry_t *header = GF_CALLOC (1, sizeof (dir_entry_t), - gf_meta_mt_dir_entry_t); - ERR_ABORT (header); - header->next = entries; - STACK_UNWIND (frame, 0, 0, header, count); - return 0; - } - } - else { - if (!strcmp (path, "/")) { - STACK_WIND_COOKIE (frame, meta_readdir_cbk, - (int) 1, /* cookie to tell _cbk to add .meta entry */ - FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdir, - path); - } - else { - STACK_WIND (frame, meta_readdir_cbk, - FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdir, - path); - } - } - return 0; + META_FOP(fd->inode, writev, frame, this, fd, iov, count, offset, flags, + iobref, xdata); + return 0; } -int32_t -meta_releasedir_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno) +int +meta_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, + dict_t *xdata) { - STACK_UNWIND (frame, - op_ret, - op_errno); - return 0; -} + META_FOP(loc->inode, truncate, frame, this, loc, offset, xdata); -int32_t -meta_releasedir (call_frame_t *frame, - xlator_t *this, - dict_t *fd) -{ - STACK_WIND (frame, - meta_releasedir_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->releasedir, - fd); - return 0; + return 0; } -int32_t -meta_fsyncdir_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno) +int +meta_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + dict_t *xdata) { - STACK_UNWIND (frame, - op_ret, - op_errno); - return 0; -} + META_FOP(fd->inode, ftruncate, frame, this, fd, offset, xdata); -int32_t -meta_fsyncdir (call_frame_t *frame, - xlator_t *this, - dict_t *fd, - int32_t flags) -{ - STACK_WIND (frame, - meta_fsyncdir_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->fsyncdir, - fd, - flags); - return 0; + return 0; } int32_t -meta_statfs_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - struct statvfs *buf) +meta_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, + dict_t *xdata) { - STACK_UNWIND (frame, - op_ret, - op_errno, - buf); - return 0; -} + META_FOP(fd->inode, fsync, frame, this, fd, flags, xdata); -int32_t -meta_statfs (call_frame_t *frame, - xlator_t *this, - const char *path) -{ - STACK_WIND (frame, - meta_statfs_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->statfs, - path); - return 0; + return 0; } int32_t -meta_setxattr_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno) +meta_fsyncdir(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, + dict_t *xdata) { - STACK_UNWIND (frame, - op_ret, - op_errno); - return 0; -} + META_FOP(fd->inode, fsyncdir, frame, this, fd, flags, xdata); -int32_t -meta_setxattr (call_frame_t *frame, - xlator_t *this, - const char *path, - const char *name, - const char *value, - size_t size, - int32_t flags) -{ - STACK_WIND (frame, - meta_setxattr_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->setxattr, - path, - name, - value, - size, - flags); - return 0; + return 0; } -int32_t -meta_getxattr_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - char *value) +int +meta_forget(xlator_t *this, inode_t *inode) { - STACK_UNWIND (frame, - op_ret, - op_errno, - value); - return 0; + return 0; } -int32_t -meta_getxattr (call_frame_t *frame, - xlator_t *this, - const char *path, - const char *name, - size_t size) +int +meta_release(xlator_t *this, fd_t *fd) { - STACK_WIND (frame, - meta_getxattr_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->getxattr, - path, - name, - size); - return 0; + return meta_fd_release(fd, this); } -int32_t -meta_listxattr_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - char *value) +int +meta_releasedir(xlator_t *this, fd_t *fd) { - STACK_UNWIND (frame, - op_ret, - op_errno, - value); - return 0; + return meta_fd_release(fd, this); } -int32_t -meta_listxattr (call_frame_t *frame, - xlator_t *this, - const char *path, - size_t size) +int +mem_acct_init(xlator_t *this) { - STACK_WIND (frame, - meta_listxattr_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->listxattr, - path, - size); - return 0; -} + int ret = -1; -int32_t -meta_removexattr_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno) -{ - STACK_UNWIND (frame, - op_ret, - op_errno); - return 0; -} + if (!this) + return ret; -int32_t -meta_removexattr (call_frame_t *frame, - xlator_t *this, - const char *path, - const char *name) -{ - STACK_WIND (frame, - meta_removexattr_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->removexattr, - path, - name); - return 0; -} + ret = xlator_mem_acct_init(this, gf_meta_mt_end + 1); -int32_t -meta_lk_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - struct gf_flock *lock) -{ - STACK_UNWIND (frame, - op_ret, - op_errno, - lock); - return 0; -} + if (ret != 0) { + gf_log(this->name, GF_LOG_ERROR, "Memory accounting init failed"); + return ret; + } -int32_t -meta_lk (call_frame_t *frame, - xlator_t *this, - dict_t *file, - int32_t cmd, - struct gf_flock *lock) -{ - STACK_WIND (frame, - meta_lk_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->lk, - file, - cmd, - lock); - return 0; + return ret; } -static void -add_xlator_to_tree (meta_dirent_t *tree, xlator_t *this, - const char *prefix) +int +init(xlator_t *this) { - char *dir; - gf_asprintf (&dir, "%s/%s", prefix, this->name); - - char *children; - gf_asprintf (&children, "%s/%s", dir, "subvolumes"); - - char *type; - gf_asprintf (&type, "%s/%s", dir, "type"); - - char *view; - gf_asprintf (&view, "%s/%s", dir, "view"); - - insert_meta_entry (tree, dir, S_IFDIR, NULL, NULL); - insert_meta_entry (tree, children, S_IFDIR, NULL, NULL); - meta_dirent_t *v = insert_meta_entry (tree, view, S_IFDIR, NULL, - &meta_xlator_view_fops); - v->view_xlator = this; - meta_dirent_t *t = insert_meta_entry (tree, type, S_IFREG, NULL, - &meta_xlator_type_fops); - t->view_xlator = this; - - xlator_list_t *trav = this->children; - while (trav) { - add_xlator_to_tree (tree, trav->xlator, children); - trav = trav->next; - } -} + meta_priv_t *priv = NULL; + int ret = -1; -static void -build_meta_tree (xlator_t *this) -{ - meta_private_t *priv = (meta_private_t *) this->private; - priv->tree = GF_CALLOC (1, sizeof (meta_dirent_t), - gf_meta_mt_meta_dirent_t); - ERR_ABORT (priv->tree); - priv->tree->name = gf_strdup (".meta"); - priv->tree->stbuf = new_stbuf (); - priv->tree->stbuf->st_mode = S_IFDIR | S_IRUSR | S_IRGRP | S_IROTH | - S_IXUSR | S_IXGRP | S_IXOTH; + priv = GF_CALLOC(sizeof(*priv), 1, gf_meta_mt_priv_t); + if (!priv) + return ret; - insert_meta_entry (priv->tree, "/.meta/version", - S_IFREG, NULL, &meta_version_fops); + GF_OPTION_INIT("meta-dir-name", priv->meta_dir_name, str, out); - insert_meta_entry (priv->tree, "/.meta/xlators", - S_IFDIR, NULL, NULL); + this->private = priv; + ret = 0; +out: + if (ret) + GF_FREE(priv); - xlator_list_t *trav = this->children; - while (trav) { - add_xlator_to_tree (priv->tree, trav->xlator, "/.meta/xlators"); - trav = trav->next; - } + return ret; } -int32_t -mem_acct_init (xlator_t *this) +void +fini(xlator_t *this) { - int ret = -1; - - if (!this) - return ret; - - ret = xlator_mem_acct_init (this, gf_meta_mt_end + 1); - - if (ret != 0) { - gf_log(this->name, GF_LOG_ERROR, "Memory accounting init" - "failed"); - return ret; - } - - return ret; + GF_FREE(this->private); + return; } -int32_t -init (xlator_t *this) -{ - if (this->parent != NULL) { - gf_log ("meta", GF_LOG_ERROR, "FATAL: meta should be the root of the xlator tree"); - return -1; - } - - meta_private_t *priv = GF_CALLOC (1, sizeof (meta_private_t), - gf_meta_mt_meta_private_t); - ERR_ABORT (priv); - - data_t *directory = dict_get (this->options, "directory"); - if (directory) { - priv->directory = gf_strdup (data_to_str (directory)); - } - else { - priv->directory = ".meta"; - } - - this->private = priv; - build_meta_tree (this); +struct xlator_fops fops = {.lookup = meta_lookup, + .opendir = meta_opendir, + .open = meta_open, + .readv = meta_readv, + .flush = meta_flush, + .stat = meta_stat, + .fstat = meta_fstat, + .readdir = meta_readdir, + .readdirp = meta_readdirp, + .readlink = meta_readlink, + .writev = meta_writev, + .truncate = meta_truncate, + .ftruncate = meta_ftruncate, + .fsync = meta_fsync, + .fsyncdir = meta_fsyncdir}; - return 0; -} +struct xlator_cbks cbks = { + .forget = meta_forget, + .release = meta_release, + .releasedir = meta_releasedir, +}; -int32_t -fini (xlator_t *this) -{ - return 0; -} +struct volume_options options[] = { + {.key = {"meta-dir-name"}, + .type = GF_OPTION_TYPE_STR, + .default_value = DEFAULT_META_DIR_NAME, + .description = "Name of default meta directory."}, + {.key = {NULL}}, +}; -struct xlator_fops fops = { - .getattr = meta_getattr, - .readlink = meta_readlink, - .mknod = meta_mknod, - .mkdir = meta_mkdir, - .unlink = meta_unlink, - .rmdir = meta_rmdir, - .symlink = meta_symlink, - .rename = meta_rename, - .link = meta_link, - .chmod = meta_chmod, - .chown = meta_chown, - .truncate = meta_truncate, - .utimes = meta_utimes, - .open = meta_open, - .readv = meta_readv, - .writev = meta_writev, - .statfs = meta_statfs, - .flush = meta_flush, - .release = meta_release, - .fsync = meta_fsync, - .setxattr = meta_setxattr, - .getxattr = meta_getxattr, - .listxattr = meta_listxattr, - .removexattr = meta_removexattr, - .opendir = meta_opendir, - .readdir = meta_readdir, - .releasedir = meta_releasedir, - .fsyncdir = meta_fsyncdir, - .access = meta_access, - .ftruncate = meta_ftruncate, - .fgetattr = meta_fgetattr, - .create = meta_create, - .lk = meta_lk, +xlator_api_t xlator_api = { + .init = init, + .fini = fini, + .mem_acct_init = mem_acct_init, + .op_version = {1}, /* Present from the initial version */ + .fops = &fops, + .cbks = &cbks, + .options = options, + .identifier = "meta", + .category = GF_TECH_PREVIEW, }; diff --git a/xlators/meta/src/meta.h b/xlators/meta/src/meta.h index 73e0e50db57..7f0cf28808a 100644 --- a/xlators/meta/src/meta.h +++ b/xlators/meta/src/meta.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2006-2012 Red Hat, Inc. <http://www.redhat.com> + Copyright (c) 2014 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 @@ -10,29 +10,131 @@ #ifndef __META_H__ #define __META_H__ -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -struct _meta_dirent { - const char *name; - int type; - struct _meta_dirent *children; - struct _meta_dirent *parent; - struct _meta_dirent *next; - struct stat *stbuf; - xlator_t *view_xlator; - struct xlator_fops *fops; +#include <glusterfs/strfd.h> + +#define DEFAULT_META_DIR_NAME ".meta" + +#define META_ROOT_GFID "ba926388-bb9c-4eec-ad60-79dba4cc083a" + +#define IS_META_ROOT_GFID(g) (strcmp(uuid_utoa(g), META_ROOT_GFID) == 0) + +typedef int (*meta_hook_t)(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata); + +typedef struct { + dict_t *xdata; +} meta_local_t; + +typedef struct { + char *meta_dir_name; +} meta_priv_t; + +struct meta_dirent { + const char *name; + ia_type_t type; + meta_hook_t hook; +}; + +#define DOT_DOTDOT \ + {.name = ".", .type = IA_IFDIR}, { .name = "..", .type = IA_IFDIR } + +struct meta_ops { + struct meta_dirent *fixed_dirents; + int (*dir_fill)(xlator_t *this, inode_t *dir, struct meta_dirent **entries); + int (*file_fill)(xlator_t *this, inode_t *file, strfd_t *strfd); + int (*iatt_fill)(xlator_t *this, inode_t *inode, struct iatt *iatt); + int (*link_fill)(xlator_t *this, inode_t *inode, strfd_t *strfd); + int (*file_write)(xlator_t *this, fd_t *fd, struct iovec *iov, int count); + struct xlator_fops fops; + struct xlator_cbks cbks; }; -typedef struct _meta_dirent meta_dirent_t; typedef struct { - const char *directory; - meta_dirent_t *tree; -} meta_private_t; + char *data; + struct meta_dirent *dirents; + size_t size; +} meta_fd_t; + +#define COUNT(arr) (sizeof(arr) / sizeof(arr[0])) + +#define META_HOOK(loc) \ + (__is_root_gfid(loc->pargfid) && \ + !strcmp(loc->name, META_PRIV(THIS)->meta_dir_name)) + +#define META_PRIV(t) ((meta_priv_t *)(t->private)) + +#define META_STACK_UNWIND(fop, frame, params...) \ + do { \ + meta_local_t *__local = NULL; \ + xlator_t *__this = NULL; \ + if (frame) { \ + __local = frame->local; \ + __this = frame->this; \ + frame->local = NULL; \ + } \ + STACK_UNWIND_STRICT(fop, frame, params); \ + if (__local) { \ + meta_local_cleanup(__local, __this); \ + } \ + } while (0) + +#define META_FOP(i, fop, fr, t, params...) \ + { \ + struct xlator_fops *_fops = NULL; \ + \ + _fops = meta_fops_get(i, t); \ + \ + _fops->fop(fr, t, params); \ + } \ + while (0) + +void +meta_iatt_fill(struct iatt *iatt, inode_t *inode, ia_type_t type); + +int +meta_inode_discover(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata); + +int +meta_ops_set(inode_t *inode, xlator_t *this, struct meta_ops *ops); + +struct xlator_fops * +meta_fops_get(inode_t *inode, xlator_t *this); +struct xlator_cbks * +meta_cbks_get(inode_t *inode, xlator_t *this); +struct meta_ops * +meta_ops_get(inode_t *inode, xlator_t *this); + +int +meta_ctx_set(inode_t *inode, xlator_t *this, void *ctx); + +void * +meta_ctx_get(inode_t *inode, xlator_t *this); + +void +meta_local_cleanup(meta_local_t *local, xlator_t *this); + +struct xlator_fops * +meta_defaults_init(struct xlator_fops *fops); + +meta_fd_t * +meta_fd_get(fd_t *fd, xlator_t *this); + +int +meta_fd_release(fd_t *fd, xlator_t *this); + +dict_t * +meta_direct_io_mode(dict_t *xdata, call_frame_t *frame); + +meta_local_t * +meta_local(call_frame_t *frame); + +int +meta_file_fill(xlator_t *this, fd_t *fd); -#include "tree.h" -#include "misc.h" +int +meta_dir_fill(xlator_t *this, fd_t *fd); +int +fixed_dirents_len(struct meta_dirent *dirents); #endif /* __META_H__ */ diff --git a/xlators/meta/src/misc.c b/xlators/meta/src/misc.c deleted file mode 100644 index 1a8dfa8068d..00000000000 --- a/xlators/meta/src/misc.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - Copyright (c) 2006-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. -*/ -#include <unistd.h> -#include <sys/uio.h> - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include "xlator.h" -#include "meta.h" - -#define min(x,y) ((x) < (y) ? (x) : (y)) - -/* /.meta/version */ -static const char *version_str = PACKAGE_NAME " " PACKAGE_VERSION "\n"; - -int32_t -meta_version_readv (call_frame_t *frame, xlator_t *this, - dict_t *fd, size_t size, off_t offset) -{ - static int version_size; - version_size = strlen (version_str); - - struct iovec vec; - vec.iov_base = version_str + offset; - vec.iov_len = min (version_size - offset, size); - - STACK_UNWIND (frame, vec.iov_len, 0, &vec, 1); - return 0; -} - -int32_t -meta_version_getattr (call_frame_t *frame, - xlator_t *this, - const char *path) -{ - meta_private_t *priv = (meta_private_t *) this->private; - meta_dirent_t *root = priv->tree; - meta_dirent_t *file = lookup_meta_entry (root, path, NULL); - file->stbuf->st_size = strlen (version_str); - STACK_UNWIND (frame, 0, 0, file->stbuf); -} - -struct xlator_fops meta_version_fops = { - .readv = meta_version_readv, - .getattr = meta_version_getattr -}; - diff --git a/xlators/meta/src/misc.h b/xlators/meta/src/misc.h deleted file mode 100644 index 30dd10e34ff..00000000000 --- a/xlators/meta/src/misc.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - Copyright (c) 2006-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 __MISC_H__ -#define __MISC_H__ - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - - -struct xlator_fops meta_version_fops; - -#endif /* __MISC_H__ */ diff --git a/xlators/meta/src/name-file.c b/xlators/meta/src/name-file.c new file mode 100644 index 00000000000..5874a24d78a --- /dev/null +++ b/xlators/meta/src/name-file.c @@ -0,0 +1,44 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" +#include <glusterfs/strfd.h> +#include <glusterfs/lkowner.h> + +static int +name_file_fill(xlator_t *this, inode_t *file, strfd_t *strfd) +{ + xlator_t *xl = NULL; + + xl = meta_ctx_get(file, this); + + strprintf(strfd, "%s\n", xl->name); + + return strfd->size; +} + +static struct meta_ops name_file_ops = { + .file_fill = name_file_fill, +}; + +int +meta_name_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + meta_ops_set(loc->inode, this, &name_file_ops); + + meta_ctx_set(loc->inode, this, meta_ctx_get(loc->parent, this)); + + return 0; +} diff --git a/xlators/meta/src/option-file.c b/xlators/meta/src/option-file.c new file mode 100644 index 00000000000..ff55eca592f --- /dev/null +++ b/xlators/meta/src/option-file.c @@ -0,0 +1,45 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" +#include "meta-hooks.h" + +static int +option_file_fill(xlator_t *this, inode_t *inode, strfd_t *strfd) +{ + data_t *data = NULL; + + data = meta_ctx_get(inode, this); + + strprintf(strfd, "%s\n", data_to_str(data)); + + return strfd->size; +} + +static struct meta_ops option_file_ops = {.file_fill = option_file_fill}; + +int +meta_option_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + xlator_t *xl = NULL; + + xl = meta_ctx_get(loc->parent, this); + + meta_ctx_set(loc->inode, this, dict_get(xl->options, (char *)loc->name)); + + meta_ops_set(loc->inode, this, &option_file_ops); + + return 0; +} diff --git a/xlators/meta/src/options-dir.c b/xlators/meta/src/options-dir.c new file mode 100644 index 00000000000..d68a7eeaffc --- /dev/null +++ b/xlators/meta/src/options-dir.c @@ -0,0 +1,65 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" +#include "meta-hooks.h" + +static int +dict_key_add(dict_t *dict, char *key, data_t *value, void *data) +{ + struct meta_dirent **direntp = data; + + (*direntp)->name = gf_strdup(key); + (*direntp)->type = IA_IFREG; + (*direntp)->hook = meta_option_file_hook; + + (*direntp)++; + return 0; +} + +static int +options_dir_fill(xlator_t *this, inode_t *inode, struct meta_dirent **dp) +{ + struct meta_dirent *dirent = NULL; + struct meta_dirent *direntp = NULL; + xlator_t *xl = NULL; + + xl = meta_ctx_get(inode, this); + + dirent = GF_CALLOC(sizeof(*dirent), xl->options->count, + gf_meta_mt_dirents_t); + if (!dirent) + return -1; + + direntp = dirent; + + dict_foreach(xl->options, dict_key_add, &direntp); + + *dp = dirent; + + return xl->options->count; +} + +static struct meta_ops options_dir_ops = {.dir_fill = options_dir_fill}; + +int +meta_options_dir_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + meta_ctx_set(loc->inode, this, meta_ctx_get(loc->parent, this)); + + meta_ops_set(loc->inode, this, &options_dir_ops); + + return 0; +} diff --git a/xlators/meta/src/private-file.c b/xlators/meta/src/private-file.c new file mode 100644 index 00000000000..23ec319456b --- /dev/null +++ b/xlators/meta/src/private-file.c @@ -0,0 +1,44 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" +#include <glusterfs/strfd.h> +#include <glusterfs/statedump.h> + +static int +private_file_fill(xlator_t *this, inode_t *file, strfd_t *strfd) +{ + xlator_t *xl = NULL; + + xl = meta_ctx_get(file, this); + + gf_proc_dump_xlator_private(xl, strfd); + + return strfd->size; +} + +static struct meta_ops private_file_ops = { + .file_fill = private_file_fill, +}; + +int +meta_private_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + meta_ops_set(loc->inode, this, &private_file_ops); + + meta_ctx_set(loc->inode, this, meta_ctx_get(loc->parent, this)); + + return 0; +} diff --git a/xlators/meta/src/process_uuid-file.c b/xlators/meta/src/process_uuid-file.c new file mode 100644 index 00000000000..a24c1b57ab3 --- /dev/null +++ b/xlators/meta/src/process_uuid-file.c @@ -0,0 +1,37 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" +#include <glusterfs/strfd.h> +#include <glusterfs/lkowner.h> + +static int +process_uuid_file_fill(xlator_t *this, inode_t *file, strfd_t *strfd) +{ + strprintf(strfd, "%s\n", this->ctx->process_uuid); + return strfd->size; +} + +static struct meta_ops process_uuid_file_ops = { + .file_fill = process_uuid_file_fill, +}; + +int +meta_process_uuid_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + meta_ops_set(loc->inode, this, &process_uuid_file_ops); + + return 0; +} diff --git a/xlators/meta/src/profile-file.c b/xlators/meta/src/profile-file.c new file mode 100644 index 00000000000..829dcb77451 --- /dev/null +++ b/xlators/meta/src/profile-file.c @@ -0,0 +1,44 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" +#include <glusterfs/strfd.h> +#include <glusterfs/statedump.h> + +static int +profile_file_fill(xlator_t *this, inode_t *file, strfd_t *strfd) +{ + xlator_t *xl = NULL; + + xl = meta_ctx_get(file, this); + + gf_proc_dump_xlator_profile(xl, strfd); + + return strfd->size; +} + +static struct meta_ops profile_file_ops = { + .file_fill = profile_file_fill, +}; + +int +meta_profile_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + meta_ops_set(loc->inode, this, &profile_file_ops); + + meta_ctx_set(loc->inode, this, meta_ctx_get(loc->parent, this)); + + return 0; +} diff --git a/xlators/meta/src/root-dir.c b/xlators/meta/src/root-dir.c new file mode 100644 index 00000000000..80292bd3dda --- /dev/null +++ b/xlators/meta/src/root-dir.c @@ -0,0 +1,77 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" +#include "meta-hooks.h" + +static struct meta_dirent root_dir_dirents[] = { + DOT_DOTDOT, + + { + .name = "graphs", + .type = IA_IFDIR, + .hook = meta_graphs_dir_hook, + }, + { + .name = "frames", + .type = IA_IFREG, + .hook = meta_frames_file_hook, + }, + { + .name = "logging", + .type = IA_IFDIR, + .hook = meta_logging_dir_hook, + }, + { + .name = "process_uuid", + .type = IA_IFREG, + .hook = meta_process_uuid_file_hook, + }, + { + .name = "version", + .type = IA_IFREG, + .hook = meta_version_file_hook, + }, + { + .name = "cmdline", + .type = IA_IFREG, + .hook = meta_cmdline_file_hook, + }, + { + .name = "mallinfo", + .type = IA_IFREG, + .hook = meta_mallinfo_file_hook, + }, + { + .name = "master", + .type = IA_IFDIR, + .hook = meta_master_dir_hook, + }, + { + .name = "measure_latency", + .type = IA_IFREG, + .hook = meta_measure_file_hook, + }, + {.name = NULL}}; + +static struct meta_ops meta_root_dir_ops = {.fixed_dirents = root_dir_dirents}; + +int +meta_root_dir_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + meta_ops_set(loc->inode, this, &meta_root_dir_ops); + + return 0; +} diff --git a/xlators/meta/src/subvolume-link.c b/xlators/meta/src/subvolume-link.c new file mode 100644 index 00000000000..5b1f752efd0 --- /dev/null +++ b/xlators/meta/src/subvolume-link.c @@ -0,0 +1,56 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" + +static int +subvolume_link_fill(xlator_t *this, inode_t *inode, strfd_t *strfd) +{ + xlator_t *xl = NULL; + + xl = meta_ctx_get(inode, this); + + strprintf(strfd, "../../%s", xl->name); + + return 0; +} + +struct meta_ops subvolume_link_ops = {.link_fill = subvolume_link_fill}; + +int +meta_subvolume_link_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + int count = 0; + int i = 0; + xlator_t *xl = NULL; + xlator_list_t *subv = NULL; + xlator_t *subvol = NULL; + + count = strtol(loc->name, 0, 0); + xl = meta_ctx_get(loc->parent, this); + + for (subv = xl->children; subv; subv = subv->next) { + if (i == count) { + subvol = subv->xlator; + break; + } + i++; + } + + meta_ctx_set(loc->inode, this, subvol); + + meta_ops_set(loc->inode, this, &subvolume_link_ops); + return 0; +} diff --git a/xlators/meta/src/subvolumes-dir.c b/xlators/meta/src/subvolumes-dir.c new file mode 100644 index 00000000000..3cb170ea1f4 --- /dev/null +++ b/xlators/meta/src/subvolumes-dir.c @@ -0,0 +1,62 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" +#include "meta-hooks.h" + +static int +subvolumes_dir_fill(xlator_t *this, inode_t *dir, struct meta_dirent **dp) +{ + struct meta_dirent *dirents = NULL; + xlator_t *xl = NULL; + xlator_list_t *subv = NULL; + int i = 0; + int count = 0; + + xl = meta_ctx_get(dir, this); + + for (subv = xl->children; subv; subv = subv->next) + count++; + + dirents = GF_MALLOC(sizeof(*dirents) * count, gf_meta_mt_dirents_t); + if (!dirents) + return -1; + + for (subv = xl->children; subv; subv = subv->next) { + char num[16] = {}; + snprintf(num, 16, "%d", i); + + dirents[i].name = gf_strdup(num); + dirents[i].type = IA_IFLNK; + dirents[i].hook = meta_subvolume_link_hook; + i++; + } + + *dp = dirents; + + return count; +} + +static struct meta_ops subvolumes_dir_ops = {.dir_fill = subvolumes_dir_fill}; + +int +meta_subvolumes_dir_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + meta_ctx_set(loc->inode, this, meta_ctx_get(loc->parent, this)); + + meta_ops_set(loc->inode, this, &subvolumes_dir_ops); + + return 0; +} diff --git a/xlators/meta/src/top-link.c b/xlators/meta/src/top-link.c new file mode 100644 index 00000000000..33f0d407411 --- /dev/null +++ b/xlators/meta/src/top-link.c @@ -0,0 +1,40 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" + +static int +top_link_fill(xlator_t *this, inode_t *inode, strfd_t *strfd) +{ + glusterfs_graph_t *graph = NULL; + + graph = meta_ctx_get(inode, this); + + strprintf(strfd, "%s", ((xlator_t *)graph->top)->name); + + return 0; +} + +struct meta_ops top_link_ops = {.link_fill = top_link_fill}; + +int +meta_top_link_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + meta_ops_set(loc->inode, this, &top_link_ops); + + meta_ctx_set(loc->inode, this, meta_ctx_get(loc->parent, this)); + + return 0; +} diff --git a/xlators/meta/src/tree.c b/xlators/meta/src/tree.c deleted file mode 100644 index dacbd665a4a..00000000000 --- a/xlators/meta/src/tree.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - Copyright (c) 2006-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 _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> -#include <string.h> - -#include "glusterfs.h" -#include "xlator.h" - -#include "meta.h" -#include "meta-mem-types.h" - -static int -is_meta_path (const char *path) -{ - while (*path == '/') - path++; - if (!strncmp (path, ".meta", strlen (".meta"))) - return 1; - return 0; -} - -struct stat * -new_stbuf (void) -{ - static int next_inode = 0; - struct stat *stbuf = GF_CALLOC (1, sizeof (struct stat), gf_meta_mt_stat); - - ERR_ABORT (stbuf); - - stbuf->st_dev = 0; - stbuf->st_ino = next_inode++; - stbuf->st_mode = S_IRUSR | S_IRGRP | S_IROTH; - stbuf->st_nlink = 1; - stbuf->st_uid = 0; - stbuf->st_gid = 0; - stbuf->st_rdev = 0; - stbuf->st_size = 0; - stbuf->st_blksize = 0; - stbuf->st_blocks = 0; - stbuf->st_atime = time (NULL); - stbuf->st_atim.tv_nsec = 0; - stbuf->st_mtime = stbuf->st_atime; - stbuf->st_mtim.tv_nsec = 0; - stbuf->st_ctime = stbuf->st_ctime; - stbuf->st_ctim.tv_nsec = 0; - - return stbuf; -} - -/* find an entry among the siblings of an entry */ -static meta_dirent_t * -find_entry (meta_dirent_t *node, const char *dir) -{ - meta_dirent_t *trav = node; - while (trav) { - if (!strcmp (trav->name, dir)) - return trav; - trav = trav->next; - } - return NULL; -} - -/* - * Return the meta_dirent_t corresponding to the pathname. - * - * If pathname does not exist in the meta tree, try to return - * its highest parent that does exist. The part of the - * pathname that is left over is returned in the value-result - * variable {remain}. - * For example, for "/.meta/xlators/brick1/view/foo/bar/baz", - * return the entry for "/.meta/xlators/brick1/view" - * and set remain to "/bar/baz" - */ - -meta_dirent_t * -lookup_meta_entry (meta_dirent_t *root, const char *path, - char **remain) -{ - char *_path = gf_strdup (path); - - if (!is_meta_path (path)) - return NULL; - - meta_dirent_t *trav = root; - char *dir = strtok (_path, "/"); - dir = strtok (NULL, "/"); - - while (dir) { - meta_dirent_t *ntrav; - ntrav = find_entry (trav->children, dir); - if (!ntrav) { - /* we have reached bottom of the meta tree. - Unknown dragons lie further below */ - if (remain) { - char *piece = dir; - while (piece) { - char *tmp = *remain; - if (*remain) - gf_asprintf (remain, "/%s/%s", *remain, piece); - else - gf_asprintf (remain, "/%s", piece); - GF_FREE (tmp); - piece = strtok (NULL, "/"); - } - } - return trav; - } - dir = strtok (NULL, "/"); - trav = ntrav; - } - - GF_FREE (_path); - return trav; -} - -meta_dirent_t * -insert_meta_entry (meta_dirent_t *root, const char *path, - int type, struct stat *stbuf, struct xlator_fops *fops) -{ - if (!is_meta_path (path)) - return NULL; - char *slashpos = strrchr (path, '/'); - char *dir = strndup (path, slashpos - path); - meta_dirent_t *parent = lookup_meta_entry (root, dir, NULL); - if (!dir) - return NULL; - - meta_dirent_t *new = GF_CALLOC (1, sizeof (meta_dirent_t), - gf_meta_mt_meta_dirent_t); - ERR_ABORT (new); - new->name = gf_strdup (slashpos+1); - new->type = type; - new->parent = parent; - new->next = parent->children; - parent->children = new; - if (stbuf) - new->stbuf = stbuf; - else - new->stbuf = new_stbuf (); - - new->stbuf->st_mode |= type; - new->fops = fops; - return new; -} - -int main (void) -{ - meta_dirent_t *root = GF_CALLOC (1, sizeof (meta_dirent_t), - gf_meta_mt_meta_dirent_t); - ERR_ABORT (root); - root->name = gf_strdup (".meta"); - - insert_meta_entry (root, "/.meta/version", S_IFREG, NULL, NULL); - return 0; -} diff --git a/xlators/meta/src/tree.h b/xlators/meta/src/tree.h deleted file mode 100644 index 985df3bd7cb..00000000000 --- a/xlators/meta/src/tree.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (c) 2006-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 __TREE_H__ -#define __TREE_H__ - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -meta_dirent_t * -insert_meta_entry (meta_dirent_t *root, const char *path, - int type, struct stat *stbuf, struct xlator_fops *fops); -meta_dirent_t * -lookup_meta_entry (meta_dirent_t *root, const char *path, - char **remain); - -#endif /* __TREE_H__ */ diff --git a/xlators/meta/src/type-file.c b/xlators/meta/src/type-file.c new file mode 100644 index 00000000000..ece342a0b2a --- /dev/null +++ b/xlators/meta/src/type-file.c @@ -0,0 +1,44 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" +#include <glusterfs/strfd.h> +#include <glusterfs/lkowner.h> + +static int +type_file_fill(xlator_t *this, inode_t *file, strfd_t *strfd) +{ + xlator_t *xl = NULL; + + xl = meta_ctx_get(file, this); + + strprintf(strfd, "%s\n", xl->type); + + return strfd->size; +} + +static struct meta_ops type_file_ops = { + .file_fill = type_file_fill, +}; + +int +meta_type_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + meta_ops_set(loc->inode, this, &type_file_ops); + + meta_ctx_set(loc->inode, this, meta_ctx_get(loc->parent, this)); + + return 0; +} diff --git a/xlators/meta/src/version-file.c b/xlators/meta/src/version-file.c new file mode 100644 index 00000000000..36276fb810a --- /dev/null +++ b/xlators/meta/src/version-file.c @@ -0,0 +1,37 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" +#include <glusterfs/strfd.h> +#include <glusterfs/lkowner.h> + +static int +version_file_fill(xlator_t *this, inode_t *file, strfd_t *strfd) +{ + strprintf(strfd, "{ \n \"Package Version\": \"%s\"\n}", PACKAGE_VERSION); + return strfd->size; +} + +static struct meta_ops version_file_ops = { + .file_fill = version_file_fill, +}; + +int +meta_version_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + meta_ops_set(loc->inode, this, &version_file_ops); + + return 0; +} diff --git a/xlators/meta/src/view-dir.c b/xlators/meta/src/view-dir.c new file mode 100644 index 00000000000..30931061567 --- /dev/null +++ b/xlators/meta/src/view-dir.c @@ -0,0 +1,33 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" +#include "meta-hooks.h" + +static struct meta_dirent view_dir_dirents[] = {DOT_DOTDOT, + + {.name = NULL}}; + +static struct meta_ops view_dir_ops = {.fixed_dirents = view_dir_dirents}; + +int +meta_view_dir_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + meta_ctx_set(loc->inode, this, meta_ctx_get(loc->parent, this)); + + meta_ops_set(loc->inode, this, &view_dir_ops); + + return 0; +} diff --git a/xlators/meta/src/view.c b/xlators/meta/src/view.c deleted file mode 100644 index b4e2d64a239..00000000000 --- a/xlators/meta/src/view.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - Copyright (c) 2006-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 _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include "glusterfs.h" -#include "xlator.h" - -#include "meta.h" - -/* - * This file contains fops for the files and directories in - * an xlator directory - */ - -/* /.meta/xlators/.../type */ - -int32_t -meta_xlator_type_readv (call_frame_t *frame, xlator_t *this, - dict_t *fd, size_t size, off_t offset) -{ - meta_private_t *priv = (meta_private_t *) this->private; - meta_dirent_t *root = priv->tree; - data_t *path_data = dict_get (fd, this->name); - - if (path_data) { - const char *path = data_to_str (path_data); - meta_dirent_t *file = lookup_meta_entry (root, path, NULL); - xlator_t *view_xlator = file->view_xlator; - - int type_size; - type_size = strlen (view_xlator->type); - - struct iovec vec; - vec.iov_base = view_xlator->type + offset; - vec.iov_len = min (type_size - offset, size); - - STACK_UNWIND (frame, vec.iov_len, 0, &vec, 1); - return 0; - } -} - -int32_t -meta_xlator_type_getattr (call_frame_t *frame, - xlator_t *this, - const char *path) -{ - meta_private_t *priv = (meta_private_t *) this->private; - meta_dirent_t *root = priv->tree; - - meta_dirent_t *file = lookup_meta_entry (root, path, NULL); - xlator_t *view_xlator = file->view_xlator; - file->stbuf->st_size = strlen (view_xlator->type); - - STACK_UNWIND (frame, 0, 0, file->stbuf); - return 0; -} - -struct xlator_fops meta_xlator_type_fops = { - .readv = meta_xlator_type_readv, - .getattr = meta_xlator_type_getattr -}; - -/* - * fops for the "view" directory - * {xlator}/view shows the filesystem as it appears - * to {xlator} - */ - -static int32_t -meta_xlator_view_getattr_cbk (call_frame_t *frame, void *cookie, - xlator_t *this, int32_t op_ret, int32_t op_errno, - struct stat *buf) -{ - STACK_UNWIND (frame, op_ret, op_errno, buf); - return 0; -} - -int32_t -meta_xlator_view_getattr (call_frame_t *frame, - xlator_t *this, - const char *path) -{ - meta_private_t *priv = (meta_private_t *) this->private; - meta_dirent_t *root = priv->tree; - char *op_path = NULL; - - meta_dirent_t *file = lookup_meta_entry (root, path, &op_path); - - if (op_path) { - STACK_WIND (frame, meta_xlator_view_getattr_cbk, file->view_xlator, - file->view_xlator->fops->getattr, - op_path); - } - else { - STACK_UNWIND (frame, 0, 0, file->stbuf); - } - - return 0; -} - -static int32_t -meta_xlator_view_readdir_cbk (call_frame_t *frame, void *cookie, - xlator_t *this, int32_t op_ret, int32_t op_errno, - dir_entry_t *entries, int32_t count) -{ - STACK_UNWIND (frame, op_ret, op_errno, entries, count); - return 0; -} - -int32_t -meta_xlator_view_readdir (call_frame_t *frame, - xlator_t *this, - const char *path) -{ - meta_private_t *priv = (meta_private_t *) this->private; - meta_dirent_t *root = priv->tree; - char *op_path = NULL; - - meta_dirent_t *dir = lookup_meta_entry (root, path, &op_path); - - STACK_WIND (frame, meta_xlator_view_readdir_cbk, - dir->view_xlator, dir->view_xlator->fops->readdir, - op_path ? op_path : "/"); - return 0; -} - -static int32_t -meta_xlator_view_open_cbk (call_frame_t *frame, void *cookie, - xlator_t *this, - int32_t op_ret, int32_t op_errno, - dict_t *ctx, struct stat *buf) -{ - STACK_UNWIND (frame, op_ret, op_errno, ctx, buf); - return 0; -} - -int32_t -meta_xlator_view_open (call_frame_t *frame, xlator_t *this, - const char *path, int32_t flags, mode_t mode) -{ - meta_private_t *priv = (meta_private_t *) this->private; - meta_dirent_t *root = priv->tree; - char *op_path = NULL; - - meta_dirent_t *file = lookup_meta_entry (root, path, &op_path); - STACK_WIND (frame, meta_xlator_view_open_cbk, - file->view_xlator, file->view_xlator->fops->open, - op_path, flags, mode); - return 0; -} - -int32_t -meta_xlator_view_create (call_frame_t *frame, xlator_t *this, - const char *path, int32_t flags, mode_t mode) -{ - meta_private_t *priv = (meta_private_t *) this->private; - meta_dirent_t *root = priv->tree; - char *op_path = NULL; - - meta_dirent_t *file = lookup_meta_entry (root, path, &op_path); - STACK_WIND (frame, meta_xlator_view_open_cbk, - file->view_xlator, file->view_xlator->fops->create, - op_path, flags, mode); - return 0; -} - -static int32_t -meta_xlator_view_readv_cbk (call_frame_t *frame, void *cookie, - xlator_t *this, int32_t op_ret, - int32_t op_errno, struct iovec *vector, - int32_t count) -{ - STACK_UNWIND (frame, op_ret, op_errno, vector, count); - return 0; -} - -int32_t -meta_xlator_view_readv (call_frame_t *frame, xlator_t *this, - dict_t *fd, size_t size, off_t offset) -{ - meta_private_t *priv = (meta_private_t *) this->private; - meta_dirent_t *root = priv->tree; - data_t *path_data = dict_get (fd, this->name); - - if (path_data) { - const char *path = data_to_str (path_data); - meta_dirent_t *file = lookup_meta_entry (root, path, NULL); - - STACK_WIND (frame, meta_xlator_view_readv_cbk, - file->view_xlator, file->view_xlator->fops->readv, - fd, size, offset); - return 0; - } - - STACK_UNWIND (frame, -1, EBADFD, NULL, 0); - return 0; -} - -static int32_t -meta_xlator_view_writev_cbk (call_frame_t *frame, void *cookie, - xlator_t *this, int32_t op_ret, - int32_t op_errno) -{ - STACK_UNWIND (frame, op_ret, op_errno); - return 0; -} - -int32_t -meta_xlator_view_writev (call_frame_t *frame, xlator_t *this, - dict_t *fd, - struct iovec *vector, int32_t count, off_t offset) -{ - meta_private_t *priv = (meta_private_t *) this->private; - meta_dirent_t *root = priv->tree; - data_t *path_data = dict_get (fd, this->name); - - if (path_data) { - const char *path = data_to_str (path_data); - meta_dirent_t *file = lookup_meta_entry (root, path, NULL); - - STACK_WIND (frame, meta_xlator_view_writev_cbk, - file->view_xlator, file->view_xlator->fops->writev, - fd, vector, count, offset); - return 0; - } - - STACK_UNWIND (frame, -1, EBADFD, NULL, 0); - return 0; -} - -struct xlator_fops meta_xlator_view_fops = { - .getattr = meta_xlator_view_getattr, - .readdir = meta_xlator_view_readdir, - .open = meta_xlator_view_open, - .create = meta_xlator_view_create, - .readv = meta_xlator_view_readv, - .writev = meta_xlator_view_writev -}; diff --git a/xlators/meta/src/view.h b/xlators/meta/src/view.h deleted file mode 100644 index 2eff6126e0f..00000000000 --- a/xlators/meta/src/view.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - Copyright (c) 2006-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 __VIEW_H__ -#define __VIEW_H__ - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - - -struct xlator_fops meta_xlator_type_fops; -struct xlator_fops meta_xlator_view_fops; - -#endif /* __VIEW_H__ */ diff --git a/xlators/meta/src/volfile-file.c b/xlators/meta/src/volfile-file.c new file mode 100644 index 00000000000..b2e2562ab8b --- /dev/null +++ b/xlators/meta/src/volfile-file.c @@ -0,0 +1,79 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" +#include <glusterfs/strfd.h> + +static int +xldump_options(dict_t *this, char *key, data_t *value, void *strfd) +{ + strprintf(strfd, " option %s %s\n", key, value->data); + return 0; +} + +static void +xldump_subvolumes(xlator_t *this, void *strfd) +{ + xlator_list_t *subv = NULL; + + if (!this->children) + return; + + strprintf(strfd, " subvolumes"); + + for (subv = this->children; subv; subv = subv->next) + strprintf(strfd, " %s", subv->xlator->name); + + strprintf(strfd, "\n"); +} + +static void +xldump(xlator_t *each, void *strfd) +{ + strprintf(strfd, "volume %s\n", each->name); + strprintf(strfd, " type %s\n", each->type); + dict_foreach(each->options, xldump_options, strfd); + + xldump_subvolumes(each, strfd); + + strprintf(strfd, "end-volume\n"); + strprintf(strfd, "\n"); +} + +static int +volfile_file_fill(xlator_t *this, inode_t *file, strfd_t *strfd) +{ + glusterfs_graph_t *graph = NULL; + + graph = meta_ctx_get(file, this); + + xlator_foreach_depth_first(graph->top, xldump, strfd); + + return strfd->size; +} + +static struct meta_ops volfile_file_ops = { + .file_fill = volfile_file_fill, +}; + +int +meta_volfile_file_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + meta_ops_set(loc->inode, this, &volfile_file_ops); + + meta_ctx_set(loc->inode, this, meta_ctx_get(loc->parent, this)); + + return 0; +} diff --git a/xlators/meta/src/xlator-dir.c b/xlators/meta/src/xlator-dir.c new file mode 100644 index 00000000000..86189715790 --- /dev/null +++ b/xlators/meta/src/xlator-dir.c @@ -0,0 +1,97 @@ +/* + Copyright (c) 2014 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. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +#include "meta-mem-types.h" +#include "meta.h" +#include "meta-hooks.h" + +static struct meta_dirent xlator_dir_dirents[] = { + DOT_DOTDOT, + + { + .name = "view", + .type = IA_IFDIR, + .hook = meta_view_dir_hook, + }, + { + .name = "type", + .type = IA_IFREG, + .hook = meta_type_file_hook, + }, + { + .name = "name", + .type = IA_IFREG, + .hook = meta_name_file_hook, + }, + { + .name = "subvolumes", + .type = IA_IFDIR, + .hook = meta_subvolumes_dir_hook, + }, + { + .name = "options", + .type = IA_IFDIR, + .hook = meta_options_dir_hook, + }, + { + .name = "private", + .type = IA_IFREG, + .hook = meta_private_file_hook, + }, + { + .name = "history", + .type = IA_IFREG, + .hook = meta_history_file_hook, + }, + { + .name = "meminfo", + .type = IA_IFREG, + .hook = meta_meminfo_file_hook, + }, + { + .name = "profile", + .type = IA_IFREG, + .hook = meta_profile_file_hook, + }, + {.name = NULL}}; + +static struct meta_ops xlator_dir_ops = {.fixed_dirents = xlator_dir_dirents}; + +int +meta_xlator_dir_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + glusterfs_graph_t *graph = NULL; + xlator_t *xl = NULL; + + graph = meta_ctx_get(loc->parent, this); + + xl = xlator_search_by_name(graph->first, loc->name); + + meta_ctx_set(loc->inode, this, xl); + + meta_ops_set(loc->inode, this, &xlator_dir_ops); + + return 0; +} + +int +meta_master_dir_hook(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) +{ + meta_ctx_set(loc->inode, this, this->ctx->master); + + meta_ops_set(loc->inode, this, &xlator_dir_ops); + + return 0; +} |
