summaryrefslogtreecommitdiffstats
path: root/xlators/meta
diff options
context:
space:
mode:
authorAnand Avati <avati@redhat.com>2014-03-26 11:52:53 -0700
committerAnand Avati <avati@redhat.com>2014-05-05 17:28:55 -0700
commit8160399a36eff62a49a066f16dea9140d877c5e8 (patch)
treee51d49bd93ff98822986569fdfada5d2819546b0 /xlators/meta
parent7fba3a88f1ced610eca0c23516a1e720d75160cd (diff)
meta: (re-)Implement Meta translator
The meta translator exposes details about glusterfs itself in the form of a virtual namespace. Loading the translator on the client side creates the meta virtual view under $mntpoint/.meta by default. The directory is not listed (even with ls -a) and can be accessed by doing a "cd /mnt/.meta" Change-Id: I5ffdf39203841a9562a8280a1f79dc76d4dded5d BUG: 1089216 Signed-off-by: Anand Avati <avati@redhat.com> Reviewed-on: http://review.gluster.org/7509 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Harshavardhana <harsha@harshavardhana.net>
Diffstat (limited to 'xlators/meta')
-rw-r--r--xlators/meta/src/Makefile.am38
-rw-r--r--xlators/meta/src/meta-defaults.c611
-rw-r--r--xlators/meta/src/meta-helpers.c370
-rw-r--r--xlators/meta/src/meta-hooks.h39
-rw-r--r--xlators/meta/src/meta-mem-types.h13
-rw-r--r--xlators/meta/src/meta.c1313
-rw-r--r--xlators/meta/src/meta.h119
-rw-r--r--xlators/meta/src/misc.c57
-rw-r--r--xlators/meta/src/misc.h21
-rw-r--r--xlators/meta/src/plugins/active-link.c44
-rw-r--r--xlators/meta/src/plugins/cmdline-file.c47
-rw-r--r--xlators/meta/src/plugins/frames-file.c96
-rw-r--r--xlators/meta/src/plugins/graph-dir.c106
-rw-r--r--xlators/meta/src/plugins/graphs-dir.c79
-rw-r--r--xlators/meta/src/plugins/logfile-link.c44
-rw-r--r--xlators/meta/src/plugins/logging-dir.c51
-rw-r--r--xlators/meta/src/plugins/loglevel-file.c93
-rw-r--r--xlators/meta/src/plugins/name-file.c53
-rw-r--r--xlators/meta/src/plugins/option-file.c56
-rw-r--r--xlators/meta/src/plugins/options-dir.c76
-rw-r--r--xlators/meta/src/plugins/process_uuid-file.c46
-rw-r--r--xlators/meta/src/plugins/root-dir.c67
-rw-r--r--xlators/meta/src/plugins/subvolume-link.c66
-rw-r--r--xlators/meta/src/plugins/subvolumes-dir.c72
-rw-r--r--xlators/meta/src/plugins/top-link.c50
-rw-r--r--xlators/meta/src/plugins/type-file.c53
-rw-r--r--xlators/meta/src/plugins/version-file.c46
-rw-r--r--xlators/meta/src/plugins/view-dir.c45
-rw-r--r--xlators/meta/src/plugins/volfile-file.c91
-rw-r--r--xlators/meta/src/plugins/xlator-dir.c72
-rw-r--r--xlators/meta/src/tree.c169
-rw-r--r--xlators/meta/src/tree.h25
-rw-r--r--xlators/meta/src/view.c248
-rw-r--r--xlators/meta/src/view.h22
34 files changed, 2657 insertions, 1741 deletions
diff --git a/xlators/meta/src/Makefile.am b/xlators/meta/src/Makefile.am
index f8fa7d4cb13..530fea9792b 100644
--- a/xlators/meta/src/Makefile.am
+++ b/xlators/meta/src/Makefile.am
@@ -1,11 +1,37 @@
-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 -avoid-version
+
+meta_la_SOURCES = meta.c meta-helpers.c meta-defaults.c \
+ plugins/root-dir.c \
+ plugins/graphs-dir.c \
+ plugins/frames-file.c \
+ plugins/graph-dir.c \
+ plugins/active-link.c \
+ plugins/xlator-dir.c \
+ plugins/top-link.c \
+ plugins/logging-dir.c \
+ plugins/logfile-link.c \
+ plugins/loglevel-file.c \
+ plugins/process_uuid-file.c \
+ plugins/volfile-file.c \
+ plugins/view-dir.c \
+ plugins/subvolumes-dir.c \
+ plugins/subvolume-link.c \
+ plugins/type-file.c \
+ plugins/version-file.c \
+ plugins/options-dir.c \
+ plugins/option-file.c \
+ plugins/cmdline-file.c \
+ plugins/name-file.c
+
+meta_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
+
+noinst_HEADERS = meta.h meta-hooks.h meta-mem-types.h
AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
-AM_CFLAGS = -Wall
+AM_CFLAGS = -Wall $(GF_CFLAGS)
-CLEANFILES =
+CLEANFILES =
diff --git a/xlators/meta/src/meta-defaults.c b/xlators/meta/src/meta-defaults.c
new file mode 100644
index 00000000000..f2b637fa28a
--- /dev/null
+++ b/xlators/meta/src/meta-defaults.c
@@ -0,0 +1,611 @@
+/*
+ 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 _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "xlator.h"
+#include "defaults.h"
+
+#include "meta-mem-types.h"
+#include "meta.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)
+{
+ 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;
+ size_t 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);
+
+ 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);
+
+ 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 = { };
+
+ ops = meta_ops_get (loc->inode, this);
+ if (!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)
+ META_STACK_UNWIND (readlink, frame, strlen (strfd->data), 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)
+{
+ return default_ftruncate_failure_cbk (frame, EPERM);
+}
+
+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)
+{
+ return default_truncate_failure_cbk (frame, EPERM);
+}
+
+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..a67671050b8
--- /dev/null
+++ b/xlators/meta/src/meta-helpers.c
@@ -0,0 +1,370 @@
+/*
+ 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 _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "xlator.h"
+#include "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);
+ {
+ __fd_ctx_get (fd, this, &value);
+ 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);
+ }
+
+ meta_fd = (void *) 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 *) value;
+
+ if (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 *) 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 *) 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 uint64_t
+gfid_to_ino (uuid_t gfid)
+{
+ uint64_t ino = 0;
+ int i = 0, j = 0;
+
+ for (i = 15; i > (15 - 8); i--) {
+ ino += (uint64_t)(gfid[i]) << j;
+ j += 8;
+ }
+
+ return ino;
+}
+
+
+static void
+meta_uuid_copy (uuid_t dst, uuid_t src)
+{
+ uuid_copy (dst, src);
+ if (uuid_is_null (dst))
+ uuid_generate (dst);
+}
+
+
+static void
+default_meta_iatt_fill (struct iatt *iatt, inode_t *inode, ia_type_t type)
+{
+ struct timeval tv = { };
+
+ iatt->ia_type = type;
+ switch (type)
+ {
+ case IA_IFDIR:
+ iatt->ia_prot = ia_prot_from_st_mode (0755);
+ 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 (0644);
+ 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);
+ 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..f8ce3b61e4c
--- /dev/null
+++ b/xlators/meta/src/meta-hooks.h
@@ -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.
+*/
+
+#ifndef __META_HOOKS_H
+#define __META_HOOKS_H
+#include "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);
+
+#endif
diff --git a/xlators/meta/src/meta-mem-types.h b/xlators/meta/src/meta-mem-types.h
index 62028b246bf..e8a31856e71 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
@@ -14,11 +14,12 @@
#include "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_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..036ed112acf 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,262 @@
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.h"
-#include "dict.h"
#include "xlator.h"
+#include "defaults.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;
-}
+#include "meta-hooks.h"
-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)
+int
+meta_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
{
- STACK_UNWIND (frame,
- op_ret,
- op_errno,
- dest);
- return 0;
-}
+ inode_t *inode = NULL;
-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;
-}
+ if (META_HOOK (loc) || IS_META_ROOT_GFID (loc->gfid)) {
+ struct iatt iatt = { };
+ struct iatt parent = { };
-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;
-}
+ meta_root_dir_hook (frame, this, loc, xdata);
-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;
-}
+ meta_iatt_fill (&iatt, loc->inode, IA_IFDIR);
+ uuid_parse (META_ROOT_GFID, iatt.ia_gfid);
-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;
-}
+ META_STACK_UNWIND (lookup, frame, 0, 0, loc->inode, &iatt,
+ xdata, &parent);
+ 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;
-}
+ if (loc->parent)
+ inode = loc->parent;
+ else
+ inode = loc->inode;
-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;
-}
+ META_FOP (inode, lookup, frame, this, loc, xdata);
-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;
+ 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)
+int
+meta_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
+ dict_t *xdata)
{
- STACK_WIND (frame,
- meta_rmdir_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rmdir,
- path);
- return 0;
-}
+ META_FOP (fd->inode, opendir, frame, this, loc, fd, xdata);
-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;
+ return 0;
}
-int32_t
-meta_symlink (call_frame_t *frame,
- xlator_t *this,
- const char *oldpath,
- const char *newpath)
-{
- STACK_WIND (frame,
- meta_symlink_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->symlink,
- oldpath,
- newpath);
- return 0;
-}
-int32_t
-meta_rename_cbk (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno)
+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);
- return 0;
-}
+ META_FOP (fd->inode, open, frame, this, loc, flags, fd, xdata);
-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;
+ return 0;
}
-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;
-}
-int32_t
-meta_link (call_frame_t *frame,
- xlator_t *this,
- const char *oldpath,
- const char *newpath)
+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)
{
- STACK_WIND (frame,
- meta_link_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->link,
- oldpath,
- newpath);
- return 0;
-}
+ META_FOP (fd->inode, readv, frame, this, fd, size, offset, flags, xdata);
-struct _open_local {
- const char *path;
-};
-
-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;
-}
-
-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);
-
- 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)
-{
- 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->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;
- }
+ 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)
-{
- STACK_UNWIND (frame,
- op_ret,
- op_errno,
- vector,
- count);
- return 0;
-}
-int32_t
-meta_readv (call_frame_t *frame,
- xlator_t *this,
- dict_t *fd,
- size_t size,
- off_t offset)
+int
+meta_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, 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);
-
- 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;
- }
-}
+ META_FOP (fd->inode, flush, frame, this, fd, xdata);
-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;
+ 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)
-{
- 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->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_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
{
- STACK_UNWIND (frame,
- op_ret,
- op_errno);
- return 0;
-}
+ META_FOP (loc->inode, stat, frame, this, loc, 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)
-{
- STACK_UNWIND (frame,
- op_ret,
- op_errno);
- return 0;
-}
-int32_t
-meta_release (call_frame_t *frame,
- xlator_t *this,
- dict_t *fd)
+int
+meta_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, 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);
-
- 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;
- }
-}
+ META_FOP (fd->inode, fstat, frame, this, fd, xdata);
-int32_t
-meta_fsync_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;
+ return 0;
}
-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;
-}
-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)
-{
- STACK_UNWIND (frame,
- op_ret,
- op_errno,
- fd);
- return 0;
-}
-int32_t
-meta_opendir (call_frame_t *frame,
- xlator_t *this,
- const char *path)
+int
+meta_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset, 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) {
- 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;
- }
-}
+ META_FOP (fd->inode, readdirp, frame, this, fd, size, offset, xdata);
-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)
-{
- 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;
-
- STACK_UNWIND (frame, op_ret, op_errno, entries, count+1);
- return 0;
- }
-
- STACK_UNWIND (frame, op_ret, op_errno, entries, count);
- return 0;
+ return 0;
}
-int32_t
-meta_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;
-
- 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;
-}
-int32_t
-meta_releasedir_cbk (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno)
+int
+meta_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size,
+ dict_t *xdata)
{
- STACK_UNWIND (frame,
- op_ret,
- op_errno);
- return 0;
-}
+ META_FOP (loc->inode, readlink, frame, this, loc, size, 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;
-}
-
-int32_t
-meta_fsyncdir_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_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)
-{
- STACK_UNWIND (frame,
- op_ret,
- op_errno,
- buf);
- return 0;
-}
-int32_t
-meta_statfs (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)
{
- STACK_WIND (frame,
- meta_statfs_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->statfs,
- path);
- return 0;
+ META_FOP (fd->inode, writev, frame, this, fd, iov, count, offset, flags,
+ iobref, xdata);
+ return 0;
}
-int32_t
-meta_setxattr_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_setxattr (call_frame_t *frame,
- xlator_t *this,
- const char *path,
- const char *name,
- const char *value,
- size_t size,
- int32_t flags)
+int
+meta_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
+ dict_t *xdata)
{
- STACK_WIND (frame,
- meta_setxattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setxattr,
- path,
- name,
- value,
- size,
- flags);
- return 0;
-}
+ META_FOP (loc->inode, truncate, frame, this, loc, offset, xdata);
-int32_t
-meta_getxattr_cbk (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- char *value)
-{
- 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)
-{
- STACK_WIND (frame,
- meta_getxattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->getxattr,
- path,
- name,
- size);
- return 0;
-}
-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_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ dict_t *xdata)
{
- STACK_UNWIND (frame,
- op_ret,
- op_errno,
- value);
- return 0;
-}
+ META_FOP (fd->inode, ftruncate, frame, this, fd, offset, xdata);
-int32_t
-meta_listxattr (call_frame_t *frame,
- xlator_t *this,
- const char *path,
- size_t size)
-{
- STACK_WIND (frame,
- meta_listxattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->listxattr,
- path,
- size);
- return 0;
+ return 0;
}
-int32_t
-meta_removexattr_cbk (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno)
+int
+meta_forget (xlator_t *this, inode_t *inode)
{
- STACK_UNWIND (frame,
- op_ret,
- op_errno);
- return 0;
+ return 0;
}
-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;
-}
-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)
+int
+meta_release (xlator_t *this, fd_t *fd)
{
- STACK_UNWIND (frame,
- op_ret,
- op_errno,
- lock);
- return 0;
+ return meta_fd_release (fd, this);
}
-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;
-}
-static void
-add_xlator_to_tree (meta_dirent_t *tree, xlator_t *this,
- const char *prefix)
+int
+meta_releasedir (xlator_t *this, fd_t *fd)
{
- 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;
- }
+ return meta_fd_release (fd, this);
}
-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;
-
- insert_meta_entry (priv->tree, "/.meta/version",
- S_IFREG, NULL, &meta_version_fops);
-
- insert_meta_entry (priv->tree, "/.meta/xlators",
- S_IFDIR, NULL, NULL);
-
- xlator_list_t *trav = this->children;
- while (trav) {
- add_xlator_to_tree (priv->tree, trav->xlator, "/.meta/xlators");
- trav = trav->next;
- }
-}
-int32_t
+int
mem_acct_init (xlator_t *this)
{
- int ret = -1;
+ 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");
+ gf_log (this->name, GF_LOG_ERROR,
+ "Memory accounting init failed");
return ret;
}
return ret;
}
-int32_t
+
+int
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);
-
- return 0;
+ meta_priv_t *priv = NULL;
+
+ priv = GF_CALLOC (sizeof(*priv), 1, gf_meta_mt_priv_t);
+ if (!priv)
+ return -1;
+
+ GF_OPTION_INIT ("meta-dir-name", priv->meta_dir_name, str, out);
+
+ this->private = priv;
+out:
+ return 0;
}
-int32_t
+
+int
fini (xlator_t *this)
{
- return 0;
+ return 0;
}
+
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,
+ .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
+};
+
+
+struct xlator_cbks cbks = {
+ .forget = meta_forget,
+ .release = meta_release,
+ .releasedir = meta_releasedir,
+};
+
+
+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} },
};
diff --git a/xlators/meta/src/meta.h b/xlators/meta/src/meta.h
index 73e0e50db57..f6ec8cb9cb7 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
@@ -15,24 +15,111 @@
#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 "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);
+ 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/plugins/active-link.c b/xlators/meta/src/plugins/active-link.c
new file mode 100644
index 00000000000..99d38597bdf
--- /dev/null
+++ b/xlators/meta/src/plugins/active-link.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.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "xlator.h"
+#include "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/plugins/cmdline-file.c b/xlators/meta/src/plugins/cmdline-file.c
new file mode 100644
index 00000000000..1eded6d19b8
--- /dev/null
+++ b/xlators/meta/src/plugins/cmdline-file.c
@@ -0,0 +1,47 @@
+/*
+ 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 _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "xlator.h"
+#include "defaults.h"
+
+#include "meta-mem-types.h"
+#include "meta.h"
+#include "strfd.h"
+#include "globals.h"
+#include "lkowner.h"
+
+
+static int
+cmdline_file_fill (xlator_t *this, inode_t *file, strfd_t *strfd)
+{
+ if (this->ctx->cmdlinestr)
+ strprintf (strfd, "%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/plugins/frames-file.c b/xlators/meta/src/plugins/frames-file.c
new file mode 100644
index 00000000000..0c3b9a2eb71
--- /dev/null
+++ b/xlators/meta/src/plugins/frames-file.c
@@ -0,0 +1,96 @@
+/*
+ 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 _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "xlator.h"
+#include "defaults.h"
+
+#include "meta-mem-types.h"
+#include "meta.h"
+#include "strfd.h"
+#include "globals.h"
+#include "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 = 0;
+
+ pool = this->ctx->pool;
+
+ LOCK (&pool->lock);
+ {
+ strprintf (strfd, "Call_Count: %d\n", (int)pool->cnt);
+
+ list_for_each_entry (stack, &pool->all_frames, all_frames) {
+ strprintf (strfd, "== Stack %d ==\n", i++);
+ strprintf (strfd, "Unique: %"PRId64"\n", stack->unique);
+ strprintf (strfd, "Type: %s\n", gf_fop_list[stack->op]);
+ strprintf (strfd, "UID: %d\n", stack->uid);
+ strprintf (strfd, "GID: %d\n", stack->gid);
+ strprintf (strfd, "LK_owner: %s\n",
+ lkowner_utoa (&stack->lk_owner));
+
+ j = 0;
+ for (frame = &stack->frames; frame; frame = frame->next) {
+ strprintf (strfd, "\t-- Frame %d --\n", j++);
+ strprintf (strfd, "\tXlator: %s\n", frame->this->name);
+ if (frame->begin.tv_sec)
+ strprintf (strfd, "\tCreation_time: %d.%d\n",
+ (int)frame->begin.tv_sec,
+ (int)frame->begin.tv_usec);
+ strprintf (strfd, "\tRefcount: %d\n", frame->ref_count);
+ strprintf (strfd, "\tComplete: %d\n", frame->complete);
+ if (frame->parent)
+ strprintf (strfd, "\tParent: %s\n",
+ frame->parent->this->name);
+ if (frame->wind_from)
+ strprintf (strfd, "\tWind_from: %s\n",
+ frame->wind_from);
+ if (frame->wind_to)
+ strprintf (strfd, "\tWind_to: %s\n",
+ frame->wind_to);
+ if (frame->unwind_from)
+ strprintf (strfd, "\tUnwind_from: %s\n",
+ frame->unwind_from);
+ if (frame->unwind_to)
+ strprintf (strfd, "\tUnwind_to: %s\n",
+ frame->unwind_to);
+ }
+ }
+ }
+ 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/plugins/graph-dir.c b/xlators/meta/src/plugins/graph-dir.c
new file mode 100644
index 00000000000..3cd6b482e74
--- /dev/null
+++ b/xlators/meta/src/plugins/graph-dir.c
@@ -0,0 +1,106 @@
+/*
+ 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 _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "xlator.h"
+#include "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_CALLOC (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/plugins/graphs-dir.c b/xlators/meta/src/plugins/graphs-dir.c
new file mode 100644
index 00000000000..4a538fb6176
--- /dev/null
+++ b/xlators/meta/src/plugins/graphs-dir.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.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "xlator.h"
+#include "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/plugins/logfile-link.c b/xlators/meta/src/plugins/logfile-link.c
new file mode 100644
index 00000000000..435cab80c33
--- /dev/null
+++ b/xlators/meta/src/plugins/logfile-link.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.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "xlator.h"
+#include "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/plugins/logging-dir.c b/xlators/meta/src/plugins/logging-dir.c
new file mode 100644
index 00000000000..783d38e8e12
--- /dev/null
+++ b/xlators/meta/src/plugins/logging-dir.c
@@ -0,0 +1,51 @@
+/*
+ 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 _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "xlator.h"
+#include "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/plugins/loglevel-file.c b/xlators/meta/src/plugins/loglevel-file.c
new file mode 100644
index 00000000000..24ac68ddc69
--- /dev/null
+++ b/xlators/meta/src/plugins/loglevel-file.c
@@ -0,0 +1,93 @@
+/*
+ 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 _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "xlator.h"
+#include "defaults.h"
+
+#include "meta-mem-types.h"
+#include "meta.h"
+#include "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_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)
+{
+ struct iatt dummy = { };
+ 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 (level);
+
+ META_STACK_UNWIND (writev, frame, iov_length (iov, count), 0,
+ &dummy, &dummy, xdata);
+ return 0;
+}
+
+
+int
+loglevel_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
+loglevel_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;
+}
+
+static struct meta_ops loglevel_file_ops = {
+ .file_fill = loglevel_file_fill,
+ .fops = {
+ .truncate = loglevel_truncate,
+ .ftruncate = loglevel_ftruncate,
+ .writev = loglevel_writev
+ }
+};
+
+
+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/plugins/name-file.c b/xlators/meta/src/plugins/name-file.c
new file mode 100644
index 00000000000..8ddd42945d7
--- /dev/null
+++ b/xlators/meta/src/plugins/name-file.c
@@ -0,0 +1,53 @@
+/*
+ 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 _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "xlator.h"
+#include "defaults.h"
+
+#include "meta-mem-types.h"
+#include "meta.h"
+#include "strfd.h"
+#include "globals.h"
+#include "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/plugins/option-file.c b/xlators/meta/src/plugins/option-file.c
new file mode 100644
index 00000000000..4f9067e1490
--- /dev/null
+++ b/xlators/meta/src/plugins/option-file.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.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "xlator.h"
+#include "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/plugins/options-dir.c b/xlators/meta/src/plugins/options-dir.c
new file mode 100644
index 00000000000..229d365a9c7
--- /dev/null
+++ b/xlators/meta/src/plugins/options-dir.c
@@ -0,0 +1,76 @@
+/*
+ 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 _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "xlator.h"
+#include "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/plugins/process_uuid-file.c b/xlators/meta/src/plugins/process_uuid-file.c
new file mode 100644
index 00000000000..c16ceaac150
--- /dev/null
+++ b/xlators/meta/src/plugins/process_uuid-file.c
@@ -0,0 +1,46 @@
+/*
+ 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 _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "xlator.h"
+#include "defaults.h"
+
+#include "meta-mem-types.h"
+#include "meta.h"
+#include "strfd.h"
+#include "globals.h"
+#include "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/plugins/root-dir.c b/xlators/meta/src/plugins/root-dir.c
new file mode 100644
index 00000000000..bd6870b21d7
--- /dev/null
+++ b/xlators/meta/src/plugins/root-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.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "xlator.h"
+#include "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 = 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/plugins/subvolume-link.c b/xlators/meta/src/plugins/subvolume-link.c
new file mode 100644
index 00000000000..ca71a751541
--- /dev/null
+++ b/xlators/meta/src/plugins/subvolume-link.c
@@ -0,0 +1,66 @@
+/*
+ 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 _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "xlator.h"
+#include "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/plugins/subvolumes-dir.c b/xlators/meta/src/plugins/subvolumes-dir.c
new file mode 100644
index 00000000000..f8d0e8039a1
--- /dev/null
+++ b/xlators/meta/src/plugins/subvolumes-dir.c
@@ -0,0 +1,72 @@
+/*
+ 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 _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "xlator.h"
+#include "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_CALLOC (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/plugins/top-link.c b/xlators/meta/src/plugins/top-link.c
new file mode 100644
index 00000000000..94b7f7a9f56
--- /dev/null
+++ b/xlators/meta/src/plugins/top-link.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.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "xlator.h"
+#include "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/plugins/type-file.c b/xlators/meta/src/plugins/type-file.c
new file mode 100644
index 00000000000..1970f4e33e8
--- /dev/null
+++ b/xlators/meta/src/plugins/type-file.c
@@ -0,0 +1,53 @@
+/*
+ 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 _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "xlator.h"
+#include "defaults.h"
+
+#include "meta-mem-types.h"
+#include "meta.h"
+#include "strfd.h"
+#include "globals.h"
+#include "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/plugins/version-file.c b/xlators/meta/src/plugins/version-file.c
new file mode 100644
index 00000000000..77f2dea3d66
--- /dev/null
+++ b/xlators/meta/src/plugins/version-file.c
@@ -0,0 +1,46 @@
+/*
+ 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 _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "xlator.h"
+#include "defaults.h"
+
+#include "meta-mem-types.h"
+#include "meta.h"
+#include "strfd.h"
+#include "globals.h"
+#include "lkowner.h"
+
+
+static int
+version_file_fill (xlator_t *this, inode_t *file, strfd_t *strfd)
+{
+ strprintf (strfd, "%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/plugins/view-dir.c b/xlators/meta/src/plugins/view-dir.c
new file mode 100644
index 00000000000..6edd455b072
--- /dev/null
+++ b/xlators/meta/src/plugins/view-dir.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.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "xlator.h"
+#include "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/plugins/volfile-file.c b/xlators/meta/src/plugins/volfile-file.c
new file mode 100644
index 00000000000..899285763e0
--- /dev/null
+++ b/xlators/meta/src/plugins/volfile-file.c
@@ -0,0 +1,91 @@
+/*
+ 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 _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "xlator.h"
+#include "defaults.h"
+
+#include "meta-mem-types.h"
+#include "meta.h"
+#include "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/plugins/xlator-dir.c b/xlators/meta/src/plugins/xlator-dir.c
new file mode 100644
index 00000000000..279df385cef
--- /dev/null
+++ b/xlators/meta/src/plugins/xlator-dir.c
@@ -0,0 +1,72 @@
+/*
+ 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 _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "xlator.h"
+#include "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 = 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;
+}
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/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__ */