/*
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 __SNAP_VIEW_H__
#define __SNAP_VIEW_H__
#include <glusterfs/dict.h>
#include <glusterfs/defaults.h>
#include <glusterfs/mem-types.h>
#include <glusterfs/call-stub.h>
#include <glusterfs/byte-order.h>
#include <glusterfs/iatt.h>
#include <ctype.h>
#include <sys/uio.h>
#include <glusterfs/glusterfs.h>
#include <glusterfs/xlator.h>
#include <glusterfs/logging.h>
#include "glfs.h"
#include <glusterfs/common-utils.h>
#include "glfs-handles.h"
#include "glfs-internal.h"
#include "glusterfs3-xdr.h"
#include <glusterfs/glusterfs-acl.h>
#include <glusterfs/syncop.h>
#include <glusterfs/list.h>
#include <glusterfs/timer.h>
#include "rpc-clnt.h"
#include "protocol-common.h"
#include "xdr-generic.h"
#include "snapview-server-messages.h"
#define DEFAULT_SVD_LOG_FILE_DIRECTORY DATADIR "/log/glusterfs"
#define SNAP_VIEW_MAX_GLFS_T 256
#define SNAP_VIEW_MAX_GLFS_FDS 1024
#define SNAP_VIEW_MAX_GLFS_OBJ_HANDLES 1024
#define SVS_STACK_DESTROY(_frame) \
do { \
((call_frame_t *)_frame)->local = NULL; \
STACK_DESTROY(((call_frame_t *)_frame)->root); \
} while (0)
#define SVS_CHECK_VALID_SNAPSHOT_HANDLE(fs, this) \
do { \
svs_private_t *_private = NULL; \
_private = this->private; \
int i = 0; \
gf_boolean_t found = _gf_false; \
glfs_t *tmp_fs = NULL; \
LOCK(&_private->snaplist_lock); \
{ \
for (i = 0; i < _private->num_snaps; i++) { \
tmp_fs = _private->dirents[i].fs; \
gf_log(this->name, GF_LOG_DEBUG, "dirent->fs: %p", tmp_fs); \
if (tmp_fs && fs && (tmp_fs == fs)) { \
found = _gf_true; \
break; \
} \
} \
} \
UNLOCK(&_private->snaplist_lock); \
\
if (!found) { \
gf_log(this->name, GF_LOG_WARNING, \
"failed to" \
" find the fs instance %p", \
fs); \
fs = NULL; \
} \
} while (0)
#define SVS_GET_INODE_CTX_INFO(inode_ctx, fs, object, this, loc, ret, \
op_errno, label) \
do { \
fs = inode_ctx->fs; \
object = inode_ctx->object; \
SVS_CHECK_VALID_SNAPSHOT_HANDLE(fs, this); \
if (!fs) \
object = NULL; \
\
if (!fs || !object) { \
int32_t tmp = -1; \
char tmp_uuid[64]; \
\
tmp = svs_get_handle(this, loc, inode_ctx, &op_errno); \
if (tmp) { \
gf_log(this->name, GF_LOG_ERROR, \
"failed to get the handle for %s " \
"(gfid: %s)", \
loc->path, uuid_utoa_r(loc->inode->gfid, tmp_uuid)); \
ret = -1; \
goto label; \
} \
\
fs = inode_ctx->fs; \
object = inode_ctx->object; \
} \
} while (0);
#define SVS_STRDUP(dst, src) \
do { \
if (dst && strcmp(src, dst)) { \
GF_FREE(dst); \
dst = NULL; \
} \
\
if (!dst) \
dst = gf_strdup(src); \
} while (0)
int
svs_mgmt_submit_request(void *req, call_frame_t *frame, glusterfs_ctx_t *ctx,
rpc_clnt_prog_t *prog, int procnum, fop_cbk_fn_t cbkfn,
xdrproc_t xdrproc);
int
svs_get_snapshot_list(xlator_t *this);
int
mgmt_get_snapinfo_cbk(struct rpc_req *req, struct iovec *iov, int count,
void *myframe);
typedef enum {
SNAP_VIEW_ENTRY_POINT_INODE = 0,
SNAP_VIEW_SNAPSHOT_INODE,
SNAP_VIEW_VIRTUAL_INODE
} inode_type_t;
struct svs_inode {
glfs_t *fs;
glfs_object_t *object;
inode_type_t type;
/* used only for entry point directory where gfid of the directory
from where the entry point was entered is saved.
*/
uuid_t pargfid;
/* This is used to generate gfid for all sub files/dirs under this
* snapshot
*/
char *snapname;
struct iatt buf;
};
typedef struct svs_inode svs_inode_t;
struct svs_fd {
glfs_fd_t *fd;
};
typedef struct svs_fd svs_fd_t;
struct snap_dirent {
char name[NAME_MAX];
char uuid[UUID_CANONICAL_FORM_LEN + 1];
char snap_volname[NAME_MAX];
glfs_t *fs;
};
typedef struct snap_dirent snap_dirent_t;
struct svs_private {
snap_dirent_t *dirents;
int num_snaps;
char *volname;
struct list_head snaplist;
gf_lock_t snaplist_lock;
struct rpc_clnt *rpc;
};
typedef struct svs_private svs_private_t;
int
__svs_inode_ctx_set(xlator_t *this, inode_t *inode, svs_inode_t *svs_inode);
svs_inode_t *
__svs_inode_ctx_get(xlator_t *this, inode_t *inode);
svs_inode_t *
svs_inode_ctx_get(xlator_t *this, inode_t *inode);
int32_t
svs_inode_ctx_set(xlator_t *this, inode_t *inode, svs_inode_t *svs_inode);
svs_inode_t *
svs_inode_ctx_get_or_new(xlator_t *this, inode_t *inode);
int
__svs_fd_ctx_set(xlator_t *this, fd_t *fd, svs_fd_t *svs_fd);
svs_fd_t *
__svs_fd_ctx_get(xlator_t *this, fd_t *fd);
svs_fd_t *
svs_fd_ctx_get(xlator_t *this, fd_t *fd);
int32_t
svs_fd_ctx_set(xlator_t *this, fd_t *fd, svs_fd_t *svs_fd);
svs_fd_t *
__svs_fd_ctx_get_or_new(xlator_t *this, fd_t *fd);
svs_fd_t *
svs_fd_ctx_get_or_new(xlator_t *this, fd_t *fd);
int
svs_uuid_generate(xlator_t *this, uuid_t gfid, char *snapname,
uuid_t origin_gfid);
void
svs_fill_ino_from_gfid(struct iatt *buf);
void
svs_iatt_fill(uuid_t gfid, struct iatt *buf);
snap_dirent_t *
svs_get_latest_snap_entry(xlator_t *this);
glfs_t *
svs_get_latest_snapshot(xlator_t *this);
glfs_t *
svs_initialise_snapshot_volume(xlator_t *this, const char *name,
int32_t *op_errno);
glfs_t *
__svs_initialise_snapshot_volume(xlator_t *this, const char *name,
int32_t *op_errno);
snap_dirent_t *
__svs_get_snap_dirent(xlator_t *this, const char *name);
int
svs_mgmt_init(xlator_t *this);
int32_t
svs_get_handle(xlator_t *this, loc_t *loc, svs_inode_t *inode_ctx,
int32_t *op_errno);
glfs_t *
svs_inode_glfs_mapping(xlator_t *this, inode_t *inode);
glfs_t *
svs_inode_ctx_glfs_mapping(xlator_t *this, svs_inode_t *inode_ctx);
#endif /* __SNAP_VIEW_H__ */