diff options
Diffstat (limited to 'xlators/features/utime/src/utime.c')
| -rw-r--r-- | xlators/features/utime/src/utime.c | 398 |
1 files changed, 281 insertions, 117 deletions
diff --git a/xlators/features/utime/src/utime.c b/xlators/features/utime/src/utime.c index a8d74d9cb5c..2acc63e6a05 100644 --- a/xlators/features/utime/src/utime.c +++ b/xlators/features/utime/src/utime.c @@ -9,220 +9,384 @@ */ #include "utime.h" +#include "utime-helpers.h" +#include "utime-messages.h" +#include "utime-mem-types.h" +#include <glusterfs/call-stub.h> int32_t -gf_utime_invalidate (xlator_t *this, - inode_t *inode) +gf_utime_invalidate(xlator_t *this, inode_t *inode) { - return 0; + return 0; } - int32_t -gf_utime_forget (xlator_t *this, - inode_t *inode) +gf_utime_forget(xlator_t *this, inode_t *inode) { - return 0; + return 0; } - int32_t -gf_utime_client_destroy (xlator_t *this, - client_t *client) +gf_utime_client_destroy(xlator_t *this, client_t *client) { - return 0; + return 0; } - void -gf_utime_ictxmerge (xlator_t *this, - fd_t *fd, - inode_t *inode, - inode_t *linked_inode) +gf_utime_ictxmerge(xlator_t *this, fd_t *fd, inode_t *inode, + inode_t *linked_inode) { - return; + return; } - int32_t -gf_utime_release (xlator_t *this, - fd_t *fd) +gf_utime_release(xlator_t *this, fd_t *fd) { - return 0; + return 0; } - int32_t -gf_utime_releasedir (xlator_t *this, - fd_t *fd) +gf_utime_releasedir(xlator_t *this, fd_t *fd) { - return 0; + return 0; } - int32_t -gf_utime_client_disconnect (xlator_t *this, - client_t *client) +gf_utime_client_disconnect(xlator_t *this, client_t *client) { - return 0; + return 0; } - int32_t -gf_utime_fdctx_to_dict (xlator_t *this, - fd_t *fd, - dict_t *dict) +gf_utime_fdctx_to_dict(xlator_t *this, fd_t *fd, dict_t *dict) { - return 0; + return 0; } - int32_t -gf_utime_inode (xlator_t *this) +gf_utime_inode(xlator_t *this) { - return 0; + return 0; } - int32_t -gf_utime_inode_to_dict (xlator_t *this, - dict_t *dict) +gf_utime_inode_to_dict(xlator_t *this, dict_t *dict) { - return 0; + return 0; } - int32_t -gf_utime_history (xlator_t *this) +gf_utime_history(xlator_t *this) { - return 0; + return 0; } - int32_t -gf_utime_fd (xlator_t *this) +gf_utime_fd(xlator_t *this) { - return 0; + return 0; } - int32_t -gf_utime_fd_to_dict (xlator_t *this, - dict_t *dict) +gf_utime_fd_to_dict(xlator_t *this, dict_t *dict) { - return 0; + return 0; } - int32_t -gf_utime_fdctx (xlator_t *this, - fd_t *fd) +gf_utime_fdctx(xlator_t *this, fd_t *fd) { - return 0; + return 0; } - int32_t -gf_utime_inodectx (xlator_t *this, - inode_t *ino) +gf_utime_inodectx(xlator_t *this, inode_t *ino) { - return 0; + return 0; } +int32_t +gf_utime_inodectx_to_dict(xlator_t *this, inode_t *ino, dict_t *dict) +{ + return 0; +} int32_t -gf_utime_inodectx_to_dict (xlator_t *this, - inode_t *ino, - dict_t *dict) +gf_utime_priv_to_dict(xlator_t *this, dict_t *dict, char *brickname) { - return 0; + return 0; } +int32_t +gf_utime_priv(xlator_t *this) +{ + return 0; +} int32_t -gf_utime_priv_to_dict (xlator_t *this, - dict_t *dict, char *brickname) +mem_acct_init(xlator_t *this) { - return 0; + if (xlator_mem_acct_init(this, utime_mt_end + 1) != 0) { + gf_msg(this->name, GF_LOG_ERROR, ENOMEM, UTIME_MSG_NO_MEMORY, + "Memory accounting initialization failed."); + return -1; + } + return 0; } +int32_t +gf_utime_set_mdata_setxattr_cbk(call_frame_t *frame, void *cookie, + xlator_t *this, int op_ret, int op_errno, + dict_t *xdata) +{ + call_stub_t *stub = frame->local; + /* Don't fail lookup if mdata setxattr fails */ + if (op_ret) { + gf_msg(this->name, GF_LOG_ERROR, op_errno, UTIME_MSG_SET_MDATA_FAILED, + "dict set of key for set-ctime-mdata failed"); + } + frame->local = NULL; + call_resume(stub); + STACK_DESTROY(frame->root); + return 0; +} int32_t -gf_utime_priv (xlator_t *this) +gf_utime_set_mdata_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, inode_t *inode, + struct iatt *stbuf, dict_t *xdata, + struct iatt *postparent) { + dict_t *dict = NULL; + struct mdata_iatt *mdata = NULL; + int ret = 0; + loc_t loc = { + 0, + }; + call_frame_t *new_frame = NULL; + + if (!op_ret && dict_get(xdata, GF_XATTR_MDATA_KEY) == NULL) { + dict = dict_new(); + if (!dict) { + op_errno = ENOMEM; + goto err; + } + mdata = GF_MALLOC(sizeof(struct mdata_iatt), gf_common_mt_char); + if (mdata == NULL) { + op_errno = ENOMEM; + goto err; + } + iatt_to_mdata(mdata, stbuf); + ret = dict_set_mdata(dict, CTIME_MDATA_XDATA_KEY, mdata, _gf_false); + if (ret < 0) { + gf_msg(this->name, GF_LOG_WARNING, ENOMEM, UTIME_MSG_NO_MEMORY, + "dict set of key for set-ctime-mdata failed"); + goto err; + } + new_frame = copy_frame(frame); + if (!new_frame) { + op_errno = ENOMEM; + goto stub_err; + } + + new_frame->local = fop_lookup_cbk_stub(frame, default_lookup_cbk, + op_ret, op_errno, inode, stbuf, + xdata, postparent); + if (!new_frame->local) { + gf_msg(this->name, GF_LOG_WARNING, ENOMEM, UTIME_MSG_NO_MEMORY, + "lookup_cbk stub allocation failed"); + op_errno = ENOMEM; + STACK_DESTROY(new_frame->root); + goto stub_err; + } + + loc.inode = inode_ref(inode); + gf_uuid_copy(loc.gfid, stbuf->ia_gfid); + + new_frame->root->uid = 0; + new_frame->root->gid = 0; + new_frame->root->pid = GF_CLIENT_PID_SET_UTIME; + STACK_WIND(new_frame, gf_utime_set_mdata_setxattr_cbk, + FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, &loc, + dict, 0, NULL); + + dict_unref(dict); + inode_unref(loc.inode); return 0; + } + + STACK_UNWIND_STRICT(lookup, frame, op_ret, op_errno, inode, stbuf, xdata, + postparent); + return 0; + +err: + if (mdata) { + GF_FREE(mdata); + } +stub_err: + if (dict) { + dict_unref(dict); + } + STACK_UNWIND_STRICT(lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL); + return 0; } +int +gf_utime_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) +{ + int op_errno = EINVAL; + int ret = -1; + + VALIDATE_OR_GOTO(frame, err); + VALIDATE_OR_GOTO(this, err); + VALIDATE_OR_GOTO(loc, err); + VALIDATE_OR_GOTO(loc->inode, err); + + xdata = xdata ? dict_ref(xdata) : dict_new(); + if (!xdata) { + op_errno = ENOMEM; + goto err; + } + + ret = dict_set_int8(xdata, GF_XATTR_MDATA_KEY, 1); + if (ret < 0) { + gf_msg(this->name, GF_LOG_WARNING, -ret, UTIME_MSG_DICT_SET_FAILED, + "%s: Unable to set dict value for %s", loc->path, + GF_XATTR_MDATA_KEY); + op_errno = -ret; + goto free_dict; + } + + STACK_WIND(frame, gf_utime_set_mdata_lookup_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->lookup, loc, xdata); + dict_unref(xdata); + return 0; + +free_dict: + dict_unref(xdata); +err: + STACK_UNWIND_STRICT(lookup, frame, ret, op_errno, NULL, NULL, NULL, NULL); + return 0; +} int32_t -init (xlator_t *this) +init(xlator_t *this) { - return 0; + utime_priv_t *utime = NULL; + + utime = GF_MALLOC(sizeof(*utime), utime_mt_utime_t); + if (utime == NULL) { + gf_msg(this->name, GF_LOG_ERROR, ENOMEM, UTIME_MSG_NO_MEMORY, + "Failed to allocate private memory."); + return -1; + } + memset(utime, 0, sizeof(*utime)); + + this->private = utime; + GF_OPTION_INIT("noatime", utime->noatime, bool, err); + + return 0; +err: + return -1; } void -fini (xlator_t *this) +fini(xlator_t *this) { - return; + utime_priv_t *utime = NULL; + + utime = this->private; + GF_FREE(utime); + return; } int32_t -reconfigure (xlator_t *this, dict_t *dict) +reconfigure(xlator_t *this, dict_t *options) { - return 0; + utime_priv_t *utime = this->private; + + GF_OPTION_RECONF("noatime", utime->noatime, options, bool, err); + + return 0; +err: + return -1; } int -notify (xlator_t *this, int event, void *data, ...) +notify(xlator_t *this, int event, void *data, ...) { - return default_notify (this, event, data); + return default_notify(this, event, data); } - struct xlator_fops fops = { - /* TODO: Need to go through other fops and - * check if they modify time attributes - */ - .rename = gf_utime_rename, - .mknod = gf_utime_mknod, - .readv = gf_utime_readv, - .fremovexattr = gf_utime_fremovexattr, - .open = gf_utime_open, - .create = gf_utime_create, - .mkdir = gf_utime_mkdir, - .writev = gf_utime_writev, - .rmdir = gf_utime_rmdir, - .fallocate = gf_utime_fallocate, - .truncate = gf_utime_truncate, - .symlink = gf_utime_symlink, - .zerofill = gf_utime_zerofill, - .link = gf_utime_link, - .ftruncate = gf_utime_ftruncate, - .unlink = gf_utime_unlink, - .setattr = gf_utime_setattr, - .fsetattr = gf_utime_fsetattr, - .opendir = gf_utime_opendir, - .removexattr = gf_utime_removexattr, + .rename = gf_utime_rename, + .mknod = gf_utime_mknod, + .readv = gf_utime_readv, + .fremovexattr = gf_utime_fremovexattr, + .open = gf_utime_open, + .create = gf_utime_create, + .mkdir = gf_utime_mkdir, + .writev = gf_utime_writev, + .rmdir = gf_utime_rmdir, + .fallocate = gf_utime_fallocate, + .truncate = gf_utime_truncate, + .symlink = gf_utime_symlink, + .zerofill = gf_utime_zerofill, + .link = gf_utime_link, + .ftruncate = gf_utime_ftruncate, + .unlink = gf_utime_unlink, + .setattr = gf_utime_setattr, + .fsetattr = gf_utime_fsetattr, + .opendir = gf_utime_opendir, + .removexattr = gf_utime_removexattr, + .lookup = gf_utime_lookup, }; struct xlator_cbks cbks = { - .invalidate = gf_utime_invalidate, - .forget = gf_utime_forget, - .client_destroy = gf_utime_client_destroy, - .ictxmerge = gf_utime_ictxmerge, - .release = gf_utime_release, - .releasedir = gf_utime_releasedir, - .client_disconnect = gf_utime_client_disconnect, + .invalidate = gf_utime_invalidate, + .forget = gf_utime_forget, + .client_destroy = gf_utime_client_destroy, + .ictxmerge = gf_utime_ictxmerge, + .release = gf_utime_release, + .releasedir = gf_utime_releasedir, + .client_disconnect = gf_utime_client_disconnect, }; struct xlator_dumpops dumpops = { - .fdctx_to_dict = gf_utime_fdctx_to_dict, - .inode = gf_utime_inode, - .inode_to_dict = gf_utime_inode_to_dict, - .history = gf_utime_history, - .fd = gf_utime_fd, - .fd_to_dict = gf_utime_fd_to_dict, - .fdctx = gf_utime_fdctx, - .inodectx = gf_utime_inodectx, - .inodectx_to_dict = gf_utime_inodectx_to_dict, - .priv_to_dict = gf_utime_priv_to_dict, - .priv = gf_utime_priv, + .fdctx_to_dict = gf_utime_fdctx_to_dict, + .inode = gf_utime_inode, + .inode_to_dict = gf_utime_inode_to_dict, + .history = gf_utime_history, + .fd = gf_utime_fd, + .fd_to_dict = gf_utime_fd_to_dict, + .fdctx = gf_utime_fdctx, + .inodectx = gf_utime_inodectx, + .inodectx_to_dict = gf_utime_inodectx_to_dict, + .priv_to_dict = gf_utime_priv_to_dict, + .priv = gf_utime_priv, +}; + +struct volume_options options[] = { + {.key = {"noatime"}, + .type = GF_OPTION_TYPE_BOOL, + .default_value = "on", + .op_version = {GD_OP_VERSION_5_0}, + .flags = OPT_FLAG_SETTABLE | OPT_FLAG_CLIENT_OPT | OPT_FLAG_DOC, + .tags = {"ctime"}, + .description = "Enable/Disable atime updation when ctime feature is " + "enabled. When noatime is on, atime is not updated with " + "ctime feature enabled and vice versa."}, + {.key = {NULL}}}; + +xlator_api_t xlator_api = { + .init = init, + .fini = fini, + .notify = notify, + .reconfigure = reconfigure, + .mem_acct_init = mem_acct_init, + .op_version = {GD_OP_VERSION_5_0}, + .dumpops = &dumpops, + .fops = &fops, + .cbks = &cbks, + .options = options, + .identifier = "utime", + .category = GF_MAINTAINED, }; |
