summaryrefslogtreecommitdiffstats
path: root/INSTALL
Commit message (Expand)AuthorAgeFilesLines
* Added all filesVikas Gorur2009-02-181-0/+32
='1'>ssdiff
Diffstat (limited to 'libglusterfs')
-rw-r--r--libglusterfs/src/Makefile.am115
-rw-r--r--libglusterfs/src/async.c720
-rw-r--r--libglusterfs/src/byte-order.h310
-rw-r--r--libglusterfs/src/call-stub.c4661
-rw-r--r--libglusterfs/src/call-stub.h1116
-rw-r--r--libglusterfs/src/changelog.h115
-rw-r--r--libglusterfs/src/checksum.c84
-rw-r--r--libglusterfs/src/checksum.h27
-rw-r--r--libglusterfs/src/circ-buff.c193
-rw-r--r--libglusterfs/src/client_t.c825
-rw-r--r--libglusterfs/src/cluster-syncop.c1261
-rw-r--r--libglusterfs/src/common-utils.c6185
-rw-r--r--libglusterfs/src/common-utils.h366
-rw-r--r--libglusterfs/src/compat-errno.c1772
-rw-r--r--libglusterfs/src/compat-errno.h240
-rw-r--r--libglusterfs/src/compat.c927
-rw-r--r--libglusterfs/src/compat.h381
-rw-r--r--libglusterfs/src/ctx.c97
-rw-r--r--libglusterfs/src/daemon.c102
-rw-r--r--libglusterfs/src/daemon.h20
-rw-r--r--libglusterfs/src/default-args.c1651
-rw-r--r--libglusterfs/src/defaults-tmpl.c247
-rw-r--r--libglusterfs/src/defaults.c1261
-rw-r--r--libglusterfs/src/defaults.h680
-rw-r--r--libglusterfs/src/dict.c4479
-rw-r--r--libglusterfs/src/dict.h189
-rw-r--r--libglusterfs/src/event-epoll.c1032
-rw-r--r--libglusterfs/src/event-history.c82
-rw-r--r--libglusterfs/src/event-poll.c513
-rw-r--r--libglusterfs/src/event.c1083
-rw-r--r--libglusterfs/src/event.h90
-rw-r--r--libglusterfs/src/events.c136
-rw-r--r--libglusterfs/src/fd-lk.c433
-rw-r--r--libglusterfs/src/fd.c1593
-rw-r--r--libglusterfs/src/fd.h172
-rwxr-xr-xlibglusterfs/src/gen-defaults.py81
-rwxr-xr-xlibglusterfs/src/generator.py777
-rw-r--r--libglusterfs/src/gf-dirent.c327
-rw-r--r--libglusterfs/src/gf-dirent.h62
-rw-r--r--libglusterfs/src/gidcache.c211
-rw-r--r--libglusterfs/src/globals.c543
-rw-r--r--libglusterfs/src/globals.h59
-rw-r--r--libglusterfs/src/glusterfs.h381
-rw-r--r--libglusterfs/src/glusterfs/async.h209
-rw-r--r--libglusterfs/src/glusterfs/atomic.h459
-rw-r--r--libglusterfs/src/glusterfs/byte-order.h279
-rw-r--r--libglusterfs/src/glusterfs/call-stub.h622
-rw-r--r--libglusterfs/src/glusterfs/checksum.h22
-rw-r--r--libglusterfs/src/glusterfs/circ-buff.h61
-rw-r--r--libglusterfs/src/glusterfs/client_t.h147
-rw-r--r--libglusterfs/src/glusterfs/cluster-syncop.h227
-rw-r--r--libglusterfs/src/glusterfs/common-utils.h1256
-rw-r--r--libglusterfs/src/glusterfs/compat-errno.h238
-rw-r--r--libglusterfs/src/glusterfs/compat-uuid.h71
-rw-r--r--libglusterfs/src/glusterfs/compat.h544
-rw-r--r--libglusterfs/src/glusterfs/daemon.h20
-rw-r--r--libglusterfs/src/glusterfs/default-args.h455
-rw-r--r--libglusterfs/src/glusterfs/defaults.h1275
-rw-r--r--libglusterfs/src/glusterfs/dict.h420
-rw-r--r--libglusterfs/src/glusterfs/event-history.h40
-rw-r--r--libglusterfs/src/glusterfs/events.h34
-rw-r--r--libglusterfs/src/glusterfs/fd-lk.h59
-rw-r--r--libglusterfs/src/glusterfs/fd.h169
-rw-r--r--libglusterfs/src/glusterfs/gf-dirent.h71
-rw-r--r--libglusterfs/src/glusterfs/gf-event.h140
-rw-r--r--libglusterfs/src/glusterfs/gidcache.h60
-rw-r--r--libglusterfs/src/glusterfs/glfs-message-id.h102
-rw-r--r--libglusterfs/src/glusterfs/globals.h188
-rw-r--r--libglusterfs/src/glusterfs/glusterfs-acl.h162
-rw-r--r--libglusterfs/src/glusterfs/glusterfs-fops.h241
-rw-r--r--libglusterfs/src/glusterfs/glusterfs.h838
-rw-r--r--libglusterfs/src/glusterfs/graph-utils.h20
-rw-r--r--libglusterfs/src/glusterfs/hashfn.h23
-rw-r--r--libglusterfs/src/glusterfs/iatt.h489
-rw-r--r--libglusterfs/src/glusterfs/inode.h306
-rw-r--r--libglusterfs/src/glusterfs/iobuf.h194
-rw-r--r--libglusterfs/src/glusterfs/latency.h33
-rw-r--r--libglusterfs/src/glusterfs/libglusterfs-messages.h245
-rw-r--r--libglusterfs/src/glusterfs/list.h273
-rw-r--r--libglusterfs/src/glusterfs/lkowner.h93
-rw-r--r--libglusterfs/src/glusterfs/locking.h84
-rw-r--r--libglusterfs/src/glusterfs/logging.h383
-rw-r--r--libglusterfs/src/glusterfs/lvm-defaults.h20
-rw-r--r--libglusterfs/src/glusterfs/mem-pool.h336
-rw-r--r--libglusterfs/src/glusterfs/mem-types.h139
-rw-r--r--libglusterfs/src/glusterfs/monitoring.h21
-rw-r--r--libglusterfs/src/glusterfs/options.h327
-rw-r--r--libglusterfs/src/glusterfs/parse-utils.h50
-rw-r--r--libglusterfs/src/glusterfs/quota-common-utils.h68
-rw-r--r--libglusterfs/src/glusterfs/rbthash.h75
-rw-r--r--libglusterfs/src/glusterfs/refcount.h101
-rw-r--r--libglusterfs/src/glusterfs/revision.h1
-rw-r--r--libglusterfs/src/glusterfs/rot-buffs.h125
-rw-r--r--libglusterfs/src/glusterfs/run.h207
-rw-r--r--libglusterfs/src/glusterfs/stack.h555
-rw-r--r--libglusterfs/src/glusterfs/statedump.h132
-rw-r--r--libglusterfs/src/glusterfs/store.h112
-rw-r--r--libglusterfs/src/glusterfs/strfd.h34
-rw-r--r--libglusterfs/src/glusterfs/syncop-utils.h54
-rw-r--r--libglusterfs/src/glusterfs/syncop.h718
-rw-r--r--libglusterfs/src/glusterfs/syscall.h278
-rw-r--r--libglusterfs/src/glusterfs/template-component-messages.h28
-rw-r--r--libglusterfs/src/glusterfs/throttle-tbf.h74
-rw-r--r--libglusterfs/src/glusterfs/timer.h56
-rw-r--r--libglusterfs/src/glusterfs/timespec.h33
-rw-r--r--libglusterfs/src/glusterfs/trie.h52
-rw-r--r--libglusterfs/src/glusterfs/upcall-utils.h110
-rw-r--r--libglusterfs/src/glusterfs/xlator.h1106
-rw-r--r--libglusterfs/src/graph-mem-types.h31
-rw-r--r--libglusterfs/src/graph-print.c241
-rw-r--r--libglusterfs/src/graph-utils.h29
-rw-r--r--libglusterfs/src/graph.c2029
-rw-r--r--libglusterfs/src/graph.l66
-rw-r--r--libglusterfs/src/graph.y280
-rw-r--r--libglusterfs/src/hashfn.c288
-rw-r--r--libglusterfs/src/hashfn.h36
-rw-r--r--libglusterfs/src/iatt.h320
-rw-r--r--libglusterfs/src/inode.c3303
-rw-r--r--libglusterfs/src/inode.h187
-rw-r--r--libglusterfs/src/iobuf.c1418
-rw-r--r--libglusterfs/src/iobuf.h139
-rw-r--r--libglusterfs/src/latency.c205
-rw-r--r--libglusterfs/src/latency.h36
-rw-r--r--libglusterfs/src/libglusterfs.sym1193
-rw-r--r--libglusterfs/src/list.h187
-rw-r--r--libglusterfs/src/locking.c27
-rw-r--r--libglusterfs/src/locking.h49
-rw-r--r--libglusterfs/src/logging.c2747
-rw-r--r--libglusterfs/src/logging.h149
-rw-r--r--libglusterfs/src/mem-pool.c1185
-rw-r--r--libglusterfs/src/mem-pool.h164
-rw-r--r--libglusterfs/src/mem-types.h104
-rw-r--r--libglusterfs/src/monitoring.c282
-rw-r--r--libglusterfs/src/options.c1249
-rw-r--r--libglusterfs/src/parse-utils.c174
-rw-r--r--libglusterfs/src/quota-common-utils.c241
-rw-r--r--libglusterfs/src/rbthash.c657
-rw-r--r--libglusterfs/src/rbthash.h78
-rw-r--r--libglusterfs/src/refcount.c108
-rw-r--r--libglusterfs/src/revision.h1
-rw-r--r--libglusterfs/src/rot-buffs.c490
-rw-r--r--libglusterfs/src/run.c570
-rw-r--r--libglusterfs/src/scheduler.c91
-rw-r--r--libglusterfs/src/scheduler.h41
-rw-r--r--libglusterfs/src/stack.c586
-rw-r--r--libglusterfs/src/stack.h398
-rw-r--r--libglusterfs/src/statedump.c1191
-rw-r--r--libglusterfs/src/statedump.h90
-rw-r--r--libglusterfs/src/store.c744
-rw-r--r--libglusterfs/src/strfd.c93
-rw-r--r--libglusterfs/src/syncop-utils.c669
-rw-r--r--libglusterfs/src/syncop.c3658
-rw-r--r--libglusterfs/src/syncop.h176
-rw-r--r--libglusterfs/src/syscall.c790
-rw-r--r--libglusterfs/src/syscall.h148
-rw-r--r--libglusterfs/src/throttle-tbf.c290
-rw-r--r--libglusterfs/src/timer.c400
-rw-r--r--libglusterfs/src/timer.h70
-rw-r--r--libglusterfs/src/timespec.c129
-rw-r--r--libglusterfs/src/trie-mem-types.h34
-rw-r--r--libglusterfs/src/trie.c509
-rw-r--r--libglusterfs/src/trie.h60
-rw-r--r--libglusterfs/src/unittest/global_mock.c25
-rw-r--r--libglusterfs/src/unittest/log_mock.c52
-rw-r--r--libglusterfs/src/unittest/mem_pool_unittest.c483
-rw-r--r--libglusterfs/src/unittest/unittest.h47
-rw-r--r--libglusterfs/src/xlator.c3005
-rw-r--r--libglusterfs/src/xlator.h889
168 files changed, 58634 insertions, 25260 deletions
diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am
index b3df8518d57..385e8ef4600 100644
--- a/libglusterfs/src/Makefile.am
+++ b/libglusterfs/src/Makefile.am
@@ -1,21 +1,116 @@
-libglusterfs_la_CFLAGS = -fPIC -Wall -g -shared -nostartfiles $(GF_CFLAGS) $(GF_DARWIN_LIBGLUSTERFS_CFLAGS)
+noinst_PYTHON = generator.py gen-defaults.py $(top_srcdir)/events/eventskeygen.py
-libglusterfs_la_CPPFLAGS = -D_FILE_OFFSET_BITS=64 -D__USE_FILE_OFFSET64 -D_GNU_SOURCE -DXLATORDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator\" -D$(GF_HOST_OS) -I$(CONTRIBDIR)/rbtree -DSCHEDULERDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/scheduler\" -I$(CONTRIBDIR)/md5
+libglusterfs_la_CFLAGS = $(GF_CFLAGS) $(GF_DARWIN_LIBGLUSTERFS_CFLAGS) \
+ -DDATADIR=\"$(localstatedir)\"
-libglusterfs_la_LIBADD = @LEXLIB@
+libglusterfs_la_CPPFLAGS = $(GF_CPPFLAGS) -D__USE_FILE_OFFSET64 \
+ -DXLATORDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator\" \
+ -DXLATORPARENTDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)\" \
+ -DXXH_NAMESPACE=GF_ -D__USE_LARGEFILE64 \
+ -I$(CONTRIBDIR)/rbtree \
+ -I$(CONTRIBDIR)/libexecinfo ${ARGP_STANDALONE_CPPFLAGS} \
+ -DSBIN_DIR=\"$(sbindir)\" -I$(CONTRIBDIR)/timer-wheel \
+ -I$(CONTRIBDIR)/xxhash
+
+libglusterfs_la_LIBADD = $(ZLIB_LIBS) $(MATH_LIB) $(UUID_LIBS) $(LIB_DL) \
+ $(URCU_LIBS) $(URCU_CDS_LIBS)
+libglusterfs_la_LDFLAGS = -version-info $(LIBGLUSTERFS_LT_VERSION) $(GF_LDFLAGS) \
+ -export-symbols $(top_srcdir)/libglusterfs/src/libglusterfs.sym
lib_LTLIBRARIES = libglusterfs.la
+libgfchangelogdir = $(includedir)/glusterfs/gfchangelog
+
+CONTRIB_BUILDDIR = $(top_builddir)/contrib
+
+libglusterfs_la_SOURCES = dict.c xlator.c logging.c \
+ hashfn.c common-utils.c timer.c inode.c call-stub.c \
+ compat.c fd.c compat-errno.c event.c mem-pool.c gf-dirent.c syscall.c \
+ iobuf.c globals.c statedump.c stack.c checksum.c daemon.c timespec.c \
+ $(CONTRIBDIR)/rbtree/rb.c rbthash.c store.c latency.c \
+ graph.c syncop.c graph-print.c trie.c run.c options.c fd-lk.c \
+ circ-buff.c event-history.c gidcache.c ctx.c client_t.c event-poll.c \
+ event-epoll.c syncop-utils.c cluster-syncop.c refcount.c \
+ $(CONTRIBDIR)/libgen/basename_r.c \
+ $(CONTRIBDIR)/libgen/dirname_r.c \
+ strfd.c parse-utils.c $(CONTRIBDIR)/mount/mntent.c \
+ $(CONTRIBDIR)/libexecinfo/execinfo.c quota-common-utils.c rot-buffs.c \
+ $(CONTRIBDIR)/timer-wheel/timer-wheel.c \
+ $(CONTRIBDIR)/timer-wheel/find_last_bit.c default-args.c locking.c \
+ $(CONTRIBDIR)/xxhash/xxhash.c \
+ throttle-tbf.c monitoring.c async.c
+
+nodist_libglusterfs_la_SOURCES = y.tab.c graph.lex.c defaults.c
+nodist_libglusterfs_la_HEADERS = y.tab.h
+
+BUILT_SOURCES = graph.lex.c defaults.c eventtypes.h
+
+libglusterfs_la_HEADERS = glusterfs/common-utils.h glusterfs/defaults.h \
+ glusterfs/default-args.h glusterfs/dict.h glusterfs/glusterfs.h \
+ glusterfs/hashfn.h glusterfs/timespec.h glusterfs/logging.h \
+ glusterfs/xlator.h glusterfs/stack.h glusterfs/timer.h glusterfs/list.h \
+ glusterfs/inode.h glusterfs/call-stub.h glusterfs/compat.h glusterfs/fd.h \
+ glusterfs/revision.h glusterfs/compat-errno.h glusterfs/gf-event.h \
+ glusterfs/mem-pool.h glusterfs/byte-order.h glusterfs/gf-dirent.h \
+ glusterfs/locking.h glusterfs/syscall.h glusterfs/iobuf.h \
+ glusterfs/globals.h glusterfs/statedump.h glusterfs/checksum.h \
+ glusterfs/daemon.h glusterfs/store.h glusterfs/rbthash.h glusterfs/iatt.h \
+ glusterfs/latency.h glusterfs/mem-types.h glusterfs/syncop.h \
+ glusterfs/cluster-syncop.h glusterfs/graph-utils.h glusterfs/trie.h \
+ glusterfs/refcount.h glusterfs/run.h glusterfs/options.h \
+ glusterfs/lkowner.h glusterfs/fd-lk.h glusterfs/circ-buff.h \
+ glusterfs/event-history.h glusterfs/gidcache.h glusterfs/client_t.h \
+ glusterfs/glusterfs-acl.h glusterfs/glfs-message-id.h \
+ glusterfs/template-component-messages.h glusterfs/strfd.h \
+ glusterfs/syncop-utils.h glusterfs/parse-utils.h \
+ glusterfs/libglusterfs-messages.h glusterfs/lvm-defaults.h \
+ glusterfs/quota-common-utils.h glusterfs/rot-buffs.h \
+ glusterfs/compat-uuid.h glusterfs/upcall-utils.h glusterfs/throttle-tbf.h \
+ glusterfs/events.h glusterfs/atomic.h glusterfs/monitoring.h \
+ glusterfs/async.h glusterfs/glusterfs-fops.h
-libglusterfs_la_SOURCES = dict.c graph.lex.c y.tab.c xlator.c logging.c hashfn.c defaults.c common-utils.c timer.c inode.c call-stub.c compat.c fd.c compat-errno.c event.c mem-pool.c gf-dirent.c syscall.c iobuf.c globals.c statedump.c stack.c checksum.c $(CONTRIBDIR)/md5/md5.c $(CONTRIBDIR)/rbtree/rb.c rbthash.c latency.c graph.c $(CONTRIBDIR)/uuid/clear.c $(CONTRIBDIR)/uuid/copy.c $(CONTRIBDIR)/uuid/gen_uuid.c $(CONTRIBDIR)/uuid/pack.c $(CONTRIBDIR)/uuid/parse.c $(CONTRIBDIR)/uuid/unparse.c $(CONTRIBDIR)/uuid/uuid_time.c $(CONTRIBDIR)/uuid/compare.c $(CONTRIBDIR)/uuid/isnull.c $(CONTRIBDIR)/uuid/unpack.c syncop.c graph-print.c trie.c daemon.c
+libglusterfs_ladir = $(includedir)/glusterfs
-noinst_HEADERS = common-utils.h defaults.h dict.h glusterfs.h hashfn.h logging.h xlator.h stack.h timer.h list.h inode.h call-stub.h compat.h fd.h revision.h compat-errno.h event.h mem-pool.h byte-order.h gf-dirent.h locking.h syscall.h iobuf.h globals.h statedump.h checksum.h $(CONTRIBDIR)/md5/md5.h $(CONTRIBDIR)/rbtree/rb.h rbthash.h iatt.h latency.h mem-types.h $(CONTRIBDIR)/uuid/uuidd.h $(CONTRIBDIR)/uuid/uuid.h $(CONTRIBDIR)/uuid/uuidP.h $(CONTRIBDIR)/uuid/uuid_types.h syncop.h graph-utils.h graph-mem-types.h trie.h trie-mem-types.h daemon.h
+noinst_HEADERS = unittest/unittest.h \
+ $(CONTRIBDIR)/rbtree/rb.h \
+ $(CONTRIBDIR)/mount/mntent_compat.h \
+ $(CONTRIBDIR)/libexecinfo/execinfo_compat.h \
+ $(CONTRIBDIR)/timer-wheel/timer-wheel.h \
+ $(CONTRIBDIR)/xxhash/xxhash.h \
+ $(CONTRIBDIR)/userspace-rcu/wfcqueue.h \
+ $(CONTRIBDIR)/userspace-rcu/wfstack.h \
+ $(CONTRIBDIR)/userspace-rcu/static-wfcqueue.h \
+ $(CONTRIBDIR)/userspace-rcu/static-wfstack.h
-EXTRA_DIST = graph.l graph.y
+eventtypes.h: $(top_srcdir)/events/eventskeygen.py
+ $(PYTHON) $(top_srcdir)/events/eventskeygen.py C_HEADER
+
+if BUILD_EVENTS
+libglusterfs_la_SOURCES += events.c
+endif
+
+libgfchangelog_HEADERS = changelog.h
+
+EXTRA_DIST = graph.l graph.y defaults-tmpl.c libglusterfs.sym
graph.lex.c: graph.l y.tab.h
- $(LEX) -t $(srcdir)/graph.l > $@
+ $(LEX) -Pgraphyy -t $(srcdir)/graph.l > $@
+
+y.tab.c: y.tab.h
+y.tab.h: graph.y
+ $(YACC) -p graphyy -d $(srcdir)/graph.y
+
+defaults.c: defaults-tmpl.c generator.py gen-defaults.py
+ $(PYTHON) $(srcdir)/gen-defaults.py $(srcdir)/defaults-tmpl.c > $@
+
+CLEANFILES = $(nodist_libglusterfs_la_SOURCES) \
+ $(nodist_libglusterfs_la_HEADERS) *.pyc
-y.tab.c y.tab.h: graph.y
- $(YACC) -d $(srcdir)/graph.y
+if UNITTEST
+CLEANFILES += *.gcda *.gcno *_xunit.xml
+noinst_PROGRAMS =
+TESTS =
+endif
-CLEANFILES = graph.lex.c y.tab.c y.tab.h
+if BUILD_EVENTS
+CLEANFILES += eventtypes.h
+endif
diff --git a/libglusterfs/src/async.c b/libglusterfs/src/async.c
new file mode 100644
index 00000000000..1d6cfa374b6
--- /dev/null
+++ b/libglusterfs/src/async.c
@@ -0,0 +1,720 @@
+/*
+ Copyright (c) 2019 Red Hat, Inc <https://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.
+*/
+
+/* To implement an efficient thread pool with minimum contention we have used
+ * the following ideas:
+ *
+ * - The queue of jobs has been implemented using a Wait-Free queue provided
+ * by the userspace-rcu library. This queue requires a mutex when multiple
+ * consumers can be extracting items from it concurrently, but the locked
+ * region is very small, which minimizes the chances of contention. To
+ * further minimize contention, the number of active worker threads that
+ * are accessing the queue is dynamically adjusted so that we always have
+ * the minimum required amount of workers contending for the queue. Adding
+ * new items can be done with a single atomic operation, without locks.
+ *
+ * - All queue management operations, like creating more threads, enabling
+ * sleeping ones, etc. are done by a single thread. This makes it possible
+ * to manage all scaling related information and workers lists without
+ * locks. This functionality is implemented as a role that can be assigned
+ * to any of the worker threads, which avoids that some lengthy operations
+ * could interfere with this task.
+ *
+ * - Management is based on signals. We used signals for management tasks to
+ * avoid multiple system calls for each request (with signals we can wait
+ * for multiple events and get some additional data for each request in a
+ * single call, instead of first polling and then reading).
+ *
+ * TODO: There are some other changes that can take advantage of this new
+ * thread pool.
+ *
+ * - Use this thread pool as the core threading model for synctasks. I
+ * think this would improve synctask performance because I think we
+ * currently have some contention there for some workloads.
+ *
+ * - Implement a per thread timer that will allow adding and removing
+ * timers without using mutexes.
+ *
+ * - Integrate with userspace-rcu library in QSBR mode, allowing
+ * other portions of code to be implemented using RCU-based
+ * structures with a extremely fast read side without contention.
+ *
+ * - Integrate I/O into the thread pool so that the thread pool is
+ * able to efficiently manage all loads and scale dynamically. This
+ * could make it possible to minimize context switching when serving
+ * requests from fuse or network.
+ *
+ * - Dynamically scale the number of workers based on system load.
+ * This will make it possible to reduce contention when system is
+ * heavily loaded, improving performance under these circumstances
+ * (or minimizing performance loss). This will also make it possible
+ * that gluster can coexist with other processes that also consume
+ * CPU, with minimal interference from each other.
+ */
+
+#include <unistd.h>
+#include <pthread.h>
+#include <errno.h>
+
+#include "glusterfs/list.h"
+#include "glusterfs/mem-types.h"
+#include "glusterfs/async.h"
+
+/* These macros wrap a simple system/library call to check the returned error
+ * and log a message in case of failure. */
+#define GF_ASYNC_CHECK(_func, _args...) \
+ ({ \
+ int32_t __async_error = -_func(_args); \
+ if (caa_unlikely(__async_error != 0)) { \
+ gf_async_error(__async_error, #_func "() failed."); \
+ } \
+ __async_error; \
+ })
+
+#define GF_ASYNC_CHECK_ERRNO(_func, _args...) \
+ ({ \
+ int32_t __async_error = _func(_args); \
+ if (caa_unlikely(__async_error < 0)) { \
+ __async_error = -errno; \
+ gf_async_error(__async_error, #_func "() failed."); \
+ } \
+ __async_error; \
+ })
+
+/* These macros are used when, based on POSIX documentation, the function
+ * should never fail under the conditions we are using it. So any unexpected
+ * error will be handled as a fatal event. It probably means a critical bug
+ * or memory corruption. In both cases we consider that stopping the process
+ * is safer (otherwise it could cause more corruption with unknown effects
+ * that could be worse). */
+#define GF_ASYNC_CANTFAIL(_func, _args...) \
+ do { \
+ int32_t __async_error = -_func(_args); \
+ if (caa_unlikely(__async_error != 0)) { \
+ gf_async_fatal(__async_error, #_func "() failed"); \
+ } \
+ } while (0)
+
+#define GF_ASYNC_CANTFAIL_ERRNO(_func, _args...) \
+ ({ \
+ int32_t __async_error = _func(_args); \
+ if (caa_unlikely(__async_error < 0)) { \
+ __async_error = -errno; \
+ gf_async_fatal(__async_error, #_func "() failed"); \
+ } \
+ __async_error; \
+ })
+
+/* TODO: for now we allocate a static array of workers. There's an issue if we
+ * try to use dynamic memory since these workers are initialized very
+ * early in the process startup and it seems that sometimes not all is
+ * ready to use dynamic memory. */
+static gf_async_worker_t gf_async_workers[GF_ASYNC_MAX_THREADS];
+
+/* This is the only global variable needed to manage the entire framework. */
+gf_async_control_t gf_async_ctrl = {};
+
+static __thread gf_async_worker_t *gf_async_current_worker = NULL;
+
+/* The main function of the worker threads. */
+static void *
+gf_async_worker(void *arg);
+
+static void
+gf_async_sync_init(void)
+{
+ GF_ASYNC_CANTFAIL(pthread_barrier_init, &gf_async_ctrl.sync, NULL, 2);
+}
+
+static void
+gf_async_sync_now(void)
+{
+ int32_t ret;
+
+ ret = pthread_barrier_wait(&gf_async_ctrl.sync);
+ if (ret == PTHREAD_BARRIER_SERIAL_THREAD) {
+ GF_ASYNC_CANTFAIL(pthread_barrier_destroy, &gf_async_ctrl.sync);
+ ret = 0;
+ }
+ if (caa_unlikely(ret != 0)) {
+ gf_async_fatal(-ret, "pthread_barrier_wait() failed");
+ }
+}
+
+static void
+gf_async_sigmask_empty(sigset_t *mask)
+{
+ GF_ASYNC_CANTFAIL_ERRNO(sigemptyset, mask);
+}
+
+static void
+gf_async_sigmask_add(sigset_t *mask, int32_t signal)
+{
+ GF_ASYNC_CANTFAIL_ERRNO(sigaddset, mask, signal);
+}
+
+static void
+gf_async_sigmask_set(int32_t mode, sigset_t *mask, sigset_t *old)
+{
+ GF_ASYNC_CANTFAIL(pthread_sigmask, mode, mask, old);
+}
+
+static void
+gf_async_sigaction(int32_t signum, const struct sigaction *action,
+ struct sigaction *old)
+{
+ GF_ASYNC_CANTFAIL_ERRNO(sigaction, signum, action, old);
+}
+
+static int32_t
+gf_async_sigwait(sigset_t *set)
+{
+ int32_t ret, signum;
+
+ do {
+ ret = sigwait(set, &signum);
+ } while (caa_unlikely((ret < 0) && (errno == EINTR)));
+
+ if (caa_unlikely(ret < 0)) {
+ ret = -errno;
+ gf_async_fatal(ret, "sigwait() failed");
+ }
+
+ return signum;
+}
+
+static int32_t
+gf_async_sigtimedwait(sigset_t *set, struct timespec *timeout)
+{
+ int32_t ret;
+
+ do {
+ ret = sigtimedwait(set, NULL, timeout);
+ } while (caa_unlikely((ret < 0) && (errno == EINTR)));
+ if (caa_unlikely(ret < 0)) {
+ ret = -errno;
+ /* EAGAIN means that the timeout has expired, so we allow this error.
+ * Any other error shouldn't happen. */
+ if (caa_unlikely(ret != -EAGAIN)) {
+ gf_async_fatal(ret, "sigtimedwait() failed");
+ }
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static void
+gf_async_sigbroadcast(int32_t signum)
+{
+ GF_ASYNC_CANTFAIL_ERRNO(kill, gf_async_ctrl.pid, signum);
+}
+
+static void
+gf_async_signal_handler(int32_t signum)
+{
+ /* We should never handle a signal in this function. */
+ gf_async_fatal(-EBUSY,
+ "Unexpected processing of signal %d through a handler.",
+ signum);
+}
+
+static void
+gf_async_signal_setup(void)
+{
+ struct sigaction action;
+
+ /* We configure all related signals so that we can detect threads using an
+ * invalid signal mask that doesn't block our critical signal. */
+ memset(&action, 0, sizeof(action));
+ action.sa_handler = gf_async_signal_handler;
+
+ gf_async_sigaction(GF_ASYNC_SIGCTRL, &action, &gf_async_ctrl.handler_ctrl);
+
+ gf_async_sigaction(GF_ASYNC_SIGQUEUE, &action,
+ &gf_async_ctrl.handler_queue);
+}
+
+static void
+gf_async_signal_restore(void)
+{
+ /* Handlers we have previously changed are restored back to their original
+ * value. */
+
+ if (gf_async_ctrl.handler_ctrl.sa_handler != gf_async_signal_handler) {
+ gf_async_sigaction(GF_ASYNC_SIGCTRL, &gf_async_ctrl.handler_ctrl, NULL);
+ }
+
+ if (gf_async_ctrl.handler_queue.sa_handler != gf_async_signal_handler) {
+ gf_async_sigaction(GF_ASYNC_SIGQUEUE, &gf_async_ctrl.handler_queue,
+ NULL);
+ }
+}
+
+static void
+gf_async_signal_flush(void)
+{
+ struct timespec delay;
+
+ delay.tv_sec = 0;
+ delay.tv_nsec = 0;
+
+ /* We read all pending signals so that they don't trigger once the signal
+ * mask of some thread is changed. */
+ while (gf_async_sigtimedwait(&gf_async_ctrl.sigmask_ctrl, &delay) > 0) {
+ }
+ while (gf_async_sigtimedwait(&gf_async_ctrl.sigmask_queue, &delay) > 0) {
+ }
+}
+
+static int32_t
+gf_async_thread_create(pthread_t *thread, int32_t id, void *data)
+{
+ int32_t ret;
+
+ ret = gf_thread_create(thread, NULL, gf_async_worker, data,
+ GF_ASYNC_THREAD_NAME "%u", id);
+ if (caa_unlikely(ret < 0)) {
+ /* TODO: gf_thread_create() should return a more specific error
+ * code. */
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static void
+gf_async_thread_wait(pthread_t thread)
+{
+ /* TODO: this is a blocking call executed inside one of the workers of the
+ * thread pool. This is bad, but this is only executed once we have
+ * received a notification from the thread that it's terminating, so
+ * this should return almost immediately. However, to be more robust
+ * it would be better to use pthread_timedjoin_np() (or even a call
+ * to pthread_tryjoin_np() followed by a delayed recheck if it
+ * fails), but they are not portable. We should see how to do this
+ * in other platforms. */
+ GF_ASYNC_CANTFAIL(pthread_join, thread, NULL);
+}
+
+static int32_t
+gf_async_worker_create(void)
+{
+ struct cds_wfs_node *node;
+ gf_async_worker_t *worker;
+ uint32_t counts, running, max;
+ int32_t ret;
+
+ node = __cds_wfs_pop_blocking(&gf_async_ctrl.available);
+ if (caa_unlikely(node == NULL)) {
+ /* There are no more available workers. We have all threads running. */
+ return 1;
+ }
+ cds_wfs_node_init(node);
+
+ ret = 1;
+
+ counts = uatomic_read(&gf_async_ctrl.counts);
+ max = uatomic_read(&gf_async_ctrl.max_threads);
+ running = GF_ASYNC_COUNT_RUNNING(counts);
+ if (running < max) {
+ uatomic_add(&gf_async_ctrl.counts, GF_ASYNC_COUNTS(1, 0));
+
+ worker = caa_container_of(node, gf_async_worker_t, stack);
+
+ ret = gf_async_thread_create(&worker->thread, worker->id, worker);
+ if (caa_likely(ret >= 0)) {
+ return 0;
+ }
+
+ uatomic_add(&gf_async_ctrl.counts, GF_ASYNC_COUNTS(-1, 0));
+ }
+
+ cds_wfs_push(&gf_async_ctrl.available, node);
+
+ return ret;
+}
+
+static void
+gf_async_worker_enable(void)
+{
+ /* This will wake one of the spare workers. If all workers are busy now,
+ * the signal will be queued so that the first one that completes its
+ * work will become the leader. */
+ gf_async_sigbroadcast(GF_ASYNC_SIGCTRL);
+
+ /* We have consumed a spare worker. We create another one for future
+ * needs. */
+ gf_async_worker_create();
+}
+
+static void
+gf_async_worker_wait(void)
+{
+ int32_t signum;
+
+ signum = gf_async_sigwait(&gf_async_ctrl.sigmask_ctrl);
+ if (caa_unlikely(signum != GF_ASYNC_SIGCTRL)) {
+ gf_async_fatal(-EINVAL, "Worker received an unexpected signal (%d)",
+ signum);
+ }
+}
+
+static void
+gf_async_leader_wait(void)
+{
+ int32_t signum;
+
+ signum = gf_async_sigwait(&gf_async_ctrl.sigmask_queue);
+ if (caa_unlikely(signum != GF_ASYNC_SIGQUEUE)) {
+ gf_async_fatal(-EINVAL, "Leader received an unexpected signal (%d)",
+ signum);
+ }
+}
+
+static void
+gf_async_run(struct cds_wfcq_node *node)
+{
+ gf_async_t *async;
+
+ /* We've just got work from the queue. Process it. */
+ async = caa_container_of(node, gf_async_t, queue);
+ /* TODO: remove dependency from THIS and xl. */
+ THIS = async->xl;
+ async->cbk(async->xl, async);
+}
+
+static void
+gf_async_worker_run(void)
+{
+ struct cds_wfcq_node *node;
+
+ do {
+ /* We keep executing jobs from the queue while it's not empty. Note
+ * that while we do this, we are ignoring any stop request. That's
+ * fine, since we need to process our own 'join' messages to fully
+ * terminate all threads. Note that normal jobs should have already
+ * completed once a stop request is received. */
+ node = cds_wfcq_dequeue_blocking(&gf_async_ctrl.queue.head,
+ &gf_async_ctrl.queue.tail);
+ if (node != NULL) {
+ gf_async_run(node);
+ }
+ } while (node != NULL);
+
+ /* TODO: I've tried to keep the worker looking at the queue for some small
+ * amount of time in a busy loop to see if more jobs come soon. With
+ * this I attempted to avoid the overhead of signal management if
+ * jobs come fast enough. However experimental results seem to
+ * indicate that doing this, CPU utilization grows and performance
+ * is actually reduced. We need to see if that's because I used bad
+ * parameters or it's really better to do it as it's done now. */
+}
+
+static void
+gf_async_leader_run(void)
+{
+ struct cds_wfcq_node *node;
+
+ node = cds_wfcq_dequeue_blocking(&gf_async_ctrl.queue.head,
+ &gf_async_ctrl.queue.tail);
+ while (caa_unlikely(node == NULL)) {
+ gf_async_leader_wait();
+
+ node = cds_wfcq_dequeue_blocking(&gf_async_ctrl.queue.head,
+ &gf_async_ctrl.queue.tail);
+ }
+
+ /* Activate the next available worker thread. It will become the new
+ * leader. */
+ gf_async_worker_enable();
+
+ gf_async_run(node);
+}
+
+static uint32_t
+gf_async_stop_check(gf_async_worker_t *worker)
+{
+ uint32_t counts, old, running, max;
+
+ /* First we check if we should stop without doing any costly atomic
+ * operation. */
+ old = uatomic_read(&gf_async_ctrl.counts);
+ max = uatomic_read(&gf_async_ctrl.max_threads);
+ running = GF_ASYNC_COUNT_RUNNING(old);
+ while (running > max) {
+ /* There are too many threads. We try to stop the current worker. */
+ counts = uatomic_cmpxchg(&gf_async_ctrl.counts, old,
+ old + GF_ASYNC_COUNTS(-1, 1));
+ if (old != counts) {
+ /* Another thread has just updated the counts. We need to retry. */
+ old = counts;
+ running = GF_ASYNC_COUNT_RUNNING(old);
+
+ continue;
+ }
+
+ running--;
+ worker->running = false;
+ }
+
+ return running;
+}
+
+static void
+gf_async_stop_all(xlator_t *xl, gf_async_t *async)
+{
+ if (gf_async_stop_check(gf_async_current_worker) > 0) {
+ /* There are more workers running. We propagate the stop request to
+ * them. */
+ gf_async(async, xl, gf_async_stop_all);
+ }
+}
+
+static void
+gf_async_join(xlator_t *xl, gf_async_t *async)
+{
+ gf_async_worker_t *worker;
+
+ worker = caa_container_of(async, gf_async_worker_t, async);
+
+ gf_async_thread_wait(worker->thread);
+
+ cds_wfs_push(&gf_async_ctrl.available, &worker->stack);
+}
+
+static void
+gf_async_terminate(gf_async_worker_t *worker)
+{
+ uint32_t counts;
+
+ counts = uatomic_add_return(&gf_async_ctrl.counts, GF_ASYNC_COUNTS(0, -1));
+ if (counts == 0) {
+ /* This is the termination of the last worker thread. We need to
+ * synchronize the main thread that is waiting for all workers to
+ * finish. */
+ gf_async_ctrl.sync_thread = worker->thread;
+
+ gf_async_sync_now();
+ } else {
+ /* Force someone else to join this thread to release resources. */
+ gf_async(&worker->async, THIS, gf_async_join);
+ }
+}
+
+static void *
+gf_async_worker(void *arg)
+{
+ gf_async_worker_t *worker;
+
+ worker = (gf_async_worker_t *)arg;
+ gf_async_current_worker = worker;
+
+ worker->running = true;
+ do {
+ /* This thread does nothing until someone enables it to become a
+ * leader. */
+ gf_async_worker_wait();
+
+ /* This thread is now a leader. It will process jobs from the queue
+ * and, if necessary, enable another worker and transfer leadership
+ * to it. */
+ gf_async_leader_run();
+
+ /* This thread is not a leader anymore. It will continue processing
+ * queued jobs until it becomes empty. */
+ gf_async_worker_run();
+
+ /* Stop the current thread if there are too many threads running. */
+ gf_async_stop_check(worker);
+ } while (worker->running);
+
+ gf_async_terminate(worker);
+
+ return NULL;
+}
+
+static void
+gf_async_cleanup(void)
+{
+ /* We do some basic initialization of the global variable 'gf_async_ctrl'
+ * so that it's put into a relatively consistent state. */
+
+ gf_async_ctrl.enabled = false;
+
+ gf_async_ctrl.pid = 0;
+ gf_async_sigmask_empty(&gf_async_ctrl.sigmask_ctrl);
+ gf_async_sigmask_empty(&gf_async_ctrl.sigmask_queue);
+
+ /* This is used to later detect if the handler of these signals have been
+ * changed or not. */
+ gf_async_ctrl.handler_ctrl.sa_handler = gf_async_signal_handler;
+ gf_async_ctrl.handler_queue.sa_handler = gf_async_signal_handler;
+
+ gf_async_ctrl.table = NULL;
+ gf_async_ctrl.max_threads = 0;
+ gf_async_ctrl.counts = 0;
+}
+
+void
+gf_async_fini(void)
+{
+ gf_async_t async;
+
+ if (uatomic_read(&gf_async_ctrl.counts) != 0) {
+ /* We ensure that all threads will quit on the next check. */
+ gf_async_ctrl.max_threads = 0;
+
+ /* Send the stop request to the thread pool. This will cause the
+ * execution of gf_async_stop_all() by one of the worker threads which,
+ * eventually, will terminate all worker threads. */
+ gf_async(&async, THIS, gf_async_stop_all);
+
+ /* We synchronize here with the last thread. */
+ gf_async_sync_now();
+
+ /* We have just synchronized with the latest thread. Now just wait for
+ * it to terminate. */
+ gf_async_thread_wait(gf_async_ctrl.sync_thread);
+
+ gf_async_signal_flush();
+ }
+
+ gf_async_signal_restore();
+
+ gf_async_cleanup();
+}
+
+void
+gf_async_adjust_threads(int32_t threads)
+{
+ if (threads == 0) {
+ /* By default we allow a maximum of 2 * #cores worker threads. This
+ * value is to try to accommodate threads that will do some I/O. Having
+ * more threads than cores we can keep CPU busy even if some threads
+ * are blocked for I/O. In the most efficient case, we can have #cores
+ * computing threads and #cores blocked threads on I/O. However this is
+ * hard to achieve because we can end with more than #cores computing
+ * threads, which won't provide a real benefit and will increase
+ * contention.
+ *
+ * TODO: implement a more intelligent dynamic maximum based on CPU
+ * usage and/or system load. */
+ threads = sysconf(_SC_NPROCESSORS_ONLN) * 2;
+ if (threads < 0) {
+ /* If we can't get the current number of processors, we pick a
+ * random number. */
+ threads = 16;
+ }
+ }
+ if (threads > GF_ASYNC_MAX_THREADS) {
+ threads = GF_ASYNC_MAX_THREADS;
+ }
+ uatomic_set(&gf_async_ctrl.max_threads, threads);
+}
+
+int32_t
+gf_async_init(glusterfs_ctx_t *ctx)
+{
+ sigset_t set;
+ gf_async_worker_t *worker;
+ uint32_t i;
+ int32_t ret;
+ bool running;
+
+ gf_async_cleanup();
+
+ if (!ctx->cmd_args.global_threading ||
+ (ctx->process_mode == GF_GLUSTERD_PROCESS)) {
+ return 0;
+ }
+
+ /* At the init time, the maximum number of threads has not yet been
+ * configured. We use a small starting value that will be layer dynamically
+ * adjusted when ctx->config.max_threads is updated. */
+ gf_async_adjust_threads(GF_ASYNC_SPARE_THREADS + 1);
+
+ gf_async_ctrl.pid = getpid();
+
+ __cds_wfs_init(&gf_async_ctrl.available);
+ cds_wfcq_init(&gf_async_ctrl.queue.head, &gf_async_ctrl.queue.tail);
+
+ gf_async_sync_init();
+
+ /* TODO: it would be cleaner to use dynamic memory, but at this point some
+ * memory management resources are not yet initialized. */
+ gf_async_ctrl.table = gf_async_workers;
+
+ /* We keep all workers in a stack. It will be used when a new thread needs
+ * to be created. */
+ for (i = GF_ASYNC_MAX_THREADS; i > 0; i--) {
+ worker = &gf_async_ctrl.table[i - 1];
+
+ worker->id = i - 1;
+ cds_wfs_node_init(&worker->stack);
+ cds_wfs_push(&gf_async_ctrl.available, &worker->stack);
+ }
+
+ /* Prepare the signal mask for regular workers and the leader. */
+ gf_async_sigmask_add(&gf_async_ctrl.sigmask_ctrl, GF_ASYNC_SIGCTRL);
+ gf_async_sigmask_add(&gf_async_ctrl.sigmask_queue, GF_ASYNC_SIGQUEUE);
+
+ /* TODO: this is needed to block our special signals in the current thread
+ * and all children that it starts. It would be cleaner to do it when
+ * signals are initialized, but there doesn't seem to be a unique
+ * place to do that, so for now we do it here. */
+ gf_async_sigmask_empty(&set);
+ gf_async_sigmask_add(&set, GF_ASYNC_SIGCTRL);
+ gf_async_sigmask_add(&set, GF_ASYNC_SIGQUEUE);
+ gf_async_sigmask_set(SIG_BLOCK, &set, NULL);
+
+ /* Configure the signal handlers. This is mostly for safety, not really
+ * needed, but it doesn't hurt. Note that the caller must ensure that the
+ * signals we need to run are already blocked in any thread already
+ * started. Otherwise this won't work. */
+ gf_async_signal_setup();
+
+ running = false;
+
+ /* We start the spare workers + 1 for the leader. */
+ for (i = 0; i < GF_ASYNC_SPARE_THREADS; i++) {
+ ret = gf_async_worker_create();
+ if (caa_unlikely(ret < 0)) {
+ /* This is the initial start up so we enforce that the spare
+ * threads are created. If this fails at the beginning, it's very
+ * unlikely that the async workers could do its job, so we abort
+ * the initialization. */
+ goto out;
+ }
+
+ /* Once the first thread is started, we can enable it to become the
+ * initial leader. */
+ if ((ret == 0) && !running) {
+ running = true;
+ gf_async_worker_enable();
+ }
+ }
+
+ if (caa_unlikely(!running)) {
+ gf_async_fatal(-ENOMEM, "No worker thread has started");
+ }
+
+ gf_async_ctrl.enabled = true;
+
+ ret = 0;
+
+out:
+ if (ret < 0) {
+ gf_async_error(ret, "Unable to initialize the thread pool.");
+ gf_async_fini();
+ }
+
+ return ret;
+}
diff --git a/libglusterfs/src/byte-order.h b/libglusterfs/src/byte-order.h
deleted file mode 100644
index e325e522df8..00000000000
--- a/libglusterfs/src/byte-order.h
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _BYTE_ORDER_H
-#define _BYTE_ORDER_H
-
-#include <inttypes.h>
-
-#define LS1 0x00ffU
-#define MS1 0xff00U
-#define LS2 0x0000ffffU
-#define MS2 0xffff0000U
-#define LS4 0x00000000ffffffffULL
-#define MS4 0xffffffff00000000ULL
-
-
-static uint16_t (*hton16) (uint16_t);
-static uint32_t (*hton32) (uint32_t);
-static uint64_t (*hton64) (uint64_t);
-
-#define ntoh16 hton16
-#define ntoh32 hton32
-#define ntoh64 hton64
-
-static uint16_t (*htole16) (uint16_t);
-static uint32_t (*htole32) (uint32_t);
-static uint64_t (*htole64) (uint64_t);
-
-#define letoh16 htole16
-#define letoh32 htole32
-#define letoh64 htole64
-
-static uint16_t (*htobe16) (uint16_t);
-static uint32_t (*htobe32) (uint32_t);
-static uint64_t (*htobe64) (uint64_t);
-
-#define betoh16 htobe16
-#define betoh32 htobe32
-#define betoh64 htobe64
-
-
-#define do_swap2(x) (((x&LS1) << 8)|(((x&MS1) >> 8)))
-#define do_swap4(x) ((do_swap2(x&LS2) << 16)|(do_swap2((x&MS2) >> 16)))
-#define do_swap8(x) ((do_swap4(x&LS4) << 32)|(do_swap4((x&MS4) >> 32)))
-
-
-static inline uint16_t
-__swap16 (uint16_t x)
-{
- return do_swap2(x);
-}
-
-
-static inline uint32_t
-__swap32 (uint32_t x)
-{
- return do_swap4(x);
-}
-
-
-static inline uint64_t
-__swap64 (uint64_t x)
-{
- return do_swap8(x);
-}
-
-
-static inline uint16_t
-__noswap16 (uint16_t x)
-{
- return x;
-}
-
-
-static inline uint32_t
-__noswap32 (uint32_t x)
-{
- return x;
-}
-
-
-static inline uint64_t
-__noswap64 (uint64_t x)
-{
- return x;
-}
-
-
-static inline uint16_t
-__byte_order_n16 (uint16_t i)
-{
- uint32_t num = 1;
-
- if (((char *)(&num))[0] == 1) {
- /* cpu is le */
- hton16 = __swap16;
- hton32 = __swap32;
- hton64 = __swap64;
- } else {
- /* cpu is be */
- hton16 = __noswap16;
- hton32 = __noswap32;
- hton64 = __noswap64;
- }
-
- return hton16 (i);
-}
-
-
-static inline uint32_t
-__byte_order_n32 (uint32_t i)
-{
- uint32_t num = 1;
-
- if (((char *)(&num))[0] == 1) {
- /* cpu is le */
- hton16 = __swap16;
- hton32 = __swap32;
- hton64 = __swap64;
- } else {
- /* cpu is be */
- hton16 = __noswap16;
- hton32 = __noswap32;
- hton64 = __noswap64;
- }
-
- return hton32 (i);
-}
-
-
-static inline uint64_t
-__byte_order_n64 (uint64_t i)
-{
- uint32_t num = 1;
-
- if (((char *)(&num))[0] == 1) {
- /* cpu is le */
- hton16 = __swap16;
- hton32 = __swap32;
- hton64 = __swap64;
- } else {
- /* cpu is be */
- hton16 = __noswap16;
- hton32 = __noswap32;
- hton64 = __noswap64;
- }
-
- return hton64 (i);
-}
-
-
-static uint16_t (*hton16) (uint16_t) = __byte_order_n16;
-static uint32_t (*hton32) (uint32_t) = __byte_order_n32;
-static uint64_t (*hton64) (uint64_t) = __byte_order_n64;
-
-
-static inline uint16_t
-__byte_order_le16 (uint16_t i)
-{
- uint32_t num = 1;
-
- if (((char *)(&num))[0] == 1) {
- /* cpu is le */
- htole16 = __noswap16;
- htole32 = __noswap32;
- htole64 = __noswap64;
- } else {
- /* cpu is be */
- htole16 = __swap16;
- htole32 = __swap32;
- htole64 = __swap64;
- }
-
- return htole16 (i);
-}
-
-
-static inline uint32_t
-__byte_order_le32 (uint32_t i)
-{
- uint32_t num = 1;
-
- if (((char *)(&num))[0] == 1) {
- /* cpu is le */
- htole16 = __noswap16;
- htole32 = __noswap32;
- htole64 = __noswap64;
- } else {
- /* cpu is be */
- htole16 = __swap16;
- htole32 = __swap32;
- htole64 = __swap64;
- }
-
- return htole32 (i);
-}
-
-
-static inline uint64_t
-__byte_order_le64 (uint64_t i)
-{
- uint32_t num = 1;
-
- if (((char *)(&num))[0] == 1) {
- /* cpu is le */
- htole16 = __noswap16;
- htole32 = __noswap32;
- htole64 = __noswap64;
- } else {
- /* cpu is be */
- htole16 = __swap16;
- htole32 = __swap32;
- htole64 = __swap64;
- }
-
- return htole64 (i);
-}
-
-
-static uint16_t (*htole16) (uint16_t) = __byte_order_le16;
-static uint32_t (*htole32) (uint32_t) = __byte_order_le32;
-static uint64_t (*htole64) (uint64_t) = __byte_order_le64;
-
-
-static inline uint16_t
-__byte_order_be16 (uint16_t i)
-{
- uint32_t num = 1;
-
- if (((char *)(&num))[0] == 1) {
- /* cpu is le */
- htobe16 = __swap16;
- htobe32 = __swap32;
- htobe64 = __swap64;
- } else {
- /* cpu is be */
- htobe16 = __noswap16;
- htobe32 = __noswap32;
- htobe64 = __noswap64;
- }
-
- return htobe16 (i);
-}
-
-
-static inline uint32_t
-__byte_order_be32 (uint32_t i)
-{
- uint32_t num = 1;
-
- if (((char *)(&num))[0] == 1) {
- /* cpu is le */
- htobe16 = __swap16;
- htobe32 = __swap32;
- htobe64 = __swap64;
- } else {
- /* cpu is be */
- htobe16 = __noswap16;
- htobe32 = __noswap32;
- htobe64 = __noswap64;
- }
-
- return htobe32 (i);
-}
-
-
-static inline uint64_t
-__byte_order_be64 (uint64_t i)
-{
- uint32_t num = 1;
-
- if (((char *)(&num))[0] == 1) {
- /* cpu is le */
- htobe16 = __swap16;
- htobe32 = __swap32;
- htobe64 = __swap64;
- } else {
- /* cpu is be */
- htobe16 = __noswap16;
- htobe32 = __noswap32;
- htobe64 = __noswap64;
- }
-
- return htobe64 (i);
-}
-
-
-static uint16_t (*htobe16) (uint16_t) = __byte_order_be16;
-static uint32_t (*htobe32) (uint32_t) = __byte_order_be32;
-static uint64_t (*htobe64) (uint64_t) = __byte_order_be64;
-
-
-
-#endif /* _BYTE_ORDER_H */
diff --git a/libglusterfs/src/call-stub.c b/libglusterfs/src/call-stub.c
index fab368a6ddd..ee84f08acd4 100644
--- a/libglusterfs/src/call-stub.c
+++ b/libglusterfs/src/call-stub.c
@@ -1,3868 +1,2467 @@
/*
- Copyright (c) 2007-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
+#include <openssl/md5.h>
#include <inttypes.h>
-#include "md5.h"
-#include "call-stub.h"
-#include "mem-types.h"
-
+#include "glusterfs/call-stub.h"
+#include "glusterfs/mem-types.h"
+#include "glusterfs/libglusterfs-messages.h"
static call_stub_t *
-stub_new (call_frame_t *frame,
- char wind,
- glusterfs_fop_t fop)
+stub_new(call_frame_t *frame, const char wind, const glusterfs_fop_t fop)
{
- call_stub_t *new = NULL;
+ call_stub_t *new = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", frame, out);
- new = mem_get0 (frame->this->ctx->stub_mem_pool);
- GF_VALIDATE_OR_GOTO ("call-stub", new, out);
+ new = mem_get0(frame->this->ctx->stub_mem_pool);
+ GF_VALIDATE_OR_GOTO("call-stub", new, out);
- new->frame = frame;
- new->wind = wind;
- new->fop = fop;
- new->stub_mem_pool = frame->this->ctx->stub_mem_pool;
- INIT_LIST_HEAD (&new->list);
+ new->frame = frame;
+ new->wind = wind;
+ new->fop = fop;
+ new->stub_mem_pool = frame->this->ctx->stub_mem_pool;
+ INIT_LIST_HEAD(&new->list);
+
+ INIT_LIST_HEAD(&new->args_cbk.entries);
out:
- return new;
+ return new;
}
-
call_stub_t *
-fop_lookup_stub (call_frame_t *frame,
- fop_lookup_t fn,
- loc_t *loc,
- dict_t *xattr_req)
+fop_lookup_stub(call_frame_t *frame, fop_lookup_t fn, loc_t *loc, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
-
- stub = stub_new (frame, 1, GF_FOP_LOOKUP);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ call_stub_t *stub = NULL;
- stub->args.lookup.fn = fn;
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- if (xattr_req)
- stub->args.lookup.xattr_req = dict_ref (xattr_req);
+ stub = stub_new(frame, 1, GF_FOP_LOOKUP);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- loc_copy (&stub->args.lookup.loc, loc);
+ stub->fn.lookup = fn;
+ args_lookup_store(&stub->args, loc, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_lookup_cbk_stub (call_frame_t *frame,
- fop_lookup_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- inode_t *inode,
- struct iatt *buf,
- dict_t *dict,
- struct iatt *postparent)
+fop_lookup_cbk_stub(call_frame_t *frame, fop_lookup_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ dict_t *xdata, struct iatt *postparent)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 0, GF_FOP_LOOKUP);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_LOOKUP);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.lookup_cbk.fn = fn;
- stub->args.lookup_cbk.op_ret = op_ret;
- stub->args.lookup_cbk.op_errno = op_errno;
- if (inode)
- stub->args.lookup_cbk.inode = inode_ref (inode);
- if (buf)
- stub->args.lookup_cbk.buf = *buf;
- if (dict)
- stub->args.lookup_cbk.dict = dict_ref (dict);
- if (postparent)
- stub->args.lookup_cbk.postparent = *postparent;
+ stub->fn_cbk.lookup = fn;
+ args_lookup_cbk_store(&stub->args_cbk, op_ret, op_errno, inode, buf, xdata,
+ postparent);
out:
- return stub;
+ return stub;
}
-
-
call_stub_t *
-fop_stat_stub (call_frame_t *frame,
- fop_stat_t fn,
- loc_t *loc)
+fop_stat_stub(call_frame_t *frame, fop_stat_t fn, loc_t *loc, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- stub = stub_new (frame, 1, GF_FOP_STAT);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_STAT);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.stat.fn = fn;
- loc_copy (&stub->args.stat.loc, loc);
+ stub->fn.stat = fn;
+ args_stat_store(&stub->args, loc, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_stat_cbk_stub (call_frame_t *frame,
- fop_stat_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *buf)
+fop_stat_cbk_stub(call_frame_t *frame, fop_stat_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iatt *buf, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 0, GF_FOP_STAT);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_STAT);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.stat_cbk.fn = fn;
- stub->args.stat_cbk.op_ret = op_ret;
- stub->args.stat_cbk.op_errno = op_errno;
- if (op_ret == 0)
- stub->args.stat_cbk.buf = *buf;
+ stub->fn_cbk.stat = fn;
+ args_stat_cbk_store(&stub->args_cbk, op_ret, op_errno, buf, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_fstat_stub (call_frame_t *frame,
- fop_fstat_t fn,
- fd_t *fd)
+fop_fstat_stub(call_frame_t *frame, fop_fstat_t fn, fd_t *fd, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 1, GF_FOP_FSTAT);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_FSTAT);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->args.fstat.fn = fn;
-
- if (fd)
- stub->args.fstat.fd = fd_ref (fd);
+ stub->fn.fstat = fn;
+ args_fstat_store(&stub->args, fd, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_fstat_cbk_stub (call_frame_t *frame,
- fop_fstat_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *buf)
+fop_fstat_cbk_stub(call_frame_t *frame, fop_fstat_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iatt *buf, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 0, GF_FOP_FSTAT);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_FSTAT);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.fstat_cbk.fn = fn;
- stub->args.fstat_cbk.op_ret = op_ret;
- stub->args.fstat_cbk.op_errno = op_errno;
- if (buf)
- stub->args.fstat_cbk.buf = *buf;
+ stub->fn_cbk.fstat = fn;
+ args_fstat_cbk_store(&stub->args_cbk, op_ret, op_errno, buf, xdata);
out:
- return stub;
+ return stub;
}
-
-/* truncate */
-
call_stub_t *
-fop_truncate_stub (call_frame_t *frame,
- fop_truncate_t fn,
- loc_t *loc,
- off_t off)
+fop_truncate_stub(call_frame_t *frame, fop_truncate_t fn, loc_t *loc, off_t off,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- stub = stub_new (frame, 1, GF_FOP_TRUNCATE);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_TRUNCATE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.truncate.fn = fn;
- loc_copy (&stub->args.truncate.loc, loc);
- stub->args.truncate.off = off;
+ stub->fn.truncate = fn;
+ args_truncate_store(&stub->args, loc, off, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_truncate_cbk_stub (call_frame_t *frame,
- fop_truncate_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *prebuf,
- struct iatt *postbuf)
+fop_truncate_cbk_stub(call_frame_t *frame, fop_truncate_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 0, GF_FOP_TRUNCATE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 0, GF_FOP_TRUNCATE);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->args.truncate_cbk.fn = fn;
- stub->args.truncate_cbk.op_ret = op_ret;
- stub->args.truncate_cbk.op_errno = op_errno;
- if (prebuf)
- stub->args.truncate_cbk.prebuf = *prebuf;
- if (postbuf)
- stub->args.truncate_cbk.postbuf = *postbuf;
+ stub->fn_cbk.truncate = fn;
+ args_truncate_cbk_store(&stub->args_cbk, op_ret, op_errno, prebuf, postbuf,
+ xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_ftruncate_stub (call_frame_t *frame,
- fop_ftruncate_t fn,
- fd_t *fd,
- off_t off)
+fop_ftruncate_stub(call_frame_t *frame, fop_ftruncate_t fn, fd_t *fd, off_t off,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 1, GF_FOP_FTRUNCATE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_FTRUNCATE);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub->fn.ftruncate = fn;
+ args_ftruncate_store(&stub->args, fd, off, xdata);
- stub->args.ftruncate.fn = fn;
- if (fd)
- stub->args.ftruncate.fd = fd_ref (fd);
-
- stub->args.ftruncate.off = off;
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_ftruncate_cbk_stub (call_frame_t *frame,
- fop_ftruncate_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *prebuf,
- struct iatt *postbuf)
+fop_ftruncate_cbk_stub(call_frame_t *frame, fop_ftruncate_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 0, GF_FOP_FTRUNCATE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 0, GF_FOP_FTRUNCATE);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub->fn_cbk.ftruncate = fn;
+ args_ftruncate_cbk_store(&stub->args_cbk, op_ret, op_errno, prebuf, postbuf,
+ xdata);
- stub->args.ftruncate_cbk.fn = fn;
- stub->args.ftruncate_cbk.op_ret = op_ret;
- stub->args.ftruncate_cbk.op_errno = op_errno;
- if (prebuf)
- stub->args.ftruncate_cbk.prebuf = *prebuf;
- if (postbuf)
- stub->args.ftruncate_cbk.postbuf = *postbuf;
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_access_stub (call_frame_t *frame,
- fop_access_t fn,
- loc_t *loc,
- int32_t mask)
+fop_access_stub(call_frame_t *frame, fop_access_t fn, loc_t *loc, int32_t mask,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- stub = stub_new (frame, 1, GF_FOP_ACCESS);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_ACCESS);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.access.fn = fn;
- loc_copy (&stub->args.access.loc, loc);
- stub->args.access.mask = mask;
+ stub->fn.access = fn;
+ args_access_store(&stub->args, loc, mask, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_access_cbk_stub (call_frame_t *frame,
- fop_access_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno)
+fop_access_cbk_stub(call_frame_t *frame, fop_access_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 0, GF_FOP_ACCESS);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_ACCESS);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.access_cbk.fn = fn;
- stub->args.access_cbk.op_ret = op_ret;
- stub->args.access_cbk.op_errno = op_errno;
+ stub->fn_cbk.access = fn;
+ args_access_cbk_store(&stub->args_cbk, op_ret, op_errno, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_readlink_stub (call_frame_t *frame,
- fop_readlink_t fn,
- loc_t *loc,
- size_t size)
+fop_readlink_stub(call_frame_t *frame, fop_readlink_t fn, loc_t *loc,
+ size_t size, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- stub = stub_new (frame, 1, GF_FOP_READLINK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_READLINK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.readlink.fn = fn;
- loc_copy (&stub->args.readlink.loc, loc);
- stub->args.readlink.size = size;
+ stub->fn.readlink = fn;
+ args_readlink_store(&stub->args, loc, size, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_readlink_cbk_stub (call_frame_t *frame,
- fop_readlink_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- const char *path,
- struct iatt *sbuf)
+fop_readlink_cbk_stub(call_frame_t *frame, fop_readlink_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, const char *path,
+ struct iatt *stbuf, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 0, GF_FOP_READLINK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 0, GF_FOP_READLINK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->args.readlink_cbk.fn = fn;
- stub->args.readlink_cbk.op_ret = op_ret;
- stub->args.readlink_cbk.op_errno = op_errno;
- if (path)
- stub->args.readlink_cbk.buf = gf_strdup (path);
- if (sbuf)
- stub->args.readlink_cbk.sbuf = *sbuf;
+ stub->fn_cbk.readlink = fn;
+ args_readlink_cbk_store(&stub->args_cbk, op_ret, op_errno, path, stbuf,
+ xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_mknod_stub (call_frame_t *frame, fop_mknod_t fn,
- loc_t *loc, mode_t mode, dev_t rdev, dict_t *params)
+fop_mknod_stub(call_frame_t *frame, fop_mknod_t fn, loc_t *loc, mode_t mode,
+ dev_t rdev, mode_t umask, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- stub = stub_new (frame, 1, GF_FOP_MKNOD);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_MKNOD);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.mknod.fn = fn;
- loc_copy (&stub->args.mknod.loc, loc);
- stub->args.mknod.mode = mode;
- stub->args.mknod.rdev = rdev;
- if (params)
- stub->args.mknod.params = dict_ref (params);
+ stub->fn.mknod = fn;
+ args_mknod_store(&stub->args, loc, mode, rdev, umask, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_mknod_cbk_stub (call_frame_t *frame,
- fop_mknod_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent)
+fop_mknod_cbk_stub(call_frame_t *frame, fop_mknod_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ struct iatt *preparent, struct iatt *postparent,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 0, GF_FOP_MKNOD);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_MKNOD);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.mknod_cbk.fn = fn;
- stub->args.mknod_cbk.op_ret = op_ret;
- stub->args.mknod_cbk.op_errno = op_errno;
- if (inode)
- stub->args.mknod_cbk.inode = inode_ref (inode);
- if (buf)
- stub->args.mknod_cbk.buf = *buf;
- if (preparent)
- stub->args.mknod_cbk.preparent = *preparent;
- if (postparent)
- stub->args.mknod_cbk.postparent = *postparent;
+ stub->fn_cbk.mknod = fn;
+ args_mknod_cbk_store(&stub->args_cbk, op_ret, op_errno, inode, buf,
+ preparent, postparent, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_mkdir_stub (call_frame_t *frame, fop_mkdir_t fn,
- loc_t *loc, mode_t mode, dict_t *params)
+fop_mkdir_stub(call_frame_t *frame, fop_mkdir_t fn, loc_t *loc, mode_t mode,
+ mode_t umask, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- stub = stub_new (frame, 1, GF_FOP_MKDIR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_MKDIR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.mkdir.fn = fn;
- loc_copy (&stub->args.mkdir.loc, loc);
- stub->args.mkdir.mode = mode;
- if (params)
- stub->args.mkdir.params = dict_ref (params);
+ stub->fn.mkdir = fn;
+ args_mkdir_store(&stub->args, loc, mode, umask, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_mkdir_cbk_stub (call_frame_t *frame,
- fop_mkdir_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent)
+fop_mkdir_cbk_stub(call_frame_t *frame, fop_mkdir_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ struct iatt *preparent, struct iatt *postparent,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 0, GF_FOP_MKDIR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_MKDIR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.mkdir_cbk.fn = fn;
- stub->args.mkdir_cbk.op_ret = op_ret;
- stub->args.mkdir_cbk.op_errno = op_errno;
- if (inode)
- stub->args.mkdir_cbk.inode = inode_ref (inode);
- if (buf)
- stub->args.mkdir_cbk.buf = *buf;
- if (preparent)
- stub->args.mkdir_cbk.preparent = *preparent;
- if (postparent)
- stub->args.mkdir_cbk.postparent = *postparent;
+ stub->fn_cbk.mkdir = fn;
+ args_mkdir_cbk_store(&stub->args_cbk, op_ret, op_errno, inode, buf,
+ preparent, postparent, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_unlink_stub (call_frame_t *frame,
- fop_unlink_t fn,
- loc_t *loc)
+fop_unlink_stub(call_frame_t *frame, fop_unlink_t fn, loc_t *loc, int xflag,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
+
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ stub = stub_new(frame, 1, GF_FOP_UNLINK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_UNLINK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub->fn.unlink = fn;
+ args_unlink_store(&stub->args, loc, xflag, xdata);
- stub->args.unlink.fn = fn;
- loc_copy (&stub->args.unlink.loc, loc);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_unlink_cbk_stub (call_frame_t *frame,
- fop_unlink_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *preparent,
- struct iatt *postparent)
+fop_unlink_cbk_stub(call_frame_t *frame, fop_unlink_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 0, GF_FOP_UNLINK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_UNLINK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.unlink_cbk.fn = fn;
- stub->args.unlink_cbk.op_ret = op_ret;
- stub->args.unlink_cbk.op_errno = op_errno;
- if (preparent)
- stub->args.unlink_cbk.preparent = *preparent;
- if (postparent)
- stub->args.unlink_cbk.postparent = *postparent;
+ stub->fn_cbk.unlink = fn;
+ args_unlink_cbk_store(&stub->args_cbk, op_ret, op_errno, preparent,
+ postparent, xdata);
out:
- return stub;
+ return stub;
}
-
-
call_stub_t *
-fop_rmdir_stub (call_frame_t *frame, fop_rmdir_t fn,
- loc_t *loc, int flags)
+fop_rmdir_stub(call_frame_t *frame, fop_rmdir_t fn, loc_t *loc, int flags,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
+
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ stub = stub_new(frame, 1, GF_FOP_RMDIR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_RMDIR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub->fn.rmdir = fn;
+ args_rmdir_store(&stub->args, loc, flags, xdata);
- stub->args.rmdir.fn = fn;
- loc_copy (&stub->args.rmdir.loc, loc);
- stub->args.rmdir.flags = flags;
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_rmdir_cbk_stub (call_frame_t *frame,
- fop_rmdir_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *preparent,
- struct iatt *postparent)
+fop_rmdir_cbk_stub(call_frame_t *frame, fop_rmdir_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 0, GF_FOP_RMDIR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_RMDIR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.rmdir_cbk.fn = fn;
- stub->args.rmdir_cbk.op_ret = op_ret;
- stub->args.rmdir_cbk.op_errno = op_errno;
- if (preparent)
- stub->args.rmdir_cbk.preparent = *preparent;
- if (postparent)
- stub->args.rmdir_cbk.postparent = *postparent;
+ stub->fn_cbk.rmdir = fn;
+ args_rmdir_cbk_store(&stub->args_cbk, op_ret, op_errno, preparent,
+ postparent, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_symlink_stub (call_frame_t *frame, fop_symlink_t fn,
- const char *linkname, loc_t *loc, dict_t *params)
+fop_symlink_stub(call_frame_t *frame, fop_symlink_t fn, const char *linkname,
+ loc_t *loc, mode_t umask, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
- GF_VALIDATE_OR_GOTO ("call-stub", linkname, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
+ GF_VALIDATE_OR_GOTO("call-stub", linkname, out);
- stub = stub_new (frame, 1, GF_FOP_SYMLINK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_SYMLINK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.symlink.fn = fn;
- stub->args.symlink.linkname = gf_strdup (linkname);
- loc_copy (&stub->args.symlink.loc, loc);
- if (params)
- stub->args.symlink.params = dict_ref (params);
+ stub->fn.symlink = fn;
+ args_symlink_store(&stub->args, linkname, loc, umask, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_symlink_cbk_stub (call_frame_t *frame,
- fop_symlink_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent)
+fop_symlink_cbk_stub(call_frame_t *frame, fop_symlink_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ struct iatt *preparent, struct iatt *postparent,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 0, GF_FOP_SYMLINK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_SYMLINK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.symlink_cbk.fn = fn;
- stub->args.symlink_cbk.op_ret = op_ret;
- stub->args.symlink_cbk.op_errno = op_errno;
- if (inode)
- stub->args.symlink_cbk.inode = inode_ref (inode);
- if (buf)
- stub->args.symlink_cbk.buf = *buf;
- if (preparent)
- stub->args.symlink_cbk.preparent = *preparent;
- if (postparent)
- stub->args.symlink_cbk.postparent = *postparent;
+ stub->fn_cbk.symlink = fn;
+ args_symlink_cbk_store(&stub->args_cbk, op_ret, op_errno, inode, buf,
+ preparent, postparent, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_rename_stub (call_frame_t *frame,
- fop_rename_t fn,
- loc_t *oldloc,
- loc_t *newloc)
+fop_rename_stub(call_frame_t *frame, fop_rename_t fn, loc_t *oldloc,
+ loc_t *newloc, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", oldloc, out);
- GF_VALIDATE_OR_GOTO ("call-stub", newloc, out);
+ GF_VALIDATE_OR_GOTO("call-stub", oldloc, out);
+ GF_VALIDATE_OR_GOTO("call-stub", newloc, out);
- stub = stub_new (frame, 1, GF_FOP_RENAME);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_RENAME);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.rename.fn = fn;
- loc_copy (&stub->args.rename.old, oldloc);
- loc_copy (&stub->args.rename.new, newloc);
+ stub->fn.rename = fn;
+ args_rename_store(&stub->args, oldloc, newloc, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_rename_cbk_stub (call_frame_t *frame,
- fop_rename_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *buf,
- struct iatt *preoldparent,
- struct iatt *postoldparent,
- struct iatt *prenewparent,
- struct iatt *postnewparent)
+fop_rename_cbk_stub(call_frame_t *frame, fop_rename_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iatt *buf,
+ struct iatt *preoldparent, struct iatt *postoldparent,
+ struct iatt *prenewparent, struct iatt *postnewparent,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 0, GF_FOP_RENAME);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 0, GF_FOP_RENAME);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->args.rename_cbk.fn = fn;
- stub->args.rename_cbk.op_ret = op_ret;
- stub->args.rename_cbk.op_errno = op_errno;
- if (buf)
- stub->args.rename_cbk.buf = *buf;
- if (preoldparent)
- stub->args.rename_cbk.preoldparent = *preoldparent;
- if (postoldparent)
- stub->args.rename_cbk.postoldparent = *postoldparent;
- if (prenewparent)
- stub->args.rename_cbk.prenewparent = *prenewparent;
- if (postnewparent)
- stub->args.rename_cbk.postnewparent = *postnewparent;
+ stub->fn_cbk.rename = fn;
+ args_rename_cbk_store(&stub->args_cbk, op_ret, op_errno, buf, preoldparent,
+ postoldparent, prenewparent, postnewparent, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_link_stub (call_frame_t *frame,
- fop_link_t fn,
- loc_t *oldloc,
- loc_t *newloc)
+fop_link_stub(call_frame_t *frame, fop_link_t fn, loc_t *oldloc, loc_t *newloc,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", oldloc, out);
- GF_VALIDATE_OR_GOTO ("call-stub", newloc, out);
+ GF_VALIDATE_OR_GOTO("call-stub", oldloc, out);
+ GF_VALIDATE_OR_GOTO("call-stub", newloc, out);
- stub = stub_new (frame, 1, GF_FOP_LINK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->args.link.fn = fn;
- loc_copy (&stub->args.link.oldloc, oldloc);
- loc_copy (&stub->args.link.newloc, newloc);
+ stub = stub_new(frame, 1, GF_FOP_LINK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
+ stub->fn.link = fn;
+ args_link_store(&stub->args, oldloc, newloc, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_link_cbk_stub (call_frame_t *frame,
- fop_link_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent)
+fop_link_cbk_stub(call_frame_t *frame, fop_link_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ struct iatt *preparent, struct iatt *postparent,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 0, GF_FOP_LINK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_LINK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.link_cbk.fn = fn;
- stub->args.link_cbk.op_ret = op_ret;
- stub->args.link_cbk.op_errno = op_errno;
- if (inode)
- stub->args.link_cbk.inode = inode_ref (inode);
- if (buf)
- stub->args.link_cbk.buf = *buf;
- if (preparent)
- stub->args.link_cbk.preparent = *preparent;
- if (postparent)
- stub->args.link_cbk.postparent = *postparent;
+ stub->fn_cbk.link = fn;
+ args_link_cbk_store(&stub->args_cbk, op_ret, op_errno, inode, buf,
+ preparent, postparent, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_create_stub (call_frame_t *frame, fop_create_t fn,
- loc_t *loc, int32_t flags, mode_t mode,
- fd_t *fd, dict_t *params)
+fop_create_stub(call_frame_t *frame, fop_create_t fn, loc_t *loc, int32_t flags,
+ mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- stub = stub_new (frame, 1, GF_FOP_CREATE);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_CREATE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.create.fn = fn;
- loc_copy (&stub->args.create.loc, loc);
- stub->args.create.flags = flags;
- stub->args.create.mode = mode;
- if (fd)
- stub->args.create.fd = fd_ref (fd);
- if (params)
- stub->args.create.params = dict_ref (params);
+ stub->fn.create = fn;
+ args_create_store(&stub->args, loc, flags, mode, umask, fd, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_create_cbk_stub (call_frame_t *frame,
- fop_create_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- fd_t *fd,
- inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent)
+fop_create_cbk_stub(call_frame_t *frame, fop_create_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, fd_t *fd, inode_t *inode,
+ struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 0, GF_FOP_CREATE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 0, GF_FOP_CREATE);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->args.create_cbk.fn = fn;
- stub->args.create_cbk.op_ret = op_ret;
- stub->args.create_cbk.op_errno = op_errno;
- if (fd)
- stub->args.create_cbk.fd = fd_ref (fd);
- if (inode)
- stub->args.create_cbk.inode = inode_ref (inode);
- if (buf)
- stub->args.create_cbk.buf = *buf;
- if (preparent)
- stub->args.create_cbk.preparent = *preparent;
- if (postparent)
- stub->args.create_cbk.postparent = *postparent;
+ stub->fn_cbk.create = fn;
+ args_create_cbk_store(&stub->args_cbk, op_ret, op_errno, fd, inode, buf,
+ preparent, postparent, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_open_stub (call_frame_t *frame,
- fop_open_t fn,
- loc_t *loc,
- int32_t flags, fd_t *fd,
- int32_t wbflags)
+fop_open_stub(call_frame_t *frame, fop_open_t fn, loc_t *loc, int32_t flags,
+ fd_t *fd, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- stub = stub_new (frame, 1, GF_FOP_OPEN);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_OPEN);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.open.fn = fn;
- loc_copy (&stub->args.open.loc, loc);
- stub->args.open.flags = flags;
- stub->args.open.wbflags = wbflags;
- if (fd)
- stub->args.open.fd = fd_ref (fd);
+ stub->fn.open = fn;
+ args_open_store(&stub->args, loc, flags, fd, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_open_cbk_stub (call_frame_t *frame,
- fop_open_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- fd_t *fd)
-
+fop_open_cbk_stub(call_frame_t *frame, fop_open_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, fd_t *fd, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 0, GF_FOP_OPEN);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 0, GF_FOP_OPEN);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->args.open_cbk.fn = fn;
- stub->args.open_cbk.op_ret = op_ret;
- stub->args.open_cbk.op_errno = op_errno;
- if (fd)
- stub->args.open_cbk.fd = fd_ref (fd);
+ stub->fn_cbk.open = fn;
+ args_open_cbk_store(&stub->args_cbk, op_ret, op_errno, fd, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_readv_stub (call_frame_t *frame,
- fop_readv_t fn,
- fd_t *fd,
- size_t size,
- off_t off)
+fop_readv_stub(call_frame_t *frame, fop_readv_t fn, fd_t *fd, size_t size,
+ off_t off, uint32_t flags, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 1, GF_FOP_READ);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_READ);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->args.readv.fn = fn;
- if (fd)
- stub->args.readv.fd = fd_ref (fd);
- stub->args.readv.size = size;
- stub->args.readv.off = off;
+ stub->fn.readv = fn;
+ args_readv_store(&stub->args, fd, size, off, flags, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_readv_cbk_stub (call_frame_t *frame,
- fop_readv_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iovec *vector,
- int32_t count,
- struct iatt *stbuf,
- struct iobref *iobref)
-
+fop_readv_cbk_stub(call_frame_t *frame, fop_readv_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iovec *vector, int32_t count,
+ struct iatt *stbuf, struct iobref *iobref, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 0, GF_FOP_READ);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_READ);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.readv_cbk.fn = fn;
- stub->args.readv_cbk.op_ret = op_ret;
- stub->args.readv_cbk.op_errno = op_errno;
- if (op_ret >= 0) {
- stub->args.readv_cbk.vector = iov_dup (vector, count);
- stub->args.readv_cbk.count = count;
- stub->args.readv_cbk.stbuf = *stbuf;
- stub->args.readv_cbk.iobref = iobref_ref (iobref);
- }
+ stub->fn_cbk.readv = fn;
+ args_readv_cbk_store(&stub->args_cbk, op_ret, op_errno, vector, count,
+ stbuf, iobref, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_writev_stub (call_frame_t *frame,
- fop_writev_t fn,
- fd_t *fd,
- struct iovec *vector,
- int32_t count,
- off_t off,
- struct iobref *iobref)
+fop_writev_stub(call_frame_t *frame, fop_writev_t fn, fd_t *fd,
+ struct iovec *vector, int32_t count, off_t off, uint32_t flags,
+ struct iobref *iobref, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", vector, out);
+ GF_VALIDATE_OR_GOTO("call-stub", vector, out);
- stub = stub_new (frame, 1, GF_FOP_WRITE);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_WRITE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.writev.fn = fn;
- if (fd)
- stub->args.writev.fd = fd_ref (fd);
- stub->args.writev.vector = iov_dup (vector, count);
- stub->args.writev.count = count;
- stub->args.writev.off = off;
- stub->args.writev.iobref = iobref_ref (iobref);
+ stub->fn.writev = fn;
+ args_writev_store(&stub->args, fd, vector, count, off, flags, iobref,
+ xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_writev_cbk_stub (call_frame_t *frame,
- fop_writev_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *prebuf,
- struct iatt *postbuf)
-
+fop_writev_cbk_stub(call_frame_t *frame, fop_writev_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 0, GF_FOP_WRITE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 0, GF_FOP_WRITE);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->args.writev_cbk.fn = fn;
- stub->args.writev_cbk.op_ret = op_ret;
- stub->args.writev_cbk.op_errno = op_errno;
- if (op_ret >= 0)
- stub->args.writev_cbk.postbuf = *postbuf;
- if (prebuf)
- stub->args.writev_cbk.prebuf = *prebuf;
+ stub->fn_cbk.writev = fn;
+ args_writev_cbk_store(&stub->args_cbk, op_ret, op_errno, prebuf, postbuf,
+ xdata);
out:
- return stub;
+ return stub;
}
-
-
call_stub_t *
-fop_flush_stub (call_frame_t *frame,
- fop_flush_t fn,
- fd_t *fd)
+fop_flush_stub(call_frame_t *frame, fop_flush_t fn, fd_t *fd, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 1, GF_FOP_FLUSH);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_FLUSH);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.flush.fn = fn;
- if (fd)
- stub->args.flush.fd = fd_ref (fd);
+ stub->fn.flush = fn;
+ args_flush_store(&stub->args, fd, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_flush_cbk_stub (call_frame_t *frame,
- fop_flush_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno)
-
+fop_flush_cbk_stub(call_frame_t *frame, fop_flush_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 0, GF_FOP_FLUSH);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_FLUSH);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.flush_cbk.fn = fn;
- stub->args.flush_cbk.op_ret = op_ret;
- stub->args.flush_cbk.op_errno = op_errno;
+ stub->fn_cbk.flush = fn;
+ args_flush_cbk_store(&stub->args_cbk, op_ret, op_errno, xdata);
out:
- return stub;
+ return stub;
}
+call_stub_t *
+fop_fsync_stub(call_frame_t *frame, fop_fsync_t fn, fd_t *fd, int32_t datasync,
+ dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
+ stub = stub_new(frame, 1, GF_FOP_FSYNC);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
+ stub->fn.fsync = fn;
+ args_fsync_store(&stub->args, fd, datasync, xdata);
+out:
+ return stub;
+}
call_stub_t *
-fop_fsync_stub (call_frame_t *frame,
- fop_fsync_t fn,
- fd_t *fd,
- int32_t datasync)
+fop_fsync_cbk_stub(call_frame_t *frame, fop_fsync_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 0, GF_FOP_FSYNC);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_FSYNC);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->args.fsync.fn = fn;
- if (fd)
- stub->args.fsync.fd = fd_ref (fd);
- stub->args.fsync.datasync = datasync;
+ stub->fn_cbk.fsync = fn;
+ args_fsync_cbk_store(&stub->args_cbk, op_ret, op_errno, prebuf, postbuf,
+ xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_fsync_cbk_stub (call_frame_t *frame,
- fop_fsync_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *prebuf,
- struct iatt *postbuf)
+fop_opendir_stub(call_frame_t *frame, fop_opendir_t fn, loc_t *loc, fd_t *fd,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- stub = stub_new (frame, 0, GF_FOP_FSYNC);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_OPENDIR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.fsync_cbk.fn = fn;
- stub->args.fsync_cbk.op_ret = op_ret;
- stub->args.fsync_cbk.op_errno = op_errno;
- if (prebuf)
- stub->args.fsync_cbk.prebuf = *prebuf;
- if (postbuf)
- stub->args.fsync_cbk.postbuf = *postbuf;
+ stub->fn.opendir = fn;
+ args_opendir_store(&stub->args, loc, fd, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_opendir_stub (call_frame_t *frame,
- fop_opendir_t fn,
- loc_t *loc, fd_t *fd)
+fop_opendir_cbk_stub(call_frame_t *frame, fop_opendir_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, fd_t *fd, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ stub = stub_new(frame, 0, GF_FOP_OPENDIR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_OPENDIR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->args.opendir.fn = fn;
- loc_copy (&stub->args.opendir.loc, loc);
- if (fd)
- stub->args.opendir.fd = fd_ref (fd);
+ stub->fn_cbk.opendir = fn;
+ args_opendir_cbk_store(&stub->args_cbk, op_ret, op_errno, fd, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_opendir_cbk_stub (call_frame_t *frame,
- fop_opendir_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- fd_t *fd)
-
+fop_fsyncdir_stub(call_frame_t *frame, fop_fsyncdir_t fn, fd_t *fd,
+ int32_t datasync, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 0, GF_FOP_OPENDIR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_FSYNCDIR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.opendir_cbk.fn = fn;
- stub->args.opendir_cbk.op_ret = op_ret;
- stub->args.opendir_cbk.op_errno = op_errno;
-
- if (fd)
- stub->args.opendir_cbk.fd = fd_ref (fd);
+ stub->fn.fsyncdir = fn;
+ args_fsyncdir_store(&stub->args, fd, datasync, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_fsyncdir_stub (call_frame_t *frame,
- fop_fsyncdir_t fn,
- fd_t *fd,
- int32_t datasync)
+fop_fsyncdir_cbk_stub(call_frame_t *frame, fop_fsyncdir_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 1, GF_FOP_FSYNCDIR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_FSYNCDIR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.fsyncdir.fn = fn;
- if (fd)
- stub->args.fsyncdir.fd = fd_ref (fd);
- stub->args.fsyncdir.datasync = datasync;
+ stub->fn_cbk.fsyncdir = fn;
+ args_fsyncdir_cbk_store(&stub->args_cbk, op_ret, op_errno, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_fsyncdir_cbk_stub (call_frame_t *frame,
- fop_fsyncdir_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno)
-
+fop_statfs_stub(call_frame_t *frame, fop_statfs_t fn, loc_t *loc, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- stub = stub_new (frame, 0, GF_FOP_FSYNCDIR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_STATFS);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.fsyncdir_cbk.fn = fn;
- stub->args.fsyncdir_cbk.op_ret = op_ret;
- stub->args.fsyncdir_cbk.op_errno = op_errno;
+ stub->fn.statfs = fn;
+ args_statfs_store(&stub->args, loc, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_statfs_stub (call_frame_t *frame,
- fop_statfs_t fn,
- loc_t *loc)
+fop_statfs_cbk_stub(call_frame_t *frame, fop_statfs_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct statvfs *buf, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 1, GF_FOP_STATFS);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_STATFS);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.statfs.fn = fn;
- loc_copy (&stub->args.statfs.loc, loc);
+ stub->fn_cbk.statfs = fn;
+ args_statfs_cbk_store(&stub->args_cbk, op_ret, op_errno, buf, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_statfs_cbk_stub (call_frame_t *frame,
- fop_statfs_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct statvfs *buf)
-
+fop_setxattr_stub(call_frame_t *frame, fop_setxattr_t fn, loc_t *loc,
+ dict_t *dict, int32_t flags, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- stub = stub_new (frame, 0, GF_FOP_STATFS);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_SETXATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.statfs_cbk.fn = fn;
- stub->args.statfs_cbk.op_ret = op_ret;
- stub->args.statfs_cbk.op_errno = op_errno;
- if (op_ret == 0)
- stub->args.statfs_cbk.buf = *buf;
+ stub->fn.setxattr = fn;
+ args_setxattr_store(&stub->args, loc, dict, flags, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_setxattr_stub (call_frame_t *frame,
- fop_setxattr_t fn,
- loc_t *loc,
- dict_t *dict,
- int32_t flags)
+fop_setxattr_cbk_stub(call_frame_t *frame, fop_setxattr_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ stub = stub_new(frame, 0, GF_FOP_SETXATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_SETXATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->args.setxattr.fn = fn;
- loc_copy (&stub->args.setxattr.loc, loc);
- /* TODO */
- if (dict)
- stub->args.setxattr.dict = dict_ref (dict);
- stub->args.setxattr.flags = flags;
+ stub->fn_cbk.setxattr = fn;
+ args_setxattr_cbk_store(&stub->args_cbk, op_ret, op_errno, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_setxattr_cbk_stub (call_frame_t *frame,
- fop_setxattr_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno)
+fop_getxattr_stub(call_frame_t *frame, fop_getxattr_t fn, loc_t *loc,
+ const char *name, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- stub = stub_new (frame, 0, GF_FOP_SETXATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_GETXATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.setxattr_cbk.fn = fn;
- stub->args.setxattr_cbk.op_ret = op_ret;
- stub->args.setxattr_cbk.op_errno = op_errno;
+ stub->fn.getxattr = fn;
+ args_getxattr_store(&stub->args, loc, name, xdata);
out:
- return stub;
+ return stub;
}
call_stub_t *
-fop_getxattr_stub (call_frame_t *frame,
- fop_getxattr_t fn,
- loc_t *loc,
- const char *name)
+fop_getxattr_cbk_stub(call_frame_t *frame, fop_getxattr_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
-
- stub = stub_new (frame, 1, GF_FOP_GETXATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ call_stub_t *stub = NULL;
- stub->args.getxattr.fn = fn;
- loc_copy (&stub->args.getxattr.loc, loc);
+ stub = stub_new(frame, 0, GF_FOP_GETXATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- if (name)
- stub->args.getxattr.name = gf_strdup (name);
+ stub->fn_cbk.getxattr = fn;
+ args_getxattr_cbk_store(&stub->args_cbk, op_ret, op_errno, dict, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_getxattr_cbk_stub (call_frame_t *frame,
- fop_getxattr_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- dict_t *dict)
+fop_fsetxattr_stub(call_frame_t *frame, fop_fsetxattr_t fn, fd_t *fd,
+ dict_t *dict, int32_t flags, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", fd, out);
- stub = stub_new (frame, 0, GF_FOP_GETXATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_FSETXATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.getxattr_cbk.fn = fn;
- stub->args.getxattr_cbk.op_ret = op_ret;
- stub->args.getxattr_cbk.op_errno = op_errno;
- /* TODO */
- if (dict)
- stub->args.getxattr_cbk.dict = dict_ref (dict);
+ stub->fn.fsetxattr = fn;
+ args_fsetxattr_store(&stub->args, fd, dict, flags, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_fsetxattr_stub (call_frame_t *frame,
- fop_fsetxattr_t fn,
- fd_t *fd,
- dict_t *dict,
- int32_t flags)
+fop_fsetxattr_cbk_stub(call_frame_t *frame, fop_fsetxattr_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", fd, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 1, GF_FOP_FSETXATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_FSETXATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.fsetxattr.fn = fn;
- stub->args.fsetxattr.fd = fd_ref (fd);
-
- /* TODO */
- if (dict)
- stub->args.fsetxattr.dict = dict_ref (dict);
- stub->args.fsetxattr.flags = flags;
+ stub->fn_cbk.fsetxattr = fn;
+ args_fsetxattr_cbk_store(&stub->args_cbk, op_ret, op_errno, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_fsetxattr_cbk_stub (call_frame_t *frame,
- fop_fsetxattr_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno)
+fop_fgetxattr_stub(call_frame_t *frame, fop_fgetxattr_t fn, fd_t *fd,
+ const char *name, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", fd, out);
- stub = stub_new (frame, 0, GF_FOP_FSETXATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_FGETXATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.fsetxattr_cbk.fn = fn;
- stub->args.fsetxattr_cbk.op_ret = op_ret;
- stub->args.fsetxattr_cbk.op_errno = op_errno;
+ stub->fn.fgetxattr = fn;
+ args_fgetxattr_store(&stub->args, fd, name, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_fgetxattr_stub (call_frame_t *frame,
- fop_fgetxattr_t fn,
- fd_t *fd,
- const char *name)
+fop_fgetxattr_cbk_stub(call_frame_t *frame, fop_fgetxattr_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", fd, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 1, GF_FOP_FGETXATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_GETXATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.fgetxattr.fn = fn;
- stub->args.fgetxattr.fd = fd_ref (fd);
-
- if (name)
- stub->args.fgetxattr.name = gf_strdup (name);
+ stub->fn_cbk.fgetxattr = fn;
+ args_fgetxattr_cbk_store(&stub->args_cbk, op_ret, op_errno, dict, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_fgetxattr_cbk_stub (call_frame_t *frame,
- fop_fgetxattr_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- dict_t *dict)
+fop_removexattr_stub(call_frame_t *frame, fop_removexattr_t fn, loc_t *loc,
+ const char *name, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 0, GF_FOP_GETXATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
+ GF_VALIDATE_OR_GOTO("call-stub", name, out);
- stub->args.fgetxattr_cbk.fn = fn;
- stub->args.fgetxattr_cbk.op_ret = op_ret;
- stub->args.fgetxattr_cbk.op_errno = op_errno;
+ stub = stub_new(frame, 1, GF_FOP_REMOVEXATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- /* TODO */
- if (dict)
- stub->args.fgetxattr_cbk.dict = dict_ref (dict);
+ stub->fn.removexattr = fn;
+ args_removexattr_store(&stub->args, loc, name, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_removexattr_stub (call_frame_t *frame,
- fop_removexattr_t fn,
- loc_t *loc,
- const char *name)
+fop_removexattr_cbk_stub(call_frame_t *frame, fop_removexattr_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
- GF_VALIDATE_OR_GOTO ("call-stub", name, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 1, GF_FOP_REMOVEXATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_REMOVEXATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.removexattr.fn = fn;
- loc_copy (&stub->args.removexattr.loc, loc);
- stub->args.removexattr.name = gf_strdup (name);
+ stub->fn_cbk.removexattr = fn;
+ args_removexattr_cbk_store(&stub->args_cbk, op_ret, op_errno, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_removexattr_cbk_stub (call_frame_t *frame,
- fop_removexattr_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno)
+fop_fremovexattr_stub(call_frame_t *frame, fop_fremovexattr_t fn, fd_t *fd,
+ const char *name, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", fd, out);
+ GF_VALIDATE_OR_GOTO("call-stub", name, out);
- stub = stub_new (frame, 0, GF_FOP_REMOVEXATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_FREMOVEXATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.removexattr_cbk.fn = fn;
- stub->args.removexattr_cbk.op_ret = op_ret;
- stub->args.removexattr_cbk.op_errno = op_errno;
+ stub->fn.fremovexattr = fn;
+ args_fremovexattr_store(&stub->args, fd, name, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_lk_stub (call_frame_t *frame,
- fop_lk_t fn,
- fd_t *fd,
- int32_t cmd,
- struct gf_flock *lock)
+fop_fremovexattr_cbk_stub(call_frame_t *frame, fop_fremovexattr_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", lock, out);
+ stub = stub_new(frame, 0, GF_FOP_FREMOVEXATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_LK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->args.lk.fn = fn;
- if (fd)
- stub->args.lk.fd = fd_ref (fd);
- stub->args.lk.cmd = cmd;
- stub->args.lk.lock = *lock;
+ stub->fn_cbk.fremovexattr = fn;
+ args_fremovexattr_cbk_store(&stub->args_cbk, op_ret, op_errno, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_lk_cbk_stub (call_frame_t *frame,
- fop_lk_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct gf_flock *lock)
-
+fop_lk_stub(call_frame_t *frame, fop_lk_t fn, fd_t *fd, int32_t cmd,
+ struct gf_flock *lock, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", lock, out);
- stub = stub_new (frame, 0, GF_FOP_LK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_LK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.lk_cbk.fn = fn;
- stub->args.lk_cbk.op_ret = op_ret;
- stub->args.lk_cbk.op_errno = op_errno;
- if (op_ret == 0)
- stub->args.lk_cbk.lock = *lock;
+ stub->fn.lk = fn;
+ args_lk_store(&stub->args, fd, cmd, lock, xdata);
out:
- return stub;
+ return stub;
}
call_stub_t *
-fop_inodelk_stub (call_frame_t *frame, fop_inodelk_t fn,
- const char *volume, loc_t *loc, int32_t cmd, struct gf_flock *lock)
+fop_lk_cbk_stub(call_frame_t *frame, fop_lk_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct gf_flock *lock, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", lock, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 1, GF_FOP_INODELK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_LK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.inodelk.fn = fn;
-
- if (volume)
- stub->args.inodelk.volume = gf_strdup (volume);
-
- loc_copy (&stub->args.inodelk.loc, loc);
- stub->args.inodelk.cmd = cmd;
- stub->args.inodelk.lock = *lock;
+ stub->fn_cbk.lk = fn;
+ args_lk_cbk_store(&stub->args_cbk, op_ret, op_errno, lock, xdata);
out:
- return stub;
+ return stub;
}
call_stub_t *
-fop_inodelk_cbk_stub (call_frame_t *frame, fop_inodelk_cbk_t fn,
- int32_t op_ret, int32_t op_errno)
+fop_inodelk_stub(call_frame_t *frame, fop_inodelk_t fn, const char *volume,
+ loc_t *loc, int32_t cmd, struct gf_flock *lock, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", lock, out);
- stub = stub_new (frame, 0, GF_FOP_INODELK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->args.inodelk_cbk.fn = fn;
- stub->args.inodelk_cbk.op_ret = op_ret;
- stub->args.inodelk_cbk.op_errno = op_errno;
+ stub = stub_new(frame, 1, GF_FOP_INODELK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
+ stub->fn.inodelk = fn;
+ args_inodelk_store(&stub->args, volume, loc, cmd, lock, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_finodelk_stub (call_frame_t *frame, fop_finodelk_t fn,
- const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *lock)
+fop_inodelk_cbk_stub(call_frame_t *frame, fop_inodelk_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", lock, out);
+ stub = stub_new(frame, 0, GF_FOP_INODELK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_FINODELK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub->fn_cbk.inodelk = fn;
+ args_inodelk_cbk_store(&stub->args_cbk, op_ret, op_errno, xdata);
+out:
+ return stub;
+}
- stub->args.finodelk.fn = fn;
+call_stub_t *
+fop_finodelk_stub(call_frame_t *frame, fop_finodelk_t fn, const char *volume,
+ fd_t *fd, int32_t cmd, struct gf_flock *lock, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- if (fd)
- stub->args.finodelk.fd = fd_ref (fd);
+ GF_VALIDATE_OR_GOTO("call-stub", lock, out);
- if (volume)
- stub->args.finodelk.volume = gf_strdup (volume);
+ stub = stub_new(frame, 1, GF_FOP_FINODELK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.finodelk.cmd = cmd;
- stub->args.finodelk.lock = *lock;
+ stub->fn.finodelk = fn;
+ args_finodelk_store(&stub->args, volume, fd, cmd, lock, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_finodelk_cbk_stub (call_frame_t *frame, fop_inodelk_cbk_t fn,
- int32_t op_ret, int32_t op_errno)
+fop_finodelk_cbk_stub(call_frame_t *frame, fop_inodelk_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
-
- stub = stub_new (frame, 0, GF_FOP_FINODELK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ call_stub_t *stub = NULL;
- stub->args.finodelk_cbk.fn = fn;
- stub->args.finodelk_cbk.op_ret = op_ret;
- stub->args.finodelk_cbk.op_errno = op_errno;
+ stub = stub_new(frame, 0, GF_FOP_FINODELK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
+ stub->fn_cbk.finodelk = fn;
+ args_finodelk_cbk_store(&stub->args_cbk, op_ret, op_errno, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_entrylk_stub (call_frame_t *frame, fop_entrylk_t fn,
- const char *volume, loc_t *loc, const char *name,
- entrylk_cmd cmd, entrylk_type type)
+fop_entrylk_stub(call_frame_t *frame, fop_entrylk_t fn, const char *volume,
+ loc_t *loc, const char *name, entrylk_cmd cmd,
+ entrylk_type type, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 1, GF_FOP_ENTRYLK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_ENTRYLK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.entrylk.fn = fn;
+ stub->fn.entrylk = fn;
+ args_entrylk_store(&stub->args, volume, loc, name, cmd, type, xdata);
- if (volume)
- stub->args.entrylk.volume = gf_strdup (volume);
+out:
+ return stub;
+}
- loc_copy (&stub->args.entrylk.loc, loc);
+call_stub_t *
+fop_entrylk_cbk_stub(call_frame_t *frame, fop_entrylk_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- stub->args.entrylk.cmd = cmd;
- stub->args.entrylk.type = type;
- if (name)
- stub->args.entrylk.name = gf_strdup (name);
+ stub = stub_new(frame, 0, GF_FOP_ENTRYLK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
+ stub->fn_cbk.entrylk = fn;
+ args_entrylk_cbk_store(&stub->args_cbk, op_ret, op_errno, xdata);
out:
- return stub;
+ return stub;
}
call_stub_t *
-fop_entrylk_cbk_stub (call_frame_t *frame, fop_entrylk_cbk_t fn,
- int32_t op_ret, int32_t op_errno)
+fop_fentrylk_stub(call_frame_t *frame, fop_fentrylk_t fn, const char *volume,
+ fd_t *fd, const char *name, entrylk_cmd cmd,
+ entrylk_type type, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 0, GF_FOP_ENTRYLK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->args.entrylk_cbk.fn = fn;
- stub->args.entrylk_cbk.op_ret = op_ret;
- stub->args.entrylk_cbk.op_errno = op_errno;
+ stub = stub_new(frame, 1, GF_FOP_FENTRYLK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
+ stub->fn.fentrylk = fn;
+ args_fentrylk_store(&stub->args, volume, fd, name, cmd, type, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_fentrylk_stub (call_frame_t *frame, fop_fentrylk_t fn,
- const char *volume, fd_t *fd, const char *name,
- entrylk_cmd cmd, entrylk_type type)
+fop_fentrylk_cbk_stub(call_frame_t *frame, fop_fentrylk_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 1, GF_FOP_FENTRYLK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_FENTRYLK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.fentrylk.fn = fn;
+ stub->fn_cbk.fentrylk = fn;
+ args_fentrylk_cbk_store(&stub->args_cbk, op_ret, op_errno, xdata);
+out:
+ return stub;
+}
- if (volume)
- stub->args.fentrylk.volume = gf_strdup (volume);
+call_stub_t *
+fop_readdirp_cbk_stub(call_frame_t *frame, fop_readdirp_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
+ dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- if (fd)
- stub->args.fentrylk.fd = fd_ref (fd);
- stub->args.fentrylk.cmd = cmd;
- stub->args.fentrylk.type = type;
- if (name)
- stub->args.fentrylk.name = gf_strdup (name);
+ stub = stub_new(frame, 0, GF_FOP_READDIRP);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
+ stub->fn_cbk.readdirp = fn;
+ args_readdirp_cbk_store(&stub->args_cbk, op_ret, op_errno, entries, xdata);
out:
- return stub;
+ return stub;
}
call_stub_t *
-fop_fentrylk_cbk_stub (call_frame_t *frame, fop_fentrylk_cbk_t fn,
- int32_t op_ret, int32_t op_errno)
+fop_readdir_cbk_stub(call_frame_t *frame, fop_readdir_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, gf_dirent_t *entries, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
-
- stub = stub_new (frame, 0, GF_FOP_FENTRYLK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->args.fentrylk_cbk.fn = fn;
- stub->args.fentrylk_cbk.op_ret = op_ret;
- stub->args.fentrylk_cbk.op_errno = op_errno;
+ stub = stub_new(frame, 0, GF_FOP_READDIR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
+ stub->fn_cbk.readdir = fn;
+ args_readdir_cbk_store(&stub->args_cbk, op_ret, op_errno, entries, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_readdirp_cbk_stub (call_frame_t *frame,
- fop_readdirp_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- gf_dirent_t *entries)
+fop_readdir_stub(call_frame_t *frame, fop_readdir_t fn, fd_t *fd, size_t size,
+ off_t off, dict_t *xdata)
{
- call_stub_t *stub = NULL;
- gf_dirent_t *stub_entry = NULL, *entry = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 1, GF_FOP_READDIR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 0, GF_FOP_READDIRP);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub->fn.readdir = fn;
+ args_readdir_store(&stub->args, fd, size, off, xdata);
+out:
+ return stub;
+}
- stub->args.readdirp_cbk.fn = fn;
- stub->args.readdirp_cbk.op_ret = op_ret;
- stub->args.readdirp_cbk.op_errno = op_errno;
- INIT_LIST_HEAD (&stub->args.readdirp_cbk.entries.list);
+call_stub_t *
+fop_readdirp_stub(call_frame_t *frame, fop_readdirp_t fn, fd_t *fd, size_t size,
+ off_t off, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- /* This check must come after the init of head above
- * so we're sure the list is empty for list_empty.
- */
- GF_VALIDATE_OR_GOTO ("call-stub", entries, out);
+ stub = stub_new(frame, 1, GF_FOP_READDIRP);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- if (op_ret > 0) {
- list_for_each_entry (entry, &entries->list, list) {
- stub_entry = gf_dirent_for_name (entry->d_name);
- if (!stub_entry)
- goto out;
- stub_entry->d_off = entry->d_off;
- stub_entry->d_ino = entry->d_ino;
- stub_entry->d_stat = entry->d_stat;
- list_add_tail (&stub_entry->list,
- &stub->args.readdirp_cbk.entries.list);
- }
- }
+ stub->fn.readdirp = fn;
+ args_readdirp_store(&stub->args, fd, size, off, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_readdir_cbk_stub (call_frame_t *frame,
- fop_readdir_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- gf_dirent_t *entries)
+fop_rchecksum_stub(call_frame_t *frame, fop_rchecksum_t fn, fd_t *fd,
+ off_t offset, int32_t len, dict_t *xdata)
{
- call_stub_t *stub = NULL;
- gf_dirent_t *stub_entry = NULL, *entry = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", fd, out);
- stub = stub_new (frame, 0, GF_FOP_READDIR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_RCHECKSUM);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.readdir_cbk.fn = fn;
- stub->args.readdir_cbk.op_ret = op_ret;
- stub->args.readdir_cbk.op_errno = op_errno;
- INIT_LIST_HEAD (&stub->args.readdir_cbk.entries.list);
+ stub->fn.rchecksum = fn;
+ args_rchecksum_store(&stub->args, fd, offset, len, xdata);
+out:
+ return stub;
+}
- /* This check must come after the init of head above
- * so we're sure the list is empty for list_empty.
- */
- GF_VALIDATE_OR_GOTO ("call-stub", entries, out);
+call_stub_t *
+fop_rchecksum_cbk_stub(call_frame_t *frame, fop_rchecksum_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, uint32_t weak_checksum,
+ uint8_t *strong_checksum, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- if (op_ret > 0) {
- list_for_each_entry (entry, &entries->list, list) {
- stub_entry = gf_dirent_for_name (entry->d_name);
- if (!stub_entry)
- goto out;
- stub_entry->d_off = entry->d_off;
- stub_entry->d_ino = entry->d_ino;
+ stub = stub_new(frame, 0, GF_FOP_RCHECKSUM);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- list_add_tail (&stub_entry->list,
- &stub->args.readdir_cbk.entries.list);
- }
- }
+ stub->fn_cbk.rchecksum = fn;
+ args_rchecksum_cbk_store(&stub->args_cbk, op_ret, op_errno, weak_checksum,
+ strong_checksum, xdata);
out:
- return stub;
+ return stub;
}
call_stub_t *
-fop_readdir_stub (call_frame_t *frame,
- fop_readdir_t fn,
- fd_t *fd,
- size_t size,
- off_t off)
+fop_xattrop_cbk_stub(call_frame_t *frame, fop_xattrop_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, dict_t *xattr, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 1, GF_FOP_READDIR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->args.readdir.fn = fn;
- stub->args.readdir.fd = fd_ref (fd);
- stub->args.readdir.size = size;
- stub->args.readdir.off = off;
+ stub = stub_new(frame, 0, GF_FOP_XATTROP);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
+ stub->fn_cbk.xattrop = fn;
+ args_xattrop_cbk_store(&stub->args_cbk, op_ret, op_errno, xattr, xdata);
out:
- return stub;
+ return stub;
}
call_stub_t *
-fop_readdirp_stub (call_frame_t *frame,
- fop_readdirp_t fn,
- fd_t *fd,
- size_t size,
- off_t off)
+fop_fxattrop_cbk_stub(call_frame_t *frame, fop_fxattrop_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, dict_t *xattr,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- stub = stub_new (frame, 1, GF_FOP_READDIRP);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ call_stub_t *stub = NULL;
- stub->args.readdirp.fn = fn;
- stub->args.readdirp.fd = fd_ref (fd);
- stub->args.readdirp.size = size;
- stub->args.readdirp.off = off;
+ stub = stub_new(frame, 0, GF_FOP_FXATTROP);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
+ stub->fn_cbk.fxattrop = fn;
+ args_xattrop_cbk_store(&stub->args_cbk, op_ret, op_errno, xattr, xdata);
out:
- return stub;
+ return stub;
}
call_stub_t *
-fop_rchecksum_stub (call_frame_t *frame,
- fop_rchecksum_t fn,
- fd_t *fd, off_t offset,
- int32_t len)
+fop_xattrop_stub(call_frame_t *frame, fop_xattrop_t fn, loc_t *loc,
+ gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", fd, out);
+ GF_VALIDATE_OR_GOTO("call-stub", xattr, out);
- stub = stub_new (frame, 1, GF_FOP_RCHECKSUM);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_XATTROP);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.rchecksum.fn = fn;
- stub->args.rchecksum.fd = fd_ref (fd);
- stub->args.rchecksum.offset = offset;
- stub->args.rchecksum.len = len;
+ stub->fn.xattrop = fn;
+ args_xattrop_store(&stub->args, loc, optype, xattr, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_rchecksum_cbk_stub (call_frame_t *frame,
- fop_rchecksum_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- uint32_t weak_checksum,
- uint8_t *strong_checksum)
+fop_fxattrop_stub(call_frame_t *frame, fop_fxattrop_t fn, fd_t *fd,
+ gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
-
- stub = stub_new (frame, 0, GF_FOP_RCHECKSUM);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ call_stub_t *stub = NULL;
- stub->args.rchecksum_cbk.fn = fn;
- stub->args.rchecksum_cbk.op_ret = op_ret;
- stub->args.rchecksum_cbk.op_errno = op_errno;
+ GF_VALIDATE_OR_GOTO("call-stub", xattr, out);
- if (op_ret >= 0)
- {
- stub->args.rchecksum_cbk.weak_checksum =
- weak_checksum;
+ stub = stub_new(frame, 1, GF_FOP_FXATTROP);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.rchecksum_cbk.strong_checksum =
- memdup (strong_checksum, MD5_DIGEST_LEN);
- }
+ stub->fn.fxattrop = fn;
+ args_fxattrop_store(&stub->args, fd, optype, xattr, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_xattrop_cbk_stub (call_frame_t *frame,
- fop_xattrop_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno)
+fop_setattr_cbk_stub(call_frame_t *frame, fop_setattr_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 0, GF_FOP_SETATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 0, GF_FOP_XATTROP);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub->fn_cbk.setattr = fn;
+ args_setattr_cbk_store(&stub->args_cbk, op_ret, op_errno, statpre, statpost,
+ xdata);
+out:
+ return stub;
+}
- stub->args.xattrop_cbk.fn = fn;
- stub->args.xattrop_cbk.op_ret = op_ret;
- stub->args.xattrop_cbk.op_errno = op_errno;
+call_stub_t *
+fop_fsetattr_cbk_stub(call_frame_t *frame, fop_setattr_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
+
+ stub = stub_new(frame, 0, GF_FOP_FSETATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
+ stub->fn_cbk.fsetattr = fn;
+ args_fsetattr_cbk_store(&stub->args_cbk, op_ret, op_errno, statpre,
+ statpost, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_fxattrop_cbk_stub (call_frame_t *frame,
- fop_fxattrop_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- dict_t *xattr)
+fop_setattr_stub(call_frame_t *frame, fop_setattr_t fn, loc_t *loc,
+ struct iatt *stbuf, int32_t valid, dict_t *xdata)
{
- call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 0, GF_FOP_FXATTROP);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ GF_VALIDATE_OR_GOTO("call-stub", fn, out);
- stub->args.fxattrop_cbk.fn = fn;
- stub->args.fxattrop_cbk.op_ret = op_ret;
- stub->args.fxattrop_cbk.op_errno = op_errno;
- if (xattr)
- stub->args.fxattrop_cbk.xattr = dict_ref (xattr);
+ stub = stub_new(frame, 1, GF_FOP_SETATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
+ stub->fn.setattr = fn;
+ args_setattr_store(&stub->args, loc, stbuf, valid, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_xattrop_stub (call_frame_t *frame,
- fop_xattrop_t fn,
- loc_t *loc,
- gf_xattrop_flags_t optype,
- dict_t *xattr)
+fop_fsetattr_stub(call_frame_t *frame, fop_fsetattr_t fn, fd_t *fd,
+ struct iatt *stbuf, int32_t valid, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
+
+ GF_VALIDATE_OR_GOTO("call-stub", fn, out);
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", xattr, out);
+ stub = stub_new(frame, 1, GF_FOP_FSETATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_XATTROP);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub->fn.fsetattr = fn;
+ args_fsetattr_store(&stub->args, fd, stbuf, valid, xdata);
+out:
+ return stub;
+}
- stub->args.xattrop.fn = fn;
+call_stub_t *
+fop_fallocate_cbk_stub(call_frame_t *frame, fop_fallocate_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- loc_copy (&stub->args.xattrop.loc, loc);
+ stub = stub_new(frame, 0, GF_FOP_FALLOCATE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.xattrop.optype = optype;
- stub->args.xattrop.xattr = dict_ref (xattr);
+ stub->fn_cbk.fallocate = fn;
+ args_fallocate_cbk_store(&stub->args_cbk, op_ret, op_errno, statpre,
+ statpost, xdata);
out:
- return stub;
+ return stub;
}
call_stub_t *
-fop_fxattrop_stub (call_frame_t *frame,
- fop_fxattrop_t fn,
- fd_t *fd,
- gf_xattrop_flags_t optype,
- dict_t *xattr)
+fop_fallocate_stub(call_frame_t *frame, fop_fallocate_t fn, fd_t *fd,
+ int32_t mode, off_t offset, size_t len, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", xattr, out);
+ GF_VALIDATE_OR_GOTO("call-stub", fn, out);
- stub = stub_new (frame, 1, GF_FOP_FXATTROP);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_FALLOCATE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.fxattrop.fn = fn;
+ stub->fn.fallocate = fn;
+ args_fallocate_store(&stub->args, fd, mode, offset, len, xdata);
+out:
+ return stub;
+}
- stub->args.fxattrop.fd = fd_ref (fd);
+call_stub_t *
+fop_discard_cbk_stub(call_frame_t *frame, fop_discard_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- stub->args.fxattrop.optype = optype;
- stub->args.fxattrop.xattr = dict_ref (xattr);
+ stub = stub_new(frame, 0, GF_FOP_DISCARD);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
+ stub->fn_cbk.discard = fn;
+
+ args_discard_cbk_store(&stub->args_cbk, op_ret, op_errno, statpre, statpost,
+ xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_setattr_cbk_stub (call_frame_t *frame,
- fop_setattr_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *statpre,
- struct iatt *statpost)
+fop_discard_stub(call_frame_t *frame, fop_discard_t fn, fd_t *fd, off_t offset,
+ size_t len, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", fn, out);
- stub = stub_new (frame, 0, GF_FOP_SETATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_DISCARD);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.setattr_cbk.fn = fn;
+ stub->fn.discard = fn;
+ args_discard_store(&stub->args, fd, offset, len, xdata);
+out:
+ return stub;
+}
- stub->args.setattr_cbk.op_ret = op_ret;
- stub->args.setattr_cbk.op_errno = op_errno;
+call_stub_t *
+fop_zerofill_cbk_stub(call_frame_t *frame, fop_zerofill_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
+
+ stub = stub_new(frame, 0, GF_FOP_ZEROFILL);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- if (statpre)
- stub->args.setattr_cbk.statpre = *statpre;
- if (statpost)
- stub->args.setattr_cbk.statpost = *statpost;
+ stub->fn_cbk.zerofill = fn;
+ args_zerofill_cbk_store(&stub->args_cbk, op_ret, op_errno, statpre,
+ statpost, xdata);
out:
- return stub;
+ return stub;
}
call_stub_t *
-fop_fsetattr_cbk_stub (call_frame_t *frame,
- fop_setattr_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *statpre,
- struct iatt *statpost)
+fop_zerofill_stub(call_frame_t *frame, fop_zerofill_t fn, fd_t *fd,
+ off_t offset, off_t len, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
-
- stub = stub_new (frame, 0, GF_FOP_FSETATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ call_stub_t *stub = NULL;
- stub->args.fsetattr_cbk.fn = fn;
+ GF_VALIDATE_OR_GOTO("call-stub", fn, out);
- stub->args.fsetattr_cbk.op_ret = op_ret;
- stub->args.fsetattr_cbk.op_errno = op_errno;
+ stub = stub_new(frame, 1, GF_FOP_ZEROFILL);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- if (statpre)
- stub->args.setattr_cbk.statpre = *statpre;
- if (statpost)
- stub->args.fsetattr_cbk.statpost = *statpost;
+ stub->fn.zerofill = fn;
+ args_zerofill_store(&stub->args, fd, offset, len, xdata);
out:
- return stub;
+ return stub;
}
call_stub_t *
-fop_setattr_stub (call_frame_t *frame,
- fop_setattr_t fn,
- loc_t *loc,
- struct iatt *stbuf,
- int32_t valid)
+fop_ipc_cbk_stub(call_frame_t *frame, fop_ipc_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", fn, out);
+ stub = stub_new(frame, 0, GF_FOP_IPC);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_SETATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub->fn_cbk.ipc = fn;
- stub->args.setattr.fn = fn;
+ args_ipc_cbk_store(&stub->args_cbk, op_ret, op_errno, xdata);
+out:
+ return stub;
+}
- loc_copy (&stub->args.setattr.loc, loc);
+call_stub_t *
+fop_ipc_stub(call_frame_t *frame, fop_ipc_t fn, int32_t op, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- if (stbuf)
- stub->args.setattr.stbuf = *stbuf;
+ GF_VALIDATE_OR_GOTO("call-stub", fn, out);
- stub->args.setattr.valid = valid;
+ stub = stub_new(frame, 1, GF_FOP_IPC);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
+ stub->fn.ipc = fn;
+ args_ipc_store(&stub->args, op, xdata);
out:
- return stub;
+ return stub;
}
call_stub_t *
-fop_fsetattr_stub (call_frame_t *frame,
- fop_fsetattr_t fn,
- fd_t *fd,
- struct iatt *stbuf,
- int32_t valid)
+fop_lease_cbk_stub(call_frame_t *frame, fop_lease_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct gf_lease *lease, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", fn, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 1, GF_FOP_FSETATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_LEASE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.fsetattr.fn = fn;
+ stub->fn_cbk.lease = fn;
+ args_lease_cbk_store(&stub->args_cbk, op_ret, op_errno, lease, xdata);
+out:
+ return stub;
+}
- if (fd)
- stub->args.fsetattr.fd = fd_ref (fd);
+call_stub_t *
+fop_lease_stub(call_frame_t *frame, fop_lease_t fn, loc_t *loc,
+ struct gf_lease *lease, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- if (stbuf)
- stub->args.fsetattr.stbuf = *stbuf;
+ GF_VALIDATE_OR_GOTO("call-stub", fn, out);
+ GF_VALIDATE_OR_GOTO("call-stub", lease, out);
- stub->args.fsetattr.valid = valid;
+ stub = stub_new(frame, 1, GF_FOP_LEASE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
+ stub->fn.lease = fn;
+ args_lease_store(&stub->args, loc, lease, xdata);
out:
- return stub;
+ return stub;
}
-static void
-call_resume_wind (call_stub_t *stub)
+call_stub_t *
+fop_seek_cbk_stub(call_frame_t *frame, fop_seek_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, off_t offset, dict_t *xdata)
{
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ call_stub_t *stub = NULL;
- switch (stub->fop) {
- case GF_FOP_OPEN:
- {
- stub->args.open.fn (stub->frame,
- stub->frame->this,
- &stub->args.open.loc,
- stub->args.open.flags, stub->args.open.fd,
- stub->args.open.wbflags);
- break;
- }
- case GF_FOP_CREATE:
- {
- stub->args.create.fn (stub->frame,
- stub->frame->this,
- &stub->args.create.loc,
- stub->args.create.flags,
- stub->args.create.mode,
- stub->args.create.fd,
- stub->args.create.params);
- break;
- }
- case GF_FOP_STAT:
- {
- stub->args.stat.fn (stub->frame,
- stub->frame->this,
- &stub->args.stat.loc);
- break;
- }
- case GF_FOP_READLINK:
- {
- stub->args.readlink.fn (stub->frame,
- stub->frame->this,
- &stub->args.readlink.loc,
- stub->args.readlink.size);
- break;
- }
+ stub = stub_new(frame, 0, GF_FOP_SEEK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- case GF_FOP_MKNOD:
- {
- stub->args.mknod.fn (stub->frame, stub->frame->this,
- &stub->args.mknod.loc,
- stub->args.mknod.mode,
- stub->args.mknod.rdev,
- stub->args.mknod.params);
- }
- break;
+ stub->fn_cbk.seek = fn;
- case GF_FOP_MKDIR:
- {
- stub->args.mkdir.fn (stub->frame, stub->frame->this,
- &stub->args.mkdir.loc,
- stub->args.mkdir.mode,
- stub->args.mkdir.params);
- }
- break;
+ args_seek_cbk_store(&stub->args_cbk, op_ret, op_errno, offset, xdata);
+out:
+ return stub;
+}
- case GF_FOP_UNLINK:
- {
- stub->args.unlink.fn (stub->frame,
- stub->frame->this,
- &stub->args.unlink.loc);
- }
- break;
+call_stub_t *
+fop_seek_stub(call_frame_t *frame, fop_seek_t fn, fd_t *fd, off_t offset,
+ gf_seek_what_t what, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- case GF_FOP_RMDIR:
- {
- stub->args.rmdir.fn (stub->frame, stub->frame->this,
- &stub->args.rmdir.loc,
- stub->args.rmdir.flags);
- }
- break;
+ GF_VALIDATE_OR_GOTO("call-stub", fn, out);
- case GF_FOP_SYMLINK:
- {
- stub->args.symlink.fn (stub->frame,
- stub->frame->this,
- stub->args.symlink.linkname,
- &stub->args.symlink.loc,
- stub->args.symlink.params);
- }
- break;
+ stub = stub_new(frame, 1, GF_FOP_SEEK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- case GF_FOP_RENAME:
- {
- stub->args.rename.fn (stub->frame,
- stub->frame->this,
- &stub->args.rename.old,
- &stub->args.rename.new);
- }
- break;
+ stub->fn.seek = fn;
+ args_seek_store(&stub->args, fd, offset, what, xdata);
+out:
+ return stub;
+}
- case GF_FOP_LINK:
- {
- stub->args.link.fn (stub->frame,
- stub->frame->this,
- &stub->args.link.oldloc,
- &stub->args.link.newloc);
- }
- break;
+call_stub_t *
+fop_getactivelk_cbk_stub(call_frame_t *frame, fop_getactivelk_cbk_t fn,
+ int32_t op_ret, int32_t op_errno,
+ lock_migration_info_t *lmi, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- case GF_FOP_TRUNCATE:
- {
- stub->args.truncate.fn (stub->frame,
- stub->frame->this,
- &stub->args.truncate.loc,
- stub->args.truncate.off);
- break;
- }
+ stub = stub_new(frame, 0, GF_FOP_GETACTIVELK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- case GF_FOP_READ:
- {
- stub->args.readv.fn (stub->frame,
- stub->frame->this,
- stub->args.readv.fd,
- stub->args.readv.size,
- stub->args.readv.off);
- break;
- }
+ stub->fn_cbk.getactivelk = fn;
- case GF_FOP_WRITE:
- {
- stub->args.writev.fn (stub->frame,
- stub->frame->this,
- stub->args.writev.fd,
- stub->args.writev.vector,
- stub->args.writev.count,
- stub->args.writev.off,
- stub->args.writev.iobref);
- break;
- }
+ args_getactivelk_cbk_store(&stub->args_cbk, op_ret, op_errno, lmi, xdata);
+out:
+ return stub;
+}
- case GF_FOP_STATFS:
- {
- stub->args.statfs.fn (stub->frame,
- stub->frame->this,
- &stub->args.statfs.loc);
- break;
- }
- case GF_FOP_FLUSH:
- {
- stub->args.flush.fn (stub->frame,
- stub->frame->this,
- stub->args.flush.fd);
- break;
- }
+call_stub_t *
+fop_getactivelk_stub(call_frame_t *frame, fop_getactivelk_t fn, loc_t *loc,
+ dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- case GF_FOP_FSYNC:
- {
- stub->args.fsync.fn (stub->frame,
- stub->frame->this,
- stub->args.fsync.fd,
- stub->args.fsync.datasync);
- break;
- }
+ GF_VALIDATE_OR_GOTO("call-stub", fn, out);
- case GF_FOP_SETXATTR:
- {
- stub->args.setxattr.fn (stub->frame,
- stub->frame->this,
- &stub->args.setxattr.loc,
- stub->args.setxattr.dict,
- stub->args.setxattr.flags);
- break;
- }
+ stub = stub_new(frame, 1, GF_FOP_GETACTIVELK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- case GF_FOP_GETXATTR:
- {
- stub->args.getxattr.fn (stub->frame,
- stub->frame->this,
- &stub->args.getxattr.loc,
- stub->args.getxattr.name);
- break;
- }
+ stub->fn.getactivelk = fn;
- case GF_FOP_FSETXATTR:
- {
- stub->args.fsetxattr.fn (stub->frame,
- stub->frame->this,
- stub->args.fsetxattr.fd,
- stub->args.fsetxattr.dict,
- stub->args.fsetxattr.flags);
- break;
- }
+ loc_copy(&stub->args.loc, loc);
- case GF_FOP_FGETXATTR:
- {
- stub->args.fgetxattr.fn (stub->frame,
- stub->frame->this,
- stub->args.fgetxattr.fd,
- stub->args.fgetxattr.name);
- break;
- }
+ if (xdata)
+ stub->args.xdata = dict_ref(xdata);
+out:
+ return stub;
+}
- case GF_FOP_REMOVEXATTR:
- {
- stub->args.removexattr.fn (stub->frame,
- stub->frame->this,
- &stub->args.removexattr.loc,
- stub->args.removexattr.name);
- break;
- }
+call_stub_t *
+fop_setactivelk_cbk_stub(call_frame_t *frame, fop_setactivelk_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- case GF_FOP_OPENDIR:
- {
- stub->args.opendir.fn (stub->frame,
- stub->frame->this,
- &stub->args.opendir.loc,
- stub->args.opendir.fd);
- break;
- }
+ stub = stub_new(frame, 0, GF_FOP_SETACTIVELK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- case GF_FOP_FSYNCDIR:
- {
- stub->args.fsyncdir.fn (stub->frame,
- stub->frame->this,
- stub->args.fsyncdir.fd,
- stub->args.fsyncdir.datasync);
- break;
- }
+ stub->fn_cbk.setactivelk = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
- case GF_FOP_ACCESS:
- {
- stub->args.access.fn (stub->frame,
- stub->frame->this,
- &stub->args.access.loc,
- stub->args.access.mask);
- break;
- }
+ if (xdata)
+ stub->args.xdata = dict_ref(xdata);
- case GF_FOP_FTRUNCATE:
- {
- stub->args.ftruncate.fn (stub->frame,
- stub->frame->this,
- stub->args.ftruncate.fd,
- stub->args.ftruncate.off);
- break;
- }
+out:
+ return stub;
+}
- case GF_FOP_FSTAT:
- {
- stub->args.fstat.fn (stub->frame,
- stub->frame->this,
- stub->args.fstat.fd);
- break;
- }
+call_stub_t *
+fop_setactivelk_stub(call_frame_t *frame, fop_setactivelk_t fn, loc_t *loc,
+ lock_migration_info_t *locklist, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- case GF_FOP_LK:
- {
- stub->args.lk.fn (stub->frame,
- stub->frame->this,
- stub->args.lk.fd,
- stub->args.lk.cmd,
- &stub->args.lk.lock);
- break;
- }
+ GF_VALIDATE_OR_GOTO("call-stub", fn, out);
- case GF_FOP_INODELK:
- {
- stub->args.inodelk.fn (stub->frame,
- stub->frame->this,
- stub->args.inodelk.volume,
- &stub->args.inodelk.loc,
- stub->args.inodelk.cmd,
- &stub->args.inodelk.lock);
- break;
- }
+ stub = stub_new(frame, 1, GF_FOP_SETACTIVELK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- case GF_FOP_FINODELK:
- {
- stub->args.finodelk.fn (stub->frame,
- stub->frame->this,
- stub->args.finodelk.volume,
- stub->args.finodelk.fd,
- stub->args.finodelk.cmd,
- &stub->args.finodelk.lock);
- break;
- }
+ stub->fn.setactivelk = fn;
- case GF_FOP_ENTRYLK:
- {
- stub->args.entrylk.fn (stub->frame,
- stub->frame->this,
- stub->args.entrylk.volume,
- &stub->args.entrylk.loc,
- stub->args.entrylk.name,
- stub->args.entrylk.cmd,
- stub->args.entrylk.type);
- break;
- }
+ args_setactivelk_store(&stub->args, loc, locklist, xdata);
- case GF_FOP_FENTRYLK:
- {
- stub->args.fentrylk.fn (stub->frame,
- stub->frame->this,
- stub->args.fentrylk.volume,
- stub->args.fentrylk.fd,
- stub->args.fentrylk.name,
- stub->args.fentrylk.cmd,
- stub->args.fentrylk.type);
- break;
- }
-
- break;
+out:
+ return stub;
+}
- case GF_FOP_LOOKUP:
- {
- stub->args.lookup.fn (stub->frame,
- stub->frame->this,
- &stub->args.lookup.loc,
- stub->args.lookup.xattr_req);
- break;
- }
+call_stub_t *
+fop_copy_file_range_stub(call_frame_t *frame, fop_copy_file_range_t fn,
+ fd_t *fd_in, off64_t off_in, fd_t *fd_out,
+ off64_t off_out, size_t len, uint32_t flags,
+ dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- case GF_FOP_RCHECKSUM:
- {
- stub->args.rchecksum.fn (stub->frame,
- stub->frame->this,
- stub->args.rchecksum.fd,
- stub->args.rchecksum.offset,
- stub->args.rchecksum.len);
- break;
- }
+ GF_VALIDATE_OR_GOTO("call-stub", fn, out);
- case GF_FOP_READDIR:
- {
- stub->args.readdir.fn (stub->frame,
- stub->frame->this,
- stub->args.readdir.fd,
- stub->args.readdir.size,
- stub->args.readdir.off);
- break;
- }
+ stub = stub_new(frame, 1, GF_FOP_COPY_FILE_RANGE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- case GF_FOP_READDIRP:
- {
- stub->args.readdirp.fn (stub->frame,
- stub->frame->this,
- stub->args.readdirp.fd,
- stub->args.readdirp.size,
- stub->args.readdirp.off);
- break;
- }
+ stub->fn.copy_file_range = fn;
- case GF_FOP_XATTROP:
- {
- stub->args.xattrop.fn (stub->frame,
- stub->frame->this,
- &stub->args.xattrop.loc,
- stub->args.xattrop.optype,
- stub->args.xattrop.xattr);
-
- break;
- }
- case GF_FOP_FXATTROP:
- {
- stub->args.fxattrop.fn (stub->frame,
- stub->frame->this,
- stub->args.fxattrop.fd,
- stub->args.fxattrop.optype,
- stub->args.fxattrop.xattr);
-
- break;
- }
- case GF_FOP_SETATTR:
- {
- stub->args.setattr.fn (stub->frame,
- stub->frame->this,
- &stub->args.setattr.loc,
- &stub->args.setattr.stbuf,
- stub->args.setattr.valid);
- break;
- }
- case GF_FOP_FSETATTR:
- {
- stub->args.fsetattr.fn (stub->frame,
- stub->frame->this,
- stub->args.fsetattr.fd,
- &stub->args.fsetattr.stbuf,
- stub->args.fsetattr.valid);
- break;
- }
- default:
- {
- gf_log_callingfn ("call-stub", GF_LOG_ERROR,
- "Invalid value of FOP (%d)",
- stub->fop);
- break;
- }
+ args_copy_file_range_store(&stub->args, fd_in, off_in, fd_out, off_out, len,
+ flags, xdata);
- }
out:
- return;
+ return stub;
}
-
-
-static void
-call_resume_unwind (call_stub_t *stub)
+call_stub_t *
+fop_copy_file_range_cbk_stub(call_frame_t *frame, fop_copy_file_range_cbk_t fn,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *stbuf, struct iatt *prebuf_dst,
+ struct iatt *postbuf_dst, dict_t *xdata)
{
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- switch (stub->fop) {
- case GF_FOP_OPEN:
- {
- if (!stub->args.open_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.open_cbk.op_ret,
- stub->args.open_cbk.op_errno,
- stub->args.open_cbk.fd);
- else
- stub->args.open_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.open_cbk.op_ret,
- stub->args.open_cbk.op_errno,
- stub->args.open_cbk.fd);
- break;
- }
-
- case GF_FOP_CREATE:
- {
- if (!stub->args.create_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.create_cbk.op_ret,
- stub->args.create_cbk.op_errno,
- stub->args.create_cbk.fd,
- stub->args.create_cbk.inode,
- &stub->args.create_cbk.buf,
- &stub->args.create_cbk.preparent,
- &stub->args.create_cbk.postparent);
- else
- stub->args.create_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.create_cbk.op_ret,
- stub->args.create_cbk.op_errno,
- stub->args.create_cbk.fd,
- stub->args.create_cbk.inode,
- &stub->args.create_cbk.buf,
- &stub->args.create_cbk.preparent,
- &stub->args.create_cbk.postparent);
-
- break;
- }
+ call_stub_t *stub = NULL;
- case GF_FOP_STAT:
- {
- if (!stub->args.stat_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.stat_cbk.op_ret,
- stub->args.stat_cbk.op_errno,
- &stub->args.stat_cbk.buf);
- else
- stub->args.stat_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.stat_cbk.op_ret,
- stub->args.stat_cbk.op_errno,
- &stub->args.stat_cbk.buf);
-
- break;
- }
+ GF_VALIDATE_OR_GOTO("call-stub", fn, out);
- case GF_FOP_READLINK:
- {
- if (!stub->args.readlink_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.readlink_cbk.op_ret,
- stub->args.readlink_cbk.op_errno,
- stub->args.readlink_cbk.buf,
- &stub->args.readlink_cbk.sbuf);
- else
- stub->args.readlink_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.readlink_cbk.op_ret,
- stub->args.readlink_cbk.op_errno,
- stub->args.readlink_cbk.buf,
- &stub->args.readlink_cbk.sbuf);
-
- break;
- }
-
- case GF_FOP_MKNOD:
- {
- if (!stub->args.mknod_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.mknod_cbk.op_ret,
- stub->args.mknod_cbk.op_errno,
- stub->args.mknod_cbk.inode,
- &stub->args.mknod_cbk.buf,
- &stub->args.mknod_cbk.preparent,
- &stub->args.mknod_cbk.postparent);
- else
- stub->args.mknod_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.mknod_cbk.op_ret,
- stub->args.mknod_cbk.op_errno,
- stub->args.mknod_cbk.inode,
- &stub->args.mknod_cbk.buf,
- &stub->args.mknod_cbk.preparent,
- &stub->args.mknod_cbk.postparent);
- break;
- }
+ stub = stub_new(frame, 0, GF_FOP_COPY_FILE_RANGE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- case GF_FOP_MKDIR:
- {
- if (!stub->args.mkdir_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.mkdir_cbk.op_ret,
- stub->args.mkdir_cbk.op_errno,
- stub->args.mkdir_cbk.inode,
- &stub->args.mkdir_cbk.buf,
- &stub->args.mkdir_cbk.preparent,
- &stub->args.mkdir_cbk.postparent);
- else
- stub->args.mkdir_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.mkdir_cbk.op_ret,
- stub->args.mkdir_cbk.op_errno,
- stub->args.mkdir_cbk.inode,
- &stub->args.mkdir_cbk.buf,
- &stub->args.mkdir_cbk.preparent,
- &stub->args.mkdir_cbk.postparent);
-
- if (stub->args.mkdir_cbk.inode)
- inode_unref (stub->args.mkdir_cbk.inode);
-
- break;
- }
+ stub->fn_cbk.copy_file_range = fn;
+ args_copy_file_range_cbk_store(&stub->args_cbk, op_ret, op_errno, stbuf,
+ prebuf_dst, postbuf_dst, xdata);
- case GF_FOP_UNLINK:
- {
- if (!stub->args.unlink_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.unlink_cbk.op_ret,
- stub->args.unlink_cbk.op_errno,
- &stub->args.unlink_cbk.preparent,
- &stub->args.unlink_cbk.postparent);
- else
- stub->args.unlink_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.unlink_cbk.op_ret,
- stub->args.unlink_cbk.op_errno,
- &stub->args.unlink_cbk.preparent,
- &stub->args.unlink_cbk.postparent);
- break;
- }
+out:
+ return stub;
+}
- case GF_FOP_RMDIR:
- {
- if (!stub->args.rmdir_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.rmdir_cbk.op_ret,
- stub->args.rmdir_cbk.op_errno,
- &stub->args.rmdir_cbk.preparent,
- &stub->args.rmdir_cbk.postparent);
- else
- stub->args.rmdir_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.rmdir_cbk.op_ret,
- stub->args.rmdir_cbk.op_errno,
- &stub->args.rmdir_cbk.preparent,
- &stub->args.rmdir_cbk.postparent);
- break;
- }
+call_stub_t *
+fop_put_stub(call_frame_t *frame, fop_put_t fn, loc_t *loc, mode_t mode,
+ mode_t umask, uint32_t flags, struct iovec *vector, int32_t count,
+ off_t offset, struct iobref *iobref, dict_t *xattr, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- case GF_FOP_SYMLINK:
- {
- if (!stub->args.symlink_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.symlink_cbk.op_ret,
- stub->args.symlink_cbk.op_errno,
- stub->args.symlink_cbk.inode,
- &stub->args.symlink_cbk.buf,
- &stub->args.symlink_cbk.preparent,
- &stub->args.symlink_cbk.postparent);
- else
- stub->args.symlink_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.symlink_cbk.op_ret,
- stub->args.symlink_cbk.op_errno,
- stub->args.symlink_cbk.inode,
- &stub->args.symlink_cbk.buf,
- &stub->args.symlink_cbk.preparent,
- &stub->args.symlink_cbk.postparent);
- }
- break;
+ GF_VALIDATE_OR_GOTO("call-stub", vector, out);
- case GF_FOP_RENAME:
- {
- if (!stub->args.rename_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.rename_cbk.op_ret,
- stub->args.rename_cbk.op_errno,
- &stub->args.rename_cbk.buf,
- &stub->args.rename_cbk.preoldparent,
- &stub->args.rename_cbk.postoldparent,
- &stub->args.rename_cbk.prenewparent,
- &stub->args.rename_cbk.postnewparent);
- else
- stub->args.rename_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.rename_cbk.op_ret,
- stub->args.rename_cbk.op_errno,
- &stub->args.rename_cbk.buf,
- &stub->args.rename_cbk.preoldparent,
- &stub->args.rename_cbk.postoldparent,
- &stub->args.rename_cbk.prenewparent,
- &stub->args.rename_cbk.postnewparent);
- break;
- }
+ stub = stub_new(frame, 1, GF_FOP_PUT);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- case GF_FOP_LINK:
- {
- if (!stub->args.link_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.link_cbk.op_ret,
- stub->args.link_cbk.op_errno,
- stub->args.link_cbk.inode,
- &stub->args.link_cbk.buf);
- else
- stub->args.link_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.link_cbk.op_ret,
- stub->args.link_cbk.op_errno,
- stub->args.link_cbk.inode,
- &stub->args.link_cbk.buf,
- &stub->args.link_cbk.preparent,
- &stub->args.link_cbk.postparent);
- break;
- }
+ stub->fn.put = fn;
+ args_put_store(&stub->args, loc, mode, umask, flags, vector, count, offset,
+ iobref, xattr, xdata);
+out:
+ return stub;
+}
- case GF_FOP_TRUNCATE:
- {
- if (!stub->args.truncate_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.truncate_cbk.op_ret,
- stub->args.truncate_cbk.op_errno,
- &stub->args.truncate_cbk.prebuf,
- &stub->args.truncate_cbk.postbuf);
- else
- stub->args.truncate_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.truncate_cbk.op_ret,
- stub->args.truncate_cbk.op_errno,
- &stub->args.truncate_cbk.prebuf,
- &stub->args.truncate_cbk.postbuf);
- break;
- }
+call_stub_t *
+fop_put_cbk_stub(call_frame_t *frame, fop_put_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- case GF_FOP_READ:
- {
- if (!stub->args.readv_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.readv_cbk.op_ret,
- stub->args.readv_cbk.op_errno,
- stub->args.readv_cbk.vector,
- stub->args.readv_cbk.count,
- &stub->args.readv_cbk.stbuf,
- stub->args.readv_cbk.iobref);
- else
- stub->args.readv_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.readv_cbk.op_ret,
- stub->args.readv_cbk.op_errno,
- stub->args.readv_cbk.vector,
- stub->args.readv_cbk.count,
- &stub->args.readv_cbk.stbuf,
- stub->args.readv_cbk.iobref);
- }
- break;
+ stub = stub_new(frame, 0, GF_FOP_PUT);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- case GF_FOP_WRITE:
- {
- if (!stub->args.writev_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.writev_cbk.op_ret,
- stub->args.writev_cbk.op_errno,
- &stub->args.writev_cbk.prebuf,
- &stub->args.writev_cbk.postbuf);
- else
- stub->args.writev_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.writev_cbk.op_ret,
- stub->args.writev_cbk.op_errno,
- &stub->args.writev_cbk.prebuf,
- &stub->args.writev_cbk.postbuf);
- break;
- }
+ stub->fn_cbk.put = fn;
+ args_put_cbk_store(&stub->args_cbk, op_ret, op_errno, inode, buf, preparent,
+ postparent, xdata);
+out:
+ return stub;
+}
- case GF_FOP_STATFS:
- {
- if (!stub->args.statfs_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.statfs_cbk.op_ret,
- stub->args.statfs_cbk.op_errno,
- &(stub->args.statfs_cbk.buf));
- else
- stub->args.statfs_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.statfs_cbk.op_ret,
- stub->args.statfs_cbk.op_errno,
- &(stub->args.statfs_cbk.buf));
- }
- break;
+call_stub_t *
+fop_icreate_stub(call_frame_t *frame, fop_icreate_t fn, loc_t *loc, mode_t mode,
+ dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- case GF_FOP_FLUSH:
- {
- if (!stub->args.flush_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.flush_cbk.op_ret,
- stub->args.flush_cbk.op_errno);
- else
- stub->args.flush_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.flush_cbk.op_ret,
- stub->args.flush_cbk.op_errno);
-
- break;
- }
+ GF_VALIDATE_OR_GOTO("call-stub", fn, out);
- case GF_FOP_FSYNC:
- {
- if (!stub->args.fsync_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.fsync_cbk.op_ret,
- stub->args.fsync_cbk.op_errno,
- &stub->args.fsync_cbk.prebuf,
- &stub->args.fsync_cbk.postbuf);
- else
- stub->args.fsync_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.fsync_cbk.op_ret,
- stub->args.fsync_cbk.op_errno,
- &stub->args.fsync_cbk.prebuf,
- &stub->args.fsync_cbk.postbuf);
- break;
- }
+ stub = stub_new(frame, 1, GF_FOP_ICREATE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- case GF_FOP_SETXATTR:
- {
- if (!stub->args.setxattr_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.setxattr_cbk.op_ret,
- stub->args.setxattr_cbk.op_errno);
-
- else
- stub->args.setxattr_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.setxattr_cbk.op_ret,
- stub->args.setxattr_cbk.op_errno);
-
- break;
- }
+ stub->fn.icreate = fn;
- case GF_FOP_GETXATTR:
- {
- if (!stub->args.getxattr_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.getxattr_cbk.op_ret,
- stub->args.getxattr_cbk.op_errno,
- stub->args.getxattr_cbk.dict);
- else
- stub->args.getxattr_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.getxattr_cbk.op_ret,
- stub->args.getxattr_cbk.op_errno,
- stub->args.getxattr_cbk.dict);
- break;
- }
+ stub->args.mode = mode;
+ if (loc)
+ loc_copy(&stub->args.loc, loc);
+ if (xdata)
+ stub->args.xdata = dict_ref(xdata);
- case GF_FOP_FSETXATTR:
- {
- if (!stub->args.fsetxattr_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.fsetxattr_cbk.op_ret,
- stub->args.fsetxattr_cbk.op_errno);
-
- else
- stub->args.fsetxattr_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.fsetxattr_cbk.op_ret,
- stub->args.fsetxattr_cbk.op_errno);
-
- break;
- }
+out:
+ return stub;
+}
- case GF_FOP_FGETXATTR:
- {
- if (!stub->args.fgetxattr_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.fgetxattr_cbk.op_ret,
- stub->args.fgetxattr_cbk.op_errno,
- stub->args.fgetxattr_cbk.dict);
- else
- stub->args.fgetxattr_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.fgetxattr_cbk.op_ret,
- stub->args.fgetxattr_cbk.op_errno,
- stub->args.fgetxattr_cbk.dict);
- break;
- }
+static void
+args_icreate_store_cbk(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (inode)
+ args->inode = inode_ref(inode);
+ if (buf)
+ args->stat = *buf;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+}
- case GF_FOP_REMOVEXATTR:
- {
- if (!stub->args.removexattr_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.removexattr_cbk.op_ret,
- stub->args.removexattr_cbk.op_errno);
- else
- stub->args.removexattr_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.removexattr_cbk.op_ret,
- stub->args.removexattr_cbk.op_errno);
-
- break;
- }
+call_stub_t *
+fop_icreate_cbk_stub(call_frame_t *frame, fop_icreate_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- case GF_FOP_OPENDIR:
- {
- if (!stub->args.opendir_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.opendir_cbk.op_ret,
- stub->args.opendir_cbk.op_errno,
- stub->args.opendir_cbk.fd);
- else
- stub->args.opendir_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.opendir_cbk.op_ret,
- stub->args.opendir_cbk.op_errno,
- stub->args.opendir_cbk.fd);
- break;
- }
+ stub = stub_new(frame, 0, GF_FOP_ICREATE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- case GF_FOP_FSYNCDIR:
- {
- if (!stub->args.fsyncdir_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.fsyncdir_cbk.op_ret,
- stub->args.fsyncdir_cbk.op_errno);
- else
- stub->args.fsyncdir_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.fsyncdir_cbk.op_ret,
- stub->args.fsyncdir_cbk.op_errno);
- break;
- }
+ stub->fn_cbk.icreate = fn;
+ args_icreate_store_cbk(&stub->args_cbk, op_ret, op_errno, inode, buf,
+ xdata);
- case GF_FOP_ACCESS:
- {
- if (!stub->args.access_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.access_cbk.op_ret,
- stub->args.access_cbk.op_errno);
- else
- stub->args.access_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.access_cbk.op_ret,
- stub->args.access_cbk.op_errno);
-
- break;
- }
+out:
+ return stub;
+}
- case GF_FOP_FTRUNCATE:
- {
- if (!stub->args.ftruncate_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.ftruncate_cbk.op_ret,
- stub->args.ftruncate_cbk.op_errno,
- &stub->args.ftruncate_cbk.prebuf,
- &stub->args.ftruncate_cbk.postbuf);
- else
- stub->args.ftruncate_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.ftruncate_cbk.op_ret,
- stub->args.ftruncate_cbk.op_errno,
- &stub->args.ftruncate_cbk.prebuf,
- &stub->args.ftruncate_cbk.postbuf);
- break;
- }
+call_stub_t *
+fop_namelink_stub(call_frame_t *frame, fop_namelink_t fn, loc_t *loc,
+ dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- case GF_FOP_FSTAT:
- {
- if (!stub->args.fstat_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.fstat_cbk.op_ret,
- stub->args.fstat_cbk.op_errno,
- &stub->args.fstat_cbk.buf);
- else
- stub->args.fstat_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.fstat_cbk.op_ret,
- stub->args.fstat_cbk.op_errno,
- &stub->args.fstat_cbk.buf);
-
- break;
- }
+ GF_VALIDATE_OR_GOTO("call-stub", fn, out);
- case GF_FOP_LK:
- {
- if (!stub->args.lk_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.lk_cbk.op_ret,
- stub->args.lk_cbk.op_errno,
- &stub->args.lk_cbk.lock);
- else
- stub->args.lk_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.lk_cbk.op_ret,
- stub->args.lk_cbk.op_errno,
- &stub->args.lk_cbk.lock);
- break;
- }
+ stub = stub_new(frame, 1, GF_FOP_NAMELINK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- case GF_FOP_INODELK:
- {
- if (!stub->args.inodelk_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.inodelk_cbk.op_ret,
- stub->args.inodelk_cbk.op_errno);
-
- else
- stub->args.inodelk_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.inodelk_cbk.op_ret,
- stub->args.inodelk_cbk.op_errno);
- break;
- }
+ stub->fn.namelink = fn;
- case GF_FOP_FINODELK:
- {
- if (!stub->args.finodelk_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.finodelk_cbk.op_ret,
- stub->args.finodelk_cbk.op_errno);
-
- else
- stub->args.finodelk_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.finodelk_cbk.op_ret,
- stub->args.finodelk_cbk.op_errno);
- break;
- }
+ if (loc)
+ loc_copy(&stub->args.loc, loc);
+ if (xdata)
+ stub->args.xdata = dict_ref(xdata);
- case GF_FOP_ENTRYLK:
- {
- if (!stub->args.entrylk_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.entrylk_cbk.op_ret,
- stub->args.entrylk_cbk.op_errno);
-
- else
- stub->args.entrylk_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.entrylk_cbk.op_ret,
- stub->args.entrylk_cbk.op_errno);
- break;
- }
+out:
+ return stub;
+}
- case GF_FOP_FENTRYLK:
- {
- if (!stub->args.fentrylk_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.fentrylk_cbk.op_ret,
- stub->args.fentrylk_cbk.op_errno);
-
- else
- stub->args.fentrylk_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.fentrylk_cbk.op_ret,
- stub->args.fentrylk_cbk.op_errno);
- break;
- }
+static void
+args_namelink_store_cbk(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
- case GF_FOP_LOOKUP:
- {
- if (!stub->args.lookup_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.lookup_cbk.op_ret,
- stub->args.lookup_cbk.op_errno,
- stub->args.lookup_cbk.inode,
- &stub->args.lookup_cbk.buf,
- stub->args.lookup_cbk.dict,
- &stub->args.lookup_cbk.postparent);
- else
- stub->args.lookup_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.lookup_cbk.op_ret,
- stub->args.lookup_cbk.op_errno,
- stub->args.lookup_cbk.inode,
- &stub->args.lookup_cbk.buf,
- stub->args.lookup_cbk.dict,
- &stub->args.lookup_cbk.postparent);
- /* FIXME NULL should not be passed */
-
- if (stub->args.lookup_cbk.dict)
- dict_unref (stub->args.lookup_cbk.dict);
- if (stub->args.lookup_cbk.inode)
- inode_unref (stub->args.lookup_cbk.inode);
-
- break;
- }
+ if (prebuf)
+ args->prestat = *prebuf;
+ if (postbuf)
+ args->poststat = *postbuf;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+}
- case GF_FOP_RCHECKSUM:
- {
- if (!stub->args.rchecksum_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.rchecksum_cbk.op_ret,
- stub->args.rchecksum_cbk.op_errno,
- stub->args.rchecksum_cbk.weak_checksum,
- stub->args.rchecksum_cbk.strong_checksum);
- else
- stub->args.rchecksum_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.rchecksum_cbk.op_ret,
- stub->args.rchecksum_cbk.op_errno,
- stub->args.rchecksum_cbk.weak_checksum,
- stub->args.rchecksum_cbk.strong_checksum);
- if (stub->args.rchecksum_cbk.op_ret >= 0)
- {
- GF_FREE (stub->args.rchecksum_cbk.strong_checksum);
- }
-
- break;
- }
+call_stub_t *
+fop_namelink_cbk_stub(call_frame_t *frame, fop_namelink_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- case GF_FOP_READDIR:
- {
- if (!stub->args.readdir_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.readdir_cbk.op_ret,
- stub->args.readdir_cbk.op_errno,
- &stub->args.readdir_cbk.entries);
- else
- stub->args.readdir_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.readdir_cbk.op_ret,
- stub->args.readdir_cbk.op_errno,
- &stub->args.readdir_cbk.entries);
-
- if (stub->args.readdir_cbk.op_ret > 0)
- gf_dirent_free (&stub->args.readdir_cbk.entries);
-
- break;
- }
+ stub = stub_new(frame, 0, GF_FOP_NAMELINK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- case GF_FOP_READDIRP:
- {
- if (!stub->args.readdirp_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.readdirp_cbk.op_ret,
- stub->args.readdirp_cbk.op_errno,
- &stub->args.readdirp_cbk.entries);
- else
- stub->args.readdirp_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.readdirp_cbk.op_ret,
- stub->args.readdirp_cbk.op_errno,
- &stub->args.readdirp_cbk.entries);
-
- if (stub->args.readdirp_cbk.op_ret > 0)
- gf_dirent_free (&stub->args.readdirp_cbk.entries);
-
- break;
- }
+ stub->fn_cbk.namelink = fn;
+ args_namelink_store_cbk(&stub->args_cbk, op_ret, op_errno, prebuf, postbuf,
+ xdata);
- case GF_FOP_XATTROP:
- {
- if (!stub->args.xattrop_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.xattrop_cbk.op_ret,
- stub->args.xattrop_cbk.op_errno);
- else
- stub->args.xattrop_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.xattrop_cbk.op_ret,
- stub->args.xattrop_cbk.op_errno,
- stub->args.xattrop_cbk.xattr);
-
- if (stub->args.xattrop_cbk.xattr)
- dict_unref (stub->args.xattrop_cbk.xattr);
-
- break;
- }
- case GF_FOP_FXATTROP:
- {
- if (!stub->args.fxattrop_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.fxattrop_cbk.op_ret,
- stub->args.fxattrop_cbk.op_errno);
- else
- stub->args.fxattrop_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.fxattrop_cbk.op_ret,
- stub->args.fxattrop_cbk.op_errno,
- stub->args.fxattrop_cbk.xattr);
-
- if (stub->args.fxattrop_cbk.xattr)
- dict_unref (stub->args.fxattrop_cbk.xattr);
-
- break;
- }
- case GF_FOP_SETATTR:
- {
- if (!stub->args.setattr_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.setattr_cbk.op_ret,
- stub->args.setattr_cbk.op_errno,
- &stub->args.setattr_cbk.statpre,
- &stub->args.setattr_cbk.statpost);
- else
- stub->args.setattr_cbk.fn (
- stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.setattr_cbk.op_ret,
- stub->args.setattr_cbk.op_errno,
- &stub->args.setattr_cbk.statpre,
- &stub->args.setattr_cbk.statpost);
- break;
- }
- case GF_FOP_FSETATTR:
- {
- if (!stub->args.fsetattr_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.fsetattr_cbk.op_ret,
- stub->args.fsetattr_cbk.op_errno,
- &stub->args.fsetattr_cbk.statpre,
- &stub->args.fsetattr_cbk.statpost);
- else
- stub->args.fsetattr_cbk.fn (
- stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.fsetattr_cbk.op_ret,
- stub->args.fsetattr_cbk.op_errno,
- &stub->args.fsetattr_cbk.statpre,
- &stub->args.fsetattr_cbk.statpost);
- break;
- }
- default:
- {
- gf_log_callingfn ("call-stub", GF_LOG_ERROR,
- "Invalid value of FOP (%d)",
- stub->fop);
- break;
- }
- }
out:
- return;
+ return stub;
}
-
-static void
-call_stub_destroy_wind (call_stub_t *stub)
+void
+call_resume_wind(call_stub_t *stub)
{
- switch (stub->fop) {
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
+
+ switch (stub->fop) {
case GF_FOP_OPEN:
- {
- loc_wipe (&stub->args.open.loc);
- if (stub->args.open.fd)
- fd_unref (stub->args.open.fd);
- break;
- }
+ stub->fn.open(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.flags, stub->args.fd, stub->args.xdata);
+ break;
case GF_FOP_CREATE:
- {
- loc_wipe (&stub->args.create.loc);
- if (stub->args.create.fd)
- fd_unref (stub->args.create.fd);
- if (stub->args.create.params)
- dict_unref (stub->args.create.params);
- break;
- }
+ stub->fn.create(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.flags, stub->args.mode, stub->args.umask,
+ stub->args.fd, stub->args.xdata);
+ break;
case GF_FOP_STAT:
- {
- loc_wipe (&stub->args.stat.loc);
- break;
- }
+ stub->fn.stat(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.xdata);
+ break;
case GF_FOP_READLINK:
- {
- loc_wipe (&stub->args.readlink.loc);
- break;
- }
-
+ stub->fn.readlink(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.size, stub->args.xdata);
+ break;
case GF_FOP_MKNOD:
- {
- loc_wipe (&stub->args.mknod.loc);
- if (stub->args.mknod.params)
- dict_unref (stub->args.mknod.params);
- }
- break;
-
+ stub->fn.mknod(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.mode, stub->args.rdev, stub->args.umask,
+ stub->args.xdata);
+ break;
case GF_FOP_MKDIR:
- {
- loc_wipe (&stub->args.mkdir.loc);
- if (stub->args.mkdir.params)
- dict_unref (stub->args.mkdir.params);
- }
- break;
-
+ stub->fn.mkdir(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.mode, stub->args.umask, stub->args.xdata);
+ break;
case GF_FOP_UNLINK:
- {
- loc_wipe (&stub->args.unlink.loc);
- }
- break;
-
+ stub->fn.unlink(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.xflag, stub->args.xdata);
+ break;
case GF_FOP_RMDIR:
- {
- loc_wipe (&stub->args.rmdir.loc);
- }
- break;
-
+ stub->fn.rmdir(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.flags, stub->args.xdata);
+ break;
case GF_FOP_SYMLINK:
- {
- GF_FREE ((char *)stub->args.symlink.linkname);
- loc_wipe (&stub->args.symlink.loc);
- if (stub->args.symlink.params)
- dict_unref (stub->args.symlink.params);
- }
- break;
-
+ stub->fn.symlink(stub->frame, stub->frame->this,
+ stub->args.linkname, &stub->args.loc,
+ stub->args.umask, stub->args.xdata);
+ break;
case GF_FOP_RENAME:
- {
- loc_wipe (&stub->args.rename.old);
- loc_wipe (&stub->args.rename.new);
- }
- break;
-
+ stub->fn.rename(stub->frame, stub->frame->this, &stub->args.loc,
+ &stub->args.loc2, stub->args.xdata);
+ break;
case GF_FOP_LINK:
- {
- loc_wipe (&stub->args.link.oldloc);
- loc_wipe (&stub->args.link.newloc);
- }
- break;
-
+ stub->fn.link(stub->frame, stub->frame->this, &stub->args.loc,
+ &stub->args.loc2, stub->args.xdata);
+ break;
case GF_FOP_TRUNCATE:
- {
- loc_wipe (&stub->args.truncate.loc);
- break;
- }
-
+ stub->fn.truncate(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.offset, stub->args.xdata);
+ break;
case GF_FOP_READ:
- {
- if (stub->args.readv.fd)
- fd_unref (stub->args.readv.fd);
- break;
- }
-
+ stub->fn.readv(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.size, stub->args.offset, stub->args.flags,
+ stub->args.xdata);
+ break;
case GF_FOP_WRITE:
- {
- struct iobref *iobref = stub->args.writev.iobref;
- if (stub->args.writev.fd)
- fd_unref (stub->args.writev.fd);
- GF_FREE (stub->args.writev.vector);
- if (iobref)
- iobref_unref (iobref);
- break;
- }
-
+ stub->fn.writev(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.vector, stub->args.count,
+ stub->args.offset, stub->args.flags,
+ stub->args.iobref, stub->args.xdata);
+ break;
case GF_FOP_STATFS:
- {
- loc_wipe (&stub->args.statfs.loc);
- break;
- }
+ stub->fn.statfs(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.xdata);
+ break;
case GF_FOP_FLUSH:
- {
- if (stub->args.flush.fd)
- fd_unref (stub->args.flush.fd);
- break;
- }
-
+ stub->fn.flush(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.xdata);
+ break;
case GF_FOP_FSYNC:
- {
- if (stub->args.fsync.fd)
- fd_unref (stub->args.fsync.fd);
- break;
- }
-
+ stub->fn.fsync(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.datasync, stub->args.xdata);
+ break;
case GF_FOP_SETXATTR:
- {
- loc_wipe (&stub->args.setxattr.loc);
- if (stub->args.setxattr.dict)
- dict_unref (stub->args.setxattr.dict);
- break;
- }
-
+ stub->fn.setxattr(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.xattr, stub->args.flags,
+ stub->args.xdata);
+ break;
case GF_FOP_GETXATTR:
- {
- if (stub->args.getxattr.name)
- GF_FREE ((char *)stub->args.getxattr.name);
- loc_wipe (&stub->args.getxattr.loc);
- break;
- }
-
+ stub->fn.getxattr(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.name, stub->args.xdata);
+ break;
case GF_FOP_FSETXATTR:
- {
- fd_unref (stub->args.fsetxattr.fd);
- if (stub->args.fsetxattr.dict)
- dict_unref (stub->args.fsetxattr.dict);
- break;
- }
-
+ stub->fn.fsetxattr(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.xattr, stub->args.flags,
+ stub->args.xdata);
+ break;
case GF_FOP_FGETXATTR:
- {
- if (stub->args.fgetxattr.name)
- GF_FREE ((char *)stub->args.fgetxattr.name);
- fd_unref (stub->args.fgetxattr.fd);
- break;
- }
-
+ stub->fn.fgetxattr(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.name, stub->args.xdata);
+ break;
case GF_FOP_REMOVEXATTR:
- {
- loc_wipe (&stub->args.removexattr.loc);
- GF_FREE ((char *)stub->args.removexattr.name);
- break;
- }
-
+ stub->fn.removexattr(stub->frame, stub->frame->this,
+ &stub->args.loc, stub->args.name,
+ stub->args.xdata);
+ break;
+ case GF_FOP_FREMOVEXATTR:
+ stub->fn.fremovexattr(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.name, stub->args.xdata);
+ break;
case GF_FOP_OPENDIR:
- {
- loc_wipe (&stub->args.opendir.loc);
- if (stub->args.opendir.fd)
- fd_unref (stub->args.opendir.fd);
- break;
- }
-
+ stub->fn.opendir(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.fd, stub->args.xdata);
+ break;
case GF_FOP_FSYNCDIR:
- {
- if (stub->args.fsyncdir.fd)
- fd_unref (stub->args.fsyncdir.fd);
- break;
- }
-
+ stub->fn.fsyncdir(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.datasync, stub->args.xdata);
+ break;
case GF_FOP_ACCESS:
- {
- loc_wipe (&stub->args.access.loc);
- break;
- }
+ stub->fn.access(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.mask, stub->args.xdata);
+ break;
case GF_FOP_FTRUNCATE:
- {
- if (stub->args.ftruncate.fd)
- fd_unref (stub->args.ftruncate.fd);
- break;
- }
-
+ stub->fn.ftruncate(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.offset, stub->args.xdata);
+ break;
case GF_FOP_FSTAT:
- {
- if (stub->args.fstat.fd)
- fd_unref (stub->args.fstat.fd);
- break;
- }
-
+ stub->fn.fstat(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.xdata);
+ break;
case GF_FOP_LK:
- {
- if (stub->args.lk.fd)
- fd_unref (stub->args.lk.fd);
- break;
- }
-
+ stub->fn.lk(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.cmd, &stub->args.lock, stub->args.xdata);
+ break;
case GF_FOP_INODELK:
- {
- if (stub->args.inodelk.volume)
- GF_FREE ((char *)stub->args.inodelk.volume);
-
- loc_wipe (&stub->args.inodelk.loc);
- break;
- }
+ stub->fn.inodelk(stub->frame, stub->frame->this, stub->args.volume,
+ &stub->args.loc, stub->args.cmd, &stub->args.lock,
+ stub->args.xdata);
+ break;
case GF_FOP_FINODELK:
- {
- if (stub->args.finodelk.volume)
- GF_FREE ((char *)stub->args.finodelk.volume);
-
- if (stub->args.finodelk.fd)
- fd_unref (stub->args.finodelk.fd);
- break;
- }
+ stub->fn.finodelk(stub->frame, stub->frame->this, stub->args.volume,
+ stub->args.fd, stub->args.cmd, &stub->args.lock,
+ stub->args.xdata);
+ break;
case GF_FOP_ENTRYLK:
- {
- if (stub->args.entrylk.volume)
- GF_FREE ((char *)stub->args.entrylk.volume);
-
- if (stub->args.entrylk.name)
- GF_FREE ((char *)stub->args.entrylk.name);
- loc_wipe (&stub->args.entrylk.loc);
- break;
- }
+ stub->fn.entrylk(stub->frame, stub->frame->this, stub->args.volume,
+ &stub->args.loc, stub->args.name,
+ stub->args.entrylkcmd, stub->args.entrylktype,
+ stub->args.xdata);
+ break;
case GF_FOP_FENTRYLK:
- {
- if (stub->args.fentrylk.volume)
- GF_FREE ((char *)stub->args.fentrylk.volume);
-
- if (stub->args.fentrylk.name)
- GF_FREE ((char *)stub->args.fentrylk.name);
-
- if (stub->args.fentrylk.fd)
- fd_unref (stub->args.fentrylk.fd);
- break;
- }
-
+ stub->fn.fentrylk(stub->frame, stub->frame->this, stub->args.volume,
+ stub->args.fd, stub->args.name,
+ stub->args.entrylkcmd, stub->args.entrylktype,
+ stub->args.xdata);
+ break;
case GF_FOP_LOOKUP:
- {
- loc_wipe (&stub->args.lookup.loc);
- if (stub->args.lookup.xattr_req)
- dict_unref (stub->args.lookup.xattr_req);
- break;
- }
-
+ stub->fn.lookup(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.xdata);
+ break;
case GF_FOP_RCHECKSUM:
- {
- if (stub->args.rchecksum.fd)
- fd_unref (stub->args.rchecksum.fd);
- break;
- }
-
+ stub->fn.rchecksum(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.offset, stub->args.size,
+ stub->args.xdata);
+ break;
case GF_FOP_READDIR:
- {
- if (stub->args.readdir.fd)
- fd_unref (stub->args.readdir.fd);
- break;
- }
-
+ stub->fn.readdir(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.size, stub->args.offset,
+ stub->args.xdata);
+ break;
case GF_FOP_READDIRP:
- {
- if (stub->args.readdirp.fd)
- fd_unref (stub->args.readdirp.fd);
- break;
- }
-
+ stub->fn.readdirp(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.size, stub->args.offset,
+ stub->args.xdata);
+ break;
case GF_FOP_XATTROP:
- {
- loc_wipe (&stub->args.xattrop.loc);
- dict_unref (stub->args.xattrop.xattr);
- break;
- }
+ stub->fn.xattrop(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.optype, stub->args.xattr,
+ stub->args.xdata);
+ break;
case GF_FOP_FXATTROP:
- {
- if (stub->args.fxattrop.fd)
- fd_unref (stub->args.fxattrop.fd);
- dict_unref (stub->args.fxattrop.xattr);
- break;
- }
+ stub->fn.fxattrop(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.optype, stub->args.xattr,
+ stub->args.xdata);
+ break;
case GF_FOP_SETATTR:
- {
- loc_wipe (&stub->args.setattr.loc);
- break;
- }
+ stub->fn.setattr(stub->frame, stub->frame->this, &stub->args.loc,
+ &stub->args.stat, stub->args.valid,
+ stub->args.xdata);
+ break;
case GF_FOP_FSETATTR:
- {
- if (stub->args.fsetattr.fd)
- fd_unref (stub->args.fsetattr.fd);
- break;
- }
- default:
- {
- gf_log_callingfn ("call-stub", GF_LOG_ERROR,
- "Invalid value of FOP (%d)",
- stub->fop);
- break;
- }
- }
-}
+ stub->fn.fsetattr(stub->frame, stub->frame->this, stub->args.fd,
+ &stub->args.stat, stub->args.valid,
+ stub->args.xdata);
+ break;
+ case GF_FOP_FALLOCATE:
+ stub->fn.fallocate(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.flags, stub->args.offset,
+ stub->args.size, stub->args.xdata);
+ break;
+ case GF_FOP_DISCARD:
+ stub->fn.discard(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.offset, stub->args.size,
+ stub->args.xdata);
+ break;
+ case GF_FOP_ZEROFILL:
+ stub->fn.zerofill(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.offset, stub->args.size,
+ stub->args.xdata);
+ break;
+ case GF_FOP_IPC:
+ stub->fn.ipc(stub->frame, stub->frame->this, stub->args.cmd,
+ stub->args.xdata);
+ break;
+ case GF_FOP_SEEK:
+ stub->fn.seek(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.offset, stub->args.what, stub->args.xdata);
+ break;
+ case GF_FOP_LEASE:
+ stub->fn.lease(stub->frame, stub->frame->this, &stub->args.loc,
+ &stub->args.lease, stub->args.xdata);
+ break;
+
+ case GF_FOP_GETACTIVELK:
+ stub->fn.getactivelk(stub->frame, stub->frame->this,
+ &stub->args.loc, stub->args.xdata);
+ break;
+
+ case GF_FOP_SETACTIVELK:
+ stub->fn.setactivelk(stub->frame, stub->frame->this,
+ &stub->args.loc, &stub->args.locklist,
+ stub->args.xdata);
+ break;
+
+ case GF_FOP_PUT:
+ stub->fn.put(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.mode, stub->args.umask, stub->args.flags,
+ stub->args.vector, stub->args.count, stub->args.offset,
+ stub->args.iobref, stub->args.xattr, stub->args.xdata);
+ break;
+
+ case GF_FOP_COPY_FILE_RANGE:
+ stub->fn.copy_file_range(
+ stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.off_in, stub->args.fd_dst, stub->args.off_out,
+ stub->args.size, stub->args.flags, stub->args.xdata);
+ break;
+ default:
+ gf_msg_callingfn("call-stub", GF_LOG_ERROR, EINVAL,
+ LG_MSG_INVALID_ENTRY,
+ "Invalid value of FOP"
+ " (%d)",
+ stub->fop);
+ break;
+ }
+out:
+ return;
+}
+
+#define STUB_UNWIND(stb, fop, args...) \
+ do { \
+ if (stb->fn_cbk.fop) \
+ stb->fn_cbk.fop(stb->frame, stb->frame->cookie, stb->frame->this, \
+ stb->args_cbk.op_ret, stb->args_cbk.op_errno, \
+ args); \
+ else \
+ STACK_UNWIND_STRICT(fop, stb->frame, stb->args_cbk.op_ret, \
+ stb->args_cbk.op_errno, args); \
+ } while (0)
static void
-call_stub_destroy_unwind (call_stub_t *stub)
+call_resume_unwind(call_stub_t *stub)
{
- switch (stub->fop) {
- case GF_FOP_OPEN:
- {
- if (stub->args.open_cbk.fd)
- fd_unref (stub->args.open_cbk.fd);
- }
- break;
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
+ switch (stub->fop) {
+ case GF_FOP_OPEN:
+ STUB_UNWIND(stub, open, stub->args_cbk.fd, stub->args_cbk.xdata);
+ break;
case GF_FOP_CREATE:
- {
- if (stub->args.create_cbk.fd)
- fd_unref (stub->args.create_cbk.fd);
-
- if (stub->args.create_cbk.inode)
- inode_unref (stub->args.create_cbk.inode);
- }
- break;
-
+ STUB_UNWIND(stub, create, stub->args_cbk.fd, stub->args_cbk.inode,
+ &stub->args_cbk.stat, &stub->args_cbk.preparent,
+ &stub->args_cbk.postparent, stub->args_cbk.xdata);
+ break;
case GF_FOP_STAT:
- break;
-
+ STUB_UNWIND(stub, stat, &stub->args_cbk.stat, stub->args_cbk.xdata);
+ break;
case GF_FOP_READLINK:
- {
- if (stub->args.readlink_cbk.buf)
- GF_FREE ((char *)stub->args.readlink_cbk.buf);
- }
- break;
-
+ STUB_UNWIND(stub, readlink, stub->args_cbk.buf,
+ &stub->args_cbk.stat, stub->args.xdata);
+ break;
case GF_FOP_MKNOD:
- {
- if (stub->args.mknod_cbk.inode)
- inode_unref (stub->args.mknod_cbk.inode);
- }
- break;
-
+ STUB_UNWIND(stub, mknod, stub->args_cbk.inode, &stub->args_cbk.stat,
+ &stub->args_cbk.preparent, &stub->args_cbk.postparent,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_MKDIR:
- {
- if (stub->args.mkdir_cbk.inode)
- inode_unref (stub->args.mkdir_cbk.inode);
- }
- break;
-
+ STUB_UNWIND(stub, mkdir, stub->args_cbk.inode, &stub->args_cbk.stat,
+ &stub->args_cbk.preparent, &stub->args_cbk.postparent,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_UNLINK:
- break;
-
+ STUB_UNWIND(stub, unlink, &stub->args_cbk.preparent,
+ &stub->args_cbk.postparent, stub->args_cbk.xdata);
+ break;
case GF_FOP_RMDIR:
- break;
-
+ STUB_UNWIND(stub, rmdir, &stub->args_cbk.preparent,
+ &stub->args_cbk.postparent, stub->args_cbk.xdata);
+ break;
case GF_FOP_SYMLINK:
- {
- if (stub->args.symlink_cbk.inode)
- inode_unref (stub->args.symlink_cbk.inode);
- }
- break;
-
+ STUB_UNWIND(stub, symlink, stub->args_cbk.inode,
+ &stub->args_cbk.stat, &stub->args_cbk.preparent,
+ &stub->args_cbk.postparent, stub->args_cbk.xdata);
+ break;
case GF_FOP_RENAME:
- break;
-
+ STUB_UNWIND(stub, rename, &stub->args_cbk.stat,
+ &stub->args_cbk.preparent, &stub->args_cbk.postparent,
+ &stub->args_cbk.preparent2, &stub->args_cbk.postparent2,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_LINK:
- {
- if (stub->args.link_cbk.inode)
- inode_unref (stub->args.link_cbk.inode);
- }
- break;
-
+ STUB_UNWIND(stub, link, stub->args_cbk.inode, &stub->args_cbk.stat,
+ &stub->args_cbk.preparent, &stub->args_cbk.postparent,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_TRUNCATE:
- break;
-
+ STUB_UNWIND(stub, truncate, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
case GF_FOP_READ:
- {
- if (stub->args.readv_cbk.op_ret >= 0) {
- struct iobref *iobref = stub->args.readv_cbk.iobref;
- GF_FREE (stub->args.readv_cbk.vector);
-
- if (iobref) {
- iobref_unref (iobref);
- }
- }
- }
- break;
-
+ STUB_UNWIND(stub, readv, stub->args_cbk.vector,
+ stub->args_cbk.count, &stub->args_cbk.stat,
+ stub->args_cbk.iobref, stub->args_cbk.xdata);
+ break;
case GF_FOP_WRITE:
- break;
-
+ STUB_UNWIND(stub, writev, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
case GF_FOP_STATFS:
- break;
-
+ STUB_UNWIND(stub, statfs, &stub->args_cbk.statvfs,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_FLUSH:
- break;
-
+ STUB_UNWIND(stub, flush, stub->args_cbk.xdata);
+ break;
case GF_FOP_FSYNC:
- break;
-
+ STUB_UNWIND(stub, fsync, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
case GF_FOP_SETXATTR:
- break;
-
+ STUB_UNWIND(stub, setxattr, stub->args_cbk.xdata);
+ break;
case GF_FOP_GETXATTR:
- {
- if (stub->args.getxattr_cbk.dict)
- dict_unref (stub->args.getxattr_cbk.dict);
- }
- break;
-
+ STUB_UNWIND(stub, getxattr, stub->args_cbk.xattr,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_FSETXATTR:
- break;
-
+ STUB_UNWIND(stub, fsetxattr, stub->args_cbk.xdata);
+ break;
case GF_FOP_FGETXATTR:
- {
- if (stub->args.fgetxattr_cbk.dict)
- dict_unref (stub->args.fgetxattr_cbk.dict);
- }
- break;
-
+ STUB_UNWIND(stub, fgetxattr, stub->args_cbk.xattr,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_REMOVEXATTR:
- break;
-
+ STUB_UNWIND(stub, removexattr, stub->args_cbk.xdata);
+ break;
+ case GF_FOP_FREMOVEXATTR:
+ STUB_UNWIND(stub, fremovexattr, stub->args_cbk.xdata);
+ break;
case GF_FOP_OPENDIR:
- {
- if (stub->args.opendir_cbk.fd)
- fd_unref (stub->args.opendir_cbk.fd);
- }
- break;
-
+ STUB_UNWIND(stub, opendir, stub->args_cbk.fd, stub->args_cbk.xdata);
+ break;
case GF_FOP_FSYNCDIR:
- break;
-
+ STUB_UNWIND(stub, fsyncdir, stub->args_cbk.xdata);
+ break;
case GF_FOP_ACCESS:
- break;
-
+ STUB_UNWIND(stub, access, stub->args_cbk.xdata);
+ break;
case GF_FOP_FTRUNCATE:
- break;
-
+ STUB_UNWIND(stub, ftruncate, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
case GF_FOP_FSTAT:
- break;
-
+ STUB_UNWIND(stub, fstat, &stub->args_cbk.stat,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_LK:
- break;
-
+ STUB_UNWIND(stub, lk, &stub->args_cbk.lock, stub->args_cbk.xdata);
+ break;
case GF_FOP_INODELK:
- break;
-
+ STUB_UNWIND(stub, inodelk, stub->args_cbk.xdata);
+ break;
case GF_FOP_FINODELK:
- break;
-
+ STUB_UNWIND(stub, finodelk, stub->args_cbk.xdata);
+ break;
case GF_FOP_ENTRYLK:
- break;
-
+ STUB_UNWIND(stub, entrylk, stub->args_cbk.xdata);
+ break;
case GF_FOP_FENTRYLK:
- break;
-
+ STUB_UNWIND(stub, fentrylk, stub->args_cbk.xdata);
+ break;
case GF_FOP_LOOKUP:
- {
- if (stub->args.lookup_cbk.inode)
- inode_unref (stub->args.lookup_cbk.inode);
-
- if (stub->args.lookup_cbk.dict)
- dict_unref (stub->args.lookup_cbk.dict);
- }
- break;
-
+ STUB_UNWIND(stub, lookup, stub->args_cbk.inode,
+ &stub->args_cbk.stat, stub->args_cbk.xdata,
+ &stub->args_cbk.postparent);
+ break;
case GF_FOP_RCHECKSUM:
- {
- if (stub->args.rchecksum_cbk.op_ret >= 0) {
- GF_FREE (stub->args.rchecksum_cbk.strong_checksum);
- }
- }
- break;
-
+ STUB_UNWIND(stub, rchecksum, stub->args_cbk.weak_checksum,
+ stub->args_cbk.strong_checksum, stub->args_cbk.xdata);
+ break;
case GF_FOP_READDIR:
- {
- if (stub->args.readdir_cbk.op_ret > 0) {
- gf_dirent_free (&stub->args.readdir_cbk.entries);
- }
- }
- break;
-
+ STUB_UNWIND(stub, readdir, &stub->args_cbk.entries,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_READDIRP:
- {
- if (stub->args.readdirp_cbk.op_ret > 0) {
- gf_dirent_free (&stub->args.readdirp_cbk.entries);
- }
- }
- break;
-
+ STUB_UNWIND(stub, readdir, &stub->args_cbk.entries,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_XATTROP:
- {
- if (stub->args.xattrop_cbk.xattr)
- dict_unref (stub->args.xattrop_cbk.xattr);
- }
- break;
-
+ STUB_UNWIND(stub, xattrop, stub->args_cbk.xattr,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_FXATTROP:
- {
- if (stub->args.fxattrop_cbk.xattr)
- dict_unref (stub->args.fxattrop_cbk.xattr);
- }
- break;
-
+ STUB_UNWIND(stub, fxattrop, stub->args_cbk.xattr,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_SETATTR:
- {
- break;
- }
-
+ STUB_UNWIND(stub, setattr, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
case GF_FOP_FSETATTR:
- {
- break;
- }
+ STUB_UNWIND(stub, fsetattr, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
+ case GF_FOP_FALLOCATE:
+ STUB_UNWIND(stub, fallocate, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
+ case GF_FOP_DISCARD:
+ STUB_UNWIND(stub, discard, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
+ case GF_FOP_ZEROFILL:
+ STUB_UNWIND(stub, zerofill, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
+ case GF_FOP_IPC:
+ STUB_UNWIND(stub, ipc, stub->args_cbk.xdata);
+ break;
+ case GF_FOP_SEEK:
+ STUB_UNWIND(stub, seek, stub->args_cbk.offset,
+ stub->args_cbk.xdata);
+ break;
+ case GF_FOP_LEASE:
+ STUB_UNWIND(stub, lease, &stub->args_cbk.lease,
+ stub->args_cbk.xdata);
+ break;
+
+ case GF_FOP_GETACTIVELK:
+ STUB_UNWIND(stub, getactivelk, &stub->args_cbk.locklist,
+ stub->args_cbk.xdata);
+ break;
+
+ case GF_FOP_SETACTIVELK:
+ STUB_UNWIND(stub, setactivelk, stub->args_cbk.xdata);
+ break;
+
+ case GF_FOP_PUT:
+ STUB_UNWIND(stub, put, stub->args_cbk.inode, &stub->args_cbk.stat,
+ &stub->args_cbk.preparent, &stub->args_cbk.postparent,
+ stub->args_cbk.xdata);
+ break;
+
+ case GF_FOP_COPY_FILE_RANGE:
+ STUB_UNWIND(stub, copy_file_range, &stub->args_cbk.stat,
+ &stub->args_cbk.prestat, &stub->args_cbk.poststat,
+ stub->args_cbk.xdata);
+ break;
default:
- {
- gf_log_callingfn ("call-stub", GF_LOG_ERROR,
- "Invalid value of FOP (%d)",
- stub->fop);
- break;
- }
- }
+ gf_msg_callingfn("call-stub", GF_LOG_ERROR, EINVAL,
+ LG_MSG_INVALID_ENTRY,
+ "Invalid value of FOP"
+ " (%d)",
+ stub->fop);
+ break;
+ }
+out:
+ return;
}
+static void
+call_stub_wipe_args(call_stub_t *stub)
+{
+ args_wipe(&stub->args);
+}
+
+static void
+call_stub_wipe_args_cbk(call_stub_t *stub)
+{
+ args_cbk_wipe(&stub->args_cbk);
+}
+
+void
+call_stub_destroy(call_stub_t *stub)
+{
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
+
+ if (stub->wind)
+ call_stub_wipe_args(stub);
+ else
+ call_stub_wipe_args_cbk(stub);
+
+ stub->stub_mem_pool = NULL;
+
+ mem_put(stub);
+out:
+ return;
+}
void
-call_stub_destroy (call_stub_t *stub)
+call_resume(call_stub_t *stub)
{
- struct mem_pool *tmp_pool = NULL;
+ xlator_t *old_THIS = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ errno = EINVAL;
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- tmp_pool = stub->stub_mem_pool;
+ list_del_init(&stub->list);
- if (stub->wind) {
- call_stub_destroy_wind (stub);
- } else {
- call_stub_destroy_unwind (stub);
- }
+ old_THIS = THIS;
+ THIS = stub->frame->this;
+ {
+ if (stub->wind)
+ call_resume_wind(stub);
+ else
+ call_resume_unwind(stub);
+ }
+ THIS = old_THIS;
- stub->stub_mem_pool = NULL;
- mem_put (tmp_pool, stub);
+ call_stub_destroy(stub);
out:
- tmp_pool = NULL;
+ return;
+}
+
+void
+call_unwind_error(call_stub_t *stub, int op_ret, int op_errno)
+{
+ xlator_t *old_THIS = NULL;
+
+ list_del_init(&stub->list);
+
+ old_THIS = THIS;
+ THIS = stub->frame->this;
+ {
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ call_resume_unwind(stub);
+ }
+ THIS = old_THIS;
+
+ call_stub_destroy(stub);
+
+ return;
+}
- return;
+void
+call_unwind_error_keep_stub(call_stub_t *stub, int op_ret, int op_errno)
+{
+ xlator_t *old_THIS = NULL;
+
+ list_del_init(&stub->list);
+
+ old_THIS = THIS;
+ THIS = stub->frame->this;
+ {
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ call_resume_unwind(stub);
+ }
+
+ THIS = old_THIS;
+
+ return;
}
void
-call_resume (call_stub_t *stub)
+call_resume_keep_stub(call_stub_t *stub)
{
- xlator_t *old_THIS = NULL;
+ xlator_t *old_THIS = NULL;
+
+ errno = EINVAL;
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- errno = EINVAL;
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ list_del_init(&stub->list);
- list_del_init (&stub->list);
+ old_THIS = THIS;
+ THIS = stub->frame->this;
+ {
+ if (stub->wind)
+ call_resume_wind(stub);
+ else
+ call_resume_unwind(stub);
+ }
- old_THIS = THIS;
- THIS = stub->frame->this;
- {
- if (stub->wind)
- call_resume_wind (stub);
- else
- call_resume_unwind (stub);
- }
- THIS = old_THIS;
+ THIS = old_THIS;
- call_stub_destroy (stub);
out:
- return;
+ return;
}
diff --git a/libglusterfs/src/call-stub.h b/libglusterfs/src/call-stub.h
deleted file mode 100644
index 01b6cdd1b38..00000000000
--- a/libglusterfs/src/call-stub.h
+++ /dev/null
@@ -1,1116 +0,0 @@
-/*
- Copyright (c) 2007-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _CALL_STUB_H_
-#define _CALL_STUB_H_
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "xlator.h"
-#include "stack.h"
-#include "list.h"
-
-typedef struct {
- struct list_head list;
- char wind;
- call_frame_t *frame;
- glusterfs_fop_t fop;
- struct mem_pool *stub_mem_pool; /* pointer to stub mempool in glusterfs ctx */
-
- union {
- /* lookup */
- struct {
- fop_lookup_t fn;
- loc_t loc;
- dict_t *xattr_req;
- } lookup;
- struct {
- fop_lookup_cbk_t fn;
- int32_t op_ret, op_errno;
- inode_t *inode;
- struct iatt buf;
- dict_t *dict;
- struct iatt postparent;
- } lookup_cbk;
-
- /* stat */
- struct {
- fop_stat_t fn;
- loc_t loc;
- } stat;
- struct {
- fop_stat_cbk_t fn;
- int32_t op_ret, op_errno;
- struct iatt buf;
- } stat_cbk;
-
- /* fstat */
- struct {
- fop_fstat_t fn;
- fd_t *fd;
- } fstat;
- struct {
- fop_fstat_cbk_t fn;
- int32_t op_ret, op_errno;
- struct iatt buf;
- } fstat_cbk;
-
- /* truncate */
- struct {
- fop_truncate_t fn;
- loc_t loc;
- off_t off;
- } truncate;
- struct {
- fop_truncate_cbk_t fn;
- int32_t op_ret, op_errno;
- struct iatt prebuf;
- struct iatt postbuf;
- } truncate_cbk;
-
- /* ftruncate */
- struct {
- fop_ftruncate_t fn;
- fd_t *fd;
- off_t off;
- } ftruncate;
- struct {
- fop_ftruncate_cbk_t fn;
- int32_t op_ret, op_errno;
- struct iatt prebuf;
- struct iatt postbuf;
- } ftruncate_cbk;
-
- /* access */
- struct {
- fop_access_t fn;
- loc_t loc;
- int32_t mask;
- } access;
- struct {
- fop_access_cbk_t fn;
- int32_t op_ret, op_errno;
- } access_cbk;
-
- /* readlink */
- struct {
- fop_readlink_t fn;
- loc_t loc;
- size_t size;
- } readlink;
- struct {
- fop_readlink_cbk_t fn;
- int32_t op_ret, op_errno;
- const char *buf;
- struct iatt sbuf;
- } readlink_cbk;
-
- /* mknod */
- struct {
- fop_mknod_t fn;
- loc_t loc;
- mode_t mode;
- dev_t rdev;
- dict_t *params;
- } mknod;
- struct {
- fop_mknod_cbk_t fn;
- int32_t op_ret, op_errno;
- inode_t *inode;
- struct iatt buf;
- struct iatt preparent;
- struct iatt postparent;
- } mknod_cbk;
-
- /* mkdir */
- struct {
- fop_mkdir_t fn;
- loc_t loc;
- mode_t mode;
- dict_t *params;
- } mkdir;
- struct {
- fop_mkdir_cbk_t fn;
- int32_t op_ret, op_errno;
- inode_t *inode;
- struct iatt buf;
- struct iatt preparent;
- struct iatt postparent;
- } mkdir_cbk;
-
- /* unlink */
- struct {
- fop_unlink_t fn;
- loc_t loc;
- } unlink;
- struct {
- fop_unlink_cbk_t fn;
- int32_t op_ret, op_errno;
- struct iatt preparent;
- struct iatt postparent;
- } unlink_cbk;
-
- /* rmdir */
- struct {
- fop_rmdir_t fn;
- loc_t loc;
- int flags;
- } rmdir;
- struct {
- fop_rmdir_cbk_t fn;
- int32_t op_ret, op_errno;
- struct iatt preparent;
- struct iatt postparent;
- } rmdir_cbk;
-
- /* symlink */
- struct {
- fop_symlink_t fn;
- const char *linkname;
- loc_t loc;
- dict_t *params;
- } symlink;
- struct {
- fop_symlink_cbk_t fn;
- int32_t op_ret, op_errno;
- inode_t *inode;
- struct iatt buf;
- struct iatt preparent;
- struct iatt postparent;
- } symlink_cbk;
-
- /* rename */
- struct {
- fop_rename_t fn;
- loc_t old;
- loc_t new;
- } rename;
- struct {
- fop_rename_cbk_t fn;
- int32_t op_ret, op_errno;
- struct iatt buf;
- struct iatt preoldparent;
- struct iatt postoldparent;
- struct iatt prenewparent;
- struct iatt postnewparent;
- } rename_cbk;
-
- /* link */
- struct {
- fop_link_t fn;
- loc_t oldloc;
- loc_t newloc;
- } link;
- struct {
- fop_link_cbk_t fn;
- int32_t op_ret, op_errno;
- inode_t *inode;
- struct iatt buf;
- struct iatt preparent;
- struct iatt postparent;
- } link_cbk;
-
- /* create */
- struct {
- fop_create_t fn;
- loc_t loc;
- int32_t flags;
- mode_t mode;
- fd_t *fd;
- dict_t *params;
- } create;
- struct {
- fop_create_cbk_t fn;
- int32_t op_ret, op_errno;
- fd_t *fd;
- inode_t *inode;
- struct iatt buf;
- struct iatt preparent;
- struct iatt postparent;
- } create_cbk;
-
- /* open */
- struct {
- fop_open_t fn;
- loc_t loc;
- int32_t flags;
- fd_t *fd;
- int32_t wbflags;
- } open;
- struct {
- fop_open_cbk_t fn;
- int32_t op_ret, op_errno;
- fd_t *fd;
- } open_cbk;
-
- /* readv */
- struct {
- fop_readv_t fn;
- fd_t *fd;
- size_t size;
- off_t off;
- } readv;
- struct {
- fop_readv_cbk_t fn;
- int32_t op_ret;
- int32_t op_errno;
- struct iovec *vector;
- int32_t count;
- struct iatt stbuf;
- struct iobref *iobref;
- } readv_cbk;
-
- /* writev */
- struct {
- fop_writev_t fn;
- fd_t *fd;
- struct iovec *vector;
- int32_t count;
- off_t off;
- struct iobref *iobref;
- } writev;
- struct {
- fop_writev_cbk_t fn;
- int32_t op_ret, op_errno;
- struct iatt prebuf;
- struct iatt postbuf;
- } writev_cbk;
-
- /* flush */
- struct {
- fop_flush_t fn;
- fd_t *fd;
- } flush;
- struct {
- fop_flush_cbk_t fn;
- int32_t op_ret, op_errno;
- } flush_cbk;
-
- /* fsync */
- struct {
- fop_fsync_t fn;
- fd_t *fd;
- int32_t datasync;
- } fsync;
- struct {
- fop_fsync_cbk_t fn;
- int32_t op_ret, op_errno;
- struct iatt prebuf;
- struct iatt postbuf;
- } fsync_cbk;
-
- /* opendir */
- struct {
- fop_opendir_t fn;
- loc_t loc;
- fd_t *fd;
- } opendir;
- struct {
- fop_opendir_cbk_t fn;
- int32_t op_ret, op_errno;
- fd_t *fd;
- } opendir_cbk;
-
-
- /* fsyncdir */
- struct {
- fop_fsyncdir_t fn;
- fd_t *fd;
- int32_t datasync;
- } fsyncdir;
- struct {
- fop_fsyncdir_cbk_t fn;
- int32_t op_ret, op_errno;
- } fsyncdir_cbk;
-
- /* statfs */
- struct {
- fop_statfs_t fn;
- loc_t loc;
- } statfs;
- struct {
- fop_statfs_cbk_t fn;
- int32_t op_ret, op_errno;
- struct statvfs buf;
- } statfs_cbk;
-
- /* setxattr */
- struct {
- fop_setxattr_t fn;
- loc_t loc;
- dict_t *dict;
- int32_t flags;
- } setxattr;
- struct {
- fop_setxattr_cbk_t fn;
- int32_t op_ret, op_errno;
- } setxattr_cbk;
-
- /* getxattr */
- struct {
- fop_getxattr_t fn;
- loc_t loc;
- const char *name;
- } getxattr;
- struct {
- fop_getxattr_cbk_t fn;
- int32_t op_ret, op_errno;
- dict_t *dict;
- } getxattr_cbk;
-
- /* fsetxattr */
- struct {
- fop_fsetxattr_t fn;
- fd_t *fd;
- dict_t *dict;
- int32_t flags;
- } fsetxattr;
- struct {
- fop_fsetxattr_cbk_t fn;
- int32_t op_ret, op_errno;
- } fsetxattr_cbk;
-
- /* fgetxattr */
- struct {
- fop_fgetxattr_t fn;
- fd_t *fd;
- const char *name;
- } fgetxattr;
- struct {
- fop_fgetxattr_cbk_t fn;
- int32_t op_ret, op_errno;
- dict_t *dict;
- } fgetxattr_cbk;
-
- /* removexattr */
- struct {
- fop_removexattr_t fn;
- loc_t loc;
- const char *name;
- } removexattr;
- struct {
- fop_removexattr_cbk_t fn;
- int32_t op_ret, op_errno;
- } removexattr_cbk;
-
- /* lk */
- struct {
- fop_lk_t fn;
- fd_t *fd;
- int32_t cmd;
- struct gf_flock lock;
- } lk;
- struct {
- fop_lk_cbk_t fn;
- int32_t op_ret, op_errno;
- struct gf_flock lock;
- } lk_cbk;
-
- /* inodelk */
- struct {
- fop_inodelk_t fn;
- const char *volume;
- loc_t loc;
- int32_t cmd;
- struct gf_flock lock;
- } inodelk;
-
- struct {
- fop_inodelk_cbk_t fn;
- int32_t op_ret, op_errno;
- } inodelk_cbk;
-
- /* finodelk */
- struct {
- fop_finodelk_t fn;
- const char *volume;
- fd_t *fd;
- int32_t cmd;
- struct gf_flock lock;
- } finodelk;
-
- struct {
- fop_finodelk_cbk_t fn;
- int32_t op_ret, op_errno;
- } finodelk_cbk;
-
- /* entrylk */
- struct {
- fop_entrylk_t fn;
- loc_t loc;
- const char *volume;
- const char *name;
- entrylk_cmd cmd;
- entrylk_type type;
- } entrylk;
-
- struct {
- fop_entrylk_cbk_t fn;
- int32_t op_ret, op_errno;
- } entrylk_cbk;
-
- /* fentrylk */
- struct {
- fop_fentrylk_t fn;
- fd_t *fd;
- const char *volume;
- const char *name;
- entrylk_cmd cmd;
- entrylk_type type;
- } fentrylk;
-
- struct {
- fop_fentrylk_cbk_t fn;
- int32_t op_ret, op_errno;
- } fentrylk_cbk;
-
- /* readdir */
- struct {
- fop_readdir_t fn;
- fd_t *fd;
- size_t size;
- off_t off;
- } readdir;
- struct {
- fop_readdir_cbk_t fn;
- int32_t op_ret, op_errno;
- gf_dirent_t entries;
- } readdir_cbk;
-
- /* readdirp */
- struct {
- fop_readdirp_t fn;
- fd_t *fd;
- size_t size;
- off_t off;
- } readdirp;
- struct {
- fop_readdirp_cbk_t fn;
- int32_t op_ret, op_errno;
- gf_dirent_t entries;
- } readdirp_cbk;
-
- /* rchecksum */
- struct {
- fop_rchecksum_t fn;
- fd_t *fd;
- off_t offset;
- int32_t len;
- } rchecksum;
- struct {
- fop_rchecksum_cbk_t fn;
- int32_t op_ret, op_errno;
- uint32_t weak_checksum;
- uint8_t *strong_checksum;
- } rchecksum_cbk;
-
- /* xattrop */
- struct {
- fop_xattrop_t fn;
- loc_t loc;
- gf_xattrop_flags_t optype;
- dict_t *xattr;
- } xattrop;
- struct {
- fop_xattrop_cbk_t fn;
- int32_t op_ret;
- int32_t op_errno;
- dict_t *xattr;
- } xattrop_cbk;
-
- /* fxattrop */
- struct {
- fop_fxattrop_t fn;
- fd_t *fd;
- gf_xattrop_flags_t optype;
- dict_t *xattr;
- } fxattrop;
- struct {
- fop_fxattrop_cbk_t fn;
- int32_t op_ret;
- int32_t op_errno;
- dict_t *xattr;
- } fxattrop_cbk;
-
- /* setattr */
- struct {
- fop_setattr_t fn;
- loc_t loc;
- struct iatt stbuf;
- int32_t valid;
- } setattr;
- struct {
- fop_setattr_cbk_t fn;
- int32_t op_ret;
- int32_t op_errno;
- struct iatt statpre;
- struct iatt statpost;
- } setattr_cbk;
-
- /* fsetattr */
- struct {
- fop_fsetattr_t fn;
- fd_t *fd;
- struct iatt stbuf;
- int32_t valid;
- } fsetattr;
- struct {
- fop_fsetattr_cbk_t fn;
- int32_t op_ret;
- int32_t op_errno;
- struct iatt statpre;
- struct iatt statpost;
- } fsetattr_cbk;
-
- } args;
-} call_stub_t;
-
-call_stub_t *
-fop_lookup_stub (call_frame_t *frame,
- fop_lookup_t fn,
- loc_t *loc,
- dict_t *xattr_req);
-
-call_stub_t *
-fop_lookup_cbk_stub (call_frame_t *frame,
- fop_lookup_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- inode_t *inode,
- struct iatt *buf,
- dict_t *dict,
- struct iatt *postparent);
-call_stub_t *
-fop_stat_stub (call_frame_t *frame,
- fop_stat_t fn,
- loc_t *loc);
-call_stub_t *
-fop_stat_cbk_stub (call_frame_t *frame,
- fop_stat_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *buf);
-call_stub_t *
-fop_fstat_stub (call_frame_t *frame,
- fop_fstat_t fn,
- fd_t *fd);
-call_stub_t *
-fop_fstat_cbk_stub (call_frame_t *frame,
- fop_fstat_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *buf);
-
-call_stub_t *
-fop_truncate_stub (call_frame_t *frame,
- fop_truncate_t fn,
- loc_t *loc,
- off_t off);
-
-call_stub_t *
-fop_truncate_cbk_stub (call_frame_t *frame,
- fop_truncate_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *prebuf,
- struct iatt *postbuf);
-
-call_stub_t *
-fop_ftruncate_stub (call_frame_t *frame,
- fop_ftruncate_t fn,
- fd_t *fd,
- off_t off);
-
-call_stub_t *
-fop_ftruncate_cbk_stub (call_frame_t *frame,
- fop_ftruncate_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *prebuf,
- struct iatt *postbuf);
-
-call_stub_t *
-fop_access_stub (call_frame_t *frame,
- fop_access_t fn,
- loc_t *loc,
- int32_t mask);
-
-call_stub_t *
-fop_access_cbk_stub (call_frame_t *frame,
- fop_access_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno);
-
-call_stub_t *
-fop_readlink_stub (call_frame_t *frame,
- fop_readlink_t fn,
- loc_t *loc,
- size_t size);
-
-call_stub_t *
-fop_readlink_cbk_stub (call_frame_t *frame,
- fop_readlink_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- const char *path,
- struct iatt *buf);
-
-call_stub_t *
-fop_mknod_stub (call_frame_t *frame, fop_mknod_t fn,
- loc_t *loc, mode_t mode, dev_t rdev, dict_t *params);
-
-call_stub_t *
-fop_mknod_cbk_stub (call_frame_t *frame,
- fop_mknod_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent);
-
-call_stub_t *
-fop_mkdir_stub (call_frame_t *frame, fop_mkdir_t fn,
- loc_t *loc, mode_t mode, dict_t *params);
-
-call_stub_t *
-fop_mkdir_cbk_stub (call_frame_t *frame,
- fop_mkdir_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent);
-
-call_stub_t *
-fop_unlink_stub (call_frame_t *frame,
- fop_unlink_t fn,
- loc_t *loc);
-
-call_stub_t *
-fop_unlink_cbk_stub (call_frame_t *frame,
- fop_unlink_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *preparent,
- struct iatt *postparent);
-
-call_stub_t *
-fop_rmdir_stub (call_frame_t *frame, fop_rmdir_t fn,
- loc_t *loc, int flags);
-
-call_stub_t *
-fop_rmdir_cbk_stub (call_frame_t *frame,
- fop_rmdir_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *preparent,
- struct iatt *postparent);
-
-call_stub_t *
-fop_symlink_stub (call_frame_t *frame, fop_symlink_t fn,
- const char *linkname, loc_t *loc, dict_t *params);
-
-call_stub_t *
-fop_symlink_cbk_stub (call_frame_t *frame,
- fop_symlink_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent);
-
-call_stub_t *
-fop_rename_stub (call_frame_t *frame,
- fop_rename_t fn,
- loc_t *oldloc,
- loc_t *newloc);
-
-call_stub_t *
-fop_rename_cbk_stub (call_frame_t *frame,
- fop_rename_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *buf,
- struct iatt *preoldparent,
- struct iatt *postoldparent,
- struct iatt *prenewparent,
- struct iatt *postnewparent);
-
-call_stub_t *
-fop_link_stub (call_frame_t *frame,
- fop_link_t fn,
- loc_t *oldloc,
- loc_t *newloc);
-
-call_stub_t *
-fop_link_cbk_stub (call_frame_t *frame,
- fop_link_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent);
-
-call_stub_t *
-fop_create_stub (call_frame_t *frame, fop_create_t fn,
- loc_t *loc, int32_t flags, mode_t mode,
- fd_t *fd, dict_t *params);
-
-call_stub_t *
-fop_create_cbk_stub (call_frame_t *frame,
- fop_create_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- fd_t *fd,
- inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent);
-
-call_stub_t *
-fop_open_stub (call_frame_t *frame,
- fop_open_t fn,
- loc_t *loc,
- int32_t flags,
- fd_t *fd,
- int32_t wbflags);
-
-call_stub_t *
-fop_open_cbk_stub (call_frame_t *frame,
- fop_open_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- fd_t *fd);
-
-call_stub_t *
-fop_readv_stub (call_frame_t *frame,
- fop_readv_t fn,
- fd_t *fd,
- size_t size,
- off_t off);
-
-call_stub_t *
-fop_readv_cbk_stub (call_frame_t *frame,
- fop_readv_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iovec *vector,
- int32_t count,
- struct iatt *stbuf,
- struct iobref *iobref);
-
-call_stub_t *
-fop_writev_stub (call_frame_t *frame,
- fop_writev_t fn,
- fd_t *fd,
- struct iovec *vector,
- int32_t count,
- off_t off,
- struct iobref *iobref);
-
-call_stub_t *
-fop_writev_cbk_stub (call_frame_t *frame,
- fop_writev_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *prebuf,
- struct iatt *postbuf);
-
-call_stub_t *
-fop_flush_stub (call_frame_t *frame,
- fop_flush_t fn,
- fd_t *fd);
-
-call_stub_t *
-fop_flush_cbk_stub (call_frame_t *frame,
- fop_flush_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno);
-
-call_stub_t *
-fop_fsync_stub (call_frame_t *frame,
- fop_fsync_t fn,
- fd_t *fd,
- int32_t datasync);
-
-call_stub_t *
-fop_fsync_cbk_stub (call_frame_t *frame,
- fop_fsync_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *prebuf,
- struct iatt *postbuf);
-
-call_stub_t *
-fop_opendir_stub (call_frame_t *frame,
- fop_opendir_t fn,
- loc_t *loc, fd_t *fd);
-
-call_stub_t *
-fop_opendir_cbk_stub (call_frame_t *frame,
- fop_opendir_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- fd_t *fd);
-
-call_stub_t *
-fop_fsyncdir_stub (call_frame_t *frame,
- fop_fsyncdir_t fn,
- fd_t *fd,
- int32_t datasync);
-
-call_stub_t *
-fop_fsyncdir_cbk_stub (call_frame_t *frame,
- fop_fsyncdir_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno);
-
-call_stub_t *
-fop_statfs_stub (call_frame_t *frame,
- fop_statfs_t fn,
- loc_t *loc);
-
-call_stub_t *
-fop_statfs_cbk_stub (call_frame_t *frame,
- fop_statfs_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct statvfs *buf);
-
-call_stub_t *
-fop_setxattr_stub (call_frame_t *frame,
- fop_setxattr_t fn,
- loc_t *loc,
- dict_t *dict,
- int32_t flags);
-
-call_stub_t *
-fop_setxattr_cbk_stub (call_frame_t *frame,
- fop_setxattr_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno);
-
-call_stub_t *
-fop_getxattr_stub (call_frame_t *frame,
- fop_getxattr_t fn,
- loc_t *loc,
- const char *name);
-
-call_stub_t *
-fop_getxattr_cbk_stub (call_frame_t *frame,
- fop_getxattr_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- dict_t *value);
-
-call_stub_t *
-fop_fsetxattr_stub (call_frame_t *frame,
- fop_fsetxattr_t fn,
- fd_t *fd,
- dict_t *dict,
- int32_t flags);
-
-call_stub_t *
-fop_fsetxattr_cbk_stub (call_frame_t *frame,
- fop_fsetxattr_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno);
-
-call_stub_t *
-fop_fgetxattr_stub (call_frame_t *frame,
- fop_fgetxattr_t fn,
- fd_t *fd,
- const char *name);
-
-call_stub_t *
-fop_fgetxattr_cbk_stub (call_frame_t *frame,
- fop_fgetxattr_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- dict_t *value);
-
-call_stub_t *
-fop_removexattr_stub (call_frame_t *frame,
- fop_removexattr_t fn,
- loc_t *loc,
- const char *name);
-
-call_stub_t *
-fop_removexattr_cbk_stub (call_frame_t *frame,
- fop_removexattr_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno);
-call_stub_t *
-fop_lk_stub (call_frame_t *frame,
- fop_lk_t fn,
- fd_t *fd,
- int32_t cmd,
- struct gf_flock *lock);
-
-call_stub_t *
-fop_lk_cbk_stub (call_frame_t *frame,
- fop_lk_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct gf_flock *lock);
-
-call_stub_t *
-fop_inodelk_stub (call_frame_t *frame, fop_inodelk_t fn,
- const char *volume, loc_t *loc, int32_t cmd,
- struct gf_flock *lock);
-
-call_stub_t *
-fop_finodelk_stub (call_frame_t *frame, fop_finodelk_t fn,
- const char *volume, fd_t *fd, int32_t cmd,
- struct gf_flock *lock);
-
-call_stub_t *
-fop_entrylk_stub (call_frame_t *frame, fop_entrylk_t fn,
- const char *volume, loc_t *loc, const char *basename,
- entrylk_cmd cmd, entrylk_type type);
-
-call_stub_t *
-fop_fentrylk_stub (call_frame_t *frame, fop_fentrylk_t fn,
- const char *volume, fd_t *fd, const char *basename,
- entrylk_cmd cmd, entrylk_type type);
-
-call_stub_t *
-fop_inodelk_cbk_stub (call_frame_t *frame, fop_inodelk_cbk_t fn,
- int32_t op_ret, int32_t op_errno);
-
-call_stub_t *
-fop_finodelk_cbk_stub (call_frame_t *frame, fop_inodelk_cbk_t fn,
- int32_t op_ret, int32_t op_errno);
-
-call_stub_t *
-fop_entrylk_cbk_stub (call_frame_t *frame, fop_entrylk_cbk_t fn,
- int32_t op_ret, int32_t op_errno);
-
-call_stub_t *
-fop_fentrylk_cbk_stub (call_frame_t *frame, fop_entrylk_cbk_t fn,
- int32_t op_ret, int32_t op_errno);
-
-call_stub_t *
-fop_readdir_stub (call_frame_t *frame,
- fop_readdir_t fn,
- fd_t *fd,
- size_t size,
- off_t off);
-
-call_stub_t *
-fop_readdirp_stub (call_frame_t *frame,
- fop_readdir_t fn,
- fd_t *fd,
- size_t size,
- off_t off);
-
-call_stub_t *
-fop_readdirp_cbk_stub (call_frame_t *frame,
- fop_readdir_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- gf_dirent_t *entries);
-
-call_stub_t *
-fop_readdir_cbk_stub (call_frame_t *frame,
- fop_readdir_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- gf_dirent_t *entries);
-
-call_stub_t *
-fop_rchecksum_stub (call_frame_t *frame,
- fop_rchecksum_t fn,
- fd_t *fd, off_t offset,
- int32_t len);
-
-call_stub_t *
-fop_rchecksum_cbk_stub (call_frame_t *frame,
- fop_rchecksum_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- uint32_t weak_checksum,
- uint8_t *strong_checksum);
-
-call_stub_t *
-fop_xattrop_stub (call_frame_t *frame,
- fop_xattrop_t fn,
- loc_t *loc,
- gf_xattrop_flags_t optype,
- dict_t *xattr);
-
-call_stub_t *
-fop_xattrop_stub_cbk_stub (call_frame_t *frame,
- fop_xattrop_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno);
-
-call_stub_t *
-fop_fxattrop_stub (call_frame_t *frame,
- fop_fxattrop_t fn,
- fd_t *fd,
- gf_xattrop_flags_t optype,
- dict_t *xattr);
-
-call_stub_t *
-fop_fxattrop_stub_cbk_stub (call_frame_t *frame,
- fop_xattrop_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno);
-
-call_stub_t *
-fop_setattr_stub (call_frame_t *frame,
- fop_setattr_t fn,
- loc_t *loc,
- struct iatt *stbuf,
- int32_t valid);
-
-call_stub_t *
-fop_setattr_cbk_stub (call_frame_t *frame,
- fop_setattr_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *statpre,
- struct iatt *statpost);
-
-call_stub_t *
-fop_fsetattr_stub (call_frame_t *frame,
- fop_fsetattr_t fn,
- fd_t *fd,
- struct iatt *stbuf,
- int32_t valid);
-
-call_stub_t *
-fop_fsetattr_cbk_stub (call_frame_t *frame,
- fop_setattr_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *statpre,
- struct iatt *statpost);
-
-void call_resume (call_stub_t *stub);
-void call_stub_destroy (call_stub_t *stub);
-#endif
diff --git a/libglusterfs/src/changelog.h b/libglusterfs/src/changelog.h
new file mode 100644
index 00000000000..a09d9f25287
--- /dev/null
+++ b/libglusterfs/src/changelog.h
@@ -0,0 +1,115 @@
+/*
+ Copyright (c) 2013 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 _GF_CHANGELOG_H
+#define _GF_CHANGELOG_H
+
+struct gf_brick_spec;
+
+/**
+ * Max bit shiter for event selection
+ */
+#define CHANGELOG_EV_SELECTION_RANGE 5
+
+#define CHANGELOG_OP_TYPE_JOURNAL (1 << 0)
+#define CHANGELOG_OP_TYPE_OPEN (1 << 1)
+#define CHANGELOG_OP_TYPE_CREATE (1 << 2)
+#define CHANGELOG_OP_TYPE_RELEASE (1 << 3)
+#define CHANGELOG_OP_TYPE_BR_RELEASE \
+ (1 << 4) /* logical release (last close()), \
+ sent by bitrot stub */
+#define CHANGELOG_OP_TYPE_MAX (1 << CHANGELOG_EV_SELECTION_RANGE)
+
+struct ev_open {
+ unsigned char gfid[16];
+ int32_t flags;
+};
+
+struct ev_creat {
+ unsigned char gfid[16];
+ int32_t flags;
+};
+
+struct ev_release {
+ unsigned char gfid[16];
+};
+
+struct ev_release_br {
+ unsigned long version;
+ unsigned char gfid[16];
+ int32_t sign_info;
+};
+
+struct ev_changelog {
+ char path[PATH_MAX];
+};
+
+typedef struct changelog_event {
+ unsigned int ev_type;
+
+ union {
+ struct ev_open open;
+ struct ev_creat create;
+ struct ev_release release;
+ struct ev_changelog journal;
+ struct ev_release_br releasebr;
+ } u;
+} changelog_event_t;
+
+#define CHANGELOG_EV_SIZE (sizeof(changelog_event_t))
+
+/**
+ * event callback, connected & disconnection defs
+ */
+typedef void(CALLBACK)(void *, char *, void *, changelog_event_t *);
+typedef void *(INIT)(void *, struct gf_brick_spec *);
+typedef void(FINI)(void *, char *, void *);
+typedef void(CONNECT)(void *, char *, void *);
+typedef void(DISCONNECT)(void *, char *, void *);
+
+struct gf_brick_spec {
+ char *brick_path;
+ unsigned int filter;
+
+ INIT *init;
+ FINI *fini;
+ CALLBACK *callback;
+ CONNECT *connected;
+ DISCONNECT *disconnected;
+
+ void *ptr;
+};
+
+/* API set */
+
+int
+gf_changelog_register(char *brick_path, char *scratch_dir, char *log_file,
+ int log_levl, int max_reconnects);
+ssize_t
+gf_changelog_scan();
+
+int
+gf_changelog_start_fresh();
+
+ssize_t
+gf_changelog_next_change(char *bufptr, size_t maxlen);
+
+int
+gf_changelog_done(char *file);
+
+/* newer flexible API */
+int
+gf_changelog_init(void *xl);
+
+int
+gf_changelog_register_generic(struct gf_brick_spec *bricks, int count,
+ int ordered, char *logfile, int lvl, void *xl);
+
+#endif
diff --git a/libglusterfs/src/checksum.c b/libglusterfs/src/checksum.c
index cea782293bd..acdaed04ae2 100644
--- a/libglusterfs/src/checksum.c
+++ b/libglusterfs/src/checksum.c
@@ -1,78 +1,44 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 <inttypes.h>
-
-#include "glusterfs.h"
-#include "md5.h"
-#include "checksum.h"
-
+#include <openssl/md5.h>
+#include <openssl/sha.h>
+#include <zlib.h>
+#include <stdint.h>
+#include <string.h>
/*
- * The "weak" checksum required for the rsync algorithm,
- * adapted from the rsync source code. The following comment
- * appears there:
+ * The "weak" checksum required for the rsync algorithm.
*
- * "a simple 32 bit checksum that can be upadted from either end
- * (inspired by Mark Adler's Adler-32 checksum)"
+ * Note: these functions are only called to compute checksums on
+ * pathnames; they don't need to handle arbitrarily long strings of
+ * data. Thus int32_t and uint32_t are sufficient
*/
-
uint32_t
-gf_rsync_weak_checksum (char *buf1, int32_t len)
+gf_rsync_weak_checksum(unsigned char *buf, size_t len)
{
- int32_t i;
- uint32_t s1, s2;
-
- signed char *buf = (signed char *) buf1;
- uint32_t csum;
-
- s1 = s2 = 0;
- for (i = 0; i < (len-4); i+=4) {
- s2 += 4*(s1 + buf[i]) + 3*buf[i+1] + 2*buf[i+2] + buf[i+3];
-
- s1 += buf[i+0] + buf[i+1] + buf[i+2] + buf[i+3];
- }
-
- for (; i < len; i++) {
- s1 += buf[i];
- s2 += s1;
- }
-
- csum = (s1 & 0xffff) + (s2 << 16);
-
- return csum;
+ return adler32(0, buf, len);
}
-
/*
- * The "strong" checksum required for the rsync algorithm,
- * adapted from the rsync source code.
+ * The "strong" checksum required for the rsync algorithm.
*/
-
void
-gf_rsync_strong_checksum (char *buf, int32_t len, uint8_t *sum)
+gf_rsync_strong_checksum(unsigned char *data, size_t len,
+ unsigned char *sha256_md)
{
- md_context m;
-
- md5_begin (&m);
- md5_update (&m, (unsigned char *) buf, len);
- md5_result (&m, (unsigned char *) sum);
+ SHA256((const unsigned char *)data, len, sha256_md);
+}
- return;
+void
+gf_rsync_md5_checksum(unsigned char *data, size_t len, unsigned char *md5)
+{
+ MD5(data, len, md5);
}
diff --git a/libglusterfs/src/checksum.h b/libglusterfs/src/checksum.h
deleted file mode 100644
index 3542036bffc..00000000000
--- a/libglusterfs/src/checksum.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef __CHECKSUM_H__
-#define __CHECKSUM_H__
-
-uint32_t gf_rsync_weak_checksum (char *buf, int32_t len);
-
-void gf_rsync_strong_checksum (char *buf, int32_t len, uint8_t *sum);
-
-#endif /* __CHECKSUM_H__ */
diff --git a/libglusterfs/src/circ-buff.c b/libglusterfs/src/circ-buff.c
new file mode 100644
index 00000000000..913115c7be1
--- /dev/null
+++ b/libglusterfs/src/circ-buff.c
@@ -0,0 +1,193 @@
+/*
+ Copyright (c) 2008-2012 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 "glusterfs/circ-buff.h"
+#include "glusterfs/libglusterfs-messages.h"
+
+void
+cb_destroy_data(circular_buffer_t *cb, void (*destroy_buffer_data)(void *data))
+{
+ if (destroy_buffer_data)
+ destroy_buffer_data(cb->data);
+ GF_FREE(cb->data);
+ return;
+}
+
+/* hold lock while calling this function */
+int
+__cb_add_entry_buffer(buffer_t *buffer, void *item)
+{
+ circular_buffer_t *ptr = NULL;
+ int ret = -1;
+ // DO we really need the assert here?
+ GF_ASSERT(buffer->used_len <= buffer->size_buffer);
+
+ if (buffer->use_once == _gf_true &&
+ buffer->used_len == buffer->size_buffer) {
+ gf_msg("circ-buff", GF_LOG_WARNING, 0, LG_MSG_BUFFER_ERROR,
+ "buffer %p is use once buffer", buffer);
+ return -1;
+ } else {
+ if (buffer->used_len == buffer->size_buffer) {
+ if (buffer->cb[buffer->w_index]) {
+ ptr = buffer->cb[buffer->w_index];
+ if (ptr->data) {
+ cb_destroy_data(ptr, buffer->destroy_buffer_data);
+ ptr->data = NULL;
+ GF_FREE(ptr);
+ }
+ buffer->cb[buffer->w_index] = NULL;
+ ptr = NULL;
+ }
+ }
+
+ buffer->cb[buffer->w_index] = GF_CALLOC(1, sizeof(circular_buffer_t),
+ gf_common_mt_circular_buffer_t);
+ if (!buffer->cb[buffer->w_index])
+ return -1;
+
+ buffer->cb[buffer->w_index]->data = item;
+ ret = gettimeofday(&buffer->cb[buffer->w_index]->tv, NULL);
+ if (ret == -1)
+ gf_msg_callingfn("circ-buff", GF_LOG_WARNING, 0,
+ LG_MSG_GETTIMEOFDAY_FAILED,
+ "getting time of the day failed");
+ buffer->w_index++;
+ buffer->w_index %= buffer->size_buffer;
+ // used_buffer size cannot be greater than the total buffer size
+
+ if (buffer->used_len < buffer->size_buffer)
+ buffer->used_len++;
+ return buffer->w_index;
+ }
+}
+
+int
+cb_add_entry_buffer(buffer_t *buffer, void *item)
+{
+ int write_index = -1;
+
+ pthread_mutex_lock(&buffer->lock);
+ {
+ write_index = __cb_add_entry_buffer(buffer, item);
+ }
+ pthread_mutex_unlock(&buffer->lock);
+
+ return write_index;
+}
+
+void
+cb_buffer_show(buffer_t *buffer)
+{
+ pthread_mutex_lock(&buffer->lock);
+ {
+ gf_msg_debug("circ-buff", 0,
+ "w_index: %d, size: %" GF_PRI_SIZET " used_buffer: %d",
+ buffer->w_index, buffer->size_buffer, buffer->used_len);
+ }
+ pthread_mutex_unlock(&buffer->lock);
+}
+
+void
+cb_buffer_dump(buffer_t *buffer, void *data,
+ int(fn)(circular_buffer_t *buffer, void *data))
+{
+ int index = 0;
+ circular_buffer_t *entry = NULL;
+ int entries = 0;
+ int ul = 0;
+ int w_ind = 0;
+ int size_buff = 0;
+ int i = 0;
+
+ ul = buffer->used_len;
+ w_ind = buffer->w_index;
+ size_buff = buffer->size_buffer;
+
+ pthread_mutex_lock(&buffer->lock);
+ {
+ if (buffer->use_once == _gf_false) {
+ index = (size_buff + (w_ind - ul)) % size_buff;
+ for (entries = 0; entries < buffer->used_len; entries++) {
+ entry = buffer->cb[index];
+ if (entry)
+ fn(entry, data);
+ else
+ gf_msg_callingfn("circ-buff", GF_LOG_WARNING, 0,
+ LG_MSG_NULL_PTR,
+ "Null entry in "
+ "circular buffer at "
+ "index %d.",
+ index);
+
+ index++;
+ index %= buffer->size_buffer;
+ }
+ } else {
+ for (i = 0; i < buffer->used_len; i++) {
+ entry = buffer->cb[i];
+ fn(entry, data);
+ }
+ }
+ }
+ pthread_mutex_unlock(&buffer->lock);
+}
+
+buffer_t *
+cb_buffer_new(size_t buffer_size, gf_boolean_t use_once,
+ void (*destroy_buffer_data)(void *data))
+{
+ buffer_t *buffer = NULL;
+
+ buffer = GF_CALLOC(1, sizeof(*buffer), gf_common_mt_buffer_t);
+ if (!buffer) {
+ goto out;
+ }
+
+ buffer->cb = GF_CALLOC(buffer_size, sizeof(circular_buffer_t *),
+ gf_common_mt_circular_buffer_t);
+ if (!buffer->cb) {
+ GF_FREE(buffer);
+ buffer = NULL;
+ goto out;
+ }
+
+ buffer->w_index = 0;
+ buffer->size_buffer = buffer_size;
+ buffer->use_once = use_once;
+ buffer->used_len = 0;
+ buffer->destroy_buffer_data = destroy_buffer_data;
+ pthread_mutex_init(&buffer->lock, NULL);
+
+out:
+ return buffer;
+}
+
+void
+cb_buffer_destroy(buffer_t *buffer)
+{
+ int i = 0;
+ circular_buffer_t *ptr = NULL;
+ if (buffer) {
+ if (buffer->cb) {
+ for (i = 0; i < buffer->used_len; i++) {
+ ptr = buffer->cb[i];
+ if (ptr->data) {
+ cb_destroy_data(ptr, buffer->destroy_buffer_data);
+ ptr->data = NULL;
+ GF_FREE(ptr);
+ }
+ }
+ GF_FREE(buffer->cb);
+ }
+ pthread_mutex_destroy(&buffer->lock);
+ GF_FREE(buffer);
+ }
+}
diff --git a/libglusterfs/src/client_t.c b/libglusterfs/src/client_t.c
new file mode 100644
index 00000000000..9d377c3c2e1
--- /dev/null
+++ b/libglusterfs/src/client_t.c
@@ -0,0 +1,825 @@
+/*
+ Copyright (c) 2008-2013 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 "glusterfs/glusterfs.h"
+#include "glusterfs/dict.h"
+#include "glusterfs/statedump.h"
+#include "glusterfs/client_t.h"
+#include "glusterfs/list.h"
+#include "glusterfs/libglusterfs-messages.h"
+
+static int
+gf_client_chain_client_entries(cliententry_t *entries, uint32_t startidx,
+ uint32_t endcount)
+{
+ uint32_t i = 0;
+
+ if (!entries) {
+ gf_msg_callingfn("client_t", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "!entries");
+ return -1;
+ }
+
+ /* Chain only till the second to last entry because we want to
+ * ensure that the last entry has GF_CLIENTTABLE_END.
+ */
+ for (i = startidx; i < (endcount - 1); i++)
+ entries[i].next_free = i + 1;
+
+ /* i has already been incremented up to the last entry. */
+ entries[i].next_free = GF_CLIENTTABLE_END;
+
+ return 0;
+}
+
+static int
+gf_client_clienttable_expand(clienttable_t *clienttable, uint32_t nr)
+{
+ cliententry_t *oldclients = NULL;
+ uint32_t oldmax_clients = -1;
+ int ret = -1;
+
+ if (clienttable == NULL || nr <= clienttable->max_clients) {
+ gf_msg_callingfn("client_t", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ ret = EINVAL;
+ goto out;
+ }
+
+ oldclients = clienttable->cliententries;
+ oldmax_clients = clienttable->max_clients;
+
+ clienttable->cliententries = GF_CALLOC(nr, sizeof(cliententry_t),
+ gf_common_mt_cliententry_t);
+ if (!clienttable->cliententries) {
+ clienttable->cliententries = oldclients;
+ ret = 0;
+ goto out;
+ }
+ clienttable->max_clients = nr;
+
+ if (oldclients) {
+ uint32_t cpy = oldmax_clients * sizeof(cliententry_t);
+ memcpy(clienttable->cliententries, oldclients, cpy);
+ }
+
+ gf_client_chain_client_entries(clienttable->cliententries, oldmax_clients,
+ clienttable->max_clients);
+
+ /* Now that expansion is done, we must update the client list
+ * head pointer so that the client allocation functions can continue
+ * using the expanded table.
+ */
+ clienttable->first_free = oldmax_clients;
+ GF_FREE(oldclients);
+ ret = 0;
+out:
+ return ret;
+}
+
+clienttable_t *
+gf_clienttable_alloc(void)
+{
+ clienttable_t *clienttable = NULL;
+ int result = 0;
+
+ clienttable = GF_CALLOC(1, sizeof(clienttable_t),
+ gf_common_mt_clienttable_t);
+ if (!clienttable)
+ return NULL;
+
+ LOCK_INIT(&clienttable->lock);
+
+ result = gf_client_clienttable_expand(clienttable,
+ GF_CLIENTTABLE_INITIAL_SIZE);
+ if (result != 0) {
+ gf_msg("client_t", GF_LOG_ERROR, 0, LG_MSG_EXPAND_CLIENT_TABLE_FAILED,
+ "gf_client_clienttable_expand failed");
+ GF_FREE(clienttable);
+ return NULL;
+ }
+
+ return clienttable;
+}
+
+/*
+ * Increments ref.bind if the client is already present or creates a new
+ * client with ref.bind = 1,ref.count = 1 it signifies that
+ * as long as ref.bind is > 0 client should be alive.
+ */
+client_t *
+gf_client_get(xlator_t *this, client_auth_data_t *cred, char *client_uid,
+ char *subdir_mount)
+{
+ client_t *client = NULL;
+ cliententry_t *cliententry = NULL;
+ clienttable_t *clienttable = NULL;
+ unsigned int i = 0;
+
+ if (this == NULL || client_uid == NULL) {
+ gf_msg_callingfn("client_t", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ errno = EINVAL;
+ return NULL;
+ }
+
+ clienttable = this->ctx->clienttable;
+
+ LOCK(&clienttable->lock);
+ {
+ for (; i < clienttable->max_clients; i++) {
+ client = clienttable->cliententries[i].client;
+ if (client == NULL)
+ continue;
+ /*
+ * look for matching client_uid, _and_
+ * if auth was used, matching auth flavour and data
+ */
+ if (strcmp(client_uid, client->client_uid) == 0 &&
+ (cred->flavour && (cred->flavour == client->auth.flavour &&
+ (size_t)cred->datalen == client->auth.len &&
+ memcmp(cred->authdata, client->auth.data,
+ client->auth.len) == 0))) {
+ GF_ATOMIC_INC(client->bind);
+ goto unlock;
+ }
+ }
+
+ client = GF_CALLOC(1, sizeof(client_t), gf_common_mt_client_t);
+ if (client == NULL) {
+ errno = ENOMEM;
+ goto unlock;
+ }
+
+ client->this = this;
+ if (subdir_mount != NULL)
+ client->subdir_mount = gf_strdup(subdir_mount);
+
+ LOCK_INIT(&client->scratch_ctx.lock);
+
+ client->client_uid = gf_strdup(client_uid);
+ if (client->client_uid == NULL) {
+ GF_FREE(client);
+ client = NULL;
+ errno = ENOMEM;
+ goto unlock;
+ }
+ client->scratch_ctx.count = GF_CLIENTCTX_INITIAL_SIZE;
+ client->scratch_ctx.ctx = GF_CALLOC(GF_CLIENTCTX_INITIAL_SIZE,
+ sizeof(struct client_ctx),
+ gf_common_mt_client_ctx);
+ if (client->scratch_ctx.ctx == NULL) {
+ GF_FREE(client->client_uid);
+ GF_FREE(client);
+ client = NULL;
+ errno = ENOMEM;
+ goto unlock;
+ }
+
+ GF_ATOMIC_INIT(client->bind, 1);
+ GF_ATOMIC_INIT(client->count, 1);
+ GF_ATOMIC_INIT(client->fd_cnt, 0);
+
+ client->auth.flavour = cred->flavour;
+ if (cred->flavour) {
+ client->auth.data = GF_MALLOC(cred->datalen, gf_common_mt_client_t);
+ if (client->auth.data == NULL) {
+ GF_FREE(client->scratch_ctx.ctx);
+ GF_FREE(client->client_uid);
+ GF_FREE(client);
+ client = NULL;
+ errno = ENOMEM;
+ goto unlock;
+ }
+ memcpy(client->auth.data, cred->authdata, cred->datalen);
+ client->auth.len = cred->datalen;
+ }
+
+ client->tbl_index = clienttable->first_free;
+ cliententry = &clienttable->cliententries[clienttable->first_free];
+ if (cliententry->next_free == GF_CLIENTTABLE_END) {
+ int result = gf_client_clienttable_expand(
+ clienttable,
+ clienttable->max_clients + GF_CLIENTTABLE_INITIAL_SIZE);
+ if (result != 0) {
+ GF_FREE(client->scratch_ctx.ctx);
+ GF_FREE(client->client_uid);
+ GF_FREE(client);
+ client = NULL;
+ errno = result;
+ goto unlock;
+ }
+ cliententry = &clienttable->cliententries[client->tbl_index];
+ cliententry->next_free = clienttable->first_free;
+ }
+ cliententry->client = client;
+ clienttable->first_free = cliententry->next_free;
+ cliententry->next_free = GF_CLIENTENTRY_ALLOCATED;
+ }
+unlock:
+ UNLOCK(&clienttable->lock);
+
+ if (client)
+ gf_msg_callingfn("client_t", GF_LOG_DEBUG, 0, LG_MSG_BIND_REF,
+ "%s: bind_ref: %" GF_PRI_ATOMIC
+ ", ref: "
+ "%" GF_PRI_ATOMIC,
+ client->client_uid, GF_ATOMIC_GET(client->bind),
+ GF_ATOMIC_GET(client->count));
+ return client;
+}
+
+void
+gf_client_put(client_t *client, gf_boolean_t *detached)
+{
+ gf_boolean_t unref = _gf_false;
+ int bind_ref;
+
+ if (client == NULL)
+ goto out;
+
+ if (detached)
+ *detached = _gf_false;
+
+ bind_ref = GF_ATOMIC_DEC(client->bind);
+ if (bind_ref == 0)
+ unref = _gf_true;
+
+ gf_msg_callingfn("client_t", GF_LOG_DEBUG, 0, LG_MSG_BIND_REF,
+ "%s: "
+ "bind_ref: %" GF_PRI_ATOMIC ", ref: %" GF_PRI_ATOMIC
+ ", "
+ "unref: %d",
+ client->client_uid, GF_ATOMIC_GET(client->bind),
+ GF_ATOMIC_GET(client->count), unref);
+ if (unref) {
+ if (detached)
+ *detached = _gf_true;
+ gf_client_unref(client);
+ }
+
+out:
+ return;
+}
+
+client_t *
+gf_client_ref(client_t *client)
+{
+ if (!client) {
+ gf_msg_callingfn("client_t", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "null client");
+ return NULL;
+ }
+
+ GF_ATOMIC_INC(client->count);
+ gf_msg_callingfn("client_t", GF_LOG_DEBUG, 0, LG_MSG_REF_COUNT,
+ "%s: "
+ "ref-count %" GF_PRI_ATOMIC,
+ client->client_uid, GF_ATOMIC_GET(client->count));
+ return client;
+}
+
+static void
+gf_client_destroy_recursive(xlator_t *xl, client_t *client)
+{
+ xlator_list_t *trav;
+
+ if (!xl->call_cleanup && xl->cbks->client_destroy) {
+ xl->cbks->client_destroy(xl, client);
+ }
+
+ for (trav = xl->children; trav; trav = trav->next) {
+ gf_client_destroy_recursive(trav->xlator, client);
+ }
+}
+
+static void
+client_destroy(client_t *client)
+{
+ clienttable_t *clienttable = NULL;
+ glusterfs_graph_t *gtrav = NULL;
+
+ if (client == NULL) {
+ gf_msg_callingfn("xlator", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ goto out;
+ }
+
+ clienttable = client->this->ctx->clienttable;
+
+ LOCK(&clienttable->lock);
+ {
+ clienttable->cliententries[client->tbl_index].client = NULL;
+ clienttable->cliententries[client->tbl_index]
+ .next_free = clienttable->first_free;
+ clienttable->first_free = client->tbl_index;
+ }
+ UNLOCK(&clienttable->lock);
+
+ list_for_each_entry(gtrav, &client->this->ctx->graphs, list)
+ {
+ gf_client_destroy_recursive(gtrav->top, client);
+ }
+
+ if (client->subdir_inode)
+ inode_unref(client->subdir_inode);
+
+ LOCK_DESTROY(&client->scratch_ctx.lock);
+
+ GF_FREE(client->auth.data);
+ GF_FREE(client->auth.username);
+ GF_FREE(client->auth.passwd);
+ GF_FREE(client->scratch_ctx.ctx);
+ GF_FREE(client->client_uid);
+ GF_FREE(client->subdir_mount);
+ GF_FREE(client->client_name);
+ GF_FREE(client);
+out:
+ return;
+}
+
+static int
+gf_client_disconnect_recursive(xlator_t *xl, client_t *client)
+{
+ int ret = 0;
+ xlator_list_t *trav;
+
+ if (!xl->call_cleanup && xl->cbks->client_disconnect) {
+ ret = xl->cbks->client_disconnect(xl, client);
+ }
+
+ for (trav = xl->children; trav; trav = trav->next) {
+ ret |= gf_client_disconnect_recursive(trav->xlator, client);
+ }
+
+ return ret;
+}
+
+int
+gf_client_disconnect(client_t *client)
+{
+ int ret = 0;
+ glusterfs_graph_t *gtrav = NULL;
+
+ list_for_each_entry(gtrav, &client->this->ctx->graphs, list)
+ {
+ ret |= gf_client_disconnect_recursive(gtrav->top, client);
+ }
+
+ return ret;
+}
+
+void
+gf_client_unref(client_t *client)
+{
+ uint64_t refcount;
+
+ if (!client) {
+ gf_msg_callingfn("client_t", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "client is NULL");
+ return;
+ }
+
+ refcount = GF_ATOMIC_DEC(client->count);
+ gf_msg_callingfn("client_t", GF_LOG_DEBUG, 0, LG_MSG_REF_COUNT,
+ "%s: "
+ "ref-count %" GF_PRI_ATOMIC,
+ client->client_uid, refcount);
+ if (refcount == 0) {
+ gf_msg(THIS->name, GF_LOG_INFO, 0, LG_MSG_DISCONNECT_CLIENT,
+ "Shutting down connection %s", client->client_uid);
+ client_destroy(client);
+ }
+}
+
+static int
+__client_ctx_get_int(client_t *client, void *key, void **value)
+{
+ int index = 0;
+ int ret = 0;
+
+ for (index = 0; index < client->scratch_ctx.count; index++) {
+ if (client->scratch_ctx.ctx[index].ctx_key == key)
+ break;
+ }
+
+ if (index == client->scratch_ctx.count) {
+ ret = -1;
+ goto out;
+ }
+
+ if (value)
+ *value = client->scratch_ctx.ctx[index].ctx_value;
+
+out:
+ return ret;
+}
+
+static int
+__client_ctx_set_int(client_t *client, void *key, void *value)
+{
+ int index = 0;
+ int ret = 0;
+ int set_idx = -1;
+
+ for (index = 0; index < client->scratch_ctx.count; index++) {
+ if (!client->scratch_ctx.ctx[index].ctx_key) {
+ if (set_idx == -1)
+ set_idx = index;
+ /* don't break, to check if key already exists
+ further on */
+ }
+ if (client->scratch_ctx.ctx[index].ctx_key == key) {
+ set_idx = index;
+ break;
+ }
+ }
+
+ if (set_idx == -1) {
+ ret = -1;
+ goto out;
+ }
+
+ client->scratch_ctx.ctx[set_idx].ctx_key = key;
+ client->scratch_ctx.ctx[set_idx].ctx_value = value;
+
+out:
+ return ret;
+}
+
+/*will return success with old value if exist*/
+void *
+client_ctx_set(client_t *client, void *key, void *value)
+{
+ int ret = 0;
+ void *ret_value = NULL;
+
+ if (!client || !key || !value)
+ return NULL;
+
+ LOCK(&client->scratch_ctx.lock);
+ {
+ ret = __client_ctx_get_int(client, key, &ret_value);
+ if (!ret && ret_value) {
+ UNLOCK(&client->scratch_ctx.lock);
+ return ret_value;
+ }
+
+ ret = __client_ctx_set_int(client, key, value);
+ }
+ UNLOCK(&client->scratch_ctx.lock);
+
+ if (ret)
+ return NULL;
+ return value;
+}
+
+int
+client_ctx_get(client_t *client, void *key, void **value)
+{
+ int ret = 0;
+
+ if (!client || !key)
+ return -1;
+
+ LOCK(&client->scratch_ctx.lock);
+ {
+ ret = __client_ctx_get_int(client, key, value);
+ }
+ UNLOCK(&client->scratch_ctx.lock);
+
+ return ret;
+}
+
+static int
+__client_ctx_del_int(client_t *client, void *key, void **value)
+{
+ int index = 0;
+ int ret = 0;
+
+ for (index = 0; index < client->scratch_ctx.count; index++) {
+ if (client->scratch_ctx.ctx[index].ctx_key == key)
+ break;
+ }
+
+ if (index == client->scratch_ctx.count) {
+ ret = -1;
+ goto out;
+ }
+
+ if (value)
+ *value = client->scratch_ctx.ctx[index].ctx_value;
+
+ client->scratch_ctx.ctx[index].ctx_key = 0;
+ client->scratch_ctx.ctx[index].ctx_value = 0;
+
+out:
+ return ret;
+}
+
+int
+client_ctx_del(client_t *client, void *key, void **value)
+{
+ int ret = 0;
+
+ if (!client || !key)
+ return -1;
+
+ LOCK(&client->scratch_ctx.lock);
+ {
+ ret = __client_ctx_del_int(client, key, value);
+ }
+ UNLOCK(&client->scratch_ctx.lock);
+
+ return ret;
+}
+
+void
+client_ctx_dump(client_t *client, char *prefix)
+{
+#if 0 /* TBD, FIXME */
+ struct client_ctx *client_ctx = NULL;
+ xlator_t *xl = NULL;
+ int i = 0;
+
+ if ((client == NULL) || (client->ctx == NULL)) {
+ goto out;
+ }
+
+ LOCK (&client->ctx_lock);
+ if (client->ctx != NULL) {
+ client_ctx = GF_CALLOC (client->inode->table->xl->graph->ctx_count,
+ sizeof (*client_ctx),
+ gf_common_mt_client_ctx);
+ if (client_ctx == NULL) {
+ goto unlock;
+ }
+
+ for (i = 0; i < client->inode->table->xl->graph->ctx_count; i++) {
+ client_ctx[i] = client->ctx[i];
+ }
+ }
+unlock:
+ UNLOCK (&client->ctx_lock);
+
+ if (client_ctx == NULL) {
+ goto out;
+ }
+
+ for (i = 0; i < client->inode->table->xl->graph->ctx_count; i++) {
+ if (client_ctx[i].xl_key) {
+ xl = (xlator_t *)(long)client_ctx[i].xl_key;
+ if (xl->dumpops && xl->dumpops->clientctx)
+ xl->dumpops->clientctx (xl, client);
+ }
+ }
+out:
+ GF_FREE (client_ctx);
+#endif
+}
+
+/*
+ * the following functions are here to preserve legacy behavior of the
+ * protocol/server xlator dump, but perhaps they should just be folded
+ * into the client dump instead?
+ */
+int
+gf_client_dump_fdtables_to_dict(xlator_t *this, dict_t *dict)
+{
+ clienttable_t *clienttable = NULL;
+ int count = 0;
+ int ret = -1;
+#ifdef NOTYET
+ client_t *client = NULL;
+ char key[GF_DUMP_MAX_BUF_LEN] = {
+ 0,
+ };
+#endif
+
+ GF_VALIDATE_OR_GOTO(THIS->name, this, out);
+ GF_VALIDATE_OR_GOTO(this->name, dict, out);
+
+ clienttable = this->ctx->clienttable;
+
+ if (!clienttable)
+ return -1;
+
+#ifdef NOTYET
+ ret = TRY_LOCK(&clienttable->lock);
+ {
+ if (ret) {
+ gf_msg("client_t", GF_LOG_WARNING, 0, LG_MSG_LOCK_FAILED,
+ "Unable to acquire lock");
+ return -1;
+ }
+ for (; count < clienttable->max_clients; count++) {
+ if (GF_CLIENTENTRY_ALLOCATED !=
+ clienttable->cliententries[count].next_free)
+ continue;
+ client = clienttable->cliententries[count].client;
+ if (client->bound_xl &&
+ !strcmp(client->bound_xl->name, this->name)) {
+ snprintf(key, sizeof(key), "conn%d", count++);
+ fdtable_dump_to_dict(client->server_ctx.fdtable, key, dict);
+ }
+ }
+ }
+ UNLOCK(&clienttable->lock);
+#endif
+
+ ret = dict_set_int32(dict, "conncount", count);
+out:
+ return ret;
+}
+
+int
+gf_client_dump_fdtables(xlator_t *this)
+{
+ client_t *client = NULL;
+ clienttable_t *clienttable = NULL;
+ int count = 1;
+ int ret = -1;
+ char key[GF_DUMP_MAX_BUF_LEN] = {
+ 0,
+ };
+
+ GF_VALIDATE_OR_GOTO(THIS->name, this, out);
+
+ clienttable = this->ctx->clienttable;
+
+ if (!clienttable)
+ return -1;
+
+ ret = TRY_LOCK(&clienttable->lock);
+ {
+ if (ret) {
+ gf_msg("client_t", GF_LOG_WARNING, 0, LG_MSG_LOCK_FAILED,
+ "Unable to acquire lock");
+ return -1;
+ }
+
+ for (; count < clienttable->max_clients; count++) {
+ if (GF_CLIENTENTRY_ALLOCATED !=
+ clienttable->cliententries[count].next_free)
+ continue;
+ client = clienttable->cliententries[count].client;
+ if (client->client_uid) {
+ gf_proc_dump_build_key(key, "conn", "%d.id", count);
+ gf_proc_dump_write(key, "%s", client->client_uid);
+ }
+
+ if (client->subdir_mount) {
+ gf_proc_dump_build_key(key, "conn", "%d.subdir", count);
+ gf_proc_dump_write(key, "%s", client->subdir_mount);
+ }
+ gf_proc_dump_build_key(key, "conn", "%d.ref", count);
+ gf_proc_dump_write(key, "%" GF_PRI_ATOMIC,
+ GF_ATOMIC_GET(client->count));
+ if (client->bound_xl) {
+ gf_proc_dump_build_key(key, "conn", "%d.bound_xl", count);
+ gf_proc_dump_write(key, "%s", client->bound_xl->name);
+ }
+
+#ifdef NOTYET
+ gf_proc_dump_build_key(key, "conn", "%d.id", count);
+ fdtable_dump(client->server_ctx.fdtable, key);
+#endif
+ }
+ }
+
+ UNLOCK(&clienttable->lock);
+
+ ret = 0;
+out:
+ return ret;
+}
+
+int
+gf_client_dump_inodes_to_dict(xlator_t *this, dict_t *dict)
+{
+ client_t *client = NULL;
+ clienttable_t *clienttable = NULL;
+ xlator_t *prev_bound_xl = NULL;
+ char key[32] = {
+ 0,
+ };
+ int count = 0;
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO(THIS->name, this, out);
+ GF_VALIDATE_OR_GOTO(this->name, dict, out);
+
+ clienttable = this->ctx->clienttable;
+
+ if (!clienttable)
+ return -1;
+
+ ret = LOCK(&clienttable->lock);
+ {
+ if (ret) {
+ gf_msg("client_t", GF_LOG_WARNING, 0, LG_MSG_LOCK_FAILED,
+ "Unable to acquire lock");
+ return -1;
+ }
+ for (; count < clienttable->max_clients; count++) {
+ if (GF_CLIENTENTRY_ALLOCATED !=
+ clienttable->cliententries[count].next_free)
+ continue;
+ client = clienttable->cliententries[count].client;
+ if (!strcmp(client->bound_xl->name, this->name)) {
+ if (client->bound_xl && client->bound_xl->itable) {
+ /* Presently every brick contains only
+ * one bound_xl for all connections.
+ * This will lead to duplicating of
+ * the inode lists, if listing is
+ * done for every connection. This
+ * simple check prevents duplication
+ * in the present case. If need arises
+ * the check can be improved.
+ */
+ if (client->bound_xl == prev_bound_xl)
+ continue;
+ prev_bound_xl = client->bound_xl;
+
+ snprintf(key, sizeof(key), "conn%d", count);
+ inode_table_dump_to_dict(client->bound_xl->itable, key,
+ dict);
+ }
+ }
+ }
+ }
+ UNLOCK(&clienttable->lock);
+
+ ret = dict_set_int32(dict, "conncount", count);
+
+out:
+ if (prev_bound_xl)
+ prev_bound_xl = NULL;
+ return ret;
+}
+
+int
+gf_client_dump_inodes(xlator_t *this)
+{
+ client_t *client = NULL;
+ clienttable_t *clienttable = NULL;
+ xlator_t *prev_bound_xl = NULL;
+ int count = 0;
+ int ret = -1;
+ char key[GF_DUMP_MAX_BUF_LEN] = {
+ 0,
+ };
+
+ GF_VALIDATE_OR_GOTO(THIS->name, this, out);
+
+ clienttable = this->ctx->clienttable;
+
+ if (!clienttable)
+ goto out;
+
+ ret = TRY_LOCK(&clienttable->lock);
+ {
+ if (ret) {
+ gf_msg("client_t", GF_LOG_WARNING, 0, LG_MSG_LOCK_FAILED,
+ "Unable to acquire lock");
+ goto out;
+ }
+
+ for (; count < clienttable->max_clients; count++) {
+ if (GF_CLIENTENTRY_ALLOCATED !=
+ clienttable->cliententries[count].next_free)
+ continue;
+ client = clienttable->cliententries[count].client;
+ if (client->bound_xl && client->bound_xl->itable) {
+ /* Presently every brick contains only
+ * one bound_xl for all connections.
+ * This will lead to duplicating of
+ * the inode lists, if listing is
+ * done for every connection. This
+ * simple check prevents duplication
+ * in the present case. If need arises
+ * the check can be improved.
+ */
+ if (client->bound_xl == prev_bound_xl)
+ continue;
+ prev_bound_xl = client->bound_xl;
+
+ gf_proc_dump_build_key(key, "conn", "%d.bound_xl.%s", count,
+ client->bound_xl->name);
+ inode_table_dump(client->bound_xl->itable, key);
+ }
+ }
+ }
+ UNLOCK(&clienttable->lock);
+
+ ret = 0;
+out:
+ return ret;
+}
diff --git a/libglusterfs/src/cluster-syncop.c b/libglusterfs/src/cluster-syncop.c
new file mode 100644
index 00000000000..6ee89ddfdcf
--- /dev/null
+++ b/libglusterfs/src/cluster-syncop.c
@@ -0,0 +1,1261 @@
+/*
+ Copyright (c) 2015 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.
+*/
+
+/* Perform fop on all subvolumes represented by list[] array and wait
+ for all callbacks to return */
+
+/* NOTE: Cluster-syncop, like syncop blocks the executing thread until the
+ * responses are gathered if it is not executed as part of synctask. So it
+ * shouldn't be invoked in epoll worker thread */
+#include "glusterfs/cluster-syncop.h"
+#include "glusterfs/defaults.h"
+
+#define FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, fop, \
+ args...) \
+ do { \
+ int __i = 0; \
+ int __count = 0; \
+ cluster_local_t __local = { \
+ 0, \
+ }; \
+ void *__old_local = frame->local; \
+ \
+ __local.replies = replies; \
+ memset(output, 0, numsubvols); \
+ cluster_replies_wipe(replies, numsubvols); \
+ for (__i = 0; __i < numsubvols; __i++) \
+ INIT_LIST_HEAD(&replies[__i].entries.list); \
+ if (syncbarrier_init(&__local.barrier)) \
+ break; \
+ frame->local = &__local; \
+ for (__i = 0; __i < numsubvols; __i++) { \
+ if (on[__i]) { \
+ __count++; \
+ } \
+ } \
+ __local.barrier.waitfor = __count; \
+ for (__i = 0; __i < numsubvols; __i++) { \
+ if (!on[__i]) \
+ continue; \
+ STACK_WIND_COOKIE(frame, cluster_##fop##_cbk, (void *)(long)__i, \
+ subvols[__i], subvols[__i]->fops->fop, args); \
+ } \
+ syncbarrier_wait(&__local.barrier, __count); \
+ syncbarrier_destroy(&__local.barrier); \
+ frame->local = __old_local; \
+ STACK_RESET(frame->root); \
+ } while (0)
+
+#define FOP_SEQ(subvols, on, numsubvols, replies, output, frame, fop, args...) \
+ do { \
+ int __i = 0; \
+ \
+ cluster_local_t __local = { \
+ 0, \
+ }; \
+ void *__old_local = frame->local; \
+ __local.replies = replies; \
+ memset(output, 0, numsubvols); \
+ cluster_replies_wipe(replies, numsubvols); \
+ for (__i = 0; __i < numsubvols; __i++) \
+ INIT_LIST_HEAD(&replies[__i].entries.list); \
+ if (syncbarrier_init(&__local.barrier)) \
+ break; \
+ frame->local = &__local; \
+ for (__i = 0; __i < numsubvols; __i++) { \
+ if (!on[__i]) \
+ continue; \
+ STACK_WIND_COOKIE(frame, cluster_##fop##_cbk, (void *)(long)__i, \
+ subvols[__i], subvols[__i]->fops->fop, args); \
+ syncbarrier_wait(&__local.barrier, 1); \
+ } \
+ syncbarrier_destroy(&__local.barrier); \
+ frame->local = __old_local; \
+ STACK_RESET(frame->root); \
+ } while (0)
+
+#define FOP_CBK(fop, frame, cookie, args...) \
+ do { \
+ cluster_local_t *__local = frame->local; \
+ int __i = (long)cookie; \
+ args_##fop##_cbk_store(&__local->replies[__i], args); \
+ __local->replies[__i].valid = 1; \
+ syncbarrier_wake(&__local->barrier); \
+ } while (0)
+
+int32_t
+cluster_fop_success_fill(default_args_cbk_t *replies, int numsubvols,
+ unsigned char *success)
+{
+ int i = 0;
+ int count = 0;
+
+ for (i = 0; i < numsubvols; i++) {
+ if (replies[i].valid && replies[i].op_ret >= 0) {
+ success[i] = 1;
+ count++;
+ } else {
+ success[i] = 0;
+ }
+ }
+
+ return count;
+}
+
+void
+cluster_replies_wipe(default_args_cbk_t *replies, int numsubvols)
+{
+ int i = 0;
+
+ if (!replies)
+ return;
+
+ for (i = 0; i < numsubvols; i++)
+ args_cbk_wipe(&replies[i]);
+ memset(replies, 0, numsubvols * sizeof(*replies));
+}
+
+int32_t
+cluster_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *buf, dict_t *xdata, struct iatt *postparent)
+{
+ FOP_CBK(lookup, frame, cookie, op_ret, op_errno, inode, buf, xdata,
+ postparent);
+ return 0;
+}
+
+int32_t
+cluster_stat_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf,
+ dict_t *xdata)
+{
+ FOP_CBK(stat, frame, cookie, op_ret, op_errno, buf, xdata);
+ return 0;
+}
+
+int32_t
+cluster_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ FOP_CBK(truncate, frame, cookie, op_ret, op_errno, prebuf, postbuf, xdata);
+ return 0;
+}
+
+int32_t
+cluster_ftruncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ FOP_CBK(ftruncate, frame, cookie, op_ret, op_errno, prebuf, postbuf, xdata);
+ return 0;
+}
+
+int32_t
+cluster_access_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ FOP_CBK(access, frame, cookie, op_ret, op_errno, xdata);
+ return 0;
+}
+
+int32_t
+cluster_readlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, const char *path,
+ struct iatt *buf, dict_t *xdata)
+{
+ FOP_CBK(readlink, frame, cookie, op_ret, op_errno, path, buf, xdata);
+ return 0;
+}
+
+int32_t
+cluster_mknod_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ FOP_CBK(mknod, frame, cookie, op_ret, op_errno, inode, buf, preparent,
+ postparent, xdata);
+ return 0;
+}
+
+int32_t
+cluster_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ FOP_CBK(mkdir, frame, cookie, op_ret, op_errno, inode, buf, preparent,
+ postparent, xdata);
+ return 0;
+}
+
+int32_t
+cluster_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ FOP_CBK(unlink, frame, cookie, op_ret, op_errno, preparent, postparent,
+ xdata);
+ return 0;
+}
+
+int32_t
+cluster_rmdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ FOP_CBK(rmdir, frame, cookie, op_ret, op_errno, preparent, postparent,
+ xdata);
+ return 0;
+}
+
+int32_t
+cluster_symlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ FOP_CBK(symlink, frame, cookie, op_ret, op_errno, inode, buf, preparent,
+ postparent, xdata);
+ return 0;
+}
+
+int32_t
+cluster_rename_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf,
+ struct iatt *preoldparent, struct iatt *postoldparent,
+ struct iatt *prenewparent, struct iatt *postnewparent,
+ dict_t *xdata)
+{
+ FOP_CBK(rename, frame, cookie, op_ret, op_errno, buf, preoldparent,
+ postoldparent, prenewparent, postnewparent, xdata);
+ return 0;
+}
+
+int32_t
+cluster_link_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ FOP_CBK(link, frame, cookie, op_ret, op_errno, inode, buf, preparent,
+ postparent, xdata);
+ return 0;
+}
+
+int32_t
+cluster_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode,
+ struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ FOP_CBK(create, frame, cookie, op_ret, op_errno, fd, inode, buf, preparent,
+ postparent, xdata);
+ return 0;
+}
+
+int32_t
+cluster_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+{
+ FOP_CBK(open, frame, cookie, op_ret, op_errno, fd, xdata);
+ return 0;
+}
+
+int32_t
+cluster_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iovec *vector,
+ int32_t count, struct iatt *stbuf, struct iobref *iobref,
+ dict_t *xdata)
+{
+ FOP_CBK(readv, frame, cookie, op_ret, op_errno, vector, count, stbuf,
+ iobref, xdata);
+ return 0;
+}
+
+int32_t
+cluster_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ FOP_CBK(writev, frame, cookie, op_ret, op_errno, prebuf, postbuf, xdata);
+ return 0;
+}
+
+int32_t
+cluster_put_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ FOP_CBK(put, frame, cookie, op_ret, op_errno, inode, buf, preparent,
+ postparent, xdata);
+ return 0;
+}
+
+int32_t
+cluster_flush_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ FOP_CBK(flush, frame, cookie, op_ret, op_errno, xdata);
+ return 0;
+}
+
+int32_t
+cluster_fsync_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ FOP_CBK(fsync, frame, cookie, op_ret, op_errno, prebuf, postbuf, xdata);
+ return 0;
+}
+
+int32_t
+cluster_fstat_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf,
+ dict_t *xdata)
+{
+ FOP_CBK(fstat, frame, cookie, op_ret, op_errno, buf, xdata);
+ return 0;
+}
+
+int32_t
+cluster_opendir_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+{
+ FOP_CBK(opendir, frame, cookie, op_ret, op_errno, fd, xdata);
+ return 0;
+}
+
+int32_t
+cluster_fsyncdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ FOP_CBK(fsyncdir, frame, cookie, op_ret, op_errno, xdata);
+ return 0;
+}
+
+int32_t
+cluster_statfs_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct statvfs *buf,
+ dict_t *xdata)
+{
+ FOP_CBK(statfs, frame, cookie, op_ret, op_errno, buf, xdata);
+ return 0;
+}
+
+int32_t
+cluster_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ FOP_CBK(setxattr, frame, cookie, op_ret, op_errno, xdata);
+ return 0;
+}
+
+int32_t
+cluster_fsetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ FOP_CBK(fsetxattr, frame, cookie, op_ret, op_errno, xdata);
+ return 0;
+}
+
+int32_t
+cluster_fgetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
+{
+ FOP_CBK(fgetxattr, frame, cookie, op_ret, op_errno, dict, xdata);
+ return 0;
+}
+
+int32_t
+cluster_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
+{
+ FOP_CBK(getxattr, frame, cookie, op_ret, op_errno, dict, xdata);
+ return 0;
+}
+
+int32_t
+cluster_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
+{
+ FOP_CBK(xattrop, frame, cookie, op_ret, op_errno, dict, xdata);
+ return 0;
+}
+
+int32_t
+cluster_fxattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
+{
+ FOP_CBK(fxattrop, frame, cookie, op_ret, op_errno, dict, xdata);
+ return 0;
+}
+
+int32_t
+cluster_removexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ FOP_CBK(removexattr, frame, cookie, op_ret, op_errno, xdata);
+ return 0;
+}
+
+int32_t
+cluster_fremovexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ FOP_CBK(fremovexattr, frame, cookie, op_ret, op_errno, xdata);
+ return 0;
+}
+
+int32_t
+cluster_lk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct gf_flock *lock,
+ dict_t *xdata)
+{
+ FOP_CBK(lk, frame, cookie, op_ret, op_errno, lock, xdata);
+ return 0;
+}
+
+int32_t
+cluster_inodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ FOP_CBK(inodelk, frame, cookie, op_ret, op_errno, xdata);
+ return 0;
+}
+
+int32_t
+cluster_finodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ FOP_CBK(finodelk, frame, cookie, op_ret, op_errno, xdata);
+ return 0;
+}
+
+int32_t
+cluster_entrylk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ FOP_CBK(entrylk, frame, cookie, op_ret, op_errno, xdata);
+ return 0;
+}
+
+int32_t
+cluster_fentrylk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ FOP_CBK(fentrylk, frame, cookie, op_ret, op_errno, xdata);
+ return 0;
+}
+
+int32_t
+cluster_rchecksum_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, uint32_t weak_checksum,
+ uint8_t *strong_checksum, dict_t *xdata)
+{
+ FOP_CBK(rchecksum, frame, cookie, op_ret, op_errno, weak_checksum,
+ strong_checksum, xdata);
+ return 0;
+}
+
+int32_t
+cluster_readdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
+ dict_t *xdata)
+{
+ FOP_CBK(readdir, frame, cookie, op_ret, op_errno, entries, xdata);
+ return 0;
+}
+
+int32_t
+cluster_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
+ dict_t *xdata)
+{
+ FOP_CBK(readdirp, frame, cookie, op_ret, op_errno, entries, xdata);
+ return 0;
+}
+
+int32_t
+cluster_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata)
+{
+ FOP_CBK(setattr, frame, cookie, op_ret, op_errno, statpre, statpost, xdata);
+ return 0;
+}
+
+int32_t
+cluster_fsetattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata)
+{
+ FOP_CBK(fsetattr, frame, cookie, op_ret, op_errno, statpre, statpost,
+ xdata);
+ return 0;
+}
+
+int32_t
+cluster_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *pre,
+ struct iatt *post, dict_t *xdata)
+{
+ FOP_CBK(fallocate, frame, cookie, op_ret, op_errno, pre, post, xdata);
+ return 0;
+}
+
+int32_t
+cluster_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *pre,
+ struct iatt *post, dict_t *xdata)
+{
+ FOP_CBK(discard, frame, cookie, op_ret, op_errno, pre, post, xdata);
+ return 0;
+}
+
+int32_t
+cluster_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *pre,
+ struct iatt *post, dict_t *xdata)
+{
+ FOP_CBK(zerofill, frame, cookie, op_ret, op_errno, pre, post, xdata);
+ return 0;
+}
+
+int32_t
+cluster_ipc_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ FOP_CBK(ipc, frame, cookie, op_ret, op_errno, xdata);
+ return 0;
+}
+
+int32_t
+cluster_fgetxattr(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd,
+ const char *name, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, fgetxattr, fd,
+ name, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_fsetxattr(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
+ int32_t flags, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, fsetxattr, fd,
+ dict, flags, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_setxattr(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
+ int32_t flags, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, setxattr, loc,
+ dict, flags, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_statfs(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, statfs, loc,
+ xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_fsyncdir(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags,
+ dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, fsyncdir, fd,
+ flags, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_opendir(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
+ dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, opendir, loc,
+ fd, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_fstat(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, fstat, fd,
+ xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_fsync(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags,
+ dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, fsync, fd,
+ flags, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_flush(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, flush, fd,
+ xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_writev(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd,
+ struct iovec *vector, int32_t count, off_t off, uint32_t flags,
+ struct iobref *iobref, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, writev, fd,
+ vector, count, off, flags, iobref, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_put(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ mode_t umask, uint32_t flags, struct iovec *vector, int32_t count,
+ off_t offset, struct iobref *iobref, dict_t *xattr, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, put, loc, mode,
+ umask, flags, vector, count, offset, iobref, xattr, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_readv(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset, uint32_t flags, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, readv, fd, size,
+ offset, flags, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_open(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
+ fd_t *fd, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, open, loc,
+ flags, fd, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_create(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ 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)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, create, loc,
+ flags, mode, umask, fd, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_link(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
+ dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, link, oldloc,
+ newloc, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_rename(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *oldloc,
+ loc_t *newloc, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, rename, oldloc,
+ newloc, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int
+cluster_symlink(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, const char *linkpath,
+ loc_t *loc, mode_t umask, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, symlink,
+ linkpath, loc, umask, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_rmdir(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
+ dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, rmdir, loc,
+ flags, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_unlink(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
+ dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, unlink, loc,
+ xflag, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int
+cluster_mkdir(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ mode_t umask, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, mkdir, loc,
+ mode, umask, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int
+cluster_mknod(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ dev_t rdev, mode_t umask, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, mknod, loc,
+ mode, rdev, umask, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_readlink(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size,
+ dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, readlink, loc,
+ size, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_access(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask,
+ dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, access, loc,
+ mask, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_ftruncate(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, ftruncate, fd,
+ offset, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_getxattr(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc,
+ const char *name, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, getxattr, loc,
+ name, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_xattrop(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc,
+ gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, xattrop, loc,
+ flags, dict, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_fxattrop(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd,
+ gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, fxattrop, fd,
+ flags, dict, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_removexattr(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc,
+ const char *name, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, removexattr,
+ loc, name, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_fremovexattr(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd,
+ const char *name, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, fremovexattr,
+ fd, name, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_lk(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
+ struct gf_flock *lock, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, lk, fd, cmd,
+ lock, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_rchecksum(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ int32_t len, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, rchecksum, fd,
+ offset, len, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_readdir(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t off, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, readdir, fd,
+ size, off, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_readdirp(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t off, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, readdirp, fd,
+ size, off, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_setattr(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc,
+ struct iatt *stbuf, int32_t valid, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, setattr, loc,
+ stbuf, valid, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_truncate(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
+ dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, truncate, loc,
+ offset, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_stat(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, stat, loc,
+ xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_lookup(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, lookup, loc,
+ xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_fsetattr(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd,
+ struct iatt *stbuf, int32_t valid, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, fsetattr, fd,
+ stbuf, valid, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_fallocate(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd,
+ int32_t keep_size, off_t offset, size_t len, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, fallocate, fd,
+ keep_size, offset, len, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_discard(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ size_t len, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, discard, fd,
+ offset, len, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_zerofill(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ off_t len, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, zerofill, fd,
+ offset, len, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int32_t
+cluster_ipc(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, ipc, op, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int
+cluster_uninodelk(xlator_t **subvols, unsigned char *locked_on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, char *dom,
+ inode_t *inode, off_t off, size_t size)
+{
+ loc_t loc = {
+ 0,
+ };
+ struct gf_flock flock = {
+ 0,
+ };
+
+ loc.inode = inode_ref(inode);
+ gf_uuid_copy(loc.gfid, inode->gfid);
+
+ flock.l_type = F_UNLCK;
+ flock.l_start = off;
+ flock.l_len = size;
+
+ FOP_ONLIST(subvols, locked_on, numsubvols, replies, output, frame, inodelk,
+ dom, &loc, F_SETLK, &flock, NULL);
+
+ loc_wipe(&loc);
+
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int
+cluster_tryinodelk(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *locked_on,
+ call_frame_t *frame, xlator_t *this, char *dom,
+ inode_t *inode, off_t off, size_t size)
+{
+ struct gf_flock flock = {
+ 0,
+ };
+ loc_t loc = {0};
+
+ flock.l_type = F_WRLCK;
+ flock.l_start = off;
+ flock.l_len = size;
+
+ loc.inode = inode_ref(inode);
+ gf_uuid_copy(loc.gfid, inode->gfid);
+ FOP_ONLIST(subvols, on, numsubvols, replies, locked_on, frame, inodelk, dom,
+ &loc, F_SETLK, &flock, NULL);
+
+ loc_wipe(&loc);
+ return cluster_fop_success_fill(replies, numsubvols, locked_on);
+}
+
+int
+cluster_inodelk(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *locked_on,
+ call_frame_t *frame, xlator_t *this, char *dom, inode_t *inode,
+ off_t off, size_t size)
+{
+ struct gf_flock flock = {
+ 0,
+ };
+ int i = 0;
+ loc_t loc = {0};
+ unsigned char *output = NULL;
+
+ flock.l_type = F_WRLCK;
+ flock.l_start = off;
+ flock.l_len = size;
+
+ output = alloca(numsubvols);
+ loc.inode = inode_ref(inode);
+ gf_uuid_copy(loc.gfid, inode->gfid);
+ FOP_ONLIST(subvols, on, numsubvols, replies, locked_on, frame, inodelk, dom,
+ &loc, F_SETLK, &flock, NULL);
+
+ for (i = 0; i < numsubvols; i++) {
+ if (replies[i].op_ret == -1 && replies[i].op_errno == EAGAIN) {
+ cluster_fop_success_fill(replies, numsubvols, locked_on);
+ cluster_uninodelk(subvols, locked_on, numsubvols, replies, output,
+ frame, this, dom, inode, off, size);
+
+ FOP_SEQ(subvols, on, numsubvols, replies, locked_on, frame, inodelk,
+ dom, &loc, F_SETLKW, &flock, NULL);
+ break;
+ }
+ }
+
+ loc_wipe(&loc);
+ return cluster_fop_success_fill(replies, numsubvols, locked_on);
+}
+
+int
+cluster_unentrylk(xlator_t **subvols, unsigned char *locked_on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, char *dom,
+ inode_t *inode, const char *name)
+{
+ loc_t loc = {
+ 0,
+ };
+
+ loc.inode = inode_ref(inode);
+ gf_uuid_copy(loc.gfid, inode->gfid);
+
+ FOP_ONLIST(subvols, locked_on, numsubvols, replies, output, frame, entrylk,
+ dom, &loc, name, ENTRYLK_UNLOCK, ENTRYLK_WRLCK, NULL);
+
+ loc_wipe(&loc);
+
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
+
+int
+cluster_tryentrylk(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *locked_on,
+ call_frame_t *frame, xlator_t *this, char *dom,
+ inode_t *inode, const char *name)
+{
+ loc_t loc = {0};
+
+ loc.inode = inode_ref(inode);
+ gf_uuid_copy(loc.gfid, inode->gfid);
+ FOP_ONLIST(subvols, on, numsubvols, replies, locked_on, frame, entrylk, dom,
+ &loc, name, ENTRYLK_LOCK_NB, ENTRYLK_WRLCK, NULL);
+
+ loc_wipe(&loc);
+ return cluster_fop_success_fill(replies, numsubvols, locked_on);
+}
+
+int
+cluster_entrylk(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *locked_on,
+ call_frame_t *frame, xlator_t *this, char *dom, inode_t *inode,
+ const char *name)
+{
+ int i = 0;
+ loc_t loc = {0};
+ unsigned char *output = NULL;
+
+ output = alloca(numsubvols);
+ loc.inode = inode_ref(inode);
+ gf_uuid_copy(loc.gfid, inode->gfid);
+ FOP_ONLIST(subvols, on, numsubvols, replies, locked_on, frame, entrylk, dom,
+ &loc, name, ENTRYLK_LOCK_NB, ENTRYLK_WRLCK, NULL);
+
+ for (i = 0; i < numsubvols; i++) {
+ if (replies[i].op_ret == -1 && replies[i].op_errno == EAGAIN) {
+ cluster_fop_success_fill(replies, numsubvols, locked_on);
+ cluster_unentrylk(subvols, locked_on, numsubvols, replies, output,
+ frame, this, dom, inode, name);
+ FOP_SEQ(subvols, on, numsubvols, replies, locked_on, frame, entrylk,
+ dom, &loc, name, ENTRYLK_LOCK, ENTRYLK_WRLCK, NULL);
+ break;
+ }
+ }
+
+ loc_wipe(&loc);
+ return cluster_fop_success_fill(replies, numsubvols, locked_on);
+}
+
+int
+cluster_tiebreaker_inodelk(xlator_t **subvols, unsigned char *on,
+ int numsubvols, default_args_cbk_t *replies,
+ unsigned char *locked_on, call_frame_t *frame,
+ xlator_t *this, char *dom, inode_t *inode, off_t off,
+ size_t size)
+{
+ struct gf_flock flock = {
+ 0,
+ };
+ int i = 0;
+ int num_success = 0;
+ loc_t loc = {0};
+ unsigned char *output = NULL;
+
+ flock.l_type = F_WRLCK;
+ flock.l_start = off;
+ flock.l_len = size;
+
+ output = alloca(numsubvols);
+ loc.inode = inode_ref(inode);
+ gf_uuid_copy(loc.gfid, inode->gfid);
+ FOP_ONLIST(subvols, on, numsubvols, replies, locked_on, frame, inodelk, dom,
+ &loc, F_SETLK, &flock, NULL);
+
+ for (i = 0; i < numsubvols; i++) {
+ if (replies[i].valid && replies[i].op_ret == 0) {
+ num_success++;
+ continue;
+ }
+
+ /* TODO: If earlier subvols fail with an error other
+ * than EAGAIN, we could still have 2 clients competing
+ * for the lock*/
+ if (replies[i].op_ret == -1 && replies[i].op_errno == EAGAIN) {
+ cluster_fop_success_fill(replies, numsubvols, locked_on);
+ cluster_uninodelk(subvols, locked_on, numsubvols, replies, output,
+ frame, this, dom, inode, off, size);
+
+ if (num_success) {
+ FOP_SEQ(subvols, on, numsubvols, replies, locked_on, frame,
+ inodelk, dom, &loc, F_SETLKW, &flock, NULL);
+ } else {
+ loc_wipe(&loc);
+ memset(locked_on, 0, numsubvols);
+ return 0;
+ }
+ break;
+ }
+ }
+
+ loc_wipe(&loc);
+ return cluster_fop_success_fill(replies, numsubvols, locked_on);
+}
+
+int
+cluster_tiebreaker_entrylk(xlator_t **subvols, unsigned char *on,
+ int numsubvols, default_args_cbk_t *replies,
+ unsigned char *locked_on, call_frame_t *frame,
+ xlator_t *this, char *dom, inode_t *inode,
+ const char *name)
+{
+ int i = 0;
+ loc_t loc = {0};
+ unsigned char *output = NULL;
+ int num_success = 0;
+
+ output = alloca(numsubvols);
+ loc.inode = inode_ref(inode);
+ gf_uuid_copy(loc.gfid, inode->gfid);
+ FOP_ONLIST(subvols, on, numsubvols, replies, locked_on, frame, entrylk, dom,
+ &loc, name, ENTRYLK_LOCK_NB, ENTRYLK_WRLCK, NULL);
+
+ for (i = 0; i < numsubvols; i++) {
+ if (replies[i].valid && replies[i].op_ret == 0) {
+ num_success++;
+ continue;
+ }
+ if (replies[i].op_ret == -1 && replies[i].op_errno == EAGAIN) {
+ cluster_fop_success_fill(replies, numsubvols, locked_on);
+ cluster_unentrylk(subvols, locked_on, numsubvols, replies, output,
+ frame, this, dom, inode, name);
+ if (num_success) {
+ FOP_SEQ(subvols, on, numsubvols, replies, locked_on, frame,
+ entrylk, dom, &loc, name, ENTRYLK_LOCK, ENTRYLK_WRLCK,
+ NULL);
+ } else {
+ loc_wipe(&loc);
+ memset(locked_on, 0, numsubvols);
+ return 0;
+ }
+ break;
+ }
+ }
+
+ loc_wipe(&loc);
+ return cluster_fop_success_fill(replies, numsubvols, locked_on);
+}
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c
index 89c000bcfb6..682cbf28055 100644
--- a/libglusterfs/src/common-utils.c
+++ b/libglusterfs/src/common-utils.c
@@ -1,29 +1,17 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
#ifdef HAVE_BACKTRACE
#include <execinfo.h>
+#else
+#include "execinfo_compat.h"
#endif
#include <stdio.h>
@@ -36,1807 +24,5442 @@
#include <time.h>
#include <locale.h>
#include <sys/socket.h>
-#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
+#include <assert.h>
+#include <libgen.h> /* for dirname() */
+#include <grp.h>
+
+#if defined(GF_BSD_HOST_OS) || defined(GF_DARWIN_HOST_OS)
+#include <sys/sysctl.h>
+#endif
+#ifndef GF_LINUX_HOST_OS
+#include <sys/resource.h>
+#endif
+#ifdef HAVE_SYNCFS_SYS
+#include <sys/syscall.h>
+#endif
-#include "logging.h"
-#include "common-utils.h"
-#include "revision.h"
-#include "glusterfs.h"
-#include "stack.h"
-#include "globals.h"
-#include "md5.h"
+#include "glusterfs/compat-errno.h"
+#include "glusterfs/common-utils.h"
+#include "glusterfs/revision.h"
+#include "glusterfs/glusterfs.h"
+#include "glusterfs/stack.h"
+#include "glusterfs/lkowner.h"
+#include "glusterfs/syscall.h"
+#include "glusterfs/globals.h"
+#define XXH_INLINE_ALL
+#include "xxhash.h"
+#include <ifaddrs.h>
+#include "glusterfs/libglusterfs-messages.h"
+#include "glusterfs/glusterfs-acl.h"
+#ifdef __FreeBSD__
+#include <pthread_np.h>
+#undef BIT_SET
+#endif
+
+#ifndef AI_ADDRCONFIG
+#define AI_ADDRCONFIG 0
+#endif /* AI_ADDRCONFIG */
+
+char *vol_type_str[] = {
+ "Distribute",
+ "Stripe [NOT SUPPORTED from v6.0]",
+ "Replicate",
+ "Striped-Replicate [NOT SUPPORTED from v6.0]",
+ "Disperse",
+ "Tier [NOT SUPPORTED from v6.0]",
+ "Distributed-Stripe [NOT SUPPORTED from v6.0]",
+ "Distributed-Replicate",
+ "Distributed-Striped-Replicate [NOT SUPPORTED from v6.0]",
+ "Distributed-Disperse",
+};
typedef int32_t (*rw_op_t)(int32_t fd, char *buf, int32_t size);
typedef int32_t (*rwv_op_t)(int32_t fd, const struct iovec *buf, int32_t size);
-struct dnscache6 {
- struct addrinfo *first;
- struct addrinfo *next;
-};
+char *xattrs_to_heal[] = {"user.",
+ POSIX_ACL_ACCESS_XATTR,
+ POSIX_ACL_DEFAULT_XATTR,
+ QUOTA_LIMIT_KEY,
+ QUOTA_LIMIT_OBJECTS_KEY,
+ GF_SELINUX_XATTR_KEY,
+ GF_XATTR_MDATA_KEY,
+ NULL};
+void
+gf_xxh64_wrapper(const unsigned char *data, size_t const len,
+ unsigned long long const seed, char *xxh64)
+{
+ unsigned short i = 0;
+ const unsigned short lim = GF_XXH64_DIGEST_LENGTH * 2 + 1;
+ XXH64_hash_t hash = 0;
+ XXH64_canonical_t c_hash = {
+ {
+ 0,
+ },
+ };
+ const uint8_t *p = (const uint8_t *)&c_hash;
+ hash = XXH64(data, len, seed);
+ XXH64_canonicalFromHash(&c_hash, hash);
+
+ for (i = 0; i < GF_XXH64_DIGEST_LENGTH; i++)
+ snprintf(xxh64 + i * 2, lim - i * 2, "%02x", p[i]);
+}
+
+/**
+ * This function takes following arguments
+ * @this: xlator
+ * @gfid: The gfid which has to be filled
+ * @hash: the 8 byte hash which has to be filled inside the gfid
+ * @index: the array element of the uuid_t structure (which is
+ * a array of unsigned char) from where the 8 bytes of
+ * the hash has to be filled. Since uuid_t contains 16
+ * char elements in the array, each byte of the hash has
+ * to be filled in one array element.
+ *
+ * This function is called twice for 2 hashes (of 8 byte each) to
+ * be filled in the gfid.
+ *
+ * The for loop in this function actually is doing these 2 things
+ * for each hash
+ *
+ * 1) One of the hashes
+ * tmp[0] = (hash_2 >> 56) & 0xff;
+ * tmp[1] = (hash_2 >> 48) & 0xff;
+ * tmp[2] = (hash_2 >> 40) & 0xff;
+ * tmp[3] = (hash_2 >> 32) & 0xff;
+ * tmp[4] = (hash_2 >> 24) & 0xff;
+ * tmp[5] = (hash_2 >> 16) & 0xff;
+ * tmp[6] = (hash_2 >> 8) & 0xff;
+ * tmp[7] = (hash_2) & 0xff;
+ *
+ * 2) The other hash:
+ * tmp[8] = (hash_1 >> 56) & 0xff;
+ * tmp[9] = (hash_1 >> 48) & 0xff;
+ * tmp[10] = (hash_1 >> 40) & 0xff;
+ * tmp[11] = (hash_1 >> 32) & 0xff;
+ * tmp[12] = (hash_1 >> 24) & 0xff;
+ * tmp[13] = (hash_1 >> 16) & 0xff;
+ * tmp[14] = (hash_1 >> 8) & 0xff;
+ * tmp[15] = (hash_1) & 0xff;
+ **/
+static int
+gf_gfid_from_xxh64(xlator_t *this, uuid_t gfid, XXH64_hash_t hash,
+ unsigned short index)
+{
+ int ret = -1;
+ int i = -1;
+
+ if ((index != 0) && (index != 8)) {
+ gf_msg_callingfn("gfid-from-xxh64", GF_LOG_WARNING, 0,
+ LG_MSG_INDEX_NOT_FOUND,
+ "index can only be either 0 or 8, as this"
+ "function's purpose is to encode a 8 byte "
+ "hash inside the gfid (index: %d)",
+ index);
+ goto out;
+ }
+
+ for (i = 0; i < sizeof(hash); i++) {
+ /*
+ * As of now the below statement is equivalent of this.
+ * gfid[index+i] = (hash >> (64 - (8 * (i+1)))) & 0xff;
+ */
+ gfid[index + i] = (hash >> ((sizeof(hash) * 8) - (8 * (i + 1)))) &
+ (0xff);
+ }
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+/**
+ * This function does the same thing as gf_xxh64_wrapper. But gf_xxh64_wrapper
+ * does not return anything and in this xlator there is a need for both the
+ * actual hash and the canonicalized form of the hash.
+ *
+ * To summarize:
+ * - XXH64_hash_t is needed as return because, those bytes which contain the
+ * hash can be used for different purposes as needed. One example is
+ * to have those bytes copied into the uuid_t structure to be used as gfid
+ * - xxh64 string is needed because, it can be used as the key for generating
+ * the next hash (and any other purpose which might require canonical form
+ * of the hash).
+ **/
+XXH64_hash_t
+gf_xxh64_hash_wrapper(const unsigned char *data, size_t const len,
+ unsigned long long const seed, char *xxh64)
+{
+ unsigned short i = 0;
+ const unsigned short lim = GF_XXH64_DIGEST_LENGTH * 2 + 1;
+ XXH64_hash_t hash = 0;
+ XXH64_canonical_t c_hash = {
+ {
+ 0,
+ },
+ };
+ const uint8_t *p = (const uint8_t *)&c_hash;
+
+ hash = XXH64(data, len, seed);
+ XXH64_canonicalFromHash(&c_hash, hash);
+
+ for (i = 0; i < GF_XXH64_DIGEST_LENGTH; i++)
+ snprintf(xxh64 + i * 2, lim - i * 2, "%02x", p[i]);
+
+ return hash;
+}
+
+/**
+ * This is the algorithm followed for generating new gfid
+ * 1) generate xxh64 hash using snapname and original gfid of the object
+ * 2) Using the canonicalized form of above hash as the key, generate
+ * another hash
+ * 3) Combine both of the 8 byte hashes to generate a 16 byte uuid_t type
+ * 4) Use the above uuid as the gfid
+ *
+ * Each byte of the hash is stored separately in different elements of the
+ * character array represented by uuid_t
+ * Ex: tmp[0] = (hash_2 >> 56) & 0xFF
+ * This saves the most significant byte of hash_2 in tmp[0]
+ * tmp[1] = (hash_2 >> 48) & 0xFF
+ * This saves next most significant byte of hash_2 in tmp[1]
+ * .
+ * .
+ * So on.
+ * tmp[0] - tmp[7] holds the contents of hash_2
+ * tmp[8] - tmp[15] hold the conents of hash_1
+ *
+ * The hash generated (i.e. of type XXH64_hash_t) is 8 bytes long. And for
+ * gfid 16 byte uuid is needed. Hecne the 2 hashes are combined to form
+ * one 16 byte entity.
+ **/
int
-log_base2 (unsigned long x)
+gf_gfid_generate_from_xxh64(uuid_t gfid, char *key)
{
- int val = 0;
+ char xxh64_1[GF_XXH64_DIGEST_LENGTH * 2 + 1] = {
+ 0,
+ };
+ char xxh64_2[GF_XXH64_DIGEST_LENGTH * 2 + 1] = {
+ 0,
+ };
+ XXH64_hash_t hash_1 = 0;
+ XXH64_hash_t hash_2 = 0;
+ int ret = -1;
+ xlator_t *this = THIS;
+
+ hash_1 = gf_xxh64_hash_wrapper((unsigned char *)key, strlen(key),
+ GF_XXHSUM64_DEFAULT_SEED, xxh64_1);
+
+ hash_2 = gf_xxh64_hash_wrapper((unsigned char *)xxh64_1, strlen(xxh64_1),
+ GF_XXHSUM64_DEFAULT_SEED, xxh64_2);
+
+ /* hash_2 is saved in 1st 8 elements of uuid_t char array */
+ if (gf_gfid_from_xxh64(this, gfid, hash_2, 0)) {
+ gf_msg_callingfn(this->name, GF_LOG_WARNING, 0,
+ LG_MSG_XXH64_TO_GFID_FAILED,
+ "failed to encode the hash %llx into the 1st"
+ "half of gfid",
+ hash_2);
+ goto out;
+ }
+
+ /* hash_1 is saved in the remaining 8 elements of uuid_t */
+ if (gf_gfid_from_xxh64(this, gfid, hash_1, 8)) {
+ gf_msg_callingfn(this->name, GF_LOG_WARNING, 0,
+ LG_MSG_XXH64_TO_GFID_FAILED,
+ "failed to encode the hash %llx into the 2nd"
+ "half of gfid",
+ hash_1);
+ goto out;
+ }
+
+ gf_msg_debug(this->name, 0,
+ "gfid generated is %s (hash1: %llx) "
+ "hash2: %llx, xxh64_1: %s xxh64_2: %s",
+ uuid_utoa(gfid), hash_1, hash_2, xxh64_1, xxh64_2);
+
+ ret = 0;
- while (x > 1) {
- x /= 2;
- val++;
+out:
+ return ret;
+}
+
+/* works similar to mkdir(1) -p.
+ */
+int
+mkdir_p(char *path, mode_t mode, gf_boolean_t allow_symlinks)
+{
+ int i = 0;
+ int ret = -1;
+ char dir[PATH_MAX] = {
+ 0,
+ };
+ struct stat stbuf = {
+ 0,
+ };
+
+ const int path_len = min(strlen(path), PATH_MAX - 1);
+
+ snprintf(dir, path_len + 1, "%s", path);
+
+ i = (dir[0] == '/') ? 1 : 0;
+ do {
+ if (path[i] != '/' && path[i] != '\0')
+ continue;
+
+ dir[i] = '\0';
+ ret = sys_mkdir(dir, mode);
+ if (ret && errno != EEXIST) {
+ gf_smsg("", GF_LOG_ERROR, errno, LG_MSG_DIR_OP_FAILED, NULL);
+ goto out;
}
- return val;
+ if (ret && errno == EEXIST && !allow_symlinks) {
+ ret = sys_lstat(dir, &stbuf);
+ if (ret)
+ goto out;
+
+ if (S_ISLNK(stbuf.st_mode)) {
+ ret = -1;
+ gf_smsg("", GF_LOG_ERROR, 0, LG_MSG_DIR_IS_SYMLINK, "dir=%s",
+ dir, NULL);
+ goto out;
+ }
+ }
+ dir[i] = '/';
+
+ } while (path[i++] != '\0');
+
+ ret = sys_stat(dir, &stbuf);
+ if (ret || !S_ISDIR(stbuf.st_mode)) {
+ if (ret == 0)
+ errno = 0;
+ ret = -1;
+ gf_smsg("", GF_LOG_ERROR, errno, LG_MSG_DIR_OP_FAILED,
+ "possibly some of the components"
+ " were not directories",
+ NULL);
+ goto out;
+ }
+
+ ret = 0;
+out:
+
+ return ret;
+}
+
+int
+gf_lstat_dir(const char *path, struct stat *stbuf_in)
+{
+ int ret = -1;
+ struct stat stbuf = {
+ 0,
+ };
+
+ if (path == NULL) {
+ errno = EINVAL;
+ goto out;
+ }
+
+ ret = sys_lstat(path, &stbuf);
+ if (ret)
+ goto out;
+
+ if (!S_ISDIR(stbuf.st_mode)) {
+ errno = ENOTDIR;
+ ret = -1;
+ goto out;
+ }
+ ret = 0;
+
+out:
+ if (!ret && stbuf_in)
+ *stbuf_in = stbuf;
+
+ return ret;
+}
+
+int
+log_base2(unsigned long x)
+{
+ int val = 0;
+
+ while (x > 1) {
+ x /= 2;
+ val++;
+ }
+
+ return val;
}
+/**
+ * gf_rev_dns_lookup -- Perform a reverse DNS lookup on the IP address.
+ *
+ * @ip: The IP address to perform a reverse lookup on
+ *
+ * @return: success: Allocated string containing the hostname
+ * failure: NULL
+ */
+char *
+gf_rev_dns_lookup(const char *ip)
+{
+ char *fqdn = NULL;
+ int ret = 0;
+
+ GF_VALIDATE_OR_GOTO("resolver", ip, out);
+
+ /* Get the FQDN */
+ ret = gf_get_hostname_from_ip((char *)ip, &fqdn);
+ if (ret != 0) {
+ gf_smsg("resolver", GF_LOG_INFO, errno, LG_MSG_RESOLVE_HOSTNAME_FAILED,
+ "hostname=%s", ip, NULL);
+ }
+out:
+ return fqdn;
+}
+
+/**
+ * gf_resolve_path_parent -- Given a path, returns an allocated string
+ * containing the parent's path.
+ * @path: Path to parse
+ * @return: The parent path if found, NULL otherwise
+ */
+char *
+gf_resolve_path_parent(const char *path)
+{
+ char *parent = NULL;
+ char *tmp = NULL;
+ char *pathc = NULL;
+
+ GF_VALIDATE_OR_GOTO(THIS->name, path, out);
+
+ if (0 == strlen(path)) {
+ gf_msg_callingfn(THIS->name, GF_LOG_DEBUG, 0, LG_MSG_INVALID_STRING,
+ "invalid string for 'path'");
+ goto out;
+ }
+
+ /* dup the parameter, we don't want to modify it */
+ pathc = strdupa(path);
+ if (!pathc) {
+ goto out;
+ }
+
+ /* Get the parent directory */
+ tmp = dirname(pathc);
+ if (strcmp(tmp, "/") == 0)
+ goto out;
+
+ parent = gf_strdup(tmp);
+out:
+ return parent;
+}
int32_t
-gf_resolve_ip6 (const char *hostname,
- uint16_t port,
- int family,
- void **dnscache,
- struct addrinfo **addr_info)
-{
- int32_t ret = 0;
- struct addrinfo hints;
- struct dnscache6 *cache = NULL;
- char service[NI_MAXSERV], host[NI_MAXHOST];
-
- if (!hostname) {
- gf_log_callingfn ("resolver", GF_LOG_WARNING, "hostname is NULL");
- return -1;
+gf_resolve_ip6(const char *hostname, uint16_t port, int family, void **dnscache,
+ struct addrinfo **addr_info)
+{
+ int32_t ret = 0;
+ struct addrinfo hints;
+ struct dnscache6 *cache = NULL;
+ char service[NI_MAXSERV], host[NI_MAXHOST];
+
+ if (!hostname) {
+ gf_msg_callingfn("resolver", GF_LOG_WARNING, 0, LG_MSG_HOSTNAME_NULL,
+ "hostname is NULL");
+ return -1;
+ }
+
+ if (!*dnscache) {
+ *dnscache = GF_CALLOC(1, sizeof(struct dnscache6),
+ gf_common_mt_dnscache6);
+ if (!*dnscache)
+ return -1;
+ }
+
+ cache = *dnscache;
+ if (cache->first && !cache->next) {
+ freeaddrinfo(cache->first);
+ cache->first = cache->next = NULL;
+ gf_msg_trace("resolver", 0, "flushing DNS cache");
+ }
+
+ if (!cache->first) {
+ char *port_str = NULL;
+ gf_msg_trace("resolver", 0,
+ "DNS cache not present, freshly "
+ "probing hostname: %s",
+ hostname);
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = family;
+ hints.ai_socktype = SOCK_STREAM;
+
+ ret = gf_asprintf(&port_str, "%d", port);
+ if (-1 == ret) {
+ return -1;
}
-
- if (!*dnscache) {
- *dnscache = GF_CALLOC (1, sizeof (struct dnscache6),
- gf_common_mt_dnscache6);
- if (!*dnscache)
- return -1;
+ if ((ret = getaddrinfo(hostname, port_str, &hints, &cache->first)) !=
+ 0) {
+ gf_smsg("resolver", GF_LOG_ERROR, 0, LG_MSG_GETADDRINFO_FAILED,
+ "family=%d", family, "ret=%s", gai_strerror(ret), NULL);
+
+ GF_FREE(*dnscache);
+ *dnscache = NULL;
+ GF_FREE(port_str);
+ return -1;
}
-
- cache = *dnscache;
- if (cache->first && !cache->next) {
- freeaddrinfo(cache->first);
- cache->first = cache->next = NULL;
- gf_log ("resolver", GF_LOG_TRACE,
- "flushing DNS cache");
+ GF_FREE(port_str);
+
+ cache->next = cache->first;
+ }
+
+ if (cache->next) {
+ ret = getnameinfo((struct sockaddr *)cache->next->ai_addr,
+ cache->next->ai_addrlen, host, sizeof(host), service,
+ sizeof(service), NI_NUMERICHOST);
+ if (ret != 0) {
+ gf_smsg("resolver", GF_LOG_ERROR, 0, LG_MSG_GETNAMEINFO_FAILED,
+ "ret=%s", gai_strerror(ret), NULL);
+ goto err;
}
- if (!cache->first) {
- char *port_str = NULL;
- gf_log ("resolver", GF_LOG_TRACE,
- "DNS cache not present, freshly probing hostname: %s",
- hostname);
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = family;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_flags = AI_ADDRCONFIG;
-
- ret = gf_asprintf (&port_str, "%d", port);
- if (-1 == ret) {
- gf_log ("resolver", GF_LOG_ERROR, "asprintf failed");
- return -1;
- }
- if ((ret = getaddrinfo(hostname, port_str, &hints, &cache->first)) != 0) {
- gf_log ("resolver", GF_LOG_ERROR,
- "getaddrinfo failed (%s)", gai_strerror (ret));
-
- GF_FREE (*dnscache);
- *dnscache = NULL;
- GF_FREE (port_str);
- return -1;
- }
- GF_FREE (port_str);
-
- cache->next = cache->first;
+ gf_msg_debug("resolver", 0,
+ "returning ip-%s (port-%s) for "
+ "hostname: %s and port: %d",
+ host, service, hostname, port);
+
+ *addr_info = cache->next;
+ }
+
+ if (cache->next)
+ cache->next = cache->next->ai_next;
+ if (cache->next) {
+ ret = getnameinfo((struct sockaddr *)cache->next->ai_addr,
+ cache->next->ai_addrlen, host, sizeof(host), service,
+ sizeof(service), NI_NUMERICHOST);
+ if (ret != 0) {
+ gf_smsg("resolver", GF_LOG_ERROR, 0, LG_MSG_GETNAMEINFO_FAILED,
+ "ret=%s", gai_strerror(ret), NULL);
+ goto err;
}
- if (cache->next) {
- ret = getnameinfo((struct sockaddr *)cache->next->ai_addr,
- cache->next->ai_addrlen,
- host, sizeof (host),
- service, sizeof (service),
- NI_NUMERICHOST);
- if (ret != 0) {
- gf_log ("resolver", GF_LOG_ERROR,
- "getnameinfo failed (%s)", gai_strerror (ret));
- goto err;
- }
-
- gf_log ("resolver", GF_LOG_DEBUG,
- "returning ip-%s (port-%s) for hostname: %s and port: %d",
- host, service, hostname, port);
-
- *addr_info = cache->next;
+ gf_msg_debug("resolver", 0,
+ "next DNS query will return: "
+ "ip-%s port-%s",
+ host, service);
+ }
+
+ return 0;
+
+err:
+ freeaddrinfo(cache->first);
+ cache->first = cache->next = NULL;
+ GF_FREE(cache);
+ *dnscache = NULL;
+ return -1;
+}
+
+/**
+ * gf_dnscache_init -- Initializes a dnscache struct and sets the ttl
+ * to the specified value in the parameter.
+ *
+ * @ttl: the TTL in seconds
+ * @return: SUCCESS: Pointer to an allocated dnscache struct
+ * FAILURE: NULL
+ */
+struct dnscache *
+gf_dnscache_init(time_t ttl)
+{
+ struct dnscache *cache = GF_MALLOC(sizeof(*cache), gf_common_mt_dnscache);
+ if (!cache)
+ return NULL;
+
+ cache->cache_dict = dict_new();
+ if (!cache->cache_dict) {
+ GF_FREE(cache);
+ cache = NULL;
+ } else {
+ cache->ttl = ttl;
+ }
+
+ return cache;
+}
+
+/**
+ * gf_dnscache_deinit -- cleanup resources used by struct dnscache
+ */
+void
+gf_dnscache_deinit(struct dnscache *cache)
+{
+ if (!cache) {
+ gf_msg_plain(GF_LOG_WARNING, "dnscache is NULL");
+ return;
+ }
+ dict_unref(cache->cache_dict);
+ GF_FREE(cache);
+}
+
+/**
+ * gf_dnscache_entry_init -- Initialize a dnscache entry
+ *
+ * @return: SUCCESS: Pointer to an allocated dnscache entry struct
+ * FAILURE: NULL
+ */
+struct dnscache_entry *
+gf_dnscache_entry_init()
+{
+ struct dnscache_entry *entry = GF_CALLOC(1, sizeof(*entry),
+ gf_common_mt_dnscache_entry);
+ return entry;
+}
+
+/**
+ * gf_dnscache_entry_deinit -- Free memory used by a dnscache entry
+ *
+ * @entry: Pointer to deallocate
+ */
+void
+gf_dnscache_entry_deinit(struct dnscache_entry *entry)
+{
+ GF_FREE(entry->ip);
+ GF_FREE(entry->fqdn);
+ GF_FREE(entry);
+}
+
+/**
+ * gf_rev_dns_lookup -- Perform a reverse DNS lookup on the IP address.
+ *
+ * @ip: The IP address to perform a reverse lookup on
+ *
+ * @return: success: Allocated string containing the hostname
+ * failure: NULL
+ */
+char *
+gf_rev_dns_lookup_cached(const char *ip, struct dnscache *dnscache)
+{
+ char *fqdn = NULL;
+ int ret = 0;
+ dict_t *cache = NULL;
+ data_t *entrydata = NULL;
+ struct dnscache_entry *dnsentry = NULL;
+ gf_boolean_t from_cache = _gf_false;
+
+ if (!dnscache)
+ goto out;
+
+ cache = dnscache->cache_dict;
+
+ /* Quick cache lookup to see if we already hold it */
+ entrydata = dict_get(cache, (char *)ip);
+ if (entrydata) {
+ dnsentry = (struct dnscache_entry *)entrydata->data;
+ /* First check the TTL & timestamp */
+ if (gf_time() - dnsentry->timestamp > dnscache->ttl) {
+ gf_dnscache_entry_deinit(dnsentry);
+ entrydata->data = NULL; /* Mark this as 'null' so
+ * dict_del () doesn't try free
+ * this after we've already
+ * freed it.
+ */
+
+ dict_del(cache, (char *)ip); /* Remove this entry */
+ } else {
+ /* Cache entry is valid, get the FQDN and return */
+ fqdn = dnsentry->fqdn;
+ from_cache = _gf_true; /* Mark this as from cache */
+ goto out;
}
+ }
+
+ /* Get the FQDN */
+ ret = gf_get_hostname_from_ip((char *)ip, &fqdn);
+ if (ret != 0)
+ goto out;
+
+ if (!fqdn) {
+ gf_log_callingfn("resolver", GF_LOG_CRITICAL,
+ "Allocation failed for the host address");
+ goto out;
+ }
- if (cache->next)
- cache->next = cache->next->ai_next;
- if (cache->next) {
- ret = getnameinfo((struct sockaddr *)cache->next->ai_addr,
- cache->next->ai_addrlen,
- host, sizeof (host),
- service, sizeof (service),
- NI_NUMERICHOST);
- if (ret != 0) {
- gf_log ("resolver", GF_LOG_ERROR,
- "getnameinfo failed (%s)", gai_strerror (ret));
- goto err;
- }
-
- gf_log ("resolver", GF_LOG_DEBUG,
- "next DNS query will return: ip-%s port-%s", host, service);
+ from_cache = _gf_false;
+out:
+ /* Insert into the cache */
+ if (fqdn && !from_cache && ip) {
+ struct dnscache_entry *entry = gf_dnscache_entry_init();
+
+ if (entry) {
+ entry->fqdn = fqdn;
+ entry->ip = gf_strdup(ip);
+ entry->timestamp = gf_time();
+ entrydata = bin_to_data(entry, sizeof(*entry));
+ dict_set(cache, (char *)ip, entrydata);
}
+ }
+ return fqdn;
+}
- return 0;
+struct xldump {
+ int lineno;
+};
-err:
- freeaddrinfo (cache->first);
- cache->first = cache->next = NULL;
- GF_FREE (cache);
- *dnscache = NULL;
- return -1;
+/* to catch any format discrepencies that may arise in code */
+static int
+nprintf(struct xldump *dump, const char *fmt, ...)
+ __attribute__((__format__(__printf__, 2, 3)));
+static int
+nprintf(struct xldump *dump, const char *fmt, ...)
+{
+ va_list ap;
+ char *msg = NULL;
+ char header[32];
+ int ret = 0;
+
+ ret = snprintf(header, 32, "%3d:", ++dump->lineno);
+ if (ret < 0)
+ goto out;
+
+ va_start(ap, fmt);
+ ret = vasprintf(&msg, fmt, ap);
+ va_end(ap);
+ if (-1 == ret)
+ goto out;
+
+ /* NOTE: No ret value from gf_msg_plain, so unable to compute printed
+ * characters. The return value from nprintf is not used, so for now
+ * living with it */
+ gf_msg_plain(GF_LOG_WARNING, "%s %s", header, msg);
+
+out:
+ FREE(msg);
+ return 0;
+}
+
+static int
+xldump_options(dict_t *this, char *key, data_t *value, void *d)
+{
+ nprintf(d, " option %s %s", key, value->data);
+ return 0;
+}
+
+static void
+xldump_subvolumes(xlator_t *this, void *d)
+{
+ xlator_list_t *subv = NULL;
+ int len = 0;
+ char *subvstr = NULL;
+
+ if (!this->children)
+ return;
+
+ for (subv = this->children; subv; subv = subv->next)
+ len += (strlen(subv->xlator->name) + 1);
+
+ subvstr = GF_MALLOC(len, gf_common_mt_strdup);
+
+ len = 0;
+ for (subv = this->children; subv; subv = subv->next)
+ len += sprintf(subvstr + len, "%s%s", subv->xlator->name,
+ subv->next ? " " : "");
+
+ nprintf(d, " subvolumes %s", subvstr);
+
+ GF_FREE(subvstr);
}
+static void
+xldump(xlator_t *each, void *d)
+{
+ nprintf(d, "volume %s", each->name);
+ nprintf(d, " type %s", each->type);
+ dict_foreach(each->options, xldump_options, d);
+
+ xldump_subvolumes(each, d);
+
+ nprintf(d, "end-volume");
+ nprintf(d, " ");
+}
void
-gf_log_volume_file (FILE *specfp)
+gf_log_dump_graph(FILE *specfp, glusterfs_graph_t *graph)
{
- extern FILE *gf_log_logfile;
- int lcount = 0;
- char data[GF_UNIT_KB];
+ struct xldump xld = {
+ 0,
+ };
- fseek (specfp, 0L, SEEK_SET);
+ gf_msg_plain(GF_LOG_WARNING, "Final graph:");
+ gf_msg_plain(GF_LOG_WARNING,
+ "+---------------------------------------"
+ "---------------------------------------+");
+
+ xlator_foreach_depth_first(graph->top, xldump, &xld);
- fprintf (gf_log_logfile, "Given volfile:\n");
- fprintf (gf_log_logfile,
+ gf_msg_plain(GF_LOG_WARNING,
"+---------------------------------------"
- "---------------------------------------+\n");
- while (fgets (data, GF_UNIT_KB, specfp) != NULL){
- lcount++;
- fprintf (gf_log_logfile, "%3d: %s", lcount, data);
- }
- fprintf (gf_log_logfile,
- "\n+---------------------------------------"
- "---------------------------------------+\n");
- fflush (gf_log_logfile);
- fseek (specfp, 0L, SEEK_SET);
+ "---------------------------------------+");
}
static void
-gf_dump_config_flags (int fd)
+gf_dump_config_flags()
{
- int ret = 0;
-
- ret = write (fd, "configuration details:\n", 23);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem(GF_LOG_ALERT, "configuration details:");
/* have argp */
#ifdef HAVE_ARGP
- ret = write (fd, "argp 1\n", 7);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem(GF_LOG_ALERT, "argp 1");
#endif
/* ifdef if found backtrace */
#ifdef HAVE_BACKTRACE
- ret = write (fd, "backtrace 1\n", 12);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem(GF_LOG_ALERT, "backtrace 1");
#endif
/* Berkeley-DB version has cursor->get() */
#ifdef HAVE_BDB_CURSOR_GET
- ret = write (fd, "bdb->cursor->get 1\n", 19);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem(GF_LOG_ALERT, "bdb->cursor->get 1");
#endif
/* Define to 1 if you have the <db.h> header file. */
#ifdef HAVE_DB_H
- ret = write (fd, "db.h 1\n", 7);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem(GF_LOG_ALERT, "db.h 1");
#endif
/* Define to 1 if you have the <dlfcn.h> header file. */
#ifdef HAVE_DLFCN_H
- ret = write (fd, "dlfcn 1\n", 8);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem(GF_LOG_ALERT, "dlfcn 1");
#endif
/* define if fdatasync exists */
#ifdef HAVE_FDATASYNC
- ret = write (fd, "fdatasync 1\n", 12);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem(GF_LOG_ALERT, "fdatasync 1");
#endif
/* Define to 1 if you have the `pthread' library (-lpthread). */
#ifdef HAVE_LIBPTHREAD
- ret = write (fd, "libpthread 1\n", 13);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem(GF_LOG_ALERT, "libpthread 1");
#endif
/* define if llistxattr exists */
#ifdef HAVE_LLISTXATTR
- ret = write (fd, "llistxattr 1\n", 13);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem(GF_LOG_ALERT, "llistxattr 1");
#endif
/* define if found setfsuid setfsgid */
#ifdef HAVE_SET_FSID
- ret = write (fd, "setfsid 1\n", 10);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem(GF_LOG_ALERT, "setfsid 1");
#endif
/* define if found spinlock */
#ifdef HAVE_SPINLOCK
- ret = write (fd, "spinlock 1\n", 11);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem(GF_LOG_ALERT, "spinlock 1");
#endif
/* Define to 1 if you have the <sys/epoll.h> header file. */
#ifdef HAVE_SYS_EPOLL_H
- ret = write (fd, "epoll.h 1\n", 10);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem(GF_LOG_ALERT, "epoll.h 1");
#endif
/* Define to 1 if you have the <sys/extattr.h> header file. */
#ifdef HAVE_SYS_EXTATTR_H
- ret = write (fd, "extattr.h 1\n", 12);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem(GF_LOG_ALERT, "extattr.h 1");
#endif
/* Define to 1 if you have the <sys/xattr.h> header file. */
#ifdef HAVE_SYS_XATTR_H
- ret = write (fd, "xattr.h 1\n", 10);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem(GF_LOG_ALERT, "xattr.h 1");
#endif
/* define if found st_atim.tv_nsec */
#ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
- ret = write (fd, "st_atim.tv_nsec 1\n", 18);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem(GF_LOG_ALERT, "st_atim.tv_nsec 1");
#endif
/* define if found st_atimespec.tv_nsec */
#ifdef HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC
- ret = write (fd, "st_atimespec.tv_nsec 1\n",23);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem(GF_LOG_ALERT, "st_atimespec.tv_nsec 1");
#endif
/* Define to the full name and version of this package. */
#ifdef PACKAGE_STRING
- {
- char msg[128];
- sprintf (msg, "package-string: %s\n", PACKAGE_STRING);
- ret = write (fd, msg, strlen (msg));
- if (ret == -1)
- goto out;
+ {
+ char *msg = NULL;
+ int ret = -1;
+
+ ret = gf_asprintf(&msg, "package-string: %s", PACKAGE_STRING);
+ if (ret >= 0) {
+ gf_msg_plain_nomem(GF_LOG_ALERT, msg);
+ GF_FREE(msg);
}
+ }
#endif
-out:
- return;
+ return;
}
-/* Obtain a backtrace and print it to stdout. */
-/* TODO: It looks like backtrace_symbols allocates memory,
- it may be problem because mostly memory allocation/free causes 'sigsegv' */
+/* Obtain a backtrace and print it to the log */
void
-gf_print_trace (int32_t signum)
+gf_print_trace(int32_t signum, glusterfs_ctx_t *ctx)
{
- extern FILE *gf_log_logfile;
- struct tm *tm = NULL;
- char msg[1024] = {0,};
- char timestr[256] = {0,};
- time_t utime = 0;
- int ret = 0;
- int fd = 0;
-
- fd = fileno (gf_log_logfile);
-
- /* Pending frames, (if any), list them in order */
- ret = write (fd, "pending frames:\n", 16);
+ char msg[1024] = {
+ 0,
+ };
+ char timestr[GF_TIMESTR_SIZE] = {
+ 0,
+ };
+ call_stack_t *stack = NULL;
+
+ /* Now every gf_log call will just write to a buffer and when the
+ * buffer becomes full, its written to the log-file. Suppose the process
+ * crashes and prints the backtrace in the log-file, then the previous
+ * log information will still be in the buffer itself. So flush the
+ * contents of the buffer to the log file before printing the backtrace
+ * which helps in debugging.
+ */
+ gf_log_flush();
+
+ gf_log_disable_suppression_before_exit(ctx);
+
+ /* Pending frames, (if any), list them in order */
+ gf_msg_plain_nomem(GF_LOG_ALERT, "pending frames:");
+ {
+ /* FIXME: traversing stacks outside pool->lock */
+ list_for_each_entry(stack, &ctx->pool->all_frames, all_frames)
{
- glusterfs_ctx_t *ctx = glusterfs_ctx_get ();
- struct list_head *trav = ((call_pool_t *)ctx->pool)->all_frames.next;
- while (trav != (&((call_pool_t *)ctx->pool)->all_frames)) {
- call_frame_t *tmp = (call_frame_t *)(&((call_stack_t *)trav)->frames);
- if (tmp->root->type == GF_OP_TYPE_FOP)
- sprintf (msg,"frame : type(%d) op(%s)\n",
- tmp->root->type,
- gf_fop_list[tmp->root->op]);
- if (tmp->root->type == GF_OP_TYPE_MGMT)
- sprintf (msg,"frame : type(%d) op(%s)\n",
- tmp->root->type,
- gf_mgmt_list[tmp->root->op]);
-
- ret = write (fd, msg, strlen (msg));
- trav = trav->next;
- }
- ret = write (fd, "\n", 1);
+ if (stack->type == GF_OP_TYPE_FOP)
+ sprintf(msg, "frame : type(%d) op(%s)", stack->type,
+ gf_fop_list[stack->op]);
+ else
+ sprintf(msg, "frame : type(%d) op(%d)", stack->type, stack->op);
+
+ gf_msg_plain_nomem(GF_LOG_ALERT, msg);
}
+ }
+
+ sprintf(msg, "patchset: %s", GLUSTERFS_REPOSITORY_REVISION);
+ gf_msg_plain_nomem(GF_LOG_ALERT, msg);
+
+ sprintf(msg, "signal received: %d", signum);
+ gf_msg_plain_nomem(GF_LOG_ALERT, msg);
+ {
+ /* Dump the timestamp of the crash too, so the previous logs
+ can be related */
+ gf_time_fmt(timestr, sizeof timestr, gf_time(), gf_timefmt_FT);
+ gf_msg_plain_nomem(GF_LOG_ALERT, "time of crash: ");
+ gf_msg_plain_nomem(GF_LOG_ALERT, timestr);
+ }
+
+ gf_dump_config_flags();
+ gf_msg_backtrace_nomem(GF_LOG_ALERT, 200);
+ sprintf(msg, "---------");
+ gf_msg_plain_nomem(GF_LOG_ALERT, msg);
+
+ /* Send a signal to terminate the process */
+ signal(signum, SIG_DFL);
+ raise(signum);
+}
+
+void
+trap(void)
+{
+}
- sprintf (msg, "patchset: %s\n", GLUSTERFS_REPOSITORY_REVISION);
- ret = write (fd, msg, strlen (msg));
+char *
+gf_trim(char *string)
+{
+ register char *s, *t;
- sprintf (msg, "signal received: %d\n", signum);
- ret = write (fd, msg, strlen (msg));
+ if (string == NULL) {
+ return NULL;
+ }
- {
- /* Dump the timestamp of the crash too, so the previous logs
- can be related */
- utime = time (NULL);
- tm = localtime (&utime);
- strftime (timestr, 256, "%Y-%m-%d %H:%M:%S\n", tm);
- ret = write (fd, "time of crash: ", 15);
- ret = write (fd, timestr, strlen (timestr));
- }
+ for (s = string; isspace(*s); s++)
+ ;
- gf_dump_config_flags (fd);
-#if HAVE_BACKTRACE
- /* Print 'backtrace' */
- {
- void *array[200];
- size_t size;
+ if (*s == 0)
+ return s;
- size = backtrace (array, 200);
- backtrace_symbols_fd (&array[1], size-1, fd);
- sprintf (msg, "---------\n");
- ret = write (fd, msg, strlen (msg));
- }
-#endif /* HAVE_BACKTRACE */
+ t = s + strlen(s) - 1;
+ while (t > s && isspace(*t))
+ t--;
+ *++t = '\0';
- /* Send a signal to terminate the process */
- signal (signum, SIG_DFL);
- raise (signum);
+ return s;
}
-void
-trap (void)
+int
+gf_strstr(const char *str, const char *delim, const char *match)
{
+ char *tmp = NULL;
+ char *save_ptr = NULL;
+ char *tmp_str = NULL;
-}
+ int ret = 0;
-char *
-gf_trim (char *string)
-{
- register char *s, *t;
+ tmp_str = strdup(str);
- if (string == NULL)
- {
- return NULL;
- }
+ if (str == NULL || delim == NULL || match == NULL || tmp_str == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "argument invalid");
+ ret = -1;
+ goto out;
+ }
- for (s = string; isspace (*s); s++)
- ;
+ tmp = strtok_r(tmp_str, delim, &save_ptr);
- if (*s == 0)
- return s;
+ while (tmp) {
+ ret = strcmp(tmp, match);
- t = s + strlen (s) - 1;
- while (t > s && isspace (*t))
- t--;
- *++t = '\0';
+ if (ret == 0)
+ break;
- return s;
+ tmp = strtok_r(NULL, delim, &save_ptr);
+ }
+
+out:
+ free(tmp_str);
+
+ return ret;
}
int
-gf_strsplit (const char *str, const char *delim,
- char ***tokens, int *token_count)
+gf_volume_name_validate(const char *volume_name)
{
- char *_running = NULL;
- char *running = NULL;
- char *token = NULL;
- char **token_list = NULL;
- int count = 0;
- int i = 0;
- int j = 0;
+ const char *vname = NULL;
- if (str == NULL || delim == NULL || tokens == NULL || token_count == NULL) {
- gf_log_callingfn ("", GF_LOG_WARNING, "arguement invalid");
- return -1;
- }
+ if (volume_name == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "argument invalid");
+ return -1;
+ }
- _running = gf_strdup (str);
- if (_running == NULL)
- {
- return -1;
- }
- running = _running;
+ if (!isalpha(volume_name[0]))
+ return 1;
- while ((token = strsep (&running, delim)) != NULL)
- {
- if (token[0] != '\0')
- count++;
- }
- GF_FREE (_running);
+ for (vname = &volume_name[1]; *vname != '\0'; vname++) {
+ if (!(isalnum(*vname) || *vname == '_'))
+ return 1;
+ }
- _running = gf_strdup (str);
- if (_running == NULL)
- {
- return -1;
- }
- running = _running;
+ return 0;
+}
- if ((token_list = GF_CALLOC (count, sizeof (char *),
- gf_common_mt_char)) == NULL)
- {
- GF_FREE (_running);
- return -1;
- }
+int
+gf_string2time(const char *str, uint32_t *n)
+{
+ unsigned long value = 0;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
+
+ if (str == NULL || n == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
+
+ for (s = str; *s != '\0'; s++) {
+ if (isspace(*s))
+ continue;
+ if (*s == '-')
+ return -1;
+ break;
+ }
+
+ old_errno = errno;
+ errno = 0;
+ value = strtol(str, &tail, 0);
+ if (str == tail)
+ errno = EINVAL;
+
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- while ((token = strsep (&running, delim)) != NULL)
- {
- if (token[0] == '\0')
- continue;
+ if (errno == 0)
+ errno = old_errno;
+
+ if (((tail[0] == '\0') || ((tail[0] == 's') && (tail[1] == '\0')) ||
+ ((tail[0] == 's') && (tail[1] == 'e') && (tail[2] == 'c') &&
+ (tail[3] == '\0'))))
+ goto out;
+
+ else if (((tail[0] == 'm') && (tail[1] == '\0')) ||
+ ((tail[0] == 'm') && (tail[1] == 'i') && (tail[2] == 'n') &&
+ (tail[3] == '\0'))) {
+ value = value * GF_MINUTE_IN_SECONDS;
+ goto out;
+ }
+
+ else if (((tail[0] == 'h') && (tail[1] == '\0')) ||
+ ((tail[0] == 'h') && (tail[1] == 'r') && (tail[2] == '\0'))) {
+ value = value * GF_HOUR_IN_SECONDS;
+ goto out;
+ }
+
+ else if (((tail[0] == 'd') && (tail[1] == '\0')) ||
+ ((tail[0] == 'd') && (tail[1] == 'a') && (tail[2] == 'y') &&
+ (tail[3] == 's') && (tail[4] == '\0'))) {
+ value = value * GF_DAY_IN_SECONDS;
+ goto out;
+ }
+
+ else if (((tail[0] == 'w') && (tail[1] == '\0')) ||
+ ((tail[0] == 'w') && (tail[1] == 'k') && (tail[2] == '\0'))) {
+ value = value * GF_WEEK_IN_SECONDS;
+ goto out;
+ } else {
+ return -1;
+ }
- token_list[i] = gf_strdup (token);
- if (token_list[i] == NULL)
- goto free_exit;
- i++;
- }
+out:
+ *n = value;
- GF_FREE (_running);
+ return 0;
+}
- *tokens = token_list;
- *token_count = count;
- return 0;
+int
+gf_string2percent(const char *str, double *n)
+{
+ double value = 0;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
+
+ if (str == NULL || n == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
+
+ for (s = str; *s != '\0'; s++) {
+ if (isspace(*s))
+ continue;
+ if (*s == '-')
+ return -1;
+ break;
+ }
+
+ old_errno = errno;
+ errno = 0;
+ value = strtod(str, &tail);
+ if (str == tail)
+ errno = EINVAL;
+
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
-free_exit:
- GF_FREE (_running);
- for (j = 0; j < i; j++)
- {
- GF_FREE (token_list[j]);
- }
- GF_FREE (token_list);
+ if (errno == 0)
+ errno = old_errno;
+
+ if (!((tail[0] == '\0') || ((tail[0] == '%') && (tail[1] == '\0'))))
return -1;
+
+ *n = value;
+
+ return 0;
}
-int
-gf_strstr (const char *str, const char *delim, const char *match)
+static int
+_gf_string2long(const char *str, long *n, int base)
{
- char *tmp = NULL;
- char *save_ptr = NULL;
- char *tmp_str = NULL;
+ long value = 0;
+ char *tail = NULL;
+ int old_errno = 0;
+
+ if (str == NULL || n == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
- int ret = 0;
+ old_errno = errno;
+ errno = 0;
+ value = strtol(str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
- tmp_str = strdup (str);
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- if (str == NULL || delim == NULL || match == NULL || tmp_str == NULL) {
- gf_log_callingfn ("", GF_LOG_WARNING, "arguement invalid");
- ret = -1;
- goto out;
- }
+ if (errno == 0)
+ errno = old_errno;
+ if (tail[0] != '\0')
+ return -1;
- tmp = strtok_r (tmp_str, delim, &save_ptr);
+ *n = value;
- while (tmp) {
- ret = strcmp (tmp, match);
+ return 0;
+}
- if (ret == 0)
- break;
+static int
+_gf_string2ulong(const char *str, unsigned long *n, int base)
+{
+ unsigned long value = 0;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
+
+ if (str == NULL || n == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
+
+ for (s = str; *s != '\0'; s++) {
+ if (isspace(*s))
+ continue;
+ if (*s == '-')
+ return -1;
+ break;
+ }
+
+ old_errno = errno;
+ errno = 0;
+ value = strtoul(str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
+
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- tmp = strtok_r (NULL, delim, &save_ptr);
- }
+ if (errno == 0)
+ errno = old_errno;
-out:
- if (tmp_str)
- free (tmp_str);
+ if (tail[0] != '\0')
+ return -1;
- return ret;
+ *n = value;
+ return 0;
}
-int
-gf_volume_name_validate (const char *volume_name)
+static int
+_gf_string2uint(const char *str, unsigned int *n, int base)
{
- const char *vname = NULL;
+ unsigned long value = 0;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
+
+ if (str == NULL || n == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
+
+ for (s = str; *s != '\0'; s++) {
+ if (isspace(*s))
+ continue;
+ if (*s == '-')
+ return -1;
+ break;
+ }
+
+ old_errno = errno;
+ errno = 0;
+ value = strtoul(str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
+
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- if (volume_name == NULL) {
- gf_log_callingfn ("", GF_LOG_WARNING, "arguement invalid");
- return -1;
- }
+ if (errno == 0)
+ errno = old_errno;
- if (!isalpha (volume_name[0]))
- {
- return 1;
- }
+ if (tail[0] != '\0')
+ return -1;
- for (vname = &volume_name[1]; *vname != '\0'; vname++)
- {
- if (!(isalnum (*vname) || *vname == '_'))
- return 1;
- }
+ *n = (unsigned int)value;
- return 0;
+ return 0;
}
+static int
+_gf_string2double(const char *str, double *n)
+{
+ double value = 0.0;
+ char *tail = NULL;
+ int old_errno = 0;
+
+ if (str == NULL || n == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
+
+ old_errno = errno;
+ errno = 0;
+ value = strtod(str, &tail);
+ if (str == tail)
+ errno = EINVAL;
-int
-gf_string2time (const char *str, uint32_t *n)
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
+
+ if (errno == 0)
+ errno = old_errno;
+
+ if (tail[0] != '\0')
+ return -1;
+
+ *n = value;
+
+ return 0;
+}
+
+static int
+_gf_string2longlong(const char *str, long long *n, int base)
{
- unsigned long value = 0;
- char *tail = NULL;
- int old_errno = 0;
- const char *s = NULL;
+ long long value = 0;
+ char *tail = NULL;
+ int old_errno = 0;
+
+ if (str == NULL || n == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
- if (str == NULL || n == NULL)
- {
- gf_log_callingfn ("", GF_LOG_WARNING, "arguement invalid");
- errno = EINVAL;
- return -1;
- }
+ old_errno = errno;
+ errno = 0;
+ value = strtoll(str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
- for (s = str; *s != '\0'; s++)
- {
- if (isspace (*s))
- {
- continue;
- }
- if (*s == '-')
- {
- return -1;
- }
- break;
- }
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- old_errno = errno;
- errno = 0;
- value = strtol (str, &tail, 0);
+ if (errno == 0)
+ errno = old_errno;
- if (errno == ERANGE || errno == EINVAL)
- {
- return -1;
- }
+ if (tail[0] != '\0')
+ return -1;
- if (errno == 0)
- {
- errno = old_errno;
- }
+ *n = value;
- if (!((tail[0] == '\0') ||
- ((tail[0] == 's') && (tail[1] == '\0')) ||
- ((tail[0] == 's') && (tail[1] == 'e') && (tail[2] == 'c') && (tail[3] == '\0'))))
- {
- return -1;
- }
+ return 0;
+}
- *n = value;
+static int
+_gf_string2ulonglong(const char *str, unsigned long long *n, int base)
+{
+ unsigned long long value = 0;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
+
+ if (str == NULL || n == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
+
+ for (s = str; *s != '\0'; s++) {
+ if (isspace(*s))
+ continue;
+ if (*s == '-')
+ return -1;
+ break;
+ }
+
+ old_errno = errno;
+ errno = 0;
+ value = strtoull(str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
+
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- return 0;
+ if (errno == 0)
+ errno = old_errno;
+
+ if (tail[0] != '\0')
+ return -1;
+
+ *n = value;
+
+ return 0;
}
+int
+gf_string2long(const char *str, long *n)
+{
+ return _gf_string2long(str, n, 0);
+}
int
-gf_string2percent (const char *str, uint32_t *n)
+gf_string2ulong(const char *str, unsigned long *n)
{
- unsigned long value = 0;
- char *tail = NULL;
- int old_errno = 0;
- const char *s = NULL;
+ return _gf_string2ulong(str, n, 0);
+}
- if (str == NULL || n == NULL)
- {
- gf_log_callingfn ("", GF_LOG_WARNING, "arguement invalid");
- errno = EINVAL;
- return -1;
- }
+int
+gf_string2int(const char *str, int *n)
+{
+ long l = 0;
+ int ret = 0;
- for (s = str; *s != '\0'; s++)
- {
- if (isspace (*s))
- {
- continue;
- }
- if (*s == '-')
- {
- return -1;
- }
- break;
- }
+ ret = _gf_string2long(str, &l, 0);
- old_errno = errno;
- errno = 0;
- value = strtol (str, &tail, 0);
+ *n = l;
+ return ret;
+}
- if (errno == ERANGE || errno == EINVAL)
- {
- return -1;
- }
+int
+gf_string2uint(const char *str, unsigned int *n)
+{
+ return _gf_string2uint(str, n, 0);
+}
- if (errno == 0)
- {
- errno = old_errno;
- }
+int
+gf_string2double(const char *str, double *n)
+{
+ return _gf_string2double(str, n);
+}
- if (!((tail[0] == '\0') ||
- ((tail[0] == '%') && (tail[1] == '\0'))))
- {
- return -1;
- }
+int
+gf_string2longlong(const char *str, long long *n)
+{
+ return _gf_string2longlong(str, n, 0);
+}
- *n = value;
+int
+gf_string2ulonglong(const char *str, unsigned long long *n)
+{
+ return _gf_string2ulonglong(str, n, 0);
+}
+int
+gf_string2int8(const char *str, int8_t *n)
+{
+ long l = 0L;
+ int rv = 0;
+
+ rv = _gf_string2long(str, &l, 0);
+ if (rv != 0)
+ return rv;
+
+ if ((l >= INT8_MIN) && (l <= INT8_MAX)) {
+ *n = (int8_t)l;
return 0;
+ }
+
+ errno = ERANGE;
+ return -1;
}
+int
+gf_string2int16(const char *str, int16_t *n)
+{
+ long l = 0L;
+ int rv = 0;
-static int
-_gf_string2long (const char *str, long *n, int base)
+ rv = _gf_string2long(str, &l, 0);
+ if (rv != 0)
+ return rv;
+
+ if ((l >= INT16_MIN) && (l <= INT16_MAX)) {
+ *n = (int16_t)l;
+ return 0;
+ }
+
+ errno = ERANGE;
+ return -1;
+}
+
+int
+gf_string2int32(const char *str, int32_t *n)
{
- long value = 0;
- char *tail = NULL;
- int old_errno = 0;
+ long l = 0L;
+ int rv = 0;
- if (str == NULL || n == NULL)
- {
- gf_log_callingfn ("", GF_LOG_WARNING, "arguement invalid");
- errno = EINVAL;
- return -1;
- }
+ rv = _gf_string2long(str, &l, 0);
+ if (rv != 0)
+ return rv;
- old_errno = errno;
- errno = 0;
- value = strtol (str, &tail, base);
+ if ((l >= INT32_MIN) && (l <= INT32_MAX)) {
+ *n = (int32_t)l;
+ return 0;
+ }
- if (errno == ERANGE || errno == EINVAL)
- {
- return -1;
- }
+ errno = ERANGE;
+ return -1;
+}
- if (errno == 0)
- {
- errno = old_errno;
- }
+int
+gf_string2int64(const char *str, int64_t *n)
+{
+ long long l = 0LL;
+ int rv = 0;
- if (tail[0] != '\0')
- {
- /* bala: invalid integer format */
- return -1;
- }
+ rv = _gf_string2longlong(str, &l, 0);
+ if (rv != 0)
+ return rv;
+
+ *n = (int64_t)l;
+ return 0;
+}
+
+int
+gf_string2uint8(const char *str, uint8_t *n)
+{
+ unsigned long l = 0L;
+ int rv = 0;
- *n = value;
+ rv = _gf_string2ulong(str, &l, 0);
+ if (rv != 0)
+ return rv;
+ if (l <= UINT8_MAX) {
+ *n = (uint8_t)l;
return 0;
+ }
+
+ errno = ERANGE;
+ return -1;
}
-static int
-_gf_string2ulong (const char *str, unsigned long *n, int base)
+int
+gf_string2uint16(const char *str, uint16_t *n)
{
- unsigned long value = 0;
- char *tail = NULL;
- int old_errno = 0;
- const char *s = NULL;
+ unsigned long l = 0L;
+ int rv = 0;
- if (str == NULL || n == NULL)
- {
- gf_log_callingfn ("", GF_LOG_WARNING, "arguement invalid");
- errno = EINVAL;
- return -1;
- }
+ rv = _gf_string2ulong(str, &l, 0);
+ if (rv != 0)
+ return rv;
- for (s = str; *s != '\0'; s++)
- {
- if (isspace (*s))
- {
- continue;
- }
- if (*s == '-')
- {
- /* bala: we do not support suffixed (-) sign and
- invalid integer format */
- return -1;
- }
- break;
- }
+ if (l <= UINT16_MAX) {
+ *n = (uint16_t)l;
+ return 0;
+ }
- old_errno = errno;
- errno = 0;
- value = strtoul (str, &tail, base);
+ errno = ERANGE;
+ return -1;
+}
- if (errno == ERANGE || errno == EINVAL)
- {
- return -1;
- }
+int
+gf_string2uint32(const char *str, uint32_t *n)
+{
+ unsigned long l = 0L;
+ int rv = 0;
- if (errno == 0)
- {
- errno = old_errno;
- }
+ rv = _gf_string2ulong(str, &l, 0);
+ if (rv != 0)
+ return rv;
- if (tail[0] != '\0')
- {
- /* bala: invalid integer format */
- return -1;
- }
+ if (l <= UINT32_MAX) {
+ *n = (uint32_t)l;
+ return 0;
+ }
- *n = value;
+ errno = ERANGE;
+ return -1;
+}
+int
+gf_string2uint64(const char *str, uint64_t *n)
+{
+ unsigned long long l = 0ULL;
+ int rv = 0;
+
+ rv = _gf_string2ulonglong(str, &l, 0);
+ if (rv != 0)
+ return rv;
+
+ if (l <= UINT64_MAX) {
+ *n = (uint64_t)l;
return 0;
+ }
+
+ errno = ERANGE;
+ return -1;
}
-static int
-_gf_string2uint (const char *str, unsigned int *n, int base)
+int
+gf_string2ulong_base10(const char *str, unsigned long *n)
{
- unsigned long value = 0;
- char *tail = NULL;
- int old_errno = 0;
- const char *s = NULL;
+ return _gf_string2ulong(str, n, 10);
+}
- if (str == NULL || n == NULL)
- {
- gf_log_callingfn ("", GF_LOG_WARNING, "arguement invalid");
- errno = EINVAL;
- return -1;
- }
+int
+gf_string2uint_base10(const char *str, unsigned int *n)
+{
+ return _gf_string2uint(str, n, 10);
+}
- for (s = str; *s != '\0'; s++)
- {
- if (isspace (*s))
- {
- continue;
- }
- if (*s == '-')
- {
- /* bala: we do not support suffixed (-) sign and
- invalid integer format */
- return -1;
- }
- break;
- }
+int
+gf_string2uint8_base10(const char *str, uint8_t *n)
+{
+ unsigned long l = 0L;
+ int rv = 0;
- old_errno = errno;
- errno = 0;
- value = strtoul (str, &tail, base);
+ rv = _gf_string2ulong(str, &l, 10);
+ if (rv != 0)
+ return rv;
- if (errno == ERANGE || errno == EINVAL)
- {
- return -1;
- }
+ if (l <= UINT8_MAX) {
+ *n = (uint8_t)l;
+ return 0;
+ }
- if (errno == 0)
- {
- errno = old_errno;
- }
+ errno = ERANGE;
+ return -1;
+}
- if (tail[0] != '\0')
- {
- /* bala: invalid integer format */
- return -1;
- }
+int
+gf_string2uint16_base10(const char *str, uint16_t *n)
+{
+ unsigned long l = 0L;
+ int rv = 0;
- *n = (unsigned int)value;
+ rv = _gf_string2ulong(str, &l, 10);
+ if (rv != 0)
+ return rv;
+ if (l <= UINT16_MAX) {
+ *n = (uint16_t)l;
return 0;
+ }
+
+ errno = ERANGE;
+ return -1;
}
-static int
-_gf_string2double (const char *str, double *n)
+int
+gf_string2uint32_base10(const char *str, uint32_t *n)
{
- double value = 0.0;
- char *tail = NULL;
- int old_errno = 0;
-
- if (str == NULL || n == NULL) {
- gf_log_callingfn ("", GF_LOG_WARNING, "arguement invalid");
- errno = EINVAL;
- return -1;
- }
+ unsigned long l = 0L;
+ int rv = 0;
- old_errno = errno;
- errno = 0;
- value = strtod (str, &tail);
+ rv = _gf_string2ulong(str, &l, 10);
+ if (rv != 0)
+ return rv;
- if (errno == ERANGE || errno == EINVAL) {
- return -1;
- }
+ if (l <= UINT32_MAX) {
+ *n = (uint32_t)l;
+ return 0;
+ }
- if (errno == 0) {
- errno = old_errno;
- }
+ errno = ERANGE;
+ return -1;
+}
- if (tail[0] != '\0') {
- return -1;
- }
+int
+gf_string2uint64_base10(const char *str, uint64_t *n)
+{
+ unsigned long long l = 0ULL;
+ int rv = 0;
- *n = value;
+ rv = _gf_string2ulonglong(str, &l, 10);
+ if (rv != 0)
+ return rv;
+ if (l <= UINT64_MAX) {
+ *n = (uint64_t)l;
return 0;
+ }
+
+ errno = ERANGE;
+ return -1;
}
-static int
-_gf_string2longlong (const char *str, long long *n, int base)
+char *
+gf_uint64_2human_readable(uint64_t n)
{
- long long value = 0;
- char *tail = NULL;
- int old_errno = 0;
+ int ret = 0;
+ char *str = NULL;
+
+ if (n >= GF_UNIT_PB) {
+ ret = gf_asprintf(&str, "%.1lfPB", ((double)n) / GF_UNIT_PB);
+ if (ret < 0)
+ goto err;
+ } else if (n >= GF_UNIT_TB) {
+ ret = gf_asprintf(&str, "%.1lfTB", ((double)n) / GF_UNIT_TB);
+ if (ret < 0)
+ goto err;
+ } else if (n >= GF_UNIT_GB) {
+ ret = gf_asprintf(&str, "%.1lfGB", ((double)n) / GF_UNIT_GB);
+ if (ret < 0)
+ goto err;
+ } else if (n >= GF_UNIT_MB) {
+ ret = gf_asprintf(&str, "%.1lfMB", ((double)n) / GF_UNIT_MB);
+ if (ret < 0)
+ goto err;
+ } else if (n >= GF_UNIT_KB) {
+ ret = gf_asprintf(&str, "%.1lfKB", ((double)n) / GF_UNIT_KB);
+ if (ret < 0)
+ goto err;
+ } else {
+ ret = gf_asprintf(&str, "%" PRIu64 "Bytes", n);
+ if (ret < 0)
+ goto err;
+ }
+ return str;
+err:
+ return NULL;
+}
- if (str == NULL || n == NULL)
- {
- gf_log_callingfn ("", GF_LOG_WARNING, "arguement invalid");
- errno = EINVAL;
- return -1;
- }
+int
+gf_string2bytesize_range(const char *str, uint64_t *n, uint64_t umax)
+{
+ double value = 0.0;
+ int64_t int_value = 0;
+ uint64_t unit = 0;
+ int64_t max = 0;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
+ gf_boolean_t fraction = _gf_false;
+
+ if (str == NULL || n == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
- old_errno = errno;
- errno = 0;
- value = strtoll (str, &tail, base);
+ max = umax & 0x7fffffffffffffffLL;
- if (errno == ERANGE || errno == EINVAL)
- {
- return -1;
- }
+ for (s = str; *s != '\0'; s++) {
+ if (isspace(*s))
+ continue;
+ if (*s == '-')
+ return -1;
+ break;
+ }
- if (errno == 0)
- {
- errno = old_errno;
+ if (strrchr(str, '.'))
+ fraction = _gf_true;
+
+ old_errno = errno;
+ errno = 0;
+ if (fraction)
+ value = strtod(str, &tail);
+ else
+ int_value = strtoll(str, &tail, 10);
+
+ if (str == tail)
+ errno = EINVAL;
+
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
+
+ if (errno == 0)
+ errno = old_errno;
+
+ if (tail[0] != '\0') {
+ if (strcasecmp(tail, GF_UNIT_KB_STRING) == 0)
+ unit = GF_UNIT_KB;
+ else if (strcasecmp(tail, GF_UNIT_MB_STRING) == 0)
+ unit = GF_UNIT_MB;
+ else if (strcasecmp(tail, GF_UNIT_GB_STRING) == 0)
+ unit = GF_UNIT_GB;
+ else if (strcasecmp(tail, GF_UNIT_TB_STRING) == 0)
+ unit = GF_UNIT_TB;
+ else if (strcasecmp(tail, GF_UNIT_PB_STRING) == 0)
+ unit = GF_UNIT_PB;
+ else if (strcasecmp(tail, GF_UNIT_B_STRING) != 0)
+ return -1;
+
+ if (unit > 0) {
+ if (fraction)
+ value *= unit;
+ else
+ int_value *= unit;
}
+ }
- if (tail[0] != '\0')
- {
- /* bala: invalid integer format */
- return -1;
+ if (fraction) {
+ if ((max - value) < 0) {
+ errno = ERANGE;
+ return -1;
+ }
+ *n = (uint64_t)value;
+ } else {
+ if ((max - int_value) < 0) {
+ errno = ERANGE;
+ return -1;
}
+ *n = int_value;
+ }
- *n = value;
+ return 0;
+}
- return 0;
+int
+gf_string2bytesize_uint64(const char *str, uint64_t *n)
+{
+ return gf_string2bytesize_range(str, n, UINT64_MAX);
}
-static int
-_gf_string2ulonglong (const char *str, unsigned long long *n, int base)
+int
+gf_string2bytesize_int64(const char *str, int64_t *n)
{
- unsigned long long value = 0;
- char *tail = NULL;
- int old_errno = 0;
- const char *s = NULL;
+ uint64_t u64 = 0;
+ int ret = 0;
- if (str == NULL || n == NULL)
- {
- gf_log_callingfn ("", GF_LOG_WARNING, "arguement invalid");
- errno = EINVAL;
- return -1;
- }
+ ret = gf_string2bytesize_range(str, &u64, INT64_MAX);
+ *n = (int64_t)u64;
+ return ret;
+}
- for (s = str; *s != '\0'; s++)
- {
- if (isspace (*s))
- {
- continue;
- }
- if (*s == '-')
- {
- /* bala: we do not support suffixed (-) sign and
- invalid integer format */
- return -1;
- }
- break;
- }
+int
+gf_string2percent_or_bytesize(const char *str, double *n,
+ gf_boolean_t *is_percent)
+{
+ double value = 0ULL;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
+
+ if (str == NULL || n == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
+
+ for (s = str; *s != '\0'; s++) {
+ if (isspace(*s))
+ continue;
+ if (*s == '-')
+ return -1;
+ break;
+ }
+
+ old_errno = errno;
+ errno = 0;
+ value = strtod(str, &tail);
+ if (str == tail)
+ errno = EINVAL;
+
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- old_errno = errno;
- errno = 0;
- value = strtoull (str, &tail, base);
+ if (errno == 0)
+ errno = old_errno;
+
+ /*Maximum accepted value for 64 bit OS will be (2^14 -1)PB*/
+ if (tail[0] != '\0') {
+ if (strcasecmp(tail, GF_UNIT_KB_STRING) == 0)
+ value *= GF_UNIT_KB;
+ else if (strcasecmp(tail, GF_UNIT_MB_STRING) == 0)
+ value *= GF_UNIT_MB;
+ else if (strcasecmp(tail, GF_UNIT_GB_STRING) == 0)
+ value *= GF_UNIT_GB;
+ else if (strcasecmp(tail, GF_UNIT_TB_STRING) == 0)
+ value *= GF_UNIT_TB;
+ else if (strcasecmp(tail, GF_UNIT_PB_STRING) == 0)
+ value *= GF_UNIT_PB;
+ else if (strcasecmp(tail, GF_UNIT_PERCENT_STRING) == 0)
+ *is_percent = _gf_true;
+ else
+ return -1;
+ }
+
+ /* Error out if we cannot store the value in uint64 */
+ if ((UINT64_MAX - value) < 0) {
+ errno = ERANGE;
+ return -1;
+ }
- if (errno == ERANGE || errno == EINVAL)
- {
- return -1;
- }
+ *n = value;
- if (errno == 0)
- {
- errno = old_errno;
- }
+ return 0;
+}
- if (tail[0] != '\0')
- {
- /* bala: invalid integer format */
- return -1;
+int64_t
+gf_str_to_long_long(const char *number)
+{
+ int64_t unit = 1;
+ int64_t ret = 0;
+ char *endptr = NULL;
+ if (!number)
+ return 0;
+
+ ret = strtoll(number, &endptr, 0);
+
+ if (endptr) {
+ switch (*endptr) {
+ case 'G':
+ case 'g':
+ if ((*(endptr + 1) == 'B') || (*(endptr + 1) == 'b'))
+ unit = 1024 * 1024 * 1024;
+ break;
+ case 'M':
+ case 'm':
+ if ((*(endptr + 1) == 'B') || (*(endptr + 1) == 'b'))
+ unit = 1024 * 1024;
+ break;
+ case 'K':
+ case 'k':
+ if ((*(endptr + 1) == 'B') || (*(endptr + 1) == 'b'))
+ unit = 1024;
+ break;
+ case '%':
+ unit = 1;
+ break;
+ default:
+ unit = 1;
+ break;
}
+ }
+ return ret * unit;
+}
- *n = value;
+int
+gf_string2boolean(const char *str, gf_boolean_t *b)
+{
+ if (str == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "argument invalid");
+ return -1;
+ }
+
+ if ((strcasecmp(str, "1") == 0) || (strcasecmp(str, "on") == 0) ||
+ (strcasecmp(str, "yes") == 0) || (strcasecmp(str, "true") == 0) ||
+ (strcasecmp(str, "enable") == 0)) {
+ *b = _gf_true;
+ return 0;
+ }
+ if ((strcasecmp(str, "0") == 0) || (strcasecmp(str, "off") == 0) ||
+ (strcasecmp(str, "no") == 0) || (strcasecmp(str, "false") == 0) ||
+ (strcasecmp(str, "disable") == 0)) {
+ *b = _gf_false;
return 0;
+ }
+
+ return -1;
}
int
-gf_string2long (const char *str, long *n)
+gf_strn2boolean(const char *str, const int len, gf_boolean_t *b)
{
- return _gf_string2long (str, n, 0);
+ if (str == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "argument invalid");
+ return -1;
+ }
+
+ switch (len) {
+ case 1:
+ if (strcasecmp(str, "1") == 0) {
+ *b = _gf_true;
+ return 0;
+ } else if (strcasecmp(str, "0") == 0) {
+ *b = _gf_false;
+ return 0;
+ }
+ break;
+ case 2:
+ if (strcasecmp(str, "on") == 0) {
+ *b = _gf_true;
+ return 0;
+ } else if (strcasecmp(str, "no") == 0) {
+ *b = _gf_false;
+ return 0;
+ }
+ break;
+ case 3:
+ if (strcasecmp(str, "yes") == 0) {
+ *b = _gf_true;
+ return 0;
+ } else if (strcasecmp(str, "off") == 0) {
+ *b = _gf_false;
+ return 0;
+ }
+ break;
+ case 4:
+ if (strcasecmp(str, "true") == 0) {
+ *b = _gf_true;
+ return 0;
+ }
+ break;
+ case 5:
+ if (strcasecmp(str, "false") == 0) {
+ *b = _gf_false;
+ return 0;
+ }
+ break;
+ case 6:
+ if (strcasecmp(str, "enable") == 0) {
+ *b = _gf_true;
+ return 0;
+ }
+ break;
+ case 7:
+ if (strcasecmp(str, "disable") == 0) {
+ *b = _gf_false;
+ return 0;
+ }
+ break;
+ default:
+ return -1;
+ break;
+ }
+ return -1;
}
int
-gf_string2ulong (const char *str, unsigned long *n)
+gf_lockfd(int fd)
{
- return _gf_string2ulong (str, n, 0);
+ struct gf_flock fl;
+
+ fl.l_type = F_WRLCK;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0;
+ fl.l_len = 0;
+
+ return fcntl(fd, F_SETLK, &fl);
}
int
-gf_string2int (const char *str, int *n)
+gf_unlockfd(int fd)
{
- long l = 0;
- int ret = 0;
+ struct gf_flock fl;
- ret = _gf_string2long (str, &l, 0);
+ fl.l_type = F_UNLCK;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0;
+ fl.l_len = 0;
- *n = l;
- return ret;
+ return fcntl(fd, F_SETLK, &fl);
}
-int
-gf_string2uint (const char *str, unsigned int *n)
+static void
+compute_checksum(char *buf, const ssize_t size, uint32_t *checksum)
{
- return _gf_string2uint (str, n, 0);
+ int ret = -1;
+ char *checksum_buf = NULL;
+
+ checksum_buf = (char *)(checksum);
+
+ if (!(*checksum)) {
+ checksum_buf[0] = 0xba;
+ checksum_buf[1] = 0xbe;
+ checksum_buf[2] = 0xb0;
+ checksum_buf[3] = 0x0b;
+ }
+
+ for (ret = 0; ret < (size - 4); ret += 4) {
+ checksum_buf[0] ^= (buf[ret]);
+ checksum_buf[1] ^= (buf[ret + 1] << 1);
+ checksum_buf[2] ^= (buf[ret + 2] << 2);
+ checksum_buf[3] ^= (buf[ret + 3] << 3);
+ }
+
+ for (ret = 0; ret <= (size % 4); ret++) {
+ checksum_buf[ret] ^= (buf[(size - 4) + ret] << ret);
+ }
+
+ return;
}
+#define GF_CHECKSUM_BUF_SIZE 1024
+
int
-gf_string2double (const char *str, double *n)
+get_checksum_for_file(int fd, uint32_t *checksum, int op_version)
{
- return _gf_string2double (str, n);
+ int ret = -1;
+ char buf[GF_CHECKSUM_BUF_SIZE] = {
+ 0,
+ };
+
+ /* goto first place */
+ sys_lseek(fd, 0L, SEEK_SET);
+ do {
+ ret = sys_read(fd, &buf, GF_CHECKSUM_BUF_SIZE);
+ if (ret > 0) {
+ if (op_version < GD_OP_VERSION_5_4)
+ compute_checksum(buf, GF_CHECKSUM_BUF_SIZE, checksum);
+ else
+ compute_checksum(buf, ret, checksum);
+ }
+ } while (ret > 0);
+
+ /* set it back */
+ sys_lseek(fd, 0L, SEEK_SET);
+
+ return ret;
}
int
-gf_string2longlong (const char *str, long long *n)
+get_checksum_for_path(char *path, uint32_t *checksum, int op_version)
{
- return _gf_string2longlong (str, n, 0);
+ int ret = -1;
+ int fd = -1;
+
+ GF_ASSERT(path);
+ GF_ASSERT(checksum);
+
+ fd = open(path, O_RDWR);
+
+ if (fd == -1) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, errno, LG_MSG_PATH_OPEN_FAILED,
+ "path=%s", path, NULL);
+ goto out;
+ }
+
+ ret = get_checksum_for_file(fd, checksum, op_version);
+
+out:
+ if (fd != -1)
+ sys_close(fd);
+
+ return ret;
}
+/**
+ * get_file_mtime -- Given a path, get the mtime for the file
+ *
+ * @path: The filepath to check the mtime on
+ * @stamp: The parameter to set after we get the mtime
+ *
+ * @returns: success: 0
+ * errors : Errors returned by the stat () call
+ */
int
-gf_string2ulonglong (const char *str, unsigned long long *n)
+get_file_mtime(const char *path, time_t *stamp)
{
- return _gf_string2ulonglong (str, n, 0);
+ struct stat f_stat = {0};
+ int ret = -EINVAL;
+
+ GF_VALIDATE_OR_GOTO(THIS->name, path, out);
+ GF_VALIDATE_OR_GOTO(THIS->name, stamp, out);
+
+ ret = sys_stat(path, &f_stat);
+ if (ret < 0) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, errno, LG_MSG_FILE_STAT_FAILED,
+ "path=%s", path, NULL);
+ goto out;
+ }
+
+ /* Set the mtime */
+ *stamp = f_stat.st_mtime;
+out:
+ return ret;
}
-int
-gf_string2int8 (const char *str, int8_t *n)
+/**
+ * gf_is_ip_in_net -- Checks if an IP Address is in a network.
+ * A network should be specified by something like
+ * '10.5.153.0/24' (in CIDR notation).
+ *
+ * @result : Sets to true if the IP is in the network
+ * @ip_str : The IP to check
+ * @network: The network to check the IP against.
+ *
+ * @return: success: _gf_true
+ * failure: -EINVAL for bad args, retval of inet_pton otherwise
+ */
+gf_boolean_t
+gf_is_ip_in_net(const char *network, const char *ip_str)
+{
+ unsigned long ip_buf = 0;
+ unsigned long net_ip_buf = 0;
+ unsigned long subnet_mask = 0;
+ int ret = -EINVAL;
+ char *slash = NULL;
+ char *net_ip = NULL;
+ char *subnet = NULL;
+ char *net_str = NULL;
+ int family = AF_INET;
+ gf_boolean_t result = _gf_false;
+
+ GF_ASSERT(network);
+ GF_ASSERT(ip_str);
+
+ if (strchr(network, ':'))
+ family = AF_INET6;
+ else if (strchr(network, '.'))
+ family = AF_INET;
+ else {
+ goto out;
+ }
+
+ net_str = strdupa(network);
+ slash = strchr(net_str, '/');
+ if (!slash)
+ goto out;
+ *slash = '\0';
+
+ subnet = slash + 1;
+ net_ip = net_str;
+
+ /* Convert IP address to a long */
+ ret = inet_pton(family, ip_str, &ip_buf);
+ if (ret < 0)
+ gf_smsg("common-utils", GF_LOG_ERROR, errno, LG_MSG_INET_PTON_FAILED,
+ NULL);
+
+ /* Convert network IP address to a long */
+ ret = inet_pton(family, net_ip, &net_ip_buf);
+ if (ret < 0) {
+ gf_smsg("common-utils", GF_LOG_ERROR, errno, LG_MSG_INET_PTON_FAILED,
+ NULL);
+ goto out;
+ }
+
+ /* Converts /x into a mask */
+ subnet_mask = (1 << atoi(subnet)) - 1;
+
+ result = ((ip_buf & subnet_mask) == (net_ip_buf & subnet_mask));
+out:
+ return result;
+}
+
+char *
+strtail(char *str, const char *pattern)
{
- long l = 0L;
- int rv = 0;
+ int i = 0;
- rv = _gf_string2long (str, &l, 0);
- if (rv != 0)
- return rv;
+ for (i = 0; str[i] == pattern[i] && str[i]; i++)
+ ;
- if (l >= INT8_MIN && l <= INT8_MAX)
- {
- *n = (int8_t) l;
- return 0;
- }
+ if (pattern[i] == '\0')
+ return str + i;
- errno = ERANGE;
- return -1;
+ return NULL;
}
-int
-gf_string2int16 (const char *str, int16_t *n)
+void
+skipwhite(char **s)
{
- long l = 0L;
- int rv = 0;
+ while (isspace(**s))
+ (*s)++;
+}
- rv = _gf_string2long (str, &l, 0);
- if (rv != 0)
- return rv;
+void
+gf_strTrim(char **s)
+{
+ char *end = NULL;
- if (l >= INT16_MIN && l <= INT16_MAX)
- {
- *n = (int16_t) l;
- return 0;
- }
+ end = *s + strlen(*s) - 1;
+ while (end > *s && isspace((unsigned char)*end))
+ end--;
- errno = ERANGE;
- return -1;
+ *(end + 1) = '\0';
+
+ while (isspace(**s))
+ (*s)++;
+
+ return;
}
-int
-gf_string2int32 (const char *str, int32_t *n)
+char *
+nwstrtail(char *str, char *pattern)
{
- long l = 0L;
- int rv = 0;
+ for (;;) {
+ skipwhite(&str);
+ skipwhite(&pattern);
- rv = _gf_string2long (str, &l, 0);
- if (rv != 0)
- return rv;
+ if (*str != *pattern || !*str)
+ break;
- if (l >= INT32_MIN && l <= INT32_MAX)
- {
- *n = (int32_t) l;
- return 0;
- }
+ str++;
+ pattern++;
+ }
- errno = ERANGE;
- return -1;
+ return *pattern ? NULL : str;
}
-int
-gf_string2int64 (const char *str, int64_t *n)
+/**
+ * token_iter_init -- initialize tokenization
+ *
+ * @str: string to be tokenized
+ * @sep: token separator character
+ * @tit: pointer to iteration state
+ *
+ * @return: token string
+ *
+ * The returned token string and tit are
+ * not to be used directly, but through
+ * next_token().
+ */
+char *
+token_iter_init(char *str, char sep, token_iter_t *tit)
{
- long long l = 0LL;
- int rv = 0;
+ tit->end = str + strlen(str);
+ tit->sep = sep;
- rv = _gf_string2longlong (str, &l, 0);
- if (rv != 0)
- return rv;
+ return str;
+}
- if (l >= INT64_MIN && l <= INT64_MAX)
- {
- *n = (int64_t) l;
- return 0;
- }
+/**
+ * next_token -- fetch next token in tokenization
+ * inited by token_iter_init().
+ *
+ * @tokenp: pointer to token
+ * @tit: pointer to iteration state
+ *
+ * @return: true if iteration ends, else false
+ *
+ * The token pointed by @tokenp can be used
+ * after a call to next_token(). When next_token()
+ * returns true the iteration is to be stopped
+ * and the string with which the tokenization
+ * was inited (see token_iter_init() is restored,
+ * apart from dropped tokens (see drop_token()).
+ */
+gf_boolean_t
+next_token(char **tokenp, token_iter_t *tit)
+{
+ char *cursor = NULL;
+ gf_boolean_t is_last = _gf_false;
+
+ for (cursor = *tokenp; *cursor; cursor++)
+ ;
+ if (cursor < tit->end) {
+ /*
+ * We detect that in between current token and end a zero
+ * marker has already been inserted. This means that the
+ * token has already been returned. We restore the
+ * separator and move ahead.
+ */
+ *cursor = tit->sep;
+ *tokenp = cursor + 1;
+ }
+
+ for (cursor = *tokenp; *cursor && *cursor != tit->sep; cursor++)
+ ;
+ /* If the cursor ended up on a zero byte, then it's the last token. */
+ is_last = !*cursor;
+ /* Zero-terminate the token. */
+ *cursor = 0;
+
+ return is_last;
+}
- errno = ERANGE;
- return -1;
+/*
+ * drop_token -- drop a token during iterated calls of next_token().
+ *
+ * Sample program that uses these functions to tokenize
+ * a comma-separated first argument while dropping the
+ * rest of the arguments if they occur as token:
+ *
+ * #include <stdio.h>
+ * #include <stdlib.h>
+ * #include <string.h>
+ * #include "glusterfs/common-utils.h"
+ *
+ * int
+ * main (int argc, char **argv)
+ * {
+ * char *buf;
+ * char *token;
+ * token_iter_t tit;
+ * int i;
+ * gf_boolean_t iter_end;
+ *
+ * if (argc <= 1)
+ * abort();
+ *
+ * buf = strdup (argv[1]);
+ * if (!buf)
+ * abort();
+ *
+ * for (token = token_iter_init (buf, ',', &tit) ;;) {
+ * iter_end = next_token (&token, &tit);
+ * printf("found token: '%s'\n", token);
+ * for (i = 2; i < argc; i++) {
+ * if (strcmp (argv[i], token) == 0) {
+ * printf ("%s\n", "dropping token!");
+ * drop_token (token, &tit);
+ * break;
+ * }
+ * }
+ * if (iter_end)
+ * break;
+ * }
+ *
+ * printf ("finally: '%s'\n", buf);
+ *
+ * return 0;
+ * }
+ */
+void
+drop_token(char *token, token_iter_t *tit)
+{
+ char *cursor = NULL;
+
+ for (cursor = token; *cursor; cursor++)
+ ;
+ if (cursor < tit->end) {
+ /*
+ * We detect a zero inserted by next_token().
+ * Step the cursor and copy what comes after
+ * to token.
+ */
+ for (cursor++; cursor < tit->end; *token++ = *cursor++)
+ ;
+ }
+
+ /*
+ * Zero out the remainder of the buffer.
+ * It would be enough to insert just a single zero,
+ * but we continue 'till the end to have cleaner
+ * memory content.
+ */
+ for (cursor = token; cursor < tit->end; *cursor++ = 0)
+ ;
+
+ /* Adjust the end to point to the new terminating zero. */
+ tit->end = token;
}
-int
-gf_string2uint8 (const char *str, uint8_t *n)
+/* Syntax formed according to RFC 1912 (RFC 1123 & 952 are more restrictive) *
+ <hname> ::= <gen-name>*["."<gen-name>] *
+ <gen-name> ::= <let-or-digit> <[*[<let-or-digit-or-hyphen>]<let-or-digit>] */
+char
+valid_host_name(char *address, int length)
{
- unsigned long l = 0L;
- int rv = 0;
+ int i = 0;
+ int str_len = 0;
+ char ret = 1;
+ char *dup_addr = NULL;
+ char *temp_str = NULL;
+ char *save_ptr = NULL;
+
+ if ((length > _POSIX_HOST_NAME_MAX) || (length < 1)) {
+ ret = 0;
+ goto out;
+ }
+
+ dup_addr = gf_strdup(address);
+ if (!dup_addr) {
+ ret = 0;
+ goto out;
+ }
+
+ if (!isalnum(dup_addr[length - 1]) && (dup_addr[length - 1] != '*')) {
+ ret = 0;
+ goto out;
+ }
+
+ /* Check for consecutive dots, which is invalid in a hostname and is
+ * ignored by strtok()
+ */
+ if (strstr(dup_addr, "..")) {
+ ret = 0;
+ goto out;
+ }
+
+ /* gen-name */
+ temp_str = strtok_r(dup_addr, ".", &save_ptr);
+ do {
+ str_len = strlen(temp_str);
+
+ if (!isalnum(temp_str[0]) || !isalnum(temp_str[str_len - 1])) {
+ ret = 0;
+ goto out;
+ }
+ for (i = 1; i < str_len; i++) {
+ if (!isalnum(temp_str[i]) && (temp_str[i] != '-')) {
+ ret = 0;
+ goto out;
+ }
+ }
+ } while ((temp_str = strtok_r(NULL, ".", &save_ptr)));
- rv = _gf_string2ulong (str, &l, 0);
- if (rv != 0)
- return rv;
+out:
+ GF_FREE(dup_addr);
+ return ret;
+}
- if (l >= 0 && l <= UINT8_MAX)
- {
- *n = (uint8_t) l;
- return 0;
+/* Matches all ipv4 address, if wildcard_acc is true '*' wildcard pattern for*
+ subnets is considered as valid strings as well */
+char
+valid_ipv4_address(char *address, int length, gf_boolean_t wildcard_acc)
+{
+ int octets = 0;
+ int value = 0;
+ char *tmp = NULL, *ptr = NULL, *prev = NULL, *endptr = NULL;
+ char ret = 1;
+ int is_wildcard = 0;
+
+ tmp = gf_strdup(address);
+
+ /*
+ * To prevent cases where last character is '.' and which have
+ * consecutive dots like ".." as strtok ignore consecutive
+ * delimiters.
+ */
+ if (length <= 0 || (strstr(address, "..")) ||
+ (!isdigit(tmp[length - 1]) && (tmp[length - 1] != '*'))) {
+ ret = 0;
+ goto out;
+ }
+
+ prev = strtok_r(tmp, ".", &ptr);
+
+ while (prev != NULL) {
+ octets++;
+ if (wildcard_acc && !strcmp(prev, "*")) {
+ is_wildcard = 1;
+ } else {
+ value = strtol(prev, &endptr, 10);
+ if ((value > 255) || (value < 0) ||
+ (endptr != NULL && *endptr != '\0')) {
+ ret = 0;
+ goto out;
+ }
}
+ prev = strtok_r(NULL, ".", &ptr);
+ }
- errno = ERANGE;
- return -1;
+ if ((octets > 4) || (octets < 4 && !is_wildcard)) {
+ ret = 0;
+ }
+
+out:
+ GF_FREE(tmp);
+ return ret;
}
-int
-gf_string2uint16 (const char *str, uint16_t *n)
+char
+valid_cidr_address(char *cidr_address, gf_boolean_t wildcard_acc)
{
- unsigned long l = 0L;
- int rv = 0;
+ unsigned int net_mask = 0, len = 0;
+ char *temp = NULL, *cidr_str = NULL, ret = 1;
- rv = _gf_string2ulong (str, &l, 0);
- if (rv != 0)
- return rv;
+ cidr_str = strdupa(cidr_address);
+ temp = strstr(cidr_str, "/");
+ if (temp == NULL)
+ return 0; /* Since Invalid cidr ip address we return 0 */
- if (l >= 0 && l <= UINT16_MAX)
- {
- *n = (uint16_t) l;
- return 0;
- }
+ *temp = '\0';
+ temp++;
+ net_mask = (unsigned int)atoi(temp);
- errno = ERANGE;
- return -1;
+ if (net_mask > 32 || net_mask < 1)
+ return 0; /* Since Invalid cidr ip address we return 0*/
+
+ len = strlen(cidr_str);
+
+ ret = valid_ipv4_address(cidr_str, len, wildcard_acc);
+
+ return ret;
}
-int
-gf_string2uint32 (const char *str, uint32_t *n)
+/**
+ * valid_ipv4_subnetwork() takes the pattern and checks if it contains
+ * a valid ipv4 subnetwork pattern i.e. xx.xx.xx.xx/n. IPv4 address
+ * part (xx.xx.xx.xx) and mask bits length part (n). The mask bits length
+ * must be in 0-32 range (ipv4 addr is 32 bit). The pattern must be
+ * in this format.
+ *
+ * Returns _gf_true if both IP addr and mask bits len are valid
+ * _gf_false otherwise.
+ */
+gf_boolean_t
+valid_ipv4_subnetwork(const char *address)
{
- unsigned long l = 0L;
- int rv = 0;
+ char *slash = NULL;
+ char *paddr = NULL;
+ char *endptr = NULL;
+ long prefixlen = -1;
+ gf_boolean_t retv = _gf_true;
+
+ if (address == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "argument invalid");
+ return _gf_false;
+ }
+
+ paddr = gf_strdup(address);
+ if (paddr == NULL) /* ENOMEM */
+ return _gf_false;
+
+ /*
+ * INVALID: If '/' is not present OR
+ * Nothing specified after '/'
+ */
+ slash = strchr(paddr, '/');
+ if ((slash == NULL) || (slash[1] == '\0')) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0,
+ LG_MSG_INVALID_IPV4_FORMAT,
+ "Invalid IPv4 "
+ "subnetwork format");
+ retv = _gf_false;
+ goto out;
+ }
+
+ *slash = '\0';
+ retv = valid_ipv4_address(paddr, strlen(paddr), _gf_false);
+ if (retv == _gf_false) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0,
+ LG_MSG_INVALID_IPV4_FORMAT,
+ "Invalid IPv4 subnetwork address");
+ goto out;
+ }
+ /*
+ * Reset errno before checking it
+ */
+ errno = 0;
+ prefixlen = strtol(slash + 1, &endptr, 10);
+ if ((errno != 0) || (*endptr != '\0') || (prefixlen < 0) ||
+ (prefixlen > IPv4_ADDR_SIZE)) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0,
+ LG_MSG_INVALID_IPV4_FORMAT,
+ "Invalid IPv4 subnetwork mask");
+ retv = _gf_false;
+ goto out;
+ }
+
+ retv = _gf_true;
+out:
+ GF_FREE(paddr);
+ return retv;
+}
- rv = _gf_string2ulong (str, &l, 0);
- if (rv != 0)
- return rv;
+char
+valid_ipv6_address(char *address, int length, gf_boolean_t wildcard_acc)
+{
+ int hex_numbers = 0;
+ int value = 0;
+ int i = 0;
+ char *tmp = NULL, *ptr = NULL, *prev = NULL, *endptr = NULL;
+ char ret = 1;
+ int is_wildcard = 0;
+ int is_compressed = 0;
+
+ tmp = gf_strdup(address);
+
+ /* Check for '%' for link local addresses */
+ endptr = strchr(tmp, '%');
+ if (endptr) {
+ *endptr = '\0';
+ length = strlen(tmp);
+ endptr = NULL;
+ }
+
+ /* Check for compressed form */
+ if (length <= 0 || tmp[length - 1] == ':') {
+ ret = 0;
+ goto out;
+ }
+ for (i = 0; i < (length - 1); i++) {
+ if (tmp[i] == ':' && tmp[i + 1] == ':') {
+ if (is_compressed == 0)
+ is_compressed = 1;
+ else {
+ ret = 0;
+ goto out;
+ }
+ }
+ }
- if (l >= 0 && l <= UINT32_MAX)
- {
- *n = (uint32_t) l;
- return 0;
+ prev = strtok_r(tmp, ":", &ptr);
+
+ while (prev != NULL) {
+ hex_numbers++;
+ if (wildcard_acc && !strcmp(prev, "*")) {
+ is_wildcard = 1;
+ } else {
+ value = strtol(prev, &endptr, 16);
+ if ((value > 0xffff) || (value < 0) ||
+ (endptr != NULL && *endptr != '\0')) {
+ ret = 0;
+ goto out;
+ }
}
+ prev = strtok_r(NULL, ":", &ptr);
+ }
- errno = ERANGE;
- return -1;
+ if ((hex_numbers > 8) ||
+ (hex_numbers < 8 && !is_wildcard && !is_compressed)) {
+ ret = 0;
+ }
+
+out:
+ GF_FREE(tmp);
+ return ret;
}
-int
-gf_string2uint64 (const char *str, uint64_t *n)
+char
+valid_internet_address(char *address, gf_boolean_t wildcard_acc,
+ gf_boolean_t cidr)
{
- unsigned long long l = 0ULL;
- int rv = 0;
+ char ret = 0;
+ int length = 0;
- rv = _gf_string2ulonglong (str, &l, 0);
- if (rv != 0)
- return rv;
+ if (address == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "argument invalid");
+ goto out;
+ }
- if (l >= 0 && l <= UINT64_MAX)
- {
- *n = (uint64_t) l;
- return 0;
+ length = strlen(address);
+ if (length == 0)
+ goto out;
+
+ if (cidr && valid_cidr_address(address, wildcard_acc)) {
+ ret = 1;
+ }
+
+ if (valid_ipv4_address(address, length, wildcard_acc) ||
+ valid_ipv6_address(address, length, wildcard_acc) ||
+ valid_host_name(address, length))
+ ret = 1;
+
+out:
+ return ret;
+}
+
+/**
+ * valid_mount_auth_address - Validate the rpc-auth.addr.allow/reject pattern
+ *
+ * @param address - Pattern to be validated
+ *
+ * @return _gf_true if "address" is "*" (anonymous) 'OR'
+ * if "address" is valid FQDN or valid IPv4/6 address 'OR'
+ * if "address" contains wildcard chars e.g. "'*' or '?' or
+ * '['" if "address" is valid ipv4 subnet pattern (xx.xx.xx.xx/n) _gf_false
+ * otherwise
+ *
+ *
+ * NB: If the user/admin set for wildcard pattern, then it does not have
+ * to be validated. Make it similar to the way exportfs (kNFS) works.
+ */
+gf_boolean_t
+valid_mount_auth_address(char *address)
+{
+ int length = 0;
+ char *cp = NULL;
+
+ /* 1. Check for "NULL and empty string */
+ if ((address == NULL) || (address[0] == '\0')) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "argument invalid");
+ return _gf_false;
+ }
+
+ /* 2. Check for Anonymous */
+ if (strcmp(address, "*") == 0)
+ return _gf_true;
+
+ for (cp = address; *cp; cp++) {
+ /* 3. Check for wildcard pattern */
+ if (*cp == '*' || *cp == '?' || *cp == '[') {
+ return _gf_true;
}
- errno = ERANGE;
- return -1;
+ /*
+ * 4. check for IPv4 subnetwork i.e. xx.xx.xx.xx/n
+ * TODO: check for IPv6 subnetwork
+ * NB: Wildcard must not be mixed with subnetwork.
+ */
+ if (*cp == '/') {
+ return valid_ipv4_subnetwork(address);
+ }
+ }
+
+ /* 5. Check for v4/v6 IP addr and FQDN/hostname */
+ length = strlen(address);
+ if ((valid_ipv4_address(address, length, _gf_false)) ||
+ (valid_ipv6_address(address, length, _gf_false)) ||
+ (valid_host_name(address, length))) {
+ return _gf_true;
+ }
+
+ return _gf_false;
}
-int
-gf_string2ulong_base10 (const char *str, unsigned long *n)
+/**
+ * gf_sock_union_equal_addr - check if two given gf_sock_unions have same addr
+ *
+ * @param a - first sock union
+ * @param b - second sock union
+ * @return _gf_true if a and b have same ipv{4,6} addr, _gf_false otherwise
+ */
+gf_boolean_t
+gf_sock_union_equal_addr(union gf_sock_union *a, union gf_sock_union *b)
{
- return _gf_string2ulong (str, n, 10);
+ if (!a || !b) {
+ gf_smsg("common-utils", GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY,
+ "gf_sock_union_equal_addr", NULL);
+ return _gf_false;
+ }
+
+ if (a->storage.ss_family != b->storage.ss_family)
+ return _gf_false;
+
+ switch (a->storage.ss_family) {
+ case AF_INET:
+ if (a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr)
+ return _gf_true;
+ else
+ return _gf_false;
+
+ case AF_INET6:
+ if (memcmp((void *)(&a->sin6.sin6_addr),
+ (void *)(&b->sin6.sin6_addr), sizeof(a->sin6.sin6_addr)))
+ return _gf_false;
+ else
+ return _gf_true;
+
+ default:
+ gf_msg_debug("common-utils", 0,
+ "Unsupported/invalid address "
+ "family");
+ break;
+ }
+
+ return _gf_false;
}
-int
-gf_string2uint_base10 (const char *str, unsigned int *n)
+/*
+ * Check if both have same network address.
+ * Extract the network address from the sockaddr(s) addr by applying the
+ * network mask. If they match, return boolean _gf_true, _gf_false otherwise.
+ *
+ * (x == y) <=> (x ^ y == 0)
+ * (x & y) ^ (x & z) <=> x & (y ^ z)
+ *
+ * ((ip1 & mask) == (ip2 & mask)) <=> ((mask & (ip1 ^ ip2)) == 0)
+ */
+gf_boolean_t
+mask_match(const uint32_t a, const uint32_t b, const uint32_t m)
{
- return _gf_string2uint (str, n, 10);
+ return (((a ^ b) & m) == 0);
}
-int
-gf_string2uint8_base10 (const char *str, uint8_t *n)
+/*Thread safe conversion function*/
+char *
+uuid_utoa(uuid_t uuid)
{
- unsigned long l = 0L;
- int rv = 0;
+ char *uuid_buffer = glusterfs_uuid_buf_get();
+ gf_uuid_unparse(uuid, uuid_buffer);
+ return uuid_buffer;
+}
- rv = _gf_string2ulong (str, &l, 10);
- if (rv != 0)
- return rv;
+/*Re-entrant conversion function*/
+char *
+uuid_utoa_r(uuid_t uuid, char *dst)
+{
+ if (!dst)
+ return NULL;
+ gf_uuid_unparse(uuid, dst);
+ return dst;
+}
- if (l >= 0 && l <= UINT8_MAX)
- {
- *n = (uint8_t) l;
- return 0;
+/*Thread safe conversion function*/
+char *
+lkowner_utoa(gf_lkowner_t *lkowner)
+{
+ char *lkowner_buffer = glusterfs_lkowner_buf_get();
+ lkowner_unparse(lkowner, lkowner_buffer, GF_LKOWNER_BUF_SIZE);
+ return lkowner_buffer;
+}
+
+/*Re-entrant conversion function*/
+char *
+lkowner_utoa_r(gf_lkowner_t *lkowner, char *dst, int len)
+{
+ if (!dst)
+ return NULL;
+ lkowner_unparse(lkowner, dst, len);
+ return dst;
+}
+
+gf_boolean_t
+is_valid_lease_id(const char *lease_id)
+{
+ int i = 0;
+ gf_boolean_t valid = _gf_false;
+
+ for (i = 0; i < LEASE_ID_SIZE; i++) {
+ if (lease_id[i] != 0) {
+ valid = _gf_true;
+ goto out;
}
+ }
+out:
+ return valid;
+}
- errno = ERANGE;
- return -1;
+/* Lease_id can be a either in printable or non printable binary
+ * format. This function can be used to print any lease_id.
+ *
+ * This function returns a pointer to a buf, containing the ascii
+ * representation of the value in lease_id, in the following format:
+ * 4hexnum-4hexnum-4hexnum-4hexnum-4hexnum-4hexnum-4hexnum-4hexnum
+ *
+ * Eg: If lease_id = "lid1-clnt1" the printable string would be:
+ * 6c69-6431-2d63-6c6e-7431-0000-0000-0000
+ *
+ * Note: The pointer returned should not be stored for further use, as any
+ * subsequent call to this function will override the same buffer.
+ */
+char *
+leaseid_utoa(const char *lease_id)
+{
+ char *buf = NULL;
+ int i = 0;
+ int j = 0;
+
+ buf = glusterfs_leaseid_buf_get();
+ if (!buf)
+ goto out;
+
+ for (i = 0; i < LEASE_ID_SIZE; i++) {
+ if (i && !(i % 2)) {
+ buf[j] = '-';
+ j++;
+ }
+ sprintf(&buf[j], "%02hhx", lease_id[i]);
+ j += 2;
+ if (j == GF_LEASE_ID_BUF_SIZE)
+ break;
+ }
+ buf[GF_LEASE_ID_BUF_SIZE - 1] = '\0';
+out:
+ return buf;
+}
+
+char *
+gf_leaseid_get()
+{
+ return glusterfs_leaseid_buf_get();
+}
+
+char *
+gf_existing_leaseid()
+{
+ return glusterfs_leaseid_exist();
+}
+
+void *
+gf_array_elem(void *a, int index, size_t elem_size)
+{
+ uint8_t *ptr = a;
+ return (void *)(ptr + index * elem_size);
+}
+
+void
+gf_elem_swap(void *x, void *y, size_t l)
+{
+ uint8_t *a = x, *b = y, c;
+ while (l--) {
+ c = *a;
+ *a++ = *b;
+ *b++ = c;
+ }
+}
+
+void
+gf_array_insertionsort(void *A, int l, int r, size_t elem_size, gf_cmp cmp)
+{
+ int i = l;
+ int N = r + 1;
+ void *Temp = NULL;
+ int j = 0;
+
+ for (i = l; i < N; i++) {
+ Temp = gf_array_elem(A, i, elem_size);
+ j = i - 1;
+ while (j >= 0 && (cmp(Temp, gf_array_elem(A, j, elem_size)) < 0)) {
+ gf_elem_swap(Temp, gf_array_elem(A, j, elem_size), elem_size);
+ Temp = gf_array_elem(A, j, elem_size);
+ j = j - 1;
+ }
+ }
}
int
-gf_string2uint16_base10 (const char *str, uint16_t *n)
+gf_is_str_int(const char *value)
{
- unsigned long l = 0L;
- int rv = 0;
+ int flag = 0;
+ char *str = NULL;
+ char *fptr = NULL;
- rv = _gf_string2ulong (str, &l, 10);
- if (rv != 0)
- return rv;
+ GF_VALIDATE_OR_GOTO(THIS->name, value, out);
- if (l >= 0 && l <= UINT16_MAX)
- {
- *n = (uint16_t) l;
- return 0;
+ str = gf_strdup(value);
+ if (!str)
+ goto out;
+
+ fptr = str;
+
+ while (*str) {
+ if (!isdigit(*str)) {
+ flag = 1;
+ goto out;
}
+ str++;
+ }
- errno = ERANGE;
- return -1;
+out:
+ GF_FREE(fptr);
+
+ return flag;
+}
+/*
+ * rounds up nr to power of two. If nr is already a power of two, just returns
+ * nr
+ */
+
+int32_t
+gf_roundup_power_of_two(int32_t nr)
+{
+ int32_t result = 1;
+
+ if (nr < 0) {
+ gf_smsg("common-utils", GF_LOG_WARNING, 0, LG_MSG_NEGATIVE_NUM_PASSED,
+ NULL);
+ result = -1;
+ goto out;
+ }
+
+ while (result < nr)
+ result *= 2;
+
+out:
+ return result;
+}
+
+/*
+ * rounds up nr to next power of two. If nr is already a power of two, next
+ * power of two is returned.
+ */
+
+int32_t
+gf_roundup_next_power_of_two(int32_t nr)
+{
+ int32_t result = 1;
+
+ if (nr < 0) {
+ gf_smsg("common-utils", GF_LOG_WARNING, 0, LG_MSG_NEGATIVE_NUM_PASSED,
+ NULL);
+ result = -1;
+ goto out;
+ }
+
+ while (result <= nr)
+ result *= 2;
+
+out:
+ return result;
}
int
-gf_string2uint32_base10 (const char *str, uint32_t *n)
+validate_brick_name(char *brick)
{
- unsigned long l = 0L;
- int rv = 0;
+ char *delimiter = NULL;
+ int ret = 0;
+ delimiter = strrchr(brick, ':');
+ if (!delimiter || delimiter == brick || *(delimiter + 1) != '/')
+ ret = -1;
- rv = _gf_string2ulong (str, &l, 10);
- if (rv != 0)
- return rv;
+ return ret;
+}
- if (l >= 0 && l <= UINT32_MAX)
- {
- *n = (uint32_t) l;
- return 0;
- }
+char *
+get_host_name(char *word, char **host)
+{
+ char *delimiter = NULL;
+ delimiter = strrchr(word, ':');
+ if (delimiter)
+ *delimiter = '\0';
+ else
+ return NULL;
+ *host = word;
+ return *host;
+}
- errno = ERANGE;
+char *
+get_path_name(char *word, char **path)
+{
+ char *delimiter = NULL;
+ delimiter = strchr(word, '/');
+ if (!delimiter)
+ return NULL;
+ *path = delimiter;
+ return *path;
+}
+
+void
+gf_path_strip_trailing_slashes(char *path)
+{
+ int i = 0;
+ int len = 0;
+
+ if (!path)
+ return;
+
+ len = strlen(path);
+ for (i = len - 1; i > 0; i--) {
+ if (path[i] != '/')
+ break;
+ }
+
+ if (i < (len - 1))
+ path[i + 1] = '\0';
+
+ return;
+}
+
+uint64_t
+get_mem_size()
+{
+ uint64_t memsize = -1;
+
+#if defined GF_LINUX_HOST_OS || defined GF_SOLARIS_HOST_OS
+
+ uint64_t page_size = 0;
+ uint64_t num_pages = 0;
+
+ page_size = sysconf(_SC_PAGESIZE);
+ num_pages = sysconf(_SC_PHYS_PAGES);
+
+ memsize = page_size * num_pages;
+#endif
+
+#if defined GF_DARWIN_HOST_OS || defined __FreeBSD__
+
+ size_t len = sizeof(memsize);
+ int name[] = {CTL_HW, HW_PHYSMEM};
+
+ sysctl(name, 2, &memsize, &len, NULL, 0);
+#endif
+
+#if defined __NetBSD__
+
+ size_t len = sizeof(memsize);
+ int name64[] = {CTL_HW, HW_PHYSMEM64};
+
+ sysctl(name64, 2, &memsize, &len, NULL, 0);
+ if (memsize == -1)
+ sysctl(name64, 2, &memsize, &len, NULL, 0);
+#endif
+ return memsize;
+}
+
+/* Strips all whitespace characters in a string and returns length of new string
+ * on success
+ */
+int
+gf_strip_whitespace(char *str, int len)
+{
+ int i = 0;
+ int new_len = 0;
+ char *new_str = NULL;
+
+ GF_ASSERT(str);
+
+ new_str = GF_MALLOC(len + 1, gf_common_mt_char);
+ if (new_str == NULL)
return -1;
+
+ for (i = 0; i < len; i++) {
+ if (!isspace(str[i]))
+ new_str[new_len++] = str[i];
+ }
+ new_str[new_len] = '\0';
+
+ if (new_len != len) {
+ snprintf(str, new_len + 1, "%s", new_str);
+ }
+
+ GF_FREE(new_str);
+ return new_len;
}
int
-gf_string2uint64_base10 (const char *str, uint64_t *n)
+gf_canonicalize_path(char *path)
{
- unsigned long long l = 0ULL;
- int rv = 0;
+ int ret = -1;
+ int path_len = 0;
+ int dir_path_len = 0;
+ char *tmppath = NULL;
+ char *dir = NULL;
+ char *tmpstr = NULL;
- rv = _gf_string2ulonglong (str, &l, 10);
- if (rv != 0)
- return rv;
+ if (!path || *path != '/')
+ goto out;
- if (l >= 0 && l <= UINT64_MAX)
- {
- *n = (uint64_t) l;
- return 0;
+ if (!strcmp(path, "/"))
+ return 0;
+
+ tmppath = gf_strdup(path);
+ if (!tmppath)
+ goto out;
+
+ /* Strip the extra slashes and return */
+ bzero(path, strlen(path));
+ path[0] = '/';
+ dir = strtok_r(tmppath, "/", &tmpstr);
+
+ while (dir) {
+ dir_path_len = strlen(dir);
+ memcpy((path + path_len + 1), dir, dir_path_len);
+ path_len += dir_path_len + 1;
+ dir = strtok_r(NULL, "/", &tmpstr);
+ if (dir) {
+ path[path_len] = '/';
}
+ }
+ path[path_len] = '\0';
+ ret = 0;
- errno = ERANGE;
- return -1;
+out:
+ if (ret)
+ gf_smsg("common-utils", GF_LOG_ERROR, 0, LG_MSG_PATH_ERROR, NULL);
+
+ GF_FREE(tmppath);
+
+ return ret;
+}
+
+static const char *__gf_timefmts[] = {
+ "%F %T", "%Y/%m/%d-%T", "%b %d %T", "%F %H%M%S", "%Y-%m-%d-%T", "%s",
+};
+
+static const char *__gf_zerotimes[] = {
+ "0000-00-00 00:00:00", "0000/00/00-00:00:00", "xxx 00 00:00:00",
+ "0000-00-00 000000", "0000-00-00-00:00:00", "0",
+};
+
+void
+_gf_timestuff(const char ***fmts, const char ***zeros)
+{
+ *fmts = __gf_timefmts;
+ *zeros = __gf_zerotimes;
+}
+
+char *
+generate_glusterfs_ctx_id(void)
+{
+ uuid_t ctxid;
+ char *tmp = NULL;
+
+ gf_uuid_generate(ctxid);
+ tmp = uuid_utoa(ctxid);
+
+ return gf_strdup(tmp);
}
char *
-gf_uint64_2human_readable (uint64_t n)
-{
- int ret = 0;
- char *str = NULL;
-
- if (n >= GF_UNIT_PB) {
- ret = gf_asprintf (&str, "%.1lfPB", ((double) n)/GF_UNIT_PB);
- if (ret < 0)
- goto err;
- } else if (n >= GF_UNIT_TB) {
- ret = gf_asprintf (&str, "%.1lfTB", ((double) n)/GF_UNIT_TB);
- if (ret < 0)
- goto err;
- } else if (n >= GF_UNIT_GB) {
- ret = gf_asprintf (&str, "%.1lfGB", ((double) n)/GF_UNIT_GB);
- if (ret < 0)
- goto err;
- } else if (n >= GF_UNIT_MB) {
- ret = gf_asprintf (&str, "%.1lfMB", ((double) n)/GF_UNIT_MB);
- if (ret < 0)
- goto err;
- } else if (n >= GF_UNIT_KB) {
- ret = gf_asprintf (&str, "%.1lfKB", ((double) n)/GF_UNIT_KB);
- if (ret < 0)
- goto err;
+gf_get_reserved_ports()
+{
+ char *ports_info = NULL;
+#if defined GF_LINUX_HOST_OS
+ int proc_fd = -1;
+ char *proc_file = "/proc/sys/net/ipv4/ip_local_reserved_ports";
+ char buffer[4096] = {
+ 0,
+ };
+ int32_t ret = -1;
+
+ proc_fd = open(proc_file, O_RDONLY);
+ if (proc_fd == -1) {
+ /* What should be done in this case? error out from here
+ * and thus stop the glusterfs process from starting or
+ * continue with older method of using any of the available
+ * port? For now 2nd option is considered.
+ */
+ gf_smsg("glusterfs", GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED,
+ " /proc/sys/net/ipv4/ip_local_reserved_ports", NULL);
+ goto out;
+ }
+
+ ret = sys_read(proc_fd, buffer, sizeof(buffer) - 1);
+ if (ret < 0) {
+ gf_smsg("glusterfs", GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED,
+ "file=%s", proc_file, NULL);
+ goto out;
+ }
+
+ buffer[ret] = '\0';
+ ports_info = gf_strdup(buffer);
+
+out:
+ if (proc_fd != -1)
+ sys_close(proc_fd);
+#endif /* GF_LINUX_HOST_OS */
+ return ports_info;
+}
+
+int
+gf_process_reserved_ports(unsigned char *ports, uint32_t ceiling)
+{
+ int ret = -1;
+
+ memset(ports, 0, GF_PORT_ARRAY_SIZE);
+
+#if defined GF_LINUX_HOST_OS
+ char *ports_info = NULL;
+ char *tmp = NULL;
+ char *blocked_port = NULL;
+
+ ports_info = gf_get_reserved_ports();
+ if (!ports_info) {
+ gf_smsg("glusterfs", GF_LOG_WARNING, 0, LG_MSG_RESERVED_PORTS_ERROR,
+ NULL);
+ goto out;
+ }
+
+ blocked_port = strtok_r(ports_info, ",\n", &tmp);
+
+ while (blocked_port) {
+ gf_ports_reserved(blocked_port, ports, ceiling);
+ blocked_port = strtok_r(NULL, ",\n", &tmp);
+ }
+
+ ret = 0;
+
+out:
+ GF_FREE(ports_info);
+
+#else /* FIXME: Non Linux Host */
+ ret = 0;
+#endif /* GF_LINUX_HOST_OS */
+
+ return ret;
+}
+
+gf_boolean_t
+gf_ports_reserved(char *blocked_port, unsigned char *ports, uint32_t ceiling)
+{
+ gf_boolean_t result = _gf_false;
+ char *range_port = NULL;
+ int32_t tmp_port1 = -1;
+ int32_t tmp_port2 = -1;
+
+ if (strstr(blocked_port, "-") == NULL) {
+ /* get rid of the new line character*/
+ if (blocked_port[strlen(blocked_port) - 1] == '\n')
+ blocked_port[strlen(blocked_port) - 1] = '\0';
+ if (gf_string2int32(blocked_port, &tmp_port1) == 0) {
+ if (tmp_port1 > GF_PORT_MAX || tmp_port1 < 0) {
+ gf_smsg("glusterfs-socket", GF_LOG_WARNING, 0,
+ LG_MSG_INVALID_PORT, "port=%d", tmp_port1, NULL);
+ result = _gf_true;
+ goto out;
+ } else {
+ gf_msg_debug("glusterfs", 0,
+ "blocking port "
+ "%d",
+ tmp_port1);
+ BIT_SET(ports, tmp_port1);
+ }
} else {
- ret = gf_asprintf (&str, "%luBytes", n);
- if (ret < 0)
- goto err;
+ gf_smsg("glusterfs-socket", GF_LOG_WARNING, 0, LG_MSG_INVALID_PORT,
+ "port=%s", blocked_port, NULL);
+ result = _gf_true;
+ goto out;
}
- return str;
-err:
- return NULL;
+ } else {
+ range_port = strtok(blocked_port, "-");
+ if (!range_port) {
+ result = _gf_true;
+ goto out;
+ }
+ if (gf_string2int32(range_port, &tmp_port1) == 0) {
+ if (tmp_port1 > ceiling)
+ tmp_port1 = ceiling;
+ if (tmp_port1 < 0)
+ tmp_port1 = 0;
+ }
+ range_port = strtok(NULL, "-");
+ if (!range_port) {
+ result = _gf_true;
+ goto out;
+ }
+ /* get rid of the new line character*/
+ if (range_port[strlen(range_port) - 1] == '\n')
+ range_port[strlen(range_port) - 1] = '\0';
+ if (gf_string2int32(range_port, &tmp_port2) == 0) {
+ if (tmp_port2 > ceiling)
+ tmp_port2 = ceiling;
+ if (tmp_port2 < 0)
+ tmp_port2 = 0;
+ }
+ gf_msg_debug("glusterfs", 0, "lower: %d, higher: %d", tmp_port1,
+ tmp_port2);
+ for (; tmp_port1 <= tmp_port2; tmp_port1++)
+ BIT_SET(ports, tmp_port1);
+ }
+
+out:
+ return result;
}
+/* Takes in client ip{v4,v6} and returns associated hostname, if any
+ * Also, allocates memory for the hostname.
+ * Returns: 0 for success, -1 for failure
+ */
int
-gf_string2bytesize (const char *str, uint64_t *n)
+gf_get_hostname_from_ip(char *client_ip, char **hostname)
{
- uint64_t value = 0ULL;
- char *tail = NULL;
- int old_errno = 0;
- const char *s = NULL;
+ int ret = -1;
+ struct sockaddr *client_sockaddr = NULL;
+ struct sockaddr_in client_sock_in = {0};
+ struct sockaddr_in6 client_sock_in6 = {0};
+ char client_hostname[NI_MAXHOST] = {0};
+ char *client_ip_copy = NULL;
+ char *tmp = NULL;
+ char *ip = NULL;
+ size_t addr_sz = 0;
+
+ /* if ipv4, reverse lookup the hostname to
+ * allow FQDN based rpc authentication
+ */
+ if (!valid_ipv6_address(client_ip, strlen(client_ip), 0) &&
+ !valid_ipv4_address(client_ip, strlen(client_ip), 0)) {
+ /* most times, we get a.b.c.d:port form, so check that */
+ client_ip_copy = gf_strdup(client_ip);
+ if (!client_ip_copy)
+ goto out;
+
+ ip = strtok_r(client_ip_copy, ":", &tmp);
+ } else {
+ ip = client_ip;
+ }
+
+ if (valid_ipv4_address(ip, strlen(ip), 0) == _gf_true) {
+ client_sockaddr = (struct sockaddr *)&client_sock_in;
+ addr_sz = sizeof(client_sock_in);
+ client_sock_in.sin_family = AF_INET;
+ ret = inet_pton(AF_INET, ip, (void *)&client_sock_in.sin_addr.s_addr);
+
+ } else if (valid_ipv6_address(ip, strlen(ip), 0) == _gf_true) {
+ client_sockaddr = (struct sockaddr *)&client_sock_in6;
+ addr_sz = sizeof(client_sock_in6);
+
+ client_sock_in6.sin6_family = AF_INET6;
+ ret = inet_pton(AF_INET6, ip, (void *)&client_sock_in6.sin6_addr);
+ } else {
+ goto out;
+ }
+
+ if (ret != 1) {
+ ret = -1;
+ goto out;
+ }
+
+ /* You cannot just use sizeof (*client_sockaddr), as per the man page
+ * the (getnameinfo) size must be the size of the underlying sockaddr
+ * struct e.g. sockaddr_in6 or sockaddr_in. Failure to do so will
+ * break IPv6 hostname resolution (IPv4 will work only because
+ * the sockaddr_in struct happens to be of the correct size).
+ */
+ ret = getnameinfo(client_sockaddr, addr_sz, client_hostname,
+ sizeof(client_hostname), NULL, 0, 0);
+ if (ret) {
+ gf_smsg("common-utils", GF_LOG_ERROR, 0, LG_MSG_GETNAMEINFO_FAILED,
+ "ip=%s", client_ip, "ret=%s", gai_strerror(ret), NULL);
+ ret = -1;
+ goto out;
+ }
+
+ *hostname = gf_strdup((char *)client_hostname);
+out:
+ if (client_ip_copy)
+ GF_FREE(client_ip_copy);
- if (str == NULL || n == NULL)
- {
- gf_log_callingfn ("", GF_LOG_WARNING, "arguement invalid");
- errno = EINVAL;
- return -1;
- }
+ return ret;
+}
- for (s = str; *s != '\0'; s++)
- {
- if (isspace (*s))
- {
- continue;
- }
- if (*s == '-')
- {
- /* bala: we do not support suffixed (-) sign and
- invalid integer format */
- return -1;
- }
- break;
+gf_boolean_t
+gf_interface_search(char *ip)
+{
+ int32_t ret = -1;
+ gf_boolean_t found = _gf_false;
+ struct ifaddrs *ifaddr, *ifa;
+ int family;
+ char host[NI_MAXHOST];
+ xlator_t *this = NULL;
+ char *pct = NULL;
+
+ this = THIS;
+
+ ret = getifaddrs(&ifaddr);
+
+ if (ret != 0) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0, LG_MSG_GETIFADDRS_FAILED, "ret=%s",
+ gai_strerror(ret), NULL);
+ goto out;
+ }
+
+ for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
+ if (!ifa->ifa_addr) {
+ /*
+ * This seemingly happens if an interface hasn't
+ * been bound to a particular protocol (seen with
+ * TUN devices).
+ */
+ continue;
}
+ family = ifa->ifa_addr->sa_family;
- old_errno = errno;
- errno = 0;
- value = strtoull (str, &tail, 10);
+ if (family != AF_INET && family != AF_INET6)
+ continue;
- if (errno == ERANGE || errno == EINVAL)
- {
- return -1;
+ ret = getnameinfo(ifa->ifa_addr,
+ (family == AF_INET) ? sizeof(struct sockaddr_in)
+ : sizeof(struct sockaddr_in6),
+ host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
+
+ if (ret != 0) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0, LG_MSG_GETNAMEINFO_FAILED,
+ "ret=%s", gai_strerror(ret), NULL);
+ goto out;
}
- if (errno == 0)
- {
- errno = old_errno;
+ /*
+ * Sometimes the address comes back as addr%eth0 or
+ * similar. Since % is an invalid character, we can
+ * strip it out with confidence that doing so won't
+ * harm anything.
+ */
+ pct = index(host, '%');
+ if (pct) {
+ *pct = '\0';
}
- if (tail[0] != '\0')
- {
- if (strcasecmp (tail, GF_UNIT_KB_STRING) == 0)
- {
- value *= GF_UNIT_KB;
- }
- else if (strcasecmp (tail, GF_UNIT_MB_STRING) == 0)
- {
- value *= GF_UNIT_MB;
- }
- else if (strcasecmp (tail, GF_UNIT_GB_STRING) == 0)
- {
- value *= GF_UNIT_GB;
- }
- else if (strcasecmp (tail, GF_UNIT_TB_STRING) == 0)
- {
- value *= GF_UNIT_TB;
- }
- else if (strcasecmp (tail, GF_UNIT_PB_STRING) == 0)
- {
- value *= GF_UNIT_PB;
- }
- else
- {
- /* bala: invalid integer format */
- return -1;
- }
+ if (strncmp(ip, host, NI_MAXHOST) == 0) {
+ gf_msg_debug(this->name, 0,
+ "%s is local address at "
+ "interface %s",
+ ip, ifa->ifa_name);
+ found = _gf_true;
+ goto out;
}
+ }
+out:
+ if (ifaddr)
+ freeifaddrs(ifaddr);
+ return found;
+}
- *n = value;
+char *
+get_ip_from_addrinfo(struct addrinfo *addr, char **ip)
+{
+ char buf[64];
+ void *in_addr = NULL;
+ struct sockaddr_in *s4 = NULL;
+ struct sockaddr_in6 *s6 = NULL;
+
+ switch (addr->ai_family) {
+ case AF_INET:
+ s4 = (struct sockaddr_in *)addr->ai_addr;
+ in_addr = &s4->sin_addr;
+ break;
+
+ case AF_INET6:
+ s6 = (struct sockaddr_in6 *)addr->ai_addr;
+ in_addr = &s6->sin6_addr;
+ break;
+
+ default:
+ gf_smsg("glusterd", GF_LOG_ERROR, 0, LG_MSG_INVALID_FAMILY, NULL);
+ return NULL;
+ }
+
+ if (!inet_ntop(addr->ai_family, in_addr, buf, sizeof(buf))) {
+ gf_smsg("glusterd", GF_LOG_ERROR, 0, LG_MSG_CONVERSION_FAILED, NULL);
+ return NULL;
+ }
- return 0;
+ *ip = gf_strdup(buf);
+ return *ip;
}
-int64_t
-gf_str_to_long_long (const char *number)
+gf_boolean_t
+gf_is_loopback_localhost(const struct sockaddr *sa, char *hostname)
{
- int64_t unit = 1;
- int64_t ret = 0;
- char *endptr = NULL ;
- if (!number)
- return 0;
+ GF_ASSERT(sa);
+
+ gf_boolean_t is_local = _gf_false;
+ const struct in_addr *addr4 = NULL;
+ const struct in6_addr *addr6 = NULL;
+ uint8_t *ap = NULL;
+ struct in6_addr loopbackaddr6 = IN6ADDR_LOOPBACK_INIT;
+
+ switch (sa->sa_family) {
+ case AF_INET:
+ addr4 = &(((struct sockaddr_in *)sa)->sin_addr);
+ ap = (uint8_t *)&addr4->s_addr;
+ if (ap[0] == 127)
+ is_local = _gf_true;
+ break;
+
+ case AF_INET6:
+ addr6 = &(((struct sockaddr_in6 *)sa)->sin6_addr);
+ if (memcmp(addr6, &loopbackaddr6, sizeof(loopbackaddr6)) == 0)
+ is_local = _gf_true;
+ break;
+
+ default:
+ if (hostname)
+ gf_smsg("glusterd", GF_LOG_ERROR, 0, LG_MSG_INVALID_FAMILY,
+ "family=%d", sa->sa_family, "hostname=%s", hostname,
+ NULL);
+ break;
+ }
+
+ return is_local;
+}
- ret = strtoll (number, &endptr, 0);
-
- if (endptr) {
- switch (*endptr) {
- case 'G':
- case 'g':
- if ((* (endptr + 1) == 'B') ||(* (endptr + 1) == 'b'))
- unit = 1024 * 1024 * 1024;
- break;
- case 'M':
- case 'm':
- if ((* (endptr + 1) == 'B') ||(* (endptr + 1) == 'b'))
- unit = 1024 * 1024;
- break;
- case 'K':
- case 'k':
- if ((* (endptr + 1) == 'B') ||(* (endptr + 1) == 'b'))
- unit = 1024;
- break;
- case '%':
- unit = 1;
- break;
- default:
- unit = 1;
- break;
- }
+gf_boolean_t
+gf_is_local_addr(char *hostname)
+{
+ int32_t ret = -1;
+ struct addrinfo *result = NULL;
+ struct addrinfo *res = NULL;
+ gf_boolean_t found = _gf_false;
+ char *ip = NULL;
+ xlator_t *this = NULL;
+ struct addrinfo hints;
+
+ this = THIS;
+
+ memset(&hints, 0, sizeof(hints));
+ /*
+ * Removing AI_ADDRCONFIG from default_hints
+ * for being able to use link local ipv6 addresses
+ */
+ hints.ai_family = AF_UNSPEC;
+
+ ret = getaddrinfo(hostname, NULL, &hints, &result);
+
+ if (ret != 0) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0, LG_MSG_GETADDRINFO_FAILED,
+ "ret=%s", gai_strerror(ret), NULL);
+ goto out;
+ }
+
+ for (res = result; res != NULL; res = res->ai_next) {
+ get_ip_from_addrinfo(res, &ip);
+ gf_msg_debug(this->name, 0, "%s ", ip);
+
+ if (ip) {
+ found = (gf_is_loopback_localhost(res->ai_addr, hostname) ||
+ gf_interface_search(ip));
+ }
+ if (found) {
+ GF_FREE(ip);
+ goto out;
}
- return ret * unit;
+ GF_FREE(ip);
+ /* the above free will not set ip to NULL, and hence, there is
+ double free possible as the loop continues. set ip to NULL. */
+ ip = NULL;
+ }
+
+out:
+ if (result)
+ freeaddrinfo(result);
+
+ if (!found)
+ gf_msg_debug(this->name, 0, "%s is not local", hostname);
+
+ return found;
}
-int
-gf_string2boolean (const char *str, gf_boolean_t *b)
+gf_boolean_t
+gf_is_same_address(char *name1, char *name2)
{
- if (str == NULL) {
- gf_log_callingfn ("", GF_LOG_WARNING, "arguement invalid");
- return -1;
+ struct addrinfo *addr1 = NULL;
+ struct addrinfo *addr2 = NULL;
+ struct addrinfo *p = NULL;
+ struct addrinfo *q = NULL;
+ gf_boolean_t ret = _gf_false;
+ int gai_err = 0;
+ struct addrinfo hints;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+
+ gai_err = getaddrinfo(name1, NULL, &hints, &addr1);
+ if (gai_err != 0) {
+ gf_smsg(name1, GF_LOG_WARNING, 0, LG_MSG_GETADDRINFO_FAILED, "error=%s",
+ gai_strerror(gai_err), NULL);
+ goto out;
+ }
+
+ gai_err = getaddrinfo(name2, NULL, &hints, &addr2);
+ if (gai_err != 0) {
+ gf_smsg(name2, GF_LOG_WARNING, 0, LG_MSG_GETADDRINFO_FAILED, "error=%s",
+ gai_strerror(gai_err), NULL);
+ goto out;
+ }
+
+ for (p = addr1; p; p = p->ai_next) {
+ for (q = addr2; q; q = q->ai_next) {
+ if (p->ai_addrlen != q->ai_addrlen) {
+ continue;
+ }
+ if (memcmp(p->ai_addr, q->ai_addr, p->ai_addrlen)) {
+ continue;
+ }
+ ret = _gf_true;
+ goto out;
}
+ }
- if ((strcasecmp (str, "1") == 0) ||
- (strcasecmp (str, "on") == 0) ||
- (strcasecmp (str, "yes") == 0) ||
- (strcasecmp (str, "true") == 0) ||
- (strcasecmp (str, "enable") == 0)) {
- *b = _gf_true;
- return 0;
- }
+out:
+ if (addr1) {
+ freeaddrinfo(addr1);
+ }
+ if (addr2) {
+ freeaddrinfo(addr2);
+ }
+ return ret;
+}
- if ((strcasecmp (str, "0") == 0) ||
- (strcasecmp (str, "off") == 0) ||
- (strcasecmp (str, "no") == 0) ||
- (strcasecmp (str, "false") == 0) ||
- (strcasecmp (str, "disable") == 0)) {
- *b = _gf_false;
- return 0;
+/*
+ * Processes list of volfile servers.
+ * Format: <host1>:<port1> <host2>:<port2>...
+ */
+int
+gf_process_getspec_servers_list(cmd_args_t *cmd_args, const char *servers_list)
+{
+ char *tmp = NULL;
+ char *address = NULL;
+ char *host = NULL;
+ char *last_colon = NULL;
+ char *save_ptr = NULL;
+ int port = 0;
+ int ret = -1;
+
+ tmp = gf_strdup(servers_list);
+ if (!tmp) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ address = strtok_r(tmp, " ", &save_ptr);
+ if (!address) {
+ errno = EINVAL;
+ goto out;
+ }
+
+ while (1) {
+ last_colon = strrchr(address, ':');
+ if (!last_colon) {
+ errno = EINVAL;
+ ret = -1;
+ break;
+ }
+ *last_colon = '\0';
+ host = address;
+ port = atoi(last_colon + 1);
+ if (port <= 0) {
+ errno = EINVAL;
+ ret = -1;
+ break;
+ }
+ ret = gf_set_volfile_server_common(cmd_args, host,
+ GF_DEFAULT_VOLFILE_TRANSPORT, port);
+ if (ret && errno != EEXIST) {
+ break;
+ }
+ address = strtok_r(NULL, " ", &save_ptr);
+ if (!address) {
+ errno = 0;
+ ret = 0;
+ break;
}
+ }
- return -1;
-}
+out:
+ if (tmp) {
+ GF_FREE(tmp);
+ }
+ return ret;
+}
int
-gf_lockfd (int fd)
+gf_set_volfile_server_common(cmd_args_t *cmd_args, const char *host,
+ const char *transport, int port)
{
- struct gf_flock fl;
+ server_cmdline_t *server = NULL;
+ server_cmdline_t *tmp = NULL;
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO(THIS->name, cmd_args, out);
+ GF_VALIDATE_OR_GOTO(THIS->name, host, out);
+ GF_VALIDATE_OR_GOTO(THIS->name, transport, out);
+
+ server = GF_CALLOC(1, sizeof(server_cmdline_t),
+ gf_common_mt_server_cmdline_t);
+ if (!server) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ INIT_LIST_HEAD(&server->list);
+
+ server->volfile_server = gf_strdup(host);
+ if (!server->volfile_server) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ server->transport = gf_strdup(transport);
+ if (!server->transport) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ server->port = port;
+
+ if (!cmd_args->volfile_server) {
+ cmd_args->volfile_server = server->volfile_server;
+ cmd_args->volfile_server_transport = server->transport;
+ cmd_args->volfile_server_port = server->port;
+ cmd_args->curr_server = server;
+ }
+
+ list_for_each_entry(tmp, &cmd_args->volfile_servers, list)
+ {
+ if ((!strcmp(tmp->volfile_server, server->volfile_server) &&
+ !strcmp(tmp->transport, server->transport) &&
+ (tmp->port == server->port))) {
+ /* Duplicate option given, log and ignore */
+ gf_smsg("gluster", GF_LOG_INFO, EEXIST, LG_MSG_DUPLICATE_ENTRY,
+ NULL);
+ ret = 0;
+ goto out;
+ }
+ }
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
- fl.l_start = 0;
- fl.l_len = 0;
+ list_add_tail(&server->list, &cmd_args->volfile_servers);
- return fcntl (fd, F_SETLK, &fl);
+ ret = 0;
+out:
+ if (-1 == ret) {
+ if (server) {
+ GF_FREE(server->volfile_server);
+ GF_FREE(server->transport);
+ GF_FREE(server);
+ }
+ }
+
+ return ret;
}
+/* Sets log file path from user provided arguments */
+int
+gf_set_log_file_path(cmd_args_t *cmd_args, glusterfs_ctx_t *ctx)
+{
+ int i = 0;
+ int j = 0;
+ int ret = 0;
+ int tmp_len = 0;
+ char tmp_str[1024] = {
+ 0,
+ };
+
+ if (!cmd_args)
+ goto done;
+
+ if (cmd_args->mount_point) {
+ j = 0;
+ i = 0;
+ if (cmd_args->mount_point[0] == '/')
+ i = 1;
+ for (; i < strlen(cmd_args->mount_point); i++, j++) {
+ tmp_str[j] = cmd_args->mount_point[i];
+ if (cmd_args->mount_point[i] == '/')
+ tmp_str[j] = '-';
+ }
+
+ ret = gf_asprintf(&cmd_args->log_file,
+ DEFAULT_LOG_FILE_DIRECTORY "/%s.log", tmp_str);
+ if (ret > 0)
+ ret = 0;
+ goto done;
+ }
+
+ if (ctx && GF_GLUSTERD_PROCESS == ctx->process_mode) {
+ ret = gf_asprintf(&cmd_args->log_file,
+ DEFAULT_LOG_FILE_DIRECTORY "/%s.log", GLUSTERD_NAME);
+ if (ret > 0)
+ ret = 0;
+
+ goto done;
+ }
+
+ if (cmd_args->volfile) {
+ j = 0;
+ i = 0;
+ if (cmd_args->volfile[0] == '/')
+ i = 1;
+ for (; i < strlen(cmd_args->volfile); i++, j++) {
+ tmp_str[j] = cmd_args->volfile[i];
+ if (cmd_args->volfile[i] == '/')
+ tmp_str[j] = '-';
+ }
+ ret = gf_asprintf(&cmd_args->log_file,
+ DEFAULT_LOG_FILE_DIRECTORY "/%s.log", tmp_str);
+ if (ret > 0)
+ ret = 0;
+ goto done;
+ }
+
+ if (cmd_args->volfile_server) {
+ if (strncmp(cmd_args->volfile_server_transport, "unix", 4) == 0) {
+ if (cmd_args->volfile_server[0] == '/')
+ i = 1;
+ tmp_len = strlen(cmd_args->volfile_server);
+ for (j = 0; i < tmp_len; i++, j++) {
+ tmp_str[j] = cmd_args->volfile_server[i];
+ if (cmd_args->volfile_server[i] == '/')
+ tmp_str[j] = '-';
+ }
+ ret = gf_asprintf(&cmd_args->log_file, "%s/%s-%s-%d.log",
+ DEFAULT_LOG_FILE_DIRECTORY, tmp_str,
+ cmd_args->volfile_id, getpid());
+ } else {
+ ret = gf_asprintf(&cmd_args->log_file, "%s/%s-%s-%d.log",
+ DEFAULT_LOG_FILE_DIRECTORY,
+ cmd_args->volfile_server, cmd_args->volfile_id,
+ getpid());
+ }
+ if (ret > 0)
+ ret = 0;
+ }
+done:
+ return ret;
+}
int
-gf_unlockfd (int fd)
+gf_set_log_ident(cmd_args_t *cmd_args)
{
- struct gf_flock fl;
+ int ret = 0;
+ char *ptr = NULL;
+
+ if (cmd_args->log_file == NULL) {
+ /* no ident source */
+ return 0;
+ }
+
+ /* TODO: Some idents would look like, etc-glusterfs-glusterd.vol, which
+ * seems ugly and can be bettered? */
+ /* just get the filename as the ident */
+ if (NULL != (ptr = strrchr(cmd_args->log_file, '/'))) {
+ ret = gf_asprintf(&cmd_args->log_ident, "%s", ptr + 1);
+ } else {
+ ret = gf_asprintf(&cmd_args->log_ident, "%s", cmd_args->log_file);
+ }
+
+ if (ret > 0)
+ ret = 0;
+ else
+ return ret;
- fl.l_type = F_UNLCK;
- fl.l_whence = SEEK_SET;
- fl.l_start = 0;
- fl.l_len = 0;
+ /* remove .log suffix */
+ if (NULL != (ptr = strrchr(cmd_args->log_ident, '.'))) {
+ if (strcmp(ptr, ".log") == 0) {
+ ptr[0] = '\0';
+ }
+ }
- return fcntl (fd, F_SETLK, &fl);
+ return ret;
}
-static void
-compute_checksum (char *buf, size_t size, uint32_t *checksum)
+int
+gf_thread_cleanup_xint(pthread_t thread)
{
- int ret = -1;
- char *checksum_buf = NULL;
+ int ret = 0;
+ void *res = NULL;
- checksum_buf = (char *)(checksum);
+ ret = pthread_cancel(thread);
+ if (ret != 0)
+ goto error_return;
- if (!(*checksum)) {
- checksum_buf [0] = 0xba;
- checksum_buf [1] = 0xbe;
- checksum_buf [2] = 0xb0;
- checksum_buf [3] = 0x0b;
- }
+ ret = pthread_join(thread, &res);
+ if (ret != 0)
+ goto error_return;
- for (ret = 0; ret < (size - 4); ret += 4) {
- checksum_buf[0] ^= (buf[ret]);
- checksum_buf[1] ^= (buf[ret + 1] << 1) ;
- checksum_buf[2] ^= (buf[ret + 2] << 2);
- checksum_buf[3] ^= (buf[ret + 3] << 3);
- }
+ if (res != PTHREAD_CANCELED)
+ goto error_return;
- for (ret = 0; ret <= (size % 4); ret++) {
- checksum_buf[ret] ^= (buf[(size - 4) + ret] << ret);
- }
+ ret = 0;
+
+error_return:
+ return ret;
+}
+void
+gf_thread_set_vname(pthread_t thread, const char *name, va_list args)
+{
+ char thread_name[GF_THREAD_NAME_LIMIT];
+ int ret;
+
+ /* Initialize the thread name with the prefix (not NULL terminated). */
+ memcpy(thread_name, GF_THREAD_NAME_PREFIX,
+ sizeof(GF_THREAD_NAME_PREFIX) - 1);
+
+ ret = vsnprintf(thread_name + sizeof(GF_THREAD_NAME_PREFIX) - 1,
+ sizeof(thread_name) - sizeof(GF_THREAD_NAME_PREFIX) + 1,
+ name, args);
+ if (ret < 0) {
+ gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_PTHREAD_NAMING_FAILED,
+ "name=%s", name, NULL);
return;
+ }
+
+ if (ret >= sizeof(thread_name)) {
+ gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_THREAD_NAME_TOO_LONG,
+ "name=%s", thread_name, NULL);
+ }
+
+#ifdef GF_LINUX_HOST_OS
+ ret = pthread_setname_np(thread, thread_name);
+#elif defined(__NetBSD__)
+ ret = pthread_setname_np(thread, thread_name, NULL);
+#elif defined(__FreeBSD__)
+ pthread_set_name_np(thread, thread_name);
+ ret = 0;
+#else
+ ret = ENOSYS;
+#endif
+ if (ret != 0) {
+ gf_smsg(THIS->name, GF_LOG_WARNING, ret, LG_MSG_SET_THREAD_FAILED,
+ "name=%s", thread_name, NULL);
+ }
}
-#define GF_CHECKSUM_BUF_SIZE 1024
+void
+gf_thread_set_name(pthread_t thread, const char *name, ...)
+{
+ va_list args;
+
+ va_start(args, name);
+ gf_thread_set_vname(thread, name, args);
+ va_end(args);
+}
int
-get_checksum_for_file (int fd, uint32_t *checksum)
+gf_thread_vcreate(pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start_routine)(void *), void *arg, const char *name,
+ va_list args)
{
- int ret = -1;
- char buf[GF_CHECKSUM_BUF_SIZE] = {0,};
+ sigset_t set, old;
+ int ret;
+
+ sigemptyset(&old);
+ sigfillset(&set);
+ sigdelset(&set, SIGSEGV);
+ sigdelset(&set, SIGBUS);
+ sigdelset(&set, SIGILL);
+ sigdelset(&set, SIGSYS);
+ sigdelset(&set, SIGFPE);
+ sigdelset(&set, SIGABRT);
+
+ pthread_sigmask(SIG_BLOCK, &set, &old);
+
+ ret = pthread_create(thread, attr, start_routine, arg);
+ if (ret != 0) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, ret, LG_MSG_THREAD_CREATE_FAILED,
+ NULL);
+ ret = -1;
+ } else if (name != NULL) {
+ gf_thread_set_vname(*thread, name, args);
+ }
+
+ pthread_sigmask(SIG_SETMASK, &old, NULL);
+
+ return ret;
+}
- /* goto first place */
- lseek (fd, 0L, SEEK_SET);
- do {
- ret = read (fd, &buf, GF_CHECKSUM_BUF_SIZE);
- if (ret > 0)
- compute_checksum (buf, GF_CHECKSUM_BUF_SIZE,
- checksum);
- } while (ret > 0);
+int
+gf_thread_create(pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start_routine)(void *), void *arg, const char *name,
+ ...)
+{
+ va_list args;
+ int ret;
- /* set it back */
- lseek (fd, 0L, SEEK_SET);
+ va_start(args, name);
+ ret = gf_thread_vcreate(thread, attr, start_routine, arg, name, args);
+ va_end(args);
- return ret;
+ return ret;
}
+int
+gf_thread_create_detached(pthread_t *thread, void *(*start_routine)(void *),
+ void *arg, const char *name, ...)
+{
+ pthread_attr_t attr;
+ va_list args;
+ int ret = -1;
+
+ ret = pthread_attr_init(&attr);
+ if (ret) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, ret, LG_MSG_PTHREAD_ATTR_INIT_FAILED,
+ NULL);
+ return -1;
+ }
+
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+ va_start(args, name);
+ ret = gf_thread_vcreate(thread, &attr, start_routine, arg, name, args);
+ va_end(args);
+
+ pthread_attr_destroy(&attr);
+
+ return ret;
+}
-/* One should pass the command here with command with full path,
- otherwise, execv will fail */
int
-gf_system (const char *command)
+gf_skip_header_section(int fd, int header_len)
{
- int ret = -1;
- pid_t pid = 0;
- int status = 0;
- int idx = 0;
- char *dupcmd = NULL;
- char *arg = NULL;
- char *tmp = NULL;
- char *argv[100] = { NULL, };
+ int ret = -1;
- dupcmd = gf_strdup (command);
- if (!dupcmd)
- goto out;
+ ret = sys_lseek(fd, header_len, SEEK_SET);
+ if (ret == (off_t)-1) {
+ gf_smsg("", GF_LOG_ERROR, 0, LG_MSG_SKIP_HEADER_FAILED, NULL);
+ } else {
+ ret = 0;
+ }
- pid = fork ();
- if (pid < 0) {
- /* failure */
- goto out;
- }
- if (pid == 0) {
- /* Child process */
- /* Step 0: Prepare the argv */
- arg = strtok_r (dupcmd, " ", &tmp);
- while (arg) {
- argv[idx] = arg;
- arg = strtok_r (NULL, " ", &tmp);
- idx++;
- }
- /* Step 1: Close all 'fd' */
- for (idx = 3; idx < 65536; idx++) {
- close (idx);
- }
- /* Step 2: execv (); */
- ret = execvp (argv[0], argv);
-
- /* Code will not come here at all */
- gf_log ("", GF_LOG_ERROR, "execv of (%s) failed", command);
-
- kill (getpid(), SIGKILL);
- }
- if (pid > 0) {
- /* Current, ie, parent process */
- pid = waitpid (pid, &status, 0);
- if (WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS)
- ret = 0;
- else
- ret = -1;
- }
+ return ret;
+}
+
+/* Below function is use to check at runtime if pid is running */
+
+gf_boolean_t
+gf_is_pid_running(int pid)
+{
+#ifdef __FreeBSD__
+ int ret = -1;
+
+ ret = sys_kill(pid, 0);
+ if (ret < 0) {
+ return _gf_false;
+ }
+#else
+ char fname[32] = {
+ 0,
+ };
+ int fd = -1;
+
+ snprintf(fname, sizeof(fname), "/proc/%d/cmdline", pid);
+
+ fd = sys_open(fname, O_RDONLY, 0);
+ if (fd < 0) {
+ return _gf_false;
+ }
+
+ sys_close(fd);
+#endif
+ return _gf_true;
+}
+
+gf_boolean_t
+gf_is_service_running(char *pidfile, int *pid)
+{
+ FILE *file = NULL;
+ gf_boolean_t running = _gf_false;
+ int ret = 0;
+ int fno = 0;
+
+ file = fopen(pidfile, "r+");
+ if (!file) {
+ goto out;
+ }
+
+ fno = fileno(file);
+ ret = lockf(fno, F_TEST, 0);
+ if (ret == -1) {
+ running = _gf_true;
+ }
+
+ ret = fscanf(file, "%d", pid);
+ if (ret <= 0) {
+ gf_smsg("", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED, "pidfile=%s",
+ pidfile, NULL);
+ *pid = -1;
+ running = _gf_false;
+ goto out;
+ }
+
+ running = gf_is_pid_running(*pid);
out:
- if (dupcmd)
- GF_FREE (dupcmd);
+ if (file)
+ fclose(file);
+ return running;
+}
- return ret;
+/* Check if the pid is > 0 */
+gf_boolean_t
+gf_valid_pid(const char *pid, int length)
+{
+ gf_boolean_t ret = _gf_true;
+ pid_t value = 0;
+ char *end_ptr = NULL;
+
+ if (length <= 0) {
+ ret = _gf_false;
+ goto out;
+ }
+
+ value = strtol(pid, &end_ptr, 10);
+ if (value <= 0) {
+ ret = _gf_false;
+ }
+out:
+ return ret;
+}
+
+static int
+dht_is_linkfile_key(dict_t *this, char *key, data_t *value, void *data)
+{
+ gf_boolean_t *linkfile_key_found = NULL;
+
+ if (!data)
+ goto out;
+
+ linkfile_key_found = data;
+
+ *linkfile_key_found = _gf_true;
+out:
+ return 0;
+}
+
+gf_boolean_t
+dht_is_linkfile(struct iatt *buf, dict_t *dict)
+{
+ gf_boolean_t linkfile_key_found = _gf_false;
+
+ if (!IS_DHT_LINKFILE_MODE(buf))
+ return _gf_false;
+
+ dict_foreach_fnmatch(dict, "*." DHT_LINKFILE_STR, dht_is_linkfile_key,
+ &linkfile_key_found);
+
+ return linkfile_key_found;
}
int
-get_checksum_for_path (char *path, uint32_t *checksum)
+gf_check_log_format(const char *value)
{
- int ret = -1;
- int fd = -1;
+ int log_format = -1;
- GF_ASSERT (path);
- GF_ASSERT (checksum);
+ if (!strcasecmp(value, GF_LOG_FORMAT_NO_MSG_ID))
+ log_format = gf_logformat_traditional;
+ else if (!strcasecmp(value, GF_LOG_FORMAT_WITH_MSG_ID))
+ log_format = gf_logformat_withmsgid;
- fd = open (path, O_RDWR);
+ if (log_format == -1)
+ gf_smsg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_LOG,
+ "possible_values=" GF_LOG_FORMAT_NO_MSG_ID
+ "|" GF_LOG_FORMAT_WITH_MSG_ID,
+ NULL);
- if (fd == -1) {
- gf_log ("", GF_LOG_ERROR, "Unable to open %s, errno: %d",
- path, errno);
- goto out;
- }
+ return log_format;
+}
+
+int
+gf_check_logger(const char *value)
+{
+ int logger = -1;
+
+ if (!strcasecmp(value, GF_LOGGER_GLUSTER_LOG))
+ logger = gf_logger_glusterlog;
+ else if (!strcasecmp(value, GF_LOGGER_SYSLOG))
+ logger = gf_logger_syslog;
+
+ if (logger == -1)
+ gf_smsg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_LOG,
+ "possible_values=" GF_LOGGER_GLUSTER_LOG "|" GF_LOGGER_SYSLOG,
+ NULL);
+
+ return logger;
+}
+
+/* gf_compare_sockaddr compares the given addresses @addr1 and @addr2 for
+ * equality, ie. if they both refer to the same address.
+ *
+ * This was inspired by sock_addr_cmp_addr() from
+ * https://www.opensource.apple.com/source/postfix/postfix-197/postfix/src/util/sock_addr.c
+ */
+gf_boolean_t
+gf_compare_sockaddr(const struct sockaddr *addr1, const struct sockaddr *addr2)
+{
+ GF_ASSERT(addr1 != NULL);
+ GF_ASSERT(addr2 != NULL);
+
+ /* Obviously, the addresses don't match if their families are different
+ */
+ if (addr1->sa_family != addr2->sa_family)
+ return _gf_false;
+
+ if (AF_INET == addr1->sa_family) {
+ if (((struct sockaddr_in *)addr1)->sin_addr.s_addr ==
+ ((struct sockaddr_in *)addr2)->sin_addr.s_addr)
+ return _gf_true;
+
+ } else if (AF_INET6 == addr1->sa_family) {
+ if (memcmp((char *)&((struct sockaddr_in6 *)addr1)->sin6_addr,
+ (char *)&((struct sockaddr_in6 *)addr2)->sin6_addr,
+ sizeof(struct in6_addr)) == 0)
+ return _gf_true;
+ }
+ return _gf_false;
+}
- ret = get_checksum_for_file (fd, checksum);
+/*
+ * gf_set_timestamp:
+ * It sets the mtime and atime of 'dest' file as of 'src'.
+ */
+int
+gf_set_timestamp(const char *src, const char *dest)
+{
+ struct stat sb = {
+ 0,
+ };
+#if defined(HAVE_UTIMENSAT)
+ struct timespec new_time[2] = {{
+ 0,
+ },
+ {
+ 0,
+ }};
+#else
+ struct timeval new_time[2] = {{
+ 0,
+ },
+ {
+ 0,
+ }};
+#endif
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT(this);
+ GF_ASSERT(src);
+ GF_ASSERT(dest);
+
+ ret = sys_stat(src, &sb);
+ if (ret) {
+ gf_smsg(this->name, GF_LOG_ERROR, errno, LG_MSG_FILE_STAT_FAILED,
+ "stat=%s", src, NULL);
+ goto out;
+ }
+ /* The granularity is nano seconds if `utimensat()` is available,
+ * and micro seconds otherwise.
+ */
+#if defined(HAVE_UTIMENSAT)
+ new_time[0].tv_sec = sb.st_atime;
+ new_time[0].tv_nsec = ST_ATIM_NSEC(&sb);
+
+ new_time[1].tv_sec = sb.st_mtime;
+ new_time[1].tv_nsec = ST_MTIM_NSEC(&sb);
+
+ /* dirfd = 0 is ignored because `dest` is an absolute path. */
+ ret = sys_utimensat(AT_FDCWD, dest, new_time, AT_SYMLINK_NOFOLLOW);
+ if (ret) {
+ gf_smsg(this->name, GF_LOG_ERROR, errno, LG_MSG_UTIMENSAT_FAILED,
+ "dest=%s", dest, NULL);
+ }
+#else
+ new_time[0].tv_sec = sb.st_atime;
+ new_time[0].tv_usec = ST_ATIM_NSEC(&sb) / 1000;
+
+ new_time[1].tv_sec = sb.st_mtime;
+ new_time[1].tv_usec = ST_MTIM_NSEC(&sb) / 1000;
+
+ ret = sys_utimes(dest, new_time);
+ if (ret) {
+ gf_smsg(this->name, GF_LOG_ERROR, errno, LG_MSG_UTIMES_FAILED,
+ "dest=%s", dest, NULL);
+ }
+#endif
out:
- if (fd != -1)
- close (fd);
+ return ret;
+}
- return ret;
+static void
+gf_backtrace_end(char *buf, size_t frames)
+{
+ size_t pos = 0;
+
+ if (!buf)
+ return;
+
+ pos = strlen(buf);
+
+ frames = min(frames, GF_BACKTRACE_LEN - pos - 1);
+
+ if (0 == frames)
+ return;
+
+ memset(buf + pos, ')', frames);
+ buf[pos + frames] = '\0';
}
-char *
-strtail (char *str, const char *pattern)
+/*Returns bytes written*/
+static int
+gf_backtrace_append(char *buf, size_t pos, char *framestr)
{
- int i = 0;
+ if (pos >= GF_BACKTRACE_LEN)
+ return -1;
+ return snprintf(buf + pos, GF_BACKTRACE_LEN - pos, "(--> %s ", framestr);
+}
- for (i = 0; str[i] == pattern[i] && str[i]; i++);
+static int
+gf_backtrace_fillframes(char *buf)
+{
+ void *array[GF_BACKTRACE_FRAME_COUNT];
+ size_t frames = 0;
+ FILE *fp = NULL;
+ char callingfn[GF_BACKTRACE_FRAME_COUNT - 2][1024] = {
+ {0},
+ };
+ int ret = -1;
+ int fd = -1;
+ size_t idx = 0;
+ size_t pos = 0;
+ size_t inc = 0;
+ char tmpl[] = "/tmp/glfs-bt-XXXXXX";
+
+ frames = backtrace(array, GF_BACKTRACE_FRAME_COUNT);
+ if (!frames)
+ return -1;
- if (pattern[i] == '\0')
- return str + i;
+ /* coverity[secure_temp] mkstemp uses 0600 as the mode and is safe */
+ fd = mkstemp(tmpl);
+ if (fd == -1)
+ return -1;
- return NULL;
+ /* Calling unlink so that when the file is closed or program
+ * terminates the temporary file is deleted.
+ */
+ ret = sys_unlink(tmpl);
+ if (ret < 0) {
+ gf_smsg(THIS->name, GF_LOG_INFO, 0, LG_MSG_FILE_DELETE_FAILED,
+ "temporary_file=%s", tmpl, NULL);
+ }
+
+ /*The most recent two frames are the calling function and
+ * gf_backtrace_save, which we can infer.*/
+
+ backtrace_symbols_fd(&array[2], frames - 2, fd);
+
+ fp = fdopen(fd, "r");
+ if (!fp) {
+ sys_close(fd);
+ goto out;
+ }
+
+ ret = fseek(fp, 0L, SEEK_SET);
+ if (ret)
+ goto out;
+
+ pos = 0;
+ for (idx = 0; idx < frames - 2; idx++) {
+ ret = fscanf(fp, "%1023s", callingfn[idx]);
+ if (ret == EOF)
+ break;
+ inc = gf_backtrace_append(buf, pos, callingfn[idx]);
+ if (inc == -1)
+ break;
+ pos += inc;
+ }
+ gf_backtrace_end(buf, idx);
+
+out:
+ if (fp)
+ fclose(fp);
+
+ return (idx > 0) ? 0 : -1;
}
-/* RFC 1123 & 952 */
-char
-valid_host_name (char *address, int length)
+/* Optionally takes @buf to save backtrace. If @buf is NULL, uses the
+ * pre-allocated ctx->btbuf to avoid allocating memory while printing
+ * backtrace.
+ * TODO: This API doesn't provide flexibility in terms of no. of frames
+ * of the backtrace is being saved in the buffer. Deferring fixing it
+ * when there is a real-use for that.*/
+
+char *
+gf_backtrace_save(char *buf)
{
- int i = 0;
- char ret = 1;
+ char *bt = NULL;
- if ((length > 75) || (length == 1)) {
- ret = 0;
- goto out;
- }
+ if (!buf) {
+ bt = THIS->ctx->btbuf;
+ GF_ASSERT(bt);
- if (!isalnum (address[length - 1])) {
- ret = 0;
- goto out;
- }
+ } else {
+ bt = buf;
+ }
- for (i = 0; i < length; i++) {
- if (!isalnum (address[i]) && (address[i] != '.')
- && (address[i] != '-')) {
- ret = 0;
- goto out;
- }
+ if ((0 == gf_backtrace_fillframes(bt)))
+ return bt;
+
+ gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_BACKTRACE_SAVE_FAILED, NULL);
+ return NULL;
+}
+
+gf_loglevel_t
+fop_log_level(glusterfs_fop_t fop, int op_errno)
+{
+ /* if gfid doesn't exist ESTALE comes */
+ if (op_errno == ENOENT || op_errno == ESTALE)
+ return GF_LOG_DEBUG;
+
+ if ((fop == GF_FOP_ENTRYLK) || (fop == GF_FOP_FENTRYLK) ||
+ (fop == GF_FOP_FINODELK) || (fop == GF_FOP_INODELK) ||
+ (fop == GF_FOP_LK)) {
+ /*
+ * if non-blocking lock fails EAGAIN comes
+ * if locks xlator is not loaded ENOSYS comes
+ */
+ if (op_errno == EAGAIN || op_errno == ENOSYS)
+ return GF_LOG_DEBUG;
+ }
+
+ if ((fop == GF_FOP_GETXATTR) || (fop == GF_FOP_FGETXATTR)) {
+ if (op_errno == ENOTSUP || op_errno == ENODATA)
+ return GF_LOG_DEBUG;
+ }
+
+ if ((fop == GF_FOP_SETXATTR) || (fop == GF_FOP_FSETXATTR) ||
+ (fop == GF_FOP_REMOVEXATTR) || (fop == GF_FOP_FREMOVEXATTR)) {
+ if (op_errno == ENOTSUP)
+ return GF_LOG_DEBUG;
+ }
+
+ if (fop == GF_FOP_MKNOD || fop == GF_FOP_MKDIR)
+ if (op_errno == EEXIST)
+ return GF_LOG_DEBUG;
+
+ if (fop == GF_FOP_SEEK) {
+#ifdef HAVE_SEEK_HOLE
+ if (op_errno == ENXIO) {
+ return GF_LOG_DEBUG;
}
+#else
+ return GF_LOG_DEBUG;
+#endif
+ }
-out:
- return ret;
+ return GF_LOG_ERROR;
}
-char
-valid_ipv4_address (char *address, int length)
+/* This function will build absolute path of file/directory from the
+ * current location and relative path given from the current location
+ * For example consider our current path is /a/b/c/ and relative path
+ * from current location is ./../x/y/z .After parsing through this
+ * function the absolute path becomes /a/b/x/y/z/.
+ *
+ * The function gives a pointer to absolute path if it is successful
+ * and also returns zero.
+ * Otherwise function gives NULL pointer with returning an err value.
+ *
+ * So the user need to free memory allocated for path.
+ *
+ */
+
+int32_t
+gf_build_absolute_path(char *current_path, char *relative_path, char **path)
{
- int octets = 0;
- int value = 0;
- char *tmp = NULL, *ptr = NULL, *prev = NULL, *endptr = NULL;
- char ret = 1;
+ char *absolute_path = NULL;
+ char *token = NULL;
+ char *component = NULL;
+ char *saveptr = NULL;
+ char *end = NULL;
+ int ret = 0;
+ size_t relativepath_len = 0;
+ size_t currentpath_len = 0;
+ size_t max_absolutepath_len = 0;
+
+ GF_ASSERT(current_path);
+ GF_ASSERT(relative_path);
+ GF_ASSERT(path);
+
+ if (!path || !current_path || !relative_path) {
+ ret = -EFAULT;
+ goto err;
+ }
+ /* Check for current and relative path
+ * current path should be absolute one and start from '/'
+ * relative path should not start from '/'
+ */
+ currentpath_len = strlen(current_path);
+ if (current_path[0] != '/' || (currentpath_len > PATH_MAX)) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_WRONG_VALUE,
+ "current-path=%s", current_path, NULL);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ relativepath_len = strlen(relative_path);
+ if (relative_path[0] == '/' || (relativepath_len > PATH_MAX)) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_WRONG_VALUE,
+ "relative-path=%s", relative_path, NULL);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ /* It is maximum possible value for absolute path */
+ max_absolutepath_len = currentpath_len + relativepath_len + 2;
+
+ absolute_path = GF_CALLOC(1, max_absolutepath_len, gf_common_mt_char);
+ if (!absolute_path) {
+ ret = -ENOMEM;
+ goto err;
+ }
+ absolute_path[0] = '\0';
+
+ /* If current path is root i.e contains only "/", we do not
+ * need to copy it
+ */
+ if (strcmp(current_path, "/") != 0) {
+ strcpy(absolute_path, current_path);
+
+ /* We trim '/' at the end for easier string manipulation */
+ gf_path_strip_trailing_slashes(absolute_path);
+ }
+
+ /* Used to spilt relative path based on '/' */
+ component = gf_strdup(relative_path);
+ if (!component) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ /* In the relative path, we want to consider ".." and "."
+ * if token is ".." , we just need to reduce one level hierarchy
+ * if token is "." , we just ignore it
+ * if token is NULL , end of relative path
+ * if absolute path becomes '\0' and still "..", then it is a bad
+ * relative path, it points to out of boundary area and stop
+ * building the absolute path
+ * All other cases we just concatenate token to the absolute path
+ */
+ for (token = strtok_r(component, "/", &saveptr),
+ end = strchr(absolute_path, '\0');
+ token; token = strtok_r(NULL, "/", &saveptr)) {
+ if (strcmp(token, ".") == 0)
+ continue;
+
+ else if (strcmp(token, "..") == 0) {
+ if (absolute_path[0] == '\0') {
+ ret = -EACCES;
+ goto err;
+ }
+
+ end = strrchr(absolute_path, '/');
+ *end = '\0';
+ } else {
+ ret = snprintf(end, max_absolutepath_len - strlen(absolute_path),
+ "/%s", token);
+ end = strchr(absolute_path, '\0');
+ }
+ }
+
+ if (strlen(absolute_path) > PATH_MAX) {
+ ret = -EINVAL;
+ goto err;
+ }
+ *path = gf_strdup(absolute_path);
- tmp = gf_strdup (address);
- prev = tmp;
- prev = strtok_r (tmp, ".", &ptr);
+err:
+ if (component)
+ GF_FREE(component);
+ if (absolute_path)
+ GF_FREE(absolute_path);
+ return ret;
+}
- while (prev != NULL)
+/* This is an utility function which will recursively delete
+ * a folder and its contents.
+ *
+ * @param delete_path folder to be deleted.
+ *
+ * @return 0 on success and -1 on failure.
+ */
+int
+recursive_rmdir(const char *delete_path)
+{
+ int ret = -1;
+ char path[PATH_MAX] = {
+ 0,
+ };
+ struct stat st = {
+ 0,
+ };
+ DIR *dir = NULL;
+ struct dirent *entry = NULL;
+ struct dirent scratch[2] = {
{
- octets++;
- value = strtol (prev, &endptr, 10);
- if ((value > 255) || (value < 0) || (endptr != NULL)) {
- ret = 0;
- goto out;
- }
-
- prev = strtok_r (NULL, ".", &ptr);
+ 0,
+ },
+ };
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT(this);
+ GF_VALIDATE_OR_GOTO(this->name, delete_path, out);
+
+ dir = sys_opendir(delete_path);
+ if (!dir) {
+ gf_msg_debug(this->name, 0,
+ "Failed to open directory %s. "
+ "Reason : %s",
+ delete_path, strerror(errno));
+ ret = 0;
+ goto out;
+ }
+
+ while ((entry = sys_readdir(dir, scratch))) {
+ if (gf_irrelevant_entry(entry))
+ continue;
+ snprintf(path, PATH_MAX, "%s/%s", delete_path, entry->d_name);
+ ret = sys_lstat(path, &st);
+ if (ret == -1) {
+ gf_msg_debug(this->name, 0,
+ "Failed to stat entry %s :"
+ " %s",
+ path, strerror(errno));
+ (void)sys_closedir(dir);
+ goto out;
}
- if (octets != 4) {
- ret = 0;
+ if (S_ISDIR(st.st_mode))
+ ret = recursive_rmdir(path);
+ else
+ ret = sys_unlink(path);
+
+ if (ret) {
+ gf_msg_debug(this->name, 0,
+ " Failed to remove %s. "
+ "Reason : %s",
+ path, strerror(errno));
}
+ gf_msg_debug(this->name, 0, "%s %s",
+ ret ? "Failed to remove" : "Removed", entry->d_name);
+ }
+
+ ret = sys_closedir(dir);
+ if (ret) {
+ gf_msg_debug(this->name, 0,
+ "Failed to close dir %s. Reason :"
+ " %s",
+ delete_path, strerror(errno));
+ }
+
+ ret = sys_rmdir(delete_path);
+ if (ret) {
+ gf_msg_debug(this->name, 0, "Failed to rmdir: %s,err: %s", delete_path,
+ strerror(errno));
+ }
+
out:
- GF_FREE (tmp);
- return ret;
+ return ret;
+}
+/*
+ * Input: Array of strings 'array' terminating in NULL
+ * string 'elem' to be searched in the array
+ *
+ * Output: Index of the element in the array if found, '-1' otherwise
+ */
+int
+gf_get_index_by_elem(char **array, char *elem)
+{
+ int i = 0;
+
+ for (i = 0; array[i]; i++) {
+ if (strcmp(elem, array[i]) == 0)
+ return i;
+ }
+
+ return -1;
}
-char
-valid_ipv6_address (char *address, int length)
+static int
+get_pathinfo_host(char *pathinfo, char *hostname, size_t size)
+{
+ char *start = NULL;
+ char *end = NULL;
+ int ret = -1;
+ int i = 0;
+
+ if (!pathinfo)
+ goto out;
+
+ start = strchr(pathinfo, ':');
+ if (!start)
+ goto out;
+
+ end = strrchr(pathinfo, ':');
+ if (start == end)
+ goto out;
+
+ memset(hostname, 0, size);
+ i = 0;
+ while (++start != end)
+ hostname[i++] = *start;
+ ret = 0;
+out:
+ return ret;
+}
+
+/*Note: 'pathinfo' should be gathered only from one brick*/
+int
+glusterfs_is_local_pathinfo(char *pathinfo, gf_boolean_t *is_local)
{
- int hex_numbers = 0;
- int value = 0;
- char *tmp = NULL, *ptr = NULL, *prev = NULL, *endptr = NULL;
- char ret = 1;
+ int ret = 0;
+ char pathinfohost[1024] = {0};
+ char localhost[1024] = {0};
- tmp = gf_strdup (address);
- prev = strtok_r (tmp, ":", &ptr);
+ *is_local = _gf_false;
+ ret = get_pathinfo_host(pathinfo, pathinfohost, sizeof(pathinfohost));
+ if (ret)
+ goto out;
- while (prev != NULL)
- {
- hex_numbers++;
- value = strtol (prev, &endptr, 16);
- if ((value > 0xffff) || (value < 0)
- || (endptr != NULL && *endptr != '\0')) {
- ret = 0;
- goto out;
- }
-
- prev = strtok_r (NULL, ":", &ptr);
- }
+ ret = gethostname(localhost, sizeof(localhost));
+ if (ret)
+ goto out;
- if (hex_numbers > 8) {
+ if (!strcmp(localhost, pathinfohost))
+ *is_local = _gf_true;
+out:
+ return ret;
+}
+
+ssize_t
+gf_nread(int fd, void *buf, size_t count)
+{
+ ssize_t ret = 0;
+ ssize_t read_bytes = 0;
+
+ for (read_bytes = 0; read_bytes < count; read_bytes += ret) {
+ ret = sys_read(fd, buf + read_bytes, count - read_bytes);
+ if (ret == 0) {
+ break;
+ } else if (ret < 0) {
+ if (errno == EINTR)
ret = 0;
+ else
+ goto out;
}
+ }
+ ret = read_bytes;
out:
- GF_FREE (tmp);
- return ret;
+ return ret;
}
-char
-valid_internet_address (char *address)
+ssize_t
+gf_nwrite(int fd, const void *buf, size_t count)
{
- char ret = 0;
- int length = 0;
+ ssize_t ret = 0;
+ ssize_t written = 0;
- if (address == NULL) {
- gf_log_callingfn ("", GF_LOG_WARNING, "arguement invalid");
+ for (written = 0; written != count; written += ret) {
+ ret = sys_write(fd, buf + written, count - written);
+ if (ret < 0) {
+ if (errno == EINTR)
+ ret = 0;
+ else
goto out;
}
+ }
- length = strlen (address);
- if (length == 0) {
- goto out;
- }
+ ret = written;
+out:
+ return ret;
+}
- if (valid_ipv4_address (address, length)
- || valid_ipv6_address (address, length)
- || valid_host_name (address, length)) {
- ret = 1;
- }
+void
+gf_free_mig_locks(lock_migration_info_t *locks)
+{
+ lock_migration_info_t *current = NULL;
+ lock_migration_info_t *temp = NULL;
+
+ if (!locks)
+ return;
+
+ if (list_empty(&locks->list))
+ return;
+
+ list_for_each_entry_safe(current, temp, &locks->list, list)
+ {
+ list_del_init(&current->list);
+ GF_FREE(current->client_uid);
+ GF_FREE(current);
+ }
+}
+
+void
+_mask_cancellation(void)
+{
+ (void)pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+}
+
+void
+_unmask_cancellation(void)
+{
+ (void)pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+}
+
+/* This is a wrapper function to add a pointer to a list,
+ * which doesn't contain list member
+ */
+struct list_node *
+_list_node_add(void *ptr, struct list_head *list,
+ int (*compare)(struct list_head *, struct list_head *))
+{
+ struct list_node *node = NULL;
+ if (ptr == NULL || list == NULL)
+ goto out;
+
+ node = GF_CALLOC(1, sizeof(struct list_node), gf_common_list_node);
+
+ if (node == NULL)
+ goto out;
+
+ node->ptr = ptr;
+ if (compare)
+ list_add_order(&node->list, list, compare);
+ else
+ list_add_tail(&node->list, list);
out:
- return ret;
+ return node;
}
-/*Thread safe conversion function*/
-char *
-uuid_utoa (uuid_t uuid)
+struct list_node *
+list_node_add(void *ptr, struct list_head *list)
{
- char *uuid_buffer = glusterfs_uuid_buf_get();
- uuid_unparse (uuid, uuid_buffer);
- return uuid_buffer;
+ return _list_node_add(ptr, list, NULL);
}
-/*Re-entrant conversion function*/
-char *
-uuid_utoa_r (uuid_t uuid, char *dst)
+struct list_node *
+list_node_add_order(void *ptr, struct list_head *list,
+ int (*compare)(struct list_head *, struct list_head *))
{
- if(!dst)
- return NULL;
- uuid_unparse (uuid, dst);
- return dst;
+ return _list_node_add(ptr, list, compare);
}
-void _get_md5_str (char *out_str, size_t outlen,
- const uint8_t *input, int n)
+void
+list_node_del(struct list_node *node)
{
- uint8_t out[MD5_DIGEST_LEN] = {0};
- int j = 0;
+ if (node == NULL)
+ return;
- GF_ASSERT (outlen >= (2*MD5_DIGEST_LEN + 1));
- get_md5 (out, input, n);
- for (j = 0; j < MD5_DIGEST_LEN; j++)
- snprintf(out_str + j * 2, outlen-j*2, "%02x", out[j]);
+ list_del_init(&node->list);
+ GF_FREE(node);
+}
+const char *
+fop_enum_to_pri_string(glusterfs_fop_t fop)
+{
+ switch (fop) {
+ case GF_FOP_OPEN:
+ case GF_FOP_STAT:
+ case GF_FOP_FSTAT:
+ case GF_FOP_LOOKUP:
+ case GF_FOP_ACCESS:
+ case GF_FOP_READLINK:
+ case GF_FOP_OPENDIR:
+ case GF_FOP_STATFS:
+ case GF_FOP_READDIR:
+ case GF_FOP_READDIRP:
+ case GF_FOP_GETACTIVELK:
+ case GF_FOP_SETACTIVELK:
+ case GF_FOP_ICREATE:
+ case GF_FOP_NAMELINK:
+ return "HIGH";
+
+ case GF_FOP_CREATE:
+ case GF_FOP_FLUSH:
+ case GF_FOP_LK:
+ case GF_FOP_INODELK:
+ case GF_FOP_FINODELK:
+ case GF_FOP_ENTRYLK:
+ case GF_FOP_FENTRYLK:
+ case GF_FOP_UNLINK:
+ case GF_FOP_SETATTR:
+ case GF_FOP_FSETATTR:
+ case GF_FOP_MKNOD:
+ case GF_FOP_MKDIR:
+ case GF_FOP_RMDIR:
+ case GF_FOP_SYMLINK:
+ case GF_FOP_RENAME:
+ case GF_FOP_LINK:
+ case GF_FOP_SETXATTR:
+ case GF_FOP_GETXATTR:
+ case GF_FOP_FGETXATTR:
+ case GF_FOP_FSETXATTR:
+ case GF_FOP_REMOVEXATTR:
+ case GF_FOP_FREMOVEXATTR:
+ case GF_FOP_IPC:
+ case GF_FOP_LEASE:
+ return "NORMAL";
+
+ case GF_FOP_READ:
+ case GF_FOP_WRITE:
+ case GF_FOP_FSYNC:
+ case GF_FOP_TRUNCATE:
+ case GF_FOP_FTRUNCATE:
+ case GF_FOP_FSYNCDIR:
+ case GF_FOP_XATTROP:
+ case GF_FOP_FXATTROP:
+ case GF_FOP_RCHECKSUM:
+ case GF_FOP_ZEROFILL:
+ case GF_FOP_FALLOCATE:
+ case GF_FOP_SEEK:
+ return "LOW";
+
+ case GF_FOP_NULL:
+ case GF_FOP_FORGET:
+ case GF_FOP_RELEASE:
+ case GF_FOP_RELEASEDIR:
+ case GF_FOP_GETSPEC:
+ case GF_FOP_MAXVALUE:
+ case GF_FOP_DISCARD:
+ return "LEAST";
+ default:
+ return "UNKNOWN";
+ }
}
-void* gf_array_elem (void *a, int index, size_t elem_size)
+const char *
+gf_inode_type_to_str(ia_type_t type)
{
- uint8_t* ptr = a;
- return (void*)(ptr + index * elem_size);
+ static const char *const str_ia_type[] = {
+ "UNKNOWN", "REGULAR FILE", "DIRECTORY", "LINK",
+ "BLOCK DEVICE", "CHARACTER DEVICE", "PIPE", "SOCKET"};
+ return str_ia_type[type];
+}
+
+gf_boolean_t
+gf_is_zero_filled_stat(struct iatt *buf)
+{
+ if (!buf)
+ return 1;
+
+ /* Do not use st_dev because it is transformed to store the xlator id
+ * in place of the device number. Do not use st_ino because by this time
+ * we've already mapped the root ino to 1 so it is not guaranteed to be
+ * 0.
+ */
+ if ((buf->ia_nlink == 0) && (buf->ia_ctime == 0))
+ return 1;
+
+ return 0;
}
void
-gf_elem_swap (void *x, void *y, size_t l) {
- uint8_t *a = x, *b = y, c;
- while(l--) {
- c = *a;
- *a++ = *b;
- *b++ = c;
+gf_zero_fill_stat(struct iatt *buf)
+{
+ buf->ia_nlink = 0;
+ buf->ia_ctime = 0;
+}
+
+gf_boolean_t
+gf_is_valid_xattr_namespace(char *key)
+{
+ static char *xattr_namespaces[] = {"trusted.", "system.", "user.",
+ "security.", NULL};
+ int i = 0;
+
+ for (i = 0; xattr_namespaces[i]; i++) {
+ if (strncmp(key, xattr_namespaces[i], strlen(xattr_namespaces[i])) == 0)
+ return _gf_true;
+ }
+
+ return _gf_false;
+}
+
+ino_t
+gfid_to_ino(uuid_t gfid)
+{
+ ino_t ino = 0;
+ int32_t i;
+
+ for (i = 8; i < 16; i++) {
+ ino <<= 8;
+ ino += (uint8_t)gfid[i];
+ }
+
+ return ino;
+}
+
+int
+gf_bits_count(uint64_t n)
+{
+ int val = 0;
+#if defined(__GNUC__) || defined(__clang__)
+ val = __builtin_popcountll(n);
+#else
+ n -= (n >> 1) & 0x5555555555555555ULL;
+ n = ((n >> 2) & 0x3333333333333333ULL) + (n & 0x3333333333333333ULL);
+ n = (n + (n >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
+ n += n >> 8;
+ n += n >> 16;
+ n += n >> 32;
+ val = n & 0xFF;
+#endif
+ return val;
+}
+
+int
+gf_bits_index(uint64_t n)
+{
+#if defined(__GNUC__) || defined(__clang__)
+ return __builtin_ffsll(n) - 1;
+#else
+ return ffsll(n) - 1;
+#endif
+}
+
+const char *
+gf_fop_string(glusterfs_fop_t fop)
+{
+ if ((fop > GF_FOP_NULL) && (fop < GF_FOP_MAXVALUE))
+ return gf_fop_list[fop];
+ return "INVALID";
+}
+
+int
+gf_fop_int(char *fop)
+{
+ int i = 0;
+
+ for (i = GF_FOP_NULL + 1; i < GF_FOP_MAXVALUE; i++) {
+ if (strcasecmp(fop, gf_fop_list[i]) == 0)
+ return i;
+ }
+ return -1;
+}
+
+int
+close_fds_except(int *fdv, size_t count)
+{
+ int i = 0;
+ size_t j = 0;
+ gf_boolean_t should_close = _gf_true;
+#ifdef GF_LINUX_HOST_OS
+ DIR *d = NULL;
+ struct dirent *de = NULL;
+ struct dirent scratch[2] = {
+ {
+ 0,
+ },
+ };
+ char *e = NULL;
+
+ d = sys_opendir("/proc/self/fd");
+ if (!d)
+ return -1;
+
+ for (;;) {
+ should_close = _gf_true;
+
+ errno = 0;
+ de = sys_readdir(d, scratch);
+ if (!de || errno != 0)
+ break;
+ i = strtoul(de->d_name, &e, 10);
+ if (*e != '\0' || i == dirfd(d))
+ continue;
+
+ for (j = 0; j < count; j++) {
+ if (i == fdv[j]) {
+ should_close = _gf_false;
+ break;
+ }
+ }
+ if (should_close)
+ sys_close(i);
+ }
+ sys_closedir(d);
+#else /* !GF_LINUX_HOST_OS */
+ struct rlimit rl;
+ int ret = -1;
+
+ ret = getrlimit(RLIMIT_NOFILE, &rl);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < rl.rlim_cur; i++) {
+ should_close = _gf_true;
+ for (j = 0; j < count; j++) {
+ if (i == fdv[j]) {
+ should_close = _gf_false;
+ break;
+ }
}
+ if (should_close)
+ sys_close(i);
+ }
+#endif /* !GF_LINUX_HOST_OS */
+ return 0;
}
-void
-gf_array_insertionsort (void *A, int l, int r, size_t elem_size,
- gf_cmp cmp)
-{
- int i = l;
- int N = r+1;
- void *Temp = NULL;
- int j = 0;
-
- for(i = l; i < N; i++) {
- Temp = gf_array_elem (A, i, elem_size);
- j = i - 1;
- while((cmp (Temp, gf_array_elem (A, j, elem_size)) < 0) && j>=0)
- {
- gf_elem_swap (Temp, gf_array_elem (A, j, elem_size),
- elem_size);
- Temp = gf_array_elem (A, j, elem_size);
- j = j-1;
- }
+/**
+ * gf_getgrouplist - get list of groups to which a user belongs
+ *
+ * A convenience wrapper for getgrouplist(3).
+ *
+ * @param user - same as in getgrouplist(3)
+ * @param group - same as in getgrouplist(3)
+ * @param groups - pointer to a gid_t pointer
+ *
+ * gf_getgrouplist allocates a gid_t buffer which is big enough to
+ * hold the list of auxiliary group ids for user, up to the GF_MAX_AUX_GROUPS
+ * threshold. Upon successful invocation groups will be pointed to that buffer.
+ *
+ * @return success: the number of auxiliary group ids retrieved
+ * failure: -1
+ */
+int
+gf_getgrouplist(const char *user, gid_t group, gid_t **groups)
+{
+ int ret = -1;
+ int ngroups = SMALL_GROUP_COUNT;
+
+ *groups = GF_CALLOC(sizeof(gid_t), ngroups, gf_common_mt_groups_t);
+ if (!*groups)
+ return -1;
+
+ /*
+ * We are running getgrouplist() in a loop until we succeed (or hit
+ * certain exit conditions, see the comments below). This is because
+ * the indicated number of auxiliary groups that we obtain in case of
+ * the failure of the first invocation is not guaranteed to keep its
+ * validity upon the next invocation with a gid buffer of that size.
+ */
+ for (;;) {
+ int ngroups_old = ngroups;
+ ret = getgrouplist(user, group, *groups, &ngroups);
+ if (ret != -1)
+ break;
+
+ if (ngroups >= GF_MAX_AUX_GROUPS) {
+ /*
+ * This should not happen as GF_MAX_AUX_GROUPS is set
+ * to the max value of number of supported auxiliary
+ * groups across all platforms supported by GlusterFS.
+ * However, if it still happened some way, we wouldn't
+ * care about the incompleteness of the result, we'd
+ * just go on with what we got.
+ */
+ return GF_MAX_AUX_GROUPS;
+ } else if (ngroups <= ngroups_old) {
+ /*
+ * There is an edge case that getgrouplist() fails but
+ * ngroups remains the same. This is actually not
+ * specified in getgrouplist(3), but implementations
+ * can do this upon internal failure[1]. To avoid
+ * falling into an infinite loop when this happens, we
+ * break the loop if the getgrouplist call failed
+ * without an increase in the indicated group number.
+ *
+ * [1]
+ * https://sourceware.org/git/?p=glibc.git;a=blob;f=grp/initgroups.c;hb=refs/heads/release/2.25/master#l168
+ */
+ GF_FREE(*groups);
+ return -1;
}
+
+ *groups = GF_REALLOC(*groups, ngroups * sizeof(gid_t));
+ if (!*groups)
+ return -1;
+ }
+ return ret;
}
int
-gf_is_str_int (const char *value)
+glusterfs_compute_sha256(const unsigned char *content, size_t size,
+ char *sha256_hash)
{
- int flag = 0;
- char *str = NULL;
- char *fptr = NULL;
+ SHA256_CTX sha256;
- GF_VALIDATE_OR_GOTO ("", value, out);
+ SHA256_Init(&sha256);
+ SHA256_Update(&sha256, (const unsigned char *)(content), size);
+ SHA256_Final((unsigned char *)sha256_hash, &sha256);
- str = gf_strdup (value);
- if (!str)
- goto out;
+ return 0;
+}
- fptr = str;
+/* * Safe wrapper function for strncpy.
+ * This wrapper makes sure that when there is no null byte among the first n in
+ * source srting for strncpy function call, the string placed in dest will be
+ * null-terminated.
+ */
- while (*str) {
- if (!isdigit(*str)) {
- flag = 1;
- goto out;
- }
- str++;
- }
+char *
+gf_strncpy(char *dest, const char *src, const size_t dest_size)
+{
+ strncpy(dest, src, dest_size - 1);
+ dest[dest_size - 1] = '\0';
+ return dest;
+}
-out:
- if (fptr)
- GF_FREE (fptr);
+int
+gf_replace_old_iatt_in_dict(dict_t *xdata)
+{
+ int ret;
+ struct old_iatt *o_iatt; /* old iatt structure */
+ struct iatt *c_iatt; /* current iatt */
+
+ if (!xdata) {
+ return 0;
+ }
+
+ ret = dict_get_bin(xdata, DHT_IATT_IN_XDATA_KEY, (void **)&c_iatt);
+ if (ret < 0) {
+ return 0;
+ }
+
+ o_iatt = GF_CALLOC(1, sizeof(struct old_iatt), gf_common_mt_char);
+ if (!o_iatt) {
+ return -1;
+ }
- return flag;
+ oldiatt_from_iatt(o_iatt, c_iatt);
+
+ ret = dict_set_bin(xdata, DHT_IATT_IN_XDATA_KEY, o_iatt,
+ sizeof(struct old_iatt));
+ if (ret) {
+ GF_FREE(o_iatt);
+ }
+
+ return ret;
+}
+
+int
+gf_replace_new_iatt_in_dict(dict_t *xdata)
+{
+ int ret;
+ struct old_iatt *o_iatt; /* old iatt structure */
+ struct iatt *c_iatt; /* new iatt */
+
+ if (!xdata) {
+ return 0;
+ }
+
+ ret = dict_get_bin(xdata, DHT_IATT_IN_XDATA_KEY, (void **)&o_iatt);
+ if (ret < 0) {
+ return 0;
+ }
+
+ c_iatt = GF_CALLOC(1, sizeof(struct iatt), gf_common_mt_char);
+ if (!c_iatt) {
+ return -1;
+ }
+
+ iatt_from_oldiatt(c_iatt, o_iatt);
+
+ ret = dict_set_bin(xdata, DHT_IATT_IN_XDATA_KEY, c_iatt,
+ sizeof(struct iatt));
+ if (ret) {
+ GF_FREE(c_iatt);
+ }
+
+ return ret;
+}
+
+xlator_cmdline_option_t *
+find_xlator_option_in_cmd_args_t(const char *option_name, cmd_args_t *args)
+{
+ xlator_cmdline_option_t *pos = NULL;
+ xlator_cmdline_option_t *tmp = NULL;
+
+ list_for_each_entry_safe(pos, tmp, &args->xlator_options, cmd_args)
+ {
+ if (strcmp(pos->key, option_name) == 0)
+ return pos;
+ }
+ return NULL;
}
+int
+gf_d_type_from_ia_type(ia_type_t type)
+{
+ switch (type) {
+ case IA_IFDIR:
+ return DT_DIR;
+ case IA_IFCHR:
+ return DT_CHR;
+ case IA_IFBLK:
+ return DT_BLK;
+ case IA_IFIFO:
+ return DT_FIFO;
+ case IA_IFLNK:
+ return DT_LNK;
+ case IA_IFREG:
+ return DT_REG;
+ case IA_IFSOCK:
+ return DT_SOCK;
+ default:
+ return DT_UNKNOWN;
+ }
+}
+
+int
+gf_nanosleep(uint64_t nsec)
+{
+ struct timespec req;
+ struct timespec rem;
+ int ret = -1;
+
+ req.tv_sec = nsec / GF_SEC_IN_NS;
+ req.tv_nsec = nsec % GF_SEC_IN_NS;
+
+ do {
+ ret = nanosleep(&req, &rem);
+ req = rem;
+ } while (ret == -1 && errno == EINTR);
+
+ return ret;
+}
+
+int
+gf_syncfs(int fd)
+{
+ int ret = 0;
+#if defined(HAVE_SYNCFS)
+ /* Linux with glibc recent enough. */
+ ret = syncfs(fd);
+#elif defined(HAVE_SYNCFS_SYS)
+ /* Linux with no library function. */
+ ret = syscall(SYS_syncfs, fd);
+#else
+ /* Fallback to generic UNIX stuff. */
+ sync();
+#endif
+ return ret;
+}
+
+char **
+get_xattrs_to_heal()
+{
+ return xattrs_to_heal;
+}
diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h
deleted file mode 100644
index e4d30297002..00000000000
--- a/libglusterfs/src/common-utils.h
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _COMMON_UTILS_H
-#define _COMMON_UTILS_H
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdint.h>
-#include <sys/uio.h>
-#include <netdb.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <pthread.h>
-#ifndef GF_BSD_HOST_OS
-#include <alloca.h>
-#endif
-
-void trap (void);
-
-#define GF_UNIVERSAL_ANSWER 42 /* :O */
-
-/* To solve type punned error */
-#define VOID(ptr) ((void **) ((void *) ptr))
-
-#include "logging.h"
-#include "glusterfs.h"
-#include "locking.h"
-#include "mem-pool.h"
-#include "uuid.h"
-
-
-#define min(a,b) ((a)<(b)?(a):(b))
-#define max(a,b) ((a)>(b)?(a):(b))
-#define roof(a,b) ((((a)+(b)-1)/((b)?(b):1))*(b))
-#define floor(a,b) (((a)/((b)?(b):1))*(b))
-
-
-#define GF_UNIT_KB 1024ULL
-#define GF_UNIT_MB 1048576ULL
-#define GF_UNIT_GB 1073741824ULL
-#define GF_UNIT_TB 1099511627776ULL
-#define GF_UNIT_PB 1125899906842624ULL
-
-#define GF_UNIT_KB_STRING "KB"
-#define GF_UNIT_MB_STRING "MB"
-#define GF_UNIT_GB_STRING "GB"
-#define GF_UNIT_TB_STRING "TB"
-#define GF_UNIT_PB_STRING "PB"
-
-#define GEOREP "geo-replication"
-
-enum _gf_boolean
-{
- _gf_false = 0,
- _gf_true = 1
-};
-
-typedef enum _gf_boolean gf_boolean_t;
-typedef int (*gf_cmp) (void *, void *);
-
-void gf_global_variable_init(void);
-
-in_addr_t gf_resolve_ip (const char *hostname, void **dnscache);
-
-void gf_log_volume_file (FILE *specfp);
-void gf_print_trace (int32_t signal);
-
-extern char *gf_fop_list[GF_FOP_MAXVALUE];
-extern char *gf_mgmt_list[GF_MGMT_MAXVALUE];
-
-#define VECTORSIZE(count) (count * (sizeof (struct iovec)))
-
-#define STRLEN_0(str) (strlen(str) + 1)
-#define VALIDATE_OR_GOTO(arg,label) do { \
- if (!arg) { \
- errno = EINVAL; \
- gf_log_callingfn ((this ? (this->name) : \
- "(Govinda! Govinda!)"), \
- GF_LOG_WARNING, \
- "invalid argument: " #arg); \
- goto label; \
- } \
- } while (0);
-
-#define GF_VALIDATE_OR_GOTO(name,arg,label) do { \
- if (!arg) { \
- errno = EINVAL; \
- gf_log_callingfn (name, GF_LOG_ERROR, \
- "invalid argument: " #arg); \
- goto label; \
- } \
- } while (0);
-
-#define GF_VALIDATE_OR_GOTO_WITH_ERROR(name, arg, label, errno, error) do { \
- if (!arg) { \
- errno = error; \
- gf_log_callingfn (name, GF_LOG_ERROR, \
- "invalid argument: " #arg); \
- goto label; \
- } \
- }while (0);
-
-#define GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO(name,arg,label) \
- do { \
- GF_VALIDATE_OR_GOTO (name, arg, label); \
- if ((arg[0]) != '/') { \
- errno = EINVAL; \
- gf_log_callingfn (name, GF_LOG_ERROR, \
- "invalid argument: " #arg); \
- goto label; \
- } \
- } while (0);
-
-#define GF_FILE_CONTENT_REQUESTED(_xattr_req,_content_limit) \
- (dict_get_uint64 (_xattr_req, "glusterfs.content", _content_limit) == 0)
-
-#ifdef DEBUG
-#define GF_ASSERT(x) assert (x);
-#else
-#define GF_ASSERT(x) \
- do { \
- if (!(x)) { \
- gf_log_callingfn ("", GF_LOG_ERROR, \
- "Assertion failed: " #x); \
- } \
- } while (0);
-#endif
-
-#define GF_HIDDEN_PATH ".glusterfs"
-
-static inline void
-iov_free (struct iovec *vector, int count)
-{
- int i;
-
- for (i = 0; i < count; i++)
- FREE (vector[i].iov_base);
-
- GF_FREE (vector);
-}
-
-
-static inline int
-iov_length (const struct iovec *vector, int count)
-{
- int i = 0;
- size_t size = 0;
-
- for (i = 0; i < count; i++)
- size += vector[i].iov_len;
-
- return size;
-}
-
-
-static inline struct iovec *
-iov_dup (struct iovec *vector, int count)
-{
- int bytecount = 0;
- int i;
- struct iovec *newvec = NULL;
-
- bytecount = (count * sizeof (struct iovec));
- newvec = GF_MALLOC (bytecount, gf_common_mt_iovec);
- if (!newvec)
- return NULL;
-
- for (i = 0; i < count; i++) {
- newvec[i].iov_len = vector[i].iov_len;
- newvec[i].iov_base = vector[i].iov_base;
- }
-
- return newvec;
-}
-
-
-static inline int
-iov_subset (struct iovec *orig, int orig_count,
- off_t src_offset, off_t dst_offset,
- struct iovec *new)
-{
- int new_count = 0;
- int i;
- off_t offset = 0;
- size_t start_offset = 0;
- size_t end_offset = 0;
-
-
- for (i = 0; i < orig_count; i++) {
- if ((offset + orig[i].iov_len < src_offset)
- || (offset > dst_offset)) {
- goto not_subset;
- }
-
- if (!new) {
- goto count_only;
- }
-
- start_offset = 0;
- end_offset = orig[i].iov_len;
-
- if (src_offset >= offset) {
- start_offset = (src_offset - offset);
- }
-
- if (dst_offset <= (offset + orig[i].iov_len)) {
- end_offset = (dst_offset - offset);
- }
-
- new[new_count].iov_base = orig[i].iov_base + start_offset;
- new[new_count].iov_len = end_offset - start_offset;
-
- count_only:
- new_count++;
-
- not_subset:
- offset += orig[i].iov_len;
- }
-
- return new_count;
-}
-
-
-static inline void
-iov_unload (char *buf, const struct iovec *vector, int count)
-{
- int i;
- int copied = 0;
-
- for (i = 0; i < count; i++) {
- memcpy (buf + copied, vector[i].iov_base, vector[i].iov_len);
- copied += vector[i].iov_len;
- }
-}
-
-
-static inline int
-mem_0filled (const char *buf, size_t size)
-{
- int i = 0;
- int ret = 0;
-
- for (i = 0; i < size; i++) {
- ret = buf[i];
- if (ret)
- break;
- }
-
- return ret;
-}
-
-
-static inline int
-iov_0filled (struct iovec *vector, int count)
-{
- int i = 0;
- int ret = 0;
-
- for (i = 0; i < count; i++) {
- ret = mem_0filled (vector[i].iov_base, vector[i].iov_len);
- if (ret)
- break;
- }
-
- return ret;
-}
-
-
-static inline void *
-memdup (const void *ptr, size_t size)
-{
- void *newptr = NULL;
-
- newptr = GF_MALLOC (size, gf_common_mt_memdup);
- if (!newptr)
- return NULL;
-
- memcpy (newptr, ptr, size);
- return newptr;
-}
-
-
-char *gf_trim (char *string);
-int gf_strsplit (const char *str, const char *delim,
- char ***tokens, int *token_count);
-int gf_volume_name_validate (const char *volume_name);
-
-int gf_string2long (const char *str, long *n);
-int gf_string2ulong (const char *str, unsigned long *n);
-int gf_string2int (const char *str, int *n);
-int gf_string2uint (const char *str, unsigned int *n);
-int gf_string2double (const char *str, double *n);
-int gf_string2longlong (const char *str, long long *n);
-int gf_string2ulonglong (const char *str, unsigned long long *n);
-
-int gf_string2int8 (const char *str, int8_t *n);
-int gf_string2int16 (const char *str, int16_t *n);
-int gf_string2int32 (const char *str, int32_t *n);
-int gf_string2int64 (const char *str, int64_t *n);
-int gf_string2uint8 (const char *str, uint8_t *n);
-int gf_string2uint16 (const char *str, uint16_t *n);
-int gf_string2uint32 (const char *str, uint32_t *n);
-int gf_string2uint64 (const char *str, uint64_t *n);
-
-int gf_strstr (const char *str, const char *delim, const char *match);
-
-int gf_string2ulong_base10 (const char *str, unsigned long *n);
-int gf_string2uint_base10 (const char *str, unsigned int *n);
-int gf_string2uint8_base10 (const char *str, uint8_t *n);
-int gf_string2uint16_base10 (const char *str, uint16_t *n);
-int gf_string2uint32_base10 (const char *str, uint32_t *n);
-int gf_string2uint64_base10 (const char *str, uint64_t *n);
-
-int gf_string2bytesize (const char *str, uint64_t *n);
-
-int gf_string2boolean (const char *str, gf_boolean_t *b);
-int gf_string2percent (const char *str, uint32_t *n);
-int gf_string2time (const char *str, uint32_t *n);
-
-int gf_lockfd (int fd);
-int gf_unlockfd (int fd);
-
-int get_checksum_for_file (int fd, uint32_t *checksum);
-int log_base2 (unsigned long x);
-
-int gf_system (const char *command);
-int get_checksum_for_path (char *path, uint32_t *checksum);
-
-char *strtail (char *str, const char *pattern);
-
-char valid_host_name (char *address, int length);
-char valid_ipv4_address (char *address, int length);
-char valid_ipv6_address (char *address, int length);
-char valid_internet_address (char *address);
-
-char *uuid_utoa (uuid_t uuid);
-char *uuid_utoa_r (uuid_t uuid, char *dst);
-void _get_md5_str (char *out_str, size_t outlen,
- const uint8_t *input, int n);
-void gf_array_insertionsort (void *a, int l, int r, size_t elem_size,
- gf_cmp cmp);
-int gf_is_str_int (const char *value);
-
-char *gf_uint64_2human_readable (uint64_t);
-#endif /* _COMMON_UTILS_H */
diff --git a/libglusterfs/src/compat-errno.c b/libglusterfs/src/compat-errno.c
index f0362fc00c4..df57e243239 100644
--- a/libglusterfs/src/compat-errno.c
+++ b/libglusterfs/src/compat-errno.c
@@ -1,31 +1,16 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
#include <stdint.h>
-#include "compat-errno.h"
-
+#include "glusterfs/compat-errno.h"
static int32_t gf_error_to_errno_array[1024];
static int32_t gf_errno_to_error_array[1024];
@@ -34,904 +19,937 @@ static int32_t gf_compat_errno_init_done;
#ifdef GF_SOLARIS_HOST_OS
static void
-init_compat_errno_arrays ()
+init_compat_errno_arrays()
{
-/* ENOMSG 35 / * No message of desired type */
- gf_error_to_errno_array[GF_ERROR_CODE_NOMSG] = ENOMSG;
- gf_errno_to_error_array[ENOMSG] = GF_ERROR_CODE_NOMSG;
-
-/* EIDRM 36 / * Identifier removed */
- gf_error_to_errno_array[GF_ERROR_CODE_IDRM] = EIDRM;
- gf_errno_to_error_array[EIDRM] = GF_ERROR_CODE_IDRM;
-
-/* ECHRNG 37 / * Channel number out of range */
- gf_error_to_errno_array[GF_ERROR_CODE_CHRNG] = ECHRNG;
- gf_errno_to_error_array[ECHRNG] = GF_ERROR_CODE_CHRNG;
-
-/* EL2NSYNC 38 / * Level 2 not synchronized */
- gf_error_to_errno_array[GF_ERROR_CODE_L2NSYNC] = EL2NSYNC;
- gf_errno_to_error_array[EL2NSYNC] = GF_ERROR_CODE_L2NSYNC;
-
-/* EL3HLT 39 / * Level 3 halted */
- gf_error_to_errno_array[GF_ERROR_CODE_L3HLT] = EL3HLT;
- gf_errno_to_error_array[EL3HLT] = GF_ERROR_CODE_L3HLT;
-
-/* EL3RST 40 / * Level 3 reset */
- gf_error_to_errno_array[GF_ERROR_CODE_L3RST] = EL3RST;
- gf_errno_to_error_array[EL3RST] = GF_ERROR_CODE_L3RST;
-
-/* ELNRNG 41 / * Link number out of range */
- gf_error_to_errno_array[GF_ERROR_CODE_LNRNG] = ELNRNG;
- gf_errno_to_error_array[ELNRNG] = GF_ERROR_CODE_LNRNG;
-
-/* EUNATCH 42 / * Protocol driver not attached */
- gf_error_to_errno_array[GF_ERROR_CODE_UNATCH] = EUNATCH;
- gf_errno_to_error_array[EUNATCH] = GF_ERROR_CODE_UNATCH;
-
-/* ENOCSI 43 / * No CSI structure available */
- gf_error_to_errno_array[GF_ERROR_CODE_NOCSI] = ENOCSI;
- gf_errno_to_error_array[ENOCSI] = GF_ERROR_CODE_NOCSI;
-
-/* EL2HLT 44 / * Level 2 halted */
- gf_error_to_errno_array[GF_ERROR_CODE_L2HLT] = EL2HLT;
- gf_errno_to_error_array[EL2HLT] = GF_ERROR_CODE_L2HLT;
-
-/* EDEADLK 45 / * Deadlock condition. */
- gf_error_to_errno_array[GF_ERROR_CODE_DEADLK] = EDEADLK;
- gf_errno_to_error_array[EDEADLK] = GF_ERROR_CODE_DEADLK;
-
-/* ENOLCK 46 / * No record locks available. */
- gf_error_to_errno_array[GF_ERROR_CODE_NOLCK] = ENOLCK;
- gf_errno_to_error_array[ENOLCK] = GF_ERROR_CODE_NOLCK;
-
-/* ECANCELED 47 / * Operation canceled */
- gf_error_to_errno_array[GF_ERROR_CODE_CANCELED] = ECANCELED;
- gf_errno_to_error_array[ECANCELED] = GF_ERROR_CODE_CANCELED;
-
-/* ENOTSUP 48 / * Operation not supported */
- gf_error_to_errno_array[GF_ERROR_CODE_NOTSUPP] = ENOTSUP;
- gf_errno_to_error_array[ENOTSUP] = GF_ERROR_CODE_NOTSUPP;
-
-/* Filesystem Quotas */
-/* EDQUOT 49 / * Disc quota exceeded */
- gf_error_to_errno_array[GF_ERROR_CODE_DQUOT] = EDQUOT;
- gf_errno_to_error_array[EDQUOT] = GF_ERROR_CODE_DQUOT;
-
-/* Convergent Error Returns */
-/* EBADE 50 / * invalid exchange */
- gf_error_to_errno_array[GF_ERROR_CODE_BADE] = EBADE;
- gf_errno_to_error_array[EBADE] = GF_ERROR_CODE_BADE;
-/* EBADR 51 / * invalid request descriptor */
- gf_error_to_errno_array[GF_ERROR_CODE_BADR] = EBADR;
- gf_errno_to_error_array[EBADR] = GF_ERROR_CODE_BADR;
-/* EXFULL 52 / * exchange full */
- gf_error_to_errno_array[GF_ERROR_CODE_XFULL] = EXFULL;
- gf_errno_to_error_array[EXFULL] = GF_ERROR_CODE_XFULL;
-/* ENOANO 53 / * no anode */
- gf_error_to_errno_array[GF_ERROR_CODE_NOANO] = ENOANO;
- gf_errno_to_error_array[ENOANO] = GF_ERROR_CODE_NOANO;
-/* EBADRQC 54 / * invalid request code */
- gf_error_to_errno_array[GF_ERROR_CODE_BADRQC] = EBADRQC;
- gf_errno_to_error_array[EBADRQC] = GF_ERROR_CODE_BADRQC;
-/* EBADSLT 55 / * invalid slot */
- gf_error_to_errno_array[GF_ERROR_CODE_BADSLT] = EBADSLT;
- gf_errno_to_error_array[EBADSLT] = GF_ERROR_CODE_BADSLT;
-/* EDEADLOCK 56 / * file locking deadlock error */
-/* This is same as EDEADLK on linux */
- gf_error_to_errno_array[GF_ERROR_CODE_DEADLK] = EDEADLOCK;
- gf_errno_to_error_array[EDEADLOCK] = GF_ERROR_CODE_DEADLK;
-
-/* EBFONT 57 / * bad font file fmt */
- gf_error_to_errno_array[GF_ERROR_CODE_BFONT] = EBFONT;
- gf_errno_to_error_array[EBFONT] = GF_ERROR_CODE_BFONT;
-
-/* Interprocess Robust Locks */
-/* EOWNERDEAD 58 / * process died with the lock */
- gf_error_to_errno_array[GF_ERROR_CODE_OWNERDEAD] = EOWNERDEAD;
- gf_errno_to_error_array[EOWNERDEAD] = GF_ERROR_CODE_OWNERDEAD;
-/* ENOTRECOVERABLE 59 / * lock is not recoverable */
- gf_error_to_errno_array[GF_ERROR_CODE_NOTRECOVERABLE] = ENOTRECOVERABLE;
- gf_errno_to_error_array[ENOTRECOVERABLE] = GF_ERROR_CODE_NOTRECOVERABLE;
-
-/* stream problems */
-/* ENOSTR 60 / * Device not a stream */
- gf_error_to_errno_array[GF_ERROR_CODE_NOSTR] = ENOSTR;
- gf_errno_to_error_array[ENOSTR] = GF_ERROR_CODE_NOSTR;
-/* ENODATA 61 / * no data (for no delay io) */
- gf_error_to_errno_array[GF_ERROR_CODE_NODATA] = ENODATA;
- gf_errno_to_error_array[ENODATA] = GF_ERROR_CODE_NODATA;
-/* ETIME 62 / * timer expired */
- gf_error_to_errno_array[GF_ERROR_CODE_TIME] = ETIME;
- gf_errno_to_error_array[ETIME] = GF_ERROR_CODE_TIME;
-/* ENOSR 63 / * out of streams resources */
- gf_error_to_errno_array[GF_ERROR_CODE_NOSR] = ENOSR;
- gf_errno_to_error_array[ENOSR] = GF_ERROR_CODE_NOSR;
-
-/* ENONET 64 / * Machine is not on the network */
- gf_error_to_errno_array[GF_ERROR_CODE_NONET] = ENONET;
- gf_errno_to_error_array[ENONET] = GF_ERROR_CODE_NONET;
-/* ENOPKG 65 / * Package not installed */
- gf_error_to_errno_array[GF_ERROR_CODE_NOPKG] = ENOPKG;
- gf_errno_to_error_array[ENOPKG] = GF_ERROR_CODE_NOPKG;
-/* EREMOTE 66 / * The object is remote */
- gf_error_to_errno_array[GF_ERROR_CODE_REMOTE] = EREMOTE;
- gf_errno_to_error_array[EREMOTE] = GF_ERROR_CODE_REMOTE;
-/* ENOLINK 67 / * the link has been severed */
- gf_error_to_errno_array[GF_ERROR_CODE_NOLINK] = ENOLINK;
- gf_errno_to_error_array[ENOLINK] = GF_ERROR_CODE_NOLINK;
-/* EADV 68 / * advertise error */
- gf_error_to_errno_array[GF_ERROR_CODE_ADV] = EADV;
- gf_errno_to_error_array[EADV] = GF_ERROR_CODE_ADV;
-/* ESRMNT 69 / * srmount error */
- gf_error_to_errno_array[GF_ERROR_CODE_SRMNT] = ESRMNT;
- gf_errno_to_error_array[ESRMNT] = GF_ERROR_CODE_SRMNT;
-
-/* ECOMM 70 / * Communication error on send */
- gf_error_to_errno_array[GF_ERROR_CODE_COMM] = ECOMM;
- gf_errno_to_error_array[ECOMM] = GF_ERROR_CODE_COMM;
-/* EPROTO 71 / * Protocol error */
- gf_error_to_errno_array[GF_ERROR_CODE_PROTO] = EPROTO;
- gf_errno_to_error_array[EPROTO] = GF_ERROR_CODE_PROTO;
-
-/* Interprocess Robust Locks */
-/* ELOCKUNMAPPED 72 / * locked lock was unmapped */
- gf_error_to_errno_array[GF_ERROR_CODE_LOCKUNMAPPED] = ELOCKUNMAPPED;
- gf_errno_to_error_array[ELOCKUNMAPPED] = GF_ERROR_CODE_LOCKUNMAPPED;
-
-/* ENOTACTIVE 73 / * Facility is not active */
- gf_error_to_errno_array[GF_ERROR_CODE_NOTACTIVE] = ENOTACTIVE;
- gf_errno_to_error_array[ENOTACTIVE] = GF_ERROR_CODE_NOTACTIVE;
-/* EMULTIHOP 74 / * multihop attempted */
- gf_error_to_errno_array[GF_ERROR_CODE_MULTIHOP] = EMULTIHOP;
- gf_errno_to_error_array[EMULTIHOP] = GF_ERROR_CODE_MULTIHOP;
-/* EBADMSG 77 / * trying to read unreadable message */
- gf_error_to_errno_array[GF_ERROR_CODE_BADMSG] = EBADMSG;
- gf_errno_to_error_array[EBADMSG] = GF_ERROR_CODE_BADMSG;
-/* ENAMETOOLONG 78 / * path name is too long */
- gf_error_to_errno_array[GF_ERROR_CODE_NAMETOOLONG] = ENAMETOOLONG;
- gf_errno_to_error_array[ENAMETOOLONG] = GF_ERROR_CODE_NAMETOOLONG;
-/* EOVERFLOW 79 / * value too large to be stored in data type */
- gf_error_to_errno_array[GF_ERROR_CODE_OVERFLOW] = EOVERFLOW;
- gf_errno_to_error_array[EOVERFLOW] = GF_ERROR_CODE_OVERFLOW;
-/* ENOTUNIQ 80 / * given log. name not unique */
- gf_error_to_errno_array[GF_ERROR_CODE_NOTUNIQ] = ENOTUNIQ;
- gf_errno_to_error_array[ENOTUNIQ] = GF_ERROR_CODE_NOTUNIQ;
-/* EBADFD 81 / * f.d. invalid for this operation */
- gf_error_to_errno_array[GF_ERROR_CODE_BADFD] = EBADFD;
- gf_errno_to_error_array[EBADFD] = GF_ERROR_CODE_BADFD;
-/* EREMCHG 82 / * Remote address changed */
- gf_error_to_errno_array[GF_ERROR_CODE_REMCHG] = EREMCHG;
- gf_errno_to_error_array[EREMCHG] = GF_ERROR_CODE_REMCHG;
-
-/* shared library problems */
-/* ELIBACC 83 / * Can't access a needed shared lib. */
- gf_error_to_errno_array[GF_ERROR_CODE_LIBACC] = ELIBACC;
- gf_errno_to_error_array[ELIBACC] = GF_ERROR_CODE_LIBACC;
-/* ELIBBAD 84 / * Accessing a corrupted shared lib. */
- gf_error_to_errno_array[GF_ERROR_CODE_LIBBAD] = ELIBBAD;
- gf_errno_to_error_array[ELIBBAD] = GF_ERROR_CODE_LIBBAD;
-/* ELIBSCN 85 / * .lib section in a.out corrupted. */
- gf_error_to_errno_array[GF_ERROR_CODE_LIBSCN] = ELIBSCN;
- gf_errno_to_error_array[ELIBSCN] = GF_ERROR_CODE_LIBSCN;
-/* ELIBMAX 86 / * Attempting to link in too many libs. */
- gf_error_to_errno_array[GF_ERROR_CODE_LIBMAX] = ELIBMAX;
- gf_errno_to_error_array[ELIBMAX] = GF_ERROR_CODE_LIBMAX;
-/* ELIBEXEC 87 / * Attempting to exec a shared library. */
- gf_error_to_errno_array[GF_ERROR_CODE_LIBEXEC] = ELIBEXEC;
- gf_errno_to_error_array[ELIBEXEC] = GF_ERROR_CODE_LIBEXEC;
-/* EILSEQ 88 / * Illegal byte sequence. */
- gf_error_to_errno_array[GF_ERROR_CODE_ILSEQ] = EILSEQ;
- gf_errno_to_error_array[EILSEQ] = GF_ERROR_CODE_ILSEQ;
-/* ENOSYS 89 / * Unsupported file system operation */
- gf_error_to_errno_array[GF_ERROR_CODE_NOSYS] = ENOSYS;
- gf_errno_to_error_array[ENOSYS] = GF_ERROR_CODE_NOSYS;
-/* ELOOP 90 / * Symbolic link loop */
- gf_error_to_errno_array[GF_ERROR_CODE_LOOP] = ELOOP;
- gf_errno_to_error_array[ELOOP] = GF_ERROR_CODE_LOOP;
-/* ERESTART 91 / * Restartable system call */
- gf_error_to_errno_array[GF_ERROR_CODE_RESTART] = ERESTART;
- gf_errno_to_error_array[ERESTART] = GF_ERROR_CODE_RESTART;
-/* ESTRPIPE 92 / * if pipe/FIFO, don't sleep in stream head */
- gf_error_to_errno_array[GF_ERROR_CODE_STRPIPE] = ESTRPIPE;
- gf_errno_to_error_array[ESTRPIPE] = GF_ERROR_CODE_STRPIPE;
-/* ENOTEMPTY 93 / * directory not empty */
- gf_error_to_errno_array[GF_ERROR_CODE_NOTEMPTY] = ENOTEMPTY;
- gf_errno_to_error_array[ENOTEMPTY] = GF_ERROR_CODE_NOTEMPTY;
-/* EUSERS 94 / * Too many users (for UFS) */
- gf_error_to_errno_array[GF_ERROR_CODE_USERS] = EUSERS;
- gf_errno_to_error_array[EUSERS] = GF_ERROR_CODE_USERS;
-
-/* BSD Networking Software */
- /* argument errors */
-/* ENOTSOCK 95 / * Socket operation on non-socket */
- gf_error_to_errno_array[GF_ERROR_CODE_NOTSOCK] = ENOTSOCK;
- gf_errno_to_error_array[ENOTSOCK] = GF_ERROR_CODE_NOTSOCK;
-/* EDESTADDRREQ 96 / * Destination address required */
- gf_error_to_errno_array[GF_ERROR_CODE_DESTADDRREQ] = EDESTADDRREQ;
- gf_errno_to_error_array[EDESTADDRREQ] = GF_ERROR_CODE_DESTADDRREQ;
-/* EMSGSIZE 97 / * Message too long */
- gf_error_to_errno_array[GF_ERROR_CODE_MSGSIZE] = EMSGSIZE;
- gf_errno_to_error_array[EMSGSIZE] = GF_ERROR_CODE_MSGSIZE;
-/* EPROTOTYPE 98 / * Protocol wrong type for socket */
- gf_error_to_errno_array[GF_ERROR_CODE_PROTOTYPE] = EPROTOTYPE;
- gf_errno_to_error_array[EPROTOTYPE] = GF_ERROR_CODE_PROTOTYPE;
-/* ENOPROTOOPT 99 / * Protocol not available */
- gf_error_to_errno_array[GF_ERROR_CODE_NOPROTOOPT] = ENOPROTOOPT;
- gf_errno_to_error_array[ENOPROTOOPT] = GF_ERROR_CODE_NOPROTOOPT;
-/* EPROTONOSUPPORT 120 / * Protocol not supported */
- gf_error_to_errno_array[GF_ERROR_CODE_PROTONOSUPPORT] = EPROTONOSUPPORT;
- gf_errno_to_error_array[EPROTONOSUPPORT] = GF_ERROR_CODE_PROTONOSUPPORT;
-/* ESOCKTNOSUPPORT 121 / * Socket type not supported */
- gf_error_to_errno_array[GF_ERROR_CODE_SOCKTNOSUPPORT] = ESOCKTNOSUPPORT;
- gf_errno_to_error_array[ESOCKTNOSUPPORT] = GF_ERROR_CODE_SOCKTNOSUPPORT;
-
-/* EOPNOTSUPP 122 / * Operation not supported on socket */
- gf_error_to_errno_array[GF_ERROR_CODE_OPNOTSUPP] = EOPNOTSUPP;
- gf_errno_to_error_array[EOPNOTSUPP] = GF_ERROR_CODE_OPNOTSUPP;
-/* EPFNOSUPPORT 123 / * Protocol family not supported */
- gf_error_to_errno_array[GF_ERROR_CODE_PFNOSUPPORT] = EPFNOSUPPORT;
- gf_errno_to_error_array[EPFNOSUPPORT] = GF_ERROR_CODE_PFNOSUPPORT;
-/* EAFNOSUPPORT 124 / * Address family not supported by */
- /* protocol family */
- gf_error_to_errno_array[GF_ERROR_CODE_AFNOSUPPORT] = EAFNOSUPPORT;
- gf_errno_to_error_array[EAFNOSUPPORT] = GF_ERROR_CODE_AFNOSUPPORT;
-/* EADDRINUSE 125 / * Address already in use */
- gf_error_to_errno_array[GF_ERROR_CODE_ADDRINUSE] = EADDRINUSE;
- gf_errno_to_error_array[EADDRINUSE] = GF_ERROR_CODE_ADDRINUSE;
-/* EADDRNOTAVAIL 126 / * Can't assign requested address */
- /* operational errors */
- gf_error_to_errno_array[GF_ERROR_CODE_ADDRNOTAVAIL] = EADDRNOTAVAIL;
- gf_errno_to_error_array[EADDRNOTAVAIL] = GF_ERROR_CODE_ADDRNOTAVAIL;
-/* ENETDOWN 127 / * Network is down */
- gf_error_to_errno_array[GF_ERROR_CODE_NETDOWN] = ENETDOWN;
- gf_errno_to_error_array[ENETDOWN] = GF_ERROR_CODE_NETDOWN;
-/* ENETUNREACH 128 / * Network is unreachable */
- gf_error_to_errno_array[GF_ERROR_CODE_NETUNREACH] = ENETUNREACH;
- gf_errno_to_error_array[ENETUNREACH] = GF_ERROR_CODE_NETUNREACH;
-/* ENETRESET 129 / * Network dropped connection because */
- /* of reset */
- gf_error_to_errno_array[GF_ERROR_CODE_NETRESET] = ENETRESET;
- gf_errno_to_error_array[ENETRESET] = GF_ERROR_CODE_NETRESET;
-/* ECONNABORTED 130 / * Software caused connection abort */
- gf_error_to_errno_array[GF_ERROR_CODE_CONNABORTED] = ECONNABORTED;
- gf_errno_to_error_array[ECONNABORTED] = GF_ERROR_CODE_CONNABORTED;
-/* ECONNRESET 131 / * Connection reset by peer */
- gf_error_to_errno_array[GF_ERROR_CODE_CONNRESET] = ECONNRESET;
- gf_errno_to_error_array[ECONNRESET] = GF_ERROR_CODE_CONNRESET;
-/* ENOBUFS 132 / * No buffer space available */
- gf_error_to_errno_array[GF_ERROR_CODE_NOBUFS] = ENOBUFS;
- gf_errno_to_error_array[ENOBUFS] = GF_ERROR_CODE_NOBUFS;
-/* EISCONN 133 / * Socket is already connected */
- gf_error_to_errno_array[GF_ERROR_CODE_ISCONN] = EISCONN;
- gf_errno_to_error_array[EISCONN] = GF_ERROR_CODE_ISCONN;
-/* ENOTCONN 134 / * Socket is not connected */
- gf_error_to_errno_array[GF_ERROR_CODE_NOTCONN] = ENOTCONN;
- gf_errno_to_error_array[ENOTCONN] = GF_ERROR_CODE_NOTCONN;
-/* XENIX has 135 - 142 */
-/* ESHUTDOWN 143 / * Can't send after socket shutdown */
- gf_error_to_errno_array[GF_ERROR_CODE_SHUTDOWN] = ESHUTDOWN;
- gf_errno_to_error_array[ESHUTDOWN] = GF_ERROR_CODE_SHUTDOWN;
-/* ETOOMANYREFS 144 / * Too many references: can't splice */
- gf_error_to_errno_array[GF_ERROR_CODE_TOOMANYREFS] = ETOOMANYREFS;
- gf_errno_to_error_array[ETOOMANYREFS] = GF_ERROR_CODE_TOOMANYREFS;
-/* ETIMEDOUT 145 / * Connection timed out */
- gf_error_to_errno_array[GF_ERROR_CODE_TIMEDOUT] = ETIMEDOUT;
- gf_errno_to_error_array[ETIMEDOUT] = GF_ERROR_CODE_TIMEDOUT;
-
-/* ECONNREFUSED 146 / * Connection refused */
- gf_error_to_errno_array[GF_ERROR_CODE_CONNREFUSED] = ECONNREFUSED;
- gf_errno_to_error_array[ECONNREFUSED] = GF_ERROR_CODE_CONNREFUSED;
-/* EHOSTDOWN 147 / * Host is down */
- gf_error_to_errno_array[GF_ERROR_CODE_HOSTDOWN] = EHOSTDOWN;
- gf_errno_to_error_array[EHOSTDOWN] = GF_ERROR_CODE_HOSTDOWN;
-/* EHOSTUNREACH 148 / * No route to host */
- gf_error_to_errno_array[GF_ERROR_CODE_HOSTUNREACH] = EHOSTUNREACH;
- gf_errno_to_error_array[EHOSTUNREACH] = GF_ERROR_CODE_HOSTUNREACH;
-/* EALREADY 149 / * operation already in progress */
- gf_error_to_errno_array[GF_ERROR_CODE_ALREADY] = EALREADY;
- gf_errno_to_error_array[EALREADY] = GF_ERROR_CODE_ALREADY;
-/* EINPROGRESS 150 / * operation now in progress */
- gf_error_to_errno_array[GF_ERROR_CODE_INPROGRESS] = EINPROGRESS;
- gf_errno_to_error_array[EINPROGRESS] = GF_ERROR_CODE_INPROGRESS;
-
-/* SUN Network File System */
-/* ESTALE 151 / * Stale NFS file handle */
- gf_error_to_errno_array[GF_ERROR_CODE_STALE] = ESTALE;
- gf_errno_to_error_array[ESTALE] = GF_ERROR_CODE_STALE;
-
- return ;
+ /* ENOMSG 35 / * No message of desired type */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOMSG] = ENOMSG;
+ gf_errno_to_error_array[ENOMSG] = GF_ERROR_CODE_NOMSG;
+
+ /* EIDRM 36 / * Identifier removed */
+ gf_error_to_errno_array[GF_ERROR_CODE_IDRM] = EIDRM;
+ gf_errno_to_error_array[EIDRM] = GF_ERROR_CODE_IDRM;
+
+ /* ECHRNG 37 / * Channel number out of range */
+ gf_error_to_errno_array[GF_ERROR_CODE_CHRNG] = ECHRNG;
+ gf_errno_to_error_array[ECHRNG] = GF_ERROR_CODE_CHRNG;
+
+ /* EL2NSYNC 38 / * Level 2 not synchronized */
+ gf_error_to_errno_array[GF_ERROR_CODE_L2NSYNC] = EL2NSYNC;
+ gf_errno_to_error_array[EL2NSYNC] = GF_ERROR_CODE_L2NSYNC;
+
+ /* EL3HLT 39 / * Level 3 halted */
+ gf_error_to_errno_array[GF_ERROR_CODE_L3HLT] = EL3HLT;
+ gf_errno_to_error_array[EL3HLT] = GF_ERROR_CODE_L3HLT;
+
+ /* EL3RST 40 / * Level 3 reset */
+ gf_error_to_errno_array[GF_ERROR_CODE_L3RST] = EL3RST;
+ gf_errno_to_error_array[EL3RST] = GF_ERROR_CODE_L3RST;
+
+ /* ELNRNG 41 / * Link number out of range */
+ gf_error_to_errno_array[GF_ERROR_CODE_LNRNG] = ELNRNG;
+ gf_errno_to_error_array[ELNRNG] = GF_ERROR_CODE_LNRNG;
+
+ /* EUNATCH 42 / * Protocol driver not attached */
+ gf_error_to_errno_array[GF_ERROR_CODE_UNATCH] = EUNATCH;
+ gf_errno_to_error_array[EUNATCH] = GF_ERROR_CODE_UNATCH;
+
+ /* ENOCSI 43 / * No CSI structure available */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOCSI] = ENOCSI;
+ gf_errno_to_error_array[ENOCSI] = GF_ERROR_CODE_NOCSI;
+
+ /* EL2HLT 44 / * Level 2 halted */
+ gf_error_to_errno_array[GF_ERROR_CODE_L2HLT] = EL2HLT;
+ gf_errno_to_error_array[EL2HLT] = GF_ERROR_CODE_L2HLT;
+
+ /* EDEADLK 45 / * Deadlock condition. */
+ gf_error_to_errno_array[GF_ERROR_CODE_DEADLK] = EDEADLK;
+ gf_errno_to_error_array[EDEADLK] = GF_ERROR_CODE_DEADLK;
+
+ /* ENOLCK 46 / * No record locks available. */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOLCK] = ENOLCK;
+ gf_errno_to_error_array[ENOLCK] = GF_ERROR_CODE_NOLCK;
+
+ /* ECANCELED 47 / * Operation canceled */
+ gf_error_to_errno_array[GF_ERROR_CODE_CANCELED] = ECANCELED;
+ gf_errno_to_error_array[ECANCELED] = GF_ERROR_CODE_CANCELED;
+
+ /* ENOTSUP 48 / * Operation not supported */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOTSUPP] = ENOTSUP;
+ gf_errno_to_error_array[ENOTSUP] = GF_ERROR_CODE_NOTSUPP;
+
+ /* Filesystem Quotas */
+ /* EDQUOT 49 / * Disc quota exceeded */
+ gf_error_to_errno_array[GF_ERROR_CODE_DQUOT] = EDQUOT;
+ gf_errno_to_error_array[EDQUOT] = GF_ERROR_CODE_DQUOT;
+
+ /* Convergent Error Returns */
+ /* EBADE 50 / * invalid exchange */
+ gf_error_to_errno_array[GF_ERROR_CODE_BADE] = EBADE;
+ gf_errno_to_error_array[EBADE] = GF_ERROR_CODE_BADE;
+ /* EBADR 51 / * invalid request descriptor */
+ gf_error_to_errno_array[GF_ERROR_CODE_BADR] = EBADR;
+ gf_errno_to_error_array[EBADR] = GF_ERROR_CODE_BADR;
+ /* EXFULL 52 / * exchange full */
+ gf_error_to_errno_array[GF_ERROR_CODE_XFULL] = EXFULL;
+ gf_errno_to_error_array[EXFULL] = GF_ERROR_CODE_XFULL;
+ /* ENOANO 53 / * no anode */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOANO] = ENOANO;
+ gf_errno_to_error_array[ENOANO] = GF_ERROR_CODE_NOANO;
+ /* EBADRQC 54 / * invalid request code */
+ gf_error_to_errno_array[GF_ERROR_CODE_BADRQC] = EBADRQC;
+ gf_errno_to_error_array[EBADRQC] = GF_ERROR_CODE_BADRQC;
+ /* EBADSLT 55 / * invalid slot */
+ gf_error_to_errno_array[GF_ERROR_CODE_BADSLT] = EBADSLT;
+ gf_errno_to_error_array[EBADSLT] = GF_ERROR_CODE_BADSLT;
+ /* EDEADLOCK 56 / * file locking deadlock error */
+ /* This is same as EDEADLK on linux */
+ gf_error_to_errno_array[GF_ERROR_CODE_DEADLK] = EDEADLOCK;
+ gf_errno_to_error_array[EDEADLOCK] = GF_ERROR_CODE_DEADLK;
+
+ /* EBFONT 57 / * bad font file fmt */
+ gf_error_to_errno_array[GF_ERROR_CODE_BFONT] = EBFONT;
+ gf_errno_to_error_array[EBFONT] = GF_ERROR_CODE_BFONT;
+
+ /* Interprocess Robust Locks */
+ /* EOWNERDEAD 58 / * process died with the lock */
+ gf_error_to_errno_array[GF_ERROR_CODE_OWNERDEAD] = EOWNERDEAD;
+ gf_errno_to_error_array[EOWNERDEAD] = GF_ERROR_CODE_OWNERDEAD;
+ /* ENOTRECOVERABLE 59 / * lock is not recoverable */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOTRECOVERABLE] = ENOTRECOVERABLE;
+ gf_errno_to_error_array[ENOTRECOVERABLE] = GF_ERROR_CODE_NOTRECOVERABLE;
+
+ /* stream problems */
+ /* ENOSTR 60 / * Device not a stream */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOSTR] = ENOSTR;
+ gf_errno_to_error_array[ENOSTR] = GF_ERROR_CODE_NOSTR;
+ /* ENODATA 61 / * no data (for no delay io) */
+ gf_error_to_errno_array[GF_ERROR_CODE_NODATA] = ENODATA;
+ gf_errno_to_error_array[ENODATA] = GF_ERROR_CODE_NODATA;
+ /* ETIME 62 / * timer expired */
+ gf_error_to_errno_array[GF_ERROR_CODE_TIME] = ETIME;
+ gf_errno_to_error_array[ETIME] = GF_ERROR_CODE_TIME;
+ /* ENOSR 63 / * out of streams resources */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOSR] = ENOSR;
+ gf_errno_to_error_array[ENOSR] = GF_ERROR_CODE_NOSR;
+
+ /* ENONET 64 / * Machine is not on the network */
+ gf_error_to_errno_array[GF_ERROR_CODE_NONET] = ENONET;
+ gf_errno_to_error_array[ENONET] = GF_ERROR_CODE_NONET;
+ /* ENOPKG 65 / * Package not installed */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOPKG] = ENOPKG;
+ gf_errno_to_error_array[ENOPKG] = GF_ERROR_CODE_NOPKG;
+ /* EREMOTE 66 / * The object is remote */
+ gf_error_to_errno_array[GF_ERROR_CODE_REMOTE] = EREMOTE;
+ gf_errno_to_error_array[EREMOTE] = GF_ERROR_CODE_REMOTE;
+ /* ENOLINK 67 / * the link has been severed */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOLINK] = ENOLINK;
+ gf_errno_to_error_array[ENOLINK] = GF_ERROR_CODE_NOLINK;
+ /* EADV 68 / * advertise error */
+ gf_error_to_errno_array[GF_ERROR_CODE_ADV] = EADV;
+ gf_errno_to_error_array[EADV] = GF_ERROR_CODE_ADV;
+ /* ESRMNT 69 / * srmount error */
+ gf_error_to_errno_array[GF_ERROR_CODE_SRMNT] = ESRMNT;
+ gf_errno_to_error_array[ESRMNT] = GF_ERROR_CODE_SRMNT;
+
+ /* ECOMM 70 / * Communication error on send */
+ gf_error_to_errno_array[GF_ERROR_CODE_COMM] = ECOMM;
+ gf_errno_to_error_array[ECOMM] = GF_ERROR_CODE_COMM;
+ /* EPROTO 71 / * Protocol error */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROTO] = EPROTO;
+ gf_errno_to_error_array[EPROTO] = GF_ERROR_CODE_PROTO;
+
+ /* Interprocess Robust Locks */
+ /* ELOCKUNMAPPED 72 / * locked lock was unmapped */
+ gf_error_to_errno_array[GF_ERROR_CODE_LOCKUNMAPPED] = ELOCKUNMAPPED;
+ gf_errno_to_error_array[ELOCKUNMAPPED] = GF_ERROR_CODE_LOCKUNMAPPED;
+
+ /* ENOTACTIVE 73 / * Facility is not active */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOTACTIVE] = ENOTACTIVE;
+ gf_errno_to_error_array[ENOTACTIVE] = GF_ERROR_CODE_NOTACTIVE;
+ /* EMULTIHOP 74 / * multihop attempted */
+ gf_error_to_errno_array[GF_ERROR_CODE_MULTIHOP] = EMULTIHOP;
+ gf_errno_to_error_array[EMULTIHOP] = GF_ERROR_CODE_MULTIHOP;
+ /* EBADMSG 77 / * trying to read unreadable message */
+ gf_error_to_errno_array[GF_ERROR_CODE_BADMSG] = EBADMSG;
+ gf_errno_to_error_array[EBADMSG] = GF_ERROR_CODE_BADMSG;
+ /* ENAMETOOLONG 78 / * path name is too long */
+ gf_error_to_errno_array[GF_ERROR_CODE_NAMETOOLONG] = ENAMETOOLONG;
+ gf_errno_to_error_array[ENAMETOOLONG] = GF_ERROR_CODE_NAMETOOLONG;
+ /* EOVERFLOW 79 / * value too large to be stored in data type */
+ gf_error_to_errno_array[GF_ERROR_CODE_OVERFLOW] = EOVERFLOW;
+ gf_errno_to_error_array[EOVERFLOW] = GF_ERROR_CODE_OVERFLOW;
+ /* ENOTUNIQ 80 / * given log. name not unique */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOTUNIQ] = ENOTUNIQ;
+ gf_errno_to_error_array[ENOTUNIQ] = GF_ERROR_CODE_NOTUNIQ;
+ /* EBADFD 81 / * f.d. invalid for this operation */
+ gf_error_to_errno_array[GF_ERROR_CODE_BADFD] = EBADFD;
+ gf_errno_to_error_array[EBADFD] = GF_ERROR_CODE_BADFD;
+ /* EREMCHG 82 / * Remote address changed */
+ gf_error_to_errno_array[GF_ERROR_CODE_REMCHG] = EREMCHG;
+ gf_errno_to_error_array[EREMCHG] = GF_ERROR_CODE_REMCHG;
+
+ /* shared library problems */
+ /* ELIBACC 83 / * Can't access a needed shared lib. */
+ gf_error_to_errno_array[GF_ERROR_CODE_LIBACC] = ELIBACC;
+ gf_errno_to_error_array[ELIBACC] = GF_ERROR_CODE_LIBACC;
+ /* ELIBBAD 84 / * Accessing a corrupted shared lib. */
+ gf_error_to_errno_array[GF_ERROR_CODE_LIBBAD] = ELIBBAD;
+ gf_errno_to_error_array[ELIBBAD] = GF_ERROR_CODE_LIBBAD;
+ /* ELIBSCN 85 / * .lib section in a.out corrupted. */
+ gf_error_to_errno_array[GF_ERROR_CODE_LIBSCN] = ELIBSCN;
+ gf_errno_to_error_array[ELIBSCN] = GF_ERROR_CODE_LIBSCN;
+ /* ELIBMAX 86 / * Attempting to link in too many libs. */
+ gf_error_to_errno_array[GF_ERROR_CODE_LIBMAX] = ELIBMAX;
+ gf_errno_to_error_array[ELIBMAX] = GF_ERROR_CODE_LIBMAX;
+ /* ELIBEXEC 87 / * Attempting to exec a shared library. */
+ gf_error_to_errno_array[GF_ERROR_CODE_LIBEXEC] = ELIBEXEC;
+ gf_errno_to_error_array[ELIBEXEC] = GF_ERROR_CODE_LIBEXEC;
+ /* EILSEQ 88 / * Illegal byte sequence. */
+ gf_error_to_errno_array[GF_ERROR_CODE_ILSEQ] = EILSEQ;
+ gf_errno_to_error_array[EILSEQ] = GF_ERROR_CODE_ILSEQ;
+ /* ENOSYS 89 / * Unsupported file system operation */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOSYS] = ENOSYS;
+ gf_errno_to_error_array[ENOSYS] = GF_ERROR_CODE_NOSYS;
+ /* ELOOP 90 / * Symbolic link loop */
+ gf_error_to_errno_array[GF_ERROR_CODE_LOOP] = ELOOP;
+ gf_errno_to_error_array[ELOOP] = GF_ERROR_CODE_LOOP;
+ /* ERESTART 91 / * Restartable system call */
+ gf_error_to_errno_array[GF_ERROR_CODE_RESTART] = ERESTART;
+ gf_errno_to_error_array[ERESTART] = GF_ERROR_CODE_RESTART;
+ /* ESTRPIPE 92 / * if pipe/FIFO, don't sleep in stream head */
+ gf_error_to_errno_array[GF_ERROR_CODE_STRPIPE] = ESTRPIPE;
+ gf_errno_to_error_array[ESTRPIPE] = GF_ERROR_CODE_STRPIPE;
+ /* ENOTEMPTY 93 / * directory not empty */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOTEMPTY] = ENOTEMPTY;
+ gf_errno_to_error_array[ENOTEMPTY] = GF_ERROR_CODE_NOTEMPTY;
+ /* EUSERS 94 / * Too many users (for UFS) */
+ gf_error_to_errno_array[GF_ERROR_CODE_USERS] = EUSERS;
+ gf_errno_to_error_array[EUSERS] = GF_ERROR_CODE_USERS;
+
+ /* BSD Networking Software */
+ /* argument errors */
+ /* ENOTSOCK 95 / * Socket operation on non-socket */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOTSOCK] = ENOTSOCK;
+ gf_errno_to_error_array[ENOTSOCK] = GF_ERROR_CODE_NOTSOCK;
+ /* EDESTADDRREQ 96 / * Destination address required */
+ gf_error_to_errno_array[GF_ERROR_CODE_DESTADDRREQ] = EDESTADDRREQ;
+ gf_errno_to_error_array[EDESTADDRREQ] = GF_ERROR_CODE_DESTADDRREQ;
+ /* EMSGSIZE 97 / * Message too long */
+ gf_error_to_errno_array[GF_ERROR_CODE_MSGSIZE] = EMSGSIZE;
+ gf_errno_to_error_array[EMSGSIZE] = GF_ERROR_CODE_MSGSIZE;
+ /* EPROTOTYPE 98 / * Protocol wrong type for socket */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROTOTYPE] = EPROTOTYPE;
+ gf_errno_to_error_array[EPROTOTYPE] = GF_ERROR_CODE_PROTOTYPE;
+ /* ENOPROTOOPT 99 / * Protocol not available */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOPROTOOPT] = ENOPROTOOPT;
+ gf_errno_to_error_array[ENOPROTOOPT] = GF_ERROR_CODE_NOPROTOOPT;
+ /* EPROTONOSUPPORT 120 / * Protocol not supported */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROTONOSUPPORT] = EPROTONOSUPPORT;
+ gf_errno_to_error_array[EPROTONOSUPPORT] = GF_ERROR_CODE_PROTONOSUPPORT;
+ /* ESOCKTNOSUPPORT 121 / * Socket type not supported */
+ gf_error_to_errno_array[GF_ERROR_CODE_SOCKTNOSUPPORT] = ESOCKTNOSUPPORT;
+ gf_errno_to_error_array[ESOCKTNOSUPPORT] = GF_ERROR_CODE_SOCKTNOSUPPORT;
+
+ /* EOPNOTSUPP 122 / * Operation not supported on socket */
+ gf_error_to_errno_array[GF_ERROR_CODE_OPNOTSUPP] = EOPNOTSUPP;
+ gf_errno_to_error_array[EOPNOTSUPP] = GF_ERROR_CODE_OPNOTSUPP;
+ /* EPFNOSUPPORT 123 / * Protocol family not supported */
+ gf_error_to_errno_array[GF_ERROR_CODE_PFNOSUPPORT] = EPFNOSUPPORT;
+ gf_errno_to_error_array[EPFNOSUPPORT] = GF_ERROR_CODE_PFNOSUPPORT;
+ /* EAFNOSUPPORT 124 / * Address family not supported by */
+ /* protocol family */
+ gf_error_to_errno_array[GF_ERROR_CODE_AFNOSUPPORT] = EAFNOSUPPORT;
+ gf_errno_to_error_array[EAFNOSUPPORT] = GF_ERROR_CODE_AFNOSUPPORT;
+ /* EADDRINUSE 125 / * Address already in use */
+ gf_error_to_errno_array[GF_ERROR_CODE_ADDRINUSE] = EADDRINUSE;
+ gf_errno_to_error_array[EADDRINUSE] = GF_ERROR_CODE_ADDRINUSE;
+ /* EADDRNOTAVAIL 126 / * Can't assign requested address */
+ /* operational errors */
+ gf_error_to_errno_array[GF_ERROR_CODE_ADDRNOTAVAIL] = EADDRNOTAVAIL;
+ gf_errno_to_error_array[EADDRNOTAVAIL] = GF_ERROR_CODE_ADDRNOTAVAIL;
+ /* ENETDOWN 127 / * Network is down */
+ gf_error_to_errno_array[GF_ERROR_CODE_NETDOWN] = ENETDOWN;
+ gf_errno_to_error_array[ENETDOWN] = GF_ERROR_CODE_NETDOWN;
+ /* ENETUNREACH 128 / * Network is unreachable */
+ gf_error_to_errno_array[GF_ERROR_CODE_NETUNREACH] = ENETUNREACH;
+ gf_errno_to_error_array[ENETUNREACH] = GF_ERROR_CODE_NETUNREACH;
+ /* ENETRESET 129 / * Network dropped connection because */
+ /* of reset */
+ gf_error_to_errno_array[GF_ERROR_CODE_NETRESET] = ENETRESET;
+ gf_errno_to_error_array[ENETRESET] = GF_ERROR_CODE_NETRESET;
+ /* ECONNABORTED 130 / * Software caused connection abort */
+ gf_error_to_errno_array[GF_ERROR_CODE_CONNABORTED] = ECONNABORTED;
+ gf_errno_to_error_array[ECONNABORTED] = GF_ERROR_CODE_CONNABORTED;
+ /* ECONNRESET 131 / * Connection reset by peer */
+ gf_error_to_errno_array[GF_ERROR_CODE_CONNRESET] = ECONNRESET;
+ gf_errno_to_error_array[ECONNRESET] = GF_ERROR_CODE_CONNRESET;
+ /* ENOBUFS 132 / * No buffer space available */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOBUFS] = ENOBUFS;
+ gf_errno_to_error_array[ENOBUFS] = GF_ERROR_CODE_NOBUFS;
+ /* EISCONN 133 / * Socket is already connected */
+ gf_error_to_errno_array[GF_ERROR_CODE_ISCONN] = EISCONN;
+ gf_errno_to_error_array[EISCONN] = GF_ERROR_CODE_ISCONN;
+ /* ENOTCONN 134 / * Socket is not connected */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOTCONN] = ENOTCONN;
+ gf_errno_to_error_array[ENOTCONN] = GF_ERROR_CODE_NOTCONN;
+ /* XENIX has 135 - 142 */
+ /* ESHUTDOWN 143 / * Can't send after socket shutdown */
+ gf_error_to_errno_array[GF_ERROR_CODE_SHUTDOWN] = ESHUTDOWN;
+ gf_errno_to_error_array[ESHUTDOWN] = GF_ERROR_CODE_SHUTDOWN;
+ /* ETOOMANYREFS 144 / * Too many references: can't splice */
+ gf_error_to_errno_array[GF_ERROR_CODE_TOOMANYREFS] = ETOOMANYREFS;
+ gf_errno_to_error_array[ETOOMANYREFS] = GF_ERROR_CODE_TOOMANYREFS;
+ /* ETIMEDOUT 145 / * Connection timed out */
+ gf_error_to_errno_array[GF_ERROR_CODE_TIMEDOUT] = ETIMEDOUT;
+ gf_errno_to_error_array[ETIMEDOUT] = GF_ERROR_CODE_TIMEDOUT;
+
+ /* ECONNREFUSED 146 / * Connection refused */
+ gf_error_to_errno_array[GF_ERROR_CODE_CONNREFUSED] = ECONNREFUSED;
+ gf_errno_to_error_array[ECONNREFUSED] = GF_ERROR_CODE_CONNREFUSED;
+ /* EHOSTDOWN 147 / * Host is down */
+ gf_error_to_errno_array[GF_ERROR_CODE_HOSTDOWN] = EHOSTDOWN;
+ gf_errno_to_error_array[EHOSTDOWN] = GF_ERROR_CODE_HOSTDOWN;
+ /* EHOSTUNREACH 148 / * No route to host */
+ gf_error_to_errno_array[GF_ERROR_CODE_HOSTUNREACH] = EHOSTUNREACH;
+ gf_errno_to_error_array[EHOSTUNREACH] = GF_ERROR_CODE_HOSTUNREACH;
+ /* EALREADY 149 / * operation already in progress */
+ gf_error_to_errno_array[GF_ERROR_CODE_ALREADY] = EALREADY;
+ gf_errno_to_error_array[EALREADY] = GF_ERROR_CODE_ALREADY;
+ /* EINPROGRESS 150 / * operation now in progress */
+ gf_error_to_errno_array[GF_ERROR_CODE_INPROGRESS] = EINPROGRESS;
+ gf_errno_to_error_array[EINPROGRESS] = GF_ERROR_CODE_INPROGRESS;
+
+ /* SUN Network File System */
+ /* ESTALE 151 / * Stale NFS file handle */
+ gf_error_to_errno_array[GF_ERROR_CODE_STALE] = ESTALE;
+ gf_errno_to_error_array[ESTALE] = GF_ERROR_CODE_STALE;
+
+ return;
}
#endif /* GF_SOLARIS_HOST_OS */
#ifdef GF_DARWIN_HOST_OS
static void
-init_compat_errno_arrays ()
+init_compat_errno_arrays()
{
- /* EDEADLK 11 / * Resource deadlock would occur */
- gf_error_to_errno_array[GF_ERROR_CODE_DEADLK] = EDEADLK;
- gf_errno_to_error_array[EDEADLK] = GF_ERROR_CODE_DEADLK;
-
- /* EAGAIN 35 / * Try Again */
- gf_error_to_errno_array[GF_ERROR_CODE_AGAIN] = EAGAIN;
- gf_errno_to_error_array[EAGAIN] = GF_ERROR_CODE_AGAIN;
-
- /* EINPROGRESS 36 / * Operation now in progress */
- gf_error_to_errno_array[GF_ERROR_CODE_INPROGRESS] = EINPROGRESS;
- gf_errno_to_error_array[EINPROGRESS] = GF_ERROR_CODE_INPROGRESS;
-
- /* EALREADY 37 / * Operation already in progress */
- gf_error_to_errno_array[GF_ERROR_CODE_ALREADY] = EALREADY;
- gf_errno_to_error_array[EALREADY] = GF_ERROR_CODE_ALREADY;
-
- /* ENOTSOCK 38 / * Socket operation on non-socket */
- gf_error_to_errno_array[GF_ERROR_CODE_NOTSOCK] = ENOTSOCK;
- gf_errno_to_error_array[ENOTSOCK] = GF_ERROR_CODE_NOTSOCK;
-
- /* EDESTADDRREQ 39 / * Destination address required */
- gf_error_to_errno_array[GF_ERROR_CODE_DESTADDRREQ] = EDESTADDRREQ;
- gf_errno_to_error_array[EDESTADDRREQ] = GF_ERROR_CODE_DESTADDRREQ;
-
- /* EMSGSIZE 40 / * Message too long */
- gf_error_to_errno_array[GF_ERROR_CODE_MSGSIZE] = EMSGSIZE;
- gf_errno_to_error_array[EMSGSIZE] = GF_ERROR_CODE_MSGSIZE;
-
- /* EPROTOTYPE 41 / * Protocol wrong type for socket */
- gf_error_to_errno_array[GF_ERROR_CODE_PROTOTYPE] = EPROTOTYPE;
- gf_errno_to_error_array[EPROTOTYPE] = GF_ERROR_CODE_PROTOTYPE;
-
- /* ENOPROTOOPT 42 / * Protocol not available */
- gf_error_to_errno_array[GF_ERROR_CODE_NOPROTOOPT] = ENOPROTOOPT;
- gf_errno_to_error_array[ENOPROTOOPT] = GF_ERROR_CODE_NOPROTOOPT;
-
- /* EPROTONOSUPPORT 43 / * Protocol not supported */
- gf_error_to_errno_array[GF_ERROR_CODE_PROTONOSUPPORT] = EPROTONOSUPPORT;
- gf_errno_to_error_array[EPROTONOSUPPORT] = GF_ERROR_CODE_PROTONOSUPPORT;
-
- /* ESOCKTNOSUPPORT 44 / * Socket type not supported */
- gf_error_to_errno_array[GF_ERROR_CODE_SOCKTNOSUPPORT] = ESOCKTNOSUPPORT;
- gf_errno_to_error_array[ESOCKTNOSUPPORT] = GF_ERROR_CODE_SOCKTNOSUPPORT;
-
- /* EOPNOTSUPP 45 / * Operation not supported */
- gf_error_to_errno_array[GF_ERROR_CODE_OPNOTSUPP] = EOPNOTSUPP;
- gf_errno_to_error_array[EOPNOTSUPP] = GF_ERROR_CODE_OPNOTSUPP;
-
- /* EPFNOSUPPORT 46 / * Protocol family not supported */
- gf_error_to_errno_array[GF_ERROR_CODE_PFNOSUPPORT] = EPFNOSUPPORT;
- gf_errno_to_error_array[EPFNOSUPPORT] = GF_ERROR_CODE_PFNOSUPPORT;
-
- /* EAFNOSUPPORT 47 / * Address family not supported by protocol family */
- gf_error_to_errno_array[GF_ERROR_CODE_AFNOSUPPORT] = EAFNOSUPPORT;
- gf_errno_to_error_array[EAFNOSUPPORT] = GF_ERROR_CODE_AFNOSUPPORT;
-
- /* EADDRINUSE 48 / * Address already in use */
- gf_error_to_errno_array[GF_ERROR_CODE_ADDRINUSE] = EADDRINUSE;
- gf_errno_to_error_array[EADDRINUSE] = GF_ERROR_CODE_ADDRINUSE;
-
- /* EADDRNOTAVAIL 49 / * Can't assign requested address */
- gf_error_to_errno_array[GF_ERROR_CODE_ADDRNOTAVAIL] = EADDRNOTAVAIL;
- gf_errno_to_error_array[EADDRNOTAVAIL] = GF_ERROR_CODE_ADDRNOTAVAIL;
-
- /* ENETDOWN 50 / * Network is down */
- gf_error_to_errno_array[GF_ERROR_CODE_NETDOWN] = ENETDOWN;
- gf_errno_to_error_array[ENETDOWN] = GF_ERROR_CODE_NETDOWN;
-
- /* ENETUNREACH 51 / * Network is unreachable */
- gf_error_to_errno_array[GF_ERROR_CODE_NETUNREACH] = ENETUNREACH;
- gf_errno_to_error_array[ENETUNREACH] = GF_ERROR_CODE_NETUNREACH;
-
- /* ENETRESET 52 / * Network dropped connection on reset */
- gf_error_to_errno_array[GF_ERROR_CODE_NETRESET] = ENETRESET;
- gf_errno_to_error_array[ENETRESET] = GF_ERROR_CODE_NETRESET;
-
- /* ECONNABORTED 53 / * Software caused connection abort */
- gf_error_to_errno_array[GF_ERROR_CODE_CONNABORTED] = ECONNABORTED;
- gf_errno_to_error_array[ECONNABORTED] = GF_ERROR_CODE_CONNABORTED;
-
- /* ECONNRESET 54 / * Connection reset by peer */
- gf_error_to_errno_array[GF_ERROR_CODE_CONNRESET] = ECONNRESET;
- gf_errno_to_error_array[ECONNRESET] = GF_ERROR_CODE_CONNRESET;
-
- /* ENOBUFS 55 / * No buffer space available */
- gf_error_to_errno_array[GF_ERROR_CODE_NOBUFS] = ENOBUFS;
- gf_errno_to_error_array[ENOBUFS] = GF_ERROR_CODE_NOBUFS;
-
- /* EISCONN 56 / * Socket is already connected */
- gf_error_to_errno_array[GF_ERROR_CODE_ISCONN] = EISCONN;
- gf_errno_to_error_array[EISCONN] = GF_ERROR_CODE_ISCONN;
-
- /* ENOTCONN 57 / * Socket is not connected */
- gf_error_to_errno_array[GF_ERROR_CODE_NOTCONN] = ENOTCONN;
- gf_errno_to_error_array[ENOTCONN] = GF_ERROR_CODE_NOTCONN;
-
- /* ESHUTDOWN 58 / * Can't send after socket shutdown */
- gf_error_to_errno_array[GF_ERROR_CODE_SHUTDOWN] = ESHUTDOWN;
- gf_errno_to_error_array[ESHUTDOWN] = GF_ERROR_CODE_SHUTDOWN;
-
- /* ETOOMANYREFS 59 / * Too many references: can't splice */
- gf_error_to_errno_array[GF_ERROR_CODE_TOOMANYREFS] = ETOOMANYREFS;
- gf_errno_to_error_array[ETOOMANYREFS] = GF_ERROR_CODE_TOOMANYREFS;
-
- /* ETIMEDOUT 60 / * Operation timed out */
- gf_error_to_errno_array[GF_ERROR_CODE_TIMEDOUT] = ETIMEDOUT;
- gf_errno_to_error_array[ETIMEDOUT] = GF_ERROR_CODE_TIMEDOUT;
-
- /* ECONNREFUSED 61 / * Connection refused */
- gf_error_to_errno_array[GF_ERROR_CODE_CONNREFUSED] = ECONNREFUSED;
- gf_errno_to_error_array[ECONNREFUSED] = GF_ERROR_CODE_CONNREFUSED;
-
- /* ELOOP 62 / * Too many levels of symbolic links */
- gf_error_to_errno_array[GF_ERROR_CODE_LOOP] = ELOOP;
- gf_errno_to_error_array[ELOOP] = GF_ERROR_CODE_LOOP;
-
- /* ENAMETOOLONG 63 / * File name too long */
- gf_error_to_errno_array[GF_ERROR_CODE_NAMETOOLONG] = ENAMETOOLONG;
- gf_errno_to_error_array[ENAMETOOLONG] = GF_ERROR_CODE_NAMETOOLONG;
-
- /* EHOSTDOWN 64 / * Host is down */
- gf_error_to_errno_array[GF_ERROR_CODE_HOSTDOWN] = EHOSTDOWN;
- gf_errno_to_error_array[EHOSTDOWN] = GF_ERROR_CODE_HOSTDOWN;
-
- /* EHOSTUNREACH 65 / * No route to host */
- gf_error_to_errno_array[GF_ERROR_CODE_HOSTUNREACH] = EHOSTUNREACH;
- gf_errno_to_error_array[EHOSTUNREACH] = GF_ERROR_CODE_HOSTUNREACH;
-
- /* ENOTEMPTY 66 / * Directory not empty */
- gf_error_to_errno_array[GF_ERROR_CODE_NOTEMPTY] = ENOTEMPTY;
- gf_errno_to_error_array[ENOTEMPTY] = GF_ERROR_CODE_NOTEMPTY;
-
- /* EPROCLIM 67 / * Too many processes */
- gf_error_to_errno_array[GF_ERROR_CODE_PROCLIM] = EPROCLIM;
- gf_errno_to_error_array[EPROCLIM] = GF_ERROR_CODE_PROCLIM;
-
- /* EUSERS 68 / * Too many users */
- gf_error_to_errno_array[GF_ERROR_CODE_USERS] = EUSERS;
- gf_errno_to_error_array[EUSERS] = GF_ERROR_CODE_USERS;
-
- /* EDQUOT 69 / * Disc quota exceeded */
- gf_error_to_errno_array[GF_ERROR_CODE_DQUOT] = EDQUOT;
- gf_errno_to_error_array[EDQUOT] = GF_ERROR_CODE_DQUOT;
-
- /* ESTALE 70 / * Stale NFS file handle */
- gf_error_to_errno_array[GF_ERROR_CODE_STALE] = ESTALE;
- gf_errno_to_error_array[ESTALE] = GF_ERROR_CODE_STALE;
-
- /* EREMOTE 71 / * Too many levels of remote in path */
- gf_error_to_errno_array[GF_ERROR_CODE_REMOTE] = EREMOTE;
- gf_errno_to_error_array[EREMOTE] = GF_ERROR_CODE_REMOTE;
-
- /* EBADRPC 72 / * RPC struct is bad */
- gf_error_to_errno_array[GF_ERROR_CODE_BADRPC] = EBADRPC;
- gf_errno_to_error_array[EBADRPC] = GF_ERROR_CODE_BADRPC;
-
- /* ERPCMISMATCH 73 / * RPC version wrong */
- gf_error_to_errno_array[GF_ERROR_CODE_RPCMISMATCH] = ERPCMISMATCH;
- gf_errno_to_error_array[ERPCMISMATCH] = GF_ERROR_CODE_RPCMISMATCH;
-
- /* EPROGUNAVAIL 74 / * RPC prog. not avail */
- gf_error_to_errno_array[GF_ERROR_CODE_PROGUNAVAIL] = EPROGUNAVAIL;
- gf_errno_to_error_array[EPROGUNAVAIL] = GF_ERROR_CODE_PROGUNAVAIL;
-
- /* EPROGMISMATCH 75 / * Program version wrong */
- gf_error_to_errno_array[GF_ERROR_CODE_PROGMISMATCH] = EPROGMISMATCH;
- gf_errno_to_error_array[EPROGMISMATCH] = GF_ERROR_CODE_PROGMISMATCH;
-
- /* EPROCUNAVAIL 76 / * Bad procedure for program */
- gf_error_to_errno_array[GF_ERROR_CODE_PROCUNAVAIL] = EPROCUNAVAIL;
- gf_errno_to_error_array[EPROCUNAVAIL] = GF_ERROR_CODE_PROCUNAVAIL;
-
- /* ENOLCK 77 / * No locks available */
- gf_error_to_errno_array[GF_ERROR_CODE_NOLCK] = ENOLCK;
- gf_errno_to_error_array[ENOLCK] = GF_ERROR_CODE_NOLCK;
-
- /* ENOSYS 78 / * Function not implemented */
- gf_error_to_errno_array[GF_ERROR_CODE_NOSYS] = ENOSYS;
- gf_errno_to_error_array[ENOSYS] = GF_ERROR_CODE_NOSYS;
-
- /* EFTYPE 79 / * Inappropriate file type or format */
- gf_error_to_errno_array[GF_ERROR_CODE_FTYPE] = EFTYPE;
- gf_errno_to_error_array[EFTYPE] = GF_ERROR_CODE_FTYPE;
-
- /* EAUTH 80 / * Authentication error */
- gf_error_to_errno_array[GF_ERROR_CODE_AUTH] = EAUTH;
- gf_errno_to_error_array[EAUTH] = GF_ERROR_CODE_AUTH;
-
- /* ENEEDAUTH 81 / * Need authenticator */
- gf_error_to_errno_array[GF_ERROR_CODE_NEEDAUTH] = ENEEDAUTH;
- gf_errno_to_error_array[ENEEDAUTH] = GF_ERROR_CODE_NEEDAUTH;
-/* Intelligent device errors */
-/* EPWROFF 82 / * Device power is off */
- gf_error_to_errno_array[GF_ERROR_CODE_PWROFF] = EPWROFF;
- gf_errno_to_error_array[EPWROFF] = GF_ERROR_CODE_PWROFF;
-/* EDEVERR 83 / * Device error, e.g. paper out */
- gf_error_to_errno_array[GF_ERROR_CODE_DEVERR] = EDEVERR;
- gf_errno_to_error_array[EDEVERR] = GF_ERROR_CODE_DEVERR;
-
- /* EOVERFLOW 84 / * Value too large to be stored in data type */
- gf_error_to_errno_array[GF_ERROR_CODE_OVERFLOW] = EOVERFLOW;
- gf_errno_to_error_array[EOVERFLOW] = GF_ERROR_CODE_OVERFLOW;
-
-/* Program loading errors */
-/* EBADEXEC 85 / * Bad executable */
- gf_error_to_errno_array[GF_ERROR_CODE_BADEXEC] = EBADEXEC;
- gf_errno_to_error_array[EBADEXEC] = GF_ERROR_CODE_BADEXEC;
-
-/* EBADARCH 86 / * Bad CPU type in executable */
- gf_error_to_errno_array[GF_ERROR_CODE_BADARCH] = EBADARCH;
- gf_errno_to_error_array[EBADARCH] = GF_ERROR_CODE_BADARCH;
-
-/* ESHLIBVERS 87 / * Shared library version mismatch */
- gf_error_to_errno_array[GF_ERROR_CODE_SHLIBVERS] = ESHLIBVERS;
- gf_errno_to_error_array[ESHLIBVERS] = GF_ERROR_CODE_SHLIBVERS;
-
-/* EBADMACHO 88 / * Malformed Macho file */
- gf_error_to_errno_array[GF_ERROR_CODE_BADMACHO] = EBADMACHO;
- gf_errno_to_error_array[EBADMACHO] = GF_ERROR_CODE_BADMACHO;
-
-#if 0
- /* EDOOFUS 88 / * Programming error */
- gf_error_to_errno_array[GF_ERROR_CODE_DOOFUS] = EDOOFUS;
- gf_errno_to_error_array[EDOOFUS] = GF_ERROR_CODE_DOOFUS;
+ /* EDEADLK 11 / * Resource deadlock would occur */
+ gf_error_to_errno_array[GF_ERROR_CODE_DEADLK] = EDEADLK;
+ gf_errno_to_error_array[EDEADLK] = GF_ERROR_CODE_DEADLK;
+
+ /* EAGAIN 35 / * Try Again */
+ gf_error_to_errno_array[GF_ERROR_CODE_AGAIN] = EAGAIN;
+ gf_errno_to_error_array[EAGAIN] = GF_ERROR_CODE_AGAIN;
+
+ /* EINPROGRESS 36 / * Operation now in progress */
+ gf_error_to_errno_array[GF_ERROR_CODE_INPROGRESS] = EINPROGRESS;
+ gf_errno_to_error_array[EINPROGRESS] = GF_ERROR_CODE_INPROGRESS;
+
+ /* EALREADY 37 / * Operation already in progress */
+ gf_error_to_errno_array[GF_ERROR_CODE_ALREADY] = EALREADY;
+ gf_errno_to_error_array[EALREADY] = GF_ERROR_CODE_ALREADY;
+
+ /* ENOTSOCK 38 / * Socket operation on non-socket
+ */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOTSOCK] = ENOTSOCK;
+ gf_errno_to_error_array[ENOTSOCK] = GF_ERROR_CODE_NOTSOCK;
+
+ /* EDESTADDRREQ 39 / * Destination address required */
+ gf_error_to_errno_array[GF_ERROR_CODE_DESTADDRREQ] = EDESTADDRREQ;
+ gf_errno_to_error_array[EDESTADDRREQ] = GF_ERROR_CODE_DESTADDRREQ;
+
+ /* EMSGSIZE 40 / * Message too long */
+ gf_error_to_errno_array[GF_ERROR_CODE_MSGSIZE] = EMSGSIZE;
+ gf_errno_to_error_array[EMSGSIZE] = GF_ERROR_CODE_MSGSIZE;
+
+ /* EPROTOTYPE 41 / * Protocol wrong type for socket
+ */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROTOTYPE] = EPROTOTYPE;
+ gf_errno_to_error_array[EPROTOTYPE] = GF_ERROR_CODE_PROTOTYPE;
+
+ /* ENOPROTOOPT 42 / * Protocol not available */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOPROTOOPT] = ENOPROTOOPT;
+ gf_errno_to_error_array[ENOPROTOOPT] = GF_ERROR_CODE_NOPROTOOPT;
+
+ /* EPROTONOSUPPORT 43 / * Protocol not supported */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROTONOSUPPORT] = EPROTONOSUPPORT;
+ gf_errno_to_error_array[EPROTONOSUPPORT] = GF_ERROR_CODE_PROTONOSUPPORT;
+
+ /* ESOCKTNOSUPPORT 44 / * Socket type not supported */
+ gf_error_to_errno_array[GF_ERROR_CODE_SOCKTNOSUPPORT] = ESOCKTNOSUPPORT;
+ gf_errno_to_error_array[ESOCKTNOSUPPORT] = GF_ERROR_CODE_SOCKTNOSUPPORT;
+
+ /* EOPNOTSUPP 45 / * Operation not supported */
+ gf_error_to_errno_array[GF_ERROR_CODE_OPNOTSUPP] = EOPNOTSUPP;
+ gf_errno_to_error_array[EOPNOTSUPP] = GF_ERROR_CODE_OPNOTSUPP;
+
+ /* EPFNOSUPPORT 46 / * Protocol family not supported */
+ gf_error_to_errno_array[GF_ERROR_CODE_PFNOSUPPORT] = EPFNOSUPPORT;
+ gf_errno_to_error_array[EPFNOSUPPORT] = GF_ERROR_CODE_PFNOSUPPORT;
+
+ /* EAFNOSUPPORT 47 / * Address family not supported by
+ * protocol family */
+ gf_error_to_errno_array[GF_ERROR_CODE_AFNOSUPPORT] = EAFNOSUPPORT;
+ gf_errno_to_error_array[EAFNOSUPPORT] = GF_ERROR_CODE_AFNOSUPPORT;
+
+ /* EADDRINUSE 48 / * Address already in use */
+ gf_error_to_errno_array[GF_ERROR_CODE_ADDRINUSE] = EADDRINUSE;
+ gf_errno_to_error_array[EADDRINUSE] = GF_ERROR_CODE_ADDRINUSE;
+
+ /* EADDRNOTAVAIL 49 / * Can't assign requested address
+ */
+ gf_error_to_errno_array[GF_ERROR_CODE_ADDRNOTAVAIL] = EADDRNOTAVAIL;
+ gf_errno_to_error_array[EADDRNOTAVAIL] = GF_ERROR_CODE_ADDRNOTAVAIL;
+
+ /* ENETDOWN 50 / * Network is down */
+ gf_error_to_errno_array[GF_ERROR_CODE_NETDOWN] = ENETDOWN;
+ gf_errno_to_error_array[ENETDOWN] = GF_ERROR_CODE_NETDOWN;
+
+ /* ENETUNREACH 51 / * Network is unreachable */
+ gf_error_to_errno_array[GF_ERROR_CODE_NETUNREACH] = ENETUNREACH;
+ gf_errno_to_error_array[ENETUNREACH] = GF_ERROR_CODE_NETUNREACH;
+
+ /* ENETRESET 52 / * Network dropped connection on
+ * reset */
+ gf_error_to_errno_array[GF_ERROR_CODE_NETRESET] = ENETRESET;
+ gf_errno_to_error_array[ENETRESET] = GF_ERROR_CODE_NETRESET;
+
+ /* ECONNABORTED 53 / * Software caused connection abort
+ */
+ gf_error_to_errno_array[GF_ERROR_CODE_CONNABORTED] = ECONNABORTED;
+ gf_errno_to_error_array[ECONNABORTED] = GF_ERROR_CODE_CONNABORTED;
+
+ /* ECONNRESET 54 / * Connection reset by peer */
+ gf_error_to_errno_array[GF_ERROR_CODE_CONNRESET] = ECONNRESET;
+ gf_errno_to_error_array[ECONNRESET] = GF_ERROR_CODE_CONNRESET;
+
+ /* ENOBUFS 55 / * No buffer space available */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOBUFS] = ENOBUFS;
+ gf_errno_to_error_array[ENOBUFS] = GF_ERROR_CODE_NOBUFS;
+
+ /* EISCONN 56 / * Socket is already connected */
+ gf_error_to_errno_array[GF_ERROR_CODE_ISCONN] = EISCONN;
+ gf_errno_to_error_array[EISCONN] = GF_ERROR_CODE_ISCONN;
+
+ /* ENOTCONN 57 / * Socket is not connected */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOTCONN] = ENOTCONN;
+ gf_errno_to_error_array[ENOTCONN] = GF_ERROR_CODE_NOTCONN;
+
+ /* ESHUTDOWN 58 / * Can't send after socket shutdown
+ */
+ gf_error_to_errno_array[GF_ERROR_CODE_SHUTDOWN] = ESHUTDOWN;
+ gf_errno_to_error_array[ESHUTDOWN] = GF_ERROR_CODE_SHUTDOWN;
+
+ /* ETOOMANYREFS 59 / * Too many references: can't
+ * splice */
+ gf_error_to_errno_array[GF_ERROR_CODE_TOOMANYREFS] = ETOOMANYREFS;
+ gf_errno_to_error_array[ETOOMANYREFS] = GF_ERROR_CODE_TOOMANYREFS;
+
+ /* ETIMEDOUT 60 / * Operation timed out */
+ gf_error_to_errno_array[GF_ERROR_CODE_TIMEDOUT] = ETIMEDOUT;
+ gf_errno_to_error_array[ETIMEDOUT] = GF_ERROR_CODE_TIMEDOUT;
+
+ /* ECONNREFUSED 61 / * Connection refused */
+ gf_error_to_errno_array[GF_ERROR_CODE_CONNREFUSED] = ECONNREFUSED;
+ gf_errno_to_error_array[ECONNREFUSED] = GF_ERROR_CODE_CONNREFUSED;
+
+ /* ELOOP 62 / * Too many levels of symbolic
+ * links */
+ gf_error_to_errno_array[GF_ERROR_CODE_LOOP] = ELOOP;
+ gf_errno_to_error_array[ELOOP] = GF_ERROR_CODE_LOOP;
+
+ /* ENAMETOOLONG 63 / * File name too long */
+ gf_error_to_errno_array[GF_ERROR_CODE_NAMETOOLONG] = ENAMETOOLONG;
+ gf_errno_to_error_array[ENAMETOOLONG] = GF_ERROR_CODE_NAMETOOLONG;
+
+ /* EHOSTDOWN 64 / * Host is down */
+ gf_error_to_errno_array[GF_ERROR_CODE_HOSTDOWN] = EHOSTDOWN;
+ gf_errno_to_error_array[EHOSTDOWN] = GF_ERROR_CODE_HOSTDOWN;
+
+ /* EHOSTUNREACH 65 / * No route to host */
+ gf_error_to_errno_array[GF_ERROR_CODE_HOSTUNREACH] = EHOSTUNREACH;
+ gf_errno_to_error_array[EHOSTUNREACH] = GF_ERROR_CODE_HOSTUNREACH;
+
+ /* ENOTEMPTY 66 / * Directory not empty */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOTEMPTY] = ENOTEMPTY;
+ gf_errno_to_error_array[ENOTEMPTY] = GF_ERROR_CODE_NOTEMPTY;
+
+ /* EPROCLIM 67 / * Too many processes */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROCLIM] = EPROCLIM;
+ gf_errno_to_error_array[EPROCLIM] = GF_ERROR_CODE_PROCLIM;
+
+ /* EUSERS 68 / * Too many users */
+ gf_error_to_errno_array[GF_ERROR_CODE_USERS] = EUSERS;
+ gf_errno_to_error_array[EUSERS] = GF_ERROR_CODE_USERS;
+
+ /* EDQUOT 69 / * Disc quota exceeded */
+ gf_error_to_errno_array[GF_ERROR_CODE_DQUOT] = EDQUOT;
+ gf_errno_to_error_array[EDQUOT] = GF_ERROR_CODE_DQUOT;
+
+ /* ESTALE 70 / * Stale NFS file handle */
+ gf_error_to_errno_array[GF_ERROR_CODE_STALE] = ESTALE;
+ gf_errno_to_error_array[ESTALE] = GF_ERROR_CODE_STALE;
+
+ /* EREMOTE 71 / * Too many levels of remote in
+ * path */
+ gf_error_to_errno_array[GF_ERROR_CODE_REMOTE] = EREMOTE;
+ gf_errno_to_error_array[EREMOTE] = GF_ERROR_CODE_REMOTE;
+
+ /* EBADRPC 72 / * RPC struct is bad */
+ gf_error_to_errno_array[GF_ERROR_CODE_BADRPC] = EBADRPC;
+ gf_errno_to_error_array[EBADRPC] = GF_ERROR_CODE_BADRPC;
+
+ /* ERPCMISMATCH 73 / * RPC version wrong */
+ gf_error_to_errno_array[GF_ERROR_CODE_RPCMISMATCH] = ERPCMISMATCH;
+ gf_errno_to_error_array[ERPCMISMATCH] = GF_ERROR_CODE_RPCMISMATCH;
+
+ /* EPROGUNAVAIL 74 / * RPC prog. not avail */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROGUNAVAIL] = EPROGUNAVAIL;
+ gf_errno_to_error_array[EPROGUNAVAIL] = GF_ERROR_CODE_PROGUNAVAIL;
+
+ /* EPROGMISMATCH 75 / * Program version wrong */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROGMISMATCH] = EPROGMISMATCH;
+ gf_errno_to_error_array[EPROGMISMATCH] = GF_ERROR_CODE_PROGMISMATCH;
+
+ /* EPROCUNAVAIL 76 / * Bad procedure for program */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROCUNAVAIL] = EPROCUNAVAIL;
+ gf_errno_to_error_array[EPROCUNAVAIL] = GF_ERROR_CODE_PROCUNAVAIL;
+
+ /* ENOLCK 77 / * No locks available */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOLCK] = ENOLCK;
+ gf_errno_to_error_array[ENOLCK] = GF_ERROR_CODE_NOLCK;
+
+ /* ENOSYS 78 / * Function not implemented */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOSYS] = ENOSYS;
+ gf_errno_to_error_array[ENOSYS] = GF_ERROR_CODE_NOSYS;
+
+ /* EFTYPE 79 / * Inappropriate file type or
+ * format */
+ gf_error_to_errno_array[GF_ERROR_CODE_FTYPE] = EFTYPE;
+ gf_errno_to_error_array[EFTYPE] = GF_ERROR_CODE_FTYPE;
+
+ /* EAUTH 80 / * Authentication error */
+ gf_error_to_errno_array[GF_ERROR_CODE_AUTH] = EAUTH;
+ gf_errno_to_error_array[EAUTH] = GF_ERROR_CODE_AUTH;
+
+ /* ENEEDAUTH 81 / * Need authenticator */
+ gf_error_to_errno_array[GF_ERROR_CODE_NEEDAUTH] = ENEEDAUTH;
+ gf_errno_to_error_array[ENEEDAUTH] = GF_ERROR_CODE_NEEDAUTH;
+ /* Intelligent device errors */
+ /* EPWROFF 82 / * Device power is off */
+ gf_error_to_errno_array[GF_ERROR_CODE_PWROFF] = EPWROFF;
+ gf_errno_to_error_array[EPWROFF] = GF_ERROR_CODE_PWROFF;
+ /* EDEVERR 83 / * Device error, e.g. paper out */
+ gf_error_to_errno_array[GF_ERROR_CODE_DEVERR] = EDEVERR;
+ gf_errno_to_error_array[EDEVERR] = GF_ERROR_CODE_DEVERR;
+
+ /* EOVERFLOW 84 / * Value too large to be stored in
+ * data type */
+ gf_error_to_errno_array[GF_ERROR_CODE_OVERFLOW] = EOVERFLOW;
+ gf_errno_to_error_array[EOVERFLOW] = GF_ERROR_CODE_OVERFLOW;
+
+ /* Program loading errors */
+ /* EBADEXEC 85 / * Bad executable */
+ gf_error_to_errno_array[GF_ERROR_CODE_BADEXEC] = EBADEXEC;
+ gf_errno_to_error_array[EBADEXEC] = GF_ERROR_CODE_BADEXEC;
+
+ /* EBADARCH 86 / * Bad CPU type in executable */
+ gf_error_to_errno_array[GF_ERROR_CODE_BADARCH] = EBADARCH;
+ gf_errno_to_error_array[EBADARCH] = GF_ERROR_CODE_BADARCH;
+
+ /* ESHLIBVERS 87 / * Shared library version mismatch */
+ gf_error_to_errno_array[GF_ERROR_CODE_SHLIBVERS] = ESHLIBVERS;
+ gf_errno_to_error_array[ESHLIBVERS] = GF_ERROR_CODE_SHLIBVERS;
+
+ /* EBADMACHO 88 / * Malformed Macho file */
+ gf_error_to_errno_array[GF_ERROR_CODE_BADMACHO] = EBADMACHO;
+ gf_errno_to_error_array[EBADMACHO] = GF_ERROR_CODE_BADMACHO;
+
+#ifdef EDOOFUS
+ /* EDOOFUS 88 / * Programming error */
+ gf_error_to_errno_array[GF_ERROR_CODE_DOOFUS] = EDOOFUS;
+ gf_errno_to_error_array[EDOOFUS] = GF_ERROR_CODE_DOOFUS;
#endif
- /* ECANCELED 89 / * Operation canceled */
- gf_error_to_errno_array[GF_ERROR_CODE_CANCELED] = ECANCELED;
- gf_errno_to_error_array[ECANCELED] = GF_ERROR_CODE_CANCELED;
-
- /* EIDRM 90 / * Identifier removed */
- gf_error_to_errno_array[GF_ERROR_CODE_IDRM] = EIDRM;
- gf_errno_to_error_array[EIDRM] = GF_ERROR_CODE_IDRM;
- /* ENOMSG 91 / * No message of desired type */
- gf_error_to_errno_array[GF_ERROR_CODE_NOMSG] = ENOMSG;
- gf_errno_to_error_array[ENOMSG] = GF_ERROR_CODE_NOMSG;
-
- /* EILSEQ 92 / * Illegal byte sequence */
- gf_error_to_errno_array[GF_ERROR_CODE_ILSEQ] = EILSEQ;
- gf_errno_to_error_array[EILSEQ] = GF_ERROR_CODE_ILSEQ;
-
- /* ENOATTR 93 / * Attribute not found */
- gf_error_to_errno_array[GF_ERROR_CODE_NOATTR] = ENOATTR;
- gf_errno_to_error_array[ENOATTR] = GF_ERROR_CODE_NOATTR;
-
- /* EBADMSG 94 / * Bad message */
- gf_error_to_errno_array[GF_ERROR_CODE_BADMSG] = EBADMSG;
- gf_errno_to_error_array[EBADMSG] = GF_ERROR_CODE_BADMSG;
-
- /* EMULTIHOP 95 / * Reserved */
- gf_error_to_errno_array[GF_ERROR_CODE_MULTIHOP] = EMULTIHOP;
- gf_errno_to_error_array[EMULTIHOP] = GF_ERROR_CODE_MULTIHOP;
-
- /* ENODATA 96 / * No message available on STREAM */
- gf_error_to_errno_array[GF_ERROR_CODE_NEEDAUTH] = ENEEDAUTH;
- gf_errno_to_error_array[ENEEDAUTH] = GF_ERROR_CODE_NEEDAUTH;
-
- /* ENOLINK 97 / * Reserved */
- gf_error_to_errno_array[GF_ERROR_CODE_NOLINK] = ENOLINK;
- gf_errno_to_error_array[ENOLINK] = GF_ERROR_CODE_NOLINK;
-
- /* ENOSR 98 / * No STREAM resources */
- gf_error_to_errno_array[GF_ERROR_CODE_NOSR] = ENOSR;
- gf_errno_to_error_array[ENOSR] = GF_ERROR_CODE_NOSR;
-
- /* ENOSTR 99 / * Not a STREAM */
- gf_error_to_errno_array[GF_ERROR_CODE_NOSTR] = ENOSTR;
- gf_errno_to_error_array[ENOSTR] = GF_ERROR_CODE_NOSTR;
-
-/* EPROTO 100 / * Protocol error */
- gf_error_to_errno_array[GF_ERROR_CODE_PROTO] = EPROTO;
- gf_errno_to_error_array[EPROTO] = GF_ERROR_CODE_PROTO;
-/* ETIME 101 / * STREAM ioctl timeout */
- gf_error_to_errno_array[GF_ERROR_CODE_TIME] = ETIME;
- gf_errno_to_error_array[ETIME] = GF_ERROR_CODE_TIME;
-
-/* This value is only discrete when compiling __DARWIN_UNIX03, or KERNEL */
-/* EOPNOTSUPP 102 / * Operation not supported on socket */
- gf_error_to_errno_array[GF_ERROR_CODE_OPNOTSUPP] = EOPNOTSUPP;
- gf_errno_to_error_array[EOPNOTSUPP] = GF_ERROR_CODE_OPNOTSUPP;
-
-/* ENOPOLICY 103 / * No such policy registered */
- gf_error_to_errno_array[GF_ERROR_CODE_NOPOLICY] = ENOPOLICY;
- gf_errno_to_error_array[ENOPOLICY] = GF_ERROR_CODE_NOPOLICY;
-
- return ;
+ /* ECANCELED 89 / * Operation canceled */
+ gf_error_to_errno_array[GF_ERROR_CODE_CANCELED] = ECANCELED;
+ gf_errno_to_error_array[ECANCELED] = GF_ERROR_CODE_CANCELED;
+
+ /* EIDRM 90 / * Identifier removed */
+ gf_error_to_errno_array[GF_ERROR_CODE_IDRM] = EIDRM;
+ gf_errno_to_error_array[EIDRM] = GF_ERROR_CODE_IDRM;
+ /* ENOMSG 91 / * No message of desired type */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOMSG] = ENOMSG;
+ gf_errno_to_error_array[ENOMSG] = GF_ERROR_CODE_NOMSG;
+
+ /* EILSEQ 92 / * Illegal byte sequence */
+ gf_error_to_errno_array[GF_ERROR_CODE_ILSEQ] = EILSEQ;
+ gf_errno_to_error_array[EILSEQ] = GF_ERROR_CODE_ILSEQ;
+
+ /* ENOATTR 93 / * Attribute not found */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOATTR] = ENOATTR;
+ gf_errno_to_error_array[ENOATTR] = GF_ERROR_CODE_NOATTR;
+
+ /* EBADMSG 94 / * Bad message */
+ gf_error_to_errno_array[GF_ERROR_CODE_BADMSG] = EBADMSG;
+ gf_errno_to_error_array[EBADMSG] = GF_ERROR_CODE_BADMSG;
+
+ /* EMULTIHOP 95 / * Reserved */
+ gf_error_to_errno_array[GF_ERROR_CODE_MULTIHOP] = EMULTIHOP;
+ gf_errno_to_error_array[EMULTIHOP] = GF_ERROR_CODE_MULTIHOP;
+
+ /* ENODATA 96 / * No message available on STREAM
+ */
+ gf_error_to_errno_array[GF_ERROR_CODE_NEEDAUTH] = ENEEDAUTH;
+ gf_errno_to_error_array[ENEEDAUTH] = GF_ERROR_CODE_NEEDAUTH;
+
+ /* ENOLINK 97 / * Reserved */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOLINK] = ENOLINK;
+ gf_errno_to_error_array[ENOLINK] = GF_ERROR_CODE_NOLINK;
+
+ /* ENOSR 98 / * No STREAM resources */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOSR] = ENOSR;
+ gf_errno_to_error_array[ENOSR] = GF_ERROR_CODE_NOSR;
+
+ /* ENOSTR 99 / * Not a STREAM */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOSTR] = ENOSTR;
+ gf_errno_to_error_array[ENOSTR] = GF_ERROR_CODE_NOSTR;
+
+ /* EPROTO 100 / * Protocol error */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROTO] = EPROTO;
+ gf_errno_to_error_array[EPROTO] = GF_ERROR_CODE_PROTO;
+ /* ETIME 101 / * STREAM ioctl timeout */
+ gf_error_to_errno_array[GF_ERROR_CODE_TIME] = ETIME;
+ gf_errno_to_error_array[ETIME] = GF_ERROR_CODE_TIME;
+
+ /* This value is only discrete when compiling __DARWIN_UNIX03, or KERNEL */
+ /* EOPNOTSUPP 102 / * Operation not supported on
+ * socket */
+ gf_error_to_errno_array[GF_ERROR_CODE_OPNOTSUPP] = EOPNOTSUPP;
+ gf_errno_to_error_array[EOPNOTSUPP] = GF_ERROR_CODE_OPNOTSUPP;
+
+ /* ENOPOLICY 103 / * No such policy registered */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOPOLICY] = ENOPOLICY;
+ gf_errno_to_error_array[ENOPOLICY] = GF_ERROR_CODE_NOPOLICY;
+
+ return;
}
#endif /* GF_DARWIN_HOST_OS */
#ifdef GF_BSD_HOST_OS
static void
-init_compat_errno_arrays ()
+init_compat_errno_arrays()
{
- /* Quite a bit of things changed in FreeBSD - current */
-
- /* EAGAIN 35 / * Try Again */
- gf_error_to_errno_array[GF_ERROR_CODE_AGAIN] = EAGAIN;
- gf_errno_to_error_array[EAGAIN] = GF_ERROR_CODE_AGAIN;
-
- /* EDEADLK 11 / * Resource deadlock would occur */
- gf_error_to_errno_array[GF_ERROR_CODE_DEADLK] = EDEADLK;
- gf_errno_to_error_array[EDEADLK] = GF_ERROR_CODE_DEADLK;
-
- /* EINPROGRESS 36 / * Operation now in progress */
- gf_error_to_errno_array[GF_ERROR_CODE_INPROGRESS] = EINPROGRESS;
- gf_errno_to_error_array[EINPROGRESS] = GF_ERROR_CODE_INPROGRESS;
-
- /* EALREADY 37 / * Operation already in progress */
- gf_error_to_errno_array[GF_ERROR_CODE_ALREADY] = EALREADY;
- gf_errno_to_error_array[EALREADY] = GF_ERROR_CODE_ALREADY;
-
- /* ENOTSOCK 38 / * Socket operation on non-socket */
- gf_error_to_errno_array[GF_ERROR_CODE_NOTSOCK] = ENOTSOCK;
- gf_errno_to_error_array[ENOTSOCK] = GF_ERROR_CODE_NOTSOCK;
-
- /* EDESTADDRREQ 39 / * Destination address required */
- gf_error_to_errno_array[GF_ERROR_CODE_DESTADDRREQ] = EDESTADDRREQ;
- gf_errno_to_error_array[EDESTADDRREQ] = GF_ERROR_CODE_DESTADDRREQ;
-
- /* EMSGSIZE 40 / * Message too long */
- gf_error_to_errno_array[GF_ERROR_CODE_MSGSIZE] = EMSGSIZE;
- gf_errno_to_error_array[EMSGSIZE] = GF_ERROR_CODE_MSGSIZE;
-
- /* EPROTOTYPE 41 / * Protocol wrong type for socket */
- gf_error_to_errno_array[GF_ERROR_CODE_PROTOTYPE] = EPROTOTYPE;
- gf_errno_to_error_array[EPROTOTYPE] = GF_ERROR_CODE_PROTOTYPE;
-
- /* ENOPROTOOPT 42 / * Protocol not available */
- gf_error_to_errno_array[GF_ERROR_CODE_NOPROTOOPT] = ENOPROTOOPT;
- gf_errno_to_error_array[ENOPROTOOPT] = GF_ERROR_CODE_NOPROTOOPT;
-
- /* EPROTONOSUPPORT 43 / * Protocol not supported */
- gf_error_to_errno_array[GF_ERROR_CODE_PROTONOSUPPORT] = EPROTONOSUPPORT;
- gf_errno_to_error_array[EPROTONOSUPPORT] = GF_ERROR_CODE_PROTONOSUPPORT;
-
- /* ESOCKTNOSUPPORT 44 / * Socket type not supported */
- gf_error_to_errno_array[GF_ERROR_CODE_SOCKTNOSUPPORT] = ESOCKTNOSUPPORT;
- gf_errno_to_error_array[ESOCKTNOSUPPORT] = GF_ERROR_CODE_SOCKTNOSUPPORT;
-
- /* EOPNOTSUPP 45 / * Operation not supported */
- gf_error_to_errno_array[GF_ERROR_CODE_OPNOTSUPP] = EOPNOTSUPP;
- gf_errno_to_error_array[EOPNOTSUPP] = GF_ERROR_CODE_OPNOTSUPP;
-
- /* EPFNOSUPPORT 46 / * Protocol family not supported */
- gf_error_to_errno_array[GF_ERROR_CODE_PFNOSUPPORT] = EPFNOSUPPORT;
- gf_errno_to_error_array[EPFNOSUPPORT] = GF_ERROR_CODE_PFNOSUPPORT;
-
- /* EAFNOSUPPORT 47 / * Address family not supported by protocol family */
- gf_error_to_errno_array[GF_ERROR_CODE_AFNOSUPPORT] = EAFNOSUPPORT;
- gf_errno_to_error_array[EAFNOSUPPORT] = GF_ERROR_CODE_AFNOSUPPORT;
-
- /* EADDRINUSE 48 / * Address already in use */
- gf_error_to_errno_array[GF_ERROR_CODE_ADDRINUSE] = EADDRINUSE;
- gf_errno_to_error_array[EADDRINUSE] = GF_ERROR_CODE_ADDRINUSE;
-
- /* EADDRNOTAVAIL 49 / * Can't assign requested address */
- gf_error_to_errno_array[GF_ERROR_CODE_ADDRNOTAVAIL] = EADDRNOTAVAIL;
- gf_errno_to_error_array[EADDRNOTAVAIL] = GF_ERROR_CODE_ADDRNOTAVAIL;
-
- /* ENETDOWN 50 / * Network is down */
- gf_error_to_errno_array[GF_ERROR_CODE_NETDOWN] = ENETDOWN;
- gf_errno_to_error_array[ENETDOWN] = GF_ERROR_CODE_NETDOWN;
-
- /* ENETUNREACH 51 / * Network is unreachable */
- gf_error_to_errno_array[GF_ERROR_CODE_NETUNREACH] = ENETUNREACH;
- gf_errno_to_error_array[ENETUNREACH] = GF_ERROR_CODE_NETUNREACH;
-
- /* ENETRESET 52 / * Network dropped connection on reset */
- gf_error_to_errno_array[GF_ERROR_CODE_NETRESET] = ENETRESET;
- gf_errno_to_error_array[ENETRESET] = GF_ERROR_CODE_NETRESET;
-
- /* ECONNABORTED 53 / * Software caused connection abort */
- gf_error_to_errno_array[GF_ERROR_CODE_CONNABORTED] = ECONNABORTED;
- gf_errno_to_error_array[ECONNABORTED] = GF_ERROR_CODE_CONNABORTED;
-
- /* ECONNRESET 54 / * Connection reset by peer */
- gf_error_to_errno_array[GF_ERROR_CODE_CONNRESET] = ECONNRESET;
- gf_errno_to_error_array[ECONNRESET] = GF_ERROR_CODE_CONNRESET;
-
- /* ENOBUFS 55 / * No buffer space available */
- gf_error_to_errno_array[GF_ERROR_CODE_NOBUFS] = ENOBUFS;
- gf_errno_to_error_array[ENOBUFS] = GF_ERROR_CODE_NOBUFS;
-
- /* EISCONN 56 / * Socket is already connected */
- gf_error_to_errno_array[GF_ERROR_CODE_ISCONN] = EISCONN;
- gf_errno_to_error_array[EISCONN] = GF_ERROR_CODE_ISCONN;
-
- /* ENOTCONN 57 / * Socket is not connected */
- gf_error_to_errno_array[GF_ERROR_CODE_NOTCONN] = ENOTCONN;
- gf_errno_to_error_array[ENOTCONN] = GF_ERROR_CODE_NOTCONN;
-
- /* ESHUTDOWN 58 / * Can't send after socket shutdown */
- gf_error_to_errno_array[GF_ERROR_CODE_SHUTDOWN] = ESHUTDOWN;
- gf_errno_to_error_array[ESHUTDOWN] = GF_ERROR_CODE_SHUTDOWN;
-
- /* ETOOMANYREFS 59 / * Too many references: can't splice */
- gf_error_to_errno_array[GF_ERROR_CODE_TOOMANYREFS] = ETOOMANYREFS;
- gf_errno_to_error_array[ETOOMANYREFS] = GF_ERROR_CODE_TOOMANYREFS;
-
- /* ETIMEDOUT 60 / * Operation timed out */
- gf_error_to_errno_array[GF_ERROR_CODE_TIMEDOUT] = ETIMEDOUT;
- gf_errno_to_error_array[ETIMEDOUT] = GF_ERROR_CODE_TIMEDOUT;
-
- /* ECONNREFUSED 61 / * Connection refused */
- gf_error_to_errno_array[GF_ERROR_CODE_CONNREFUSED] = ECONNREFUSED;
- gf_errno_to_error_array[ECONNREFUSED] = GF_ERROR_CODE_CONNREFUSED;
-
- /* ELOOP 62 / * Too many levels of symbolic links */
- gf_error_to_errno_array[GF_ERROR_CODE_LOOP] = ELOOP;
- gf_errno_to_error_array[ELOOP] = GF_ERROR_CODE_LOOP;
-
- /* ENAMETOOLONG 63 / * File name too long */
- gf_error_to_errno_array[GF_ERROR_CODE_NAMETOOLONG] = ENAMETOOLONG;
- gf_errno_to_error_array[ENAMETOOLONG] = GF_ERROR_CODE_NAMETOOLONG;
-
- /* EHOSTDOWN 64 / * Host is down */
- gf_error_to_errno_array[GF_ERROR_CODE_HOSTDOWN] = EHOSTDOWN;
- gf_errno_to_error_array[EHOSTDOWN] = GF_ERROR_CODE_HOSTDOWN;
-
- /* EHOSTUNREACH 65 / * No route to host */
- gf_error_to_errno_array[GF_ERROR_CODE_HOSTUNREACH] = EHOSTUNREACH;
- gf_errno_to_error_array[EHOSTUNREACH] = GF_ERROR_CODE_HOSTUNREACH;
-
- /* ENOTEMPTY 66 / * Directory not empty */
- gf_error_to_errno_array[GF_ERROR_CODE_NOTEMPTY] = ENOTEMPTY;
- gf_errno_to_error_array[ENOTEMPTY] = GF_ERROR_CODE_NOTEMPTY;
-
- /* EPROCLIM 67 / * Too many processes */
- gf_error_to_errno_array[GF_ERROR_CODE_PROCLIM] = EPROCLIM;
- gf_errno_to_error_array[EPROCLIM] = GF_ERROR_CODE_PROCLIM;
-
- /* EUSERS 68 / * Too many users */
- gf_error_to_errno_array[GF_ERROR_CODE_USERS] = EUSERS;
- gf_errno_to_error_array[EUSERS] = GF_ERROR_CODE_USERS;
-
- /* EDQUOT 69 / * Disc quota exceeded */
- gf_error_to_errno_array[GF_ERROR_CODE_DQUOT] = EDQUOT;
- gf_errno_to_error_array[EDQUOT] = GF_ERROR_CODE_DQUOT;
-
- /* ESTALE 70 / * Stale NFS file handle */
- gf_error_to_errno_array[GF_ERROR_CODE_STALE] = ESTALE;
- gf_errno_to_error_array[ESTALE] = GF_ERROR_CODE_STALE;
-
- /* EREMOTE 71 / * Too many levels of remote in path */
- gf_error_to_errno_array[GF_ERROR_CODE_REMOTE] = EREMOTE;
- gf_errno_to_error_array[EREMOTE] = GF_ERROR_CODE_REMOTE;
-
- /* EBADRPC 72 / * RPC struct is bad */
- gf_error_to_errno_array[GF_ERROR_CODE_BADRPC] = EBADRPC;
- gf_errno_to_error_array[EBADRPC] = GF_ERROR_CODE_BADRPC;
-
- /* ERPCMISMATCH 73 / * RPC version wrong */
- gf_error_to_errno_array[GF_ERROR_CODE_RPCMISMATCH] = ERPCMISMATCH;
- gf_errno_to_error_array[ERPCMISMATCH] = GF_ERROR_CODE_RPCMISMATCH;
-
- /* EPROGUNAVAIL 74 / * RPC prog. not avail */
- gf_error_to_errno_array[GF_ERROR_CODE_PROGUNAVAIL] = EPROGUNAVAIL;
- gf_errno_to_error_array[EPROGUNAVAIL] = GF_ERROR_CODE_PROGUNAVAIL;
-
- /* EPROGMISMATCH 75 / * Program version wrong */
- gf_error_to_errno_array[GF_ERROR_CODE_PROGMISMATCH] = EPROGMISMATCH;
- gf_errno_to_error_array[EPROGMISMATCH] = GF_ERROR_CODE_PROGMISMATCH;
-
- /* EPROCUNAVAIL 76 / * Bad procedure for program */
- gf_error_to_errno_array[GF_ERROR_CODE_PROCUNAVAIL] = EPROCUNAVAIL;
- gf_errno_to_error_array[EPROCUNAVAIL] = GF_ERROR_CODE_PROCUNAVAIL;
-
- /* ENOLCK 77 / * No locks available */
- gf_error_to_errno_array[GF_ERROR_CODE_NOLCK] = ENOLCK;
- gf_errno_to_error_array[ENOLCK] = GF_ERROR_CODE_NOLCK;
-
- /* ENOSYS 78 / * Function not implemented */
- gf_error_to_errno_array[GF_ERROR_CODE_NOSYS] = ENOSYS;
- gf_errno_to_error_array[ENOSYS] = GF_ERROR_CODE_NOSYS;
-
- /* EFTYPE 79 / * Inappropriate file type or format */
- gf_error_to_errno_array[GF_ERROR_CODE_FTYPE] = EFTYPE;
- gf_errno_to_error_array[EFTYPE] = GF_ERROR_CODE_FTYPE;
-
- /* EAUTH 80 / * Authentication error */
- gf_error_to_errno_array[GF_ERROR_CODE_AUTH] = EAUTH;
- gf_errno_to_error_array[EAUTH] = GF_ERROR_CODE_AUTH;
-
- /* ENEEDAUTH 81 / * Need authenticator */
- gf_error_to_errno_array[GF_ERROR_CODE_NEEDAUTH] = ENEEDAUTH;
- gf_errno_to_error_array[ENEEDAUTH] = GF_ERROR_CODE_NEEDAUTH;
-
- /* EIDRM 82 / * Identifier removed */
- gf_error_to_errno_array[GF_ERROR_CODE_IDRM] = EIDRM;
- gf_errno_to_error_array[EIDRM] = GF_ERROR_CODE_IDRM;
-
- /* ENOMSG 83 / * No message of desired type */
- gf_error_to_errno_array[GF_ERROR_CODE_NOMSG] = ENOMSG;
- gf_errno_to_error_array[ENOMSG] = GF_ERROR_CODE_NOMSG;
-
- /* EOVERFLOW 84 / * Value too large to be stored in data type */
- gf_error_to_errno_array[GF_ERROR_CODE_OVERFLOW] = EOVERFLOW;
- gf_errno_to_error_array[EOVERFLOW] = GF_ERROR_CODE_OVERFLOW;
-
- /* ECANCELED 85 / * Operation canceled */
- gf_error_to_errno_array[GF_ERROR_CODE_CANCELED] = ECANCELED;
- gf_errno_to_error_array[ECANCELED] = GF_ERROR_CODE_CANCELED;
-
- /* EILSEQ 86 / * Illegal byte sequence */
- gf_error_to_errno_array[GF_ERROR_CODE_ILSEQ] = EILSEQ;
- gf_errno_to_error_array[EILSEQ] = GF_ERROR_CODE_ILSEQ;
-
- /* ENOATTR 87 / * Attribute not found */
- gf_error_to_errno_array[GF_ERROR_CODE_NOATTR] = ENOATTR;
- gf_errno_to_error_array[ENOATTR] = GF_ERROR_CODE_NOATTR;
-
- /* EDOOFUS 88 / * Programming error */
- gf_error_to_errno_array[GF_ERROR_CODE_DOOFUS] = EDOOFUS;
- gf_errno_to_error_array[EDOOFUS] = GF_ERROR_CODE_DOOFUS;
+ /* Quite a bit of things changed in FreeBSD - current */
+
+ /* EAGAIN 35 / * Try Again */
+ gf_error_to_errno_array[GF_ERROR_CODE_AGAIN] = EAGAIN;
+ gf_errno_to_error_array[EAGAIN] = GF_ERROR_CODE_AGAIN;
+
+ /* EDEADLK 11 / * Resource deadlock would occur */
+ gf_error_to_errno_array[GF_ERROR_CODE_DEADLK] = EDEADLK;
+ gf_errno_to_error_array[EDEADLK] = GF_ERROR_CODE_DEADLK;
+
+ /* EINPROGRESS 36 / * Operation now in progress */
+ gf_error_to_errno_array[GF_ERROR_CODE_INPROGRESS] = EINPROGRESS;
+ gf_errno_to_error_array[EINPROGRESS] = GF_ERROR_CODE_INPROGRESS;
+
+ /* EALREADY 37 / * Operation already in progress */
+ gf_error_to_errno_array[GF_ERROR_CODE_ALREADY] = EALREADY;
+ gf_errno_to_error_array[EALREADY] = GF_ERROR_CODE_ALREADY;
+
+ /* ENOTSOCK 38 / * Socket operation on non-socket
+ */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOTSOCK] = ENOTSOCK;
+ gf_errno_to_error_array[ENOTSOCK] = GF_ERROR_CODE_NOTSOCK;
+
+ /* EDESTADDRREQ 39 / * Destination address required */
+ gf_error_to_errno_array[GF_ERROR_CODE_DESTADDRREQ] = EDESTADDRREQ;
+ gf_errno_to_error_array[EDESTADDRREQ] = GF_ERROR_CODE_DESTADDRREQ;
+
+ /* EMSGSIZE 40 / * Message too long */
+ gf_error_to_errno_array[GF_ERROR_CODE_MSGSIZE] = EMSGSIZE;
+ gf_errno_to_error_array[EMSGSIZE] = GF_ERROR_CODE_MSGSIZE;
+
+ /* EPROTOTYPE 41 / * Protocol wrong type for socket
+ */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROTOTYPE] = EPROTOTYPE;
+ gf_errno_to_error_array[EPROTOTYPE] = GF_ERROR_CODE_PROTOTYPE;
+
+ /* ENOPROTOOPT 42 / * Protocol not available */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOPROTOOPT] = ENOPROTOOPT;
+ gf_errno_to_error_array[ENOPROTOOPT] = GF_ERROR_CODE_NOPROTOOPT;
+
+ /* EPROTONOSUPPORT 43 / * Protocol not supported */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROTONOSUPPORT] = EPROTONOSUPPORT;
+ gf_errno_to_error_array[EPROTONOSUPPORT] = GF_ERROR_CODE_PROTONOSUPPORT;
+
+ /* ESOCKTNOSUPPORT 44 / * Socket type not supported */
+ gf_error_to_errno_array[GF_ERROR_CODE_SOCKTNOSUPPORT] = ESOCKTNOSUPPORT;
+ gf_errno_to_error_array[ESOCKTNOSUPPORT] = GF_ERROR_CODE_SOCKTNOSUPPORT;
+
+ /* EOPNOTSUPP 45 / * Operation not supported */
+ gf_error_to_errno_array[GF_ERROR_CODE_OPNOTSUPP] = EOPNOTSUPP;
+ gf_errno_to_error_array[EOPNOTSUPP] = GF_ERROR_CODE_OPNOTSUPP;
+
+ /* EPFNOSUPPORT 46 / * Protocol family not supported */
+ gf_error_to_errno_array[GF_ERROR_CODE_PFNOSUPPORT] = EPFNOSUPPORT;
+ gf_errno_to_error_array[EPFNOSUPPORT] = GF_ERROR_CODE_PFNOSUPPORT;
+
+ /* EAFNOSUPPORT 47 / * Address family not supported by
+ * protocol family */
+ gf_error_to_errno_array[GF_ERROR_CODE_AFNOSUPPORT] = EAFNOSUPPORT;
+ gf_errno_to_error_array[EAFNOSUPPORT] = GF_ERROR_CODE_AFNOSUPPORT;
+
+ /* EADDRINUSE 48 / * Address already in use */
+ gf_error_to_errno_array[GF_ERROR_CODE_ADDRINUSE] = EADDRINUSE;
+ gf_errno_to_error_array[EADDRINUSE] = GF_ERROR_CODE_ADDRINUSE;
+
+ /* EADDRNOTAVAIL 49 / * Can't assign requested address
+ */
+ gf_error_to_errno_array[GF_ERROR_CODE_ADDRNOTAVAIL] = EADDRNOTAVAIL;
+ gf_errno_to_error_array[EADDRNOTAVAIL] = GF_ERROR_CODE_ADDRNOTAVAIL;
+
+ /* ENETDOWN 50 / * Network is down */
+ gf_error_to_errno_array[GF_ERROR_CODE_NETDOWN] = ENETDOWN;
+ gf_errno_to_error_array[ENETDOWN] = GF_ERROR_CODE_NETDOWN;
+
+ /* ENETUNREACH 51 / * Network is unreachable */
+ gf_error_to_errno_array[GF_ERROR_CODE_NETUNREACH] = ENETUNREACH;
+ gf_errno_to_error_array[ENETUNREACH] = GF_ERROR_CODE_NETUNREACH;
+
+ /* ENETRESET 52 / * Network dropped connection on
+ * reset */
+ gf_error_to_errno_array[GF_ERROR_CODE_NETRESET] = ENETRESET;
+ gf_errno_to_error_array[ENETRESET] = GF_ERROR_CODE_NETRESET;
+
+ /* ECONNABORTED 53 / * Software caused connection abort
+ */
+ gf_error_to_errno_array[GF_ERROR_CODE_CONNABORTED] = ECONNABORTED;
+ gf_errno_to_error_array[ECONNABORTED] = GF_ERROR_CODE_CONNABORTED;
+
+ /* ECONNRESET 54 / * Connection reset by peer */
+ gf_error_to_errno_array[GF_ERROR_CODE_CONNRESET] = ECONNRESET;
+ gf_errno_to_error_array[ECONNRESET] = GF_ERROR_CODE_CONNRESET;
+
+ /* ENOBUFS 55 / * No buffer space available */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOBUFS] = ENOBUFS;
+ gf_errno_to_error_array[ENOBUFS] = GF_ERROR_CODE_NOBUFS;
+
+ /* EISCONN 56 / * Socket is already connected */
+ gf_error_to_errno_array[GF_ERROR_CODE_ISCONN] = EISCONN;
+ gf_errno_to_error_array[EISCONN] = GF_ERROR_CODE_ISCONN;
+
+ /* ENOTCONN 57 / * Socket is not connected */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOTCONN] = ENOTCONN;
+ gf_errno_to_error_array[ENOTCONN] = GF_ERROR_CODE_NOTCONN;
+
+ /* ESHUTDOWN 58 / * Can't send after socket shutdown
+ */
+ gf_error_to_errno_array[GF_ERROR_CODE_SHUTDOWN] = ESHUTDOWN;
+ gf_errno_to_error_array[ESHUTDOWN] = GF_ERROR_CODE_SHUTDOWN;
+
+ /* ETOOMANYREFS 59 / * Too many references: can't
+ * splice */
+ gf_error_to_errno_array[GF_ERROR_CODE_TOOMANYREFS] = ETOOMANYREFS;
+ gf_errno_to_error_array[ETOOMANYREFS] = GF_ERROR_CODE_TOOMANYREFS;
+
+ /* ETIMEDOUT 60 / * Operation timed out */
+ gf_error_to_errno_array[GF_ERROR_CODE_TIMEDOUT] = ETIMEDOUT;
+ gf_errno_to_error_array[ETIMEDOUT] = GF_ERROR_CODE_TIMEDOUT;
+
+ /* ECONNREFUSED 61 / * Connection refused */
+ gf_error_to_errno_array[GF_ERROR_CODE_CONNREFUSED] = ECONNREFUSED;
+ gf_errno_to_error_array[ECONNREFUSED] = GF_ERROR_CODE_CONNREFUSED;
+
+ /* ELOOP 62 / * Too many levels of symbolic
+ * links */
+ gf_error_to_errno_array[GF_ERROR_CODE_LOOP] = ELOOP;
+ gf_errno_to_error_array[ELOOP] = GF_ERROR_CODE_LOOP;
+
+ /* ENAMETOOLONG 63 / * File name too long */
+ gf_error_to_errno_array[GF_ERROR_CODE_NAMETOOLONG] = ENAMETOOLONG;
+ gf_errno_to_error_array[ENAMETOOLONG] = GF_ERROR_CODE_NAMETOOLONG;
+
+ /* EHOSTDOWN 64 / * Host is down */
+ gf_error_to_errno_array[GF_ERROR_CODE_HOSTDOWN] = EHOSTDOWN;
+ gf_errno_to_error_array[EHOSTDOWN] = GF_ERROR_CODE_HOSTDOWN;
+
+ /* EHOSTUNREACH 65 / * No route to host */
+ gf_error_to_errno_array[GF_ERROR_CODE_HOSTUNREACH] = EHOSTUNREACH;
+ gf_errno_to_error_array[EHOSTUNREACH] = GF_ERROR_CODE_HOSTUNREACH;
+
+ /* ENOTEMPTY 66 / * Directory not empty */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOTEMPTY] = ENOTEMPTY;
+ gf_errno_to_error_array[ENOTEMPTY] = GF_ERROR_CODE_NOTEMPTY;
+
+ /* EPROCLIM 67 / * Too many processes */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROCLIM] = EPROCLIM;
+ gf_errno_to_error_array[EPROCLIM] = GF_ERROR_CODE_PROCLIM;
+
+ /* EUSERS 68 / * Too many users */
+ gf_error_to_errno_array[GF_ERROR_CODE_USERS] = EUSERS;
+ gf_errno_to_error_array[EUSERS] = GF_ERROR_CODE_USERS;
+
+ /* EDQUOT 69 / * Disc quota exceeded */
+ gf_error_to_errno_array[GF_ERROR_CODE_DQUOT] = EDQUOT;
+ gf_errno_to_error_array[EDQUOT] = GF_ERROR_CODE_DQUOT;
+
+ /* ESTALE 70 / * Stale NFS file handle */
+ gf_error_to_errno_array[GF_ERROR_CODE_STALE] = ESTALE;
+ gf_errno_to_error_array[ESTALE] = GF_ERROR_CODE_STALE;
+
+ /* EREMOTE 71 / * Too many levels of remote in
+ * path */
+ gf_error_to_errno_array[GF_ERROR_CODE_REMOTE] = EREMOTE;
+ gf_errno_to_error_array[EREMOTE] = GF_ERROR_CODE_REMOTE;
+
+ /* EBADRPC 72 / * RPC struct is bad */
+ gf_error_to_errno_array[GF_ERROR_CODE_BADRPC] = EBADRPC;
+ gf_errno_to_error_array[EBADRPC] = GF_ERROR_CODE_BADRPC;
+
+ /* ERPCMISMATCH 73 / * RPC version wrong */
+ gf_error_to_errno_array[GF_ERROR_CODE_RPCMISMATCH] = ERPCMISMATCH;
+ gf_errno_to_error_array[ERPCMISMATCH] = GF_ERROR_CODE_RPCMISMATCH;
+
+ /* EPROGUNAVAIL 74 / * RPC prog. not avail */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROGUNAVAIL] = EPROGUNAVAIL;
+ gf_errno_to_error_array[EPROGUNAVAIL] = GF_ERROR_CODE_PROGUNAVAIL;
+
+ /* EPROGMISMATCH 75 / * Program version wrong */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROGMISMATCH] = EPROGMISMATCH;
+ gf_errno_to_error_array[EPROGMISMATCH] = GF_ERROR_CODE_PROGMISMATCH;
+
+ /* EPROCUNAVAIL 76 / * Bad procedure for program */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROCUNAVAIL] = EPROCUNAVAIL;
+ gf_errno_to_error_array[EPROCUNAVAIL] = GF_ERROR_CODE_PROCUNAVAIL;
+
+ /* ENOLCK 77 / * No locks available */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOLCK] = ENOLCK;
+ gf_errno_to_error_array[ENOLCK] = GF_ERROR_CODE_NOLCK;
+
+ /* ENOSYS 78 / * Function not implemented */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOSYS] = ENOSYS;
+ gf_errno_to_error_array[ENOSYS] = GF_ERROR_CODE_NOSYS;
+
+ /* EFTYPE 79 / * Inappropriate file type or
+ * format */
+ gf_error_to_errno_array[GF_ERROR_CODE_FTYPE] = EFTYPE;
+ gf_errno_to_error_array[EFTYPE] = GF_ERROR_CODE_FTYPE;
+
+ /* EAUTH 80 / * Authentication error */
+ gf_error_to_errno_array[GF_ERROR_CODE_AUTH] = EAUTH;
+ gf_errno_to_error_array[EAUTH] = GF_ERROR_CODE_AUTH;
+
+ /* ENEEDAUTH 81 / * Need authenticator */
+ gf_error_to_errno_array[GF_ERROR_CODE_NEEDAUTH] = ENEEDAUTH;
+ gf_errno_to_error_array[ENEEDAUTH] = GF_ERROR_CODE_NEEDAUTH;
+
+ /* EIDRM 82 / * Identifier removed */
+ gf_error_to_errno_array[GF_ERROR_CODE_IDRM] = EIDRM;
+ gf_errno_to_error_array[EIDRM] = GF_ERROR_CODE_IDRM;
+
+ /* ENOMSG 83 / * No message of desired type */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOMSG] = ENOMSG;
+ gf_errno_to_error_array[ENOMSG] = GF_ERROR_CODE_NOMSG;
+
+ /* EOVERFLOW 84 / * Value too large to be stored in
+ * data type */
+ gf_error_to_errno_array[GF_ERROR_CODE_OVERFLOW] = EOVERFLOW;
+ gf_errno_to_error_array[EOVERFLOW] = GF_ERROR_CODE_OVERFLOW;
+
+ /* ECANCELED 85 / * Operation canceled */
+ gf_error_to_errno_array[GF_ERROR_CODE_CANCELED] = ECANCELED;
+ gf_errno_to_error_array[ECANCELED] = GF_ERROR_CODE_CANCELED;
+
+ /* EILSEQ 86 / * Illegal byte sequence */
+ gf_error_to_errno_array[GF_ERROR_CODE_ILSEQ] = EILSEQ;
+ gf_errno_to_error_array[EILSEQ] = GF_ERROR_CODE_ILSEQ;
+
+ /* ENOATTR 87 / * Attribute not found */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOATTR] = ENOATTR;
+ gf_errno_to_error_array[ENOATTR] = GF_ERROR_CODE_NOATTR;
+
+#ifdef EDOOFUS
+ /* EDOOFUS 88 / * Programming error */
+ gf_error_to_errno_array[GF_ERROR_CODE_DOOFUS] = EDOOFUS;
+ gf_errno_to_error_array[EDOOFUS] = GF_ERROR_CODE_DOOFUS;
+#endif
- /* EBADMSG 89 / * Bad message */
- gf_error_to_errno_array[GF_ERROR_CODE_BADMSG] = EBADMSG;
- gf_errno_to_error_array[EBADMSG] = GF_ERROR_CODE_BADMSG;
+ /* EBADMSG 89 / * Bad message */
+ gf_error_to_errno_array[GF_ERROR_CODE_BADMSG] = EBADMSG;
+ gf_errno_to_error_array[EBADMSG] = GF_ERROR_CODE_BADMSG;
- /* EMULTIHOP 90 / * Multihop attempted */
- gf_error_to_errno_array[GF_ERROR_CODE_MULTIHOP] = EMULTIHOP;
- gf_errno_to_error_array[EMULTIHOP] = GF_ERROR_CODE_MULTIHOP;
+#ifdef __NetBSD__
+ /* ENODATA 89 / * No message available */
+ gf_error_to_errno_array[GF_ERROR_CODE_NODATA] = ENODATA;
+ gf_errno_to_error_array[ENODATA] = GF_ERROR_CODE_NODATA;
+#endif
- /* ENOLINK 91 / * Link has been severed */
- gf_error_to_errno_array[GF_ERROR_CODE_NOLINK] = ENOLINK;
- gf_errno_to_error_array[ENOLINK] = GF_ERROR_CODE_NOLINK;
+ /* EMULTIHOP 90 / * Multihop attempted */
+ gf_error_to_errno_array[GF_ERROR_CODE_MULTIHOP] = EMULTIHOP;
+ gf_errno_to_error_array[EMULTIHOP] = GF_ERROR_CODE_MULTIHOP;
- /* EPROTO 92 / * Protocol error */
- gf_error_to_errno_array[GF_ERROR_CODE_PROTO] = EPROTO;
- gf_errno_to_error_array[EPROTO] = GF_ERROR_CODE_PROTO;
+ /* ENOLINK 91 / * Link has been severed */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOLINK] = ENOLINK;
+ gf_errno_to_error_array[ENOLINK] = GF_ERROR_CODE_NOLINK;
+ /* EPROTO 92 / * Protocol error */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROTO] = EPROTO;
+ gf_errno_to_error_array[EPROTO] = GF_ERROR_CODE_PROTO;
- return ;
+ return;
}
#endif /* GF_BSD_HOST_OS */
#ifdef GF_LINUX_HOST_OS
static void
-init_compat_errno_arrays ()
+init_compat_errno_arrays()
{
- /* Things are fine. Everything should work seemlessly on GNU/Linux machines */
- return ;
+ /* Things are fine. Everything should work seemlessly on GNU/Linux machines
+ */
+ return;
}
#endif /* GF_LINUX_HOST_OS */
-
static void
-init_errno_arrays ()
+init_errno_arrays()
{
- int i;
- for (i=0; i < GF_ERROR_CODE_UNKNOWN; i++) {
- gf_errno_to_error_array[i] = i;
- gf_error_to_errno_array[i] = i;
- }
- /* Now change the order if it needs to be. */
- init_compat_errno_arrays();
-
- return;
+ int i;
+ for (i = 0; i < GF_ERROR_CODE_UNKNOWN; i++) {
+ gf_errno_to_error_array[i] = i;
+ gf_error_to_errno_array[i] = i;
+ }
+ /* Now change the order if it needs to be. */
+ init_compat_errno_arrays();
+
+ return;
}
int32_t
-gf_errno_to_error (int32_t op_errno)
+gf_errno_to_error(int32_t op_errno)
{
- if (!gf_compat_errno_init_done) {
- init_errno_arrays ();
- gf_compat_errno_init_done = 1;
- }
+ if (!gf_compat_errno_init_done) {
+ init_errno_arrays();
+ gf_compat_errno_init_done = 1;
+ }
- if ((op_errno > GF_ERROR_CODE_SUCCESS) && (op_errno < GF_ERROR_CODE_UNKNOWN))
- return gf_errno_to_error_array[op_errno];
+ if ((op_errno > GF_ERROR_CODE_SUCCESS) &&
+ (op_errno < GF_ERROR_CODE_UNKNOWN))
+ return gf_errno_to_error_array[op_errno];
- return op_errno;
+ return op_errno;
}
-
int32_t
-gf_error_to_errno (int32_t error)
+gf_error_to_errno(int32_t error)
{
- if (!gf_compat_errno_init_done) {
- init_errno_arrays ();
- gf_compat_errno_init_done = 1;
- }
+ if (!gf_compat_errno_init_done) {
+ init_errno_arrays();
+ gf_compat_errno_init_done = 1;
+ }
- if ((error > GF_ERROR_CODE_SUCCESS) && (error < GF_ERROR_CODE_UNKNOWN))
- return gf_error_to_errno_array[error];
+ if ((error > GF_ERROR_CODE_SUCCESS) && (error < GF_ERROR_CODE_UNKNOWN))
+ return gf_error_to_errno_array[error];
- return error;
+ return error;
}
diff --git a/libglusterfs/src/compat-errno.h b/libglusterfs/src/compat-errno.h
deleted file mode 100644
index a61457960c4..00000000000
--- a/libglusterfs/src/compat-errno.h
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef __COMPAT_ERRNO_H__
-#define __COMPAT_ERRNO_H__
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include <errno.h>
-
-#define GF_ERROR_CODE_SUCCESS 0
-#define GF_ERROR_CODE_UNKNOWN 1024
-#define GF_ERRNO_UNKNOWN 1024
-
-#define GF_ERROR_CODE_PERM 1 /* Operation not permitted */
-#define GF_ERROR_CODE_NOENT 2 /* No such file or directory */
-#define GF_ERROR_CODE_SRCH 3 /* No such process */
-#define GF_ERROR_CODE_INTR 4 /* Interrupted system call */
-#define GF_ERROR_CODE_IO 5 /* I/O error */
-#define GF_ERROR_CODE_NXIO 6 /* No such device or address */
-#define GF_ERROR_CODE_2BIG 7 /* Argument list too long */
-#define GF_ERROR_CODE_NOEXEC 8 /* Exec format error */
-#define GF_ERROR_CODE_BADF 9 /* Bad file number */
-#define GF_ERROR_CODE_CHILD 10 /* No child processes */
-#define GF_ERROR_CODE_AGAIN 11 /* Try again */
-#define GF_ERROR_CODE_NOMEM 12 /* Out of memory */
-#define GF_ERROR_CODE_ACCES 13 /* Permission denied */
-#define GF_ERROR_CODE_FAULT 14 /* Bad address */
-#define GF_ERROR_CODE_NOTBLK 15 /* Block device required */
-#define GF_ERROR_CODE_BUSY 16 /* Device or resource busy */
-#define GF_ERROR_CODE_EXIST 17 /* File exists */
-#define GF_ERROR_CODE_XDEV 18 /* Cross-device link */
-#define GF_ERROR_CODE_NODEV 19 /* No such device */
-#define GF_ERROR_CODE_NOTDIR 20 /* Not a directory */
-#define GF_ERROR_CODE_ISDIR 21 /* Is a directory */
-#define GF_ERROR_CODE_INVAL 22 /* Invalid argument */
-#define GF_ERROR_CODE_NFILE 23 /* File table overflow */
-#define GF_ERROR_CODE_MFILE 24 /* Too many open files */
-#define GF_ERROR_CODE_NOTTY 25 /* Not a typewriter */
-#define GF_ERROR_CODE_TXTBSY 26 /* Text file busy */
-#define GF_ERROR_CODE_FBIG 27 /* File too large */
-#define GF_ERROR_CODE_NOSPC 28 /* No space left on device */
-#define GF_ERROR_CODE_SPIPE 29 /* Illegal seek */
-#define GF_ERROR_CODE_ROFS 30 /* Read-only file system */
-#define GF_ERROR_CODE_MLINK 31 /* Too many links */
-#define GF_ERROR_CODE_PIPE 32 /* Broken pipe */
-#define GF_ERROR_CODE_DOM 33 /* Math argument out of domain of func */
-#define GF_ERROR_CODE_RANGE 34 /* Math result not representable */
-#define GF_ERROR_CODE_DEADLK 35 /* Resource deadlock would occur */
-#define GF_ERROR_CODE_NAMETOOLONG 36 /* File name too long */
-#define GF_ERROR_CODE_NOLCK 37 /* No record locks available */
-#define GF_ERROR_CODE_NOSYS 38 /* Function not implemented */
-#define GF_ERROR_CODE_NOTEMPTY 39 /* Directory not empty */
-#define GF_ERROR_CODE_LOOP 40 /* Too many symbolic links encountered */
-
-#define GF_ERROR_CODE_NOMSG 42 /* No message of desired type */
-#define GF_ERROR_CODE_IDRM 43 /* Identifier removed */
-#define GF_ERROR_CODE_CHRNG 44 /* Channel number out of range */
-#define GF_ERROR_CODE_L2NSYNC 45 /* Level 2 not synchronized */
-#define GF_ERROR_CODE_L3HLT 46 /* Level 3 halted */
-#define GF_ERROR_CODE_L3RST 47 /* Level 3 reset */
-#define GF_ERROR_CODE_LNRNG 48 /* Link number out of range */
-#define GF_ERROR_CODE_UNATCH 49 /* Protocol driver not attached */
-#define GF_ERROR_CODE_NOCSI 50 /* No CSI structure available */
-#define GF_ERROR_CODE_L2HLT 51 /* Level 2 halted */
-#define GF_ERROR_CODE_BADE 52 /* Invalid exchange */
-#define GF_ERROR_CODE_BADR 53 /* Invalid request descriptor */
-#define GF_ERROR_CODE_XFULL 54 /* Exchange full */
-#define GF_ERROR_CODE_NOANO 55 /* No anode */
-#define GF_ERROR_CODE_BADRQC 56 /* Invalid request code */
-#define GF_ERROR_CODE_BADSLT 57 /* Invalid slot */
-#define GF_ERROR_CODE_BFONT 59 /* Bad font file format */
-#define GF_ERROR_CODE_NOSTR 60 /* Device not a stream */
-#define GF_ERROR_CODE_NODATA 61 /* No data available */
-#define GF_ERROR_CODE_TIME 62 /* Timer expired */
-#define GF_ERROR_CODE_NOSR 63 /* Out of streams resources */
-#define GF_ERROR_CODE_NONET 64 /* Machine is not on the network */
-#define GF_ERROR_CODE_NOPKG 65 /* Package not installed */
-#define GF_ERROR_CODE_REMOTE 66 /* Object is remote */
-#define GF_ERROR_CODE_NOLINK 67 /* Link has been severed */
-#define GF_ERROR_CODE_ADV 68 /* Advertise error */
-#define GF_ERROR_CODE_SRMNT 69 /* Srmount error */
-#define GF_ERROR_CODE_COMM 70 /* Communication error on send */
-#define GF_ERROR_CODE_PROTO 71 /* Protocol error */
-#define GF_ERROR_CODE_MULTIHOP 72 /* Multihop attempted */
-#define GF_ERROR_CODE_DOTDOT 73 /* RFS specific error */
-#define GF_ERROR_CODE_BADMSG 74 /* Not a data message */
-#define GF_ERROR_CODE_OVERFLOW 75 /* Value too large for defined data type */
-#define GF_ERROR_CODE_NOTUNIQ 76 /* Name not unique on network */
-#define GF_ERROR_CODE_BADFD 77 /* File descriptor in bad state */
-#define GF_ERROR_CODE_REMCHG 78 /* Remote address changed */
-#define GF_ERROR_CODE_LIBACC 79 /* Can not access a needed shared library */
-#define GF_ERROR_CODE_LIBBAD 80 /* Accessing a corrupted shared library */
-#define GF_ERROR_CODE_LIBSCN 81 /* .lib section in a.out corrupted */
-#define GF_ERROR_CODE_LIBMAX 82 /* Attempting to link in too many shared libraries */
-#define GF_ERROR_CODE_LIBEXEC 83 /* Cannot exec a shared library directly */
-#define GF_ERROR_CODE_ILSEQ 84 /* Illegal byte sequence */
-#define GF_ERROR_CODE_RESTART 85 /* Interrupted system call should be restarted */
-#define GF_ERROR_CODE_STRPIPE 86 /* Streams pipe error */
-#define GF_ERROR_CODE_USERS 87 /* Too many users */
-#define GF_ERROR_CODE_NOTSOCK 88 /* Socket operation on non-socket */
-#define GF_ERROR_CODE_DESTADDRREQ 89 /* Destination address required */
-#define GF_ERROR_CODE_MSGSIZE 90 /* Message too long */
-#define GF_ERROR_CODE_PROTOTYPE 91 /* Protocol wrong type for socket */
-#define GF_ERROR_CODE_NOPROTOOPT 92 /* Protocol not available */
-#define GF_ERROR_CODE_PROTONOSUPPORT 93 /* Protocol not supported */
-#define GF_ERROR_CODE_SOCKTNOSUPPORT 94 /* Socket type not supported */
-#define GF_ERROR_CODE_OPNOTSUPP 95 /* Operation not supported on transport endpoint */
-#define GF_ERROR_CODE_PFNOSUPPORT 96 /* Protocol family not supported */
-#define GF_ERROR_CODE_AFNOSUPPORT 97 /* Address family not supported by protocol */
-#define GF_ERROR_CODE_ADDRINUSE 98 /* Address already in use */
-#define GF_ERROR_CODE_ADDRNOTAVAIL 99 /* Cannot assign requested address */
-#define GF_ERROR_CODE_NETDOWN 100 /* Network is down */
-#define GF_ERROR_CODE_NETUNREACH 101 /* Network is unreachable */
-#define GF_ERROR_CODE_NETRESET 102 /* Network dropped connection because of reset */
-#define GF_ERROR_CODE_CONNABORTED 103 /* Software caused connection abort */
-#define GF_ERROR_CODE_CONNRESET 104 /* Connection reset by peer */
-#define GF_ERROR_CODE_NOBUFS 105 /* No buffer space available */
-#define GF_ERROR_CODE_ISCONN 106 /* Transport endpoint is already connected */
-#define GF_ERROR_CODE_NOTCONN 107 /* Transport endpoint is not connected */
-#define GF_ERROR_CODE_SHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
-#define GF_ERROR_CODE_TOOMANYREFS 109 /* Too many references: cannot splice */
-#define GF_ERROR_CODE_TIMEDOUT 110 /* Connection timed out */
-#define GF_ERROR_CODE_CONNREFUSED 111 /* Connection refused */
-#define GF_ERROR_CODE_HOSTDOWN 112 /* Host is down */
-#define GF_ERROR_CODE_HOSTUNREACH 113 /* No route to host */
-#define GF_ERROR_CODE_ALREADY 114 /* Operation already in progress */
-#define GF_ERROR_CODE_INPROGRESS 115 /* Operation now in progress */
-#define GF_ERROR_CODE_ALREADY 114 /* Operation already in progress */
-#define GF_ERROR_CODE_INPROGRESS 115 /* Operation now in progress */
-#define GF_ERROR_CODE_STALE 116 /* Stale NFS file handle */
-#define GF_ERROR_CODE_UCLEAN 117 /* Structure needs cleaning */
-#define GF_ERROR_CODE_NOTNAM 118 /* Not a XENIX named type file */
-#define GF_ERROR_CODE_NAVAIL 119 /* No XENIX semaphores available */
-#define GF_ERROR_CODE_ISNAM 120 /* Is a named type file */
-#define GF_ERROR_CODE_REMOTEIO 121 /* Remote I/O error */
-#define GF_ERROR_CODE_DQUOT 122 /* Quota exceeded */
-#define GF_ERROR_CODE_NOMEDIUM 123 /* No medium found */
-#define GF_ERROR_CODE_MEDIUMTYPE 124 /* Wrong medium type */
-#define GF_ERROR_CODE_CANCELED 125 /* Operation Canceled */
-#define GF_ERROR_CODE_NOKEY 126 /* Required key not available */
-#define GF_ERROR_CODE_KEYEXPIRED 127 /* Key has expired */
-#define GF_ERROR_CODE_KEYREVOKED 128 /* Key has been revoked */
-#define GF_ERROR_CODE_KEYREJECTED 129 /* Key was rejected by service */
-
-/* for robust mutexes */
-#define GF_ERROR_CODE_OWNERDEAD 130 /* Owner died */
-#define GF_ERROR_CODE_NOTRECOVERABLE 131 /* State not recoverable */
-
-
-
-/* Should never be seen by user programs */
-#define GF_ERROR_CODE_RESTARTSYS 512
-#define GF_ERROR_CODE_RESTARTNOINTR 513
-#define GF_ERROR_CODE_RESTARTNOHAND 514 /* restart if no handler.. */
-#define GF_ERROR_CODE_NOIOCTLCMD 515 /* No ioctl command */
-#define GF_ERROR_CODE_RESTART_RESTARTBLOCK 516 /* restart by calling sys_restart_syscall */
-
-/* Defined for the NFSv3 protocol */
-#define GF_ERROR_CODE_BADHANDLE 521 /* Illegal NFS file handle */
-#define GF_ERROR_CODE_NOTSYNC 522 /* Update synchronization mismatch */
-#define GF_ERROR_CODE_BADCOOKIE 523 /* Cookie is stale */
-#define GF_ERROR_CODE_NOTSUPP 524 /* Operation is not supported */
-#define GF_ERROR_CODE_TOOSMALL 525 /* Buffer or request is too small */
-#define GF_ERROR_CODE_SERVERFAULT 526 /* An untranslatable error occurred */
-#define GF_ERROR_CODE_BADTYPE 527 /* Type not supported by server */
-#define GF_ERROR_CODE_JUKEBOX 528 /* Request initiated, but will not complete before timeout */
-#define GF_ERROR_CODE_IOCBQUEUED 529 /* iocb queued, will get completion event */
-#define GF_ERROR_CODE_IOCBRETRY 530 /* iocb queued, will trigger a retry */
-
-/* Darwin OS X */
-#define GF_ERROR_CODE_NOPOLICY 701
-#define GF_ERROR_CODE_BADMACHO 702
-#define GF_ERROR_CODE_PWROFF 703
-#define GF_ERROR_CODE_DEVERR 704
-#define GF_ERROR_CODE_BADARCH 705
-#define GF_ERROR_CODE_BADEXEC 706
-#define GF_ERROR_CODE_SHLIBVERS 707
-
-
-
-/* Solaris */
-/* ENOTACTIVE 73 / * Facility is not active */
-#define GF_ERROR_CODE_NOTACTIVE 801
-/* ELOCKUNMAPPED 72 / * locked lock was unmapped */
-#define GF_ERROR_CODE_LOCKUNMAPPED 802
-
-/* BSD system */
-#define GF_ERROR_CODE_PROCLIM 901 /* Too many processes */
-#define GF_ERROR_CODE_BADRPC 902 /* RPC struct is bad */
-#define GF_ERROR_CODE_RPCMISMATCH 903 /* RPC version wrong */
-#define GF_ERROR_CODE_PROGUNAVAIL 904 /* RPC prog. not avail */
-#define GF_ERROR_CODE_PROGMISMATCH 905 /* Program version wrong */
-#define GF_ERROR_CODE_PROCUNAVAIL 905 /* Bad procedure for program */
-#define GF_ERROR_CODE_FTYPE 906 /* Inappropriate file type or format */
-#define GF_ERROR_CODE_AUTH 907 /* Authentication error */
-#define GF_ERROR_CODE_NEEDAUTH 908 /* Need authenticator */
-#define GF_ERROR_CODE_DOOFUS 909 /* Programming error */
-
-#define GF_ERROR_CODE_NOATTR GF_ERROR_CODE_NODATA /* Attribute not found */
-
-/* Either one of enodata or enoattr will be there in system */
-#ifndef ENOATTR
-#define ENOATTR ENODATA
-#endif /* ENOATTR */
-
-#ifndef ENODATA
-#define ENODATA ENOATTR
-#endif /* ENODATA */
-
-#ifndef EBADFD
-#define EBADFD EBADRPC
-#endif /* EBADFD */
-
-/* These functions are defined for all the OS flags, but content will
- * be different for each OS flag.
- */
-int32_t gf_errno_to_error (int32_t op_errno);
-int32_t gf_error_to_errno (int32_t error);
-
-#endif /* __COMPAT_ERRNO_H__ */
diff --git a/libglusterfs/src/compat.c b/libglusterfs/src/compat.c
index a5a49d4e6a1..8a05a30a8fe 100644
--- a/libglusterfs/src/compat.c
+++ b/libglusterfs/src/compat.c
@@ -1,563 +1,618 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
#include <stdlib.h>
+#include <unistd.h>
#include <stdarg.h>
#include <getopt.h>
#include <sys/types.h>
#include <dirent.h>
-#ifdef GF_SOLARIS_HOST_OS
-#include "logging.h"
-#endif /* GF_SOLARIS_HOST_OS */
-
-#include "compat.h"
-#include "common-utils.h"
-#include "iatt.h"
-#include "inode.h"
+#include "glusterfs/logging.h"
+#include "glusterfs/compat.h"
+#include "glusterfs/iatt.h"
+#include "glusterfs/syscall.h"
+#include "glusterfs/run.h"
+#include "glusterfs/libglusterfs-messages.h"
#ifdef GF_SOLARIS_HOST_OS
int
-solaris_fsetxattr(int fd, const char* key, const char *value, size_t size,
+solaris_fsetxattr(int fd, const char *key, const char *value, size_t size,
int flags)
{
- int attrfd = -1;
- int ret = 0;
-
- attrfd = openat (fd, key, flags|O_CREAT|O_WRONLY|O_XATTR, 0777);
- if (attrfd >= 0) {
- ftruncate (attrfd, 0);
- ret = write (attrfd, value, size);
- close (attrfd);
- } else {
- if (errno != ENOENT)
- gf_log ("libglusterfs", GF_LOG_ERROR,
- "Couldn't set extended attribute for %d (%d)",
- fd, errno);
- return -1;
- }
-
- return 0;
+ int attrfd = -1;
+ int ret = 0;
+
+ attrfd = openat(fd, key, flags | O_CREAT | O_WRONLY | O_XATTR, 0777);
+ if (attrfd >= 0) {
+ ftruncate(attrfd, 0);
+ ret = write(attrfd, value, size);
+ close(attrfd);
+ } else {
+ if (errno != ENOENT)
+ gf_msg("libglusterfs", GF_LOG_ERROR, errno,
+ LG_MSG_SET_ATTRIBUTE_FAILED,
+ "Couldn't set "
+ "extended attribute for %d",
+ fd);
+ return -1;
+ }
+
+ return 0;
}
-
int
-solaris_fgetxattr(int fd, const char* key, char *value, size_t size)
+solaris_fgetxattr(int fd, const char *key, char *value, size_t size)
{
- int attrfd = -1;
- int ret = 0;
-
- attrfd = openat (fd, key, O_RDONLY|O_XATTR);
- if (attrfd >= 0) {
- if (size == 0) {
- struct stat buf;
- fstat (attrfd, &buf);
- ret = buf.st_size;
- } else {
- ret = read (attrfd, value, size);
- }
- close (attrfd);
+ int attrfd = -1;
+ int ret = 0;
+
+ attrfd = openat(fd, key, O_RDONLY | O_XATTR);
+ if (attrfd >= 0) {
+ if (size == 0) {
+ struct stat buf;
+ fstat(attrfd, &buf);
+ ret = buf.st_size;
} else {
- if (errno != ENOENT)
- gf_log ("libglusterfs", GF_LOG_INFO,
- "Couldn't read extended attribute for the file %d (%d)",
- fd, errno);
- if (errno == ENOENT)
- errno = ENODATA;
- return -1;
+ ret = read(attrfd, value, size);
}
-
- return ret;
+ close(attrfd);
+ } else {
+ if (errno != ENOENT)
+ gf_msg("libglusterfs", GF_LOG_INFO, errno,
+ LG_MSG_READ_ATTRIBUTE_FAILED,
+ "Couldn't read "
+ "extended attribute for the file %d",
+ fd);
+ if (errno == ENOENT)
+ errno = ENODATA;
+ return -1;
+ }
+
+ return ret;
}
/* Solaris does not support xattr for symlinks and dev files. Since gfid and
other trusted attributes are stored as xattrs, we need to provide support for
- them. A mapped regular file is stored in the /.glusterfs_xattr_inode of the export dir.
- All xattr ops related to the special files are redirected to this map file.
+ them. A mapped regular file is stored in the /.glusterfs_xattr_inode of the
+ export dir. All xattr ops related to the special files are redirected to this
+ map file.
*/
int
-make_export_path (const char *real_path, char **path)
+make_export_path(const char *real_path, char **path)
{
- int ret = -1;
- char *tmp = NULL;
- char *export_path = NULL;
- char *dup = NULL;
- char *ptr = NULL;
- char *freeptr = NULL;
- uuid_t gfid = {0, };
-
- export_path = GF_CALLOC (1, sizeof (char) * PATH_MAX, 0);
- if (!export_path)
- goto out;
+ int ret = -1;
+ char *tmp = NULL;
+ char *export_path = NULL;
+ char *dup = NULL;
+ char *ptr = NULL;
+ char *freeptr = NULL;
+ uuid_t gfid = {
+ 0,
+ };
+
+ export_path = GF_CALLOC(1, sizeof(char) * PATH_MAX, 0);
+ if (!export_path)
+ goto out;
- dup = gf_strdup (real_path);
- if (!dup)
- goto out;
+ dup = gf_strdup(real_path);
+ if (!dup)
+ goto out;
- freeptr = dup;
- ret = solaris_getxattr ("/", GFID_XATTR_KEY, gfid, 16);
- /* Return value of getxattr */
+ freeptr = dup;
+ ret = solaris_getxattr("/", GFID_XATTR_KEY, gfid, 16);
+ /* Return value of getxattr */
+ if (ret == 16) {
+ if (__is_root_gfid(gfid)) {
+ strcat(export_path, "/");
+ ret = 0;
+ goto done;
+ }
+ }
+
+ do {
+ ptr = strtok_r(dup, "/", &tmp);
+ if (!ptr)
+ break;
+ strcat(export_path, dup);
+ ret = solaris_getxattr(export_path, GFID_XATTR_KEY, gfid, 16);
if (ret == 16) {
- if (!__is_root_gfid (gfid)){
- strcat (export_path, "/");
- ret = 0;
- goto done;
- }
+ if (__is_root_gfid(gfid)) {
+ ret = 0;
+ goto done;
+ }
}
+ strcat(export_path, "/");
+ dup = tmp;
+ } while (ptr);
- do {
- ptr = strtok_r (dup, "/", &tmp);
- if (!ptr)
- break;
- strcat (export_path, dup);
- ret = solaris_getxattr (export_path, GFID_XATTR_KEY, gfid, 16);
- if (ret == 16) {
- if (!__is_root_gfid (gfid)) {
- ret = 0;
- goto done;
- }
- }
- strcat (export_path, "/");
- dup = tmp;
- } while (ptr);
-
- goto out;
+ goto out;
done:
- if (!ret) {
- *path = export_path;
- }
+ if (!ret) {
+ *path = export_path;
+ }
out:
- if (freeptr)
- GF_FREE (freeptr);
- if (ret && export_path)
- GF_FREE (export_path);
+ GF_FREE(freeptr);
+ if (ret && export_path)
+ GF_FREE(export_path);
- return ret;
+ return ret;
}
int
-solaris_xattr_resolve_path (const char *real_path, char **path)
+solaris_xattr_resolve_path(const char *real_path, char **path)
{
- int ret = -1;
- char *export_path = NULL;
- char xattr_path[PATH_MAX] = {0, };
- struct stat lstatbuf = {0, };
- struct iatt stbuf = {0, };
- struct stat statbuf = {0, };
-
- ret = lstat (real_path, &lstatbuf);
- if (ret != 0 )
- return ret;
- iatt_from_stat (&stbuf, &lstatbuf);
- if (IA_ISREG(stbuf.ia_type) || IA_ISDIR(stbuf.ia_type))
- return -1;
-
- ret = make_export_path (real_path, &export_path);
- if (!ret && export_path) {
- strcat (export_path, "/"GF_SOLARIS_XATTR_DIR);
- if (lstat (export_path, &statbuf)) {
- ret = mkdir (export_path, 0777);
- if (ret && (errno != EEXIST)) {
- gf_log ("", GF_LOG_DEBUG, "mkdir failed,"
- " errno: %d", errno);
- goto out;
- }
- }
+ int ret = -1;
+ char *export_path = NULL;
+ char xattr_path[PATH_MAX] = {
+ 0,
+ };
+ struct stat lstatbuf = {
+ 0,
+ };
+ struct iatt stbuf = {
+ 0,
+ };
+ struct stat statbuf = {
+ 0,
+ };
+
+ ret = lstat(real_path, &lstatbuf);
+ if (ret != 0)
+ return ret;
+ iatt_from_stat(&stbuf, &lstatbuf);
+ if (IA_ISREG(stbuf.ia_type) || IA_ISDIR(stbuf.ia_type))
+ return -1;
+
+ ret = make_export_path(real_path, &export_path);
+ if (!ret && export_path) {
+ strcat(export_path, "/" GF_SOLARIS_XATTR_DIR);
+ if (lstat(export_path, &statbuf)) {
+ ret = mkdir(export_path, 0755);
+ if (ret && (errno != EEXIST)) {
+ gf_msg_debug(THIS->name, 0,
+ "mkdir failed,"
+ " errno: %d",
+ errno);
+ goto out;
+ }
+ }
- snprintf(xattr_path, PATH_MAX, "%s%s%lu", export_path,
- "/", stbuf.ia_ino);
+ snprintf(xattr_path, PATH_MAX, "%s%s%lu", export_path, "/",
+ stbuf.ia_ino);
- ret = lstat (xattr_path, &statbuf);
+ ret = lstat(xattr_path, &statbuf);
- if (ret) {
- ret = mknod (xattr_path, S_IFREG|O_WRONLY, 0);
- if (ret && (errno != EEXIST)) {
- gf_log ("", GF_LOG_WARNING,"Failed to create "
- "mapped file %s, error %d", xattr_path,
- errno);
- goto out;
- }
- }
- *path = gf_strdup (xattr_path);
+ if (ret) {
+ ret = mknod(xattr_path, S_IFREG | O_WRONLY, 0);
+ if (ret && (errno != EEXIST)) {
+ gf_msg(THIS->name, GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED,
+ "Failed to "
+ "create mapped file %s",
+ xattr_path);
+ goto out;
+ }
}
+ *path = gf_strdup(xattr_path);
+ }
out:
- if (export_path)
- GF_FREE (export_path);
- if (*path)
- return 0;
- else
- return -1;
+ GF_FREE(export_path);
+ if (*path)
+ return 0;
+ else
+ return -1;
}
int
-solaris_setxattr(const char *path, const char* key, const char *value,
+solaris_setxattr(const char *path, const char *key, const char *value,
size_t size, int flags)
{
- int attrfd = -1;
- int ret = 0;
- char *mapped_path = NULL;
-
- ret = solaris_xattr_resolve_path (path, &mapped_path);
- if (!ret) {
- attrfd = attropen (mapped_path, key, flags|O_CREAT|O_WRONLY,
- 0777);
- } else {
- attrfd = attropen (path, key, flags|O_CREAT|O_WRONLY, 0777);
- }
- if (attrfd >= 0) {
- ftruncate (attrfd, 0);
- ret = write (attrfd, value, size);
- close (attrfd);
- ret = 0;
- } else {
- if (errno != ENOENT)
- gf_log ("libglusterfs", GF_LOG_ERROR,
- "Couldn't set extended attribute for %s (%d)",
- path, errno);
- ret = -1;
- }
- if (mapped_path)
- GF_FREE (mapped_path);
- return ret;
+ int attrfd = -1;
+ int ret = 0;
+ char *mapped_path = NULL;
+
+ ret = solaris_xattr_resolve_path(path, &mapped_path);
+ if (!ret) {
+ attrfd = attropen(mapped_path, key, flags | O_CREAT | O_WRONLY, 0777);
+ } else {
+ attrfd = attropen(path, key, flags | O_CREAT | O_WRONLY, 0777);
+ }
+ if (attrfd >= 0) {
+ ftruncate(attrfd, 0);
+ ret = write(attrfd, value, size);
+ close(attrfd);
+ ret = 0;
+ } else {
+ if (errno != ENOENT)
+ gf_msg("libglusterfs", GF_LOG_ERROR, errno,
+ LG_MSG_SET_ATTRIBUTE_FAILED,
+ "Couldn't set "
+ "extended attribute for %s",
+ path);
+ ret = -1;
+ }
+ GF_FREE(mapped_path);
+ return ret;
}
-
int
solaris_listxattr(const char *path, char *list, size_t size)
{
- int attrdirfd = -1;
- ssize_t len = 0;
- DIR *dirptr = NULL;
- struct dirent *dent = NULL;
- int newfd = -1;
- char *mapped_path = NULL;
- int ret = -1;
-
- ret = solaris_xattr_resolve_path (path, &mapped_path);
- if (!ret) {
- attrdirfd = attropen (mapped_path, ".", O_RDONLY, 0);
- } else {
- attrdirfd = attropen (path, ".", O_RDONLY, 0);
- }
- if (attrdirfd >= 0) {
- newfd = dup(attrdirfd);
- dirptr = fdopendir(newfd);
- if (dirptr) {
- while ((dent = readdir(dirptr))) {
- size_t listlen = strlen(dent->d_name);
- if (!strcmp(dent->d_name, ".") ||
- !strcmp(dent->d_name, "..")) {
- /* we don't want "." and ".." here */
- continue;
- }
- if (size == 0) {
- /* return the current size of the list
- of extended attribute names*/
- len += listlen + 1;
- } else {
- /* check size and copy entry + null
- into list. */
- if ((len + listlen + 1) > size) {
- errno = ERANGE;
- len = -1;
- break;
- } else {
- strncpy(list + len, dent->d_name, listlen);
- len += listlen;
- list[len] = '\0';
- ++len;
- }
- }
- }
-
- if (closedir(dirptr) == -1) {
- close (attrdirfd);
- len = -1;
- goto out;
- }
+ int attrdirfd = -1;
+ ssize_t len = 0;
+ DIR *dirptr = NULL;
+ struct dirent *dent = NULL;
+ int newfd = -1;
+ char *mapped_path = NULL;
+ int ret = -1;
+
+ ret = solaris_xattr_resolve_path(path, &mapped_path);
+ if (!ret) {
+ attrdirfd = attropen(mapped_path, ".", O_RDONLY, 0);
+ } else {
+ attrdirfd = attropen(path, ".", O_RDONLY, 0);
+ }
+ if (attrdirfd >= 0) {
+ newfd = dup(attrdirfd);
+ dirptr = fdopendir(newfd);
+ if (dirptr) {
+ while ((dent = readdir(dirptr))) {
+ size_t listlen = strlen(dent->d_name);
+ if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) {
+ /* we don't want "." and ".." here */
+ continue;
+ }
+ if (size == 0) {
+ /* return the current size of the list
+ of extended attribute names*/
+ len += listlen + 1;
} else {
- close (attrdirfd);
+ /* check size and copy entry + null
+ into list. */
+ if ((len + listlen + 1) > size) {
+ errno = ERANGE;
len = -1;
- goto out;
+ break;
+ } else {
+ strncpy(list + len, dent->d_name, listlen);
+ len += listlen;
+ list[len] = '\0';
+ ++len;
+ }
}
- close (attrdirfd);
+ }
+
+ if (closedir(dirptr) == -1) {
+ close(attrdirfd);
+ len = -1;
+ goto out;
+ }
+ } else {
+ close(attrdirfd);
+ len = -1;
+ goto out;
}
+ close(attrdirfd);
+ }
out:
- if (mapped_path)
- GF_FREE (mapped_path);
- return len;
+ GF_FREE(mapped_path);
+ return len;
}
-
int
solaris_flistxattr(int fd, char *list, size_t size)
{
- int attrdirfd = -1;
- ssize_t len = 0;
- DIR *dirptr = NULL;
- struct dirent *dent = NULL;
- int newfd = -1;
-
- attrdirfd = openat (fd, ".", O_RDONLY, 0);
- if (attrdirfd >= 0) {
- newfd = dup(attrdirfd);
- dirptr = fdopendir(newfd);
- if (dirptr) {
- while ((dent = readdir(dirptr))) {
- size_t listlen = strlen(dent->d_name);
- if (!strcmp(dent->d_name, ".") ||
- !strcmp(dent->d_name, "..")) {
- /* we don't want "." and ".." here */
- continue;
- }
- if (size == 0) {
- /* return the current size of the list
- of extended attribute names*/
- len += listlen + 1;
- } else {
- /* check size and copy entry + null
- into list. */
- if ((len + listlen + 1) > size) {
- errno = ERANGE;
- len = -1;
- break;
- } else {
- strncpy(list + len, dent->d_name, listlen);
- len += listlen;
- list[len] = '\0';
- ++len;
- }
- }
- }
-
- if (closedir(dirptr) == -1) {
- close (attrdirfd);
- return -1;
- }
+ int attrdirfd = -1;
+ ssize_t len = 0;
+ DIR *dirptr = NULL;
+ struct dirent *dent = NULL;
+ int newfd = -1;
+
+ attrdirfd = openat(fd, ".", O_RDONLY, 0);
+ if (attrdirfd >= 0) {
+ newfd = dup(attrdirfd);
+ dirptr = fdopendir(newfd);
+ if (dirptr) {
+ while ((dent = readdir(dirptr))) {
+ size_t listlen = strlen(dent->d_name);
+ if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) {
+ /* we don't want "." and ".." here */
+ continue;
+ }
+ if (size == 0) {
+ /* return the current size of the list
+ of extended attribute names*/
+ len += listlen + 1;
} else {
- close (attrdirfd);
- return -1;
+ /* check size and copy entry + null
+ into list. */
+ if ((len + listlen + 1) > size) {
+ errno = ERANGE;
+ len = -1;
+ break;
+ } else {
+ strncpy(list + len, dent->d_name, listlen);
+ len += listlen;
+ list[len] = '\0';
+ ++len;
+ }
}
- close (attrdirfd);
+ }
+
+ if (closedir(dirptr) == -1) {
+ close(attrdirfd);
+ return -1;
+ }
+ } else {
+ close(attrdirfd);
+ return -1;
}
- return len;
+ close(attrdirfd);
+ }
+ return len;
}
-
int
-solaris_removexattr(const char *path, const char* key)
+solaris_removexattr(const char *path, const char *key)
{
- int ret = -1;
- int attrfd = -1;
- char *mapped_path = NULL;
-
- ret = solaris_xattr_resolve_path (path, &mapped_path);
- if (!ret) {
- attrfd = attropen (mapped_path, ".", O_RDONLY, 0);
- } else {
- attrfd = attropen (path, ".", O_RDONLY, 0);
- }
- if (attrfd >= 0) {
- ret = unlinkat (attrfd, key, 0);
- close (attrfd);
- } else {
- if (errno == ENOENT)
- errno = ENODATA;
- ret = -1;
- }
-
- if (mapped_path)
- GF_FREE (mapped_path);
-
- return ret;
+ int ret = -1;
+ int attrfd = -1;
+ char *mapped_path = NULL;
+
+ ret = solaris_xattr_resolve_path(path, &mapped_path);
+ if (!ret) {
+ attrfd = attropen(mapped_path, ".", O_RDONLY, 0);
+ } else {
+ attrfd = attropen(path, ".", O_RDONLY, 0);
+ }
+ if (attrfd >= 0) {
+ ret = unlinkat(attrfd, key, 0);
+ close(attrfd);
+ } else {
+ if (errno == ENOENT)
+ errno = ENODATA;
+ ret = -1;
+ }
+
+ GF_FREE(mapped_path);
+
+ return ret;
}
int
-solaris_getxattr(const char *path,
- const char* key,
- char *value,
- size_t size)
+solaris_getxattr(const char *path, const char *key, char *value, size_t size)
{
- int attrfd = -1;
- int ret = 0;
- char *mapped_path = NULL;
-
- ret = solaris_xattr_resolve_path (path, &mapped_path);
- if (!ret) {
- attrfd = attropen (mapped_path, key, O_RDONLY, 0);
- } else {
- attrfd = attropen (path, key, O_RDONLY, 0);
- }
-
- if (attrfd >= 0) {
- if (size == 0) {
- struct stat buf;
- fstat (attrfd, &buf);
- ret = buf.st_size;
- } else {
- ret = read (attrfd, value, size);
- }
- close (attrfd);
+ int attrfd = -1;
+ int ret = 0;
+ char *mapped_path = NULL;
+
+ ret = solaris_xattr_resolve_path(path, &mapped_path);
+ if (!ret) {
+ attrfd = attropen(mapped_path, key, O_RDONLY, 0);
+ } else {
+ attrfd = attropen(path, key, O_RDONLY, 0);
+ }
+
+ if (attrfd >= 0) {
+ if (size == 0) {
+ struct stat buf;
+ fstat(attrfd, &buf);
+ ret = buf.st_size;
} else {
- if (errno != ENOENT)
- gf_log ("libglusterfs", GF_LOG_INFO,
- "Couldn't read extended attribute for the file %s (%s)",
- path, strerror (errno));
- if (errno == ENOENT)
- errno = ENODATA;
- ret = -1;
+ ret = read(attrfd, value, size);
}
- if (mapped_path)
- GF_FREE (mapped_path);
- return ret;
+ close(attrfd);
+ } else {
+ if (errno != ENOENT)
+ gf_msg("libglusterfs", GF_LOG_INFO, errno,
+ LG_MSG_READ_ATTRIBUTE_FAILED,
+ "Couldn't read "
+ "extended attribute for the file %s",
+ path);
+ if (errno == ENOENT)
+ errno = ENODATA;
+ ret = -1;
+ }
+ GF_FREE(mapped_path);
+ return ret;
}
-
-char* strsep(char** str, const char* delims)
+char *
+strsep(char **str, const char *delims)
{
- char* token;
-
- if (*str==NULL) {
- /* No more tokens */
- return NULL;
+ char *token;
+
+ if (*str == NULL) {
+ /* No more tokens */
+ return NULL;
+ }
+
+ token = *str;
+ while (**str != '\0') {
+ if (strchr(delims, **str) != NULL) {
+ **str = '\0';
+ (*str)++;
+ return token;
}
-
- token=*str;
- while (**str!='\0') {
- if (strchr(delims,**str)!=NULL) {
- **str='\0';
- (*str)++;
- return token;
- }
- (*str)++;
- }
- /* There is no other token */
- *str=NULL;
- return token;
+ (*str)++;
+ }
+ /* There is no other token */
+ *str = NULL;
+ return token;
}
/* Code comes from libiberty */
int
-vasprintf (char **result, const char *format, va_list args)
+vasprintf(char **result, const char *format, va_list args)
{
- return gf_vasprintf(result, format, args);
+ return gf_vasprintf(result, format, args);
}
int
-asprintf (char **buf, const char *fmt, ...)
+asprintf(char **buf, const char *fmt, ...)
{
- int status;
- va_list ap;
+ int status;
+ va_list ap;
- va_start (ap, fmt);
- status = vasprintf (buf, fmt, ap);
- va_end (ap);
- return status;
+ va_start(ap, fmt);
+ status = vasprintf(buf, fmt, ap);
+ va_end(ap);
+ return status;
}
-int solaris_unlink (const char *path)
+int
+solaris_unlink(const char *path)
{
- char *mapped_path = NULL;
- struct stat stbuf = {0, };
- int ret = -1;
-
- ret = solaris_xattr_resolve_path (path, &mapped_path);
-
-
- if (!ret && mapped_path) {
- if (lstat(path, &stbuf)) {
- gf_log ("",GF_LOG_WARNING, "Stat failed on mapped"
- " file %s with error %d", mapped_path, errno);
- goto out;
- }
- if (stbuf.st_nlink == 1) {
- if(remove (mapped_path))
- gf_log ("", GF_LOG_WARNING, "Failed to remove mapped "
- "file %s. Errno %d", mapped_path, errno);
- }
-
+ char *mapped_path = NULL;
+ struct stat stbuf = {
+ 0,
+ };
+ int ret = -1;
+
+ ret = solaris_xattr_resolve_path(path, &mapped_path);
+
+ if (!ret && mapped_path) {
+ if (lstat(path, &stbuf)) {
+ gf_msg(THIS->name, GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED,
+ "Stat failed on "
+ "mapped file %s",
+ mapped_path);
+ goto out;
+ }
+ if (stbuf.st_nlink == 1) {
+ if (remove(mapped_path))
+ gf_msg(THIS->name, GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED,
+ "Failed to "
+ "remove mapped file %s",
+ mapped_path);
}
+ }
out:
- if (mapped_path)
- GF_FREE (mapped_path);
+ GF_FREE(mapped_path);
- return unlink (path);
+ return unlink(path);
}
int
-solaris_rename (const char *old_path, const char *new_path)
+solaris_rename(const char *old_path, const char *new_path)
{
- char *mapped_path = NULL;
- int ret = -1;
+ char *mapped_path = NULL;
+ int ret = -1;
- ret = solaris_xattr_resolve_path (new_path, &mapped_path);
-
-
- if (!ret && mapped_path) {
- if (!remove (mapped_path))
- gf_log ("", GF_LOG_WARNING, "Failed to remove mapped "
- "file %s. Errno %d", mapped_path, errno);
- GF_FREE (mapped_path);
- }
+ ret = solaris_xattr_resolve_path(new_path, &mapped_path);
- return rename(old_path, new_path);
+ if (!ret && mapped_path) {
+ if (!remove(mapped_path))
+ gf_msg(THIS->name, GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED,
+ "Failed to remove "
+ "mapped file %s.",
+ mapped_path);
+ GF_FREE(mapped_path);
+ }
+ return rename(old_path, new_path);
}
-
char *
-mkdtemp (char *tempstring)
+mkdtemp(char *tempstring)
{
- char *new_string = NULL;
- int ret = 0;
+ char *new_string = NULL;
+ int ret = 0;
- new_string = mktemp (tempstring);
- if (!new_string)
- goto out;
+ new_string = mkstemp(tempstring);
+ if (!new_string)
+ goto out;
- ret = mkdir (new_string, 0700);
- if (ret < 0)
- new_string = NULL;
+ ret = mkdir(new_string, 0700);
+ if (ret < 0)
+ new_string = NULL;
out:
- return new_string;
+ return new_string;
}
-
#endif /* GF_SOLARIS_HOST_OS */
+#ifdef GF_BSD_HOST_OS
+void
+gf_extattr_list_reshape(char *bsd_list, ssize_t size)
+{
+ /*
+ * the format of bsd_list is
+ * <attr_len>attr<attr_len>attr...
+ * we try to reformat it as Linux's
+ * attr<\0>attr<\0>...
+ * */
+ if (NULL == bsd_list || size <= 0)
+ return;
+
+ size_t i = 0, j;
+
+ while (i < size) {
+ size_t attr_len = bsd_list[i];
+
+ for (j = i; j < i + attr_len; ++j)
+ bsd_list[j] = bsd_list[j + 1];
+ bsd_list[j] = '\0';
+
+ i += attr_len + 1;
+ gf_msg_debug("syscall", 0, "syscall debug: %lu", attr_len);
+ }
+}
+#endif /* GF_BSD_HOST_OS */
+
#ifndef HAVE_STRNLEN
size_t
strnlen(const char *string, size_t maxlen)
{
- int len = 0;
- while ((len < maxlen) && string[len])
- len++;
- return len;
+ int len = 0;
+ while ((len < maxlen) && string[len])
+ len++;
+ return len;
}
#endif /* STRNLEN */
+
+int
+gf_umount_lazy(char *xlname, char *path, int rmdir_flag)
+{
+ int ret = -1;
+ runner_t runner = {
+ 0,
+ };
+
+ runinit(&runner);
+#ifdef GF_LINUX_HOST_OS
+ runner_add_args(&runner, _PATH_UMOUNT, "-l", path, NULL);
+#else
+ if (rmdir_flag)
+ runner_add_args(&runner, SBIN_DIR "/umountd", "-r", path, NULL);
+ else
+ runner_add_args(&runner, SBIN_DIR "/umountd", path, NULL);
+#endif
+ ret = runner_run(&runner);
+ if (ret) {
+ gf_msg(xlname, GF_LOG_ERROR, errno, LG_MSG_UNMOUNT_FAILED,
+ "Lazy unmount of %s", path);
+ }
+
+#ifdef GF_LINUX_HOST_OS
+ if (!ret && rmdir_flag) {
+ ret = sys_rmdir(path);
+ if (ret)
+ gf_msg(xlname, GF_LOG_WARNING, errno, LG_MSG_DIR_OP_FAILED,
+ "rmdir %s", path);
+ }
+#endif
+
+ return ret;
+}
diff --git a/libglusterfs/src/compat.h b/libglusterfs/src/compat.h
deleted file mode 100644
index b04a71df4f0..00000000000
--- a/libglusterfs/src/compat.h
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef __COMPAT_H__
-#define __COMPAT_H__
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdint.h>
-#include "dict.h"
-
-#ifndef LLONG_MAX
-#define LLONG_MAX __LONG_LONG_MAX__ /* compat with old gcc */
-#endif /* LLONG_MAX */
-
-
-#ifdef GF_LINUX_HOST_OS
-
-#define UNIX_PATH_MAX 108
-
-#include <sys/un.h>
-#include <linux/limits.h>
-#include <sys/xattr.h>
-#include <endian.h>
-
-
-#ifndef HAVE_LLISTXATTR
-
-/* This part is valid only incase of old glibc which doesn't support
- * 'llistxattr()' system calls.
- */
-
-#define lremovexattr(path,key) removexattr(path,key)
-#define llistxattr(path,key,size) listxattr(path,key,size)
-#define lgetxattr(path, key, value, size) getxattr(path,key,value,size)
-#define lsetxattr(path,key,value,size,flags) setxattr(path,key,value,size,flags)
-
-#endif /* HAVE_LLISTXATTR */
-#endif /* GF_LINUX_HOST_OS */
-
-#ifdef GF_BSD_HOST_OS
-/* In case of FreeBSD */
-
-#define UNIX_PATH_MAX 104
-#include <sys/types.h>
-
-#include <sys/un.h>
-#include <sys/endian.h>
-#include <sys/extattr.h>
-#include <limits.h>
-
-#include <libgen.h>
-
-enum {
- ATTR_CREATE = 1,
-#define XATTR_CREATE ATTR_CREATE
- ATTR_REPLACE = 2
-#define XATTR_REPLACE ATTR_REPLACE
-};
-
-
-#ifndef sighandler_t
-#define sighandler_t sig_t
-#endif
-
-#ifndef ino64_t
-#define ino64_t ino_t
-#endif
-
-#ifndef EUCLEAN
-#define EUCLEAN 0
-#endif
-
-#include <netinet/in.h>
-#ifndef s6_addr16
-#define s6_addr16 __u6_addr.__u6_addr16
-#endif
-#ifndef s6_addr32
-#define s6_addr32 __u6_addr.__u6_addr32
-#endif
-
-/* Posix dictates NAME_MAX to be used */
-# ifndef NAME_MAX
-# ifdef MAXNAMLEN
-# define NAME_MAX MAXNAMLEN
-# else
-# define NAME_MAX 255
-# endif
-# endif
-
-#define F_GETLK64 F_GETLK
-#define F_SETLK64 F_SETLK
-#define F_SETLKW64 F_SETLKW
-
-#endif /* GF_BSD_HOST_OS */
-
-#ifdef GF_DARWIN_HOST_OS
-
-#define UNIX_PATH_MAX 104
-#include <sys/types.h>
-
-#include <sys/un.h>
-#include <machine/endian.h>
-#include <sys/xattr.h>
-#include <limits.h>
-
-#include <libgen.h>
-
-
-#if __DARWIN_64_BIT_INO_T == 0
-# error '64 bit ino_t is must for GlusterFS to work, Compile with "CFLAGS=-D__DARWIN_64_BIT_INO_T"'
-#endif /* __DARWIN_64_BIT_INO_T */
-
-
-#if __DARWIN_64_BIT_INO_T == 0
-# error '64 bit ino_t is must for GlusterFS to work, Compile with "CFLAGS=-D__DARWIN_64_BIT_INO_T"'
-#endif /* __DARWIN_64_BIT_INO_T */
-
-#ifndef sighandler_t
-#define sighandler_t sig_t
-#endif
-
-#ifndef EUCLEAN
-#define EUCLEAN 0
-#endif
-
-#include <netinet/in.h>
-#ifndef s6_addr16
-#define s6_addr16 __u6_addr.__u6_addr16
-#endif
-#ifndef s6_addr32
-#define s6_addr32 __u6_addr.__u6_addr32
-#endif
-
-/* Posix dictates NAME_MAX to be used */
-# ifndef NAME_MAX
-# ifdef MAXNAMLEN
-# define NAME_MAX MAXNAMLEN
-# else
-# define NAME_MAX 255
-# endif
-# endif
-
-#define F_GETLK64 F_GETLK
-#define F_SETLK64 F_SETLK
-#define F_SETLKW64 F_SETLKW
-
-#ifndef FTW_CONTINUE
- #define FTW_CONTINUE 0
-#endif
-
-int32_t gf_darwin_compat_listxattr (int len, dict_t *dict, int size);
-int32_t gf_darwin_compat_getxattr (const char *key, dict_t *dict);
-int32_t gf_darwin_compat_setxattr (dict_t *dict);
-
-#endif /* GF_DARWIN_HOST_OS */
-
-#ifdef GF_SOLARIS_HOST_OS
-
-#define UNIX_PATH_MAX 108
-#define EUCLEAN 117
-
-#include <sys/un.h>
-#include <limits.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <sys/fcntl.h>
-#include <libgen.h>
-#include <sys/mkdev.h>
-
-#ifndef lchmod
-#define lchmod chmod
-#endif
-
-#define lgetxattr(path, key, value, size) solaris_getxattr(path,key,value,size)
-enum {
- ATTR_CREATE = 1,
-#define XATTR_CREATE ATTR_CREATE
- ATTR_REPLACE = 2
-#define XATTR_REPLACE ATTR_REPLACE
-};
-
-/* This patch is not present in Solaris 10 and before */
-#ifndef dirfd
-#define dirfd(dirp) ((dirp)->dd_fd)
-#endif
-
-/* Posix dictates NAME_MAX to be used */
-# ifndef NAME_MAX
-# ifdef MAXNAMLEN
-# define NAME_MAX MAXNAMLEN
-# else
-# define NAME_MAX 255
-# endif
-# endif
-
-#include <netinet/in.h>
-#ifndef s6_addr16
-#define S6_ADDR16(x) ((uint16_t*) ((char*)&(x).s6_addr))
-#endif
-#ifndef s6_addr32
-#define s6_addr32 _S6_un._S6_u32
-#endif
-
-#define lutimes(filename,times) utimes(filename,times)
-
-#ifndef SEEK_SET
-#define SEEK_SET 0
-#endif
-
-enum {
- DT_UNKNOWN = 0,
-# define DT_UNKNOWN DT_UNKNOWN
- DT_FIFO = 1,
-# define DT_FIFO DT_FIFO
- DT_CHR = 2,
-# define DT_CHR DT_CHR
- DT_DIR = 4,
-# define DT_DIR DT_DIR
- DT_BLK = 6,
-# define DT_BLK DT_BLK
- DT_REG = 8,
-# define DT_REG DT_REG
- DT_LNK = 10,
-# define DT_LNK DT_LNK
- DT_SOCK = 12,
-# define DT_SOCK DT_SOCK
- DT_WHT = 14
-# define DT_WHT DT_WHT
-};
-
-#ifndef _PATH_MOUNTED
- #define _PATH_MOUNTED "/etc/mtab"
-#endif
-
-#ifndef O_ASYNC
- #ifdef FASYNC
- #define O_ASYNC FASYNC
- #else
- #define O_ASYNC 0
- #endif
-#endif
-
-#ifndef FTW_CONTINUE
- #define FTW_CONTINUE 0
-#endif
-
-int asprintf(char **string_ptr, const char *format, ...);
-
-int vasprintf (char **result, const char *format, va_list args);
-char* strsep(char** str, const char* delims);
-int solaris_listxattr(const char *path, char *list, size_t size);
-int solaris_removexattr(const char *path, const char* key);
-int solaris_getxattr(const char *path, const char* key,
- char *value, size_t size);
-int solaris_setxattr(const char *path, const char* key, const char *value,
- size_t size, int flags);
-int solaris_fgetxattr(int fd, const char* key,
- char *value, size_t size);
-int solaris_fsetxattr(int fd, const char* key, const char *value,
- size_t size, int flags);
-int solaris_flistxattr(int fd, char *list, size_t size);
-
-int solaris_rename (const char *oldpath, const char *newpath);
-
-int solaris_unlink (const char *pathname);
-
-#define GF_SOLARIS_XATTR_DIR ".glusterfs_xattr_inode"
-
-int solaris_xattr_resolve_path (const char *real_path, char **path);
-char *mkdtemp (char *__template);
-#endif /* GF_SOLARIS_HOST_OS */
-
-#ifndef HAVE_ARGP
-#include "argp.h"
-#else
-#include <argp.h>
-#endif /* HAVE_ARGP */
-
-#ifndef HAVE_STRNLEN
-size_t strnlen(const char *string, size_t maxlen);
-#endif /* STRNLEN */
-
-#ifndef strdupa
-#define strdupa(s) \
- (__extension__ \
- ({ \
- __const char *__old = (s); \
- size_t __len = strlen (__old) + 1; \
- char *__new = (char *) __builtin_alloca (__len); \
- (char *) memcpy (__new, __old, __len); \
- }))
-#endif
-
-#define GF_DIR_ALIGN(x) (((x) + sizeof (uint64_t) - 1) & ~(sizeof (uint64_t) - 1))
-
-#include <sys/types.h>
-#include <dirent.h>
-
-static inline int32_t
-dirent_size (struct dirent *entry)
-{
- int32_t size = -1;
-
-#ifdef GF_BSD_HOST_OS
- size = GF_DIR_ALIGN (24 /* FIX MEEEE!!! */ + entry->d_namlen);
-#endif
-#ifdef GF_DARWIN_HOST_OS
- size = GF_DIR_ALIGN (24 /* FIX MEEEE!!! */ + entry->d_namlen);
-#endif
-#ifdef GF_LINUX_HOST_OS
- size = GF_DIR_ALIGN (24 /* FIX MEEEE!!! */ + entry->d_reclen);
-#endif
-#ifdef GF_SOLARIS_HOST_OS
- size = GF_DIR_ALIGN (24 /* FIX MEEEE!!! */ + entry->d_reclen);
-#endif
- return size;
-}
-
-
-#ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
-/* Linux, Solaris, Cygwin */
-#define ST_ATIM_NSEC(stbuf) ((stbuf)->st_atim.tv_nsec)
-#define ST_CTIM_NSEC(stbuf) ((stbuf)->st_ctim.tv_nsec)
-#define ST_MTIM_NSEC(stbuf) ((stbuf)->st_mtim.tv_nsec)
-#define ST_ATIM_NSEC_SET(stbuf, val) ((stbuf)->st_atim.tv_nsec = (val))
-#define ST_MTIM_NSEC_SET(stbuf, val) ((stbuf)->st_mtim.tv_nsec = (val))
-#define ST_CTIM_NSEC_SET(stbuf, val) ((stbuf)->st_ctim.tv_nsec = (val))
-#elif defined(HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC)
-/* FreeBSD, NetBSD */
-#define ST_ATIM_NSEC(stbuf) ((stbuf)->st_atimespec.tv_nsec)
-#define ST_CTIM_NSEC(stbuf) ((stbuf)->st_ctimespec.tv_nsec)
-#define ST_MTIM_NSEC(stbuf) ((stbuf)->st_mtimespec.tv_nsec)
-#define ST_ATIM_NSEC_SET(stbuf, val) ((stbuf)->st_atimespec.tv_nsec = (val))
-#define ST_MTIM_NSEC_SET(stbuf, val) ((stbuf)->st_mtimespec.tv_nsec = (val))
-#define ST_CTIM_NSEC_SET(stbuf, val) ((stbuf)->st_ctimespec.tv_nsec = (val))
-#else
-#define ST_ATIM_NSEC(stbuf) (0)
-#define ST_CTIM_NSEC(stbuf) (0)
-#define ST_MTIM_NSEC(stbuf) (0)
-#define ST_ATIM_NSEC_SET(stbuf, val) do { } while (0);
-#define ST_MTIM_NSEC_SET(stbuf, val) do { } while (0);
-#define ST_CTIM_NSEC_SET(stbuf, val) do { } while (0);
-#endif
-
-#ifndef IXDR_GET_LONG
-#define IXDR_GET_LONG(buf) ((long)IXDR_GET_U_INT32(buf))
-#endif
-
-#ifndef IXDR_PUT_LONG
-#define IXDR_PUT_LONG(buf, v) ((long)IXDR_PUT_INT32(buf, (long)(v)))
-#endif
-
-#ifndef IXDR_GET_U_LONG
-#define IXDR_GET_U_LONG(buf) ((u_long)IXDR_GET_LONG(buf))
-#endif
-
-#ifndef IXDR_PUT_U_LONG
-#define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG(buf, (long)(v))
-#endif
-
-#endif /* __COMPAT_H__ */
diff --git a/libglusterfs/src/ctx.c b/libglusterfs/src/ctx.c
new file mode 100644
index 00000000000..3d890b04ec9
--- /dev/null
+++ b/libglusterfs/src/ctx.c
@@ -0,0 +1,97 @@
+/*
+ Copyright (c) 2008-2012 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 <pthread.h>
+
+#include "glusterfs/globals.h"
+#include "glusterfs/glusterfs.h"
+#include "timer-wheel.h"
+
+glusterfs_ctx_t *
+glusterfs_ctx_new()
+{
+ glusterfs_ctx_t *ctx = NULL;
+
+ /* no GF_CALLOC here, gf_acct_mem_set_enable is not
+ yet decided at this point */
+ ctx = CALLOC(1, sizeof(*ctx));
+ if (!ctx) {
+ goto out;
+ }
+
+ ctx->mem_acct_enable = gf_global_mem_acct_enable_get();
+
+ INIT_LIST_HEAD(&ctx->graphs);
+ INIT_LIST_HEAD(&ctx->mempool_list);
+ INIT_LIST_HEAD(&ctx->volfile_list);
+
+ ctx->daemon_pipe[0] = -1;
+ ctx->daemon_pipe[1] = -1;
+
+ ctx->log.loglevel = DEFAULT_LOG_LEVEL;
+
+#if defined(RUN_WITH_MEMCHECK)
+ ctx->cmd_args.vgtool = _gf_memcheck;
+#elif defined(RUN_WITH_DRD)
+ ctx->cmd_args.vgtool = _gf_drd;
+#else
+ ctx->cmd_args.vgtool = _gf_none;
+#endif
+
+ /* lock is never destroyed! */
+ if (LOCK_INIT(&ctx->lock)) {
+ free(ctx);
+ ctx = NULL;
+ goto out;
+ }
+
+ GF_ATOMIC_INIT(ctx->stats.max_dict_pairs, 0);
+ GF_ATOMIC_INIT(ctx->stats.total_pairs_used, 0);
+ GF_ATOMIC_INIT(ctx->stats.total_dicts_used, 0);
+out:
+ return ctx;
+}
+
+static void
+glusterfs_ctx_tw_destroy(struct gf_ctx_tw *ctx_tw)
+{
+ if (ctx_tw->timer_wheel)
+ gf_tw_cleanup_timers(ctx_tw->timer_wheel);
+
+ GF_FREE(ctx_tw);
+}
+
+struct tvec_base *
+glusterfs_ctx_tw_get(glusterfs_ctx_t *ctx)
+{
+ struct gf_ctx_tw *ctx_tw = NULL;
+
+ LOCK(&ctx->lock);
+ {
+ if (ctx->tw) {
+ ctx_tw = GF_REF_GET(ctx->tw);
+ } else {
+ ctx_tw = GF_CALLOC(1, sizeof(struct gf_ctx_tw),
+ gf_common_mt_tw_ctx);
+ ctx_tw->timer_wheel = gf_tw_init_timers();
+ GF_REF_INIT(ctx_tw, glusterfs_ctx_tw_destroy);
+ ctx->tw = ctx_tw;
+ }
+ }
+ UNLOCK(&ctx->lock);
+
+ return ctx_tw->timer_wheel;
+}
+
+void
+glusterfs_ctx_tw_put(glusterfs_ctx_t *ctx)
+{
+ GF_REF_PUT(ctx->tw);
+}
diff --git a/libglusterfs/src/daemon.c b/libglusterfs/src/daemon.c
index 38dfd3f386b..0a3e5438325 100644
--- a/libglusterfs/src/daemon.c
+++ b/libglusterfs/src/daemon.c
@@ -1,61 +1,65 @@
/*
- Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 <fcntl.h>
#include <unistd.h>
#include <stdio.h>
+#include "glusterfs/daemon.h"
int
-os_daemon (int nochdir, int noclose)
+os_daemon_return(int nochdir, int noclose)
{
- pid_t pid = -1;
- int ret = -1;
- FILE *ptr = NULL;
-
- ret = fork();
-
- switch (ret) {
- case -1:
- return (-1);
- case 0:
- break;
- default:
- _exit(0);
- }
-
- pid = setsid();
-
- if (pid == -1) {
- ret = -1;
- goto out;
- }
-
- if (!nochdir)
- ret = chdir("/");
-
- if (!noclose) {
- ptr = freopen ("/dev/null", "r", stdin);
- ptr = freopen ("/dev/null", "w", stdout);
- ptr = freopen ("/dev/null", "w", stderr);
- }
-
- ret = 0;
+ pid_t pid = -1;
+ int ret = -1;
+ FILE *ptr = NULL;
+
+ ret = fork();
+ if (ret)
+ return ret;
+
+ pid = setsid();
+
+ if (pid == -1) {
+ ret = -1;
+ goto out;
+ }
+
+ if (!nochdir)
+ ret = chdir("/");
+
+ if (!noclose) {
+ ptr = freopen(DEVNULLPATH, "r", stdin);
+ if (!ptr)
+ goto out;
+
+ ptr = freopen(DEVNULLPATH, "w", stdout);
+ if (!ptr)
+ goto out;
+
+ ptr = freopen(DEVNULLPATH, "w", stderr);
+ if (!ptr)
+ goto out;
+ }
+
+ ret = 0;
out:
- return ret;
+ return ret;
+}
+
+int
+os_daemon(int nochdir, int noclose)
+{
+ int ret = -1;
+
+ ret = os_daemon_return(nochdir, noclose);
+ if (ret <= 0)
+ return ret;
+
+ _exit(0);
}
diff --git a/libglusterfs/src/daemon.h b/libglusterfs/src/daemon.h
deleted file mode 100644
index 6edc4566b19..00000000000
--- a/libglusterfs/src/daemon.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-int os_daemon(int nochdir, int noclose);
diff --git a/libglusterfs/src/default-args.c b/libglusterfs/src/default-args.c
new file mode 100644
index 00000000000..a0ba1cfb299
--- /dev/null
+++ b/libglusterfs/src/default-args.c
@@ -0,0 +1,1651 @@
+/*
+ Copyright (c) 2008-2015 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 _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "glusterfs/defaults.h"
+
+int
+args_lookup_store(default_args_t *args, loc_t *loc, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_lookup_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ dict_t *xdata, struct iatt *postparent)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (inode)
+ args->inode = inode_ref(inode);
+ if (buf)
+ args->stat = *buf;
+ if (postparent)
+ args->postparent = *postparent;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_stat_store(default_args_t *args, loc_t *loc, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_stat_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ struct iatt *buf, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (op_ret == 0)
+ args->stat = *buf;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_fstat_store(default_args_t *args, fd_t *fd, dict_t *xdata)
+{
+ if (fd)
+ args->fd = fd_ref(fd);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_fstat_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ struct iatt *buf, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (buf)
+ args->stat = *buf;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_truncate_store(default_args_t *args, loc_t *loc, off_t off, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ args->offset = off;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_truncate_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (prebuf)
+ args->prestat = *prebuf;
+ if (postbuf)
+ args->poststat = *postbuf;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_ftruncate_store(default_args_t *args, fd_t *fd, off_t off, dict_t *xdata)
+{
+ if (fd)
+ args->fd = fd_ref(fd);
+
+ args->offset = off;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_ftruncate_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (prebuf)
+ args->prestat = *prebuf;
+ if (postbuf)
+ args->poststat = *postbuf;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_access_store(default_args_t *args, loc_t *loc, int32_t mask, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ args->mask = mask;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_access_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_readlink_store(default_args_t *args, loc_t *loc, size_t size,
+ dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ args->size = size;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_readlink_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, const char *path, struct iatt *stbuf,
+ dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (path)
+ args->buf = gf_strdup(path);
+ if (stbuf)
+ args->stat = *stbuf;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_mknod_store(default_args_t *args, loc_t *loc, mode_t mode, dev_t rdev,
+ mode_t umask, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ args->mode = mode;
+ args->rdev = rdev;
+ args->umask = umask;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_mknod_cbk_store(default_args_cbk_t *args, int op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (inode)
+ args->inode = inode_ref(inode);
+ if (buf)
+ args->stat = *buf;
+ if (preparent)
+ args->preparent = *preparent;
+ if (postparent)
+ args->postparent = *postparent;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_mkdir_store(default_args_t *args, loc_t *loc, mode_t mode, mode_t umask,
+ dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ args->mode = mode;
+ args->umask = umask;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_mkdir_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (inode)
+ args->inode = inode_ref(inode);
+ if (buf)
+ args->stat = *buf;
+ if (preparent)
+ args->preparent = *preparent;
+ if (postparent)
+ args->postparent = *postparent;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_unlink_store(default_args_t *args, loc_t *loc, int xflag, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ args->xflag = xflag;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_unlink_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (preparent)
+ args->preparent = *preparent;
+ if (postparent)
+ args->postparent = *postparent;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_rmdir_store(default_args_t *args, loc_t *loc, int flags, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ args->flags = flags;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_rmdir_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ struct iatt *preparent, struct iatt *postparent,
+ dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (preparent)
+ args->preparent = *preparent;
+ if (postparent)
+ args->postparent = *postparent;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_symlink_store(default_args_t *args, const char *linkname, loc_t *loc,
+ mode_t umask, dict_t *xdata)
+{
+ args->linkname = gf_strdup(linkname);
+ args->umask = umask;
+ loc_copy(&args->loc, loc);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_symlink_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ struct iatt *preparent, struct iatt *postparent,
+ dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (inode)
+ args->inode = inode_ref(inode);
+ if (buf)
+ args->stat = *buf;
+ if (preparent)
+ args->preparent = *preparent;
+ if (postparent)
+ args->postparent = *postparent;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_rename_store(default_args_t *args, loc_t *oldloc, loc_t *newloc,
+ dict_t *xdata)
+{
+ loc_copy(&args->loc, oldloc);
+ loc_copy(&args->loc2, newloc);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_rename_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *buf,
+ struct iatt *preoldparent, struct iatt *postoldparent,
+ struct iatt *prenewparent, struct iatt *postnewparent,
+ dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (buf)
+ args->stat = *buf;
+ if (preoldparent)
+ args->preparent = *preoldparent;
+ if (postoldparent)
+ args->postparent = *postoldparent;
+ if (prenewparent)
+ args->preparent2 = *prenewparent;
+ if (postnewparent)
+ args->postparent2 = *postnewparent;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_link_store(default_args_t *args, loc_t *oldloc, loc_t *newloc,
+ dict_t *xdata)
+{
+ loc_copy(&args->loc, oldloc);
+ loc_copy(&args->loc2, newloc);
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_link_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (inode)
+ args->inode = inode_ref(inode);
+ if (buf)
+ args->stat = *buf;
+ if (preparent)
+ args->preparent = *preparent;
+ if (postparent)
+ args->postparent = *postparent;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_create_store(default_args_t *args, loc_t *loc, int32_t flags, mode_t mode,
+ mode_t umask, fd_t *fd, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ args->flags = flags;
+ args->mode = mode;
+ args->umask = umask;
+ if (fd)
+ args->fd = fd_ref(fd);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_create_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, fd_t *fd, inode_t *inode,
+ struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (fd)
+ args->fd = fd_ref(fd);
+ if (inode)
+ args->inode = inode_ref(inode);
+ if (buf)
+ args->stat = *buf;
+ if (preparent)
+ args->preparent = *preparent;
+ if (postparent)
+ args->postparent = *postparent;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_open_store(default_args_t *args, loc_t *loc, int32_t flags, fd_t *fd,
+ dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ args->flags = flags;
+ if (fd)
+ args->fd = fd_ref(fd);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_open_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ fd_t *fd, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (fd)
+ args->fd = fd_ref(fd);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_readv_store(default_args_t *args, fd_t *fd, size_t size, off_t off,
+ uint32_t flags, dict_t *xdata)
+{
+ if (fd)
+ args->fd = fd_ref(fd);
+ args->size = size;
+ args->offset = off;
+ args->flags = flags;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_readv_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ struct iovec *vector, int32_t count, struct iatt *stbuf,
+ struct iobref *iobref, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (op_ret >= 0) {
+ args->vector = iov_dup(vector, count);
+ args->count = count;
+ args->stat = *stbuf;
+ args->iobref = iobref_ref(iobref);
+ }
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_writev_store(default_args_t *args, fd_t *fd, struct iovec *vector,
+ int32_t count, off_t off, uint32_t flags,
+ struct iobref *iobref, dict_t *xdata)
+{
+ if (fd)
+ args->fd = fd_ref(fd);
+ args->vector = iov_dup(vector, count);
+ args->count = count;
+ args->offset = off;
+ args->flags = flags;
+ args->iobref = iobref_ref(iobref);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_writev_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (op_ret >= 0)
+ args->poststat = *postbuf;
+ if (prebuf)
+ args->prestat = *prebuf;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_put_store(default_args_t *args, loc_t *loc, mode_t mode, mode_t umask,
+ uint32_t flags, struct iovec *vector, int32_t count, off_t off,
+ struct iobref *iobref, dict_t *xattr, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ args->mode = mode;
+ args->umask = umask;
+ args->flags = flags;
+ args->vector = iov_dup(vector, count);
+ args->count = count;
+ args->offset = off;
+ args->iobref = iobref_ref(iobref);
+ if (xattr)
+ args->xattr = dict_ref(xattr);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_put_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (op_ret >= 0)
+ args->stat = *buf;
+ if (inode)
+ args->inode = inode_ref(inode);
+ if (preparent)
+ args->preparent = *preparent;
+ if (postparent)
+ args->postparent = *postparent;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+int
+args_flush_store(default_args_t *args, fd_t *fd, dict_t *xdata)
+{
+ if (fd)
+ args->fd = fd_ref(fd);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_flush_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_fsync_store(default_args_t *args, fd_t *fd, int32_t datasync,
+ dict_t *xdata)
+{
+ if (fd)
+ args->fd = fd_ref(fd);
+ args->datasync = datasync;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_fsync_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (prebuf)
+ args->prestat = *prebuf;
+ if (postbuf)
+ args->poststat = *postbuf;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_opendir_store(default_args_t *args, loc_t *loc, fd_t *fd, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ if (fd)
+ args->fd = fd_ref(fd);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_opendir_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, fd_t *fd, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (fd)
+ args->fd = fd_ref(fd);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_fsyncdir_store(default_args_t *args, fd_t *fd, int32_t datasync,
+ dict_t *xdata)
+{
+ if (fd)
+ args->fd = fd_ref(fd);
+ args->datasync = datasync;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+int
+args_fsyncdir_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_statfs_store(default_args_t *args, loc_t *loc, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_statfs_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct statvfs *buf, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (op_ret == 0)
+ args->statvfs = *buf;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_setxattr_store(default_args_t *args, loc_t *loc, dict_t *dict,
+ int32_t flags, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ /* TODO */
+ if (dict)
+ args->xattr = dict_ref(dict);
+ args->flags = flags;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_setxattr_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_getxattr_store(default_args_t *args, loc_t *loc, const char *name,
+ dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+
+ if (name)
+ args->name = gf_strdup(name);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_getxattr_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *dict, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (dict)
+ args->xattr = dict_ref(dict);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_fsetxattr_store(default_args_t *args, fd_t *fd, dict_t *dict,
+ int32_t flags, dict_t *xdata)
+{
+ args->fd = fd_ref(fd);
+
+ if (dict)
+ args->xattr = dict_ref(dict);
+ args->flags = flags;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_fsetxattr_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_fgetxattr_store(default_args_t *args, fd_t *fd, const char *name,
+ dict_t *xdata)
+{
+ args->fd = fd_ref(fd);
+
+ if (name)
+ args->name = gf_strdup(name);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_fgetxattr_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *dict, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (dict)
+ args->xattr = dict_ref(dict);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_removexattr_store(default_args_t *args, loc_t *loc, const char *name,
+ dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ args->name = gf_strdup(name);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_removexattr_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_fremovexattr_store(default_args_t *args, fd_t *fd, const char *name,
+ dict_t *xdata)
+{
+ args->fd = fd_ref(fd);
+ args->name = gf_strdup(name);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_fremovexattr_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_lk_store(default_args_t *args, fd_t *fd, int32_t cmd,
+ struct gf_flock *lock, dict_t *xdata)
+{
+ if (fd)
+ args->fd = fd_ref(fd);
+ args->cmd = cmd;
+ args->lock = *lock;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_lk_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ struct gf_flock *lock, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (op_ret == 0)
+ args->lock = *lock;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_inodelk_store(default_args_t *args, const char *volume, loc_t *loc,
+ int32_t cmd, struct gf_flock *lock, dict_t *xdata)
+{
+ if (volume)
+ args->volume = gf_strdup(volume);
+
+ loc_copy(&args->loc, loc);
+ args->cmd = cmd;
+ args->lock = *lock;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_inodelk_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_finodelk_store(default_args_t *args, const char *volume, fd_t *fd,
+ int32_t cmd, struct gf_flock *lock, dict_t *xdata)
+{
+ if (fd)
+ args->fd = fd_ref(fd);
+
+ if (volume)
+ args->volume = gf_strdup(volume);
+
+ args->cmd = cmd;
+ args->lock = *lock;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_finodelk_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_entrylk_store(default_args_t *args, const char *volume, loc_t *loc,
+ const char *name, entrylk_cmd cmd, entrylk_type type,
+ dict_t *xdata)
+{
+ if (volume)
+ args->volume = gf_strdup(volume);
+
+ loc_copy(&args->loc, loc);
+
+ args->entrylkcmd = cmd;
+ args->entrylktype = type;
+
+ if (name)
+ args->name = gf_strdup(name);
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_entrylk_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_fentrylk_store(default_args_t *args, const char *volume, fd_t *fd,
+ const char *name, entrylk_cmd cmd, entrylk_type type,
+ dict_t *xdata)
+{
+ if (volume)
+ args->volume = gf_strdup(volume);
+
+ if (fd)
+ args->fd = fd_ref(fd);
+ args->entrylkcmd = cmd;
+ args->entrylktype = type;
+ if (name)
+ args->name = gf_strdup(name);
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_fentrylk_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_readdirp_store(default_args_t *args, fd_t *fd, size_t size, off_t off,
+ dict_t *xdata)
+{
+ args->fd = fd_ref(fd);
+ args->size = size;
+ args->offset = off;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_readdirp_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, gf_dirent_t *entries, dict_t *xdata)
+{
+ gf_dirent_t *stub_entry = NULL, *entry = NULL;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (op_ret > 0) {
+ list_for_each_entry(entry, &entries->list, list)
+ {
+ stub_entry = gf_dirent_for_name(entry->d_name);
+ if (!stub_entry)
+ goto out;
+ stub_entry->d_off = entry->d_off;
+ stub_entry->d_ino = entry->d_ino;
+ stub_entry->d_stat = entry->d_stat;
+ stub_entry->d_type = entry->d_type;
+ if (entry->inode)
+ stub_entry->inode = inode_ref(entry->inode);
+ if (entry->dict)
+ stub_entry->dict = dict_ref(entry->dict);
+ list_add_tail(&stub_entry->list, &args->entries.list);
+ }
+ }
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+out:
+ return 0;
+}
+
+int
+args_readdir_store(default_args_t *args, fd_t *fd, size_t size, off_t off,
+ dict_t *xdata)
+{
+ args->fd = fd_ref(fd);
+ args->size = size;
+ args->offset = off;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_readdir_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, gf_dirent_t *entries, dict_t *xdata)
+{
+ gf_dirent_t *stub_entry = NULL, *entry = NULL;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (op_ret > 0) {
+ list_for_each_entry(entry, &entries->list, list)
+ {
+ stub_entry = gf_dirent_for_name(entry->d_name);
+ if (!stub_entry)
+ goto out;
+ stub_entry->d_off = entry->d_off;
+ stub_entry->d_ino = entry->d_ino;
+ stub_entry->d_type = entry->d_type;
+ list_add_tail(&stub_entry->list, &args->entries.list);
+ }
+ }
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+out:
+ return 0;
+}
+
+int
+args_rchecksum_store(default_args_t *args, fd_t *fd, off_t offset, int32_t len,
+ dict_t *xdata)
+{
+ args->fd = fd_ref(fd);
+ args->offset = offset;
+ args->size = len;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_rchecksum_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, uint32_t weak_checksum,
+ uint8_t *strong_checksum, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (op_ret >= 0) {
+ args->weak_checksum = weak_checksum;
+ args->strong_checksum = gf_memdup(strong_checksum,
+ SHA256_DIGEST_LENGTH);
+ }
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_xattrop_store(default_args_t *args, loc_t *loc, gf_xattrop_flags_t optype,
+ dict_t *xattr, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+
+ args->optype = optype;
+ args->xattr = dict_ref(xattr);
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_xattrop_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xattr, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xattr)
+ args->xattr = dict_ref(xattr);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_fxattrop_store(default_args_t *args, fd_t *fd, gf_xattrop_flags_t optype,
+ dict_t *xattr, dict_t *xdata)
+{
+ args->fd = fd_ref(fd);
+
+ args->optype = optype;
+ args->xattr = dict_ref(xattr);
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_fxattrop_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xattr, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xattr)
+ args->xattr = dict_ref(xattr);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_setattr_store(default_args_t *args, loc_t *loc, struct iatt *stbuf,
+ int32_t valid, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+
+ if (stbuf)
+ args->stat = *stbuf;
+
+ args->valid = valid;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_setattr_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (statpre)
+ args->prestat = *statpre;
+ if (statpost)
+ args->poststat = *statpost;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_fsetattr_store(default_args_t *args, fd_t *fd, struct iatt *stbuf,
+ int32_t valid, dict_t *xdata)
+{
+ if (fd)
+ args->fd = fd_ref(fd);
+
+ if (stbuf)
+ args->stat = *stbuf;
+
+ args->valid = valid;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+int
+args_fsetattr_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (statpre)
+ args->prestat = *statpre;
+ if (statpost)
+ args->poststat = *statpost;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_fallocate_store(default_args_t *args, fd_t *fd, int32_t mode, off_t offset,
+ size_t len, dict_t *xdata)
+{
+ if (fd)
+ args->fd = fd_ref(fd);
+
+ args->flags = mode;
+ args->offset = offset;
+ args->size = len;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_fallocate_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (statpre)
+ args->prestat = *statpre;
+ if (statpost)
+ args->poststat = *statpost;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_discard_store(default_args_t *args, fd_t *fd, off_t offset, size_t len,
+ dict_t *xdata)
+{
+ if (fd)
+ args->fd = fd_ref(fd);
+
+ args->offset = offset;
+ args->size = len;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_discard_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (statpre)
+ args->prestat = *statpre;
+ if (statpost)
+ args->poststat = *statpost;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_zerofill_store(default_args_t *args, fd_t *fd, off_t offset, off_t len,
+ dict_t *xdata)
+{
+ if (fd)
+ args->fd = fd_ref(fd);
+
+ args->offset = offset;
+ args->size = len;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_zerofill_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (statpre)
+ args->prestat = *statpre;
+ if (statpost)
+ args->poststat = *statpost;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_ipc_store(default_args_t *args, int32_t op, dict_t *xdata)
+{
+ args->cmd = op;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_ipc_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_seek_store(default_args_t *args, fd_t *fd, off_t offset,
+ gf_seek_what_t what, dict_t *xdata)
+{
+ if (fd)
+ args->fd = fd_ref(fd);
+
+ args->offset = offset;
+ args->what = what;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_seek_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ off_t offset, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ args->offset = offset;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_getactivelk_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, lock_migration_info_t *locklist,
+ dict_t *xdata)
+{
+ lock_migration_info_t *stub_entry = NULL, *entry = NULL;
+ int ret = 0;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ /*op_ret needs to carry the number of locks present in the list*/
+ if (op_ret > 0) {
+ list_for_each_entry(entry, &locklist->list, list)
+ {
+ stub_entry = GF_CALLOC(1, sizeof(*stub_entry), gf_common_mt_char);
+ if (!stub_entry) {
+ ret = -1;
+ goto out;
+ }
+
+ INIT_LIST_HEAD(&stub_entry->list);
+ stub_entry->flock = entry->flock;
+
+ stub_entry->lk_flags = entry->lk_flags;
+
+ stub_entry->client_uid = gf_strdup(entry->client_uid);
+ if (!stub_entry->client_uid) {
+ GF_FREE(stub_entry);
+ ret = -1;
+ goto out;
+ }
+
+ list_add_tail(&stub_entry->list, &args->locklist.list);
+ }
+ }
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+out:
+ return ret;
+}
+
+int
+args_setactivelk_store(default_args_t *args, loc_t *loc,
+ lock_migration_info_t *locklist, dict_t *xdata)
+{
+ lock_migration_info_t *stub_entry = NULL, *entry = NULL;
+ int ret = 0;
+
+ list_for_each_entry(entry, &locklist->list, list)
+ {
+ stub_entry = GF_CALLOC(1, sizeof(*stub_entry), gf_common_mt_lock_mig);
+ if (!stub_entry) {
+ ret = -1;
+ goto out;
+ }
+
+ INIT_LIST_HEAD(&stub_entry->list);
+ stub_entry->flock = entry->flock;
+
+ stub_entry->lk_flags = entry->lk_flags;
+
+ stub_entry->client_uid = gf_strdup(entry->client_uid);
+ if (!stub_entry->client_uid) {
+ GF_FREE(stub_entry);
+ ret = -1;
+ goto out;
+ }
+
+ list_add_tail(&stub_entry->list, &args->locklist.list);
+ }
+
+ loc_copy(&args->loc, loc);
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+out:
+ return ret;
+}
+
+void
+args_lease_store(default_args_t *args, loc_t *loc, struct gf_lease *lease,
+ dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ args->lease = *lease;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return;
+}
+
+void
+args_lease_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ struct gf_lease *lease, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (op_ret == 0)
+ args->lease = *lease;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+}
+
+int
+args_icreate_store(default_args_t *args, loc_t *loc, mode_t mode, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ args->mode = mode;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_namelink_store(default_args_t *args, loc_t *loc, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_copy_file_range_store(default_args_t *args, fd_t *fd_in, off64_t off_in,
+ fd_t *fd_out, off64_t off_out, size_t len,
+ uint32_t flags, dict_t *xdata)
+{
+ if (fd_in)
+ args->fd = fd_ref(fd_in);
+ if (fd_out)
+ args->fd_dst = fd_ref(fd_out);
+ args->size = len;
+ args->off_in = off_in;
+ args->off_out = off_out;
+ args->flags = flags;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_copy_file_range_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *stbuf,
+ struct iatt *prebuf_dst,
+ struct iatt *postbuf_dst, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (op_ret >= 0) {
+ if (postbuf_dst)
+ args->poststat = *postbuf_dst;
+ if (prebuf_dst)
+ args->prestat = *prebuf_dst;
+ if (stbuf)
+ args->stat = *stbuf;
+ }
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+void
+args_cbk_wipe(default_args_cbk_t *args_cbk)
+{
+ if (!args_cbk)
+ return;
+ if (args_cbk->inode)
+ inode_unref(args_cbk->inode);
+
+ GF_FREE((char *)args_cbk->buf);
+
+ GF_FREE(args_cbk->vector);
+
+ if (args_cbk->iobref)
+ iobref_unref(args_cbk->iobref);
+
+ if (args_cbk->fd)
+ fd_unref(args_cbk->fd);
+
+ if (args_cbk->xattr)
+ dict_unref(args_cbk->xattr);
+
+ GF_FREE(args_cbk->strong_checksum);
+
+ if (args_cbk->xdata)
+ dict_unref(args_cbk->xdata);
+
+ if (!list_empty(&args_cbk->entries.list))
+ gf_dirent_free(&args_cbk->entries);
+}
+
+void
+args_wipe(default_args_t *args)
+{
+ if (!args)
+ return;
+
+ loc_wipe(&args->loc);
+
+ loc_wipe(&args->loc2);
+
+ if (args->fd)
+ fd_unref(args->fd);
+
+ GF_FREE((char *)args->linkname);
+
+ GF_FREE(args->vector);
+
+ if (args->iobref)
+ iobref_unref(args->iobref);
+
+ if (args->xattr)
+ dict_unref(args->xattr);
+
+ if (args->xdata)
+ dict_unref(args->xdata);
+
+ GF_FREE((char *)args->name);
+
+ GF_FREE((char *)args->volume);
+}
+
+void
+args_cbk_init(default_args_cbk_t *args_cbk)
+{
+ INIT_LIST_HEAD(&args_cbk->entries);
+}
diff --git a/libglusterfs/src/defaults-tmpl.c b/libglusterfs/src/defaults-tmpl.c
new file mode 100644
index 00000000000..3cf707f42aa
--- /dev/null
+++ b/libglusterfs/src/defaults-tmpl.c
@@ -0,0 +1,247 @@
+/*
+ Copyright (c) 2008-2015 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.
+*/
+
+/* libglusterfs/src/defaults.c:
+ This file contains functions, which are used to fill the 'fops', 'cbk'
+ structures in the xlator structures, if they are not written. Here, all the
+ function calls are plainly forwarded to the first child of the xlator, and
+ all the *_cbk function does plain STACK_UNWIND of the frame, and returns.
+
+ This function also implements *_resume () functions, which does same
+ operation as a fop().
+
+ All the functions are plain enough to understand.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "glusterfs/xlator.h"
+#include "glusterfs/defaults.h"
+
+#pragma generate
+
+struct xlator_fops _default_fops = {
+ .create = default_create,
+ .open = default_open,
+ .stat = default_stat,
+ .readlink = default_readlink,
+ .mknod = default_mknod,
+ .mkdir = default_mkdir,
+ .unlink = default_unlink,
+ .rmdir = default_rmdir,
+ .symlink = default_symlink,
+ .rename = default_rename,
+ .link = default_link,
+ .truncate = default_truncate,
+ .readv = default_readv,
+ .writev = default_writev,
+ .statfs = default_statfs,
+ .flush = default_flush,
+ .fsync = default_fsync,
+ .setxattr = default_setxattr,
+ .getxattr = default_getxattr,
+ .fsetxattr = default_fsetxattr,
+ .fgetxattr = default_fgetxattr,
+ .removexattr = default_removexattr,
+ .fremovexattr = default_fremovexattr,
+ .opendir = default_opendir,
+ .readdir = default_readdir,
+ .readdirp = default_readdirp,
+ .fsyncdir = default_fsyncdir,
+ .access = default_access,
+ .ftruncate = default_ftruncate,
+ .fstat = default_fstat,
+ .lk = default_lk,
+ .inodelk = default_inodelk,
+ .finodelk = default_finodelk,
+ .entrylk = default_entrylk,
+ .fentrylk = default_fentrylk,
+ .lookup = default_lookup,
+ .rchecksum = default_rchecksum,
+ .xattrop = default_xattrop,
+ .fxattrop = default_fxattrop,
+ .setattr = default_setattr,
+ .fsetattr = default_fsetattr,
+ .fallocate = default_fallocate,
+ .discard = default_discard,
+ .zerofill = default_zerofill,
+ .ipc = default_ipc,
+ .seek = default_seek,
+
+ .getspec = default_getspec,
+ .getactivelk = default_getactivelk,
+ .setactivelk = default_setactivelk,
+ .put = default_put,
+ .icreate = default_icreate,
+ .namelink = default_namelink,
+ .copy_file_range = default_copy_file_range,
+};
+struct xlator_fops *default_fops = &_default_fops;
+
+/*
+ * Remaining functions don't follow the fop calling conventions, so they're
+ * not generated.
+ */
+
+int32_t
+default_forget(xlator_t *this, inode_t *inode)
+{
+ gf_log_callingfn(this->name, GF_LOG_DEBUG,
+ "xlator does not "
+ "implement forget_cbk");
+ return 0;
+}
+
+int32_t
+default_releasedir(xlator_t *this, fd_t *fd)
+{
+ gf_log_callingfn(this->name, GF_LOG_DEBUG,
+ "xlator does not "
+ "implement releasedir_cbk");
+ return 0;
+}
+
+int32_t
+default_release(xlator_t *this, fd_t *fd)
+{
+ gf_log_callingfn(this->name, GF_LOG_DEBUG,
+ "xlator does not "
+ "implement release_cbk");
+ return 0;
+}
+
+/* notify */
+int
+default_notify(xlator_t *this, int32_t event, void *data, ...)
+{
+ GF_UNUSED int ret = 0;
+ xlator_t *victim = data;
+
+ glusterfs_graph_t *graph = NULL;
+
+ GF_VALIDATE_OR_GOTO("notify", this, out);
+ graph = this->graph;
+ GF_VALIDATE_OR_GOTO(this->name, graph, out);
+
+ switch (event) {
+ case GF_EVENT_PARENT_UP:
+ case GF_EVENT_PARENT_DOWN: {
+ xlator_list_t *list = this->children;
+
+ while (list) {
+ if (victim && victim->cleanup_starting)
+ xlator_notify(list->xlator, event, victim);
+ else
+ xlator_notify(list->xlator, event, this);
+ list = list->next;
+ }
+ } break;
+ case GF_EVENT_CHILD_CONNECTING:
+ case GF_EVENT_CHILD_DOWN:
+ case GF_EVENT_CHILD_UP:
+ case GF_EVENT_AUTH_FAILED: {
+ xlator_list_t *parent = this->parents;
+
+ /*
+ * Handle case of CHILD_* & AUTH_FAILED event specially, send
+ * it to fuse.
+ */
+ if (!parent && this->ctx && this->ctx->master) {
+ xlator_notify(this->ctx->master, event, this->graph, NULL);
+ }
+
+ while (parent) {
+ if (parent->xlator->init_succeeded)
+ xlator_notify(parent->xlator, event, this, NULL);
+ parent = parent->next;
+ }
+
+ if (event == GF_EVENT_CHILD_DOWN &&
+ !(this->ctx && this->ctx->master) && (graph->top == this)) {
+ /* Make sure this is not a daemon with master xlator */
+ pthread_mutex_lock(&graph->mutex);
+ {
+ if (graph->parent_down ==
+ graph_total_client_xlator(graph)) {
+ graph->used = 0;
+ pthread_cond_broadcast(&graph->child_down_cond);
+ }
+ }
+ pthread_mutex_unlock(&graph->mutex);
+ }
+ } break;
+ case GF_EVENT_UPCALL: {
+ xlator_list_t *parent = this->parents;
+
+ if (!parent && this->ctx && this->ctx->master)
+ xlator_notify(this->ctx->master, event, data, NULL);
+
+ while (parent) {
+ if (parent->xlator->init_succeeded)
+ xlator_notify(parent->xlator, event, data, NULL);
+ parent = parent->next;
+ }
+ } break;
+ case GF_EVENT_CHILD_PING: {
+ xlator_list_t *parent = this->parents;
+
+ while (parent) {
+ if (parent->xlator->init_succeeded)
+ XLATOR_NOTIFY(ret, parent->xlator, event, this, data);
+ parent = parent->next;
+ }
+ } break;
+ case GF_EVENT_CLEANUP: {
+ xlator_list_t *list = this->children;
+
+ while (list) {
+ xlator_notify(list->xlator, event, this);
+ list = list->next;
+ }
+ } break;
+
+ default: {
+ xlator_list_t *parent = this->parents;
+
+ while (parent) {
+ if (parent->xlator->init_succeeded)
+ xlator_notify(parent->xlator, event, this, NULL);
+ parent = parent->next;
+ }
+ }
+ /*
+ * Apparently our picky-about-everything else coding standard allows
+ * adjacent same-indendation-level close braces. Clearly it has
+ * nothing to do with readability.
+ */
+ }
+out:
+ return 0;
+}
+
+int32_t
+default_mem_acct_init(xlator_t *this)
+{
+ int ret = -1;
+
+ ret = xlator_mem_acct_init(this, gf_common_mt_end);
+
+ return ret;
+}
+
+void
+default_fini(xlator_t *this)
+{
+ if (this && this->private)
+ GF_FREE(this->private);
+}
diff --git a/libglusterfs/src/defaults.c b/libglusterfs/src/defaults.c
deleted file mode 100644
index 392819ca9d1..00000000000
--- a/libglusterfs/src/defaults.c
+++ /dev/null
@@ -1,1261 +0,0 @@
-/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-/* libglusterfs/src/defaults.c:
- This file contains functions, which are used to fill the 'fops', 'cbk'
- structures in the xlator structures, if they are not written. Here, all the
- function calls are plainly forwared to the first child of the xlator, and
- all the *_cbk function does plain STACK_UNWIND of the frame, and returns.
-
- This function also implements *_resume () functions, which does same
- operation as a fop().
-
- All the functions are plain enough to understand.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "xlator.h"
-
-/* _CBK function section */
-
-int32_t
-default_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, dict_t *dict, struct iatt *postparent)
-{
- STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode, buf,
- dict, postparent);
- return 0;
-}
-
-int32_t
-default_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf)
-{
- STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf);
- return 0;
-}
-
-
-int32_t
-default_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf)
-{
- STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno, prebuf,
- postbuf);
- return 0;
-}
-
-int32_t
-default_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf)
-{
- STACK_UNWIND_STRICT (ftruncate, frame, op_ret, op_errno, prebuf,
- postbuf);
- return 0;
-}
-
-int32_t
-default_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (access, frame, op_ret, op_errno);
- return 0;
-}
-
-int32_t
-default_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, const char *path,
- struct iatt *buf)
-{
- STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, path, buf);
- return 0;
-}
-
-
-int32_t
-default_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent)
-{
- STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno, inode,
- buf, preparent, postparent);
- return 0;
-}
-
-int32_t
-default_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent)
-{
- STACK_UNWIND_STRICT (mkdir, frame, op_ret, op_errno, inode,
- buf, preparent, postparent);
- return 0;
-}
-
-int32_t
-default_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent)
-{
- STACK_UNWIND_STRICT (unlink, frame, op_ret, op_errno, preparent,
- postparent);
- return 0;
-}
-
-int32_t
-default_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent)
-{
- STACK_UNWIND_STRICT (rmdir, frame, op_ret, op_errno, preparent,
- postparent);
- return 0;
-}
-
-
-int32_t
-default_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent)
-{
- STACK_UNWIND_STRICT (symlink, frame, op_ret, op_errno, inode, buf,
- preparent, postparent);
- return 0;
-}
-
-
-int32_t
-default_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent)
-{
- STACK_UNWIND_STRICT (rename, frame, op_ret, op_errno, buf, preoldparent,
- postoldparent, prenewparent, postnewparent);
- return 0;
-}
-
-
-int32_t
-default_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent)
-{
- STACK_UNWIND_STRICT (link, frame, op_ret, op_errno, inode, buf,
- preparent, postparent);
- return 0;
-}
-
-
-int32_t
-default_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent)
-{
- STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf,
- preparent, postparent);
- return 0;
-}
-
-int32_t
-default_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd)
-{
- STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd);
- return 0;
-}
-
-int32_t
-default_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iovec *vector,
- int32_t count, struct iatt *stbuf, struct iobref *iobref)
-{
- STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vector, count,
- stbuf, iobref);
- return 0;
-}
-
-
-int32_t
-default_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf)
-{
- STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf);
- return 0;
-}
-
-
-int32_t
-default_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno);
- return 0;
-}
-
-
-
-int32_t
-default_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf)
-{
- STACK_UNWIND_STRICT (fsync, frame, op_ret, op_errno, prebuf, postbuf);
- return 0;
-}
-
-int32_t
-default_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf)
-{
- STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, buf);
- return 0;
-}
-
-int32_t
-default_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd)
-{
- STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd);
- return 0;
-}
-
-int32_t
-default_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (fsyncdir, frame, op_ret, op_errno);
- return 0;
-}
-
-int32_t
-default_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct statvfs *buf)
-{
- STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, buf);
- return 0;
-}
-
-
-int32_t
-default_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno);
- return 0;
-}
-
-
-int32_t
-default_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno);
- return 0;
-}
-
-
-
-int32_t
-default_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict)
-{
- STACK_UNWIND_STRICT (fgetxattr, frame, op_ret, op_errno, dict);
- return 0;
-}
-
-
-int32_t
-default_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict)
-{
- STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict);
- return 0;
-}
-
-int32_t
-default_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict)
-{
- STACK_UNWIND_STRICT (xattrop, frame, op_ret, op_errno, dict);
- return 0;
-}
-
-int32_t
-default_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict)
-{
- STACK_UNWIND_STRICT (fxattrop, frame, op_ret, op_errno, dict);
- return 0;
-}
-
-
-int32_t
-default_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno);
- return 0;
-}
-
-int32_t
-default_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct gf_flock *lock)
-{
- STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, lock);
- return 0;
-}
-
-int32_t
-default_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (inodelk, frame, op_ret, op_errno);
- return 0;
-}
-
-
-int32_t
-default_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (finodelk, frame, op_ret, op_errno);
- return 0;
-}
-
-int32_t
-default_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno);
- return 0;
-}
-
-int32_t
-default_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (fentrylk, frame, op_ret, op_errno);
- return 0;
-}
-
-
-int32_t
-default_rchecksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, uint32_t weak_checksum,
- uint8_t *strong_checksum)
-{
- STACK_UNWIND_STRICT (rchecksum, frame, op_ret, op_errno, weak_checksum,
- strong_checksum);
- return 0;
-}
-
-
-int32_t
-default_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)
-{
- STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, entries);
- return 0;
-}
-
-
-int32_t
-default_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)
-{
- STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries);
- return 0;
-}
-
-int32_t
-default_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *statpre,
- struct iatt *statpost)
-{
- STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, statpre,
- statpost);
- return 0;
-}
-
-int32_t
-default_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *statpre,
- struct iatt *statpost)
-{
- STACK_UNWIND_STRICT (fsetattr, frame, op_ret, op_errno, statpre,
- statpost);
- return 0;
-}
-
-int32_t
-default_getspec_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, char *spec_data)
-{
- STACK_UNWIND_STRICT (getspec, frame, op_ret, op_errno, spec_data);
- return 0;
-}
-
-/* RESUME */
-
-int32_t
-default_fgetxattr_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name)
-{
- STACK_WIND (frame, default_fgetxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fgetxattr, fd, name);
- return 0;
-}
-
-int32_t
-default_fsetxattr_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- dict_t *dict, int32_t flags)
-{
- STACK_WIND (frame, default_fsetxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags);
- return 0;
-}
-
-int32_t
-default_setxattr_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *dict, int32_t flags)
-{
- STACK_WIND (frame, default_setxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setxattr, loc, dict, flags);
- return 0;
-}
-
-int32_t
-default_statfs_resume (call_frame_t *frame, xlator_t *this, loc_t *loc)
-{
- STACK_WIND (frame, default_statfs_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->statfs, loc);
- return 0;
-}
-
-int32_t
-default_fsyncdir_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t flags)
-{
- STACK_WIND (frame, default_fsyncdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsyncdir, fd, flags);
- return 0;
-}
-
-int32_t
-default_opendir_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- fd_t *fd)
-{
- STACK_WIND (frame, default_opendir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->opendir, loc, fd);
- return 0;
-}
-
-int32_t
-default_fstat_resume (call_frame_t *frame, xlator_t *this, fd_t *fd)
-{
- STACK_WIND (frame, default_fstat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fstat, fd);
- return 0;
-}
-
-int32_t
-default_fsync_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t flags)
-{
- STACK_WIND (frame, default_fsync_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsync, fd, flags);
- return 0;
-}
-
-int32_t
-default_flush_resume (call_frame_t *frame, xlator_t *this, fd_t *fd)
-{
- STACK_WIND (frame, default_flush_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->flush, fd);
- return 0;
-}
-
-int32_t
-default_writev_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iovec *vector, int32_t count, off_t off,
- struct iobref *iobref)
-{
- STACK_WIND (frame, default_writev_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->writev, fd, vector, count, off,
- iobref);
- return 0;
-}
-
-int32_t
-default_readv_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t offset)
-{
- STACK_WIND (frame, default_readv_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readv, fd, size, offset);
- return 0;
-}
-
-
-int32_t
-default_open_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t flags, fd_t *fd, int32_t wbflags)
-{
- STACK_WIND (frame, default_open_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->open, loc, flags, fd, wbflags);
- return 0;
-}
-
-int32_t
-default_create_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t flags, mode_t mode, fd_t *fd, dict_t *params)
-{
- STACK_WIND (frame, default_create_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->create, loc, flags, mode, fd,
- params);
- return 0;
-}
-
-int32_t
-default_link_resume (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc)
-{
- STACK_WIND (frame, default_link_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->link, oldloc, newloc);
- return 0;
-}
-
-int32_t
-default_rename_resume (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc)
-{
- STACK_WIND (frame, default_rename_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rename, oldloc, newloc);
- return 0;
-}
-
-
-int
-default_symlink_resume (call_frame_t *frame, xlator_t *this,
- const char *linkpath, loc_t *loc, dict_t *params)
-{
- STACK_WIND (frame, default_symlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->symlink, linkpath, loc, params);
- return 0;
-}
-
-int32_t
-default_rmdir_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int flags)
-{
- STACK_WIND (frame, default_rmdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rmdir, loc, flags);
- return 0;
-}
-
-int32_t
-default_unlink_resume (call_frame_t *frame, xlator_t *this, loc_t *loc)
-{
- STACK_WIND (frame, default_unlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->unlink, loc);
- return 0;
-}
-
-int
-default_mkdir_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- mode_t mode, dict_t *params)
-{
- STACK_WIND (frame, default_mkdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mkdir, loc, mode, params);
- return 0;
-}
-
-
-int
-default_mknod_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- mode_t mode, dev_t rdev, dict_t *parms)
-{
- STACK_WIND (frame, default_mknod_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, parms);
- return 0;
-}
-
-int32_t
-default_readlink_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- size_t size)
-{
- STACK_WIND (frame, default_readlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readlink, loc, size);
- return 0;
-}
-
-
-int32_t
-default_access_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t mask)
-{
- STACK_WIND (frame, default_access_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->access, loc, mask);
- return 0;
-}
-
-int32_t
-default_ftruncate_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset)
-{
- STACK_WIND (frame, default_ftruncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->ftruncate, fd, offset);
- return 0;
-}
-
-int32_t
-default_getxattr_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name)
-{
- STACK_WIND (frame, default_getxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->getxattr, loc, name);
- return 0;
-}
-
-
-int32_t
-default_xattrop_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- gf_xattrop_flags_t flags, dict_t *dict)
-{
- STACK_WIND (frame, default_xattrop_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->xattrop, loc, flags, dict);
- return 0;
-}
-
-int32_t
-default_fxattrop_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- gf_xattrop_flags_t flags, dict_t *dict)
-{
- STACK_WIND (frame, default_fxattrop_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fxattrop, fd, flags, dict);
- return 0;
-}
-
-int32_t
-default_removexattr_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name)
-{
- STACK_WIND (frame, default_removexattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->removexattr, loc, name);
- return 0;
-}
-
-int32_t
-default_lk_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t cmd, struct gf_flock *lock)
-{
- STACK_WIND (frame, default_lk_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lk, fd, cmd, lock);
- return 0;
-}
-
-
-int32_t
-default_inodelk_resume (call_frame_t *frame, xlator_t *this,
- const char *volume, loc_t *loc, int32_t cmd,
- struct gf_flock *lock)
-{
- STACK_WIND (frame, default_inodelk_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->inodelk,
- volume, loc, cmd, lock);
- return 0;
-}
-
-int32_t
-default_finodelk_resume (call_frame_t *frame, xlator_t *this,
- const char *volume, fd_t *fd, int32_t cmd,
- struct gf_flock *lock)
-{
- STACK_WIND (frame, default_finodelk_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->finodelk,
- volume, fd, cmd, lock);
- return 0;
-}
-
-int32_t
-default_entrylk_resume (call_frame_t *frame, xlator_t *this,
- const char *volume, loc_t *loc, const char *basename,
- entrylk_cmd cmd, entrylk_type type)
-{
- STACK_WIND (frame, default_entrylk_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->entrylk,
- volume, loc, basename, cmd, type);
- return 0;
-}
-
-int32_t
-default_fentrylk_resume (call_frame_t *frame, xlator_t *this,
- const char *volume, fd_t *fd, const char *basename,
- entrylk_cmd cmd, entrylk_type type)
-{
- STACK_WIND (frame, default_fentrylk_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fentrylk,
- volume, fd, basename, cmd, type);
- return 0;
-}
-
-int32_t
-default_rchecksum_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset, int32_t len)
-{
- STACK_WIND (frame, default_rchecksum_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rchecksum, fd, offset, len);
- return 0;
-}
-
-
-int32_t
-default_readdir_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t off)
-{
- STACK_WIND (frame, default_readdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdir, fd, size, off);
- return 0;
-}
-
-
-int32_t
-default_readdirp_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t off)
-{
- STACK_WIND (frame, default_readdirp_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdirp, fd, size, off);
- return 0;
-}
-
-int32_t
-default_setattr_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid)
-{
- STACK_WIND (frame, default_setattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->setattr, loc, stbuf, valid);
- return 0;
-}
-
-int32_t
-default_truncate_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- off_t offset)
-{
- STACK_WIND (frame, default_truncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->truncate, loc, offset);
- return 0;
-}
-
-int32_t
-default_stat_resume (call_frame_t *frame, xlator_t *this, loc_t *loc)
-{
- STACK_WIND (frame, default_stat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->stat, loc);
- return 0;
-}
-
-int32_t
-default_lookup_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xattr_req)
-{
- STACK_WIND (frame, default_lookup_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup, loc, xattr_req);
- return 0;
-}
-
-int32_t
-default_fsetattr_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iatt *stbuf, int32_t valid)
-{
- STACK_WIND (frame, default_fsetattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fsetattr, fd, stbuf, valid);
- return 0;
-}
-
-/* FOPS */
-
-int32_t
-default_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name)
-{
- STACK_WIND (frame, default_fgetxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fgetxattr, fd, name);
- return 0;
-}
-
-int32_t
-default_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
- int32_t flags)
-{
- STACK_WIND (frame, default_fsetxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags);
- return 0;
-}
-
-int32_t
-default_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
- int32_t flags)
-{
- STACK_WIND (frame, default_setxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setxattr, loc, dict, flags);
- return 0;
-}
-
-int32_t
-default_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc)
-{
- STACK_WIND (frame, default_statfs_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->statfs, loc);
- return 0;
-}
-
-int32_t
-default_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags)
-{
- STACK_WIND (frame, default_fsyncdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsyncdir, fd, flags);
- return 0;
-}
-
-int32_t
-default_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd)
-{
- STACK_WIND (frame, default_opendir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->opendir, loc, fd);
- return 0;
-}
-
-int32_t
-default_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd)
-{
- STACK_WIND (frame, default_fstat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fstat, fd);
- return 0;
-}
-
-int32_t
-default_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags)
-{
- STACK_WIND (frame, default_fsync_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsync, fd, flags);
- return 0;
-}
-
-int32_t
-default_flush (call_frame_t *frame, xlator_t *this, fd_t *fd)
-{
- STACK_WIND (frame, default_flush_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->flush, fd);
- return 0;
-}
-
-int32_t
-default_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iovec *vector, int32_t count, off_t off,
- struct iobref *iobref)
-{
- STACK_WIND (frame, default_writev_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->writev, fd, vector, count, off,
- iobref);
- return 0;
-}
-
-int32_t
-default_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset)
-{
- STACK_WIND (frame, default_readv_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readv, fd, size, offset);
- return 0;
-}
-
-
-int32_t
-default_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- fd_t *fd, int32_t wbflags)
-{
- STACK_WIND (frame, default_open_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->open, loc, flags, fd, wbflags);
- return 0;
-}
-
-int32_t
-default_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- mode_t mode, fd_t *fd, dict_t *params)
-{
- STACK_WIND (frame, default_create_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->create, loc, flags, mode, fd,
- params);
- return 0;
-}
-
-int32_t
-default_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc)
-{
- STACK_WIND (frame, default_link_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->link, oldloc, newloc);
- return 0;
-}
-
-int32_t
-default_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc)
-{
- STACK_WIND (frame, default_rename_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rename, oldloc, newloc);
- return 0;
-}
-
-
-int
-default_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
- loc_t *loc, dict_t *params)
-{
- STACK_WIND (frame, default_symlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->symlink, linkpath, loc, params);
- return 0;
-}
-
-int32_t
-default_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags)
-{
- STACK_WIND (frame, default_rmdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rmdir, loc, flags);
- return 0;
-}
-
-int32_t
-default_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc)
-{
- STACK_WIND (frame, default_unlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->unlink, loc);
- return 0;
-}
-
-int
-default_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- dict_t *params)
-{
- STACK_WIND (frame, default_mkdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mkdir, loc, mode, params);
- return 0;
-}
-
-
-int
-default_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- dev_t rdev, dict_t *parms)
-{
- STACK_WIND (frame, default_mknod_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, parms);
- return 0;
-}
-
-int32_t
-default_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size)
-{
- STACK_WIND (frame, default_readlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readlink, loc, size);
- return 0;
-}
-
-
-int32_t
-default_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask)
-{
- STACK_WIND (frame, default_access_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->access, loc, mask);
- return 0;
-}
-
-int32_t
-default_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset)
-{
- STACK_WIND (frame, default_ftruncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->ftruncate, fd, offset);
- return 0;
-}
-
-int32_t
-default_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name)
-{
- STACK_WIND (frame, default_getxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->getxattr, loc, name);
- return 0;
-}
-
-
-int32_t
-default_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
- gf_xattrop_flags_t flags, dict_t *dict)
-{
- STACK_WIND (frame, default_xattrop_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->xattrop, loc, flags, dict);
- return 0;
-}
-
-int32_t
-default_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
- gf_xattrop_flags_t flags, dict_t *dict)
-{
- STACK_WIND (frame, default_fxattrop_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fxattrop, fd, flags, dict);
- return 0;
-}
-
-int32_t
-default_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name)
-{
- STACK_WIND (frame, default_removexattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->removexattr, loc, name);
- return 0;
-}
-
-int32_t
-default_lk (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t cmd, struct gf_flock *lock)
-{
- STACK_WIND (frame, default_lk_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lk, fd, cmd, lock);
- return 0;
-}
-
-
-int32_t
-default_inodelk (call_frame_t *frame, xlator_t *this,
- const char *volume, loc_t *loc, int32_t cmd,
- struct gf_flock *lock)
-{
- STACK_WIND (frame, default_inodelk_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->inodelk,
- volume, loc, cmd, lock);
- return 0;
-}
-
-int32_t
-default_finodelk (call_frame_t *frame, xlator_t *this,
- const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *lock)
-{
- STACK_WIND (frame, default_finodelk_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->finodelk,
- volume, fd, cmd, lock);
- return 0;
-}
-
-int32_t
-default_entrylk (call_frame_t *frame, xlator_t *this,
- const char *volume, loc_t *loc, const char *basename,
- entrylk_cmd cmd, entrylk_type type)
-{
- STACK_WIND (frame, default_entrylk_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->entrylk,
- volume, loc, basename, cmd, type);
- return 0;
-}
-
-int32_t
-default_fentrylk (call_frame_t *frame, xlator_t *this,
- const char *volume, fd_t *fd, const char *basename,
- entrylk_cmd cmd, entrylk_type type)
-{
- STACK_WIND (frame, default_fentrylk_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fentrylk,
- volume, fd, basename, cmd, type);
- return 0;
-}
-
-int32_t
-default_rchecksum (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- int32_t len)
-{
- STACK_WIND (frame, default_rchecksum_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rchecksum, fd, offset, len);
- return 0;
-}
-
-
-int32_t
-default_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t off)
-{
- STACK_WIND (frame, default_readdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdir, fd, size, off);
- return 0;
-}
-
-
-int32_t
-default_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t off)
-{
- STACK_WIND (frame, default_readdirp_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdirp, fd, size, off);
- return 0;
-}
-
-int32_t
-default_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid)
-{
- STACK_WIND (frame, default_setattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->setattr, loc, stbuf, valid);
- return 0;
-}
-
-int32_t
-default_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset)
-{
- STACK_WIND (frame, default_truncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->truncate, loc, offset);
- return 0;
-}
-
-int32_t
-default_stat (call_frame_t *frame, xlator_t *this, loc_t *loc)
-{
- STACK_WIND (frame, default_stat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->stat, loc);
- return 0;
-}
-
-int32_t
-default_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xattr_req)
-{
- STACK_WIND (frame, default_lookup_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup, loc, xattr_req);
- return 0;
-}
-
-int32_t
-default_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iatt *stbuf, int32_t valid)
-{
- STACK_WIND (frame, default_fsetattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fsetattr, fd, stbuf, valid);
- return 0;
-}
-
-
-int32_t
-default_forget (xlator_t *this, inode_t *inode)
-{
- return 0;
-}
-
-
-int32_t
-default_releasedir (xlator_t *this, fd_t *fd)
-{
- return 0;
-}
-
-int32_t
-default_release (xlator_t *this, fd_t *fd)
-{
- return 0;
-}
-
-/* End of FOP/_CBK/_RESUME section */
-
-
-/* Management operations */
-
-int32_t
-default_getspec (call_frame_t *frame, xlator_t *this, const char *key,
- int32_t flags)
-{
- STACK_WIND (frame, default_getspec_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->getspec, key, flags);
- return 0;
-}
-
-/* notify */
-int
-default_notify (xlator_t *this, int32_t event, void *data, ...)
-{
- switch (event)
- {
- case GF_EVENT_PARENT_UP:
- {
- xlator_list_t *list = this->children;
-
- while (list) {
- xlator_notify (list->xlator, event, this);
- list = list->next;
- }
- }
- break;
- case GF_EVENT_CHILD_CONNECTING:
- case GF_EVENT_CHILD_MODIFIED:
- case GF_EVENT_CHILD_DOWN:
- case GF_EVENT_CHILD_UP:
- {
- xlator_list_t *parent = this->parents;
- /* Handle case of CHILD_* event specially, send it to fuse */
- if (!parent && this->ctx && this->ctx->master)
- xlator_notify (this->ctx->master, event, this->graph, NULL);
-
- while (parent) {
- if (parent->xlator->init_succeeded)
- xlator_notify (parent->xlator, event,
- this, NULL);
- parent = parent->next;
- }
- }
- break;
- default:
- {
- xlator_list_t *parent = this->parents;
- while (parent) {
- if (parent->xlator->init_succeeded)
- xlator_notify (parent->xlator, event,
- this, NULL);
- parent = parent->next;
- }
- }
- }
-
- return 0;
-}
-
-int32_t
-default_mem_acct_init (xlator_t *this)
-{
- int ret = -1;
-
- ret = xlator_mem_acct_init (this, gf_common_mt_end);
-
- return ret;
-}
diff --git a/libglusterfs/src/defaults.h b/libglusterfs/src/defaults.h
deleted file mode 100644
index a312901a779..00000000000
--- a/libglusterfs/src/defaults.h
+++ /dev/null
@@ -1,680 +0,0 @@
-/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-/* libglusterfs/src/defaults.h:
- This file contains definition of default fops and mops functions.
-*/
-
-#ifndef _DEFAULTS_H
-#define _DEFAULTS_H
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "xlator.h"
-
-/* Management Operations */
-
-int32_t default_getspec (call_frame_t *frame,
- xlator_t *this,
- const char *key,
- int32_t flag);
-
-int32_t default_rchecksum (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd, off_t offset,
- int32_t len);
-
-/* FileSystem operations */
-int32_t default_lookup (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- dict_t *xattr_req);
-
-int32_t default_stat (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc);
-
-int32_t default_fstat (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd);
-
-int32_t default_truncate (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- off_t offset);
-
-int32_t default_ftruncate (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- off_t offset);
-
-int32_t default_access (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- int32_t mask);
-
-int32_t default_readlink (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- size_t size);
-
-int32_t default_mknod (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, dev_t rdev, dict_t *params);
-
-int32_t default_mkdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, dict_t *params);
-
-int32_t default_unlink (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc);
-
-int32_t default_rmdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int flags);
-
-int32_t default_symlink (call_frame_t *frame, xlator_t *this,
- const char *linkpath, loc_t *loc, dict_t *params);
-
-int32_t default_rename (call_frame_t *frame,
- xlator_t *this,
- loc_t *oldloc,
- loc_t *newloc);
-
-int32_t default_link (call_frame_t *frame,
- xlator_t *this,
- loc_t *oldloc,
- loc_t *newloc);
-
-int32_t default_create (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int32_t flags, mode_t mode,
- fd_t *fd, dict_t *params);
-
-int32_t default_open (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- int32_t flags, fd_t *fd,
- int32_t wbflags);
-
-int32_t default_readv (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- size_t size,
- off_t offset);
-
-int32_t default_writev (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- struct iovec *vector,
- int32_t count,
- off_t offset,
- struct iobref *iobref);
-
-int32_t default_flush (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd);
-
-int32_t default_fsync (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- int32_t datasync);
-
-int32_t default_opendir (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc, fd_t *fd);
-
-int32_t default_fsyncdir (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- int32_t datasync);
-
-int32_t default_statfs (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc);
-
-int32_t default_setxattr (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- dict_t *dict,
- int32_t flags);
-
-int32_t default_getxattr (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- const char *name);
-
-int32_t default_fsetxattr (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- dict_t *dict,
- int32_t flags);
-
-int32_t default_fgetxattr (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- const char *name);
-
-int32_t default_removexattr (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- const char *name);
-
-int32_t default_lk (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- int32_t cmd,
- struct gf_flock *flock);
-
-int32_t default_inodelk (call_frame_t *frame, xlator_t *this,
- const char *volume, loc_t *loc, int32_t cmd,
- struct gf_flock *flock);
-
-int32_t default_finodelk (call_frame_t *frame, xlator_t *this,
- const char *volume, fd_t *fd, int32_t cmd,
- struct gf_flock *flock);
-
-int32_t default_entrylk (call_frame_t *frame, xlator_t *this,
- const char *volume, loc_t *loc, const char *basename,
- entrylk_cmd cmd, entrylk_type type);
-
-int32_t default_fentrylk (call_frame_t *frame, xlator_t *this,
- const char *volume, fd_t *fd, const char *basename,
- entrylk_cmd cmd, entrylk_type type);
-
-int32_t default_readdir (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- size_t size, off_t off);
-
-int32_t default_readdirp (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- size_t size, off_t off);
-
-int32_t default_xattrop (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- gf_xattrop_flags_t flags,
- dict_t *dict);
-
-int32_t default_fxattrop (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- gf_xattrop_flags_t flags,
- dict_t *dict);
-
-int32_t default_notify (xlator_t *this,
- int32_t event,
- void *data,
- ...);
-
-int32_t default_forget (xlator_t *this,
- inode_t *inode);
-
-int32_t default_release (xlator_t *this,
- fd_t *fd);
-
-int32_t default_releasedir (xlator_t *this,
- fd_t *fd);
-
-int32_t default_setattr (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- struct iatt *stbuf,
- int32_t valid);
-
-int32_t default_fsetattr (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- struct iatt *stbuf,
- int32_t valid);
-
-/* Resume */
-int32_t default_getspec (call_frame_t *frame,
- xlator_t *this,
- const char *key,
- int32_t flag);
-
-int32_t default_rchecksum (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd, off_t offset,
- int32_t len);
-
-/* FileSystem operations */
-int32_t default_lookup_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- dict_t *xattr_req);
-
-int32_t default_stat_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc);
-
-int32_t default_fstat_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd);
-
-int32_t default_truncate_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- off_t offset);
-
-int32_t default_ftruncate_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- off_t offset);
-
-int32_t default_access_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- int32_t mask);
-
-int32_t default_readlink_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- size_t size);
-
-int32_t default_mknod_resume (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, dev_t rdev, dict_t *params);
-
-int32_t default_mkdir_resume (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, dict_t *params);
-
-int32_t default_unlink_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc);
-
-int32_t default_rmdir_resume (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int flags);
-
-int32_t default_symlink_resume (call_frame_t *frame, xlator_t *this,
- const char *linkpath, loc_t *loc, dict_t *params);
-
-int32_t default_rename_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *oldloc,
- loc_t *newloc);
-
-int32_t default_link_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *oldloc,
- loc_t *newloc);
-
-int32_t default_create_resume (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int32_t flags, mode_t mode,
- fd_t *fd, dict_t *params);
-
-int32_t default_open_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- int32_t flags, fd_t *fd,
- int32_t wbflags);
-
-int32_t default_readv_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- size_t size,
- off_t offset);
-
-int32_t default_writev_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- struct iovec *vector,
- int32_t count,
- off_t offset,
- struct iobref *iobref);
-
-int32_t default_flush_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd);
-
-int32_t default_fsync_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- int32_t datasync);
-
-int32_t default_opendir_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc, fd_t *fd);
-
-int32_t default_fsyncdir_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- int32_t datasync);
-
-int32_t default_statfs_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc);
-
-int32_t default_setxattr_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- dict_t *dict,
- int32_t flags);
-
-int32_t default_getxattr_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- const char *name);
-
-int32_t default_fsetxattr_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- dict_t *dict,
- int32_t flags);
-
-int32_t default_fgetxattr_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- const char *name);
-
-int32_t default_removexattr_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- const char *name);
-
-int32_t default_lk_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- int32_t cmd,
- struct gf_flock *flock);
-
-int32_t default_inodelk_resume (call_frame_t *frame, xlator_t *this,
- const char *volume, loc_t *loc, int32_t cmd,
- struct gf_flock *flock);
-
-int32_t default_finodelk_resume (call_frame_t *frame, xlator_t *this,
- const char *volume, fd_t *fd, int32_t cmd,
- struct gf_flock *flock);
-
-int32_t default_entrylk_resume (call_frame_t *frame, xlator_t *this,
- const char *volume, loc_t *loc, const char *basename,
- entrylk_cmd cmd, entrylk_type type);
-
-int32_t default_fentrylk_resume (call_frame_t *frame, xlator_t *this,
- const char *volume, fd_t *fd, const char *basename,
- entrylk_cmd cmd, entrylk_type type);
-
-int32_t default_readdir_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- size_t size, off_t off);
-
-int32_t default_readdirp_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- size_t size, off_t off);
-
-int32_t default_xattrop_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- gf_xattrop_flags_t flags,
- dict_t *dict);
-
-int32_t default_fxattrop_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- gf_xattrop_flags_t flags,
- dict_t *dict);
-int32_t default_rchecksum_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd, off_t offset,
- int32_t len);
-
-int32_t default_notify (xlator_t *this,
- int32_t event,
- void *data,
- ...);
-
-int32_t default_forget (xlator_t *this,
- inode_t *inode);
-
-int32_t default_release (xlator_t *this,
- fd_t *fd);
-
-int32_t default_releasedir (xlator_t *this,
- fd_t *fd);
-
-int32_t default_setattr_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- struct iatt *stbuf,
- int32_t valid);
-
-int32_t default_fsetattr_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- struct iatt *stbuf,
- int32_t valid);
-
-/* _cbk */
-
-int32_t
-default_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, dict_t *dict, struct iatt *postparent);
-
-int32_t
-default_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf);
-
-
-int32_t
-default_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf);
-
-int32_t
-default_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf);
-
-int32_t
-default_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
-
-int32_t
-default_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, const char *path,
- struct iatt *buf);
-
-
-int32_t
-default_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent);
-
-int32_t
-default_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent);
-
-int32_t
-default_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent);
-
-int32_t
-default_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent);
-
-
-int32_t
-default_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent);
-
-
-int32_t
-default_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent);
-
-
-int32_t
-default_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent);
-
-
-int32_t
-default_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent);
-
-int32_t
-default_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd);
-
-int32_t
-default_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iovec *vector,
- int32_t count, struct iatt *stbuf, struct iobref *iobref);
-
-
-int32_t
-default_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf);
-
-
-int32_t
-default_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
-
-
-
-int32_t
-default_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf);
-
-int32_t
-default_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf);
-
-int32_t
-default_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd);
-
-int32_t
-default_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
-
-int32_t
-default_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct statvfs *buf);
-
-
-int32_t
-default_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
-
-
-int32_t
-default_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
-
-
-
-int32_t
-default_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict);
-
-
-int32_t
-default_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict);
-
-int32_t
-default_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict);
-
-int32_t
-default_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict);
-
-
-int32_t
-default_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
-
-int32_t
-default_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct gf_flock *lock);
-
-int32_t
-default_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
-
-
-int32_t
-default_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
-
-int32_t
-default_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
-
-int32_t
-default_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
-
-
-int32_t
-default_rchecksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, uint32_t weak_checksum,
- uint8_t *strong_checksum);
-
-
-int32_t
-default_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *entries);
-
-
-int32_t
-default_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *entries);
-
-int32_t
-default_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *statpre,
- struct iatt *statpost);
-
-int32_t
-default_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *statpre,
- struct iatt *statpost);
-
-int32_t
-default_getspec_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, char *spec_data);
-
-int32_t
-default_mem_acct_init (xlator_t *this);
-
-#endif /* _DEFAULTS_H */
diff --git a/libglusterfs/src/dict.c b/libglusterfs/src/dict.c
index 7fbacf7c3d0..1d9be9217a6 100644
--- a/libglusterfs/src/dict.c
+++ b/libglusterfs/src/dict.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 <unistd.h>
@@ -22,1229 +13,1475 @@
#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
+#include <limits.h>
+#include <fnmatch.h>
+
+#include "glusterfs/dict.h"
+#define XXH_INLINE_ALL
+#include "xxhash.h"
+#include "glusterfs/compat.h"
+#include "glusterfs/compat-errno.h"
+#include "glusterfs/byte-order.h"
+#include "glusterfs/statedump.h"
+#include "glusterfs/libglusterfs-messages.h"
+
+struct dict_cmp {
+ dict_t *dict;
+ gf_boolean_t (*value_ignore)(char *k);
+};
+
+#define VALIDATE_DATA_AND_LOG(data, type, key, ret_val) \
+ do { \
+ if (!data || !data->data) { \
+ gf_msg_callingfn("dict", GF_LOG_DEBUG, EINVAL, LG_MSG_INVALID_ARG, \
+ "data is NULL"); \
+ return ret_val; \
+ } \
+ /* Not of the asked type, or old version */ \
+ if ((data->data_type != type) && \
+ (data->data_type != GF_DATA_TYPE_STR_OLD)) { \
+ gf_msg_callingfn("dict", GF_LOG_DEBUG, EINVAL, LG_MSG_INVALID_ARG, \
+ "key %s, %s type asked, has %s type", key, \
+ data_type_name[type], \
+ data_type_name[data->data_type]); \
+ } \
+ } while (0)
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "glusterfs.h"
-#include "common-utils.h"
-#include "dict.h"
-#include "hashfn.h"
-#include "logging.h"
-#include "compat.h"
-#include "byte-order.h"
-
-data_pair_t *
-get_new_data_pair ()
+static data_t *
+get_new_data()
{
- data_pair_t *data_pair_ptr = NULL;
-
- data_pair_ptr = (data_pair_t *) GF_CALLOC (1, sizeof (data_pair_t),
- gf_common_mt_data_pair_t);
- return data_pair_ptr;
-}
+ data_t *data = mem_get(THIS->ctx->dict_data_pool);
-data_t *
-get_new_data ()
-{
- data_t *data = NULL;
+ if (!data)
+ return NULL;
- data = (data_t *) GF_CALLOC (1, sizeof (data_t), gf_common_mt_data_t);
- if (!data) {
- return NULL;
- }
+ GF_ATOMIC_INIT(data->refcount, 0);
+ data->is_static = _gf_false;
- LOCK_INIT (&data->lock);
- return data;
+ return data;
}
-dict_t *
-get_new_dict_full (int size_hint)
+static dict_t *
+get_new_dict_full(int size_hint)
{
- dict_t *dict = GF_CALLOC (1, sizeof (dict_t), gf_common_mt_dict_t);
-
- if (!dict) {
- return NULL;
- }
-
- dict->hash_size = size_hint;
- dict->members = GF_CALLOC (size_hint, sizeof (data_pair_t *),
- gf_common_mt_data_pair_t);
+ dict_t *dict = mem_get0(THIS->ctx->dict_pool);
+ if (!dict) {
+ return NULL;
+ }
+
+ dict->hash_size = size_hint;
+ if (size_hint == 1) {
+ /*
+ * This is the only case we ever see currently. If we ever
+ * need to support resizing the hash table, the resize function
+ * will have to take into account the possibility that
+ * "members" is not separately allocated (i.e. don't just call
+ * realloc() blindly.
+ */
+ dict->members = &dict->members_internal;
+ } else {
+ /*
+ * We actually need to allocate space for size_hint *pointers*
+ * but we actually allocate space for one *structure*. Since
+ * a data_pair_t consists of five pointers, we're wasting four
+ * pointers' worth for N=1, and will overrun what we allocated
+ * for N>5. If anybody ever starts using size_hint, we'll need
+ * to fix this.
+ */
+ GF_ASSERT(size_hint <= (sizeof(data_pair_t) / sizeof(data_pair_t *)));
+ dict->members = mem_get0(THIS->ctx->dict_pair_pool);
if (!dict->members) {
- GF_FREE (dict);
- return NULL;
+ mem_put(dict);
+ return NULL;
}
+ }
- LOCK_INIT (&dict->lock);
+ dict->free_pair.key = NULL;
+ dict->totkvlen = 0;
+ LOCK_INIT(&dict->lock);
- return dict;
+ return dict;
}
dict_t *
-get_new_dict (void)
+dict_new(void)
{
- return get_new_dict_full (1);
+ dict_t *dict = get_new_dict_full(1);
+
+ if (dict)
+ dict_ref(dict);
+
+ return dict;
}
-dict_t *
-dict_new (void)
+int32_t
+is_data_equal(data_t *one, data_t *two)
{
- dict_t *dict = NULL;
+ struct iatt *iatt1, *iatt2;
+ struct mdata_iatt *mdata_iatt1, *mdata_iatt2;
- dict = get_new_dict_full(1);
+ if (!one || !two || !one->data || !two->data) {
+ gf_msg_callingfn("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "input arguments are provided "
+ "with value data_t as NULL");
+ return -1;
+ }
- if (dict)
- dict_ref (dict);
+ if (one == two)
+ return 1;
- return dict;
-}
+ if (one->data == two->data)
+ return 1;
+ if (one->data_type != two->data_type) {
+ return 0;
+ }
-int32_t
-is_data_equal (data_t *one,
- data_t *two)
-{
- /* LOG-TODO */
- if (!one || !two || !one->data || !two->data)
- return 1;
+ if (one->data_type == GF_DATA_TYPE_IATT) {
+ if ((one->len < sizeof(struct iatt)) ||
+ (two->len < sizeof(struct iatt))) {
+ return 0;
+ }
- if (one == two)
- return 1;
+ iatt1 = (struct iatt *)one->data;
+ iatt2 = (struct iatt *)two->data;
- if (one->len != two->len)
+ /* Two iatt structs are considered equal if main fields are
+ * equal, even if times differ.
+ * TODO: maybe when ctime if fully operational we could
+ * enforce time matching. */
+ if (iatt1->ia_ino != iatt2->ia_ino) {
+ return 0;
+ }
+ if (iatt1->ia_type != iatt2->ia_type) {
+ return 0;
+ }
+ if ((iatt1->ia_type == IA_IFBLK) || (iatt1->ia_type == IA_IFCHR)) {
+ if (iatt1->ia_rdev != iatt2->ia_rdev) {
return 0;
+ }
+ }
+ if (gf_uuid_compare(iatt1->ia_gfid, iatt2->ia_gfid) != 0) {
+ return 0;
+ }
- if (one->data == two->data)
- return 1;
+ /* TODO: ia_uid, ia_gid, ia_prot and ia_size can be changed
+ * with some commands. Here we don't have enough
+ * information to decide if they should match or not. */
+ /*
+ if ((iatt1->ia_uid != iatt2->ia_uid) ||
+ (iatt1->ia_gid != iatt2->ia_gid) ||
+ (st_mode_from_ia(iatt1->ia_prot, iatt1->ia_type) !=
+ st_mode_from_ia(iatt2->ia_prot,
+ iatt2->ia_type))) { return 0;
+ }
+ if (iatt1->ia_type == IA_IFREG) {
+ if (iatt1->ia_size != iatt2->ia_size) {
+ return 0;
+ }
+ }
+ */
+ return 1;
+ }
+ if (one->data_type == GF_DATA_TYPE_MDATA) {
+ if ((one->len < sizeof(struct mdata_iatt)) ||
+ (two->len < sizeof(struct mdata_iatt))) {
+ return 0;
+ }
+ mdata_iatt1 = (struct mdata_iatt *)one->data;
+ mdata_iatt2 = (struct mdata_iatt *)two->data;
+
+ if (mdata_iatt1->ia_atime != mdata_iatt2->ia_atime ||
+ mdata_iatt1->ia_mtime != mdata_iatt2->ia_mtime ||
+ mdata_iatt1->ia_ctime != mdata_iatt2->ia_ctime ||
+ mdata_iatt1->ia_atime_nsec != mdata_iatt2->ia_atime_nsec ||
+ mdata_iatt1->ia_mtime_nsec != mdata_iatt2->ia_mtime_nsec ||
+ mdata_iatt1->ia_ctime_nsec != mdata_iatt2->ia_ctime_nsec) {
+ return 0;
+ }
+ return 1;
+ }
+
+ if (one->len != two->len)
+ return 0;
- if (memcmp (one->data, two->data, one->len) == 0)
- return 1;
+ if (memcmp(one->data, two->data, one->len) == 0)
+ return 1;
- return 0;
+ return 0;
+}
+
+static int
+key_value_cmp(dict_t *one, char *key1, data_t *value1, void *data)
+{
+ struct dict_cmp *cmp = data;
+ dict_t *two = cmp->dict;
+ data_t *value2 = dict_get(two, key1);
+
+ if (value2) {
+ if (cmp->value_ignore && cmp->value_ignore(key1))
+ return 0;
+
+ if (is_data_equal(value1, value2) == 1)
+ return 0;
+ }
+
+ if (value2 == NULL) {
+ gf_msg_debug(THIS->name, 0, "'%s' found only on one dict", key1);
+ } else {
+ gf_msg_debug(THIS->name, 0,
+ "'%s' is different in two dicts "
+ "(%u, %u)",
+ key1, value1->len, value2->len);
+ }
+
+ return -1;
+}
+
+/* If both dicts are NULL then equal. If one of the dicts is NULL but the
+ * other has only ignorable keys then also they are equal. If both dicts are
+ * non-null then check if for each non-ignorable key, values are same or
+ * not. value_ignore function is used to skip comparing values for the keys
+ * which must be present in both the dictionaries but the value could be
+ * different.
+ */
+gf_boolean_t
+are_dicts_equal(dict_t *one, dict_t *two,
+ gf_boolean_t (*match)(dict_t *d, char *k, data_t *v,
+ void *data),
+ gf_boolean_t (*value_ignore)(char *k))
+{
+ int num_matches1 = 0;
+ int num_matches2 = 0;
+ struct dict_cmp cmp = {0};
+
+ if (one == two)
+ return _gf_true;
+
+ if (!match)
+ match = dict_match_everything;
+
+ if ((one == NULL) || (two == NULL)) {
+ num_matches1 = dict_foreach_match(one ? one : two, match, NULL,
+ dict_null_foreach_fn, NULL);
+ goto done;
+ }
+
+ cmp.dict = two;
+ cmp.value_ignore = value_ignore;
+ num_matches1 = dict_foreach_match(one, match, NULL, key_value_cmp, &cmp);
+
+ if (num_matches1 == -1)
+ return _gf_false;
+
+ if ((num_matches1 == one->count) && (one->count == two->count))
+ return _gf_true;
+
+ num_matches2 = dict_foreach_match(two, match, NULL, dict_null_foreach_fn,
+ NULL);
+done:
+ /* If the number of matches is same in 'two' then for all the
+ * valid-keys that exist in 'one' the value matched and no extra valid
+ * keys exist in 'two' alone. Otherwise there exists at least one extra
+ * valid-key in 'two' which doesn't exist in 'one' */
+ if (num_matches1 == num_matches2)
+ return _gf_true;
+ return _gf_false;
}
void
-data_destroy (data_t *data)
+data_destroy(data_t *data)
{
- if (data) {
- LOCK_DESTROY (&data->lock);
-
- if (!data->is_static) {
- if (data->data) {
- if (data->is_stdalloc)
- free (data->data);
- else
- GF_FREE (data->data);
- }
- if (data->vec)
- GF_FREE (data->vec);
- }
+ if (data) {
+ if (!data->is_static)
+ GF_FREE(data->data);
- data->len = 0xbabababa;
- if (!data->is_const)
- GF_FREE (data);
- }
+ data->len = 0xbabababa;
+ mem_put(data);
+ }
}
data_t *
-data_copy (data_t *old)
+data_copy(data_t *old)
{
- if (!old) {
- gf_log_callingfn ("dict", GF_LOG_WARNING,
- "old is NULL");
- return NULL;
- }
+ if (!old) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, 0, LG_MSG_NULL_PTR,
+ "old is NULL");
+ return NULL;
+ }
- data_t *newdata = (data_t *) GF_CALLOC (1, sizeof (*newdata),
- gf_common_mt_data_t);
+ data_t *newdata = mem_get0(THIS->ctx->dict_data_pool);
+ if (!newdata) {
+ return NULL;
+ }
- if (!newdata) {
- return NULL;
- }
+ newdata->len = old->len;
+ if (old->data) {
+ newdata->data = gf_memdup(old->data, old->len);
+ if (!newdata->data)
+ goto err_out;
+ }
+ newdata->data_type = old->data_type;
- if (old) {
- newdata->len = old->len;
- if (old->data) {
- newdata->data = memdup (old->data, old->len);
- if (!newdata->data)
- goto err_out;
- }
- if (old->vec) {
- newdata->vec = memdup (old->vec, old->len * (sizeof (void *) +
- sizeof (size_t)));
- if (!newdata->vec)
- goto err_out;
- }
- }
-
- LOCK_INIT (&newdata->lock);
- return newdata;
+ return newdata;
err_out:
+ mem_put(newdata);
- if (newdata->data)
- FREE (newdata->data);
- if (newdata->vec)
- FREE (newdata->vec);
- GF_FREE (newdata);
-
- return NULL;
+ return NULL;
}
+/* Always need to be called under lock
+ * Always this and key variables are not null -
+ * checked by callers.
+ */
static data_pair_t *
-_dict_lookup (dict_t *this, char *key)
+dict_lookup_common(const dict_t *this, const char *key, const uint32_t hash)
{
- if (!this || !key) {
- gf_log_callingfn ("dict", GF_LOG_WARNING,
- "!this || !key (%s)", key);
- return NULL;
- }
+ int hashval = 0;
+ data_pair_t *pair;
- int hashval = SuperFastHash (key, strlen (key)) % this->hash_size;
- data_pair_t *pair;
+ /* If the divisor is 1, the modulo is always 0,
+ * in such case avoid hash calculation.
+ */
+ if (this->hash_size != 1)
+ hashval = hash % this->hash_size;
- for (pair = this->members[hashval]; pair != NULL; pair = pair->hash_next) {
- if (pair->key && !strcmp (pair->key, key))
- return pair;
- }
+ for (pair = this->members[hashval]; pair != NULL; pair = pair->hash_next) {
+ if (pair->key && (hash == pair->key_hash) && !strcmp(pair->key, key))
+ return pair;
+ }
- return NULL;
+ return NULL;
}
+int32_t
+dict_lookup(dict_t *this, char *key, data_t **data)
+{
+ if (!this || !key || !data) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "!this || !key || "
+ "!data");
+ return -1;
+ }
-static int32_t
-_dict_set (dict_t *this,
- char *key,
- data_t *value)
-{
- int hashval;
- data_pair_t *pair;
- char key_free = 0;
- int tmp = 0;
- int ret = 0;
-
- if (!key) {
- ret = gf_asprintf (&key, "ref:%p", value);
- if (-1 == ret) {
- gf_log ("dict", GF_LOG_WARNING, "asprintf failed %s", key);
- return -1;
- }
- key_free = 1;
- }
-
- tmp = SuperFastHash (key, strlen (key));
- hashval = (tmp % this->hash_size);
- pair = _dict_lookup (this, key);
-
- if (pair) {
- data_t *unref_data = pair->value;
- pair->value = data_ref (value);
- data_unref (unref_data);
- if (key_free)
- GF_FREE (key);
- /* Indicates duplicate key */
- return 0;
- }
- pair = (data_pair_t *) GF_CALLOC (1, sizeof (*pair),
- gf_common_mt_data_pair_t);
- if (!pair) {
- return -1;
- }
-
- pair->key = (char *) GF_CALLOC (1, strlen (key) + 1,
- gf_common_mt_char);
- if (!pair->key) {
- GF_FREE (pair);
+ data_pair_t *tmp = NULL;
- if (key_free)
- GF_FREE (key);
- return -1;
- }
+ uint32_t hash = (uint32_t)XXH64(key, strlen(key), 0);
- strcpy (pair->key, key);
- pair->value = data_ref (value);
+ LOCK(&this->lock);
+ {
+ tmp = dict_lookup_common(this, key, hash);
+ }
+ UNLOCK(&this->lock);
- pair->hash_next = this->members[hashval];
- this->members[hashval] = pair;
+ if (!tmp)
+ return -1;
- pair->next = this->members_list;
- pair->prev = NULL;
- if (this->members_list)
- this->members_list->prev = pair;
- this->members_list = pair;
- this->count++;
+ *data = tmp->value;
+ return 0;
+}
- if (key_free)
- GF_FREE (key);
- return 0;
+static int32_t
+dict_set_lk(dict_t *this, char *key, const int key_len, data_t *value,
+ const uint32_t hash, gf_boolean_t replace)
+{
+ int hashval = 0;
+ data_pair_t *pair;
+ int key_free = 0;
+ uint32_t key_hash;
+ int keylen;
+
+ if (!key) {
+ keylen = gf_asprintf(&key, "ref:%p", value);
+ if (-1 == keylen) {
+ return -1;
+ }
+ key_free = 1;
+ key_hash = (uint32_t)XXH64(key, keylen, 0);
+ } else {
+ keylen = key_len;
+ key_hash = hash;
+ }
+
+ /* Search for a existing key if 'replace' is asked for */
+ if (replace) {
+ pair = dict_lookup_common(this, key, key_hash);
+ if (pair) {
+ data_t *unref_data = pair->value;
+ pair->value = data_ref(value);
+ this->totkvlen += (value->len - unref_data->len);
+ data_unref(unref_data);
+ if (key_free)
+ GF_FREE(key);
+ /* Indicates duplicate key */
+ return 0;
+ }
+ }
+
+ if (this->free_pair.key) { /* the free_pair is used */
+ pair = mem_get(THIS->ctx->dict_pair_pool);
+ if (!pair) {
+ if (key_free)
+ GF_FREE(key);
+ return -1;
+ }
+ } else { /* assign the pair to the free pair */
+ pair = &this->free_pair;
+ }
+
+ if (key_free) {
+ /* It's ours. Use it. */
+ pair->key = key;
+ key_free = 0;
+ } else {
+ pair->key = (char *)GF_MALLOC(keylen + 1, gf_common_mt_char);
+ if (!pair->key) {
+ if (pair != &this->free_pair) {
+ mem_put(pair);
+ }
+ return -1;
+ }
+ strcpy(pair->key, key);
+ }
+ pair->key_hash = key_hash;
+ pair->value = data_ref(value);
+ this->totkvlen += (keylen + 1 + value->len);
+
+ /* If the divisor is 1, the modulo is always 0,
+ * in such case avoid hash calculation.
+ */
+ if (this->hash_size != 1) {
+ hashval = (key_hash % this->hash_size);
+ }
+ pair->hash_next = this->members[hashval];
+ this->members[hashval] = pair;
+
+ pair->next = this->members_list;
+ pair->prev = NULL;
+ if (this->members_list)
+ this->members_list->prev = pair;
+ this->members_list = pair;
+ this->count++;
+
+ if (key_free)
+ GF_FREE(key);
+
+ if (this->max_count < this->count)
+ this->max_count = this->count;
+ return 0;
}
int32_t
-dict_set (dict_t *this,
- char *key,
- data_t *value)
+dict_set(dict_t *this, char *key, data_t *value)
{
- int32_t ret;
-
- if (!this || !value) {
- gf_log_callingfn ("dict", GF_LOG_WARNING,
- "!this || !value for key=%s", key);
- return -1;
- }
-
- LOCK (&this->lock);
-
- ret = _dict_set (this, key, value);
-
- UNLOCK (&this->lock);
-
- return ret;
+ if (key)
+ return dict_setn(this, key, strlen(key), value);
+ else
+ return dict_setn(this, NULL, 0, value);
}
-
-data_t *
-dict_get (dict_t *this, char *key)
+int32_t
+dict_setn(dict_t *this, char *key, const int keylen, data_t *value)
{
- data_pair_t *pair;
+ int32_t ret;
+ uint32_t key_hash = 0;
- if (!this || !key) {
- gf_log_callingfn ("dict", GF_LOG_INFO,
- "!this || key=%s", (key) ? key : "()");
- return NULL;
- }
+ if (!this || !value) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "!this || !value for "
+ "key=%s",
+ key);
+ return -1;
+ }
- LOCK (&this->lock);
+ if (key) {
+ key_hash = (uint32_t)XXH64(key, keylen, 0);
+ }
- pair = _dict_lookup (this, key);
+ LOCK(&this->lock);
- UNLOCK (&this->lock);
+ ret = dict_set_lk(this, key, keylen, value, key_hash, 1);
- if (pair)
- return pair->value;
+ UNLOCK(&this->lock);
- return NULL;
+ return ret;
}
-void
-dict_del (dict_t *this, char *key)
+int32_t
+dict_add(dict_t *this, char *key, data_t *value)
{
- if (!this || !key) {
- gf_log_callingfn ("dict", GF_LOG_WARNING,
- "!this || key=%s", key);
- return;
- }
-
- LOCK (&this->lock);
-
- int hashval = SuperFastHash (key, strlen (key)) % this->hash_size;
- data_pair_t *pair = this->members[hashval];
- data_pair_t *prev = NULL;
+ if (key)
+ return dict_addn(this, key, strlen(key), value);
+ else
+ return dict_addn(this, NULL, 0, value);
+}
- while (pair) {
- if (strcmp (pair->key, key) == 0) {
- if (prev)
- prev->hash_next = pair->hash_next;
- else
- this->members[hashval] = pair->hash_next;
+int32_t
+dict_addn(dict_t *this, char *key, const int keylen, data_t *value)
+{
+ int32_t ret;
+ uint32_t key_hash = 0;
- data_unref (pair->value);
+ if (!this || !value) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "!this || !value for key=%s", key);
+ return -1;
+ }
- if (pair->prev)
- pair->prev->next = pair->next;
- else
- this->members_list = pair->next;
+ if (key) {
+ key_hash = (uint32_t)XXH64(key, keylen, 0);
+ }
- if (pair->next)
- pair->next->prev = pair->prev;
+ LOCK(&this->lock);
- GF_FREE (pair->key);
- GF_FREE (pair);
- this->count--;
- break;
- }
+ ret = dict_set_lk(this, key, keylen, value, key_hash, 0);
- prev = pair;
- pair = pair->hash_next;
- }
+ UNLOCK(&this->lock);
- UNLOCK (&this->lock);
-
- return;
+ return ret;
}
-void
-dict_destroy (dict_t *this)
+data_t *
+dict_get(dict_t *this, char *key)
{
- if (!this) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is NULL");
- return;
- }
-
- data_pair_t *pair = this->members_list;
- data_pair_t *prev = this->members_list;
-
- LOCK_DESTROY (&this->lock);
-
- while (prev) {
- pair = pair->next;
- data_unref (prev->value);
- GF_FREE (prev->key);
- GF_FREE (prev);
- prev = pair;
- }
-
- GF_FREE (this->members);
-
- if (this->extra_free)
- GF_FREE (this->extra_free);
- if (this->extra_stdfree)
- free (this->extra_stdfree);
-
- if (!this->is_static)
- GF_FREE (this);
+ if (!this || !key) {
+ gf_msg_callingfn("dict", GF_LOG_DEBUG, EINVAL, LG_MSG_INVALID_ARG,
+ "!this || key=%s", (key) ? key : "()");
+ return NULL;
+ }
- return;
+ return dict_getn(this, key, strlen(key));
}
-void
-dict_unref (dict_t *this)
+data_t *
+dict_getn(dict_t *this, char *key, const int keylen)
{
- int32_t ref;
+ data_pair_t *pair;
+ uint32_t hash;
- if (!this) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is NULL");
- return;
- }
+ if (!this || !key) {
+ gf_msg_callingfn("dict", GF_LOG_DEBUG, EINVAL, LG_MSG_INVALID_ARG,
+ "!this || key=%s", (key) ? key : "()");
+ return NULL;
+ }
- LOCK (&this->lock);
+ hash = (uint32_t)XXH64(key, keylen, 0);
- this->refcount--;
- ref = this->refcount;
+ LOCK(&this->lock);
+ {
+ pair = dict_lookup_common(this, key, hash);
+ }
+ UNLOCK(&this->lock);
- UNLOCK (&this->lock);
+ if (pair)
+ return pair->value;
- if (!ref)
- dict_destroy (this);
+ return NULL;
}
-dict_t *
-dict_ref (dict_t *this)
+int
+dict_key_count(dict_t *this)
{
- if (!this) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is NULL");
- return NULL;
- }
-
- LOCK (&this->lock);
+ int ret = -1;
- this->refcount++;
+ if (!this) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "dict passed is NULL");
+ return ret;
+ }
- UNLOCK (&this->lock);
+ LOCK(&this->lock);
+ {
+ ret = this->count;
+ }
+ UNLOCK(&this->lock);
- return this;
+ return ret;
}
void
-data_unref (data_t *this)
+dict_del(dict_t *this, char *key)
{
- int32_t ref;
-
- if (!this) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is NULL");
- return;
- }
-
- LOCK (&this->lock);
-
- this->refcount--;
- ref = this->refcount;
-
- UNLOCK (&this->lock);
+ if (!this || !key) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "!this || key=%s", key);
+ return;
+ }
- if (!ref)
- data_destroy (this);
+ return dict_deln(this, key, strlen(key));
}
-data_t *
-data_ref (data_t *this)
+void
+dict_deln(dict_t *this, char *key, const int keylen)
{
- if (!this) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is NULL");
- return NULL;
- }
+ int hashval = 0;
+ uint32_t hash;
- LOCK (&this->lock);
+ if (!this || !key) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "!this || key=%s", key);
+ return;
+ }
- this->refcount++;
+ hash = (uint32_t)XXH64(key, keylen, 0);
- UNLOCK (&this->lock);
+ LOCK(&this->lock);
- return this;
-}
+ /* If the divisor is 1, the modulo is always 0,
+ * in such case avoid hash calculation.
+ */
+ if (this->hash_size != 1)
+ hashval = hash % this->hash_size;
-/*
- Serialization format:
- ----
- Count:8
- Key_len:8:Value_len:8
- Key
- Value
- .
- .
- .
-*/
+ data_pair_t *pair = this->members[hashval];
+ data_pair_t *prev = NULL;
-int32_t
-dict_serialized_length_old (dict_t *this)
-{
+ while (pair) {
+ if ((hash == pair->key_hash) && strcmp(pair->key, key) == 0) {
+ if (prev)
+ prev->hash_next = pair->hash_next;
+ else
+ this->members[hashval] = pair->hash_next;
- if (!this) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is NULL");
- return -1;
- }
+ this->totkvlen -= pair->value->len;
+ data_unref(pair->value);
- int32_t len = 9; /* count + \n */
- int32_t count = this->count;
- data_pair_t *pair = this->members_list;
-
- while (count) {
- len += 18;
- len += strlen (pair->key) + 1;
- if (pair->value->vec) {
- int i;
- for (i=0; i<pair->value->len; i++) {
- len += pair->value->vec[i].iov_len;
- }
- } else {
- len += pair->value->len;
- }
- pair = pair->next;
- count--;
- }
+ if (pair->prev)
+ pair->prev->next = pair->next;
+ else
+ this->members_list = pair->next;
- return len;
-}
+ if (pair->next)
+ pair->next->prev = pair->prev;
-int32_t
-dict_serialize_old (dict_t *this, char *buf)
-{
- if (!this || !buf) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is NULL");
- return -1;
+ this->totkvlen -= (strlen(pair->key) + 1);
+ GF_FREE(pair->key);
+ if (pair == &this->free_pair) {
+ this->free_pair.key = NULL;
+ } else {
+ mem_put(pair);
+ }
+ this->count--;
+ break;
}
- data_pair_t *pair = this->members_list;
- int32_t count = this->count;
- uint64_t dcount = this->count;
-
- // FIXME: magic numbers
-
- sprintf (buf, "%08"PRIx64"\n", dcount);
- buf += 9;
- while (count) {
- uint64_t keylen = strlen (pair->key) + 1;
- uint64_t vallen = pair->value->len;
-
- sprintf (buf, "%08"PRIx64":%08"PRIx64"\n", keylen, vallen);
- buf += 18;
- memcpy (buf, pair->key, keylen);
- buf += keylen;
- memcpy (buf, pair->value->data, pair->value->len);
- buf += pair->value->len;
- pair = pair->next;
- count--;
- }
- return (0);
-}
+ prev = pair;
+ pair = pair->hash_next;
+ }
+ UNLOCK(&this->lock);
-dict_t *
-dict_unserialize_old (char *buf, int32_t size, dict_t **fill)
-{
- int32_t ret = 0;
- int32_t cnt = 0;
+ return;
+}
- if (!buf || !fill || !(*fill)) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "buf is NULL");
- return NULL;
- }
+void
+dict_destroy(dict_t *this)
+{
+ if (!this) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "dict is NULL");
+ return;
+ }
- uint64_t count;
- ret = sscanf (buf, "%"SCNx64"\n", &count);
- (*fill)->count = 0;
+ data_pair_t *pair = this->members_list;
+ data_pair_t *prev = this->members_list;
+ glusterfs_ctx_t *ctx = NULL;
+ uint64_t current_max = 0;
+ uint32_t total_pairs = 0;
- if (!ret){
- gf_log ("dict", GF_LOG_ERROR, "sscanf on buf failed");
- goto err;
- }
- buf += 9;
+ LOCK_DESTROY(&this->lock);
- if (count == 0) {
- gf_log ("dict", GF_LOG_ERROR, "count == 0");
- goto err;
+ while (prev) {
+ pair = pair->next;
+ data_unref(prev->value);
+ GF_FREE(prev->key);
+ if (prev != &this->free_pair) {
+ mem_put(prev);
+ } else {
+ this->free_pair.key = NULL;
}
+ total_pairs++;
+ prev = pair;
+ }
- for (cnt = 0; cnt < count; cnt++) {
- data_t *value = NULL;
- char *key = NULL;
- uint64_t key_len, value_len;
-
- ret = sscanf (buf, "%"SCNx64":%"SCNx64"\n", &key_len, &value_len);
- if (ret != 2) {
- gf_log ("dict", GF_LOG_ERROR,
- "sscanf for key_len and value_len failed");
- goto err;
- }
- buf += 18;
+ this->totkvlen = 0;
+ if (this->members != &this->members_internal) {
+ mem_put(this->members);
+ }
- key = buf;
- buf += key_len;
+ free(this->extra_stdfree);
- value = get_new_data ();
- value->len = value_len;
- value->data = buf;
- value->is_static = 1;
- buf += value_len;
+ /* update 'ctx->stats.dict.details' using max_count */
+ ctx = THIS->ctx;
- dict_set (*fill, key, value);
- }
+ /* NOTE: below logic is not totaly race proof */
+ /* thread0 and thread1 gets current_max as 10 */
+ /* thread0 has 'this->max_count as 11 */
+ /* thread1 has 'this->max_count as 20 */
+ /* thread1 goes ahead and sets the max_dict_pairs to 20 */
+ /* thread0 then goes and sets it to 11 */
+ /* As it is for information purpose only, no functionality will be
+ broken by this, but a point to consider about ATOMIC macros. */
+ current_max = GF_ATOMIC_GET(ctx->stats.max_dict_pairs);
+ if (current_max < this->max_count)
+ GF_ATOMIC_INIT(ctx->stats.max_dict_pairs, this->max_count);
- goto ret;
+ GF_ATOMIC_ADD(ctx->stats.total_pairs_used, total_pairs);
+ GF_ATOMIC_INC(ctx->stats.total_dicts_used);
-err:
- GF_FREE (*fill);
- *fill = NULL;
+ mem_put(this);
-ret:
- return *fill;
+ return;
}
-
-int32_t
-dict_iovec_len (dict_t *this)
+void
+dict_unref(dict_t *this)
{
- if (!this) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is NULL");
- return -1;
- }
-
- int32_t len = 0;
- data_pair_t *pair = this->members_list;
+ uint64_t ref = 0;
- len++; /* initial header */
- while (pair) {
- len++; /* pair header */
- len++; /* key */
+ if (!this) {
+ gf_msg_callingfn("dict", GF_LOG_DEBUG, EINVAL, LG_MSG_INVALID_ARG,
+ "dict is NULL");
+ return;
+ }
- if (pair->value->vec)
- len += pair->value->len;
- else
- len++;
- pair = pair->next;
- }
+ ref = GF_ATOMIC_DEC(this->refcount);
- return len;
+ if (!ref)
+ dict_destroy(this);
}
-int32_t
-dict_to_iovec (dict_t *this,
- struct iovec *vec,
- int32_t count)
+dict_t *
+dict_ref(dict_t *this)
{
- if (!this || !vec) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is NULL");
- return -1;
- }
-
- int32_t i = 0;
- data_pair_t *pair = this->members_list;
-
- vec[0].iov_len = 9;
- if (vec[0].iov_base)
- sprintf (vec[0].iov_base,
- "%08"PRIx64"\n",
- (int64_t)this->count);
- i++;
-
- while (pair) {
- int64_t keylen = strlen (pair->key) + 1;
- int64_t vallen = 0;
+ if (!this) {
+ gf_msg_callingfn("dict", GF_LOG_DEBUG, EINVAL, LG_MSG_INVALID_ARG,
+ "dict is NULL");
+ return NULL;
+ }
- if (pair->value->vec) {
- int i;
+ GF_ATOMIC_INC(this->refcount);
+ return this;
+}
- for (i=0; i<pair->value->len; i++) {
- vallen += pair->value->vec[i].iov_len;
- }
- } else {
- vallen = pair->value->len;
- }
+void
+data_unref(data_t *this)
+{
+ uint64_t ref;
- vec[i].iov_len = 18;
- if (vec[i].iov_base)
- sprintf (vec[i].iov_base,
- "%08"PRIx64":%08"PRIx64"\n",
- keylen,
- vallen);
- i++;
-
- vec[i].iov_len = keylen;
- vec[i].iov_base = pair->key;
- i++;
-
- if (pair->value->vec) {
- int k;
-
- for (k=0; k<pair->value->len; k++) {
- vec[i].iov_len = pair->value->vec[k].iov_len;
- vec[i].iov_base = pair->value->vec[k].iov_base;
- i++;
- }
- } else {
- vec[i].iov_len = pair->value->len;
- vec[i].iov_base = pair->value->data;
- i++;
- }
+ if (!this) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "data is NULL");
+ return;
+ }
- pair = pair->next;
- }
+ ref = GF_ATOMIC_DEC(this->refcount);
- return 0;
+ if (!ref)
+ data_destroy(this);
}
data_t *
-int_to_data (int64_t value)
+data_ref(data_t *this)
{
- int ret = 0;
- data_t *data = get_new_data ();
-
- if (!data) {
- return NULL;
- }
+ if (!this) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "data is NULL");
+ return NULL;
+ }
- ret = gf_asprintf (&data->data, "%"PRId64, value);
- if (-1 == ret) {
- gf_log ("dict", GF_LOG_DEBUG, "asprintf failed");
- return NULL;
- }
- data->len = strlen (data->data) + 1;
+ GF_ATOMIC_INC(this->refcount);
- return data;
+ return this;
}
data_t *
-data_from_int64 (int64_t value)
+int_to_data(int64_t value)
{
- int ret = 0;
- data_t *data = get_new_data ();
+ data_t *data = get_new_data();
- if (!data) {
- return NULL;
- }
- ret = gf_asprintf (&data->data, "%"PRId64, value);
- if (-1 == ret) {
- gf_log ("dict", GF_LOG_DEBUG, "asprintf failed");
- return NULL;
- }
- data->len = strlen (data->data) + 1;
+ if (!data) {
+ return NULL;
+ }
- return data;
+ data->len = gf_asprintf(&data->data, "%" PRId64, value);
+ if (-1 == data->len) {
+ gf_msg_debug("dict", 0, "asprintf failed");
+ data_destroy(data);
+ return NULL;
+ }
+ data->len++; /* account for terminating NULL */
+ data->data_type = GF_DATA_TYPE_INT;
+
+ return data;
}
data_t *
-data_from_int32 (int32_t value)
+data_from_int64(int64_t value)
{
- int ret = 0;
- data_t *data = get_new_data ();
-
- if (!data) {
- return NULL;
- }
- ret = gf_asprintf (&data->data, "%"PRId32, value);
- if (-1 == ret) {
- gf_log ("dict", GF_LOG_DEBUG, "asprintf failed");
- return NULL;
- }
+ data_t *data = get_new_data();
- data->len = strlen (data->data) + 1;
+ if (!data) {
+ return NULL;
+ }
+ data->len = gf_asprintf(&data->data, "%" PRId64, value);
+ if (-1 == data->len) {
+ gf_msg_debug("dict", 0, "asprintf failed");
+ data_destroy(data);
+ return NULL;
+ }
+ data->len++; /* account for terminating NULL */
+ data->data_type = GF_DATA_TYPE_INT;
- return data;
+ return data;
}
data_t *
-data_from_int16 (int16_t value)
+data_from_int32(int32_t value)
{
- int ret = 0;
- data_t *data = get_new_data ();
+ data_t *data = get_new_data();
- if (!data) {
- return NULL;
- }
- ret = gf_asprintf (&data->data, "%"PRId16, value);
- if (-1 == ret) {
- gf_log ("dict", GF_LOG_DEBUG, "asprintf failed");
- return NULL;
- }
+ if (!data) {
+ return NULL;
+ }
+ data->len = gf_asprintf(&data->data, "%" PRId32, value);
+ if (-1 == data->len) {
+ gf_msg_debug("dict", 0, "asprintf failed");
+ data_destroy(data);
+ return NULL;
+ }
- data->len = strlen (data->data) + 1;
+ data->len++; /* account for terminating NULL */
+ data->data_type = GF_DATA_TYPE_INT;
- return data;
+ return data;
}
data_t *
-data_from_int8 (int8_t value)
+data_from_int16(int16_t value)
{
- int ret = 0;
- data_t *data = get_new_data ();
+ data_t *data = get_new_data();
- if (!data) {
- return NULL;
- }
- ret = gf_asprintf (&data->data, "%d", value);
- if (-1 == ret) {
- gf_log ("dict", GF_LOG_DEBUG, "asprintf failed");
- return NULL;
- }
+ if (!data) {
+ return NULL;
+ }
+ data->len = gf_asprintf(&data->data, "%" PRId16, value);
+ if (-1 == data->len) {
+ gf_msg_debug("dict", 0, "asprintf failed");
+ data_destroy(data);
+ return NULL;
+ }
- data->len = strlen (data->data) + 1;
+ data->len++; /* account for terminating NULL */
+ data->data_type = GF_DATA_TYPE_INT;
- return data;
+ return data;
}
data_t *
-data_from_uint64 (uint64_t value)
+data_from_int8(int8_t value)
{
- int ret = 0;
- data_t *data = get_new_data ();
+ data_t *data = get_new_data();
- if (!data) {
- return NULL;
- }
- ret = gf_asprintf (&data->data, "%"PRIu64, value);
- if (-1 == ret) {
- gf_log ("dict", GF_LOG_DEBUG, "asprintf failed");
- return NULL;
- }
+ if (!data) {
+ return NULL;
+ }
+ data->len = gf_asprintf(&data->data, "%d", value);
+ if (-1 == data->len) {
+ gf_msg_debug("dict", 0, "asprintf failed");
+ data_destroy(data);
+ return NULL;
+ }
- data->len = strlen (data->data) + 1;
+ data->len++; /* account for terminating NULL */
+ data->data_type = GF_DATA_TYPE_INT;
- return data;
+ return data;
}
-static data_t *
-data_from_double (double value)
+data_t *
+data_from_uint64(uint64_t value)
{
- data_t *data = NULL;
- int ret = 0;
-
- data = get_new_data ();
+ data_t *data = get_new_data();
- if (!data) {
- return NULL;
- }
+ if (!data) {
+ return NULL;
+ }
+ data->len = gf_asprintf(&data->data, "%" PRIu64, value);
+ if (-1 == data->len) {
+ gf_msg_debug("dict", 0, "asprintf failed");
+ data_destroy(data);
+ return NULL;
+ }
- ret = gf_asprintf (&data->data, "%f", value);
- if (ret == -1) {
- return NULL;
- }
- data->len = strlen (data->data) + 1;
+ data->len++; /* account for terminating NULL */
+ data->data_type = GF_DATA_TYPE_UINT;
- return data;
+ return data;
}
-
data_t *
-data_from_uint32 (uint32_t value)
+data_from_double(double value)
{
- int ret = 0;
- data_t *data = get_new_data ();
+ data_t *data = get_new_data();
- if (!data) {
- return NULL;
- }
- ret = gf_asprintf (&data->data, "%"PRIu32, value);
- if (-1 == ret) {
- gf_log ("dict", GF_LOG_DEBUG, "asprintf failed");
- return NULL;
- }
+ if (!data) {
+ return NULL;
+ }
- data->len = strlen (data->data) + 1;
+ data->len = gf_asprintf(&data->data, "%f", value);
+ if (data->len == -1) {
+ gf_msg_debug("dict", 0, "asprintf failed");
+ data_destroy(data);
+ return NULL;
+ }
+ data->len++; /* account for terminating NULL */
+ data->data_type = GF_DATA_TYPE_DOUBLE;
- return data;
+ return data;
}
-
data_t *
-data_from_uint16 (uint16_t value)
+data_from_uint32(uint32_t value)
{
- int ret = 0;
- data_t *data = get_new_data ();
+ data_t *data = get_new_data();
- if (!data) {
- return NULL;
- }
- ret = gf_asprintf (&data->data, "%"PRIu16, value);
- if (-1 == ret) {
- return NULL;
- }
+ if (!data) {
+ return NULL;
+ }
+ data->len = gf_asprintf(&data->data, "%" PRIu32, value);
+ if (-1 == data->len) {
+ gf_msg_debug("dict", 0, "asprintf failed");
+ data_destroy(data);
+ return NULL;
+ }
- data->len = strlen (data->data) + 1;
+ data->len++; /* account for terminating NULL */
+ data->data_type = GF_DATA_TYPE_UINT;
- return data;
+ return data;
}
-
data_t *
-data_from_ptr (void *value)
+data_from_uint16(uint16_t value)
{
- if (!value) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "value is NULL");
- return NULL;
- }
+ data_t *data = get_new_data();
- data_t *data = get_new_data ();
+ if (!data) {
+ return NULL;
+ }
+ data->len = gf_asprintf(&data->data, "%" PRIu16, value);
+ if (-1 == data->len) {
+ gf_msg_debug("dict", 0, "asprintf failed");
+ data_destroy(data);
+ return NULL;
+ }
- if (!data) {
- return NULL;
- }
+ data->len++; /* account for terminating NULL */
+ data->data_type = GF_DATA_TYPE_UINT;
- data->data = value;
- return data;
+ return data;
}
-data_t *
-data_from_static_ptr (void *value)
+static data_t *
+data_from_ptr_common(void *value, gf_boolean_t is_static)
{
-/*
- this is valid to set 0 as value..
-
- if (!value) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@value=%p", value);
- return NULL;
- }
-*/
- data_t *data = get_new_data ();
+ /* it is valid to set 0/NULL as a value, no need to check *value */
- if (!data) {
- return NULL;
- }
+ data_t *data = get_new_data();
+ if (!data) {
+ return NULL;
+ }
- data->is_static = 1;
- data->data = value;
+ data->data = value;
+ data->len = 0;
+ data->is_static = is_static;
- return data;
+ data->data_type = GF_DATA_TYPE_PTR;
+ return data;
}
data_t *
-str_to_data (char *value)
+str_to_data(char *value)
{
- if (!value) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "value is NULL");
- return NULL;
- }
- data_t *data = get_new_data ();
-
- if (!data) {
- return NULL;
- }
- data->len = strlen (value) + 1;
-
- data->data = value;
- data->is_static = 1;
+ if (!value) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "value is NULL");
+ return NULL;
+ }
- return data;
+ return strn_to_data(value, strlen(value));
}
data_t *
-data_from_dynstr (char *value)
+strn_to_data(char *value, const int vallen)
{
- if (!value) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "value is NULL");
- return NULL;
- }
+ if (!value) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "value is NULL");
+ return NULL;
+ }
+ data_t *data = get_new_data();
- data_t *data = get_new_data ();
+ if (!data) {
+ return NULL;
+ }
+ data->len = vallen + 1;
+ data->data_type = GF_DATA_TYPE_STR;
- data->len = strlen (value) + 1;
- data->data = value;
+ data->data = value;
+ data->is_static = _gf_true;
- return data;
+ return data;
}
-data_t *
-data_from_dynmstr (char *value)
+static data_t *
+data_from_dynstr(char *value)
{
- if (!value) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "value is NULL");
- return NULL;
- }
+ if (!value) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "value is NULL");
+ return NULL;
+ }
- data_t *data = get_new_data ();
+ data_t *data = get_new_data();
- data->len = strlen (value) + 1;
- data->data = value;
- data->is_stdalloc = 1;
+ if (!data)
+ return NULL;
+ data->len = strlen(value) + 1;
+ data->data = value;
+ data->data_type = GF_DATA_TYPE_STR;
- return data;
+ return data;
}
data_t *
-data_from_dynptr (void *value, int32_t len)
+data_from_dynptr(void *value, int32_t len)
{
- data_t *data = get_new_data ();
+ data_t *data = get_new_data();
- if (!data)
- return NULL;
+ if (!data)
+ return NULL;
- data->len = len;
- data->data = value;
+ data->len = len;
+ data->data = value;
+ data->data_type = GF_DATA_TYPE_PTR;
- return data;
+ return data;
}
data_t *
-bin_to_data (void *value, int32_t len)
+bin_to_data(void *value, int32_t len)
{
- if (!value) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "value is NULL");
- return NULL;
- }
+ if (!value) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "value is NULL");
+ return NULL;
+ }
- data_t *data = get_new_data ();
+ data_t *data = get_new_data();
- if (!data)
- return NULL;
+ if (!data)
+ return NULL;
- data->is_static = 1;
- data->len = len;
- data->data = value;
+ data->is_static = _gf_true;
+ data->len = len;
+ data->data = value;
- return data;
+ return data;
}
-int64_t
-data_to_int64 (data_t *data)
-{
- if (!data) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "data is NULL");
- return -1;
- }
-
- char *str = alloca (data->len + 1);
- if (!str)
- return -1;
+static char *data_type_name[GF_DATA_TYPE_MAX] = {
+ [GF_DATA_TYPE_UNKNOWN] = "unknown",
+ [GF_DATA_TYPE_STR_OLD] = "string-old-version",
+ [GF_DATA_TYPE_INT] = "integer",
+ [GF_DATA_TYPE_UINT] = "unsigned integer",
+ [GF_DATA_TYPE_DOUBLE] = "float",
+ [GF_DATA_TYPE_STR] = "string",
+ [GF_DATA_TYPE_PTR] = "pointer",
+ [GF_DATA_TYPE_GFUUID] = "gf-uuid",
+ [GF_DATA_TYPE_IATT] = "iatt",
+ [GF_DATA_TYPE_MDATA] = "mdata",
+};
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
- return (int64_t) strtoull (str, NULL, 0);
-}
+int64_t
+data_to_int64(data_t *data)
+{
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, "null", -1);
+
+ char *endptr = NULL;
+ int64_t value = 0;
+
+ errno = 0;
+ value = strtoll(data->data, &endptr, 0);
+
+ if (endptr && *endptr != '\0')
+ /* Unrecognized characters at the end of string. */
+ errno = EINVAL;
+ if (errno) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, errno,
+ LG_MSG_DATA_CONVERSION_ERROR,
+ "Error in data conversion: '%s' can't "
+ "be represented as int64_t",
+ data->data);
+ return -1;
+ }
+ return value;
+}
+
+/* Like above but implies signed range check. */
+
+#define DATA_TO_RANGED_SIGNED(endptr, value, data, type, min, max) \
+ do { \
+ errno = 0; \
+ value = strtoll(data->data, &endptr, 0); \
+ if (endptr && *endptr != '\0') \
+ errno = EINVAL; \
+ if (errno || value > max || value < min) { \
+ gf_msg_callingfn("dict", GF_LOG_WARNING, errno, \
+ LG_MSG_DATA_CONVERSION_ERROR, \
+ "Error in data conversion: '%s' can't " \
+ "be represented as " #type, \
+ data->data); \
+ return -1; \
+ } \
+ return (type)value; \
+ } while (0)
int32_t
-data_to_int32 (data_t *data)
+data_to_int32(data_t *data)
{
- if (!data) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "data is NULL");
- return -1;
- }
+ char *endptr = NULL;
+ int64_t value = 0;
- char *str = alloca (data->len + 1);
- if (!str)
- return -1;
-
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
-
- return strtoul (str, NULL, 0);
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, "null", -1);
+ DATA_TO_RANGED_SIGNED(endptr, value, data, int32_t, INT_MIN, INT_MAX);
}
int16_t
-data_to_int16 (data_t *data)
+data_to_int16(data_t *data)
{
- if (!data) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "data is NULL");
- return -1;
- }
+ char *endptr = NULL;
+ int64_t value = 0;
- char *str = alloca (data->len + 1);
- if (!str)
- return -1;
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, "null", -1);
+ DATA_TO_RANGED_SIGNED(endptr, value, data, int16_t, SHRT_MIN, SHRT_MAX);
+}
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
+int8_t
+data_to_int8(data_t *data)
+{
+ char *endptr = NULL;
+ int64_t value = 0;
- return strtol (str, NULL, 0);
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, "null", -1);
+ DATA_TO_RANGED_SIGNED(endptr, value, data, int8_t, CHAR_MIN, CHAR_MAX);
}
+uint64_t
+data_to_uint64(data_t *data)
+{
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, "null", -1);
+
+ char *endptr = NULL;
+ uint64_t value = 0;
+
+ errno = 0;
+ value = strtoull(data->data, &endptr, 0);
+
+ if (endptr && *endptr != '\0')
+ errno = EINVAL;
+ if (errno) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, errno,
+ LG_MSG_DATA_CONVERSION_ERROR,
+ "Error in data conversion: '%s' can't "
+ "be represented as uint64_t",
+ data->data);
+ return -1;
+ }
+ return value;
+}
+
+/* Like above but implies unsigned range check. */
+
+#define DATA_TO_RANGED_UNSIGNED(endptr, value, data, type, max) \
+ do { \
+ errno = 0; \
+ value = strtoull(data->data, &endptr, 0); \
+ if (endptr && *endptr != '\0') \
+ errno = EINVAL; \
+ if (errno || value > max) { \
+ gf_msg_callingfn("dict", GF_LOG_WARNING, errno, \
+ LG_MSG_DATA_CONVERSION_ERROR, \
+ "Error in data conversion: '%s' can't " \
+ "be represented as " #type, \
+ data->data); \
+ return -1; \
+ } \
+ return (type)value; \
+ } while (0)
-int8_t
-data_to_int8 (data_t *data)
+uint32_t
+data_to_uint32(data_t *data)
{
- if (!data) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "data is NULL");
- return -1;
- }
+ char *endptr = NULL;
+ uint64_t value = 0;
- char *str = alloca (data->len + 1);
- if (!str)
- return -1;
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, "null", -1);
+ DATA_TO_RANGED_UNSIGNED(endptr, value, data, uint32_t, UINT_MAX);
+}
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
+uint16_t
+data_to_uint16(data_t *data)
+{
+ char *endptr = NULL;
+ uint64_t value = 0;
- return (int8_t)strtol (str, NULL, 0);
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, "null", -1);
+ DATA_TO_RANGED_UNSIGNED(endptr, value, data, uint16_t, USHRT_MAX);
}
-
-uint64_t
-data_to_uint64 (data_t *data)
+uint8_t
+data_to_uint8(data_t *data)
{
- if (!data)
- return -1;
- char *str = alloca (data->len + 1);
- if (!str)
- return -1;
+ char *endptr = NULL;
+ uint64_t value = 0;
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, "null", -1);
+ DATA_TO_RANGED_UNSIGNED(endptr, value, data, uint8_t, UCHAR_MAX);
+}
- return strtoll (str, NULL, 0);
+char *
+data_to_str(data_t *data)
+{
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_STR, "null", NULL);
+ return data->data;
}
-uint32_t
-data_to_uint32 (data_t *data)
+void *
+data_to_ptr(data_t *data)
{
- if (!data)
- return -1;
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_PTR, "null", NULL);
+ return data->data;
+}
- char *str = alloca (data->len + 1);
- if (!str)
- return -1;
+void *
+data_to_bin(data_t *data)
+{
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_PTR, "null", NULL);
+ return data->data;
+}
+
+struct iatt *
+data_to_iatt(data_t *data, char *key)
+{
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_IATT, key, NULL);
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
+ /* We only check for smaller size. If it's bigger we simply ignore
+ * the extra data. This way it's easy to do changes in the future that
+ * pass more data but are backward compatible (if the initial contents
+ * of the struct are maintained, of course). */
+ if (data->len < sizeof(struct iatt)) {
+ gf_smsg("glusterfs", GF_LOG_ERROR, ENOBUFS, LG_MSG_UNDERSIZED_BUF,
+ "key=%s", key, NULL);
+ return NULL;
+ }
- return strtol (str, NULL, 0);
+ return (struct iatt *)data->data;
}
-uint16_t
-data_to_uint16 (data_t *data)
+int
+dict_null_foreach_fn(dict_t *d, char *k, data_t *v, void *tmp)
{
- if (!data)
- return -1;
-
- char *str = alloca (data->len + 1);
- if (!str)
- return -1;
+ return 0;
+}
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
+int
+dict_remove_foreach_fn(dict_t *d, char *k, data_t *v, void *_tmp)
+{
+ if (!d || !k) {
+ gf_smsg("glusterfs", GF_LOG_WARNING, EINVAL, LG_MSG_KEY_OR_VALUE_NULL,
+ "d=%s", d ? "key" : "dictionary", NULL);
+ return -1;
+ }
- return strtol (str, NULL, 0);
+ dict_del(d, k);
+ return 0;
}
-char *
-data_to_str (data_t *data)
+gf_boolean_t
+dict_match_everything(dict_t *d, char *k, data_t *v, void *data)
{
- if (!data) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "data is NULL");
- return NULL;
- }
- return data->data;
+ return _gf_true;
}
-void *
-data_to_ptr (data_t *data)
+int
+dict_foreach(dict_t *dict,
+ int (*fn)(dict_t *this, char *key, data_t *value, void *data),
+ void *data)
{
- if (!data) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "data is NULL");
- return NULL;
- }
- return data->data;
+ int ret = dict_foreach_match(dict, dict_match_everything, NULL, fn, data);
+
+ if (ret > 0)
+ ret = 0;
+
+ return ret;
}
-void *
-data_to_bin (data_t *data)
+/* return values:
+ -1 = failure,
+ 0 = no matches found,
+ +n = n number of matches
+*/
+int
+dict_foreach_match(dict_t *dict,
+ gf_boolean_t (*match)(dict_t *this, char *key, data_t *value,
+ void *mdata),
+ void *match_data,
+ int (*action)(dict_t *this, char *key, data_t *value,
+ void *adata),
+ void *action_data)
+{
+ if (!dict || !match || !action) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "dict|match|action is "
+ "NULL");
+ return -1;
+ }
+
+ int ret = -1;
+ int count = 0;
+ data_pair_t *pairs = dict->members_list;
+ data_pair_t *next = NULL;
+
+ while (pairs) {
+ next = pairs->next;
+ if (match(dict, pairs->key, pairs->value, match_data)) {
+ ret = action(dict, pairs->key, pairs->value, action_data);
+ if (ret < 0)
+ return ret;
+ count++;
+ }
+ pairs = next;
+ }
+
+ return count;
+}
+
+static gf_boolean_t
+dict_fnmatch(dict_t *d, char *k, data_t *val, void *match_data)
+{
+ return (fnmatch(match_data, k, 0) == 0);
+}
+/* return values:
+ -1 = failure,
+ 0 = no matches found,
+ +n = n number of matches
+*/
+int
+dict_foreach_fnmatch(dict_t *dict, char *pattern,
+ int (*fn)(dict_t *this, char *key, data_t *value,
+ void *data),
+ void *data)
{
- if (!data) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "data is NULL");
- return NULL;
- }
- return data->data;
+ return dict_foreach_match(dict, dict_fnmatch, pattern, fn, data);
}
-void
-dict_foreach (dict_t *dict,
- void (*fn)(dict_t *this,
- char *key,
- data_t *value,
- void *data),
- void *data)
-{
- if (!dict) {
- gf_log_callingfn ("dict", GF_LOG_WARNING,
- "dict is NULL");
- return;
- }
+/**
+ * dict_keys_join - pack the keys of the dictionary in a buffer.
+ *
+ * @value : buffer in which the keys will be packed (can be NULL)
+ * @size : size of the buffer which is sent (can be 0, in which case buffer
+ * is not packed but only length is returned)
+ * @dict : dictionary of which all the keys will be packed
+ * @filter_fn : keys matched in filter_fn() is counted.
+ *
+ * @return : @length of string after joining keys.
+ *
+ */
+
+int
+dict_keys_join(void *value, int size, dict_t *dict, int (*filter_fn)(char *k))
+{
+ int len = 0;
+ data_pair_t *pairs = dict->members_list;
+ data_pair_t *next = NULL;
- data_pair_t *pairs = dict->members_list;
- data_pair_t *next = NULL;
+ while (pairs) {
+ next = pairs->next;
- while (pairs) {
- next = pairs->next;
- fn (dict, pairs->key, pairs->value, data);
- pairs = next;
+ if (filter_fn && filter_fn(pairs->key)) {
+ pairs = next;
+ continue;
}
-}
+ if (value && (size > len))
+ strncpy(value + len, pairs->key, size - len);
-static void
-_copy (dict_t *unused,
- char *key,
- data_t *value,
- void *newdict)
-{
- dict_set ((dict_t *)newdict, key, (value));
+ len += (strlen(pairs->key) + 1);
+
+ pairs = next;
+ }
+
+ return len;
}
+static int
+dict_copy_one(dict_t *unused, char *key, data_t *value, void *newdict)
+{
+ return dict_set((dict_t *)newdict, key, (value));
+}
dict_t *
-dict_copy (dict_t *dict,
- dict_t *new)
+dict_copy(dict_t *dict, dict_t *new)
{
- if (!dict) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is NULL");
- return NULL;
- }
+ if (!dict) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "dict is NULL");
+ return NULL;
+ }
- if (!new)
- new = get_new_dict_full (dict->hash_size);
+ if (!new)
+ new = get_new_dict_full(dict->hash_size);
- dict_foreach (dict, _copy, new);
+ dict_foreach(dict, dict_copy_one, new);
- return new;
+ return new;
+}
+
+int
+dict_reset(dict_t *dict)
+{
+ int32_t ret = -1;
+ if (!dict) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "dict is NULL");
+ goto out;
+ }
+ dict_foreach(dict, dict_remove_foreach_fn, NULL);
+ ret = 0;
+out:
+ return ret;
}
dict_t *
-dict_copy_with_ref (dict_t *dict,
- dict_t *new)
+dict_copy_with_ref(dict_t *dict, dict_t *new)
{
- dict_t *local_new = NULL;
+ dict_t *local_new = NULL;
- GF_VALIDATE_OR_GOTO("dict", dict, fail);
+ GF_VALIDATE_OR_GOTO("dict", dict, fail);
- if (new == NULL) {
- local_new = dict_new ();
- GF_VALIDATE_OR_GOTO("dict", local_new, fail);
- new = local_new;
- }
+ if (new == NULL) {
+ local_new = dict_new();
+ GF_VALIDATE_OR_GOTO("dict", local_new, fail);
+ new = local_new;
+ }
- dict_foreach (dict, _copy, new);
+ dict_foreach(dict, dict_copy_one, new);
fail:
- return new;
+ return new;
}
/*
@@ -1258,870 +1495,1292 @@ fail:
* -val error, val = errno
*/
-
static int
-dict_get_with_ref (dict_t *this, char *key, data_t **data)
+dict_get_with_refn(dict_t *this, char *key, const int keylen, data_t **data)
{
- data_pair_t * pair = NULL;
- int ret = -ENOENT;
+ data_pair_t *pair = NULL;
+ int ret = -ENOENT;
+ uint32_t hash;
- if (!this || !key || !data) {
- gf_log_callingfn ("dict", GF_LOG_WARNING,
- "dict OR key (%s) is NULL", key);
- ret = -EINVAL;
- goto err;
- }
+ hash = (uint32_t)XXH64(key, keylen, 0);
- LOCK (&this->lock);
- {
- pair = _dict_lookup (this, key);
- }
- UNLOCK (&this->lock);
+ LOCK(&this->lock);
+ {
+ pair = dict_lookup_common(this, key, hash);
if (pair) {
- ret = 0;
- *data = data_ref (pair->value);
+ ret = 0;
+ *data = data_ref(pair->value);
}
+ }
+ UNLOCK(&this->lock);
-err:
- return ret;
+ return ret;
+}
+
+int
+dict_get_with_ref(dict_t *this, char *key, data_t **data)
+{
+ if (!this || !key || !data) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "dict OR key (%s) is NULL", key);
+ return -EINVAL;
+ }
+
+ return dict_get_with_refn(this, key, strlen(key), data);
}
static int
-_data_to_ptr (data_t *data, void **val)
+data_to_ptr_common(data_t *data, void **val)
{
- int ret = 0;
+ int ret = 0;
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- *val = data->data;
+ *val = data->data;
err:
- return ret;
+ return ret;
}
-
static int
-_data_to_int8 (data_t *data, int8_t *val)
+data_to_int8_ptr(data_t *data, int8_t *val)
{
- int ret = 0;
- char * str = NULL;
-
- if (!data || !val) {
- ret = -EINVAL;
- goto err;
- }
+ int ret = 0;
- str = alloca (data->len + 1);
- if (!str) {
- ret = -ENOMEM;
- goto err;
- }
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
+ if (!data || !val) {
+ ret = -EINVAL;
+ goto err;
+ }
- errno = 0;
- *val = strtol (str, NULL, 0);
- if (errno != 0)
- ret = -errno;
+ errno = 0;
+ *val = strtol(data->data, NULL, 0);
+ if (errno != 0)
+ ret = -errno;
err:
- return ret;
+ return ret;
}
static int
-_data_to_int16 (data_t *data, int16_t *val)
+data_to_int16_ptr(data_t *data, int16_t *val)
{
- int ret = 0;
- char * str = NULL;
+ int ret = 0;
- if (!data || !val) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data || !val) {
+ ret = -EINVAL;
+ goto err;
+ }
- str = alloca (data->len + 1);
- if (!str) {
- ret = -ENOMEM;
- goto err;
- }
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
-
- errno = 0;
- *val = strtol (str, NULL, 0);
- if (errno != 0)
- ret = -errno;
+ errno = 0;
+ *val = strtol(data->data, NULL, 0);
+ if (errno != 0)
+ ret = -errno;
err:
- return ret;
+ return ret;
}
static int
-_data_to_int32 (data_t *data, int32_t *val)
+data_to_int32_ptr(data_t *data, int32_t *val)
{
- int ret = 0;
- char * str = NULL;
+ int ret = 0;
- if (!data || !val) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data || !val) {
+ ret = -EINVAL;
+ goto err;
+ }
- str = alloca (data->len + 1);
- if (!str) {
- ret = -ENOMEM;
- goto err;
- }
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
-
- errno = 0;
- *val = strtol (str, NULL, 0);
- if (errno != 0)
- ret = -errno;
+ errno = 0;
+ *val = strtol(data->data, NULL, 0);
+ if (errno != 0)
+ ret = -errno;
err:
- return ret;
+ return ret;
}
static int
-_data_to_int64 (data_t *data, int64_t *val)
+data_to_int64_ptr(data_t *data, int64_t *val)
{
- int ret = 0;
- char * str = NULL;
+ int ret = 0;
- if (!data || !val) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data || !val) {
+ ret = -EINVAL;
+ goto err;
+ }
- str = alloca (data->len + 1);
- if (!str) {
- ret = -ENOMEM;
- goto err;
- }
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
-
- errno = 0;
- *val = strtoll (str, NULL, 0);
- if (errno != 0)
- ret = -errno;
+ errno = 0;
+ *val = strtoll(data->data, NULL, 0);
+ if (errno != 0)
+ ret = -errno;
err:
- return ret;
+ return ret;
}
static int
-_data_to_uint16 (data_t *data, uint16_t *val)
+data_to_uint16_ptr(data_t *data, uint16_t *val)
{
- int ret = 0;
- char * str = NULL;
-
- if (!data || !val) {
- ret = -EINVAL;
- goto err;
- }
+ int ret = 0;
- str = alloca (data->len + 1);
- if (!str) {
- ret = -ENOMEM;
- goto err;
- }
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
+ if (!data || !val) {
+ ret = -EINVAL;
+ goto err;
+ }
- errno = 0;
- *val = strtoul (str, NULL, 0);
- if (errno != 0)
- ret = -errno;
+ errno = 0;
+ *val = strtoul(data->data, NULL, 0);
+ if (errno != 0)
+ ret = -errno;
err:
- return ret;
+ return ret;
}
static int
-_data_to_uint32 (data_t *data, uint32_t *val)
+data_to_uint32_ptr(data_t *data, uint32_t *val)
{
- int ret = 0;
- char * str = NULL;
+ int ret = 0;
- if (!data || !val) {
- ret = -EINVAL;
- goto err;
- }
-
- str = alloca (data->len + 1);
- if (!str) {
- ret = -ENOMEM;
- goto err;
- }
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
+ if (!data || !val) {
+ ret = -EINVAL;
+ goto err;
+ }
- errno = 0;
- *val = strtoul (str, NULL, 0);
- if (errno != 0)
- ret = -errno;
+ errno = 0;
+ *val = strtoul(data->data, NULL, 0);
+ if (errno != 0)
+ ret = -errno;
err:
- return ret;
+ return ret;
}
static int
-_data_to_uint64 (data_t *data, uint64_t *val)
+data_to_uint64_ptr(data_t *data, uint64_t *val)
{
- int ret = 0;
- char * str = NULL;
+ int ret = 0;
- if (!data || !val) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data || !val) {
+ ret = -EINVAL;
+ goto err;
+ }
- str = alloca (data->len + 1);
- if (!str) {
- ret = -ENOMEM;
- goto err;
- }
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
-
- errno = 0;
- *val = strtoull (str, NULL, 0);
- if (errno != 0)
- ret = -errno;
+ errno = 0;
+ *val = strtoull(data->data, NULL, 0);
+ if (errno != 0)
+ ret = -errno;
err:
- return ret;
+ return ret;
}
static int
-_data_to_double (data_t *data, double *val)
+data_to_double_ptr(data_t *data, double *val)
{
- int ret = 0;
- char * str = NULL;
+ int ret = 0;
- if (!data || !val) {
- ret = -EINVAL;
- goto err;
- }
-
- str = alloca (data->len + 1);
- if (!str) {
- ret = -ENOMEM;
- goto err;
- }
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
+ if (!data || !val) {
+ ret = -EINVAL;
+ goto err;
+ }
- errno = 0;
- *val = strtod (str, NULL);
- if (errno != 0)
- ret = -errno;
+ errno = 0;
+ *val = strtod(data->data, NULL);
+ if (errno != 0)
+ ret = -errno;
err:
- return ret;
+ return ret;
}
int
-dict_get_int8 (dict_t *this, char *key, int8_t *val)
+dict_get_int8(dict_t *this, char *key, int8_t *val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = 0;
- if (!this || !key || !val) {
- ret = -EINVAL;
- goto err;
- }
+ if (!val) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_get_with_ref (this, key, &data);
- if (ret != 0) {
- goto err;
- }
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret != 0) {
+ goto err;
+ }
+
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, key, -EINVAL);
- ret = _data_to_int8 (data, val);
+ ret = data_to_int8_ptr(data, val);
err:
- if (data)
- data_unref (data);
- return ret;
+ if (data)
+ data_unref(data);
+ return ret;
}
-
int
-dict_set_int8 (dict_t *this, char *key, int8_t val)
+dict_set_int8(dict_t *this, char *key, int8_t val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = 0;
- data = data_from_int8 (val);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ data = data_from_int8(val);
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
+ ret = dict_set(this, key, data);
+ if (ret < 0)
+ data_destroy(data);
err:
- return ret;
+ return ret;
}
int
-dict_get_int16 (dict_t *this, char *key, int16_t *val)
+dict_get_int16(dict_t *this, char *key, int16_t *val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = 0;
- if (!this || !key || !val) {
- ret = -EINVAL;
- goto err;
- }
+ if (!val) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_get_with_ref (this, key, &data);
- if (ret != 0) {
- goto err;
- }
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret != 0) {
+ goto err;
+ }
- ret = _data_to_int16 (data, val);
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, key, -EINVAL);
+
+ ret = data_to_int16_ptr(data, val);
err:
- if (data)
- data_unref (data);
- return ret;
+ if (data)
+ data_unref(data);
+ return ret;
}
+int
+dict_set_int16(dict_t *this, char *key, int16_t val)
+{
+ data_t *data = NULL;
+ int ret = 0;
+
+ data = data_from_int16(val);
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ ret = dict_set(this, key, data);
+ if (ret < 0)
+ data_destroy(data);
+
+err:
+ return ret;
+}
int
-dict_set_int16 (dict_t *this, char *key, int16_t val)
+dict_get_int32n(dict_t *this, char *key, const int keylen, int32_t *val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = 0;
- data = data_from_int16 (val);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ if (!this || !key || !val) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ ret = dict_get_with_refn(this, key, keylen, &data);
+ if (ret != 0) {
+ goto err;
+ }
- ret = dict_set (this, key, data);
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, key, -EINVAL);
+
+ ret = data_to_int32_ptr(data, val);
err:
- return ret;
+ if (data)
+ data_unref(data);
+ return ret;
}
int
-dict_get_int32 (dict_t *this, char *key, int32_t *val)
+dict_get_int32(dict_t *this, char *key, int32_t *val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = 0;
- if (!this || !key || !val) {
- ret = -EINVAL;
- goto err;
- }
+ if (!val) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_get_with_ref (this, key, &data);
- if (ret != 0) {
- goto err;
- }
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret != 0) {
+ goto err;
+ }
+
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, key, -EINVAL);
- ret = _data_to_int32 (data, val);
+ ret = data_to_int32_ptr(data, val);
err:
- if (data)
- data_unref (data);
- return ret;
+ if (data)
+ data_unref(data);
+ return ret;
}
+int
+dict_set_int32n(dict_t *this, char *key, const int keylen, int32_t val)
+{
+ data_t *data = NULL;
+ int ret = 0;
+
+ data = data_from_int32(val);
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ ret = dict_setn(this, key, keylen, data);
+ if (ret < 0)
+ data_destroy(data);
+
+err:
+ return ret;
+}
int
-dict_set_int32 (dict_t *this, char *key, int32_t val)
+dict_set_int32(dict_t *this, char *key, int32_t val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = data_from_int32(val);
+ int ret = 0;
- data = data_from_int32 (val);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
+ ret = dict_set(this, key, data);
+ if (ret < 0)
+ data_destroy(data);
err:
- return ret;
+ return ret;
}
int
-dict_get_int64 (dict_t *this, char *key, int64_t *val)
+dict_get_int64(dict_t *this, char *key, int64_t *val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = 0;
- if (!this || !key || !val) {
- ret = -EINVAL;
- goto err;
- }
+ if (!val) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_get_with_ref (this, key, &data);
- if (ret != 0) {
- goto err;
- }
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret != 0) {
+ goto err;
+ }
+
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, key, -EINVAL);
- ret = _data_to_int64 (data, val);
+ ret = data_to_int64_ptr(data, val);
err:
- if (data)
- data_unref (data);
- return ret;
+ if (data)
+ data_unref(data);
+ return ret;
}
-
int
-dict_set_int64 (dict_t *this, char *key, int64_t val)
+dict_set_int64(dict_t *this, char *key, int64_t val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = data_from_int64(val);
+ int ret = 0;
- data = data_from_int64 (val);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
+ ret = dict_set(this, key, data);
+ if (ret < 0)
+ data_destroy(data);
err:
- return ret;
+ return ret;
}
int
-dict_get_uint16 (dict_t *this, char *key, uint16_t *val)
+dict_get_uint16(dict_t *this, char *key, uint16_t *val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = 0;
- if (!this || !key || !val) {
- ret = -EINVAL;
- goto err;
- }
+ if (!val) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_get_with_ref (this, key, &data);
- if (ret != 0) {
- goto err;
- }
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret != 0) {
+ goto err;
+ }
+
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, key, -EINVAL);
- ret = _data_to_uint16 (data, val);
+ ret = data_to_uint16_ptr(data, val);
err:
- if (data)
- data_unref (data);
- return ret;
+ if (data)
+ data_unref(data);
+ return ret;
}
-
int
-dict_set_uint16 (dict_t *this, char *key, uint16_t val)
+dict_set_uint16(dict_t *this, char *key, uint16_t val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = data_from_uint16(val);
+ int ret = 0;
- data = data_from_uint16 (val);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
+ ret = dict_set(this, key, data);
+ if (ret < 0)
+ data_destroy(data);
err:
- return ret;
+ return ret;
}
int
-dict_get_uint32 (dict_t *this, char *key, uint32_t *val)
+dict_get_uint32(dict_t *this, char *key, uint32_t *val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = 0;
- if (!this || !key || !val) {
- ret = -EINVAL;
- goto err;
- }
+ if (!val) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_get_with_ref (this, key, &data);
- if (ret != 0) {
- goto err;
- }
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret != 0) {
+ goto err;
+ }
+
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, key, -EINVAL);
- ret = _data_to_uint32 (data, val);
+ ret = data_to_uint32_ptr(data, val);
err:
- if (data)
- data_unref (data);
- return ret;
+ if (data)
+ data_unref(data);
+ return ret;
}
+int
+dict_set_uint32(dict_t *this, char *key, uint32_t val)
+{
+ data_t *data = data_from_uint32(val);
+ int ret = 0;
+
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ ret = dict_set(this, key, data);
+ if (ret < 0)
+ data_destroy(data);
+err:
+ return ret;
+}
int
-dict_set_uint32 (dict_t *this, char *key, uint32_t val)
+dict_get_uint64(dict_t *this, char *key, uint64_t *val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = 0;
- data = data_from_uint32 (val);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ if (!val) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret != 0) {
+ goto err;
+ }
- ret = dict_set (this, key, data);
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, key, -EINVAL);
+
+ ret = data_to_uint64_ptr(data, val);
err:
- return ret;
+ if (data)
+ data_unref(data);
+ return ret;
}
int
-dict_get_uint64 (dict_t *this, char *key, uint64_t *val)
+dict_set_uint64(dict_t *this, char *key, uint64_t val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = data_from_uint64(val);
+ int ret = 0;
+
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ ret = dict_set(this, key, data);
+ if (ret < 0)
+ data_destroy(data);
+
+err:
+ return ret;
+}
- if (!this || !key || !val) {
- ret = -EINVAL;
+/*
+ * dict_check_flag can be used to check a one bit flag in an array of flags
+ * The flag argument indicates the bit position (within the array of bits).
+ * Currently limited to max of 256 flags for a key.
+ * return value,
+ * 1 : flag is set
+ * 0 : flag is not set
+ * <0: Error
+ */
+int
+dict_check_flag(dict_t *this, char *key, int flag)
+{
+ data_t *data = NULL;
+ int ret = -ENOENT;
+
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret < 0) {
+ return ret;
+ }
+
+ if (BIT_VALUE((unsigned char *)(data->data), flag))
+ ret = 1;
+ else
+ ret = 0;
+
+ data_unref(data);
+ return ret;
+}
+
+/*
+ * _dict_modify_flag can be used to set/clear a bit flag in an array of flags
+ * flag: indicates the bit position. limited to max of DICT_MAX_FLAGS.
+ * op: Indicates operation DICT_FLAG_SET / DICT_FLAG_CLEAR
+ */
+static int
+_dict_modify_flag(dict_t *this, char *key, int flag, int op)
+{
+ data_t *data = NULL;
+ int ret = 0;
+ data_pair_t *pair = NULL;
+ char *ptr = NULL;
+ int hashval = 0;
+ uint32_t hash;
+
+ if (!this || !key) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "dict OR key (%s) is NULL", key);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ /*
+ * Using a size of 32 bytes to support max of 256
+ * flags in a single key. This should be suffcient.
+ */
+ GF_ASSERT(flag >= 0 && flag < DICT_MAX_FLAGS);
+
+ hash = (uint32_t)XXH64(key, strlen(key), 0);
+ LOCK(&this->lock);
+ {
+ pair = dict_lookup_common(this, key, hash);
+
+ if (pair) {
+ data = pair->value;
+ if (op == DICT_FLAG_SET)
+ BIT_SET((unsigned char *)(data->data), flag);
+ else
+ BIT_CLEAR((unsigned char *)(data->data), flag);
+ } else {
+ ptr = GF_CALLOC(1, DICT_MAX_FLAGS / 8, gf_common_mt_char);
+ if (!ptr) {
+ gf_smsg("dict", GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY,
+ "flag bit array", NULL);
+ ret = -ENOMEM;
goto err;
- }
+ }
+
+ data = data_from_dynptr(ptr, DICT_MAX_FLAGS / 8);
- ret = dict_get_with_ref (this, key, &data);
- if (ret != 0) {
+ if (!data) {
+ gf_smsg("dict", GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY, "data",
+ NULL);
+ GF_FREE(ptr);
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ if (op == DICT_FLAG_SET)
+ BIT_SET((unsigned char *)(data->data), flag);
+ else
+ BIT_CLEAR((unsigned char *)(data->data), flag);
+
+ if (this->free_pair.key) { /* the free pair is in use */
+ pair = mem_get0(THIS->ctx->dict_pair_pool);
+ if (!pair) {
+ gf_smsg("dict", GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY,
+ "dict pair", NULL);
+ ret = -ENOMEM;
+ goto err;
+ }
+ } else { /* use the free pair */
+ pair = &this->free_pair;
+ }
+
+ pair->key = (char *)GF_MALLOC(strlen(key) + 1, gf_common_mt_char);
+ if (!pair->key) {
+ gf_smsg("dict", GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY,
+ "dict pair", NULL);
+ ret = -ENOMEM;
goto err;
+ }
+ strcpy(pair->key, key);
+ pair->key_hash = hash;
+ pair->value = data_ref(data);
+ this->totkvlen += (strlen(key) + 1 + data->len);
+ hashval = hash % this->hash_size;
+ pair->hash_next = this->members[hashval];
+ this->members[hashval] = pair;
+
+ pair->next = this->members_list;
+ pair->prev = NULL;
+ if (this->members_list)
+ this->members_list->prev = pair;
+ this->members_list = pair;
+ this->count++;
+
+ if (this->max_count < this->count)
+ this->max_count = this->count;
}
+ }
- ret = _data_to_uint64 (data, val);
+ UNLOCK(&this->lock);
+ return 0;
err:
- if (data)
- data_unref (data);
- return ret;
+ if (key && this)
+ UNLOCK(&this->lock);
+
+ if (pair) {
+ if (pair->key) {
+ GF_FREE(pair->key);
+ pair->key = NULL;
+ }
+ if (pair != &this->free_pair) {
+ mem_put(pair);
+ }
+ }
+
+ if (data)
+ data_destroy(data);
+
+ gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_DICT_SET_FAILED, "key=%s", key,
+ NULL);
+
+ return ret;
}
+/*
+ * Todo:
+ * Add below primitives as needed:
+ * dict_check_flags(this, key, flag...): variadic function to check
+ * multiple flags at a time.
+ * dict_set_flags(this, key, flag...): set multiple flags
+ * dict_clear_flags(this, key, flag...): reset multiple flags
+ */
int
-dict_set_uint64 (dict_t *this, char *key, uint64_t val)
+dict_set_flag(dict_t *this, char *key, int flag)
{
- data_t * data = NULL;
- int ret = 0;
+ return _dict_modify_flag(this, key, flag, DICT_FLAG_SET);
+}
- data = data_from_uint64 (val);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+int
+dict_clear_flag(dict_t *this, char *key, int flag)
+{
+ return _dict_modify_flag(this, key, flag, DICT_FLAG_CLEAR);
+}
+
+int
+dict_get_double(dict_t *this, char *key, double *val)
+{
+ data_t *data = NULL;
+ int ret = 0;
- ret = dict_set (this, key, data);
+ if (!val) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret != 0) {
+ goto err;
+ }
+
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_DOUBLE, key, -EINVAL);
+
+ ret = data_to_double_ptr(data, val);
err:
- return ret;
+ if (data)
+ data_unref(data);
+ return ret;
}
int
-dict_get_double (dict_t *this, char *key, double *val)
+dict_set_double(dict_t *this, char *key, double val)
{
- data_t *data = NULL;
- int ret = 0;
+ data_t *data = data_from_double(val);
+ int ret = 0;
- if (!this || !key || !val) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_get_with_ref (this, key, &data);
- if (ret != 0) {
- goto err;
- }
-
- ret = _data_to_double (data, val);
+ ret = dict_set(this, key, data);
+ if (ret < 0)
+ data_destroy(data);
err:
- if (data)
- data_unref (data);
- return ret;
+ return ret;
}
int
-dict_set_double (dict_t *this, char *key, double val)
+dict_set_static_ptr(dict_t *this, char *key, void *ptr)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = data_from_ptr_common(ptr, _gf_true);
+ int ret = 0;
- data = data_from_double (val);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
+ ret = dict_set(this, key, data);
+ if (ret < 0)
+ data_destroy(data);
err:
- return ret;
+ return ret;
}
int
-dict_set_static_ptr (dict_t *this, char *key, void *ptr)
+dict_set_dynptr(dict_t *this, char *key, void *ptr, size_t len)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = data_from_dynptr(ptr, len);
+ int ret = 0;
- data = data_from_static_ptr (ptr);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
+ ret = dict_set(this, key, data);
+ if (ret < 0)
+ data_destroy(data);
err:
- return ret;
+ return ret;
}
int
-dict_set_dynptr (dict_t *this, char *key, void *ptr, size_t len)
+dict_get_ptr(dict_t *this, char *key, void **ptr)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = 0;
- data = data_from_dynptr (ptr, len);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ if (!ptr) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret != 0) {
+ goto err;
+ }
+
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_PTR, key, -EINVAL);
- ret = dict_set (this, key, data);
+ ret = data_to_ptr_common(data, ptr);
+ if (ret != 0) {
+ goto err;
+ }
err:
- return ret;
+ if (data)
+ data_unref(data);
+
+ return ret;
}
int
-dict_get_ptr (dict_t *this, char *key, void **ptr)
+dict_get_ptr_and_len(dict_t *this, char *key, void **ptr, int *len)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = 0;
- if (!this || !key || !ptr) {
- ret = -EINVAL;
- goto err;
- }
+ if (!ptr) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_get_with_ref (this, key, &data);
- if (ret != 0) {
- goto err;
- }
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret != 0) {
+ goto err;
+ }
- ret = _data_to_ptr (data, ptr);
- if (ret != 0) {
- goto err;
- }
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_PTR, key, -EINVAL);
+
+ *len = data->len;
+
+ ret = data_to_ptr_common(data, ptr);
+ if (ret != 0) {
+ goto err;
+ }
err:
- if (data)
- data_unref (data);
+ if (data)
+ data_unref(data);
- return ret;
+ return ret;
}
+/* Get string - with known key length */
int
-dict_set_ptr (dict_t *this, char *key, void *ptr)
+dict_get_strn(dict_t *this, char *key, const int keylen, char **str)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = -EINVAL;
- data = data_from_ptr (ptr);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ if (!this || !key || !str) {
+ goto err;
+ }
+ ret = dict_get_with_refn(this, key, keylen, &data);
+ if (ret < 0) {
+ goto err;
+ }
- ret = dict_set (this, key, data);
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_STR, key, -EINVAL);
+
+ *str = data->data;
err:
- return ret;
-}
+ if (data)
+ data_unref(data);
+ return ret;
+}
int
-dict_get_str (dict_t *this, char *key, char **str)
+dict_get_str(dict_t *this, char *key, char **str)
{
- data_t * data = NULL;
- int ret = -EINVAL;
+ data_t *data = NULL;
+ int ret = -EINVAL;
- if (!this || !key || !str) {
- goto err;
- }
+ if (!str) {
+ goto err;
+ }
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret < 0) {
+ goto err;
+ }
- ret = dict_get_with_ref (this, key, &data);
- if (ret < 0) {
- goto err;
- }
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_STR, key, -EINVAL);
- if (!data || !data->data) {
- goto err;
- }
- *str = data->data;
+ *str = data->data;
err:
- if (data)
- data_unref (data);
+ if (data)
+ data_unref(data);
- return ret;
+ return ret;
}
int
-dict_set_str (dict_t *this, char *key, char *str)
+dict_set_str(dict_t *this, char *key, char *str)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = str_to_data(str);
+ int ret = 0;
- data = str_to_data (str);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
+ ret = dict_set(this, key, data);
+ if (ret < 0)
+ data_destroy(data);
err:
- return ret;
+ return ret;
}
+/* Set string - with known key length */
int
-dict_set_dynstr (dict_t *this, char *key, char *str)
+dict_set_strn(dict_t *this, char *key, const int keylen, char *str)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = 0;
- data = data_from_dynstr (str);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ data = str_to_data(str);
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
+ ret = dict_setn(this, key, keylen, data);
+ if (ret < 0)
+ data_destroy(data);
err:
- return ret;
+ return ret;
}
-/*
- for malloced strings we should do a free instead of GF_FREE
-*/
+/* Set string - with known key length and known value length */
int
-dict_set_dynmstr (dict_t *this, char *key, char *str)
+dict_set_nstrn(dict_t *this, char *key, const int keylen, char *str,
+ const int vallen)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = strn_to_data(str, vallen);
+ int ret = 0;
- data = data_from_dynmstr (str);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
+ ret = dict_setn(this, key, keylen, data);
+ if (ret < 0)
+ data_destroy(data);
err:
- return ret;
+ return ret;
}
+int
+dict_set_dynstr_with_alloc(dict_t *this, char *key, const char *str)
+{
+ char *alloc_str = gf_strdup(str);
+ int ret = -1;
+
+ if (!alloc_str)
+ return ret;
+
+ ret = dict_set_dynstr(this, key, alloc_str);
+ if (ret == -EINVAL)
+ GF_FREE(alloc_str);
+
+ return ret;
+}
int
-dict_get_bin (dict_t *this, char *key, void **bin)
+dict_set_dynstr(dict_t *this, char *key, char *str)
{
- data_t * data = NULL;
- int ret = -EINVAL;
+ const int keylen = strlen(key);
+ return dict_set_dynstrn(this, key, keylen, str);
+}
- if (!this || !key || !bin) {
- goto err;
- }
+int
+dict_set_dynstrn(dict_t *this, char *key, const int keylen, char *str)
+{
+ data_t *data = data_from_dynstr(str);
+ int ret = 0;
- ret = dict_get_with_ref (this, key, &data);
- if (ret < 0) {
- goto err;
- }
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- if (!data || !data->data) {
- goto err;
- }
- *bin = data->data;
+ ret = dict_setn(this, key, keylen, data);
+ if (ret < 0)
+ data_destroy(data);
err:
- if (data)
- data_unref (data);
+ return ret;
+}
- return ret;
+/* This function is called only by the volgen for now.
+ Check how else you can handle it */
+int
+dict_set_option(dict_t *this, char *key, char *str)
+{
+ data_t *data = data_from_dynstr(str);
+ int ret = 0;
+
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ data->data_type = GF_DATA_TYPE_STR_OLD;
+ ret = dict_set(this, key, data);
+ if (ret < 0)
+ data_destroy(data);
+err:
+ return ret;
}
+int
+dict_add_dynstr_with_alloc(dict_t *this, char *key, char *str)
+{
+ data_t *data = NULL;
+ int ret = 0;
+ char *alloc_str = gf_strdup(str);
+
+ if (!alloc_str)
+ goto out;
+
+ data = data_from_dynstr(alloc_str);
+ if (!data) {
+ GF_FREE(alloc_str);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = dict_add(this, key, data);
+ if (ret < 0)
+ data_destroy(data);
+
+out:
+ return ret;
+}
int
-dict_set_bin (dict_t *this, char *key, void *ptr, size_t size)
+dict_get_bin(dict_t *this, char *key, void **bin)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = -EINVAL;
- if (!ptr || (size < 0)) {
- ret = -EINVAL;
- goto err;
- }
+ if (!bin) {
+ goto err;
+ }
- data = bin_to_data (ptr, size);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret < 0) {
+ goto err;
+ }
- data->data = ptr;
- data->len = size;
- data->is_static = 0;
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_PTR, key, ret);
- ret = dict_set (this, key, data);
+ *bin = data->data;
err:
- return ret;
+ if (data)
+ data_unref(data);
+
+ return ret;
}
+/********************************************************************
+ *
+ * dict_set_bin_common:
+ * This is the common function to set key and its value in
+ * dictionary. Flag(is_static) should be set appropriately based
+ * on the type of memory type used for value(*ptr). If flag is set
+ * to false value(*ptr) will be freed using GF_FREE() on destroy.
+ *
+ *******************************************************************/
+static int
+dict_set_bin_common(dict_t *this, char *key, void *ptr, size_t size,
+ gf_boolean_t is_static, gf_dict_data_type_t type)
+{
+ data_t *data = NULL;
+ int ret = 0;
+
+ if (!ptr || (size > DICT_KEY_VALUE_MAX_SIZE)) {
+ ret = -EINVAL;
+ goto err;
+ }
+ data = bin_to_data(ptr, size);
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ data->is_static = is_static;
+ data->data_type = type;
+
+ ret = dict_set(this, key, data);
+ if (ret < 0) {
+ /* don't free data->data, let callers handle it */
+ data->data = NULL;
+ data_destroy(data);
+ }
+
+err:
+ return ret;
+}
+
+/********************************************************************
+ *
+ * dict_set_bin:
+ * Set key and its value in the dictionary. This function should
+ * be called if the value is stored in dynamic memory.
+ *
+ *******************************************************************/
int
-dict_set_static_bin (dict_t *this, char *key, void *ptr, size_t size)
+dict_set_bin(dict_t *this, char *key, void *ptr, size_t size)
{
- data_t * data = NULL;
- int ret = 0;
+ return dict_set_bin_common(this, key, ptr, size, _gf_false,
+ GF_DATA_TYPE_PTR);
+}
- if (!ptr || (size < 0)) {
- ret = -EINVAL;
- goto err;
- }
+/********************************************************************
+ *
+ * dict_set_static_bin:
+ * Set key and its value in the dictionary. This function should
+ * be called if the value is stored in static memory.
+ *
+ *******************************************************************/
+int
+dict_set_static_bin(dict_t *this, char *key, void *ptr, size_t size)
+{
+ return dict_set_bin_common(this, key, ptr, size, _gf_true,
+ GF_DATA_TYPE_PTR);
+}
- data = bin_to_data (ptr, size);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+/* */
+int
+dict_set_gfuuid(dict_t *this, char *key, uuid_t gfid, bool is_static)
+{
+ return dict_set_bin_common(this, key, gfid, sizeof(uuid_t), is_static,
+ GF_DATA_TYPE_GFUUID);
+}
+
+int
+dict_get_gfuuid(dict_t *this, char *key, uuid_t *gfid)
+{
+ data_t *data = NULL;
+ int ret = -EINVAL;
- data->data = ptr;
- data->len = size;
- data->is_static = 1;
+ if (!gfid) {
+ goto err;
+ }
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret < 0) {
+ goto err;
+ }
- ret = dict_set (this, key, data);
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_GFUUID, key, -EINVAL);
+
+ memcpy(*gfid, data->data, min(data->len, sizeof(uuid_t)));
err:
- return ret;
+ if (data)
+ data_unref(data);
+
+ return ret;
+}
+
+int
+dict_set_mdata(dict_t *this, char *key, struct mdata_iatt *mdata,
+ bool is_static)
+{
+ return dict_set_bin_common(this, key, mdata, sizeof(struct mdata_iatt),
+ is_static, GF_DATA_TYPE_MDATA);
+}
+
+int
+dict_get_mdata(dict_t *this, char *key, struct mdata_iatt *mdata)
+{
+ data_t *data = NULL;
+ int ret = -EINVAL;
+
+ if (!mdata) {
+ goto err;
+ }
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret < 0) {
+ goto err;
+ }
+
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_MDATA, key, -EINVAL);
+ if (data->len < sizeof(struct mdata_iatt)) {
+ gf_smsg("glusterfs", GF_LOG_ERROR, ENOBUFS, LG_MSG_UNDERSIZED_BUF,
+ "key=%s", key, NULL);
+ ret = -ENOBUFS;
+ goto err;
+ }
+
+ memcpy(mdata, data->data, min(data->len, sizeof(struct mdata_iatt)));
+
+err:
+ if (data)
+ data_unref(data);
+
+ return ret;
+}
+
+int
+dict_set_iatt(dict_t *this, char *key, struct iatt *iatt, bool is_static)
+{
+ return dict_set_bin_common(this, key, iatt, sizeof(struct iatt), is_static,
+ GF_DATA_TYPE_IATT);
}
+int
+dict_get_iatt(dict_t *this, char *key, struct iatt *iatt)
+{
+ data_t *data = NULL;
+ int ret = -EINVAL;
+
+ if (!iatt) {
+ goto err;
+ }
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret < 0) {
+ goto err;
+ }
+
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_IATT, key, -EINVAL);
+
+ memcpy(iatt, data->data, min(data->len, sizeof(struct iatt)));
+
+err:
+ if (data)
+ data_unref(data);
+
+ return ret;
+}
/**
* dict_get_str_boolean - get a boolean value based on string representation.
@@ -2147,41 +2806,77 @@ err:
*/
int
-dict_get_str_boolean (dict_t *this, char *key, int default_val)
+dict_get_str_boolean(dict_t *this, char *key, int default_val)
{
- data_t *data = NULL;
- gf_boolean_t boo = _gf_false;
- int ret = 0;
+ data_t *data = NULL;
+ gf_boolean_t boo = _gf_false;
+ int ret = 0;
- ret = dict_get_with_ref (this, key, &data);
- if (ret < 0) {
- if (ret == -ENOENT)
- ret = default_val;
- else
- ret = -1;
- goto err;
- }
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret < 0) {
+ if (ret == -ENOENT)
+ ret = default_val;
+ else
+ ret = -1;
+ goto err;
+ }
- GF_ASSERT (data);
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, key, -EINVAL);
- if (!data->data) {
- ret = -1;
- goto err;
- }
+ ret = gf_strn2boolean(data->data, data->len - 1, &boo);
+ if (ret == -1)
+ goto err;
- ret = gf_string2boolean (data->data, &boo);
- if (ret == -1)
- goto err;
-
- ret = boo;
+ ret = boo;
err:
- if (data)
- data_unref (data);
+ if (data)
+ data_unref(data);
- return ret;
+ return ret;
}
+int
+dict_rename_key(dict_t *this, char *key, char *replace_key)
+{
+ data_pair_t *pair = NULL;
+ int ret = -EINVAL;
+ uint32_t hash;
+ uint32_t replacekey_hash;
+ int replacekey_len;
+
+ /* replacing a key by itself is a NO-OP */
+ if (strcmp(key, replace_key) == 0)
+ return 0;
+
+ if (!this) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "dict is NULL");
+ return ret;
+ }
+
+ hash = (uint32_t)XXH64(key, strlen(key), 0);
+ replacekey_len = strlen(replace_key);
+ replacekey_hash = (uint32_t)XXH64(replace_key, replacekey_len, 0);
+
+ LOCK(&this->lock);
+ {
+ /* no need to data_ref(pair->value), dict_set_lk() does it */
+ pair = dict_lookup_common(this, key, hash);
+ if (!pair)
+ ret = -ENODATA;
+ else
+ ret = dict_set_lk(this, replace_key, replacekey_len, pair->value,
+ replacekey_hash, 1);
+ }
+ UNLOCK(&this->lock);
+
+ if (!ret)
+ /* only delete the key on success */
+ dict_del(this, key);
+
+ return ret;
+}
/**
* Serialization format:
@@ -2191,13 +2886,9 @@ err:
* 4 4 4 <key len> <value len>
*/
-#define DICT_HDR_LEN 4
-#define DICT_DATA_HDR_KEY_LEN 4
-#define DICT_DATA_HDR_VAL_LEN 4
-
/**
- * _dict_serialized_length - return the length of serialized dict. This
- * procedure has to be called with this->lock held.
+ * dict_serialized_length_lk - return the length of serialized dict. This
+ * procedure has to be called with this->lock held.
*
* @this : dict to be serialized
* @return: success: len
@@ -2205,169 +2896,103 @@ err:
*/
int
-_dict_serialized_length (dict_t *this)
+dict_serialized_length_lk(dict_t *this)
{
- int ret = -EINVAL;
- int count = 0;
- int len = 0;
- int i = 0;
- data_pair_t * pair = NULL;
-
- len = DICT_HDR_LEN;
- count = this->count;
-
- if (count < 0) {
- gf_log ("dict", GF_LOG_ERROR, "count (%d) < 0!", count);
- goto out;
- }
-
- pair = this->members_list;
-
- while (count) {
- if (!pair) {
- gf_log ("dict", GF_LOG_ERROR,
- "less than count data pairs found!");
- goto out;
- }
-
- len += DICT_DATA_HDR_KEY_LEN + DICT_DATA_HDR_VAL_LEN;
-
- if (!pair->key) {
- gf_log ("dict", GF_LOG_ERROR, "pair->key is null!");
- goto out;
- }
-
- len += strlen (pair->key) + 1 /* for '\0' */;
-
- if (!pair->value) {
- gf_log ("dict", GF_LOG_ERROR,
- "pair->value is null!");
- goto out;
- }
-
- if (pair->value->vec) {
- for (i = 0; i < pair->value->len; i++) {
- if (pair->value->vec[i].iov_len < 0) {
- gf_log ("dict", GF_LOG_ERROR,
- "iov_len (%"GF_PRI_SIZET") < 0!",
- pair->value->vec[i].iov_len);
- goto out;
- }
+ int ret = -EINVAL;
+ int count = this->count;
+ const int keyhdrlen = DICT_DATA_HDR_KEY_LEN + DICT_DATA_HDR_VAL_LEN;
- len += pair->value->vec[i].iov_len;
- }
- } else {
- if (pair->value->len < 0) {
- gf_log ("dict", GF_LOG_ERROR,
- "value->len (%d) < 0",
- pair->value->len);
- goto out;
- }
-
- len += pair->value->len;
- }
+ if (count < 0) {
+ gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_COUNT_LESS_THAN_ZERO,
+ "count=%d", count, NULL);
+ goto out;
+ }
- pair = pair->next;
- count--;
- }
-
- ret = len;
+ ret = DICT_HDR_LEN + this->totkvlen + (count * keyhdrlen);
out:
- return ret;
+ return ret;
}
/**
- * _dict_serialize - serialize a dictionary into a buffer. This procedure has
- * to be called with this->lock held.
+ * dict_serialize_lk - serialize a dictionary into a buffer. This procedure has
+ * to be called with this->lock held.
*
* @this: dict to serialize
* @buf: buffer to serialize into. This must be
- * atleast dict_serialized_length (this) large
+ * at least dict_serialized_length (this) large
*
* @return: success: 0
* failure: -errno
*/
-int
-_dict_serialize (dict_t *this, char *buf)
-{
- int ret = -1;
- data_pair_t * pair = NULL;
- int32_t count = 0;
- int32_t keylen = 0;
- int32_t vallen = 0;
- int32_t netword = 0;
-
-
- if (!buf) {
- gf_log ("dict", GF_LOG_ERROR,
- "buf is null!");
- goto out;
+static int
+dict_serialize_lk(dict_t *this, char *buf)
+{
+ int ret = -1;
+ data_pair_t *pair = this->members_list;
+ int32_t count = this->count;
+ int32_t keylen = 0;
+ int32_t netword = 0;
+
+ if (!buf) {
+ gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, NULL);
+ goto out;
+ }
+
+ if (count < 0) {
+ gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_COUNT_LESS_THAN_ZERO,
+ "count=%d", count, NULL);
+ goto out;
+ }
+
+ netword = hton32(count);
+ memcpy(buf, &netword, sizeof(netword));
+ buf += DICT_HDR_LEN;
+
+ while (count) {
+ if (!pair) {
+ gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_PAIRS_LESS_THAN_COUNT,
+ NULL);
+ goto out;
}
-
- count = this->count;
- if (count < 0) {
- gf_log ("dict", GF_LOG_ERROR, "count (%d) < 0!", count);
- goto out;
+ if (!pair->key) {
+ gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_NULL_PTR, NULL);
+ goto out;
}
- netword = hton32 (count);
- memcpy (buf, &netword, sizeof(netword));
- buf += DICT_HDR_LEN;
- pair = this->members_list;
-
- while (count) {
- if (!pair) {
- gf_log ("dict", GF_LOG_ERROR,
- "less than count data pairs found!");
- goto out;
- }
-
- if (!pair->key) {
- gf_log ("dict", GF_LOG_ERROR,
- "pair->key is null!");
- goto out;
- }
-
- keylen = strlen (pair->key);
- netword = hton32 (keylen);
- memcpy (buf, &netword, sizeof(netword));
- buf += DICT_DATA_HDR_KEY_LEN;
+ keylen = strlen(pair->key);
+ netword = hton32(keylen);
+ memcpy(buf, &netword, sizeof(netword));
+ buf += DICT_DATA_HDR_KEY_LEN;
- if (!pair->value) {
- gf_log ("dict", GF_LOG_ERROR,
- "pair->value is null!");
- goto out;
- }
+ if (!pair->value) {
+ gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_NULL_PTR, NULL);
+ goto out;
+ }
- vallen = pair->value->len;
- netword = hton32 (vallen);
- memcpy (buf, &netword, sizeof(netword));
- buf += DICT_DATA_HDR_VAL_LEN;
+ netword = hton32(pair->value->len);
+ memcpy(buf, &netword, sizeof(netword));
+ buf += DICT_DATA_HDR_VAL_LEN;
- memcpy (buf, pair->key, keylen);
- buf += keylen;
- *buf++ = '\0';
+ memcpy(buf, pair->key, keylen);
+ buf += keylen;
+ *buf++ = '\0';
- if (!pair->value->data) {
- gf_log ("dict", GF_LOG_ERROR,
- "pair->value->data is null!");
- goto out;
- }
- memcpy (buf, pair->value->data, vallen);
- buf += vallen;
-
- pair = pair->next;
- count--;
+ if (pair->value->data) {
+ memcpy(buf, pair->value->data, pair->value->len);
+ buf += pair->value->len;
}
- ret = 0;
+ pair = pair->next;
+ count--;
+ }
+
+ ret = 0;
out:
- return ret;
+ return ret;
}
-
/**
* dict_serialized_length - return the length of serialized dict
*
@@ -2377,23 +3002,24 @@ out:
*/
int
-dict_serialized_length (dict_t *this)
+dict_serialized_length(dict_t *this)
{
- int ret = -EINVAL;
+ int ret = -EINVAL;
- if (!this) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is null!");
- goto out;
- }
+ if (!this) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "dict is null!");
+ goto out;
+ }
- LOCK (&this->lock);
- {
- ret = _dict_serialized_length (this);
- }
- UNLOCK (&this->lock);
+ LOCK(&this->lock);
+ {
+ ret = dict_serialized_length_lk(this);
+ }
+ UNLOCK(&this->lock);
out:
- return ret;
+ return ret;
}
/**
@@ -2401,32 +3027,32 @@ out:
*
* @this: dict to serialize
* @buf: buffer to serialize into. This must be
- * atleast dict_serialized_length (this) large
+ * at least dict_serialized_length (this) large
*
* @return: success: 0
* failure: -errno
*/
int
-dict_serialize (dict_t *this, char *buf)
+dict_serialize(dict_t *this, char *buf)
{
- int ret = -1;
+ int ret = -1;
- if (!this || !buf) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is null!");
- goto out;
- }
+ if (!this || !buf) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "dict is null!");
+ goto out;
+ }
- LOCK (&this->lock);
- {
- ret = _dict_serialize (this, buf);
- }
- UNLOCK (&this->lock);
+ LOCK(&this->lock);
+ {
+ ret = dict_serialize_lk(this, buf);
+ }
+ UNLOCK(&this->lock);
out:
- return ret;
+ return ret;
}
-
/**
* dict_unserialize - unserialize a buffer into a dict
*
@@ -2439,124 +3065,137 @@ out:
*/
int32_t
-dict_unserialize (char *orig_buf, int32_t size, dict_t **fill)
-{
- char *buf = NULL;
- int ret = -1;
- int32_t count = 0;
- int i = 0;
+dict_unserialize(char *orig_buf, int32_t size, dict_t **fill)
+{
+ char *buf = orig_buf;
+ int ret = -1;
+ int32_t count = 0;
+ int i = 0;
+
+ data_t *value = NULL;
+ char *key = NULL;
+ int32_t keylen = 0;
+ int32_t vallen = 0;
+ int32_t hostord = 0;
+
+ if (!buf) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "buf is null!");
+ goto out;
+ }
+
+ if (size == 0) {
+ gf_msg_callingfn("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "size is 0!");
+ goto out;
+ }
+
+ if (!fill) {
+ gf_msg_callingfn("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "fill is null!");
+ goto out;
+ }
+
+ if (!*fill) {
+ gf_msg_callingfn("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "*fill is null!");
+ goto out;
+ }
+
+ if ((buf + DICT_HDR_LEN) > (orig_buf + size)) {
+ gf_msg_callingfn("dict", GF_LOG_ERROR, 0, LG_MSG_UNDERSIZED_BUF,
+ "undersized buffer "
+ "passed. available (%lu) < required (%lu)",
+ (long)(orig_buf + size), (long)(buf + DICT_HDR_LEN));
+ goto out;
+ }
+
+ memcpy(&hostord, buf, sizeof(hostord));
+ count = ntoh32(hostord);
+ buf += DICT_HDR_LEN;
+
+ if (count < 0) {
+ gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_COUNT_LESS_THAN_ZERO,
+ "count=%d", count, NULL);
+ goto out;
+ }
+
+ /* count will be set by the dict_set's below */
+ (*fill)->count = 0;
+
+ for (i = 0; i < count; i++) {
+ if ((buf + DICT_DATA_HDR_KEY_LEN) > (orig_buf + size)) {
+ gf_msg_callingfn("dict", GF_LOG_ERROR, 0, LG_MSG_UNDERSIZED_BUF,
+ "undersized "
+ "buffer passed. available (%lu) < "
+ "required (%lu)",
+ (long)(orig_buf + size),
+ (long)(buf + DICT_DATA_HDR_KEY_LEN));
+ goto out;
+ }
+ memcpy(&hostord, buf, sizeof(hostord));
+ keylen = ntoh32(hostord);
+ buf += DICT_DATA_HDR_KEY_LEN;
+
+ if ((buf + DICT_DATA_HDR_VAL_LEN) > (orig_buf + size)) {
+ gf_msg_callingfn("dict", GF_LOG_ERROR, 0, LG_MSG_UNDERSIZED_BUF,
+ "undersized "
+ "buffer passed. available (%lu) < "
+ "required (%lu)",
+ (long)(orig_buf + size),
+ (long)(buf + DICT_DATA_HDR_VAL_LEN));
+ goto out;
+ }
+ memcpy(&hostord, buf, sizeof(hostord));
+ vallen = ntoh32(hostord);
+ buf += DICT_DATA_HDR_VAL_LEN;
+
+ if ((keylen < 0) || (vallen < 0)) {
+ gf_msg_callingfn("dict", GF_LOG_ERROR, 0, LG_MSG_UNDERSIZED_BUF,
+ "undersized length passed "
+ "key:%d val:%d",
+ keylen, vallen);
+ goto out;
+ }
+ if ((buf + keylen) > (orig_buf + size)) {
+ gf_msg_callingfn("dict", GF_LOG_ERROR, 0, LG_MSG_UNDERSIZED_BUF,
+ "undersized buffer passed. "
+ "available (%lu) < required (%lu)",
+ (long)(orig_buf + size), (long)(buf + keylen));
+ goto out;
+ }
+ key = buf;
+ buf += keylen + 1; /* for '\0' */
+
+ if ((buf + vallen) > (orig_buf + size)) {
+ gf_msg_callingfn("dict", GF_LOG_ERROR, 0, LG_MSG_UNDERSIZED_BUF,
+ "undersized buffer passed. "
+ "available (%lu) < required (%lu)",
+ (long)(orig_buf + size), (long)(buf + vallen));
+ goto out;
+ }
+ value = get_new_data();
- data_t * value = NULL;
- char * key = NULL;
- int32_t keylen = 0;
- int32_t vallen = 0;
- int32_t hostord = 0;
-
- buf = orig_buf;
-
- if (!buf) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "buf is null!");
- goto out;
- }
-
- if (size == 0) {
- gf_log_callingfn ("dict", GF_LOG_ERROR,
- "size is 0!");
- goto out;
- }
-
- if (!fill) {
- gf_log_callingfn ("dict", GF_LOG_ERROR,
- "fill is null!");
- goto out;
- }
-
- if (!*fill) {
- gf_log_callingfn ("dict", GF_LOG_ERROR,
- "*fill is null!");
- goto out;
- }
-
- if ((buf + DICT_HDR_LEN) > (orig_buf + size)) {
- gf_log_callingfn ("dict", GF_LOG_ERROR,
- "undersized buffer passed. "
- "available (%lu) < required (%lu)",
- (long)(orig_buf + size),
- (long)(buf + DICT_HDR_LEN));
- goto out;
- }
-
- memcpy (&hostord, buf, sizeof(hostord));
- count = ntoh32 (hostord);
- buf += DICT_HDR_LEN;
-
- if (count < 0) {
- gf_log ("dict", GF_LOG_ERROR,
- "count (%d) <= 0", count);
- goto out;
+ if (!value) {
+ ret = -1;
+ goto out;
}
+ value->len = vallen;
+ value->data = gf_memdup(buf, vallen);
+ value->data_type = GF_DATA_TYPE_STR_OLD;
+ value->is_static = _gf_false;
+ buf += vallen;
- /* count will be set by the dict_set's below */
- (*fill)->count = 0;
-
- for (i = 0; i < count; i++) {
- if ((buf + DICT_DATA_HDR_KEY_LEN) > (orig_buf + size)) {
- gf_log_callingfn ("dict", GF_LOG_ERROR,
- "undersized buffer passed. "
- "available (%lu) < required (%lu)",
- (long)(orig_buf + size),
- (long)(buf + DICT_DATA_HDR_KEY_LEN));
- goto out;
- }
- memcpy (&hostord, buf, sizeof(hostord));
- keylen = ntoh32 (hostord);
- buf += DICT_DATA_HDR_KEY_LEN;
-
- if ((buf + DICT_DATA_HDR_VAL_LEN) > (orig_buf + size)) {
- gf_log_callingfn ("dict", GF_LOG_ERROR,
- "undersized buffer passed. "
- "available (%lu) < required (%lu)",
- (long)(orig_buf + size),
- (long)(buf + DICT_DATA_HDR_VAL_LEN));
- goto out;
- }
- memcpy (&hostord, buf, sizeof(hostord));
- vallen = ntoh32 (hostord);
- buf += DICT_DATA_HDR_VAL_LEN;
-
- if ((buf + keylen) > (orig_buf + size)) {
- gf_log_callingfn ("dict", GF_LOG_ERROR,
- "undersized buffer passed. "
- "available (%lu) < required (%lu)",
- (long)(orig_buf + size),
- (long)(buf + keylen));
- goto out;
- }
- key = buf;
- buf += keylen + 1; /* for '\0' */
-
- if ((buf + vallen) > (orig_buf + size)) {
- gf_log_callingfn ("dict", GF_LOG_ERROR,
- "undersized buffer passed. "
- "available (%lu) < required (%lu)",
- (long)(orig_buf + size),
- (long)(buf + vallen));
- }
- value = get_new_data ();
- value->len = vallen;
- value->data = memdup (buf, vallen);
- value->is_static = 0;
- buf += vallen;
-
- dict_set (*fill, key, value);
- }
+ ret = dict_addn(*fill, key, keylen, value);
+ if (ret < 0)
+ goto out;
+ }
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
-
/**
* dict_allocate_and_serialize - serialize a dictionary into an allocated buffer
*
@@ -2569,50 +3208,49 @@ out:
*/
int32_t
-dict_allocate_and_serialize (dict_t *this, char **buf, size_t *length)
+dict_allocate_and_serialize(dict_t *this, char **buf, u_int *length)
{
- int ret = -EINVAL;
- ssize_t len = 0;
+ int ret = -EINVAL;
+ ssize_t len = 0;
- if (!this || !buf) {
- gf_log_callingfn ("dict", GF_LOG_DEBUG,
- "dict OR buf is NULL");
- goto out;
- }
+ if (!this || !buf) {
+ gf_msg_debug("dict", 0, "dict OR buf is NULL");
+ goto out;
+ }
- LOCK (&this->lock);
- {
- len = _dict_serialized_length (this);
- if (len < 0) {
- ret = len;
- goto unlock;
- }
+ LOCK(&this->lock);
+ {
+ len = dict_serialized_length_lk(this);
+ if (len < 0) {
+ ret = len;
+ goto unlock;
+ }
- *buf = GF_CALLOC (1, len, gf_common_mt_char);
- if (*buf == NULL) {
- ret = -ENOMEM;
- goto unlock;
- }
+ *buf = GF_MALLOC(len, gf_common_mt_char);
+ if (*buf == NULL) {
+ ret = -ENOMEM;
+ goto unlock;
+ }
- ret = _dict_serialize (this, *buf);
- if (ret < 0) {
- GF_FREE (*buf);
- *buf = NULL;
- goto unlock;
- }
+ ret = dict_serialize_lk(this, *buf);
+ if (ret < 0) {
+ GF_FREE(*buf);
+ *buf = NULL;
+ goto unlock;
+ }
- if (length != NULL) {
- *length = len;
- }
+ if (length != NULL) {
+ *length = len;
}
+ }
unlock:
- UNLOCK (&this->lock);
+ UNLOCK(&this->lock);
out:
- return ret;
+ return ret;
}
/**
- * _dict_serialize_value_with_delim: serialize the values in the dictionary
+ * dict_serialize_value_with_delim_lk: serialize the values in the dictionary
* into a buffer separated by delimiter (except the last)
*
* @this : dictionary to serialize
@@ -2621,88 +3259,231 @@ out:
* @delimiter : the delimiter to separate the values
*
* @return : 0 -> success
- * : -errno -> faliure
+ * : -errno -> failure
*/
int
-_dict_serialize_value_with_delim (dict_t *this, char *buf, int32_t *serz_len,
- char delimiter)
-{
- int ret = -1;
- int32_t count = 0;
- int32_t vallen = 0;
- int32_t total_len = 0;
- data_pair_t *pair = NULL;
-
- if (!buf) {
- gf_log ("dict", GF_LOG_ERROR, "buf is null");
- goto out;
+dict_serialize_value_with_delim_lk(dict_t *this, char *buf, int32_t *serz_len,
+ char delimiter)
+{
+ int ret = -1;
+ int32_t count = this->count;
+ int32_t vallen = 0;
+ int32_t total_len = 0;
+ data_pair_t *pair = this->members_list;
+
+ if (!buf) {
+ gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, NULL);
+ goto out;
+ }
+
+ if (count < 0) {
+ gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, "count=%d",
+ count, NULL);
+ goto out;
+ }
+
+ while (count) {
+ if (!pair) {
+ gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_PAIRS_LESS_THAN_COUNT,
+ NULL);
+ goto out;
}
- count = this->count;
- if (count < 0) {
- gf_log ("dict", GF_LOG_ERROR, "count (%d) < 0", count);
- goto out;
+ if (!pair->key || !pair->value) {
+ gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_KEY_OR_VALUE_NULL, NULL);
+ goto out;
}
- pair = this->members_list;
+ if (!pair->value->data) {
+ gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_NULL_VALUE_IN_DICT, NULL);
+ goto out;
+ }
- while (count) {
- if (!pair) {
- gf_log ("dict", GF_LOG_ERROR,
- "less than count data pairs found");
- goto out;
- }
+ vallen = pair->value->len - 1; // length includes \0
+ memcpy(buf, pair->value->data, vallen);
+ buf += vallen;
+ *buf++ = delimiter;
- if (!pair->key || !pair->value) {
- gf_log ("dict", GF_LOG_ERROR,
- "key or value is null");
- goto out;
- }
+ total_len += (vallen + 1);
- if (!pair->value->data) {
- gf_log ("dict", GF_LOG_ERROR,
- "null value found in dict");
- goto out;
- }
+ pair = pair->next;
+ count--;
+ }
- vallen = pair->value->len - 1; // length includes \0
- memcpy (buf, pair->value->data, vallen);
- buf += vallen;
- *buf++ = delimiter;
+ *--buf = '\0'; // remove the last delimiter
+ total_len--; // adjust the length
+ ret = 0;
- total_len += (vallen + 1);
+ if (serz_len)
+ *serz_len = total_len;
- pair = pair->next;
- count--;
- }
+out:
+ return ret;
+}
- *--buf = '\0'; // remove the last delimiter
- total_len--; // adjust the length
- ret = 0;
+int
+dict_serialize_value_with_delim(dict_t *this, char *buf, int32_t *serz_len,
+ char delimiter)
+{
+ int ret = -1;
+
+ if (!this || !buf) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "dict is null!");
+ goto out;
+ }
+
+ LOCK(&this->lock);
+ {
+ ret = dict_serialize_value_with_delim_lk(this, buf, serz_len,
+ delimiter);
+ }
+ UNLOCK(&this->lock);
+out:
+ return ret;
+}
- if (serz_len)
- *serz_len = total_len;
+int
+dict_dump_to_str(dict_t *dict, char *dump, int dumpsize, char *format)
+{
+ int ret = 0;
+ int dumplen = 0;
+ data_pair_t *trav = NULL;
- out:
- return ret;
+ if (!dict)
+ return 0;
+
+ for (trav = dict->members_list; trav; trav = trav->next) {
+ ret = snprintf(&dump[dumplen], dumpsize - dumplen, format, trav->key,
+ trav->value->data);
+ if ((ret == -1) || !ret)
+ return ret;
+
+ dumplen += ret;
+ }
+ return 0;
}
+void
+dict_dump_to_log(dict_t *dict)
+{
+ int ret = -1;
+ char *dump = NULL;
+ const int dump_size = 64 * 1024;
+ char *format = "(%s:%s)";
+
+ if (!dict) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "dict is NULL");
+ goto out;
+ }
+
+ dump = GF_MALLOC(dump_size, gf_common_mt_char);
+ if (!dump) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, ENOMEM, LG_MSG_NO_MEMORY,
+ "dump buffer is NULL");
+ goto out;
+ }
+
+ ret = dict_dump_to_str(dict, dump, dump_size, format);
+ if (ret) {
+ gf_smsg("dict", GF_LOG_WARNING, 0, LG_MSG_FAILED_TO_LOG_DICT, NULL);
+ goto out;
+ }
+ gf_smsg("dict", GF_LOG_INFO, 0, LG_MSG_DICT_ERROR, "dict=%p", dict,
+ "dump=%s", dump, NULL);
+out:
+ GF_FREE(dump);
+
+ return;
+}
+
+void
+dict_dump_to_statedump(dict_t *dict, char *dict_name, char *domain)
+{
+ int ret = -1;
+ char *dump = NULL;
+ const int dump_size = 64 * 1024;
+ char key[4096] = {
+ 0,
+ };
+ char *format = "\n\t%s:%s";
+
+ if (!dict) {
+ gf_msg_callingfn(domain, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "dict is NULL");
+ goto out;
+ }
+
+ dump = GF_MALLOC(dump_size, gf_common_mt_char);
+ if (!dump) {
+ gf_msg_callingfn(domain, GF_LOG_WARNING, ENOMEM, LG_MSG_NO_MEMORY,
+ "dump buffer is NULL");
+ goto out;
+ }
+
+ ret = dict_dump_to_str(dict, dump, dump_size, format);
+ if (ret) {
+ gf_smsg(domain, GF_LOG_WARNING, 0, LG_MSG_FAILED_TO_LOG_DICT, "name=%s",
+ dict_name, NULL);
+ goto out;
+ }
+ gf_proc_dump_build_key(key, domain, "%s", dict_name);
+ gf_proc_dump_write(key, "%s", dump);
+
+out:
+ GF_FREE(dump);
+
+ return;
+}
+
+dict_t *
+dict_for_key_value(const char *name, const char *value, size_t size,
+ gf_boolean_t is_static)
+{
+ dict_t *xattr = dict_new();
+ int ret = 0;
+
+ if (!xattr)
+ return NULL;
+
+ if (is_static)
+ ret = dict_set_static_bin(xattr, (char *)name, (void *)value, size);
+ else
+ ret = dict_set_bin(xattr, (char *)name, (void *)value, size);
+
+ if (ret) {
+ dict_destroy(xattr);
+ xattr = NULL;
+ }
+
+ return xattr;
+}
+
+/*
+ * "strings" should be NULL terminated strings array.
+ */
int
-dict_serialize_value_with_delim (dict_t *this, char *buf, int32_t *serz_len,
- char delimiter)
+dict_has_key_from_array(dict_t *dict, char **strings, gf_boolean_t *result)
{
- int ret = -1;
+ int i = 0;
+ uint32_t hash = 0;
- if (!this || !buf) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is null!");
- goto out;
- }
+ if (!dict || !strings || !result)
+ return -EINVAL;
- LOCK (&this->lock);
- {
- ret = _dict_serialize_value_with_delim (this, buf, serz_len, delimiter);
+ LOCK(&dict->lock);
+ {
+ for (i = 0; strings[i]; i++) {
+ hash = (uint32_t)XXH64(strings[i], strlen(strings[i]), 0);
+ if (dict_lookup_common(dict, strings[i], hash)) {
+ *result = _gf_true;
+ goto unlock;
+ }
}
- UNLOCK (&this->lock);
-out:
- return ret;
+ *result = _gf_false;
+ }
+unlock:
+ UNLOCK(&dict->lock);
+ return 0;
}
diff --git a/libglusterfs/src/dict.h b/libglusterfs/src/dict.h
deleted file mode 100644
index 0d404997ee0..00000000000
--- a/libglusterfs/src/dict.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _DICT_H
-#define _DICT_H
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include <inttypes.h>
-#include <sys/uio.h>
-#include <pthread.h>
-
-#include "common-utils.h"
-
-typedef struct _data data_t;
-typedef struct _dict dict_t;
-typedef struct _data_pair data_pair_t;
-
-struct _data {
- unsigned char is_static:1;
- unsigned char is_const:1;
- unsigned char is_stdalloc:1;
- int32_t len;
- struct iovec *vec;
- char *data;
- int32_t refcount;
- gf_lock_t lock;
-};
-
-struct _data_pair {
- struct _data_pair *hash_next;
- struct _data_pair *prev;
- struct _data_pair *next;
- data_t *value;
- char *key;
-};
-
-struct _dict {
- unsigned char is_static:1;
- int32_t hash_size;
- int32_t count;
- int32_t refcount;
- data_pair_t **members;
- data_pair_t *members_list;
- char *extra_free;
- char *extra_stdfree;
- gf_lock_t lock;
-};
-
-
-int32_t is_data_equal (data_t *one, data_t *two);
-void data_destroy (data_t *data);
-
-int32_t dict_set (dict_t *this, char *key, data_t *value);
-data_t *dict_get (dict_t *this, char *key);
-void dict_del (dict_t *this, char *key);
-
-int32_t dict_serialized_length (dict_t *dict);
-int32_t dict_serialize (dict_t *dict, char *buf);
-int32_t dict_unserialize (char *buf, int32_t size, dict_t **fill);
-
-int32_t dict_allocate_and_serialize (dict_t *this, char **buf, size_t *length);
-
-int32_t dict_iovec_len (dict_t *dict);
-int32_t dict_to_iovec (dict_t *dict, struct iovec *vec, int32_t count);
-
-void dict_destroy (dict_t *dict);
-void dict_unref (dict_t *dict);
-dict_t *dict_ref (dict_t *dict);
-data_t *data_ref (data_t *data);
-void data_unref (data_t *data);
-
-/*
- TODO: provide converts for differnt byte sizes, signedness, and void *
- */
-data_t *int_to_data (int64_t value);
-data_t *str_to_data (char *value);
-data_t *data_from_dynstr (char *value);
-data_t *data_from_dynptr (void *value, int32_t len);
-data_t *bin_to_data (void *value, int32_t len);
-data_t *static_str_to_data (char *value);
-data_t *static_bin_to_data (void *value);
-
-int64_t data_to_int64 (data_t *data);
-int32_t data_to_int32 (data_t *data);
-int16_t data_to_int16 (data_t *data);
-int8_t data_to_int8 (data_t *data);
-
-uint64_t data_to_uint64 (data_t *data);
-uint32_t data_to_uint32 (data_t *data);
-uint16_t data_to_uint16 (data_t *data);
-
-data_t *data_from_ptr (void *value);
-data_t *data_from_static_ptr (void *value);
-
-data_t *data_from_int64 (int64_t value);
-data_t *data_from_int32 (int32_t value);
-data_t *data_from_int16 (int16_t value);
-data_t *data_from_int8 (int8_t value);
-
-data_t *data_from_uint64 (uint64_t value);
-data_t *data_from_uint32 (uint32_t value);
-data_t *data_from_uint16 (uint16_t value);
-
-char *data_to_str (data_t *data);
-void *data_to_bin (data_t *data);
-void *data_to_ptr (data_t *data);
-
-data_t *get_new_data ();
-data_t * data_copy (data_t *old);
-dict_t *get_new_dict_full (int size_hint);
-dict_t *get_new_dict ();
-
-data_pair_t *get_new_data_pair ();
-
-void dict_foreach (dict_t *this,
- void (*fn)(dict_t *this,
- char *key,
- data_t *value,
- void *data),
- void *data);
-
-dict_t *dict_copy (dict_t *this, dict_t *new);
-
-/* CLEANED UP FUNCTIONS DECLARATIONS */
-GF_MUST_CHECK dict_t *dict_new (void);
-dict_t *dict_copy_with_ref (dict_t *this, dict_t *new);
-
-GF_MUST_CHECK int dict_get_int8 (dict_t *this, char *key, int8_t *val);
-GF_MUST_CHECK int dict_set_int8 (dict_t *this, char *key, int8_t val);
-
-GF_MUST_CHECK int dict_get_int16 (dict_t *this, char *key, int16_t *val);
-GF_MUST_CHECK int dict_set_int16 (dict_t *this, char *key, int16_t val);
-
-GF_MUST_CHECK int dict_get_int32 (dict_t *this, char *key, int32_t *val);
-GF_MUST_CHECK int dict_set_int32 (dict_t *this, char *key, int32_t val);
-
-GF_MUST_CHECK int dict_get_int64 (dict_t *this, char *key, int64_t *val);
-GF_MUST_CHECK int dict_set_int64 (dict_t *this, char *key, int64_t val);
-
-GF_MUST_CHECK int dict_get_uint16 (dict_t *this, char *key, uint16_t *val);
-GF_MUST_CHECK int dict_set_uint16 (dict_t *this, char *key, uint16_t val);
-
-GF_MUST_CHECK int dict_get_uint32 (dict_t *this, char *key, uint32_t *val);
-GF_MUST_CHECK int dict_set_uint32 (dict_t *this, char *key, uint32_t val);
-
-GF_MUST_CHECK int dict_get_uint64 (dict_t *this, char *key, uint64_t *val);
-GF_MUST_CHECK int dict_set_uint64 (dict_t *this, char *key, uint64_t val);
-
-GF_MUST_CHECK int dict_get_double (dict_t *this, char *key, double *val);
-GF_MUST_CHECK int dict_set_double (dict_t *this, char *key, double val);
-
-GF_MUST_CHECK int dict_set_static_ptr (dict_t *this, char *key, void *ptr);
-GF_MUST_CHECK int dict_get_ptr (dict_t *this, char *key, void **ptr);
-GF_MUST_CHECK int dict_set_ptr (dict_t *this, char *key, void *ptr);
-GF_MUST_CHECK int dict_set_dynptr (dict_t *this, char *key, void *ptr, size_t size);
-
-GF_MUST_CHECK int dict_get_bin (dict_t *this, char *key, void **ptr);
-GF_MUST_CHECK int dict_set_bin (dict_t *this, char *key, void *ptr, size_t size);
-GF_MUST_CHECK int dict_set_static_bin (dict_t *this, char *key, void *ptr, size_t size);
-
-GF_MUST_CHECK int dict_set_str (dict_t *this, char *key, char *str);
-GF_MUST_CHECK int dict_set_dynmstr (dict_t *this, char *key, char *str);
-GF_MUST_CHECK int dict_set_dynstr (dict_t *this, char *key, char *str);
-GF_MUST_CHECK int dict_get_str (dict_t *this, char *key, char **str);
-
-GF_MUST_CHECK int dict_get_str_boolean (dict_t *this, char *key, int default_val);
-GF_MUST_CHECK int dict_serialize_value_with_delim (dict_t *this, char *buf, int32_t *serz_len,
- char delimiter);
-#endif
diff --git a/libglusterfs/src/event-epoll.c b/libglusterfs/src/event-epoll.c
new file mode 100644
index 00000000000..fb4fb845b40
--- /dev/null
+++ b/libglusterfs/src/event-epoll.c
@@ -0,0 +1,1032 @@
+/*
+ Copyright (c) 2012 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 <pthread.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "glusterfs/gf-event.h"
+#include "glusterfs/common-utils.h"
+#include "glusterfs/syscall.h"
+#include "glusterfs/libglusterfs-messages.h"
+
+#ifdef HAVE_SYS_EPOLL_H
+#include <sys/epoll.h>
+
+struct event_slot_epoll {
+ int fd;
+ int events;
+ int gen;
+ int idx;
+ gf_atomic_t ref;
+ int do_close;
+ int in_handler;
+ int handled_error;
+ void *data;
+ event_handler_t handler;
+ gf_lock_t lock;
+ struct list_head poller_death;
+};
+
+struct event_thread_data {
+ struct event_pool *event_pool;
+ int event_index;
+};
+
+static struct event_slot_epoll *
+__event_newtable(struct event_pool *event_pool, int table_idx)
+{
+ struct event_slot_epoll *table = NULL;
+ int i = -1;
+
+ table = GF_CALLOC(sizeof(*table), EVENT_EPOLL_SLOTS, gf_common_mt_ereg);
+ if (!table)
+ return NULL;
+
+ for (i = 0; i < EVENT_EPOLL_SLOTS; i++) {
+ table[i].fd = -1;
+ LOCK_INIT(&table[i].lock);
+ INIT_LIST_HEAD(&table[i].poller_death);
+ }
+
+ event_pool->ereg[table_idx] = table;
+ event_pool->slots_used[table_idx] = 0;
+
+ return table;
+}
+
+static int
+event_slot_ref(struct event_slot_epoll *slot)
+{
+ if (!slot)
+ return -1;
+
+ return GF_ATOMIC_INC(slot->ref);
+}
+
+static int
+__event_slot_alloc(struct event_pool *event_pool, int fd,
+ char notify_poller_death, struct event_slot_epoll **slot)
+{
+ int i = 0;
+ int j = 0;
+ int table_idx = -1;
+ int gen = -1;
+ struct event_slot_epoll *table = NULL;
+
+retry:
+
+ while (i < EVENT_EPOLL_TABLES) {
+ switch (event_pool->slots_used[i]) {
+ case EVENT_EPOLL_SLOTS:
+ break;
+ case 0:
+ if (!event_pool->ereg[i]) {
+ table = __event_newtable(event_pool, i);
+ if (!table)
+ return -1;
+ } else {
+ table = event_pool->ereg[i];
+ }
+ break;
+ default:
+ table = event_pool->ereg[i];
+ break;
+ }
+
+ if (table)
+ /* break out of the loop */
+ break;
+ i++;
+ }
+
+ if (!table)
+ return -1;
+
+ table_idx = i;
+
+ for (j = 0; j < EVENT_EPOLL_SLOTS; j++) {
+ if (table[j].fd == -1) {
+ /* wipe everything except bump the generation */
+ gen = table[j].gen;
+ memset(&table[j], 0, sizeof(table[j]));
+ table[j].gen = gen + 1;
+
+ LOCK_INIT(&table[j].lock);
+ INIT_LIST_HEAD(&table[j].poller_death);
+
+ table[j].fd = fd;
+ if (notify_poller_death) {
+ table[j].idx = table_idx * EVENT_EPOLL_SLOTS + j;
+ list_add_tail(&table[j].poller_death,
+ &event_pool->poller_death);
+ }
+
+ event_pool->slots_used[table_idx]++;
+
+ break;
+ }
+ }
+
+ if (j == EVENT_EPOLL_SLOTS) {
+ table = NULL;
+ i++;
+ goto retry;
+ } else {
+ (*slot) = &table[j];
+ event_slot_ref(*slot);
+ return table_idx * EVENT_EPOLL_SLOTS + j;
+ }
+}
+
+static int
+event_slot_alloc(struct event_pool *event_pool, int fd,
+ char notify_poller_death, struct event_slot_epoll **slot)
+{
+ int idx = -1;
+
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ idx = __event_slot_alloc(event_pool, fd, notify_poller_death, slot);
+ }
+ pthread_mutex_unlock(&event_pool->mutex);
+
+ return idx;
+}
+
+static void
+__event_slot_dealloc(struct event_pool *event_pool, int idx)
+{
+ int table_idx = 0;
+ int offset = 0;
+ struct event_slot_epoll *table = NULL;
+ struct event_slot_epoll *slot = NULL;
+ int fd = -1;
+
+ table_idx = idx / EVENT_EPOLL_SLOTS;
+ offset = idx % EVENT_EPOLL_SLOTS;
+
+ table = event_pool->ereg[table_idx];
+ if (!table)
+ return;
+
+ slot = &table[offset];
+ slot->gen++;
+
+ fd = slot->fd;
+ slot->fd = -1;
+ slot->handled_error = 0;
+ slot->in_handler = 0;
+ list_del_init(&slot->poller_death);
+ if (fd != -1)
+ event_pool->slots_used[table_idx]--;
+
+ return;
+}
+
+static void
+event_slot_dealloc(struct event_pool *event_pool, int idx)
+{
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ __event_slot_dealloc(event_pool, idx);
+ }
+ pthread_mutex_unlock(&event_pool->mutex);
+
+ return;
+}
+
+static struct event_slot_epoll *
+event_slot_get(struct event_pool *event_pool, int idx)
+{
+ struct event_slot_epoll *slot = NULL;
+ struct event_slot_epoll *table = NULL;
+ int table_idx = 0;
+ int offset = 0;
+
+ table_idx = idx / EVENT_EPOLL_SLOTS;
+ offset = idx % EVENT_EPOLL_SLOTS;
+
+ table = event_pool->ereg[table_idx];
+ if (!table)
+ return NULL;
+
+ slot = &table[offset];
+
+ event_slot_ref(slot);
+ return slot;
+}
+
+static void
+__event_slot_unref(struct event_pool *event_pool, struct event_slot_epoll *slot,
+ int idx)
+{
+ int ref = -1;
+ int fd = -1;
+ int do_close = 0;
+
+ ref = GF_ATOMIC_DEC(slot->ref);
+ if (ref)
+ /* slot still alive */
+ goto done;
+
+ LOCK(&slot->lock);
+ {
+ fd = slot->fd;
+ do_close = slot->do_close;
+ slot->do_close = 0;
+ }
+ UNLOCK(&slot->lock);
+
+ __event_slot_dealloc(event_pool, idx);
+
+ if (do_close)
+ sys_close(fd);
+done:
+ return;
+}
+
+static void
+event_slot_unref(struct event_pool *event_pool, struct event_slot_epoll *slot,
+ int idx)
+{
+ int ref = -1;
+ int fd = -1;
+ int do_close = 0;
+
+ ref = GF_ATOMIC_DEC(slot->ref);
+ if (ref)
+ /* slot still alive */
+ goto done;
+
+ LOCK(&slot->lock);
+ {
+ fd = slot->fd;
+ do_close = slot->do_close;
+ slot->do_close = 0;
+ }
+ UNLOCK(&slot->lock);
+
+ event_slot_dealloc(event_pool, idx);
+
+ if (do_close)
+ sys_close(fd);
+done:
+ return;
+}
+
+static struct event_pool *
+event_pool_new_epoll(int count, int eventthreadcount)
+{
+ struct event_pool *event_pool = NULL;
+ int epfd = -1;
+
+ event_pool = GF_CALLOC(1, sizeof(*event_pool), gf_common_mt_event_pool);
+
+ if (!event_pool)
+ goto out;
+
+ epfd = epoll_create(count);
+
+ if (epfd == -1) {
+ gf_smsg("epoll", GF_LOG_ERROR, errno, LG_MSG_EPOLL_FD_CREATE_FAILED,
+ NULL);
+ GF_FREE(event_pool->reg);
+ GF_FREE(event_pool);
+ event_pool = NULL;
+ goto out;
+ }
+
+ event_pool->fd = epfd;
+
+ event_pool->count = count;
+ INIT_LIST_HEAD(&event_pool->poller_death);
+ event_pool->eventthreadcount = eventthreadcount;
+ event_pool->auto_thread_count = 0;
+
+ pthread_mutex_init(&event_pool->mutex, NULL);
+
+out:
+ return event_pool;
+}
+
+static void
+__slot_update_events(struct event_slot_epoll *slot, int poll_in, int poll_out)
+{
+ switch (poll_in) {
+ case 1:
+ slot->events |= EPOLLIN;
+ break;
+ case 0:
+ slot->events &= ~EPOLLIN;
+ break;
+ case -1:
+ /* do nothing */
+ break;
+ default:
+ gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_INVALID_POLL_IN,
+ "value=%d", poll_in, NULL);
+ break;
+ }
+
+ switch (poll_out) {
+ case 1:
+ slot->events |= EPOLLOUT;
+ break;
+ case 0:
+ slot->events &= ~EPOLLOUT;
+ break;
+ case -1:
+ /* do nothing */
+ break;
+ default:
+ gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_INVALID_POLL_OUT,
+ "value=%d", poll_out, NULL);
+ break;
+ }
+}
+
+int
+event_register_epoll(struct event_pool *event_pool, int fd,
+ event_handler_t handler, void *data, int poll_in,
+ int poll_out, char notify_poller_death)
+{
+ int idx = -1;
+ int ret = -1;
+ int destroy = 0;
+ struct epoll_event epoll_event = {
+ 0,
+ };
+ struct event_data *ev_data = (void *)&epoll_event.data;
+ struct event_slot_epoll *slot = NULL;
+
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
+
+ /* TODO: Even with the below check, there is a possibility of race,
+ * What if the destroy mode is set after the check is done.
+ * Not sure of the best way to prevent this race, ref counting
+ * is one possibility.
+ * There is no harm in registering and unregistering the fd
+ * even after destroy mode is set, just that such fds will remain
+ * open until unregister is called, also the events on that fd will be
+ * notified, until one of the poller thread is alive.
+ */
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ destroy = event_pool->destroy;
+ }
+ pthread_mutex_unlock(&event_pool->mutex);
+
+ if (destroy == 1)
+ goto out;
+
+ idx = event_slot_alloc(event_pool, fd, notify_poller_death, &slot);
+ if (idx == -1) {
+ gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, "fd=%d", fd,
+ NULL);
+ return -1;
+ }
+
+ assert(slot->fd == fd);
+
+ LOCK(&slot->lock);
+ {
+ /* make epoll 'singleshot', which
+ means we need to re-add the fd with
+ epoll_ctl(EPOLL_CTL_MOD) after delivery of every
+ single event. This assures us that while a poller
+ thread has picked up and is processing an event,
+ another poller will not try to pick this at the same
+ time as well.
+ */
+
+ slot->events = EPOLLPRI | EPOLLHUP | EPOLLERR | EPOLLONESHOT;
+ slot->handler = handler;
+ slot->data = data;
+
+ __slot_update_events(slot, poll_in, poll_out);
+
+ epoll_event.events = slot->events;
+ ev_data->idx = idx;
+ ev_data->gen = slot->gen;
+
+ ret = epoll_ctl(event_pool->fd, EPOLL_CTL_ADD, fd, &epoll_event);
+ /* check ret after UNLOCK() to avoid deadlock in
+ event_slot_unref()
+ */
+ }
+ UNLOCK(&slot->lock);
+
+ if (ret == -1) {
+ gf_smsg("epoll", GF_LOG_ERROR, errno, LG_MSG_EPOLL_FD_ADD_FAILED,
+ "fd=%d", fd, "epoll_fd=%d", event_pool->fd, NULL);
+ event_slot_unref(event_pool, slot, idx);
+ idx = -1;
+ }
+
+ /* keep slot->ref (do not event_slot_unref) if successful */
+out:
+ return idx;
+}
+
+static int
+event_unregister_epoll_common(struct event_pool *event_pool, int fd, int idx,
+ int do_close)
+{
+ int ret = -1;
+ struct event_slot_epoll *slot = NULL;
+
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
+
+ /* During shutdown, it may happen that a socket registration with
+ * the event sub-system may fail and an rpc_transport_unref() may
+ * be called for such an unregistered socket with idx == -1. This
+ * may cause the following assert(slot->fd == fd) to fail.
+ */
+ if (idx < 0)
+ goto out;
+
+ slot = event_slot_get(event_pool, idx);
+ if (!slot) {
+ gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, "fd=%d", fd,
+ "idx=%d", idx, NULL);
+ return -1;
+ }
+
+ assert(slot->fd == fd);
+
+ LOCK(&slot->lock);
+ {
+ ret = epoll_ctl(event_pool->fd, EPOLL_CTL_DEL, fd, NULL);
+
+ if (ret == -1) {
+ gf_smsg("epoll", GF_LOG_ERROR, errno, LG_MSG_EPOLL_FD_DEL_FAILED,
+ "fd=%d", fd, "epoll_fd=%d", event_pool->fd, NULL);
+ goto unlock;
+ }
+
+ slot->do_close = do_close;
+ slot->gen++; /* detect unregister in dispatch_handler() */
+ }
+unlock:
+ UNLOCK(&slot->lock);
+
+ event_slot_unref(event_pool, slot, idx); /* one for event_register() */
+ event_slot_unref(event_pool, slot, idx); /* one for event_slot_get() */
+out:
+ return ret;
+}
+
+static int
+event_unregister_epoll(struct event_pool *event_pool, int fd, int idx_hint)
+{
+ int ret = -1;
+
+ ret = event_unregister_epoll_common(event_pool, fd, idx_hint, 0);
+
+ return ret;
+}
+
+static int
+event_unregister_close_epoll(struct event_pool *event_pool, int fd,
+ int idx_hint)
+{
+ int ret = -1;
+
+ ret = event_unregister_epoll_common(event_pool, fd, idx_hint, 1);
+
+ return ret;
+}
+
+static int
+event_select_on_epoll(struct event_pool *event_pool, int fd, int idx,
+ int poll_in, int poll_out)
+{
+ int ret = -1;
+ struct event_slot_epoll *slot = NULL;
+ struct epoll_event epoll_event = {
+ 0,
+ };
+ struct event_data *ev_data = (void *)&epoll_event.data;
+
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
+
+ slot = event_slot_get(event_pool, idx);
+ if (!slot) {
+ gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, "fd=%d", fd,
+ "idx=%d", idx, NULL);
+ return -1;
+ }
+
+ assert(slot->fd == fd);
+
+ LOCK(&slot->lock);
+ {
+ __slot_update_events(slot, poll_in, poll_out);
+
+ epoll_event.events = slot->events;
+ ev_data->idx = idx;
+ ev_data->gen = slot->gen;
+
+ if (slot->in_handler)
+ /*
+ * in_handler indicates at least one thread
+ * executing event_dispatch_epoll_handler()
+ * which will perform epoll_ctl(EPOLL_CTL_MOD)
+ * anyways (because of EPOLLET)
+ *
+ * This not only saves a system call, but also
+ * avoids possibility of another epoll thread
+ * picking up the next event while the ongoing
+ * handler is still in progress (and resulting
+ * in unnecessary contention on rpc_transport_t->mutex).
+ */
+ goto unlock;
+
+ ret = epoll_ctl(event_pool->fd, EPOLL_CTL_MOD, fd, &epoll_event);
+ if (ret == -1) {
+ gf_smsg("epoll", GF_LOG_ERROR, errno, LG_MSG_EPOLL_FD_MODIFY_FAILED,
+ "fd=%d", fd, "events=%d", epoll_event.events, NULL);
+ }
+ }
+unlock:
+ UNLOCK(&slot->lock);
+
+ event_slot_unref(event_pool, slot, idx);
+
+out:
+ return idx;
+}
+
+static int
+event_dispatch_epoll_handler(struct event_pool *event_pool,
+ struct epoll_event *event)
+{
+ struct event_data *ev_data = NULL;
+ struct event_slot_epoll *slot = NULL;
+ event_handler_t handler = NULL;
+ void *data = NULL;
+ int idx = -1;
+ int gen = -1;
+ int ret = -1;
+ int fd = -1;
+ gf_boolean_t handled_error_previously = _gf_false;
+
+ ev_data = (void *)&event->data;
+ handler = NULL;
+ data = NULL;
+
+ idx = ev_data->idx;
+ gen = ev_data->gen;
+
+ slot = event_slot_get(event_pool, idx);
+ if (!slot) {
+ gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, "idx=%d", idx,
+ NULL);
+ return -1;
+ }
+
+ LOCK(&slot->lock);
+ {
+ fd = slot->fd;
+ if (fd == -1) {
+ gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_STALE_FD_FOUND, "idx=%d",
+ idx, "gen=%d", gen, "events=%d", event->events,
+ "slot->gen=%d", slot->gen, NULL);
+ /* fd got unregistered in another thread */
+ goto pre_unlock;
+ }
+
+ if (gen != slot->gen) {
+ gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_GENERATION_MISMATCH,
+ "idx=%d", idx, "gen=%d", gen, "slot->gen=%d", slot->gen,
+ "slot->fd=%d", slot->fd, NULL);
+ /* slot was re-used and therefore is another fd! */
+ goto pre_unlock;
+ }
+
+ handler = slot->handler;
+ data = slot->data;
+
+ if (slot->in_handler > 0) {
+ /* Another handler is inprogress, skip this one. */
+ handler = NULL;
+ goto pre_unlock;
+ }
+
+ if (slot->handled_error) {
+ handled_error_previously = _gf_true;
+ } else {
+ slot->handled_error = (event->events & (EPOLLERR | EPOLLHUP));
+ slot->in_handler++;
+ }
+ }
+pre_unlock:
+ UNLOCK(&slot->lock);
+
+ ret = 0;
+
+ if (!handler)
+ goto out;
+
+ if (!handled_error_previously) {
+ handler(fd, idx, gen, data, (event->events & (EPOLLIN | EPOLLPRI)),
+ (event->events & (EPOLLOUT)),
+ (event->events & (EPOLLERR | EPOLLHUP)), 0);
+ }
+out:
+ event_slot_unref(event_pool, slot, idx);
+
+ return ret;
+}
+
+static void *
+event_dispatch_epoll_worker(void *data)
+{
+ struct epoll_event event;
+ int ret = -1;
+ struct event_thread_data *ev_data = data;
+ struct event_pool *event_pool;
+ int myindex = -1;
+ int timetodie = 0, gen = 0;
+ struct list_head poller_death_notify;
+ struct event_slot_epoll *slot = NULL, *tmp = NULL;
+
+ GF_VALIDATE_OR_GOTO("event", ev_data, out);
+
+ event_pool = ev_data->event_pool;
+ myindex = ev_data->event_index;
+
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
+
+ gf_smsg("epoll", GF_LOG_INFO, 0, LG_MSG_STARTED_EPOLL_THREAD, "index=%d",
+ myindex - 1, NULL);
+
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ event_pool->activethreadcount++;
+ }
+ pthread_mutex_unlock(&event_pool->mutex);
+
+ for (;;) {
+ if (event_pool->eventthreadcount < myindex) {
+ /* ...time to die, thread count was decreased below
+ * this threads index */
+ /* Start with extra safety at this point, reducing
+ * lock conention in normal case when threads are not
+ * reconfigured always */
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ if (event_pool->eventthreadcount < myindex) {
+ while (event_pool->poller_death_sliced) {
+ pthread_cond_wait(&event_pool->cond,
+ &event_pool->mutex);
+ }
+
+ INIT_LIST_HEAD(&poller_death_notify);
+ /* if found true in critical section,
+ * die */
+ event_pool->pollers[myindex - 1] = 0;
+ event_pool->activethreadcount--;
+ timetodie = 1;
+ gen = ++event_pool->poller_gen;
+ list_for_each_entry(slot, &event_pool->poller_death,
+ poller_death)
+ {
+ event_slot_ref(slot);
+ }
+
+ list_splice_init(&event_pool->poller_death,
+ &poller_death_notify);
+ event_pool->poller_death_sliced = 1;
+ pthread_cond_broadcast(&event_pool->cond);
+ }
+ }
+ pthread_mutex_unlock(&event_pool->mutex);
+ if (timetodie) {
+ list_for_each_entry(slot, &poller_death_notify, poller_death)
+ {
+ slot->handler(slot->fd, 0, gen, slot->data, 0, 0, 0, 1);
+ }
+
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ list_for_each_entry_safe(slot, tmp, &poller_death_notify,
+ poller_death)
+ {
+ __event_slot_unref(event_pool, slot, slot->idx);
+ }
+
+ list_splice(&poller_death_notify,
+ &event_pool->poller_death);
+ event_pool->poller_death_sliced = 0;
+ pthread_cond_broadcast(&event_pool->cond);
+ }
+ pthread_mutex_unlock(&event_pool->mutex);
+
+ gf_smsg("epoll", GF_LOG_INFO, 0, LG_MSG_EXITED_EPOLL_THREAD,
+ "index=%d", myindex, NULL);
+
+ goto out;
+ }
+ }
+
+ ret = epoll_wait(event_pool->fd, &event, 1, -1);
+
+ if (ret == 0)
+ /* timeout */
+ continue;
+
+ if (ret == -1 && errno == EINTR)
+ /* sys call */
+ continue;
+
+ ret = event_dispatch_epoll_handler(event_pool, &event);
+ if (ret) {
+ gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_DISPATCH_HANDLER_FAILED,
+ NULL);
+ }
+ }
+out:
+ if (ev_data)
+ GF_FREE(ev_data);
+ return NULL;
+}
+
+/* Attempts to start the # of configured pollers, ensuring at least the first
+ * is started in a joinable state */
+static int
+event_dispatch_epoll(struct event_pool *event_pool)
+{
+ int i = 0;
+ pthread_t t_id;
+ int pollercount = 0;
+ int ret = -1;
+ struct event_thread_data *ev_data = NULL;
+
+ /* Start the configured number of pollers */
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ pollercount = event_pool->eventthreadcount;
+
+ /* Set to MAX if greater */
+ if (pollercount > EVENT_MAX_THREADS)
+ pollercount = EVENT_MAX_THREADS;
+
+ /* Default pollers to 1 in case this is incorrectly set */
+ if (pollercount <= 0)
+ pollercount = 1;
+
+ event_pool->activethreadcount++;
+
+ for (i = 0; i < pollercount; i++) {
+ ev_data = GF_CALLOC(1, sizeof(*ev_data), gf_common_mt_event_pool);
+ if (!ev_data) {
+ if (i == 0) {
+ /* Need to succeed creating 0'th
+ * thread, to joinable and wait */
+ break;
+ } else {
+ /* Inability to create other threads
+ * are a lesser evil, and ignored */
+ continue;
+ }
+ }
+
+ ev_data->event_pool = event_pool;
+ ev_data->event_index = i + 1;
+
+ ret = gf_thread_create(&t_id, NULL, event_dispatch_epoll_worker,
+ ev_data, "epoll%03hx", i & 0x3ff);
+ if (!ret) {
+ event_pool->pollers[i] = t_id;
+
+ /* mark all threads other than one in index 0
+ * as detachable. Errors can be ignored, they
+ * spend their time as zombies if not detched
+ * and the thread counts are decreased */
+ if (i != 0)
+ pthread_detach(event_pool->pollers[i]);
+ } else {
+ gf_smsg("epoll", GF_LOG_WARNING, 0,
+ LG_MSG_START_EPOLL_THREAD_FAILED, "index=%d", i, NULL);
+ if (i == 0) {
+ GF_FREE(ev_data);
+ break;
+ } else {
+ GF_FREE(ev_data);
+ continue;
+ }
+ }
+ }
+ }
+ pthread_mutex_unlock(&event_pool->mutex);
+
+ /* Just wait for the first thread, that is created in a joinable state
+ * and will never die, ensuring this function never returns */
+ if (event_pool->pollers[0] != 0)
+ pthread_join(event_pool->pollers[0], NULL);
+
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ event_pool->activethreadcount--;
+ }
+ pthread_mutex_unlock(&event_pool->mutex);
+
+ return ret;
+}
+
+/**
+ * @param event_pool event_pool on which fds of interest are registered for
+ * events.
+ *
+ * @return 1 if at least one epoll worker thread is spawned, 0 otherwise
+ *
+ * NB This function SHOULD be called under event_pool->mutex.
+ */
+
+static int
+event_pool_dispatched_unlocked(struct event_pool *event_pool)
+{
+ return (event_pool->pollers[0] != 0);
+}
+
+int
+event_reconfigure_threads_epoll(struct event_pool *event_pool, int value)
+{
+ int i;
+ int ret = 0;
+ pthread_t t_id;
+ int oldthreadcount;
+ struct event_thread_data *ev_data = NULL;
+
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ /* Reconfigure to 0 threads is allowed only in destroy mode */
+ if (event_pool->destroy == 1) {
+ value = 0;
+ } else {
+ /* Set to MAX if greater */
+ if (value > EVENT_MAX_THREADS)
+ value = EVENT_MAX_THREADS;
+
+ /* Default pollers to 1 in case this is set incorrectly */
+ if (value <= 0)
+ value = 1;
+ }
+
+ oldthreadcount = event_pool->eventthreadcount;
+
+ /* Start 'worker' threads as necessary only if event_dispatch()
+ * was called before. If event_dispatch() was not called, there
+ * will be no epoll 'worker' threads running yet. */
+
+ if (event_pool_dispatched_unlocked(event_pool) &&
+ (oldthreadcount < value)) {
+ /* create more poll threads */
+ for (i = oldthreadcount; i < value; i++) {
+ /* Start a thread if the index at this location
+ * is a 0, so that the older thread is confirmed
+ * as dead */
+ if (event_pool->pollers[i] == 0) {
+ ev_data = GF_CALLOC(1, sizeof(*ev_data),
+ gf_common_mt_event_pool);
+ if (!ev_data) {
+ continue;
+ }
+
+ ev_data->event_pool = event_pool;
+ ev_data->event_index = i + 1;
+
+ ret = gf_thread_create(&t_id, NULL,
+ event_dispatch_epoll_worker, ev_data,
+ "epoll%03hx", i & 0x3ff);
+ if (ret) {
+ gf_smsg("epoll", GF_LOG_WARNING, 0,
+ LG_MSG_START_EPOLL_THREAD_FAILED, "index=%d", i,
+ NULL);
+ GF_FREE(ev_data);
+ } else {
+ pthread_detach(t_id);
+ event_pool->pollers[i] = t_id;
+ }
+ }
+ }
+ }
+
+ /* if value decreases, threads will terminate, themselves */
+ event_pool->eventthreadcount = value;
+ }
+ pthread_mutex_unlock(&event_pool->mutex);
+
+ return 0;
+}
+
+/* This function is the destructor for the event_pool data structure
+ * Should be called only after poller_threads_destroy() is called,
+ * else will lead to crashes.
+ */
+static int
+event_pool_destroy_epoll(struct event_pool *event_pool)
+{
+ int ret = 0, i = 0, j = 0;
+ struct event_slot_epoll *table = NULL;
+
+ ret = sys_close(event_pool->fd);
+
+ for (i = 0; i < EVENT_EPOLL_TABLES; i++) {
+ if (event_pool->ereg[i]) {
+ table = event_pool->ereg[i];
+ event_pool->ereg[i] = NULL;
+ for (j = 0; j < EVENT_EPOLL_SLOTS; j++) {
+ LOCK_DESTROY(&table[j].lock);
+ }
+ GF_FREE(table);
+ }
+ }
+
+ pthread_mutex_destroy(&event_pool->mutex);
+ pthread_cond_destroy(&event_pool->cond);
+
+ GF_FREE(event_pool->evcache);
+ GF_FREE(event_pool->reg);
+ GF_FREE(event_pool);
+
+ return ret;
+}
+
+static int
+event_handled_epoll(struct event_pool *event_pool, int fd, int idx, int gen)
+{
+ struct event_slot_epoll *slot = NULL;
+ struct epoll_event epoll_event = {
+ 0,
+ };
+ struct event_data *ev_data = (void *)&epoll_event.data;
+ int ret = 0;
+
+ slot = event_slot_get(event_pool, idx);
+ if (!slot) {
+ gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, "fd=%d", fd,
+ "idx=%d", idx, NULL);
+ return -1;
+ }
+
+ assert(slot->fd == fd);
+
+ LOCK(&slot->lock);
+ {
+ slot->in_handler--;
+
+ if (gen != slot->gen) {
+ /* event_unregister() happened while we were
+ in handler()
+ */
+ gf_msg_debug("epoll", 0,
+ "generation bumped on idx=%d"
+ " from gen=%d to slot->gen=%d, fd=%d, "
+ "slot->fd=%d",
+ idx, gen, slot->gen, fd, slot->fd);
+ goto unlock;
+ }
+
+ /* This call also picks up the changes made by another
+ thread calling event_select_on_epoll() while this
+ thread was busy in handler()
+ */
+ if (slot->in_handler == 0) {
+ epoll_event.events = slot->events;
+ ev_data->idx = idx;
+ ev_data->gen = gen;
+
+ ret = epoll_ctl(event_pool->fd, EPOLL_CTL_MOD, fd, &epoll_event);
+ }
+ }
+unlock:
+ UNLOCK(&slot->lock);
+
+ event_slot_unref(event_pool, slot, idx);
+
+ return ret;
+}
+
+struct event_ops event_ops_epoll = {
+ .new = event_pool_new_epoll,
+ .event_register = event_register_epoll,
+ .event_select_on = event_select_on_epoll,
+ .event_unregister = event_unregister_epoll,
+ .event_unregister_close = event_unregister_close_epoll,
+ .event_dispatch = event_dispatch_epoll,
+ .event_reconfigure_threads = event_reconfigure_threads_epoll,
+ .event_pool_destroy = event_pool_destroy_epoll,
+ .event_handled = event_handled_epoll,
+};
+
+#endif
diff --git a/libglusterfs/src/event-history.c b/libglusterfs/src/event-history.c
new file mode 100644
index 00000000000..379fed866be
--- /dev/null
+++ b/libglusterfs/src/event-history.c
@@ -0,0 +1,82 @@
+/*
+ Copyright (c) 2008-2012 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 "glusterfs/event-history.h"
+#include "glusterfs/libglusterfs-messages.h"
+
+eh_t *
+eh_new(size_t buffer_size, gf_boolean_t use_buffer_once,
+ void (*destroy_buffer_data)(void *data))
+{
+ eh_t *history = NULL;
+ buffer_t *buffer = NULL;
+
+ history = GF_CALLOC(1, sizeof(eh_t), gf_common_mt_eh_t);
+ if (!history) {
+ goto out;
+ }
+
+ buffer = cb_buffer_new(buffer_size, use_buffer_once, destroy_buffer_data);
+ if (!buffer) {
+ GF_FREE(history);
+ history = NULL;
+ goto out;
+ }
+
+ history->buffer = buffer;
+
+ pthread_mutex_init(&history->lock, NULL);
+out:
+ return history;
+}
+
+void
+eh_dump(eh_t *history, void *data,
+ int(dump_fn)(circular_buffer_t *buffer, void *data))
+{
+ if (!history) {
+ gf_msg_debug("event-history", 0, "history is NULL");
+ goto out;
+ }
+
+ cb_buffer_dump(history->buffer, data, dump_fn);
+
+out:
+ return;
+}
+
+int
+eh_save_history(eh_t *history, void *data)
+{
+ int ret = -1;
+
+ ret = cb_add_entry_buffer(history->buffer, data);
+
+ return ret;
+}
+
+int
+eh_destroy(eh_t *history)
+{
+ if (!history) {
+ gf_msg("event-history", GF_LOG_INFO, 0, LG_MSG_INVALID_ARG,
+ "history for the xlator is NULL");
+ return -1;
+ }
+
+ cb_buffer_destroy(history->buffer);
+ history->buffer = NULL;
+
+ pthread_mutex_destroy(&history->lock);
+
+ GF_FREE(history);
+
+ return 0;
+}
diff --git a/libglusterfs/src/event-poll.c b/libglusterfs/src/event-poll.c
new file mode 100644
index 00000000000..2cba963f096
--- /dev/null
+++ b/libglusterfs/src/event-poll.c
@@ -0,0 +1,513 @@
+/*
+ Copyright (c) 2012 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 <sys/poll.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+
+#include "glusterfs/logging.h"
+#include "glusterfs/gf-event.h"
+#include "glusterfs/mem-pool.h"
+#include "glusterfs/common-utils.h"
+#include "glusterfs/syscall.h"
+#include "glusterfs/libglusterfs-messages.h"
+
+struct event_slot_poll {
+ int fd;
+ int events;
+ void *data;
+ event_handler_t handler;
+};
+
+static int
+event_register_poll(struct event_pool *event_pool, int fd,
+ event_handler_t handler, void *data, int poll_in,
+ int poll_out, char notify_poller_death);
+
+static void
+__flush_fd(int fd, int idx, int gen, void *data, int poll_in, int poll_out,
+ int poll_err, char event_thread_died)
+{
+ char buf[64];
+ int ret = -1;
+
+ if (!poll_in)
+ return;
+
+ do {
+ ret = sys_read(fd, buf, 64);
+ if (ret == -1 && errno != EAGAIN) {
+ gf_smsg("poll", GF_LOG_ERROR, errno, LG_MSG_READ_FILE_FAILED,
+ "fd=%d", fd, NULL);
+ }
+ } while (ret == 64);
+
+ return;
+}
+
+static int
+__event_getindex(struct event_pool *event_pool, int fd, int idx)
+{
+ int ret = -1;
+ int i = 0;
+
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
+
+ /* lookup in used space based on index provided */
+ if (idx > -1 && idx < event_pool->used) {
+ if (event_pool->reg[idx].fd == fd) {
+ ret = idx;
+ goto out;
+ }
+ }
+
+ /* search in used space, if lookup fails */
+ for (i = 0; i < event_pool->used; i++) {
+ if (event_pool->reg[i].fd == fd) {
+ ret = i;
+ break;
+ }
+ }
+
+out:
+ return ret;
+}
+
+static struct event_pool *
+event_pool_new_poll(int count, int eventthreadcount)
+{
+ struct event_pool *event_pool = NULL;
+ int ret = -1;
+
+ event_pool = GF_CALLOC(1, sizeof(*event_pool), gf_common_mt_event_pool);
+
+ if (!event_pool)
+ return NULL;
+
+ event_pool->count = count;
+ event_pool->reg = GF_CALLOC(event_pool->count, sizeof(*event_pool->reg),
+ gf_common_mt_reg);
+
+ if (!event_pool->reg) {
+ GF_FREE(event_pool);
+ return NULL;
+ }
+
+ pthread_mutex_init(&event_pool->mutex, NULL);
+
+ ret = pipe(event_pool->breaker);
+
+ if (ret == -1) {
+ gf_smsg("poll", GF_LOG_ERROR, errno, LG_MSG_PIPE_CREATE_FAILED, NULL);
+ GF_FREE(event_pool->reg);
+ GF_FREE(event_pool);
+ return NULL;
+ }
+
+ ret = fcntl(event_pool->breaker[0], F_SETFL, O_NONBLOCK);
+ if (ret == -1) {
+ gf_smsg("poll", GF_LOG_ERROR, errno, LG_MSG_SET_PIPE_FAILED, NULL);
+ sys_close(event_pool->breaker[0]);
+ sys_close(event_pool->breaker[1]);
+ event_pool->breaker[0] = event_pool->breaker[1] = -1;
+
+ GF_FREE(event_pool->reg);
+ GF_FREE(event_pool);
+ return NULL;
+ }
+
+ ret = fcntl(event_pool->breaker[1], F_SETFL, O_NONBLOCK);
+ if (ret == -1) {
+ gf_smsg("poll", GF_LOG_ERROR, errno, LG_MSG_SET_PIPE_FAILED, NULL);
+
+ sys_close(event_pool->breaker[0]);
+ sys_close(event_pool->breaker[1]);
+ event_pool->breaker[0] = event_pool->breaker[1] = -1;
+
+ GF_FREE(event_pool->reg);
+ GF_FREE(event_pool);
+ return NULL;
+ }
+
+ ret = event_register_poll(event_pool, event_pool->breaker[0], __flush_fd,
+ NULL, 1, 0, 0);
+ if (ret == -1) {
+ gf_smsg("poll", GF_LOG_ERROR, 0, LG_MSG_REGISTER_PIPE_FAILED, NULL);
+ sys_close(event_pool->breaker[0]);
+ sys_close(event_pool->breaker[1]);
+ event_pool->breaker[0] = event_pool->breaker[1] = -1;
+
+ GF_FREE(event_pool->reg);
+ GF_FREE(event_pool);
+ return NULL;
+ }
+
+ if (eventthreadcount > 1) {
+ gf_smsg("poll", GF_LOG_INFO, 0, LG_MSG_POLL_IGNORE_MULTIPLE_THREADS,
+ "count=%d", eventthreadcount, NULL);
+ }
+
+ /* although, eventhreadcount for poll implementation is always
+ * going to be 1, eventthreadcount needs to be set to 1 so that
+ * rpcsvc_request_handler() thread scaling works flawlessly in
+ * both epoll and poll models
+ */
+ event_pool->eventthreadcount = 1;
+
+ return event_pool;
+}
+
+static int
+event_register_poll(struct event_pool *event_pool, int fd,
+ event_handler_t handler, void *data, int poll_in,
+ int poll_out, char notify_poller_death)
+{
+ int idx = -1;
+
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
+
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ if (event_pool->count == event_pool->used) {
+ event_pool->count += 256;
+
+ event_pool->reg = GF_REALLOC(
+ event_pool->reg, event_pool->count * sizeof(*event_pool->reg));
+ if (!event_pool->reg)
+ goto unlock;
+ }
+
+ idx = event_pool->used++;
+
+ event_pool->reg[idx].fd = fd;
+ event_pool->reg[idx].events = POLLPRI;
+ event_pool->reg[idx].handler = handler;
+ event_pool->reg[idx].data = data;
+
+ switch (poll_in) {
+ case 1:
+ event_pool->reg[idx].events |= POLLIN;
+ break;
+ case 0:
+ event_pool->reg[idx].events &= ~POLLIN;
+ break;
+ case -1:
+ /* do nothing */
+ break;
+ default:
+ gf_smsg("poll", GF_LOG_ERROR, 0, LG_MSG_INVALID_POLL_IN,
+ "value=%d", poll_in, NULL);
+ break;
+ }
+
+ switch (poll_out) {
+ case 1:
+ event_pool->reg[idx].events |= POLLOUT;
+ break;
+ case 0:
+ event_pool->reg[idx].events &= ~POLLOUT;
+ break;
+ case -1:
+ /* do nothing */
+ break;
+ default:
+ gf_smsg("poll", GF_LOG_ERROR, 0, LG_MSG_INVALID_POLL_OUT,
+ "value=%d", poll_out, NULL);
+ break;
+ }
+
+ event_pool->changed = 1;
+ }
+unlock:
+ pthread_mutex_unlock(&event_pool->mutex);
+
+out:
+ return idx;
+}
+
+static int
+event_unregister_poll(struct event_pool *event_pool, int fd, int idx_hint)
+{
+ int idx = -1;
+
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
+
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ idx = __event_getindex(event_pool, fd, idx_hint);
+
+ if (idx == -1) {
+ gf_smsg("poll", GF_LOG_ERROR, 0, LG_MSG_INDEX_NOT_FOUND, "fd=%d",
+ fd, "idx_hint=%d", idx_hint, NULL);
+ errno = ENOENT;
+ goto unlock;
+ }
+
+ event_pool->reg[idx] = event_pool->reg[--event_pool->used];
+ event_pool->changed = 1;
+ }
+unlock:
+ pthread_mutex_unlock(&event_pool->mutex);
+
+out:
+ return idx;
+}
+
+static int
+event_unregister_close_poll(struct event_pool *event_pool, int fd, int idx_hint)
+{
+ int ret = -1;
+
+ ret = event_unregister_poll(event_pool, fd, idx_hint);
+
+ sys_close(fd);
+
+ return ret;
+}
+
+static int
+event_select_on_poll(struct event_pool *event_pool, int fd, int idx_hint,
+ int poll_in, int poll_out)
+{
+ int idx = -1;
+
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
+
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ idx = __event_getindex(event_pool, fd, idx_hint);
+
+ if (idx == -1) {
+ gf_smsg("poll", GF_LOG_ERROR, 0, LG_MSG_INDEX_NOT_FOUND, "fd=%d",
+ fd, "idx_hint=%d", idx_hint, NULL);
+ errno = ENOENT;
+ goto unlock;
+ }
+
+ switch (poll_in) {
+ case 1:
+ event_pool->reg[idx].events |= POLLIN;
+ break;
+ case 0:
+ event_pool->reg[idx].events &= ~POLLIN;
+ break;
+ case -1:
+ /* do nothing */
+ break;
+ default:
+ /* TODO: log error */
+ break;
+ }
+
+ switch (poll_out) {
+ case 1:
+ event_pool->reg[idx].events |= POLLOUT;
+ break;
+ case 0:
+ event_pool->reg[idx].events &= ~POLLOUT;
+ break;
+ case -1:
+ /* do nothing */
+ break;
+ default:
+ /* TODO: log error */
+ break;
+ }
+
+ if (poll_in + poll_out > -2)
+ event_pool->changed = 1;
+ }
+unlock:
+ pthread_mutex_unlock(&event_pool->mutex);
+
+out:
+ return idx;
+}
+
+static int
+event_dispatch_poll_handler(struct event_pool *event_pool, struct pollfd *ufds,
+ int i)
+{
+ event_handler_t handler = NULL;
+ void *data = NULL;
+ int idx = -1;
+ int ret = 0;
+
+ handler = NULL;
+ data = NULL;
+
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ idx = __event_getindex(event_pool, ufds[i].fd, i);
+
+ if (idx == -1) {
+ gf_smsg("poll", GF_LOG_ERROR, 0, LG_MSG_INDEX_NOT_FOUND, "fd=%d",
+ ufds[i].fd, "idx_hint=%d", i, NULL);
+ goto unlock;
+ }
+
+ handler = event_pool->reg[idx].handler;
+ data = event_pool->reg[idx].data;
+ }
+unlock:
+ pthread_mutex_unlock(&event_pool->mutex);
+
+ if (handler)
+ handler(ufds[i].fd, idx, 0, data,
+ (ufds[i].revents & (POLLIN | POLLPRI)),
+ (ufds[i].revents & (POLLOUT)),
+ (ufds[i].revents & (POLLERR | POLLHUP | POLLNVAL)), 0);
+
+ return ret;
+}
+
+static int
+event_dispatch_poll_resize(struct event_pool *event_pool, struct pollfd *ufds,
+ int size)
+{
+ int i = 0;
+
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ if (event_pool->changed == 0) {
+ goto unlock;
+ }
+
+ if (event_pool->used > event_pool->evcache_size) {
+ GF_FREE(event_pool->evcache);
+
+ event_pool->evcache = ufds = NULL;
+
+ event_pool->evcache_size = event_pool->used;
+
+ ufds = GF_CALLOC(sizeof(struct pollfd), event_pool->evcache_size,
+ gf_common_mt_pollfd);
+ if (!ufds)
+ goto unlock;
+ event_pool->evcache = ufds;
+ }
+
+ if (ufds == NULL) {
+ goto unlock;
+ }
+
+ for (i = 0; i < event_pool->used; i++) {
+ ufds[i].fd = event_pool->reg[i].fd;
+ ufds[i].events = event_pool->reg[i].events;
+ ufds[i].revents = 0;
+ }
+
+ size = i;
+ }
+unlock:
+ pthread_mutex_unlock(&event_pool->mutex);
+
+ return size;
+}
+
+static int
+event_dispatch_poll(struct event_pool *event_pool)
+{
+ struct pollfd *ufds = NULL;
+ int size = 0;
+ int i = 0;
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
+
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ event_pool->activethreadcount = 1;
+ }
+ pthread_mutex_unlock(&event_pool->mutex);
+
+ while (1) {
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ if (event_pool->destroy == 1) {
+ event_pool->activethreadcount = 0;
+ pthread_cond_broadcast(&event_pool->cond);
+ pthread_mutex_unlock(&event_pool->mutex);
+ return 0;
+ }
+ }
+ pthread_mutex_unlock(&event_pool->mutex);
+
+ size = event_dispatch_poll_resize(event_pool, ufds, size);
+ ufds = event_pool->evcache;
+
+ ret = poll(ufds, size, 1);
+
+ if (ret == 0)
+ /* timeout */
+ continue;
+
+ if (ret == -1 && errno == EINTR)
+ /* sys call */
+ continue;
+
+ for (i = 0; i < size; i++) {
+ if (!ufds[i].revents)
+ continue;
+
+ event_dispatch_poll_handler(event_pool, ufds, i);
+ }
+ }
+
+out:
+ return -1;
+}
+
+int
+event_reconfigure_threads_poll(struct event_pool *event_pool, int value)
+{
+ /* No-op for poll */
+
+ return 0;
+}
+
+/* This function is the destructor for the event_pool data structure
+ * Should be called only after poller_threads_destroy() is called,
+ * else will lead to crashes.
+ */
+static int
+event_pool_destroy_poll(struct event_pool *event_pool)
+{
+ int ret = 0;
+
+ ret = sys_close(event_pool->breaker[0]);
+ if (ret)
+ return ret;
+
+ ret = sys_close(event_pool->breaker[1]);
+ if (ret)
+ return ret;
+
+ event_pool->breaker[0] = event_pool->breaker[1] = -1;
+
+ GF_FREE(event_pool->reg);
+ GF_FREE(event_pool);
+
+ return ret;
+}
+
+struct event_ops event_ops_poll = {
+ .new = event_pool_new_poll,
+ .event_register = event_register_poll,
+ .event_select_on = event_select_on_poll,
+ .event_unregister = event_unregister_poll,
+ .event_unregister_close = event_unregister_close_poll,
+ .event_dispatch = event_dispatch_poll,
+ .event_reconfigure_threads = event_reconfigure_threads_poll,
+ .event_pool_destroy = event_pool_destroy_poll};
diff --git a/libglusterfs/src/event.c b/libglusterfs/src/event.c
index c117a4ae20a..402c253ca25 100644
--- a/libglusterfs/src/event.c
+++ b/libglusterfs/src/event.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 <sys/poll.h>
@@ -25,936 +16,290 @@
#include <errno.h>
#include <string.h>
-#include "logging.h"
-#include "event.h"
-#include "mem-pool.h"
-#include "common-utils.h"
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-static int
-event_register_poll (struct event_pool *event_pool, int fd,
- event_handler_t handler,
- void *data, int poll_in, int poll_out);
-
-
-static int
-__flush_fd (int fd, int idx, void *data,
- int poll_in, int poll_out, int poll_err)
-{
- char buf[64];
- int ret = -1;
-
- if (!poll_in)
- return ret;
-
- do {
- ret = read (fd, buf, 64);
- if (ret == -1 && errno != EAGAIN) {
- gf_log ("poll", GF_LOG_ERROR,
- "read on %d returned error (%s)",
- fd, strerror (errno));
- }
- } while (ret == 64);
-
- return ret;
-}
-
-
-static int
-__event_getindex (struct event_pool *event_pool, int fd, int idx)
-{
- int ret = -1;
- int i = 0;
-
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
-
- if (idx > -1 && idx < event_pool->used) {
- if (event_pool->reg[idx].fd == fd)
- ret = idx;
- }
-
- for (i=0; ret == -1 && i<event_pool->used; i++) {
- if (event_pool->reg[i].fd == fd) {
- ret = i;
- break;
- }
- }
-
-out:
- return ret;
-}
-
+#include "glusterfs/gf-event.h"
+#include "glusterfs/timespec.h"
+#include "glusterfs/common-utils.h"
+#include "glusterfs/libglusterfs-messages.h"
+#include "glusterfs/syscall.h"
-static struct event_pool *
-event_pool_new_poll (int count)
+struct event_pool *
+gf_event_pool_new(int count, int eventthreadcount)
{
- struct event_pool *event_pool = NULL;
- int ret = -1;
-
- event_pool = GF_CALLOC (1, sizeof (*event_pool),
- gf_common_mt_event_pool);
-
- if (!event_pool)
- return NULL;
-
- event_pool->count = count;
- event_pool->reg = GF_CALLOC (event_pool->count,
- sizeof (*event_pool->reg),
- gf_common_mt_reg);
-
- if (!event_pool->reg) {
- GF_FREE (event_pool);
- return NULL;
- }
-
- pthread_mutex_init (&event_pool->mutex, NULL);
-
- ret = pipe (event_pool->breaker);
-
- if (ret == -1) {
- gf_log ("poll", GF_LOG_ERROR,
- "pipe creation failed (%s)", strerror (errno));
- GF_FREE (event_pool->reg);
- GF_FREE (event_pool);
- return NULL;
- }
+ struct event_pool *event_pool = NULL;
+ extern struct event_ops event_ops_poll;
- ret = fcntl (event_pool->breaker[0], F_SETFL, O_NONBLOCK);
- if (ret == -1) {
- gf_log ("poll", GF_LOG_ERROR,
- "could not set pipe to non blocking mode (%s)",
- strerror (errno));
- close (event_pool->breaker[0]);
- close (event_pool->breaker[1]);
- event_pool->breaker[0] = event_pool->breaker[1] = -1;
-
- GF_FREE (event_pool->reg);
- GF_FREE (event_pool);
- return NULL;
- }
+#ifdef HAVE_SYS_EPOLL_H
+ extern struct event_ops event_ops_epoll;
- ret = fcntl (event_pool->breaker[1], F_SETFL, O_NONBLOCK);
- if (ret == -1) {
- gf_log ("poll", GF_LOG_ERROR,
- "could not set pipe to non blocking mode (%s)",
- strerror (errno));
+ event_pool = event_ops_epoll.new(count, eventthreadcount);
- close (event_pool->breaker[0]);
- close (event_pool->breaker[1]);
- event_pool->breaker[0] = event_pool->breaker[1] = -1;
+ if (event_pool) {
+ event_pool->ops = &event_ops_epoll;
+ } else {
+ gf_msg("event", GF_LOG_WARNING, 0, LG_MSG_FALLBACK_TO_POLL,
+ "falling back to poll based event handling");
+ }
+#endif
- GF_FREE (event_pool->reg);
- GF_FREE (event_pool);
- return NULL;
- }
+ if (!event_pool) {
+ event_pool = event_ops_poll.new(count, eventthreadcount);
- ret = event_register_poll (event_pool, event_pool->breaker[0],
- __flush_fd, NULL, 1, 0);
- if (ret == -1) {
- gf_log ("poll", GF_LOG_ERROR,
- "could not register pipe fd with poll event loop");
- close (event_pool->breaker[0]);
- close (event_pool->breaker[1]);
- event_pool->breaker[0] = event_pool->breaker[1] = -1;
-
- GF_FREE (event_pool->reg);
- GF_FREE (event_pool);
- return NULL;
- }
+ if (event_pool)
+ event_pool->ops = &event_ops_poll;
+ }
- return event_pool;
+ return event_pool;
}
-
-static int
-event_register_poll (struct event_pool *event_pool, int fd,
- event_handler_t handler,
- void *data, int poll_in, int poll_out)
+int
+gf_event_register(struct event_pool *event_pool, int fd,
+ event_handler_t handler, void *data, int poll_in,
+ int poll_out, char notify_poller_death)
{
- int idx = -1;
-
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
-
- pthread_mutex_lock (&event_pool->mutex);
- {
- if (event_pool->count == event_pool->used)
- {
- event_pool->count += 256;
-
- event_pool->reg = GF_REALLOC (event_pool->reg,
- event_pool->count *
- sizeof (*event_pool->reg));
- if (!event_pool->reg)
- goto unlock;
- }
-
- idx = event_pool->used++;
-
- event_pool->reg[idx].fd = fd;
- event_pool->reg[idx].events = POLLPRI;
- event_pool->reg[idx].handler = handler;
- event_pool->reg[idx].data = data;
-
- switch (poll_in) {
- case 1:
- event_pool->reg[idx].events |= POLLIN;
- break;
- case 0:
- event_pool->reg[idx].events &= ~POLLIN;
- break;
- case -1:
- /* do nothing */
- break;
- default:
- gf_log ("poll", GF_LOG_ERROR,
- "invalid poll_in value %d", poll_in);
- break;
- }
-
- switch (poll_out) {
- case 1:
- event_pool->reg[idx].events |= POLLOUT;
- break;
- case 0:
- event_pool->reg[idx].events &= ~POLLOUT;
- break;
- case -1:
- /* do nothing */
- break;
- default:
- gf_log ("poll", GF_LOG_ERROR,
- "invalid poll_out value %d", poll_out);
- break;
- }
-
- event_pool->changed = 1;
+ int ret = -1;
- }
-unlock:
- pthread_mutex_unlock (&event_pool->mutex);
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
+ ret = event_pool->ops->event_register(
+ event_pool, fd, handler, data, poll_in, poll_out, notify_poller_death);
out:
- return idx;
+ return ret;
}
-
-static int
-event_unregister_poll (struct event_pool *event_pool, int fd, int idx_hint)
+int
+gf_event_unregister(struct event_pool *event_pool, int fd, int idx)
{
- int idx = -1;
-
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
-
- pthread_mutex_lock (&event_pool->mutex);
- {
- idx = __event_getindex (event_pool, fd, idx_hint);
-
- if (idx == -1) {
- gf_log ("poll", GF_LOG_ERROR,
- "index not found for fd=%d (idx_hint=%d)",
- fd, idx_hint);
- errno = ENOENT;
- goto unlock;
- }
-
- event_pool->reg[idx] = event_pool->reg[--event_pool->used];
- event_pool->changed = 1;
- }
-unlock:
- pthread_mutex_unlock (&event_pool->mutex);
+ int ret = -1;
-out:
- return idx;
-}
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
-
-static int
-event_select_on_poll (struct event_pool *event_pool, int fd, int idx_hint,
- int poll_in, int poll_out)
-{
- int idx = -1;
-
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
-
- pthread_mutex_lock (&event_pool->mutex);
- {
- idx = __event_getindex (event_pool, fd, idx_hint);
-
- if (idx == -1) {
- gf_log ("poll", GF_LOG_ERROR,
- "index not found for fd=%d (idx_hint=%d)",
- fd, idx_hint);
- errno = ENOENT;
- goto unlock;
- }
-
- switch (poll_in) {
- case 1:
- event_pool->reg[idx].events |= POLLIN;
- break;
- case 0:
- event_pool->reg[idx].events &= ~POLLIN;
- break;
- case -1:
- /* do nothing */
- break;
- default:
- /* TODO: log error */
- break;
- }
-
- switch (poll_out) {
- case 1:
- event_pool->reg[idx].events |= POLLOUT;
- break;
- case 0:
- event_pool->reg[idx].events &= ~POLLOUT;
- break;
- case -1:
- /* do nothing */
- break;
- default:
- /* TODO: log error */
- break;
- }
-
- if (poll_in + poll_out > -2)
- event_pool->changed = 1;
- }
-unlock:
- pthread_mutex_unlock (&event_pool->mutex);
+ ret = event_pool->ops->event_unregister(event_pool, fd, idx);
out:
- return idx;
-}
-
-
-static int
-event_dispatch_poll_handler (struct event_pool *event_pool,
- struct pollfd *ufds, int i)
-{
- event_handler_t handler = NULL;
- void *data = NULL;
- int idx = -1;
- int ret = 0;
-
- handler = NULL;
- data = NULL;
-
- pthread_mutex_lock (&event_pool->mutex);
- {
- idx = __event_getindex (event_pool, ufds[i].fd, i);
-
- if (idx == -1) {
- gf_log ("poll", GF_LOG_ERROR,
- "index not found for fd=%d (idx_hint=%d)",
- ufds[i].fd, i);
- goto unlock;
- }
-
- handler = event_pool->reg[idx].handler;
- data = event_pool->reg[idx].data;
- }
-unlock:
- pthread_mutex_unlock (&event_pool->mutex);
-
- if (handler)
- ret = handler (ufds[i].fd, idx, data,
- (ufds[i].revents & (POLLIN|POLLPRI)),
- (ufds[i].revents & (POLLOUT)),
- (ufds[i].revents & (POLLERR|POLLHUP|POLLNVAL)));
-
- return ret;
+ return ret;
}
-
-static int
-event_dispatch_poll_resize (struct event_pool *event_pool,
- struct pollfd *ufds, int size)
-{
- int i = 0;
-
- pthread_mutex_lock (&event_pool->mutex);
- {
- if (event_pool->changed == 0) {
- goto unlock;
- }
-
- if (event_pool->used > event_pool->evcache_size) {
- if (event_pool->evcache)
- GF_FREE (event_pool->evcache);
-
- event_pool->evcache = ufds = NULL;
-
- event_pool->evcache_size = event_pool->used;
-
- ufds = GF_CALLOC (sizeof (struct pollfd),
- event_pool->evcache_size,
- gf_common_mt_pollfd);
- if (!ufds)
- goto unlock;
- event_pool->evcache = ufds;
- }
-
- for (i = 0; i < event_pool->used; i++) {
- ufds[i].fd = event_pool->reg[i].fd;
- ufds[i].events = event_pool->reg[i].events;
- ufds[i].revents = 0;
- }
-
- size = i;
- }
-unlock:
- pthread_mutex_unlock (&event_pool->mutex);
-
- return size;
-}
-
-
-static int
-event_dispatch_poll (struct event_pool *event_pool)
+int
+gf_event_unregister_close(struct event_pool *event_pool, int fd, int idx)
{
- struct pollfd *ufds = NULL;
- int size = 0;
- int i = 0;
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
-
- while (1) {
- size = event_dispatch_poll_resize (event_pool, ufds, size);
- ufds = event_pool->evcache;
+ int ret = -1;
- ret = poll (ufds, size, 1);
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
- if (ret == 0)
- /* timeout */
- continue;
-
- if (ret == -1 && errno == EINTR)
- /* sys call */
- continue;
-
- for (i = 0; i < size; i++) {
- if (!ufds[i].revents)
- continue;
-
- event_dispatch_poll_handler (event_pool, ufds, i);
- }
- }
+ ret = event_pool->ops->event_unregister_close(event_pool, fd, idx);
out:
- return -1;
+ return ret;
}
-
-static struct event_ops event_ops_poll = {
- .new = event_pool_new_poll,
- .event_register = event_register_poll,
- .event_select_on = event_select_on_poll,
- .event_unregister = event_unregister_poll,
- .event_dispatch = event_dispatch_poll
-};
-
-
-
-#ifdef HAVE_SYS_EPOLL_H
-#include <sys/epoll.h>
-
-
-static struct event_pool *
-event_pool_new_epoll (int count)
+int
+gf_event_select_on(struct event_pool *event_pool, int fd, int idx_hint,
+ int poll_in, int poll_out)
{
- struct event_pool *event_pool = NULL;
- int epfd = -1;
-
- event_pool = GF_CALLOC (1, sizeof (*event_pool),
- gf_common_mt_event_pool);
-
- if (!event_pool)
- goto out;
+ int ret = -1;
- event_pool->count = count;
- event_pool->reg = GF_CALLOC (event_pool->count,
- sizeof (*event_pool->reg),
- gf_common_mt_reg);
-
- if (!event_pool->reg) {
- GF_FREE (event_pool);
- event_pool = NULL;
- goto out;
- }
-
- epfd = epoll_create (count);
-
- if (epfd == -1) {
- gf_log ("epoll", GF_LOG_ERROR, "epoll fd creation failed (%s)",
- strerror (errno));
- GF_FREE (event_pool->reg);
- GF_FREE (event_pool);
- event_pool = NULL;
- goto out;
- }
-
- event_pool->fd = epfd;
-
- event_pool->count = count;
-
- pthread_mutex_init (&event_pool->mutex, NULL);
- pthread_cond_init (&event_pool->cond, NULL);
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
+ ret = event_pool->ops->event_select_on(event_pool, fd, idx_hint, poll_in,
+ poll_out);
out:
- return event_pool;
+ return ret;
}
-
int
-event_register_epoll (struct event_pool *event_pool, int fd,
- event_handler_t handler,
- void *data, int poll_in, int poll_out)
-{
- int idx = -1;
- int ret = -1;
- struct epoll_event epoll_event = {0, };
- struct event_data *ev_data = (void *)&epoll_event.data;
-
-
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
-
- pthread_mutex_lock (&event_pool->mutex);
- {
- if (event_pool->count == event_pool->used) {
- event_pool->count *= 2;
-
- event_pool->reg = GF_REALLOC (event_pool->reg,
- event_pool->count *
- sizeof (*event_pool->reg));
-
- if (!event_pool->reg) {
- gf_log ("epoll", GF_LOG_ERROR,
- "event registry re-allocation failed");
- goto unlock;
- }
- }
-
- idx = event_pool->used;
- event_pool->used++;
-
- event_pool->reg[idx].fd = fd;
- event_pool->reg[idx].events = EPOLLPRI;
- event_pool->reg[idx].handler = handler;
- event_pool->reg[idx].data = data;
-
- switch (poll_in) {
- case 1:
- event_pool->reg[idx].events |= EPOLLIN;
- break;
- case 0:
- event_pool->reg[idx].events &= ~EPOLLIN;
- break;
- case -1:
- /* do nothing */
- break;
- default:
- gf_log ("epoll", GF_LOG_ERROR,
- "invalid poll_in value %d", poll_in);
- break;
- }
-
- switch (poll_out) {
- case 1:
- event_pool->reg[idx].events |= EPOLLOUT;
- break;
- case 0:
- event_pool->reg[idx].events &= ~EPOLLOUT;
- break;
- case -1:
- /* do nothing */
- break;
- default:
- gf_log ("epoll", GF_LOG_ERROR,
- "invalid poll_out value %d", poll_out);
- break;
- }
-
- event_pool->changed = 1;
-
- epoll_event.events = event_pool->reg[idx].events;
- ev_data->fd = fd;
- ev_data->idx = idx;
-
- ret = epoll_ctl (event_pool->fd, EPOLL_CTL_ADD, fd,
- &epoll_event);
-
- if (ret == -1) {
- gf_log ("epoll", GF_LOG_ERROR,
- "failed to add fd(=%d) to epoll fd(=%d) (%s)",
- fd, event_pool->fd, strerror (errno));
- goto unlock;
- }
-
- pthread_cond_broadcast (&event_pool->cond);
- }
-unlock:
- pthread_mutex_unlock (&event_pool->mutex);
-
-out:
- return ret;
-}
-
-
-static int
-event_unregister_epoll (struct event_pool *event_pool, int fd, int idx_hint)
+gf_event_dispatch(struct event_pool *event_pool)
{
- int idx = -1;
- int ret = -1;
-
- struct epoll_event epoll_event = {0, };
- struct event_data *ev_data = (void *)&epoll_event.data;
- int lastidx = -1;
-
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
-
- pthread_mutex_lock (&event_pool->mutex);
- {
- idx = __event_getindex (event_pool, fd, idx_hint);
-
- if (idx == -1) {
- gf_log ("epoll", GF_LOG_ERROR,
- "index not found for fd=%d (idx_hint=%d)",
- fd, idx_hint);
- errno = ENOENT;
- goto unlock;
- }
-
- ret = epoll_ctl (event_pool->fd, EPOLL_CTL_DEL, fd, NULL);
-
- /* if ret is -1, this array member should never be accessed */
- /* if it is 0, the array member might be used by idx_cache
- * in which case the member should not be accessed till
- * it is reallocated
- */
-
- event_pool->reg[idx].fd = -1;
-
- if (ret == -1) {
- gf_log ("epoll", GF_LOG_ERROR,
- "fail to del fd(=%d) from epoll fd(=%d) (%s)",
- fd, event_pool->fd, strerror (errno));
- goto unlock;
- }
-
- lastidx = event_pool->used - 1;
- if (lastidx == idx) {
- event_pool->used--;
- goto unlock;
- }
-
- epoll_event.events = event_pool->reg[lastidx].events;
- ev_data->fd = event_pool->reg[lastidx].fd;
- ev_data->idx = idx;
-
- ret = epoll_ctl (event_pool->fd, EPOLL_CTL_MOD, ev_data->fd,
- &epoll_event);
- if (ret == -1) {
- gf_log ("epoll", GF_LOG_ERROR,
- "fail to modify fd(=%d) index %d to %d (%s)",
- ev_data->fd, event_pool->used, idx,
- strerror (errno));
- goto unlock;
- }
-
- /* just replace the unregistered idx by last one */
- event_pool->reg[idx] = event_pool->reg[lastidx];
- event_pool->used--;
- }
-unlock:
- pthread_mutex_unlock (&event_pool->mutex);
-
-out:
- return ret;
-}
+ int ret = -1;
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
-static int
-event_select_on_epoll (struct event_pool *event_pool, int fd, int idx_hint,
- int poll_in, int poll_out)
-{
- int idx = -1;
- int ret = -1;
-
- struct epoll_event epoll_event = {0, };
- struct event_data *ev_data = (void *)&epoll_event.data;
-
-
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
-
- pthread_mutex_lock (&event_pool->mutex);
- {
- idx = __event_getindex (event_pool, fd, idx_hint);
-
- if (idx == -1) {
- gf_log ("epoll", GF_LOG_ERROR,
- "index not found for fd=%d (idx_hint=%d)",
- fd, idx_hint);
- errno = ENOENT;
- goto unlock;
- }
-
- switch (poll_in) {
- case 1:
- event_pool->reg[idx].events |= EPOLLIN;
- break;
- case 0:
- event_pool->reg[idx].events &= ~EPOLLIN;
- break;
- case -1:
- /* do nothing */
- break;
- default:
- gf_log ("epoll", GF_LOG_ERROR,
- "invalid poll_in value %d", poll_in);
- break;
- }
-
- switch (poll_out) {
- case 1:
- event_pool->reg[idx].events |= EPOLLOUT;
- break;
- case 0:
- event_pool->reg[idx].events &= ~EPOLLOUT;
- break;
- case -1:
- /* do nothing */
- break;
- default:
- gf_log ("epoll", GF_LOG_ERROR,
- "invalid poll_out value %d", poll_out);
- break;
- }
-
- epoll_event.events = event_pool->reg[idx].events;
- ev_data->fd = fd;
- ev_data->idx = idx;
-
- ret = epoll_ctl (event_pool->fd, EPOLL_CTL_MOD, fd,
- &epoll_event);
- if (ret == -1) {
- gf_log ("epoll", GF_LOG_ERROR,
- "failed to modify fd(=%d) events to %d",
- fd, epoll_event.events);
- }
- }
-unlock:
- pthread_mutex_unlock (&event_pool->mutex);
+ ret = event_pool->ops->event_dispatch(event_pool);
+ if (ret)
+ goto out;
out:
- return ret;
-}
-
-
-static int
-event_dispatch_epoll_handler (struct event_pool *event_pool,
- struct epoll_event *events, int i)
-{
- struct event_data *event_data = NULL;
- event_handler_t handler = NULL;
- void *data = NULL;
- int idx = -1;
- int ret = -1;
-
-
- event_data = (void *)&events[i].data;
- handler = NULL;
- data = NULL;
-
- pthread_mutex_lock (&event_pool->mutex);
- {
- idx = __event_getindex (event_pool, event_data->fd,
- event_data->idx);
-
- if (idx == -1) {
- gf_log ("epoll", GF_LOG_ERROR,
- "index not found for fd(=%d) (idx_hint=%d)",
- event_data->fd, event_data->idx);
- goto unlock;
- }
-
- handler = event_pool->reg[idx].handler;
- data = event_pool->reg[idx].data;
- }
-unlock:
- pthread_mutex_unlock (&event_pool->mutex);
-
- if (handler)
- ret = handler (event_data->fd, event_data->idx, data,
- (events[i].events & (EPOLLIN|EPOLLPRI)),
- (events[i].events & (EPOLLOUT)),
- (events[i].events & (EPOLLERR|EPOLLHUP)));
- return ret;
+ return ret;
}
-
-static int
-event_dispatch_epoll (struct event_pool *event_pool)
+int
+gf_event_reconfigure_threads(struct event_pool *event_pool, int value)
{
- struct epoll_event *events = NULL;
- int size = 0;
- int i = 0;
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
+ int ret = -1;
- while (1) {
- pthread_mutex_lock (&event_pool->mutex);
- {
- while (event_pool->used == 0)
- pthread_cond_wait (&event_pool->cond,
- &event_pool->mutex);
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
- if (event_pool->used > event_pool->evcache_size) {
- if (event_pool->evcache)
- GF_FREE (event_pool->evcache);
-
- event_pool->evcache = events = NULL;
-
- event_pool->evcache_size =
- event_pool->used + 256;
-
- events = GF_CALLOC (event_pool->evcache_size,
- sizeof (struct epoll_event),
- gf_common_mt_epoll_event);
- if (!events)
- break;
-
- event_pool->evcache = events;
- }
- }
- pthread_mutex_unlock (&event_pool->mutex);
-
- ret = epoll_wait (event_pool->fd, event_pool->evcache,
- event_pool->evcache_size, -1);
-
- if (ret == 0)
- /* timeout */
- continue;
-
- if (ret == -1 && errno == EINTR)
- /* sys call */
- continue;
-
- size = ret;
-
- for (i = 0; i < size; i++) {
- if (!events || !events[i].events)
- continue;
-
- ret = event_dispatch_epoll_handler (event_pool,
- events, i);
- }
- }
+ /* call event refresh function */
+ ret = event_pool->ops->event_reconfigure_threads(event_pool, value);
out:
- return ret;
+ return ret;
}
-
-static struct event_ops event_ops_epoll = {
- .new = event_pool_new_epoll,
- .event_register = event_register_epoll,
- .event_select_on = event_select_on_epoll,
- .event_unregister = event_unregister_epoll,
- .event_dispatch = event_dispatch_epoll
-};
-
-#endif
-
-
-struct event_pool *
-event_pool_new (int count)
+int
+gf_event_pool_destroy(struct event_pool *event_pool)
{
- struct event_pool *event_pool = NULL;
+ int ret = -1;
+ int destroy = 0, activethreadcount = 0;
-#ifdef HAVE_SYS_EPOLL_H
- event_pool = event_ops_epoll.new (count);
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
- if (event_pool) {
- event_pool->ops = &event_ops_epoll;
- } else {
- gf_log ("event", GF_LOG_WARNING,
- "falling back to poll based event handling");
- }
-#endif
-
- if (!event_pool) {
- event_pool = event_ops_poll.new (count);
-
- if (event_pool)
- event_pool->ops = &event_ops_poll;
- }
-
- return event_pool;
-}
-
-
-int
-event_register (struct event_pool *event_pool, int fd,
- event_handler_t handler,
- void *data, int poll_in, int poll_out)
-{
- int ret = -1;
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ destroy = event_pool->destroy;
+ activethreadcount = event_pool->activethreadcount;
+ }
+ pthread_mutex_unlock(&event_pool->mutex);
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
+ if (!destroy || (activethreadcount > 0)) {
+ goto out;
+ }
- ret = event_pool->ops->event_register (event_pool, fd, handler, data,
- poll_in, poll_out);
+ ret = event_pool->ops->event_pool_destroy(event_pool);
out:
- return ret;
+ return ret;
}
-
-int
-event_unregister (struct event_pool *event_pool, int fd, int idx)
+void
+poller_destroy_handler(int fd, int idx, int gen, void *data, int poll_out,
+ int poll_in, int poll_err, char event_thread_exit)
{
- int ret = -1;
+ struct event_destroy_data *destroy = NULL;
+ int readfd = -1;
+ char buf = '\0';
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
+ destroy = data;
+ readfd = destroy->readfd;
+ if (readfd < 0) {
+ goto out;
+ }
- ret = event_pool->ops->event_unregister (event_pool, fd, idx);
+ while (sys_read(readfd, &buf, 1) > 0) {
+ }
out:
- return ret;
-}
+ gf_event_handled(destroy->pool, fd, idx, gen);
+ return;
+}
+/* This function destroys all the poller threads.
+ * Note: to be called before gf_event_pool_destroy is called.
+ * The order in which cleaning is performed:
+ * - Register a pipe fd(this is for waking threads in poll()/epoll_wait())
+ * - Set the destroy mode, which this no new event registration will succeed
+ * - Reconfigure the thread count to 0(this will succeed only in destroy mode)
+ * - Wake up all the threads in poll() or epoll_wait(), so that they can
+ * destroy themselves.
+ * - Wait for the thread to join(which will happen only after all the other
+ * threads are destroyed)
+ */
int
-event_select_on (struct event_pool *event_pool, int fd, int idx_hint,
- int poll_in, int poll_out)
+gf_event_dispatch_destroy(struct event_pool *event_pool)
{
- int ret = -1;
+ int ret = -1, threadcount = 0;
+ int fd[2] = {-1};
+ int idx = -1;
+ int flags = 0;
+ struct timespec sleep_till = {
+ 0,
+ };
+ struct event_destroy_data data = {
+ 0,
+ };
+
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
+
+ ret = pipe(fd);
+ if (ret < 0)
+ goto out;
+
+ /* Make the read end of the pipe nonblocking */
+ flags = fcntl(fd[0], F_GETFL);
+ flags |= O_NONBLOCK;
+ ret = fcntl(fd[0], F_SETFL, flags);
+ if (ret < 0)
+ goto out;
+
+ /* Make the write end of the pipe nonblocking */
+ flags = fcntl(fd[1], F_GETFL);
+ flags |= O_NONBLOCK;
+ ret = fcntl(fd[1], F_SETFL, flags);
+ if (ret < 0)
+ goto out;
+
+ data.pool = event_pool;
+ data.readfd = fd[1];
+
+ /* From the main thread register an event on the pipe fd[0],
+ */
+ idx = gf_event_register(event_pool, fd[0], poller_destroy_handler, &data, 1,
+ 0, 0);
+ if (idx < 0)
+ goto out;
+
+ /* Enter the destroy mode first, set this before reconfiguring to 0
+ * threads, to prevent further reconfigure to thread count > 0.
+ */
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ threadcount = event_pool->eventthreadcount;
+ event_pool->destroy = 1;
+ }
+ pthread_mutex_unlock(&event_pool->mutex);
+
+ ret = gf_event_reconfigure_threads(event_pool, 0);
+ if (ret < 0)
+ goto out;
+
+ /* Write something onto the write end of the pipe(fd[1]) so that
+ * poll wakes up and calls the handler, poller_destroy_handler()
+ */
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ /* Write to pipe(fd[1]) and then wait for 1 second or until
+ * a poller thread that is dying, broadcasts. Make sure we
+ * do not loop forever by limiting to 10 retries
+ */
+ int retry = 0;
+
+ while (event_pool->activethreadcount > 0 &&
+ (retry++ < (threadcount + 10))) {
+ if (sys_write(fd[1], "dummy", 6) == -1) {
+ break;
+ }
+ timespec_now_realtime(&sleep_till);
+ sleep_till.tv_sec += 1;
+ ret = pthread_cond_timedwait(&event_pool->cond, &event_pool->mutex,
+ &sleep_till);
+ if (ret) {
+ gf_msg_debug("event", 0,
+ "thread cond-timedwait failed "
+ "active-thread-count: %d, "
+ "retry: %d",
+ event_pool->activethreadcount, retry);
+ }
+ }
+ }
+ pthread_mutex_unlock(&event_pool->mutex);
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
+ ret = gf_event_unregister(event_pool, fd[0], idx);
- ret = event_pool->ops->event_select_on (event_pool, fd, idx_hint,
- poll_in, poll_out);
out:
- return ret;
-}
+ if (fd[0] != -1)
+ sys_close(fd[0]);
+ if (fd[1] != -1)
+ sys_close(fd[1]);
+ return ret;
+}
int
-event_dispatch (struct event_pool *event_pool)
+gf_event_handled(struct event_pool *event_pool, int fd, int idx, int gen)
{
- int ret = -1;
+ int ret = 0;
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
+ if (event_pool->ops->event_handled)
+ ret = event_pool->ops->event_handled(event_pool, fd, idx, gen);
- ret = event_pool->ops->event_dispatch (event_pool);
-
-out:
- return ret;
+ return ret;
}
diff --git a/libglusterfs/src/event.h b/libglusterfs/src/event.h
deleted file mode 100644
index 0e87f0cd794..00000000000
--- a/libglusterfs/src/event.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _EVENT_H_
-#define _EVENT_H_
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include <pthread.h>
-
-struct event_pool;
-struct event_ops;
-struct event_data {
- int fd;
- int idx;
-} __attribute__ ((__packed__, __may_alias__));
-
-
-typedef int (*event_handler_t) (int fd, int idx, void *data,
- int poll_in, int poll_out, int poll_err);
-
-struct event_pool {
- struct event_ops *ops;
-
- int fd;
- int breaker[2];
-
- int count;
- struct {
- int fd;
- int events;
- void *data;
- event_handler_t handler;
- } *reg;
-
- int used;
- int idx_cache;
- int changed;
-
- pthread_mutex_t mutex;
- pthread_cond_t cond;
-
- void *evcache;
- int evcache_size;
-};
-
-struct event_ops {
- struct event_pool * (*new) (int count);
-
- int (*event_register) (struct event_pool *event_pool, int fd,
- event_handler_t handler,
- void *data, int poll_in, int poll_out);
-
- int (*event_select_on) (struct event_pool *event_pool, int fd, int idx,
- int poll_in, int poll_out);
-
- int (*event_unregister) (struct event_pool *event_pool, int fd, int idx);
-
- int (*event_dispatch) (struct event_pool *event_pool);
-};
-
-struct event_pool * event_pool_new (int count);
-int event_select_on (struct event_pool *event_pool, int fd, int idx,
- int poll_in, int poll_out);
-int event_register (struct event_pool *event_pool, int fd,
- event_handler_t handler,
- void *data, int poll_in, int poll_out);
-int event_unregister (struct event_pool *event_pool, int fd, int idx);
-int event_dispatch (struct event_pool *event_pool);
-
-#endif /* _EVENT_H_ */
diff --git a/libglusterfs/src/events.c b/libglusterfs/src/events.c
new file mode 100644
index 00000000000..33157549897
--- /dev/null
+++ b/libglusterfs/src/events.c
@@ -0,0 +1,136 @@
+/*
+ Copyright (c) 2016 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 <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <time.h>
+#include <stdarg.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#include "glusterfs/syscall.h"
+#include "glusterfs/mem-pool.h"
+#include "glusterfs/glusterfs.h"
+#include "glusterfs/globals.h"
+#include "glusterfs/events.h"
+
+#define EVENT_HOST "127.0.0.1"
+#define EVENT_PORT 24009
+
+int
+_gf_event(eventtypes_t event, const char *fmt, ...)
+{
+ int ret = 0;
+ int sock = -1;
+ char *eventstr = NULL;
+ va_list arguments;
+ char *msg = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ char *host = NULL;
+ struct addrinfo hints;
+ struct addrinfo *result = NULL;
+ struct addrinfo *iter_result_ptr = NULL;
+ xlator_t *this = THIS;
+ char *volfile_server_transport = NULL;
+
+ /* Global context */
+ ctx = this->ctx;
+
+ if (event < 0 || event >= EVENT_LAST) {
+ ret = EVENT_ERROR_INVALID_INPUTS;
+ goto out;
+ }
+
+ if (ctx) {
+ volfile_server_transport = ctx->cmd_args.volfile_server_transport;
+ }
+ if (!volfile_server_transport) {
+ volfile_server_transport = "tcp";
+ }
+
+ /* host = NULL returns localhost */
+ if (ctx && ctx->cmd_args.volfile_server &&
+ (strcmp(volfile_server_transport, "unix"))) {
+ /* If it is client code then volfile_server is set
+ use that information to push the events. */
+ host = ctx->cmd_args.volfile_server;
+ }
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_flags = AI_ADDRCONFIG;
+
+ if ((getaddrinfo(host, TOSTRING(EVENT_PORT), &hints, &result)) != 0) {
+ ret = EVENT_ERROR_RESOLVE;
+ goto out;
+ }
+
+ // iterate over the result and break when socket creation is success.
+ for (iter_result_ptr = result; iter_result_ptr != NULL;
+ iter_result_ptr = iter_result_ptr->ai_next) {
+ sock = socket(iter_result_ptr->ai_family, iter_result_ptr->ai_socktype,
+ iter_result_ptr->ai_protocol);
+ if (sock != -1) {
+ break;
+ }
+ }
+ /*
+ * If none of the addrinfo structures lead to a successful socket
+ * creation, socket creation has failed.
+ */
+ if (sock < 0) {
+ ret = EVENT_ERROR_SOCKET;
+ goto out;
+ }
+
+ va_start(arguments, fmt);
+ ret = gf_vasprintf(&msg, fmt, arguments);
+ va_end(arguments);
+
+ if (ret < 0) {
+ ret = EVENT_ERROR_INVALID_INPUTS;
+ goto out;
+ }
+
+ ret = gf_asprintf(&eventstr, "%u %d %s", (unsigned)gf_time(), event, msg);
+ GF_FREE(msg);
+ if (ret <= 0) {
+ ret = EVENT_ERROR_MSG_FORMAT;
+ goto out;
+ }
+
+ /* Send Message */
+ if (sendto(sock, eventstr, strlen(eventstr), 0, result->ai_addr,
+ result->ai_addrlen) <= 0) {
+ ret = EVENT_ERROR_SEND;
+ goto out;
+ }
+
+ ret = EVENT_SEND_OK;
+
+out:
+ if (sock >= 0) {
+ sys_close(sock);
+ }
+
+ /* Allocated by gf_asprintf */
+ if (eventstr)
+ GF_FREE(eventstr);
+
+ if (result)
+ freeaddrinfo(result);
+
+ return ret;
+}
diff --git a/libglusterfs/src/fd-lk.c b/libglusterfs/src/fd-lk.c
new file mode 100644
index 00000000000..c2d34f81c9c
--- /dev/null
+++ b/libglusterfs/src/fd-lk.c
@@ -0,0 +1,433 @@
+/*
+ Copyright (c) 2008-2012 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 "glusterfs/fd-lk.h"
+#include "glusterfs/common-utils.h"
+#include "glusterfs/libglusterfs-messages.h"
+
+int32_t
+_fd_lk_delete_lock(fd_lk_ctx_node_t *lock)
+{
+ int32_t ret = -1;
+
+ GF_VALIDATE_OR_GOTO("fd-lk", lock, out);
+
+ list_del_init(&lock->next);
+
+ ret = 0;
+out:
+ return ret;
+}
+
+int32_t
+_fd_lk_destroy_lock(fd_lk_ctx_node_t *lock)
+{
+ int32_t ret = -1;
+
+ GF_VALIDATE_OR_GOTO("fd-lk", lock, out);
+
+ GF_FREE(lock);
+
+ ret = 0;
+out:
+ return ret;
+}
+
+int
+_fd_lk_destroy_lock_list(fd_lk_ctx_t *lk_ctx)
+{
+ int ret = -1;
+ fd_lk_ctx_node_t *lk = NULL;
+ fd_lk_ctx_node_t *tmp = NULL;
+
+ GF_VALIDATE_OR_GOTO("fd-lk", lk_ctx, out);
+
+ list_for_each_entry_safe(lk, tmp, &lk_ctx->lk_list, next)
+ {
+ _fd_lk_delete_lock(lk);
+ _fd_lk_destroy_lock(lk);
+ }
+ ret = 0;
+out:
+ return ret;
+}
+
+int
+fd_lk_ctx_unref(fd_lk_ctx_t *lk_ctx)
+{
+ int ref = -1;
+
+ GF_VALIDATE_OR_GOTO("fd-lk", lk_ctx, err);
+
+ ref = GF_ATOMIC_DEC(lk_ctx->ref);
+ if (ref < 0)
+ GF_ASSERT(!ref);
+ if (ref == 0)
+ _fd_lk_destroy_lock_list(lk_ctx);
+
+ if (ref == 0) {
+ LOCK_DESTROY(&lk_ctx->lock);
+ GF_FREE(lk_ctx);
+ }
+
+ return 0;
+err:
+ return -1;
+}
+
+fd_lk_ctx_t *
+fd_lk_ctx_ref(fd_lk_ctx_t *lk_ctx)
+{
+ if (!lk_ctx) {
+ gf_msg_callingfn("fd-lk", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ return NULL;
+ }
+
+ GF_ATOMIC_INC(lk_ctx->ref);
+
+ return lk_ctx;
+}
+
+fd_lk_ctx_t *
+fd_lk_ctx_create()
+{
+ fd_lk_ctx_t *fd_lk_ctx = NULL;
+
+ fd_lk_ctx = GF_CALLOC(1, sizeof(fd_lk_ctx_t), gf_common_mt_fd_lk_ctx_t);
+ if (!fd_lk_ctx)
+ goto out;
+
+ INIT_LIST_HEAD(&fd_lk_ctx->lk_list);
+
+ LOCK_INIT(&fd_lk_ctx->lock);
+
+ fd_lk_ctx = fd_lk_ctx_ref(fd_lk_ctx);
+out:
+ return fd_lk_ctx;
+}
+
+int
+_fd_lk_insert_lock(fd_lk_ctx_t *lk_ctx, fd_lk_ctx_node_t *lock)
+{
+ list_add_tail(&lock->next, &lk_ctx->lk_list);
+ return 0;
+}
+
+static off_t
+_fd_lk_get_lock_len(off_t start, off_t end)
+{
+ if (end == LLONG_MAX)
+ return 0;
+ else
+ return (end - start + 1);
+}
+
+fd_lk_ctx_node_t *
+fd_lk_ctx_node_new(int32_t cmd, struct gf_flock *flock)
+{
+ fd_lk_ctx_node_t *new_lock = NULL;
+
+ /* TODO: get from mem-pool */
+ new_lock = GF_CALLOC(1, sizeof(fd_lk_ctx_node_t),
+ gf_common_mt_fd_lk_ctx_node_t);
+ if (!new_lock)
+ goto out;
+
+ new_lock->cmd = cmd;
+
+ if (flock) {
+ new_lock->fl_type = flock->l_type;
+ new_lock->fl_start = flock->l_start;
+
+ if (flock->l_len == 0)
+ new_lock->fl_end = LLONG_MAX;
+ else
+ new_lock->fl_end = flock->l_start + flock->l_len - 1;
+
+ memcpy(&new_lock->user_flock, flock, sizeof(struct gf_flock));
+ }
+
+ INIT_LIST_HEAD(&new_lock->next);
+out:
+ return new_lock;
+}
+
+int32_t
+_fd_lk_delete_unlck_locks(fd_lk_ctx_t *lk_ctx)
+{
+ int32_t ret = -1;
+ fd_lk_ctx_node_t *tmp = NULL;
+ fd_lk_ctx_node_t *lk = NULL;
+
+ GF_VALIDATE_OR_GOTO("fd-lk", lk_ctx, out);
+
+ list_for_each_entry_safe(lk, tmp, &lk_ctx->lk_list, next)
+ {
+ if (lk->fl_type == F_UNLCK) {
+ _fd_lk_delete_lock(lk);
+ _fd_lk_destroy_lock(lk);
+ }
+ }
+out:
+ return ret;
+}
+
+int
+fd_lk_overlap(fd_lk_ctx_node_t *l1, fd_lk_ctx_node_t *l2)
+{
+ if (l1->fl_end >= l2->fl_start && l2->fl_end >= l1->fl_start)
+ return 1;
+
+ return 0;
+}
+
+fd_lk_ctx_node_t *
+_fd_lk_add_locks(fd_lk_ctx_node_t *l1, fd_lk_ctx_node_t *l2)
+{
+ fd_lk_ctx_node_t *sum = NULL;
+
+ sum = fd_lk_ctx_node_new(0, NULL);
+ if (!sum)
+ goto out;
+
+ sum->fl_start = min(l1->fl_start, l2->fl_start);
+ sum->fl_end = max(l1->fl_end, l2->fl_end);
+
+ sum->user_flock.l_start = sum->fl_start;
+ sum->user_flock.l_len = _fd_lk_get_lock_len(sum->fl_start, sum->fl_end);
+out:
+ return sum;
+}
+
+/* Subtract two locks */
+struct _values {
+ fd_lk_ctx_node_t *locks[3];
+};
+
+int32_t
+_fd_lk_sub_locks(struct _values *v, fd_lk_ctx_node_t *big,
+ fd_lk_ctx_node_t *small)
+{
+ int32_t ret = -1;
+
+ if ((big->fl_start == small->fl_start) && (big->fl_end == small->fl_end)) {
+ /* both edges coincide with big */
+ v->locks[0] = fd_lk_ctx_node_new(small->cmd, NULL);
+ if (!v->locks[0])
+ goto out;
+
+ memcpy(v->locks[0], big, sizeof(fd_lk_ctx_node_t));
+
+ v->locks[0]->fl_type = small->fl_type;
+ v->locks[0]->user_flock.l_type = small->fl_type;
+ } else if ((small->fl_start > big->fl_start) &&
+ (small->fl_end < big->fl_end)) {
+ /* small lock is completely inside big lock,
+ break it down into 3 different locks. */
+ v->locks[0] = fd_lk_ctx_node_new(big->cmd, NULL);
+ if (!v->locks[0])
+ goto out;
+
+ v->locks[1] = fd_lk_ctx_node_new(small->cmd, NULL);
+ if (!v->locks[1])
+ goto out;
+
+ v->locks[2] = fd_lk_ctx_node_new(big->cmd, NULL);
+ if (!v->locks[2])
+ goto out;
+
+ memcpy(v->locks[0], big, sizeof(fd_lk_ctx_node_t));
+ v->locks[0]->fl_end = small->fl_start - 1;
+ v->locks[0]->user_flock.l_len = _fd_lk_get_lock_len(
+ v->locks[0]->fl_start, v->locks[0]->fl_end);
+
+ memcpy(v->locks[1], small, sizeof(fd_lk_ctx_node_t));
+
+ memcpy(v->locks[2], big, sizeof(fd_lk_ctx_node_t));
+ v->locks[2]->fl_start = small->fl_end + 1;
+ v->locks[2]->user_flock.l_len = _fd_lk_get_lock_len(
+ v->locks[2]->fl_start, v->locks[2]->fl_end);
+ } else if (small->fl_start == big->fl_start) {
+ /* One of the ends co-incide, break the
+ locks into two separate parts */
+ v->locks[0] = fd_lk_ctx_node_new(small->cmd, NULL);
+ if (!v->locks[0])
+ goto out;
+
+ v->locks[1] = fd_lk_ctx_node_new(big->cmd, NULL);
+ if (!v->locks[1])
+ goto out;
+
+ memcpy(v->locks[0], small, sizeof(fd_lk_ctx_node_t));
+
+ memcpy(v->locks[1], big, sizeof(fd_lk_ctx_node_t));
+ v->locks[1]->fl_start = small->fl_end + 1;
+ v->locks[1]->user_flock.l_start = small->fl_end + 1;
+ } else if (small->fl_end == big->fl_end) {
+ /* One of the ends co-incide, break the
+ locks into two separate parts */
+ v->locks[0] = fd_lk_ctx_node_new(small->cmd, NULL);
+ if (!v->locks[0])
+ goto out;
+
+ v->locks[1] = fd_lk_ctx_node_new(big->cmd, NULL);
+ if (!v->locks[1])
+ goto out;
+
+ memcpy(v->locks[0], big, sizeof(fd_lk_ctx_node_t));
+ v->locks[0]->fl_end = small->fl_start - 1;
+ v->locks[0]->user_flock.l_len = _fd_lk_get_lock_len(
+ v->locks[0]->fl_start, v->locks[0]->fl_end);
+
+ memcpy(v->locks[1], small, sizeof(fd_lk_ctx_node_t));
+ } else {
+ /* We should never come to this case */
+ GF_ASSERT(!"Invalid case");
+ }
+ ret = 0;
+out:
+ return ret;
+}
+
+static void
+_fd_lk_insert_and_merge(fd_lk_ctx_t *lk_ctx, fd_lk_ctx_node_t *lock)
+{
+ int32_t ret = -1;
+ int32_t i = 0;
+ fd_lk_ctx_node_t *entry = NULL;
+ fd_lk_ctx_node_t *t = NULL;
+ fd_lk_ctx_node_t *sum = NULL;
+ struct _values v = {.locks = {0, 0, 0}};
+
+ list_for_each_entry_safe(entry, t, &lk_ctx->lk_list, next)
+ {
+ if (!fd_lk_overlap(entry, lock))
+ continue;
+
+ if (entry->fl_type == lock->fl_type) {
+ sum = _fd_lk_add_locks(entry, lock);
+ if (!sum)
+ return;
+ sum->fl_type = entry->fl_type;
+ sum->user_flock.l_type = entry->fl_type;
+ _fd_lk_delete_lock(entry);
+ _fd_lk_destroy_lock(entry);
+ _fd_lk_destroy_lock(lock);
+ _fd_lk_insert_and_merge(lk_ctx, sum);
+ return;
+ } else {
+ sum = _fd_lk_add_locks(entry, lock);
+ sum->fl_type = lock->fl_type;
+ sum->user_flock.l_type = lock->fl_type;
+ ret = _fd_lk_sub_locks(&v, sum, lock);
+ if (ret)
+ return;
+ _fd_lk_delete_lock(entry);
+ _fd_lk_destroy_lock(entry);
+
+ _fd_lk_delete_lock(lock);
+ _fd_lk_destroy_lock(lock);
+
+ _fd_lk_destroy_lock(sum);
+
+ for (i = 0; i < 3; i++) {
+ if (!v.locks[i])
+ continue;
+
+ INIT_LIST_HEAD(&v.locks[i]->next);
+ _fd_lk_insert_and_merge(lk_ctx, v.locks[i]);
+ }
+ _fd_lk_delete_unlck_locks(lk_ctx);
+ return;
+ }
+ }
+
+ /* no conflicts, so just insert */
+ if (lock->fl_type != F_UNLCK) {
+ _fd_lk_insert_lock(lk_ctx, lock);
+ } else {
+ _fd_lk_destroy_lock(lock);
+ }
+}
+
+static void
+print_lock_list(fd_lk_ctx_t *lk_ctx)
+{
+ fd_lk_ctx_node_t *lk = NULL;
+
+ gf_msg_debug("fd-lk", 0, "lock list:");
+
+ list_for_each_entry(lk, &lk_ctx->lk_list, next)
+ gf_msg_debug("fd-lk", 0,
+ "owner = %s, cmd = %s fl_type = %s,"
+ " fs_start = %" PRId64 ", fs_end = %" PRId64
+ ", "
+ "user_flock: l_type = %s, l_start = %" PRId64
+ ", "
+ "l_len = %" PRId64 ", ",
+ lkowner_utoa(&lk->user_flock.l_owner), get_lk_cmd(lk->cmd),
+ get_lk_type(lk->fl_type), lk->fl_start, lk->fl_end,
+ get_lk_type(lk->user_flock.l_type), lk->user_flock.l_start,
+ lk->user_flock.l_len);
+}
+
+int
+fd_lk_insert_and_merge(fd_t *fd, int32_t cmd, struct gf_flock *flock)
+{
+ int32_t ret = -1;
+ fd_lk_ctx_t *lk_ctx = NULL;
+ fd_lk_ctx_node_t *lk = NULL;
+
+ GF_VALIDATE_OR_GOTO("fd-lk", fd, out);
+ GF_VALIDATE_OR_GOTO("fd-lk", flock, out);
+
+ lk_ctx = fd_lk_ctx_ref(fd->lk_ctx);
+ lk = fd_lk_ctx_node_new(cmd, flock);
+
+ gf_msg_debug("fd-lk", 0,
+ "new lock request: owner = %s, fl_type = %s"
+ ", fs_start = %" PRId64 ", fs_end = %" PRId64
+ ", user_flock:"
+ " l_type = %s, l_start = %" PRId64 ", l_len = %" PRId64,
+ lkowner_utoa(&flock->l_owner), get_lk_type(lk->fl_type),
+ lk->fl_start, lk->fl_end, get_lk_type(lk->user_flock.l_type),
+ lk->user_flock.l_start, lk->user_flock.l_len);
+
+ LOCK(&lk_ctx->lock);
+ {
+ _fd_lk_insert_and_merge(lk_ctx, lk);
+ print_lock_list(lk_ctx);
+ }
+ UNLOCK(&lk_ctx->lock);
+
+ fd_lk_ctx_unref(lk_ctx);
+
+ ret = 0;
+out:
+ return ret;
+}
+
+gf_boolean_t
+fd_lk_ctx_empty(fd_lk_ctx_t *lk_ctx)
+{
+ gf_boolean_t verdict = _gf_true;
+
+ if (!lk_ctx)
+ return _gf_true;
+
+ LOCK(&lk_ctx->lock);
+ {
+ verdict = list_empty(&lk_ctx->lk_list);
+ }
+ UNLOCK(&lk_ctx->lock);
+
+ return verdict;
+}
diff --git a/libglusterfs/src/fd.c b/libglusterfs/src/fd.c
index ee98ef2eb89..62606e91164 100644
--- a/libglusterfs/src/fd.c
+++ b/libglusterfs/src/fd.c
@@ -1,868 +1,1203 @@
/*
- Copyright (c) 2007-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 "fd.h"
-#include "glusterfs.h"
-#include "inode.h"
-#include "dict.h"
-#include "statedump.h"
-
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
+#include "glusterfs/fd.h"
+#include <errno.h> // for EINVAL, errno, ENOMEM
+#include <inttypes.h> // for PRIu64
+#include <stdint.h> // for UINT32_MAX
+#include <string.h> // for NULL, memcpy, memset, size_t
+#include "glusterfs/statedump.h"
static int
-gf_fd_fdtable_expand (fdtable_t *fdtable, uint32_t nr);
-
+gf_fd_fdtable_expand(fdtable_t *fdtable, uint32_t nr);
fd_t *
-_fd_ref (fd_t *fd);
+__fd_ref(fd_t *fd);
-/*
- Allocate in memory chunks of power of 2 starting from 1024B
- Assumes fdtable->lock is held
-*/
-static inline int
-gf_roundup_power_of_two (uint32_t nr)
+static int
+gf_fd_chain_fd_entries(fdentry_t *entries, uint32_t startidx, uint32_t endcount)
{
- uint32_t result = 1;
+ uint32_t i = 0;
- if (nr < 0) {
- gf_log ("fd", GF_LOG_ERROR, "negative number passed");
- return -1;
- }
+ if (!entries) {
+ gf_msg_callingfn("fd", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "!entries");
+ return -1;
+ }
- while (result <= nr)
- result *= 2;
+ /* Chain only till the second to last entry because we want to
+ * ensure that the last entry has GF_FDTABLE_END.
+ */
+ for (i = startidx; i < (endcount - 1); i++)
+ entries[i].next_free = i + 1;
- return result;
-}
+ /* i has already been incremented up to the last entry. */
+ entries[i].next_free = GF_FDTABLE_END;
+ return 0;
+}
static int
-gf_fd_chain_fd_entries (fdentry_t *entries, uint32_t startidx,
- uint32_t endcount)
+gf_fd_fdtable_expand(fdtable_t *fdtable, uint32_t nr)
{
- uint32_t i = 0;
-
- if (!entries) {
- gf_log_callingfn ("fd", GF_LOG_WARNING, "!entries");
- return -1;
- }
-
- /* Chain only till the second to last entry because we want to
- * ensure that the last entry has GF_FDTABLE_END.
- */
- for (i = startidx; i < (endcount - 1); i++)
- entries[i].next_free = i + 1;
-
- /* i has already been incremented upto the last entry. */
- entries[i].next_free = GF_FDTABLE_END;
-
- return 0;
+ fdentry_t *oldfds = NULL;
+ uint32_t oldmax_fds = -1;
+ int ret = -1;
+
+ if (fdtable == NULL || nr > UINT32_MAX) {
+ gf_msg_callingfn("fd", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ ret = EINVAL;
+ goto out;
+ }
+
+ nr /= (1024 / sizeof(fdentry_t));
+ nr = gf_roundup_next_power_of_two(nr + 1);
+ nr *= (1024 / sizeof(fdentry_t));
+
+ oldfds = fdtable->fdentries;
+ oldmax_fds = fdtable->max_fds;
+
+ fdtable->fdentries = GF_CALLOC(nr, sizeof(fdentry_t),
+ gf_common_mt_fdentry_t);
+ if (!fdtable->fdentries) {
+ ret = ENOMEM;
+ goto out;
+ }
+ fdtable->max_fds = nr;
+
+ if (oldfds) {
+ uint32_t cpy = oldmax_fds * sizeof(fdentry_t);
+ memcpy(fdtable->fdentries, oldfds, cpy);
+ }
+
+ gf_fd_chain_fd_entries(fdtable->fdentries, oldmax_fds, fdtable->max_fds);
+
+ /* Now that expansion is done, we must update the fd list
+ * head pointer so that the fd allocation functions can continue
+ * using the expanded table.
+ */
+ fdtable->first_free = oldmax_fds;
+ GF_FREE(oldfds);
+ ret = 0;
+out:
+ return ret;
}
-
-static int
-gf_fd_fdtable_expand (fdtable_t *fdtable, uint32_t nr)
+fdtable_t *
+gf_fd_fdtable_alloc(void)
{
- fdentry_t *oldfds = NULL;
- uint32_t oldmax_fds = -1;
- int ret = -1;
+ fdtable_t *fdtable = NULL;
- if (fdtable == NULL || nr < 0) {
- gf_log_callingfn ("fd", GF_LOG_ERROR, "invalid argument");
- ret = EINVAL;
- goto out;
- }
+ fdtable = GF_CALLOC(1, sizeof(*fdtable), gf_common_mt_fdtable_t);
+ if (!fdtable)
+ return NULL;
- nr /= (1024 / sizeof (fdentry_t));
- nr = gf_roundup_power_of_two (nr + 1);
- nr *= (1024 / sizeof (fdentry_t));
+ pthread_rwlock_init(&fdtable->lock, NULL);
- oldfds = fdtable->fdentries;
- oldmax_fds = fdtable->max_fds;
+ pthread_rwlock_wrlock(&fdtable->lock);
+ {
+ gf_fd_fdtable_expand(fdtable, 0);
+ }
+ pthread_rwlock_unlock(&fdtable->lock);
- fdtable->fdentries = GF_CALLOC (nr, sizeof (fdentry_t),
- gf_common_mt_fdentry_t);
- if (!fdtable->fdentries) {
- ret = ENOMEM;
- goto out;
- }
- fdtable->max_fds = nr;
+ return fdtable;
+}
- if (oldfds) {
- uint32_t cpy = oldmax_fds * sizeof (fdentry_t);
- memcpy (fdtable->fdentries, oldfds, cpy);
- }
+static fdentry_t *
+__gf_fd_fdtable_get_all_fds(fdtable_t *fdtable, uint32_t *count)
+{
+ fdentry_t *fdentries = NULL;
- gf_fd_chain_fd_entries (fdtable->fdentries, oldmax_fds,
- fdtable->max_fds);
+ if (count == NULL) {
+ gf_msg_callingfn("fd", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "!count");
+ goto out;
+ }
+
+ fdentries = fdtable->fdentries;
+ fdtable->fdentries = GF_CALLOC(fdtable->max_fds, sizeof(fdentry_t),
+ gf_common_mt_fdentry_t);
+ gf_fd_chain_fd_entries(fdtable->fdentries, 0, fdtable->max_fds);
+ *count = fdtable->max_fds;
- /* Now that expansion is done, we must update the fd list
- * head pointer so that the fd allocation functions can continue
- * using the expanded table.
- */
- fdtable->first_free = oldmax_fds;
- GF_FREE (oldfds);
- ret = 0;
out:
- return ret;
+ return fdentries;
}
-
-fdtable_t *
-gf_fd_fdtable_alloc (void)
+fdentry_t *
+gf_fd_fdtable_get_all_fds(fdtable_t *fdtable, uint32_t *count)
{
- fdtable_t *fdtable = NULL;
-
- fdtable = GF_CALLOC (1, sizeof (*fdtable), gf_common_mt_fdtable_t);
- if (!fdtable)
- return NULL;
-
- pthread_mutex_init (&fdtable->lock, NULL);
+ fdentry_t *entries = NULL;
- pthread_mutex_lock (&fdtable->lock);
+ if (fdtable) {
+ pthread_rwlock_wrlock(&fdtable->lock);
{
- gf_fd_fdtable_expand (fdtable, 0);
+ entries = __gf_fd_fdtable_get_all_fds(fdtable, count);
}
- pthread_mutex_unlock (&fdtable->lock);
+ pthread_rwlock_unlock(&fdtable->lock);
+ }
- return fdtable;
+ return entries;
}
-
-fdentry_t *
-__gf_fd_fdtable_get_all_fds (fdtable_t *fdtable, uint32_t *count)
+static fdentry_t *
+__gf_fd_fdtable_copy_all_fds(fdtable_t *fdtable, uint32_t *count)
{
- fdentry_t *fdentries = NULL;
-
- if (count == NULL) {
- gf_log_callingfn ("fd", GF_LOG_WARNING, "!count");
- goto out;
+ fdentry_t *fdentries = NULL;
+ int i = 0;
+
+ if (count == NULL) {
+ gf_msg_callingfn("fd", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "!count");
+ goto out;
+ }
+
+ fdentries = GF_CALLOC(fdtable->max_fds, sizeof(fdentry_t),
+ gf_common_mt_fdentry_t);
+ if (fdentries == NULL) {
+ goto out;
+ }
+
+ *count = fdtable->max_fds;
+
+ for (i = 0; i < fdtable->max_fds; i++) {
+ if (fdtable->fdentries[i].fd != NULL) {
+ fdentries[i].fd = fd_ref(fdtable->fdentries[i].fd);
}
-
- fdentries = fdtable->fdentries;
- fdtable->fdentries = GF_CALLOC (fdtable->max_fds, sizeof (fdentry_t),
- gf_common_mt_fdentry_t);
- gf_fd_chain_fd_entries (fdtable->fdentries, 0, fdtable->max_fds);
- *count = fdtable->max_fds;
+ }
out:
- return fdentries;
+ return fdentries;
}
-
fdentry_t *
-gf_fd_fdtable_get_all_fds (fdtable_t *fdtable, uint32_t *count)
+gf_fd_fdtable_copy_all_fds(fdtable_t *fdtable, uint32_t *count)
{
- fdentry_t *entries = NULL;
+ fdentry_t *entries = NULL;
- if (fdtable) {
- pthread_mutex_lock (&fdtable->lock);
- {
- entries = __gf_fd_fdtable_get_all_fds (fdtable, count);
- }
- pthread_mutex_unlock (&fdtable->lock);
+ if (fdtable) {
+ pthread_rwlock_rdlock(&fdtable->lock);
+ {
+ entries = __gf_fd_fdtable_copy_all_fds(fdtable, count);
}
+ pthread_rwlock_unlock(&fdtable->lock);
+ }
- return entries;
+ return entries;
}
-
void
-gf_fd_fdtable_destroy (fdtable_t *fdtable)
+gf_fd_fdtable_destroy(fdtable_t *fdtable)
{
- struct list_head list = {0, };
- fd_t *fd = NULL;
- fdentry_t *fdentries = NULL;
- uint32_t fd_count = 0;
- int32_t i = 0;
-
- INIT_LIST_HEAD (&list);
-
- if (!fdtable) {
- gf_log_callingfn ("fd", GF_LOG_WARNING, "!fdtable");
- return;
- }
-
- pthread_mutex_lock (&fdtable->lock);
- {
- fdentries = __gf_fd_fdtable_get_all_fds (fdtable, &fd_count);
- GF_FREE (fdtable->fdentries);
+ struct list_head list = {
+ 0,
+ };
+ fd_t *fd = NULL;
+ fdentry_t *fdentries = NULL;
+ uint32_t fd_count = 0;
+ int32_t i = 0;
+
+ INIT_LIST_HEAD(&list);
+
+ if (!fdtable) {
+ gf_msg_callingfn("fd", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "!fdtable");
+ return;
+ }
+
+ pthread_rwlock_wrlock(&fdtable->lock);
+ {
+ fdentries = __gf_fd_fdtable_get_all_fds(fdtable, &fd_count);
+ GF_FREE(fdtable->fdentries);
+ }
+ pthread_rwlock_unlock(&fdtable->lock);
+
+ if (fdentries != NULL) {
+ for (i = 0; i < fd_count; i++) {
+ fd = fdentries[i].fd;
+ if (fd != NULL) {
+ fd_unref(fd);
+ }
}
- pthread_mutex_unlock (&fdtable->lock);
-
- if (fdentries != NULL) {
- for (i = 0; i < fd_count; i++) {
- fd = fdentries[i].fd;
- if (fd != NULL) {
- fd_unref (fd);
- }
- }
- GF_FREE (fdentries);
- pthread_mutex_destroy (&fdtable->lock);
- GF_FREE (fdtable);
- }
+ GF_FREE(fdentries);
+ pthread_rwlock_destroy(&fdtable->lock);
+ GF_FREE(fdtable);
+ }
}
-
int
-gf_fd_unused_get (fdtable_t *fdtable, fd_t *fdptr)
+gf_fd_unused_get(fdtable_t *fdtable, fd_t *fdptr)
{
- int32_t fd = -1;
- fdentry_t *fde = NULL;
- int error;
- int alloc_attempts = 0;
-
- if (fdtable == NULL || fdptr == NULL) {
- gf_log_callingfn ("fd", GF_LOG_ERROR, "invalid argument");
- return EINVAL;
- }
-
- pthread_mutex_lock (&fdtable->lock);
- {
- fd_alloc_try_again:
- if (fdtable->first_free != GF_FDTABLE_END) {
- fde = &fdtable->fdentries[fdtable->first_free];
- fd = fdtable->first_free;
- fdtable->first_free = fde->next_free;
- fde->next_free = GF_FDENTRY_ALLOCATED;
- fde->fd = fdptr;
- } else {
- /* If this is true, there is something
- * seriously wrong with our data structures.
- */
- if (alloc_attempts >= 2) {
- gf_log ("fd", GF_LOG_ERROR,
- "multiple attempts to expand fd table"
- " have failed.");
- goto out;
- }
- error = gf_fd_fdtable_expand (fdtable,
- fdtable->max_fds + 1);
- if (error) {
- gf_log ("fd", GF_LOG_ERROR,
- "Cannot expand fdtable: %s",
- strerror (error));
- goto out;
- }
- ++alloc_attempts;
- /* At this point, the table stands expanded
- * with the first_free referring to the first
- * free entry in the new set of fdentries that
- * have just been allocated. That means, the
- * above logic should just work.
- */
- goto fd_alloc_try_again;
- }
+ int32_t fd = -1;
+ fdentry_t *fde = NULL;
+ int error;
+ int alloc_attempts = 0;
+
+ if (fdtable == NULL || fdptr == NULL) {
+ gf_msg_callingfn("fd", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ return EINVAL;
+ }
+
+ pthread_rwlock_wrlock(&fdtable->lock);
+ {
+ fd_alloc_try_again:
+ if (fdtable->first_free != GF_FDTABLE_END) {
+ fde = &fdtable->fdentries[fdtable->first_free];
+ fd = fdtable->first_free;
+ fdtable->first_free = fde->next_free;
+ fde->next_free = GF_FDENTRY_ALLOCATED;
+ fde->fd = fdptr;
+ } else {
+ /* If this is true, there is something
+ * seriously wrong with our data structures.
+ */
+ if (alloc_attempts >= 2) {
+ gf_msg("fd", GF_LOG_ERROR, 0, LG_MSG_EXPAND_FD_TABLE_FAILED,
+ "multiple attempts to expand fd table"
+ " have failed.");
+ goto out;
+ }
+ error = gf_fd_fdtable_expand(fdtable, fdtable->max_fds + 1);
+ if (error) {
+ gf_msg("fd", GF_LOG_ERROR, error, LG_MSG_EXPAND_FD_TABLE_FAILED,
+ "Cannot expand fdtable");
+ goto out;
+ }
+ ++alloc_attempts;
+ /* At this point, the table stands expanded
+ * with the first_free referring to the first
+ * free entry in the new set of fdentries that
+ * have just been allocated. That means, the
+ * above logic should just work.
+ */
+ goto fd_alloc_try_again;
}
+ }
out:
- pthread_mutex_unlock (&fdtable->lock);
+ pthread_rwlock_unlock(&fdtable->lock);
- return fd;
+ return fd;
}
-
-inline void
-gf_fd_put (fdtable_t *fdtable, int32_t fd)
+void
+gf_fd_put(fdtable_t *fdtable, int32_t fd)
{
- fd_t *fdptr = NULL;
- fdentry_t *fde = NULL;
+ fd_t *fdptr = NULL;
+ fdentry_t *fde = NULL;
- if (fdtable == NULL || fd < 0) {
- gf_log_callingfn ("fd", GF_LOG_ERROR, "invalid argument");
- return;
- }
+ if (fd == GF_ANON_FD_NO)
+ return;
- if (!(fd < fdtable->max_fds)) {
- gf_log_callingfn ("fd", GF_LOG_ERROR, "invalid argument");
- return;
- }
+ if (fdtable == NULL || fd < 0) {
+ gf_msg_callingfn("fd", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ return;
+ }
- pthread_mutex_lock (&fdtable->lock);
- {
- fde = &fdtable->fdentries[fd];
- /* If the entry is not allocated, put operation must return
- * without doing anything.
- * This has the potential of masking out any bugs in a user of
- * fd that ends up calling gf_fd_put twice for the same fd or
- * for an unallocated fd, but thats a price we have to pay for
- * ensuring sanity of our fd-table.
- */
- if (fde->next_free != GF_FDENTRY_ALLOCATED)
- goto unlock_out;
- fdptr = fde->fd;
- fde->fd = NULL;
- fde->next_free = fdtable->first_free;
- fdtable->first_free = fd;
- }
+ if (!(fd < fdtable->max_fds)) {
+ gf_msg_callingfn("fd", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ return;
+ }
+
+ pthread_rwlock_wrlock(&fdtable->lock);
+ {
+ fde = &fdtable->fdentries[fd];
+ /* If the entry is not allocated, put operation must return
+ * without doing anything.
+ * This has the potential of masking out any bugs in a user of
+ * fd that ends up calling gf_fd_put twice for the same fd or
+ * for an unallocated fd, but it is a price we have to pay for
+ * ensuring sanity of our fd-table.
+ */
+ if (fde->next_free != GF_FDENTRY_ALLOCATED)
+ goto unlock_out;
+ fdptr = fde->fd;
+ fde->fd = NULL;
+ fde->next_free = fdtable->first_free;
+ fdtable->first_free = fd;
+ }
unlock_out:
- pthread_mutex_unlock (&fdtable->lock);
+ pthread_rwlock_unlock(&fdtable->lock);
- if (fdptr) {
- fd_unref (fdptr);
- }
+ if (fdptr) {
+ fd_unref(fdptr);
+ }
}
-
-fd_t *
-gf_fd_fdptr_get (fdtable_t *fdtable, int64_t fd)
+void
+gf_fdptr_put(fdtable_t *fdtable, fd_t *fd)
{
- fd_t *fdptr = NULL;
+ fdentry_t *fde = NULL;
+ int32_t i = 0;
- if (fdtable == NULL || fd < 0) {
- gf_log_callingfn ("fd", GF_LOG_ERROR, "invalid argument");
- errno = EINVAL;
- return NULL;
+ if ((fdtable == NULL) || (fd == NULL)) {
+ gf_msg_callingfn("fd", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ return;
+ }
+
+ pthread_rwlock_wrlock(&fdtable->lock);
+ {
+ for (i = 0; i < fdtable->max_fds; i++) {
+ if (fdtable->fdentries[i].fd == fd) {
+ fde = &fdtable->fdentries[i];
+ break;
+ }
}
- if (!(fd < fdtable->max_fds)) {
- gf_log_callingfn ("fd", GF_LOG_ERROR, "invalid argument");
- errno = EINVAL;
- return NULL;
+ if (fde == NULL) {
+ gf_msg_callingfn("fd", GF_LOG_WARNING, 0,
+ LG_MSG_FD_NOT_FOUND_IN_FDTABLE,
+ "fd (%p) is not present in fdtable", fd);
+ goto unlock_out;
}
- pthread_mutex_lock (&fdtable->lock);
- {
- fdptr = fdtable->fdentries[fd].fd;
- if (fdptr) {
- fd_ref (fdptr);
- }
- }
- pthread_mutex_unlock (&fdtable->lock);
+ /* If the entry is not allocated, put operation must return
+ * without doing anything.
+ * This has the potential of masking out any bugs in a user of
+ * fd that ends up calling gf_fd_put twice for the same fd or
+ * for an unallocated fd, but it is a price we have to pay for
+ * ensuring sanity of our fd-table.
+ */
+ if (fde->next_free != GF_FDENTRY_ALLOCATED)
+ goto unlock_out;
+ fde->fd = NULL;
+ fde->next_free = fdtable->first_free;
+ fdtable->first_free = i;
+ }
+unlock_out:
+ pthread_rwlock_unlock(&fdtable->lock);
- return fdptr;
+ if ((fd != NULL) && (fde != NULL)) {
+ fd_unref(fd);
+ }
}
-
fd_t *
-_fd_ref (fd_t *fd)
+gf_fd_fdptr_get(fdtable_t *fdtable, int64_t fd)
{
- ++fd->refcount;
+ fd_t *fdptr = NULL;
+
+ if (fdtable == NULL || fd < 0) {
+ gf_msg_callingfn("fd", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if (!(fd < fdtable->max_fds)) {
+ gf_msg_callingfn("fd", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ errno = EINVAL;
+ return NULL;
+ }
+
+ pthread_rwlock_rdlock(&fdtable->lock);
+ {
+ fdptr = fdtable->fdentries[fd].fd;
+ if (fdptr) {
+ fd_ref(fdptr);
+ }
+ }
+ pthread_rwlock_unlock(&fdtable->lock);
- return fd;
+ return fdptr;
}
-
fd_t *
-fd_ref (fd_t *fd)
+__fd_ref(fd_t *fd)
{
- fd_t *refed_fd = NULL;
-
- if (!fd) {
- gf_log_callingfn ("fd", GF_LOG_ERROR, "null fd");
- return NULL;
- }
+ GF_ATOMIC_INC(fd->refcount);
- LOCK (&fd->inode->lock);
- refed_fd = _fd_ref (fd);
- UNLOCK (&fd->inode->lock);
-
- return refed_fd;
+ return fd;
}
-
fd_t *
-_fd_unref (fd_t *fd)
+fd_ref(fd_t *fd)
{
- GF_ASSERT (fd->refcount);
+ if (!fd) {
+ gf_msg_callingfn("fd", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "null fd");
+ return NULL;
+ }
- --fd->refcount;
-
- if (fd->refcount == 0) {
- list_del_init (&fd->inode_list);
- }
+ GF_ATOMIC_INC(fd->refcount);
- return fd;
+ return fd;
}
-
static void
-fd_destroy (fd_t *fd)
+fd_destroy(fd_t *fd, gf_boolean_t bound)
{
- xlator_t *xl = NULL;
- int i = 0;
- xlator_t *old_THIS = NULL;
- struct mem_pool *tmp_pool = NULL;
-
- if (fd == NULL){
- gf_log_callingfn ("xlator", GF_LOG_ERROR, "invalid arugument");
- goto out;
+ xlator_t *xl = NULL;
+ int i = 0;
+ xlator_t *old_THIS = NULL;
+
+ if (fd == NULL) {
+ gf_msg_callingfn("xlator", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ goto out;
+ }
+
+ if (fd->inode == NULL) {
+ gf_msg_callingfn("xlator", GF_LOG_ERROR, 0, LG_MSG_FD_INODE_NULL,
+ "fd->inode is NULL");
+ goto out;
+ }
+ if (!fd->_ctx)
+ goto out;
+
+ if (IA_ISDIR(fd->inode->ia_type)) {
+ for (i = 0; i < fd->xl_count; i++) {
+ if (fd->_ctx[i].key) {
+ xl = fd->_ctx[i].xl_key;
+ old_THIS = THIS;
+ THIS = xl;
+ if (!xl->call_cleanup && xl->cbks->releasedir)
+ xl->cbks->releasedir(xl, fd);
+ THIS = old_THIS;
+ }
}
+ } else {
+ for (i = 0; i < fd->xl_count; i++) {
+ if (fd->_ctx[i].key) {
+ xl = fd->_ctx[i].xl_key;
+ old_THIS = THIS;
+ THIS = xl;
+ if (!xl->call_cleanup && xl->cbks->release)
+ xl->cbks->release(xl, fd);
+ THIS = old_THIS;
+ }
+ }
+ }
- if (fd->inode == NULL){
- gf_log_callingfn ("xlator", GF_LOG_ERROR, "fd->inode is NULL");
- goto out;
+ LOCK_DESTROY(&fd->lock);
+
+ GF_FREE(fd->_ctx);
+ if (bound) {
+ /*Decrease the count only after close happens on file*/
+ LOCK(&fd->inode->lock);
+ {
+ fd->inode->fd_count--;
}
- if (!fd->_ctx)
- goto out;
+ UNLOCK(&fd->inode->lock);
+ }
+ inode_unref(fd->inode);
+ fd->inode = NULL;
+ fd_lk_ctx_unref(fd->lk_ctx);
+ mem_put(fd);
+out:
+ return;
+}
- tmp_pool = fd->inode->table->fd_mem_pool;
-
- if (IA_ISDIR (fd->inode->ia_type)) {
- for (i = 0; i < fd->xl_count; i++) {
- if (fd->_ctx[i].key) {
- xl = fd->_ctx[i].xl_key;
- old_THIS = THIS;
- THIS = xl;
- if (xl->cbks->releasedir)
- xl->cbks->releasedir (xl, fd);
- THIS = old_THIS;
- }
+void
+fd_close(fd_t *fd)
+{
+ xlator_t *xl, *old_THIS;
+
+ old_THIS = THIS;
+
+ for (xl = fd->inode->table->xl->graph->first; xl != NULL; xl = xl->next) {
+ if (!xl->call_cleanup) {
+ THIS = xl;
+
+ if (IA_ISDIR(fd->inode->ia_type)) {
+ if (xl->cbks->fdclosedir != NULL) {
+ xl->cbks->fdclosedir(xl, fd);
}
- } else {
- for (i = 0; i < fd->xl_count; i++) {
- if (fd->_ctx[i].key) {
- xl = fd->_ctx[i].xl_key;
- old_THIS = THIS;
- THIS = xl;
- if (xl->cbks->release)
- xl->cbks->release (xl, fd);
- THIS = old_THIS;
- }
+ } else {
+ if (xl->cbks->fdclose != NULL) {
+ xl->cbks->fdclose(xl, fd);
}
+ }
}
+ }
- LOCK_DESTROY (&fd->lock);
-
- GF_FREE (fd->_ctx);
- inode_unref (fd->inode);
- fd->inode = (inode_t *)0xaaaaaaaa;
- mem_put (tmp_pool,fd);
- tmp_pool = NULL;
-out:
- return;
+ THIS = old_THIS;
}
-
void
-fd_unref (fd_t *fd)
+fd_unref(fd_t *fd)
{
- int32_t refcount = 0;
+ int32_t refcount = 0;
+ gf_boolean_t bound = _gf_false;
- if (!fd) {
- gf_log_callingfn ("fd", GF_LOG_ERROR, "fd is NULL");
- return;
- }
-
- LOCK (&fd->inode->lock);
- {
- _fd_unref (fd);
- refcount = fd->refcount;
- }
- UNLOCK (&fd->inode->lock);
+ if (!fd) {
+ gf_msg_callingfn("fd", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "fd is NULL");
+ return;
+ }
+ LOCK(&fd->inode->lock);
+ {
+ refcount = GF_ATOMIC_DEC(fd->refcount);
if (refcount == 0) {
- fd_destroy (fd);
+ if (!list_empty(&fd->inode_list)) {
+ list_del_init(&fd->inode_list);
+ fd->inode->active_fd_count--;
+ bound = _gf_true;
+ }
}
+ }
+ UNLOCK(&fd->inode->lock);
+
+ if (refcount == 0) {
+ fd_destroy(fd, bound);
+ }
- return ;
+ return;
}
+static fd_t *
+__fd_bind(fd_t *fd)
+{
+ list_del_init(&fd->inode_list);
+ list_add(&fd->inode_list, &fd->inode->fd_list);
+ fd->inode->fd_count++;
+ fd->inode->active_fd_count++;
+
+ return fd;
+}
fd_t *
-fd_bind (fd_t *fd)
+fd_bind(fd_t *fd)
{
- inode_t *inode = NULL;
+ if (!fd || !fd->inode) {
+ gf_msg_callingfn("fd", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "!fd || !fd->inode");
+ return NULL;
+ }
+
+ LOCK(&fd->inode->lock);
+ {
+ fd = __fd_bind(fd);
+ }
+ UNLOCK(&fd->inode->lock);
+
+ return fd;
+}
- if (!fd || !fd->inode) {
- gf_log_callingfn ("fd", GF_LOG_ERROR, "!fd || !fd->inode");
- return NULL;
- }
- inode = fd->inode;
+static fd_t *
+fd_allocate(inode_t *inode, uint64_t pid)
+{
+ fd_t *fd;
+
+ if (inode == NULL) {
+ gf_msg_callingfn("fd", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ return NULL;
+ }
+
+ fd = mem_get0(inode->table->fd_mem_pool);
+ if (fd == NULL) {
+ return NULL;
+ }
+
+ fd->xl_count = inode->table->xl->graph->xl_count + 1;
+
+ fd->_ctx = GF_CALLOC(1, (sizeof(struct _fd_ctx) * fd->xl_count),
+ gf_common_mt_fd_ctx);
+ if (fd->_ctx == NULL) {
+ goto failed;
+ }
+
+ fd->lk_ctx = fd_lk_ctx_create();
+ if (fd->lk_ctx != NULL) {
+ /* We need to take a reference from the inode, but we cannot do it
+ * here because this function can be called with the inode lock taken
+ * and inode_ref() takes the inode's table lock. This is the reverse
+ * of the logical lock acquisition order and can cause a deadlock. So
+ * we simply assign the inode here and we delefate the inode reference
+ * responsibility to the caller (when this function succeeds and the
+ * inode lock is released). This is safe because the caller must hold
+ * a reference of the inode to use it, so it's guaranteed that the
+ * number of references won't reach 0 before the caller finishes.
+ *
+ * TODO: minimize use of locks in favor of atomic operations to avoid
+ * these dependencies. */
+ fd->inode = inode;
+ fd->pid = pid;
+ INIT_LIST_HEAD(&fd->inode_list);
+ LOCK_INIT(&fd->lock);
+ GF_ATOMIC_INIT(fd->refcount, 1);
+ return fd;
+ }
- LOCK (&inode->lock);
- {
- list_add (&fd->inode_list, &inode->fd_list);
- }
- UNLOCK (&inode->lock);
+ GF_FREE(fd->_ctx);
- return fd;
+failed:
+ mem_put(fd);
+
+ return NULL;
}
+fd_t *
+fd_create_uint64(inode_t *inode, uint64_t pid)
+{
+ fd_t *fd;
+
+ fd = fd_allocate(inode, pid);
+ if (fd != NULL) {
+ /* fd_allocate() doesn't get a reference from the inode. We need to
+ * take it here in case of success. */
+ inode_ref(inode);
+ }
+
+ return fd;
+}
fd_t *
-fd_create (inode_t *inode, pid_t pid)
+fd_create(inode_t *inode, pid_t pid)
{
- fd_t *fd = NULL;
+ return fd_create_uint64(inode, (uint64_t)pid);
+}
- if (inode == NULL) {
- gf_log_callingfn ("fd", GF_LOG_ERROR, "invalid argument");
- return NULL;
+static fd_t *
+__fd_lookup(inode_t *inode, uint64_t pid)
+{
+ fd_t *iter_fd = NULL;
+ fd_t *fd = NULL;
+
+ if (list_empty(&inode->fd_list))
+ return NULL;
+
+ list_for_each_entry(iter_fd, &inode->fd_list, inode_list)
+ {
+ if (iter_fd->anonymous)
+ /* If someone was interested in getting an
+ anonymous fd (or was OK getting an anonymous fd),
+ they can as well call fd_anonymous() directly */
+ continue;
+
+ if (!pid || iter_fd->pid == pid) {
+ fd = __fd_ref(iter_fd);
+ break;
}
+ }
- fd = mem_get0 (inode->table->fd_mem_pool);
- if (!fd)
- goto out;
+ return fd;
+}
- fd->xl_count = inode->table->xl->graph->xl_count + 1;
+fd_t *
+fd_lookup(inode_t *inode, pid_t pid)
+{
+ fd_t *fd = NULL;
- fd->_ctx = GF_CALLOC (1, (sizeof (struct _fd_ctx) * fd->xl_count),
- gf_common_mt_fd_ctx);
- if (!fd->_ctx) {
- GF_FREE (fd);
- fd = NULL;
- goto out;
- }
+ if (!inode) {
+ gf_msg_callingfn("fd", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "!inode");
+ return NULL;
+ }
- fd->inode = inode_ref (inode);
- fd->pid = pid;
- INIT_LIST_HEAD (&fd->inode_list);
+ LOCK(&inode->lock);
+ {
+ fd = __fd_lookup(inode, (uint64_t)pid);
+ }
+ UNLOCK(&inode->lock);
- LOCK_INIT (&fd->lock);
+ return fd;
+}
- LOCK (&inode->lock);
- {
- fd = _fd_ref (fd);
- }
- UNLOCK (&inode->lock);
-out:
- return fd;
+fd_t *
+fd_lookup_uint64(inode_t *inode, uint64_t pid)
+{
+ fd_t *fd = NULL;
+
+ if (!inode) {
+ gf_msg_callingfn("fd", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "!inode");
+ return NULL;
+ }
+
+ LOCK(&inode->lock);
+ {
+ fd = __fd_lookup(inode, pid);
+ }
+ UNLOCK(&inode->lock);
+
+ return fd;
}
+static fd_t *
+__fd_lookup_anonymous(inode_t *inode, int32_t flags)
+{
+ fd_t *iter_fd = NULL;
+ fd_t *fd = NULL;
+
+ if (list_empty(&inode->fd_list))
+ return NULL;
+
+ list_for_each_entry(iter_fd, &inode->fd_list, inode_list)
+ {
+ if ((iter_fd->anonymous) && (flags == iter_fd->flags)) {
+ fd = __fd_ref(iter_fd);
+ break;
+ }
+ }
+
+ return fd;
+}
fd_t *
-fd_lookup (inode_t *inode, pid_t pid)
+fd_anonymous_with_flags(inode_t *inode, int32_t flags)
{
- fd_t *fd = NULL;
- fd_t *iter_fd = NULL;
+ fd_t *fd = NULL;
+ bool ref = false;
- if (!inode) {
- gf_log_callingfn ("fd", GF_LOG_WARNING, "!inode");
- return NULL;
- }
+ LOCK(&inode->lock);
- LOCK (&inode->lock);
- {
- if (list_empty (&inode->fd_list)) {
- fd = NULL;
- } else {
- list_for_each_entry (iter_fd, &inode->fd_list, inode_list) {
- if (pid) {
- if (iter_fd->pid == pid) {
- fd = _fd_ref (iter_fd);
- break;
- }
- } else {
- fd = _fd_ref (iter_fd);
- break;
- }
- }
- }
+ fd = __fd_lookup_anonymous(inode, flags);
+
+ /* if (fd); then we already have increased the refcount in
+ __fd_lookup_anonymous(), so no need of one more fd_ref().
+ if (!fd); then both create and bind won't bump up the ref
+ count, so we have to call fd_ref() after bind. */
+ if (fd == NULL) {
+ fd = fd_allocate(inode, 0);
+ if (fd != NULL) {
+ fd->anonymous = _gf_true;
+ fd->flags = GF_ANON_FD_FLAGS | (flags & O_DIRECT);
+
+ __fd_bind(fd);
+
+ ref = true;
}
- UNLOCK (&inode->lock);
+ }
- return fd;
+ UNLOCK(&inode->lock);
+
+ if (ref) {
+ /* fd_allocate() doesn't get a reference from the inode. We need to
+ * take it here in case of success. */
+ inode_ref(inode);
+ }
+
+ return fd;
}
+fd_t *
+fd_anonymous(inode_t *inode)
+{
+ return fd_anonymous_with_flags(inode, 0);
+}
+
+fd_t *
+fd_lookup_anonymous(inode_t *inode, int32_t flags)
+{
+ fd_t *fd = NULL;
+
+ if (!inode) {
+ gf_msg_callingfn("fd", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "!inode");
+ return NULL;
+ }
+
+ LOCK(&inode->lock);
+ {
+ fd = __fd_lookup_anonymous(inode, flags);
+ }
+ UNLOCK(&inode->lock);
+ return fd;
+}
+
+gf_boolean_t
+fd_is_anonymous(fd_t *fd)
+{
+ return (fd && fd->anonymous);
+}
uint8_t
-fd_list_empty (inode_t *inode)
+fd_list_empty(inode_t *inode)
{
- uint8_t empty = 0;
+ uint8_t empty = 0;
- LOCK (&inode->lock);
- {
- empty = list_empty (&inode->fd_list);
- }
- UNLOCK (&inode->lock);
+ LOCK(&inode->lock);
+ {
+ empty = list_empty(&inode->fd_list);
+ }
+ UNLOCK(&inode->lock);
- return empty;
+ return empty;
}
-
int
-__fd_ctx_set (fd_t *fd, xlator_t *xlator, uint64_t value)
+__fd_ctx_set(fd_t *fd, xlator_t *xlator, uint64_t value)
{
- int index = 0;
- int ret = 0;
- int set_idx = -1;
+ int index = 0, new_xl_count = 0;
+ int ret = 0;
+ int set_idx = -1;
+ void *begin = NULL;
+ size_t diff = 0;
+ struct _fd_ctx *tmp = NULL;
+
+ if (!fd || !xlator)
+ return -1;
+
+ for (index = 0; index < fd->xl_count; index++) {
+ if (!fd->_ctx[index].key) {
+ if (set_idx == -1)
+ set_idx = index;
+ /* don't break, to check if key already exists
+ further on */
+ }
+ if (fd->_ctx[index].xl_key == xlator) {
+ set_idx = index;
+ break;
+ }
+ }
- if (!fd || !xlator)
- return -1;
+ if (set_idx == -1) {
+ set_idx = fd->xl_count;
- for (index = 0; index < fd->xl_count; index++) {
- if (!fd->_ctx[index].key) {
- if (set_idx == -1)
- set_idx = index;
- /* dont break, to check if key already exists
- further on */
- }
- if (fd->_ctx[index].xl_key == xlator) {
- set_idx = index;
- break;
- }
- }
+ new_xl_count = fd->xl_count + xlator->graph->xl_count;
- if (set_idx == -1) {
- gf_log_callingfn ("", GF_LOG_WARNING, "%p %s", fd, xlator->name);
- ret = -1;
- goto out;
+ tmp = GF_REALLOC(fd->_ctx, (sizeof(struct _fd_ctx) * new_xl_count));
+ if (tmp == NULL) {
+ ret = -1;
+ goto out;
}
- fd->_ctx[set_idx].xl_key = xlator;
- fd->_ctx[set_idx].value1 = value;
+ fd->_ctx = tmp;
+
+ begin = fd->_ctx;
+ begin += (fd->xl_count * sizeof(struct _fd_ctx));
+
+ diff = (new_xl_count - fd->xl_count) * sizeof(struct _fd_ctx);
+
+ memset(begin, 0, diff);
+
+ fd->xl_count = new_xl_count;
+ }
+
+ fd->_ctx[set_idx].xl_key = xlator;
+ fd->_ctx[set_idx].value1 = value;
out:
- return ret;
+ return ret;
}
-
int
-fd_ctx_set (fd_t *fd, xlator_t *xlator, uint64_t value)
+fd_ctx_set(fd_t *fd, xlator_t *xlator, uint64_t value)
{
- int ret = 0;
+ int ret = 0;
- if (!fd || !xlator) {
- gf_log_callingfn ("", GF_LOG_WARNING, "%p %p", fd, xlator);
- return -1;
- }
+ if (!fd || !xlator) {
+ gf_msg_callingfn("fd", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "%p %p", fd, xlator);
+ return -1;
+ }
- LOCK (&fd->lock);
- {
- ret = __fd_ctx_set (fd, xlator, value);
- }
- UNLOCK (&fd->lock);
+ LOCK(&fd->lock);
+ {
+ ret = __fd_ctx_set(fd, xlator, value);
+ }
+ UNLOCK(&fd->lock);
- return ret;
+ return ret;
}
-
int
-__fd_ctx_get (fd_t *fd, xlator_t *xlator, uint64_t *value)
+__fd_ctx_get(fd_t *fd, xlator_t *xlator, uint64_t *value)
{
- int index = 0;
- int ret = 0;
+ int index = 0;
+ int ret = 0;
- if (!fd || !xlator)
- return -1;
+ if (!fd || !xlator)
+ return -1;
- for (index = 0; index < fd->xl_count; index++) {
- if (fd->_ctx[index].xl_key == xlator)
- break;
- }
+ for (index = 0; index < fd->xl_count; index++) {
+ if (fd->_ctx[index].xl_key == xlator)
+ break;
+ }
- if (index == fd->xl_count) {
- ret = -1;
- goto out;
- }
+ if (index == fd->xl_count) {
+ ret = -1;
+ goto out;
+ }
- if (value)
- *value = fd->_ctx[index].value1;
+ if (value)
+ *value = fd->_ctx[index].value1;
out:
- return ret;
+ return ret;
}
-
int
-fd_ctx_get (fd_t *fd, xlator_t *xlator, uint64_t *value)
+fd_ctx_get(fd_t *fd, xlator_t *xlator, uint64_t *value)
{
- int ret = 0;
+ int ret = 0;
- if (!fd || !xlator)
- return -1;
+ if (!fd || !xlator)
+ return -1;
- LOCK (&fd->lock);
- {
- ret = __fd_ctx_get (fd, xlator, value);
- }
- UNLOCK (&fd->lock);
+ LOCK(&fd->lock);
+ {
+ ret = __fd_ctx_get(fd, xlator, value);
+ }
+ UNLOCK(&fd->lock);
- return ret;
+ return ret;
}
-
int
-__fd_ctx_del (fd_t *fd, xlator_t *xlator, uint64_t *value)
+__fd_ctx_del(fd_t *fd, xlator_t *xlator, uint64_t *value)
{
- int index = 0;
- int ret = 0;
+ int index = 0;
+ int ret = 0;
- if (!fd || !xlator)
- return -1;
+ if (!fd || !xlator)
+ return -1;
- for (index = 0; index < fd->xl_count; index++) {
- if (fd->_ctx[index].xl_key == xlator)
- break;
- }
+ for (index = 0; index < fd->xl_count; index++) {
+ if (fd->_ctx[index].xl_key == xlator)
+ break;
+ }
- if (index == fd->xl_count) {
- ret = -1;
- goto out;
- }
+ if (index == fd->xl_count) {
+ ret = -1;
+ goto out;
+ }
- if (value)
- *value = fd->_ctx[index].value1;
+ if (value)
+ *value = fd->_ctx[index].value1;
- fd->_ctx[index].key = 0;
- fd->_ctx[index].value1 = 0;
+ fd->_ctx[index].key = 0;
+ fd->_ctx[index].value1 = 0;
out:
- return ret;
+ return ret;
}
-
int
-fd_ctx_del (fd_t *fd, xlator_t *xlator, uint64_t *value)
+fd_ctx_del(fd_t *fd, xlator_t *xlator, uint64_t *value)
{
- int ret = 0;
+ int ret = 0;
- if (!fd || !xlator)
- return -1;
+ if (!fd || !xlator)
+ return -1;
- LOCK (&fd->lock);
- {
- ret = __fd_ctx_del (fd, xlator, value);
- }
- UNLOCK (&fd->lock);
+ LOCK(&fd->lock);
+ {
+ ret = __fd_ctx_del(fd, xlator, value);
+ }
+ UNLOCK(&fd->lock);
- return ret;
+ return ret;
}
-
void
-fd_dump (fd_t *fd, char *prefix)
-{
- char key[GF_DUMP_MAX_BUF_LEN];
-
- if (!fd)
- return;
-
- memset(key, 0, sizeof(key));
- gf_proc_dump_build_key(key, prefix, "pid");
- gf_proc_dump_write(key, "%d", fd->pid);
- gf_proc_dump_build_key(key, prefix, "refcount");
- gf_proc_dump_write(key, "%d", fd->refcount);
- gf_proc_dump_build_key(key, prefix, "flags");
- gf_proc_dump_write(key, "%d", fd->flags);
- if (fd->inode) {
- gf_proc_dump_build_key(key, prefix, "inode");
- gf_proc_dump_write(key, "%ld", fd->inode->ino);
- }
-}
+fd_dump(fd_t *fd, char *prefix)
+{
+ char key[GF_DUMP_MAX_BUF_LEN];
+ if (!fd)
+ return;
+
+ gf_proc_dump_write("pid", "%" PRIu64, fd->pid);
+ gf_proc_dump_write("refcount", "%" GF_PRI_ATOMIC,
+ GF_ATOMIC_GET(fd->refcount));
+ gf_proc_dump_write("flags", "%d", fd->flags);
+
+ if (fd->inode) {
+ gf_proc_dump_build_key(key, "inode", NULL);
+ gf_proc_dump_add_section("%s", key);
+ inode_dump(fd->inode, key);
+ }
+}
void
-fdentry_dump (fdentry_t *fdentry, char *prefix)
+fdentry_dump(fdentry_t *fdentry, char *prefix)
{
- if (!fdentry)
- return;
+ if (!fdentry)
+ return;
- if (GF_FDENTRY_ALLOCATED != fdentry->next_free)
- return;
+ if (GF_FDENTRY_ALLOCATED != fdentry->next_free)
+ return;
- if (fdentry->fd)
- fd_dump(fdentry->fd, prefix);
+ if (fdentry->fd)
+ fd_dump(fdentry->fd, prefix);
}
-
void
-fdtable_dump (fdtable_t *fdtable, char *prefix)
+fdtable_dump(fdtable_t *fdtable, char *prefix)
{
- char key[GF_DUMP_MAX_BUF_LEN];
- int i = 0;
- int ret = -1;
+ char key[GF_DUMP_MAX_BUF_LEN];
+ int i = 0;
+ int ret = -1;
+
+ if (!fdtable)
+ return;
- if (!fdtable)
- return;
+ ret = pthread_rwlock_tryrdlock(&fdtable->lock);
+ if (ret)
+ goto out;
+
+ gf_proc_dump_build_key(key, prefix, "refcount");
+ gf_proc_dump_write(key, "%d", fdtable->refcount);
+ gf_proc_dump_build_key(key, prefix, "maxfds");
+ gf_proc_dump_write(key, "%d", fdtable->max_fds);
+ gf_proc_dump_build_key(key, prefix, "first_free");
+ gf_proc_dump_write(key, "%d", fdtable->first_free);
+
+ for (i = 0; i < fdtable->max_fds; i++) {
+ if (GF_FDENTRY_ALLOCATED == fdtable->fdentries[i].next_free) {
+ gf_proc_dump_build_key(key, prefix, "fdentry[%d]", i);
+ gf_proc_dump_add_section("%s", key);
+ fdentry_dump(&fdtable->fdentries[i], key);
+ }
+ }
- ret = pthread_mutex_trylock (&fdtable->lock);
+ pthread_rwlock_unlock(&fdtable->lock);
- if (ret) {
- gf_log ("fd", GF_LOG_WARNING, "Unable to acquire lock");
- return;
+out:
+ if (ret != 0)
+ gf_proc_dump_write("Unable to dump the fdtable",
+ "(Lock acquistion failed) %p", fdtable);
+ return;
+}
+
+void
+fd_ctx_dump(fd_t *fd, char *prefix)
+{
+ struct _fd_ctx *fd_ctx = NULL;
+ xlator_t *xl = NULL;
+ int i = 0;
+
+ if ((fd == NULL) || (fd->_ctx == NULL)) {
+ goto out;
+ }
+
+ LOCK(&fd->lock);
+ {
+ if (fd->_ctx != NULL) {
+ fd_ctx = GF_CALLOC(fd->xl_count, sizeof(*fd_ctx),
+ gf_common_mt_fd_ctx);
+ if (fd_ctx == NULL) {
+ goto unlock;
+ }
+
+ for (i = 0; i < fd->xl_count; i++) {
+ fd_ctx[i] = fd->_ctx[i];
+ }
}
+ }
+unlock:
+ UNLOCK(&fd->lock);
- memset(key, 0, sizeof(key));
- gf_proc_dump_build_key(key, prefix, "refcount");
- gf_proc_dump_write(key, "%d", fdtable->refcount);
- gf_proc_dump_build_key(key, prefix, "maxfds");
- gf_proc_dump_write(key, "%d", fdtable->max_fds);
- gf_proc_dump_build_key(key, prefix, "first_free");
- gf_proc_dump_write(key, "%d", fdtable->first_free);
-
- for ( i = 0 ; i < fdtable->max_fds; i++) {
- if (GF_FDENTRY_ALLOCATED ==
- fdtable->fdentries[i].next_free) {
- gf_proc_dump_build_key(key, prefix, "fdentry[%d]", i);
- gf_proc_dump_add_section(key);
- fdentry_dump(&fdtable->fdentries[i], key);
- }
+ if (fd_ctx == NULL) {
+ goto out;
+ }
+
+ for (i = 0; i < fd->xl_count; i++) {
+ if (fd_ctx[i].xl_key) {
+ xl = (xlator_t *)(long)fd_ctx[i].xl_key;
+ if (xl->dumpops && xl->dumpops->fdctx)
+ xl->dumpops->fdctx(xl, fd);
}
+ }
- pthread_mutex_unlock(&fdtable->lock);
-}
+out:
+ GF_FREE(fd_ctx);
+ return;
+}
void
-fd_ctx_dump (fd_t *fd, char *prefix)
+fdentry_dump_to_dict(fdentry_t *fdentry, char *prefix, dict_t *dict,
+ int *openfds)
{
- struct _fd_ctx *fd_ctx = NULL;
- xlator_t *xl = NULL;
- int i = 0;
+ char key[GF_DUMP_MAX_BUF_LEN] = {
+ 0,
+ };
+ int ret = -1;
+ if (!fdentry)
+ return;
+ if (!dict)
+ return;
- if ((fd == NULL) || (fd->_ctx == NULL)) {
- goto out;
- }
+ if (GF_FDENTRY_ALLOCATED != fdentry->next_free)
+ return;
- LOCK (&fd->lock);
- {
- if (fd->_ctx != NULL) {
- fd_ctx = GF_CALLOC (fd->inode->table->xl->graph->xl_count,
- sizeof (*fd_ctx),
- gf_common_mt_fd_ctx);
- if (fd_ctx == NULL) {
- goto unlock;
- }
-
- for (i = 0; i < fd->inode->table->xl->graph->xl_count;
- i++) {
- fd_ctx[i] = fd->_ctx[i];
- }
- }
- }
-unlock:
- UNLOCK (&fd->lock);
+ if (fdentry->fd) {
+ snprintf(key, sizeof(key), "%s.pid", prefix);
+ ret = dict_set_uint64(dict, key, fdentry->fd->pid);
+ if (ret)
+ return;
+
+ snprintf(key, sizeof(key), "%s.refcount", prefix);
+ ret = dict_set_int32(dict, key, GF_ATOMIC_GET(fdentry->fd->refcount));
+ if (ret)
+ return;
+
+ snprintf(key, sizeof(key), "%s.flags", prefix);
+ ret = dict_set_int32(dict, key, fdentry->fd->flags);
+ if (ret)
+ return;
+
+ (*openfds)++;
+ }
+ return;
+}
- if (fd_ctx == NULL) {
- goto out;
- }
+void
+fdtable_dump_to_dict(fdtable_t *fdtable, char *prefix, dict_t *dict)
+{
+ char key[GF_DUMP_MAX_BUF_LEN] = {
+ 0,
+ };
+ int i = 0;
+ int openfds = 0;
+ int ret = -1;
+
+ if (!fdtable)
+ return;
+ if (!dict)
+ return;
- for (i = 0; i < fd->inode->table->xl->graph->xl_count; i++) {
- if (fd_ctx[i].xl_key) {
- xl = (xlator_t *)(long)fd_ctx[i].xl_key;
- if (xl->dumpops && xl->dumpops->fdctx)
- xl->dumpops->fdctx (xl, fd);
- }
- }
+ ret = pthread_rwlock_tryrdlock(&fdtable->lock);
+ if (ret)
+ return;
-out:
- if (fd_ctx != NULL) {
- GF_FREE (fd_ctx);
+ snprintf(key, sizeof(key), "%s.fdtable.refcount", prefix);
+ ret = dict_set_int32(dict, key, fdtable->refcount);
+ if (ret)
+ goto out;
+
+ snprintf(key, sizeof(key), "%s.fdtable.maxfds", prefix);
+ ret = dict_set_uint32(dict, key, fdtable->max_fds);
+ if (ret)
+ goto out;
+
+ snprintf(key, sizeof(key), "%s.fdtable.firstfree", prefix);
+ ret = dict_set_int32(dict, key, fdtable->first_free);
+ if (ret)
+ goto out;
+
+ for (i = 0; i < fdtable->max_fds; i++) {
+ if (GF_FDENTRY_ALLOCATED == fdtable->fdentries[i].next_free) {
+ snprintf(key, sizeof(key), "%s.fdtable.fdentry%d", prefix, i);
+ fdentry_dump_to_dict(&fdtable->fdentries[i], key, dict, &openfds);
}
+ }
- return;
+ snprintf(key, sizeof(key), "%s.fdtable.openfds", prefix);
+ ret = dict_set_int32(dict, key, openfds);
+ if (ret)
+ goto out;
+
+out:
+ pthread_rwlock_unlock(&fdtable->lock);
+ return;
}
diff --git a/libglusterfs/src/fd.h b/libglusterfs/src/fd.h
deleted file mode 100644
index 3c2be972ad9..00000000000
--- a/libglusterfs/src/fd.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- Copyright (c) 2007-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _FD_H
-#define _FD_H
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "list.h"
-#include <sys/types.h>
-#include <unistd.h>
-#include "glusterfs.h"
-#include "locking.h"
-
-struct _inode;
-struct _dict;
-
-struct _fd_ctx {
- union {
- uint64_t key;
- void *xl_key;
- };
- union {
- uint64_t value1;
- void *ptr1;
- };
-};
-
-/* If this structure changes, please have mercy on the booster maintainer
- * and update the fd_t struct in booster/src/booster-fd.h.
- * See the comment there to know why.
- */
-struct _fd {
- pid_t pid;
- int32_t flags;
- int32_t refcount;
- struct list_head inode_list;
- struct _inode *inode;
- gf_lock_t lock; /* used ONLY for manipulating
- 'struct _fd_ctx' array (_ctx).*/
- struct _fd_ctx *_ctx;
- int xl_count; /* Number of xl referred in this fd */
-};
-typedef struct _fd fd_t;
-
-
-struct fd_table_entry {
- fd_t *fd;
- int next_free;
-};
-typedef struct fd_table_entry fdentry_t;
-
-
-struct _fdtable {
- int refcount;
- uint32_t max_fds;
- pthread_mutex_t lock;
- fdentry_t *fdentries;
- int first_free;
-};
-typedef struct _fdtable fdtable_t;
-
-
-/* Signifies no more entries in the fd table. */
-#define GF_FDTABLE_END -1
-
-/* This is used to invalidated
- * the next_free value in an fdentry that has been allocated
- */
-#define GF_FDENTRY_ALLOCATED -2
-
-#include "logging.h"
-#include "xlator.h"
-
-
-inline void
-gf_fd_put (fdtable_t *fdtable, int32_t fd);
-
-
-fd_t *
-gf_fd_fdptr_get (fdtable_t *fdtable, int64_t fd);
-
-
-fdtable_t *
-gf_fd_fdtable_alloc (void);
-
-
-int
-gf_fd_unused_get (fdtable_t *fdtable, fd_t *fdptr);
-
-
-fdentry_t *
-gf_fd_fdtable_get_all_fds (fdtable_t *fdtable, uint32_t *count);
-
-
-void
-gf_fd_fdtable_destroy (fdtable_t *fdtable);
-
-
-fd_t *
-fd_ref (fd_t *fd);
-
-
-void
-fd_unref (fd_t *fd);
-
-
-fd_t *
-fd_create (struct _inode *inode, pid_t pid);
-
-
-fd_t *
-fd_lookup (struct _inode *inode, pid_t pid);
-
-
-uint8_t
-fd_list_empty (struct _inode *inode);
-
-
-fd_t *
-fd_bind (fd_t *fd);
-
-
-int
-fd_ctx_set (fd_t *fd, xlator_t *xlator, uint64_t value);
-
-
-int
-fd_ctx_get (fd_t *fd, xlator_t *xlator, uint64_t *value);
-
-
-int
-fd_ctx_del (fd_t *fd, xlator_t *xlator, uint64_t *value);
-
-
-int
-__fd_ctx_set (fd_t *fd, xlator_t *xlator, uint64_t value);
-
-
-int
-__fd_ctx_get (fd_t *fd, xlator_t *xlator, uint64_t *value);
-
-
-int
-__fd_ctx_del (fd_t *fd, xlator_t *xlator, uint64_t *value);
-
-fd_t *
-_fd_ref (fd_t *fd);
-
-void
-fd_ctx_dump (fd_t *fd, char *prefix);
-
-#endif /* _FD_H */
diff --git a/libglusterfs/src/gen-defaults.py b/libglusterfs/src/gen-defaults.py
new file mode 100755
index 00000000000..e31d3a9fe8a
--- /dev/null
+++ b/libglusterfs/src/gen-defaults.py
@@ -0,0 +1,81 @@
+#!/usr/bin/python3
+
+from __future__ import print_function
+import sys
+from generator import ops, fop_subs, cbk_subs, generate
+
+FAILURE_CBK_TEMPLATE = """
+int32_t
+default_@NAME@_failure_cbk (call_frame_t *frame, int32_t op_errno)
+{
+ STACK_UNWIND_STRICT (@NAME@, frame, -1, op_errno, @ERROR_ARGS@);
+ return 0;
+}
+"""
+
+CBK_RESUME_TEMPLATE = """
+int32_t
+default_@NAME@_cbk_resume (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;
+}
+"""
+
+CBK_TEMPLATE = """
+int32_t
+default_@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;
+}
+"""
+
+RESUME_TEMPLATE = """
+int32_t
+default_@NAME@_resume (call_frame_t *frame, xlator_t *this, @LONG_ARGS@)
+{
+ STACK_WIND (frame, default_@NAME@_cbk,
+ FIRST_CHILD(this), FIRST_CHILD(this)->fops->@NAME@,
+ @SHORT_ARGS@);
+ return 0;
+}
+"""
+
+FOP_TEMPLATE = """
+int32_t
+default_@NAME@ (
+ call_frame_t *frame,
+ xlator_t *this,
+ @LONG_ARGS@)
+{
+ STACK_WIND_TAIL (frame,
+ FIRST_CHILD(this), FIRST_CHILD(this)->fops->@NAME@,
+ @SHORT_ARGS@);
+ return 0;
+}
+"""
+
+def gen_defaults ():
+ for name in list(ops.keys()):
+ print(generate(FAILURE_CBK_TEMPLATE, name, cbk_subs))
+ for name in list(ops.keys()):
+ print(generate(CBK_RESUME_TEMPLATE, name, cbk_subs))
+ for name in list(ops.keys()):
+ print(generate(CBK_TEMPLATE, name, cbk_subs))
+ for name in list(ops.keys()):
+ print(generate(RESUME_TEMPLATE, name, fop_subs))
+ for name in list(ops.keys()):
+ print(generate(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/libglusterfs/src/generator.py b/libglusterfs/src/generator.py
new file mode 100755
index 00000000000..5b7aa4764a0
--- /dev/null
+++ b/libglusterfs/src/generator.py
@@ -0,0 +1,777 @@
+#!/usr/bin/python3
+
+import string
+
+# ops format: 'fop-arg' name type stub-field [nosync]
+# 'cbk-arg' name type
+# 'extra' name type arg-str
+# 'journal' fop-type
+# 'link' inode iatt
+#
+# 'role' indicates the significance of this line to the code generator (sort of
+# our own type).
+#
+# For fop-arg, we first need to know the name and the type of the arg so that
+# we can generate SHORT_ARGS (for function calls) and LONG_ARGS (for
+# declarations). For code that uses stubs, we also need to know the name of
+# the stub field, which might be different than the argument itself. Lastly,
+# for code that uses syncops, we need to know whether whoever wrote the syncop
+# for this fop "forgot" to include this argument. (Editorial: this kind of
+# creeping inconsistency is why we should have used code generation for stubs
+# and syncops as well as defaults all along.) To address this need, we use the
+# optional 'nosync' field for arguments (e.g. mkdir.umask) that we should skip
+# in generated syncop code.
+#
+# 'cbk-arg' is like fop-arg but simpler and used for generating callbacks
+# instead of fop functions.
+#
+# 'extra' is also like fop-arg, but it's another hack for syncops. This time
+# the problem is that some of what would normally be *callback* arguments are
+# instead created in the caller and passed to the syncop. We handle that by
+# adding an entry at the appropriate place in the fop-arg list, with the name
+# and type to generate a declaration and an argument string to generate the
+# actual syncop call.
+#
+# The mere presence of a 'journal' item is sufficient for most of the journal
+# code to recognize that it should do something. However, reconciliation also
+# needs to decide how reconciliation builds the arguments it needs to call down
+# to the syncop layer, based on what's in the journal. To do that, we divide
+# ops into three types and store those types in the ops table. In general,
+# these three types work as follows.
+#
+# For an fd-op, the GFID in the journal is used (in loc.gfid) field to
+# look up an inode, then an anonymous fd is found/created for that inode.
+#
+# For an inode-op, the GFID in the journal is used the same way, but no fd
+# is needed.
+#
+# For an entry-op, the *parent* GFID and name from the journal are used to
+# look up an inode (via loc.pargfid and par.name respectively).
+#
+# The only places this seems to fall down is for link and create. In link,
+# which is generally an entry-op, the source is looked up as though it's an
+# inode-op. In create, we have an fd argument but it's really a return
+# argument so we get a fresh inode instead of looking one up. Those two cases
+# need to be handled as special cases in the reconciliation code.
+#
+# 'link' is (hopefully) the last of the journal/syncop hacks. Much like
+# 'extra', some values that are returned as callback arguments in the normal
+# case are handled differently for syncops. For syncops that create objects
+# (e.g. mkdir) we need to link those objects into our inode table. The 'inode'
+# and 'iatt' fields here give us the information we need to construct the
+# proper inode_link call(s).
+
+ops = {}
+xlator_cbks = {}
+xlator_dumpops = {}
+
+ops['fgetxattr'] = (
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'name', 'const char *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'dict', 'dict_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['fsetxattr'] = (
+ ('fop-arg', 'fd', 'fd_t *', 'fd'),
+ ('fop-arg', 'dict', 'dict_t *', 'xattr'),
+ ('fop-arg', 'flags', 'int32_t', 'flags'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'fd-op'),
+)
+
+ops['setxattr'] = (
+ ('fop-arg', 'loc', 'loc_t *', 'loc'),
+ ('fop-arg', 'dict', 'dict_t *', 'xattr'),
+ ('fop-arg', 'flags', 'int32_t', 'flags'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'inode-op'),
+)
+
+ops['statfs'] = (
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'buf', 'struct statvfs *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['fsyncdir'] = (
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'flags', 'int32_t'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['opendir'] = (
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'fd', 'fd_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['fstat'] = (
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'buf', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['fsync'] = (
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'flags', 'int32_t'),
+ ('extra', 'preop', 'struct iatt', '&preop'),
+ ('extra', 'postop', 'struct iatt', '&postop'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'prebuf', 'struct iatt *'),
+ ('cbk-arg', 'postbuf', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['flush'] = (
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['writev'] = (
+ ('fop-arg', 'fd', 'fd_t *', 'fd'),
+ ('fop-arg', 'vector', 'struct iovec *', 'vector'),
+ ('fop-arg', 'count', 'int32_t'),
+ ('fop-arg', 'off', 'off_t', 'offset'),
+ ('fop-arg', 'flags', 'uint32_t', 'flags'),
+ ('fop-arg', 'iobref', 'struct iobref *'),
+ ('extra', 'preop', 'struct iatt', '&preop'),
+ ('extra', 'postop', 'struct iatt', '&postop'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'prebuf', 'struct iatt *'),
+ ('cbk-arg', 'postbuf', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'fd-op'),
+)
+
+ops['readv'] = (
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'size', 'size_t'),
+ ('fop-arg', 'offset', 'off_t'),
+ ('fop-arg', 'flags', 'uint32_t'),
+ ('extra', 'iatt', 'struct iatt', '&iatt'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'vector', 'struct iovec *'),
+ ('cbk-arg', 'count', 'int32_t'),
+ ('cbk-arg', 'stbuf', 'struct iatt *'),
+ ('cbk-arg', 'iobref', 'struct iobref *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['open'] = (
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'flags', 'int32_t'),
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'fd', 'fd_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['create'] = (
+ ('fop-arg', 'loc', 'loc_t *', 'loc'),
+ ('fop-arg', 'flags', 'int32_t', 'flags'),
+ ('fop-arg', 'mode', 'mode_t', 'mode'),
+ ('fop-arg', 'umask', 'mode_t', 'umask', 'nosync'),
+ ('fop-arg', 'fd', 'fd_t *', 'fd'),
+ ('extra', 'iatt', 'struct iatt', '&iatt'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'fd', 'fd_t *'),
+ ('cbk-arg', 'inode', 'inode_t *'),
+ ('cbk-arg', 'buf', 'struct iatt *'),
+ ('cbk-arg', 'preparent', 'struct iatt *'),
+ ('cbk-arg', 'postparent', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'entry-op'),
+ ('link', 'loc.inode', '&iatt'),
+)
+
+ops['link'] = (
+ ('fop-arg', 'oldloc', 'loc_t *', 'loc'),
+ ('fop-arg', 'newloc', 'loc_t *', 'loc2'),
+ ('extra', 'iatt', 'struct iatt', '&iatt'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'inode', 'inode_t *'),
+ ('cbk-arg', 'buf', 'struct iatt *'),
+ ('cbk-arg', 'preparent', 'struct iatt *'),
+ ('cbk-arg', 'postparent', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'entry-op'),
+)
+
+ops['rename'] = (
+ ('fop-arg', 'oldloc', 'loc_t *', 'loc'),
+ ('fop-arg', 'newloc', 'loc_t *', 'loc2'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'buf', 'struct iatt *'),
+ ('cbk-arg', 'preoldparent', 'struct iatt *'),
+ ('cbk-arg', 'postoldparent', 'struct iatt *'),
+ ('cbk-arg', 'prenewparent', 'struct iatt *'),
+ ('cbk-arg', 'postnewparent', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'entry-op'),
+)
+
+ops['symlink'] = (
+ ('fop-arg', 'linkpath', 'const char *', 'linkname'),
+ ('fop-arg', 'loc', 'loc_t *', 'loc'),
+ ('fop-arg', 'umask', 'mode_t', 'mode', 'nosync'),
+ ('extra', 'iatt', 'struct iatt', '&iatt'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'inode', 'inode_t *'),
+ ('cbk-arg', 'buf', 'struct iatt *'),
+ ('cbk-arg', 'preparent', 'struct iatt *'),
+ ('cbk-arg', 'postparent', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'entry-op'),
+)
+
+ops['rmdir'] = (
+ ('fop-arg', 'loc', 'loc_t *', 'loc'),
+ ('fop-arg', 'flags', 'int32_t', 'flags'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'preparent', 'struct iatt *'),
+ ('cbk-arg', 'postparent', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'entry-op'),
+)
+
+ops['unlink'] = (
+ ('fop-arg', 'loc', 'loc_t *', 'loc'),
+ ('fop-arg', 'flags', 'int32_t', 'flags', 'nosync'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'preparent', 'struct iatt *'),
+ ('cbk-arg', 'postparent', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'entry-op'),
+)
+
+ops['mkdir'] = (
+ ('fop-arg', 'loc', 'loc_t *', 'loc'),
+ ('fop-arg', 'mode', 'mode_t', 'mode'),
+ ('fop-arg', 'umask', 'mode_t', 'umask', 'nosync'),
+ ('extra', 'iatt', 'struct iatt', '&iatt'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'inode', 'inode_t *'),
+ ('cbk-arg', 'buf', 'struct iatt *'),
+ ('cbk-arg', 'preparent', 'struct iatt *'),
+ ('cbk-arg', 'postparent', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'entry-op'),
+ ('link', 'loc.inode', '&iatt'),
+)
+
+ops['mknod'] = (
+ ('fop-arg', 'loc', 'loc_t *', 'loc'),
+ ('fop-arg', 'mode', 'mode_t', 'mode'),
+ ('fop-arg', 'rdev', 'dev_t', 'rdev'),
+ ('fop-arg', 'umask', 'mode_t', 'umask', 'nosync'),
+ ('extra', 'iatt', 'struct iatt', '&iatt'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'inode', 'inode_t *'),
+ ('cbk-arg', 'buf', 'struct iatt *'),
+ ('cbk-arg', 'preparent', 'struct iatt *'),
+ ('cbk-arg', 'postparent', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'entry-op'),
+)
+
+ops['readlink'] = (
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'size', 'size_t'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'path', 'const char *'),
+ ('cbk-arg', 'buf', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['access'] = (
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'mask', 'int32_t'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['ftruncate'] = (
+ ('fop-arg', 'fd', 'fd_t *', 'fd'),
+ ('fop-arg', 'offset', 'off_t', 'offset'),
+ ('extra', 'preop', 'struct iatt', '&preop'),
+ ('extra', 'postop', 'struct iatt', '&postop'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'prebuf', 'struct iatt *'),
+ ('cbk-arg', 'postbuf', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'fd-op'),
+)
+
+ops['getxattr'] = (
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'name', 'const char *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'dict', 'dict_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['xattrop'] = (
+ ('fop-arg', 'loc', 'loc_t *', 'loc'),
+ ('fop-arg', 'flags', 'gf_xattrop_flags_t', 'optype'),
+ ('fop-arg', 'dict', 'dict_t *', 'xattr'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'dict', 'dict_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'inode-op'),
+)
+
+ops['fxattrop'] = (
+ ('fop-arg', 'fd', 'fd_t *', 'fd'),
+ ('fop-arg', 'flags', 'gf_xattrop_flags_t', 'optype'),
+ ('fop-arg', 'dict', 'dict_t *', 'xattr'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'dict', 'dict_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'fd-op'),
+)
+
+ops['removexattr'] = (
+ ('fop-arg', 'loc', 'loc_t *', 'loc'),
+ ('fop-arg', 'name', 'const char *', 'name'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'inode-op'),
+)
+
+ops['fremovexattr'] = (
+ ('fop-arg', 'fd', 'fd_t *', 'fd'),
+ ('fop-arg', 'name', 'const char *', 'name'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'fd-op'),
+)
+
+ops['lk'] = (
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'cmd', 'int32_t'),
+ ('fop-arg', 'lock', 'struct gf_flock *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'lock', 'struct gf_flock *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['inodelk'] = (
+ ('fop-arg', 'volume', 'const char *'),
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'cmd', 'int32_t'),
+ ('fop-arg', 'lock', 'struct gf_flock *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['finodelk'] = (
+ ('fop-arg', 'volume', 'const char *'),
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'cmd', 'int32_t'),
+ ('fop-arg', 'lock', 'struct gf_flock *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['entrylk'] = (
+ ('fop-arg', 'volume', 'const char *'),
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'basename', 'const char *'),
+ ('fop-arg', 'cmd', 'entrylk_cmd'),
+ ('fop-arg', 'type', 'entrylk_type'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['fentrylk'] = (
+ ('fop-arg', 'volume', 'const char *'),
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'basename', 'const char *'),
+ ('fop-arg', 'cmd', 'entrylk_cmd'),
+ ('fop-arg', 'type', 'entrylk_type'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['rchecksum'] = (
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'offset', 'off_t'),
+ ('fop-arg', 'len', 'int32_t'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'weak_cksum', 'uint32_t'),
+ ('cbk-arg', 'strong_cksum', 'uint8_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['readdir'] = (
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'size', 'size_t'),
+ ('fop-arg', 'off', 'off_t'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'entries', 'gf_dirent_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['readdirp'] = (
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'size', 'size_t'),
+ ('fop-arg', 'off', 'off_t'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'entries', 'gf_dirent_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['setattr'] = (
+ ('fop-arg', 'loc', 'loc_t *', 'loc'),
+ ('fop-arg', 'stbuf', 'struct iatt *', 'stat'),
+ ('fop-arg', 'valid', 'int32_t', 'valid'),
+ ('extra', 'preop', 'struct iatt', '&preop'),
+ ('extra', 'postop', 'struct iatt', '&postop'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'statpre', 'struct iatt *'),
+ ('cbk-arg', 'statpost', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'inode-op'),
+)
+
+ops['truncate'] = (
+ ('fop-arg', 'loc', 'loc_t *', 'loc'),
+ ('fop-arg', 'offset', 'off_t', 'offset'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'prebuf', 'struct iatt *'),
+ ('cbk-arg', 'postbuf', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'inode-op'),
+)
+
+ops['stat'] = (
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'buf', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['lookup'] = (
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'inode', 'inode_t *'),
+ ('cbk-arg', 'buf', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ # We could add xdata everywhere automatically if somebody hadn't put
+ # something after it here.
+ ('cbk-arg', 'postparent', 'struct iatt *'),
+)
+
+ops['fsetattr'] = (
+ ('fop-arg', 'fd', 'fd_t *', 'fd'),
+ ('fop-arg', 'stbuf', 'struct iatt *', 'stat'),
+ ('fop-arg', 'valid', 'int32_t', 'valid'),
+ ('extra', 'preop', 'struct iatt', '&preop'),
+ ('extra', 'postop', 'struct iatt', '&postop'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'statpre', 'struct iatt *'),
+ ('cbk-arg', 'statpost', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'fd-op'),
+)
+
+ops['fallocate'] = (
+ ('fop-arg', 'fd', 'fd_t *', 'fd'),
+ ('fop-arg', 'keep_size', 'int32_t', 'mode'),
+ ('fop-arg', 'offset', 'off_t', 'offset'),
+ ('fop-arg', 'len', 'size_t', 'size'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'pre', 'struct iatt *'),
+ ('cbk-arg', 'post', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'fd-op'),
+)
+
+ops['discard'] = (
+ ('fop-arg', 'fd', 'fd_t *', 'fd'),
+ ('fop-arg', 'offset', 'off_t', 'offset'),
+ ('fop-arg', 'len', 'size_t', 'size'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'pre', 'struct iatt *'),
+ ('cbk-arg', 'post', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'fd-op'),
+)
+
+ops['zerofill'] = (
+ ('fop-arg', 'fd', 'fd_t *', 'fd'),
+ ('fop-arg', 'offset', 'off_t', 'offset'),
+ # As e.g. fallocate/discard (above) "len" should really be a size_t.
+ ('fop-arg', 'len', 'off_t', 'size'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'pre', 'struct iatt *'),
+ ('cbk-arg', 'post', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'fd-op'),
+)
+
+ops['ipc'] = (
+ ('fop-arg', 'op', 'int32_t'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'fd-op'),
+)
+
+ops['seek'] = (
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'offset', 'off_t'),
+ ('fop-arg', 'what', 'gf_seek_what_t'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'offset', 'off_t'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['getspec'] = (
+ ('fop-arg', 'key', 'const char *'),
+ ('fop-arg', 'flags', 'int32_t'),
+ ('cbk-arg', 'spec_data', 'char *'),
+)
+
+ops['lease'] = (
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'lease', 'struct gf_lease *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'lease', 'struct gf_lease *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['getactivelk'] = (
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'locklist', 'lock_migration_info_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['setactivelk'] = (
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'locklist', 'lock_migration_info_t *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['put'] = (
+ ('fop-arg', 'loc', 'loc_t *', 'loc'),
+ ('fop-arg', 'mode', 'mode_t', 'mode'),
+ ('fop-arg', 'umask', 'mode_t', 'umask'),
+ ('fop-arg', 'flags', 'uint32_t', 'flags'),
+ ('fop-arg', 'vector', 'struct iovec *', 'vector'),
+ ('fop-arg', 'count', 'int32_t'),
+ ('fop-arg', 'off', 'off_t', 'offset'),
+ ('fop-arg', 'iobref', 'struct iobref *'),
+ ('fop-arg', 'dict', 'dict_t *', 'xattr'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'inode', 'inode_t *'),
+ ('cbk-arg', 'buf', 'struct iatt *'),
+ ('cbk-arg', 'preparent', 'struct iatt *'),
+ ('cbk-arg', 'postparent', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['icreate'] = (
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'mode', 'mode_t'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'inode', 'inode_t *'),
+ ('cbk-arg', 'buf', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['namelink'] = (
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'prebuf', 'struct iatt *'),
+ ('cbk-arg', 'postbuf', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['copy_file_range'] = (
+ ('fop-arg', 'fd_in', 'fd_t *'),
+ ('fop-arg', 'off_in', 'off64_t '),
+ ('fop-arg', 'fd_out', 'fd_t *'),
+ ('fop-arg', 'off_out', 'off64_t '),
+ ('fop-arg', 'len', 'size_t'),
+ ('fop-arg', 'flags', 'uint32_t'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'stbuf', 'struct iatt *'),
+ ('cbk-arg', 'prebuf_dst', 'struct iatt *'),
+ ('cbk-arg', 'postbuf_dst', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+#####################################################################
+xlator_cbks['forget'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('fn-arg', 'inode', 'inode_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_cbks['release'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('fn-arg', 'fd', 'fd_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_cbks['releasedir'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('fn-arg', 'fd', 'fd_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_cbks['invalidate'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('fn-arg', 'inode', 'inode_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_cbks['client_destroy'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('fn-arg', 'client', 'client_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_cbks['client_disconnect'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('fn-arg', 'client', 'client_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_cbks['ictxmerge'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('fn-arg', 'fd', 'fd_t *'),
+ ('fn-arg', 'inode', 'inode_t *'),
+ ('fn-arg', 'linked_inode', 'inode_t *'),
+ ('ret-val', 'void', ''),
+)
+
+#####################################################################
+xlator_dumpops['priv'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_dumpops['inode'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_dumpops['fd'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_dumpops['inodectx'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('fn-arg', 'ino', 'inode_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_dumpops['fdctx'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('fn-arg', 'fd', 'fd_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_dumpops['priv_to_dict'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('fn-arg', 'dict', 'dict_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_dumpops['inode_to_dict'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('fn-arg', 'dict', 'dict_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_dumpops['fd_to_dict'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('fn-arg', 'dict', 'dict_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_dumpops['inodectx_to_dict'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('fn-arg', 'ino', 'inode_t *'),
+ ('fn-arg', 'dict', 'dict_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_dumpops['fdctx_to_dict'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('fn-arg', 'fd', 'fd_t *'),
+ ('fn-arg', 'dict', 'dict_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_dumpops['history'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+def get_error_arg (type_str):
+ if type_str.find(" *") != -1:
+ return "NULL"
+ return "-1"
+
+def get_subs (names, types, cbktypes=None):
+ sdict = {}
+ sdict["@SHORT_ARGS@"] = ', '.join(names)
+ # Convert two separate tuples to one of (name, type) sub-tuples.
+ as_tuples = list(zip(types, names))
+ # Convert each sub-tuple into a "type name" string.
+ as_strings = [' '.join(item) for item in as_tuples]
+ # Join all of those into one big string.
+ sdict["@LONG_ARGS@"] = ',\n\t'.join(as_strings)
+ # So much more readable than string.join(map(string.join,zip(...))))
+ sdict["@ERROR_ARGS@"] = ', '.join(list(map(get_error_arg, types)))
+ if cbktypes is not None:
+ sdict["@CBK_ERROR_ARGS@"] = ', '.join(list(map(get_error_arg, cbktypes)))
+ return sdict
+
+def generate (tmpl, name, subs):
+ text = tmpl.replace("@NAME@", name)
+ if name == "writev":
+ # More spurious inconsistency.
+ text = text.replace("@UPNAME@", "WRITE")
+ elif name == "readv":
+ text = text.replace("@UPNAME@", "READ")
+ else:
+ text = text.replace("@UPNAME@", name.upper())
+ for old, new in subs[name].items():
+ text = text.replace(old, new)
+ # TBD: reindent/reformat the result for maximum readability.
+ return text
+
+fop_subs = {}
+cbk_subs = {}
+
+for name, args in ops.items():
+
+ # Create the necessary substitution strings for fops.
+ arg_names = [ a[1] for a in args if a[0] == 'fop-arg']
+ arg_types = [ a[2] for a in args if a[0] == 'fop-arg']
+ cbk_types = [ a[2] for a in args if a[0] == 'cbk-arg']
+ fop_subs[name] = get_subs(arg_names, arg_types, cbk_types)
+
+ # Same thing for callbacks.
+ arg_names = [ a[1] for a in args if a[0] == 'cbk-arg']
+ arg_types = [ a[2] for a in args if a[0] == 'cbk-arg']
+ cbk_subs[name] = get_subs(arg_names, arg_types)
+
+ # Callers can add other subs to these tables, or even create their
+ # own tables, using these same techniques, and then pass the result
+ # to generate() which would Do The Right Thing with them.
diff --git a/libglusterfs/src/gf-dirent.c b/libglusterfs/src/gf-dirent.c
index 4c85db3f3cf..a809efc97ef 100644
--- a/libglusterfs/src/gf-dirent.c
+++ b/libglusterfs/src/gf-dirent.c
@@ -1,92 +1,301 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
+ 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.
+*/
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include "glusterfs/compat.h"
+#include "glusterfs/syncop.h"
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
+#define ONE 1ULL
+#define PRESENT_D_OFF_BITS 63
+#define BACKEND_D_OFF_BITS 63
+#define TOP_BIT (ONE << (PRESENT_D_OFF_BITS - 1))
+#define MASK (~0ULL)
+#define SHIFT_BITS (max(0, (BACKEND_D_OFF_BITS - PRESENT_D_OFF_BITS + 1)))
+#define PRESENT_MASK (MASK >> (64 - PRESENT_D_OFF_BITS))
+static uint64_t
+bits_for(uint64_t num)
+{
+ uint64_t bits = 0, ctrl = 1;
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
+ while (ctrl < num) {
+ ctrl *= 2;
+ bits++;
+ }
+ return bits;
+}
-#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-#include "compat.h"
-#include "xlator.h"
+int
+gf_deitransform(xlator_t *this, uint64_t offset)
+{
+ int cnt = 0;
+ int max = 0;
+ int max_bits = 0;
+ uint64_t off_mask = 0;
+ uint64_t host_mask = 0;
+
+ max = glusterfs_get_leaf_count(this->graph);
+
+ if (max == 1) {
+ cnt = 0;
+ goto out;
+ }
+
+ if (offset & TOP_BIT) {
+ /* HUGE d_off */
+ max_bits = bits_for(max);
+ off_mask = (MASK << max_bits);
+ host_mask = ~(off_mask);
+
+ cnt = offset & host_mask;
+ } else {
+ /* small d_off */
+ cnt = offset % max;
+ }
+out:
+ return cnt;
+}
+
+uint64_t
+gf_dirent_orig_offset(xlator_t *this, uint64_t offset)
+{
+ int max = 0;
+ int max_bits = 0;
+ uint64_t off_mask = 0;
+ uint64_t orig_offset;
+
+ max = glusterfs_get_leaf_count(this->graph);
+
+ if (max == 1) {
+ orig_offset = offset;
+ goto out;
+ }
+
+ if (offset & TOP_BIT) {
+ /* HUGE d_off */
+ max_bits = bits_for(max);
+ off_mask = (MASK << max_bits);
+ orig_offset = ((offset & ~TOP_BIT) & off_mask) << SHIFT_BITS;
+ } else {
+ /* small d_off */
+ orig_offset = offset / max;
+ }
+out:
+ return orig_offset;
+}
+
+int
+gf_itransform(xlator_t *this, uint64_t x, uint64_t *y_p, int client_id)
+{
+ int max = 0;
+ uint64_t y = 0;
+ uint64_t hi_mask = 0;
+ uint64_t off_mask = 0;
+ int max_bits = 0;
+
+ if (x == ((uint64_t)-1)) {
+ y = (uint64_t)-1;
+ goto out;
+ }
+
+ if (!x) {
+ y = 0;
+ goto out;
+ }
+
+ max = glusterfs_get_leaf_count(this->graph);
+
+ if (max == 1) {
+ y = x;
+ goto out;
+ }
+
+ max_bits = bits_for(max);
+
+ hi_mask = ~(PRESENT_MASK >> (max_bits + 1));
+
+ if (x & hi_mask) {
+ /* HUGE d_off */
+ off_mask = MASK << max_bits;
+ y = TOP_BIT | ((x >> SHIFT_BITS) & off_mask) | client_id;
+ } else {
+ /* small d_off */
+ y = ((x * max) + client_id);
+ }
+
+out:
+ if (y_p)
+ *y_p = y;
+
+ return 0;
+}
gf_dirent_t *
-gf_dirent_for_namelen (int len)
+gf_dirent_for_name(const char *name)
{
- gf_dirent_t *gf_dirent = NULL;
+ gf_dirent_t *gf_dirent = NULL;
- /* TODO: use mem-pool */
- gf_dirent = CALLOC (len, sizeof(char));
- if (!gf_dirent)
- return NULL;
+ /* TODO: use mem-pool */
+ gf_dirent = GF_CALLOC(gf_dirent_size(name), 1, gf_common_mt_gf_dirent_t);
+ if (!gf_dirent)
+ return NULL;
- INIT_LIST_HEAD (&gf_dirent->list);
+ INIT_LIST_HEAD(&gf_dirent->list);
+ strcpy(gf_dirent->d_name, name);
- gf_dirent->d_off = 0;
- gf_dirent->d_ino = -1;
- gf_dirent->d_type = 0;
+ gf_dirent->d_off = 0;
+ gf_dirent->d_ino = -1;
+ gf_dirent->d_type = 0;
+ gf_dirent->d_len = strlen(name);
- return gf_dirent;
+ return gf_dirent;
}
+void
+gf_dirent_entry_free(gf_dirent_t *entry)
+{
+ if (!entry)
+ return;
+
+ if (entry->dict)
+ dict_unref(entry->dict);
+ if (entry->inode)
+ inode_unref(entry->inode);
+
+ list_del_init(&entry->list);
+ GF_FREE(entry);
+}
+
+void
+gf_dirent_free(gf_dirent_t *entries)
+{
+ gf_dirent_t *entry = NULL;
+ gf_dirent_t *tmp = NULL;
+
+ if (!entries)
+ return;
+
+ if (list_empty(&entries->list))
+ return;
+
+ list_for_each_entry_safe(entry, tmp, &entries->list, list)
+ {
+ gf_dirent_entry_free(entry);
+ }
+}
gf_dirent_t *
-gf_dirent_for_name (const char *name)
+entry_copy(gf_dirent_t *source)
{
- gf_dirent_t *gf_dirent = NULL;
+ gf_dirent_t *sink = NULL;
- /* TODO: use mem-pool */
- gf_dirent = GF_CALLOC (gf_dirent_size (name), 1,
- gf_common_mt_gf_dirent_t);
- if (!gf_dirent)
- return NULL;
+ sink = gf_dirent_for_name(source->d_name);
+ if (!sink)
+ return NULL;
- INIT_LIST_HEAD (&gf_dirent->list);
- strcpy (gf_dirent->d_name, name);
+ sink->d_off = source->d_off;
+ sink->d_ino = source->d_ino;
+ sink->d_type = source->d_type;
+ sink->d_stat = source->d_stat;
+ sink->d_len = source->d_len;
- gf_dirent->d_off = 0;
- gf_dirent->d_ino = -1;
- gf_dirent->d_type = 0;
- gf_dirent->d_len = strlen (name);
+ if (source->inode)
+ sink->inode = inode_ref(source->inode);
- return gf_dirent;
+ if (source->dict)
+ sink->dict = dict_ref(source->dict);
+ return sink;
}
-
void
-gf_dirent_free (gf_dirent_t *entries)
+gf_link_inode_from_dirent(xlator_t *this, inode_t *parent, gf_dirent_t *entry)
+{
+ inode_t *link_inode = NULL;
+ inode_t *tmp = NULL;
+
+ if (!entry->inode)
+ return;
+ link_inode = inode_link(entry->inode, parent, entry->d_name,
+ &entry->d_stat);
+ if (!link_inode)
+ return;
+
+ inode_lookup(link_inode);
+ tmp = entry->inode;
+ entry->inode = link_inode;
+ inode_unref(tmp);
+}
+
+/* TODO: Currently, with this function, we will be breaking the
+ policy of 1-1 mapping of kernel nlookup refs with our inode_t's
+ nlookup count.
+ Need more thoughts before finalizing this function
+*/
+int
+gf_link_inodes_from_dirent(xlator_t *this, inode_t *parent,
+ gf_dirent_t *entries)
{
- gf_dirent_t *entry = NULL;
- gf_dirent_t *tmp = NULL;
+ gf_dirent_t *entry = NULL;
+
+ list_for_each_entry(entry, &entries->list, list)
+ {
+ gf_link_inode_from_dirent(this, parent, entry);
+ }
+
+ return 0;
+}
+
+int
+gf_fill_iatt_for_dirent(gf_dirent_t *entry, inode_t *parent, xlator_t *subvol)
+{
+ loc_t loc = {
+ 0,
+ };
+ int ret = -1;
+ char *path = NULL;
+ struct iatt iatt = {
+ 0,
+ };
+
+ loc.inode = inode_grep(parent->table, parent, entry->d_name);
+ if (!loc.inode) {
+ loc.inode = inode_new(parent->table);
+ gf_uuid_copy(loc.inode->gfid, entry->d_stat.ia_gfid);
+ }
+
+ gf_uuid_copy(loc.pargfid, parent->gfid);
+ loc.name = entry->d_name;
+ loc.parent = inode_ref(parent);
+ ret = inode_path(loc.parent, entry->d_name, &path);
+ loc.path = path;
+ if (ret < 0)
+ goto out;
- if (!entries)
- return;
+ ret = syncop_lookup(subvol, &loc, &iatt, NULL, NULL, NULL);
+ if (ret)
+ goto out;
- if (list_empty (&entries->list))
- return;
+ entry->d_stat = iatt;
+ entry->inode = inode_ref(loc.inode);
+ /* We don't need to link inode here, because as part of readdirp_cbk
+ * we will link all dirents.
+ *
+ * Since we did a proper lookup, we don't need to set need_lookup
+ * flag.
+ */
- list_for_each_entry_safe (entry, tmp, &entries->list, list) {
- list_del (&entry->list);
- GF_FREE (entry);
- }
+ ret = 0;
+out:
+ loc_wipe(&loc);
+ return ret;
}
diff --git a/libglusterfs/src/gf-dirent.h b/libglusterfs/src/gf-dirent.h
deleted file mode 100644
index db1dac83566..00000000000
--- a/libglusterfs/src/gf-dirent.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-
-#ifndef _GF_DIRENT_H
-#define _GF_DIRENT_H
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "iatt.h"
-
-#define gf_dirent_size(name) (sizeof (gf_dirent_t) + strlen (name) + 1)
-
-struct _dir_entry_t {
- struct _dir_entry_t *next;
- char *name;
- char *link;
- struct iatt buf;
-};
-
-
-struct _gf_dirent_t {
- union {
- struct list_head list;
- struct {
- struct _gf_dirent_t *next;
- struct _gf_dirent_t *prev;
- };
- };
- uint64_t d_ino;
- uint64_t d_off;
- uint32_t d_len;
- uint32_t d_type;
- struct iatt d_stat;
- char d_name[0];
-};
-
-
-gf_dirent_t *gf_dirent_for_name (const char *name);
-void gf_dirent_free (gf_dirent_t *entries);
-gf_dirent_t * gf_dirent_for_namelen (int len);
-
-#endif /* _GF_DIRENT_H */
diff --git a/libglusterfs/src/gidcache.c b/libglusterfs/src/gidcache.c
new file mode 100644
index 00000000000..64a93802f76
--- /dev/null
+++ b/libglusterfs/src/gidcache.c
@@ -0,0 +1,211 @@
+/*
+ Copyright (c) 2008-2012 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 "glusterfs/gidcache.h"
+#include "glusterfs/mem-pool.h"
+#include "glusterfs/common-utils.h"
+
+/*
+ * We treat this as a very simple set-associative LRU cache, with entries aged
+ * out after a configurable interval. Hardly rocket science, but lots of
+ * details to worry about.
+ */
+#define BUCKET_START(p, n) ((p) + ((n)*AUX_GID_CACHE_ASSOC))
+
+/*
+ * Initialize the cache.
+ */
+int
+gid_cache_init(gid_cache_t *cache, uint32_t timeout)
+{
+ if (!cache)
+ return -1;
+
+ LOCK_INIT(&cache->gc_lock);
+ cache->gc_max_age = timeout;
+ cache->gc_nbuckets = AUX_GID_CACHE_BUCKETS;
+ memset(cache->gc_cache, 0, sizeof(gid_list_t) * AUX_GID_CACHE_SIZE);
+
+ return 0;
+}
+
+/*
+ * Reconfigure the cache timeout.
+ */
+int
+gid_cache_reconf(gid_cache_t *cache, uint32_t timeout)
+{
+ if (!cache)
+ return -1;
+
+ LOCK(&cache->gc_lock);
+ cache->gc_max_age = timeout;
+ UNLOCK(&cache->gc_lock);
+
+ return 0;
+}
+
+/*
+ * Look up an ID in the cache. If found, return the actual cache entry to avoid
+ * an additional allocation and memory copy. The caller should copy the data and
+ * release (unlock) the cache as soon as possible.
+ */
+const gid_list_t *
+gid_cache_lookup(gid_cache_t *cache, uint64_t id, uint64_t uid, uint64_t gid)
+{
+ int bucket;
+ int i;
+ time_t now;
+ const gid_list_t *agl;
+
+ now = gf_time();
+ LOCK(&cache->gc_lock);
+ bucket = id % cache->gc_nbuckets;
+ agl = BUCKET_START(cache->gc_cache, bucket);
+ for (i = 0; i < AUX_GID_CACHE_ASSOC; i++, agl++) {
+ if (!agl->gl_list)
+ continue;
+ if (agl->gl_id != id)
+ continue;
+
+ /*
+ @uid and @gid reflect the latest UID/GID of the
+ process performing the syscall (taken from frame->root).
+
+ If the UID and GID has changed for the PID since the
+ time we cached it, we should treat the cache as having
+ stale values and query them freshly.
+ */
+ if (agl->gl_uid != uid || agl->gl_gid != gid)
+ break;
+
+ /*
+ * We don't put new entries in the cache when expiration=0, but
+ * there might be entries still in there if expiration was
+ * changed very recently. Writing the check this way ensures
+ * that they're not used.
+ */
+ if (now < agl->gl_deadline) {
+ return agl;
+ }
+
+ /*
+ * We're not going to find any more UID matches, and reaping
+ * is handled further down to maintain LRU order.
+ */
+ break;
+ }
+ UNLOCK(&cache->gc_lock);
+ return NULL;
+}
+
+/*
+ * Release an entry found via lookup.
+ */
+void
+gid_cache_release(gid_cache_t *cache, const gid_list_t *agl)
+{
+ UNLOCK(&cache->gc_lock);
+}
+
+/*
+ * Add a new list entry to the cache. If an entry for this ID already exists,
+ * update it.
+ */
+int
+gid_cache_add(gid_cache_t *cache, gid_list_t *gl)
+{
+ gid_list_t *agl;
+ int bucket;
+ int i;
+ time_t now;
+
+ if (!gl || !gl->gl_list)
+ return -1;
+
+ if (!cache->gc_max_age)
+ return 0;
+
+ now = gf_time();
+ LOCK(&cache->gc_lock);
+
+ /*
+ * Scan for the first free entry or one that matches this id. The id
+ * check is added to address a bug where the cache might contain an
+ * expired entry for this id. Since lookup occurs in LRU order and
+ * does not reclaim entries, it will always return failure on discovery
+ * of an expired entry. This leads to duplicate entries being added,
+ * which still do not satisfy lookups until the expired entry (and
+ * everything before it) is reclaimed.
+ *
+ * We address this through reuse of an entry already allocated to this
+ * id, whether expired or not, since we have obviously already received
+ * more recent data. The entry is repopulated with the new data and a new
+ * deadline and is pushed forward to reside as the last populated entry in
+ * the bucket.
+ */
+ bucket = gl->gl_id % cache->gc_nbuckets;
+ agl = BUCKET_START(cache->gc_cache, bucket);
+ for (i = 0; i < AUX_GID_CACHE_ASSOC; ++i, ++agl) {
+ if (agl->gl_id == gl->gl_id)
+ break;
+ if (!agl->gl_list)
+ break;
+ }
+
+ /*
+ * The way we allocate free entries naturally places the newest
+ * ones at the highest indices, so evicting the lowest makes
+ * sense, but that also means we can't just replace it with the
+ * one that caused the eviction. That would cause us to thrash
+ * the first entry while others remain idle. Therefore, we
+ * need to slide the other entries down and add the new one at
+ * the end just as if the *last* slot had been free.
+ *
+ * Deadline expiration is also handled here, since the oldest
+ * expired entry will be in the first position. This does mean
+ * the bucket can stay full of expired entries if we're idle
+ * but, if the small amount of extra memory or scan time before
+ * we decide to evict someone ever become issues, we could
+ * easily add a reaper thread.
+ */
+
+ if (i >= AUX_GID_CACHE_ASSOC) {
+ /* cache full, evict the first (LRU) entry */
+ i = 0;
+ agl = BUCKET_START(cache->gc_cache, bucket);
+ GF_FREE(agl->gl_list);
+ } else if (agl->gl_list) {
+ /* evict the old entry we plan to reuse */
+ GF_FREE(agl->gl_list);
+ }
+
+ /*
+ * If we have evicted an entry, slide the subsequent populated entries
+ * back and populate the last entry.
+ */
+ for (; i < AUX_GID_CACHE_ASSOC - 1; i++) {
+ if (!agl[1].gl_list)
+ break;
+ agl[0] = agl[1];
+ agl++;
+ }
+
+ agl->gl_id = gl->gl_id;
+ agl->gl_uid = gl->gl_uid;
+ agl->gl_gid = gl->gl_gid;
+ agl->gl_count = gl->gl_count;
+ agl->gl_list = gl->gl_list;
+ agl->gl_deadline = now + cache->gc_max_age;
+
+ UNLOCK(&cache->gc_lock);
+
+ return 1;
+}
diff --git a/libglusterfs/src/globals.c b/libglusterfs/src/globals.c
index d1985b7ed04..ae06f8be386 100644
--- a/libglusterfs/src/globals.c
+++ b/libglusterfs/src/globals.c
@@ -1,355 +1,366 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif /* !_CONFIG_H */
-
#include <pthread.h>
-#include "glusterfs.h"
-#include "globals.h"
-#include "xlator.h"
-#include "mem-pool.h"
+#include "glusterfs/syncop.h"
+#include "glusterfs/libglusterfs-messages.h"
+
+const char *gf_fop_list[GF_FOP_MAXVALUE] = {
+ [GF_FOP_NULL] = "NULL",
+ [GF_FOP_STAT] = "STAT",
+ [GF_FOP_READLINK] = "READLINK",
+ [GF_FOP_MKNOD] = "MKNOD",
+ [GF_FOP_MKDIR] = "MKDIR",
+ [GF_FOP_UNLINK] = "UNLINK",
+ [GF_FOP_RMDIR] = "RMDIR",
+ [GF_FOP_SYMLINK] = "SYMLINK",
+ [GF_FOP_RENAME] = "RENAME",
+ [GF_FOP_LINK] = "LINK",
+ [GF_FOP_TRUNCATE] = "TRUNCATE",
+ [GF_FOP_OPEN] = "OPEN",
+ [GF_FOP_READ] = "READ",
+ [GF_FOP_WRITE] = "WRITE",
+ [GF_FOP_STATFS] = "STATFS",
+ [GF_FOP_FLUSH] = "FLUSH",
+ [GF_FOP_FSYNC] = "FSYNC",
+ [GF_FOP_SETXATTR] = "SETXATTR",
+ [GF_FOP_GETXATTR] = "GETXATTR",
+ [GF_FOP_REMOVEXATTR] = "REMOVEXATTR",
+ [GF_FOP_OPENDIR] = "OPENDIR",
+ [GF_FOP_FSYNCDIR] = "FSYNCDIR",
+ [GF_FOP_ACCESS] = "ACCESS",
+ [GF_FOP_CREATE] = "CREATE",
+ [GF_FOP_FTRUNCATE] = "FTRUNCATE",
+ [GF_FOP_FSTAT] = "FSTAT",
+ [GF_FOP_LK] = "LK",
+ [GF_FOP_LOOKUP] = "LOOKUP",
+ [GF_FOP_READDIR] = "READDIR",
+ [GF_FOP_INODELK] = "INODELK",
+ [GF_FOP_FINODELK] = "FINODELK",
+ [GF_FOP_ENTRYLK] = "ENTRYLK",
+ [GF_FOP_FENTRYLK] = "FENTRYLK",
+ [GF_FOP_XATTROP] = "XATTROP",
+ [GF_FOP_FXATTROP] = "FXATTROP",
+ [GF_FOP_FSETXATTR] = "FSETXATTR",
+ [GF_FOP_FGETXATTR] = "FGETXATTR",
+ [GF_FOP_RCHECKSUM] = "RCHECKSUM",
+ [GF_FOP_SETATTR] = "SETATTR",
+ [GF_FOP_FSETATTR] = "FSETATTR",
+ [GF_FOP_READDIRP] = "READDIRP",
+ [GF_FOP_GETSPEC] = "GETSPEC",
+ [GF_FOP_FORGET] = "FORGET",
+ [GF_FOP_RELEASE] = "RELEASE",
+ [GF_FOP_RELEASEDIR] = "RELEASEDIR",
+ [GF_FOP_FREMOVEXATTR] = "FREMOVEXATTR",
+ [GF_FOP_FALLOCATE] = "FALLOCATE",
+ [GF_FOP_DISCARD] = "DISCARD",
+ [GF_FOP_ZEROFILL] = "ZEROFILL",
+ [GF_FOP_IPC] = "IPC",
+ [GF_FOP_SEEK] = "SEEK",
+ [GF_FOP_LEASE] = "LEASE",
+ [GF_FOP_COMPOUND] = "COMPOUND",
+ [GF_FOP_GETACTIVELK] = "GETACTIVELK",
+ [GF_FOP_SETACTIVELK] = "SETACTIVELK",
+ [GF_FOP_PUT] = "PUT",
+ [GF_FOP_ICREATE] = "ICREATE",
+ [GF_FOP_NAMELINK] = "NAMELINK",
+ [GF_FOP_COPY_FILE_RANGE] = "COPY_FILE_RANGE",
+};
+
+const char *gf_upcall_list[GF_UPCALL_FLAGS_MAXVALUE] = {
+ [GF_UPCALL_NULL] = "NULL",
+ [GF_UPCALL] = "UPCALL",
+ [GF_UPCALL_CI_STAT] = "CI_IATT",
+ [GF_UPCALL_CI_XATTR] = "CI_XATTR",
+ [GF_UPCALL_CI_RENAME] = "CI_RENAME",
+ [GF_UPCALL_CI_NLINK] = "CI_UNLINK",
+ [GF_UPCALL_CI_FORGET] = "CI_FORGET",
+ [GF_UPCALL_LEASE_RECALL] = "LEASE_RECALL",
+};
+/* THIS */
-/* gf_*_list[] */
+/* This global ctx is a bad hack to prevent some of the libgfapi crashes.
+ * This should be removed once the patch on resource pool is accepted
+ */
+glusterfs_ctx_t *global_ctx = NULL;
+pthread_mutex_t global_ctx_mutex = PTHREAD_MUTEX_INITIALIZER;
+xlator_t global_xlator;
+static int gf_global_mem_acct_enable = 1;
+static pthread_once_t globals_inited = PTHREAD_ONCE_INIT;
-char *gf_fop_list[GF_FOP_MAXVALUE];
-char *gf_mgmt_list[GF_MGMT_MAXVALUE];
+static pthread_key_t free_key;
+static __thread xlator_t *thread_xlator = NULL;
+static __thread void *thread_synctask = NULL;
+static __thread void *thread_leaseid = NULL;
+static __thread struct syncopctx thread_syncopctx = {};
+static __thread char thread_uuid_buf[GF_UUID_BUF_SIZE] = {};
+static __thread char thread_lkowner_buf[GF_LKOWNER_BUF_SIZE] = {};
+static __thread char thread_leaseid_buf[GF_LEASE_ID_BUF_SIZE] = {};
-void
-gf_op_list_init()
+int
+gf_global_mem_acct_enable_get(void)
{
- gf_fop_list[GF_FOP_NULL] = "NULL";
- gf_fop_list[GF_FOP_STAT] = "STAT";
- gf_fop_list[GF_FOP_READLINK] = "READLINK";
- gf_fop_list[GF_FOP_MKNOD] = "MKNOD";
- gf_fop_list[GF_FOP_MKDIR] = "MKDIR";
- gf_fop_list[GF_FOP_UNLINK] = "UNLINK";
- gf_fop_list[GF_FOP_RMDIR] = "RMDIR";
- gf_fop_list[GF_FOP_SYMLINK] = "SYMLINK";
- gf_fop_list[GF_FOP_RENAME] = "RENAME";
- gf_fop_list[GF_FOP_LINK] = "LINK";
- gf_fop_list[GF_FOP_TRUNCATE] = "TRUNCATE";
- gf_fop_list[GF_FOP_OPEN] = "OPEN";
- gf_fop_list[GF_FOP_READ] = "READ";
- gf_fop_list[GF_FOP_WRITE] = "WRITE";
- gf_fop_list[GF_FOP_STATFS] = "STATFS";
- gf_fop_list[GF_FOP_FLUSH] = "FLUSH";
- gf_fop_list[GF_FOP_FSYNC] = "FSYNC";
- gf_fop_list[GF_FOP_SETXATTR] = "SETXATTR";
- gf_fop_list[GF_FOP_GETXATTR] = "GETXATTR";
- gf_fop_list[GF_FOP_REMOVEXATTR] = "REMOVEXATTR";
- gf_fop_list[GF_FOP_OPENDIR] = "OPENDIR";
- gf_fop_list[GF_FOP_FSYNCDIR] = "FSYNCDIR";
- gf_fop_list[GF_FOP_ACCESS] = "ACCESS";
- gf_fop_list[GF_FOP_CREATE] = "CREATE";
- gf_fop_list[GF_FOP_FTRUNCATE] = "FTRUNCATE";
- gf_fop_list[GF_FOP_FSTAT] = "FSTAT";
- gf_fop_list[GF_FOP_LK] = "LK";
- gf_fop_list[GF_FOP_LOOKUP] = "LOOKUP";
- gf_fop_list[GF_FOP_READDIR] = "READDIR";
- gf_fop_list[GF_FOP_INODELK] = "INODELK";
- gf_fop_list[GF_FOP_FINODELK] = "FINODELK";
- gf_fop_list[GF_FOP_ENTRYLK] = "ENTRYLK";
- gf_fop_list[GF_FOP_FENTRYLK] = "FENTRYLK";
- gf_fop_list[GF_FOP_XATTROP] = "XATTROP";
- gf_fop_list[GF_FOP_FXATTROP] = "FXATTROP";
- gf_fop_list[GF_FOP_FSETXATTR] = "FSETXATTR";
- gf_fop_list[GF_FOP_FGETXATTR] = "FGETXATTR";
- gf_fop_list[GF_FOP_RCHECKSUM] = "RCHECKSUM";
- gf_fop_list[GF_FOP_SETATTR] = "SETATTR";
- gf_fop_list[GF_FOP_FSETATTR] = "FSETATTR";
- gf_fop_list[GF_FOP_READDIRP] = "READDIRP";
- gf_fop_list[GF_FOP_GETSPEC] = "GETSPEC";
- gf_fop_list[GF_FOP_FORGET] = "FORGET";
- gf_fop_list[GF_FOP_RELEASE] = "RELEASE";
- gf_fop_list[GF_FOP_RELEASEDIR] = "RELEASEDIR";
-
- gf_fop_list[GF_MGMT_NULL] = "NULL";
- return;
+ return gf_global_mem_acct_enable;
}
+int
+gf_global_mem_acct_enable_set(int val)
+{
+ gf_global_mem_acct_enable = val;
+ return 0;
+}
-/* CTX */
-static glusterfs_ctx_t *glusterfs_ctx;
+static struct xlator_cbks global_cbks = {
+ .forget = NULL,
+ .release = NULL,
+ .releasedir = NULL,
+ .invalidate = NULL,
+ .client_destroy = NULL,
+ .client_disconnect = NULL,
+ .ictxmerge = NULL,
+ .ictxsize = NULL,
+ .fdctxsize = NULL,
+};
+/* This is required to get through the check in graph.c */
+static struct xlator_fops global_fops = {};
-int
-glusterfs_ctx_init ()
+static int
+global_xl_reconfigure(xlator_t *this, dict_t *options)
{
- int ret = 0;
+ int ret = -1;
+ gf_boolean_t bool_opt = _gf_false;
- if (glusterfs_ctx) {
- gf_log_callingfn ("", GF_LOG_WARNING, "init called again");
- goto out;
- }
+ /* This is not added in volume dump, hence adding the options in log
+ would be helpful for debugging later */
+ dict_dump_to_log(options);
- glusterfs_ctx = CALLOC (1, sizeof (*glusterfs_ctx));
- if (!glusterfs_ctx) {
- ret = -1;
- goto out;
- }
+ GF_OPTION_RECONF("measure-latency", bool_opt, options, bool, out);
+ this->ctx->measure_latency = bool_opt;
- INIT_LIST_HEAD (&glusterfs_ctx->graphs);
- ret = pthread_mutex_init (&glusterfs_ctx->lock, NULL);
+ GF_OPTION_RECONF("metrics-dump-path", this->ctx->config.metrics_dumppath,
+ options, str, out);
+ /* TODO: add more things here */
+ ret = 0;
out:
- return ret;
+ return ret;
}
-
-glusterfs_ctx_t *
-glusterfs_ctx_get ()
+static int
+global_xl_init(xlator_t *this)
{
- return glusterfs_ctx;
-
-}
+ int ret = -1;
+ gf_boolean_t bool_opt = false;
+ GF_OPTION_INIT("measure-latency", bool_opt, bool, out);
+ this->ctx->measure_latency = bool_opt;
-/* THIS */
+ GF_OPTION_INIT("metrics-dump-path", this->ctx->config.metrics_dumppath, str,
+ out);
-xlator_t global_xlator;
-static pthread_key_t this_xlator_key;
+ ret = 0;
-void
-glusterfs_this_destroy (void *ptr)
-{
- if (ptr)
- FREE (ptr);
+out:
+ return ret;
}
-
-int
-glusterfs_this_init ()
+static void
+global_xl_fini(xlator_t *this)
{
- int ret = 0;
+ return;
+}
- ret = pthread_key_create (&this_xlator_key, glusterfs_this_destroy);
- if (ret != 0) {
- gf_log ("", GF_LOG_WARNING, "failed to create the pthread key");
- return ret;
- }
+struct volume_options global_xl_options[] = {
+ {.key = {"measure-latency"},
+ .type = GF_OPTION_TYPE_BOOL,
+ .default_value = "no",
+ .op_version = {GD_OP_VERSION_4_0_0},
+ .flags = OPT_FLAG_SETTABLE,
+ .tags = {"global", "context"},
+ .description = "Use this option to toggle measuring latency"},
+ {.key = {"metrics-dump-path"},
+ .type = GF_OPTION_TYPE_STR,
+ .default_value = "{{gluster_workdir}}/metrics",
+ .op_version = {GD_OP_VERSION_4_0_0},
+ .flags = OPT_FLAG_SETTABLE,
+ .tags = {"global", "context"},
+ .description = "Use this option to set the metrics dump path"},
+
+ {
+ .key = {NULL},
+ },
+};
- global_xlator.name = "glusterfs";
- global_xlator.type = "global";
- global_xlator.ctx = glusterfs_ctx;
+static volume_opt_list_t global_xl_opt_list;
- return ret;
+void
+glusterfs_this_init()
+{
+ global_xlator.name = "glusterfs";
+ global_xlator.type = GF_GLOBAL_XLATOR_NAME;
+ global_xlator.cbks = &global_cbks;
+ global_xlator.fops = &global_fops;
+ global_xlator.reconfigure = global_xl_reconfigure;
+ global_xlator.init = global_xl_init;
+ global_xlator.fini = global_xl_fini;
+
+ INIT_LIST_HEAD(&global_xlator.volume_options);
+ INIT_LIST_HEAD(&global_xl_opt_list.list);
+ global_xl_opt_list.given_opt = global_xl_options;
+
+ list_add_tail(&global_xl_opt_list.list, &global_xlator.volume_options);
}
-
xlator_t **
-__glusterfs_this_location ()
+__glusterfs_this_location()
{
- xlator_t **this_location = NULL;
- int ret = 0;
-
- this_location = pthread_getspecific (this_xlator_key);
-
- if (!this_location) {
- this_location = CALLOC (1, sizeof (*this_location));
- if (!this_location)
- goto out;
+ xlator_t **this_location;
- ret = pthread_setspecific (this_xlator_key, this_location);
- if (ret != 0) {
- gf_log ("", GF_LOG_WARNING, "pthread setspecific failed");
+ this_location = &thread_xlator;
+ if (*this_location == NULL) {
+ thread_xlator = &global_xlator;
+ }
- FREE (this_location);
- this_location = NULL;
- goto out;
- }
- }
-out:
- if (this_location) {
- if (!*this_location)
- *this_location = &global_xlator;
- }
- return this_location;
+ return this_location;
}
-
xlator_t *
-glusterfs_this_get ()
+glusterfs_this_get()
{
- xlator_t **this_location = NULL;
-
- this_location = __glusterfs_this_location ();
- if (!this_location)
- return &global_xlator;
-
- return *this_location;
+ return *__glusterfs_this_location();
}
-
-int
-glusterfs_this_set (xlator_t *this)
+void
+glusterfs_this_set(xlator_t *this)
{
- xlator_t **this_location = NULL;
-
- this_location = __glusterfs_this_location ();
- if (!this_location)
- return -ENOMEM;
+ thread_xlator = this;
+}
- *this_location = this;
+/* SYNCOPCTX */
- return 0;
+void *
+syncopctx_getctx()
+{
+ return &thread_syncopctx;
}
/* SYNCTASK */
-static pthread_key_t synctask_key;
+void *
+synctask_get()
+{
+ return thread_synctask;
+}
+void
+synctask_set(void *synctask)
+{
+ thread_synctask = synctask;
+}
-int
-synctask_init ()
+// UUID_BUFFER
+
+char *
+glusterfs_uuid_buf_get()
{
- int ret = 0;
+ return thread_uuid_buf;
+}
- ret = pthread_key_create (&synctask_key, NULL);
+/* LKOWNER_BUFFER */
- return ret;
+char *
+glusterfs_lkowner_buf_get()
+{
+ return thread_lkowner_buf;
}
+/* Leaseid buffer */
-void *
-synctask_get ()
+char *
+glusterfs_leaseid_buf_get()
{
- void *synctask = NULL;
+ char *buf = NULL;
- synctask = pthread_getspecific (synctask_key);
+ buf = thread_leaseid;
+ if (buf == NULL) {
+ buf = thread_leaseid_buf;
+ thread_leaseid = buf;
+ }
- return synctask;
+ return buf;
}
-
-int
-synctask_set (void *synctask)
+char *
+glusterfs_leaseid_exist()
{
- int ret = 0;
+ return thread_leaseid;
+}
- pthread_setspecific (synctask_key, synctask);
+static void
+glusterfs_cleanup(void *ptr)
+{
+ if (thread_syncopctx.groups != NULL) {
+ GF_FREE(thread_syncopctx.groups);
+ }
- return ret;
+ mem_pool_thread_destructor(NULL);
}
-//UUID_BUFFER
-
-static pthread_key_t uuid_buf_key;
-static char global_uuid_buf[GF_UUID_BUF_SIZE];
void
-glusterfs_uuid_buf_destroy (void *ptr)
+gf_thread_needs_cleanup(void)
{
- if (ptr)
- FREE (ptr);
+ /* The value stored in free_key TLS is not really used for anything, but
+ * pthread implementation doesn't call the TLS destruction function unless
+ * it's != NULL. This function must be called whenever something is
+ * allocated for this thread so that glusterfs_cleanup() will be called
+ * and resources can be released. */
+ (void)pthread_setspecific(free_key, (void *)1);
}
-int
-glusterfs_uuid_buf_init ()
+static void
+gf_globals_init_once()
{
- int ret = 0;
+ int ret = 0;
- ret = pthread_key_create (&uuid_buf_key,
- glusterfs_uuid_buf_destroy);
- return ret;
-}
+ glusterfs_this_init();
-char *
-glusterfs_uuid_buf_get ()
-{
- char *buf;
- int ret = 0;
-
- buf = pthread_getspecific (uuid_buf_key);
- if(!buf) {
- buf = MALLOC (GF_UUID_BUF_SIZE);
- ret = pthread_setspecific (uuid_buf_key, (void *) buf);
- if(ret)
- buf = global_uuid_buf;
- }
- return buf;
+ /* This is needed only to cleanup the potential allocation of
+ * thread_syncopctx.groups. */
+ ret = pthread_key_create(&free_key, glusterfs_cleanup);
+ if (ret != 0) {
+ gf_msg("", GF_LOG_ERROR, ret, LG_MSG_PTHREAD_KEY_CREATE_FAILED,
+ "failed to create the pthread key");
+
+ gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_GLOBAL_INIT_FAILED,
+ "Exiting as global initialization failed");
+
+ exit(ret);
+ }
}
int
-glusterfs_globals_init ()
+glusterfs_globals_init(glusterfs_ctx_t *ctx)
{
- int ret = 0;
-
- gf_op_list_init ();
-
- gf_log_globals_init ();
-
- ret = glusterfs_ctx_init ();
- if (ret) {
- gf_log ("", GF_LOG_CRITICAL,
- "ERROR: glusterfs context init failed");
- goto out;
- }
-
- ret = glusterfs_this_init ();
- if (ret) {
- gf_log ("", GF_LOG_CRITICAL,
- "ERROR: glusterfs-translator init failed");
- goto out;
- }
-
- ret = glusterfs_uuid_buf_init ();
- if(ret) {
- gf_log ("", GF_LOG_CRITICAL,
- "ERROR: glusterfs uuid buffer init failed");
- goto out;
- }
-
- gf_mem_acct_enable_set ();
-
- ret = synctask_init ();
- if (ret) {
- gf_log ("", GF_LOG_CRITICAL,
- "ERROR: glusterfs synctask init failed");
- goto out;
- }
-out:
- return ret;
-}
+ int ret = 0;
+ gf_log_globals_init(ctx, GF_LOG_INFO);
-char eventstring[GF_EVENT_MAXVAL][64] = {
- "Invalid event",
- "Parent Up",
- "Poll In",
- "Poll Out",
- "Poll Err",
- "Child Up",
- "Child Down",
- "Child Connecting",
- "Transport Cleanup",
- "Transport Connected",
- "Volfile Modified",
-};
+ ret = pthread_once(&globals_inited, gf_globals_init_once);
-/* Copy the string ptr contents if needed for yourself */
-char *
-glusterfs_strevent (glusterfs_event_t ev)
-{
- return eventstring[ev];
+ if (ret)
+ gf_msg("", GF_LOG_CRITICAL, ret, LG_MSG_PTHREAD_FAILED,
+ "pthread_once failed");
+
+ return ret;
}
diff --git a/libglusterfs/src/globals.h b/libglusterfs/src/globals.h
deleted file mode 100644
index 7003351ab55..00000000000
--- a/libglusterfs/src/globals.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _GLOBALS_H
-#define _GLOBALS_H
-
-#define GF_DEFAULT_BASE_PORT 24007
-
-/* This corresponds to the max 16 number of group IDs that are sent through an
- * RPC request. Since NFS is the only one going to set this, we can be safe
- * in keeping this size hardcoded.
- */
-#define GF_REQUEST_MAXGROUPS 16
-
-#include "glusterfs.h"
-
-/* CTX */
-#define CTX (glusterfs_ctx_get())
-
-glusterfs_ctx_t *glusterfs_ctx_get ();
-
-#include "xlator.h"
-
-/* THIS */
-#define THIS (*__glusterfs_this_location())
-
-#define GF_UUID_BUF_SIZE 50
-
-xlator_t **__glusterfs_this_location ();
-xlator_t *glusterfs_this_get ();
-int glusterfs_this_set (xlator_t *);
-
-/* task */
-void *synctask_get ();
-int synctask_set (void *);
-
-/* uuid_buf */
-char *glusterfs_uuid_buf_get();
-
-/* init */
-int glusterfs_globals_init (void);
-
-#endif /* !_GLOBALS_H */
diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h
deleted file mode 100644
index 14a0dbc7575..00000000000
--- a/libglusterfs/src/glusterfs.h
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _GLUSTERFS_H
-#define _GLUSTERFS_H
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/statvfs.h>
-#include <netdb.h>
-#include <errno.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <arpa/inet.h>
-#include <sys/poll.h>
-#include <pthread.h>
-
-#include "list.h"
-#include "logging.h"
-
-
-#define GF_YES 1
-#define GF_NO 0
-
-#ifndef O_LARGEFILE
-/* savannah bug #20053, patch for compiling on darwin */
-#define O_LARGEFILE 0
-#endif
-
-#ifndef O_DIRECT
-/* savannah bug #20050, #20052 */
-#define O_DIRECT 0 /* From asm/fcntl.h */
-#endif
-
-#ifndef O_DIRECTORY
-/* FreeBSD does not need O_DIRECTORY */
-#define O_DIRECTORY 0
-#endif
-
-#ifndef EBADFD
-/* Mac OS X does not have EBADFD */
-#define EBADFD EBADF
-#endif
-
-#ifndef FNM_EXTMATCH
-#define FNM_EXTMATCH 0
-#endif
-
-#define ZR_MOUNTPOINT_OPT "mountpoint"
-#define ZR_ATTR_TIMEOUT_OPT "attribute-timeout"
-#define ZR_ENTRY_TIMEOUT_OPT "entry-timeout"
-#define ZR_DIRECT_IO_OPT "direct-io-mode"
-#define ZR_STRICT_VOLFILE_CHECK "strict-volfile-check"
-#define ZR_DUMP_FUSE "dump-fuse"
-
-#define GF_XATTR_PATHINFO_KEY "trusted.glusterfs.pathinfo"
-#define GF_XATTR_LINKINFO_KEY "trusted.distribute.linkinfo"
-#define GFID_XATTR_KEY "trusted.gfid"
-
-#define ZR_FILE_CONTENT_STR "glusterfs.file."
-#define ZR_FILE_CONTENT_STRLEN 15
-
-#define GLUSTERFS_OPEN_FD_COUNT "glusterfs.open-fd-count"
-#define GLUSTERFS_INODELK_COUNT "glusterfs.inodelk-count"
-#define GLUSTERFS_ENTRYLK_COUNT "glusterfs.entrylk-count"
-#define GLUSTERFS_POSIXLK_COUNT "glusterfs.posixlk-count"
-#define QUOTA_SIZE_KEY "trusted.glusterfs.quota.size"
-
-#define GLUSTERFS_RDMA_INLINE_THRESHOLD (2048)
-#define GLUSTERFS_RDMA_MAX_HEADER_SIZE (228) /* (sizeof (rdma_header_t) \
- + RDMA_MAX_SEGMENTS \
- * sizeof (rdma_read_chunk_t))
- */
-
-#define GLUSTERFS_RPC_REPLY_SIZE 24
-
-#define ZR_FILE_CONTENT_REQUEST(key) (!strncmp(key, ZR_FILE_CONTENT_STR, \
- ZR_FILE_CONTENT_STRLEN))
-
-/* TODO: Should we use PATH-MAX? On some systems it may save space */
-#define ZR_PATH_MAX 4096
-
-/* NOTE: add members ONLY at the end (just before _MAXVALUE) */
-typedef enum {
- GF_FOP_NULL = 0,
- GF_FOP_STAT,
- GF_FOP_READLINK,
- GF_FOP_MKNOD,
- GF_FOP_MKDIR,
- GF_FOP_UNLINK,
- GF_FOP_RMDIR,
- GF_FOP_SYMLINK,
- GF_FOP_RENAME,
- GF_FOP_LINK,
- GF_FOP_TRUNCATE,
- GF_FOP_OPEN,
- GF_FOP_READ,
- GF_FOP_WRITE,
- GF_FOP_STATFS,
- GF_FOP_FLUSH,
- GF_FOP_FSYNC, /* 15 */
- GF_FOP_SETXATTR,
- GF_FOP_GETXATTR,
- GF_FOP_REMOVEXATTR,
- GF_FOP_OPENDIR,
- GF_FOP_FSYNCDIR,
- GF_FOP_ACCESS,
- GF_FOP_CREATE,
- GF_FOP_FTRUNCATE,
- GF_FOP_FSTAT, /* 25 */
- GF_FOP_LK,
- GF_FOP_LOOKUP,
- GF_FOP_READDIR,
- GF_FOP_INODELK,
- GF_FOP_FINODELK,
- GF_FOP_ENTRYLK,
- GF_FOP_FENTRYLK,
- GF_FOP_XATTROP,
- GF_FOP_FXATTROP,
- GF_FOP_FGETXATTR,
- GF_FOP_FSETXATTR,
- GF_FOP_RCHECKSUM,
- GF_FOP_SETATTR,
- GF_FOP_FSETATTR,
- GF_FOP_READDIRP,
- GF_FOP_FORGET,
- GF_FOP_RELEASE,
- GF_FOP_RELEASEDIR,
- GF_FOP_GETSPEC,
- GF_FOP_MAXVALUE,
-} glusterfs_fop_t;
-
-
-typedef enum {
- GF_MGMT_NULL = 0,
- GF_MGMT_MAXVALUE,
-} glusterfs_mgmt_t;
-
-typedef enum {
- GF_OP_TYPE_NULL = 0,
- GF_OP_TYPE_FOP,
- GF_OP_TYPE_MGMT,
- GF_OP_TYPE_MAX,
-} gf_op_type_t;
-
-struct gf_flock {
- short l_type;
- short l_whence;
- off_t l_start;
- off_t l_len;
- pid_t l_pid;
- uint64_t l_owner;
-};
-
-/* NOTE: all the miscellaneous flags used by GlusterFS should be listed here */
-typedef enum {
- GF_LK_GETLK = 0,
- GF_LK_SETLK,
- GF_LK_SETLKW,
- GF_LK_RESLK_LCK,
- GF_LK_RESLK_LCKW,
- GF_LK_RESLK_UNLCK,
- GF_LK_GETLK_FD,
-} glusterfs_lk_cmds_t;
-
-
-typedef enum {
- GF_LK_F_RDLCK = 0,
- GF_LK_F_WRLCK,
- GF_LK_F_UNLCK,
- GF_LK_EOL,
-} glusterfs_lk_types_t;
-
-typedef enum {
- F_RESLK_LCK = 200,
- F_RESLK_LCKW,
- F_RESLK_UNLCK,
- F_GETLK_FD,
-} glusterfs_lk_recovery_cmds_t;
-
-typedef enum {
- GF_LOCK_POSIX,
- GF_LOCK_INTERNAL
-} gf_lk_domain_t;
-
-
-typedef enum {
- ENTRYLK_LOCK,
- ENTRYLK_UNLOCK,
- ENTRYLK_LOCK_NB
-} entrylk_cmd;
-
-
-typedef enum {
- ENTRYLK_RDLCK,
- ENTRYLK_WRLCK
-} entrylk_type;
-
-
-typedef enum {
- GF_XATTROP_ADD_ARRAY,
- GF_XATTROP_ADD_ARRAY64
-} gf_xattrop_flags_t;
-
-
-#define GF_SET_IF_NOT_PRESENT 0x1 /* default behaviour */
-#define GF_SET_OVERWRITE 0x2 /* Overwrite with the buf given */
-#define GF_SET_DIR_ONLY 0x4
-#define GF_SET_EPOCH_TIME 0x8 /* used by afr dir lookup selfheal */
-
-/* Directory into which replicate self-heal will move deleted files and
- directories into. The storage/posix janitor thread will periodically
- clean up this directory */
-
-#define GF_REPLICATE_TRASH_DIR ".landfill"
-
-/* key value which quick read uses to get small files in lookup cbk */
-#define GF_CONTENT_KEY "glusterfs.content"
-
-struct _xlator_cmdline_option {
- struct list_head cmd_args;
- char *volume;
- char *key;
- char *value;
-};
-typedef struct _xlator_cmdline_option xlator_cmdline_option_t;
-
-
-#define GF_OPTION_ENABLE _gf_true
-#define GF_OPTION_DISABLE _gf_false
-#define GF_OPTION_DEFERRED 2
-
-struct _cmd_args {
- /* basic options */
- char *volfile_server;
- char *volfile;
- char *log_server;
- gf_loglevel_t log_level;
- char *log_file;
- int32_t max_connect_attempts;
- /* advanced options */
- uint32_t volfile_server_port;
- char *volfile_server_transport;
- uint32_t log_server_port;
- char *pid_file;
- char *sock_file;
- int no_daemon_mode;
- char *run_id;
- int debug_mode;
- int read_only;
- int acl;
- int mac_compat;
- struct list_head xlator_options; /* list of xlator_option_t */
-
- /* fuse options */
- int fuse_direct_io_mode;
- int volfile_check;
- double fuse_entry_timeout;
- double fuse_attribute_timeout;
- char *volume_name;
- int fuse_nodev;
- int fuse_nosuid;
- char *dump_fuse;
- pid_t client_pid;
- int client_pid_set;
-
- /* key args */
- char *mount_point;
- char *volfile_id;
-
- /* required for portmap */
- int brick_port;
- char *brick_name;
- int brick_port2;
-};
-typedef struct _cmd_args cmd_args_t;
-
-
-struct _glusterfs_graph {
- struct list_head list;
- char graph_uuid[128];
- struct timeval dob;
- void *first;
- void *top; /* selected by -n */
- int xl_count;
- int id; /* Used in logging */
- int used; /* Should be set when fuse gets
- first CHILD_UP */
- uint32_t volfile_checksum;
-};
-typedef struct _glusterfs_graph glusterfs_graph_t;
-
-
-struct _glusterfs_ctx {
- cmd_args_t cmd_args;
- char *process_uuid;
- FILE *pidfp;
- char fin;
- void *timer;
- void *ib;
- void *pool;
- void *event_pool;
- void *iobuf_pool;
- pthread_mutex_t lock;
- size_t page_size;
- struct list_head graphs; /* double linked list of graphs - one per volfile parse */
- glusterfs_graph_t *active; /* the latest graph in use */
- void *master; /* fuse, or libglusterfsclient (however, not protocol/server) */
- void *mgmt; /* xlator implementing MOPs for centralized logging, volfile server */
- void *listener; /* listener of the commands from glusterd */
- unsigned char measure_latency; /* toggle switch for latency measurement */
- pthread_t sigwaiter;
- struct mem_pool *stub_mem_pool;
- unsigned char cleanup_started;
- int graph_id; /* Incremented per graph, value should
- indicate how many times the graph has
- got changed */
-};
-typedef struct _glusterfs_ctx glusterfs_ctx_t;
-
-
-/* If you edit this structure then, make a corresponding change in
- * globals.c in the eventstring.
- */
-typedef enum {
- GF_EVENT_PARENT_UP = 1,
- GF_EVENT_POLLIN,
- GF_EVENT_POLLOUT,
- GF_EVENT_POLLERR,
- GF_EVENT_CHILD_UP,
- GF_EVENT_CHILD_DOWN,
- GF_EVENT_CHILD_CONNECTING,
- GF_EVENT_CHILD_MODIFIED,
- GF_EVENT_TRANSPORT_CLEANUP,
- GF_EVENT_TRANSPORT_CONNECTED,
- GF_EVENT_VOLFILE_MODIFIED,
- GF_EVENT_GRAPH_NEW,
- GF_EVENT_TRANSLATOR_INFO,
- GF_EVENT_MAXVAL,
-} glusterfs_event_t;
-
-extern char *glusterfs_strevent (glusterfs_event_t ev);
-
-#define GF_MUST_CHECK __attribute__((warn_unused_result))
-
-int glusterfs_graph_prepare (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx);
-int glusterfs_graph_destroy (glusterfs_graph_t *graph);
-int glusterfs_graph_activate (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx);
-glusterfs_graph_t *glusterfs_graph_construct (FILE *fp);
-glusterfs_graph_t *glusterfs_graph_new ();
-int glusterfs_graph_reconfigure (glusterfs_graph_t *oldgraph,
- glusterfs_graph_t *newgraph);
-
-#endif /* _GLUSTERFS_H */
diff --git a/libglusterfs/src/glusterfs/async.h b/libglusterfs/src/glusterfs/async.h
new file mode 100644
index 00000000000..d1d70ae0bc7
--- /dev/null
+++ b/libglusterfs/src/glusterfs/async.h
@@ -0,0 +1,209 @@
+/*
+ Copyright (c) 2019 Red Hat, Inc <https://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 __GLUSTERFS_ASYNC_H__
+#define __GLUSTERFS_ASYNC_H__
+
+#define _LGPL_SOURCE
+
+#include <sys/types.h>
+#include <signal.h>
+#include <errno.h>
+
+#ifdef URCU_OLD
+
+/* TODO: Fix the include paths. Since this is a .h included from many places
+ * it makes no sense to append a '-I$(CONTRIBDIR)/userspace-rcu/' to each
+ * Makefile.am. I've also seen some problems with CI builders (they
+ * failed to find the include files, but the same source on another setup
+ * is working fine). */
+#include "wfcqueue.h"
+#include "wfstack.h"
+
+#else /* !URCU_OLD */
+
+#include <urcu/wfcqueue.h>
+#include <urcu/wfstack.h>
+
+#endif /* URCU_OLD */
+
+#include "glusterfs/xlator.h"
+#include "glusterfs/common-utils.h"
+#include "glusterfs/list.h"
+#include "glusterfs/libglusterfs-messages.h"
+
+/* This is the name prefix that all worker threads will have. A number will
+ * be added to differentiate them. */
+#define GF_ASYNC_THREAD_NAME "tpw"
+
+/* This value determines the maximum number of threads that are allowed. */
+#define GF_ASYNC_MAX_THREADS 128
+
+/* This value determines how many additional threads will be started but will
+ * remain inactive until they are explicitly activated by the leader. This is
+ * useful to react faster to bursts of load, but at the same time we minimize
+ * contention if they are not really needed to handle current load.
+ *
+ * TODO: Instead of a fixed number, it would probably be better to use a
+ * prcentage of the available cores. */
+#define GF_ASYNC_SPARE_THREADS 2
+
+/* This value determines the signal used to wake the leader when new work has
+ * been added to the queue. To do so we reuse SIGALRM, since the most logical
+ * candidates (SIGUSR1/SIGUSR2) are already used. This signal must not be used
+ * by anything else in the process. */
+#define GF_ASYNC_SIGQUEUE SIGALRM
+
+/* This value determines the signal that will be used to transfer leader role
+ * to other workers. */
+#define GF_ASYNC_SIGCTRL SIGVTALRM
+
+#define gf_async_warning(_err, _msg, _args...) \
+ gf_msg("async", GF_LOG_WARNING, -(_err), LG_MSG_ASYNC_WARNING, _msg, \
+ ##_args)
+
+#define gf_async_error(_err, _msg, _args...) \
+ gf_msg("async", GF_LOG_ERROR, -(_err), LG_MSG_ASYNC_FAILURE, _msg, ##_args)
+
+#define gf_async_fatal(_err, _msg, _args...) \
+ do { \
+ GF_ABORT("Critical error in async module. Unable to continue. (" _msg \
+ "). Error %d.", \
+ ##_args, -(_err)); \
+ } while (0)
+
+struct _gf_async;
+typedef struct _gf_async gf_async_t;
+
+struct _gf_async_worker;
+typedef struct _gf_async_worker gf_async_worker_t;
+
+struct _gf_async_queue;
+typedef struct _gf_async_queue gf_async_queue_t;
+
+struct _gf_async_control;
+typedef struct _gf_async_control gf_async_control_t;
+
+typedef void (*gf_async_callback_f)(xlator_t *xl, gf_async_t *async);
+
+struct _gf_async {
+ /* TODO: remove dependency on xl/THIS. */
+ xlator_t *xl;
+ gf_async_callback_f cbk;
+ struct cds_wfcq_node queue;
+};
+
+struct _gf_async_worker {
+ /* Used to send asynchronous jobs related to the worker. */
+ gf_async_t async;
+
+ /* Member of the available workers stack. */
+ struct cds_wfs_node stack;
+
+ /* Thread object of the current worker. */
+ pthread_t thread;
+
+ /* Unique identifier of this worker. */
+ int32_t id;
+
+ /* Indicates if this worker is enabled. */
+ bool running;
+};
+
+struct _gf_async_queue {
+ /* Structures needed to manage a wait-free queue. For better performance
+ * they are placed in two different cache lines, as recommended by URCU
+ * documentation, even though in our case some threads will be producers
+ * and consumers at the same time. */
+ struct cds_wfcq_head head __attribute__((aligned(64)));
+ struct cds_wfcq_tail tail __attribute__((aligned(64)));
+};
+
+#define GF_ASYNC_COUNTS(_run, _stop) (((uint32_t)(_run) << 16) + (_stop))
+#define GF_ASYNC_COUNT_RUNNING(_count) ((_count) >> 16)
+#define GF_ASYNC_COUNT_STOPPING(_count) ((_count)&65535)
+
+struct _gf_async_control {
+ gf_async_queue_t queue;
+
+ /* Stack of unused workers. */
+ struct __cds_wfs_stack available;
+
+ /* Array of preallocated worker structures. */
+ gf_async_worker_t *table;
+
+ /* Used to synchronize main thread with workers on termination. */
+ pthread_barrier_t sync;
+
+ /* The id of the last thread that will be used for synchronization. */
+ pthread_t sync_thread;
+
+ /* Signal mask to wait for control signals from leader. */
+ sigset_t sigmask_ctrl;
+
+ /* Signal mask to wait for queued items. */
+ sigset_t sigmask_queue;
+
+ /* Saved signal handlers. */
+ struct sigaction handler_ctrl;
+ struct sigaction handler_queue;
+
+ /* PID of the current process. */
+ pid_t pid;
+
+ /* Maximum number of allowed threads. */
+ uint32_t max_threads;
+
+ /* Current number of running and stopping workers. This value is split
+ * into 2 16-bits fields to track both counters atomically at the same
+ * time. */
+ uint32_t counts;
+
+ /* It's used to control whether the asynchronous infrastructure is used
+ * or not. */
+ bool enabled;
+};
+
+extern gf_async_control_t gf_async_ctrl;
+
+int32_t
+gf_async_init(glusterfs_ctx_t *ctx);
+
+void
+gf_async_fini(void);
+
+void
+gf_async_adjust_threads(int32_t threads);
+
+static inline void
+gf_async(gf_async_t *async, xlator_t *xl, gf_async_callback_f cbk)
+{
+ if (!gf_async_ctrl.enabled) {
+ cbk(xl, async);
+ return;
+ }
+
+ async->xl = xl;
+ async->cbk = cbk;
+ cds_wfcq_node_init(&async->queue);
+ if (caa_unlikely(!cds_wfcq_enqueue(&gf_async_ctrl.queue.head,
+ &gf_async_ctrl.queue.tail,
+ &async->queue))) {
+ /* The queue was empty, so the leader could be sleeping. We need to
+ * wake it so that the new item can be processed. If the queue was not
+ * empty, we don't need to do anything special since the leader will
+ * take care of it. */
+ if (caa_unlikely(kill(gf_async_ctrl.pid, GF_ASYNC_SIGQUEUE) < 0)) {
+ gf_async_fatal(errno, "Unable to wake leader worker.");
+ };
+ }
+}
+
+#endif /* !__GLUSTERFS_ASYNC_H__ */
diff --git a/libglusterfs/src/glusterfs/atomic.h b/libglusterfs/src/glusterfs/atomic.h
new file mode 100644
index 00000000000..ced81748218
--- /dev/null
+++ b/libglusterfs/src/glusterfs/atomic.h
@@ -0,0 +1,459 @@
+/*
+ Copyright (c) 2017 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 _ATOMIC_H
+#define _ATOMIC_H
+
+#include <inttypes.h>
+#include <stdbool.h>
+
+#include "glusterfs/locking.h"
+
+/* Macros used to join two arguments and generate a new macro name. */
+#define GF_ATOMIC_MACRO_1(_macro) _macro
+#define GF_ATOMIC_MACRO(_base, _name) GF_ATOMIC_MACRO_1(_base##_name)
+
+/* There's a problem on 32-bit architectures when we try to use atomic
+ * builtins with 64-bit types. Only way to solve the problem is to use
+ * a mutex to protect the access to the atomic, but we don't want to
+ * use mutexes for other smaller types that could work with the atomic
+ * builtins.
+ *
+ * So on each atomic type we add a field for the mutex if atomic operation
+ * is not supported and a dummy zero size field if it's supported. This way
+ * we can have different atomic types, some with a mutex and some without.
+ *
+ * To define these types, we use two macros:
+ *
+ * GF_ATOMIC_MUTEX_FIELD_0 = char lk[0]
+ * GF_ATOMIC_MUTEX_FILED_1 = gf_lock_t lk
+ *
+ * Both macros define the 'lk' field that will be used in the atomic
+ * structure. One when the atomic is supported by the architecture and
+ * another when not. We need to define the field even if it won't be
+ * used. Otherwise the compiler will return an error.
+ *
+ * Now we need to take the mutex or not depending on the existence of
+ * the mutex field in the structure. To do so we check the size of the
+ * structure, and if it's bigger than uint64_t (all structures with a
+ * mutex will be bigger), we use the mutex-based version. Otherwise we
+ * use the atomic builtin. This check is easily optimized out by the
+ * compiler, leaving a clean and efficient compiled code. */
+
+#define GF_ATOMIC_MUTEX_FIELD_0 char lk[0]
+#define GF_ATOMIC_MUTEX_FIELD_1 gf_lock_t lk
+
+/* We'll use SIZEOF_LONG to determine the architecture. 32-bit machines
+ * will have 4 here, while 64-bit machines will have 8. If additional
+ * needs or restrictions appear on other platforms, these tests can be
+ * extended to handle them. */
+
+/* GF_ATOMIC_SIZE_X macros map each type size to one of the
+ * GF_ATOMIC_MUTEX_FIELD_X macros, depending on detected conditions. */
+
+#if defined(HAVE_ATOMIC_BUILTINS) || defined(HAVE_SYNC_BUILTINS)
+
+#define GF_ATOMIC_SIZE_1 GF_ATOMIC_MUTEX_FIELD_0
+#define GF_ATOMIC_SIZE_2 GF_ATOMIC_MUTEX_FIELD_0
+#define GF_ATOMIC_SIZE_4 GF_ATOMIC_MUTEX_FIELD_0
+
+#if SIZEOF_LONG >= 8
+#define GF_ATOMIC_SIZE_8 GF_ATOMIC_MUTEX_FIELD_0
+#endif
+
+#endif /* HAVE_(ATOMIC|SYNC)_BUILTINS */
+
+/* Any GF_ATOMIC_SIZE_X macro not yet defined will use the mutex version */
+#ifndef GF_ATOMIC_SIZE_1
+#define GF_ATOMIC_SIZE_1 GF_ATOMIC_MUTEX_FIELD_1
+#endif
+
+#ifndef GF_ATOMIC_SIZE_2
+#define GF_ATOMIC_SIZE_2 GF_ATOMIC_MUTEX_FIELD_1
+#endif
+
+#ifndef GF_ATOMIC_SIZE_4
+#define GF_ATOMIC_SIZE_4 GF_ATOMIC_MUTEX_FIELD_1
+#endif
+
+#ifndef GF_ATOMIC_SIZE_8
+#define GF_ATOMIC_SIZE_8 GF_ATOMIC_MUTEX_FIELD_1
+#endif
+
+/* This macro is used to define all atomic types supported. First field
+ * represents the size of the type in bytes, and the second one the name. */
+#define GF_ATOMIC_TYPE(_size, _name) \
+ typedef struct _gf_atomic_##_name##_t { \
+ GF_ATOMIC_MACRO(GF_ATOMIC_SIZE_, _size); \
+ _name##_t value; \
+ } gf_atomic_##_name##_t
+
+/* The atomic types we support */
+GF_ATOMIC_TYPE(1, int8); /* gf_atomic_int8_t */
+GF_ATOMIC_TYPE(2, int16); /* gf_atomic_int16_t */
+GF_ATOMIC_TYPE(4, int32); /* gf_atomic_int32_t */
+GF_ATOMIC_TYPE(8, int64); /* gf_atomic_int64_t */
+GF_ATOMIC_TYPE(SIZEOF_LONG, intptr); /* gf_atomic_intptr_t */
+GF_ATOMIC_TYPE(1, uint8); /* gf_atomic_uint8_t */
+GF_ATOMIC_TYPE(2, uint16); /* gf_atomic_uint16_t */
+GF_ATOMIC_TYPE(4, uint32); /* gf_atomic_uint32_t */
+GF_ATOMIC_TYPE(8, uint64); /* gf_atomic_uint64_t */
+GF_ATOMIC_TYPE(SIZEOF_LONG, uintptr); /* gf_atomic_uintptr_t */
+
+/* Define the default atomic type as int64_t */
+#define gf_atomic_t gf_atomic_int64_t
+
+/* This macro will choose between the mutex based version and the atomic
+ * builtin version depending on the size of the atomic structure. */
+#define GF_ATOMIC_CHOOSE(_atomic, _op, _args...) \
+ ((sizeof(_atomic) > sizeof(uint64_t)) \
+ ? ({ \
+ GF_ATOMIC_MACRO(GF_ATOMIC_LOCK_, _op) \
+ (_atomic, ##_args); \
+ }) \
+ : ({ \
+ GF_ATOMIC_MACRO(GF_ATOMIC_BASE_, _op) \
+ (_atomic, ##_args); \
+ }))
+
+/* Macros to implement the mutex-based atomics. */
+#define GF_ATOMIC_OP_PREPARE(_atomic, _name) \
+ typeof(_atomic) *__atomic = &(_atomic); \
+ gf_lock_t *__lock = (gf_lock_t *)&__atomic->lk; \
+ LOCK(__lock); \
+ typeof(__atomic->value) _name = __atomic->value
+
+#define GF_ATOMIC_OP_STORE(_value) (__atomic->value = (_value))
+
+#define GF_ATOMIC_OP_RETURN(_value) \
+ ({ \
+ UNLOCK(__lock); \
+ _value; \
+ })
+
+#define GF_ATOMIC_LOCK_INIT(_atomic, _value) \
+ do { \
+ typeof(_atomic) *__atomic = &(_atomic); \
+ LOCK_INIT((gf_lock_t *)&__atomic->lk); \
+ __atomic->value = (_value); \
+ } while (0)
+
+#define GF_ATOMIC_LOCK_GET(_atomic) \
+ ({ \
+ GF_ATOMIC_OP_PREPARE(_atomic, __value); \
+ GF_ATOMIC_OP_RETURN(__value); \
+ })
+
+#define GF_ATOMIC_LOCK_ADD(_atomic, _value) \
+ ({ \
+ GF_ATOMIC_OP_PREPARE(_atomic, __value); \
+ GF_ATOMIC_OP_STORE(__value += (_value)); \
+ GF_ATOMIC_OP_RETURN(__value); \
+ })
+
+#define GF_ATOMIC_LOCK_SUB(_atomic, _value) \