diff options
author | Anand Avati <avati@redhat.com> | 2014-03-26 11:52:53 -0700 |
---|---|---|
committer | Anand Avati <avati@redhat.com> | 2014-05-05 17:28:55 -0700 |
commit | 8160399a36eff62a49a066f16dea9140d877c5e8 (patch) | |
tree | e51d49bd93ff98822986569fdfada5d2819546b0 /xlators/meta/src/meta-helpers.c | |
parent | 7fba3a88f1ced610eca0c23516a1e720d75160cd (diff) |
meta: (re-)Implement Meta translator
The meta translator exposes details about glusterfs itself
in the form of a virtual namespace.
Loading the translator on the client side creates the
meta virtual view under $mntpoint/.meta by default. The
directory is not listed (even with ls -a) and can be
accessed by doing a "cd /mnt/.meta"
Change-Id: I5ffdf39203841a9562a8280a1f79dc76d4dded5d
BUG: 1089216
Signed-off-by: Anand Avati <avati@redhat.com>
Reviewed-on: http://review.gluster.org/7509
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Harshavardhana <harsha@harshavardhana.net>
Diffstat (limited to 'xlators/meta/src/meta-helpers.c')
-rw-r--r-- | xlators/meta/src/meta-helpers.c | 370 |
1 files changed, 370 insertions, 0 deletions
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; +} |