diff options
author | Anand Avati <avati@redhat.com> | 2014-03-26 11:52:53 -0700 |
---|---|---|
committer | Anand Avati <avati@redhat.com> | 2014-05-05 17:28:55 -0700 |
commit | 8160399a36eff62a49a066f16dea9140d877c5e8 (patch) | |
tree | e51d49bd93ff98822986569fdfada5d2819546b0 | |
parent | 7fba3a88f1ced610eca0c23516a1e720d75160cd (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>
41 files changed, 2731 insertions, 1745 deletions
diff --git a/configure.ac b/configure.ac index e032e8f311c..69fa0a71d71 100644 --- a/configure.ac +++ b/configure.ac @@ -52,6 +52,8 @@ AC_CONFIG_FILES([Makefile rpc/xdr/Makefile rpc/xdr/src/Makefile xlators/Makefile + xlators/meta/Makefile + xlators/meta/src/Makefile xlators/mount/Makefile xlators/mount/fuse/Makefile xlators/mount/fuse/src/Makefile diff --git a/glusterfsd/src/glusterfsd.c b/glusterfsd/src/glusterfsd.c index 1163660a1a5..79e6e593a53 100644 --- a/glusterfsd/src/glusterfsd.c +++ b/glusterfsd/src/glusterfsd.c @@ -1996,6 +1996,8 @@ main (int argc, char *argv[]) } gf_msg (argv[0], GF_LOG_INFO, 0, glusterfsd_msg_30, argv[0], PACKAGE_VERSION, cmdlinestr); + + ctx->cmdlinestr = gf_strdup (cmdlinestr); } gf_proc_dump_init(); diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h index 70df63eebbc..93d7260cbe9 100644 --- a/libglusterfs/src/glusterfs.h +++ b/libglusterfs/src/glusterfs.h @@ -453,6 +453,7 @@ struct _glusterfs_ctx { void *listener; /* listener of the commands from glusterd */ unsigned char measure_latency; /* toggle switch for latency measurement */ pthread_t sigwaiter; + char *cmdlinestr; struct mem_pool *stub_mem_pool; unsigned char cleanup_started; int graph_id; /* Incremented per graph, value should diff --git a/libglusterfs/src/graph.c b/libglusterfs/src/graph.c index b4eddd826f6..52e79ab68cd 100644 --- a/libglusterfs/src/graph.c +++ b/libglusterfs/src/graph.c @@ -196,6 +196,21 @@ glusterfs_graph_worm (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx) return ret; } + +int +glusterfs_graph_meta (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx) +{ + int ret = 0; + + if (!ctx->master) + return 0; + + ret = glusterfs_graph_insert (graph, ctx, "meta", + "meta-autoload", 1); + return ret; +} + + int glusterfs_graph_mac_compat (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx) { @@ -464,6 +479,14 @@ glusterfs_graph_prepare (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx) return -1; } + /* XXX: topmost xlator */ + ret = glusterfs_graph_meta (graph, ctx); + if (ret) { + gf_log ("graph", GF_LOG_ERROR, + "glusterfs graph meta failed"); + return -1; + } + /* XXX: this->ctx setting */ for (trav = graph->first; trav; trav = trav->next) { trav->ctx = ctx; @@ -671,6 +694,8 @@ glusterfs_volfile_reconfigure (int oldvollen, FILE *newvolfile_fp, goto out; } + glusterfs_graph_prepare (newvolfile_graph, ctx); + if (!is_graph_topology_equal (oldvolfile_graph, newvolfile_graph)) { diff --git a/tests/basic/meta.t b/tests/basic/meta.t new file mode 100755 index 00000000000..baea27d3dff --- /dev/null +++ b/tests/basic/meta.t @@ -0,0 +1,40 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc + +cleanup; + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume info; + +TEST $CLI volume create $V0 replica 2 stripe 4 $H0:$B0/${V0}{1..16}; + +EXPECT "$V0" volinfo_field $V0 'Volume Name'; +EXPECT 'Created' volinfo_field $V0 'Status'; + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +TEST glusterfs -s $H0 --volfile-id $V0 $M0; + +# the read() on frames file itself should be visible as a frame +TEST grep -q READ $M0/.meta/frames; + +# default log level (INFO) is 7 +TEST grep -q 7 $M0/.meta/logging/loglevel; + +# check for attribute_timeout exposed through state dump +TEST grep -q attribute_timeout $M0/.meta/master/private; + +# check for mount point specified as an option +TEST grep -q $M0 $M0/.meta/master/options/mountpoint; + +TEST $CLI volume stop $V0; +EXPECT 'Stopped' volinfo_field $V0 'Status'; + +TEST $CLI volume delete $V0; +TEST ! $CLI volume info $V0; + +cleanup; diff --git a/tests/bugs/bug-834465.t b/tests/bugs/bug-834465.t index af7f4bd1240..0913d9dff60 100755 --- a/tests/bugs/bug-834465.t +++ b/tests/bugs/bug-834465.t @@ -20,10 +20,10 @@ TEST glusterfs --mem-accounting --volfile-server=$H0 --volfile-id=$V0 $MOUNTDIR; sdump1=$(generate_mount_statedump $V0); nalloc1=0 -grep -A2 "fuse - usage-type 85" $sdump1 +grep -A3 "fuse - usage-type 85" $sdump1 if [ $? -eq '0' ] then - nalloc1=`grep -A2 "fuse - usage-type 85" $sdump1 | grep num_allocs | cut -d '=' -f2` + nalloc1=`grep -A3 "fuse - usage-type 85" $sdump1 | grep num_allocs | cut -d '=' -f2` fi build_tester $(dirname $0)/bug-834465.c @@ -31,7 +31,7 @@ build_tester $(dirname $0)/bug-834465.c TEST $(dirname $0)/bug-834465 $M0/testfile sdump2=$(generate_mount_statedump $V0); -nalloc2=`grep -A2 "fuse - usage-type 85" $sdump2 | grep num_allocs | cut -d '=' -f2` +nalloc2=`grep -A3 "fuse - usage-type 85" $sdump2 | grep num_allocs | cut -d '=' -f2` TEST [ $nalloc1 -eq $nalloc2 ]; diff --git a/xlators/Makefile.am b/xlators/Makefile.am index f60fa85ce06..2a03f905b6d 100644 --- a/xlators/Makefile.am +++ b/xlators/Makefile.am @@ -1,4 +1,4 @@ SUBDIRS = cluster storage protocol performance debug features encryption mount nfs mgmt system \ - playground + playground meta CLEANFILES = 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__ */ |