summaryrefslogtreecommitdiffstats
path: root/xlators/meta/src
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/meta/src')
-rw-r--r--xlators/meta/src/Makefile.am47
-rw-r--r--xlators/meta/src/active-link.c34
-rw-r--r--xlators/meta/src/cmdline-file.c39
-rw-r--r--xlators/meta/src/frames-file.c107
-rw-r--r--xlators/meta/src/graph-dir.c98
-rw-r--r--xlators/meta/src/graphs-dir.c67
-rw-r--r--xlators/meta/src/history-file.c44
-rw-r--r--xlators/meta/src/logfile-link.c34
-rw-r--r--xlators/meta/src/logging-dir.c44
-rw-r--r--xlators/meta/src/loglevel-file.c50
-rw-r--r--xlators/meta/src/mallinfo-file.c36
-rw-r--r--xlators/meta/src/measure-file.c49
-rw-r--r--xlators/meta/src/meminfo-file.c44
-rw-r--r--xlators/meta/src/meta-defaults.c655
-rw-r--r--xlators/meta/src/meta-helpers.c332
-rw-r--r--xlators/meta/src/meta-hooks.h48
-rw-r--r--xlators/meta/src/meta-mem-types.h18
-rw-r--r--xlators/meta/src/meta.c1337
-rw-r--r--xlators/meta/src/meta.h144
-rw-r--r--xlators/meta/src/misc.c57
-rw-r--r--xlators/meta/src/misc.h21
-rw-r--r--xlators/meta/src/name-file.c44
-rw-r--r--xlators/meta/src/option-file.c45
-rw-r--r--xlators/meta/src/options-dir.c65
-rw-r--r--xlators/meta/src/private-file.c44
-rw-r--r--xlators/meta/src/process_uuid-file.c37
-rw-r--r--xlators/meta/src/profile-file.c44
-rw-r--r--xlators/meta/src/root-dir.c77
-rw-r--r--xlators/meta/src/subvolume-link.c56
-rw-r--r--xlators/meta/src/subvolumes-dir.c62
-rw-r--r--xlators/meta/src/top-link.c40
-rw-r--r--xlators/meta/src/tree.c169
-rw-r--r--xlators/meta/src/tree.h25
-rw-r--r--xlators/meta/src/type-file.c44
-rw-r--r--xlators/meta/src/version-file.c37
-rw-r--r--xlators/meta/src/view-dir.c33
-rw-r--r--xlators/meta/src/view.c248
-rw-r--r--xlators/meta/src/view.h22
-rw-r--r--xlators/meta/src/volfile-file.c79
-rw-r--r--xlators/meta/src/xlator-dir.c97
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;
+}