diff options
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__ */  | 
