diff options
| author | Vikas Gorur <vikas@zresearch.com> | 2009-02-18 17:36:07 +0530 | 
|---|---|---|
| committer | Vikas Gorur <vikas@zresearch.com> | 2009-02-18 17:36:07 +0530 | 
| commit | 77adf4cd648dce41f89469dd185deec6b6b53a0b (patch) | |
| tree | 02e155a5753b398ee572b45793f889b538efab6b /xlators/meta | |
| parent | f3b2e6580e5663292ee113c741343c8a43ee133f (diff) | |
Added all files
Diffstat (limited to 'xlators/meta')
| -rw-r--r-- | xlators/meta/Makefile.am | 1 | ||||
| -rw-r--r-- | xlators/meta/src/Makefile.am | 10 | ||||
| -rw-r--r-- | xlators/meta/src/meta.c | 1285 | ||||
| -rw-r--r-- | xlators/meta/src/meta.h | 48 | ||||
| -rw-r--r-- | xlators/meta/src/misc.c | 67 | ||||
| -rw-r--r-- | xlators/meta/src/misc.h | 31 | ||||
| -rw-r--r-- | xlators/meta/src/tree.c | 176 | ||||
| -rw-r--r-- | xlators/meta/src/tree.h | 35 | ||||
| -rw-r--r-- | xlators/meta/src/view.c | 258 | ||||
| -rw-r--r-- | xlators/meta/src/view.h | 32 | 
10 files changed, 1943 insertions, 0 deletions
diff --git a/xlators/meta/Makefile.am b/xlators/meta/Makefile.am new file mode 100644 index 00000000000..e1c45f3051c --- /dev/null +++ b/xlators/meta/Makefile.am @@ -0,0 +1 @@ +SUBDIRS=src
\ No newline at end of file diff --git a/xlators/meta/src/Makefile.am b/xlators/meta/src/Makefile.am new file mode 100644 index 00000000000..385ff553f59 --- /dev/null +++ b/xlators/meta/src/Makefile.am @@ -0,0 +1,10 @@ +xlator_PROGRAMS = meta.so +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 + +AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall \ +	-I$(top_srcdir)/libglusterfs/src -shared -nostartfiles + +CLEANFILES =  diff --git a/xlators/meta/src/meta.c b/xlators/meta/src/meta.c new file mode 100644 index 00000000000..ce49ed2c459 --- /dev/null +++ b/xlators/meta/src/meta.c @@ -0,0 +1,1285 @@ +/* +   Copyright (c) 2006, 2007, 2008 Z RESEARCH, Inc. <http://www.zresearch.com> +   This file is part of GlusterFS. + +   GlusterFS is free software; you can redistribute it and/or modify +   it under the terms of the GNU General Public License as published +   by the Free Software Foundation; either version 3 of the License, +   or (at your option) any later version. + +   GlusterFS is distributed in the hope that it will be useful, but +   WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   General Public License for more details. + +   You should have received a copy of the GNU General Public License +   along with this program.  If not, see +   <http://www.gnu.org/licenses/>. +*/ + +#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 "meta.h" +#include "view.h" + +int32_t +meta_getattr_cbk (call_frame_t *frame, +		  void *cookie, +		  xlator_t *this, +		  int32_t op_ret, +		  int32_t op_errno, +		  struct stat *buf) +{ +  STACK_UNWIND (frame, op_ret, op_errno, buf); +  return 0; +} + +int32_t +meta_getattr (call_frame_t *frame, +	      xlator_t *this, +	      const char *path) +{ +  meta_private_t *priv = (meta_private_t *) this->private; +  meta_dirent_t *root = priv->tree; +  meta_dirent_t *file = lookup_meta_entry (root, path, NULL); +   +  if (file) { +    if (file->fops && file->fops->getattr) { +      STACK_WIND (frame, meta_getattr_cbk, +		  this, file->fops->getattr, path); +      return 0; +    } +    else { +      STACK_UNWIND (frame, 0, 0, file->stbuf); +      return 0; +    } +  } +  else { +    STACK_WIND (frame, meta_getattr_cbk, +	      FIRST_CHILD(this), +	      FIRST_CHILD(this)->fops->getattr, +	      path); +    return 0; +  } +} + +int32_t +meta_chmod_cbk (call_frame_t *frame, +		void *cookie, +		xlator_t *this, +		int32_t op_ret, +		int32_t op_errno, +		struct stat *buf) +{ +  STACK_UNWIND (frame, +		op_ret, +		op_errno, +		buf); +  return 0; +} + +int32_t +meta_chmod (call_frame_t *frame, +	    xlator_t *this, +	    const char *path, +	    mode_t mode) +{ +  STACK_WIND (frame, +	      meta_chmod_cbk, +	      FIRST_CHILD(this), +	      FIRST_CHILD(this)->fops->chmod, +	      path, +	      mode); +  return 0; +} + +int32_t +meta_chown_cbk (call_frame_t *frame, +		void *cookie, +		xlator_t *this, +		int32_t op_ret, +		int32_t op_errno, +		struct stat *buf) +{ +  STACK_UNWIND (frame, +		op_ret, +		op_errno, +		buf); +  return 0; +} + +int32_t +meta_chown (call_frame_t *frame, +	    xlator_t *this, +	    const char *path, +	    uid_t uid, +	    gid_t gid) +{ +  STACK_WIND (frame,	       +	      meta_chown_cbk, +	      FIRST_CHILD(this), +	      FIRST_CHILD(this)->fops->chown, +	      path, +	      uid, +	      gid); +  return 0; +} + + +int32_t +meta_truncate_cbk (call_frame_t *frame, +		   void *cookie, +		   xlator_t *this, +		   int32_t op_ret, +		   int32_t op_errno, +		   struct stat *buf) +{ +  STACK_UNWIND (frame, +		op_ret, +		op_errno, +		buf); +  return 0; +} + +int32_t +meta_truncate (call_frame_t *frame, +	       xlator_t *this, +	       const char *path, +	       off_t offset) +{ +  STACK_WIND (frame, +	      meta_truncate_cbk, +	      FIRST_CHILD(this), +	      FIRST_CHILD(this)->fops->truncate, +	      path, +	      offset); +  return 0; +} + + +int32_t +meta_ftruncate_cbk (call_frame_t *frame, +		    void *cookie, +		    xlator_t *this, +		    int32_t op_ret, +		    int32_t op_errno, +		    struct stat *buf) +{ +  STACK_UNWIND (frame, +		op_ret, +		op_errno, +		buf); +  return 0; +} + +int32_t +meta_ftruncate (call_frame_t *frame, +		xlator_t *this, +		dict_t *fd, +		off_t offset) +{ +  STACK_WIND (frame, +	      meta_ftruncate_cbk, +	      FIRST_CHILD(this), +	      FIRST_CHILD(this)->fops->ftruncate, +	      fd, +	      offset); +  return 0; +} + + +int32_t +meta_utimes_cbk (call_frame_t *frame, +		 void *cookie, +		 xlator_t *this, +		 int32_t op_ret, +		 int32_t op_errno, +		 struct stat *buf) +{ +  STACK_UNWIND (frame, +		op_ret, +		op_errno, +		buf); +  return 0; +} + +int32_t +meta_utimes (call_frame_t *frame, +	     xlator_t *this, +	     const char *path, +	     struct timespec *buf) +{ +  STACK_WIND (frame, +	      meta_utimes_cbk, +	      FIRST_CHILD(this), +	      FIRST_CHILD(this)->fops->utimes, +	      path, +	      buf); +  return 0; +} + + +int32_t +meta_access_cbk (call_frame_t *frame, +		 void *cookie, +		 xlator_t *this, +		 int32_t op_ret, +		 int32_t op_errno) +{ +  STACK_UNWIND (frame, +		op_ret, +		op_errno); +  return 0; +} + +int32_t +meta_access (call_frame_t *frame, +	     xlator_t *this, +	     const char *path, +	     mode_t mode) +{ +  STACK_WIND (frame, +	      meta_access_cbk, +	      FIRST_CHILD(this), +	      FIRST_CHILD(this)->fops->access, +	      path, +	      mode); +  return 0; +} + +int32_t +meta_readlink_cbk (call_frame_t *frame, +		   void *cookie, +		   xlator_t *this, +		   int32_t op_ret, +		   int32_t op_errno, +		   char *dest) +{ +  STACK_UNWIND (frame, +		op_ret, +		op_errno, +		dest); +  return 0; +} + +int32_t +meta_readlink (call_frame_t *frame, +	       xlator_t *this, +	       const char *path, +	       size_t size) +{ +  STACK_WIND (frame, +	      meta_readlink_cbk, +	      FIRST_CHILD(this), +	      FIRST_CHILD(this)->fops->readlink, +	      path, +	      size); +  return 0; +} + +int32_t +meta_mknod_cbk (call_frame_t *frame, +		void *cookie, +		xlator_t *this, +		int32_t op_ret, +		int32_t op_errno, +		struct stat *buf) +{ +  STACK_UNWIND (frame, +		op_ret, +		op_errno, +		buf); +  return 0; +} + +int32_t +meta_mknod (call_frame_t *frame, +	    xlator_t *this, +	    const char *path, +	    mode_t mode, +	    dev_t dev) +{ +  STACK_WIND (frame, +	      meta_mknod_cbk, +	      FIRST_CHILD(this), +	      FIRST_CHILD(this)->fops->mknod, +	      path, +	      mode, +	      dev); +  return 0; +} + +int32_t +meta_mkdir_cbk (call_frame_t *frame, +		void *cookie, +		xlator_t *this, +		int32_t op_ret, +		int32_t op_errno, +		struct stat *buf) +{ +  STACK_UNWIND (frame, +		op_ret, +		op_errno, +		buf); +  return 0; +} + +int32_t +meta_mkdir (call_frame_t *frame, +	    xlator_t *this, +	    const char *path, +	    mode_t mode) +{ +  STACK_WIND (frame, +	      meta_mkdir_cbk, +	      FIRST_CHILD(this), +	      FIRST_CHILD(this)->fops->mkdir, +	      path, +	      mode); +  return 0; +} + +int32_t +meta_unlink_cbk (call_frame_t *frame, +		 void *cookie, +		 xlator_t *this, +		 int32_t op_ret, +		 int32_t op_errno) +{ +  STACK_UNWIND (frame, +		op_ret, +		op_errno); +  return 0; +} + +int32_t +meta_unlink (call_frame_t *frame, +	     xlator_t *this, +	     const char *path) +{ +  STACK_WIND (frame, +	      meta_unlink_cbk, +	      FIRST_CHILD(this), +	      FIRST_CHILD(this)->fops->unlink, +	      path); +  return 0; +} + +int32_t +meta_rmdir_cbk (call_frame_t *frame, +		void *cookie, +		xlator_t *this, +		int32_t op_ret, +		int32_t op_errno) +{ +  STACK_UNWIND (frame, +		op_ret, +		op_errno); +  return 0; +} + +int32_t +meta_rmdir (call_frame_t *frame, +	    xlator_t *this, +	    const char *path) +{ +  STACK_WIND (frame, +	      meta_rmdir_cbk, +	      FIRST_CHILD(this), +	      FIRST_CHILD(this)->fops->rmdir, +	      path); +  return 0; +} + +int32_t +meta_symlink_cbk (call_frame_t *frame, +		  void *cookie, +		  xlator_t *this, +		  int32_t op_ret, +		  int32_t op_errno, +		  struct stat *buf) +{ +  STACK_UNWIND (frame, +		op_ret, +		op_errno, +		buf); +  return 0; +} + +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) +{ +  STACK_UNWIND (frame, +		op_ret, +		op_errno); +  return 0; +} + +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; +} + +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) +{ +  STACK_WIND (frame, +	      meta_link_cbk, +	      FIRST_CHILD(this), +	      FIRST_CHILD(this)->fops->link, +	      oldpath, +	      newpath); +  return 0; +} + +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 = CALLOC (1, sizeof (struct _open_local)); +      ERR_ABORT (local); +      local->path = 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 (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 = CALLOC (1, sizeof (struct _open_local)); +      ERR_ABORT (local); +      local->path = strdup (path); +      frame->local = local; +      STACK_WIND (frame, meta_open_cbk, +		  this, file->fops->create, +		  path, flags, mode); +      return 0; +    } +    else { +      STACK_UNWIND (frame, -1, 0, NULL, NULL); +      return 0; +    } +  } +  else { +    STACK_WIND (frame, meta_open_cbk, +		FIRST_CHILD(this), FIRST_CHILD(this)->fops->create, +		path, flags, mode); +    return 0; +  } +} + +int32_t +meta_readv_cbk (call_frame_t *frame, +		void *cookie, +		xlator_t *this, +		int32_t op_ret, +		int32_t op_errno, +		struct iovec *vector, +		int32_t count) +{ +  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) +{ +  meta_private_t *priv = (meta_private_t *) this->private; +  meta_dirent_t *root = priv->tree; +  data_t *path_data = dict_get (fd, this->name); + +  if (path_data) { +    const char *path = data_to_str (path_data); +    meta_dirent_t *file = lookup_meta_entry (root, path, NULL); +   +    if (file && file->fops && file->fops->readv) { +      STACK_WIND (frame, meta_readv_cbk,  +		  this, file->fops->readv, +		  fd, size, offset); +      return 0; +    } +  } +  else { +    STACK_WIND (frame, meta_readv_cbk, +		FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv, +		fd, size, offset); +    return 0; +  } +} + +int32_t +meta_writev_cbk (call_frame_t *frame, void *cookie, +		 xlator_t *this, int32_t op_ret, +		 int32_t op_errno) +{ +  STACK_UNWIND (frame, op_ret, op_errno); +  return 0; +} + +int32_t +meta_writev (call_frame_t *frame, xlator_t *this, +	     dict_t *fd,  +	     struct iovec *vector, int32_t count, off_t offset) +{ +  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) +{ +  STACK_UNWIND (frame, +		op_ret, +		op_errno); +  return 0; +} + +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) +{ +  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; +  } +} + +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; +} + +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) +{ +  STACK_UNWIND (frame, +		op_ret, +		op_errno, +		buf); +  return 0; +} + +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; +} + +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) +{ +  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 (strdup (path))); +    STACK_UNWIND (frame, 0, 0, ctx); +    return 0; +  } +  else {   +    STACK_WIND (frame, meta_opendir_cbk, +		FIRST_CHILD(this), FIRST_CHILD(this)->fops->opendir, +		path); +    return 0; +  } +} + +int32_t +meta_readdir_cbk (call_frame_t *frame, +		  void *cookie, +		  xlator_t *this, +		  int32_t op_ret, +		  int32_t op_errno, +		  dir_entry_t *entries, +		  int32_t count) +{ +  meta_private_t *priv = (meta_private_t *)this->private; + +  if ((int) cookie == 1) { +    dir_entry_t *dir = CALLOC (1, sizeof (dir_entry_t)); +    ERR_ABORT (dir); + +    dir->name = 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; +} + +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 = CALLOC (1, sizeof (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 = CALLOC (1, sizeof (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) +{ +  STACK_UNWIND (frame, +		op_ret, +		op_errno); +  return 0; +} + +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; +} + +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) +{ +  STACK_WIND (frame, +	      meta_statfs_cbk, +	      FIRST_CHILD(this), +	      FIRST_CHILD(this)->fops->statfs, +	      path); +  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) +{ +  STACK_WIND (frame, +	      meta_setxattr_cbk, +	      FIRST_CHILD(this), +	      FIRST_CHILD(this)->fops->setxattr, +	      path, +	      name, +	      value, +	      size, +	      flags); +  return 0; +} + +int32_t +meta_getxattr_cbk (call_frame_t *frame, +		   void *cookie, +		   xlator_t *this, +		   int32_t op_ret, +		   int32_t op_errno, +		   char *value) +{ +  STACK_UNWIND (frame, +		op_ret, +		op_errno, +		value); +  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) +{ +  STACK_UNWIND (frame, +		op_ret, +		op_errno, +		value); +  return 0; +} + +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; +} + +int32_t +meta_removexattr_cbk (call_frame_t *frame, +		      void *cookie, +		      xlator_t *this, +		      int32_t op_ret, +		      int32_t op_errno) +{ +  STACK_UNWIND (frame, +		op_ret, +		op_errno); +  return 0; +} + +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 flock *lock) +{ +  STACK_UNWIND (frame, +		op_ret, +		op_errno, +		lock); +  return 0; +} + +int32_t +meta_lk (call_frame_t *frame, +	 xlator_t *this, +	 dict_t *file, +	 int32_t cmd, +	 struct 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) +{ +  char *dir; +  asprintf (&dir, "%s/%s", prefix, this->name); + +  char *children; +  asprintf (&children, "%s/%s", dir, "subvolumes"); + +  char *type; +  asprintf (&type, "%s/%s", dir, "type"); + +  char *view; +  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; +  } +} + +static void +build_meta_tree (xlator_t *this) +{ +  meta_private_t *priv = (meta_private_t *) this->private; +  priv->tree = CALLOC (1, sizeof (meta_dirent_t)); +  ERR_ABORT (priv->tree); +  priv->tree->name = 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 +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 = CALLOC (1, sizeof (meta_private_t)); +  ERR_ABORT (priv); +   +  data_t *directory = dict_get (this->options, "directory"); +  if (directory) { +    priv->directory = strdup (data_to_str (directory)); +  } +  else { +    priv->directory = ".meta"; +  } +   +  this->private = priv; +  build_meta_tree (this); + +  return 0; +} + +int32_t +fini (xlator_t *this) +{ +  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, +}; + +struct xlator_mops mops = { +}; diff --git a/xlators/meta/src/meta.h b/xlators/meta/src/meta.h new file mode 100644 index 00000000000..6823ef85bee --- /dev/null +++ b/xlators/meta/src/meta.h @@ -0,0 +1,48 @@ +/* +   Copyright (c) 2006, 2007, 2008 Z RESEARCH, Inc. <http://www.zresearch.com> +   This file is part of GlusterFS. + +   GlusterFS is free software; you can redistribute it and/or modify +   it under the terms of the GNU General Public License as published +   by the Free Software Foundation; either version 3 of the License, +   or (at your option) any later version. + +   GlusterFS is distributed in the hope that it will be useful, but +   WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   General Public License for more details. + +   You should have received a copy of the GNU General Public License +   along with this program.  If not, see +   <http://www.gnu.org/licenses/>. +*/ + +#ifndef __META_H__ +#define __META_H__ + +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif + +struct _meta_dirent { +  const char *name; +  int type; +  struct _meta_dirent *children; +  struct _meta_dirent *parent; +  struct _meta_dirent *next; +  struct stat *stbuf; +  xlator_t *view_xlator; +  struct xlator_fops *fops; +}; +typedef struct _meta_dirent meta_dirent_t; + +typedef struct { +  const char *directory; +  meta_dirent_t *tree; +} meta_private_t; + +#include "tree.h" +#include "misc.h" + +#endif /* __META_H__ */ diff --git a/xlators/meta/src/misc.c b/xlators/meta/src/misc.c new file mode 100644 index 00000000000..9c2f50d3426 --- /dev/null +++ b/xlators/meta/src/misc.c @@ -0,0 +1,67 @@ +/* +   Copyright (c) 2006, 2007, 2008 Z RESEARCH, Inc. <http://www.zresearch.com> +   This file is part of GlusterFS. + +   GlusterFS is free software; you can redistribute it and/or modify +   it under the terms of the GNU General Public License as published +   by the Free Software Foundation; either version 3 of the License, +   or (at your option) any later version. + +   GlusterFS is distributed in the hope that it will be useful, but +   WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   General Public License for more details. + +   You should have received a copy of the GNU General Public License +   along with this program.  If not, see +   <http://www.gnu.org/licenses/>. +*/ + +#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 new file mode 100644 index 00000000000..433c604ebc3 --- /dev/null +++ b/xlators/meta/src/misc.h @@ -0,0 +1,31 @@ +/* +   Copyright (c) 2006, 2007, 2008 Z RESEARCH, Inc. <http://www.zresearch.com> +   This file is part of GlusterFS. + +   GlusterFS is free software; you can redistribute it and/or modify +   it under the terms of the GNU General Public License as published +   by the Free Software Foundation; either version 3 of the License, +   or (at your option) any later version. + +   GlusterFS is distributed in the hope that it will be useful, but +   WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   General Public License for more details. + +   You should have received a copy of the GNU General Public License +   along with this program.  If not, see +   <http://www.gnu.org/licenses/>. +*/ + +#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/tree.c b/xlators/meta/src/tree.c new file mode 100644 index 00000000000..ec88c42a084 --- /dev/null +++ b/xlators/meta/src/tree.c @@ -0,0 +1,176 @@ +/* +   Copyright (c) 2006, 2007, 2008 Z RESEARCH, Inc. <http://www.zresearch.com> +   This file is part of GlusterFS. + +   GlusterFS is free software; you can redistribute it and/or modify +   it under the terms of the GNU General Public License as published +   by the Free Software Foundation; either version 3 of the License, +   or (at your option) any later version. + +   GlusterFS is distributed in the hope that it will be useful, but +   WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   General Public License for more details. + +   You should have received a copy of the GNU General Public License +   along with this program.  If not, see +   <http://www.gnu.org/licenses/>. +*/ + +#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" + +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 = CALLOC (1, sizeof (struct 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 = 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) +	    asprintf (remain, "/%s/%s", *remain, piece); +	  else +	    asprintf (remain, "/%s", piece); +	  if (tmp) free (tmp); +	  piece = strtok (NULL, "/"); +	} +      } +      return trav; +    } +    dir = strtok (NULL, "/"); +    trav = ntrav; +  } + +  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 = CALLOC (1, sizeof (meta_dirent_t)); +  ERR_ABORT (new); +  new->name        = 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 = CALLOC (1, sizeof (meta_dirent_t)); +  ERR_ABORT (root); +  root->name = 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 new file mode 100644 index 00000000000..eb2cf0220ff --- /dev/null +++ b/xlators/meta/src/tree.h @@ -0,0 +1,35 @@ +/* +   Copyright (c) 2006, 2007, 2008 Z RESEARCH, Inc. <http://www.zresearch.com> +   This file is part of GlusterFS. + +   GlusterFS is free software; you can redistribute it and/or modify +   it under the terms of the GNU General Public License as published +   by the Free Software Foundation; either version 3 of the License, +   or (at your option) any later version. + +   GlusterFS is distributed in the hope that it will be useful, but +   WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   General Public License for more details. + +   You should have received a copy of the GNU General Public License +   along with this program.  If not, see +   <http://www.gnu.org/licenses/>. +*/ + +#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 new file mode 100644 index 00000000000..7104d10e912 --- /dev/null +++ b/xlators/meta/src/view.c @@ -0,0 +1,258 @@ +/* +   Copyright (c) 2006, 2007, 2008 Z RESEARCH, Inc. <http://www.zresearch.com> +   This file is part of GlusterFS. + +   GlusterFS is free software; you can redistribute it and/or modify +   it under the terms of the GNU General Public License as published +   by the Free Software Foundation; either version 3 of the License, +   or (at your option) any later version. + +   GlusterFS is distributed in the hope that it will be useful, but +   WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   General Public License for more details. + +   You should have received a copy of the GNU General Public License +   along with this program.  If not, see +   <http://www.gnu.org/licenses/>. +*/ + +#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 new file mode 100644 index 00000000000..2e1ac3ebf44 --- /dev/null +++ b/xlators/meta/src/view.h @@ -0,0 +1,32 @@ +/* +   Copyright (c) 2006, 2007, 2008 Z RESEARCH, Inc. <http://www.zresearch.com> +   This file is part of GlusterFS. + +   GlusterFS is free software; you can redistribute it and/or modify +   it under the terms of the GNU General Public License as published +   by the Free Software Foundation; either version 3 of the License, +   or (at your option) any later version. + +   GlusterFS is distributed in the hope that it will be useful, but +   WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   General Public License for more details. + +   You should have received a copy of the GNU General Public License +   along with this program.  If not, see +   <http://www.gnu.org/licenses/>. +*/ + +#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__ */  | 
