diff options
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 000000000..e1c45f305 --- /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 000000000..385ff553f --- /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 000000000..ce49ed2c4 --- /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 000000000..6823ef85b --- /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 000000000..9c2f50d34 --- /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 000000000..433c604eb --- /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 000000000..ec88c42a0 --- /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 000000000..eb2cf0220 --- /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 000000000..7104d10e9 --- /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 000000000..2e1ac3ebf --- /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__ */ |