/*
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.
*/
#include <glusterfs/xlator.h>
#include <glusterfs/defaults.h>
#include "meta-mem-types.h"
#include "meta.h"
#include "meta-hooks.h"
int
meta_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
{
inode_t *inode = NULL;
if (META_HOOK(loc) || IS_META_ROOT_GFID(loc->gfid)) {
struct iatt iatt = {};
struct iatt parent = {};
meta_root_dir_hook(frame, this, loc, xdata);
meta_iatt_fill(&iatt, loc->inode, IA_IFDIR);
gf_uuid_parse(META_ROOT_GFID, iatt.ia_gfid);
META_STACK_UNWIND(lookup, frame, 0, 0, loc->inode, &iatt, xdata,
&parent);
return 0;
}
if (loc->parent)
inode = loc->parent;
else
inode = loc->inode;
META_FOP(inode, lookup, frame, this, loc, xdata);
return 0;
}
int
meta_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
dict_t *xdata)
{
META_FOP(fd->inode, opendir, frame, this, loc, fd, xdata);
return 0;
}
int
meta_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, fd_t *fd,
dict_t *xdata)
{
META_FOP(fd->inode, open, frame, this, loc, flags, fd, xdata);
return 0;
}
int
meta_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
off_t offset, uint32_t flags, dict_t *xdata)
{
META_FOP(fd->inode, readv, frame, this, fd, size, offset, flags, xdata);
return 0;
}
int
meta_flush(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
{
META_FOP(fd->inode, flush, frame, this, fd, xdata);
return 0;
}
int
meta_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
{
META_FOP(loc->inode, stat, frame, this, loc, xdata);
return 0;
}
int
meta_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
{
META_FOP(fd->inode, fstat, frame, this, fd, xdata);
return 0;
}
int
meta_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
off_t offset, dict_t *xdata)
{
META_FOP(fd->inode, readdir, frame, this, fd, size, offset, xdata);
return 0;
}
int
meta_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
off_t offset, dict_t *xdata)
{
META_FOP(fd->inode, readdirp, frame, this, fd, size, offset, xdata);
return 0;
}
int
meta_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size,
dict_t *xdata)
{
META_FOP(loc->inode, readlink, frame, this, loc, size, xdata);
return 0;
}
int
meta_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *iov,
int count, off_t offset, uint32_t flags, struct iobref *iobref,
dict_t *xdata)
{
META_FOP(fd->inode, writev, frame, this, fd, iov, count, offset, flags,
iobref, xdata);
return 0;
}
int
meta_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
dict_t *xdata)
{
META_FOP(loc->inode, truncate, frame, this, loc, offset, xdata);
return 0;
}
int
meta_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
dict_t *xdata)
{
META_FOP(fd->inode, ftruncate, frame, this, fd, offset, xdata);
return 0;
}
int32_t
meta_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags,
dict_t *xdata)
{
META_FOP(fd->inode, fsync, frame, this, fd, flags, xdata);
return 0;
}
int32_t
meta_fsyncdir(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags,
dict_t *xdata)
{
META_FOP(fd->inode, fsyncdir, frame, this, fd, flags, xdata);
return 0;
}
int
meta_forget(xlator_t *this, inode_t *inode)
{
return 0;
}
int
meta_release(xlator_t *this, fd_t *fd)
{
return meta_fd_release(fd, this);
}
int
meta_releasedir(xlator_t *this, fd_t *fd)
{
return meta_fd_release(fd, this);
}
int
mem_acct_init(xlator_t *this)
{
int ret = -1;
if (!this)
return ret;
ret = xlator_mem_acct_init(this, gf_meta_mt_end + 1);
if (ret != 0) {
gf_log(this->name, GF_LOG_ERROR, "Memory accounting init failed");
return ret;
}
return ret;
}
int
init(xlator_t *this)
{
meta_priv_t *priv = NULL;
int ret = -1;
priv = GF_CALLOC(sizeof(*priv), 1, gf_meta_mt_priv_t);
if (!priv)
return ret;
GF_OPTION_INIT("meta-dir-name", priv->meta_dir_name, str, out);
this->private = priv;
ret = 0;
out:
if (ret)
GF_FREE(priv);
return ret;
}
void
fini(xlator_t *this)
{
GF_FREE(this->private);
return;
}
struct xlator_fops fops = {.lookup = meta_lookup,
.opendir = meta_opendir,
.open = meta_open,
.readv = meta_readv,
.flush = meta_flush,
.stat = meta_stat,
.fstat = meta_fstat,
.readdir = meta_readdir,
.readdirp = meta_readdirp,
.readlink = meta_readlink,
.writev = meta_writev,
.truncate = meta_truncate,
.ftruncate = meta_ftruncate,
.fsync = meta_fsync,
.fsyncdir = meta_fsyncdir};
struct xlator_cbks cbks = {
.forget = meta_forget,
.release = meta_release,
.releasedir = meta_releasedir,
};
struct volume_options options[] = {
{.key = {"meta-dir-name"},
.type = GF_OPTION_TYPE_STR,
.default_value = DEFAULT_META_DIR_NAME,
.description = "Name of default meta directory."},
{.key = {NULL}},
};
xlator_api_t xlator_api = {
.init = init,
.fini = fini,
.mem_acct_init = mem_acct_init,
.op_version = {1}, /* Present from the initial version */
.fops = &fops,
.cbks = &cbks,
.options = options,
.identifier = "meta",
.category = GF_TECH_PREVIEW,
};