summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKotresh HR <khiremat@redhat.com>2018-04-30 04:43:58 -0400
committerAmar Tumballi <amarts@redhat.com>2018-05-06 07:09:18 +0530
commit487aaafacac8af16c08eb44fe9bf178768d372fa (patch)
tree69a8ff6a8be0f40e129a71bf28ef5e4a558d5109
parentf8fe0771f0b450713595a7d298ed5a758cf2ce3e (diff)
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 <rkavunga@redhat.com> Updates: #208 Change-Id: I9cad297040c70798a0a8468a080eb4aeff73138d Signed-off-by: Kotresh HR <khiremat@redhat.com>
-rw-r--r--configure.ac2
-rw-r--r--glusterfs.spec.in1
-rw-r--r--xlators/features/Makefile.am3
-rw-r--r--xlators/features/utime/Makefile.am3
-rw-r--r--xlators/features/utime/src/Makefile.am39
-rw-r--r--xlators/features/utime/src/utime-autogen-fops-tmpl.c28
-rw-r--r--xlators/features/utime/src/utime-autogen-fops-tmpl.h22
-rw-r--r--xlators/features/utime/src/utime-gen-fops-c.py118
-rw-r--r--xlators/features/utime/src/utime-gen-fops-h.py34
-rw-r--r--xlators/features/utime/src/utime-helpers.c95
-rw-r--r--xlators/features/utime/src/utime-helpers.h24
-rw-r--r--xlators/features/utime/src/utime.c229
-rw-r--r--xlators/features/utime/src/utime.h19
13 files changed, 616 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac
index 63340e2c114..b818d3fac0d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -180,6 +180,8 @@ AC_CONFIG_FILES([Makefile
xlators/features/leases/src/Makefile
xlators/features/cloudsync/Makefile
xlators/features/cloudsync/src/Makefile
+ xlators/features/utime/Makefile
+ xlators/features/utime/src/Makefile
xlators/playground/Makefile
xlators/playground/template/Makefile
xlators/playground/template/src/Makefile
diff --git a/glusterfs.spec.in b/glusterfs.spec.in
index 0be94ca4e89..c03577d7695 100644
--- a/glusterfs.spec.in
+++ b/glusterfs.spec.in
@@ -1086,6 +1086,7 @@ exit 0
%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/barrier.so
%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/cdc.so
%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/changelog.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/utime.so
%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/gfid-access.so
%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/namespace.so
%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/read-only.so
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. <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.
+*/
+
+/* 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. <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.
+*/
+
+/* 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. <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 "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. <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 _UTIME_HELPERS_H
+#define _UTIME_HELPERS_H
+
+#include "glusterfs-fops.h"
+#include "stack.h"
+#include "timespec.h"
+#include <time.h>
+
+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. <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 "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. <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 __UTIME_H__
+#define __UTIME_H__
+
+#include "glusterfs.h"
+#include "xlator.h"
+#include "defaults.h"
+#include "utime-autogen-fops.h"
+
+#endif /* __UTIME_H__ */