/* Copyright (c) 2013 Red Hat, Inc. 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 "xlator.h" #include "defaults.h" #include "logging.h" #include "changelog-encoders.h" /** FOPS */ /* default rmdir */ int32_t changelog_default_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflags, dict_t *xdata) { int ret = -1; size_t xtra_len = 0; changelog_opt_t *co = NULL; changelog_local_t *local = NULL; CHANGELOG_INIT_NOCHECK (this, local, NULL, loc->inode->gfid, 2); if (!local) goto out; co = changelog_get_usable_buffer (local); if (!co) goto out; CHANGELOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len); co++; CHANGELOG_FILL_ENTRY (co, loc->pargfid, loc->name, entry_fn, entry_free_fn, xtra_len, out); changelog_set_usable_record_and_length (local, xtra_len, 2); frame->local = local; ret = 0; out: if (ret) changelog_local_cleanup (this, local); return ret; } /* default unlink */ int32_t changelog_default_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflags, dict_t *xdata) { int ret = -1; size_t xtra_len = 0; changelog_opt_t *co = NULL; changelog_local_t *local = NULL; CHANGELOG_INIT_NOCHECK (this, local, NULL, loc->inode->gfid, 2); if (!local) goto out; co = changelog_get_usable_buffer (local); if (!co) goto out; CHANGELOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len); co++; CHANGELOG_FILL_ENTRY (co, loc->pargfid, loc->name, entry_fn, entry_free_fn, xtra_len, out); changelog_set_usable_record_and_length (local, xtra_len, 2); frame->local = local; ret = 0; out: if (ret) changelog_local_cleanup (this, local); return ret; } /* default rename */ int32_t changelog_default_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { int ret = -1; size_t xtra_len = 0; changelog_opt_t *co = NULL; changelog_local_t *local = NULL; /* 3 == fop + oldloc + newloc */ CHANGELOG_INIT_NOCHECK (this, local, NULL, oldloc->inode->gfid, 3); if (!local) goto out; co = changelog_get_usable_buffer (local); if (!co) goto out; CHANGELOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len); co++; CHANGELOG_FILL_ENTRY (co, oldloc->pargfid, oldloc->name, entry_fn, entry_free_fn, xtra_len, out); co++; CHANGELOG_FILL_ENTRY (co, newloc->pargfid, newloc->name, entry_fn, entry_free_fn, xtra_len, out); changelog_set_usable_record_and_length (local, xtra_len, 3); frame->local = local; ret = 0; out: if (ret) changelog_local_cleanup (this, local); return ret; } /* default link */ int32_t changelog_default_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata) { int ret = 1; size_t xtra_len = 0; changelog_opt_t *co = NULL; changelog_local_t *local = NULL; CHANGELOG_INIT_NOCHECK (this, local, NULL, oldloc->gfid, 2); if (!local) goto out; co = changelog_get_usable_buffer (local); if (!co) goto out; CHANGELOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len); co++; CHANGELOG_FILL_ENTRY (co, newloc->pargfid, newloc->name, entry_fn, entry_free_fn, xtra_len, out); changelog_set_usable_record_and_length (local, xtra_len, 2); frame->local = local; ret = 0; out: if (ret) changelog_local_cleanup (this, local); return ret; } /* default mknid */ int32_t changelog_default_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata) { int ret = -1; uuid_t gfid = {0,}; void *uuid_req = NULL; size_t xtra_len = 0; changelog_opt_t *co = NULL; changelog_local_t *local = NULL; ret = dict_get_ptr (xdata, "gfid-req", &uuid_req); if (ret) { gf_log (this->name, GF_LOG_DEBUG, "failed to get gfid from dict"); goto out; } uuid_copy (gfid, uuid_req); ret = -1; CHANGELOG_INIT_NOCHECK (this, local, NULL, gfid, 2); if (!local) goto out; co = changelog_get_usable_buffer (local); if (!co) goto out; CHANGELOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len); co++; CHANGELOG_FILL_ENTRY (co, loc->pargfid, loc->name, entry_fn, entry_free_fn, xtra_len, out); changelog_set_usable_record_and_length (local, xtra_len, 2); frame->local = local; ret = 0; out: if (ret) changelog_local_cleanup (this, local); return ret; } /* default symlink */ int32_t changelog_default_symlink (call_frame_t *frame, xlator_t *this, const char *linkname, loc_t *loc, mode_t umask, dict_t *xdata) { int ret = -1; size_t xtra_len = 0; uuid_t gfid = {0,}; void *uuid_req = NULL; changelog_opt_t *co = NULL; changelog_local_t *local = NULL; ret = dict_get_ptr (xdata, "gfid-req", &uuid_req); if (ret) { gf_log (this->name, GF_LOG_DEBUG, "failed to get gfid from dict"); goto out; } uuid_copy (gfid, uuid_req); ret = -1; CHANGELOG_INIT_NOCHECK (this, local, NULL, gfid, 2); if (!local) goto out; co = changelog_get_usable_buffer (local); if (!co) goto out; CHANGELOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len); co++; CHANGELOG_FILL_ENTRY (co, loc->pargfid, loc->name, entry_fn, entry_free_fn, xtra_len, out); changelog_set_usable_record_and_length (local, xtra_len, 2); frame->local = local; ret = 0; out: if (ret) changelog_local_cleanup (this, local); return ret; } /* default mknod */ int32_t changelog_default_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dev_t dev, mode_t umask, dict_t *xdata) { int ret = -1; uuid_t gfid = {0,}; void *uuid_req = NULL; size_t xtra_len = 0; changelog_opt_t *co = NULL; changelog_local_t *local = NULL; ret = dict_get_ptr (xdata, "gfid-req", &uuid_req); if (ret) { gf_log (this->name, GF_LOG_DEBUG, "failed to get gfid from dict"); goto out; } uuid_copy (gfid, uuid_req); ret = -1; CHANGELOG_INIT_NOCHECK (this, local, NULL, gfid, 2); co = changelog_get_usable_buffer (frame->local); if (!co) goto out; CHANGELOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len); co++; CHANGELOG_FILL_ENTRY (co, loc->pargfid, loc->name, entry_fn, entry_free_fn, xtra_len, out); changelog_set_usable_record_and_length (local, xtra_len, 2); frame->local = local; ret = 0; out: if (ret) changelog_local_cleanup (this, local); return ret; } /* default create */ int32_t changelog_default_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { int ret = -1; uuid_t gfid = {0,}; void *uuid_req = NULL; changelog_opt_t *co = NULL; size_t xtra_len = 0; changelog_local_t *local = NULL; ret = dict_get_ptr (xdata, "gfid-req", &uuid_req); if (ret) { gf_log (this->name, GF_LOG_DEBUG, "failed to get gfid from dict"); goto out; } uuid_copy (gfid, uuid_req); /* init with two extra records */ ret = -1; CHANGELOG_INIT_NOCHECK (this, local, NULL, gfid, 2); if (!local) goto out; co = changelog_get_usable_buffer (local); if (!co) goto out; CHANGELOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len); co++; CHANGELOG_FILL_ENTRY (co, loc->pargfid, loc->name, entry_fn, entry_free_fn, xtra_len, out); changelog_set_usable_record_and_length (local, xtra_len, 2); frame->local = local; ret = 0; out: if (ret) changelog_local_cleanup (this, local); return ret; } /* default fsetattr */ int32_t changelog_default_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf, int32_t valid, dict_t *xdata) { CHANGELOG_INIT (this, frame->local, fd->inode, fd->inode->gfid, 0); return 0; } /* default setattr */ int32_t changelog_default_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata) { CHANGELOG_INIT (this, frame->local, loc->inode, loc->inode->gfid, 0); return 0; } /* default fremovexattr */ int32_t changelog_default_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { CHANGELOG_INIT (this, frame->local, fd->inode, fd->inode->gfid, 0); return 0; } /* default removexattr */ int32_t changelog_default_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { CHANGELOG_INIT (this, frame->local, loc->inode, loc->inode->gfid, 0); return 0; } /* default setxattr */ int32_t changelog_default_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata) { CHANGELOG_INIT (this, frame->local, loc->inode, loc->inode->gfid, 0); return 0; } /* default fsetxattr */ int32_t changelog_default_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata) { CHANGELOG_INIT (this, frame->local, fd->inode, fd->inode->gfid, 0); return 0; } /* default truncate */ int32_t changelog_default_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { CHANGELOG_INIT (this, frame->local, loc->inode, loc->inode->gfid, 0); return 0; } /* default ftruncate */ int32_t changelog_default_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata) { CHANGELOG_INIT (this, frame->local, fd->inode, fd->inode->gfid, 0); return 0; } /* default writev */ int32_t changelog_default_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int32_t count, off_t offset, uint32_t flags, struct iobref *iobref, dict_t *xdata) { CHANGELOG_INIT (this, frame->local, fd->inode, fd->inode->gfid, 0); return 0; } /** COPS */ int changelog_default_cops_open (xlator_t *this, changelog_priv_t *priv, void *cpriv, char *name, gf_boolean_t last) { changelog_log_data_t cld = {0,}; changelog_rollover_data_t *crd = NULL; struct timeval tv = {0,}; crd = &cld.cld_roll; cld.cld_type = CHANGELOG_TYPE_ROLLOVER; if (gettimeofday (&tv, NULL)) return -1; crd->crd_prealloc_size = 0; /* no preallocation */ crd->crd_finale = last; crd->crd_use_suffix = _gf_true; crd->crd_roll_key = (unsigned long) tv.tv_sec; (void) strcpy (crd->crd_changelog_name, name); (void) strcpy (crd->crd_changelog_oname, name); /* inject a roll-over event */ return changelog_inject_single_event (this, priv, NULL, &cld); } int changelog_default_cops_rollover (xlator_t *this, changelog_priv_t *priv, void *cpriv, char *name, gf_boolean_t last) { return changelog_default_cops_open (this, priv, cpriv, name, last); } int changelog_default_cops_sync (xlator_t *this, changelog_priv_t *priv, void *cpriv) { changelog_log_data_t cld = {0,}; cld.cld_type = CHANGELOG_TYPE_FSYNC; return changelog_inject_single_event (this, priv, NULL, &cld); } /** * write to the changelog: @changelog_update() implements inode version * checking and all other stuffs... */ int changelog_default_cops_write (xlator_t *this, changelog_priv_t *priv, void *cpriv, changelog_local_t *local, changelog_log_type type) { changelog_update (this, priv, local, type); return 0; } off_t changelog_default_cops_get_offset (xlator_t *this, changelog_priv_t *priv, void *cpriv, changelog_local_t *local) { return *(off_t *)cpriv; } void changelog_default_cops_set_offset (xlator_t *this, changelog_priv_t *priv, void *cpriv, changelog_local_t *local, off_t bytes) { *(off_t *)cpriv += bytes; } void changelog_default_cops_reset_offset (xlator_t *this, changelog_priv_t *priv, void *cpriv, changelog_local_t *local) { *(off_t *)cpriv = 0; } /** * roll-over takes care of close and open */ int changelog_default_cops_close (xlator_t *this, changelog_priv_t *priv, void *cpriv) { errno = ENOTSUP; return -1; } int changelog_default_cops_read (xlator_t *this, changelog_priv_t *priv, void *cpriv, char *buffer) { errno = ENOTSUP; return -1; } /** * no purging of changelogs */ int changelog_default_cops_unlink (xlator_t *this, changelog_priv_t *priv, void *cpriv, char *name) { errno = ENOTSUP; return -1; }