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; +}  | 
