From 487aaafacac8af16c08eb44fe9bf178768d372fa Mon Sep 17 00:00:00 2001 From: Kotresh HR Date: Mon, 30 Apr 2018 04:43:58 -0400 Subject: utime: ctime client side xlator The client side utime xlator does two things. 1. Update unix epoch time in frame->root->ctime 2. Update the frame->root->flags based on the fop which indicates time attributes that should be updated for the parent/entry. Credits: Rafi KC Updates: #208 Change-Id: I9cad297040c70798a0a8468a080eb4aeff73138d Signed-off-by: Kotresh HR --- xlators/features/Makefile.am | 3 +- xlators/features/utime/Makefile.am | 3 + xlators/features/utime/src/Makefile.am | 39 ++++ .../features/utime/src/utime-autogen-fops-tmpl.c | 28 +++ .../features/utime/src/utime-autogen-fops-tmpl.h | 22 ++ xlators/features/utime/src/utime-gen-fops-c.py | 118 +++++++++++ xlators/features/utime/src/utime-gen-fops-h.py | 34 +++ xlators/features/utime/src/utime-helpers.c | 95 +++++++++ xlators/features/utime/src/utime-helpers.h | 24 +++ xlators/features/utime/src/utime.c | 229 +++++++++++++++++++++ xlators/features/utime/src/utime.h | 19 ++ 11 files changed, 613 insertions(+), 1 deletion(-) create mode 100644 xlators/features/utime/Makefile.am create mode 100644 xlators/features/utime/src/Makefile.am create mode 100644 xlators/features/utime/src/utime-autogen-fops-tmpl.c create mode 100644 xlators/features/utime/src/utime-autogen-fops-tmpl.h create mode 100644 xlators/features/utime/src/utime-gen-fops-c.py create mode 100644 xlators/features/utime/src/utime-gen-fops-h.py create mode 100644 xlators/features/utime/src/utime-helpers.c create mode 100644 xlators/features/utime/src/utime-helpers.h create mode 100644 xlators/features/utime/src/utime.c create mode 100644 xlators/features/utime/src/utime.h (limited to 'xlators/features') diff --git a/xlators/features/Makefile.am b/xlators/features/Makefile.am index a8d73c83b83..81fbe856e78 100644 --- a/xlators/features/Makefile.am +++ b/xlators/features/Makefile.am @@ -1,5 +1,6 @@ SUBDIRS = locks quota read-only quiesce marker index barrier \ arbiter compress changelog changetimerecorder \ gfid-access $(GLUPY_SUBDIR) upcall snapview-client snapview-server \ - trash shard bit-rot leases selinux sdfs namespace cloudsync thin-arbiter + trash shard bit-rot leases selinux sdfs namespace cloudsync thin-arbiter \ + utime CLEANFILES = diff --git a/xlators/features/utime/Makefile.am b/xlators/features/utime/Makefile.am new file mode 100644 index 00000000000..a985f42a877 --- /dev/null +++ b/xlators/features/utime/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS = src + +CLEANFILES = diff --git a/xlators/features/utime/src/Makefile.am b/xlators/features/utime/src/Makefile.am new file mode 100644 index 00000000000..52f2eb5df24 --- /dev/null +++ b/xlators/features/utime/src/Makefile.am @@ -0,0 +1,39 @@ +xlator_LTLIBRARIES = utime.la +xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features + +UTIME_SRC = $(top_srcdir)/xlators/features/utime/src + +utime_sources = $(UTIME_SRC)/utime-helpers.c +utime_sources += $(UTIME_SRC)/utime.c + +utime_la_SOURCES = $(utime_sources) +nodist_utime_la_SOURCES = utime-autogen-fops.c utime-autogen-fops.h +BUILT_SOURCES = utime-autogen-fops.h + +utime_la_LDFLAGS = -module -avoid-version +utime_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la + +noinst_HEADERS_utime = $(UTIME_SRC)/utime-helpers.h +noinst_HEADERS_utime += $(UTIME_SRC)/utime.h +noinst_HEADERS = $(top_srcdir)/xlators/lib/src/libxlator.h +noinst_HEADERS += $(noinst_HEADERS_utime) + +AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ + -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ + -I$(top_srcdir)/xlators/lib/src + +AM_CFLAGS = -Wall $(GF_CFLAGS) + +noinst_PYTHON = utime-gen-fops-c.py utime-gen-fops-h.py +EXTRA_DIST = utime-autogen-fops-tmpl.c utime-autogen-fops-tmpl.h + +utime-autogen-fops.c: utime-gen-fops-c.py utime-autogen-fops-tmpl.c + $(PYTHON) $(UTIME_SRC)/utime-gen-fops-c.py $(UTIME_SRC)/utime-autogen-fops-tmpl.c > $@ + +utime-autogen-fops.h: utime-gen-fops-h.py utime-autogen-fops-tmpl.h + $(PYTHON) $(UTIME_SRC)/utime-gen-fops-h.py $(UTIME_SRC)/utime-autogen-fops-tmpl.h > $@ + +CLEANFILES = $(nodist_utime_la_SOURCES) + +uninstall-local: + rm -f $(DESTDIR)$(xlatordir)/utime.so diff --git a/xlators/features/utime/src/utime-autogen-fops-tmpl.c b/xlators/features/utime/src/utime-autogen-fops-tmpl.c new file mode 100644 index 00000000000..b4be66eebd1 --- /dev/null +++ b/xlators/features/utime/src/utime-autogen-fops-tmpl.c @@ -0,0 +1,28 @@ +/* + Copyright (c) 2018 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. +*/ + +/* File: utime-autogen-fops-tmpl.c + * This file contains the utime autogenerated FOPs. This is run through + * the code generator, generator.py to generate the required FOPs. + */ + +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif + +#include "glusterfs.h" +#include "xlator.h" +#include "logging.h" +#include "statedump.h" +#include "utime-helpers.h" +#include "timespec.h" + +#pragma generate diff --git a/xlators/features/utime/src/utime-autogen-fops-tmpl.h b/xlators/features/utime/src/utime-autogen-fops-tmpl.h new file mode 100644 index 00000000000..e2e807cdf64 --- /dev/null +++ b/xlators/features/utime/src/utime-autogen-fops-tmpl.h @@ -0,0 +1,22 @@ +/* + Copyright (c) 2018 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. +*/ + +/* File: utime-autogen-fops-tmpl.h + * This file contains the utime autogenerated FOPs declarations. + */ + +#ifndef _UTIME_AUTOGEN_FOPS_H +#define _UTIME_AUTOGEN_FOPS_H + +#include "xlator.h" + +#pragma generate + +#endif /* _UTIME_AUTOGEN_FOPS_H */ diff --git a/xlators/features/utime/src/utime-gen-fops-c.py b/xlators/features/utime/src/utime-gen-fops-c.py new file mode 100644 index 00000000000..4e22c2df0bc --- /dev/null +++ b/xlators/features/utime/src/utime-gen-fops-c.py @@ -0,0 +1,118 @@ +#!/usr/bin/python + +import os +import sys + +curdir = os.path.dirname(sys.argv[0]) +gendir = os.path.join(curdir, '../../../../libglusterfs/src') +sys.path.append(gendir) +from generator import ops, fop_subs, cbk_subs, generate + +FOPS_COMMON_TEMPLATE = """ +int32_t +gf_utime_@NAME@ (call_frame_t *frame, xlator_t *this, + @LONG_ARGS@) +{ + gl_timespec_get(&frame->root->ctime); + + (void) utime_update_attribute_flags(frame, GF_FOP_@UPNAME@); + STACK_WIND (frame, gf_utime_@NAME@_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->@NAME@, @SHORT_ARGS@); + return 0; +} +""" + +FOPS_CBK_COMMON_TEMPLATE = """ +int32_t +gf_utime_@NAME@_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, + @LONG_ARGS@) +{ + STACK_UNWIND_STRICT (@NAME@, frame, op_ret, op_errno, @SHORT_ARGS@); + return 0; +} +""" + +FOPS_READ_TEMPLATE = """ +int32_t +gf_utime_@NAME@ (call_frame_t *frame, xlator_t *this, + @LONG_ARGS@) +{ + gl_timespec_get(&frame->root->ctime); + + (void) utime_update_attribute_flags(frame, GF_FOP_READ); + STACK_WIND (frame, gf_utime_@NAME@_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->@NAME@, @SHORT_ARGS@); + return 0; +} +""" + +FOPS_WRITE_TEMPLATE = """ +int32_t +gf_utime_@NAME@ (call_frame_t *frame, xlator_t *this, + @LONG_ARGS@) +{ + gl_timespec_get(&frame->root->ctime); + + (void) utime_update_attribute_flags(frame, GF_FOP_WRITE); + STACK_WIND (frame, gf_utime_@NAME@_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->@NAME@, @SHORT_ARGS@); + return 0; +} +""" + +FOPS_SETATTR_TEMPLATE = """ +int32_t +gf_utime_@NAME@ (call_frame_t *frame, xlator_t *this, + @LONG_ARGS@) +{ + gl_timespec_get(&frame->root->ctime); + + if (!valid) { + frame->root->flags |= MDATA_CTIME; + } + + if (valid & (GF_SET_ATTR_UID | GF_SET_ATTR_GID)) { + frame->root->flags |= MDATA_CTIME; + } + + if (valid & GF_SET_ATTR_MODE) { + frame->root->flags |= MDATA_CTIME; + } + + STACK_WIND (frame, gf_utime_@NAME@_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->@NAME@, @SHORT_ARGS@); + return 0; +} +""" + +utime_ops = ['fallocate', 'zerofill', 'opendir', 'readlink', 'mknod', 'mkdir', + 'unlink', 'rmdir', 'symlink', 'rename', 'link', 'truncate', + 'ftruncate', 'create', 'open', 'removexattr', 'fremovexattr'] + +utime_read_op = ['readv'] +utime_write_op = ['writev'] +utime_setattr_ops = ['setattr', 'fsetattr'] + +def gen_defaults(): + for name in ops: + if name in utime_ops: + print generate(FOPS_CBK_COMMON_TEMPLATE, name, cbk_subs) + print generate(FOPS_COMMON_TEMPLATE, name, fop_subs) + if name in utime_read_op: + print generate(FOPS_CBK_COMMON_TEMPLATE, name, cbk_subs) + print generate(FOPS_READ_TEMPLATE, name, fop_subs) + if name in utime_write_op: + print generate(FOPS_CBK_COMMON_TEMPLATE, name, cbk_subs) + print generate(FOPS_WRITE_TEMPLATE, name, fop_subs) + if name in utime_setattr_ops: + print generate(FOPS_CBK_COMMON_TEMPLATE, name, cbk_subs) + print generate(FOPS_SETATTR_TEMPLATE, name, fop_subs) + +for l in open(sys.argv[1], 'r').readlines(): + if l.find('#pragma generate') != -1: + print "/* BEGIN GENERATED CODE - DO NOT MODIFY */" + gen_defaults() + print "/* END GENERATED CODE */" + else: + print l[:-1] diff --git a/xlators/features/utime/src/utime-gen-fops-h.py b/xlators/features/utime/src/utime-gen-fops-h.py new file mode 100644 index 00000000000..9f0270d5ae8 --- /dev/null +++ b/xlators/features/utime/src/utime-gen-fops-h.py @@ -0,0 +1,34 @@ +#!/usr/bin/python + +import os +import sys + +curdir = os.path.dirname(sys.argv[0]) +gendir = os.path.join(curdir, '../../../../libglusterfs/src') +sys.path.append(gendir) +from generator import ops, fop_subs, generate + +OP_FOP_TEMPLATE = """ +int32_t +gf_utime_@NAME@ (call_frame_t *frame, xlator_t *this, + @LONG_ARGS@); +""" + +utime_ops = ['fallocate', 'zerofill', 'opendir', 'readlink', 'mknod', 'mkdir', + 'unlink', 'rmdir', 'symlink', 'rename', 'link', 'truncate', + 'ftruncate', 'create', 'open', 'removexattr', 'fremovexattr', + 'readv', 'writev', 'setattr', 'fsetattr'] + +def gen_defaults(): + for name, value in ops.iteritems(): + if name in utime_ops: + print generate(OP_FOP_TEMPLATE, name, fop_subs) + + +for l in open(sys.argv[1], 'r').readlines(): + if l.find('#pragma generate') != -1: + print "/* BEGIN GENERATED CODE - DO NOT MODIFY */" + gen_defaults() + print "/* END GENERATED CODE */" + else: + print l[:-1] diff --git a/xlators/features/utime/src/utime-helpers.c b/xlators/features/utime/src/utime-helpers.c new file mode 100644 index 00000000000..d8632453e62 --- /dev/null +++ b/xlators/features/utime/src/utime-helpers.c @@ -0,0 +1,95 @@ +/* + Copyright (c) 2018 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 "utime-helpers.h" + +void +gl_timespec_get (struct timespec *ts) +{ + #ifdef TIME_UTC + timespec_get (ts, TIME_UTC); + #else + timespec_now (ts); + #endif +} + +void +utime_update_attribute_flags(call_frame_t *frame, glusterfs_fop_t fop) +{ + + if (!frame) { + goto out; + } + + switch (fop) { + case GF_FOP_SETXATTR: + case GF_FOP_FSETXATTR: + frame->root->flags |= MDATA_CTIME; + break; + + case GF_FOP_FALLOCATE: + case GF_FOP_ZEROFILL: + frame->root->flags |= MDATA_MTIME; + frame->root->flags |= MDATA_ATIME; + break; + + case GF_FOP_OPENDIR: + case GF_FOP_READLINK: + case GF_FOP_OPEN: + case GF_FOP_READ: + frame->root->flags |= MDATA_ATIME; + break; + + case GF_FOP_MKNOD: + case GF_FOP_MKDIR: + case GF_FOP_SYMLINK: + case GF_FOP_CREATE: + frame->root->flags |= MDATA_ATIME; + frame->root->flags |= MDATA_CTIME; + frame->root->flags |= MDATA_MTIME; + frame->root->flags |= MDATA_PAR_CTIME; + frame->root->flags |= MDATA_PAR_MTIME; + break; + + case GF_FOP_UNLINK: + case GF_FOP_RMDIR: + frame->root->flags |= MDATA_PAR_CTIME; + frame->root->flags |= MDATA_PAR_MTIME; + break; + + case GF_FOP_WRITE: + frame->root->flags |= MDATA_MTIME; + frame->root->flags |= MDATA_CTIME; + break; + + case GF_FOP_LINK: + case GF_FOP_RENAME: + frame->root->flags |= MDATA_CTIME; + frame->root->flags |= MDATA_PAR_CTIME; + frame->root->flags |= MDATA_PAR_MTIME; + break; + + case GF_FOP_TRUNCATE: + case GF_FOP_FTRUNCATE: + frame->root->flags |= MDATA_CTIME; + frame->root->flags |= MDATA_MTIME; + break; + + case GF_FOP_REMOVEXATTR: + case GF_FOP_FREMOVEXATTR: + frame->root->flags |= MDATA_CTIME; + break; + + default: + frame->root->flags = 0; + } +out: + return; +} diff --git a/xlators/features/utime/src/utime-helpers.h b/xlators/features/utime/src/utime-helpers.h new file mode 100644 index 00000000000..f526aecb063 --- /dev/null +++ b/xlators/features/utime/src/utime-helpers.h @@ -0,0 +1,24 @@ +/* + Copyright (c) 2018 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. +*/ + +#ifndef _UTIME_HELPERS_H +#define _UTIME_HELPERS_H + +#include "glusterfs-fops.h" +#include "stack.h" +#include "timespec.h" +#include + +void +gl_timespec_get (struct timespec *ts); +void +utime_update_attribute_flags(call_frame_t *frame, glusterfs_fop_t fop); + +#endif /* _UTIME_HELPERS_H */ diff --git a/xlators/features/utime/src/utime.c b/xlators/features/utime/src/utime.c new file mode 100644 index 00000000000..27a0e260ca4 --- /dev/null +++ b/xlators/features/utime/src/utime.c @@ -0,0 +1,229 @@ +/* + Copyright (c) 2018 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 "utime.h" + +int32_t +gf_utime_invalidate (xlator_t *this, + inode_t *inode) +{ + return 0; +} + + +int32_t +gf_utime_forget (xlator_t *this, + inode_t *inode) +{ + return 0; +} + + +int32_t +gf_utime_client_destroy (xlator_t *this, + client_t *client) +{ + return 0; +} + + +void +gf_utime_ictxmerge (xlator_t *this, + fd_t *fd, + inode_t *inode, + inode_t *linked_inode) +{ + return; +} + + +int32_t +gf_utime_release (xlator_t *this, + fd_t *fd) +{ + return 0; +} + + +int32_t +gf_utime_releasedir (xlator_t *this, + fd_t *fd) +{ + return 0; +} + + +int32_t +gf_utime_client_disconnect (xlator_t *this, + client_t *client) +{ + return 0; +} + + +int32_t +gf_utime_fdctx_to_dict (xlator_t *this, + fd_t *fd, + dict_t *dict) +{ + return 0; +} + + +int32_t +gf_utime_inode (xlator_t *this) +{ + return 0; +} + + +int32_t +gf_utime_inode_to_dict (xlator_t *this, + dict_t *dict) +{ + return 0; +} + + +int32_t +gf_utime_history (xlator_t *this) +{ + return 0; +} + + +int32_t +gf_utime_fd (xlator_t *this) +{ + return 0; +} + + +int32_t +gf_utime_fd_to_dict (xlator_t *this, + dict_t *dict) +{ + return 0; +} + + +int32_t +gf_utime_fdctx (xlator_t *this, + fd_t *fd) +{ + return 0; +} + + +int32_t +gf_utime_inodectx (xlator_t *this, + inode_t *ino) +{ + return 0; +} + + +int32_t +gf_utime_inodectx_to_dict (xlator_t *this, + inode_t *ino, + dict_t *dict) +{ + return 0; +} + + +int32_t +gf_utime_priv_to_dict (xlator_t *this, + dict_t *dict, char *brickname) +{ + return 0; +} + + +int32_t +gf_utime_priv (xlator_t *this) +{ + return 0; +} + + +int32_t +init (xlator_t *this) +{ + return 0; +} + +void +fini (xlator_t *this) +{ + return; +} + +int32_t +reconfigure (xlator_t *this, dict_t *dict) +{ + return 0; +} + +int +notify (xlator_t *this, int event, void *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, + .readlink = gf_utime_readlink, + .removexattr = gf_utime_removexattr, +}; +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, +}; +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, +}; diff --git a/xlators/features/utime/src/utime.h b/xlators/features/utime/src/utime.h new file mode 100644 index 00000000000..f8d5eca082e --- /dev/null +++ b/xlators/features/utime/src/utime.h @@ -0,0 +1,19 @@ +/* + Copyright (c) 2018 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. +*/ + +#ifndef __UTIME_H__ +#define __UTIME_H__ + +#include "glusterfs.h" +#include "xlator.h" +#include "defaults.h" +#include "utime-autogen-fops.h" + +#endif /* __UTIME_H__ */ -- cgit