summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src
diff options
context:
space:
mode:
Diffstat (limited to 'libglusterfs/src')
-rw-r--r--libglusterfs/src/Makefile.am51
-rw-r--r--libglusterfs/src/byte-order.h195
-rw-r--r--libglusterfs/src/call-stub.c4904
-rw-r--r--libglusterfs/src/call-stub.h943
-rw-r--r--libglusterfs/src/checksum.c55
-rw-r--r--libglusterfs/src/checksum.h25
-rw-r--r--libglusterfs/src/circ-buff.c202
-rw-r--r--libglusterfs/src/circ-buff.h64
-rw-r--r--libglusterfs/src/client_t.c890
-rw-r--r--libglusterfs/src/client_t.h135
-rw-r--r--libglusterfs/src/common-utils.c3162
-rw-r--r--libglusterfs/src/common-utils.h376
-rw-r--r--libglusterfs/src/compat-errno.c1596
-rw-r--r--libglusterfs/src/compat-errno.h33
-rw-r--r--libglusterfs/src/compat.c819
-rw-r--r--libglusterfs/src/compat.h124
-rw-r--r--libglusterfs/src/ctx.c48
-rw-r--r--libglusterfs/src/daemon.c66
-rw-r--r--libglusterfs/src/daemon.h23
-rw-r--r--libglusterfs/src/defaults.c810
-rw-r--r--libglusterfs/src/defaults.h424
-rw-r--r--libglusterfs/src/dict.c3276
-rw-r--r--libglusterfs/src/dict.h158
-rw-r--r--libglusterfs/src/event-epoll.c463
-rw-r--r--libglusterfs/src/event-history.c83
-rw-r--r--libglusterfs/src/event-history.h44
-rw-r--r--libglusterfs/src/event-poll.c451
-rw-r--r--libglusterfs/src/event.c976
-rw-r--r--libglusterfs/src/event.h78
-rw-r--r--libglusterfs/src/fd-lk.c490
-rw-r--r--libglusterfs/src/fd-lk.h70
-rw-r--r--libglusterfs/src/fd.c894
-rw-r--r--libglusterfs/src/fd.h70
-rw-r--r--libglusterfs/src/gf-dirent.c106
-rw-r--r--libglusterfs/src/gf-dirent.h28
-rw-r--r--libglusterfs/src/gidcache.c192
-rw-r--r--libglusterfs/src/gidcache.h53
-rw-r--r--libglusterfs/src/globals.c382
-rw-r--r--libglusterfs/src/globals.h68
-rw-r--r--libglusterfs/src/glusterfs-acl.h81
-rw-r--r--libglusterfs/src/glusterfs.h326
-rw-r--r--libglusterfs/src/graph-mem-types.h32
-rw-r--r--libglusterfs/src/graph-print.c70
-rw-r--r--libglusterfs/src/graph-utils.h27
-rw-r--r--libglusterfs/src/graph.c428
-rw-r--r--libglusterfs/src/graph.l24
-rw-r--r--libglusterfs/src/graph.y173
-rw-r--r--libglusterfs/src/hashfn.c265
-rw-r--r--libglusterfs/src/hashfn.h24
-rw-r--r--libglusterfs/src/iatt.h41
-rw-r--r--libglusterfs/src/inode.c1063
-rw-r--r--libglusterfs/src/inode.h129
-rw-r--r--libglusterfs/src/iobuf.c732
-rw-r--r--libglusterfs/src/iobuf.h80
-rw-r--r--libglusterfs/src/latency.c134
-rw-r--r--libglusterfs/src/latency.h22
-rw-r--r--libglusterfs/src/list.h96
-rw-r--r--libglusterfs/src/lkowner.h83
-rw-r--r--libglusterfs/src/locking.h23
-rw-r--r--libglusterfs/src/logging.c1110
-rw-r--r--libglusterfs/src/logging.h161
-rw-r--r--libglusterfs/src/mem-pool.c436
-rw-r--r--libglusterfs/src/mem-pool.h148
-rw-r--r--libglusterfs/src/mem-types.h205
-rw-r--r--libglusterfs/src/options.c1127
-rw-r--r--libglusterfs/src/options.h259
-rw-r--r--libglusterfs/src/rbthash.c78
-rw-r--r--libglusterfs/src/rbthash.h31
-rw-r--r--libglusterfs/src/run.c513
-rw-r--r--libglusterfs/src/run.h194
-rw-r--r--libglusterfs/src/scheduler.c91
-rw-r--r--libglusterfs/src/scheduler.h41
-rw-r--r--libglusterfs/src/stack.c389
-rw-r--r--libglusterfs/src/stack.h538
-rw-r--r--libglusterfs/src/statedump.c738
-rw-r--r--libglusterfs/src/statedump.h84
-rw-r--r--libglusterfs/src/store.c709
-rw-r--r--libglusterfs/src/store.h112
-rw-r--r--libglusterfs/src/syncop.c1917
-rw-r--r--libglusterfs/src/syncop.h403
-rw-r--r--libglusterfs/src/syscall.c189
-rw-r--r--libglusterfs/src/syscall.h24
-rw-r--r--libglusterfs/src/timer.c76
-rw-r--r--libglusterfs/src/timer.h49
-rw-r--r--libglusterfs/src/timespec.c68
-rw-r--r--libglusterfs/src/timespec.h24
-rw-r--r--libglusterfs/src/trie.c387
-rw-r--r--libglusterfs/src/trie.h51
-rw-r--r--libglusterfs/src/xlator.c1338
-rw-r--r--libglusterfs/src/xlator.h1087
90 files changed, 25274 insertions, 13983 deletions
diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am
index 71a088d98..907399ae6 100644
--- a/libglusterfs/src/Makefile.am
+++ b/libglusterfs/src/Makefile.am
@@ -1,21 +1,56 @@
-libglusterfs_la_CFLAGS = -fPIC -Wall -g -shared -nostartfiles $(GF_CFLAGS) $(GF_DARWIN_LIBGLUSTERFS_CFLAGS)
+libglusterfs_la_CFLAGS = -Wall $(GF_CFLAGS) \
+ $(GF_DARWIN_LIBGLUSTERFS_CFLAGS) \
+ -DDATADIR=\"$(localstatedir)\"
-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_CPPFLAGS = $(GF_CPPFLAGS) -D__USE_FILE_OFFSET64 \
+ -DXLATORDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator\" \
+ -I$(top_srcdir)/rpc/rpc-lib/src/ -I$(CONTRIBDIR)/rbtree
libglusterfs_la_LIBADD = @LEXLIB@
lib_LTLIBRARIES = libglusterfs.la
-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/tst_uuid.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
-
-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
+CONTRIB_BUILDDIR = $(top_builddir)/contrib
+
+libglusterfs_la_SOURCES = dict.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 daemon.c timespec.c \
+ $(CONTRIBDIR)/rbtree/rb.c rbthash.c store.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 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 \
+ $(CONTRIBDIR)/libgen/basename_r.c $(CONTRIBDIR)/libgen/dirname_r.c \
+ $(CONTRIBDIR)/stdlib/gf_mkostemp.c
+
+
+nodist_libglusterfs_la_SOURCES = y.tab.c graph.lex.c gf-error-codes.h
+
+BUILT_SOURCES = graph.lex.c
+
+noinst_HEADERS = common-utils.h defaults.h dict.h glusterfs.h hashfn.h timespec.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 daemon.h $(CONTRIBDIR)/rbtree/rb.h store.h\
+ rbthash.h iatt.h latency.h mem-types.h $(CONTRIBDIR)/uuid/uuidd.h \
+ $(CONTRIBDIR)/uuid/uuid.h $(CONTRIBDIR)/uuid/uuidP.h \
+ $(CONTRIB_BUILDDIR)/uuid/uuid_types.h syncop.h graph-utils.h trie.h \
+ run.h options.h lkowner.h fd-lk.h circ-buff.h event-history.h \
+ gidcache.h client_t.h glusterfs-acl.h
EXTRA_DIST = graph.l graph.y
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: graph.y
- $(YACC) -d $(srcdir)/graph.y
+y.tab.c: y.tab.h
+y.tab.h: graph.y
+ $(YACC) -p graphyy -d $(srcdir)/graph.y
CLEANFILES = graph.lex.c y.tab.c y.tab.h
+CONFIG_CLEAN_FILES = $(CONTRIB_BUILDDIR)/uuid/uuid_types.h
diff --git a/libglusterfs/src/byte-order.h b/libglusterfs/src/byte-order.h
index cabfcf4c6..4101db2c7 100644
--- a/libglusterfs/src/byte-order.h
+++ b/libglusterfs/src/byte-order.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
#ifndef _BYTE_ORDER_H
@@ -38,6 +29,23 @@ static uint64_t (*hton64) (uint64_t);
#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)))
@@ -86,15 +94,17 @@ __noswap64 (uint64_t x)
static inline uint16_t
-__byte_order_init16 (uint16_t i)
+__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;
@@ -105,15 +115,17 @@ __byte_order_init16 (uint16_t i)
static inline uint32_t
-__byte_order_init32 (uint32_t i)
+__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;
@@ -124,15 +136,17 @@ __byte_order_init32 (uint32_t i)
static inline uint64_t
-__byte_order_init64 (uint64_t i)
+__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;
@@ -142,9 +156,146 @@ __byte_order_init64 (uint64_t i)
}
-static uint16_t (*hton16) (uint16_t) = __byte_order_init16;
-static uint32_t (*hton32) (uint32_t) = __byte_order_init32;
-static uint64_t (*hton64) (uint64_t) = __byte_order_init64;
+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 d3b29a39a..ac79cf071 100644
--- a/libglusterfs/src/call-stub.c
+++ b/libglusterfs/src/call-stub.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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
@@ -22,3846 +13,2826 @@
#include "config.h"
#endif
+#include <openssl/md5.h>
#include <inttypes.h>
-#include "md5.h"
#include "call-stub.h"
#include "mem-types.h"
static call_stub_t *
stub_new (call_frame_t *frame,
- char wind,
- glusterfs_fop_t fop)
+ char wind,
+ 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;
+ 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", 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);
+ stub = stub_new (frame, 1, GF_FOP_LOOKUP);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.lookup.fn = fn;
+ stub->fn.lookup = fn;
- if (xattr_req)
- stub->args.lookup.xattr_req = dict_ref (xattr_req);
+ loc_copy (&stub->args.loc, loc);
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
- loc_copy (&stub->args.lookup.loc, loc);
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;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- 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);
+ stub->fn_cbk.lookup = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ if (inode)
+ stub->args_cbk.inode = inode_ref (inode);
+ if (buf)
+ stub->args_cbk.stat = *buf;
if (postparent)
- stub->args.lookup_cbk.postparent = *postparent;
+ stub->args_cbk.postparent = *postparent;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (xdata);
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;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ 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_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;
+ loc_copy (&stub->args.loc, loc);
+ if (xdata)
+ stub->args.xdata = dict_ref (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;
+
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- 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;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ if (op_ret == 0)
+ stub->args_cbk.stat = *buf;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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);
+ 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;
+ stub->fn.fstat = fn;
- if (fd)
- stub->args.fstat.fd = fd_ref (fd);
+ if (fd)
+ stub->args.fd = fd_ref (fd);
+ if (xdata)
+ stub->args.xdata = dict_ref (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;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- 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;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ if (buf)
+ stub->args_cbk.stat = *buf;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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", frame, 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;
+ loc_copy (&stub->args.loc, loc);
+ stub->args.offset = off;
+ if (xdata)
+ stub->args.xdata = dict_ref (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);
+ 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;
+ stub->fn_cbk.truncate = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ if (prebuf)
+ stub->args_cbk.prestat = *prebuf;
if (postbuf)
- stub->args.truncate_cbk.postbuf = *postbuf;
+ stub->args_cbk.poststat = *postbuf;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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);
+ 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->args.ftruncate.fn = fn;
- if (fd)
- stub->args.ftruncate.fd = fd_ref (fd);
+ stub->fn.ftruncate = fn;
+ if (fd)
+ stub->args.fd = fd_ref (fd);
- stub->args.ftruncate.off = off;
+ stub->args.offset = off;
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
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);
- 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;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ if (prebuf)
+ stub->args_cbk.prestat = *prebuf;
+ if (postbuf)
+ stub->args_cbk.poststat = *postbuf;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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", frame, 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;
+ loc_copy (&stub->args.loc, loc);
+ stub->args.mask = mask;
+ if (xdata)
+ stub->args.xdata = dict_ref (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;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- 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;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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", frame, 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;
+ loc_copy (&stub->args.loc, loc);
+ stub->args.size = size;
+ if (xdata)
+ stub->args.xdata = dict_ref (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);
+ 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;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ if (path)
+ stub->args_cbk.buf = gf_strdup (path);
+ if (stbuf)
+ stub->args_cbk.stat = *stbuf;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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", frame, 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;
+ loc_copy (&stub->args.loc, loc);
+ stub->args.mode = mode;
+ stub->args.rdev = rdev;
+ stub->args.umask = umask;
+ if (xdata)
+ stub->args.xdata = dict_ref (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;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- 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;
+ stub->fn_cbk.mknod = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ if (inode)
+ stub->args_cbk.inode = inode_ref (inode);
+ if (buf)
+ stub->args_cbk.stat = *buf;
if (preparent)
- stub->args.mknod_cbk.preparent = *preparent;
+ stub->args_cbk.preparent = *preparent;
if (postparent)
- stub->args.mknod_cbk.postparent = *postparent;
+ stub->args_cbk.postparent = *postparent;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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)
+ 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", frame, 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->fn.mkdir = fn;
+ loc_copy (&stub->args.loc, loc);
+ stub->args.mode = mode;
+ stub->args.umask = umask;
- 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);
+ if (xdata)
+ stub->args.xdata = dict_ref (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;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- 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;
+ stub->fn_cbk.mkdir = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ if (inode)
+ stub->args_cbk.inode = inode_ref (inode);
+ if (buf)
+ stub->args_cbk.stat = *buf;
if (preparent)
- stub->args.mkdir_cbk.preparent = *preparent;
+ stub->args_cbk.preparent = *preparent;
if (postparent)
- stub->args.mkdir_cbk.postparent = *postparent;
+ stub->args_cbk.postparent = *postparent;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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", frame, out);
- 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->args.unlink.fn = fn;
- loc_copy (&stub->args.unlink.loc, loc);
+ stub->fn.unlink = fn;
+ loc_copy (&stub->args.loc, loc);
+ stub->args.xflag = xflag;
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
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;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- 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;
+ stub->fn_cbk.unlink = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
if (preparent)
- stub->args.unlink_cbk.preparent = *preparent;
+ stub->args_cbk.preparent = *preparent;
if (postparent)
- stub->args.unlink_cbk.postparent = *postparent;
+ stub->args_cbk.postparent = *postparent;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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)
+ loc_t *loc, int 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);
+ 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->args.rmdir.fn = fn;
- loc_copy (&stub->args.rmdir.loc, loc);
- stub->args.rmdir.flags = flags;
+ stub->fn.rmdir = fn;
+ loc_copy (&stub->args.loc, loc);
+ stub->args.flags = flags;
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
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;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- 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;
+ stub->fn_cbk.rmdir = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
if (preparent)
- stub->args.rmdir_cbk.preparent = *preparent;
+ stub->args_cbk.preparent = *preparent;
if (postparent)
- stub->args.rmdir_cbk.postparent = *postparent;
+ stub->args_cbk.postparent = *postparent;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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)
+ 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", frame, 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;
+ stub->args.linkname = gf_strdup (linkname);
+ stub->args.umask = umask;
+ loc_copy (&stub->args.loc, loc);
+ if (xdata)
+ stub->args.xdata = dict_ref (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;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- 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;
+ stub->fn_cbk.symlink = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ if (inode)
+ stub->args_cbk.inode = inode_ref (inode);
+ if (buf)
+ stub->args_cbk.stat = *buf;
if (preparent)
- stub->args.symlink_cbk.preparent = *preparent;
+ stub->args_cbk.preparent = *preparent;
if (postparent)
- stub->args.symlink_cbk.postparent = *postparent;
+ stub->args_cbk.postparent = *postparent;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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", frame, 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;
+ loc_copy (&stub->args.loc, oldloc);
+ loc_copy (&stub->args.loc2, newloc);
+ if (xdata)
+ stub->args.xdata = dict_ref (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);
+ 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;
+ stub->fn_cbk.rename = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ if (buf)
+ stub->args_cbk.stat = *buf;
if (preoldparent)
- stub->args.rename_cbk.preoldparent = *preoldparent;
+ stub->args_cbk.preparent = *preoldparent;
if (postoldparent)
- stub->args.rename_cbk.postoldparent = *postoldparent;
+ stub->args_cbk.postparent = *postoldparent;
if (prenewparent)
- stub->args.rename_cbk.prenewparent = *prenewparent;
+ stub->args_cbk.preparent2 = *prenewparent;
if (postnewparent)
- stub->args.rename_cbk.postnewparent = *postnewparent;
+ stub->args_cbk.postparent2 = *postnewparent;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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", frame, 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 = 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->fn.link = fn;
+ loc_copy (&stub->args.loc, oldloc);
+ loc_copy (&stub->args.loc2, newloc);
+ if (xdata)
+ stub->args.xdata = dict_ref (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;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- 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;
+ stub->fn_cbk.link = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ if (inode)
+ stub->args_cbk.inode = inode_ref (inode);
+ if (buf)
+ stub->args_cbk.stat = *buf;
if (preparent)
- stub->args.link_cbk.preparent = *preparent;
+ stub->args_cbk.preparent = *preparent;
if (postparent)
- stub->args.link_cbk.postparent = *postparent;
+ stub->args_cbk.postparent = *postparent;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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)
+ 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", frame, 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;
+ loc_copy (&stub->args.loc, loc);
+ stub->args.flags = flags;
+ stub->args.mode = mode;
+ stub->args.umask = umask;
+ if (fd)
+ stub->args.fd = fd_ref (fd);
+ if (xdata)
+ stub->args.xdata = dict_ref (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);
+ 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;
+ stub->fn_cbk.create = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ if (fd)
+ stub->args_cbk.fd = fd_ref (fd);
+ if (inode)
+ stub->args_cbk.inode = inode_ref (inode);
+ if (buf)
+ stub->args_cbk.stat = *buf;
if (preparent)
- stub->args.create_cbk.preparent = *preparent;
+ stub->args_cbk.preparent = *preparent;
if (postparent)
- stub->args.create_cbk.postparent = *postparent;
+ stub->args_cbk.postparent = *postparent;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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", frame, 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;
+ loc_copy (&stub->args.loc, loc);
+ stub->args.flags = flags;
+ if (fd)
+ stub->args.fd = fd_ref (fd);
+ if (xdata)
+ stub->args.xdata = dict_ref (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);
+ 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;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ if (fd)
+ stub->args_cbk.fd = fd_ref (fd);
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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);
+ 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->fn.readv = fn;
+ if (fd)
+ stub->args.fd = fd_ref (fd);
+ stub->args.size = size;
+ stub->args.offset = off;
+ stub->args.flags = flags;
- stub->args.readv.fn = fn;
- if (fd)
- stub->args.readv.fd = fd_ref (fd);
- stub->args.readv.size = size;
- stub->args.readv.off = off;
+ if (xdata)
+ stub->args.xdata = dict_ref (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;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- 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;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ if (op_ret >= 0) {
+ stub->args_cbk.vector = iov_dup (vector, count);
+ stub->args_cbk.count = count;
+ stub->args_cbk.stat = *stbuf;
+ stub->args_cbk.iobref = iobref_ref (iobref);
+ }
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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", frame, 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;
+ if (fd)
+ stub->args.fd = fd_ref (fd);
+ stub->args.vector = iov_dup (vector, count);
+ stub->args.count = count;
+ stub->args.offset = off;
+ stub->args.flags = flags;
+ stub->args.iobref = iobref_ref (iobref);
+ if (xdata)
+ stub->args.xdata = dict_ref (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);
+ 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;
+ stub->fn_cbk.writev = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ if (op_ret >= 0)
+ stub->args_cbk.poststat = *postbuf;
if (prebuf)
- stub->args.writev_cbk.prebuf = *prebuf;
+ stub->args_cbk.prestat = *prebuf;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- 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;
+ if (fd)
+ stub->args.fd = fd_ref (fd);
+ if (xdata)
+ stub->args.xdata = dict_ref (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;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- 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;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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)
+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;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- stub = stub_new (frame, 1, 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.fsync = fn;
+ if (fd)
+ stub->args.fd = fd_ref (fd);
+ stub->args.datasync = datasync;
+ if (xdata)
+ stub->args.xdata = dict_ref (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_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);
+ 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, 0, GF_FOP_FSYNC);
+ 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;
+ stub->fn_cbk.fsync = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
if (prebuf)
- stub->args.fsync_cbk.prebuf = *prebuf;
+ stub->args_cbk.prestat = *prebuf;
if (postbuf)
- stub->args.fsync_cbk.postbuf = *postbuf;
+ stub->args_cbk.poststat = *postbuf;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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_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);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
- stub = stub_new (frame, 1, 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.opendir = fn;
+ loc_copy (&stub->args.loc, loc);
+ if (fd)
+ stub->args.fd = fd_ref (fd);
+ if (xdata)
+ stub->args.xdata = dict_ref (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_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", frame, out);
- stub = stub_new (frame, 0, GF_FOP_OPENDIR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new (frame, 0, GF_FOP_OPENDIR);
+ 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;
+ stub->fn_cbk.opendir = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
- if (fd)
- stub->args.opendir_cbk.fd = fd_ref (fd);
+ if (fd)
+ stub->args_cbk.fd = fd_ref (fd);
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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_stub (call_frame_t *frame, fop_fsyncdir_t fn,
+ fd_t *fd, int32_t datasync, 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", frame, out);
- stub = stub_new (frame, 1, GF_FOP_FSYNCDIR);
- 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.fsyncdir.fn = fn;
- if (fd)
- stub->args.fsyncdir.fd = fd_ref (fd);
- stub->args.fsyncdir.datasync = datasync;
+ stub->fn.fsyncdir = fn;
+ if (fd)
+ stub->args.fd = fd_ref (fd);
+ stub->args.datasync = datasync;
+ if (xdata)
+ stub->args.xdata = dict_ref (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_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;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- stub = stub_new (frame, 0, 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_cbk.fn = fn;
- stub->args.fsyncdir_cbk.op_ret = op_ret;
- stub->args.fsyncdir_cbk.op_errno = op_errno;
+ stub->fn_cbk.fsyncdir = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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_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);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
- stub = stub_new (frame, 1, GF_FOP_STATFS);
- 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.statfs.fn = fn;
- loc_copy (&stub->args.statfs.loc, loc);
+ stub->fn.statfs = fn;
+ loc_copy (&stub->args.loc, loc);
+ if (xdata)
+ stub->args.xdata = dict_ref (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_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;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- stub = stub_new (frame, 0, 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_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_cbk.statfs = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ if (op_ret == 0)
+ stub->args_cbk.statvfs = *buf;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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_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);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
- stub = stub_new (frame, 1, 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.setxattr = fn;
+ loc_copy (&stub->args.loc, loc);
+ /* TODO */
+ if (dict)
+ stub->args.xattr = dict_ref (dict);
+ stub->args.flags = flags;
+ if (xdata)
+ stub->args.xdata = dict_ref (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_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", frame, out);
- stub = stub_new (frame, 0, GF_FOP_SETXATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new (frame, 0, GF_FOP_SETXATTR);
+ 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_cbk.setxattr = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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_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);
+ 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);
+ stub = stub_new (frame, 1, GF_FOP_GETXATTR);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.getxattr.fn = fn;
- loc_copy (&stub->args.getxattr.loc, loc);
+ stub->fn.getxattr = fn;
+ loc_copy (&stub->args.loc, loc);
- if (name)
- stub->args.getxattr.name = gf_strdup (name);
+ if (name)
+ stub->args.name = gf_strdup (name);
+ if (xdata)
+ stub->args.xdata = dict_ref (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_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;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- stub = stub_new (frame, 0, GF_FOP_GETXATTR);
- 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.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_cbk.getxattr = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ /* TODO */
+ if (dict)
+ stub->args_cbk.xattr = dict_ref (dict);
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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_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);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", fd, out);
- stub = stub_new (frame, 1, GF_FOP_FSETXATTR);
- 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.fsetxattr.fn = fn;
- stub->args.fsetxattr.fd = fd_ref (fd);
+ stub->fn.fsetxattr = fn;
+ stub->args.fd = fd_ref (fd);
- /* TODO */
- if (dict)
- stub->args.fsetxattr.dict = dict_ref (dict);
- stub->args.fsetxattr.flags = flags;
+ if (dict)
+ stub->args.xattr = dict_ref (dict);
+ stub->args.flags = flags;
+ if (xdata)
+ stub->args.xdata = dict_ref (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_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;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- stub = stub_new (frame, 0, 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_cbk.fn = fn;
- stub->args.fsetxattr_cbk.op_ret = op_ret;
- stub->args.fsetxattr_cbk.op_errno = op_errno;
+ stub->fn_cbk.fsetxattr = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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_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);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", fd, out);
- stub = stub_new (frame, 1, GF_FOP_FGETXATTR);
- 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.fgetxattr.fn = fn;
- stub->args.fgetxattr.fd = fd_ref (fd);
+ stub->fn.fgetxattr = fn;
+ stub->args.fd = fd_ref (fd);
- if (name)
- stub->args.fgetxattr.name = gf_strdup (name);
+ if (name)
+ stub->args.name = gf_strdup (name);
+ if (xdata)
+ stub->args.xdata = dict_ref (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_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;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- stub = stub_new (frame, 0, GF_FOP_GETXATTR);
- 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_cbk.fn = fn;
- stub->args.fgetxattr_cbk.op_ret = op_ret;
- stub->args.fgetxattr_cbk.op_errno = op_errno;
+ stub->fn_cbk.fgetxattr = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
- /* TODO */
- if (dict)
- stub->args.fgetxattr_cbk.dict = dict_ref (dict);
+ if (dict)
+ stub->args_cbk.xattr = dict_ref (dict);
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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_stub (call_frame_t *frame, fop_removexattr_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);
- GF_VALIDATE_OR_GOTO ("call-stub", name, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", name, out);
- stub = stub_new (frame, 1, GF_FOP_REMOVEXATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new (frame, 1, 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.removexattr = fn;
+ loc_copy (&stub->args.loc, loc);
+ stub->args.name = gf_strdup (name);
+ if (xdata)
+ stub->args.xdata = dict_ref (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_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;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- stub = stub_new (frame, 0, 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_cbk.fn = fn;
- stub->args.removexattr_cbk.op_ret = op_ret;
- stub->args.removexattr_cbk.op_errno = op_errno;
+ stub->fn_cbk.removexattr = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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_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);
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", lock, out);
-
- stub = stub_new (frame, 1, GF_FOP_LK);
- 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.lk.fn = fn;
- if (fd)
- stub->args.lk.fd = fd_ref (fd);
- stub->args.lk.cmd = cmd;
- stub->args.lk.lock = *lock;
+ stub->fn.fremovexattr = fn;
+ stub->args.fd = fd_ref (fd);
+ stub->args.name = gf_strdup (name);
+ if (xdata)
+ stub->args.xdata = dict_ref (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_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;
+
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+
+ stub = stub_new (frame, 0, GF_FOP_FREMOVEXATTR);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+
+ stub->fn_cbk.fremovexattr = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (xdata);
+out:
+ 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, 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", 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;
+ if (fd)
+ stub->args.fd = fd_ref (fd);
+ stub->args.cmd = cmd;
+ stub->args.lock = *lock;
+ if (xdata)
+ stub->args.xdata = dict_ref (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;
+ call_stub_t *stub = NULL;
- if (!frame || !lock)
- return NULL;
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- stub = stub_new (frame, 1, GF_FOP_INODELK);
- if (!stub)
- return NULL;
+ stub = stub_new (frame, 0, GF_FOP_LK);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.inodelk.fn = fn;
+ stub->fn_cbk.lk = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ if (op_ret == 0)
+ stub->args_cbk.lock = *lock;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (xdata);
+out:
+ return stub;
+}
- 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;
+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, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- return stub;
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", lock, out);
+
+ stub = stub_new (frame, 1, GF_FOP_INODELK);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+
+ stub->fn.inodelk = fn;
+
+ if (volume)
+ stub->args.volume = gf_strdup (volume);
+
+ loc_copy (&stub->args.loc, loc);
+ stub->args.cmd = cmd;
+ stub->args.lock = *lock;
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
+out:
+ 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)
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- if (!frame)
- return NULL;
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- stub = stub_new (frame, 0, GF_FOP_INODELK);
- if (!stub)
- return NULL;
+ 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->fn_cbk.inodelk = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
- return stub;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (xdata);
+out:
+ 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)
+ const char *volume, fd_t *fd, int32_t cmd,
+ struct gf_flock *lock, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- if (!frame || !lock)
- return NULL;
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", lock, out);
- stub = stub_new (frame, 1, GF_FOP_FINODELK);
- if (!stub)
- return NULL;
+ stub = stub_new (frame, 1, GF_FOP_FINODELK);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.finodelk.fn = fn;
+ stub->fn.finodelk = fn;
- if (fd)
- stub->args.finodelk.fd = fd_ref (fd);
+ if (fd)
+ stub->args.fd = fd_ref (fd);
- if (volume)
- stub->args.finodelk.volume = gf_strdup (volume);
+ if (volume)
+ stub->args.volume = gf_strdup (volume);
- stub->args.finodelk.cmd = cmd;
- stub->args.finodelk.lock = *lock;
+ stub->args.cmd = cmd;
+ stub->args.lock = *lock;
- return stub;
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
+out:
+ 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)
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- if (!frame)
- return NULL;
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- stub = stub_new (frame, 0, GF_FOP_FINODELK);
- if (!stub)
- return NULL;
+ stub = stub_new (frame, 0, GF_FOP_FINODELK);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.finodelk_cbk.fn = fn;
- stub->args.finodelk_cbk.op_ret = op_ret;
- stub->args.finodelk_cbk.op_errno = op_errno;
+ stub->fn_cbk.finodelk = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
- return stub;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (xdata);
+out:
+ 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)
+ const char *volume, loc_t *loc, const char *name,
+ entrylk_cmd cmd, entrylk_type type, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
+
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- if (!frame)
- return 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);
- if (!stub)
- return NULL;
+ stub->fn.entrylk = fn;
- stub->args.entrylk.fn = fn;
+ if (volume)
+ stub->args.volume = gf_strdup (volume);
- if (volume)
- stub->args.entrylk.volume = gf_strdup (volume);
+ loc_copy (&stub->args.loc, loc);
- loc_copy (&stub->args.entrylk.loc, loc);
+ stub->args.entrylkcmd = cmd;
+ stub->args.entrylktype = type;
- stub->args.entrylk.cmd = cmd;
- stub->args.entrylk.type = type;
- if (name)
- stub->args.entrylk.name = gf_strdup (name);
+ if (name)
+ stub->args.name = gf_strdup (name);
- return stub;
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
+out:
+ 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)
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- if (!frame)
- return NULL;
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- stub = stub_new (frame, 0, GF_FOP_ENTRYLK);
- if (!stub)
- return 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->fn_cbk.entrylk = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
- return stub;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (xdata);
+out:
+ 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)
+ const char *volume, fd_t *fd, const char *name,
+ entrylk_cmd cmd, entrylk_type type, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- if (!frame)
- return NULL;
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- stub = stub_new (frame, 1, GF_FOP_FENTRYLK);
- if (!stub)
- return NULL;
+ stub = stub_new (frame, 1, GF_FOP_FENTRYLK);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.fentrylk.fn = fn;
+ stub->fn.fentrylk = fn;
- if (volume)
- stub->args.fentrylk.volume = gf_strdup (volume);
+ if (volume)
+ stub->args.volume = gf_strdup (volume);
- 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);
+ if (fd)
+ stub->args.fd = fd_ref (fd);
+ stub->args.entrylkcmd = cmd;
+ stub->args.entrylktype = type;
+ if (name)
+ stub->args.name = gf_strdup (name);
- return stub;
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
+out:
+ 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)
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- if (!frame)
- return NULL;
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- stub = stub_new (frame, 0, GF_FOP_FENTRYLK);
- if (!stub)
- return NULL;
+ 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->fn_cbk.fentrylk = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
- return stub;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (xdata);
+out:
+ 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_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;
- gf_dirent_t *stub_entry = NULL, *entry = NULL;
+ call_stub_t *stub = NULL;
+ gf_dirent_t *stub_entry = NULL, *entry = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- stub = stub_new (frame, 0, GF_FOP_READDIRP);
- 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->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);
+ stub->fn_cbk.readdirp = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
- /* This check must come after the init of head above
- * so we're sure the list is empty for list_empty.
- */
- if (!entries)
- goto out;
+ GF_VALIDATE_OR_GOTO ("call-stub", entries, out);
- if (op_ret > 0) {
- list_for_each_entry (entry, &entries->list, list) {
- stub_entry = gf_dirent_for_name (entry->d_name);
+ 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_entry->d_off = entry->d_off;
+ stub_entry->d_ino = entry->d_ino;
+ stub_entry->d_stat = entry->d_stat;
+ if (entry->inode)
+ stub_entry->inode = inode_ref (entry->inode);
+ list_add_tail (&stub_entry->list,
+ &stub->args_cbk.entries.list);
+ }
+ }
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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_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;
- gf_dirent_t *stub_entry = NULL, *entry = NULL;
+ call_stub_t *stub = NULL;
+ gf_dirent_t *stub_entry = NULL, *entry = NULL;
+
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new (frame, 0, GF_FOP_READDIR);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub = stub_new (frame, 0, GF_FOP_READDIR);
- 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_cbk.readdir = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
- /* This check must come after the init of head above
- * so we're sure the list is empty for list_empty.
- */
- if (!entries)
- goto out;
+ GF_VALIDATE_OR_GOTO ("call-stub", entries, out);
- if (op_ret > 0) {
- list_for_each_entry (entry, &entries->list, list) {
- stub_entry = gf_dirent_for_name (entry->d_name);
+ 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_off = entry->d_off;
+ stub_entry->d_ino = entry->d_ino;
- list_add_tail (&stub_entry->list,
- &stub->args.readdir_cbk.entries.list);
- }
- }
+ list_add_tail (&stub_entry->list,
+ &stub->args_cbk.entries.list);
+ }
+ }
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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_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;
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 1, GF_FOP_READDIR);
- 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, 1, GF_FOP_READDIR);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- return stub;
+ stub->fn.readdir = fn;
+ stub->args.fd = fd_ref (fd);
+ stub->args.size = size;
+ stub->args.offset = off;
+
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
+out:
+ 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_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;
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 1, GF_FOP_READDIRP);
- 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, 1, GF_FOP_READDIRP);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- return stub;
+ stub->fn.readdirp = fn;
+ stub->args.fd = fd_ref (fd);
+ stub->args.size = size;
+ stub->args.offset = off;
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
+out:
+ 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_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;
+ 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", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", fd, out);
- stub = stub_new (frame, 1, GF_FOP_RCHECKSUM);
- 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.rchecksum.fn = fn;
- stub->args.rchecksum.fd = fd_ref (fd);
- stub->args.rchecksum.offset = offset;
- stub->args.rchecksum.len = len;
+ stub->fn.rchecksum = fn;
+ stub->args.fd = fd_ref (fd);
+ stub->args.offset = offset;
+ stub->args.size = len;
+ if (xdata)
+ stub->args.xdata = dict_ref (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_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;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- stub = stub_new (frame, 0, GF_FOP_RCHECKSUM);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new (frame, 0, GF_FOP_RCHECKSUM);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.rchecksum_cbk.fn = fn;
- stub->args.rchecksum_cbk.op_ret = op_ret;
- stub->args.rchecksum_cbk.op_errno = op_errno;
+ stub->fn_cbk.rchecksum = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
- if (op_ret >= 0)
- {
- stub->args.rchecksum_cbk.weak_checksum =
+ if (op_ret >= 0) {
+ stub->args_cbk.weak_checksum =
weak_checksum;
+ stub->args_cbk.strong_checksum =
+ memdup (strong_checksum, MD5_DIGEST_LENGTH);
+ }
- stub->args.rchecksum_cbk.strong_checksum =
- memdup (strong_checksum, MD5_DIGEST_LEN);
- }
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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_xattrop_cbk_stub (call_frame_t *frame, fop_xattrop_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);
-
- stub = stub_new (frame, 0, GF_FOP_XATTROP);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- stub->args.xattrop_cbk.fn = fn;
- stub->args.xattrop_cbk.op_ret = op_ret;
- stub->args.xattrop_cbk.op_errno = op_errno;
+ stub = stub_new (frame, 0, GF_FOP_XATTROP);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub->fn_cbk.xattrop = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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_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;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+
+ stub = stub_new (frame, 0, GF_FOP_FXATTROP);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub = stub_new (frame, 0, GF_FOP_FXATTROP);
- 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->fn_cbk.fxattrop = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ if (xattr)
+ stub->args_cbk.xattr = dict_ref (xattr);
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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_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", xattr, out);
- if (!frame || !xattr)
- return NULL;
+ stub = stub_new (frame, 1, GF_FOP_XATTROP);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_XATTROP);
- if (!stub)
- return NULL;
+ stub->fn.xattrop = fn;
- stub->args.xattrop.fn = fn;
-
- loc_copy (&stub->args.xattrop.loc, loc);
+ loc_copy (&stub->args.loc, loc);
- stub->args.xattrop.optype = optype;
- stub->args.xattrop.xattr = dict_ref (xattr);
+ stub->args.optype = optype;
+ stub->args.xattr = dict_ref (xattr);
- return stub;
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
+out:
+ 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_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;
+ call_stub_t *stub = NULL;
+
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", xattr, out);
- if (!frame || !xattr)
- return NULL;
+ stub = stub_new (frame, 1, GF_FOP_FXATTROP);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_FXATTROP);
- if (!stub)
- return NULL;
+ stub->fn.fxattrop = fn;
- stub->args.fxattrop.fn = fn;
-
- stub->args.fxattrop.fd = fd_ref (fd);
+ stub->args.fd = fd_ref (fd);
- stub->args.fxattrop.optype = optype;
- stub->args.fxattrop.xattr = dict_ref (xattr);
+ stub->args.optype = optype;
+ stub->args.xattr = dict_ref (xattr);
- return stub;
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
+out:
+ 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_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;
- if (frame == NULL)
- goto out;
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- stub = stub_new (frame, 0, GF_FOP_SETATTR);
- if (stub == NULL)
- goto out;
+ stub = stub_new (frame, 0, GF_FOP_SETATTR);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.setattr_cbk.fn = fn;
+ stub->fn_cbk.setattr = fn;
- stub->args.setattr_cbk.op_ret = op_ret;
- stub->args.setattr_cbk.op_errno = op_errno;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
if (statpre)
- stub->args.setattr_cbk.statpre = *statpre;
+ stub->args_cbk.prestat = *statpre;
if (statpost)
- stub->args.setattr_cbk.statpost = *statpost;
+ stub->args_cbk.poststat = *statpost;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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_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;
- if (frame == NULL)
- goto out;
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- stub = stub_new (frame, 0, GF_FOP_FSETATTR);
- if (stub == NULL)
- goto out;
+ stub = stub_new (frame, 0, GF_FOP_FSETATTR);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.fsetattr_cbk.fn = fn;
+ stub->fn_cbk.fsetattr = fn;
- stub->args.fsetattr_cbk.op_ret = op_ret;
- stub->args.fsetattr_cbk.op_errno = op_errno;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
if (statpre)
- stub->args.setattr_cbk.statpre = *statpre;
+ stub->args_cbk.prestat = *statpre;
if (statpost)
- stub->args.fsetattr_cbk.statpost = *statpost;
+ stub->args_cbk.poststat = *statpost;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (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_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;
- if (frame == NULL)
- goto out;
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", fn, out);
- if (fn == NULL)
- goto out;
+ stub = stub_new (frame, 1, GF_FOP_SETATTR);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_SETATTR);
- if (stub == NULL)
- goto out;
+ stub->fn.setattr = fn;
- stub->args.setattr.fn = fn;
-
- loc_copy (&stub->args.setattr.loc, loc);
+ loc_copy (&stub->args.loc, loc);
if (stbuf)
- stub->args.setattr.stbuf = *stbuf;
+ stub->args.stat = *stbuf;
- stub->args.setattr.valid = valid;
+ stub->args.valid = valid;
+ if (xdata)
+ stub->args.xdata = dict_ref (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_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;
- if (frame == NULL)
- goto out;
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", fn, out);
- if (fn == NULL)
- goto out;
+ stub = stub_new (frame, 1, GF_FOP_FSETATTR);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_FSETATTR);
- if (stub == NULL)
- goto out;
-
- stub->args.fsetattr.fn = fn;
+ stub->fn.fsetattr = fn;
if (fd)
- stub->args.fsetattr.fd = fd_ref (fd);
+ stub->args.fd = fd_ref (fd);
if (stbuf)
- stub->args.fsetattr.stbuf = *stbuf;
+ stub->args.stat = *stbuf;
- stub->args.fsetattr.valid = valid;
+ stub->args.valid = valid;
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
out:
- return stub;
+ return stub;
}
-static void
-call_resume_wind (call_stub_t *stub)
+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)
{
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- 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;
- }
-
- 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;
-
- 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;
-
- case GF_FOP_UNLINK:
- {
- stub->args.unlink.fn (stub->frame,
- stub->frame->this,
- &stub->args.unlink.loc);
- }
- break;
-
- case GF_FOP_RMDIR:
- {
- stub->args.rmdir.fn (stub->frame, stub->frame->this,
- &stub->args.rmdir.loc,
- stub->args.rmdir.flags);
- }
- break;
-
- 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;
-
- case GF_FOP_RENAME:
- {
- stub->args.rename.fn (stub->frame,
- stub->frame->this,
- &stub->args.rename.old,
- &stub->args.rename.new);
- }
- break;
-
- case GF_FOP_LINK:
- {
- stub->args.link.fn (stub->frame,
- stub->frame->this,
- &stub->args.link.oldloc,
- &stub->args.link.newloc);
- }
- break;
-
- case GF_FOP_TRUNCATE:
- {
- stub->args.truncate.fn (stub->frame,
- stub->frame->this,
- &stub->args.truncate.loc,
- stub->args.truncate.off);
- break;
- }
-
- 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;
- }
-
- 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;
- }
-
- 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;
- }
-
- case GF_FOP_FSYNC:
- {
- stub->args.fsync.fn (stub->frame,
- stub->frame->this,
- stub->args.fsync.fd,
- stub->args.fsync.datasync);
- break;
- }
-
- 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;
- }
-
- case GF_FOP_GETXATTR:
- {
- stub->args.getxattr.fn (stub->frame,
- stub->frame->this,
- &stub->args.getxattr.loc,
- stub->args.getxattr.name);
- break;
- }
-
- 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;
- }
-
- case GF_FOP_FGETXATTR:
- {
- stub->args.fgetxattr.fn (stub->frame,
- stub->frame->this,
- stub->args.fgetxattr.fd,
- stub->args.fgetxattr.name);
- break;
- }
-
- case GF_FOP_REMOVEXATTR:
- {
- stub->args.removexattr.fn (stub->frame,
- stub->frame->this,
- &stub->args.removexattr.loc,
- stub->args.removexattr.name);
- break;
- }
-
- case GF_FOP_OPENDIR:
- {
- stub->args.opendir.fn (stub->frame,
- stub->frame->this,
- &stub->args.opendir.loc,
- stub->args.opendir.fd);
- break;
- }
-
- case GF_FOP_FSYNCDIR:
- {
- stub->args.fsyncdir.fn (stub->frame,
- stub->frame->this,
- stub->args.fsyncdir.fd,
- stub->args.fsyncdir.datasync);
- break;
- }
-
- case GF_FOP_ACCESS:
- {
- stub->args.access.fn (stub->frame,
- stub->frame->this,
- &stub->args.access.loc,
- stub->args.access.mask);
- break;
- }
-
- case GF_FOP_FTRUNCATE:
- {
- stub->args.ftruncate.fn (stub->frame,
- stub->frame->this,
- stub->args.ftruncate.fd,
- stub->args.ftruncate.off);
- break;
- }
-
- case GF_FOP_FSTAT:
- {
- stub->args.fstat.fn (stub->frame,
- stub->frame->this,
- stub->args.fstat.fd);
- break;
- }
-
- 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;
- }
-
- 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;
- }
-
- 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;
- }
-
- 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;
- }
-
- 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;
-
- case GF_FOP_LOOKUP:
- {
- stub->args.lookup.fn (stub->frame,
- stub->frame->this,
- &stub->args.lookup.loc,
- stub->args.lookup.xattr_req);
- break;
- }
-
- 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;
- }
-
- 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;
- }
+ call_stub_t *stub = NULL;
- 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;
- }
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- 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);
+ stub = stub_new (frame, 0, GF_FOP_FALLOCATE);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- 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);
+ stub->fn_cbk.fallocate = fn;
- 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 ("call-stub", GF_LOG_ERROR, "Invalid value of FOP (%d)",
- stub->fop);
- break;
- }
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
- }
+ if (statpre)
+ stub->args_cbk.prestat = *statpre;
+ if (statpost)
+ stub->args_cbk.poststat = *statpost;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (xdata);
out:
- return;
+ return stub;
}
+call_stub_t *
+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;
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", fn, out);
-static void
-call_resume_unwind (call_stub_t *stub)
-{
- 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;
- }
-
- 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);
+ stub = stub_new (frame, 1, GF_FOP_FALLOCATE);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- break;
- }
-
- 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);
+ stub->fn.fallocate = fn;
- 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;
- }
-
- 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);
+ if (fd)
+ stub->args.fd = fd_ref (fd);
- break;
- }
-
- 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;
- }
-
- 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;
- }
-
- 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;
-
- case GF_FOP_RENAME:
- {
-#if 0
- 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);
-#endif
- break;
- }
-
- 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;
- }
-
- 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;
- }
-
- 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;
-
- 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;
- }
-
- 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;
-
- 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;
- }
-
- 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;
- }
-
- 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);
+ stub->args.flags = mode;
+ stub->args.offset = offset;
+ stub->args.size = len;
- break;
- }
-
- 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;
- }
-
- 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);
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
+out:
+ return stub;
- break;
- }
-
- 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;
- }
-
- 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;
- }
-
- 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;
- }
-
- 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;
- }
-
- 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);
+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;
- break;
- }
-
- 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;
- }
-
- 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;
- }
-
- 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;
- }
-
- 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;
- }
-
- 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;
- }
-
- 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;
- }
-
- 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;
- }
-
- 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);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- break;
- }
-
- 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);
- }
+ stub = stub_new (frame, 0, GF_FOP_DISCARD);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- break;
- }
-
- 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);
+ stub->fn_cbk.discard = fn;
- break;
- }
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
- 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);
+ if (statpre)
+ stub->args_cbk.prestat = *statpre;
+ if (statpost)
+ stub->args_cbk.poststat = *statpost;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (xdata);
+out:
+ return stub;
+}
- break;
- }
-
- 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);
+call_stub_t *
+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;
- 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);
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", fn, out);
- 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 ("call-stub", GF_LOG_ERROR, "Invalid value of FOP (%d)",
- stub->fop);
- break;
- }
- }
+ stub = stub_new (frame, 1, GF_FOP_DISCARD);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+
+ stub->fn.discard = fn;
+
+ if (fd)
+ stub->args.fd = fd_ref (fd);
+
+ stub->args.offset = offset;
+ stub->args.size = len;
+
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
out:
- return;
+ return stub;
+
}
+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;
-static void
-call_stub_destroy_wind (call_stub_t *stub)
-{
- 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;
- }
- 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;
- }
- case GF_FOP_STAT:
- {
- loc_wipe (&stub->args.stat.loc);
- break;
- }
- case GF_FOP_READLINK:
- {
- loc_wipe (&stub->args.readlink.loc);
- break;
- }
-
- case GF_FOP_MKNOD:
- {
- loc_wipe (&stub->args.mknod.loc);
- if (stub->args.mknod.params)
- dict_unref (stub->args.mknod.params);
- }
- break;
-
- case GF_FOP_MKDIR:
- {
- loc_wipe (&stub->args.mkdir.loc);
- if (stub->args.mkdir.params)
- dict_unref (stub->args.mkdir.params);
- }
- break;
-
- case GF_FOP_UNLINK:
- {
- loc_wipe (&stub->args.unlink.loc);
- }
- break;
-
- case GF_FOP_RMDIR:
- {
- loc_wipe (&stub->args.rmdir.loc);
- }
- 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;
-
- case GF_FOP_RENAME:
- {
- loc_wipe (&stub->args.rename.old);
- loc_wipe (&stub->args.rename.new);
- }
- break;
-
- case GF_FOP_LINK:
- {
- loc_wipe (&stub->args.link.oldloc);
- loc_wipe (&stub->args.link.newloc);
- }
- break;
-
- case GF_FOP_TRUNCATE:
- {
- loc_wipe (&stub->args.truncate.loc);
- break;
- }
-
- case GF_FOP_READ:
- {
- if (stub->args.readv.fd)
- fd_unref (stub->args.readv.fd);
- 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;
- }
-
- case GF_FOP_STATFS:
- {
- loc_wipe (&stub->args.statfs.loc);
- break;
- }
- case GF_FOP_FLUSH:
- {
- if (stub->args.flush.fd)
- fd_unref (stub->args.flush.fd);
- break;
- }
-
- case GF_FOP_FSYNC:
- {
- if (stub->args.fsync.fd)
- fd_unref (stub->args.fsync.fd);
- break;
- }
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- case GF_FOP_SETXATTR:
- {
- loc_wipe (&stub->args.setxattr.loc);
- if (stub->args.setxattr.dict)
- dict_unref (stub->args.setxattr.dict);
- 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 = stub_new (frame, 0, GF_FOP_ZEROFILL);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- case GF_FOP_FSETXATTR:
- {
- fd_unref (stub->args.fsetxattr.fd);
- if (stub->args.fsetxattr.dict)
- dict_unref (stub->args.fsetxattr.dict);
- break;
- }
+ stub->fn_cbk.zerofill = fn;
- case GF_FOP_FGETXATTR:
- {
- if (stub->args.fgetxattr.name)
- GF_FREE ((char *)stub->args.fgetxattr.name);
- fd_unref (stub->args.fgetxattr.fd);
- break;
- }
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
- case GF_FOP_REMOVEXATTR:
- {
- loc_wipe (&stub->args.removexattr.loc);
- GF_FREE ((char *)stub->args.removexattr.name);
- break;
- }
+ if (statpre)
+ stub->args_cbk.prestat = *statpre;
+ if (statpost)
+ stub->args_cbk.poststat = *statpost;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (xdata);
+out:
+ return stub;
+}
- case GF_FOP_OPENDIR:
- {
- loc_wipe (&stub->args.opendir.loc);
- if (stub->args.opendir.fd)
- fd_unref (stub->args.opendir.fd);
- break;
- }
+call_stub_t *
+fop_zerofill_stub(call_frame_t *frame, fop_zerofill_t fn, fd_t *fd,
+ off_t offset, size_t len, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- case GF_FOP_FSYNCDIR:
- {
- if (stub->args.fsyncdir.fd)
- fd_unref (stub->args.fsyncdir.fd);
- break;
- }
-
- case GF_FOP_ACCESS:
- {
- loc_wipe (&stub->args.access.loc);
- break;
- }
-
- case GF_FOP_FTRUNCATE:
- {
- if (stub->args.ftruncate.fd)
- fd_unref (stub->args.ftruncate.fd);
- break;
- }
-
- case GF_FOP_FSTAT:
- {
- if (stub->args.fstat.fd)
- fd_unref (stub->args.fstat.fd);
- break;
- }
-
- case GF_FOP_LK:
- {
- if (stub->args.lk.fd)
- fd_unref (stub->args.lk.fd);
- break;
- }
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", fn, out);
- case GF_FOP_INODELK:
- {
- if (stub->args.inodelk.volume)
- GF_FREE ((char *)stub->args.inodelk.volume);
+ stub = stub_new (frame, 1, GF_FOP_ZEROFILL);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- loc_wipe (&stub->args.inodelk.loc);
- 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;
- }
- 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;
- }
- case GF_FOP_FENTRYLK:
- {
- if (stub->args.fentrylk.volume)
- GF_FREE ((char *)stub->args.fentrylk.volume);
+ stub->fn.zerofill = fn;
- if (stub->args.fentrylk.name)
- GF_FREE ((char *)stub->args.fentrylk.name);
+ if (fd)
+ stub->args.fd = fd_ref (fd);
- if (stub->args.fentrylk.fd)
- fd_unref (stub->args.fentrylk.fd);
- 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->args.offset = offset;
+ stub->args.size = len;
- case GF_FOP_RCHECKSUM:
- {
- if (stub->args.rchecksum.fd)
- fd_unref (stub->args.rchecksum.fd);
- break;
- }
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
+out:
+ return stub;
- case GF_FOP_READDIR:
- {
- if (stub->args.readdir.fd)
- fd_unref (stub->args.readdir.fd);
- break;
- }
+}
- case GF_FOP_READDIRP:
- {
- if (stub->args.readdirp.fd)
- fd_unref (stub->args.readdirp.fd);
- break;
- }
- case GF_FOP_XATTROP:
- {
- loc_wipe (&stub->args.xattrop.loc);
- dict_unref (stub->args.xattrop.xattr);
- break;
- }
- case GF_FOP_FXATTROP:
- {
- if (stub->args.fxattrop.fd)
- fd_unref (stub->args.fxattrop.fd);
- dict_unref (stub->args.fxattrop.xattr);
- break;
- }
+static void
+call_resume_wind (call_stub_t *stub)
+{
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+
+ switch (stub->fop) {
+ case GF_FOP_OPEN:
+ 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:
+ 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:
+ stub->fn.stat (stub->frame, stub->frame->this,
+ &stub->args.loc, stub->args.xdata);
+ break;
+ case GF_FOP_READLINK:
+ stub->fn.readlink (stub->frame, stub->frame->this,
+ &stub->args.loc, stub->args.size,
+ stub->args.xdata);
+ break;
+ case GF_FOP_MKNOD:
+ 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:
+ 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:
+ stub->fn.unlink (stub->frame, stub->frame->this,
+ &stub->args.loc, stub->args.xflag,
+ stub->args.xdata);
+ break;
+ case GF_FOP_RMDIR:
+ stub->fn.rmdir (stub->frame, stub->frame->this,
+ &stub->args.loc, stub->args.flags,
+ stub->args.xdata);
+ break;
+ case GF_FOP_SYMLINK:
+ 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:
+ stub->fn.rename (stub->frame, stub->frame->this,
+ &stub->args.loc, &stub->args.loc2,
+ stub->args.xdata);
+ break;
+ case GF_FOP_LINK:
+ stub->fn.link (stub->frame, stub->frame->this,
+ &stub->args.loc, &stub->args.loc2,
+ stub->args.xdata);
+ break;
+ case GF_FOP_TRUNCATE:
+ stub->fn.truncate (stub->frame, stub->frame->this,
+ &stub->args.loc, stub->args.offset,
+ stub->args.xdata);
+ break;
+ case GF_FOP_READ:
+ 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:
+ 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:
+ stub->fn.statfs (stub->frame, stub->frame->this,
+ &stub->args.loc, stub->args.xdata);
+ break;
+ case GF_FOP_FLUSH:
+ stub->fn.flush (stub->frame, stub->frame->this,
+ stub->args.fd, stub->args.xdata);
+ break;
+ case GF_FOP_FSYNC:
+ stub->fn.fsync (stub->frame, stub->frame->this,
+ stub->args.fd, stub->args.datasync,
+ stub->args.xdata);
+ break;
+ case GF_FOP_SETXATTR:
+ 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:
+ stub->fn.getxattr (stub->frame, stub->frame->this,
+ &stub->args.loc, stub->args.name,
+ stub->args.xdata);
+ break;
+ case GF_FOP_FSETXATTR:
+ 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:
+ stub->fn.fgetxattr (stub->frame, stub->frame->this,
+ stub->args.fd, stub->args.name,
+ stub->args.xdata);
+ break;
+ case GF_FOP_REMOVEXATTR:
+ 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:
+ stub->fn.opendir (stub->frame, stub->frame->this,
+ &stub->args.loc, stub->args.fd,
+ stub->args.xdata);
+ break;
+ case GF_FOP_FSYNCDIR:
+ stub->fn.fsyncdir (stub->frame, stub->frame->this,
+ stub->args.fd, stub->args.datasync,
+ stub->args.xdata);
+ break;
+ case GF_FOP_ACCESS:
+ stub->fn.access (stub->frame, stub->frame->this,
+ &stub->args.loc, stub->args.mask,
+ stub->args.xdata);
+ break;
+
+ case GF_FOP_FTRUNCATE:
+ stub->fn.ftruncate (stub->frame, stub->frame->this,
+ stub->args.fd, stub->args.offset,
+ stub->args.xdata);
+ break;
+ case GF_FOP_FSTAT:
+ stub->fn.fstat (stub->frame, stub->frame->this,
+ stub->args.fd, stub->args.xdata);
+ break;
+ case GF_FOP_LK:
+ 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:
+ 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:
+ 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:
+ 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:
+ 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:
+ stub->fn.lookup (stub->frame, stub->frame->this,
+ &stub->args.loc, stub->args.xdata);
+ break;
+ case GF_FOP_RCHECKSUM:
+ 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:
+ 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:
+ 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:
+ 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:
+ 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);
+ 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);
+ 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;
+
default:
- {
- gf_log ("call-stub", GF_LOG_ERROR, "Invalid value of FOP (%d)",
- stub->fop);
+ gf_log_callingfn ("call-stub", GF_LOG_ERROR,
+ "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)
-{
- switch (stub->fop) {
- case GF_FOP_OPEN:
- {
- if (stub->args.open_cbk.fd)
- fd_unref (stub->args.open_cbk.fd);
- }
- 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;
-
- case GF_FOP_STAT:
- break;
+call_resume_unwind (call_stub_t *stub)
+{
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- case GF_FOP_READLINK:
- {
- if (stub->args.readlink_cbk.buf)
- GF_FREE ((char *)stub->args.readlink_cbk.buf);
- }
- break;
-
- case GF_FOP_MKNOD:
- {
- if (stub->args.mknod_cbk.inode)
- inode_unref (stub->args.mknod_cbk.inode);
- }
- break;
-
- case GF_FOP_MKDIR:
- {
- if (stub->args.mkdir_cbk.inode)
- inode_unref (stub->args.mkdir_cbk.inode);
- }
- break;
-
- case GF_FOP_UNLINK:
+ switch (stub->fop) {
+ case GF_FOP_OPEN:
+ STUB_UNWIND (stub, open, stub->args_cbk.fd,
+ stub->args_cbk.xdata);
+ break;
+ case GF_FOP_CREATE:
+ 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:
+ STUB_UNWIND (stub, stat, &stub->args_cbk.stat,
+ stub->args_cbk.xdata);
+ break;
+ case GF_FOP_READLINK:
+ STUB_UNWIND (stub, readlink, stub->args_cbk.buf,
+ &stub->args_cbk.stat, stub->args.xdata);
+ break;
+ case GF_FOP_MKNOD:
+ 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:
+ 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:
+ STUB_UNWIND (stub, unlink, &stub->args_cbk.preparent,
+ &stub->args_cbk.postparent, stub->args_cbk.xdata);
+ break;
+ case GF_FOP_RMDIR:
+ STUB_UNWIND (stub, rmdir, &stub->args_cbk.preparent,
+ &stub->args_cbk.postparent, stub->args_cbk.xdata);
+ break;
+ case GF_FOP_SYMLINK:
+ 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:
+ 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:
+ 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:
+ STUB_UNWIND (stub, truncate, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
+ case GF_FOP_READ:
+ 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:
+ STUB_UNWIND (stub, writev, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
+ case GF_FOP_STATFS:
+ STUB_UNWIND (stub, statfs, &stub->args_cbk.statvfs,
+ stub->args_cbk.xdata);
+ break;
+ case GF_FOP_FLUSH:
+ STUB_UNWIND (stub, flush, stub->args_cbk.xdata);
+ break;
+ case GF_FOP_FSYNC:
+ STUB_UNWIND (stub, fsync, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
+ case GF_FOP_SETXATTR:
+ STUB_UNWIND (stub, setxattr, stub->args_cbk.xdata);
+ break;
+ case GF_FOP_GETXATTR:
+ STUB_UNWIND (stub, getxattr, stub->args_cbk.xattr,
+ stub->args_cbk.xdata);
+ break;
+ case GF_FOP_FSETXATTR:
+ STUB_UNWIND (stub, fsetxattr, stub->args_cbk.xdata);
+ break;
+ case GF_FOP_FGETXATTR:
+ STUB_UNWIND (stub, fgetxattr, stub->args_cbk.xattr,
+ stub->args_cbk.xdata);
+ break;
+ case GF_FOP_REMOVEXATTR:
+ 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:
+ STUB_UNWIND (stub, opendir, stub->args_cbk.fd,
+ stub->args_cbk.xdata);
+ break;
+ case GF_FOP_FSYNCDIR:
+ STUB_UNWIND (stub, fsyncdir, stub->args_cbk.xdata);
+ break;
+ case GF_FOP_ACCESS:
+ STUB_UNWIND (stub, access, stub->args_cbk.xdata);
+ break;
+ case GF_FOP_FTRUNCATE:
+ STUB_UNWIND (stub, ftruncate, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
+ case GF_FOP_FSTAT:
+ STUB_UNWIND (stub, fstat, &stub->args_cbk.stat,
+ stub->args_cbk.xdata);
+ break;
+ case GF_FOP_LK:
+ STUB_UNWIND (stub, lk, &stub->args_cbk.lock,
+ stub->args_cbk.xdata);
break;
-
- case GF_FOP_RMDIR:
+ case GF_FOP_INODELK:
+ STUB_UNWIND (stub, inodelk, stub->args_cbk.xdata);
+ break;
+ case GF_FOP_FINODELK:
+ STUB_UNWIND (stub, finodelk, stub->args_cbk.xdata);
+ break;
+ case GF_FOP_ENTRYLK:
+ STUB_UNWIND (stub, entrylk, stub->args_cbk.xdata);
break;
-
- case GF_FOP_SYMLINK:
- {
- if (stub->args.symlink_cbk.inode)
- inode_unref (stub->args.symlink_cbk.inode);
- }
- break;
-
- case GF_FOP_RENAME:
+ case GF_FOP_FENTRYLK:
+ STUB_UNWIND (stub, fentrylk, stub->args_cbk.xdata);
+ break;
+ case GF_FOP_LOOKUP:
+ 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:
+ STUB_UNWIND (stub, rchecksum, stub->args_cbk.weak_checksum,
+ stub->args_cbk.strong_checksum, stub->args_cbk.xdata);
break;
-
- case GF_FOP_LINK:
- {
- if (stub->args.link_cbk.inode)
- inode_unref (stub->args.link_cbk.inode);
- }
- break;
-
- case GF_FOP_TRUNCATE:
+ case GF_FOP_READDIR:
+ STUB_UNWIND (stub, readdir, &stub->args_cbk.entries,
+ 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;
-
- case GF_FOP_WRITE:
+ case GF_FOP_READDIRP:
+ STUB_UNWIND (stub, readdir, &stub->args_cbk.entries,
+ stub->args_cbk.xdata);
+ break;
+ case GF_FOP_XATTROP:
+ STUB_UNWIND (stub, xattrop, stub->args_cbk.xattr,
+ stub->args_cbk.xdata);
break;
-
- case GF_FOP_STATFS:
+ case GF_FOP_FXATTROP:
+ STUB_UNWIND (stub, fxattrop, stub->args_cbk.xattr,
+ stub->args_cbk.xdata);
break;
-
- case GF_FOP_FLUSH:
+ case GF_FOP_SETATTR:
+ STUB_UNWIND (stub, setattr, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
+ case GF_FOP_FSETATTR:
+ 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_FSYNC:
+ 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_SETXATTR:
- break;
-
- case GF_FOP_GETXATTR:
- {
- if (stub->args.getxattr_cbk.dict)
- dict_unref (stub->args.getxattr_cbk.dict);
- }
- break;
-
- case GF_FOP_FSETXATTR:
- break;
+ default:
+ gf_log_callingfn ("call-stub", GF_LOG_ERROR,
+ "Invalid value of FOP (%d)",
+ stub->fop);
+ break;
+ }
+out:
+ return;
+}
- case GF_FOP_FGETXATTR:
- {
- if (stub->args.fgetxattr_cbk.dict)
- dict_unref (stub->args.fgetxattr_cbk.dict);
- }
- break;
- case GF_FOP_REMOVEXATTR:
- break;
+static void
+call_stub_wipe_args (call_stub_t *stub)
+{
+ loc_wipe (&stub->args.loc);
- case GF_FOP_OPENDIR:
- {
- if (stub->args.opendir_cbk.fd)
- fd_unref (stub->args.opendir_cbk.fd);
- }
- break;
+ loc_wipe (&stub->args.loc2);
- case GF_FOP_FSYNCDIR:
- break;
-
- case GF_FOP_ACCESS:
- break;
-
- case GF_FOP_FTRUNCATE:
- break;
-
- case GF_FOP_FSTAT:
- break;
-
- case GF_FOP_LK:
- break;
+ if (stub->args.fd)
+ fd_unref (stub->args.fd);
- case GF_FOP_INODELK:
- break;
+ GF_FREE ((char *)stub->args.linkname);
- case GF_FOP_FINODELK:
- break;
+ GF_FREE (stub->args.vector);
- case GF_FOP_ENTRYLK:
- break;
+ if (stub->args.iobref)
+ iobref_unref (stub->args.iobref);
- case GF_FOP_FENTRYLK:
- break;
+ if (stub->args.xattr)
+ dict_unref (stub->args.xattr);
- 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;
-
- case GF_FOP_RCHECKSUM:
- {
- if (stub->args.rchecksum_cbk.op_ret >= 0) {
- GF_FREE (stub->args.rchecksum_cbk.strong_checksum);
- }
- }
- break;
-
- case GF_FOP_READDIR:
- {
- if (stub->args.readdir_cbk.op_ret > 0) {
- gf_dirent_free (&stub->args.readdir_cbk.entries);
- }
- }
- break;
+ GF_FREE ((char *)stub->args.name);
- case GF_FOP_READDIRP:
- {
- if (stub->args.readdirp_cbk.op_ret > 0) {
- gf_dirent_free (&stub->args.readdirp_cbk.entries);
- }
- }
- break;
-
- case GF_FOP_XATTROP:
- {
- if (stub->args.xattrop_cbk.xattr)
- dict_unref (stub->args.xattrop_cbk.xattr);
- }
- break;
-
- case GF_FOP_FXATTROP:
- {
- if (stub->args.fxattrop_cbk.xattr)
- dict_unref (stub->args.fxattrop_cbk.xattr);
- }
- break;
-
- case GF_FOP_SETATTR:
- {
- break;
- }
+ GF_FREE ((char *)stub->args.volume);
- case GF_FOP_FSETATTR:
- {
- break;
- }
+ if (stub->args.xdata)
+ dict_unref (stub->args.xdata);
+}
- default:
- {
- gf_log ("call-stub", GF_LOG_ERROR, "Invalid value of FOP (%d)",
- stub->fop);
- break;
- }
- }
+
+static void
+call_stub_wipe_args_cbk (call_stub_t *stub)
+{
+ if (stub->args_cbk.inode)
+ inode_unref (stub->args_cbk.inode);
+
+ GF_FREE ((char *)stub->args_cbk.buf);
+
+ GF_FREE (stub->args_cbk.vector);
+
+ if (stub->args_cbk.iobref)
+ iobref_unref (stub->args_cbk.iobref);
+
+ if (stub->args_cbk.fd)
+ fd_unref (stub->args_cbk.fd);
+
+ if (stub->args_cbk.xattr)
+ dict_unref (stub->args_cbk.xattr);
+
+ GF_FREE (stub->args_cbk.strong_checksum);
+
+ if (stub->args_cbk.xdata)
+ dict_unref (stub->args_cbk.xdata);
+
+ if (!list_empty (&stub->args_cbk.entries.list))
+ gf_dirent_free (&stub->args_cbk.entries);
}
-
+
void
call_stub_destroy (call_stub_t *stub)
{
- struct mem_pool *tmp_pool = NULL;
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ if (stub->wind)
+ call_stub_wipe_args (stub);
+ else
+ call_stub_wipe_args_cbk (stub);
- tmp_pool = stub->stub_mem_pool;
-
- if (stub->wind) {
- call_stub_destroy_wind (stub);
- } else {
- call_stub_destroy_unwind (stub);
- }
+ stub->stub_mem_pool = NULL;
- stub->stub_mem_pool = NULL;
- mem_put (tmp_pool, stub);
+ mem_put (stub);
out:
- tmp_pool = NULL;
-
- return;
+ return;
}
+
void
call_resume (call_stub_t *stub)
{
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;
@@ -3873,9 +2844,30 @@ call_resume (call_stub_t *stub)
}
THIS = old_THIS;
- call_stub_destroy (stub);
+ call_stub_destroy (stub);
out:
- return;
+ 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;
+
+}
diff --git a/libglusterfs/src/call-stub.h b/libglusterfs/src/call-stub.h
index 0d34b3d2e..45bef8044 100644
--- a/libglusterfs/src/call-stub.h
+++ b/libglusterfs/src/call-stub.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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 _CALL_STUB_H_
@@ -34,561 +25,164 @@ typedef struct {
char wind;
call_frame_t *frame;
glusterfs_fop_t fop;
- struct mem_pool *stub_mem_pool; /* pointer to stub mempool in glusterfs ctx */
+ struct mem_pool *stub_mem_pool; /* pointer to stub mempool in ctx_t */
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;
+ fop_lookup_t lookup;
+ fop_stat_t stat;
+ fop_fstat_t fstat;
+ fop_truncate_t truncate;
+ fop_ftruncate_t ftruncate;
+ fop_access_t access;
+ fop_readlink_t readlink;
+ fop_mknod_t mknod;
+ fop_mkdir_t mkdir;
+ fop_unlink_t unlink;
+ fop_rmdir_t rmdir;
+ fop_symlink_t symlink;
+ fop_rename_t rename;
+ fop_link_t link;
+ fop_create_t create;
+ fop_open_t open;
+ fop_readv_t readv;
+ fop_writev_t writev;
+ fop_flush_t flush;
+ fop_fsync_t fsync;
+ fop_opendir_t opendir;
+ fop_fsyncdir_t fsyncdir;
+ fop_statfs_t statfs;
+ fop_setxattr_t setxattr;
+ fop_getxattr_t getxattr;
+ fop_fgetxattr_t fgetxattr;
+ fop_fsetxattr_t fsetxattr;
+ fop_removexattr_t removexattr;
+ fop_fremovexattr_t fremovexattr;
+ fop_lk_t lk;
+ fop_inodelk_t inodelk;
+ fop_finodelk_t finodelk;
+ fop_entrylk_t entrylk;
+ fop_fentrylk_t fentrylk;
+ fop_readdir_t readdir;
+ fop_readdirp_t readdirp;
+ fop_rchecksum_t rchecksum;
+ fop_xattrop_t xattrop;
+ fop_fxattrop_t fxattrop;
+ fop_setattr_t setattr;
+ fop_fsetattr_t fsetattr;
+ fop_fallocate_t fallocate;
+ fop_discard_t discard;
+ fop_zerofill_t zerofill;
+ } fn;
+ union {
+ fop_lookup_cbk_t lookup;
+ fop_stat_cbk_t stat;
+ fop_fstat_cbk_t fstat;
+ fop_truncate_cbk_t truncate;
+ fop_ftruncate_cbk_t ftruncate;
+ fop_access_cbk_t access;
+ fop_readlink_cbk_t readlink;
+ fop_mknod_cbk_t mknod;
+ fop_mkdir_cbk_t mkdir;
+ fop_unlink_cbk_t unlink;
+ fop_rmdir_cbk_t rmdir;
+ fop_symlink_cbk_t symlink;
+ fop_rename_cbk_t rename;
+ fop_link_cbk_t link;
+ fop_create_cbk_t create;
+ fop_open_cbk_t open;
+ fop_readv_cbk_t readv;
+ fop_writev_cbk_t writev;
+ fop_flush_cbk_t flush;
+ fop_fsync_cbk_t fsync;
+ fop_opendir_cbk_t opendir;
+ fop_fsyncdir_cbk_t fsyncdir;
+ fop_statfs_cbk_t statfs;
+ fop_setxattr_cbk_t setxattr;
+ fop_getxattr_cbk_t getxattr;
+ fop_fgetxattr_cbk_t fgetxattr;
+ fop_fsetxattr_cbk_t fsetxattr;
+ fop_removexattr_cbk_t removexattr;
+ fop_fremovexattr_cbk_t fremovexattr;
+ fop_lk_cbk_t lk;
+ fop_inodelk_cbk_t inodelk;
+ fop_finodelk_cbk_t finodelk;
+ fop_entrylk_cbk_t entrylk;
+ fop_fentrylk_cbk_t fentrylk;
+ fop_readdir_cbk_t readdir;
+ fop_readdirp_cbk_t readdirp;
+ fop_rchecksum_cbk_t rchecksum;
+ fop_xattrop_cbk_t xattrop;
+ fop_fxattrop_cbk_t fxattrop;
+ fop_setattr_cbk_t setattr;
+ fop_fsetattr_cbk_t fsetattr;
+ fop_fallocate_cbk_t fallocate;
+ fop_discard_cbk_t discard;
+ fop_zerofill_cbk_t zerofill;
+ } fn_cbk;
+
+ struct {
+ loc_t loc; // @old in rename(), link()
+ loc_t loc2; // @new in rename(), link()
+ fd_t *fd;
+ off_t offset;
+ int mask;
+ size_t size;
+ mode_t mode;
+ dev_t rdev;
+ mode_t umask;
+ int xflag;
+ int flags;
+ const char *linkname;
+ struct iovec *vector;
+ int count;
+ struct iobref *iobref;
+ int datasync;
+ dict_t *xattr;
+ const char *name;
+ int cmd;
+ struct gf_flock lock;
+ const char *volume;
+ entrylk_cmd entrylkcmd;
+ entrylk_type entrylktype;
+ gf_xattrop_flags_t optype;
+ int valid;
+ struct iatt stat;
+ dict_t *xdata;
} args;
+
+ struct {
+ int op_ret;
+ int op_errno;
+ inode_t *inode;
+ struct iatt stat;
+ struct iatt prestat;
+ struct iatt poststat;
+ struct iatt preparent; // @preoldparent in rename_cbk
+ struct iatt postparent; // @postoldparent in rename_cbk
+ struct iatt preparent2; // @prenewparent in rename_cbk
+ struct iatt postparent2; // @postnewparent in rename_cbk
+ const char *buf;
+ struct iovec *vector;
+ int count;
+ struct iobref *iobref;
+ fd_t *fd;
+ struct statvfs statvfs;
+ dict_t *xattr;
+ struct gf_flock lock;
+ gf_dirent_t entries;
+ uint32_t weak_checksum;
+ uint8_t *strong_checksum;
+ dict_t *xdata;
+ } args_cbk;
} call_stub_t;
+
call_stub_t *
fop_lookup_stub (call_frame_t *frame,
fop_lookup_t fn,
loc_t *loc,
- dict_t *xattr_req);
+ dict_t *xdata);
call_stub_t *
fop_lookup_cbk_stub (call_frame_t *frame,
@@ -597,34 +191,34 @@ fop_lookup_cbk_stub (call_frame_t *frame,
int32_t op_errno,
inode_t *inode,
struct iatt *buf,
- dict_t *dict,
+ dict_t *xdata,
struct iatt *postparent);
call_stub_t *
fop_stat_stub (call_frame_t *frame,
fop_stat_t fn,
- loc_t *loc);
+ loc_t *loc, dict_t *xdata);
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);
+ struct iatt *buf, dict_t *xdata);
call_stub_t *
fop_fstat_stub (call_frame_t *frame,
fop_fstat_t fn,
- fd_t *fd);
+ fd_t *fd, dict_t *xdata);
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);
+ struct iatt *buf, dict_t *xdata);
call_stub_t *
fop_truncate_stub (call_frame_t *frame,
fop_truncate_t fn,
loc_t *loc,
- off_t off);
+ off_t off, dict_t *xdata);
call_stub_t *
fop_truncate_cbk_stub (call_frame_t *frame,
@@ -632,13 +226,13 @@ fop_truncate_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *prebuf,
- struct iatt *postbuf);
+ struct iatt *postbuf, dict_t *xdata);
call_stub_t *
fop_ftruncate_stub (call_frame_t *frame,
fop_ftruncate_t fn,
fd_t *fd,
- off_t off);
+ off_t off, dict_t *xdata);
call_stub_t *
fop_ftruncate_cbk_stub (call_frame_t *frame,
@@ -646,25 +240,25 @@ fop_ftruncate_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *prebuf,
- struct iatt *postbuf);
+ struct iatt *postbuf, dict_t *xdata);
call_stub_t *
fop_access_stub (call_frame_t *frame,
fop_access_t fn,
loc_t *loc,
- int32_t mask);
+ int32_t mask, dict_t *xdata);
call_stub_t *
fop_access_cbk_stub (call_frame_t *frame,
fop_access_cbk_t fn,
int32_t op_ret,
- int32_t op_errno);
+ int32_t op_errno, dict_t *xdata);
call_stub_t *
fop_readlink_stub (call_frame_t *frame,
fop_readlink_t fn,
loc_t *loc,
- size_t size);
+ size_t size, dict_t *xdata);
call_stub_t *
fop_readlink_cbk_stub (call_frame_t *frame,
@@ -672,11 +266,11 @@ fop_readlink_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
const char *path,
- struct iatt *buf);
+ struct iatt *buf, dict_t *xdata);
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 *
fop_mknod_cbk_stub (call_frame_t *frame,
@@ -686,11 +280,11 @@ fop_mknod_cbk_stub (call_frame_t *frame,
inode_t *inode,
struct iatt *buf,
struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
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 *
fop_mkdir_cbk_stub (call_frame_t *frame,
@@ -700,12 +294,11 @@ fop_mkdir_cbk_stub (call_frame_t *frame,
inode_t *inode,
struct iatt *buf,
struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
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 *
fop_unlink_cbk_stub (call_frame_t *frame,
@@ -713,11 +306,11 @@ fop_unlink_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
call_stub_t *
fop_rmdir_stub (call_frame_t *frame, fop_rmdir_t fn,
- loc_t *loc, int flags);
+ loc_t *loc, int flags, dict_t *xdata);
call_stub_t *
fop_rmdir_cbk_stub (call_frame_t *frame,
@@ -725,11 +318,11 @@ fop_rmdir_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
call_stub_t *
fop_symlink_stub (call_frame_t *frame, fop_symlink_t fn,
- const char *linkname, loc_t *loc, dict_t *params);
+ const char *linkname, loc_t *loc, mode_t umask, dict_t *xdata);
call_stub_t *
fop_symlink_cbk_stub (call_frame_t *frame,
@@ -739,13 +332,13 @@ fop_symlink_cbk_stub (call_frame_t *frame,
inode_t *inode,
struct iatt *buf,
struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
call_stub_t *
fop_rename_stub (call_frame_t *frame,
fop_rename_t fn,
loc_t *oldloc,
- loc_t *newloc);
+ loc_t *newloc, dict_t *xdata);
call_stub_t *
fop_rename_cbk_stub (call_frame_t *frame,
@@ -756,13 +349,13 @@ fop_rename_cbk_stub (call_frame_t *frame,
struct iatt *preoldparent,
struct iatt *postoldparent,
struct iatt *prenewparent,
- struct iatt *postnewparent);
+ struct iatt *postnewparent, dict_t *xdata);
call_stub_t *
fop_link_stub (call_frame_t *frame,
fop_link_t fn,
loc_t *oldloc,
- loc_t *newloc);
+ loc_t *newloc, dict_t *xdata);
call_stub_t *
fop_link_cbk_stub (call_frame_t *frame,
@@ -772,12 +365,12 @@ fop_link_cbk_stub (call_frame_t *frame,
inode_t *inode,
struct iatt *buf,
struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
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);
+ mode_t umask, fd_t *fd, dict_t *xdata);
call_stub_t *
fop_create_cbk_stub (call_frame_t *frame,
@@ -788,7 +381,7 @@ fop_create_cbk_stub (call_frame_t *frame,
inode_t *inode,
struct iatt *buf,
struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
call_stub_t *
fop_open_stub (call_frame_t *frame,
@@ -796,21 +389,21 @@ fop_open_stub (call_frame_t *frame,
loc_t *loc,
int32_t flags,
fd_t *fd,
- int32_t wbflags);
+ dict_t *xdata);
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);
+ fd_t *fd, dict_t *xdata);
call_stub_t *
fop_readv_stub (call_frame_t *frame,
fop_readv_t fn,
fd_t *fd,
size_t size,
- off_t off);
+ off_t off, uint32_t flags, dict_t *xdata);
call_stub_t *
fop_readv_cbk_stub (call_frame_t *frame,
@@ -820,7 +413,7 @@ fop_readv_cbk_stub (call_frame_t *frame,
struct iovec *vector,
int32_t count,
struct iatt *stbuf,
- struct iobref *iobref);
+ struct iobref *iobref, dict_t *xdata);
call_stub_t *
fop_writev_stub (call_frame_t *frame,
@@ -828,8 +421,8 @@ fop_writev_stub (call_frame_t *frame,
fd_t *fd,
struct iovec *vector,
int32_t count,
- off_t off,
- struct iobref *iobref);
+ off_t off, uint32_t flags,
+ struct iobref *iobref, dict_t *xdata);
call_stub_t *
fop_writev_cbk_stub (call_frame_t *frame,
@@ -837,24 +430,24 @@ fop_writev_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *prebuf,
- struct iatt *postbuf);
+ struct iatt *postbuf, dict_t *xdata);
call_stub_t *
fop_flush_stub (call_frame_t *frame,
fop_flush_t fn,
- fd_t *fd);
+ fd_t *fd, dict_t *xdata);
call_stub_t *
fop_flush_cbk_stub (call_frame_t *frame,
fop_flush_cbk_t fn,
int32_t op_ret,
- int32_t op_errno);
+ int32_t op_errno, dict_t *xdata);
call_stub_t *
fop_fsync_stub (call_frame_t *frame,
fop_fsync_t fn,
fd_t *fd,
- int32_t datasync);
+ int32_t datasync, dict_t *xdata);
call_stub_t *
fop_fsync_cbk_stub (call_frame_t *frame,
@@ -862,190 +455,205 @@ fop_fsync_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *prebuf,
- struct iatt *postbuf);
+ struct iatt *postbuf, dict_t *xdata);
call_stub_t *
fop_opendir_stub (call_frame_t *frame,
fop_opendir_t fn,
- loc_t *loc, fd_t *fd);
+ loc_t *loc, fd_t *fd, dict_t *xdata);
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);
+ fd_t *fd, dict_t *xdata);
call_stub_t *
fop_fsyncdir_stub (call_frame_t *frame,
fop_fsyncdir_t fn,
fd_t *fd,
- int32_t datasync);
+ int32_t datasync, dict_t *xdata);
call_stub_t *
fop_fsyncdir_cbk_stub (call_frame_t *frame,
fop_fsyncdir_cbk_t fn,
int32_t op_ret,
- int32_t op_errno);
+ int32_t op_errno, dict_t *xdata);
call_stub_t *
fop_statfs_stub (call_frame_t *frame,
fop_statfs_t fn,
- loc_t *loc);
+ loc_t *loc, dict_t *xdata);
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);
+ struct statvfs *buf, dict_t *xdata);
call_stub_t *
fop_setxattr_stub (call_frame_t *frame,
fop_setxattr_t fn,
loc_t *loc,
dict_t *dict,
- int32_t flags);
+ int32_t flags, dict_t *xdata);
call_stub_t *
fop_setxattr_cbk_stub (call_frame_t *frame,
fop_setxattr_cbk_t fn,
int32_t op_ret,
- int32_t op_errno);
+ int32_t op_errno, dict_t *xdata);
call_stub_t *
fop_getxattr_stub (call_frame_t *frame,
fop_getxattr_t fn,
loc_t *loc,
- const char *name);
+ const char *name, dict_t *xdata);
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);
+ dict_t *value, dict_t *xdata);
call_stub_t *
fop_fsetxattr_stub (call_frame_t *frame,
fop_fsetxattr_t fn,
fd_t *fd,
dict_t *dict,
- int32_t flags);
+ int32_t flags, dict_t *xdata);
call_stub_t *
fop_fsetxattr_cbk_stub (call_frame_t *frame,
fop_fsetxattr_cbk_t fn,
int32_t op_ret,
- int32_t op_errno);
+ int32_t op_errno, dict_t *xdata);
call_stub_t *
fop_fgetxattr_stub (call_frame_t *frame,
fop_fgetxattr_t fn,
fd_t *fd,
- const char *name);
+ const char *name, dict_t *xdata);
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);
+ dict_t *value, dict_t *xdata);
call_stub_t *
fop_removexattr_stub (call_frame_t *frame,
fop_removexattr_t fn,
loc_t *loc,
- const char *name);
+ const char *name, dict_t *xdata);
call_stub_t *
fop_removexattr_cbk_stub (call_frame_t *frame,
fop_removexattr_cbk_t fn,
int32_t op_ret,
- int32_t op_errno);
+ int32_t op_errno, dict_t *xdata);
+
+
+call_stub_t *
+fop_fremovexattr_stub (call_frame_t *frame,
+ fop_fremovexattr_t fn,
+ fd_t *fd,
+ const char *name, dict_t *xdata);
+
+call_stub_t *
+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 *
fop_lk_stub (call_frame_t *frame,
fop_lk_t fn,
fd_t *fd,
int32_t cmd,
- struct gf_flock *lock);
+ struct gf_flock *lock, dict_t *xdata);
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);
+ struct gf_flock *lock, dict_t *xdata);
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);
+ const char *volume, loc_t *loc, int32_t cmd,
+ struct gf_flock *lock, dict_t *xdata);
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);
+ const char *volume, fd_t *fd, int32_t cmd,
+ struct gf_flock *lock, dict_t *xdata);
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);
+ entrylk_cmd cmd, entrylk_type type, dict_t *xdata);
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);
+ entrylk_cmd cmd, entrylk_type type, dict_t *xdata);
call_stub_t *
fop_inodelk_cbk_stub (call_frame_t *frame, fop_inodelk_cbk_t fn,
- int32_t op_ret, int32_t op_errno);
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
call_stub_t *
fop_finodelk_cbk_stub (call_frame_t *frame, fop_inodelk_cbk_t fn,
- int32_t op_ret, int32_t op_errno);
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
call_stub_t *
fop_entrylk_cbk_stub (call_frame_t *frame, fop_entrylk_cbk_t fn,
- int32_t op_ret, int32_t op_errno);
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
call_stub_t *
fop_fentrylk_cbk_stub (call_frame_t *frame, fop_entrylk_cbk_t fn,
- int32_t op_ret, int32_t op_errno);
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
call_stub_t *
fop_readdir_stub (call_frame_t *frame,
fop_readdir_t fn,
fd_t *fd,
size_t size,
- off_t off);
+ off_t off, dict_t *xdata);
call_stub_t *
fop_readdirp_stub (call_frame_t *frame,
- fop_readdir_t fn,
+ fop_readdirp_t fn,
fd_t *fd,
size_t size,
- off_t off);
+ off_t off,
+ dict_t *xdata);
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);
+ gf_dirent_t *entries, dict_t *xdata);
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);
+ gf_dirent_t *entries, dict_t *xdata);
call_stub_t *
fop_rchecksum_stub (call_frame_t *frame,
fop_rchecksum_t fn,
fd_t *fd, off_t offset,
- int32_t len);
+ int32_t len, dict_t *xdata);
call_stub_t *
fop_rchecksum_cbk_stub (call_frame_t *frame,
@@ -1053,40 +661,40 @@ fop_rchecksum_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
uint32_t weak_checksum,
- uint8_t *strong_checksum);
+ uint8_t *strong_checksum, dict_t *xdata);
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);
+ dict_t *xattr, dict_t *xdata);
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);
+ int32_t op_errno, dict_t *xdata);
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);
+ dict_t *xattr, dict_t *xdata);
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);
+ int32_t op_errno, dict_t *xdata);
call_stub_t *
fop_setattr_stub (call_frame_t *frame,
fop_setattr_t fn,
loc_t *loc,
struct iatt *stbuf,
- int32_t valid);
+ int32_t valid, dict_t *xdata);
call_stub_t *
fop_setattr_cbk_stub (call_frame_t *frame,
@@ -1094,14 +702,14 @@ fop_setattr_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *statpre,
- struct iatt *statpost);
+ struct iatt *statpost, dict_t *xdata);
call_stub_t *
fop_fsetattr_stub (call_frame_t *frame,
fop_fsetattr_t fn,
fd_t *fd,
struct iatt *stbuf,
- int32_t valid);
+ int32_t valid, dict_t *xdata);
call_stub_t *
fop_fsetattr_cbk_stub (call_frame_t *frame,
@@ -1109,8 +717,51 @@ fop_fsetattr_cbk_stub (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *statpre,
- struct iatt *statpost);
+ struct iatt *statpost, dict_t *xdata);
+
+call_stub_t *
+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 *
+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 *
+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 *
+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 *
+fop_zerofill_stub(call_frame_t *frame,
+ fop_zerofill_t fn,
+ fd_t *fd,
+ off_t offset,
+ size_t len, dict_t *xdata);
+
+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);
void call_resume (call_stub_t *stub);
void call_stub_destroy (call_stub_t *stub);
+void call_unwind_error (call_stub_t *stub, int op_ret, int op_errno);
#endif
diff --git a/libglusterfs/src/checksum.c b/libglusterfs/src/checksum.c
index de86adc9a..e14a3044c 100644
--- a/libglusterfs/src/checksum.c
+++ b/libglusterfs/src/checksum.c
@@ -1,28 +1,17 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
+ 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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 <openssl/md5.h>
+#include <stdint.h>
#include "glusterfs.h"
-#include "md5.h"
-#include "checksum.h"
-
/*
* The "weak" checksum required for the rsync algorithm,
@@ -31,22 +20,26 @@
*
* "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;
+ int32_t i = 0;
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];
+ if (len >= 4) {
+ for (; 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++) {
@@ -66,13 +59,7 @@ gf_rsync_weak_checksum (char *buf1, int32_t len)
*/
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 *md5)
{
- md_context m;
-
- md5_begin (&m);
- md5_update (&m, (unsigned char *) buf, len);
- md5_result (&m, (unsigned char *) sum);
-
- return;
+ MD5(data, len, md5);
}
diff --git a/libglusterfs/src/checksum.h b/libglusterfs/src/checksum.h
index 592e99fcb..bf7eeede8 100644
--- a/libglusterfs/src/checksum.h
+++ b/libglusterfs/src/checksum.h
@@ -1,29 +1,20 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
+ 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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 __CHECKSUM_H__
#define __CHECKSUM_H__
uint32_t
-gf_rsync_weak_checksum (char *buf, int32_t len);
+gf_rsync_weak_checksum (unsigned char *buf, size_t len);
void
-gf_rsync_strong_checksum (char *buf, int32_t len, uint8_t *sum);
+gf_rsync_strong_checksum (unsigned char *buf, size_t len, unsigned char *sum);
#endif /* __CHECKSUM_H__ */
diff --git a/libglusterfs/src/circ-buff.c b/libglusterfs/src/circ-buff.c
new file mode 100644
index 000000000..484ce7dc9
--- /dev/null
+++ b/libglusterfs/src/circ-buff.c
@@ -0,0 +1,202 @@
+/*
+ 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 "circ-buff.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_log ("", GF_LOG_WARNING, "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_log_callingfn ("", GF_LOG_WARNING, "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_log ("", GF_LOG_DEBUG, "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_log_callingfn ("", GF_LOG_WARNING,
+ "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) {
+ gf_log ("", GF_LOG_ERROR, "could not allocate the "
+ "buffer");
+ goto out;
+ }
+
+ buffer->cb = GF_CALLOC (buffer_size,
+ sizeof (circular_buffer_t *),
+ gf_common_mt_circular_buffer_t);
+ if (!buffer->cb) {
+ gf_log ("", GF_LOG_ERROR, "could not allocate the "
+ "memory for the circular buffer");
+ 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/circ-buff.h b/libglusterfs/src/circ-buff.h
new file mode 100644
index 000000000..e3459f5e3
--- /dev/null
+++ b/libglusterfs/src/circ-buff.h
@@ -0,0 +1,64 @@
+/*
+ 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.
+*/
+
+#ifndef _CB_H
+#define _CB_H
+
+#include "common-utils.h"
+#include "logging.h"
+#include "mem-types.h"
+
+#define BUFFER_SIZE 10
+#define TOTAL_SIZE BUFFER_SIZE + 1
+
+
+struct _circular_buffer {
+ struct timeval tv;
+ void *data;
+};
+
+typedef struct _circular_buffer circular_buffer_t;
+
+struct _buffer {
+ unsigned int w_index;
+ size_t size_buffer;
+ gf_boolean_t use_once;
+ /* This variable is assigned the proper value at the time of initing */
+ /* the buffer. It indicates, whether the buffer should be used once */
+ /* it becomes full. */
+
+ int used_len;
+ /* indicates the amount of circular buffer used. */
+
+ circular_buffer_t **cb;
+ void (*destroy_buffer_data) (void *data);
+ pthread_mutex_t lock;
+};
+
+typedef struct _buffer buffer_t;
+
+int
+cb_add_entry_buffer (buffer_t *buffer, void *item);
+
+void
+cb_buffer_show (buffer_t *buffer);
+
+buffer_t *
+cb_buffer_new (size_t buffer_size,gf_boolean_t use_buffer_once,
+ void (*destroy_data) (void *data));
+
+void
+cb_buffer_destroy (buffer_t *buffer);
+
+void
+cb_buffer_dump (buffer_t *buffer, void *data,
+ int (fn) (circular_buffer_t *buffer, void *data));
+
+#endif /* _CB_H */
diff --git a/libglusterfs/src/client_t.c b/libglusterfs/src/client_t.c
new file mode 100644
index 000000000..06447dc5d
--- /dev/null
+++ b/libglusterfs/src/client_t.c
@@ -0,0 +1,890 @@
+/*
+ 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.h"
+#include "dict.h"
+#include "statedump.h"
+#include "client_t.h"
+#include "list.h"
+#include "rpcsvc.h"
+
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+
+static int
+gf_client_chain_client_entries (cliententry_t *entries, uint32_t startidx,
+ uint32_t endcount)
+{
+ uint32_t i = 0;
+
+ if (!entries) {
+ gf_log_callingfn ("client_t", 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_CLIENTTABLE_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_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 < 0) {
+ gf_log_callingfn ("client_t", GF_LOG_ERROR, "invalid argument");
+ ret = EINVAL;
+ goto out;
+ }
+
+ /* expand size by power-of-two...
+ this originally came from .../xlators/protocol/server/src/server.c
+ where it was not commented */
+ nr /= (1024 / sizeof (cliententry_t));
+ nr = gf_roundup_next_power_of_two (nr + 1);
+ nr *= (1024 / sizeof (cliententry_t));
+
+ oldclients = clienttable->cliententries;
+ oldmax_clients = clienttable->max_clients;
+
+ clienttable->cliententries = GF_CALLOC (nr, sizeof (cliententry_t),
+ gf_common_mt_cliententry_t);
+ if (!clienttable->cliententries) {
+ ret = ENOMEM;
+ 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;
+
+ clienttable =
+ GF_CALLOC (1, sizeof (clienttable_t), gf_common_mt_clienttable_t);
+ if (!clienttable)
+ return NULL;
+
+ LOCK_INIT (&clienttable->lock);
+ gf_client_clienttable_expand (clienttable, GF_CLIENTTABLE_INITIAL_SIZE);
+ return clienttable;
+}
+
+
+void
+gf_client_clienttable_destroy (clienttable_t *clienttable)
+{
+ client_t *client = NULL;
+ cliententry_t *cliententries = NULL;
+ uint32_t client_count = 0;
+ int32_t i = 0;
+
+ if (!clienttable) {
+ gf_log_callingfn ("client_t", GF_LOG_WARNING, "!clienttable");
+ return;
+ }
+
+ LOCK (&clienttable->lock);
+ {
+ client_count = clienttable->max_clients;
+ clienttable->max_clients = 0;
+ cliententries = clienttable->cliententries;
+ clienttable->cliententries = NULL;
+ }
+ UNLOCK (&clienttable->lock);
+
+ if (cliententries != NULL) {
+ for (i = 0; i < client_count; i++) {
+ client = cliententries[i].client;
+ if (client != NULL) {
+ gf_client_unref (client);
+ }
+ }
+
+ GF_FREE (cliententries);
+ LOCK_DESTROY (&clienttable->lock);
+ GF_FREE (clienttable);
+ }
+}
+
+client_t *
+gf_client_get (xlator_t *this, struct rpcsvc_auth_data *cred, char *client_uid)
+{
+ client_t *client = NULL;
+ cliententry_t *cliententry = NULL;
+ clienttable_t *clienttable = NULL;
+ unsigned int i = 0;
+
+ if (this == NULL || client_uid == NULL) {
+ gf_log_callingfn ("client_t", GF_LOG_ERROR, "invalid argument");
+ errno = EINVAL;
+ return NULL;
+ }
+
+ gf_log (this->name, GF_LOG_INFO, "client_uid=%s", client_uid);
+
+ 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 != AUTH_NONE &&
+ (cred->flavour == client->auth.flavour &&
+ (size_t) cred->datalen == client->auth.len &&
+ memcmp (cred->authdata,
+ client->auth.data,
+ client->auth.len) == 0))) {
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
+ __sync_add_and_fetch(&client->ref.bind, 1);
+#else
+ LOCK (&client->ref.lock);
+ {
+ ++client->ref.bind;
+ }
+ UNLOCK (&client->ref.lock);
+#endif
+ break;
+ }
+ }
+ if (client) {
+ gf_client_ref (client);
+ goto unlock;
+ }
+ client = GF_CALLOC (1, sizeof(client_t), gf_common_mt_client_t);
+ if (client == NULL) {
+ errno = ENOMEM;
+ goto unlock;
+ }
+
+ client->this = this;
+
+ LOCK_INIT (&client->scratch_ctx.lock);
+ LOCK_INIT (&client->ref.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;
+ }
+
+ /* no need to do these atomically here */
+ client->ref.bind = client->ref.count = 1;
+
+ client->auth.flavour = cred->flavour;
+ if (cred->flavour != AUTH_NONE) {
+ client->auth.data =
+ GF_CALLOC (1, 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[client->tbl_index];
+ cliententry->client = client;
+ clienttable->first_free = cliententry->next_free;
+ cliententry->next_free = GF_CLIENTENTRY_ALLOCATED;
+ gf_client_ref (client);
+ }
+unlock:
+ UNLOCK (&clienttable->lock);
+
+ return client;
+}
+
+void
+gf_client_put (client_t *client, gf_boolean_t *detached)
+{
+ gf_boolean_t unref = _gf_false;
+ int bind_ref;
+
+ if (detached)
+ *detached = _gf_false;
+
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
+ bind_ref = __sync_sub_and_fetch(&client->ref.bind, 1);
+#else
+ LOCK (&client->ref.lock);
+ {
+ bind_ref = --client->ref.bind;
+ }
+ UNLOCK (&client->ref.lock);
+#endif
+ if (bind_ref == 0)
+ unref = _gf_true;
+
+ if (unref) {
+ gf_log (THIS->name, GF_LOG_INFO, "Shutting down connection %s",
+ client->client_uid);
+ if (detached)
+ *detached = _gf_true;
+ gf_client_unref (client);
+ }
+}
+
+
+client_t *
+gf_client_ref (client_t *client)
+{
+ if (!client) {
+ gf_log_callingfn ("client_t", GF_LOG_ERROR, "null client");
+ return NULL;
+ }
+
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
+ __sync_add_and_fetch(&client->ref.count, 1);
+#else
+ LOCK (&client->ref.lock);
+ {
+ ++client->ref.count;
+ }
+ UNLOCK (&client->ref.lock);
+#endif
+ return client;
+}
+
+
+static void
+client_destroy (client_t *client)
+{
+ clienttable_t *clienttable = NULL;
+ glusterfs_graph_t *gtrav = NULL;
+ xlator_t *xtrav = NULL;
+
+ if (client == NULL){
+ gf_log_callingfn ("xlator", GF_LOG_ERROR, "invalid argument");
+ goto out;
+ }
+
+ clienttable = client->this->ctx->clienttable;
+
+ LOCK_DESTROY (&client->scratch_ctx.lock);
+ LOCK_DESTROY (&client->ref.lock);
+
+ 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) {
+ xtrav = gtrav->top;
+ while (xtrav != NULL) {
+ if (xtrav->cbks->client_destroy != NULL)
+ xtrav->cbks->client_destroy (xtrav, client);
+ xtrav = xtrav->next;
+ }
+ }
+ GF_FREE (client->auth.data);
+ GF_FREE (client->scratch_ctx.ctx);
+ GF_FREE (client->client_uid);
+ GF_FREE (client);
+out:
+ return;
+}
+
+
+int
+gf_client_disconnect (client_t *client)
+{
+ int ret = 0;
+ glusterfs_graph_t *gtrav = NULL;
+ xlator_t *xtrav = NULL;
+
+ list_for_each_entry (gtrav, &client->this->ctx->graphs, list) {
+ xtrav = gtrav->top;
+ while (xtrav != NULL) {
+ if (xtrav->cbks->client_disconnect != NULL)
+ if (xtrav->cbks->client_disconnect (xtrav, client) != 0)
+ ret = -1;
+ xtrav = xtrav->next;
+ }
+ }
+
+ return ret;
+}
+
+
+void
+gf_client_unref (client_t *client)
+{
+ int refcount;
+
+ if (!client) {
+ gf_log_callingfn ("client_t", GF_LOG_ERROR, "client is NULL");
+ return;
+ }
+
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
+ refcount = __sync_sub_and_fetch(&client->ref.count, 1);
+#else
+ LOCK (&client->ref.lock);
+ {
+ refcount = --client->ref.count;
+ }
+ UNLOCK (&client->ref.lock);
+#endif
+ if (refcount == 0) {
+ client_destroy (client);
+ }
+}
+
+
+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;
+ /* dont 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;
+}
+
+
+int
+client_ctx_set (client_t *client, void *key, void *value)
+{
+ int ret = 0;
+
+ if (!client || !key)
+ return -1;
+
+ LOCK (&client->scratch_ctx.lock);
+ {
+ ret = client_ctx_set_int (client, key, value);
+ }
+ UNLOCK (&client->scratch_ctx.lock);
+
+ return ret;
+}
+
+
+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;
+}
+
+
+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_dump (client_t *client, char *prefix)
+{
+ char key[GF_DUMP_MAX_BUF_LEN];
+
+ if (!client)
+ return;
+
+ memset(key, 0, sizeof key);
+ gf_proc_dump_write("refcount", "%d", client->ref.count);
+}
+
+
+void
+cliententry_dump (cliententry_t *cliententry, char *prefix)
+{
+ if (!cliententry)
+ return;
+
+ if (GF_CLIENTENTRY_ALLOCATED != cliententry->next_free)
+ return;
+
+ if (cliententry->client)
+ client_dump(cliententry->client, prefix);
+}
+
+
+void
+clienttable_dump (clienttable_t *clienttable, char *prefix)
+{
+ int i = 0;
+ int ret = -1;
+ char key[GF_DUMP_MAX_BUF_LEN] = {0};
+
+ if (!clienttable)
+ return;
+
+ ret = TRY_LOCK (&clienttable->lock);
+ {
+ if (ret) {
+ gf_log ("client_t", GF_LOG_WARNING,
+ "Unable to acquire lock");
+ return;
+ }
+ memset(key, 0, sizeof key);
+ gf_proc_dump_build_key(key, prefix, "maxclients");
+ gf_proc_dump_write(key, "%d", clienttable->max_clients);
+ gf_proc_dump_build_key(key, prefix, "first_free");
+ gf_proc_dump_write(key, "%d", clienttable->first_free);
+ for ( i = 0 ; i < clienttable->max_clients; i++) {
+ if (GF_CLIENTENTRY_ALLOCATED ==
+ clienttable->cliententries[i].next_free) {
+ gf_proc_dump_build_key(key, prefix,
+ "cliententry[%d]", i);
+ gf_proc_dump_add_section(key);
+ cliententry_dump(&clienttable->cliententries[i],
+ key);
+ }
+ }
+ }
+ UNLOCK(&clienttable->lock);
+}
+
+
+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_log ("client_t", GF_LOG_WARNING,
+ "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;
+ memset(key, 0, sizeof key);
+ 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_log ("client_t", GF_LOG_WARNING,
+ "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;
+ memset(key, 0, sizeof key);
+ if (client->client_uid) {
+ gf_proc_dump_build_key (key, "conn",
+ "%d.id", count);
+ gf_proc_dump_write (key, "%s",
+ client->client_uid);
+ }
+
+ gf_proc_dump_build_key (key, "conn", "%d.ref",
+ count);
+ gf_proc_dump_write (key, "%d", client->ref.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 = TRY_LOCK (&clienttable->lock);
+ {
+ if (ret) {
+ gf_log ("client_t", GF_LOG_WARNING,
+ "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;
+ memset(key, 0, sizeof key);
+ 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;
+
+ memset (key, 0, sizeof (key));
+ 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 = 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)
+ goto out;
+
+ ret = TRY_LOCK (&clienttable->lock);
+ {
+ if (ret) {
+ gf_log ("client_t", GF_LOG_WARNING,
+ "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;
+ memset(key, 0, sizeof key);
+ 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/client_t.h b/libglusterfs/src/client_t.h
new file mode 100644
index 000000000..f7812f8f0
--- /dev/null
+++ b/libglusterfs/src/client_t.h
@@ -0,0 +1,135 @@
+/*
+ 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.
+*/
+
+#ifndef _CLIENT_T_H
+#define _CLIENT_T_H
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "glusterfs.h"
+#include "locking.h" /* for gf_lock_t, not included by glusterfs.h */
+
+struct client_ctx {
+ void *ctx_key;
+ void *ctx_value;
+};
+
+typedef struct _client_t {
+ struct {
+ /* e.g. protocol/server stashes its ctx here */
+ gf_lock_t lock;
+ unsigned short count;
+ struct client_ctx *ctx;
+ } scratch_ctx;
+ struct {
+ gf_lock_t lock;
+ volatile int bind;
+ volatile int count;
+ } ref;
+ xlator_t *bound_xl;
+ xlator_t *this;
+ int tbl_index;
+ char *client_uid;
+ struct {
+ int flavour;
+ size_t len;
+ char *data;
+ } auth;
+} client_t;
+
+#define GF_CLIENTCTX_INITIAL_SIZE 8
+
+struct client_table_entry {
+ client_t *client;
+ int next_free;
+};
+typedef struct client_table_entry cliententry_t;
+
+struct clienttable {
+ unsigned int max_clients;
+ gf_lock_t lock;
+ cliententry_t *cliententries;
+ int first_free;
+};
+typedef struct clienttable clienttable_t;
+
+#define GF_CLIENTTABLE_INITIAL_SIZE 32
+
+/* Signifies no more entries in the client table. */
+#define GF_CLIENTTABLE_END -1
+
+/* This is used to invalidate
+ * the next_free value in an cliententry that has been allocated
+ */
+#define GF_CLIENTENTRY_ALLOCATED -2
+
+struct rpcsvc_auth_data;
+
+client_t *
+gf_client_get (xlator_t *this, struct rpcsvc_auth_data *cred, char *client_uid);
+
+void
+gf_client_put (client_t *client, gf_boolean_t *detached);
+
+clienttable_t *
+gf_clienttable_alloc (void);
+
+void
+gf_client_clienttable_destroy (clienttable_t *clienttable);
+
+client_t *
+gf_client_ref (client_t *client);
+
+void
+gf_client_unref (client_t *client);
+
+int
+gf_client_dump_fdtable_to_dict (xlator_t *this, dict_t *dict);
+
+int
+gf_client_dump_fdtable (xlator_t *this);
+
+int
+gf_client_dump_inodes_to_dict (xlator_t *this, dict_t *dict);
+
+int
+gf_client_dump_inodes (xlator_t *this);
+
+int
+client_ctx_set (client_t *client, void *key, void *value);
+
+int
+client_ctx_get (client_t *client, void *key, void **value);
+
+int
+client_ctx_del (client_t *client, void *key, void **value);
+
+void
+client_ctx_dump (client_t *client, char *prefix);
+
+int
+gf_client_dump_fdtables_to_dict (xlator_t *this, dict_t *dict);
+
+int
+gf_client_dump_fdtables (xlator_t *this);
+
+int
+gf_client_dump_inodes_to_dict (xlator_t *this, dict_t *dict);
+
+int
+gf_client_dump_inodes (xlator_t *this);
+
+int
+gf_client_disconnect (client_t *client);
+
+#endif /* _CLIENT_T_H */
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c
index e4c7e2c31..827475282 100644
--- a/libglusterfs/src/common-utils.c
+++ b/libglusterfs/src/common-utils.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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
@@ -40,22 +31,127 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
+#include <stdlib.h>
+
+#if defined GF_BSD_HOST_OS || defined GF_DARWIN_HOST_OS
+#include <sys/sysctl.h>
+#endif
#include "logging.h"
#include "common-utils.h"
#include "revision.h"
#include "glusterfs.h"
#include "stack.h"
+#include "globals.h"
+#include "lkowner.h"
+#include "syscall.h"
+#include <ifaddrs.h>
+
+#ifndef AI_ADDRCONFIG
+#define AI_ADDRCONFIG 0
+#endif /* AI_ADDRCONFIG */
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;
+ struct addrinfo *first;
+ struct addrinfo *next;
};
+void
+md5_wrapper(const unsigned char *data, size_t len, char *md5)
+{
+ unsigned short i = 0;
+ unsigned short lim = MD5_DIGEST_LENGTH*2+1;
+ unsigned char scratch[MD5_DIGEST_LENGTH] = {0,};
+ MD5(data, len, scratch);
+ for (; i < MD5_DIGEST_LENGTH; i++)
+ snprintf(md5 + i * 2, lim-i*2, "%02x", scratch[i]);
+}
+
+/* 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,};
+
+ strcpy (dir, path);
+ i = (dir[0] == '/')? 1: 0;
+ do {
+ if (path[i] != '/' && path[i] != '\0')
+ continue;
+
+ dir[i] = '\0';
+ ret = mkdir (dir, mode);
+ if (ret && errno != EEXIST) {
+ gf_log ("", GF_LOG_ERROR, "Failed due to reason %s",
+ strerror (errno));
+ goto out;
+ }
+
+ if (ret && errno == EEXIST && !allow_symlinks) {
+ ret = lstat (dir, &stbuf);
+ if (ret)
+ goto out;
+
+ if (S_ISLNK (stbuf.st_mode)) {
+ ret = -1;
+ gf_log ("", GF_LOG_ERROR, "%s is a symlink",
+ dir);
+ goto out;
+ }
+ }
+ dir[i] = '/';
+
+ } while (path[i++] != '\0');
+
+ ret = stat (dir, &stbuf);
+ if (ret || !S_ISDIR (stbuf.st_mode)) {
+ ret = -1;
+ gf_log ("", GF_LOG_ERROR, "Failed to create directory, "
+ "possibly some of the components were not directories");
+ 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)
@@ -73,138 +169,211 @@ log_base2 (unsigned long x)
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 ("resolver", GF_LOG_WARNING, "hostname is NULL");
- return -1;
- }
+ 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;
+ }
- if (!*dnscache) {
- *dnscache = GF_CALLOC (1, sizeof (struct dnscache6),
- gf_common_mt_dnscache6);
+ 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_log ("resolver", GF_LOG_TRACE,
- "flushing DNS cache");
- }
+ }
- if (!cache->first) {
- char *port_str = NULL;
- gf_log ("resolver", GF_LOG_TRACE,
- "DNS cache not present, freshly probing hostname: %s",
- hostname);
+ cache = *dnscache;
+ if (cache->first && !cache->next) {
+ freeaddrinfo(cache->first);
+ cache->first = cache->next = NULL;
+ gf_log ("resolver", GF_LOG_TRACE,
+ "flushing DNS cache");
+ }
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = family;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_flags = AI_ADDRCONFIG;
+ 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;
+#ifndef __NetBSD__
+ hints.ai_flags = AI_ADDRCONFIG;
+#endif
- ret = gf_asprintf (&port_str, "%d", port);
+ 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;
- }
+ if ((ret = getaddrinfo(hostname, port_str, &hints, &cache->first)) != 0) {
+ gf_log ("resolver", GF_LOG_ERROR,
+ "getaddrinfo failed (%s)", gai_strerror (ret));
- 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_TRACE,
- "returning ip-%s (port-%s) for hostname: %s and port: %d",
- host, service, hostname, port);
-
- *addr_info = cache->next;
- }
+ GF_FREE (*dnscache);
+ *dnscache = NULL;
+ GF_FREE (port_str);
+ return -1;
+ }
+ 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_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;
+ }
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_TRACE,
- "next DNS query will return: ip-%s port-%s", host, service);
- }
+ 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;
+ }
- return 0;
+ gf_log ("resolver", GF_LOG_DEBUG,
+ "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;
+ freeaddrinfo (cache->first);
+ cache->first = cache->next = NULL;
+ GF_FREE (cache);
+ *dnscache = NULL;
+ return -1;
+}
+
+
+struct xldump {
+ int lineno;
+ FILE *logfp;
+};
+
+
+static int
+nprintf (struct xldump *dump, const char *fmt, ...)
+{
+ va_list ap;
+ int ret = 0;
+
+
+ ret += fprintf (dump->logfp, "%3d: ", ++dump->lineno);
+
+ va_start (ap, fmt);
+ ret += vfprintf (dump->logfp, fmt, ap);
+ va_end (ap);
+
+ ret += fprintf (dump->logfp, "\n");
+
+ return ret;
+}
+
+
+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;
+
+ subv = this->children;
+ if (!this->children)
+ return;
+
+ for (subv = this->children; subv; subv = subv->next)
+ len += (strlen (subv->xlator->name) + 1);
+
+ subvstr = GF_CALLOC (1, 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];
+ glusterfs_ctx_t *ctx;
+ struct xldump xld = {0, };
- fseek (specfp, 0L, SEEK_SET);
- fprintf (gf_log_logfile, "Given volfile:\n");
- fprintf (gf_log_logfile,
- "+---------------------------------------"
- "---------------------------------------+\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);
+ ctx = THIS->ctx;
+ xld.logfp = ctx->log.gf_log_logfile;
+
+ fprintf (ctx->log.gf_log_logfile, "Final graph:\n");
+ fprintf (ctx->log.gf_log_logfile,
+ "+---------------------------------------"
+ "---------------------------------------+\n");
+
+ xlator_foreach_depth_first (graph->top, xldump, &xld);
+
+ fprintf (ctx->log.gf_log_logfile,
+ "+---------------------------------------"
+ "---------------------------------------+\n");
+ fflush (ctx->log.gf_log_logfile);
}
static void
@@ -212,201 +381,223 @@ gf_dump_config_flags (int fd)
{
int ret = 0;
- ret = write (fd, "configuration details:\n", 23);
+ ret = write (fd, "configuration details:\n", 23);
if (ret == -1)
goto out;
/* have argp */
#ifdef HAVE_ARGP
- ret = write (fd, "argp 1\n", 7);
+ ret = write (fd, "argp 1\n", 7);
if (ret == -1)
goto out;
#endif
/* ifdef if found backtrace */
#ifdef HAVE_BACKTRACE
- ret = write (fd, "backtrace 1\n", 12);
+ ret = write (fd, "backtrace 1\n", 12);
if (ret == -1)
goto out;
#endif
/* Berkeley-DB version has cursor->get() */
#ifdef HAVE_BDB_CURSOR_GET
- ret = write (fd, "bdb->cursor->get 1\n", 19);
+ ret = write (fd, "bdb->cursor->get 1\n", 19);
if (ret == -1)
goto out;
#endif
/* Define to 1 if you have the <db.h> header file. */
#ifdef HAVE_DB_H
- ret = write (fd, "db.h 1\n", 7);
+ ret = write (fd, "db.h 1\n", 7);
if (ret == -1)
goto out;
#endif
/* Define to 1 if you have the <dlfcn.h> header file. */
#ifdef HAVE_DLFCN_H
- ret = write (fd, "dlfcn 1\n", 8);
+ ret = write (fd, "dlfcn 1\n", 8);
if (ret == -1)
goto out;
#endif
/* define if fdatasync exists */
#ifdef HAVE_FDATASYNC
- ret = write (fd, "fdatasync 1\n", 12);
+ ret = write (fd, "fdatasync 1\n", 12);
if (ret == -1)
goto out;
#endif
/* Define to 1 if you have the `pthread' library (-lpthread). */
#ifdef HAVE_LIBPTHREAD
- ret = write (fd, "libpthread 1\n", 13);
+ ret = write (fd, "libpthread 1\n", 13);
if (ret == -1)
goto out;
#endif
/* define if llistxattr exists */
#ifdef HAVE_LLISTXATTR
- ret = write (fd, "llistxattr 1\n", 13);
+ ret = write (fd, "llistxattr 1\n", 13);
if (ret == -1)
goto out;
#endif
/* define if found setfsuid setfsgid */
#ifdef HAVE_SET_FSID
- ret = write (fd, "setfsid 1\n", 10);
+ ret = write (fd, "setfsid 1\n", 10);
if (ret == -1)
goto out;
#endif
/* define if found spinlock */
#ifdef HAVE_SPINLOCK
- ret = write (fd, "spinlock 1\n", 11);
+ ret = write (fd, "spinlock 1\n", 11);
if (ret == -1)
goto out;
#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);
+ ret = write (fd, "epoll.h 1\n", 10);
if (ret == -1)
goto out;
#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);
+ ret = write (fd, "extattr.h 1\n", 12);
if (ret == -1)
goto out;
#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);
+ ret = write (fd, "xattr.h 1\n", 10);
if (ret == -1)
goto out;
#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);
+ ret = write (fd, "st_atim.tv_nsec 1\n", 18);
if (ret == -1)
goto out;
#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);
+ ret = write (fd, "st_atimespec.tv_nsec 1\n",23);
if (ret == -1)
goto out;
#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));
+ {
+ char msg[128];
+ sprintf (msg, "package-string: %s\n", PACKAGE_STRING);
+ ret = write (fd, msg, strlen (msg));
if (ret == -1)
goto out;
- }
+ }
#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' */
+
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;
+ char timestr[64] = {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);
- {
- 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);
- }
+ fd = fileno (ctx->log.gf_log_logfile);
+
+ /* 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.
+ */
+ fflush (ctx->log.gf_log_logfile);
+ /* Pending frames, (if any), list them in order */
+ ret = write (fd, "pending frames:\n", 16);
+ if (ret < 0)
+ goto out;
- sprintf (msg, "patchset: %s\n", GLUSTERFS_REPOSITORY_REVISION);
- ret = write (fd, msg, strlen (msg));
+ {
+ 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]);
+ else
+ sprintf (msg,"frame : type(%d) op(%d)\n",
+ tmp->root->type,
+ tmp->root->op);
+
+ ret = write (fd, msg, strlen (msg));
+ if (ret < 0)
+ goto out;
+
+ trav = trav->next;
+ }
+ ret = write (fd, "\n", 1);
+ if (ret < 0)
+ goto out;
+ }
+
+ sprintf (msg, "patchset: %s\n", GLUSTERFS_REPOSITORY_REVISION);
+ ret = write (fd, msg, strlen (msg));
+ if (ret < 0)
+ goto out;
- sprintf (msg, "signal received: %d\n", signum);
- ret = write (fd, msg, strlen (msg));
+ sprintf (msg, "signal received: %d\n", signum);
+ ret = write (fd, msg, strlen (msg));
+ if (ret < 0)
+ goto out;
{
/* 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);
+ gf_time_fmt (timestr, sizeof timestr, time (NULL), gf_timefmt_FT);
ret = write (fd, "time of crash: ", 15);
+ if (ret < 0)
+ goto out;
ret = write (fd, timestr, strlen (timestr));
+ if (ret < 0)
+ goto out;
}
- gf_dump_config_flags (fd);
+ gf_dump_config_flags (fd);
#if HAVE_BACKTRACE
- /* Print 'backtrace' */
- {
- void *array[200];
- size_t size;
-
- size = backtrace (array, 200);
- backtrace_symbols_fd (&array[1], size-1, fd);
- sprintf (msg, "---------\n");
- ret = write (fd, msg, strlen (msg));
- }
+ /* Print 'backtrace' */
+ {
+ void *array[200];
+ size_t size;
+
+ size = backtrace (array, 200);
+ backtrace_symbols_fd (&array[1], size-1, fd);
+ sprintf (msg, "---------\n");
+ ret = write (fd, msg, strlen (msg));
+ if (ret < 0)
+ goto out;
+ }
#endif /* HAVE_BACKTRACE */
- /* Send a signal to terminate the process */
- signal (signum, SIG_DFL);
- raise (signum);
+out:
+ /* Send a signal to terminate the process */
+ signal (signum, SIG_DFL);
+ raise (signum);
}
void
@@ -418,97 +609,90 @@ trap (void)
char *
gf_trim (char *string)
{
- register char *s, *t;
+ register char *s, *t;
- if (string == NULL)
- {
- return NULL;
- }
+ if (string == NULL) {
+ return NULL;
+ }
- for (s = string; isspace (*s); s++)
- ;
+ for (s = string; isspace (*s); s++)
+ ;
- if (*s == 0)
- return s;
+ if (*s == 0)
+ return s;
- t = s + strlen (s) - 1;
- while (t > s && isspace (*t))
- t--;
- *++t = '\0';
+ t = s + strlen (s) - 1;
+ while (t > s && isspace (*t))
+ t--;
+ *++t = '\0';
- return s;
+ return s;
}
int
gf_strsplit (const char *str, const char *delim,
- char ***tokens, int *token_count)
-{
- char *_running = NULL;
- char *running = NULL;
- char *token = NULL;
- char **token_list = NULL;
- int count = 0;
- int i = 0;
- int j = 0;
-
- if (str == NULL || delim == NULL || tokens == NULL || token_count == NULL)
- {
- return -1;
- }
+ char ***tokens, int *token_count)
+{
+ char *_running = NULL;
+ char *running = NULL;
+ char *token = NULL;
+ char **token_list = NULL;
+ int count = 0;
+ int i = 0;
+ int j = 0;
+
+ if (str == NULL || delim == NULL || tokens == NULL || token_count == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
+ return -1;
+ }
_running = gf_strdup (str);
- if (_running == NULL)
- {
- return -1;
- }
- running = _running;
+ if (_running == NULL)
+ return -1;
- while ((token = strsep (&running, delim)) != NULL)
- {
- if (token[0] != '\0')
- count++;
- }
- GF_FREE (_running);
+ running = _running;
+
+ while ((token = strsep (&running, delim)) != NULL) {
+ if (token[0] != '\0')
+ count++;
+ }
+ GF_FREE (_running);
_running = gf_strdup (str);
- if (_running == NULL)
- {
- return -1;
- }
- running = _running;
+ if (_running == NULL)
+ return -1;
- if ((token_list = GF_CALLOC (count, sizeof (char *),
- gf_common_mt_char)) == NULL)
- {
- GF_FREE (_running);
- return -1;
- }
+ running = _running;
- while ((token = strsep (&running, delim)) != NULL)
- {
- if (token[0] == '\0')
- continue;
+ if ((token_list = GF_CALLOC (count, sizeof (char *),
+ gf_common_mt_char)) == NULL) {
+ GF_FREE (_running);
+ return -1;
+ }
+
+ while ((token = strsep (&running, delim)) != NULL) {
+ if (token[0] == '\0')
+ continue;
token_list[i] = gf_strdup (token);
- if (token_list[i] == NULL)
- goto free_exit;
+ if (token_list[i] == NULL)
+ goto free_exit;
i++;
- }
+ }
- GF_FREE (_running);
+ GF_FREE (_running);
- *tokens = token_list;
- *token_count = count;
- return 0;
+ *tokens = token_list;
+ *token_count = count;
+ return 0;
free_exit:
- GF_FREE (_running);
- for (j = 0; j < i; j++)
- {
- GF_FREE (token_list[j]);
- }
- GF_FREE (token_list);
- return -1;
+ GF_FREE (_running);
+ for (j = 0; j < i; j++)
+ GF_FREE (token_list[j]);
+
+ GF_FREE (token_list);
+ return -1;
}
int
@@ -523,9 +707,10 @@ gf_strstr (const char *str, const char *delim, const char *match)
tmp_str = strdup (str);
if (str == NULL || delim == NULL || match == NULL || tmp_str == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
ret = -1;
- goto out;
- }
+ goto out;
+ }
tmp = strtok_r (tmp_str, delim, &save_ptr);
@@ -540,8 +725,7 @@ gf_strstr (const char *str, const char *delim, const char *match)
}
out:
- if (tmp_str)
- free (tmp_str);
+ free (tmp_str);
return ret;
@@ -550,870 +734,882 @@ out:
int
gf_volume_name_validate (const char *volume_name)
{
- const char *vname = NULL;
+ const char *vname = NULL;
- if (volume_name == NULL)
- {
- return -1;
- }
+ if (volume_name == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
+ return -1;
+ }
- if (!isalpha (volume_name[0]))
- {
- return 1;
- }
+ if (!isalpha (volume_name[0]))
+ return 1;
- for (vname = &volume_name[1]; *vname != '\0'; vname++)
- {
- if (!(isalnum (*vname) || *vname == '_'))
- return 1;
- }
+ for (vname = &volume_name[1]; *vname != '\0'; vname++) {
+ if (!(isalnum (*vname) || *vname == '_'))
+ return 1;
+ }
- return 0;
+ return 0;
}
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)
- {
- errno = EINVAL;
- return -1;
- }
+ unsigned long value = 0;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
+
+ if (str == NULL || n == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
- for (s = str; *s != '\0'; s++)
- {
- if (isspace (*s))
- {
- continue;
- }
- if (*s == '-')
- {
- return -1;
- }
- break;
- }
+ 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);
+ old_errno = errno;
+ errno = 0;
+ value = strtol (str, &tail, 0);
+ if (str == tail)
+ errno = EINVAL;
- if (errno == ERANGE || errno == EINVAL)
- {
- return -1;
- }
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- if (errno == 0)
- {
- errno = old_errno;
- }
+ 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'))))
- {
- return -1;
- }
+ if (!((tail[0] == '\0') ||
+ ((tail[0] == 's') && (tail[1] == '\0')) ||
+ ((tail[0] == 's') && (tail[1] == 'e') &&
+ (tail[2] == 'c') && (tail[3] == '\0'))))
+ return -1;
- *n = value;
+ *n = value;
- return 0;
+ return 0;
}
-
int
-gf_string2percent (const char *str, uint32_t *n)
+gf_string2percent (const char *str, double *n)
{
- unsigned long value = 0;
- char *tail = NULL;
- int old_errno = 0;
- const char *s = NULL;
+ double value = 0;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
+
+ if (str == NULL || n == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
- if (str == NULL || n == NULL)
- {
- errno = EINVAL;
- return -1;
- }
+ for (s = str; *s != '\0'; s++) {
+ if (isspace (*s))
+ continue;
+ if (*s == '-')
+ return -1;
+ break;
+ }
- 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;
- old_errno = errno;
- errno = 0;
- value = strtol (str, &tail, 0);
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- if (errno == ERANGE || errno == EINVAL)
- {
- return -1;
- }
+ if (errno == 0)
+ errno = old_errno;
- if (errno == 0)
- {
- errno = old_errno;
- }
-
- if (!((tail[0] == '\0') ||
- ((tail[0] == '%') && (tail[1] == '\0'))))
- {
- return -1;
- }
+ if (!((tail[0] == '\0') ||
+ ((tail[0] == '%') && (tail[1] == '\0'))))
+ return -1;
- *n = value;
+ *n = value;
- return 0;
+ return 0;
}
static int
_gf_string2long (const char *str, long *n, int base)
{
- long value = 0;
- char *tail = NULL;
- int old_errno = 0;
-
- if (str == NULL || n == NULL)
- {
- errno = EINVAL;
- return -1;
- }
+ long value = 0;
+ char *tail = NULL;
+ int old_errno = 0;
+
+ if (str == NULL || n == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
- old_errno = errno;
- errno = 0;
- value = strtol (str, &tail, base);
+ old_errno = errno;
+ errno = 0;
+ value = strtol (str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
- if (errno == ERANGE || errno == EINVAL)
- {
- return -1;
- }
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- if (errno == 0)
- {
- errno = old_errno;
- }
+ if (errno == 0)
+ errno = old_errno;
- if (tail[0] != '\0')
- {
- /* bala: invalid integer format */
- return -1;
- }
+ if (tail[0] != '\0')
+ return -1;
- *n = value;
+ *n = value;
- return 0;
+ return 0;
}
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)
- {
- errno = EINVAL;
- return -1;
- }
+ unsigned long value = 0;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
+
+ if (str == NULL || n == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
- 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;
- }
+ 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);
+ old_errno = errno;
+ errno = 0;
+ value = strtoul (str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
- if (errno == ERANGE || errno == EINVAL)
- {
- return -1;
- }
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- if (errno == 0)
- {
- errno = old_errno;
- }
+ if (errno == 0)
+ errno = old_errno;
- if (tail[0] != '\0')
- {
- /* bala: invalid integer format */
- return -1;
- }
+ if (tail[0] != '\0')
+ return -1;
- *n = value;
+ *n = value;
- return 0;
+ return 0;
}
static int
_gf_string2uint (const char *str, unsigned int *n, int base)
{
- unsigned long value = 0;
- char *tail = NULL;
- int old_errno = 0;
- const char *s = NULL;
-
- if (str == NULL || n == NULL)
- {
- errno = EINVAL;
- return -1;
- }
+ unsigned long value = 0;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
+
+ if (str == NULL || n == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
- 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;
- }
+ 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);
+ old_errno = errno;
+ errno = 0;
+ value = strtoul (str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
- if (errno == ERANGE || errno == EINVAL)
- {
- return -1;
- }
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- if (errno == 0)
- {
- errno = old_errno;
- }
+ if (errno == 0)
+ errno = old_errno;
- if (tail[0] != '\0')
- {
- /* bala: invalid integer format */
- return -1;
- }
+ if (tail[0] != '\0')
+ return -1;
- *n = (unsigned int)value;
+ *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) {
- errno = EINVAL;
- return -1;
- }
+ double value = 0.0;
+ char *tail = NULL;
+ int old_errno = 0;
+
+ if (str == NULL || n == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
- old_errno = errno;
- errno = 0;
- value = strtod (str, &tail);
+ old_errno = errno;
+ errno = 0;
+ value = strtod (str, &tail);
+ if (str == tail)
+ errno = EINVAL;
- if (errno == ERANGE || errno == EINVAL) {
- return -1;
- }
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- if (errno == 0) {
- errno = old_errno;
- }
+ if (errno == 0)
+ errno = old_errno;
- if (tail[0] != '\0') {
- return -1;
- }
+ if (tail[0] != '\0')
+ return -1;
- *n = value;
+ *n = value;
- return 0;
+ return 0;
}
static int
_gf_string2longlong (const char *str, long long *n, int base)
{
- long long value = 0;
- char *tail = NULL;
- int old_errno = 0;
-
- if (str == NULL || n == NULL)
- {
- errno = EINVAL;
- return -1;
- }
+ long long value = 0;
+ char *tail = NULL;
+ int old_errno = 0;
+
+ if (str == NULL || n == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
- old_errno = errno;
- errno = 0;
- value = strtoll (str, &tail, base);
+ old_errno = errno;
+ errno = 0;
+ value = strtoll (str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
- if (errno == ERANGE || errno == EINVAL)
- {
- return -1;
- }
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- if (errno == 0)
- {
- errno = old_errno;
- }
+ if (errno == 0)
+ errno = old_errno;
- if (tail[0] != '\0')
- {
- /* bala: invalid integer format */
- return -1;
- }
+ if (tail[0] != '\0')
+ return -1;
- *n = value;
+ *n = value;
- return 0;
+ return 0;
}
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)
- {
- errno = EINVAL;
- return -1;
- }
+ unsigned long long value = 0;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
+
+ if (str == NULL || n == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
- 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;
- }
+ 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);
+ old_errno = errno;
+ errno = 0;
+ value = strtoull (str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
- if (errno == ERANGE || errno == EINVAL)
- {
- return -1;
- }
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- if (errno == 0)
- {
- errno = old_errno;
- }
+ if (errno == 0)
+ errno = old_errno;
- if (tail[0] != '\0')
- {
- /* bala: invalid integer format */
- return -1;
- }
+ if (tail[0] != '\0')
+ return -1;
- *n = value;
+ *n = value;
- return 0;
+ return 0;
}
int
gf_string2long (const char *str, long *n)
{
- return _gf_string2long (str, n, 0);
+ return _gf_string2long (str, n, 0);
}
int
gf_string2ulong (const char *str, unsigned long *n)
{
- return _gf_string2ulong (str, n, 0);
+ return _gf_string2ulong (str, n, 0);
}
int
gf_string2int (const char *str, int *n)
{
- return _gf_string2long (str, (long *) n, 0);
+ long l = 0;
+ int ret = 0;
+
+ ret = _gf_string2long (str, &l, 0);
+
+ *n = l;
+ return ret;
}
int
gf_string2uint (const char *str, unsigned int *n)
{
- return _gf_string2uint (str, n, 0);
+ return _gf_string2uint (str, n, 0);
}
int
gf_string2double (const char *str, double *n)
{
- return _gf_string2double (str, n);
+ return _gf_string2double (str, n);
}
int
gf_string2longlong (const char *str, long long *n)
{
- return _gf_string2longlong (str, n, 0);
+ return _gf_string2longlong (str, n, 0);
}
int
gf_string2ulonglong (const char *str, unsigned long long *n)
{
- return _gf_string2ulonglong (str, n, 0);
+ return _gf_string2ulonglong (str, n, 0);
}
int
gf_string2int8 (const char *str, int8_t *n)
{
- long l = 0L;
- int rv = 0;
+ long l = 0L;
+ int rv = 0;
- rv = _gf_string2long (str, &l, 0);
- if (rv != 0)
- return rv;
+ rv = _gf_string2long (str, &l, 0);
+ if (rv != 0)
+ return rv;
- if (l >= INT8_MIN && l <= INT8_MAX)
- {
- *n = (int8_t) l;
- return 0;
- }
+ if ((l >= INT8_MIN) && (l <= INT8_MAX)) {
+ *n = (int8_t) l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
gf_string2int16 (const char *str, int16_t *n)
{
- long l = 0L;
- int rv = 0;
+ long l = 0L;
+ int rv = 0;
- rv = _gf_string2long (str, &l, 0);
- if (rv != 0)
- return rv;
+ rv = _gf_string2long (str, &l, 0);
+ if (rv != 0)
+ return rv;
- if (l >= INT16_MIN && l <= INT16_MAX)
- {
- *n = (int16_t) l;
- return 0;
- }
+ if ((l >= INT16_MIN) && (l <= INT16_MAX)) {
+ *n = (int16_t) l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
gf_string2int32 (const char *str, int32_t *n)
{
- long l = 0L;
- int rv = 0;
+ long l = 0L;
+ int rv = 0;
- rv = _gf_string2long (str, &l, 0);
- if (rv != 0)
- return rv;
+ rv = _gf_string2long (str, &l, 0);
+ if (rv != 0)
+ return rv;
- if (l >= INT32_MIN && l <= INT32_MAX)
- {
- *n = (int32_t) l;
- return 0;
- }
+ if ((l >= INT32_MIN) && (l <= INT32_MAX)) {
+ *n = (int32_t) l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
gf_string2int64 (const char *str, int64_t *n)
{
- long long l = 0LL;
- int rv = 0;
+ long long l = 0LL;
+ int rv = 0;
- rv = _gf_string2longlong (str, &l, 0);
- if (rv != 0)
- return rv;
+ rv = _gf_string2longlong (str, &l, 0);
+ if (rv != 0)
+ return rv;
- if (l >= INT64_MIN && l <= INT64_MAX)
- {
- *n = (int64_t) l;
- return 0;
- }
+ if ((l >= INT64_MIN) && (l <= INT64_MAX)) {
+ *n = (int64_t) l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
gf_string2uint8 (const char *str, uint8_t *n)
{
- unsigned long l = 0L;
- int rv = 0;
+ unsigned long l = 0L;
+ int rv = 0;
- rv = _gf_string2ulong (str, &l, 0);
- if (rv != 0)
- return rv;
+ rv = _gf_string2ulong (str, &l, 0);
+ if (rv != 0)
+ return rv;
- if (l >= 0 && l <= UINT8_MAX)
- {
- *n = (uint8_t) l;
- return 0;
- }
+ if (l >= 0 && l <= UINT8_MAX) {
+ *n = (uint8_t) l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
gf_string2uint16 (const char *str, uint16_t *n)
{
- unsigned long l = 0L;
- int rv = 0;
+ unsigned long l = 0L;
+ int rv = 0;
- rv = _gf_string2ulong (str, &l, 0);
- if (rv != 0)
- return rv;
+ rv = _gf_string2ulong (str, &l, 0);
+ if (rv != 0)
+ return rv;
- if (l >= 0 && l <= UINT16_MAX)
- {
- *n = (uint16_t) l;
- return 0;
- }
+ if (l >= 0 && l <= UINT16_MAX) {
+ *n = (uint16_t) l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
gf_string2uint32 (const char *str, uint32_t *n)
{
- unsigned long l = 0L;
- int rv = 0;
+ unsigned long l = 0L;
+ int rv = 0;
- rv = _gf_string2ulong (str, &l, 0);
- if (rv != 0)
- return rv;
+ rv = _gf_string2ulong (str, &l, 0);
+ if (rv != 0)
+ return rv;
- if (l >= 0 && l <= UINT32_MAX)
- {
- *n = (uint32_t) l;
- return 0;
- }
+ if (l >= 0 && l <= UINT32_MAX) {
+ *n = (uint32_t) l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
gf_string2uint64 (const char *str, uint64_t *n)
{
- unsigned long long l = 0ULL;
- int rv = 0;
+ unsigned long long l = 0ULL;
+ int rv = 0;
- rv = _gf_string2ulonglong (str, &l, 0);
- if (rv != 0)
- return rv;
+ rv = _gf_string2ulonglong (str, &l, 0);
+ if (rv != 0)
+ return rv;
- if (l >= 0 && l <= UINT64_MAX)
- {
- *n = (uint64_t) l;
- return 0;
- }
+ if (l >= 0 && l <= UINT64_MAX) {
+ *n = (uint64_t) l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
gf_string2ulong_base10 (const char *str, unsigned long *n)
{
- return _gf_string2ulong (str, n, 10);
+ return _gf_string2ulong (str, n, 10);
}
int
gf_string2uint_base10 (const char *str, unsigned int *n)
{
- return _gf_string2uint (str, n, 10);
+ return _gf_string2uint (str, n, 10);
}
int
gf_string2uint8_base10 (const char *str, uint8_t *n)
{
- unsigned long l = 0L;
- int rv = 0;
+ unsigned long l = 0L;
+ int rv = 0;
- rv = _gf_string2ulong (str, &l, 10);
- if (rv != 0)
- return rv;
+ rv = _gf_string2ulong (str, &l, 10);
+ if (rv != 0)
+ return rv;
- if (l >= 0 && l <= UINT8_MAX)
- {
- *n = (uint8_t) l;
- return 0;
- }
+ if (l >= 0 && l <= UINT8_MAX) {
+ *n = (uint8_t) l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
gf_string2uint16_base10 (const char *str, uint16_t *n)
{
- unsigned long l = 0L;
- int rv = 0;
+ unsigned long l = 0L;
+ int rv = 0;
- rv = _gf_string2ulong (str, &l, 10);
- if (rv != 0)
- return rv;
+ rv = _gf_string2ulong (str, &l, 10);
+ if (rv != 0)
+ return rv;
- if (l >= 0 && l <= UINT16_MAX)
- {
- *n = (uint16_t) l;
- return 0;
- }
+ if (l >= 0 && l <= UINT16_MAX) {
+ *n = (uint16_t) l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
gf_string2uint32_base10 (const char *str, uint32_t *n)
{
- unsigned long l = 0L;
- int rv = 0;
+ unsigned long l = 0L;
+ int rv = 0;
- rv = _gf_string2ulong (str, &l, 10);
- if (rv != 0)
- return rv;
+ rv = _gf_string2ulong (str, &l, 10);
+ if (rv != 0)
+ return rv;
- if (l >= 0 && l <= UINT32_MAX)
- {
- *n = (uint32_t) l;
- return 0;
- }
+ if (l >= 0 && l <= UINT32_MAX) {
+ *n = (uint32_t) l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
gf_string2uint64_base10 (const char *str, uint64_t *n)
{
- unsigned long long l = 0ULL;
- int rv = 0;
+ unsigned long long l = 0ULL;
+ int rv = 0;
- rv = _gf_string2ulonglong (str, &l, 10);
- if (rv != 0)
- return rv;
+ rv = _gf_string2ulonglong (str, &l, 10);
+ if (rv != 0)
+ return rv;
- if (l >= 0 && l <= UINT64_MAX)
- {
- *n = (uint64_t) l;
- return 0;
- }
+ if (l >= 0 && l <= UINT64_MAX) {
+ *n = (uint64_t) l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
+}
+
+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;
+ } else {
+ ret = gf_asprintf (&str, "%luBytes", n);
+ if (ret < 0)
+ goto err;
+ }
+ return str;
+err:
+ return NULL;
}
int
gf_string2bytesize (const char *str, uint64_t *n)
{
- uint64_t value = 0ULL;
- char *tail = NULL;
- int old_errno = 0;
- const char *s = NULL;
+ double value = 0.0;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
+
+ if (str == NULL || n == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
- if (str == NULL || n == NULL)
- {
- errno = EINVAL;
- return -1;
- }
+ for (s = str; *s != '\0'; s++) {
+ if (isspace (*s))
+ continue;
+ if (*s == '-')
+ return -1;
+ break;
+ }
- 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;
- }
+ old_errno = errno;
+ errno = 0;
+ value = strtod (str, &tail);
+ if (str == tail)
+ errno = EINVAL;
- old_errno = errno;
- errno = 0;
- value = strtoull (str, &tail, 10);
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- if (errno == ERANGE || errno == EINVAL)
- {
- return -1;
- }
+ if (errno == 0)
+ errno = old_errno;
- if (errno == 0)
- {
- errno = old_errno;
- }
+ 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
+ return -1;
+ }
- 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 ((UINT64_MAX - value) < 0) {
+ errno = ERANGE;
+ return -1;
+ }
- *n = value;
+ *n = (uint64_t) value;
- return 0;
+ return 0;
+}
+
+int
+gf_string2percent_or_bytesize (const char *str,
+ uint64_t *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_log_callingfn (THIS->name, GF_LOG_WARNING,
+ "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;
+
+ if (errno == 0)
+ errno = old_errno;
+
+ 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;
+ }
+
+ *n = (uint64_t) value;
+
+ return 0;
}
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;
+ 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;
}
int
gf_string2boolean (const char *str, gf_boolean_t *b)
{
- if (str == NULL) {
- return -1;
- }
+ if (str == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "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, "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;
- }
+ 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;
+ return -1;
}
int
gf_lockfd (int fd)
{
- struct gf_flock fl;
+ struct gf_flock fl;
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
- fl.l_start = 0;
- fl.l_len = 0;
+ fl.l_type = F_WRLCK;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0;
+ fl.l_len = 0;
- return fcntl (fd, F_SETLK, &fl);
+ return fcntl (fd, F_SETLK, &fl);
}
int
gf_unlockfd (int fd)
{
- struct gf_flock fl;
+ struct gf_flock fl;
- fl.l_type = F_UNLCK;
- fl.l_whence = SEEK_SET;
- fl.l_start = 0;
- fl.l_len = 0;
+ fl.l_type = F_UNLCK;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0;
+ fl.l_len = 0;
- return fcntl (fd, F_SETLK, &fl);
+ return fcntl (fd, F_SETLK, &fl);
}
static void
@@ -1469,65 +1665,6 @@ get_checksum_for_file (int fd, uint32_t *checksum)
}
-/* One should pass the command here with command with full path,
- otherwise, execv will fail */
-int
-gf_system (const char *command)
-{
- 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, };
-
- dupcmd = gf_strdup (command);
- if (!dupcmd)
- goto out;
-
- 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;
- }
-out:
- if (dupcmd)
- GF_FREE (dupcmd);
-
- return ret;
-}
-
int
get_checksum_for_path (char *path, uint32_t *checksum)
{
@@ -1540,7 +1677,7 @@ get_checksum_for_path (char *path, uint32_t *checksum)
fd = open (path, O_RDWR);
if (fd == -1) {
- gf_log ("", GF_LOG_ERROR, "Unable to open %s, errno: %d",
+ gf_log (THIS->name, GF_LOG_ERROR, "Unable to open %s, errno: %d",
path, errno);
goto out;
}
@@ -1566,3 +1703,1206 @@ strtail (char *str, const char *pattern)
return NULL;
}
+
+void
+skipwhite (char **s)
+{
+ while (isspace (**s))
+ (*s)++;
+}
+
+char *
+nwstrtail (char *str, char *pattern)
+{
+ for (;;) {
+ skipwhite (&str);
+ skipwhite (&pattern);
+
+ if (*str != *pattern || !*str)
+ break;
+
+ str++;
+ pattern++;
+ }
+
+ return *pattern ? NULL : str;
+}
+
+void
+skipword (char **s)
+{
+ if (!*s)
+ return;
+
+ skipwhite (s);
+
+ while (!isspace(**s))
+ (*s)++;
+}
+
+char *
+get_nth_word (const char *str, int n)
+{
+ char buf[4096] = {0};
+ char *start = NULL;
+ char *word = NULL;
+ int i = 0;
+ int word_len = 0;
+ const char *end = NULL;
+
+ if (!str)
+ goto out;
+
+ snprintf (buf, sizeof (buf), "%s", str);
+ start = buf;
+
+ for (i = 0; i < n-1; i++)
+ skipword (&start);
+
+ skipwhite (&start);
+ end = strpbrk ((const char *)start, " \t\n\0");
+
+ if (!end)
+ goto out;
+
+ word_len = abs (end - start);
+
+ word = GF_CALLOC (1, word_len + 1, gf_common_mt_strdup);
+ if (!word)
+ goto out;
+
+ strncpy (word, start, word_len);
+ *(word + word_len) = '\0';
+ out:
+ return word;
+}
+
+/* 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)
+{
+ 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)));
+
+out:
+ GF_FREE (dup_addr);
+ return ret;
+}
+
+/* Matches all ipv4 address, if wildcard_acc is true '*' wildcard pattern for*
+ subnets is considerd 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
+ * delimeters.
+ */
+ if (length <= 0 ||
+ (strstr (address, "..")) ||
+ (!isdigit (tmp[length - 1]) && (tmp[length - 1] != '*'))) {
+ ret = 0;
+ goto out;
+ }
+
+ prev = tmp;
+ 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);
+ }
+
+ if ((octets > 4) || (octets < 4 && !is_wildcard)) {
+ ret = 0;
+ }
+
+out:
+ GF_FREE (tmp);
+ return ret;
+}
+
+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 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;
+ }
+ }
+ }
+
+ 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);
+ }
+
+ if ((hex_numbers > 8) || (hex_numbers < 8 && !is_wildcard
+ && !is_compressed)) {
+ ret = 0;
+ }
+
+out:
+ GF_FREE (tmp);
+ return ret;
+}
+
+char
+valid_internet_address (char *address, gf_boolean_t wildcard_acc)
+{
+ char ret = 0;
+ int length = 0;
+
+ if (address == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
+ goto out;
+ }
+
+ length = strlen (address);
+ if (length == 0)
+ goto out;
+
+ 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;
+}
+
+/**
+ * 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)
+{
+ if (!a || !b) {
+ gf_log ("common-utils", GF_LOG_ERROR, "Invalid arguments"
+ " to gf_sock_union_equal_addr");
+ 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_log ("common-utils", GF_LOG_DEBUG,
+ "Unsupported/invalid address family");
+ break;
+ }
+
+ return _gf_false;
+}
+
+/*Thread safe conversion function*/
+char *
+uuid_utoa (uuid_t uuid)
+{
+ char *uuid_buffer = glusterfs_uuid_buf_get(THIS->ctx);
+ uuid_unparse (uuid, uuid_buffer);
+ return uuid_buffer;
+}
+
+/*Re-entrant conversion function*/
+char *
+uuid_utoa_r (uuid_t uuid, char *dst)
+{
+ if(!dst)
+ return NULL;
+ uuid_unparse (uuid, dst);
+ return dst;
+}
+
+/*Thread safe conversion function*/
+char *
+lkowner_utoa (gf_lkowner_t *lkowner)
+{
+ char *lkowner_buffer = glusterfs_lkowner_buf_get(THIS->ctx);
+ 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;
+}
+
+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((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;
+ }
+ }
+}
+
+int
+gf_is_str_int (const char *value)
+{
+ int flag = 0;
+ char *str = NULL;
+ char *fptr = NULL;
+
+ GF_VALIDATE_OR_GOTO (THIS->name, value, out);
+
+ str = gf_strdup (value);
+ if (!str)
+ goto out;
+
+ fptr = str;
+
+ while (*str) {
+ if (!isdigit(*str)) {
+ flag = 1;
+ goto out;
+ }
+ str++;
+ }
+
+out:
+ GF_FREE (fptr);
+
+ return flag;
+}
+/*
+ * rounds up nr to power of two. If nr is already a power of two, just returns
+ * nr
+ */
+
+inline int32_t
+gf_roundup_power_of_two (int32_t nr)
+{
+ int32_t result = 1;
+
+ if (nr < 0) {
+ gf_log ("common-utils", GF_LOG_WARNING,
+ "negative number passed");
+ 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.
+ */
+
+inline int32_t
+gf_roundup_next_power_of_two (int32_t nr)
+{
+ int32_t result = 1;
+
+ if (nr < 0) {
+ gf_log ("common-utils", GF_LOG_WARNING,
+ "negative number passed");
+ result = -1;
+ goto out;
+ }
+
+ while (result <= nr)
+ result *= 2;
+
+out:
+ return result;
+}
+
+int
+validate_brick_name (char *brick)
+{
+ char *delimiter = NULL;
+ int ret = 0;
+ delimiter = strrchr (brick, ':');
+ if (!delimiter || delimiter == brick
+ || *(delimiter+1) != '/')
+ ret = -1;
+
+ return ret;
+}
+
+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;
+}
+
+
+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_BSD_HOST_OS || defined GF_DARWIN_HOST_OS
+
+ size_t len = sizeof(memsize);
+ int name [] = { CTL_HW, HW_PHYSMEM };
+
+ sysctl (name, 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_CALLOC (1, 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) {
+ memset (str, 0, len);
+ strncpy (str, new_str, new_len);
+ }
+
+ GF_FREE (new_str);
+ return new_len;
+}
+
+int
+gf_canonicalize_path (char *path)
+{
+ int ret = -1;
+ int path_len = 0;
+ int dir_path_len = 0;
+ char *tmppath = NULL;
+ char *dir = NULL;
+ char *tmpstr = NULL;
+
+ if (!path || *path != '/')
+ goto out;
+
+ 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);
+ strncpy ((path + path_len + 1), dir, dir_path_len);
+ path_len += dir_path_len + 1;
+ dir = strtok_r (NULL, "/", &tmpstr);
+ if (dir)
+ strncpy ((path + path_len), "/", 1);
+ }
+ path[path_len] = '\0';
+ ret = 0;
+
+ out:
+ if (ret)
+ gf_log ("common-utils", GF_LOG_ERROR,
+ "Path manipulation failed");
+
+ GF_FREE(tmppath);
+
+ return ret;
+}
+
+static const char *__gf_timefmts[] = {
+ "%F %T",
+ "%Y/%m/%d-%T",
+ "%b %d %T",
+ "%F %H%M%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"
+};
+
+void
+_gf_timestuff (gf_timefmts *fmt, const char ***fmts, const char ***zeros)
+{
+ *fmt = gf_timefmt_last;
+ *fmts = __gf_timefmts;
+ *zeros = __gf_zerotimes;
+}
+
+
+char *
+generate_glusterfs_ctx_id (void)
+{
+ char tmp_str[1024] = {0,};
+ char hostname[256] = {0,};
+ struct timeval tv = {0,};
+ char now_str[32];
+
+ if (gettimeofday (&tv, NULL) == -1) {
+ gf_log ("glusterfsd", GF_LOG_ERROR,
+ "gettimeofday: failed %s",
+ strerror (errno));
+ }
+
+ if (gethostname (hostname, 256) == -1) {
+ gf_log ("glusterfsd", GF_LOG_ERROR,
+ "gethostname: failed %s",
+ strerror (errno));
+ }
+
+ gf_time_fmt (now_str, sizeof now_str, tv.tv_sec, gf_timefmt_Ymd_T);
+ snprintf (tmp_str, sizeof tmp_str, "%s-%d-%s:%"
+#ifdef GF_DARWIN_HOST_OS
+ PRId32,
+#else
+ "ld",
+#endif
+ hostname, getpid(), now_str, tv.tv_usec);
+
+ return gf_strdup (tmp_str);
+}
+
+char *
+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_log ("glusterfs", GF_LOG_WARNING, "could not open "
+ "the file /proc/sys/net/ipv4/ip_local_reserved_ports "
+ "for getting reserved ports info (%s)",
+ strerror (errno));
+ goto out;
+ }
+
+ ret = read (proc_fd, buffer, sizeof (buffer));
+ if (ret < 0) {
+ gf_log ("glusterfs", GF_LOG_WARNING, "could not "
+ "read the file %s for getting reserved ports "
+ "info (%s)", proc_file, strerror (errno));
+ goto out;
+ }
+ ports_info = gf_strdup (buffer);
+
+out:
+ if (proc_fd != -1)
+ close (proc_fd);
+#endif /* GF_LINUX_HOST_OS */
+ return ports_info;
+}
+
+int
+gf_process_reserved_ports (gf_boolean_t *ports)
+{
+ int ret = -1;
+#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_log ("glusterfs", GF_LOG_WARNING, "Not able to get reserved "
+ "ports, hence there is a possibility that glusterfs "
+ "may consume reserved port");
+ goto out;
+ }
+
+ blocked_port = strtok_r (ports_info, ",\n",&tmp);
+
+ while (blocked_port) {
+ gf_ports_reserved (blocked_port, ports);
+ blocked_port = strtok_r (NULL, ",\n", &tmp);
+ }
+
+ ret = 0;
+
+out:
+ GF_FREE (ports_info);
+#endif /* GF_LINUX_HOST_OS */
+ return ret;
+}
+
+gf_boolean_t
+gf_ports_reserved (char *blocked_port, gf_boolean_t *ports)
+{
+ gf_boolean_t result = _gf_false;
+ char *range_port = NULL;
+ int16_t tmp_port1, 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_string2int16 (blocked_port, &tmp_port1) == 0) {
+ if (tmp_port1 > (GF_CLIENT_PORT_CEILING - 1)
+ || tmp_port1 < 0) {
+ gf_log ("glusterfs-socket", GF_LOG_WARNING,
+ "invalid port %d", tmp_port1);
+ result = _gf_true;
+ goto out;
+ } else {
+ gf_log ("glusterfs", GF_LOG_DEBUG,
+ "blocking port %d", tmp_port1);
+ ports[tmp_port1] = _gf_true;
+ }
+ } else {
+ gf_log ("glusterfs-socket", GF_LOG_WARNING, "%s is "
+ "not a valid port identifier", blocked_port);
+ result = _gf_true;
+ goto out;
+ }
+ } else {
+ range_port = strtok (blocked_port, "-");
+ if (!range_port){
+ result = _gf_true;
+ goto out;
+ }
+ if (gf_string2int16 (range_port, &tmp_port1) == 0) {
+ if (tmp_port1 > (GF_CLIENT_PORT_CEILING - 1))
+ tmp_port1 = GF_CLIENT_PORT_CEILING - 1;
+ 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_string2int16 (range_port, &tmp_port2) == 0) {
+ if (tmp_port2 >
+ (GF_CLIENT_PORT_CEILING - 1))
+ tmp_port2 = GF_CLIENT_PORT_CEILING - 1;
+ if (tmp_port2 < 0)
+ tmp_port2 = 0;
+ }
+ gf_log ("glusterfs", GF_LOG_DEBUG, "lower: %d, higher: %d",
+ tmp_port1, tmp_port2);
+ for (; tmp_port1 <= tmp_port2; tmp_port1++)
+ ports[tmp_port1] = _gf_true;
+ }
+
+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_get_hostname_from_ip (char *client_ip, char **hostname)
+{
+ 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;
+
+ /* if ipv4, reverse lookup the hostname to
+ * allow FQDN based rpc authentication
+ */
+ if (valid_ipv4_address (client_ip, strlen (client_ip), 0) == _gf_false) {
+ /* 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;
+ 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;
+
+ 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;
+ }
+
+ ret = getnameinfo (client_sockaddr,
+ sizeof (*client_sockaddr),
+ client_hostname, sizeof (client_hostname),
+ NULL, 0, 0);
+ if (ret) {
+ gf_log ("common-utils", GF_LOG_ERROR,
+ "Could not lookup hostname of %s : %s",
+ client_ip, gai_strerror (ret));
+ ret = -1;
+ goto out;
+ }
+
+ *hostname = gf_strdup ((char *)client_hostname);
+ out:
+ if (client_ip_copy)
+ GF_FREE (client_ip_copy);
+
+ return ret;
+}
+
+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_log (this->name, GF_LOG_ERROR, "getifaddrs() failed: %s\n",
+ gai_strerror(ret));
+ 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;
+
+ if (family != AF_INET && family != AF_INET6)
+ continue;
+
+ 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_log (this->name, GF_LOG_ERROR,
+ "getnameinfo() failed: %s\n",
+ gai_strerror(ret));
+ goto out;
+ }
+
+ /*
+ * 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 (strncmp (ip, host, NI_MAXHOST) == 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%s is local address at interface %s",
+ ip, ifa->ifa_name);
+ found = _gf_true;
+ goto out;
+ }
+ }
+out:
+ if(ifaddr)
+ freeifaddrs (ifaddr);
+ return found;
+}
+
+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_log ("glusterd", GF_LOG_ERROR, "Invalid family");
+ return NULL;
+ }
+
+ if (!inet_ntop(addr->ai_family, in_addr, buf, sizeof(buf))) {
+ gf_log ("glusterd", GF_LOG_ERROR, "String conversion failed");
+ return NULL;
+ }
+
+ *ip = strdup (buf);
+ return *ip;
+}
+
+gf_boolean_t
+gf_is_loopback_localhost (const struct sockaddr *sa, char *hostname)
+{
+ 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_log ("glusterd", GF_LOG_ERROR,
+ "unknown address family %d for %s",
+ sa->sa_family, hostname);
+ break;
+ }
+
+ return is_local;
+}
+
+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;
+
+ this = THIS;
+ ret = getaddrinfo (hostname, NULL, NULL, &result);
+
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error in getaddrinfo: %s\n",
+ gai_strerror(ret));
+ goto out;
+ }
+
+ for (res = result; res != NULL; res = res->ai_next) {
+ gf_log (this->name, GF_LOG_DEBUG, "%s ",
+ get_ip_from_addrinfo (res, &ip));
+
+ found = gf_is_loopback_localhost (res->ai_addr, hostname)
+ || gf_interface_search (ip);
+ if (found)
+ goto out;
+ }
+
+out:
+ if (result)
+ freeaddrinfo (result);
+
+ if (!found)
+ gf_log (this->name, GF_LOG_DEBUG, "%s is not local", hostname);
+
+ return found;
+}
+
+gf_boolean_t
+gf_is_same_address (char *name1, char *name2)
+{
+ 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;
+
+ gai_err = getaddrinfo(name1,NULL,NULL,&addr1);
+ if (gai_err != 0) {
+ gf_log (name1, GF_LOG_WARNING,
+ "error in getaddrinfo: %s\n", gai_strerror(gai_err));
+ goto out;
+ }
+
+ gai_err = getaddrinfo(name2,NULL,NULL,&addr2);
+ if (gai_err != 0) {
+ gf_log (name2, GF_LOG_WARNING,
+ "error in getaddrinfo: %s\n", gai_strerror(gai_err));
+ 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;
+ }
+ }
+
+out:
+ if (addr1) {
+ freeaddrinfo(addr1);
+ }
+ if (addr2) {
+ freeaddrinfo(addr2);
+ }
+ return ret;
+
+}
+
+
+/* Sets log file path from user provided arguments */
+int
+gf_set_log_file_path (cmd_args_t *cmd_args)
+{
+ int i = 0;
+ int j = 0;
+ int ret = 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 (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) {
+
+ ret = gf_asprintf (&cmd_args->log_file,
+ DEFAULT_LOG_FILE_DIRECTORY "/%s-%s-%d.log",
+ cmd_args->volfile_server,
+ cmd_args->volfile_id, getpid());
+ if (ret > 0)
+ ret = 0;
+ }
+done:
+ return ret;
+}
+
+int
+gf_thread_create (pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start_routine)(void *), void *arg)
+{
+ sigset_t set, old;
+ int ret;
+
+ sigemptyset (&set);
+
+ 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);
+
+ pthread_sigmask (SIG_SETMASK, &old, NULL);
+
+ return ret;
+}
diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h
index 4371888d0..3c99a4212 100644
--- a/libglusterfs/src/common-utils.h
+++ b/libglusterfs/src/common-utils.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
#ifndef _COMMON_UTILS_H
@@ -32,9 +23,10 @@
#include <string.h>
#include <assert.h>
#include <pthread.h>
+#include <openssl/md5.h>
#ifndef GF_BSD_HOST_OS
#include <alloca.h>
-#endif
+#endif
void trap (void);
@@ -47,6 +39,8 @@ void trap (void);
#include "glusterfs.h"
#include "locking.h"
#include "mem-pool.h"
+#include "uuid.h"
+
#define min(a,b) ((a)<(b)?(a):(b))
@@ -67,77 +61,185 @@ void trap (void);
#define GF_UNIT_TB_STRING "TB"
#define GF_UNIT_PB_STRING "PB"
+#define GF_UNIT_PERCENT_STRING "%"
+
+#define GEOREP "geo-replication"
+#define GHADOOP "glusterfs-hadoop"
+
+#define GF_SELINUX_XATTR_KEY "security.selinux"
-enum _gf_boolean
+#define WIPE(statp) do { typeof(*statp) z = {0,}; if (statp) *statp = z; } while (0)
+
+#define IS_EXT_FS(fs_name) \
+ (!strcmp (fs_name, "ext2") || \
+ !strcmp (fs_name, "ext3") || \
+ !strcmp (fs_name, "ext4"))
+
+/* Defining this here as it is needed by glusterd for setting
+ * nfs port in volume status.
+ */
+#define GF_NFS3_PORT 2049
+#define GF_CLIENT_PORT_CEILING 1024
+
+enum _gf_boolean
{
- _gf_false = 0,
+ _gf_false = 0,
_gf_true = 1
};
+/*
+ * we could have initialized these as +ve values and treated
+ * them as negative while comparing etc.. (which would have
+ * saved us with the pain of assigning values), but since we
+ * only have a couple of clients that use this feature, it's
+ * okay.
+ */
+enum _gf_client_pid
+{
+ GF_CLIENT_PID_MAX = 0,
+ GF_CLIENT_PID_GSYNCD = -1,
+ GF_CLIENT_PID_HADOOP = -2,
+ GF_CLIENT_PID_DEFRAG = -3,
+};
+
typedef enum _gf_boolean gf_boolean_t;
+typedef enum _gf_client_pid gf_client_pid_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];
+void gf_log_dump_graph (FILE *specfp, glusterfs_graph_t *graph);
+void gf_print_trace (int32_t signal, glusterfs_ctx_t *ctx);
+int gf_set_log_file_path (cmd_args_t *cmd_args);
#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 ((this ? this->name : "(Govinda! Govinda!)"), \
- GF_LOG_ERROR, \
- "invalid argument: " #arg); \
+ gf_log_callingfn ((this ? (this->name) : \
+ "(Govinda! Govinda!)"), \
+ GF_LOG_WARNING, \
+ "invalid argument: " #arg); \
goto label; \
} \
- } while (0);
+ } while (0)
-#define GF_VALIDATE_OR_GOTO(name,arg,label) do { \
- if (!arg) { \
- errno = EINVAL; \
- gf_log (name, GF_LOG_ERROR, \
- "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 (name, GF_LOG_ERROR, \
- "invalid argument: " #arg); \
+ 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 (name, GF_LOG_ERROR, \
- "invalid argument: " #arg); \
- goto label; \
- } \
- } while (0);
+ }while (0)
+
+#define GF_ASSERT_AND_GOTO_WITH_ERROR(name, arg, label, errno, error) do { \
+ if (!arg) { \
+ GF_ASSERT (0); \
+ errno = error; \
+ 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_REMOVE_SLASH_FROM_PATH(path, string) \
+ do { \
+ int i = 0; \
+ for (i = 1; i < strlen (path); i++) { \
+ string[i-1] = path[i]; \
+ if (string[i-1] == '/') \
+ string[i-1] = '-'; \
+ } \
+ } while (0)
+
+#define GF_IF_INTERNAL_XATTR_GOTO(pattern, dict, op_errno, label) \
+ do { \
+ if (!dict) { \
+ gf_log (this->name, GF_LOG_ERROR, \
+ "setxattr dict is null"); \
+ goto label; \
+ } \
+ if (dict_foreach_fnmatch (dict, pattern, \
+ dict_null_foreach_fn, \
+ NULL) > 0) { \
+ op_errno = EPERM; \
+ gf_log (this->name, GF_LOG_ERROR, \
+ "attempt to set internal" \
+ " xattr: %s: %s", pattern, \
+ strerror (op_errno)); \
+ goto label; \
+ } \
+ } while (0)
+
+#define GF_IF_NATIVE_XATTR_GOTO(pattern, key, op_errno, label) \
+ do { \
+ if (!key) { \
+ gf_log (this->name, GF_LOG_ERROR, \
+ "no key for removexattr"); \
+ goto label; \
+ } \
+ if (!fnmatch (pattern, key, 0)) { \
+ op_errno = EPERM; \
+ gf_log (this->name, GF_LOG_ERROR, \
+ "attempt to remove internal " \
+ "xattr: %s: %s", key, \
+ strerror (op_errno)); \
+ goto label; \
+ } \
+ } while (0)
+
#define GF_FILE_CONTENT_REQUESTED(_xattr_req,_content_limit) \
(dict_get_uint64 (_xattr_req, "glusterfs.content", _content_limit) == 0)
-#define GF_ASSERT(x) \
- do { \
- if (!(x)) { \
- gf_log_callingfn ("", GF_LOG_ERROR, \
- "Assertion failed: " #x); \
- } \
- } while (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_UUID_ASSERT(u) \
+ if (uuid_is_null (u))\
+ GF_ASSERT (!"uuid null");
+
+union gf_sock_union {
+ struct sockaddr_storage storage;
+ struct sockaddr_in6 sin6;
+ struct sockaddr_in sin;
+ struct sockaddr sa;
+};
+
+#define GF_HIDDEN_PATH ".glusterfs"
static inline void
iov_free (struct iovec *vector, int count)
@@ -165,7 +267,7 @@ iov_length (const struct iovec *vector, int count)
static inline struct iovec *
-iov_dup (struct iovec *vector, int count)
+iov_dup (const struct iovec *vector, int count)
{
int bytecount = 0;
int i;
@@ -245,6 +347,65 @@ iov_unload (char *buf, const struct iovec *vector, int count)
}
+static inline size_t
+iov_load (const struct iovec *vector, int count, char *buf, int size)
+{
+ size_t left = size;
+ size_t cp = 0;
+ int ret = 0;
+ int i = 0;
+
+ while (left && i < count) {
+ cp = min (vector[i].iov_len, left);
+ if (vector[i].iov_base != buf + (size - left))
+ memcpy (vector[i].iov_base, buf + (size - left), cp);
+ ret += cp;
+ left -= cp;
+ if (left)
+ i++;
+ }
+
+ return ret;
+}
+
+
+static inline size_t
+iov_copy (const struct iovec *dst, int dcnt,
+ const struct iovec *src, int scnt)
+{
+ size_t ret = 0;
+ size_t left = 0;
+ size_t min_i = 0;
+ int s_i = 0, s_ii = 0;
+ int d_i = 0, d_ii = 0;
+
+ ret = min (iov_length (dst, dcnt), iov_length (src, scnt));
+ left = ret;
+
+ while (left) {
+ min_i = min (dst[d_i].iov_len - d_ii, src[s_i].iov_len - s_ii);
+ memcpy (dst[d_i].iov_base + d_ii, src[s_i].iov_base + s_ii,
+ min_i);
+
+ d_ii += min_i;
+ if (d_ii == dst[d_i].iov_len) {
+ d_ii = 0;
+ d_i++;
+ }
+
+ s_ii += min_i;
+ if (s_ii == src[s_i].iov_len) {
+ s_ii = 0;
+ s_i++;
+ }
+
+ left -= min_i;
+ }
+
+ return ret;
+}
+
+
static inline int
mem_0filled (const char *buf, size_t size)
{
@@ -290,9 +451,55 @@ memdup (const void *ptr, size_t size)
return newptr;
}
+typedef enum {
+ gf_timefmt_default = 0,
+ gf_timefmt_FT = 0, /* YYYY-MM-DD hh:mm:ss */
+ gf_timefmt_Ymd_T, /* YYYY/MM-DD-hh:mm:ss */
+ gf_timefmt_bdT, /* ddd DD hh:mm:ss */
+ gf_timefmt_F_HMS, /* YYYY-MM-DD hhmmss */
+ gf_timefmt_last
+} gf_timefmts;
+
+static inline void
+gf_time_fmt (char *dst, size_t sz_dst, time_t utime, unsigned int fmt)
+{
+ extern void _gf_timestuff (gf_timefmts *, const char ***, const char ***);
+ static gf_timefmts timefmt_last = (gf_timefmts) -1;
+ static const char **fmts;
+ static const char **zeros;
+ struct tm tm;
+
+ if (timefmt_last == -1)
+ _gf_timestuff (&timefmt_last, &fmts, &zeros);
+ if (timefmt_last < fmt) fmt = gf_timefmt_default;
+ if (utime && gmtime_r (&utime, &tm) != NULL) {
+ strftime (dst, sz_dst, fmts[fmt], &tm);
+ } else {
+ strncpy (dst, "N/A", sz_dst);
+ }
+}
+
+int
+mkdir_p (char *path, mode_t mode, gf_boolean_t allow_symlinks);
+/*
+ * rounds up nr to power of two. If nr is already a power of two, just returns
+ * nr
+ */
+
+int
+gf_lstat_dir (const char *path, struct stat *stbuf_in);
+
+int32_t gf_roundup_power_of_two (int32_t nr);
+
+/*
+ * 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);
char *gf_trim (char *string);
-int gf_strsplit (const char *str, const char *delim,
+int gf_strsplit (const char *str, const char *delim,
char ***tokens, int *token_count);
int gf_volume_name_validate (const char *volume_name);
@@ -323,9 +530,11 @@ 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_string2percent_or_bytesize (const char *str, uint64_t *n,
+ gf_boolean_t *is_percent);
int gf_string2boolean (const char *str, gf_boolean_t *b);
-int gf_string2percent (const char *str, uint32_t *n);
+int gf_string2percent (const char *str, double *n);
int gf_string2time (const char *str, uint32_t *n);
int gf_lockfd (int fd);
@@ -334,9 +543,52 @@ 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);
-#endif /* _COMMON_UTILS_H */
+void skipwhite (char **s);
+char *nwstrtail (char *str, char *pattern);
+void skip_word (char **str);
+/* returns a new string with nth word of given string. n>=1 */
+char *get_nth_word (const char *str, int n);
+
+char valid_host_name (char *address, int length);
+char valid_ipv4_address (char *address, int length, gf_boolean_t wildcard_acc);
+char valid_ipv6_address (char *address, int length, gf_boolean_t wildcard_acc);
+char valid_internet_address (char *address, gf_boolean_t wildcard_acc);
+char valid_ipv4_wildcard_check (char *address);
+char valid_ipv6_wildcard_check (char *address);
+char valid_wildcard_internet_address (char *address);
+gf_boolean_t gf_sock_union_equal_addr (union gf_sock_union *a,
+ union gf_sock_union *b);
+
+char *uuid_utoa (uuid_t uuid);
+char *uuid_utoa_r (uuid_t uuid, char *dst);
+char *lkowner_utoa (gf_lkowner_t *lkowner);
+char *lkowner_utoa_r (gf_lkowner_t *lkowner, char *dst, int len);
+
+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);
+int validate_brick_name (char *brick);
+char *get_host_name (char *word, char **host);
+char *get_path_name (char *word, char **path);
+void gf_path_strip_trailing_slashes (char *path);
+uint64_t get_mem_size ();
+int gf_strip_whitespace (char *str, int len);
+int gf_canonicalize_path (char *path);
+char *generate_glusterfs_ctx_id (void);
+char *gf_get_reserved_ports();
+int gf_process_reserved_ports (gf_boolean_t ports[]);
+gf_boolean_t gf_ports_reserved (char *blocked_port, gf_boolean_t *ports);
+int gf_get_hostname_from_ip (char *client_ip, char **hostname);
+gf_boolean_t gf_is_local_addr (char *hostname);
+gf_boolean_t gf_is_same_address (char *host1, char *host2);
+void md5_wrapper(const unsigned char *data, size_t len, char *md5);
+
+int gf_thread_create (pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start_routine)(void *), void *arg);
+#endif /* _COMMON_UTILS_H */
diff --git a/libglusterfs/src/compat-errno.c b/libglusterfs/src/compat-errno.c
index 7b39b0a8d..fd5cc49ce 100644
--- a/libglusterfs/src/compat-errno.c
+++ b/libglusterfs/src/compat-errno.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
#ifndef _CONFIG_H
@@ -27,868 +18,870 @@
#include "compat-errno.h"
-static int32_t gf_error_to_errno_array[1024];
+static int32_t gf_error_to_errno_array[1024];
static int32_t gf_errno_to_error_array[1024];
static int32_t gf_compat_errno_init_done;
#ifdef GF_SOLARIS_HOST_OS
-static void
+static void
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;
+/* 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;
+/* 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;
+/* 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;
+/* 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;
+/* 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;
+/* 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;
+/* 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;
+/* 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;
+/* 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;
+/* 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;
+/* 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;
+/* 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;
+/* 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;
+/* 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;
+/* 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 */
+/* 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;
+ 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;
+/* 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;
+/* 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;
+/* 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;
+/* 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;
+/* 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;
+ /* 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;
+/* 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;
+/* 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 ;
+ return ;
}
#endif /* GF_SOLARIS_HOST_OS */
#ifdef GF_DARWIN_HOST_OS
-static void
+static void
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;
+ /* 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;
- /* ENEEDAUTH 81 / * Need authenticator */
- gf_error_to_errno_array[GF_ERROR_CODE_NEEDAUTH] = ENEEDAUTH;
- gf_errno_to_error_array[ENEEDAUTH] = GF_ERROR_CODE_NEEDAUTH;
+ /* 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;
+/* 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;
+/* 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;
+ /* 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;
+ /* 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;
+ /* 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;
+ /* 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;
+ /* 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;
+ /* 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;
+ /* 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;
+ /* 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;
+ /* 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;
+ /* 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;
+/* 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;
+/* 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;
+/* 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 ;
+ return ;
}
#endif /* GF_DARWIN_HOST_OS */
#ifdef GF_BSD_HOST_OS
-static void
+static void
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;
+ /* 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;
- /* 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;
+ /* 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;
- /* 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;
+ /* 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;
- /* 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;
+ /* 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;
- /* 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;
+ /* 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;
- /* 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;
+ /* 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;
- /* 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;
+ /* 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;
- /* 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;
+ /* 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;
- /* 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;
+ /* 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;
- /* 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;
+ /* 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;
- /* 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;
+ /* ECONNREFUSED 61 / * Connection refused */
+ gf_error_to_errno_array[GF_ERROR_CODE_CONNREFUSED] = ECONNREFUSED;
+ gf_errno_to_error_array[ECONNREFUSED] = GF_ERROR_CODE_CONNREFUSED;
- /* EAUTH 80 / * Authentication error */
- gf_error_to_errno_array[GF_ERROR_CODE_AUTH] = EAUTH;
- gf_errno_to_error_array[EAUTH] = GF_ERROR_CODE_AUTH;
+ /* 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;
- /* ENEEDAUTH 81 / * Need authenticator */
- gf_error_to_errno_array[GF_ERROR_CODE_NEEDAUTH] = ENEEDAUTH;
- gf_errno_to_error_array[ENEEDAUTH] = GF_ERROR_CODE_NEEDAUTH;
+ /* 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;
- /* EIDRM 82 / * Identifier removed */
- gf_error_to_errno_array[GF_ERROR_CODE_IDRM] = EIDRM;
- gf_errno_to_error_array[EIDRM] = GF_ERROR_CODE_IDRM;
+ /* 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;
- /* 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;
+ /* 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;
- /* 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;
+ /* 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;
- /* ECANCELED 85 / * Operation canceled */
- gf_error_to_errno_array[GF_ERROR_CODE_CANCELED] = ECANCELED;
- gf_errno_to_error_array[ECANCELED] = GF_ERROR_CODE_CANCELED;
+ /* 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;
- /* 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;
+ /* 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;
- /* 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;
+ /* 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;
- /* EBADMSG 89 / * Bad message */
- gf_error_to_errno_array[GF_ERROR_CODE_BADMSG] = EBADMSG;
- gf_errno_to_error_array[EBADMSG] = GF_ERROR_CODE_BADMSG;
+ /* 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;
- /* EMULTIHOP 90 / * Multihop attempted */
- gf_error_to_errno_array[GF_ERROR_CODE_MULTIHOP] = EMULTIHOP;
- gf_errno_to_error_array[EMULTIHOP] = GF_ERROR_CODE_MULTIHOP;
+ /* 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;
- /* 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;
+ /* 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;
- /* EPROTO 92 / * Protocol error */
- gf_error_to_errno_array[GF_ERROR_CODE_PROTO] = EPROTO;
- gf_errno_to_error_array[EPROTO] = GF_ERROR_CODE_PROTO;
+ /* 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;
- return ;
+ /* 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;
+
+ /* EMULTIHOP 90 / * Multihop attempted */
+ gf_error_to_errno_array[GF_ERROR_CODE_MULTIHOP] = EMULTIHOP;
+ gf_errno_to_error_array[EMULTIHOP] = GF_ERROR_CODE_MULTIHOP;
+
+ /* 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 ;
}
#endif /* GF_BSD_HOST_OS */
#ifdef GF_LINUX_HOST_OS
-static void
+static void
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 */
@@ -896,43 +889,42 @@ init_compat_errno_arrays ()
static void
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
+int32_t
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
+int32_t
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
index bdd8becfd..65e52081d 100644
--- a/libglusterfs/src/compat-errno.h
+++ b/libglusterfs/src/compat-errno.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
#ifndef __COMPAT_ERRNO_H__
@@ -199,9 +190,9 @@
/* Solaris */
-/* ENOTACTIVE 73 / * Facility is not active */
-#define GF_ERROR_CODE_NOTACTIVE 801
-/* ELOCKUNMAPPED 72 / * locked lock was unmapped */
+/* 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 */
@@ -231,8 +222,8 @@
#define EBADFD EBADRPC
#endif /* EBADFD */
-/* These functions are defined for all the OS flags, but content will
- * be different for each OS flag.
+/* 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);
diff --git a/libglusterfs/src/compat.c b/libglusterfs/src/compat.c
index 081869e4b..eb6d8d4b7 100644
--- a/libglusterfs/src/compat.c
+++ b/libglusterfs/src/compat.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
#ifndef _CONFIG_H
@@ -35,275 +26,422 @@
#include "compat.h"
#include "common-utils.h"
+#include "iatt.h"
+#include "inode.h"
#ifdef GF_SOLARIS_HOST_OS
+int
+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
-solaris_fsetxattr(int fd,
- 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 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, 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);
+ } 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;
+ }
+
+ 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.
+*/
-int
-solaris_fgetxattr(int fd,
- const char* key,
- char *value,
- size_t size)
+int
+make_export_path (const char *real_path, char **path)
{
- 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);
- } else {
- if (errno == ENOENT)
- errno = ENODATA;
- if (errno != ENOENT)
- gf_log ("libglusterfs", GF_LOG_DEBUG,
- "Couldn't read extended attribute for the file %d (%d)",
- fd, errno);
- return -1;
- }
-
- return ret;
+ 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;
+
+ 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)) {
+ ret = 0;
+ goto done;
+ }
+ }
+ strcat (export_path, "/");
+ dup = tmp;
+ } while (ptr);
+
+ goto out;
+
+done:
+ if (!ret) {
+ *path = export_path;
+ }
+out:
+ GF_FREE (freeptr);
+ if (ret && export_path)
+ GF_FREE (export_path);
+
+ return ret;
}
+int
+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 (THIS->name, GF_LOG_DEBUG, "mkdir failed,"
+ " errno: %d", errno);
+ goto out;
+ }
+ }
+
+ snprintf(xattr_path, PATH_MAX, "%s%s%lu", export_path,
+ "/", stbuf.ia_ino);
+ ret = lstat (xattr_path, &statbuf);
-int
-solaris_setxattr(const char *path,
- const char* key,
- const char *value,
- size_t size,
- int flags)
+ if (ret) {
+ ret = mknod (xattr_path, S_IFREG|O_WRONLY, 0);
+ if (ret && (errno != EEXIST)) {
+ gf_log (THIS->name, GF_LOG_WARNING,"Failed to create "
+ "mapped file %s, error %d", xattr_path,
+ errno);
+ goto out;
+ }
+ }
+ *path = gf_strdup (xattr_path);
+ }
+out:
+ GF_FREE (export_path);
+ if (*path)
+ return 0;
+ else
+ return -1;
+}
+
+int
+solaris_setxattr(const char *path, const char* key, const char *value,
+ size_t size, int flags)
{
- int attrfd = -1;
- int ret = 0;
-
- attrfd = attropen (path, key, flags|O_CREAT|O_WRONLY, 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 %s (%d)",
- path, errno);
- return -1;
- }
-
- return 0;
+ 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;
+ }
+ GF_FREE (mapped_path);
+ return ret;
}
int
-solaris_listxattr(const char *path,
- char *list,
- size_t size)
+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;
-
- 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 entrie + nul 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;
- }
- } else {
- close (attrdirfd);
- return -1;
- }
- close (attrdirfd);
- }
- return len;
+ 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;
+ }
+ } else {
+ close (attrdirfd);
+ len = -1;
+ goto out;
+ }
+ close (attrdirfd);
+ }
+out:
+ GF_FREE (mapped_path);
+ return len;
}
int
-solaris_flistxattr(int fd,
- char *list,
- size_t size)
+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 entrie + nul 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;
- }
- } else {
- close (attrdirfd);
- return -1;
- }
- close (attrdirfd);
- }
- return len;
+ 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;
+ }
+ } else {
+ close (attrdirfd);
+ return -1;
+ }
+ close (attrdirfd);
+ }
+ return len;
}
-int
-solaris_removexattr(const char *path,
- const char* key)
+int
+solaris_removexattr(const char *path, const char* key)
{
- int ret = -1;
- int attrfd = attropen (path, ".", O_RDONLY, 0);
- if (attrfd >= 0) {
- ret = unlinkat (attrfd, key, 0);
- close (attrfd);
- } else {
- if (errno == ENOENT)
- errno = ENODATA;
- return -1;
- }
-
- 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)
+int
+solaris_getxattr(const char *path,
+ const char* key,
+ char *value,
+ size_t size)
{
- int attrfd = -1;
- int ret = 0;
-
- 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);
- } else {
- if (errno == ENOENT)
- errno = ENODATA;
- if (errno != ENOENT)
- gf_log ("libglusterfs", GF_LOG_DEBUG,
- "Couldn't read extended attribute for the file %s (%d)",
- path, errno);
- return -1;
- }
- 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, 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);
+ } 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;
+ }
+ GF_FREE (mapped_path);
+ return ret;
}
char* strsep(char** str, const char* delims)
{
- 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;
- }
- (*str)++;
- }
- /* There is no other token */
- *str=NULL;
- return token;
+ 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;
+ }
+ (*str)++;
+ }
+ /* There is no other token */
+ *str=NULL;
+ return token;
}
/* Code comes from libiberty */
@@ -311,116 +449,97 @@ char* strsep(char** str, const char* delims)
int
vasprintf (char **result, const char *format, va_list args)
{
- const char *p = format;
- /* Add one to make sure that it is never zero, which might cause malloc
- to return NULL. */
- int total_width = strlen (format) + 1;
- va_list ap;
-
- /* vasprintf does not work on Solaris when memcpy is called on va_list pointers.
- * Replacing it with va_copy which works on Solaris
- */
- va_copy (ap, args);
-
- while (*p != '\0')
- {
- if (*p++ == '%')
- {
- while (strchr ("-+ #0", *p))
- ++p;
- if (*p == '*')
- {
- ++p;
- total_width += abs (va_arg (ap, int));
- }
- else
- {
- char *endp;
- total_width += strtoul (p, &endp, 10);
- p = endp;
- }
- if (*p == '.')
- {
- ++p;
- if (*p == '*')
- {
- ++p;
- total_width += abs (va_arg (ap, int));
- }
- else
- {
- char *endp;
- total_width += strtoul (p, &endp, 10);
- p = endp;
- }
- }
- while (strchr ("hlL", *p))
- ++p;
- /* Should be big enough for any format specifier except %s
- and floats. */
- total_width += 30;
- switch (*p)
- {
- case 'd':
- case 'i':
- case 'o':
- case 'u':
- case 'x':
- case 'X':
- case 'c':
- (void) va_arg (ap, int);
- break;
- case 'f':
- case 'e':
- case 'E':
- case 'g':
- case 'G':
- (void) va_arg (ap, double);
- /* Since an ieee double can have an exponent of 307, we'll
- make the buffer wide enough to cover the gross case. */
- total_width += 307;
-
- case 's':
- total_width += strlen (va_arg (ap, char *));
- break;
- case 'p':
- case 'n':
- (void) va_arg (ap, char *);
- break;
- }
- }
- }
-
- va_end (ap);
-
- *result = malloc (total_width);
- if (*result != NULL)
- return vsprintf (*result, format, args);
- else
- return 0;
+ return gf_vasprintf(result, format, args);
}
int
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;
+}
+
+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 (THIS->name, 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 (THIS->name, GF_LOG_WARNING, "Failed to remove mapped "
+ "file %s. Errno %d", mapped_path, errno);
+ }
+
+ }
+
+out:
+ GF_FREE (mapped_path);
+
+ return unlink (path);
+}
+
+int
+solaris_rename (const char *old_path, const char *new_path)
+{
+ 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 (THIS->name, GF_LOG_WARNING, "Failed to remove mapped "
+ "file %s. Errno %d", mapped_path, errno);
+ GF_FREE (mapped_path);
+ }
+
+ return rename(old_path, new_path);
+
+}
+
+char *
+mkdtemp (char *tempstring)
+{
+ char *new_string = NULL;
+ int ret = 0;
+
+ new_string = mkstemp (tempstring);
+ if (!new_string)
+ goto out;
+
+ ret = mkdir (new_string, 0700);
+ if (ret < 0)
+ new_string = NULL;
- va_start (ap, fmt);
- status = vasprintf (buf, fmt, ap);
- va_end (ap);
- return status;
+out:
+ return new_string;
}
#endif /* GF_SOLARIS_HOST_OS */
#ifndef HAVE_STRNLEN
-size_t
-strnlen(const char *string, size_t maxlen)
+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 */
diff --git a/libglusterfs/src/compat.h b/libglusterfs/src/compat.h
index 2f83054fa..2bd982541 100644
--- a/libglusterfs/src/compat.h
+++ b/libglusterfs/src/compat.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
#ifndef __COMPAT_H__
@@ -41,11 +32,17 @@
#include <linux/limits.h>
#include <sys/xattr.h>
#include <endian.h>
+#ifdef HAVE_FALLOC_H
+#include <linux/falloc.h>
+#else
+#define FALLOC_FL_KEEP_SIZE 0x01 /* default is extend size */
+#define FALLOC_FL_PUNCH_HOLE 0x02 /* de-allocates range */
+#endif
#ifndef HAVE_LLISTXATTR
-/* This part is valid only incase of old glibc which doesn't support
+/* This part is valid only incase of old glibc which doesn't support
* 'llistxattr()' system calls.
*/
@@ -57,8 +54,8 @@
#endif /* HAVE_LLISTXATTR */
#endif /* GF_LINUX_HOST_OS */
-#ifdef GF_BSD_HOST_OS
-/* In case of FreeBSD */
+#ifdef GF_BSD_HOST_OS
+/* In case of FreeBSD and NetBSD */
#define UNIX_PATH_MAX 104
#include <sys/types.h>
@@ -66,16 +63,21 @@
#include <sys/un.h>
#include <sys/endian.h>
#include <sys/extattr.h>
+#ifdef HAVE_SYS_XATTR_H
+#include <sys/xattr.h>
+#endif /* HAVE_SYS_XATTR_H */
#include <limits.h>
#include <libgen.h>
+#ifndef XATTR_CREATE
enum {
ATTR_CREATE = 1,
#define XATTR_CREATE ATTR_CREATE
ATTR_REPLACE = 2
#define XATTR_REPLACE ATTR_REPLACE
};
+#endif /* XATTR_CREATE */
#ifndef sighandler_t
@@ -88,7 +90,7 @@ enum {
#ifndef EUCLEAN
#define EUCLEAN 0
-#endif
+#endif
#include <netinet/in.h>
#ifndef s6_addr16
@@ -96,7 +98,7 @@ enum {
#endif
#ifndef s6_addr32
#define s6_addr32 __u6_addr.__u6_addr32
-#endif
+#endif
/* Posix dictates NAME_MAX to be used */
# ifndef NAME_MAX
@@ -106,7 +108,7 @@ enum {
# define NAME_MAX 255
# endif
# endif
-
+
#define F_GETLK64 F_GETLK
#define F_SETLK64 F_SETLK
#define F_SETLKW64 F_SETLKW
@@ -146,10 +148,10 @@ enum {
#include <netinet/in.h>
#ifndef s6_addr16
#define s6_addr16 __u6_addr.__u6_addr16
-#endif
+#endif
#ifndef s6_addr32
#define s6_addr32 __u6_addr.__u6_addr32
-#endif
+#endif
/* Posix dictates NAME_MAX to be used */
# ifndef NAME_MAX
@@ -177,7 +179,7 @@ int32_t gf_darwin_compat_setxattr (dict_t *dict);
#ifdef GF_SOLARIS_HOST_OS
#define UNIX_PATH_MAX 108
-#define EUCLEAN 117
+#define EUCLEAN 117
#include <sys/un.h>
#include <limits.h>
@@ -189,7 +191,7 @@ int32_t gf_darwin_compat_setxattr (dict_t *dict);
#ifndef lchmod
#define lchmod chmod
-#endif
+#endif
#define lgetxattr(path, key, value, size) solaris_getxattr(path,key,value,size)
enum {
@@ -208,10 +210,10 @@ enum {
# ifndef NAME_MAX
# ifdef MAXNAMLEN
# define NAME_MAX MAXNAMLEN
-# else
+# else
# define NAME_MAX 255
# endif
-# endif
+# endif
#include <netinet/in.h>
#ifndef s6_addr16
@@ -264,22 +266,32 @@ enum {
#define FTW_CONTINUE 0
#endif
-int asprintf(char **string_ptr, const char *format, ...);
+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,
+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,
+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,
+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);
+
+char *mkdtemp (char *temp);
+
+#define GF_SOLARIS_XATTR_DIR ".glusterfs_xattr_inode"
+
+int solaris_xattr_resolve_path (const char *real_path, char **path);
+
#endif /* GF_SOLARIS_HOST_OS */
#ifndef HAVE_ARGP
@@ -289,7 +301,7 @@ int solaris_flistxattr(int fd, char *list, size_t size);
#endif /* HAVE_ARGP */
#ifndef HAVE_STRNLEN
-size_t strnlen(const char *string, size_t maxlen);
+size_t strnlen(const char *string, size_t maxlen);
#endif /* STRNLEN */
#ifndef strdupa
@@ -301,7 +313,7 @@ size_t strnlen(const char *string, size_t maxlen);
char *__new = (char *) __builtin_alloca (__len); \
(char *) memcpy (__new, __old, __len); \
}))
-#endif
+#endif
#define GF_DIR_ALIGN(x) (((x) + sizeof (uint64_t) - 1) & ~(sizeof (uint64_t) - 1))
@@ -311,20 +323,35 @@ size_t strnlen(const char *string, size_t maxlen);
static inline int32_t
dirent_size (struct dirent *entry)
{
+ int32_t size = -1;
+
#ifdef GF_BSD_HOST_OS
- return GF_DIR_ALIGN (24 /* FIX MEEEE!!! */ + entry->d_namlen);
+ size = GF_DIR_ALIGN (24 /* FIX MEEEE!!! */ + entry->d_namlen);
#endif
#ifdef GF_DARWIN_HOST_OS
- return GF_DIR_ALIGN (24 /* FIX MEEEE!!! */ + entry->d_namlen);
+ size = GF_DIR_ALIGN (24 /* FIX MEEEE!!! */ + entry->d_namlen);
#endif
#ifdef GF_LINUX_HOST_OS
- return GF_DIR_ALIGN (24 /* FIX MEEEE!!! */ + entry->d_reclen);
+ size = GF_DIR_ALIGN (24 /* FIX MEEEE!!! */ + entry->d_reclen);
#endif
#ifdef GF_SOLARIS_HOST_OS
- return GF_DIR_ALIGN (24 /* FIX MEEEE!!! */ + entry->d_reclen);
+ size = GF_DIR_ALIGN (24 /* FIX MEEEE!!! */ + entry->d_reclen);
#endif
+ return size;
}
+#ifdef THREAD_UNSAFE_BASENAME
+char *basename_r(const char *);
+#define basename(path) basename_r(path)
+#endif /* THREAD_UNSAFE_BASENAME */
+
+#ifdef THREAD_UNSAFE_DIRNAME
+char *dirname_r(char *path);
+#define dirname(path) dirname_r(path)
+#endif /* THREAD_UNSAFE_DIRNAME */
+
+int gf_mkostemp (char *tmpl, int suffixlen, int flags);
+#define mkostemp(tmpl, flags) gf_mkostemp(tmpl, 0, flags);
#ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
/* Linux, Solaris, Cygwin */
@@ -351,4 +378,25 @@ dirent_size (struct dirent *entry)
#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
+
+#if defined(__GNUC__) && !defined(RELAX_POISONING)
+/* Use run API, see run.h */
+#pragma GCC poison system popen
+#endif
+
#endif /* __COMPAT_H__ */
diff --git a/libglusterfs/src/ctx.c b/libglusterfs/src/ctx.c
new file mode 100644
index 000000000..0082601d4
--- /dev/null
+++ b/libglusterfs/src/ctx.c
@@ -0,0 +1,48 @@
+/*
+ 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.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif /* !_CONFIG_H */
+
+#include <pthread.h>
+
+#include "glusterfs.h"
+
+glusterfs_ctx_t *
+glusterfs_ctx_new ()
+{
+ int ret = 0;
+ 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) {
+ ret = -1;
+ goto out;
+ }
+
+ INIT_LIST_HEAD (&ctx->graphs);
+ INIT_LIST_HEAD (&ctx->mempool_list);
+
+ ctx->daemon_pipe[0] = -1;
+ ctx->daemon_pipe[1] = -1;
+
+ ret = pthread_mutex_init (&ctx->lock, NULL);
+ if (ret) {
+ free (ctx);
+ ctx = NULL;
+ }
+out:
+ return ctx;
+}
+
diff --git a/libglusterfs/src/daemon.c b/libglusterfs/src/daemon.c
new file mode 100644
index 000000000..348e3ad40
--- /dev/null
+++ b/libglusterfs/src/daemon.c
@@ -0,0 +1,66 @@
+/*
+ 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 <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include "daemon.h"
+
+int
+os_daemon_return (int nochdir, int noclose)
+{
+ 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;
+}
+
+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
new file mode 100644
index 000000000..80836a326
--- /dev/null
+++ b/libglusterfs/src/daemon.h
@@ -0,0 +1,23 @@
+/*
+ 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.
+*/
+
+#ifndef _DAEMON_H
+#define _DAEMON_H
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#define DEVNULLPATH "/dev/null"
+
+int os_daemon_return(int nochdir, int noclose);
+int os_daemon(int nochdir, int noclose);
+#endif /*_DAEMON_H */
diff --git a/libglusterfs/src/defaults.c b/libglusterfs/src/defaults.c
index 718afeb9a..2ebb25150 100644
--- a/libglusterfs/src/defaults.c
+++ b/libglusterfs/src/defaults.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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.
*/
/* libglusterfs/src/defaults.c:
@@ -41,18 +32,19 @@
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)
+ struct iatt *buf, dict_t *xdata, struct iatt *postparent)
{
STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode, buf,
- dict, postparent);
+ xdata, 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)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf);
+ STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf, xdata);
return 0;
}
@@ -60,37 +52,41 @@ default_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
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)
+ struct iatt *postbuf,
+ dict_t *xdata)
{
STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno, prebuf,
- postbuf);
+ postbuf, xdata);
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)
+ struct iatt *postbuf,
+ dict_t *xdata)
{
STACK_UNWIND_STRICT (ftruncate, frame, op_ret, op_errno, prebuf,
- postbuf);
+ postbuf, xdata);
return 0;
}
int32_t
default_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
+ int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (access, frame, op_ret, op_errno);
+ STACK_UNWIND_STRICT (access, frame, op_ret, op_errno, xdata);
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)
+ struct iatt *buf, dict_t *xdata)
{
- STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, path, buf);
+ STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, path, buf,
+ xdata);
return 0;
}
@@ -99,10 +95,10 @@ 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)
+ struct iatt *postparent, dict_t *xdata)
{
STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno, inode,
- buf, preparent, postparent);
+ buf, preparent, postparent, xdata);
return 0;
}
@@ -110,30 +106,31 @@ 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)
+ struct iatt *postparent, dict_t *xdata)
{
STACK_UNWIND_STRICT (mkdir, frame, op_ret, op_errno, inode,
- buf, preparent, postparent);
+ buf, preparent, postparent, xdata);
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)
+ struct iatt *postparent, dict_t *xdata)
{
STACK_UNWIND_STRICT (unlink, frame, op_ret, op_errno, preparent,
- postparent);
+ postparent, xdata);
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)
+ struct iatt *postparent,
+ dict_t *xdata)
{
STACK_UNWIND_STRICT (rmdir, frame, op_ret, op_errno, preparent,
- postparent);
+ postparent, xdata);
return 0;
}
@@ -142,10 +139,10 @@ 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)
+ struct iatt *postparent, dict_t *xdata)
{
STACK_UNWIND_STRICT (symlink, frame, op_ret, op_errno, inode, buf,
- preparent, postparent);
+ preparent, postparent, xdata);
return 0;
}
@@ -154,10 +151,11 @@ 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)
+ struct iatt *prenewparent, struct iatt *postnewparent,
+ dict_t *xdata)
{
STACK_UNWIND_STRICT (rename, frame, op_ret, op_errno, buf, preoldparent,
- postoldparent, prenewparent, postnewparent);
+ postoldparent, prenewparent, postnewparent, xdata);
return 0;
}
@@ -166,10 +164,11 @@ 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)
+ struct iatt *postparent,
+ dict_t *xdata)
{
STACK_UNWIND_STRICT (link, frame, op_ret, op_errno, inode, buf,
- preparent, postparent);
+ preparent, postparent, xdata);
return 0;
}
@@ -178,28 +177,31 @@ 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)
+ struct iatt *postparent,
+ dict_t *xdata)
{
STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf,
- preparent, postparent);
+ preparent, postparent, xdata);
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)
+ int32_t op_ret, int32_t op_errno, fd_t *fd,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd);
+ STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd, xdata);
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)
+ int32_t count, struct iatt *stbuf, struct iobref *iobref,
+ dict_t *xdata)
{
STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vector, count,
- stbuf, iobref);
+ stbuf, iobref, xdata);
return 0;
}
@@ -207,18 +209,20 @@ default_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
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)
+ struct iatt *postbuf,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf);
+ STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf, xdata);
return 0;
}
int32_t
default_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
+ int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno);
+ STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno, xdata);
return 0;
}
@@ -227,59 +231,67 @@ default_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
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)
+ struct iatt *postbuf,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (fsync, frame, op_ret, op_errno, prebuf, postbuf);
+ STACK_UNWIND_STRICT (fsync, frame, op_ret, op_errno, prebuf, postbuf,
+ xdata);
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)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, buf);
+ STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, buf, xdata);
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)
+ int32_t op_ret, int32_t op_errno, fd_t *fd,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd);
+ STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd, xdata);
return 0;
}
int32_t
default_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
+ int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (fsyncdir, frame, op_ret, op_errno);
+ STACK_UNWIND_STRICT (fsyncdir, frame, op_ret, op_errno, xdata);
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)
+ int32_t op_ret, int32_t op_errno, struct statvfs *buf,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, buf);
+ STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, buf, xdata);
return 0;
}
int32_t
default_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
+ int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno);
+ STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, xdata);
return 0;
}
int32_t
default_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
+ int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno);
+ STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno, xdata);
return 0;
}
@@ -287,84 +299,104 @@ default_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
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 op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (fgetxattr, frame, op_ret, op_errno, dict);
+ STACK_UNWIND_STRICT (fgetxattr, frame, op_ret, op_errno, dict, xdata);
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)
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict);
+ STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict, xdata);
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)
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (xattrop, frame, op_ret, op_errno, dict);
+ STACK_UNWIND_STRICT (xattrop, frame, op_ret, op_errno, dict, xdata);
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)
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (fxattrop, frame, op_ret, op_errno, dict);
+ STACK_UNWIND_STRICT (fxattrop, frame, op_ret, op_errno, dict, xdata);
return 0;
}
int32_t
default_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
+ int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
+{
+ STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno, xdata);
+ return 0;
+}
+
+
+int32_t
+default_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno);
+ STACK_UNWIND_STRICT (fremovexattr, frame, op_ret, op_errno, xdata);
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)
+ int32_t op_ret, int32_t op_errno, struct gf_flock *lock,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, lock);
+ STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, lock, xdata);
return 0;
}
int32_t
default_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
+ int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (inodelk, frame, op_ret, op_errno);
+ STACK_UNWIND_STRICT (inodelk, frame, op_ret, op_errno, xdata);
return 0;
}
int32_t
default_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
+ int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (finodelk, frame, op_ret, op_errno);
+ STACK_UNWIND_STRICT (finodelk, frame, op_ret, op_errno, xdata);
return 0;
}
int32_t
default_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
+ int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno);
+ STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno, xdata);
return 0;
}
int32_t
default_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
+ int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (fentrylk, frame, op_ret, op_errno);
+ STACK_UNWIND_STRICT (fentrylk, frame, op_ret, op_errno, xdata);
return 0;
}
@@ -372,52 +404,86 @@ default_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
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)
+ uint8_t *strong_checksum,
+ dict_t *xdata)
{
STACK_UNWIND_STRICT (rchecksum, frame, op_ret, op_errno, weak_checksum,
- strong_checksum);
+ strong_checksum, xdata);
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)
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, entries);
+ STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, entries, xdata);
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)
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries);
+ STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries, xdata);
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)
+ struct iatt *statpost,
+ dict_t *xdata)
{
STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, statpre,
- statpost);
+ statpost, xdata);
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)
+ struct iatt *statpost,
+ dict_t *xdata)
{
STACK_UNWIND_STRICT (fsetattr, frame, op_ret, op_errno, statpre,
- statpost);
+ statpost, xdata);
return 0;
}
int32_t
+default_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)
+{
+ STACK_UNWIND_STRICT(fallocate, frame, op_ret, op_errno, pre, post, xdata);
+ return 0;
+}
+
+int32_t
+default_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)
+{
+ STACK_UNWIND_STRICT(discard, frame, op_ret, op_errno, pre, post, xdata);
+ return 0;
+}
+
+int32_t
+default_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)
+{
+ STACK_UNWIND_STRICT(zerofill, frame, op_ret, op_errno, pre,
+ post, xdata);
+ 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)
{
@@ -429,257 +495,271 @@ default_getspec_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t
default_fgetxattr_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name)
+ const char *name, dict_t *xdata)
{
STACK_WIND (frame, default_fgetxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fgetxattr, fd, name);
+ FIRST_CHILD(this)->fops->fgetxattr, fd, name, xdata);
return 0;
}
int32_t
default_fsetxattr_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- dict_t *dict, int32_t flags)
+ dict_t *dict, int32_t flags, dict_t *xdata)
{
STACK_WIND (frame, default_fsetxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags);
+ FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata);
return 0;
}
int32_t
default_setxattr_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *dict, int32_t flags)
+ dict_t *dict, int32_t flags, dict_t *xdata)
{
STACK_WIND (frame, default_setxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setxattr, loc, dict, flags);
+ FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata);
return 0;
}
int32_t
-default_statfs_resume (call_frame_t *frame, xlator_t *this, loc_t *loc)
+default_statfs_resume (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
{
STACK_WIND (frame, default_statfs_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->statfs, loc);
+ FIRST_CHILD(this)->fops->statfs, loc, xdata);
return 0;
}
int32_t
default_fsyncdir_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t flags)
+ int32_t flags, dict_t *xdata)
{
STACK_WIND (frame, default_fsyncdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsyncdir, fd, flags);
+ FIRST_CHILD(this)->fops->fsyncdir, fd, flags, xdata);
return 0;
}
int32_t
default_opendir_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- fd_t *fd)
+ fd_t *fd, dict_t *xdata)
{
STACK_WIND (frame, default_opendir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->opendir, loc, fd);
+ FIRST_CHILD(this)->fops->opendir, loc, fd, xdata);
return 0;
}
int32_t
-default_fstat_resume (call_frame_t *frame, xlator_t *this, fd_t *fd)
+default_fstat_resume (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
{
STACK_WIND (frame, default_fstat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fstat, fd);
+ FIRST_CHILD(this)->fops->fstat, fd, xdata);
return 0;
}
int32_t
default_fsync_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t flags)
+ int32_t flags, dict_t *xdata)
{
STACK_WIND (frame, default_fsync_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsync, fd, flags);
+ FIRST_CHILD(this)->fops->fsync, fd, flags, xdata);
return 0;
}
int32_t
-default_flush_resume (call_frame_t *frame, xlator_t *this, fd_t *fd)
+default_flush_resume (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
{
STACK_WIND (frame, default_flush_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->flush, fd);
+ FIRST_CHILD(this)->fops->flush, fd, xdata);
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)
+ uint32_t flags, struct iobref *iobref, dict_t *xdata)
{
STACK_WIND (frame, default_writev_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->writev, fd, vector, count, off,
- iobref);
+ flags, iobref, xdata);
return 0;
}
int32_t
default_readv_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t offset)
+ size_t size, off_t offset, uint32_t flags, dict_t *xdata)
{
STACK_WIND (frame, default_readv_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readv, fd, size, offset);
+ FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata);
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)
+ int32_t flags, fd_t *fd, dict_t *xdata)
{
STACK_WIND (frame, default_open_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->open, loc, flags, fd, wbflags);
+ FIRST_CHILD(this)->fops->open, loc, flags, fd, xdata);
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)
+ int32_t flags, mode_t mode, mode_t umask, fd_t *fd,
+ dict_t *xdata)
{
STACK_WIND (frame, default_create_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->create, loc, flags, mode, fd,
- params);
+ FIRST_CHILD(this)->fops->create, loc, flags, mode, umask,
+ fd, xdata);
return 0;
}
int32_t
default_link_resume (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc)
+ loc_t *newloc, dict_t *xdata)
{
STACK_WIND (frame, default_link_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->link, oldloc, newloc);
+ FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata);
return 0;
}
int32_t
default_rename_resume (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc)
+ loc_t *newloc, dict_t *xdata)
{
STACK_WIND (frame, default_rename_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rename, oldloc, newloc);
+ FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata);
return 0;
}
int
default_symlink_resume (call_frame_t *frame, xlator_t *this,
- const char *linkpath, loc_t *loc, dict_t *params)
+ const char *linkpath, loc_t *loc, mode_t umask,
+ dict_t *xdata)
{
STACK_WIND (frame, default_symlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->symlink, linkpath, loc, params);
+ FIRST_CHILD(this)->fops->symlink, linkpath, loc, umask,
+ xdata);
return 0;
}
int32_t
default_rmdir_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int flags)
+ int flags, dict_t *xdata)
{
STACK_WIND (frame, default_rmdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rmdir, loc, flags);
+ FIRST_CHILD(this)->fops->rmdir, loc, flags, xdata);
return 0;
}
int32_t
-default_unlink_resume (call_frame_t *frame, xlator_t *this, loc_t *loc)
+default_unlink_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ int xflag, dict_t *xdata)
{
STACK_WIND (frame, default_unlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->unlink, loc);
+ FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata);
return 0;
}
int
default_mkdir_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- mode_t mode, dict_t *params)
+ mode_t mode, mode_t umask, dict_t *xdata)
{
STACK_WIND (frame, default_mkdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mkdir, loc, mode, params);
+ FIRST_CHILD(this)->fops->mkdir, loc, mode, umask, xdata);
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)
+ mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata)
{
STACK_WIND (frame, default_mknod_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, parms);
+ FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, umask,
+ xdata);
return 0;
}
int32_t
default_readlink_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- size_t size)
+ size_t size, dict_t *xdata)
{
STACK_WIND (frame, default_readlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readlink, loc, size);
+ FIRST_CHILD(this)->fops->readlink, loc, size, xdata);
return 0;
}
int32_t
default_access_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t mask)
+ int32_t mask, dict_t *xdata)
{
STACK_WIND (frame, default_access_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->access, loc, mask);
+ FIRST_CHILD(this)->fops->access, loc, mask, xdata);
return 0;
}
int32_t
default_ftruncate_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset)
+ off_t offset, dict_t *xdata)
{
STACK_WIND (frame, default_ftruncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->ftruncate, fd, offset);
+ FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata);
return 0;
}
int32_t
default_getxattr_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name)
+ const char *name, dict_t *xdata)
{
STACK_WIND (frame, default_getxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->getxattr, loc, name);
+ FIRST_CHILD(this)->fops->getxattr, loc, name, xdata);
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)
+ gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
{
STACK_WIND (frame, default_xattrop_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->xattrop, loc, flags, dict);
+ FIRST_CHILD(this)->fops->xattrop, loc, flags, dict, xdata);
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)
+ gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
{
STACK_WIND (frame, default_fxattrop_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fxattrop, fd, flags, dict);
+ FIRST_CHILD(this)->fops->fxattrop, fd, flags, dict, xdata);
return 0;
}
int32_t
default_removexattr_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name)
+ const char *name, dict_t *xdata)
{
STACK_WIND (frame, default_removexattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->removexattr, loc, name);
+ FIRST_CHILD(this)->fops->removexattr, loc, name, xdata);
+ return 0;
+}
+
+int32_t
+default_fremovexattr_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ const char *name, dict_t *xdata)
+{
+ STACK_WIND (frame, default_fremovexattr_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fremovexattr, fd, name, xdata);
return 0;
}
int32_t
default_lk_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t cmd, struct gf_flock *lock)
+ int32_t cmd, struct gf_flock *lock, dict_t *xdata)
{
STACK_WIND (frame, default_lk_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lk, fd, cmd, lock);
+ FIRST_CHILD(this)->fops->lk, fd, cmd, lock, xdata);
return 0;
}
@@ -687,367 +767,431 @@ default_lk_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
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)
+ struct gf_flock *lock,
+ dict_t *xdata)
{
STACK_WIND (frame, default_inodelk_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->inodelk,
- volume, loc, cmd, lock);
+ volume, loc, cmd, lock, xdata);
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)
+ struct gf_flock *lock,
+ dict_t *xdata)
{
STACK_WIND (frame, default_finodelk_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->finodelk,
- volume, fd, cmd, lock);
+ volume, fd, cmd, lock, xdata);
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)
+ entrylk_cmd cmd, entrylk_type type,
+ dict_t *xdata)
{
STACK_WIND (frame, default_entrylk_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->entrylk,
- volume, loc, basename, cmd, type);
+ volume, loc, basename, cmd, type, xdata);
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)
+ entrylk_cmd cmd, entrylk_type type,
+ dict_t *xdata)
{
STACK_WIND (frame, default_fentrylk_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fentrylk,
- volume, fd, basename, cmd, type);
+ volume, fd, basename, cmd, type, xdata);
return 0;
}
int32_t
default_rchecksum_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset, int32_t len)
+ off_t offset, int32_t len,
+ dict_t *xdata)
{
STACK_WIND (frame, default_rchecksum_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rchecksum, fd, offset, len);
+ FIRST_CHILD(this)->fops->rchecksum, fd, offset, len, xdata);
return 0;
}
int32_t
default_readdir_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t off)
+ size_t size, off_t off,
+ dict_t *xdata)
{
STACK_WIND (frame, default_readdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdir, fd, size, off);
+ FIRST_CHILD(this)->fops->readdir, fd, size, off, xdata);
return 0;
}
int32_t
default_readdirp_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t off)
+ size_t size, off_t off, dict_t *xdata)
{
STACK_WIND (frame, default_readdirp_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdirp, fd, size, off);
+ FIRST_CHILD(this)->fops->readdirp, fd, size, off, xdata);
return 0;
}
int32_t
default_setattr_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid)
+ struct iatt *stbuf, int32_t valid,
+ dict_t *xdata)
{
STACK_WIND (frame, default_setattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->setattr, loc, stbuf, valid);
+ FIRST_CHILD (this)->fops->setattr, loc, stbuf, valid, xdata);
return 0;
}
int32_t
default_truncate_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- off_t offset)
+ off_t offset,
+ dict_t *xdata)
{
STACK_WIND (frame, default_truncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->truncate, loc, offset);
+ FIRST_CHILD(this)->fops->truncate, loc, offset, xdata);
return 0;
}
int32_t
-default_stat_resume (call_frame_t *frame, xlator_t *this, loc_t *loc)
+default_stat_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ dict_t *xdata)
{
STACK_WIND (frame, default_stat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->stat, loc);
+ FIRST_CHILD(this)->fops->stat, loc, xdata);
return 0;
}
int32_t
default_lookup_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xattr_req)
+ dict_t *xdata)
{
STACK_WIND (frame, default_lookup_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup, loc, xattr_req);
+ FIRST_CHILD(this)->fops->lookup, loc, xdata);
return 0;
}
int32_t
default_fsetattr_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iatt *stbuf, int32_t valid)
+ struct iatt *stbuf, int32_t valid,
+ dict_t *xdata)
{
STACK_WIND (frame, default_fsetattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fsetattr, fd, stbuf, valid);
+ FIRST_CHILD (this)->fops->fsetattr, fd, stbuf, valid, xdata);
return 0;
}
+int32_t
+default_fallocate_resume(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ int32_t keep_size, off_t offset, size_t len, dict_t *xdata)
+{
+ STACK_WIND(frame, default_fallocate_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fallocate, fd, keep_size, offset, len,
+ xdata);
+ return 0;
+}
+
+int32_t
+default_discard_resume(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ off_t offset, size_t len, dict_t *xdata)
+{
+ STACK_WIND(frame, default_discard_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->discard, fd, offset, len,
+ xdata);
+ return 0;
+}
+
+int32_t
+default_zerofill_resume(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ off_t offset, size_t len, dict_t *xdata)
+{
+ STACK_WIND(frame, default_zerofill_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->zerofill, fd, offset, len,
+ xdata);
+ return 0;
+}
+
+
/* FOPS */
int32_t
default_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name)
+ const char *name, dict_t *xdata)
{
- STACK_WIND (frame, default_fgetxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fgetxattr, fd, name);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fgetxattr, fd, name, xdata);
return 0;
}
int32_t
default_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
- int32_t flags)
+ int32_t flags, dict_t *xdata)
{
- STACK_WIND (frame, default_fsetxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags,
+ xdata);
return 0;
}
int32_t
default_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
- int32_t flags)
+ int32_t flags, dict_t *xdata)
{
- STACK_WIND (frame, default_setxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setxattr, loc, dict, flags);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->setxattr, loc, dict, flags,
+ xdata);
return 0;
}
int32_t
-default_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc)
+default_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
{
- STACK_WIND (frame, default_statfs_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->statfs, loc);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->statfs, loc, xdata);
return 0;
}
int32_t
-default_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags)
+default_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata)
{
- STACK_WIND (frame, default_fsyncdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsyncdir, fd, flags);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fsyncdir, fd, flags, xdata);
return 0;
}
int32_t
-default_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd)
+default_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t *xdata)
{
- STACK_WIND (frame, default_opendir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->opendir, loc, fd);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->opendir, loc, fd, xdata);
return 0;
}
int32_t
-default_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd)
+default_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
{
- STACK_WIND (frame, default_fstat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fstat, fd);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fstat, fd, xdata);
return 0;
}
int32_t
-default_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags)
+default_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata)
{
- STACK_WIND (frame, default_fsync_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsync, fd, flags);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fsync, fd, flags, xdata);
return 0;
}
int32_t
-default_flush (call_frame_t *frame, xlator_t *this, fd_t *fd)
+default_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
{
- STACK_WIND (frame, default_flush_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->flush, fd);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->flush, fd, xdata);
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)
+ struct iovec *vector, int32_t count, off_t off, uint32_t flags,
+ struct iobref *iobref, dict_t *xdata)
{
- STACK_WIND (frame, default_writev_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->writev, fd, vector, count, off,
- iobref);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->writev, fd, vector, count,
+ off, flags, iobref, xdata);
return 0;
}
int32_t
default_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset)
+ off_t offset, uint32_t flags, dict_t *xdata)
{
- STACK_WIND (frame, default_readv_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readv, fd, size, offset);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->readv, fd, size, offset,
+ flags, xdata);
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)
+ fd_t *fd, dict_t *xdata)
{
- STACK_WIND (frame, default_open_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->open, loc, flags, fd, wbflags);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, loc, flags, fd, xdata);
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)
+ mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata)
{
- STACK_WIND (frame, default_create_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->create, loc, flags, mode, fd,
- params);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->create, loc, flags, mode,
+ umask, fd, xdata);
return 0;
}
int32_t
-default_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc)
+default_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
+ dict_t *xdata)
{
- STACK_WIND (frame, default_link_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->link, oldloc, newloc);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata);
return 0;
}
int32_t
default_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc)
+ loc_t *newloc, dict_t *xdata)
{
- STACK_WIND (frame, default_rename_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rename, oldloc, newloc);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->rename, oldloc, newloc,
+ xdata);
return 0;
}
int
default_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
- loc_t *loc, dict_t *params)
+ loc_t *loc, mode_t umask, dict_t *xdata)
{
- STACK_WIND (frame, default_symlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->symlink, linkpath, loc, params);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->symlink, linkpath, loc,
+ umask, xdata);
return 0;
}
int32_t
-default_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags)
+default_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
+ dict_t *xdata)
{
- STACK_WIND (frame, default_rmdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rmdir, loc, flags);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->rmdir, loc, flags, xdata);
return 0;
}
int32_t
-default_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc)
+default_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
+ dict_t *xdata)
{
- STACK_WIND (frame, default_unlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->unlink, loc);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata);
return 0;
}
int
default_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- dict_t *params)
+ mode_t umask, dict_t *xdata)
{
- STACK_WIND (frame, default_mkdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mkdir, loc, mode, params);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->mkdir, loc, mode, umask,
+ xdata);
return 0;
}
int
default_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- dev_t rdev, dict_t *parms)
+ dev_t rdev, mode_t umask, dict_t *xdata)
{
- STACK_WIND (frame, default_mknod_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, parms);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->mknod, loc, mode, rdev,
+ umask, xdata);
return 0;
}
int32_t
-default_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size)
+default_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, dict_t *xdata)
{
- STACK_WIND (frame, default_readlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readlink, loc, size);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->readlink, loc, size, xdata);
return 0;
}
int32_t
-default_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask)
+default_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask, dict_t *xdata)
{
- STACK_WIND (frame, default_access_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->access, loc, mask);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->access, loc, mask, xdata);
return 0;
}
int32_t
-default_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset)
+default_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata)
{
- STACK_WIND (frame, default_ftruncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->ftruncate, fd, offset);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata);
return 0;
}
int32_t
default_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name)
+ const char *name, dict_t *xdata)
{
- STACK_WIND (frame, default_getxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->getxattr, loc, name);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->getxattr, loc, name, xdata);
return 0;
}
int32_t
default_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
- gf_xattrop_flags_t flags, dict_t *dict)
+ gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
{
- STACK_WIND (frame, default_xattrop_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->xattrop, loc, flags, dict);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->xattrop, loc, flags, dict,
+ xdata);
return 0;
}
int32_t
default_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
- gf_xattrop_flags_t flags, dict_t *dict)
+ gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
{
- STACK_WIND (frame, default_fxattrop_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fxattrop, fd, flags, dict);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fxattrop, fd, flags, dict,
+ xdata);
return 0;
}
int32_t
default_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name)
+ const char *name, dict_t *xdata)
{
- STACK_WIND (frame, default_removexattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->removexattr, loc, name);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->removexattr, loc, name,
+ xdata);
+ return 0;
+}
+
+int32_t
+default_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ const char *name, dict_t *xdata)
+{
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fremovexattr, fd, name,
+ xdata);
return 0;
}
int32_t
default_lk (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t cmd, struct gf_flock *lock)
+ int32_t cmd, struct gf_flock *lock, dict_t *xdata)
{
- STACK_WIND (frame, default_lk_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lk, fd, cmd, lock);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lk, fd, cmd, lock, xdata);
return 0;
}
@@ -1055,115 +1199,160 @@ default_lk (call_frame_t *frame, xlator_t *this, fd_t *fd,
int32_t
default_inodelk (call_frame_t *frame, xlator_t *this,
const char *volume, loc_t *loc, int32_t cmd,
- struct gf_flock *lock)
+ struct gf_flock *lock,
+ dict_t *xdata)
{
- STACK_WIND (frame, default_inodelk_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->inodelk,
- volume, loc, cmd, lock);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->inodelk, volume, loc, cmd,
+ lock, xdata);
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)
+ const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *lock,
+ dict_t *xdata)
{
- STACK_WIND (frame, default_finodelk_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->finodelk,
- volume, fd, cmd, lock);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->finodelk, volume, fd, cmd,
+ lock, xdata);
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)
+ entrylk_cmd cmd, entrylk_type type,
+ dict_t *xdata)
{
- STACK_WIND (frame, default_entrylk_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->entrylk,
- volume, loc, basename, cmd, type);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->entrylk, volume, loc,
+ basename, cmd, type, xdata);
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)
+ entrylk_cmd cmd, entrylk_type type,
+ dict_t *xdata)
{
- STACK_WIND (frame, default_fentrylk_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fentrylk,
- volume, fd, basename, cmd, type);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fentrylk, volume, fd,
+ basename, cmd, type, xdata);
return 0;
}
int32_t
default_rchecksum (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- int32_t len)
+ int32_t len,
+ dict_t *xdata)
{
- STACK_WIND (frame, default_rchecksum_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rchecksum, fd, offset, len);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->rchecksum, fd, offset, len,
+ xdata);
return 0;
}
int32_t
default_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t off)
+ size_t size, off_t off,
+ dict_t *xdata)
{
- STACK_WIND (frame, default_readdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdir, fd, size, off);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->readdir, fd, size, off,
+ xdata);
return 0;
}
int32_t
default_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t off)
+ size_t size, off_t off, dict_t *xdata)
{
- STACK_WIND (frame, default_readdirp_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdirp, fd, size, off);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->readdirp, fd, size, off,
+ xdata);
return 0;
}
int32_t
default_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid)
+ struct iatt *stbuf, int32_t valid,
+ dict_t *xdata)
{
- STACK_WIND (frame, default_setattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->setattr, loc, stbuf, valid);
+ STACK_WIND_TAIL (frame, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->setattr, loc, stbuf, valid,
+ xdata);
return 0;
}
int32_t
-default_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset)
+default_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
+ dict_t *xdata)
{
- STACK_WIND (frame, default_truncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->truncate, loc, offset);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->truncate, loc, offset, xdata);
return 0;
}
int32_t
-default_stat (call_frame_t *frame, xlator_t *this, loc_t *loc)
+default_stat (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ dict_t *xdata)
{
- STACK_WIND (frame, default_stat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->stat, loc);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->stat, loc, xdata);
return 0;
}
int32_t
default_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xattr_req)
+ dict_t *xdata)
{
- STACK_WIND (frame, default_lookup_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup, loc, xattr_req);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lookup, loc, xdata);
return 0;
}
int32_t
default_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iatt *stbuf, int32_t valid)
+ struct iatt *stbuf, int32_t valid,
+ dict_t *xdata)
{
- STACK_WIND (frame, default_fsetattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fsetattr, fd, stbuf, valid);
+ STACK_WIND_TAIL (frame, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fsetattr, fd, stbuf, valid,
+ xdata);
+ return 0;
+}
+
+int32_t
+default_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ int32_t keep_size, off_t offset, size_t len, dict_t *xdata)
+{
+ STACK_WIND_TAIL(frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fallocate, fd, keep_size, offset,
+ len, xdata);
+ return 0;
+}
+
+int32_t
+default_discard(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ off_t offset, size_t len, dict_t *xdata)
+{
+ STACK_WIND_TAIL(frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->discard, fd, offset, len,
+ xdata);
+ return 0;
+}
+
+int32_t
+default_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ off_t offset, size_t len, dict_t *xdata)
+{
+ STACK_WIND_TAIL(frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->zerofill, fd, offset, len,
+ xdata);
return 0;
}
@@ -1171,6 +1360,8 @@ default_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
int32_t
default_forget (xlator_t *this, inode_t *inode)
{
+ gf_log_callingfn (this->name, GF_LOG_WARNING, "xlator does not "
+ "implement forget_cbk");
return 0;
}
@@ -1178,12 +1369,16 @@ default_forget (xlator_t *this, inode_t *inode)
int32_t
default_releasedir (xlator_t *this, fd_t *fd)
{
+ gf_log_callingfn (this->name, GF_LOG_WARNING, "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_WARNING, "xlator does not "
+ "implement release_cbk");
return 0;
}
@@ -1196,8 +1391,8 @@ 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);
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->getspec, key, flags);
return 0;
}
@@ -1208,6 +1403,7 @@ default_notify (xlator_t *this, int32_t event, void *data, ...)
switch (event)
{
case GF_EVENT_PARENT_UP:
+ case GF_EVENT_PARENT_DOWN:
{
xlator_list_t *list = this->children;
@@ -1218,10 +1414,13 @@ default_notify (xlator_t *this, int32_t event, void *data, ...)
}
break;
case GF_EVENT_CHILD_CONNECTING:
+ case GF_EVENT_CHILD_MODIFIED:
+ case GF_EVENT_CHILD_DOWN:
case GF_EVENT_CHILD_UP:
+ case GF_EVENT_AUTH_FAILED:
{
xlator_list_t *parent = this->parents;
- /* Handle the case of CHILD_UP specially, send it to fuse */
+ /* 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);
@@ -1233,7 +1432,6 @@ default_notify (xlator_t *this, int32_t event, void *data, ...)
}
}
break;
- case GF_EVENT_CHILD_DOWN:
default:
{
xlator_list_t *parent = this->parents;
diff --git a/libglusterfs/src/defaults.h b/libglusterfs/src/defaults.h
index 6e451602b..0747027bc 100644
--- a/libglusterfs/src/defaults.h
+++ b/libglusterfs/src/defaults.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
/* libglusterfs/src/defaults.h:
@@ -31,6 +22,18 @@
#include "xlator.h"
+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);
+
+
/* Management Operations */
int32_t default_getspec (call_frame_t *frame,
@@ -41,83 +44,85 @@ int32_t default_getspec (call_frame_t *frame,
int32_t default_rchecksum (call_frame_t *frame,
xlator_t *this,
fd_t *fd, off_t offset,
- int32_t len);
+ int32_t len, dict_t *xdata);
/* FileSystem operations */
int32_t default_lookup (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- dict_t *xattr_req);
+ dict_t *xdata);
int32_t default_stat (call_frame_t *frame,
xlator_t *this,
- loc_t *loc);
+ loc_t *loc, dict_t *xdata);
int32_t default_fstat (call_frame_t *frame,
xlator_t *this,
- fd_t *fd);
+ fd_t *fd, dict_t *xdata);
int32_t default_truncate (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- off_t offset);
+ off_t offset, dict_t *xdata);
int32_t default_ftruncate (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- off_t offset);
+ off_t offset, dict_t *xdata);
int32_t default_access (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- int32_t mask);
+ int32_t mask, dict_t *xdata);
int32_t default_readlink (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- size_t size);
+ size_t size, dict_t *xdata);
-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_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata);
int32_t default_mkdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, dict_t *params);
+ loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata);
int32_t default_unlink (call_frame_t *frame,
xlator_t *this,
- loc_t *loc);
+ loc_t *loc, int xflag, dict_t *xdata);
int32_t default_rmdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int flags);
+ loc_t *loc, int xflag, dict_t *xdata);
int32_t default_symlink (call_frame_t *frame, xlator_t *this,
- const char *linkpath, loc_t *loc, dict_t *params);
+ const char *linkpath, loc_t *loc, mode_t umask,
+ dict_t *xdata);
int32_t default_rename (call_frame_t *frame,
xlator_t *this,
loc_t *oldloc,
- loc_t *newloc);
+ loc_t *newloc, dict_t *xdata);
int32_t default_link (call_frame_t *frame,
xlator_t *this,
loc_t *oldloc,
- loc_t *newloc);
+ loc_t *newloc, dict_t *xdata);
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);
+ mode_t umask, fd_t *fd, dict_t *xdata);
int32_t default_open (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
int32_t flags, fd_t *fd,
- int32_t wbflags);
+ dict_t *xdata);
int32_t default_readv (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
size_t size,
- off_t offset);
+ off_t offset,
+ uint32_t flags, dict_t *xdata);
int32_t default_writev (call_frame_t *frame,
xlator_t *this,
@@ -125,550 +130,588 @@ int32_t default_writev (call_frame_t *frame,
struct iovec *vector,
int32_t count,
off_t offset,
- struct iobref *iobref);
+ uint32_t flags,
+ struct iobref *iobref, dict_t *xdata);
int32_t default_flush (call_frame_t *frame,
xlator_t *this,
- fd_t *fd);
+ fd_t *fd, dict_t *xdata);
int32_t default_fsync (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- int32_t datasync);
+ int32_t datasync, dict_t *xdata);
int32_t default_opendir (call_frame_t *frame,
xlator_t *this,
- loc_t *loc, fd_t *fd);
+ loc_t *loc, fd_t *fd, dict_t *xdata);
int32_t default_fsyncdir (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- int32_t datasync);
+ int32_t datasync, dict_t *xdata);
int32_t default_statfs (call_frame_t *frame,
xlator_t *this,
- loc_t *loc);
+ loc_t *loc, dict_t *xdata);
int32_t default_setxattr (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
dict_t *dict,
- int32_t flags);
+ int32_t flags, dict_t *xdata);
int32_t default_getxattr (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- const char *name);
+ const char *name, dict_t *xdata);
int32_t default_fsetxattr (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
dict_t *dict,
- int32_t flags);
+ int32_t flags, dict_t *xdata);
int32_t default_fgetxattr (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- const char *name);
+ const char *name, dict_t *xdata);
int32_t default_removexattr (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- const char *name);
+ const char *name, dict_t *xdata);
+
+int32_t default_fremovexattr (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ const char *name, dict_t *xdata);
int32_t default_lk (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
int32_t cmd,
- struct gf_flock *flock);
+ struct gf_flock *flock, dict_t *xdata);
int32_t default_inodelk (call_frame_t *frame, xlator_t *this,
const char *volume, loc_t *loc, int32_t cmd,
- struct gf_flock *flock);
+ struct gf_flock *flock, dict_t *xdata);
int32_t default_finodelk (call_frame_t *frame, xlator_t *this,
const char *volume, fd_t *fd, int32_t cmd,
- struct gf_flock *flock);
+ struct gf_flock *flock, dict_t *xdata);
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);
+ entrylk_cmd cmd, entrylk_type type, dict_t *xdata);
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);
+ entrylk_cmd cmd, entrylk_type type, dict_t *xdata);
int32_t default_readdir (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- size_t size, off_t off);
+ size_t size, off_t off, dict_t *xdata);
int32_t default_readdirp (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- size_t size, off_t off);
+ size_t size, off_t off, dict_t *xdata);
int32_t default_xattrop (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
gf_xattrop_flags_t flags,
- dict_t *dict);
+ dict_t *dict, dict_t *xdata);
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);
+ dict_t *dict, dict_t *xdata);
int32_t default_setattr (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
struct iatt *stbuf,
- int32_t valid);
+ int32_t valid, dict_t *xdata);
int32_t default_fsetattr (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
struct iatt *stbuf,
- int32_t valid);
+ int32_t valid, dict_t *xdata);
+
+int32_t default_fallocate(call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ int32_t keep_size, off_t offset,
+ size_t len, dict_t *xdata);
+
+int32_t default_discard(call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ off_t offset,
+ size_t len, dict_t *xdata);
+
+int32_t default_zerofill(call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ off_t offset,
+ size_t len, dict_t *xdata);
+
/* Resume */
-int32_t default_getspec (call_frame_t *frame,
- xlator_t *this,
- const char *key,
- int32_t flag);
+int32_t default_getspec_resume (call_frame_t *frame,
+ xlator_t *this,
+ const char *key,
+ int32_t flag);
-int32_t default_rchecksum (call_frame_t *frame,
+int32_t default_rchecksum_resume (call_frame_t *frame,
xlator_t *this,
fd_t *fd, off_t offset,
- int32_t len);
+ int32_t len, dict_t *xdata);
/* FileSystem operations */
int32_t default_lookup_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- dict_t *xattr_req);
+ xlator_t *this,
+ loc_t *loc,
+ dict_t *xdata);
int32_t default_stat_resume (call_frame_t *frame,
xlator_t *this,
- loc_t *loc);
+ loc_t *loc, dict_t *xdata);
int32_t default_fstat_resume (call_frame_t *frame,
xlator_t *this,
- fd_t *fd);
+ fd_t *fd, dict_t *xdata);
int32_t default_truncate_resume (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- off_t offset);
+ off_t offset, dict_t *xdata);
int32_t default_ftruncate_resume (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- off_t offset);
+ off_t offset, dict_t *xdata);
int32_t default_access_resume (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- int32_t mask);
+ int32_t mask, dict_t *xdata);
int32_t default_readlink_resume (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- size_t size);
+ size_t size, dict_t *xdata);
-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_mknod_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ mode_t mode, dev_t rdev, mode_t umask,
+ dict_t *xdata);
-int32_t default_mkdir_resume (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, dict_t *params);
+int32_t default_mkdir_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ mode_t mode, mode_t umask, dict_t *xdata);
int32_t default_unlink_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc);
+ xlator_t *this,
+ loc_t *loc, int xflag, dict_t *xdata);
int32_t default_rmdir_resume (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int flags);
+ loc_t *loc, int xflag, dict_t *xdata);
int32_t default_symlink_resume (call_frame_t *frame, xlator_t *this,
- const char *linkpath, loc_t *loc, dict_t *params);
+ const char *linkpath, loc_t *loc, mode_t umask,
+ dict_t *xdata);
int32_t default_rename_resume (call_frame_t *frame,
xlator_t *this,
loc_t *oldloc,
- loc_t *newloc);
+ loc_t *newloc, dict_t *xdata);
int32_t default_link_resume (call_frame_t *frame,
xlator_t *this,
loc_t *oldloc,
- loc_t *newloc);
+ loc_t *newloc, dict_t *xdata);
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);
+ loc_t *loc, int32_t flags, mode_t mode,
+ mode_t umask, fd_t *fd, dict_t *xdata);
int32_t default_open_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- int32_t flags, fd_t *fd,
- int32_t wbflags);
+ xlator_t *this,
+ loc_t *loc,
+ int32_t flags, fd_t *fd, dict_t *xdata);
int32_t default_readv_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- size_t size,
- off_t offset);
+ xlator_t *this,
+ fd_t *fd,
+ size_t size,
+ off_t offset, uint32_t flags, dict_t *xdata);
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);
+ xlator_t *this,
+ fd_t *fd,
+ struct iovec *vector,
+ int32_t count,
+ off_t offset, uint32_t flags,
+ struct iobref *iobref, dict_t *xdata);
int32_t default_flush_resume (call_frame_t *frame,
xlator_t *this,
- fd_t *fd);
+ fd_t *fd, dict_t *xdata);
int32_t default_fsync_resume (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- int32_t datasync);
+ int32_t datasync, dict_t *xdata);
int32_t default_opendir_resume (call_frame_t *frame,
xlator_t *this,
- loc_t *loc, fd_t *fd);
+ loc_t *loc, fd_t *fd, dict_t *xdata);
int32_t default_fsyncdir_resume (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- int32_t datasync);
+ int32_t datasync, dict_t *xdata);
int32_t default_statfs_resume (call_frame_t *frame,
xlator_t *this,
- loc_t *loc);
+ loc_t *loc, dict_t *xdata);
int32_t default_setxattr_resume (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
dict_t *dict,
- int32_t flags);
+ int32_t flags, dict_t *xdata);
int32_t default_getxattr_resume (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- const char *name);
+ const char *name, dict_t *xdata);
int32_t default_fsetxattr_resume (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
dict_t *dict,
- int32_t flags);
+ int32_t flags, dict_t *xdata);
int32_t default_fgetxattr_resume (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- const char *name);
+ const char *name, dict_t *xdata);
int32_t default_removexattr_resume (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- const char *name);
+ const char *name, dict_t *xdata);
+
+int32_t default_fremovexattr_resume (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ const char *name, dict_t *xdata);
int32_t default_lk_resume (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
int32_t cmd,
- struct gf_flock *flock);
+ struct gf_flock *flock, dict_t *xdata);
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);
+ struct gf_flock *flock, dict_t *xdata);
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);
+ struct gf_flock *flock, dict_t *xdata);
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);
+ entrylk_cmd cmd, entrylk_type type, dict_t *xdata);
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);
+ entrylk_cmd cmd, entrylk_type type, dict_t *xdata);
int32_t default_readdir_resume (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- size_t size, off_t off);
+ size_t size, off_t off, dict_t *xdata);
int32_t default_readdirp_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- size_t size, off_t off);
+ xlator_t *this,
+ fd_t *fd,
+ size_t size, off_t off, dict_t *xdata);
int32_t default_xattrop_resume (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
gf_xattrop_flags_t flags,
- dict_t *dict);
+ dict_t *dict, dict_t *xdata);
int32_t default_fxattrop_resume (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
gf_xattrop_flags_t flags,
- dict_t *dict);
+ dict_t *dict, dict_t *xdata);
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 len, dict_t *xdata);
int32_t default_setattr_resume (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
struct iatt *stbuf,
- int32_t valid);
+ int32_t valid, dict_t *xdata);
int32_t default_fsetattr_resume (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
struct iatt *stbuf,
- int32_t valid);
+ int32_t valid, dict_t *xdata);
+
+int32_t default_fallocate_resume(call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ int32_t keep_size, off_t offset,
+ size_t len, dict_t *xdata);
+
+int32_t default_discard_resume(call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ off_t offset,
+ size_t len, dict_t *xdata);
+
+int32_t default_zerofill_resume(call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ off_t offset,
+ size_t len, dict_t *xdata);
+
/* _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);
+ struct iatt *buf, dict_t *xdata, 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 op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata);
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);
+ struct iatt *postbuf, dict_t *xdata);
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);
+ struct iatt *postbuf, dict_t *xdata);
int32_t
default_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
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);
+ struct iatt *buf, dict_t *xdata);
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);
+ struct iatt *postparent, dict_t *xdata);
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);
+ struct iatt *postparent, dict_t *xdata);
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);
+ struct iatt *postparent, dict_t *xdata);
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);
+ struct iatt *postparent, dict_t *xdata);
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);
+ struct iatt *postparent, dict_t *xdata);
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);
+ struct iatt *prenewparent, struct iatt *postnewparent, dict_t *xdata);
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);
+ struct iatt *postparent, dict_t *xdata);
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);
+ struct iatt *postparent, dict_t *xdata);
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 op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata);
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 count, struct iatt *stbuf, struct iobref *iobref, dict_t *xdata);
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);
+ struct iatt *postbuf, dict_t *xdata);
int32_t
default_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
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);
+ struct iatt *postbuf, dict_t *xdata);
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 op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata);
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 op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata);
int32_t
default_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
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 op_ret, int32_t op_errno, struct statvfs *buf, dict_t *xdata);
int32_t
default_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
int32_t
default_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
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 op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata);
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 op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata);
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 op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata);
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 op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata);
int32_t
default_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+
+int32_t
+default_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
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 op_ret, int32_t op_errno, struct gf_flock *lock, dict_t *xdata);
int32_t
default_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
int32_t
default_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
int32_t
default_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
int32_t
default_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
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);
+ uint8_t *strong_checksum, dict_t *xdata);
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 op_ret, int32_t op_errno, gf_dirent_t *entries, dict_t *xdata);
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 op_ret, int32_t op_errno, gf_dirent_t *entries, dict_t *xdata);
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);
+ struct iatt *statpost, dict_t *xdata);
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);
+ struct iatt *statpost, dict_t *xdata);
+
+int32_t default_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);
+
+int32_t default_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);
+
+int32_t default_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);
int32_t
default_getspec_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
@@ -676,4 +719,5 @@ default_getspec_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
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 bbd14fc86..3b7ddce5e 100644
--- a/libglusterfs/src/dict.c
+++ b/libglusterfs/src/dict.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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,6 +13,8 @@
#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
+#include <limits.h>
+#include <fnmatch.h>
#ifndef _CONFIG_H
#define _CONFIG_H
@@ -35,872 +28,663 @@
#include "logging.h"
#include "compat.h"
#include "byte-order.h"
-
-data_pair_t *
-get_new_data_pair ()
-{
- 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);
- if (!data_pair_ptr)
- gf_log ("dict", GF_LOG_ERROR, "memory alloc failed");
-
- return data_pair_ptr;
-}
+#include "globals.h"
data_t *
get_new_data ()
{
- data_t *data = NULL;
+ data_t *data = NULL;
- data = (data_t *) GF_CALLOC (1, sizeof (data_t), gf_common_mt_data_t);
- if (!data) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "calloc () returned NULL");
- return NULL;
- }
+ data = mem_get0 (THIS->ctx->dict_data_pool);
+ if (!data) {
+ return NULL;
+ }
- LOCK_INIT (&data->lock);
- return data;
+ LOCK_INIT (&data->lock);
+ return data;
}
dict_t *
get_new_dict_full (int size_hint)
{
- dict_t *dict = GF_CALLOC (1, sizeof (dict_t), gf_common_mt_dict_t);
+ dict_t *dict = mem_get0 (THIS->ctx->dict_pool);
- if (!dict) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "calloc () returned NULL");
- return NULL;
- }
-
- dict->hash_size = size_hint;
- dict->members = GF_CALLOC (size_hint, sizeof (data_pair_t *),
- gf_common_mt_data_pair_t);
+ if (!dict) {
+ return NULL;
+ }
- if (!dict->members) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "calloc () returned NULL");
- 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) {
+ mem_put (dict);
+ return NULL;
+ }
+ }
- LOCK_INIT (&dict->lock);
+ LOCK_INIT (&dict->lock);
- return dict;
+ return dict;
}
dict_t *
get_new_dict (void)
{
- return get_new_dict_full (1);
+ return get_new_dict_full (1);
}
dict_t *
dict_new (void)
{
- dict_t *dict = NULL;
-
- dict = get_new_dict_full(1);
-
- if (dict)
- dict_ref (dict);
-
- return dict;
+ dict_t *dict = NULL;
+
+ dict = get_new_dict_full(1);
+
+ if (dict)
+ dict_ref (dict);
+
+ return dict;
}
-int32_t
+int32_t
is_data_equal (data_t *one,
- data_t *two)
+ data_t *two)
{
- if (!one || !two || !one->data || !two->data)
- return 1;
+ if (!one || !two || !one->data || !two->data) {
+ gf_log_callingfn ("dict", GF_LOG_ERROR,
+ "input arguments are provided "
+ "with value data_t as NULL");
+ return -1;
+ }
- if (one == two)
- return 1;
+ if (one == two)
+ return 1;
- if (one->len != two->len)
- return 0;
+ if (one->len != two->len)
+ return 0;
- if (one->data == two->data)
- return 1;
+ if (one->data == two->data)
+ return 1;
- 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;
}
void
data_destroy (data_t *data)
{
- if (data) {
- LOCK_DESTROY (&data->lock);
+ if (data) {
+ LOCK_DESTROY (&data->lock);
- if (!data->is_static) {
- if (data->data) {
+ if (!data->is_static) {
+ if (data->data) {
if (data->is_stdalloc)
free (data->data);
- else
+ else
GF_FREE (data->data);
}
- if (data->vec)
- GF_FREE (data->vec);
- }
+ }
- data->len = 0xbabababa;
- if (!data->is_const)
- GF_FREE (data);
- }
+ data->len = 0xbabababa;
+ if (!data->is_const)
+ mem_put (data);
+ }
}
data_t *
data_copy (data_t *old)
{
- if (!old) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@old is NULL");
- return NULL;
- }
-
- data_t *newdata = (data_t *) GF_CALLOC (1, sizeof (*newdata),
- gf_common_mt_data_t);
+ if (!old) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING,
+ "old is NULL");
+ return NULL;
+ }
- if (!newdata) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@newdata - NULL returned by CALLOC");
- return NULL;
- }
+ data_t *newdata = mem_get0 (THIS->ctx->dict_data_pool);
+ if (!newdata) {
+ return NULL;
+ }
- 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;
- }
- }
+ if (old) {
+ newdata->len = old->len;
+ if (old->data) {
+ newdata->data = memdup (old->data, old->len);
+ if (!newdata->data)
+ goto err_out;
+ }
+ }
- return newdata;
+ LOCK_INIT (&newdata->lock);
+ return newdata;
- err_out:
+err_out:
- if (newdata->data)
- FREE (newdata->data);
- if (newdata->vec)
- FREE (newdata->vec);
- FREE (newdata);
+ FREE (newdata->data);
+ mem_put (newdata);
- gf_log ("dict", GF_LOG_CRITICAL,
- "@newdata->data || @newdata->vec got NULL from CALLOC()");
- return NULL;
+ return NULL;
}
static data_pair_t *
_dict_lookup (dict_t *this, char *key)
{
- if (!this || !key) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@this=%p @key=%p", this, key);
- return NULL;
- }
+ if (!this || !key) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING,
+ "!this || !key (%s)", key);
+ return NULL;
+ }
- int hashval = SuperFastHash (key, strlen (key)) % this->hash_size;
- data_pair_t *pair;
-
- for (pair = this->members[hashval]; pair != NULL; pair = pair->hash_next) {
- if (pair->key && !strcmp (pair->key, key))
- return pair;
- }
-
- return NULL;
+ int hashval = SuperFastHash (key, strlen (key)) % this->hash_size;
+ data_pair_t *pair;
+
+ for (pair = this->members[hashval]; pair != NULL; pair = pair->hash_next) {
+ if (pair->key && !strcmp (pair->key, key))
+ return pair;
+ }
+
+ return NULL;
}
+int32_t
+dict_lookup (dict_t *this, char *key, data_t **data)
+{
+ if (!this || !key || !data) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING,
+ "!this || !key || !data");
+ return -1;
+ }
+
+ data_pair_t *tmp = NULL;
+ LOCK (&this->lock);
+ {
+ tmp = _dict_lookup (this, key);
+ }
+ UNLOCK (&this->lock);
+
+ if (!tmp)
+ return -1;
+
+ *data = tmp->value;
+ return 0;
+}
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;
+_dict_set (dict_t *this, char *key, data_t *value, gf_boolean_t replace)
+{
+ 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 (!key) {
+ ret = gf_asprintf (&key, "ref:%p", value);
if (-1 == ret) {
- gf_log ("dict", GF_LOG_ERROR, "asprintf failed");
+ gf_log ("dict", GF_LOG_WARNING, "asprintf failed %s", key);
return -1;
}
- key_free = 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) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@pair - NULL returned by CALLOC");
- return -1;
- }
+ tmp = SuperFastHash (key, strlen (key));
+ hashval = (tmp % this->hash_size);
+
+ /* Search for a existing key if 'replace' is asked for */
+ if (replace) {
+ 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->key = (char *) GF_CALLOC (1, strlen (key) + 1,
- gf_common_mt_char);
- if (!pair->key) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@pair->key - NULL returned by CALLOC");
- FREE (pair);
+ if (this->free_pair_in_use) {
+ pair = mem_get0 (THIS->ctx->dict_pair_pool);
+ if (!pair) {
+ if (key_free)
+ GF_FREE (key);
+ return -1;
+ }
+ }
+ else {
+ pair = &this->free_pair;
+ this->free_pair_in_use = _gf_true;
+ }
- if (key_free)
- GF_FREE (key);
- return -1;
- }
+ if (key_free) {
+ /* It's ours. Use it. */
+ pair->key = key;
+ key_free = 0;
+ }
+ else {
+ pair->key = (char *) GF_CALLOC (1, strlen (key) + 1,
+ gf_common_mt_char);
+ if (!pair->key) {
+ if (pair == &this->free_pair) {
+ this->free_pair_in_use = _gf_false;
+ }
+ else {
+ mem_put (pair);
+ }
+ return -1;
+ }
+ strcpy (pair->key, key);
+ }
+ pair->value = data_ref (value);
+
+ pair->hash_next = this->members[hashval];
+ this->members[hashval] = pair;
- strcpy (pair->key, key);
- pair->value = data_ref (value);
-
- 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);
- return 0;
+ 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);
+ return 0;
}
int32_t
dict_set (dict_t *this,
- char *key,
- data_t *value)
+ char *key,
+ data_t *value)
{
- int32_t ret;
+ int32_t ret;
- if (!this || !value) {
- gf_log ("dict", GF_LOG_ERROR,
- "@this=%p @value=%p, key=%s", this, value, key);
- return -1;
- }
+ if (!this || !value) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING,
+ "!this || !value for key=%s", key);
+ return -1;
+ }
- LOCK (&this->lock);
+ LOCK (&this->lock);
- ret = _dict_set (this, key, value);
+ ret = _dict_set (this, key, value, 1);
- UNLOCK (&this->lock);
+ UNLOCK (&this->lock);
- return ret;
+ return ret;
}
-data_t *
-dict_get (dict_t *this,
- char *key)
+int32_t
+dict_add (dict_t *this, char *key, data_t *value)
{
- data_pair_t *pair;
+ int32_t ret;
- if (!this || !key) {
- gf_log_callingfn ("dict", GF_LOG_DEBUG,
- "@this=%p key=%s", this, (key) ? key : "()");
- return NULL;
- }
+ if (!this || !value) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING,
+ "!this || !value for key=%s", key);
+ return -1;
+ }
- LOCK (&this->lock);
+ LOCK (&this->lock);
- pair = _dict_lookup (this, key);
+ ret = _dict_set (this, key, value, 0);
- UNLOCK (&this->lock);
+ UNLOCK (&this->lock);
- if (pair)
- return pair->value;
-
- return NULL;
+ return ret;
}
-void
-dict_del (dict_t *this,
- char *key)
-{
- if (!this || !key) {
- gf_log ("dict", GF_LOG_DEBUG,
- "@this=%p @key=%p", this, 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;
-
- while (pair) {
- if (strcmp (pair->key, key) == 0) {
- if (prev)
- prev->hash_next = pair->hash_next;
- else
- this->members[hashval] = pair->hash_next;
-
- data_unref (pair->value);
-
- if (pair->prev)
- pair->prev->next = pair->next;
- else
- this->members_list = pair->next;
-
- if (pair->next)
- pair->next->prev = pair->prev;
-
- GF_FREE (pair->key);
- GF_FREE (pair);
- this->count--;
- break;
- }
-
- prev = pair;
- pair = pair->hash_next;
- }
-
- UNLOCK (&this->lock);
-
- return;
-}
-void
-dict_destroy (dict_t *this)
+data_t *
+dict_get (dict_t *this, char *key)
{
- if (!this) {
- gf_log ("dict", GF_LOG_DEBUG,
- "@this=%p", this);
- return;
- }
-
- data_pair_t *pair = this->members_list;
- data_pair_t *prev = this->members_list;
+ data_pair_t *pair;
- LOCK_DESTROY (&this->lock);
+ if (!this || !key) {
+ gf_log_callingfn ("dict", GF_LOG_INFO,
+ "!this || key=%s", (key) ? key : "()");
+ return NULL;
+ }
- while (prev) {
- pair = pair->next;
- data_unref (prev->value);
- GF_FREE (prev->key);
- GF_FREE (prev);
- prev = pair;
- }
+ LOCK (&this->lock);
- GF_FREE (this->members);
+ pair = _dict_lookup (this, key);
- if (this->extra_free)
- GF_FREE (this->extra_free);
- if (this->extra_stdfree)
- free (this->extra_stdfree);
+ UNLOCK (&this->lock);
- if (!this->is_static)
- GF_FREE (this);
+ if (pair)
+ return pair->value;
- return;
+ return NULL;
}
void
-dict_unref (dict_t *this)
+dict_del (dict_t *this, char *key)
{
- int32_t ref;
+ if (!this || !key) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING,
+ "!this || key=%s", key);
+ return;
+ }
- if (!this) {
- gf_log ("dict", GF_LOG_DEBUG,
- "@this=%p", this);
- return;
- }
+ LOCK (&this->lock);
- LOCK (&this->lock);
+ int hashval = SuperFastHash (key, strlen (key)) % this->hash_size;
+ data_pair_t *pair = this->members[hashval];
+ data_pair_t *prev = NULL;
- this->refcount--;
- ref = this->refcount;
+ while (pair) {
+ if (strcmp (pair->key, key) == 0) {
+ if (prev)
+ prev->hash_next = pair->hash_next;
+ else
+ this->members[hashval] = pair->hash_next;
- UNLOCK (&this->lock);
+ data_unref (pair->value);
- if (!ref)
- dict_destroy (this);
-}
+ if (pair->prev)
+ pair->prev->next = pair->next;
+ else
+ this->members_list = pair->next;
-dict_t *
-dict_ref (dict_t *this)
-{
- if (!this) {
- gf_log ("dict", GF_LOG_DEBUG,
- "@this=%p", this);
- return NULL;
- }
+ if (pair->next)
+ pair->next->prev = pair->prev;
- LOCK (&this->lock);
+ GF_FREE (pair->key);
+ if (pair == &this->free_pair) {
+ this->free_pair_in_use = _gf_false;
+ }
+ else {
+ mem_put (pair);
+ }
+ this->count--;
+ break;
+ }
- this->refcount++;
+ prev = pair;
+ pair = pair->hash_next;
+ }
- UNLOCK (&this->lock);
+ UNLOCK (&this->lock);
- return this;
+ return;
}
void
-data_unref (data_t *this)
+dict_destroy (dict_t *this)
{
- int32_t ref;
-
- if (!this) {
- gf_log ("dict", GF_LOG_DEBUG,
- "@this=%p", this);
- return;
- }
-
- LOCK (&this->lock);
-
- this->refcount--;
- ref = this->refcount;
+ if (!this) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is NULL");
+ return;
+ }
- UNLOCK (&this->lock);
+ data_pair_t *pair = this->members_list;
+ data_pair_t *prev = this->members_list;
- if (!ref)
- data_destroy (this);
-}
+ LOCK_DESTROY (&this->lock);
-data_t *
-data_ref (data_t *this)
-{
- if (!this) {
- gf_log ("dict", GF_LOG_DEBUG,
- "@this=%p", this);
- return NULL;
- }
+ while (prev) {
+ pair = pair->next;
+ data_unref (prev->value);
+ GF_FREE (prev->key);
+ if (prev != &this->free_pair) {
+ mem_put (prev);
+ }
+ prev = pair;
+ }
- LOCK (&this->lock);
+ if (this->members != &this->members_internal) {
+ mem_put (this->members);
+ }
- this->refcount++;
+ GF_FREE (this->extra_free);
+ free (this->extra_stdfree);
- UNLOCK (&this->lock);
+ if (!this->is_static)
+ mem_put (this);
- return this;
+ return;
}
-/*
- Serialization format:
- ----
- Count:8
- Key_len:8:Value_len:8
- Key
- Value
- .
- .
- .
-*/
-
-int32_t
-dict_serialized_length_old (dict_t *this)
+void
+dict_unref (dict_t *this)
{
+ int32_t ref;
- if (!this) {
- gf_log ("dict", GF_LOG_DEBUG,
- "@this=%p", this);
- return -1;
- }
+ if (!this) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is NULL");
+ return;
+ }
- 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--;
- }
+ LOCK (&this->lock);
- return len;
-}
+ this->refcount--;
+ ref = this->refcount;
-int32_t
-dict_serialize_old (dict_t *this, char *buf)
-{
- if (!this || !buf) {
- gf_log ("dict", GF_LOG_DEBUG,
- "@this=%p @buf=%p", this, buf);
- return -1;
- }
+ UNLOCK (&this->lock);
- 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);
+ if (!ref)
+ dict_destroy (this);
}
-
dict_t *
-dict_unserialize_old (char *buf, int32_t size, dict_t **fill)
+dict_ref (dict_t *this)
{
- int32_t ret = 0;
- int32_t cnt = 0;
-
- if (!buf || !fill || !(*fill)) {
- gf_log ("dict", GF_LOG_ERROR,
- "@buf=%p @fill=%p @*fill=%p",
- buf, fill, (fill) ? (*fill) : NULL);
- return NULL;
- }
-
- uint64_t count;
- ret = sscanf (buf, "%"SCNx64"\n", &count);
- (*fill)->count = 0;
-
- if (!ret){
- gf_log ("dict",
- GF_LOG_ERROR,
- "sscanf on buf failed");
- goto err;
- }
- buf += 9;
-
- if (count == 0) {
- gf_log ("dict",
- GF_LOG_ERROR,
- "count == 0");
- goto err;
- }
+ if (!this) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is NULL");
+ return NULL;
+ }
- 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;
-
- key = buf;
- buf += key_len;
-
- value = get_new_data ();
- value->len = value_len;
- value->data = buf;
- value->is_static = 1;
- buf += value_len;
-
- dict_set (*fill, key, value);
- }
+ LOCK (&this->lock);
- goto ret;
+ this->refcount++;
-err:
- GF_FREE (*fill);
- *fill = NULL;
+ UNLOCK (&this->lock);
-ret:
- return *fill;
+ return this;
}
-
-int32_t
-dict_iovec_len (dict_t *this)
+void
+data_unref (data_t *this)
{
- if (!this) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@this=%p", this);
- return -1;
- }
+ int32_t ref;
- int32_t len = 0;
- data_pair_t *pair = this->members_list;
+ if (!this) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is NULL");
+ return;
+ }
- len++; /* initial header */
- while (pair) {
- len++; /* pair header */
- len++; /* key */
+ LOCK (&this->lock);
- if (pair->value->vec)
- len += pair->value->len;
- else
- len++;
- pair = pair->next;
- }
+ this->refcount--;
+ ref = this->refcount;
- return len;
+ UNLOCK (&this->lock);
+
+ if (!ref)
+ data_destroy (this);
}
-int32_t
-dict_to_iovec (dict_t *this,
- struct iovec *vec,
- int32_t count)
+data_t *
+data_ref (data_t *this)
{
- if (!this || !vec) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@this=%p @vec=%p", this, vec);
- 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 (pair->value->vec) {
- int i;
+ if (!this) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is NULL");
+ return NULL;
+ }
- for (i=0; i<pair->value->len; i++) {
- vallen += pair->value->vec[i].iov_len;
- }
- } else {
- vallen = pair->value->len;
- }
+ LOCK (&this->lock);
- 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++;
- }
+ this->refcount++;
- pair = pair->next;
- }
+ UNLOCK (&this->lock);
- return 0;
+ return this;
}
data_t *
int_to_data (int64_t value)
{
int ret = 0;
- data_t *data = get_new_data ();
+ data_t *data = get_new_data ();
- if (!data) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@data - NULL returned by CALLOC");
- return NULL;
- }
+ if (!data) {
+ return NULL;
+ }
- ret = gf_asprintf (&data->data, "%"PRId64, value);
+ ret = gf_asprintf (&data->data, "%"PRId64, value);
if (-1 == ret) {
- gf_log ("dict", GF_LOG_ERROR, "asprintf failed");
+ gf_log ("dict", GF_LOG_DEBUG, "asprintf failed");
return NULL;
}
- data->len = strlen (data->data) + 1;
+ data->len = strlen (data->data) + 1;
- return data;
+ return data;
}
data_t *
data_from_int64 (int64_t value)
{
int ret = 0;
- data_t *data = get_new_data ();
+ data_t *data = get_new_data ();
- if (!data) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@data - NULL returned by CALLOC");
- return NULL;
- }
- ret = gf_asprintf (&data->data, "%"PRId64, value);
+ if (!data) {
+ return NULL;
+ }
+ ret = gf_asprintf (&data->data, "%"PRId64, value);
if (-1 == ret) {
- gf_log ("dict", GF_LOG_ERROR, "asprintf failed");
+ gf_log ("dict", GF_LOG_DEBUG, "asprintf failed");
return NULL;
}
- data->len = strlen (data->data) + 1;
+ data->len = strlen (data->data) + 1;
- return data;
+ return data;
}
data_t *
data_from_int32 (int32_t value)
{
int ret = 0;
- data_t *data = get_new_data ();
+ data_t *data = get_new_data ();
- if (!data) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@data - NULL returned by CALLOC");
- return NULL;
- }
- ret = gf_asprintf (&data->data, "%"PRId32, value);
+ if (!data) {
+ return NULL;
+ }
+ ret = gf_asprintf (&data->data, "%"PRId32, value);
if (-1 == ret) {
- gf_log ("dict", GF_LOG_ERROR, "asprintf failed");
+ gf_log ("dict", GF_LOG_DEBUG, "asprintf failed");
return NULL;
}
- data->len = strlen (data->data) + 1;
+ data->len = strlen (data->data) + 1;
- return data;
+ return data;
}
data_t *
data_from_int16 (int16_t value)
{
int ret = 0;
- data_t *data = get_new_data ();
+ data_t *data = get_new_data ();
- if (!data) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@data - NULL returned by CALLOC");
- return NULL;
- }
- ret = gf_asprintf (&data->data, "%"PRId16, value);
+ if (!data) {
+ return NULL;
+ }
+ ret = gf_asprintf (&data->data, "%"PRId16, value);
if (-1 == ret) {
- gf_log ("dict", GF_LOG_ERROR, "asprintf failed");
+ gf_log ("dict", GF_LOG_DEBUG, "asprintf failed");
return NULL;
}
- data->len = strlen (data->data) + 1;
+ data->len = strlen (data->data) + 1;
- return data;
+ return data;
}
data_t *
data_from_int8 (int8_t value)
{
int ret = 0;
- data_t *data = get_new_data ();
+ data_t *data = get_new_data ();
- if (!data) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@data - NULL returned by CALLOC");
- return NULL;
- }
- ret = gf_asprintf (&data->data, "%d", value);
+ if (!data) {
+ return NULL;
+ }
+ ret = gf_asprintf (&data->data, "%d", value);
if (-1 == ret) {
- gf_log ("dict", GF_LOG_ERROR, "asprintf failed");
+ gf_log ("dict", GF_LOG_DEBUG, "asprintf failed");
return NULL;
}
- data->len = strlen (data->data) + 1;
+ data->len = strlen (data->data) + 1;
- return data;
+ return data;
}
data_t *
data_from_uint64 (uint64_t value)
{
int ret = 0;
- data_t *data = get_new_data ();
+ data_t *data = get_new_data ();
- if (!data) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@data - NULL returned by CALLOC");
- return NULL;
- }
- ret = gf_asprintf (&data->data, "%"PRIu64, value);
+ if (!data) {
+ return NULL;
+ }
+ ret = gf_asprintf (&data->data, "%"PRIu64, value);
if (-1 == ret) {
- gf_log ("dict", GF_LOG_ERROR, "asprintf failed");
+ gf_log ("dict", GF_LOG_DEBUG, "asprintf failed");
return NULL;
}
- data->len = strlen (data->data) + 1;
+ data->len = strlen (data->data) + 1;
- return data;
+ return data;
}
static data_t *
data_from_double (double value)
{
- data_t *data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = 0;
- data = get_new_data ();
+ data = get_new_data ();
- if (!data) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@data - NULL returned by CALLOC");
- return NULL;
- }
+ if (!data) {
+ return NULL;
+ }
- ret = gf_asprintf (&data->data, "%f", value);
- if (ret == -1) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@data - allocation failed by ASPRINTF");
- return NULL;
- }
- data->len = strlen (data->data) + 1;
+ ret = gf_asprintf (&data->data, "%f", value);
+ if (ret == -1) {
+ return NULL;
+ }
+ data->len = strlen (data->data) + 1;
- return data;
+ return data;
}
@@ -908,22 +692,20 @@ data_t *
data_from_uint32 (uint32_t value)
{
int ret = 0;
- data_t *data = get_new_data ();
+ data_t *data = get_new_data ();
- if (!data) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@data - NULL returned by CALLOC");
- return NULL;
- }
- ret = gf_asprintf (&data->data, "%"PRIu32, value);
+ if (!data) {
+ return NULL;
+ }
+ ret = gf_asprintf (&data->data, "%"PRIu32, value);
if (-1 == ret) {
- gf_log ("dict", GF_LOG_ERROR, "asprintf failed");
+ gf_log ("dict", GF_LOG_DEBUG, "asprintf failed");
return NULL;
}
- data->len = strlen (data->data) + 1;
+ data->len = strlen (data->data) + 1;
- return data;
+ return data;
}
@@ -931,44 +713,38 @@ data_t *
data_from_uint16 (uint16_t value)
{
int ret = 0;
- data_t *data = get_new_data ();
+ data_t *data = get_new_data ();
- if (!data) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@data - NULL returned by CALLOC");
- return NULL;
- }
- ret = gf_asprintf (&data->data, "%"PRIu16, value);
+ if (!data) {
+ return NULL;
+ }
+ ret = gf_asprintf (&data->data, "%"PRIu16, value);
if (-1 == ret) {
- gf_log ("dict", GF_LOG_ERROR, "asprintf failed");
return NULL;
}
- data->len = strlen (data->data) + 1;
+ data->len = strlen (data->data) + 1;
- return data;
+ return data;
}
data_t *
data_from_ptr (void *value)
{
- if (!value) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@value=%p", value);
- return NULL;
- }
+ 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) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@data - NULL returned by CALLOC");
- return NULL;
- }
+ if (!data) {
+ return NULL;
+ }
- data->data = value;
- return data;
+ data->data = value;
+ return data;
}
data_t *
@@ -977,326 +753,517 @@ data_from_static_ptr (void *value)
/*
this is valid to set 0 as value..
- if (!value) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@value=%p", value);
- return NULL;
- }
+ if (!value) {
+ gf_log ("dict", GF_LOG_CRITICAL,
+ "@value=%p", value);
+ return NULL;
+ }
*/
- data_t *data = get_new_data ();
+ data_t *data = get_new_data ();
- if (!data) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@data - NULL returned by CALLOC");
- return NULL;
- }
+ if (!data) {
+ return NULL;
+ }
- data->is_static = 1;
- data->data = value;
+ data->is_static = 1;
+ data->data = value;
- return data;
+ return data;
}
data_t *
str_to_data (char *value)
{
- if (!value) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@value=%p", value);
- return NULL;
- }
- data_t *data = get_new_data ();
+ if (!value) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING, "value is NULL");
+ return NULL;
+ }
+ data_t *data = get_new_data ();
- if (!data) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@data - NULL returned by CALLOC");
- return NULL;
- }
- data->len = strlen (value) + 1;
+ if (!data) {
+ return NULL;
+ }
+ data->len = strlen (value) + 1;
- data->data = value;
- data->is_static = 1;
+ data->data = value;
+ data->is_static = 1;
- return data;
+ return data;
}
data_t *
data_from_dynstr (char *value)
{
- if (!value) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@value=%p", value);
- return NULL;
- }
+ 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 ();
- data->len = strlen (value) + 1;
- data->data = value;
+ data->len = strlen (value) + 1;
+ data->data = value;
- return data;
+ return data;
}
data_t *
data_from_dynmstr (char *value)
{
- if (!value) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@value=%p", value);
- return NULL;
- }
+ 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 ();
- data->len = strlen (value) + 1;
- data->data = value;
+ data->len = strlen (value) + 1;
+ data->data = value;
data->is_stdalloc = 1;
- return data;
+ return data;
}
data_t *
data_from_dynptr (void *value, int32_t len)
{
- data_t *data = get_new_data ();
+ data_t *data = get_new_data ();
- data->len = len;
- data->data = value;
+ if (!data)
+ return NULL;
+
+ data->len = len;
+ data->data = value;
- return data;
+ return data;
}
data_t *
bin_to_data (void *value, int32_t len)
{
- if (!value) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@value=%p", value);
- return NULL;
- }
+ 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->is_static = 1;
- data->len = len;
- data->data = value;
+ data->is_static = 1;
+ data->len = len;
+ data->data = value;
- return data;
+ return data;
}
int64_t
data_to_int64 (data_t *data)
{
- if (!data)
- return -1;
+ if (!data) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING, "data is NULL");
+ return -1;
+ }
- char *str = alloca (data->len + 1);
+ char *str = alloca (data->len + 1);
if (!str)
return -1;
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
- return (int64_t) strtoull (str, NULL, 0);
+ memcpy (str, data->data, data->len);
+ str[data->len] = '\0';
+ return (int64_t) strtoull (str, NULL, 0);
}
int32_t
data_to_int32 (data_t *data)
{
- if (!data)
- return -1;
+ if (!data) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING, "data is NULL");
+ return -1;
+ }
- char *str = alloca (data->len + 1);
+ char *str = alloca (data->len + 1);
if (!str)
return -1;
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
+ memcpy (str, data->data, data->len);
+ str[data->len] = '\0';
- return strtoul (str, NULL, 0);
+ return strtoul (str, NULL, 0);
}
int16_t
data_to_int16 (data_t *data)
{
- if (!data)
- return -1;
+ int16_t value = 0;
+
+ if (!data) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING, "data is NULL");
+ return -1;
+ }
- char *str = alloca (data->len + 1);
+ char *str = alloca (data->len + 1);
if (!str)
return -1;
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
+ memcpy (str, data->data, data->len);
+ str[data->len] = '\0';
+
+ errno = 0;
+ value = strtol (str, NULL, 0);
- return strtol (str, NULL, 0);
+ if ((value > SHRT_MAX) || (value < SHRT_MIN)) {
+ errno = ERANGE;
+ gf_log_callingfn ("dict", GF_LOG_WARNING,
+ "Error in data conversion: "
+ "detected overflow");
+ return -1;
+ }
+
+ return (int16_t)value;
}
int8_t
data_to_int8 (data_t *data)
{
- if (!data)
- return -1;
+ int8_t value = 0;
- char *str = alloca (data->len + 1);
+ if (!data) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING, "data is NULL");
+ return -1;
+ }
+
+ char *str = alloca (data->len + 1);
if (!str)
return -1;
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
+ memcpy (str, data->data, data->len);
+ str[data->len] = '\0';
+
+ errno = 0;
+ value = strtol (str, NULL, 0);
- return (int8_t)strtol (str, NULL, 0);
+ if ((value > SCHAR_MAX) || (value < SCHAR_MIN)) {
+ errno = ERANGE;
+ gf_log_callingfn ("dict", GF_LOG_WARNING,
+ "Error in data conversion: "
+ "detected overflow");
+ return -1;
+ }
+
+ return (int8_t)value;
}
uint64_t
data_to_uint64 (data_t *data)
{
- if (!data)
- return -1;
- char *str = alloca (data->len + 1);
+ if (!data)
+ return -1;
+ char *str = alloca (data->len + 1);
if (!str)
return -1;
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
+ memcpy (str, data->data, data->len);
+ str[data->len] = '\0';
- return strtoll (str, NULL, 0);
+ return strtoll (str, NULL, 0);
}
uint32_t
data_to_uint32 (data_t *data)
{
- if (!data)
- return -1;
+ if (!data)
+ return -1;
- char *str = alloca (data->len + 1);
+ char *str = alloca (data->len + 1);
if (!str)
return -1;
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
+ memcpy (str, data->data, data->len);
+ str[data->len] = '\0';
- return strtol (str, NULL, 0);
+ return strtol (str, NULL, 0);
}
uint16_t
data_to_uint16 (data_t *data)
{
- if (!data)
+ uint16_t value = 0;
+
+ if (!data)
+ return -1;
+
+ char *str = alloca (data->len + 1);
+ if (!str)
+ return -1;
+
+ memcpy (str, data->data, data->len);
+ str[data->len] = '\0';
+
+ errno = 0;
+ value = strtol (str, NULL, 0);
+
+ if ((USHRT_MAX - value) < 0) {
+ errno = ERANGE;
+ gf_log_callingfn ("dict", GF_LOG_WARNING,
+ "Error in data conversion: "
+ "overflow detected");
return -1;
+ }
+
+ return (uint16_t)value;
+}
+
+uint8_t
+data_to_uint8 (data_t *data)
+{
+ uint32_t value = 0;
- char *str = alloca (data->len + 1);
+ if (!data) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING, "data is NULL");
+ return -1;
+ }
+
+ char *str = alloca (data->len + 1);
if (!str)
return -1;
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
+ memcpy (str, data->data, data->len);
+ str[data->len] = '\0';
- return strtol (str, NULL, 0);
+ errno = 0;
+ value = strtol (str, NULL, 0);
+
+ if ((UCHAR_MAX - value) < 0) {
+ errno = ERANGE;
+ gf_log_callingfn ("dict", GF_LOG_WARNING,
+ "data conversion overflow detected (%s)",
+ strerror(errno));
+ return -1;
+ }
+
+ return (uint8_t) value;
}
char *
data_to_str (data_t *data)
{
- if (!data) {
- gf_log ("dict", GF_LOG_WARNING,
- "@data=%p", data);
- return NULL;
- }
- return data->data;
+ if (!data) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING, "data is NULL");
+ return NULL;
+ }
+ return data->data;
}
void *
data_to_ptr (data_t *data)
{
- if (!data) {
- return NULL;
- }
- return data->data;
+ if (!data) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING, "data is NULL");
+ return NULL;
+ }
+ return data->data;
}
void *
data_to_bin (data_t *data)
{
- if (!data) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@data=%p", data);
- return NULL;
- }
- return data->data;
+ if (!data) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING, "data is NULL");
+ return NULL;
+ }
+ return data->data;
}
-void
+int
+dict_null_foreach_fn (dict_t *d, char *k,
+ data_t *v, void *tmp)
+{
+ return 0;
+}
+
+int
dict_foreach (dict_t *dict,
- void (*fn)(dict_t *this,
- char *key,
- data_t *value,
- void *data),
- void *data)
-{
- if (!data || !dict) {
- gf_log_callingfn ("dict", GF_LOG_CRITICAL,
- "@data=%p, @dict=%p", data, dict);
- return;
+ int (*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 -1;
}
- data_pair_t *pairs = dict->members_list;
- data_pair_t *next = NULL;
+ int ret = -1;
+ data_pair_t *pairs = NULL;
+ data_pair_t *next = NULL;
+ pairs = dict->members_list;
while (pairs) {
next = pairs->next;
- fn (dict, pairs->key, pairs->value, data);
+ ret = fn (dict, pairs->key, pairs->value, data);
+ if (ret == -1)
+ return -1;
pairs = next;
}
+
+ return 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 (!dict) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING,
+ "dict is NULL");
+ return 0;
+ }
+
+ int ret = -1;
+ int count = 0;
+ data_pair_t *pairs = NULL;
+ data_pair_t *next = NULL;
+
+ pairs = dict->members_list;
+ while (pairs) {
+ next = pairs->next;
+ if (!fnmatch (pattern, pairs->key, 0)) {
+ ret = fn (dict, pairs->key, pairs->value, data);
+ if (ret == -1)
+ return -1;
+ count++;
+ }
+ pairs = next;
+ }
+
+ return count;
+}
+
+
+/**
+ * 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 = NULL;
+ data_pair_t *next = NULL;
+
+ pairs = dict->members_list;
+ while (pairs) {
+ next = pairs->next;
+
+ if (filter_fn && filter_fn (pairs->key)){
+ pairs = next;
+ continue;
+ }
+
+ if (value && (size > len))
+ strncpy (value + len, pairs->key, size - len);
+
+ len += (strlen (pairs->key) + 1);
+
+ pairs = next;
+ }
+
+ return len;
+}
-static void
+static int
_copy (dict_t *unused,
char *key,
data_t *value,
void *newdict)
{
- dict_set ((dict_t *)newdict, key, (value));
+ return dict_set ((dict_t *)newdict, key, (value));
+}
+
+static int
+_remove (dict_t *dict,
+ char *key,
+ data_t *value,
+ void *unused)
+{
+ dict_del ((dict_t *)dict, key);
+ return 0;
}
dict_t *
dict_copy (dict_t *dict,
- dict_t *new)
+ dict_t *new)
{
- if (!dict) {
- gf_log ("dict", GF_LOG_CRITICAL,
- "@data=%p", dict);
- return NULL;
- }
+ if (!dict) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING, "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, _copy, new);
- return new;
+ return new;
+}
+
+int
+dict_reset (dict_t *dict)
+{
+ int32_t ret = -1;
+ if (!dict) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is NULL");
+ goto out;
+ }
+ dict_foreach (dict, _remove, NULL);
+ ret = 0;
+out:
+ return ret;
}
dict_t *
dict_copy_with_ref (dict_t *dict,
- dict_t *new)
+ 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, _copy, new);
fail:
- return new;
+ return new;
}
/*
@@ -1305,7 +1272,7 @@ fail:
/**
* Common cleaned up interface:
- *
+ *
* Return value: 0 success
* -val error, val = errno
*/
@@ -1314,506 +1281,508 @@ fail:
static int
dict_get_with_ref (dict_t *this, char *key, data_t **data)
{
- data_pair_t * pair = NULL;
- int ret = -ENOENT;
+ data_pair_t * pair = NULL;
+ int ret = -ENOENT;
- if (!this || !key || !data) {
- ret = -EINVAL;
- goto err;
- }
+ if (!this || !key || !data) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING,
+ "dict OR key (%s) is NULL", key);
+ ret = -EINVAL;
+ goto err;
+ }
- LOCK (&this->lock);
- {
- pair = _dict_lookup (this, key);
- }
- UNLOCK (&this->lock);
+ LOCK (&this->lock);
+ {
+ pair = _dict_lookup (this, key);
+ }
+ UNLOCK (&this->lock);
- if (pair) {
- ret = 0;
- *data = data_ref (pair->value);
- }
+ if (pair) {
+ ret = 0;
+ *data = data_ref (pair->value);
+ }
-err:
- return ret;
+err:
+ return ret;
}
static int
_data_to_ptr (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)
{
- int ret = 0;
- char * str = NULL;
+ int ret = 0;
+ char * str = NULL;
- 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';
+ 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 (str, NULL, 0);
+ if (errno != 0)
+ ret = -errno;
err:
- return ret;
+ return ret;
}
static int
_data_to_int16 (data_t *data, int16_t *val)
{
- int ret = 0;
- char * str = NULL;
+ int ret = 0;
+ char * str = NULL;
- 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';
+ 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 (str, NULL, 0);
+ if (errno != 0)
+ ret = -errno;
err:
- return ret;
+ return ret;
}
static int
_data_to_int32 (data_t *data, int32_t *val)
{
- int ret = 0;
- char * str = NULL;
+ int ret = 0;
+ char * str = NULL;
- 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';
+ 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 (str, NULL, 0);
+ if (errno != 0)
+ ret = -errno;
err:
- return ret;
+ return ret;
}
static int
_data_to_int64 (data_t *data, int64_t *val)
{
- int ret = 0;
- char * str = NULL;
+ int ret = 0;
+ char * str = NULL;
- 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';
+ 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 (str, NULL, 0);
+ if (errno != 0)
+ ret = -errno;
err:
- return ret;
+ return ret;
}
static int
_data_to_uint16 (data_t *data, uint16_t *val)
{
- int ret = 0;
- char * str = NULL;
+ int ret = 0;
+ char * str = NULL;
- 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';
+ str = alloca (data->len + 1);
+ if (!str) {
+ ret = -ENOMEM;
+ goto err;
+ }
+ memcpy (str, data->data, data->len);
+ str[data->len] = '\0';
- errno = 0;
- *val = strtoul (str, NULL, 0);
- if (errno != 0)
- ret = -errno;
+ errno = 0;
+ *val = strtoul (str, NULL, 0);
+ if (errno != 0)
+ ret = -errno;
err:
- return ret;
+ return ret;
}
static int
_data_to_uint32 (data_t *data, uint32_t *val)
{
- int ret = 0;
- char * str = NULL;
+ int ret = 0;
+ char * str = NULL;
- 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';
+ str = alloca (data->len + 1);
+ if (!str) {
+ ret = -ENOMEM;
+ goto err;
+ }
+ memcpy (str, data->data, data->len);
+ str[data->len] = '\0';
- errno = 0;
- *val = strtoul (str, NULL, 0);
- if (errno != 0)
- ret = -errno;
+ errno = 0;
+ *val = strtoul (str, NULL, 0);
+ if (errno != 0)
+ ret = -errno;
err:
- return ret;
+ return ret;
}
static int
_data_to_uint64 (data_t *data, uint64_t *val)
{
- int ret = 0;
- char * str = NULL;
+ int ret = 0;
+ char * str = NULL;
- 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';
+ 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 (str, NULL, 0);
+ if (errno != 0)
+ ret = -errno;
err:
- return ret;
+ return ret;
}
static int
_data_to_double (data_t *data, double *val)
{
- int ret = 0;
- char * str = NULL;
+ int ret = 0;
+ char * str = NULL;
- 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';
+ str = alloca (data->len + 1);
+ if (!str) {
+ ret = -ENOMEM;
+ goto err;
+ }
+ memcpy (str, data->data, data->len);
+ str[data->len] = '\0';
- errno = 0;
- *val = strtod (str, NULL);
- if (errno != 0)
- ret = -errno;
+ errno = 0;
+ *val = strtod (str, NULL);
+ if (errno != 0)
+ ret = -errno;
err:
- return ret;
+ return ret;
}
int
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 (!this || !key || !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_int8 (data, val);
- ret = _data_to_int8 (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)
{
- 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);
err:
- return ret;
+ return ret;
}
int
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 (!this || !key || !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);
- ret = _data_to_int16 (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_t * data = NULL;
+ int ret = 0;
- data = data_from_int16 (val);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ data = data_from_int16 (val);
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
+ ret = dict_set (this, key, data);
err:
- return ret;
+ return ret;
}
int
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 (!this || !key || !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_int32 (data, val);
- ret = _data_to_int32 (data, val);
-
err:
- if (data)
- data_unref (data);
- return ret;
+ if (data)
+ data_unref (data);
+ return ret;
}
int
dict_set_int32 (dict_t *this, char *key, int32_t val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t * data = NULL;
+ int ret = 0;
- data = data_from_int32 (val);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ data = data_from_int32 (val);
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
+ ret = dict_set (this, key, data);
err:
- return ret;
+ return ret;
}
int
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 (!this || !key || !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_int64 (data, val);
- ret = _data_to_int64 (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)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t * data = NULL;
+ int ret = 0;
- data = data_from_int64 (val);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ data = data_from_int64 (val);
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
+ ret = dict_set (this, key, data);
err:
- return ret;
+ return ret;
}
int
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 (!this || !key || !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_uint16 (data, val);
- ret = _data_to_uint16 (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)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t * data = NULL;
+ int ret = 0;
- data = data_from_uint16 (val);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ data = data_from_uint16 (val);
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
+ ret = dict_set (this, key, data);
err:
- return ret;
+ return ret;
}
int
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 (!this || !key || !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_uint32 (data, val);
- ret = _data_to_uint32 (data, val);
-
err:
- if (data)
- data_unref (data);
- return ret;
+ if (data)
+ data_unref (data);
+ return ret;
}
@@ -1821,355 +1790,385 @@ err:
int
dict_set_uint32 (dict_t *this, char *key, uint32_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;
- }
+ data = data_from_uint32 (val);
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
+ ret = dict_set (this, key, data);
err:
- return ret;
+ return ret;
}
int
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;
- if (!this || !key || !val) {
- ret = -EINVAL;
- goto err;
- }
+ if (!this || !key || !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_uint64 (data, val);
- ret = _data_to_uint64 (data, val);
-
err:
- if (data)
- data_unref (data);
- return ret;
+ if (data)
+ data_unref (data);
+ return ret;
}
int
dict_set_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_uint64 (val);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ data = data_from_uint64 (val);
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
+ ret = dict_set (this, key, data);
err:
- return ret;
+ return ret;
}
int
dict_get_double (dict_t *this, char *key, double *val)
{
- data_t *data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = 0;
- if (!this || !key || !val) {
- ret = -EINVAL;
- goto err;
- }
+ if (!this || !key || !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_double (data, val);
+ ret = _data_to_double (data, val);
err:
- if (data)
- data_unref (data);
- return ret;
+ if (data)
+ data_unref (data);
+ return ret;
}
int
dict_set_double (dict_t *this, char *key, double val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t * data = NULL;
+ int ret = 0;
- data = data_from_double (val);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ data = data_from_double (val);
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
+ ret = dict_set (this, key, data);
err:
- return ret;
+ return ret;
}
int
dict_set_static_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_static_ptr (ptr);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ data = data_from_static_ptr (ptr);
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
+ ret = dict_set (this, key, data);
err:
- return ret;
+ return ret;
}
int
dict_set_dynptr (dict_t *this, char *key, void *ptr, size_t len)
{
- 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;
- }
+ data = data_from_dynptr (ptr, len);
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
+ ret = dict_set (this, key, data);
err:
- return ret;
+ return ret;
}
int
dict_get_ptr (dict_t *this, char *key, void **ptr)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t * data = NULL;
+ int ret = 0;
- if (!this || !key || !ptr) {
- ret = -EINVAL;
- goto err;
- }
+ if (!this || !key || !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;
- }
+ ret = _data_to_ptr (data, ptr);
+ if (ret != 0) {
+ goto err;
+ }
+
+err:
+ if (data)
+ data_unref (data);
+
+ return ret;
+}
+
+int
+dict_get_ptr_and_len (dict_t *this, char *key, void **ptr, int *len)
+{
+ data_t * data = NULL;
+ int ret = 0;
+
+ if (!this || !key || !ptr) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ ret = dict_get_with_ref (this, key, &data);
+ if (ret != 0) {
+ goto err;
+ }
+
+ *len = data->len;
-err:
- if (data)
- data_unref (data);
+ ret = _data_to_ptr (data, ptr);
+ if (ret != 0) {
+ goto err;
+ }
- return ret;
+err:
+ if (data)
+ data_unref (data);
+
+ return ret;
}
int
dict_set_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_ptr (ptr);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ data = data_from_ptr (ptr);
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
+ ret = dict_set (this, key, data);
err:
- return ret;
+ return ret;
}
int
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 (!this || !key || !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;
+ }
- if (!data || !data->data) {
- goto err;
- }
- *str = data->data;
+ if (!data || !data->data) {
+ goto err;
+ }
+ *str = data->data;
-err:
- if (data)
- data_unref (data);
+err:
+ if (data)
+ data_unref (data);
- return ret;
+ return ret;
}
int
dict_set_str (dict_t *this, char *key, char *str)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t * data = NULL;
+ int ret = 0;
- data = str_to_data (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_set (this, key, data);
err:
- return ret;
+ return ret;
}
int
dict_set_dynstr (dict_t *this, char *key, 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 = data_from_dynstr (str);
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
+ ret = dict_set (this, key, data);
err:
- return ret;
+ return ret;
}
/*
- for malloced strings we should do a free instead of GF_FREE
+ for malloced strings we should do a free instead of GF_FREE
*/
int
dict_set_dynmstr (dict_t *this, char *key, char *str)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t * data = NULL;
+ int ret = 0;
- data = data_from_dynmstr (str);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ data = data_from_dynmstr (str);
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
+ ret = dict_set (this, key, data);
err:
- return ret;
+ return ret;
}
int
dict_get_bin (dict_t *this, char *key, void **bin)
{
- data_t * data = NULL;
- int ret = -EINVAL;
+ data_t * data = NULL;
+ int ret = -EINVAL;
- if (!this || !key || !bin) {
- goto err;
- }
+ if (!this || !key || !bin) {
+ 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;
+ }
- if (!data || !data->data) {
- goto err;
- }
- *bin = data->data;
+ if (!data || !data->data) {
+ goto err;
+ }
+ *bin = data->data;
-err:
- if (data)
- data_unref (data);
+err:
+ if (data)
+ data_unref (data);
- return ret;
+ return ret;
}
int
dict_set_bin (dict_t *this, char *key, void *ptr, size_t size)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t * data = NULL;
+ int ret = 0;
- if (!ptr || (size < 0)) {
- ret = -EINVAL;
- goto err;
- }
+ if (!ptr || (size < 0)) {
+ ret = -EINVAL;
+ goto err;
+ }
- data = bin_to_data (ptr, size);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ data = bin_to_data (ptr, size);
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- data->data = ptr;
- data->len = size;
- data->is_static = 0;
+ data->data = ptr;
+ data->len = size;
+ data->is_static = 0;
- ret = dict_set (this, key, data);
+ ret = dict_set (this, key, data);
err:
- return ret;
+ return ret;
}
int
dict_set_static_bin (dict_t *this, char *key, void *ptr, size_t size)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t * data = NULL;
+ int ret = 0;
- if (!ptr || (size < 0)) {
- ret = -EINVAL;
- goto err;
- }
+ if (!ptr || (size < 0)) {
+ ret = -EINVAL;
+ goto err;
+ }
- data = bin_to_data (ptr, size);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ data = bin_to_data (ptr, size);
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- data->data = ptr;
- data->len = size;
- data->is_static = 1;
+ data->data = ptr;
+ data->len = size;
+ data->is_static = 1;
- ret = dict_set (this, key, data);
+ ret = dict_set (this, key, data);
err:
- return ret;
+ return ret;
}
@@ -2257,81 +2256,67 @@ err:
int
_dict_serialized_length (dict_t *this)
{
- int ret = -EINVAL;
- int count = 0;
- int len = 0;
- int i = 0;
- data_pair_t * pair = NULL;
+ int ret = -EINVAL;
+ int count = 0;
+ int len = 0;
+ data_pair_t * pair = NULL;
- len = DICT_HDR_LEN;
- count = this->count;
+ len = DICT_HDR_LEN;
+ count = this->count;
- if (count < 0) {
- gf_log ("dict", GF_LOG_ERROR, "count (%d) < 0!", count);
- goto out;
- }
+ if (count < 0) {
+ gf_log ("dict", GF_LOG_ERROR, "count (%d) < 0!", count);
+ goto out;
+ }
- pair = this->members_list;
+ pair = this->members_list;
- while (count) {
- if (!pair) {
- gf_log ("dict", GF_LOG_ERROR,
- "less than count data pairs found!");
- goto out;
- }
+ 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;
+ 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;
- }
+ if (!pair->key) {
+ gf_log ("dict", GF_LOG_ERROR, "pair->key is null!");
+ goto out;
+ }
- len += strlen (pair->key) + 1 /* for '\0' */;
+ 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) {
+ 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;
- }
-
- 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 (pair->value->len < 0) {
+ gf_log ("dict", GF_LOG_ERROR,
+ "value->len (%d) < 0",
+ pair->value->len);
+ goto out;
+ }
- pair = pair->next;
- count--;
- }
-
- ret = len;
+ len += pair->value->len;
+
+ pair = pair->next;
+ count--;
+ }
+
+ ret = len;
out:
- return ret;
+ return ret;
}
/**
- * _dict_serialize - serialize a dictionary into a buffer. This procedure has
+ * _dict_serialize - 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
+ * @buf: buffer to serialize into. This must be
* atleast dict_serialized_length (this) large
*
* @return: success: 0
@@ -2341,78 +2326,80 @@ out:
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;
- }
-
- count = this->count;
- if (count < 0) {
- gf_log ("dict", GF_LOG_ERROR, "count (%d) < 0!", count);
- goto out;
- }
+ int ret = -1;
+ data_pair_t * pair = NULL;
+ int32_t count = 0;
+ int32_t keylen = 0;
+ int32_t vallen = 0;
+ int32_t netword = 0;
- 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 (!buf) {
+ gf_log ("dict", GF_LOG_ERROR,
+ "buf is null!");
+ 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;
+ count = this->count;
+ if (count < 0) {
+ gf_log ("dict", GF_LOG_ERROR, "count (%d) < 0!", count);
+ goto out;
+ }
- if (!pair->value) {
- gf_log ("dict", GF_LOG_ERROR,
- "pair->value is null!");
- goto out;
- }
+ netword = hton32 (count);
+ memcpy (buf, &netword, sizeof(netword));
+ buf += DICT_HDR_LEN;
+ pair = this->members_list;
- vallen = pair->value->len;
- netword = hton32 (vallen);
- memcpy (buf, &netword, sizeof(netword));
- buf += DICT_DATA_HDR_VAL_LEN;
+ while (count) {
+ if (!pair) {
+ gf_log ("dict", GF_LOG_ERROR,
+ "less than count data pairs found!");
+ goto out;
+ }
- memcpy (buf, pair->key, keylen);
- buf += keylen;
- *buf++ = '\0';
+ if (!pair->key) {
+ gf_log ("dict", GF_LOG_ERROR,
+ "pair->key is null!");
+ goto out;
+ }
- 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;
+ keylen = strlen (pair->key);
+ netword = hton32 (keylen);
+ memcpy (buf, &netword, sizeof(netword));
+ buf += DICT_DATA_HDR_KEY_LEN;
- pair = pair->next;
- count--;
- }
+ if (!pair->value) {
+ gf_log ("dict", GF_LOG_ERROR,
+ "pair->value is null!");
+ goto out;
+ }
+
+ vallen = pair->value->len;
+ netword = hton32 (vallen);
+ memcpy (buf, &netword, sizeof(netword));
+ buf += DICT_DATA_HDR_VAL_LEN;
+
+ memcpy (buf, pair->key, keylen);
+ buf += keylen;
+ *buf++ = '\0';
- ret = 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--;
+ }
+
+ ret = 0;
out:
- return ret;
+ return ret;
}
@@ -2427,13 +2414,13 @@ out:
int
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_log ("dict", GF_LOG_ERROR, "this is null!");
- goto out;
- }
-
LOCK (&this->lock);
{
ret = _dict_serialized_length (this);
@@ -2441,14 +2428,14 @@ dict_serialized_length (dict_t *this)
UNLOCK (&this->lock);
out:
- return ret;
+ return ret;
}
/**
* dict_serialize - serialize a dictionary into a buffer
*
* @this: dict to serialize
- * @buf: buffer to serialize into. This must be
+ * @buf: buffer to serialize into. This must be
* atleast dict_serialized_length (this) large
*
* @return: success: 0
@@ -2458,18 +2445,12 @@ out:
int
dict_serialize (dict_t *this, char *buf)
{
- int ret = -1;
-
- if (!this) {
- gf_log ("dict", GF_LOG_ERROR,
- "this is null!");
- goto out;
- }
- if (!buf) {
- gf_log ("dict", GF_LOG_ERROR,
- "buf is null!");
- goto out;
- }
+ int ret = -1;
+
+ if (!this || !buf) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is null!");
+ goto out;
+ }
LOCK (&this->lock);
{
@@ -2477,7 +2458,7 @@ dict_serialize (dict_t *this, char *buf)
}
UNLOCK (&this->lock);
out:
- return ret;
+ return ret;
}
@@ -2487,7 +2468,7 @@ out:
* @buf: buf containing serialized dict
* @size: size of the @buf
* @fill: dict to fill in
- *
+ *
* @return: success: 0
* failure: -errno
*/
@@ -2495,116 +2476,120 @@ 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;
+ char *buf = NULL;
+ 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;
+ data_t * value = NULL;
+ char * key = NULL;
+ int32_t keylen = 0;
+ int32_t vallen = 0;
+ int32_t hostord = 0;
- buf = orig_buf;
+ buf = orig_buf;
- if (!buf) {
- gf_log ("dict", GF_LOG_ERROR,
- "buf is null!");
- goto out;
- }
+ if (!buf) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING, "buf is null!");
+ goto out;
+ }
- if (size == 0) {
- gf_log ("dict", GF_LOG_ERROR,
- "size is 0!");
- goto out;
- }
+ if (size == 0) {
+ gf_log_callingfn ("dict", GF_LOG_ERROR,
+ "size is 0!");
+ goto out;
+ }
- if (!fill) {
- gf_log ("dict", GF_LOG_ERROR,
- "fill is null!");
- goto out;
- }
+ if (!fill) {
+ gf_log_callingfn ("dict", GF_LOG_ERROR,
+ "fill is null!");
+ goto out;
+ }
- if (!*fill) {
- gf_log ("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 ("dict", GF_LOG_ERROR,
- "undersized buffer passed");
- 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;
+ 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 (count < 0) {
+ gf_log ("dict", GF_LOG_ERROR,
+ "count (%d) <= 0", count);
+ 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_log ("dict", GF_LOG_DEBUG,
- "No room for keylen (size %d).",
- DICT_DATA_HDR_KEY_LEN);
- gf_log ("dict", GF_LOG_ERROR,
- "undersized buffer passed");
- 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 ("dict", GF_LOG_DEBUG,
- "No room for vallen (size %d).",
- DICT_DATA_HDR_VAL_LEN);
- gf_log ("dict", GF_LOG_ERROR,
- "undersized buffer passed");
- goto out;
- }
- memcpy (&hostord, buf, sizeof(hostord));
- vallen = ntoh32 (hostord);
- buf += DICT_DATA_HDR_VAL_LEN;
-
- if ((buf + keylen) > (orig_buf + size)) {
- gf_log ("dict", GF_LOG_DEBUG,
- "No room for key (size %d).", keylen);
- gf_log ("dict", GF_LOG_ERROR,
- "undersized buffer passed");
- goto out;
- }
- key = buf;
- buf += keylen + 1; /* for '\0' */
-
- if ((buf + vallen) > (orig_buf + size)) {
- gf_log ("dict", GF_LOG_DEBUG,
- "No room for value (size %d).", vallen);
- gf_log ("dict", GF_LOG_ERROR,
- "undersized buffer passed");
- goto out;
- }
- value = get_new_data ();
- value->len = vallen;
- value->data = buf;
- value->is_static = 1;
- 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));
+ goto out;
+ }
+ value = get_new_data ();
+ value->len = vallen;
+ value->data = memdup (buf, vallen);
+ value->is_static = 0;
+ buf += vallen;
- dict_set (*fill, key, value);
- }
+ dict_add (*fill, key, value);
+ }
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
@@ -2613,31 +2598,26 @@ out:
*
* @this: dict to serialize
* @buf: pointer to pointer to character. The allocated buffer is stored in
- * this pointer. The buffer has to be freed by the caller.
+ * this pointer. The buffer has to be freed by the caller.
*
* @return: success: 0
* failure: -errno
*/
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) {
- gf_log ("dict", GF_LOG_DEBUG,
- "NULL passed as this pointer");
- goto out;
- }
- if (!buf) {
- gf_log ("dict", GF_LOG_DEBUG,
- "NULL passed as buf");
- goto out;
- }
-
LOCK (&this->lock);
- {
+ {
len = _dict_serialized_length (this);
if (len < 0) {
ret = len;
@@ -2647,7 +2627,6 @@ dict_allocate_and_serialize (dict_t *this, char **buf, size_t *length)
*buf = GF_CALLOC (1, len, gf_common_mt_char);
if (*buf == NULL) {
ret = -ENOMEM;
- gf_log ("dict", GF_LOG_ERROR, "out of memory");
goto unlock;
}
@@ -2665,5 +2644,138 @@ dict_allocate_and_serialize (dict_t *this, char **buf, size_t *length)
unlock:
UNLOCK (&this->lock);
out:
- return ret;
+ return ret;
+}
+
+/**
+ * _dict_serialize_value_with_delim: serialize the values in the dictionary
+ * into a buffer separated by delimiter (except the last)
+ *
+ * @this : dictionary to serialize
+ * @buf : the buffer to store the serialized data
+ * @serz_len : the length of the serialized data (excluding the last delimiter)
+ * @delimiter : the delimiter to separate the values
+ *
+ * @return : 0 -> success
+ * : -errno -> faliure
+ */
+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;
+ }
+
+ 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;
+ }
+
+ if (!pair->key || !pair->value) {
+ gf_log ("dict", GF_LOG_ERROR,
+ "key or value is null");
+ goto out;
+ }
+
+ if (!pair->value->data) {
+ gf_log ("dict", GF_LOG_ERROR,
+ "null value found in dict");
+ goto out;
+ }
+
+ vallen = pair->value->len - 1; // length includes \0
+ memcpy (buf, pair->value->data, vallen);
+ buf += vallen;
+ *buf++ = delimiter;
+
+ total_len += (vallen + 1);
+
+ pair = pair->next;
+ count--;
+ }
+
+ *--buf = '\0'; // remove the last delimiter
+ total_len--; // adjust the length
+ ret = 0;
+
+ if (serz_len)
+ *serz_len = total_len;
+
+ out:
+ return ret;
+}
+
+int
+dict_serialize_value_with_delim (dict_t *this, char *buf, int32_t *serz_len,
+ char delimiter)
+{
+ int ret = -1;
+
+ if (!this || !buf) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is null!");
+ goto out;
+ }
+
+ LOCK (&this->lock);
+ {
+ ret = _dict_serialize_value_with_delim (this, buf, serz_len, delimiter);
+ }
+ UNLOCK (&this->lock);
+out:
+ return ret;
+}
+
+void
+dict_dump (dict_t *this)
+{
+ int ret = 0;
+ int dumplen = 0;
+ data_pair_t *trav = NULL;
+ char dump[64*1024]; /* This is debug only, hence
+ performance should not matter */
+
+ if (!this) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING, "dict NULL");
+ goto out;
+ }
+
+ dump[0] = '\0'; /* the array is not initialized to '\0' */
+
+ /* There is a possibility of issues if data is binary, ignore it
+ for now as debugging is more important */
+ for (trav = this->members_list; trav; trav = trav->next) {
+ ret = snprintf (&dump[dumplen], ((64*1024) - dumplen - 1),
+ "(%s:%s)", trav->key, trav->value->data);
+ if ((ret == -1) || !ret)
+ break;
+
+ dumplen += ret;
+ /* snprintf doesn't append a trailing '\0', add it here */
+ dump[dumplen] = '\0';
+ }
+
+ if (dumplen)
+ gf_log_callingfn ("dict", GF_LOG_INFO,
+ "dict=%p (%s)", this, dump);
+
+out:
+ return;
}
diff --git a/libglusterfs/src/dict.h b/libglusterfs/src/dict.h
index 417967051..9b41b5a7d 100644
--- a/libglusterfs/src/dict.h
+++ b/libglusterfs/src/dict.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
#ifndef _DICT_H
@@ -35,62 +26,102 @@ typedef struct _data data_t;
typedef struct _dict dict_t;
typedef struct _data_pair data_pair_t;
+
+#define GF_PROTOCOL_DICT_SERIALIZE(this,from_dict,to,len,ope,labl) do { \
+ int ret = 0; \
+ \
+ if (!from_dict) \
+ break; \
+ \
+ ret = dict_allocate_and_serialize (from_dict, to, &len);\
+ if (ret < 0) { \
+ gf_log (this->name, GF_LOG_WARNING, \
+ "failed to get serialized dict (%s)", \
+ (#from_dict)); \
+ ope = EINVAL; \
+ goto labl; \
+ } \
+ } while (0)
+
+
+#define GF_PROTOCOL_DICT_UNSERIALIZE(xl,to,buff,len,ret,ope,labl) do { \
+ if (!len) \
+ break; \
+ to = dict_new(); \
+ GF_VALIDATE_OR_GOTO (xl->name, to, labl); \
+ \
+ ret = dict_unserialize (buff, len, &to); \
+ if (ret < 0) { \
+ gf_log (xl->name, GF_LOG_WARNING, \
+ "failed to unserialize dictionary (%s)", \
+ (#to)); \
+ \
+ ope = EINVAL; \
+ goto labl; \
+ } \
+ \
+ } while (0)
+
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;
+ unsigned char is_static:1;
+ unsigned char is_const:1;
+ unsigned char is_stdalloc:1;
+ int32_t len;
+ 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 _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;
+ 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;
+ data_pair_t *members_internal;
+ data_pair_t free_pair;
+ gf_boolean_t free_pair_in_use;
};
int32_t is_data_equal (data_t *one, data_t *two);
void data_destroy (data_t *data);
+/* function to set a key/value pair (overwrite existing if matches the key */
int32_t dict_set (dict_t *this, char *key, data_t *value);
+/* function to set a new key/value pair (without checking for duplicate) */
+int32_t dict_add (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);
+int dict_reset (dict_t *dict);
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_allocate_and_serialize (dict_t *this, char **buf, u_int *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);
-/*
+int32_t dict_lookup (dict_t *this, char *key, data_t **data);
+/*
TODO: provide converts for differnt byte sizes, signedness, and void *
*/
data_t *int_to_data (int64_t value);
@@ -109,6 +140,7 @@ 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);
+uint8_t data_to_uint8 (data_t *data);
data_t *data_from_ptr (void *value);
data_t *data_from_static_ptr (void *value);
@@ -127,25 +159,36 @@ 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 ();
+int dict_foreach (dict_t *this,
+ int (*fn)(dict_t *this,
+ char *key,
+ data_t *value,
+ void *data),
+ void *data);
+
+int dict_foreach_fnmatch (dict_t *dict, char *pattern,
+ int (*fn)(dict_t *this,
+ char *key,
+ data_t *value,
+ void *data),
+ void *data);
-void dict_foreach (dict_t *this,
- void (*fn)(dict_t *this,
- char *key,
- data_t *value,
- void *data),
- void *data);
+int dict_null_foreach_fn (dict_t *d, char *k,
+ data_t *v, void *tmp);
-dict_t *dict_copy (dict_t *this,
- dict_t *new);
+dict_t *dict_copy (dict_t *this, dict_t *new);
+int dict_keys_join (void *value, int size, dict_t *dict,
+ int (*filter_fn)(char *key));
/* CLEANED UP FUNCTIONS DECLARATIONS */
GF_MUST_CHECK dict_t *dict_new (void);
-dict_t *dict_copy_with_ref (dict_t *this,
- dict_t *new);
+dict_t *dict_copy_with_ref (dict_t *this, dict_t *new);
+
+GF_MUST_CHECK int dict_reset (dict_t *dict);
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);
@@ -173,6 +216,7 @@ 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_get_ptr_and_len (dict_t *this, char *key, void **ptr, int *len);
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);
@@ -186,4 +230,8 @@ 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);
+
+void dict_dump (dict_t *dict);
#endif
diff --git a/libglusterfs/src/event-epoll.c b/libglusterfs/src/event-epoll.c
new file mode 100644
index 000000000..06b323624
--- /dev/null
+++ b/libglusterfs/src/event-epoll.c
@@ -0,0 +1,463 @@
+/*
+ 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 "logging.h"
+#include "event.h"
+#include "mem-pool.h"
+#include "common-utils.h"
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+
+#ifdef HAVE_SYS_EPOLL_H
+#include <sys/epoll.h>
+
+
+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;
+}
+
+
+static struct event_pool *
+event_pool_new_epoll (int count)
+{
+ 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;
+
+ 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);
+
+out:
+ return event_pool;
+}
+
+
+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)
+{
+ 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;
+}
+
+
+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);
+
+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;
+}
+
+
+static int
+event_dispatch_epoll (struct event_pool *event_pool)
+{
+ struct epoll_event *events = NULL;
+ int size = 0;
+ int i = 0;
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("event", event_pool, out);
+
+ while (1) {
+ pthread_mutex_lock (&event_pool->mutex);
+ {
+ while (event_pool->used == 0)
+ pthread_cond_wait (&event_pool->cond,
+ &event_pool->mutex);
+
+ if (event_pool->used > event_pool->evcache_size) {
+ 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);
+ }
+ }
+
+out:
+ 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_dispatch = event_dispatch_epoll
+};
+
+#endif
diff --git a/libglusterfs/src/event-history.c b/libglusterfs/src/event-history.c
new file mode 100644
index 000000000..82baa521a
--- /dev/null
+++ b/libglusterfs/src/event-history.c
@@ -0,0 +1,83 @@
+/*
+ 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 "event-history.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) {
+ gf_log ("", GF_LOG_ERROR, "allocating history failed.");
+ goto out;
+ }
+
+ buffer = cb_buffer_new (buffer_size, use_buffer_once,
+ destroy_buffer_data);
+ if (!buffer) {
+ gf_log ("", GF_LOG_ERROR, "allocating circular buffer failed");
+ GF_FREE (history);
+ history = NULL;
+ }
+
+ 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_log ("", GF_LOG_DEBUG, "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_log ("", GF_LOG_INFO, "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-history.h b/libglusterfs/src/event-history.h
new file mode 100644
index 000000000..b64f63b5e
--- /dev/null
+++ b/libglusterfs/src/event-history.h
@@ -0,0 +1,44 @@
+/*
+ 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.
+*/
+
+#ifndef _EH_H
+#define _EH_H
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "mem-types.h"
+#include "circ-buff.h"
+
+struct event_hist
+{
+ buffer_t *buffer;
+ pthread_mutex_t lock;
+};
+
+typedef struct event_hist eh_t;
+
+void
+eh_dump (eh_t *event , void *data,
+ int (fn) (circular_buffer_t *buffer, void *data));
+
+eh_t *
+eh_new (size_t buffer_size, gf_boolean_t use_buffer_once,
+ void (*destroy_data) (void *data));
+
+int
+eh_save_history (eh_t *history, void *string);
+
+int
+eh_destroy (eh_t *history);
+
+#endif /* _EH_H */
diff --git a/libglusterfs/src/event-poll.c b/libglusterfs/src/event-poll.c
new file mode 100644
index 000000000..7f7f560d0
--- /dev/null
+++ b/libglusterfs/src/event-poll.c
@@ -0,0 +1,451 @@
+/*
+ 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 "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;
+}
+
+
+static struct event_pool *
+event_pool_new_poll (int count)
+{
+ 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;
+ }
+
+ 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;
+ }
+
+ 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));
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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 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;
+
+ }
+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_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);
+
+out:
+ return idx;
+}
+
+
+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);
+
+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;
+}
+
+
+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;
+ }
+
+ 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);
+
+ while (1) {
+ 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;
+}
+
+
+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
+};
diff --git a/libglusterfs/src/event.c b/libglusterfs/src/event.c
index cb6abd418..0197e7948 100644
--- a/libglusterfs/src/event.c
+++ b/libglusterfs/src/event.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
+ 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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>
@@ -28,960 +19,99 @@
#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;
-
- if (event_pool == NULL) {
- gf_log ("event", GF_LOG_ERROR, "invalid argument");
- return -1;
- }
-
- 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;
- }
- }
-
- return ret;
-}
-
-
-static struct event_pool *
-event_pool_new_poll (int count)
-{
- 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_log ("poll", GF_LOG_CRITICAL,
- "failed to allocate event registry");
- 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;
- }
-
- 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;
- }
-
- 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));
-
- 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;
- }
-
- 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;
- }
-
- 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 idx = -1;
-
- if (event_pool == NULL) {
- gf_log ("event", GF_LOG_ERROR, "invalid argument");
- return -1;
- }
-
- 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;
-
- }
-unlock:
- pthread_mutex_unlock (&event_pool->mutex);
-
- return idx;
-}
-
-
-static int
-event_unregister_poll (struct event_pool *event_pool, int fd, int idx_hint)
-{
- int idx = -1;
-
- if (event_pool == NULL) {
- gf_log ("event", GF_LOG_ERROR, "invalid argument");
- return -1;
- }
-
- 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);
-
- return idx;
-}
-
-
-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;
-
- if (event_pool == NULL) {
- gf_log ("event", GF_LOG_ERROR, "invalid argument");
- return -1;
- }
-
- 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);
-
- 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;
-}
-
-
-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)
-{
- struct pollfd *ufds = NULL;
- int size = 0;
- int i = 0;
- int ret = -1;
-
-
- if (event_pool == NULL) {
- gf_log ("event", GF_LOG_ERROR, "invalid argument");
- return -1;
- }
-
- while (1) {
- 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);
- }
- }
-
- return -1;
-}
-
-
-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)
-{
- 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)
- 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_log ("epoll", GF_LOG_CRITICAL,
- "event registry allocation failed");
- GF_FREE (event_pool);
- return NULL;
- }
-
- 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);
- return NULL;
- }
-
- event_pool->fd = epfd;
-
- event_pool->count = count;
-
- pthread_mutex_init (&event_pool->mutex, NULL);
- pthread_cond_init (&event_pool->cond, NULL);
-
- return event_pool;
-}
-
-
-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;
-
-
- if (event_pool == NULL) {
- gf_log ("event", GF_LOG_ERROR, "invalid argument");
- return -1;
- }
-
- 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);
-
- return ret;
-}
-
-
-static int
-event_unregister_epoll (struct event_pool *event_pool, int fd, int idx_hint)
-{
- int idx = -1;
- int ret = -1;
-
- struct epoll_event epoll_event = {0, };
- struct event_data *ev_data = (void *)&epoll_event.data;
- int lastidx = -1;
-
- if (event_pool == NULL) {
- gf_log ("event", GF_LOG_ERROR, "invalid argument");
- return -1;
- }
-
- 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);
-
- return ret;
-}
-
-
-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;
-
-
- if (event_pool == NULL) {
- gf_log ("event", GF_LOG_ERROR, "invalid argument");
- return -1;
- }
-
- 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);
-
- 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;
-}
-
-
-static int
-event_dispatch_epoll (struct event_pool *event_pool)
-{
- struct epoll_event *events = NULL;
- int size = 0;
- int i = 0;
- int ret = -1;
-
-
- if (event_pool == NULL) {
- gf_log ("event", GF_LOG_ERROR, "invalid argument");
- return -1;
- }
-
- while (1) {
- pthread_mutex_lock (&event_pool->mutex);
- {
- while (event_pool->used == 0)
- pthread_cond_wait (&event_pool->cond,
- &event_pool->mutex);
-
- 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);
-
- 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);
- }
- }
-
- return -1;
-}
-
-
-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)
{
- struct event_pool *event_pool = NULL;
+ struct event_pool *event_pool = NULL;
+ extern struct event_ops event_ops_poll;
#ifdef HAVE_SYS_EPOLL_H
- event_pool = event_ops_epoll.new (count);
+ extern struct event_ops event_ops_epoll;
+
+ event_pool = event_ops_epoll.new (count);
- if (event_pool) {
- event_pool->ops = &event_ops_epoll;
- } else {
- gf_log ("event", GF_LOG_WARNING,
- "failing back to poll based event handling");
- }
+ 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 = event_ops_poll.new (count);
- if (event_pool)
- event_pool->ops = &event_ops_poll;
- }
+ if (event_pool)
+ event_pool->ops = &event_ops_poll;
+ }
- return event_pool;
+ 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)
+ event_handler_t handler,
+ void *data, int poll_in, int poll_out)
{
- int ret = -1;
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("event", event_pool, out);
- if (event_pool == NULL) {
- gf_log ("event", GF_LOG_ERROR, "invalid argument");
- return -1;
- }
-
- ret = event_pool->ops->event_register (event_pool, fd, handler, data,
- poll_in, poll_out);
- return ret;
+ ret = event_pool->ops->event_register (event_pool, fd, handler, data,
+ poll_in, poll_out);
+out:
+ return ret;
}
int
event_unregister (struct event_pool *event_pool, int fd, int idx)
{
- int ret = -1;
+ int ret = -1;
- if (event_pool == NULL) {
- gf_log ("event", GF_LOG_ERROR, "invalid argument");
- return -1;
- }
-
- ret = event_pool->ops->event_unregister (event_pool, fd, idx);
+ GF_VALIDATE_OR_GOTO ("event", event_pool, out);
- return ret;
+ ret = event_pool->ops->event_unregister (event_pool, fd, idx);
+
+out:
+ return ret;
}
int
event_select_on (struct event_pool *event_pool, int fd, int idx_hint,
- int poll_in, int poll_out)
+ int poll_in, int poll_out)
{
- int ret = -1;
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("event", event_pool, out);
- if (event_pool == NULL) {
- gf_log ("event", GF_LOG_ERROR, "invalid argument");
- return -1;
- }
-
- ret = event_pool->ops->event_select_on (event_pool, fd, idx_hint,
- poll_in, poll_out);
- return ret;
+ ret = event_pool->ops->event_select_on (event_pool, fd, idx_hint,
+ poll_in, poll_out);
+out:
+ return ret;
}
int
event_dispatch (struct event_pool *event_pool)
{
- int ret = -1;
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("event", event_pool, out);
- if (event_pool == NULL) {
- gf_log ("event", GF_LOG_ERROR, "invalid argument");
- return -1;
- }
-
- ret = event_pool->ops->event_dispatch (event_pool);
+ ret = event_pool->ops->event_dispatch (event_pool);
- return ret;
+out:
+ return ret;
}
diff --git a/libglusterfs/src/event.h b/libglusterfs/src/event.h
index 25396325c..7ed182492 100644
--- a/libglusterfs/src/event.h
+++ b/libglusterfs/src/event.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
#ifndef _EVENT_H_
@@ -30,52 +21,51 @@
struct event_pool;
struct event_ops;
struct event_data {
- int fd;
- int idx;
-} __attribute__ ((__packed__));
+ 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;
+ struct event_ops *ops;
- int fd;
- int breaker[2];
+ int fd;
+ int breaker[2];
- int count;
- struct {
- int fd;
- int events;
- void *data;
- event_handler_t handler;
- } *reg;
+ int count;
+ struct {
+ int fd;
+ int events;
+ void *data;
+ event_handler_t handler;
+ } *reg;
- int used;
- int idx_cache;
- int changed;
+ int used;
+ int changed;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
- void *evcache;
- int evcache_size;
+ void *evcache;
+ int evcache_size;
};
struct event_ops {
- struct event_pool * (*new) (int count);
+ 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_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_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_unregister) (struct event_pool *event_pool, int fd, int idx);
- int (*event_dispatch) (struct event_pool *event_pool);
+ int (*event_dispatch) (struct event_pool *event_pool);
};
struct event_pool * event_pool_new (int count);
diff --git a/libglusterfs/src/fd-lk.c b/libglusterfs/src/fd-lk.c
new file mode 100644
index 000000000..caf2bb38e
--- /dev/null
+++ b/libglusterfs/src/fd-lk.c
@@ -0,0 +1,490 @@
+/*
+ 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 "fd-lk.h"
+#include "common-utils.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);
+
+ LOCK (&lk_ctx->lock);
+ {
+ ref = --lk_ctx->ref;
+ if (ref < 0)
+ GF_ASSERT (!ref);
+ if (ref == 0)
+ _fd_lk_destroy_lock_list (lk_ctx);
+ }
+ UNLOCK (&lk_ctx->lock);
+
+ 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_log_callingfn ("fd", GF_LOG_WARNING,
+ "invalid argument");
+ return NULL;
+ }
+
+ ++lk_ctx->ref;
+
+ return lk_ctx;
+}
+
+fd_lk_ctx_t *
+fd_lk_ctx_ref (fd_lk_ctx_t *lk_ctx)
+{
+ fd_lk_ctx_t *new_lk_ctx = NULL;
+
+ if (!lk_ctx) {
+ gf_log_callingfn ("fd", GF_LOG_WARNING,
+ "invalid argument");
+ return NULL;
+ }
+
+ LOCK (&lk_ctx->lock);
+ {
+ new_lk_ctx = _fd_lk_ctx_ref (lk_ctx);
+ }
+ UNLOCK (&lk_ctx->lock);
+
+ return new_lk_ctx;
+}
+
+fd_lk_ctx_t *
+fd_lk_ctx_try_ref (fd_lk_ctx_t *lk_ctx)
+{
+ int ret = -1;
+ fd_lk_ctx_t *new_lk_ctx = NULL;
+
+ if (!lk_ctx) {
+ goto out;
+ }
+
+ ret = TRY_LOCK (&lk_ctx->lock);
+ if (ret)
+ goto out;
+
+ new_lk_ctx = _fd_lk_ctx_ref (lk_ctx);
+ UNLOCK (&lk_ctx->lock);
+
+out:
+ return new_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 seperate 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 seperate 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_log ("fd-lk", GF_LOG_DEBUG, "lock list:");
+
+ list_for_each_entry (lk, &lk_ctx->lk_list, next)
+ gf_log ("fd-lk", GF_LOG_DEBUG, "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_log ("fd-lk", GF_LOG_DEBUG,
+ "new lock requrest: 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-lk.h b/libglusterfs/src/fd-lk.h
new file mode 100644
index 000000000..1d2ff794c
--- /dev/null
+++ b/libglusterfs/src/fd-lk.h
@@ -0,0 +1,70 @@
+/*
+ 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.
+*/
+
+#ifndef _FD_LK_H
+#define _FD_LK_H
+
+#include "fd.h"
+#include "locking.h"
+#include "list.h"
+#include "logging.h"
+#include "mem-pool.h"
+#include "mem-types.h"
+#include "glusterfs.h"
+#include "common-utils.h"
+
+#define get_lk_type(type) \
+ type == F_UNLCK ? "F_UNLCK" : (type == F_RDLCK ? "F_RDLCK" : "F_WRLCK")
+
+#define get_lk_cmd(cmd) \
+ cmd == F_SETLKW ? "F_SETLKW" : (cmd == F_SETLK ? "F_SETLK" : "F_GETLK")
+
+struct _fd;
+
+struct fd_lk_ctx {
+ struct list_head lk_list;
+ int ref;
+ gf_lock_t lock;
+};
+typedef struct fd_lk_ctx fd_lk_ctx_t;
+
+struct fd_lk_ctx_node {
+ int32_t cmd;
+ struct gf_flock user_flock;
+ off_t fl_start;
+ off_t fl_end;
+ short fl_type;
+ struct list_head next;
+};
+typedef struct fd_lk_ctx_node fd_lk_ctx_node_t;
+
+fd_lk_ctx_t *
+_fd_lk_ctx_ref (fd_lk_ctx_t *lk_ctx);
+
+fd_lk_ctx_t *
+fd_lk_ctx_ref (fd_lk_ctx_t *lk_ctx);
+
+fd_lk_ctx_t *
+fd_lk_ctx_try_ref (fd_lk_ctx_t *lk_ctx);
+
+fd_lk_ctx_t *
+fd_lk_ctx_create ();
+
+int
+fd_lk_insert_and_merge (struct _fd *lk_ctx, int32_t cmd,
+ struct gf_flock *flock);
+
+int
+fd_lk_ctx_unref (fd_lk_ctx_t *lk_ctx);
+
+gf_boolean_t
+fd_lk_ctx_empty (fd_lk_ctx_t *lk_ctx);
+
+#endif /* _FD_LK_H */
diff --git a/libglusterfs/src/fd.c b/libglusterfs/src/fd.c
index e4e75d804..36cc4d056 100644
--- a/libglusterfs/src/fd.c
+++ b/libglusterfs/src/fd.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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"
@@ -35,30 +26,7 @@ gf_fd_fdtable_expand (fdtable_t *fdtable, uint32_t nr);
fd_t *
-_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)
-{
- uint32_t result = 1;
-
- if (nr < 0) {
- gf_log ("server-protocol/fd",
- GF_LOG_ERROR,
- "Negative number passed");
- return -1;
- }
-
- while (result <= nr)
- result *= 2;
-
- return result;
-}
-
+__fd_ref (fd_t *fd);
static int
gf_fd_chain_fd_entries (fdentry_t *entries, uint32_t startidx,
@@ -66,8 +34,10 @@ gf_fd_chain_fd_entries (fdentry_t *entries, uint32_t startidx,
{
uint32_t i = 0;
- if (!entries)
+ 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.
@@ -85,35 +55,35 @@ gf_fd_chain_fd_entries (fdentry_t *entries, uint32_t startidx,
static int
gf_fd_fdtable_expand (fdtable_t *fdtable, uint32_t nr)
{
- fdentry_t *oldfds = NULL;
- uint32_t oldmax_fds = -1;
+ fdentry_t *oldfds = NULL;
+ uint32_t oldmax_fds = -1;
int ret = -1;
- if (fdtable == NULL || nr < 0) {
- gf_log ("fd", GF_LOG_ERROR, "invalid argument");
+ if (fdtable == NULL || nr < 0) {
+ gf_log_callingfn ("fd", GF_LOG_ERROR, "invalid argument");
ret = EINVAL;
goto out;
- }
+ }
- nr /= (1024 / sizeof (fdentry_t));
- nr = gf_roundup_power_of_two (nr + 1);
- nr *= (1024 / sizeof (fdentry_t));
+ 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;
+ oldfds = fdtable->fdentries;
+ oldmax_fds = fdtable->max_fds;
- fdtable->fdentries = GF_CALLOC (nr, sizeof (fdentry_t),
+ fdtable->fdentries = GF_CALLOC (nr, sizeof (fdentry_t),
gf_common_mt_fdentry_t);
- if (!fdtable->fdentries) {
+ if (!fdtable->fdentries) {
ret = ENOMEM;
goto out;
}
- fdtable->max_fds = nr;
+ fdtable->max_fds = nr;
- if (oldfds) {
- uint32_t cpy = oldmax_fds * sizeof (fdentry_t);
- memcpy (fdtable->fdentries, oldfds, cpy);
- }
+ 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);
@@ -123,40 +93,41 @@ gf_fd_fdtable_expand (fdtable_t *fdtable, uint32_t nr)
* using the expanded table.
*/
fdtable->first_free = oldmax_fds;
- GF_FREE (oldfds);
+ GF_FREE (oldfds);
ret = 0;
out:
- return ret;
+ return ret;
}
fdtable_t *
gf_fd_fdtable_alloc (void)
{
- fdtable_t *fdtable = NULL;
+ fdtable_t *fdtable = NULL;
- fdtable = GF_CALLOC (1, sizeof (*fdtable), gf_common_mt_fdtable_t);
- if (!fdtable)
- return NULL;
+ fdtable = GF_CALLOC (1, sizeof (*fdtable), gf_common_mt_fdtable_t);
+ if (!fdtable)
+ return NULL;
- pthread_mutex_init (&fdtable->lock, NULL);
+ pthread_mutex_init (&fdtable->lock, NULL);
- pthread_mutex_lock (&fdtable->lock);
- {
- gf_fd_fdtable_expand (fdtable, 0);
- }
- pthread_mutex_unlock (&fdtable->lock);
+ pthread_mutex_lock (&fdtable->lock);
+ {
+ gf_fd_fdtable_expand (fdtable, 0);
+ }
+ pthread_mutex_unlock (&fdtable->lock);
- return fdtable;
+ return fdtable;
}
-fdentry_t *
+static fdentry_t *
__gf_fd_fdtable_get_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;
}
@@ -188,6 +159,53 @@ 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;
+ int i = 0;
+
+ if (count == NULL) {
+ gf_log_callingfn ("fd", GF_LOG_WARNING, "!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);
+ }
+ }
+
+out:
+ return fdentries;
+}
+
+
+fdentry_t *
+gf_fd_fdtable_copy_all_fds (fdtable_t *fdtable, uint32_t *count)
+{
+ fdentry_t *entries = NULL;
+
+ if (fdtable) {
+ pthread_mutex_lock (&fdtable->lock);
+ {
+ entries = __gf_fd_fdtable_copy_all_fds (fdtable, count);
+ }
+ pthread_mutex_unlock (&fdtable->lock);
+ }
+
+ return entries;
+}
+
+
void
gf_fd_fdtable_destroy (fdtable_t *fdtable)
{
@@ -199,15 +217,17 @@ gf_fd_fdtable_destroy (fdtable_t *fdtable)
INIT_LIST_HEAD (&list);
- if (!fdtable)
+ if (!fdtable) {
+ gf_log_callingfn ("fd", GF_LOG_WARNING, "!fdtable");
return;
+ }
- pthread_mutex_lock (&fdtable->lock);
- {
+ pthread_mutex_lock (&fdtable->lock);
+ {
fdentries = __gf_fd_fdtable_get_all_fds (fdtable, &fd_count);
- GF_FREE (fdtable->fdentries);
- }
- pthread_mutex_unlock (&fdtable->lock);
+ GF_FREE (fdtable->fdentries);
+ }
+ pthread_mutex_unlock (&fdtable->lock);
if (fdentries != NULL) {
for (i = 0; i < fd_count; i++) {
@@ -218,53 +238,52 @@ gf_fd_fdtable_destroy (fdtable_t *fdtable)
}
GF_FREE (fdentries);
- pthread_mutex_destroy (&fdtable->lock);
- GF_FREE (fdtable);
- }
+ pthread_mutex_destroy (&fdtable->lock);
+ GF_FREE (fdtable);
+ }
}
int
gf_fd_unused_get (fdtable_t *fdtable, fd_t *fdptr)
{
- int32_t fd = -1;
+ int32_t fd = -1;
fdentry_t *fde = NULL;
- int error;
+ int error;
int alloc_attempts = 0;
- if (fdtable == NULL || fdptr == NULL)
- {
- gf_log ("fd", GF_LOG_ERROR, "invalid argument");
- return EINVAL;
- }
+ 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:
+ 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 {
+ } else {
/* If this is true, there is something
* seriously wrong with our data structures.
*/
if (alloc_attempts >= 2) {
- gf_log ("server-protocol.c", GF_LOG_ERROR,
- "Multiple attempts to expand fd table"
+ 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 ("server-protocol.c",
- GF_LOG_ERROR,
- "Cannot expand fdtable:%s", strerror (error));
+ 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
@@ -273,39 +292,43 @@ fd_alloc_try_again:
* above logic should just work.
*/
goto fd_alloc_try_again;
- }
- }
+ }
+ }
out:
- pthread_mutex_unlock (&fdtable->lock);
+ pthread_mutex_unlock (&fdtable->lock);
- return fd;
+ return fd;
}
inline void
gf_fd_put (fdtable_t *fdtable, int32_t fd)
{
- fd_t *fdptr = NULL;
+ fd_t *fdptr = NULL;
fdentry_t *fde = NULL;
- if (fdtable == NULL || fd < 0) {
- gf_log ("fd", GF_LOG_ERROR, "invalid argument");
- return;
- }
+ if (fd == -2)
+ /* anonymous fd */
+ return;
- if (!(fd < fdtable->max_fds)) {
- gf_log ("fd", GF_LOG_ERROR, "invalid argument");
- return;
- }
+ if (fdtable == NULL || fd < 0) {
+ gf_log_callingfn ("fd", GF_LOG_ERROR, "invalid argument");
+ return;
+ }
+
+ if (!(fd < fdtable->max_fds)) {
+ gf_log_callingfn ("fd", GF_LOG_ERROR, "invalid argument");
+ return;
+ }
- pthread_mutex_lock (&fdtable->lock);
- {
+ 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
+ * 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)
@@ -314,85 +337,133 @@ gf_fd_put (fdtable_t *fdtable, int32_t fd)
fde->fd = NULL;
fde->next_free = fdtable->first_free;
fdtable->first_free = fd;
- }
+ }
unlock_out:
- pthread_mutex_unlock (&fdtable->lock);
+ pthread_mutex_unlock (&fdtable->lock);
- if (fdptr) {
- fd_unref (fdptr);
- }
+ if (fdptr) {
+ fd_unref (fdptr);
+ }
+}
+
+
+inline void
+gf_fdptr_put (fdtable_t *fdtable, fd_t *fd)
+{
+ fdentry_t *fde = NULL;
+ int32_t i = 0;
+
+ if ((fdtable == NULL) || (fd == NULL)) {
+ gf_log_callingfn ("fd", GF_LOG_ERROR, "invalid argument");
+ return;
+ }
+
+ pthread_mutex_lock (&fdtable->lock);
+ {
+ for (i = 0; i < fdtable->max_fds; i++) {
+ if (fdtable->fdentries[i].fd == fd) {
+ fde = &fdtable->fdentries[i];
+ break;
+ }
+ }
+
+ if (fde == NULL) {
+ gf_log_callingfn ("fd", GF_LOG_WARNING,
+ "fd (%p) is not present in fdtable", fd);
+ goto unlock_out;
+ }
+
+ /* 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_mutex_unlock (&fdtable->lock);
+
+ if ((fd != NULL) && (fde != NULL)) {
+ fd_unref (fd);
+ }
}
fd_t *
gf_fd_fdptr_get (fdtable_t *fdtable, int64_t fd)
{
- fd_t *fdptr = NULL;
+ fd_t *fdptr = NULL;
- if (fdtable == NULL || fd < 0) {
- gf_log ("fd", GF_LOG_ERROR, "invalid argument");
- errno = EINVAL;
- return NULL;
- }
+ if (fdtable == NULL || fd < 0) {
+ gf_log_callingfn ("fd", GF_LOG_ERROR, "invalid argument");
+ errno = EINVAL;
+ return NULL;
+ }
- if (!(fd < fdtable->max_fds)) {
- gf_log ("fd", GF_LOG_ERROR, "invalid argument");
- errno = EINVAL;
- return NULL;
- }
+ if (!(fd < fdtable->max_fds)) {
+ gf_log_callingfn ("fd", GF_LOG_ERROR, "invalid argument");
+ errno = EINVAL;
+ return NULL;
+ }
- pthread_mutex_lock (&fdtable->lock);
- {
- fdptr = fdtable->fdentries[fd].fd;
- if (fdptr) {
- fd_ref (fdptr);
- }
- }
- pthread_mutex_unlock (&fdtable->lock);
+ pthread_mutex_lock (&fdtable->lock);
+ {
+ fdptr = fdtable->fdentries[fd].fd;
+ if (fdptr) {
+ fd_ref (fdptr);
+ }
+ }
+ pthread_mutex_unlock (&fdtable->lock);
- return fdptr;
+ return fdptr;
}
fd_t *
-_fd_ref (fd_t *fd)
+__fd_ref (fd_t *fd)
{
- ++fd->refcount;
+ ++fd->refcount;
- return fd;
+ return fd;
}
fd_t *
fd_ref (fd_t *fd)
{
- fd_t *refed_fd = NULL;
+ fd_t *refed_fd = NULL;
- if (!fd) {
- gf_log ("fd", GF_LOG_ERROR, "@fd=%p", fd);
- return NULL;
- }
+ if (!fd) {
+ gf_log_callingfn ("fd", GF_LOG_ERROR, "null fd");
+ return NULL;
+ }
- LOCK (&fd->inode->lock);
- refed_fd = _fd_ref (fd);
- UNLOCK (&fd->inode->lock);
+ LOCK (&fd->inode->lock);
+ refed_fd = __fd_ref (fd);
+ UNLOCK (&fd->inode->lock);
- return refed_fd;
+ return refed_fd;
}
fd_t *
-_fd_unref (fd_t *fd)
+__fd_unref (fd_t *fd)
{
- GF_ASSERT (fd->refcount);
+ GF_ASSERT (fd->refcount);
- --fd->refcount;
+ --fd->refcount;
- if (fd->refcount == 0) {
- list_del_init (&fd->inode_list);
- }
+ if (fd->refcount == 0) {
+ list_del_init (&fd->inode_list);
+ }
- return fd;
+ return fd;
}
@@ -400,55 +471,57 @@ static void
fd_destroy (fd_t *fd)
{
xlator_t *xl = NULL;
- int i = 0;
+ int i = 0;
xlator_t *old_THIS = NULL;
- struct mem_pool *tmp_pool = NULL;
if (fd == NULL){
- gf_log ("xlator", GF_LOG_ERROR, "invalid arugument");
+ gf_log_callingfn ("xlator", GF_LOG_ERROR, "invalid argument");
goto out;
}
if (fd->inode == NULL){
- gf_log ("xlator", GF_LOG_ERROR, "fd->inode is NULL");
+ gf_log_callingfn ("xlator", GF_LOG_ERROR, "fd->inode is NULL");
goto out;
}
- if (!fd->_ctx)
- goto out;
-
- tmp_pool = fd->inode->table->fd_mem_pool;
+ 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;
+ 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);
+ if (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;
+ 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);
+ if (xl->cbks->release)
+ xl->cbks->release (xl, fd);
THIS = old_THIS;
- }
- }
+ }
+ }
}
LOCK_DESTROY (&fd->lock);
- GF_FREE (fd->_ctx);
+ GF_FREE (fd->_ctx);
+ LOCK (&fd->inode->lock);
+ {
+ fd->inode->fd_count--;
+ }
+ UNLOCK (&fd->inode->lock);
inode_unref (fd->inode);
fd->inode = (inode_t *)0xaaaaaaaa;
- mem_put (tmp_pool,fd);
- tmp_pool = NULL;
+ fd_lk_ctx_unref (fd->lk_ctx);
+ mem_put (fd);
out:
return;
}
@@ -460,13 +533,13 @@ fd_unref (fd_t *fd)
int32_t refcount = 0;
if (!fd) {
- gf_log ("fd.c", GF_LOG_ERROR, "fd is NULL");
+ gf_log_callingfn ("fd", GF_LOG_ERROR, "fd is NULL");
return;
}
LOCK (&fd->inode->lock);
{
- _fd_unref (fd);
+ __fd_unref (fd);
refcount = fd->refcount;
}
UNLOCK (&fd->inode->lock);
@@ -480,56 +553,41 @@ fd_unref (fd_t *fd)
fd_t *
-fd_bind (fd_t *fd)
+__fd_bind (fd_t *fd)
{
- inode_t *inode = NULL;
-
- if (!fd || !fd->inode) {
- gf_log_callingfn ("fd", GF_LOG_ERROR, "!fd || !fd->inode");
- return NULL;
- }
- inode = fd->inode;
-
- LOCK (&inode->lock);
- {
- list_add (&fd->inode_list, &inode->fd_list);
- }
- UNLOCK (&inode->lock);
+ list_del_init (&fd->inode_list);
+ list_add (&fd->inode_list, &fd->inode->fd_list);
+ fd->inode->fd_count++;
return fd;
}
-void
-fd_unref_unbind (fd_t *fd)
+fd_t *
+fd_bind (fd_t *fd)
{
- GF_ASSERT (fd->refcount);
+ if (!fd || !fd->inode) {
+ gf_log_callingfn ("fd", GF_LOG_ERROR, "!fd || !fd->inode");
+ return NULL;
+ }
LOCK (&fd->inode->lock);
{
- --fd->refcount;
- /* Better know what you're doing with this function
- * because it does not do what fd_destroy does when
- * refcount goes to 0.
- * Make sure you only call this when you know there are
- * pending refs on the fd.
- */
- GF_ASSERT (fd->refcount);
- list_del_init (&fd->inode_list);
+ fd = __fd_bind (fd);
}
UNLOCK (&fd->inode->lock);
- return;
+ return fd;
}
-fd_t *
-fd_create (inode_t *inode, pid_t pid)
+static fd_t *
+__fd_create (inode_t *inode, uint64_t pid)
{
fd_t *fd = NULL;
if (inode == NULL) {
- gf_log ("fd", GF_LOG_ERROR, "invalid argument");
+ gf_log_callingfn ("fd", GF_LOG_ERROR, "invalid argument");
return NULL;
}
@@ -541,60 +599,211 @@ fd_create (inode_t *inode, pid_t pid)
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 (!fd->_ctx)
+ goto free_fd;
+
+ fd->lk_ctx = fd_lk_ctx_create ();
+ if (!fd->lk_ctx)
+ goto free_fd_ctx;
fd->inode = inode_ref (inode);
fd->pid = pid;
INIT_LIST_HEAD (&fd->inode_list);
LOCK_INIT (&fd->lock);
+out:
+ return fd;
+
+free_fd_ctx:
+ GF_FREE (fd->_ctx);
+free_fd:
+ mem_put (fd);
+
+ return NULL;
+}
+
+
+fd_t *
+fd_create (inode_t *inode, pid_t pid)
+{
+ fd_t *fd = NULL;
+
+ fd = __fd_create (inode, (uint64_t)pid);
+ if (!fd)
+ goto out;
+
+ fd = fd_ref (fd);
+
+out:
+ return fd;
+}
+
+fd_t *
+fd_create_uint64 (inode_t *inode, uint64_t pid)
+{
+ fd_t *fd = NULL;
+
+ fd = __fd_create (inode, pid);
+ if (!fd)
+ goto out;
+
+ fd = fd_ref (fd);
+
+out:
+ return fd;
+}
+
+
+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;
+ }
+ }
+
+ return fd;
+}
+
+
+fd_t *
+fd_lookup (inode_t *inode, pid_t pid)
+{
+ fd_t *fd = NULL;
+
+ if (!inode) {
+ gf_log_callingfn ("fd", GF_LOG_WARNING, "!inode");
+ return NULL;
+ }
LOCK (&inode->lock);
{
- fd = _fd_ref (fd);
+ fd = __fd_lookup (inode, (uint64_t)pid);
}
UNLOCK (&inode->lock);
-out:
+
return fd;
}
-
fd_t *
-fd_lookup (inode_t *inode, pid_t pid)
+fd_lookup_uint64 (inode_t *inode, uint64_t pid)
{
fd_t *fd = NULL;
- fd_t *iter_fd = NULL;
- if (!inode)
+ if (!inode) {
+ gf_log_callingfn ("fd", GF_LOG_WARNING, "!inode");
return NULL;
+ }
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 (inode, pid);
+ }
+ UNLOCK (&inode->lock);
+
+ return fd;
+}
+
+static fd_t *
+__fd_lookup_anonymous (inode_t *inode)
+{
+ 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) {
+ fd = __fd_ref (iter_fd);
+ break;
}
}
+
+ return fd;
+}
+
+static fd_t *
+__fd_anonymous (inode_t *inode)
+{
+ fd_t *fd = NULL;
+
+ fd = __fd_lookup_anonymous (inode);
+
+ /* 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 wont bump up the ref
+ count, so we have to call fd_ref() after bind. */
+ if (!fd) {
+ fd = __fd_create (inode, 0);
+
+ if (!fd)
+ return NULL;
+
+ fd->anonymous = _gf_true;
+
+ __fd_bind (fd);
+
+ __fd_ref (fd);
+ }
+
+ return fd;
+}
+
+
+fd_t *
+fd_anonymous (inode_t *inode)
+{
+ fd_t *fd = NULL;
+
+ LOCK (&inode->lock);
+ {
+ fd = __fd_anonymous (inode);
+ }
UNLOCK (&inode->lock);
return fd;
}
+fd_t*
+fd_lookup_anonymous (inode_t *inode)
+{
+ fd_t *fd = NULL;
+
+ if (!inode) {
+ gf_log_callingfn ("fd", GF_LOG_WARNING, "!inode");
+ return NULL;
+ }
+
+ LOCK (&inode->lock);
+ {
+ fd = __fd_lookup_anonymous (inode);
+ }
+ 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)
@@ -614,9 +823,12 @@ fd_list_empty (inode_t *inode)
int
__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;
@@ -635,15 +847,40 @@ __fd_ctx_set (fd_t *fd, xlator_t *xlator, uint64_t value)
}
if (set_idx == -1) {
- ret = -1;
- goto out;
+ set_idx = fd->xl_count;
+
+ new_xl_count = fd->xl_count + xlator->graph->xl_count;
+
+ tmp = GF_REALLOC (fd->_ctx,
+ (sizeof (struct _fd_ctx)
+ * new_xl_count));
+ if (tmp == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING,
+ "realloc of fd->_ctx for fd "
+ "(ptr: %p) failed, cannot set the key"
+ , fd);
+ ret = -1;
+ goto out;
+ }
+
+ 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;
}
@@ -652,8 +889,10 @@ fd_ctx_set (fd_t *fd, xlator_t *xlator, uint64_t value)
{
int ret = 0;
- if (!fd || !xlator)
+ if (!fd || !xlator) {
+ gf_log_callingfn ("", GF_LOG_WARNING, "%p %p", fd, xlator);
return -1;
+ }
LOCK (&fd->lock);
{
@@ -668,11 +907,11 @@ 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 index = 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)
@@ -688,7 +927,7 @@ __fd_ctx_get (fd_t *fd, xlator_t *xlator, uint64_t *value)
*value = fd->_ctx[index].value1;
out:
- return ret;
+ return ret;
}
@@ -697,8 +936,8 @@ fd_ctx_get (fd_t *fd, xlator_t *xlator, uint64_t *value)
{
int ret = 0;
- if (!fd || !xlator)
- return -1;
+ if (!fd || !xlator)
+ return -1;
LOCK (&fd->lock);
{
@@ -713,11 +952,11 @@ 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 index = 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)
@@ -736,7 +975,7 @@ __fd_ctx_del (fd_t *fd, xlator_t *xlator, uint64_t *value)
fd->_ctx[index].value1 = 0;
out:
- return ret;
+ return ret;
}
@@ -745,8 +984,8 @@ fd_ctx_del (fd_t *fd, xlator_t *xlator, uint64_t *value)
{
int ret = 0;
- if (!fd || !xlator)
- return -1;
+ if (!fd || !xlator)
+ return -1;
LOCK (&fd->lock);
{
@@ -767,16 +1006,16 @@ fd_dump (fd_t *fd, char *prefix)
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);
+ gf_proc_dump_write("pid", "%llu", fd->pid);
+ gf_proc_dump_write("refcount", "%d", fd->refcount);
+ gf_proc_dump_write("flags", "%d", fd->flags);
+
if (fd->inode) {
- gf_proc_dump_build_key(key, prefix, "inode");
- gf_proc_dump_write(key, "%ld", fd->inode->ino);
+ gf_proc_dump_build_key (key, "inode", NULL);
+ gf_proc_dump_add_section(key);
+ inode_dump (fd->inode, key);
}
+
}
@@ -804,12 +1043,10 @@ fdtable_dump (fdtable_t *fdtable, char *prefix)
if (!fdtable)
return;
- ret = pthread_mutex_trylock (&fdtable->lock);
+ ret = pthread_mutex_trylock (&fdtable->lock);
- if (ret) {
- gf_log ("fd", GF_LOG_WARNING, "Unable to acquire lock");
- return;
- }
+ if (ret)
+ goto out;
memset(key, 0, sizeof(key));
gf_proc_dump_build_key(key, prefix, "refcount");
@@ -821,7 +1058,7 @@ fdtable_dump (fdtable_t *fdtable, char *prefix)
for ( i = 0 ; i < fdtable->max_fds; i++) {
if (GF_FDENTRY_ALLOCATED ==
- fdtable->fdentries[i].next_free) {
+ 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);
@@ -829,6 +1066,12 @@ fdtable_dump (fdtable_t *fdtable, char *prefix)
}
pthread_mutex_unlock(&fdtable->lock);
+
+out:
+ if (ret != 0)
+ gf_proc_dump_write ("Unable to dump the fdtable",
+ "(Lock acquistion failed) %p", fdtable);
+ return;
}
@@ -838,7 +1081,7 @@ 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;
@@ -847,28 +1090,25 @@ fd_ctx_dump (fd_t *fd, char *prefix)
LOCK (&fd->lock);
{
if (fd->_ctx != NULL) {
- fd_ctx = GF_CALLOC (fd->inode->table->xl->graph->xl_count,
- sizeof (*fd_ctx),
+ fd_ctx = GF_CALLOC (fd->xl_count, sizeof (*fd_ctx),
gf_common_mt_fd_ctx);
if (fd_ctx == NULL) {
- gf_log ("fd", GF_LOG_ERROR, "out of memory");
goto unlock;
}
- for (i = 0; i < fd->inode->table->xl->graph->xl_count;
- i++) {
+ for (i = 0; i < fd->xl_count; i++) {
fd_ctx[i] = fd->_ctx[i];
}
}
}
unlock:
UNLOCK (&fd->lock);
-
+
if (fd_ctx == NULL) {
goto out;
}
- for (i = 0; i < fd->inode->table->xl->graph->xl_count; i++) {
+ 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)
@@ -877,9 +1117,99 @@ unlock:
}
out:
- if (fd_ctx != NULL) {
- GF_FREE (fd_ctx);
+ GF_FREE (fd_ctx);
+
+ return;
+}
+
+void
+fdentry_dump_to_dict (fdentry_t *fdentry, char *prefix, dict_t *dict,
+ int *openfds)
+{
+ char key[GF_DUMP_MAX_BUF_LEN] = {0,};
+ int ret = -1;
+
+ if (!fdentry)
+ return;
+ if (!dict)
+ return;
+
+ if (GF_FDENTRY_ALLOCATED != fdentry->next_free)
+ return;
+
+ if (fdentry->fd) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.pid", prefix);
+ ret = dict_set_int32 (dict, key, fdentry->fd->pid);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.refcount", prefix);
+ ret = dict_set_int32 (dict, key, fdentry->fd->refcount);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.flags", prefix);
+ ret = dict_set_int32 (dict, key, fdentry->fd->flags);
+
+ (*openfds)++;
+ }
+ return;
+}
+
+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;
+
+ ret = pthread_mutex_trylock (&fdtable->lock);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.fdtable.refcount", prefix);
+ ret = dict_set_int32 (dict, key, fdtable->refcount);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.fdtable.maxfds", prefix);
+ ret = dict_set_uint32 (dict, key, fdtable->max_fds);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ 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) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.fdtable.fdentry%d",
+ prefix, i);
+ fdentry_dump_to_dict (&fdtable->fdentries[i], key,
+ dict, &openfds);
+ }
}
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.fdtable.openfds", prefix);
+ ret = dict_set_int32 (dict, key, openfds);
+
+out:
+ pthread_mutex_unlock (&fdtable->lock);
return;
}
diff --git a/libglusterfs/src/fd.h b/libglusterfs/src/fd.h
index f8bfe58d2..c1b9157d8 100644
--- a/libglusterfs/src/fd.h
+++ b/libglusterfs/src/fd.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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 _FD_H
@@ -30,9 +21,14 @@
#include <unistd.h>
#include "glusterfs.h"
#include "locking.h"
+#include "fd-lk.h"
+#include "common-utils.h"
+
+#define GF_ANON_FD_NO -2
struct _inode;
struct _dict;
+struct fd_lk_ctx;
struct _fd_ctx {
union {
@@ -45,21 +41,18 @@ struct _fd_ctx {
};
};
-/* 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;
+ uint64_t pid;
int32_t flags;
int32_t refcount;
- uint64_t flush_unique;
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 */
+ struct fd_lk_ctx *lk_ctx;
+ gf_boolean_t anonymous; /* geo-rep anonymous fd */
};
typedef struct _fd fd_t;
@@ -93,7 +86,7 @@ typedef struct _fdtable fdtable_t;
#include "xlator.h"
-inline void
+void
gf_fd_put (fdtable_t *fdtable, int32_t fd);
@@ -118,6 +111,10 @@ gf_fd_fdtable_destroy (fdtable_t *fdtable);
fd_t *
+__fd_ref (fd_t *fd);
+
+
+fd_t *
fd_ref (fd_t *fd);
@@ -128,10 +125,25 @@ fd_unref (fd_t *fd);
fd_t *
fd_create (struct _inode *inode, pid_t pid);
+fd_t *
+fd_create_uint64 (struct _inode *inode, uint64_t pid);
fd_t *
fd_lookup (struct _inode *inode, pid_t pid);
+fd_t *
+fd_lookup_uint64 (struct _inode *inode, uint64_t pid);
+
+fd_t*
+fd_lookup_anonymous (inode_t *inode);
+
+fd_t *
+fd_anonymous (inode_t *inode);
+
+
+gf_boolean_t
+fd_is_anonymous (fd_t *fd);
+
uint8_t
fd_list_empty (struct _inode *inode);
@@ -152,6 +164,9 @@ 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_del (fd_t *fd, xlator_t *xlator, uint64_t *value);
+
int
__fd_ctx_set (fd_t *fd, xlator_t *xlator, uint64_t value);
@@ -161,15 +176,14 @@ 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);
+void
+fd_ctx_dump (fd_t *fd, char *prefix);
+
+fdentry_t *
+gf_fd_fdtable_copy_all_fds (fdtable_t *fdtable, uint32_t *count);
-fd_t *
-_fd_ref (fd_t *fd);
void
-fd_ctx_dump (fd_t *fd, char *prefix);
+gf_fdptr_put (fdtable_t *fdtable, fd_t *fd);
-extern void
-fd_unref_unbind (fd_t *fd);
#endif /* _FD_H */
diff --git a/libglusterfs/src/gf-dirent.c b/libglusterfs/src/gf-dirent.c
index af09cb06c..bb028c967 100644
--- a/libglusterfs/src/gf-dirent.c
+++ b/libglusterfs/src/gf-dirent.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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.
*/
@@ -31,53 +22,33 @@
#include "xlator.h"
gf_dirent_t *
-gf_dirent_for_namelen (int len)
-{
- gf_dirent_t *gf_dirent = NULL;
-
- /* TODO: use mem-pool */
- gf_dirent = CALLOC (len, sizeof(char));
- if (!gf_dirent)
- return NULL;
-
- INIT_LIST_HEAD (&gf_dirent->list);
-
- gf_dirent->d_off = 0;
- gf_dirent->d_ino = -1;
- gf_dirent->d_type = 0;
-
- return gf_dirent;
-}
-
-
-gf_dirent_t *
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 = GF_CALLOC (gf_dirent_size (name), 1,
- gf_common_mt_gf_dirent_t);
- 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);
- strcpy (gf_dirent->d_name, name);
+ 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_len = strlen (name);
+ 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_free (gf_dirent_t *entries)
{
- gf_dirent_t *entry = NULL;
- gf_dirent_t *tmp = NULL;
+ gf_dirent_t *entry = NULL;
+ gf_dirent_t *tmp = NULL;
if (!entries)
return;
@@ -85,10 +56,37 @@ gf_dirent_free (gf_dirent_t *entries)
if (list_empty (&entries->list))
return;
- list_for_each_entry_safe (entry, tmp, &entries->list, list) {
- list_del (&entry->list);
- GF_FREE (entry);
- }
-}
+ list_for_each_entry_safe (entry, tmp, &entries->list, list) {
+ if (entry->dict)
+ dict_unref (entry->dict);
+ if (entry->inode)
+ inode_unref (entry->inode);
+ list_del (&entry->list);
+ GF_FREE (entry);
+ }
+}
+/* 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;
+ inode_t *link_inode = NULL;
+
+ list_for_each_entry (entry, &entries->list, list) {
+ if (entry->inode) {
+ link_inode = inode_link (entry->inode, parent,
+ entry->d_name, &entry->d_stat);
+ inode_lookup (link_inode);
+ inode_unref (link_inode);
+ }
+ }
+
+ return 0;
+}
diff --git a/libglusterfs/src/gf-dirent.h b/libglusterfs/src/gf-dirent.h
index 8a6533fc3..588d522db 100644
--- a/libglusterfs/src/gf-dirent.h
+++ b/libglusterfs/src/gf-dirent.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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.
*/
@@ -27,6 +18,7 @@
#endif
#include "iatt.h"
+#include "inode.h"
#define gf_dirent_size(name) (sizeof (gf_dirent_t) + strlen (name) + 1)
@@ -51,12 +43,16 @@ struct _gf_dirent_t {
uint32_t d_len;
uint32_t d_type;
struct iatt d_stat;
- char d_name[0];
+ dict_t *dict;
+ inode_t *inode;
+ char d_name[];
};
+#define DT_ISDIR(mode) (mode == DT_DIR)
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);
+int gf_link_inodes_from_dirent (xlator_t *this, inode_t *parent,
+ gf_dirent_t *entries);
#endif /* _GF_DIRENT_H */
diff --git a/libglusterfs/src/gidcache.c b/libglusterfs/src/gidcache.c
new file mode 100644
index 000000000..c5bdda925
--- /dev/null
+++ b/libglusterfs/src/gidcache.c
@@ -0,0 +1,192 @@
+/*
+ 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 "gidcache.h"
+#include "mem-pool.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)
+{
+ int bucket;
+ int i;
+ time_t now;
+ const gid_list_t *agl;
+
+ LOCK(&cache->gc_lock);
+ now = time(NULL);
+ 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;
+
+ /*
+ * 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;
+
+ LOCK(&cache->gc_lock);
+ now = time(NULL);
+
+ /*
+ * 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_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/gidcache.h b/libglusterfs/src/gidcache.h
new file mode 100644
index 000000000..9379f8e8b
--- /dev/null
+++ b/libglusterfs/src/gidcache.h
@@ -0,0 +1,53 @@
+/*
+ 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.
+*/
+
+#ifndef __GIDCACHE_H__
+#define __GIDCACHE_H__
+
+#include "glusterfs.h"
+#include "locking.h"
+
+/*
+ * TBD: make the cache size tunable
+ *
+ * The current size represents a pretty trivial amount of memory, and should
+ * provide good hit rates even for quite busy systems. If we ever want to
+ * support really large cache sizes, we'll need to do dynamic allocation
+ * instead of just defining an array within a private structure. It doesn't make
+ * a whole lot of sense to change the associativity, because it won't improve
+ * hit rates all that much and will increase the maintenance cost as we have
+ * to scan more entries with every lookup/update.
+ */
+
+#define AUX_GID_CACHE_ASSOC 4
+#define AUX_GID_CACHE_BUCKETS 256
+#define AUX_GID_CACHE_SIZE (AUX_GID_CACHE_ASSOC * AUX_GID_CACHE_BUCKETS)
+
+typedef struct {
+ uint64_t gl_id;
+ int gl_count;
+ gid_t *gl_list;
+ time_t gl_deadline;
+} gid_list_t;
+
+typedef struct {
+ gf_lock_t gc_lock;
+ uint32_t gc_max_age;
+ unsigned int gc_nbuckets;
+ gid_list_t gc_cache[AUX_GID_CACHE_SIZE];
+} gid_cache_t;
+
+int gid_cache_init(gid_cache_t *, uint32_t);
+int gid_cache_reconf(gid_cache_t *, uint32_t);
+const gid_list_t *gid_cache_lookup(gid_cache_t *, uint64_t);
+void gid_cache_release(gid_cache_t *, const gid_list_t *);
+int gid_cache_add(gid_cache_t *, gid_list_t *);
+
+#endif /* __GIDCACHE_H__ */
diff --git a/libglusterfs/src/globals.c b/libglusterfs/src/globals.c
index 979f84e32..259c5c885 100644
--- a/libglusterfs/src/globals.c
+++ b/libglusterfs/src/globals.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
#ifndef _CONFIG_H
@@ -28,112 +19,74 @@
#include "globals.h"
#include "xlator.h"
#include "mem-pool.h"
-
-
-/* gf_*_list[] */
-
-char *gf_fop_list[GF_FOP_MAXVALUE];
-char *gf_mgmt_list[GF_MGMT_MAXVALUE];
-
-
-void
-gf_op_list_init()
-{
- 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;
-}
-
-
-/* CTX */
-static glusterfs_ctx_t *glusterfs_ctx;
-
-
-int
-glusterfs_ctx_init ()
-{
- int ret = 0;
-
- if (glusterfs_ctx)
- goto out;
-
- glusterfs_ctx = CALLOC (1, sizeof (*glusterfs_ctx));
- if (!glusterfs_ctx) {
- ret = -1;
- goto out;
- }
-
- INIT_LIST_HEAD (&glusterfs_ctx->graphs);
- ret = pthread_mutex_init (&glusterfs_ctx->lock, NULL);
-
-out:
- return ret;
-}
-
-
-glusterfs_ctx_t *
-glusterfs_ctx_get ()
-{
- return glusterfs_ctx;
-
-}
-
-
+#include "syncop.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",
+};
/* THIS */
xlator_t global_xlator;
static pthread_key_t this_xlator_key;
+static pthread_key_t synctask_key;
+static pthread_key_t uuid_buf_key;
+static char global_uuid_buf[GF_UUID_BUF_SIZE];
+static pthread_key_t lkowner_buf_key;
+static char global_lkowner_buf[GF_LKOWNER_BUF_SIZE];
+
void
glusterfs_this_destroy (void *ptr)
{
- if (ptr)
- FREE (ptr);
+ FREE (ptr);
}
@@ -144,12 +97,14 @@ glusterfs_this_init ()
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;
}
global_xlator.name = "glusterfs";
global_xlator.type = "global";
- global_xlator.ctx = glusterfs_ctx;
+
+ INIT_LIST_HEAD (&global_xlator.volume_options);
return ret;
}
@@ -211,68 +166,56 @@ glusterfs_this_set (xlator_t *this)
return 0;
}
+/* SYNCOPCTX */
+static pthread_key_t syncopctx_key;
-/* IS_CENTRAL_LOG */
-
-static pthread_key_t central_log_flag_key;
-
-void
-glusterfs_central_log_flag_destroy (void *ptr)
-{
- if (ptr)
- FREE (ptr);
-}
-
-
-int
-glusterfs_central_log_flag_init ()
+static void
+syncopctx_key_destroy (void *ptr)
{
- int ret = 0;
+ struct syncopctx *opctx = ptr;
- ret = pthread_key_create (&central_log_flag_key,
- glusterfs_central_log_flag_destroy);
-
- if (ret != 0) {
- return ret;
- }
+ if (opctx) {
+ if (opctx->groups)
+ GF_FREE (opctx->groups);
- pthread_setspecific (central_log_flag_key, (void *) 0);
+ GF_FREE (opctx);
+ }
- return ret;
+ return;
}
-
-void
-glusterfs_central_log_flag_set ()
+void *
+syncopctx_getctx ()
{
- pthread_setspecific (central_log_flag_key, (void *) 1);
-}
+ void *opctx = NULL;
+ opctx = pthread_getspecific (syncopctx_key);
-long
-glusterfs_central_log_flag_get ()
+ return opctx;
+}
+
+int
+syncopctx_setctx (void *ctx)
{
- long flag = 0;
+ int ret = 0;
- flag = (long) pthread_getspecific (central_log_flag_key);
+ ret = pthread_setspecific (syncopctx_key, ctx);
- return flag;
+ return ret;
}
-
-void
-glusterfs_central_log_flag_unset ()
+static int
+syncopctx_init (void)
{
- pthread_setspecific (central_log_flag_key, (void *) 0);
-}
+ int ret;
+ ret = pthread_key_create (&syncopctx_key, syncopctx_key_destroy);
+ return ret;
+}
/* SYNCTASK */
-static pthread_key_t synctask_key;
-
-
int
synctask_init ()
{
@@ -283,7 +226,6 @@ synctask_init ()
return ret;
}
-
void *
synctask_get ()
{
@@ -305,55 +247,115 @@ synctask_set (void *synctask)
return ret;
}
+//UUID_BUFFER
+
+void
+glusterfs_uuid_buf_destroy (void *ptr)
+{
+ FREE (ptr);
+}
int
-glusterfs_globals_init ()
+glusterfs_uuid_buf_init ()
{
int ret = 0;
- gf_op_list_init ();
+ ret = pthread_key_create (&uuid_buf_key,
+ glusterfs_uuid_buf_destroy);
+ return ret;
+}
- ret = glusterfs_ctx_init ();
- if (ret)
- goto out;
+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;
+}
+
+/* LKOWNER_BUFFER */
+
+void
+glusterfs_lkowner_buf_destroy (void *ptr)
+{
+ FREE (ptr);
+}
+
+int
+glusterfs_lkowner_buf_init ()
+{
+ int ret = 0;
+
+ ret = pthread_key_create (&lkowner_buf_key,
+ glusterfs_lkowner_buf_destroy);
+ return ret;
+}
+
+char *
+glusterfs_lkowner_buf_get ()
+{
+ char *buf;
+ int ret = 0;
+
+ buf = pthread_getspecific (lkowner_buf_key);
+ if(!buf) {
+ buf = MALLOC (GF_LKOWNER_BUF_SIZE);
+ ret = pthread_setspecific (lkowner_buf_key, (void *) buf);
+ if (ret)
+ buf = global_lkowner_buf;
+ }
+ return buf;
+}
+
+int
+glusterfs_globals_init (glusterfs_ctx_t *ctx)
+{
+ int ret = 0;
+
+ gf_log_globals_init (ctx);
ret = glusterfs_this_init ();
- if (ret)
+ if (ret) {
+ gf_log ("", GF_LOG_CRITICAL,
+ "ERROR: glusterfs-translator init failed");
goto out;
+ }
- ret = glusterfs_central_log_flag_init ();
- if (ret)
+ 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 = glusterfs_lkowner_buf_init ();
+ if(ret) {
+ gf_log ("", GF_LOG_CRITICAL,
+ "ERROR: glusterfs lkowner buffer init failed");
+ goto out;
+ }
ret = synctask_init ();
- if (ret)
+ if (ret) {
+ gf_log ("", GF_LOG_CRITICAL,
+ "ERROR: glusterfs synctask init failed");
goto out;
+ }
+ ret = syncopctx_init ();
+ if (ret) {
+ gf_log ("", GF_LOG_CRITICAL,
+ "ERROR: glusterfs syncopctx init failed");
+ goto out;
+ }
out:
return ret;
}
-
-
-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",
-};
-
-/* Copy the string ptr contents if needed for yourself */
-char *
-glusterfs_strevent (glusterfs_event_t ev)
-{
- return eventstring[ev];
-}
-
diff --git a/libglusterfs/src/globals.h b/libglusterfs/src/globals.h
index 96a113623..3085db21c 100644
--- a/libglusterfs/src/globals.h
+++ b/libglusterfs/src/globals.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
#ifndef _GLOBALS_H
@@ -22,18 +13,24 @@
#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 GD_OP_VERSION_KEY "operating-version"
+#define GD_MIN_OP_VERSION_KEY "minimum-operating-version"
+#define GD_MAX_OP_VERSION_KEY "maximum-operating-version"
+
+/* Gluster versions - OP-VERSION mapping
+ *
+ * 3.3.0 - 1
+ * 3.4.0 - 2
+ * 3.next (3.5?) - 3
+ *
+ * TODO: Change above comment once gluster version is finalised
+ * TODO: Finalize the op-version ranges
*/
-#define GF_REQUEST_MAXGROUPS 16
-
-#include "glusterfs.h"
-
-/* CTX */
-#define CTX (glusterfs_ctx_get())
-
-glusterfs_ctx_t *glusterfs_ctx_get ();
+#define GD_OP_VERSION_MIN 1 /* MIN is the fresh start op-version, mostly
+ should not change */
+#define GD_OP_VERSION_MAX 3 /* MAX VERSION is the maximum count in VME table,
+ should keep changing with introduction of newer
+ versions */
#include "xlator.h"
@@ -44,17 +41,22 @@ xlator_t **__glusterfs_this_location ();
xlator_t *glusterfs_this_get ();
int glusterfs_this_set (xlator_t *);
-/* central log */
-
-void glusterfs_central_log_flag_set ();
-long glusterfs_central_log_flag_get ();
-void glusterfs_central_log_flag_unset ();
+/* syncopctx */
+void *syncopctx_getctx ();
+int syncopctx_setctx (void *ctx);
/* task */
void *synctask_get ();
int synctask_set (void *);
+/* uuid_buf */
+char *glusterfs_uuid_buf_get();
+/* lkowner_buf */
+char *glusterfs_lkowner_buf_get();
+
/* init */
-int glusterfs_globals_init (void);
+int glusterfs_globals_init (glusterfs_ctx_t *ctx);
+
+extern const char *gf_fop_list[];
#endif /* !_GLOBALS_H */
diff --git a/libglusterfs/src/glusterfs-acl.h b/libglusterfs/src/glusterfs-acl.h
new file mode 100644
index 000000000..b7de1cdb4
--- /dev/null
+++ b/libglusterfs/src/glusterfs-acl.h
@@ -0,0 +1,81 @@
+/*
+ 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.
+*/
+
+#ifndef _GLUSTERFS_ACL_H
+#define _GLUSTERFS_ACL_H
+
+#include <stdint.h>
+#include <sys/types.h> /* For uid_t */
+
+#include "locking.h" /* For gf_lock_t in struct posix_acl_conf */
+
+#define ACL_PROGRAM 100227
+#define ACLV3_VERSION 3
+
+#define POSIX_ACL_MINIMAL_ACE_COUNT 3
+
+#define POSIX_ACL_READ (0x04)
+#define POSIX_ACL_WRITE (0x02)
+#define POSIX_ACL_EXECUTE (0x01)
+
+#define POSIX_ACL_UNDEFINED_TAG (0x00)
+#define POSIX_ACL_USER_OBJ (0x01)
+#define POSIX_ACL_USER (0x02)
+#define POSIX_ACL_GROUP_OBJ (0x04)
+#define POSIX_ACL_GROUP (0x08)
+#define POSIX_ACL_MASK (0x10)
+#define POSIX_ACL_OTHER (0x20)
+
+#define POSIX_ACL_UNDEFINED_ID (-1)
+
+#define POSIX_ACL_VERSION (0x02)
+
+#define POSIX_ACL_ACCESS_XATTR "system.posix_acl_access"
+#define POSIX_ACL_DEFAULT_XATTR "system.posix_acl_default"
+
+struct posix_acl_xattr_entry {
+ uint16_t tag;
+ uint16_t perm;
+ uint32_t id;
+};
+
+struct posix_acl_xattr_header {
+ uint32_t version;
+ struct posix_acl_xattr_entry entries[];
+};
+
+struct posix_ace {
+ uint16_t tag;
+ uint16_t perm;
+ uint32_t id;
+};
+
+
+struct posix_acl {
+ int refcnt;
+ int count;
+ struct posix_ace entries[];
+};
+
+struct posix_acl_ctx {
+ uid_t uid;
+ gid_t gid;
+ mode_t perm;
+ struct posix_acl *acl_access;
+ struct posix_acl *acl_default;
+};
+
+struct posix_acl_conf {
+ gf_lock_t acl_lock;
+ uid_t super_uid;
+ struct posix_acl *minimal_acl;
+};
+
+#endif /* _GLUSTERFS_ACL_H */
diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h
index bf37f4fa5..2f1e12ee7 100644
--- a/libglusterfs/src/glusterfs.h
+++ b/libglusterfs/src/glusterfs.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
#ifndef _GLUSTERFS_H
@@ -41,17 +32,23 @@
#include <arpa/inet.h>
#include <sys/poll.h>
#include <pthread.h>
+#include <limits.h> /* For PATH_MAX */
#include "list.h"
#include "logging.h"
-
+#include "lkowner.h"
#define GF_YES 1
#define GF_NO 0
#ifndef O_LARGEFILE
/* savannah bug #20053, patch for compiling on darwin */
-#define O_LARGEFILE 0
+#define O_LARGEFILE 0100000 /* from bits/fcntl.h */
+#endif
+
+#ifndef O_FMODE_EXEC
+/* redhat bug 843080, added from linux/fs.h */
+#define O_FMODE_EXEC 040 //0x20
#endif
#ifndef O_DIRECT
@@ -64,26 +61,111 @@
#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 GLUSTERD_MAX_SNAP_NAME 256
+#define ZR_MOUNTPOINT_OPT "mountpoint"
+#define ZR_ATTR_TIMEOUT_OPT "attribute-timeout"
+#define ZR_ENTRY_TIMEOUT_OPT "entry-timeout"
+#define ZR_NEGATIVE_TIMEOUT_OPT "negative-timeout"
+#define ZR_DIRECT_IO_OPT "direct-io-mode"
+#define ZR_STRICT_VOLFILE_CHECK "strict-volfile-check"
+#define ZR_DUMP_FUSE "dump-fuse"
+#define ZR_FUSE_MOUNTOPTS "fuse-mountopts"
+
+#define GF_XATTR_CLRLK_CMD "glusterfs.clrlk"
#define GF_XATTR_PATHINFO_KEY "trusted.glusterfs.pathinfo"
+#define GF_XATTR_NODE_UUID_KEY "trusted.glusterfs.node-uuid"
+#define GF_XATTR_VOL_ID_KEY "trusted.glusterfs.volume-id"
+#define GF_XATTR_LOCKINFO_KEY "trusted.glusterfs.lockinfo"
+#define GF_XATTR_GET_REAL_FILENAME_KEY "user.glusterfs.get_real_filename:"
+
+#define GF_READDIR_SKIP_DIRS "readdir-filter-directories"
+
+#define BD_XATTR_KEY "user.glusterfs"
+
+#define XATTR_IS_PATHINFO(x) (strncmp (x, GF_XATTR_PATHINFO_KEY, \
+ strlen (GF_XATTR_PATHINFO_KEY)) == 0)
+#define XATTR_IS_NODE_UUID(x) (strncmp (x, GF_XATTR_NODE_UUID_KEY, \
+ strlen (GF_XATTR_NODE_UUID_KEY)) == 0)
+#define XATTR_IS_LOCKINFO(x) (strncmp (x, GF_XATTR_LOCKINFO_KEY, \
+ strlen (GF_XATTR_LOCKINFO_KEY)) == 0)
+
+#define XATTR_IS_BD(x) (strncmp (x, BD_XATTR_KEY, strlen (BD_XATTR_KEY)) == 0)
+
#define GF_XATTR_LINKINFO_KEY "trusted.distribute.linkinfo"
+#define GFID_XATTR_KEY "trusted.gfid"
+#define VIRTUAL_GFID_XATTR_KEY_STR "glusterfs.gfid.string"
+#define VIRTUAL_GFID_XATTR_KEY "glusterfs.gfid"
+#define UUID_CANONICAL_FORM_LEN 36
+
+#define GLUSTERFS_INTERNAL_FOP_KEY "glusterfs-internal-fop"
#define ZR_FILE_CONTENT_STR "glusterfs.file."
#define ZR_FILE_CONTENT_STRLEN 15
+#define GLUSTERFS_WRITE_IS_APPEND "glusterfs.write-is-append"
#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 GLUSTERFS_PARENT_ENTRYLK "glusterfs.parent-entrylk"
+#define GLUSTERFS_INODELK_DOM_COUNT "glusterfs.inodelk-dom-count"
+#define QUOTA_SIZE_KEY "trusted.glusterfs.quota.size"
+#define GFID_TO_PATH_KEY "glusterfs.gfid2path"
+#define GF_XATTR_STIME_PATTERN "trusted.glusterfs.*.stime"
+
+/* Index xlator related */
+#define GF_XATTROP_INDEX_GFID "glusterfs.xattrop_index_gfid"
+#define GF_BASE_INDICES_HOLDER_GFID "glusterfs.base_indicies_holder_gfid"
+
+#define GF_GFIDLESS_LOOKUP "gfidless-lookup"
+/* replace-brick and pump related internal xattrs */
+#define RB_PUMP_CMD_START "glusterfs.pump.start"
+#define RB_PUMP_CMD_PAUSE "glusterfs.pump.pause"
+#define RB_PUMP_CMD_COMMIT "glusterfs.pump.commit"
+#define RB_PUMP_CMD_ABORT "glusterfs.pump.abort"
+#define RB_PUMP_CMD_STATUS "glusterfs.pump.status"
+
+#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))
+ ZR_FILE_CONTENT_STRLEN))
+
+#define DEFAULT_VAR_RUN_DIRECTORY DATADIR "/run/gluster"
+#define GF_REPLICATE_TRASH_DIR ".landfill"
+
+/* GlusterFS's maximum supported Auxilary GIDs */
+/* TODO: Keeping it to 200, so that we can fit in 2KB buffer for auth data
+ * in RPC server code, if there is ever need for having more aux-gids, then
+ * we have to add aux-gid in payload of actors */
+#define GF_MAX_AUX_GROUPS 65536
-/* TODO: Should we use PATH-MAX? On some systems it may save space */
-#define ZR_PATH_MAX 4096
+#define GF_UUID_BUF_SIZE 50
+
+#define GF_REBALANCE_TID_KEY "rebalance-id"
+#define GF_REMOVE_BRICK_TID_KEY "remove-brick-id"
+#define GF_REPLACE_BRICK_TID_KEY "replace-brick-id"
+
+#define UUID_CANONICAL_FORM_LEN 36
+
+/* Adding this here instead of any glusterd*.h files as it is also required by
+ * cli
+ */
+#define DEFAULT_GLUSTERD_SOCKFILE DATADIR "/run/glusterd.socket"
/* NOTE: add members ONLY at the end (just before _MAXVALUE) */
typedef enum {
@@ -118,8 +200,8 @@ typedef enum {
GF_FOP_READDIR,
GF_FOP_INODELK,
GF_FOP_FINODELK,
- GF_FOP_ENTRYLK,
- GF_FOP_FENTRYLK,
+ GF_FOP_ENTRYLK,
+ GF_FOP_FENTRYLK,
GF_FOP_XATTROP,
GF_FOP_FXATTROP,
GF_FOP_FGETXATTR,
@@ -132,6 +214,10 @@ typedef enum {
GF_FOP_RELEASE,
GF_FOP_RELEASEDIR,
GF_FOP_GETSPEC,
+ GF_FOP_FREMOVEXATTR,
+ GF_FOP_FALLOCATE,
+ GF_FOP_DISCARD,
+ GF_FOP_ZEROFILL,
GF_FOP_MAXVALUE,
} glusterfs_fop_t;
@@ -148,15 +234,6 @@ typedef enum {
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,
@@ -190,20 +267,23 @@ typedef enum {
typedef enum {
- ENTRYLK_LOCK,
- ENTRYLK_UNLOCK,
- ENTRYLK_LOCK_NB
+ ENTRYLK_LOCK,
+ ENTRYLK_UNLOCK,
+ ENTRYLK_LOCK_NB
} entrylk_cmd;
typedef enum {
- ENTRYLK_RDLCK,
- ENTRYLK_WRLCK
+ ENTRYLK_RDLCK,
+ ENTRYLK_WRLCK
} entrylk_type;
typedef enum {
- GF_XATTROP_ADD_ARRAY,
+ GF_XATTROP_ADD_ARRAY,
+ GF_XATTROP_ADD_ARRAY64,
+ GF_XATTROP_OR_ARRAY,
+ GF_XATTROP_AND_ARRAY
} gf_xattrop_flags_t;
@@ -212,65 +292,84 @@ typedef enum {
#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;
+ struct list_head cmd_args;
+ char *volume;
+ char *key;
+ char *value;
};
typedef struct _xlator_cmdline_option xlator_cmdline_option_t;
+struct _server_cmdline {
+ struct list_head list;
+ char *volfile_server;
+};
+typedef struct _server_cmdline server_cmdline_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;
+ /* basic options */
+ char *volfile_server;
+ server_cmdline_t *curr_server;
+ /* List of backup volfile servers, including original */
+ struct list_head volfile_servers;
+ 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;
+ /* advanced options */
+ uint32_t volfile_server_port;
+ char *volfile_server_transport;
uint32_t log_server_port;
- char *pid_file;
- int no_daemon_mode;
- char *run_id;
- int debug_mode;
+ char *pid_file;
+ char *sock_file;
+ int no_daemon_mode;
+ char *run_id;
+ int debug_mode;
int read_only;
+ int acl;
+ int selinux;
+ int enable_ino32;
+ int worm;
int mac_compat;
- struct list_head xlator_options; /* list of xlator_option_t */
-
- /* fuse options */
- int fuse_direct_io_mode;
+ int fopen_keep_cache;
+ int gid_timeout;
+ int aux_gfid_mount;
+ struct list_head xlator_options; /* list of xlator_option_t */
+
+ /* fuse options */
+ int fuse_direct_io_mode;
+ char *use_readdirp;
int volfile_check;
- double fuse_entry_timeout;
- double fuse_attribute_timeout;
- char *volume_name;
- int fuse_nodev;
- int fuse_nosuid;
- char *dump_fuse;
-
- /* key args */
- char *mount_point;
- char *volfile_id;
+ double fuse_entry_timeout;
+ double fuse_negative_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;
+ unsigned uid_map_root;
+ int background_qlen;
+ int congestion_threshold;
+ char *fuse_mountopts;
+
+ /* 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;
@@ -282,39 +381,68 @@ struct _glusterfs_graph {
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;
+typedef int32_t (*glusterfsd_mgmt_event_notify_fn_t) (int32_t event, void *data,
+ ...);
struct _glusterfs_ctx {
- cmd_args_t cmd_args;
- char *process_uuid;
- FILE *pidfp;
- char fin;
- void *timer;
- void *ib;
- void *pool;
- void *event_pool;
+ cmd_args_t cmd_args;
+ char *process_uuid;
+ FILE *pidfp;
+ char fin;
+ void *timer;
+ void *ib;
+ struct call_pool *pool;
+ void *event_pool;
void *iobuf_pool;
- pthread_mutex_t lock;
+ 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 */
+ pid_t mnt_pid; /* pid of the mount agent */
+ int process_mode; /*mode in which process is runninng*/
+ struct syncenv *env; /* The env pointer to the synctasks */
+
+ struct list_head mempool_list; /* used to keep a global list of
+ mempools, used to log details of
+ mempool in statedump */
+ char *statedump_path;
+ struct mem_pool *dict_pool;
+ struct mem_pool *dict_pair_pool;
+ struct mem_pool *dict_data_pool;
+
+ glusterfsd_mgmt_event_notify_fn_t notify; /* Used for xlators to make
+ call to fsd-mgmt */
+ gf_log_handle_t log; /* all logging related variables */
+
+ int mem_acct_enable;
+
+ int daemon_pipe[2];
+
+ struct client_disconnect *client_disconnect;
+ struct clienttable *clienttable;
};
typedef struct _glusterfs_ctx glusterfs_ctx_t;
+glusterfs_ctx_t *glusterfs_ctx_new (void);
-/* 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,
@@ -323,17 +451,37 @@ typedef enum {
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_TRANSLATOR_OP,
+ GF_EVENT_AUTH_FAILED,
+ GF_EVENT_VOLUME_DEFRAG,
+ GF_EVENT_PARENT_DOWN,
+ GF_EVENT_VOLUME_BARRIER_OP,
GF_EVENT_MAXVAL,
} glusterfs_event_t;
-extern char *
-glusterfs_strevent (glusterfs_event_t ev);
+struct gf_flock {
+ short l_type;
+ short l_whence;
+ off_t l_start;
+ off_t l_len;
+ pid_t l_pid;
+ gf_lkowner_t l_owner;
+};
#define GF_MUST_CHECK __attribute__((warn_unused_result))
+/*
+ * Some macros (e.g. ALLOC_OR_GOTO) set variables in function scope, but the
+ * calling function might not only declare the variable to keep the macro happy
+ * and not use it otherwise. In such cases, the following can be used to
+ * suppress the "set but not used" warning that would otherwise occur.
+ */
+#define GF_UNUSED __attribute__((unused))
int glusterfs_graph_prepare (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx);
int glusterfs_graph_destroy (glusterfs_graph_t *graph);
diff --git a/libglusterfs/src/graph-mem-types.h b/libglusterfs/src/graph-mem-types.h
deleted file mode 100644
index d5a939eb9..000000000
--- a/libglusterfs/src/graph-mem-types.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- Copyright (c) 2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef __GRAPH_MEM_TYPES_H__
-#define __GRAPH_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-#define GF_MEM_TYPE_START (gf_common_mt_end + 1)
-
-enum gfd_mem_types_ {
- gf_graph_mt_buf = GF_MEM_TYPE_START,
- gfd_mt_end
-};
-#endif
-
diff --git a/libglusterfs/src/graph-print.c b/libglusterfs/src/graph-print.c
index 53d8643ee..d860d63b3 100644
--- a/libglusterfs/src/graph-print.c
+++ b/libglusterfs/src/graph-print.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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
@@ -26,7 +17,6 @@
#include "common-utils.h"
#include "xlator.h"
-#include "graph-mem-types.h"
#include "graph-utils.h"
@@ -34,6 +24,7 @@
struct gf_printer {
ssize_t (*write) (struct gf_printer *gp, char *buf, size_t len);
void *priv;
+ int len;
};
static ssize_t
@@ -90,19 +81,31 @@ gpprintf (struct gf_printer *gp, const char *format, ...)
return ret;
}
+#define GPPRINTF(gp, fmt, ...) do { \
+ ret = gpprintf (gp, fmt, ## __VA_ARGS__); \
+ if (ret == -1) \
+ goto out; \
+ else \
+ gp->len += ret; \
+ } while (0)
+
static int
-glusterfs_graph_print (struct gf_printer *gp, glusterfs_graph_t *graph)
+_print_volume_options (dict_t *d, char *k, data_t *v,
+ void *tmp)
{
-#define GPPRINTF(gp, fmt, ...) do { \
- ret = gpprintf (gp, fmt, ## __VA_ARGS__); \
- if (ret == -1) \
- goto out; \
- else \
- len += ret; \
-} while (0)
+ struct gf_printer *gp = tmp;
+ int ret = 0;
+ GPPRINTF (gp, " option %s %s\n", k, v->data);
+ return 0;
+out:
+ /* means, it is a failure */
+ return -1;
+}
+static int
+glusterfs_graph_print (struct gf_printer *gp, glusterfs_graph_t *graph)
+{
xlator_t *trav = NULL;
- data_pair_t *pair = NULL;
xlator_list_t *xch = NULL;
int ret = 0;
ssize_t len = 0;
@@ -115,11 +118,9 @@ glusterfs_graph_print (struct gf_printer *gp, glusterfs_graph_t *graph)
GPPRINTF (gp, "volume %s\n type %s\n", trav->name,
trav->type);
- for (pair = trav->options->members_list; pair && pair->next;
- pair = pair->next);
- for (; pair; pair = pair->prev)
- GPPRINTF (gp, " option %s %s\n", pair->key,
- pair->value->data);
+ ret = dict_foreach (trav->options, _print_volume_options, gp);
+ if (ret)
+ goto out;
if (trav->children) {
GPPRINTF (gp, " subvolumes");
@@ -135,7 +136,8 @@ glusterfs_graph_print (struct gf_printer *gp, glusterfs_graph_t *graph)
GPPRINTF (gp, "\n");
}
- out:
+out:
+ len = gp->len;
if (ret == -1) {
gf_log ("graph-print", GF_LOG_ERROR, "printing failed");
@@ -152,7 +154,7 @@ glusterfs_graph_print_file (FILE *file, glusterfs_graph_t *graph)
{
struct gf_printer gp = { .write = gp_write_file,
.priv = file
- };
+ };
return glusterfs_graph_print (&gp, graph);
}
@@ -166,7 +168,7 @@ glusterfs_graph_print_buf (glusterfs_graph_t *graph)
char *buf = NULL;
struct gf_printer gp = { .write = gp_write_buf,
.priv = &iov
- };
+ };
f = fopen ("/dev/null", "a");
if (!f) {
@@ -180,10 +182,8 @@ glusterfs_graph_print_buf (glusterfs_graph_t *graph)
if (len == -1)
return NULL;
- buf = GF_CALLOC (1, len + 1, gf_graph_mt_buf);
+ buf = GF_CALLOC (1, len + 1, gf_common_mt_graph_buf);
if (!buf) {
- gf_log ("graph-print", GF_LOG_ERROR, "Out of memory");
-
return NULL;
}
iov.iov_base = buf;
diff --git a/libglusterfs/src/graph-utils.h b/libglusterfs/src/graph-utils.h
index a6c1ccd5a..207664fdb 100644
--- a/libglusterfs/src/graph-utils.h
+++ b/libglusterfs/src/graph-utils.h
@@ -1,30 +1,19 @@
/*
- Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
+ 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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 _GRAPH_H_
#define _GRAPH_H_
-int
-glusterfs_graph_print_file (FILE *file, glusterfs_graph_t *graph);
+int glusterfs_graph_print_file (FILE *file, glusterfs_graph_t *graph);
-char *
-glusterfs_graph_print_buf (glusterfs_graph_t *graph);
+char *glusterfs_graph_print_buf (glusterfs_graph_t *graph);
int glusterfs_xlator_link (xlator_t *pxl, xlator_t *cxl);
void glusterfs_graph_set_first (glusterfs_graph_t *graph, xlator_t *xl);
diff --git a/libglusterfs/src/graph.c b/libglusterfs/src/graph.c
index a2d03fa0b..e76df1ca5 100644
--- a/libglusterfs/src/graph.c
+++ b/libglusterfs/src/graph.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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
@@ -29,28 +20,23 @@
#include "defaults.h"
-
-
#if 0
static void
_gf_dump_details (int argc, char **argv)
{
extern FILE *gf_log_logfile;
int i = 0;
- char timestr[256];
+ char timestr[64];
time_t utime = 0;
- struct tm *tm = NULL;
pid_t mypid = 0;
struct utsname uname_buf = {{0, }, };
int uname_ret = -1;
- utime = time (NULL);
- tm = localtime (&utime);
mypid = getpid ();
uname_ret = uname (&uname_buf);
- /* Which git? What time? */
- strftime (timestr, 256, "%Y-%m-%d %H:%M:%S", tm);
+ utime = time (NULL);
+ gf_time_fmt (timestr, sizeof timestr, utime, gf_timefmt_FT);
fprintf (gf_log_logfile,
"========================================"
"========================================\n");
@@ -84,44 +70,6 @@ _gf_dump_details (int argc, char **argv)
#endif
-static int
-_log_if_option_is_invalid (xlator_t *xl, data_pair_t *pair)
-{
- volume_opt_list_t *vol_opt = NULL;
- volume_option_t *opt = NULL;
- int i = 0;
- int index = 0;
- int found = 0;
-
- /* Get the first volume_option */
- list_for_each_entry (vol_opt, &xl->volume_options, list) {
- /* Warn for extra option */
- if (!vol_opt->given_opt)
- break;
-
- opt = vol_opt->given_opt;
- for (index = 0;
- ((index < ZR_OPTION_MAX_ARRAY_SIZE) &&
- (opt[index].key && opt[index].key[0])); index++)
- for (i = 0; (i < ZR_VOLUME_MAX_NUM_KEY) &&
- opt[index].key[i]; i++) {
- if (fnmatch (opt[index].key[i],
- pair->key,
- FNM_NOESCAPE) == 0) {
- found = 1;
- break;
- }
- }
- }
-
- if (!found) {
- gf_log (xl->name, GF_LOG_WARNING,
- "option '%s' is not recognized",
- pair->key);
- }
- return 0;
-}
-
int
glusterfs_xlator_link (xlator_t *pxl, xlator_t *cxl)
@@ -169,7 +117,8 @@ glusterfs_graph_set_first (glusterfs_graph_t *graph, xlator_t *xl)
int
glusterfs_graph_insert (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx,
- const char *type, const char *name)
+ const char *type, const char *name,
+ gf_boolean_t autoload)
{
xlator_t *ixl = NULL;
@@ -195,6 +144,8 @@ glusterfs_graph_insert (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx,
if (!ixl->name)
goto err;
+ ixl->is_autoloaded = autoload;
+
if (xlator_set_type (ixl, type) == -1) {
gf_log ("glusterfs", GF_LOG_ERROR,
"%s (%s) initialization failed",
@@ -213,23 +164,37 @@ err:
return -1;
}
-
int
-glusterfs_graph_readonly (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
+glusterfs_graph_acl (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
{
int ret = 0;
cmd_args_t *cmd_args = NULL;
cmd_args = &ctx->cmd_args;
- if (!cmd_args->read_only)
+ if (!cmd_args->acl)
return 0;
- ret = glusterfs_graph_insert (graph, ctx, "features/read-only",
- "readonly-autoload");
+ ret = glusterfs_graph_insert (graph, ctx, "system/posix-acl",
+ "posix-acl-autoload", 1);
return ret;
}
+int
+glusterfs_graph_worm (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
+{
+ int ret = 0;
+ cmd_args_t *cmd_args = NULL;
+
+ cmd_args = &ctx->cmd_args;
+
+ if (!cmd_args->worm)
+ return 0;
+
+ ret = glusterfs_graph_insert (graph, ctx, "features/worm",
+ "worm-autoload", 1);
+ return ret;
+}
int
glusterfs_graph_mac_compat (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
@@ -243,11 +208,26 @@ glusterfs_graph_mac_compat (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
return 0;
ret = glusterfs_graph_insert (graph, ctx, "features/mac-compat",
- "mac-compat-autoload");
+ "mac-compat-autoload", 1);
return ret;
}
+int
+glusterfs_graph_gfid_access (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
+{
+ int ret = 0;
+ cmd_args_t *cmd_args = NULL;
+
+ cmd_args = &ctx->cmd_args;
+
+ if (!cmd_args->aux_gfid_mount)
+ return 0;
+
+ ret = glusterfs_graph_insert (graph, ctx, "features/gfid-access",
+ "gfid-access-autoload", 1);
+ return ret;
+}
static void
gf_add_cmdline_options (glusterfs_graph_t *graph, cmd_args_t *cmd_args)
@@ -267,7 +247,7 @@ gf_add_cmdline_options (glusterfs_graph_t *graph, cmd_args_t *cmd_args)
cmd_option->key,
cmd_option->value);
if (ret == 0) {
- gf_log (trav->name, GF_LOG_WARNING,
+ gf_log (trav->name, GF_LOG_INFO,
"adding option '%s' for "
"volume '%s' with value '%s'",
cmd_option->key, trav->name,
@@ -289,9 +269,9 @@ gf_add_cmdline_options (glusterfs_graph_t *graph, cmd_args_t *cmd_args)
int
glusterfs_graph_validate_options (glusterfs_graph_t *graph)
{
- volume_opt_list_t *vol_opt = NULL;
xlator_t *trav = NULL;
int ret = -1;
+ char *errstr = NULL;
trav = graph->first;
@@ -299,14 +279,10 @@ glusterfs_graph_validate_options (glusterfs_graph_t *graph)
if (list_empty (&trav->volume_options))
continue;
- vol_opt = list_entry (trav->volume_options.next,
- volume_opt_list_t, list);
-
- ret = validate_xlator_volume_options (trav,
- vol_opt->given_opt);
+ ret = xlator_options_validate (trav, trav->options, &errstr);
if (ret) {
gf_log (trav->name, GF_LOG_ERROR,
- "validating translator failed");
+ "validation failed: %s", errstr);
return ret;
}
trav = trav->next;
@@ -338,35 +314,46 @@ glusterfs_graph_init (glusterfs_graph_t *graph)
}
-int
-glusterfs_graph_unknown_options (glusterfs_graph_t *graph)
+static int
+_log_if_unknown_option (dict_t *dict, char *key, data_t *value, void *data)
{
- data_pair_t *pair = NULL;
- xlator_t *trav = NULL;
+ volume_option_t *found = NULL;
+ xlator_t *xl = NULL;
- trav = graph->first;
+ xl = data;
- /* Validate again phase */
- while (trav) {
- pair = trav->options->members_list;
- while (pair) {
- _log_if_option_is_invalid (trav, pair);
- pair = pair->next;
- }
- trav = trav->next;
+ found = xlator_volume_option_get (xl, key);
+
+ if (!found) {
+ gf_log (xl->name, GF_LOG_WARNING,
+ "option '%s' is not recognized", key);
}
return 0;
}
+static void
+_xlator_check_unknown_options (xlator_t *xl, void *data)
+{
+ dict_foreach (xl->options, _log_if_unknown_option, xl);
+}
+
+
+int
+glusterfs_graph_unknown_options (glusterfs_graph_t *graph)
+{
+ xlator_foreach (graph->first, _xlator_check_unknown_options, NULL);
+ return 0;
+}
+
+
void
fill_uuid (char *uuid, int size)
{
char hostname[256] = {0,};
struct timeval tv = {0,};
- struct tm now = {0, };
- char now_str[32];
+ char now_str[64];
if (gettimeofday (&tv, NULL) == -1) {
gf_log ("graph", GF_LOG_ERROR,
@@ -380,8 +367,7 @@ fill_uuid (char *uuid, int size)
strerror (errno));
}
- localtime_r (&tv.tv_sec, &now);
- strftime (now_str, 32, "%Y/%m/%d-%H:%M:%S", &now);
+ gf_time_fmt (now_str, sizeof now_str, tv.tv_sec, gf_timefmt_Ymd_T);
snprintf (uuid, size, "%s-%d-%s:%"GF_PRI_SUSECONDS,
hostname, getpid(), now_str, tv.tv_usec);
@@ -446,18 +432,37 @@ glusterfs_graph_prepare (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
/* XXX: attach to -n volname */
ret = glusterfs_graph_settop (graph, ctx);
- if (ret)
+ if (ret) {
+ gf_log ("graph", GF_LOG_ERROR, "glusterfs graph settop failed");
return -1;
+ }
- /* XXX: RO VOLUME */
- ret = glusterfs_graph_readonly (graph, ctx);
- if (ret)
+ /* XXX: WORM VOLUME */
+ ret = glusterfs_graph_worm (graph, ctx);
+ if (ret) {
+ gf_log ("graph", GF_LOG_ERROR, "glusterfs graph worm failed");
return -1;
+ }
+ ret = glusterfs_graph_acl (graph, ctx);
+ if (ret) {
+ gf_log ("graph", GF_LOG_ERROR, "glusterfs graph ACL failed");
+ return -1;
+ }
/* XXX: MAC COMPAT */
ret = glusterfs_graph_mac_compat (graph, ctx);
- if (ret)
+ if (ret) {
+ gf_log ("graph", GF_LOG_ERROR, "glusterfs graph mac compat failed");
+ return -1;
+ }
+
+ /* XXX: gfid-access */
+ ret = glusterfs_graph_gfid_access (graph, ctx);
+ if (ret) {
+ gf_log ("graph", GF_LOG_ERROR,
+ "glusterfs graph 'gfid-access' failed");
return -1;
+ }
/* XXX: this->ctx setting */
for (trav = graph->first; trav; trav = trav->next) {
@@ -469,6 +474,8 @@ glusterfs_graph_prepare (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
fill_uuid (graph->graph_uuid, 128);
+ graph->id = ctx->graph_id++;
+
/* XXX: --xlator-option additions */
gf_add_cmdline_options (graph, &ctx->cmd_args);
@@ -484,17 +491,23 @@ glusterfs_graph_activate (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
/* XXX: all xlator options validation */
ret = glusterfs_graph_validate_options (graph);
- if (ret)
+ if (ret) {
+ gf_log ("graph", GF_LOG_ERROR, "validate options failed");
return ret;
+ }
/* XXX: perform init () */
ret = glusterfs_graph_init (graph);
- if (ret)
+ if (ret) {
+ gf_log ("graph", GF_LOG_ERROR, "init failed");
return ret;
+ }
ret = glusterfs_graph_unknown_options (graph);
- if (ret)
+ if (ret) {
+ gf_log ("graph", GF_LOG_ERROR, "unknown options failed");
return ret;
+ }
/* XXX: log full graph (_gf_dump_details) */
@@ -502,32 +515,224 @@ glusterfs_graph_activate (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
ctx->active = graph;
/* XXX: attach to master and set active pointer */
- if (ctx->master)
+ if (ctx->master) {
ret = xlator_notify (ctx->master, GF_EVENT_GRAPH_NEW, graph);
- if (ret)
- return ret;
+ if (ret) {
+ gf_log ("graph", GF_LOG_ERROR,
+ "graph new notification failed");
+ return ret;
+ }
+ ((xlator_t *)ctx->master)->next = graph->top;
+ }
/* XXX: perform parent up */
ret = glusterfs_graph_parent_up (graph);
- if (ret)
+ if (ret) {
+ gf_log ("graph", GF_LOG_ERROR, "parent up notification failed");
return ret;
-
+ }
return 0;
}
+
+int
+xlator_equal_rec (xlator_t *xl1, xlator_t *xl2)
+{
+ xlator_list_t *trav1 = NULL;
+ xlator_list_t *trav2 = NULL;
+ int ret = 0;
+
+ if (xl1 == NULL || xl2 == NULL) {
+ gf_log ("xlator", GF_LOG_DEBUG, "invalid argument");
+ return -1;
+ }
+
+ trav1 = xl1->children;
+ trav2 = xl2->children;
+
+ while (trav1 && trav2) {
+ ret = xlator_equal_rec (trav1->xlator, trav2->xlator);
+ if (ret) {
+ gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG,
+ "xlators children not equal");
+ goto out;
+ }
+
+ trav1 = trav1->next;
+ trav2 = trav2->next;
+ }
+
+ if (trav1 || trav2) {
+ ret = -1;
+ goto out;
+ }
+
+ if (strcmp (xl1->name, xl2->name)) {
+ ret = -1;
+ goto out;
+ }
+
+ /* type could have changed even if xlator names match,
+ e.g cluster/distrubte and cluster/nufa share the same
+ xlator name
+ */
+ if (strcmp (xl1->type, xl2->type)) {
+ ret = -1;
+ goto out;
+ }
+out :
+ return ret;
+}
+
+
+gf_boolean_t
+is_graph_topology_equal (glusterfs_graph_t *graph1, glusterfs_graph_t *graph2)
+{
+ xlator_t *trav1 = NULL;
+ xlator_t *trav2 = NULL;
+ gf_boolean_t ret = _gf_true;
+
+ trav1 = graph1->first;
+ trav2 = graph2->first;
+
+ ret = xlator_equal_rec (trav1, trav2);
+
+ if (ret) {
+ gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG,
+ "graphs are not equal");
+ ret = _gf_false;
+ goto out;
+ }
+
+ ret = _gf_true;
+ gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG,
+ "graphs are equal");
+
+out:
+ return ret;
+}
+
+
+/* Function has 3types of return value 0, -ve , 1
+ * return 0 =======> reconfiguration of options has succeeded
+ * return 1 =======> the graph has to be reconstructed and all the xlators should be inited
+ * return -1(or -ve) =======> Some Internal Error occurred during the operation
+ */
+int
+glusterfs_volfile_reconfigure (int oldvollen, FILE *newvolfile_fp,
+ glusterfs_ctx_t *ctx, const char *oldvolfile)
+{
+ glusterfs_graph_t *oldvolfile_graph = NULL;
+ glusterfs_graph_t *newvolfile_graph = NULL;
+ FILE *oldvolfile_fp = NULL;
+ gf_boolean_t active_graph_found = _gf_true;
+
+ int ret = -1;
+
+ if (!oldvollen) {
+ ret = 1; // Has to call INIT for the whole graph
+ goto out;
+ }
+
+ if (!ctx) {
+ gf_log ("glusterfsd-mgmt", GF_LOG_ERROR,
+ "ctx is NULL");
+ goto out;
+ }
+
+ oldvolfile_graph = ctx->active;
+ if (!oldvolfile_graph) {
+ active_graph_found = _gf_false;
+ gf_log ("glusterfsd-mgmt", GF_LOG_ERROR,
+ "glusterfs_ctx->active is NULL");
+
+ oldvolfile_fp = tmpfile ();
+ if (!oldvolfile_fp) {
+ gf_log ("glusterfsd-mgmt", GF_LOG_ERROR, "Unable to "
+ "create temporary volfile: (%s)",
+ strerror (errno));
+ goto out;
+ }
+
+ fwrite (oldvolfile, oldvollen, 1, oldvolfile_fp);
+ fflush (oldvolfile_fp);
+ if (ferror (oldvolfile_fp)) {
+ goto out;
+ }
+
+ oldvolfile_graph = glusterfs_graph_construct (oldvolfile_fp);
+ if (!oldvolfile_graph)
+ goto out;
+ }
+
+ newvolfile_graph = glusterfs_graph_construct (newvolfile_fp);
+ if (!newvolfile_graph) {
+ goto out;
+ }
+
+ if (!is_graph_topology_equal (oldvolfile_graph,
+ newvolfile_graph)) {
+
+ ret = 1;
+ gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG,
+ "Graph topology not equal(should call INIT)");
+ goto out;
+ }
+
+ gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG,
+ "Only options have changed in the new "
+ "graph");
+
+ /* */
+ ret = glusterfs_graph_reconfigure (oldvolfile_graph,
+ newvolfile_graph);
+ if (ret) {
+ gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG,
+ "Could not reconfigure new options in old graph");
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (oldvolfile_fp)
+ fclose (oldvolfile_fp);
+
+ /* Do not simply destroy the old graph here. If the oldgraph
+ is constructed here in this function itself instead of getting
+ it from ctx->active (which happens only of ctx->active is NULL),
+ then destroy the old graph. If some i/o is still happening in
+ the old graph and the old graph is obtained from ctx->active,
+ then destroying the graph will cause problems.
+ */
+ if (!active_graph_found && oldvolfile_graph)
+ glusterfs_graph_destroy (oldvolfile_graph);
+ if (newvolfile_graph)
+ glusterfs_graph_destroy (newvolfile_graph);
+
+ return ret;
+}
+
+
int
glusterfs_graph_reconfigure (glusterfs_graph_t *oldgraph,
glusterfs_graph_t *newgraph)
{
- xlator_t *old_xl = NULL;
- xlator_t *new_xl = NULL;
+ xlator_t *old_xl = NULL;
+ xlator_t *new_xl = NULL;
GF_ASSERT (oldgraph);
GF_ASSERT (newgraph);
old_xl = oldgraph->first;
+ while (old_xl->is_autoloaded) {
+ old_xl = old_xl->children->xlator;
+ }
+
new_xl = newgraph->first;
+ while (new_xl->is_autoloaded) {
+ new_xl = new_xl->children->xlator;
+ }
return xlator_tree_reconfigure (old_xl, new_xl);
}
@@ -535,7 +740,12 @@ glusterfs_graph_reconfigure (glusterfs_graph_t *oldgraph,
int
glusterfs_graph_destroy (glusterfs_graph_t *graph)
{
- return 0;
-}
+ xlator_tree_free (graph->first);
+ if (graph) {
+ list_del_init (&graph->list);
+ GF_FREE (graph);
+ }
+ return 0;
+}
diff --git a/libglusterfs/src/graph.l b/libglusterfs/src/graph.l
index 08f7d5367..e4eba9cbe 100644
--- a/libglusterfs/src/graph.l
+++ b/libglusterfs/src/graph.l
@@ -1,23 +1,13 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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.
*/
-
%x STRING
%option yylineno
%option noinput
@@ -80,10 +70,10 @@ TYPE [t][y][p][e]
yyunput (0, NULL);
}
BEGIN (INITIAL);
- yylval = text;
+ graphyylval = text;
return STRING_TOK;
}
}
-[^ \t\r\n\"\\]+ { yylval = gf_strdup (yytext) ; return ID; }
+[^ \t\r\n\"\\]+ { graphyylval = gf_strdup (yytext) ; return ID; }
[ \t\r\n]+ ;
%%
diff --git a/libglusterfs/src/graph.y b/libglusterfs/src/graph.y
index 52e15940a..a220abeb9 100644
--- a/libglusterfs/src/graph.y
+++ b/libglusterfs/src/graph.y
@@ -1,23 +1,13 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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.
*/
-
%token VOLUME_BEGIN VOLUME_END OPTION NEWLINE SUBVOLUME ID WHITESPACE COMMENT TYPE STRING_TOK
%{
@@ -28,6 +18,9 @@
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <pthread.h>
+
+#define RELAX_POISONING
#include "xlator.h"
#include "graph-utils.h"
@@ -45,8 +38,8 @@ static void option_error (void);
#define YYSTYPE char *
#define GF_CMD_BUFFER_LEN (8 * GF_UNIT_KB)
-int yyerror (const char *);
-int yylex ();
+int graphyyerror (const char *);
+int graphyylex ();
%}
@@ -86,11 +79,11 @@ glusterfs_graph_t *construct;
static void
type_error (void)
{
- extern int yylineno;
+ extern int graphyylineno;
gf_log ("parser", GF_LOG_ERROR,
"Volume %s, before line %d: Please specify volume type",
- curr->name, yylineno);
+ curr->name, graphyylineno);
return;
}
@@ -98,11 +91,11 @@ type_error (void)
static void
sub_error (void)
{
- extern int yylineno;
+ extern int graphyylineno;
gf_log ("parser", GF_LOG_ERROR,
"Volume %s, before line %d: Please specify subvolumes",
- curr->name, yylineno);
+ curr->name, graphyylineno);
return;
}
@@ -110,12 +103,12 @@ sub_error (void)
static void
option_error (void)
{
- extern int yylineno;
+ extern int graphyylineno;
gf_log ("parser", GF_LOG_ERROR,
"Volume %s, before line %d: Please specify "
"option <key> <value>",
- curr->name, yylineno);
+ curr->name, graphyylineno);
return;
}
@@ -123,7 +116,7 @@ option_error (void)
static int
new_volume (char *name)
{
- extern int yylineno;
+ extern int graphyylineno;
xlator_t *trav = NULL;
int ret = 0;
@@ -137,7 +130,7 @@ new_volume (char *name)
if (curr) {
gf_log ("parser", GF_LOG_ERROR,
"new volume (%s) defintion in line %d unexpected",
- name, yylineno);
+ name, graphyylineno);
ret = -1;
goto out;
}
@@ -157,7 +150,7 @@ new_volume (char *name)
if (!strcmp (name, trav->name)) {
gf_log ("parser", GF_LOG_ERROR,
"Line %d: volume '%s' defined again",
- yylineno, name);
+ graphyylineno, name);
ret = -1;
goto out;
}
@@ -202,7 +195,7 @@ out:
static int
volume_type (char *type)
{
- extern int yylineno;
+ extern int graphyylineno;
int32_t ret = 0;
if (!type) {
@@ -216,7 +209,7 @@ volume_type (char *type)
gf_log ("parser", GF_LOG_ERROR,
"Volume '%s', line %d: type '%s' is not valid or "
"not found on this machine",
- curr->name, yylineno, type);
+ curr->name, graphyylineno, type);
ret = -1;
goto out;
}
@@ -233,7 +226,7 @@ out:
static int
volume_option (char *key, char *value)
{
- extern int yylineno;
+ extern int graphyylineno;
int ret = 0;
char *set_value = NULL;
@@ -250,7 +243,7 @@ volume_option (char *key, char *value)
gf_log ("parser", GF_LOG_ERROR,
"Volume '%s', line %d: duplicate entry "
"('option %s') present",
- curr->name, yylineno, key);
+ curr->name, graphyylineno, key);
ret = -1;
goto out;
}
@@ -269,7 +262,7 @@ out:
static int
volume_sub (char *sub)
{
- extern int yylineno;
+ extern int graphyylineno;
xlator_t *trav = NULL;
int ret = 0;
@@ -291,7 +284,7 @@ volume_sub (char *sub)
gf_log ("parser", GF_LOG_ERROR,
"Volume '%s', line %d: subvolume '%s' is not defined "
"prior to usage",
- curr->name, yylineno, sub);
+ curr->name, graphyylineno, sub);
ret = -1;
goto out;
}
@@ -299,7 +292,7 @@ volume_sub (char *sub)
if (trav == curr) {
gf_log ("parser", GF_LOG_ERROR,
"Volume '%s', line %d: has '%s' itself as subvolume",
- curr->name, yylineno, sub);
+ curr->name, graphyylineno, sub);
ret = -1;
goto out;
}
@@ -336,46 +329,46 @@ volume_end (void)
int
-yywrap ()
+graphyywrap ()
{
return 1;
}
int
-yyerror (const char *str)
+graphyyerror (const char *str)
{
- extern char *yytext;
- extern int yylineno;
+ extern char *graphyytext;
+ extern int graphyylineno;
- if (curr && curr->name && yytext) {
- if (!strcmp (yytext, "volume")) {
+ if (curr && curr->name && graphyytext) {
+ if (!strcmp (graphyytext, "volume")) {
gf_log ("parser", GF_LOG_ERROR,
"'end-volume' not defined for volume '%s'",
curr->name);
- } else if (!strcmp (yytext, "type")) {
+ } else if (!strcmp (graphyytext, "type")) {
gf_log ("parser", GF_LOG_ERROR,
"line %d: duplicate 'type' defined for "
"volume '%s'",
- yylineno, curr->name);
- } else if (!strcmp (yytext, "subvolumes")) {
+ graphyylineno, curr->name);
+ } else if (!strcmp (graphyytext, "subvolumes")) {
gf_log ("parser", GF_LOG_ERROR,
"line %d: duplicate 'subvolumes' defined for "
"volume '%s'",
- yylineno, curr->name);
+ graphyylineno, curr->name);
} else if (curr) {
gf_log ("parser", GF_LOG_ERROR,
"syntax error: line %d (volume '%s'): \"%s\""
"\nallowed tokens are 'volume', 'type', "
"'subvolumes', 'option', 'end-volume'()",
- yylineno, curr->name,
- yytext);
+ graphyylineno, curr->name,
+ graphyytext);
} else {
gf_log ("parser", GF_LOG_ERROR,
"syntax error: line %d (just after volume "
"'%s'): \"%s\"\n(%s)",
- yylineno, curr->name,
- yytext,
+ graphyylineno, curr->name,
+ graphyytext,
"allowed tokens are 'volume', 'type', "
"'subvolumes', 'option', 'end-volume'");
}
@@ -384,7 +377,7 @@ yyerror (const char *str)
"syntax error in line %d: \"%s\" \n"
"(allowed tokens are 'volume', 'type', "
"'subvolumes', 'option', 'end-volume')\n",
- yylineno, yytext);
+ graphyylineno, graphyytext);
}
return -1;
@@ -443,8 +436,6 @@ preprocess (FILE *srcfp, FILE *dstfp)
char in_backtick = 0;
int line = 1;
int column = 0;
- int backtick_line = 0;
- int backtick_column = 0;
int character = 0;
@@ -482,9 +473,6 @@ preprocess (FILE *srcfp, FILE *dstfp)
} else {
i = 0;
cmd[i] = '\0';
-
- backtick_column = column;
- backtick_line = line;
}
in_backtick = !in_backtick;
@@ -494,6 +482,7 @@ preprocess (FILE *srcfp, FILE *dstfp)
cmd_buf_size *= 2;
cmd = GF_REALLOC (cmd, cmd_buf_size);
if (cmd == NULL) {
+ GF_FREE (result);
return -1;
}
@@ -535,6 +524,7 @@ preprocess (FILE *srcfp, FILE *dstfp)
out:
fseek (srcfp, 0L, SEEK_SET);
fseek (dstfp, 0L, SEEK_SET);
+
GF_FREE (cmd);
GF_FREE (result);
@@ -542,7 +532,7 @@ out:
}
-extern FILE *yyin;
+extern FILE *graphyyin;
glusterfs_graph_t *
glusterfs_graph_new ()
@@ -566,52 +556,65 @@ glusterfs_graph_t *
glusterfs_graph_construct (FILE *fp)
{
int ret = 0;
+ int tmp_fd = -1;
glusterfs_graph_t *graph = NULL;
- FILE *tmp_file = NULL;
+ FILE *tmp_file = NULL;
+ char template[PATH_MAX] = {0};
+ static pthread_mutex_t graph_mutex = PTHREAD_MUTEX_INITIALIZER;
graph = glusterfs_graph_new ();
if (!graph)
- return NULL;
+ goto err;
- tmp_file = tmpfile ();
+ strcpy (template, "/tmp/tmp.XXXXXX");
+ tmp_fd = mkstemp (template);
+ if (-1 == tmp_fd)
+ goto err;
- if (tmp_file == NULL) {
- gf_log ("parser", GF_LOG_ERROR,
- "cannot create temparory file");
+ ret = unlink (template);
+ if (ret < 0) {
+ gf_log ("parser", GF_LOG_WARNING, "Unable to delete file: %s",
+ template);
+ }
- glusterfs_graph_destroy (graph);
- return NULL;
- }
+ tmp_file = fdopen (tmp_fd, "w+b");
+ if (!tmp_file)
+ goto err;
- ret = preprocess (fp, tmp_file);
- if (ret < 0) {
- gf_log ("parser", GF_LOG_ERROR,
- "parsing of backticks failed");
+ ret = preprocess (fp, tmp_file);
+ if (ret < 0) {
+ gf_log ("parser", GF_LOG_ERROR, "parsing of backticks failed");
+ goto err;
+ }
- glusterfs_graph_destroy (graph);
- fclose (tmp_file);
- return NULL;
+ pthread_mutex_lock (&graph_mutex);
+ {
+ graphyyin = tmp_file;
+ construct = graph;
+ ret = yyparse ();
+ construct = NULL;
}
-
- yyin = tmp_file;
-
- construct = graph;
-
- ret = yyparse ();
-
- construct = NULL;
-
- fclose (tmp_file);
+ pthread_mutex_unlock (&graph_mutex);
if (ret == 1) {
gf_log ("parser", GF_LOG_DEBUG,
- "parsing of volfile failed, please review it "
- "once more");
-
- glusterfs_graph_destroy (graph);
- return NULL;
+ "parsing of volfile failed, please review it "
+ "once more");
+ goto err;
}
+ fclose (tmp_file);
return graph;
+err:
+ if (tmp_file) {
+ fclose (tmp_file);
+ } else {
+ gf_log ("parser", GF_LOG_ERROR, "cannot create temporary file");
+ if (-1 != tmp_fd)
+ close (tmp_fd);
+ }
+
+ glusterfs_graph_destroy (graph);
+ return NULL;
}
diff --git a/libglusterfs/src/hashfn.c b/libglusterfs/src/hashfn.c
index 98f741885..f79165b22 100644
--- a/libglusterfs/src/hashfn.c
+++ b/libglusterfs/src/hashfn.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 <stdint.h>
@@ -31,7 +22,7 @@
#define DM_DELTA 0x9E3779B9
#define DM_FULLROUNDS 10 /* 32 is overkill, 16 is strong crypto */
-#define DM_PARTROUNDS 6 /* 6 gets complete mixing */
+#define DM_PARTROUNDS 6 /* 6 gets complete mixing */
uint32_t
@@ -52,48 +43,48 @@ ReallySimpleHash (char *path, int len)
/* In any case make sure, you return 1 */
uint32_t SuperFastHash (const char * data, int32_t len) {
- uint32_t hash = len, tmp;
- int32_t rem;
-
- if (len <= 1 || data == NULL) return 1;
-
- rem = len & 3;
- len >>= 2;
-
- /* Main loop */
- for (;len > 0; len--) {
- hash += get16bits (data);
- tmp = (get16bits (data+2) << 11) ^ hash;
- hash = (hash << 16) ^ tmp;
- data += 2*sizeof (uint16_t);
- hash += hash >> 11;
- }
-
- /* Handle end cases */
- switch (rem) {
- case 3: hash += get16bits (data);
- hash ^= hash << 16;
- hash ^= data[sizeof (uint16_t)] << 18;
- hash += hash >> 11;
- break;
- case 2: hash += get16bits (data);
- hash ^= hash << 11;
- hash += hash >> 17;
- break;
- case 1: hash += *data;
- hash ^= hash << 10;
- hash += hash >> 1;
- }
-
- /* Force "avalanching" of final 127 bits */
- hash ^= hash << 3;
- hash += hash >> 5;
- hash ^= hash << 4;
- hash += hash >> 17;
- hash ^= hash << 25;
- hash += hash >> 6;
-
- return hash;
+ uint32_t hash = len, tmp;
+ int32_t rem;
+
+ if (len <= 1 || data == NULL) return 1;
+
+ rem = len & 3;
+ len >>= 2;
+
+ /* Main loop */
+ for (;len > 0; len--) {
+ hash += get16bits (data);
+ tmp = (get16bits (data+2) << 11) ^ hash;
+ hash = (hash << 16) ^ tmp;
+ data += 2*sizeof (uint16_t);
+ hash += hash >> 11;
+ }
+
+ /* Handle end cases */
+ switch (rem) {
+ case 3: hash += get16bits (data);
+ hash ^= hash << 16;
+ hash ^= data[sizeof (uint16_t)] << 18;
+ hash += hash >> 11;
+ break;
+ case 2: hash += get16bits (data);
+ hash ^= hash << 11;
+ hash += hash >> 17;
+ break;
+ case 1: hash += *data;
+ hash ^= hash << 10;
+ hash += hash >> 1;
+ }
+
+ /* Force "avalanching" of final 127 bits */
+ hash ^= hash << 3;
+ hash += hash >> 5;
+ hash ^= hash << 4;
+ hash += hash >> 17;
+ hash ^= hash << 25;
+ hash += hash >> 6;
+
+ return hash;
}
@@ -102,95 +93,95 @@ uint32_t SuperFastHash (const char * data, int32_t len) {
static int
dm_round (int rounds, uint32_t *array, uint32_t *h0, uint32_t *h1)
{
- uint32_t sum = 0;
- int n = 0;
- uint32_t b0 = 0;
- uint32_t b1 = 0;
-
- b0 = *h0;
- b1 = *h1;
-
- n = rounds;
-
- do {
- sum += DM_DELTA;
- b0 += ((b1 << 4) + array[0])
- ^ (b1 + sum)
- ^ ((b1 >> 5) + array[1]);
- b1 += ((b0 << 4) + array[2])
- ^ (b0 + sum)
- ^ ((b0 >> 5) + array[3]);
- } while (--n);
-
- *h0 += b0;
- *h1 += b1;
-
- return 0;
+ uint32_t sum = 0;
+ int n = 0;
+ uint32_t b0 = 0;
+ uint32_t b1 = 0;
+
+ b0 = *h0;
+ b1 = *h1;
+
+ n = rounds;
+
+ do {
+ sum += DM_DELTA;
+ b0 += ((b1 << 4) + array[0])
+ ^ (b1 + sum)
+ ^ ((b1 >> 5) + array[1]);
+ b1 += ((b0 << 4) + array[2])
+ ^ (b0 + sum)
+ ^ ((b0 >> 5) + array[3]);
+ } while (--n);
+
+ *h0 += b0;
+ *h1 += b1;
+
+ return 0;
}
uint32_t
__pad (int len)
{
- uint32_t pad = 0;
+ uint32_t pad = 0;
- pad = (uint32_t) len | ((uint32_t) len << 8);
- pad |= pad << 16;
+ pad = (uint32_t) len | ((uint32_t) len << 8);
+ pad |= pad << 16;
- return pad;
+ return pad;
}
uint32_t
gf_dm_hashfn (const char *msg, int len)
{
- uint32_t h0 = 0x9464a485;
- uint32_t h1 = 0x542e1a94;
- uint32_t array[4];
- uint32_t pad = 0;
- int i = 0;
- int j = 0;
- int full_quads = 0;
- int full_words = 0;
- int full_bytes = 0;
- uint32_t *intmsg = NULL;
- int word = 0;
-
-
- intmsg = (uint32_t *) msg;
- pad = __pad (len);
-
- full_bytes = len;
- full_words = len / 4;
- full_quads = len / 16;
-
- for (i = 0; i < full_quads; i++) {
- for (j = 0; j < 4; j++) {
- word = *intmsg;
- array[j] = word;
- intmsg++;
- full_words--;
- full_bytes -= 4;
- }
- dm_round (DM_PARTROUNDS, &array[0], &h0, &h1);
- }
-
- for (j = 0; j < 4; j++) {
- if (full_words) {
- word = *intmsg;
- array[j] = word;
- intmsg++;
- full_words--;
- full_bytes -= 4;
- } else {
- array[j] = pad;
- while (full_bytes) {
- array[j] <<= 8;
- array[j] |= msg[len - full_bytes];
- full_bytes--;
- }
- }
- }
- dm_round (DM_FULLROUNDS, &array[0], &h0, &h1);
-
- return h0 ^ h1;
+ uint32_t h0 = 0x9464a485;
+ uint32_t h1 = 0x542e1a94;
+ uint32_t array[4];
+ uint32_t pad = 0;
+ int i = 0;
+ int j = 0;
+ int full_quads = 0;
+ int full_words = 0;
+ int full_bytes = 0;
+ uint32_t *intmsg = NULL;
+ int word = 0;
+
+
+ intmsg = (uint32_t *) msg;
+ pad = __pad (len);
+
+ full_bytes = len;
+ full_words = len / 4;
+ full_quads = len / 16;
+
+ for (i = 0; i < full_quads; i++) {
+ for (j = 0; j < 4; j++) {
+ word = *intmsg;
+ array[j] = word;
+ intmsg++;
+ full_words--;
+ full_bytes -= 4;
+ }
+ dm_round (DM_PARTROUNDS, &array[0], &h0, &h1);
+ }
+
+ for (j = 0; j < 4; j++) {
+ if (full_words) {
+ word = *intmsg;
+ array[j] = word;
+ intmsg++;
+ full_words--;
+ full_bytes -= 4;
+ } else {
+ array[j] = pad;
+ while (full_bytes) {
+ array[j] <<= 8;
+ array[j] |= msg[len - full_bytes];
+ full_bytes--;
+ }
+ }
+ }
+ dm_round (DM_FULLROUNDS, &array[0], &h0, &h1);
+
+ return h0 ^ h1;
}
diff --git a/libglusterfs/src/hashfn.h b/libglusterfs/src/hashfn.h
index 8261e4c78..06ae37e79 100644
--- a/libglusterfs/src/hashfn.h
+++ b/libglusterfs/src/hashfn.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
+ 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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 __HASHFN_H__
@@ -32,6 +23,5 @@ uint32_t SuperFastHash (const char * data, int32_t len);
uint32_t gf_dm_hashfn (const char *msg, int len);
-uint32_t
-ReallySimpleHash (char *path, int len);
+uint32_t ReallySimpleHash (char *path, int len);
#endif /* __HASHFN_H__ */
diff --git a/libglusterfs/src/iatt.h b/libglusterfs/src/iatt.h
index a17e0e7a4..60ae59047 100644
--- a/libglusterfs/src/iatt.h
+++ b/libglusterfs/src/iatt.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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.
*/
@@ -103,6 +94,8 @@ struct iatt {
#define IA_PROT_SGID(prot) ((prot).sgid == 1)
#define IA_PROT_STCKY(prot) ((prot).sticky == 1)
+#define IA_FILE_OR_DIR(t) (IA_ISREG(t) || IA_ISDIR(t))
+
static inline uint32_t
ia_major (uint64_t ia_dev)
{
@@ -120,7 +113,7 @@ ia_minor (uint64_t ia_dev)
static inline uint64_t
ia_makedev (uint32_t ia_maj, uint32_t ia_min)
{
- return ((((uint64_t) ia_maj) << 32) & ia_min);
+ return ((((uint64_t) ia_maj) << 32) | ia_min);
}
@@ -272,6 +265,24 @@ iatt_from_stat (struct iatt *iatt, struct stat *stat)
iatt->ia_blksize = stat->st_blksize;
iatt->ia_blocks = stat->st_blocks;
+ /* There is a possibility that the backend FS (like XFS) can
+ allocate blocks beyond EOF for better performance reasons, which
+ results in 'st_blocks' with higher values than what is consumed by
+ the file descriptor. This would break few logic inside GlusterFS,
+ like quota behavior etc, thus we need the exact number of blocks
+ which are consumed by the file to the higher layers inside GlusterFS.
+ Currently, this logic won't work for sparse files (ie, file with
+ holes)
+ */
+ {
+ uint64_t maxblocks;
+
+ maxblocks = (iatt->ia_size + 511) / 512;
+
+ if (iatt->ia_blocks > maxblocks)
+ iatt->ia_blocks = maxblocks;
+ }
+
iatt->ia_atime = stat->st_atime;
iatt->ia_atime_nsec = ST_ATIM_NSEC (stat);
diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c
index 04e4560ed..15e0ccf78 100644
--- a/libglusterfs/src/inode.c
+++ b/libglusterfs/src/inode.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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
@@ -37,13 +28,13 @@
move latest accessed dentry to list_head of inode
*/
-#define INODE_DUMP_LIST(head, key_buf, key_prefix, list_type) \
+#define INODE_DUMP_LIST(head, key_buf, key_prefix, list_type) \
{ \
int i = 1; \
inode_t *inode = NULL; \
list_for_each_entry (inode, head, list) { \
- gf_proc_dump_build_key(key_buf, key_prefix, "%s.%d",list_type, \
- i++); \
+ gf_proc_dump_build_key(key_buf, key_prefix, \
+ "%s.%d",list_type, i++); \
gf_proc_dump_add_section(key_buf); \
inode_dump(inode, key); \
} \
@@ -93,8 +84,10 @@ __dentry_hash (dentry_t *dentry)
inode_table_t *table = NULL;
int hash = 0;
- if (!dentry)
+ if (!dentry) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "dentry not found");
return;
+ }
table = dentry->inode->table;
hash = hash_dentry (dentry->parent, dentry->name,
@@ -108,8 +101,10 @@ __dentry_hash (dentry_t *dentry)
static int
__is_dentry_hashed (dentry_t *dentry)
{
- if (!dentry)
+ if (!dentry) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "dentry not found");
return 0;
+ }
return !list_empty (&dentry->hash);
}
@@ -118,8 +113,10 @@ __is_dentry_hashed (dentry_t *dentry)
static void
__dentry_unhash (dentry_t *dentry)
{
- if (!dentry)
+ if (!dentry) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "dentry not found");
return;
+ }
list_del_init (&dentry->hash);
}
@@ -128,36 +125,109 @@ __dentry_unhash (dentry_t *dentry)
static void
__dentry_unset (dentry_t *dentry)
{
- struct mem_pool *tmp_pool = NULL;
-
- if (!dentry)
+ if (!dentry) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "dentry not found");
return;
+ }
- tmp_pool = dentry->inode->table->dentry_pool;
__dentry_unhash (dentry);
list_del_init (&dentry->inode_list);
- if (dentry->name)
- GF_FREE (dentry->name);
+ GF_FREE (dentry->name);
if (dentry->parent) {
__inode_unref (dentry->parent);
dentry->parent = NULL;
}
- mem_put (tmp_pool, dentry);
- tmp_pool = NULL;
+ mem_put (dentry);
+}
+
+
+static int
+__foreach_ancestor_dentry (dentry_t *dentry,
+ int (per_dentry_fn) (dentry_t *dentry,
+ void *data),
+ void *data)
+{
+ inode_t *parent = NULL;
+ dentry_t *each = NULL;
+ int ret = 0;
+
+ if (!dentry) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "dentry not found");
+ return 0;
+ }
+
+ ret = per_dentry_fn (dentry, data);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_WARNING, "per dentry fn returned %d", ret);
+ goto out;
+ }
+
+ parent = dentry->parent;
+ if (!parent) {
+ gf_log (THIS->name, GF_LOG_WARNING, "parent not found");
+ goto out;
+ }
+ list_for_each_entry (each, &parent->dentry_list, inode_list) {
+ ret = __foreach_ancestor_dentry (each, per_dentry_fn, data);
+ if (ret)
+ goto out;
+ }
+out:
+ return ret;
}
+static int
+__check_cycle (dentry_t *a_dentry, void *data)
+{
+ inode_t *link_inode = NULL;
+
+ link_inode = data;
+
+ if (a_dentry->parent == link_inode)
+ return 1;
+
+ return 0;
+}
+
+
+static int
+__is_dentry_cyclic (dentry_t *dentry)
+{
+ int ret = 0;
+ inode_t *inode = NULL;
+ char *name = "<nul>";
+
+ ret = __foreach_ancestor_dentry (dentry, __check_cycle,
+ dentry->inode);
+ if (ret) {
+ inode = dentry->inode;
+
+ if (dentry->name)
+ name = dentry->name;
+
+ gf_log (dentry->inode->table->name, GF_LOG_CRITICAL,
+ "detected cyclic loop formation during inode linkage."
+ " inode (%s) linking under itself as %s",
+ uuid_utoa (inode->gfid), name);
+ }
+
+ return ret;
+}
+
static void
__inode_unhash (inode_t *inode)
{
- if (!inode)
+ if (!inode) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode not found");
return;
+ }
list_del_init (&inode->hash);
}
@@ -166,8 +236,10 @@ __inode_unhash (inode_t *inode)
static int
__is_inode_hashed (inode_t *inode)
{
- if (!inode)
+ if (!inode) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode not found");
return 0;
+ }
return !list_empty (&inode->hash);
}
@@ -179,8 +251,10 @@ __inode_hash (inode_t *inode)
inode_table_t *table = NULL;
int hash = 0;
- if (!inode)
+ if (!inode) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode not found");
return;
+ }
table = inode->table;
hash = hash_gfid (inode->gfid, 65536);
@@ -191,16 +265,25 @@ __inode_hash (inode_t *inode)
static dentry_t *
-__dentry_search_for_inode (inode_t *inode, ino_t par, const char *name)
+__dentry_search_for_inode (inode_t *inode, uuid_t pargfid, const char *name)
{
dentry_t *dentry = NULL;
dentry_t *tmp = NULL;
- if (!inode || !name)
+ if (!inode || !name) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode || name not found");
+ return NULL;
+ }
+
+ /* earlier, just the ino was sent, which could have been 0, now
+ we deal with gfid, and if sent gfid is null or 0, no need to
+ continue with the check */
+ if (!pargfid || uuid_is_null (pargfid))
return NULL;
list_for_each_entry (tmp, &inode->dentry_list, inode_list) {
- if (tmp->parent->ino == par && !strcmp (tmp->name, name)) {
+ if ((uuid_compare (tmp->parent->gfid, pargfid) == 0) &&
+ !strcmp (tmp->name, name)) {
dentry = tmp;
break;
}
@@ -216,17 +299,18 @@ __inode_destroy (inode_t *inode)
int index = 0;
xlator_t *xl = NULL;
xlator_t *old_THIS = NULL;
- struct mem_pool *tmp_pool = NULL;
- if (!inode)
+ if (!inode) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode not found");
return;
+ }
- if (!inode->_ctx)
+ if (!inode->_ctx) {
+ gf_log (THIS->name, GF_LOG_WARNING, "_ctx not found");
goto noctx;
+ }
- tmp_pool = inode->table->inode_pool;
-
- for (index = 0; index < inode->table->xl->graph->xl_count; index++) {
+ for (index = 0; index < inode->table->ctxcount; index++) {
if (inode->_ctx[index].xl_key) {
xl = (xlator_t *)(long)inode->_ctx[index].xl_key;
old_THIS = THIS;
@@ -241,9 +325,7 @@ __inode_destroy (inode_t *inode)
noctx:
LOCK_DESTROY (&inode->lock);
// memset (inode, 0xb, sizeof (*inode));
- mem_put (tmp_pool, inode);
- tmp_pool = NULL;
-
+ mem_put (inode);
}
@@ -264,8 +346,10 @@ __inode_passivate (inode_t *inode)
dentry_t *dentry = NULL;
dentry_t *t = NULL;
- if (!inode)
+ if (!inode) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode not found");
return;
+ }
list_move_tail (&inode->list, &inode->table->lru);
inode->table->lru_size++;
@@ -283,8 +367,10 @@ __inode_retire (inode_t *inode)
dentry_t *dentry = NULL;
dentry_t *t = NULL;
- if (!inode)
+ if (!inode) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode not found");
return;
+ }
list_move_tail (&inode->list, &inode->table->purge);
inode->table->purge_size++;
@@ -303,7 +389,7 @@ __inode_unref (inode_t *inode)
if (!inode)
return NULL;
- if (inode->ino == 1)
+ if (__is_root_gfid(inode->gfid))
return inode;
GF_ASSERT (inode->ref);
@@ -386,13 +472,14 @@ __dentry_create (inode_t *inode, inode_t *parent, const char *name)
{
dentry_t *newd = NULL;
- if (!inode || !parent || !name)
+ if (!inode || !parent || !name) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING,
+ "inode || parent || name not found");
return NULL;
+ }
newd = mem_get0 (parent->table->dentry_pool);
-
if (newd == NULL) {
- gf_log ("inode", GF_LOG_ERROR, "out of memory");
goto out;
}
@@ -401,8 +488,7 @@ __dentry_create (inode_t *inode, inode_t *parent, const char *name)
newd->name = gf_strdup (name);
if (newd->name == NULL) {
- gf_log ("inode", GF_LOG_ERROR, "out of memory");
- mem_put (parent->table->dentry_pool, newd);
+ mem_put (newd);
newd = NULL;
goto out;
}
@@ -423,12 +509,13 @@ __inode_create (inode_table_t *table)
{
inode_t *newi = NULL;
- if (!table)
+ if (!table) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "table not found");
return NULL;
+ }
newi = mem_get0 (table->inode_pool);
if (!newi) {
- gf_log ("inode", GF_LOG_ERROR, "out of memory");
goto out;
}
@@ -441,14 +528,12 @@ __inode_create (inode_table_t *table)
INIT_LIST_HEAD (&newi->hash);
INIT_LIST_HEAD (&newi->dentry_list);
- newi->_ctx = GF_CALLOC (1, (sizeof (struct _inode_ctx) *
- table->xl->graph->xl_count),
- gf_common_mt_inode_ctx);
-
+ newi->_ctx = GF_CALLOC (1,
+ (sizeof (struct _inode_ctx) * table->ctxcount),
+ gf_common_mt_inode_ctx);
if (newi->_ctx == NULL) {
- gf_log ("inode", GF_LOG_ERROR, "out of memory");
LOCK_DESTROY (&newi->lock);
- mem_put (table->inode_pool, newi);
+ mem_put (newi);
newi = NULL;
goto out;
}
@@ -467,8 +552,10 @@ inode_new (inode_table_t *table)
{
inode_t *inode = NULL;
- if (!table)
+ if (!table) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode not found");
return NULL;
+ }
pthread_mutex_lock (&table->lock);
{
@@ -541,8 +628,11 @@ inode_grep (inode_table_t *table, inode_t *parent, const char *name)
inode_t *inode = NULL;
dentry_t *dentry = NULL;
- if (!table || !parent || !name)
+ if (!table || !parent || !name) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING,
+ "table || parent || name not found");
return NULL;
+ }
pthread_mutex_lock (&table->lock);
{
@@ -561,24 +651,94 @@ inode_grep (inode_table_t *table, inode_t *parent, const char *name)
inode_t *
-inode_get (inode_table_t *table, ino_t ino, uint64_t gen)
+inode_resolve (inode_table_t *table, char *path)
{
- return NULL;
+ char *tmp = NULL, *bname = NULL, *str = NULL, *saveptr = NULL;
+ inode_t *inode = NULL, *parent = NULL;
+
+ if ((path == NULL) || (table == NULL)) {
+ goto out;
+ }
+
+ parent = inode_ref (table->root);
+ str = tmp = gf_strdup (path);
+
+ while (1) {
+ bname = strtok_r (str, "/", &saveptr);
+ if (bname == NULL) {
+ break;
+ }
+
+ if (inode != NULL) {
+ inode_unref (inode);
+ }
+
+ inode = inode_grep (table, parent, bname);
+ if (inode == NULL) {
+ break;
+ }
+
+ if (parent != NULL) {
+ inode_unref (parent);
+ }
+
+ parent = inode_ref (inode);
+ str = NULL;
+ }
+
+ inode_unref (parent);
+ GF_FREE (tmp);
+out:
+ return inode;
}
-static int
+int
+inode_grep_for_gfid (inode_table_t *table, inode_t *parent, const char *name,
+ uuid_t gfid, ia_type_t *type)
+{
+ inode_t *inode = NULL;
+ dentry_t *dentry = NULL;
+ int ret = -1;
+
+ if (!table || !parent || !name) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING,
+ "table || parent || name not found");
+ return ret;
+ }
+
+ pthread_mutex_lock (&table->lock);
+ {
+ dentry = __dentry_grep (table, parent, name);
+
+ if (dentry)
+ inode = dentry->inode;
+
+ if (inode) {
+ uuid_copy (gfid, inode->gfid);
+ *type = inode->ia_type;
+ ret = 0;
+ }
+ }
+ pthread_mutex_unlock (&table->lock);
+
+ return ret;
+}
+
+
+/* return 1 if gfid is of root, 0 if not */
+gf_boolean_t
__is_root_gfid (uuid_t gfid)
{
uuid_t root;
- int ret;
memset (root, 0, 16);
root[15] = 1;
- ret = uuid_compare (gfid, root);
+ if (uuid_compare (gfid, root) == 0)
+ return _gf_true;
- return ret;
+ return _gf_false;
}
@@ -589,10 +749,12 @@ __inode_find (inode_table_t *table, uuid_t gfid)
inode_t *tmp = NULL;
int hash = 0;
- if (!table)
+ if (!table) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "table not found");
goto out;
+ }
- if (__is_root_gfid (gfid) == 0)
+ if (__is_root_gfid (gfid))
return table->root;
hash = hash_gfid (gfid, 65536);
@@ -614,8 +776,10 @@ inode_find (inode_table_t *table, uuid_t gfid)
{
inode_t *inode = NULL;
- if (!table)
+ if (!table) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "table not found");
return NULL;
+ }
pthread_mutex_lock (&table->lock);
{
@@ -646,6 +810,15 @@ __inode_link (inode_t *inode, inode_t *parent, const char *name,
if (!table)
return NULL;
+ if (parent) {
+ /* We should prevent inode linking between different
+ inode tables. This can cause errors which is very
+ hard to catch/debug. */
+ if (inode->table != parent->table) {
+ GF_ASSERT (!"link attempted b/w inodes of diff table");
+ }
+ }
+
link_inode = inode;
if (!__is_inode_hashed (inode)) {
@@ -655,25 +828,40 @@ __inode_link (inode_t *inode, inode_t *parent, const char *name,
if (uuid_is_null (iatt->ia_gfid))
return NULL;
- uuid_copy (inode->gfid, iatt->ia_gfid);
- inode->ino = iatt->ia_ino;
- inode->ia_type = iatt->ia_type;
-
- old_inode = __inode_find (table, inode->gfid);
+ old_inode = __inode_find (table, iatt->ia_gfid);
if (old_inode) {
link_inode = old_inode;
} else {
+ uuid_copy (inode->gfid, iatt->ia_gfid);
+ inode->ia_type = iatt->ia_type;
__inode_hash (inode);
}
}
+ if (name) {
+ if (!strcmp(name, ".") || !strcmp(name, ".."))
+ return link_inode;
+ }
+
/* use only link_inode beyond this point */
if (parent) {
old_dentry = __dentry_grep (table, parent, name);
if (!old_dentry || old_dentry->inode != link_inode) {
dentry = __dentry_create (link_inode, parent, name);
+ if (!dentry) {
+ gf_log_callingfn (THIS->name, GF_LOG_ERROR,
+ "dentry create failed on "
+ "inode %s with parent %s",
+ uuid_utoa (link_inode->gfid),
+ uuid_utoa (parent->gfid));
+ return NULL;
+ }
+ if (old_inode && __is_dentry_cyclic (dentry)) {
+ __dentry_unset (dentry);
+ return NULL;
+ }
__dentry_hash (dentry);
if (old_dentry)
@@ -692,8 +880,10 @@ inode_link (inode_t *inode, inode_t *parent, const char *name,
inode_table_t *table = NULL;
inode_t *linked_inode = NULL;
- if (!inode)
+ if (!inode) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode not found");
return NULL;
+ }
table = inode->table;
@@ -717,8 +907,10 @@ inode_lookup (inode_t *inode)
{
inode_table_t *table = NULL;
- if (!inode)
+ if (!inode) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode not found");
return -1;
+ }
table = inode->table;
@@ -737,8 +929,10 @@ inode_forget (inode_t *inode, uint64_t nlookup)
{
inode_table_t *table = NULL;
- if (!inode)
+ if (!inode) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode not found");
return -1;
+ }
table = inode->table;
@@ -753,6 +947,54 @@ inode_forget (inode_t *inode, uint64_t nlookup)
return 0;
}
+/*
+ * Invalidate an inode. This is invoked when a translator decides that an inode's
+ * cache is no longer valid. Any translator interested in taking action in this
+ * situation can define the invalidate callback.
+ */
+int
+inode_invalidate(inode_t *inode)
+{
+ int ret = 0;
+ xlator_t *xl = NULL;
+ xlator_t *old_THIS = NULL;
+
+ if (!inode) {
+ gf_log_callingfn(THIS->name, GF_LOG_WARNING, "inode not found");
+ return -1;
+ }
+
+ /*
+ * The master xlator is not in the graph but it can define an invalidate
+ * handler.
+ */
+ xl = inode->table->xl->ctx->master;
+ if (xl && xl->cbks->invalidate) {
+ old_THIS = THIS;
+ THIS = xl;
+ ret = xl->cbks->invalidate(xl, inode);
+ THIS = old_THIS;
+ if (ret)
+ return ret;
+ }
+
+ xl = inode->table->xl->graph->first;
+ while (xl) {
+ old_THIS = THIS;
+ THIS = xl;
+ if (xl->cbks->invalidate)
+ ret = xl->cbks->invalidate(xl, inode);
+ THIS = old_THIS;
+
+ if (ret)
+ break;
+
+ xl = xl->next;
+ }
+
+ return ret;
+}
+
static void
__inode_unlink (inode_t *inode, inode_t *parent, const char *name)
@@ -762,7 +1004,7 @@ __inode_unlink (inode_t *inode, inode_t *parent, const char *name)
if (!inode || !parent || !name)
return;
- dentry = __dentry_search_for_inode (inode, parent->ino, name);
+ dentry = __dentry_search_for_inode (inode, parent->gfid, name);
/* dentry NULL for corrupted backend */
if (dentry)
@@ -775,8 +1017,10 @@ inode_unlink (inode_t *inode, inode_t *parent, const char *name)
{
inode_table_t *table = NULL;
- if (!inode)
+ if (!inode) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode not found");
return;
+ }
table = inode->table;
@@ -795,8 +1039,10 @@ inode_rename (inode_table_t *table, inode_t *srcdir, const char *srcname,
inode_t *dstdir, const char *dstname, inode_t *inode,
struct iatt *iatt)
{
- if (!inode)
+ if (!inode) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode not found");
return -1;
+ }
table = inode->table;
@@ -841,21 +1087,23 @@ __dentry_search_arbit (inode_t *inode)
inode_t *
-inode_parent (inode_t *inode, ino_t par, const char *name)
+inode_parent (inode_t *inode, uuid_t pargfid, const char *name)
{
inode_t *parent = NULL;
inode_table_t *table = NULL;
dentry_t *dentry = NULL;
- if (!inode)
+ if (!inode) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode not found");
return NULL;
+ }
table = inode->table;
pthread_mutex_lock (&table->lock);
{
- if (par && name) {
- dentry = __dentry_search_for_inode (inode, par, name);
+ if (pargfid && !uuid_is_null (pargfid) && name) {
+ dentry = __dentry_search_for_inode (inode, pargfid, name);
} else {
dentry = __dentry_search_arbit (inode);
}
@@ -873,99 +1121,124 @@ inode_parent (inode_t *inode, ino_t par, const char *name)
int
-inode_path (inode_t *inode, const char *name, char **bufp)
+__inode_path (inode_t *inode, const char *name, char **bufp)
{
inode_table_t *table = NULL;
- dentry_t *trav = NULL;
- size_t i = 0, size = 0;
- int64_t ret = 0;
- int len = 0;
- char *buf = NULL;
-
- if (!inode)
+ inode_t *itrav = NULL;
+ dentry_t *trav = NULL;
+ size_t i = 0, size = 0;
+ int64_t ret = 0;
+ int len = 0;
+ char *buf = NULL;
+
+ if (!inode || uuid_is_null (inode->gfid)) {
+ GF_ASSERT (0);
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "invalid inode");
return -1;
+ }
table = inode->table;
- pthread_mutex_lock (&table->lock);
- {
- for (trav = __dentry_search_arbit (inode); trav;
- trav = __dentry_search_arbit (trav->parent)) {
- i ++; /* "/" */
- i += strlen (trav->name);
- if (i > PATH_MAX) {
- gf_log (table->name, GF_LOG_CRITICAL,
- "possible infinite loop detected, "
- "forcing break. name=(%s)", name);
- ret = -ENOENT;
- goto unlock;
- }
- }
-
- if ((inode->ino != 1) &&
- (i == 0)) {
- gf_log (table->name, GF_LOG_DEBUG,
- "no dentry for non-root inode %"PRId64,
- inode->ino);
+ itrav = inode;
+ for (trav = __dentry_search_arbit (itrav); trav;
+ trav = __dentry_search_arbit (itrav)) {
+ itrav = trav->parent;
+ i ++; /* "/" */
+ i += strlen (trav->name);
+ if (i > PATH_MAX) {
+ gf_log (table->name, GF_LOG_CRITICAL,
+ "possible infinite loop detected, "
+ "forcing break. name=(%s)", name);
ret = -ENOENT;
- goto unlock;
+ goto out;
}
+ }
- if (name) {
- i++;
- i += strlen (name);
- }
+ if (!__is_root_gfid (itrav->gfid)) {
+ /* "<gfid:00000000-0000-0000-0000-000000000000>"/path */
+ i += GFID_STR_PFX_LEN;
+ }
- ret = i;
- size = i + 1;
- buf = GF_CALLOC (size, sizeof (char), gf_common_mt_char);
- if (buf) {
+ if (name) {
+ i++;
+ i += strlen (name);
+ }
- buf[size - 1] = 0;
+ ret = i;
+ size = i + 1;
+ buf = GF_CALLOC (size, sizeof (char), gf_common_mt_char);
+ if (buf) {
- if (name) {
- len = strlen (name);
- strncpy (buf + (i - len), name, len);
- buf[i-len-1] = '/';
- i -= (len + 1);
- }
+ buf[size - 1] = 0;
- for (trav = __dentry_search_arbit (inode); trav;
- trav = __dentry_search_arbit (trav->parent)) {
- len = strlen (trav->name);
- strncpy (buf + (i - len), trav->name, len);
- buf[i-len-1] = '/';
- i -= (len + 1);
- }
- *bufp = buf;
- } else {
- gf_log (table->name, GF_LOG_ERROR,
- "out of memory");
- ret = -ENOMEM;
+ if (name) {
+ len = strlen (name);
+ strncpy (buf + (i - len), name, len);
+ buf[i-len-1] = '/';
+ i -= (len + 1);
}
+
+ itrav = inode;
+ for (trav = __dentry_search_arbit (itrav); trav;
+ trav = __dentry_search_arbit (itrav)) {
+ itrav = trav->parent;
+ len = strlen (trav->name);
+ strncpy (buf + (i - len), trav->name, len);
+ buf[i-len-1] = '/';
+ i -= (len + 1);
+ }
+
+ if (!__is_root_gfid (itrav->gfid)) {
+ snprintf (&buf[i-GFID_STR_PFX_LEN], GFID_STR_PFX_LEN,
+ INODE_PATH_FMT, uuid_utoa (itrav->gfid));
+ buf[i-1] = '>';
+ }
+
+ *bufp = buf;
+ } else {
+ ret = -ENOMEM;
}
-unlock:
- pthread_mutex_unlock (&table->lock);
- if (inode->ino == 1 && !name) {
+out:
+ if (__is_root_gfid (inode->gfid) && !name) {
ret = 1;
- if (buf) {
- GF_FREE (buf);
- }
+ GF_FREE (buf);
buf = GF_CALLOC (ret + 1, sizeof (char), gf_common_mt_char);
if (buf) {
strcpy (buf, "/");
*bufp = buf;
} else {
- gf_log (table->name, GF_LOG_ERROR,
- "out of memory");
ret = -ENOMEM;
}
}
+ if (ret < 0)
+ *bufp = NULL;
+ return ret;
+}
+
+
+int
+inode_path (inode_t *inode, const char *name, char **bufp)
+{
+ inode_table_t *table = NULL;
+ int ret = -1;
+
+ if (!inode)
+ return -1;
+
+ table = inode->table;
+
+ pthread_mutex_lock (&table->lock);
+ {
+ ret = __inode_path (inode, name, bufp);
+ }
+ pthread_mutex_unlock (&table->lock);
+
return ret;
}
+
static int
inode_table_prune (inode_table_t *table)
{
@@ -1025,8 +1298,8 @@ __inode_table_init_root (inode_table_t *table)
iatt.ia_ino = 1;
iatt.ia_type = IA_IFDIR;
- table->root = root;
__inode_link (root, NULL, NULL, &iatt);
+ table->root = root;
}
@@ -1034,7 +1307,7 @@ inode_table_t *
inode_table_new (size_t lru_limit, xlator_t *xl)
{
inode_table_t *new = NULL;
- int ret = 0;
+ int ret = -1;
int i = 0;
new = (void *)GF_CALLOC(1, sizeof (*new), gf_common_mt_inode_table_t);
@@ -1042,48 +1315,44 @@ inode_table_new (size_t lru_limit, xlator_t *xl)
return NULL;
new->xl = xl;
+ new->ctxcount = xl->graph->xl_count + 1;
new->lru_limit = lru_limit;
new->hashsize = 14057; /* TODO: Random Number?? */
- new->inode_pool = mem_pool_new (inode_t, 204654);
+ /* In case FUSE is initing the inode table. */
+ if (lru_limit == 0)
+ lru_limit = DEFAULT_INODE_MEMPOOL_ENTRIES;
- if (!new->inode_pool) {
- GF_FREE (new);
- return NULL;
- }
+ new->inode_pool = mem_pool_new (inode_t, lru_limit);
+
+ if (!new->inode_pool)
+ goto out;
- new->dentry_pool = mem_pool_new (dentry_t, 204654);
+ new->dentry_pool = mem_pool_new (dentry_t, lru_limit);
- if (!new->dentry_pool) {
- GF_FREE (new);
- return NULL;
- }
+ if (!new->dentry_pool)
+ goto out;
new->inode_hash = (void *)GF_CALLOC (65536,
sizeof (struct list_head),
gf_common_mt_list_head);
- if (!new->inode_hash) {
- GF_FREE (new);
- return NULL;
- }
+ if (!new->inode_hash)
+ goto out;
new->name_hash = (void *)GF_CALLOC (new->hashsize,
sizeof (struct list_head),
gf_common_mt_list_head);
- if (!new->name_hash) {
- GF_FREE (new->inode_hash);
- GF_FREE (new);
- return NULL;
- }
+ if (!new->name_hash)
+ goto out;
- new->fd_mem_pool = mem_pool_new (fd_t, 16384);
+ /* if number of fd open in one process is more than this,
+ we may hit perf issues */
+ new->fd_mem_pool = mem_pool_new (fd_t, 1024);
- if (!new->fd_mem_pool) {
- GF_FREE (new->inode_hash);
- GF_FREE (new);
- }
+ if (!new->fd_mem_pool)
+ goto out;
for (i = 0; i < 65536; i++) {
INIT_LIST_HEAD (&new->inode_hash[i]);
@@ -1108,6 +1377,21 @@ inode_table_new (size_t lru_limit, xlator_t *xl)
pthread_mutex_init (&new->lock, NULL);
+ ret = 0;
+out:
+ if (ret) {
+ if (new) {
+ GF_FREE (new->inode_hash);
+ GF_FREE (new->name_hash);
+ if (new->dentry_pool)
+ mem_pool_destroy (new->dentry_pool);
+ if (new->inode_pool)
+ mem_pool_destroy (new->inode_pool);
+ GF_FREE (new);
+ new = NULL;
+ }
+ }
+
return new;
}
@@ -1129,7 +1413,6 @@ inode_from_path (inode_table_t *itable, const char *path)
/* top-down approach */
pathname = gf_strdup (path);
if (pathname == NULL) {
- gf_log ("inode", GF_LOG_ERROR, "out of memory");
goto out;
}
@@ -1165,8 +1448,7 @@ inode_from_path (inode_table_t *itable, const char *path)
if (parent)
inode_unref (parent);
- if (pathname)
- GF_FREE (pathname);
+ GF_FREE (pathname);
out:
return inode;
@@ -1174,45 +1456,59 @@ out:
int
-__inode_ctx_put2 (inode_t *inode, xlator_t *xlator, uint64_t value1,
- uint64_t value2)
+__inode_ctx_set2 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p,
+ uint64_t *value2_p)
{
int ret = 0;
int index = 0;
- int put_idx = -1;
+ int set_idx = -1;
if (!inode || !xlator)
return -1;
- for (index = 0; index < xlator->graph->xl_count; index++) {
+ for (index = 0; index < inode->table->ctxcount; index++) {
if (!inode->_ctx[index].xl_key) {
- if (put_idx == -1)
- put_idx = index;
+ if (set_idx == -1)
+ set_idx = index;
/* dont break, to check if key already exists
further on */
}
if (inode->_ctx[index].xl_key == xlator) {
- put_idx = index;
+ set_idx = index;
break;
}
}
- if (put_idx == -1) {
+ if (set_idx == -1) {
ret = -1;
goto out;;
}
- inode->_ctx[put_idx].xl_key = xlator;
- inode->_ctx[put_idx].value1 = value1;
- inode->_ctx[put_idx].value2 = value2;
+ inode->_ctx[set_idx].xl_key = xlator;
+ if (value1_p)
+ inode->_ctx[set_idx].value1 = *value1_p;
+ if (value2_p)
+ inode->_ctx[set_idx].value2 = *value2_p;
out:
return ret;
}
+int
+__inode_ctx_set0 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p)
+{
+ return __inode_ctx_set2 (inode, xlator, value1_p, NULL);
+}
int
-inode_ctx_put2 (inode_t *inode, xlator_t *xlator, uint64_t value1,
- uint64_t value2)
+__inode_ctx_set1 (inode_t *inode, xlator_t *xlator, uint64_t *value2_p)
+{
+ return __inode_ctx_set2 (inode, xlator, NULL, value2_p);
+}
+
+
+int
+inode_ctx_set2 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p,
+ uint64_t *value2_p)
{
int ret = 0;
@@ -1221,7 +1517,40 @@ inode_ctx_put2 (inode_t *inode, xlator_t *xlator, uint64_t value1,
LOCK (&inode->lock);
{
- ret = __inode_ctx_put2 (inode, xlator, value1, value2);
+ ret = __inode_ctx_set2 (inode, xlator, value1_p, value2_p);
+ }
+ UNLOCK (&inode->lock);
+
+ return ret;
+}
+
+int
+inode_ctx_set1 (inode_t *inode, xlator_t *xlator, uint64_t *value2_p)
+{
+ int ret = 0;
+
+ if (!inode || !xlator)
+ return -1;
+
+ LOCK (&inode->lock);
+ {
+ ret = __inode_ctx_set1 (inode, xlator, value2_p);
+ }
+ UNLOCK (&inode->lock);
+
+ return ret;
+}
+int
+inode_ctx_set0 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p)
+{
+ int ret = 0;
+
+ if (!inode || !xlator)
+ return -1;
+
+ LOCK (&inode->lock);
+ {
+ ret = __inode_ctx_set0 (inode, xlator, value1_p);
}
UNLOCK (&inode->lock);
@@ -1234,28 +1563,58 @@ __inode_ctx_get2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
uint64_t *value2)
{
int index = 0;
- int ret = 0;
+ int ret = -1;
if (!inode || !xlator)
- return -1;
+ goto out;
- for (index = 0; index < xlator->graph->xl_count; index++) {
+ for (index = 0; index < inode->table->ctxcount; index++) {
if (inode->_ctx[index].xl_key == xlator)
break;
}
- if (index == xlator->graph->xl_count) {
- ret = -1;
+ if (index == inode->table->ctxcount)
goto out;
+
+ if (inode->_ctx[index].value1) {
+ if (value1)
+ *value1 = inode->_ctx[index].value1;
+ ret = 0;
}
+ if (inode->_ctx[index].value2) {
+ if (value2)
+ *value2 = inode->_ctx[index].value2;
+ ret = 0;
+ }
+out:
+ return ret;
+}
- if (value1)
- *value1 = inode->_ctx[index].value1;
- if (value2)
- *value2 = inode->_ctx[index].value2;
-out:
+int
+__inode_ctx_get0 (inode_t *inode, xlator_t *xlator, uint64_t *value1)
+{
+ uint64_t tmp_value = 0;
+ int ret = 0;
+
+ ret = __inode_ctx_get2 (inode, xlator, &tmp_value, NULL);
+ if (!ret)
+ *value1 = tmp_value;
+
+ return ret;
+}
+
+int
+__inode_ctx_get1 (inode_t *inode, xlator_t *xlator, uint64_t *value2)
+{
+ uint64_t tmp_value = 0;
+ int ret = 0;
+
+ ret = __inode_ctx_get2 (inode, xlator, NULL, &tmp_value);
+ if (!ret)
+ *value2 = tmp_value;
+
return ret;
}
@@ -1278,6 +1637,40 @@ inode_ctx_get2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
return ret;
}
+int
+inode_ctx_get1 (inode_t *inode, xlator_t *xlator, uint64_t *value2)
+{
+ int ret = 0;
+
+ if (!inode || !xlator)
+ return -1;
+
+ LOCK (&inode->lock);
+ {
+ ret = __inode_ctx_get1 (inode, xlator, value2);
+ }
+ UNLOCK (&inode->lock);
+
+ return ret;
+}
+
+int
+inode_ctx_get0 (inode_t *inode, xlator_t *xlator, uint64_t *value1)
+{
+ int ret = 0;
+
+ if (!inode || !xlator)
+ return -1;
+
+ LOCK (&inode->lock);
+ {
+ ret = __inode_ctx_get0 (inode, xlator, value1);
+ }
+ UNLOCK (&inode->lock);
+
+ return ret;
+}
+
int
inode_ctx_del2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
@@ -1291,19 +1684,20 @@ inode_ctx_del2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
LOCK (&inode->lock);
{
- for (index = 0; index < xlator->graph->xl_count; index++) {
+ for (index = 0; index < inode->table->ctxcount;
+ index++) {
if (inode->_ctx[index].xl_key == xlator)
break;
}
- if (index == xlator->graph->xl_count) {
+ if (index == inode->table->ctxcount) {
ret = -1;
goto unlock;
}
- if (value1)
+ if (inode->_ctx[index].value1 && value1)
*value1 = inode->_ctx[index].value1;
- if (value2)
+ if (inode->_ctx[index].value2 && value2)
*value2 = inode->_ctx[index].value2;
inode->_ctx[index].key = 0;
@@ -1316,56 +1710,106 @@ unlock:
return ret;
}
-
-int
-__inode_ctx_put (inode_t *inode, xlator_t *key, uint64_t value)
+/* function behavior:
+ - if value1 is set, value1 in ctx is reset to 0 with current value passed
+ back in value1 address.
+ - if value2 is set, value2 in ctx is reset to 0 with current value passed
+ back in value2 address.
+ - if both are set, both fields are reset.
+*/
+static int
+__inode_ctx_reset2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
+ uint64_t *value2)
{
- return __inode_ctx_put2 (inode, key, value, 0);
-}
+ int index = 0;
+ int ret = 0;
+ if (!inode || !xlator)
+ return -1;
-int
-inode_ctx_put (inode_t *inode, xlator_t *key, uint64_t value)
-{
- return inode_ctx_put2 (inode, key, value, 0);
-}
+ LOCK (&inode->lock);
+ {
+ for (index = 0; index < inode->table->ctxcount;
+ index++) {
+ if (inode->_ctx[index].xl_key == xlator)
+ break;
+ }
+ if (index == inode->table->ctxcount) {
+ ret = -1;
+ goto unlock;
+ }
+
+ if (inode->_ctx[index].value1 && value1) {
+ *value1 = inode->_ctx[index].value1;
+ inode->_ctx[index].value1 = 0;
+ }
+ if (inode->_ctx[index].value2 && value2) {
+ *value2 = inode->_ctx[index].value2;
+ inode->_ctx[index].value2 = 0;
+ }
+ }
+unlock:
+ UNLOCK (&inode->lock);
+
+ return ret;
+}
int
-__inode_ctx_get (inode_t *inode, xlator_t *key, uint64_t *value)
+inode_ctx_reset2 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p,
+ uint64_t *value2_p)
{
- return __inode_ctx_get2 (inode, key, value, 0);
-}
+ uint64_t tmp_value1 = 0;
+ uint64_t tmp_value2 = 0;
+ int ret = 0;
+ ret = __inode_ctx_reset2 (inode, xlator, &tmp_value1, &tmp_value2);
+ if (!ret) {
+ if (value1_p)
+ *value1_p = tmp_value1;
+ if (value2_p)
+ *value2_p = tmp_value2;
+ }
+ return ret;
+}
int
-inode_ctx_get (inode_t *inode, xlator_t *key, uint64_t *value)
+inode_ctx_reset1 (inode_t *inode, xlator_t *xlator, uint64_t *value2_p)
{
- return inode_ctx_get2 (inode, key, value, 0);
-}
+ uint64_t tmp_value2 = 0;
+ int ret = 0;
+ ret = __inode_ctx_reset2 (inode, xlator, NULL, &tmp_value2);
+
+ if (!ret && value2_p)
+ *value2_p = tmp_value2;
+
+ return ret;
+}
int
-inode_ctx_del (inode_t *inode, xlator_t *key, uint64_t *value)
+inode_ctx_reset0 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p)
{
- return inode_ctx_del2 (inode, key, value, 0);
+ uint64_t tmp_value1 = 0;
+ int ret = 0;
+
+ ret = __inode_ctx_reset2 (inode, xlator, &tmp_value1, NULL);
+
+ if (!ret && value1_p)
+ *value1_p = tmp_value1;
+
+ return ret;
}
void
inode_dump (inode_t *inode, char *prefix)
{
- char key[GF_DUMP_MAX_BUF_LEN];
int ret = -1;
xlator_t *xl = NULL;
int i = 0;
- char uuidbuf[256];
fd_t *fd = NULL;
struct _inode_ctx *inode_ctx = NULL;
- struct fd_wrapper {
- fd_t *fd;
- struct list_head next;
- } *fd_wrapper, *tmp;
struct list_head fd_list;
if (!inode)
@@ -1374,62 +1818,43 @@ inode_dump (inode_t *inode, char *prefix)
INIT_LIST_HEAD (&fd_list);
ret = TRY_LOCK(&inode->lock);
-
if (ret != 0) {
- gf_log ("", GF_LOG_WARNING, "Unable to dump inode"
- " errno: %d", errno);
return;
}
{
- uuid_unparse (inode->gfid, uuidbuf);
- gf_proc_dump_build_key(key, prefix, "gfid");
- gf_proc_dump_write(key, "%s", uuidbuf);
- gf_proc_dump_build_key(key, prefix, "nlookup");
- gf_proc_dump_write(key, "%ld", inode->nlookup);
- gf_proc_dump_build_key(key, prefix, "ref");
- gf_proc_dump_write(key, "%u", inode->ref);
- gf_proc_dump_build_key(key, prefix, "ino");
- gf_proc_dump_write(key, "%ld", inode->ino);
- gf_proc_dump_build_key(key, prefix, "ia_type");
- gf_proc_dump_write(key, "%d", inode->ia_type);
+ gf_proc_dump_write("gfid", "%s", uuid_utoa (inode->gfid));
+ gf_proc_dump_write("nlookup", "%ld", inode->nlookup);
+ gf_proc_dump_write("fd-count", "%u", inode->fd_count);
+ gf_proc_dump_write("ref", "%u", inode->ref);
+ gf_proc_dump_write("ia_type", "%d", inode->ia_type);
if (inode->_ctx) {
- inode_ctx = GF_CALLOC (inode->table->xl->graph->xl_count,
+ inode_ctx = GF_CALLOC (inode->table->ctxcount,
sizeof (*inode_ctx),
gf_common_mt_inode_ctx);
if (inode_ctx == NULL) {
- gf_log ("", GF_LOG_ERROR, "out of memory");
goto unlock;
}
- for (i = 0; i < inode->table->xl->graph->xl_count; i++) {
+ for (i = 0; i < inode->table->ctxcount;
+ i++) {
inode_ctx[i] = inode->_ctx[i];
}
}
- if (list_empty (&inode->fd_list)) {
- goto unlock;
- }
-
- list_for_each_entry (fd, &inode->fd_list, inode_list) {
- fd_wrapper = GF_CALLOC (1, sizeof (*fd_wrapper),
- gf_common_mt_char);
- if (fd_wrapper == NULL) {
- gf_log ("", GF_LOG_ERROR, "out of memory");
- goto unlock;
- }
+ if (dump_options.xl_options.dump_fdctx != _gf_true)
+ goto unlock;
- INIT_LIST_HEAD (&fd_wrapper->next);
- list_add_tail (&fd_wrapper->next, &fd_list);
- fd_wrapper->fd = _fd_ref (fd);
+ list_for_each_entry (fd, &inode->fd_list, inode_list) {
+ fd_ctx_dump (fd, prefix);
}
}
unlock:
UNLOCK(&inode->lock);
if (inode_ctx && (dump_options.xl_options.dump_inodectx == _gf_true)) {
- for (i = 0; i < inode->table->xl->graph->xl_count; i++) {
+ for (i = 0; i < inode->table->ctxcount; i++) {
if (inode_ctx[i].xl_key) {
xl = (xlator_t *)(long)inode_ctx[i].xl_key;
if (xl->dumpops && xl->dumpops->inodectx)
@@ -1438,21 +1863,7 @@ unlock:
}
}
- if (!list_empty (&fd_list)
- && (dump_options.xl_options.dump_fdctx == _gf_true)) {
- list_for_each_entry_safe (fd_wrapper, tmp, &fd_list,
- next) {
- list_del (&fd_wrapper->next);
- fd_ctx_dump (fd_wrapper->fd, prefix);
-
- fd_unref (fd_wrapper->fd);
- GF_FREE (fd_wrapper);
- }
- }
-
- if (inode_ctx != NULL) {
- GF_FREE (inode_ctx);
- }
+ GF_FREE (inode_ctx);
return;
}
@@ -1471,8 +1882,6 @@ inode_table_dump (inode_table_t *itable, char *prefix)
ret = pthread_mutex_trylock(&itable->lock);
if (ret != 0) {
- gf_log("", GF_LOG_WARNING, "Unable to dump inode table"
- " errno: %d", errno);
return;
}
@@ -1496,3 +1905,99 @@ inode_table_dump (inode_table_t *itable, char *prefix)
pthread_mutex_unlock(&itable->lock);
}
+
+void
+inode_dump_to_dict (inode_t *inode, char *prefix, dict_t *dict)
+{
+ int ret = -1;
+ char key[GF_DUMP_MAX_BUF_LEN] = {0,};
+
+ ret = TRY_LOCK (&inode->lock);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.gfid", prefix);
+ ret = dict_set_dynstr (dict, key, gf_strdup (uuid_utoa (inode->gfid)));
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.nlookup", prefix);
+ ret = dict_set_uint64 (dict, key, inode->nlookup);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.ref", prefix);
+ ret = dict_set_uint32 (dict, key, inode->ref);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.ia_type", prefix);
+ ret = dict_set_int32 (dict, key, inode->ia_type);
+
+out:
+ UNLOCK (&inode->lock);
+ return;
+}
+
+void
+inode_table_dump_to_dict (inode_table_t *itable, char *prefix, dict_t *dict)
+{
+ char key[GF_DUMP_MAX_BUF_LEN] = {0,};
+ int ret = 0;
+ inode_t *inode = NULL;
+ int count = 0;
+
+ ret = pthread_mutex_trylock (&itable->lock);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.itable.active_size", prefix);
+ ret = dict_set_uint32 (dict, key, itable->active_size);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.itable.lru_size", prefix);
+ ret = dict_set_uint32 (dict, key, itable->lru_size);
+ if (ret)
+ goto out;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.itable.purge_size", prefix);
+ ret = dict_set_uint32 (dict, key, itable->purge_size);
+ if (ret)
+ goto out;
+
+ list_for_each_entry (inode, &itable->active, list) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.itable.active%d", prefix,
+ count++);
+ inode_dump_to_dict (inode, key, dict);
+ }
+ count = 0;
+
+ list_for_each_entry (inode, &itable->lru, list) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.itable.lru%d", prefix,
+ count++);
+ inode_dump_to_dict (inode, key, dict);
+ }
+ count = 0;
+
+ list_for_each_entry (inode, &itable->purge, list) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.itable.purge%d", prefix,
+ count++);
+ inode_dump_to_dict (inode, key, dict);
+ }
+
+out:
+ pthread_mutex_unlock (&itable->lock);
+
+ return;
+}
diff --git a/libglusterfs/src/inode.h b/libglusterfs/src/inode.h
index de423d888..a88976265 100644
--- a/libglusterfs/src/inode.h
+++ b/libglusterfs/src/inode.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
#ifndef _INODE_H
@@ -28,6 +19,8 @@
#include <stdint.h>
#include <sys/types.h>
+#define DEFAULT_INODE_MEMPOOL_ENTRIES 32 * 1024
+#define INODE_PATH_FMT "<gfid:%s>"
struct _inode_table;
typedef struct _inode_table inode_table_t;
@@ -63,6 +56,7 @@ struct _inode_table {
struct mem_pool *inode_pool; /* memory pool for inodes */
struct mem_pool *dentry_pool; /* memory pool for dentrys */
struct mem_pool *fd_mem_pool; /* memory pool for fd_t */
+ int ctxcount; /* number of slots in inode->ctx */
};
@@ -79,10 +73,12 @@ struct _inode_ctx {
uint64_t key;
xlator_t *xl_key;
};
+ /* if value1 is 0, then field is not set.. */
union {
uint64_t value1;
void *ptr1;
};
+ /* if value2 is 0, then field is not set.. */
union {
uint64_t value2;
void *ptr2;
@@ -94,8 +90,8 @@ struct _inode {
uuid_t gfid;
gf_lock_t lock;
uint64_t nlookup;
+ uint32_t fd_count; /* Open fd count */
uint32_t ref; /* reference count on this inode */
- ino_t ino; /* inode number in the storage (persistent) */
ia_type_t ia_type; /* what kind of file */
struct list_head fd_list; /* list of open files on this inode */
struct list_head dentry_list; /* list of directory entries for this inode */
@@ -106,6 +102,10 @@ struct _inode {
};
+#define UUID0_STR "00000000-0000-0000-0000-000000000000"
+#define GFID_STR_PFX "<gfid:" UUID0_STR ">"
+#define GFID_STR_PFX_LEN (sizeof (GFID_STR_PFX) - 1)
+
inode_table_t *
inode_table_new (size_t lru_limit, xlator_t *xl);
@@ -120,7 +120,7 @@ void
inode_unlink (inode_t *inode, inode_t *parent, const char *name);
inode_t *
-inode_parent (inode_t *inode, ino_t par, const char *name);
+inode_parent (inode_t *inode, uuid_t pargfid, const char *name);
inode_t *
inode_ref (inode_t *inode);
@@ -135,6 +135,9 @@ int
inode_forget (inode_t *inode, uint64_t nlookup);
int
+inode_invalidate(inode_t *inode);
+
+int
inode_rename (inode_table_t *table, inode_t *olddir, const char *oldname,
inode_t *newdir, const char *newname,
inode_t *inode, struct iatt *stbuf);
@@ -142,8 +145,9 @@ inode_rename (inode_table_t *table, inode_t *olddir, const char *oldname,
inode_t *
inode_grep (inode_table_t *table, inode_t *parent, const char *name);
-inode_t *
-inode_get (inode_table_t *table, ino_t ino, uint64_t gen);
+int
+inode_grep_for_gfid (inode_table_t *table, inode_t *parent, const char *name,
+ uuid_t gfid, ia_type_t *type);
inode_t *
inode_find (inode_table_t *table, uuid_t gfid);
@@ -151,34 +155,97 @@ inode_find (inode_table_t *table, uuid_t gfid);
int
inode_path (inode_t *inode, const char *name, char **bufp);
+int
+__inode_path (inode_t *inode, const char *name, char **bufp);
+
inode_t *
inode_from_path (inode_table_t *table, const char *path);
+inode_t *
+inode_resolve (inode_table_t *table, char *path);
+
+/* deal with inode ctx's both values */
+
int
-__inode_ctx_put (inode_t *inode, xlator_t *xlator, uint64_t value);
+inode_ctx_set2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
+ uint64_t *value2);
+int
+__inode_ctx_set2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
+ uint64_t *value2);
int
-inode_ctx_put (inode_t *inode, xlator_t *xlator, uint64_t value);
+inode_ctx_get2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
+ uint64_t *value2);
+int
+__inode_ctx_get2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
+ uint64_t *value2);
int
-__inode_ctx_get (inode_t *inode, xlator_t *xlator, uint64_t *value);
+inode_ctx_del2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
+ uint64_t *value2);
int
-inode_ctx_get (inode_t *inode, xlator_t *xlator, uint64_t *value);
+inode_ctx_reset2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
+ uint64_t *value2);
+
+/* deal with inode ctx's 1st value */
int
-inode_ctx_del (inode_t *inode, xlator_t *xlator, uint64_t *value);
+inode_ctx_set0 (inode_t *inode, xlator_t *xlator, uint64_t *value1);
int
-inode_ctx_put2 (inode_t *inode, xlator_t *xlator, uint64_t value1,
- uint64_t value2);
+__inode_ctx_set0 (inode_t *inode, xlator_t *xlator, uint64_t *value1);
int
-inode_ctx_get2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
- uint64_t *value2);
+inode_ctx_get0 (inode_t *inode, xlator_t *xlator, uint64_t *value1);
+int
+__inode_ctx_get0 (inode_t *inode, xlator_t *xlator, uint64_t *value1);
int
-inode_ctx_del2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
- uint64_t *value2);
+inode_ctx_reset0 (inode_t *inode, xlator_t *xlator, uint64_t *value1);
+
+/* deal with inode ctx's 2st value */
+
+int
+inode_ctx_set1 (inode_t *inode, xlator_t *xlator, uint64_t *value2);
+
+int
+__inode_ctx_set1 (inode_t *inode, xlator_t *xlator, uint64_t *value2);
+
+int
+inode_ctx_get1 (inode_t *inode, xlator_t *xlator, uint64_t *value2);
+int
+__inode_ctx_get1 (inode_t *inode, xlator_t *xlator, uint64_t *value2);
+
+int
+inode_ctx_reset1 (inode_t *inode, xlator_t *xlator, uint64_t *value2);
+
+
+static inline int
+__inode_ctx_put(inode_t *inode, xlator_t *this, uint64_t v)
+{
+ return __inode_ctx_set0 (inode, this, &v);
+}
+
+static inline int
+inode_ctx_put(inode_t *inode, xlator_t *this, uint64_t v)
+{
+ return inode_ctx_set0 (inode, this, &v);
+}
+
+#define __inode_ctx_set(i,x,v_p) __inode_ctx_set0(i,x,v_p)
+
+#define inode_ctx_set(i,x,v_p) inode_ctx_set0(i,x,v_p)
+
+#define inode_ctx_reset(i,x,v) inode_ctx_reset0(i,x,v)
+
+#define __inode_ctx_get(i,x,v) __inode_ctx_get0(i,x,v)
+
+#define inode_ctx_get(i,x,v) inode_ctx_get0(i,x,v)
+
+#define inode_ctx_del(i,x,v) inode_ctx_del2(i,x,v,0)
+
+gf_boolean_t
+__is_root_gfid (uuid_t gfid);
#endif /* _INODE_H */
diff --git a/libglusterfs/src/iobuf.c b/libglusterfs/src/iobuf.c
index a8bd192cf..a89e96267 100644
--- a/libglusterfs/src/iobuf.c
+++ b/libglusterfs/src/iobuf.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
@@ -27,22 +18,70 @@
TODO: implement destroy margins and prefetching of arenas
*/
+#define IOBUF_ARENA_MAX_INDEX (sizeof (gf_iobuf_init_config) / \
+ (sizeof (struct iobuf_init_config)))
+
+/* Make sure this array is sorted based on pagesize */
+struct iobuf_init_config gf_iobuf_init_config[] = {
+ /* { pagesize, num_pages }, */
+ {128, 1024},
+ {512, 512},
+ {2 * 1024, 512},
+ {8 * 1024, 128},
+ {32 * 1024, 64},
+ {128 * 1024, 32},
+ {256 * 1024, 8},
+ {1 * 1024 * 1024, 2},
+};
+
+int
+gf_iobuf_get_arena_index (size_t page_size)
+{
+ int i = -1;
+
+ for (i = 0; i < IOBUF_ARENA_MAX_INDEX; i++) {
+ if (page_size <= gf_iobuf_init_config[i].pagesize)
+ break;
+ }
+
+ if (i >= IOBUF_ARENA_MAX_INDEX)
+ i = -1;
+
+ return i;
+}
+
+size_t
+gf_iobuf_get_pagesize (size_t page_size)
+{
+ int i = 0;
+ size_t size = 0;
+
+ for (i = 0; i < IOBUF_ARENA_MAX_INDEX; i++) {
+ size = gf_iobuf_init_config[i].pagesize;
+ if (page_size <= size)
+ break;
+ }
+
+ if (i >= IOBUF_ARENA_MAX_INDEX)
+ size = -1;
+
+ return size;
+}
+
void
__iobuf_arena_init_iobufs (struct iobuf_arena *iobuf_arena)
{
- size_t arena_size = 0;
- size_t page_size = 0;
int iobuf_cnt = 0;
struct iobuf *iobuf = NULL;
int offset = 0;
int i = 0;
- arena_size = iobuf_arena->iobuf_pool->arena_size;
- page_size = iobuf_arena->iobuf_pool->page_size;
- iobuf_cnt = arena_size / page_size;
+ GF_VALIDATE_OR_GOTO ("iobuf", iobuf_arena, out);
+
+ iobuf_cnt = iobuf_arena->page_count;
iobuf_arena->iobufs = GF_CALLOC (sizeof (*iobuf), iobuf_cnt,
- gf_common_mt_iobuf);
+ gf_common_mt_iobuf);
if (!iobuf_arena->iobufs)
return;
@@ -58,27 +97,30 @@ __iobuf_arena_init_iobufs (struct iobuf_arena *iobuf_arena)
list_add (&iobuf->list, &iobuf_arena->passive.list);
iobuf_arena->passive_cnt++;
- offset += page_size;
+ offset += iobuf_arena->page_size;
iobuf++;
}
+
+out:
+ return;
}
void
__iobuf_arena_destroy_iobufs (struct iobuf_arena *iobuf_arena)
{
- size_t arena_size = 0;
- size_t page_size = 0;
int iobuf_cnt = 0;
struct iobuf *iobuf = NULL;
int i = 0;
- arena_size = iobuf_arena->iobuf_pool->arena_size;
- page_size = iobuf_arena->iobuf_pool->page_size;
- iobuf_cnt = arena_size / page_size;
+ GF_VALIDATE_OR_GOTO ("iobuf", iobuf_arena, out);
- if (!iobuf_arena->iobufs)
+ iobuf_cnt = iobuf_arena->page_count;
+
+ if (!iobuf_arena->iobufs) {
+ gf_log_callingfn (THIS->name, GF_LOG_ERROR, "iobufs not found");
return;
+ }
iobuf = iobuf_arena->iobufs;
for (i = 0; i < iobuf_cnt; i++) {
@@ -89,37 +131,40 @@ __iobuf_arena_destroy_iobufs (struct iobuf_arena *iobuf_arena)
}
GF_FREE (iobuf_arena->iobufs);
+
+out:
+ return;
}
void
__iobuf_arena_destroy (struct iobuf_arena *iobuf_arena)
{
- struct iobuf_pool *iobuf_pool = NULL;
-
- if (!iobuf_arena)
- return;
-
- iobuf_pool = iobuf_arena->iobuf_pool;
+ GF_VALIDATE_OR_GOTO ("iobuf", iobuf_arena, out);
__iobuf_arena_destroy_iobufs (iobuf_arena);
if (iobuf_arena->mem_base
&& iobuf_arena->mem_base != MAP_FAILED)
- munmap (iobuf_arena->mem_base, iobuf_pool->arena_size);
+ munmap (iobuf_arena->mem_base, iobuf_arena->arena_size);
GF_FREE (iobuf_arena);
+out:
+ return;
}
struct iobuf_arena *
-__iobuf_arena_alloc (struct iobuf_pool *iobuf_pool)
+__iobuf_arena_alloc (struct iobuf_pool *iobuf_pool, size_t page_size,
+ int32_t num_iobufs)
{
struct iobuf_arena *iobuf_arena = NULL;
- size_t arena_size = 0;
+ size_t rounded_size = 0;
+
+ GF_VALIDATE_OR_GOTO ("iobuf", iobuf_pool, out);
iobuf_arena = GF_CALLOC (sizeof (*iobuf_arena), 1,
- gf_common_mt_iobuf_arena);
+ gf_common_mt_iobuf_arena);
if (!iobuf_arena)
goto err;
@@ -128,15 +173,26 @@ __iobuf_arena_alloc (struct iobuf_pool *iobuf_pool)
INIT_LIST_HEAD (&iobuf_arena->passive.list);
iobuf_arena->iobuf_pool = iobuf_pool;
- arena_size = iobuf_pool->arena_size;
- iobuf_arena->mem_base = mmap (NULL, arena_size, PROT_READ|PROT_WRITE,
+ rounded_size = gf_iobuf_get_pagesize (page_size);
+
+ iobuf_arena->page_size = rounded_size;
+ iobuf_arena->page_count = num_iobufs;
+
+ iobuf_arena->arena_size = rounded_size * num_iobufs;
+
+ iobuf_arena->mem_base = mmap (NULL, iobuf_arena->arena_size,
+ PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
- if (iobuf_arena->mem_base == MAP_FAILED)
+ if (iobuf_arena->mem_base == MAP_FAILED) {
+ gf_log (THIS->name, GF_LOG_WARNING, "maping failed");
goto err;
+ }
__iobuf_arena_init_iobufs (iobuf_arena);
- if (!iobuf_arena->iobufs)
+ if (!iobuf_arena->iobufs) {
+ gf_log (THIS->name, GF_LOG_ERROR, "init failed");
goto err;
+ }
iobuf_pool->arena_cnt++;
@@ -144,56 +200,87 @@ __iobuf_arena_alloc (struct iobuf_pool *iobuf_pool)
err:
__iobuf_arena_destroy (iobuf_arena);
+
+out:
return NULL;
}
struct iobuf_arena *
-__iobuf_arena_unprune (struct iobuf_pool *iobuf_pool)
+__iobuf_arena_unprune (struct iobuf_pool *iobuf_pool, size_t page_size)
{
- struct iobuf_arena *iobuf_arena = NULL;
- struct iobuf_arena *tmp = NULL;
+ struct iobuf_arena *iobuf_arena = NULL;
+ struct iobuf_arena *tmp = NULL;
+ int index = 0;
+
+ GF_VALIDATE_OR_GOTO ("iobuf", iobuf_pool, out);
+
+ index = gf_iobuf_get_arena_index (page_size);
+ if (index == -1) {
+ gf_log ("iobuf", GF_LOG_ERROR, "page_size (%zu) of "
+ "iobufs in arena being added is greater than max "
+ "available", page_size);
+ return NULL;
+ }
- list_for_each_entry (tmp, &iobuf_pool->purge.list, list) {
+ list_for_each_entry (tmp, &iobuf_pool->purge[index], list) {
list_del_init (&tmp->list);
iobuf_arena = tmp;
break;
}
-
+out:
return iobuf_arena;
}
struct iobuf_arena *
-__iobuf_pool_add_arena (struct iobuf_pool *iobuf_pool)
+__iobuf_pool_add_arena (struct iobuf_pool *iobuf_pool, size_t page_size,
+ int32_t num_pages)
{
- struct iobuf_arena *iobuf_arena = NULL;
+ struct iobuf_arena *iobuf_arena = NULL;
+ int index = 0;
+
+ index = gf_iobuf_get_arena_index (page_size);
+ if (index == -1) {
+ gf_log ("iobuf", GF_LOG_ERROR, "page_size (%zu) of "
+ "iobufs in arena being added is greater than max "
+ "available", page_size);
+ return NULL;
+ }
- iobuf_arena = __iobuf_arena_unprune (iobuf_pool);
+ iobuf_arena = __iobuf_arena_unprune (iobuf_pool, page_size);
if (!iobuf_arena)
- iobuf_arena = __iobuf_arena_alloc (iobuf_pool);
+ iobuf_arena = __iobuf_arena_alloc (iobuf_pool, page_size,
+ num_pages);
- if (!iobuf_arena)
+ if (!iobuf_arena) {
+ gf_log (THIS->name, GF_LOG_WARNING, "arena not found");
return NULL;
+ }
- list_add_tail (&iobuf_arena->list, &iobuf_pool->arenas.list);
+ list_add_tail (&iobuf_arena->list, &iobuf_pool->arenas[index]);
return iobuf_arena;
}
struct iobuf_arena *
-iobuf_pool_add_arena (struct iobuf_pool *iobuf_pool)
+iobuf_pool_add_arena (struct iobuf_pool *iobuf_pool, size_t page_size,
+ int32_t num_pages)
{
struct iobuf_arena *iobuf_arena = NULL;
+ GF_VALIDATE_OR_GOTO ("iobuf", iobuf_pool, out);
+
pthread_mutex_lock (&iobuf_pool->mutex);
{
- iobuf_arena = __iobuf_pool_add_arena (iobuf_pool);
+ iobuf_arena = __iobuf_pool_add_arena (iobuf_pool, page_size,
+ num_pages);
}
pthread_mutex_unlock (&iobuf_pool->mutex);
+out:
return iobuf_arena;
}
@@ -202,92 +289,167 @@ void
iobuf_pool_destroy (struct iobuf_pool *iobuf_pool)
{
struct iobuf_arena *iobuf_arena = NULL;
- struct iobuf_arena *tmp = NULL;
-
- if (!iobuf_pool)
- return;
+ struct iobuf_arena *tmp = NULL;
+ int i = 0;
- list_for_each_entry_safe (iobuf_arena, tmp, &iobuf_pool->arenas.list,
- list) {
+ GF_VALIDATE_OR_GOTO ("iobuf", iobuf_pool, out);
- list_del_init (&iobuf_arena->list);
- iobuf_pool->arena_cnt--;
+ for (i = 0; i < IOBUF_ARENA_MAX_INDEX; i++) {
+ list_for_each_entry_safe (iobuf_arena, tmp,
+ &iobuf_pool->arenas[i], list) {
+ list_del_init (&iobuf_arena->list);
+ iobuf_pool->arena_cnt--;
+ __iobuf_arena_destroy (iobuf_arena);
+ }
- __iobuf_arena_destroy (iobuf_arena);
}
+
+out:
+ return;
}
+static void
+iobuf_create_stdalloc_arena (struct iobuf_pool *iobuf_pool)
+{
+ struct iobuf_arena *iobuf_arena = NULL;
+
+ /* No locking required here as its called only once during init */
+ iobuf_arena = GF_CALLOC (sizeof (*iobuf_arena), 1,
+ gf_common_mt_iobuf_arena);
+ if (!iobuf_arena)
+ goto err;
+
+ INIT_LIST_HEAD (&iobuf_arena->list);
+ INIT_LIST_HEAD (&iobuf_arena->active.list);
+ INIT_LIST_HEAD (&iobuf_arena->passive.list);
+
+ iobuf_arena->iobuf_pool = iobuf_pool;
+
+ iobuf_arena->page_size = 0x7fffffff;
+
+ list_add_tail (&iobuf_arena->list,
+ &iobuf_pool->arenas[IOBUF_ARENA_MAX_INDEX]);
+
+err:
+ return;
+}
struct iobuf_pool *
-iobuf_pool_new (size_t arena_size, size_t page_size)
+iobuf_pool_new (void)
{
struct iobuf_pool *iobuf_pool = NULL;
-
- if (arena_size < page_size)
- return NULL;
+ int i = 0;
+ size_t page_size = 0;
+ size_t arena_size = 0;
+ int32_t num_pages = 0;
iobuf_pool = GF_CALLOC (sizeof (*iobuf_pool), 1,
gf_common_mt_iobuf_pool);
if (!iobuf_pool)
- return NULL;
+ goto out;
pthread_mutex_init (&iobuf_pool->mutex, NULL);
- INIT_LIST_HEAD (&iobuf_pool->arenas.list);
- INIT_LIST_HEAD (&iobuf_pool->filled.list);
- INIT_LIST_HEAD (&iobuf_pool->purge.list);
+ for (i = 0; i <= IOBUF_ARENA_MAX_INDEX; i++) {
+ INIT_LIST_HEAD (&iobuf_pool->arenas[i]);
+ INIT_LIST_HEAD (&iobuf_pool->filled[i]);
+ INIT_LIST_HEAD (&iobuf_pool->purge[i]);
+ }
- iobuf_pool->arena_size = arena_size;
- iobuf_pool->page_size = page_size;
+ iobuf_pool->default_page_size = 128 * GF_UNIT_KB;
+
+ arena_size = 0;
+ for (i = 0; i < IOBUF_ARENA_MAX_INDEX; i++) {
+ page_size = gf_iobuf_init_config[i].pagesize;
+ num_pages = gf_iobuf_init_config[i].num_pages;
- iobuf_pool_add_arena (iobuf_pool);
+ iobuf_pool_add_arena (iobuf_pool, page_size, num_pages);
+
+ arena_size += page_size * num_pages;
+ }
+
+ /* Need an arena to handle all the bigger iobuf requests */
+ iobuf_create_stdalloc_arena (iobuf_pool);
+
+ iobuf_pool->arena_size = arena_size;
+out:
return iobuf_pool;
}
void
-__iobuf_pool_prune (struct iobuf_pool *iobuf_pool)
+__iobuf_arena_prune (struct iobuf_pool *iobuf_pool,
+ struct iobuf_arena *iobuf_arena, int index)
{
- struct iobuf_arena *iobuf_arena = NULL;
- struct iobuf_arena *tmp = NULL;
-
- if (list_empty (&iobuf_pool->arenas.list))
- /* buffering - preserve this one arena (if at all)
- for __iobuf_arena_unprune */
- return;
+ GF_VALIDATE_OR_GOTO ("iobuf", iobuf_pool, out);
+
+ /* code flow comes here only if the arena is in purge list and we can
+ * free the arena only if we have atleast one arena in 'arenas' list
+ * (ie, at least few iobufs free in arena), that way, there won't
+ * be spurious mmap/unmap of buffers
+ */
+ if (list_empty (&iobuf_pool->arenas[index]))
+ goto out;
- list_for_each_entry_safe (iobuf_arena, tmp, &iobuf_pool->purge.list,
- list) {
- if (iobuf_arena->active_cnt)
- continue;
+ /* All cases matched, destroy */
+ list_del_init (&iobuf_arena->list);
+ iobuf_pool->arena_cnt--;
- list_del_init (&iobuf_arena->list);
- iobuf_pool->arena_cnt--;
+ __iobuf_arena_destroy (iobuf_arena);
- __iobuf_arena_destroy (iobuf_arena);
- }
+out:
+ return;
}
void
iobuf_pool_prune (struct iobuf_pool *iobuf_pool)
{
+ struct iobuf_arena *iobuf_arena = NULL;
+ struct iobuf_arena *tmp = NULL;
+ int i = 0;
+
+ GF_VALIDATE_OR_GOTO ("iobuf", iobuf_pool, out);
+
pthread_mutex_lock (&iobuf_pool->mutex);
{
- __iobuf_pool_prune (iobuf_pool);
+ for (i = 0; i < IOBUF_ARENA_MAX_INDEX; i++) {
+ if (list_empty (&iobuf_pool->arenas[i])) {
+ continue;
+ }
+
+ list_for_each_entry_safe (iobuf_arena, tmp,
+ &iobuf_pool->purge[i], list) {
+ __iobuf_arena_prune (iobuf_pool, iobuf_arena, i);
+ }
+ }
}
pthread_mutex_unlock (&iobuf_pool->mutex);
+
+out:
+ return;
}
struct iobuf_arena *
-__iobuf_select_arena (struct iobuf_pool *iobuf_pool)
+__iobuf_select_arena (struct iobuf_pool *iobuf_pool, size_t page_size)
{
- struct iobuf_arena *iobuf_arena = NULL;
- struct iobuf_arena *trav = NULL;
+ struct iobuf_arena *iobuf_arena = NULL;
+ struct iobuf_arena *trav = NULL;
+ int index = 0;
+
+ GF_VALIDATE_OR_GOTO ("iobuf", iobuf_pool, out);
+
+ index = gf_iobuf_get_arena_index (page_size);
+ if (index == -1) {
+ gf_log ("iobuf", GF_LOG_ERROR, "page_size (%zu) of "
+ "iobufs in arena being added is greater than max "
+ "available", page_size);
+ return NULL;
+ }
/* look for unused iobuf from the head-most arena */
- list_for_each_entry (trav, &iobuf_pool->arenas.list, list) {
+ list_for_each_entry (trav, &iobuf_pool->arenas[index], list) {
if (trav->passive_cnt) {
iobuf_arena = trav;
break;
@@ -295,10 +457,12 @@ __iobuf_select_arena (struct iobuf_pool *iobuf_pool)
}
if (!iobuf_arena) {
- /* all arenas were full */
- iobuf_arena = __iobuf_pool_add_arena (iobuf_pool);
+ /* all arenas were full, find the right count to add */
+ iobuf_arena = __iobuf_pool_add_arena (iobuf_pool, page_size,
+ gf_iobuf_init_config[index].num_pages);
}
+out:
return iobuf_arena;
}
@@ -320,12 +484,14 @@ __iobuf_unref (struct iobuf *iobuf)
return iobuf;
}
-
struct iobuf *
-__iobuf_get (struct iobuf_arena *iobuf_arena)
+__iobuf_get (struct iobuf_arena *iobuf_arena, size_t page_size)
{
- struct iobuf *iobuf = NULL;
- struct iobuf_pool *iobuf_pool = NULL;
+ struct iobuf *iobuf = NULL;
+ struct iobuf_pool *iobuf_pool = NULL;
+ int index = 0;
+
+ GF_VALIDATE_OR_GOTO ("iobuf", iobuf_arena, out);
iobuf_pool = iobuf_arena->iobuf_pool;
@@ -338,51 +504,178 @@ __iobuf_get (struct iobuf_arena *iobuf_arena)
list_add (&iobuf->list, &iobuf_arena->active.list);
iobuf_arena->active_cnt++;
+ /* no resetting requied for this element */
+ iobuf_arena->alloc_cnt++;
+
+ if (iobuf_arena->max_active < iobuf_arena->active_cnt)
+ iobuf_arena->max_active = iobuf_arena->active_cnt;
+
if (iobuf_arena->passive_cnt == 0) {
+ index = gf_iobuf_get_arena_index (page_size);
+ if (index == -1) {
+ gf_log ("iobuf", GF_LOG_ERROR, "page_size (%zu) of "
+ "iobufs in arena being added is greater "
+ "than max available", page_size);
+ goto out;
+ }
+
list_del (&iobuf_arena->list);
- list_add (&iobuf_arena->list, &iobuf_pool->filled.list);
+ list_add (&iobuf_arena->list, &iobuf_pool->filled[index]);
}
+out:
return iobuf;
}
-
struct iobuf *
-iobuf_get (struct iobuf_pool *iobuf_pool)
+iobuf_get_from_stdalloc (struct iobuf_pool *iobuf_pool, size_t page_size)
{
- struct iobuf *iobuf = NULL;
+ struct iobuf *iobuf = NULL;
struct iobuf_arena *iobuf_arena = NULL;
+ struct iobuf_arena *trav = NULL;
+ int ret = -1;
+
+ /* The first arena in the 'MAX-INDEX' will always be used for misc */
+ list_for_each_entry (trav, &iobuf_pool->arenas[IOBUF_ARENA_MAX_INDEX],
+ list) {
+ iobuf_arena = trav;
+ break;
+ }
+
+ iobuf = GF_CALLOC (1, sizeof (*iobuf), gf_common_mt_iobuf);
+ if (!iobuf)
+ goto out;
+
+ /* 4096 is the alignment */
+ iobuf->free_ptr = GF_CALLOC (1, ((page_size + GF_IOBUF_ALIGN_SIZE) - 1),
+ gf_common_mt_char);
+ if (!iobuf->free_ptr)
+ goto out;
+
+ iobuf->ptr = GF_ALIGN_BUF (iobuf->free_ptr, GF_IOBUF_ALIGN_SIZE);
+ iobuf->iobuf_arena = iobuf_arena;
+ LOCK_INIT (&iobuf->lock);
+
+ /* Hold a ref because you are allocating and using it */
+ iobuf->ref = 1;
+
+ ret = 0;
+out:
+ if (ret && iobuf) {
+ GF_FREE (iobuf->free_ptr);
+ GF_FREE (iobuf);
+ iobuf = NULL;
+ }
+
+ return iobuf;
+}
+
+
+struct iobuf *
+iobuf_get2 (struct iobuf_pool *iobuf_pool, size_t page_size)
+{
+ struct iobuf *iobuf = NULL;
+ struct iobuf_arena *iobuf_arena = NULL;
+ size_t rounded_size = 0;
+
+ if (page_size == 0) {
+ page_size = iobuf_pool->default_page_size;
+ }
+
+ rounded_size = gf_iobuf_get_pagesize (page_size);
+ if (rounded_size == -1) {
+ /* make sure to provide the requested buffer with standard
+ memory allocations */
+ iobuf = iobuf_get_from_stdalloc (iobuf_pool, page_size);
+
+ gf_log ("iobuf", GF_LOG_DEBUG, "request for iobuf of size %zu "
+ "is serviced using standard calloc() (%p) as it "
+ "exceeds the maximum available buffer size",
+ page_size, iobuf);
+
+ iobuf_pool->request_misses++;
+ return iobuf;
+ }
pthread_mutex_lock (&iobuf_pool->mutex);
{
/* most eligible arena for picking an iobuf */
- iobuf_arena = __iobuf_select_arena (iobuf_pool);
+ iobuf_arena = __iobuf_select_arena (iobuf_pool, rounded_size);
if (!iobuf_arena)
goto unlock;
- iobuf = __iobuf_get (iobuf_arena);
+ iobuf = __iobuf_get (iobuf_arena, rounded_size);
if (!iobuf)
goto unlock;
__iobuf_ref (iobuf);
- }
+ }
unlock:
pthread_mutex_unlock (&iobuf_pool->mutex);
return iobuf;
}
+struct iobuf *
+iobuf_get (struct iobuf_pool *iobuf_pool)
+{
+ struct iobuf *iobuf = NULL;
+ struct iobuf_arena *iobuf_arena = NULL;
+
+ GF_VALIDATE_OR_GOTO ("iobuf", iobuf_pool, out);
+
+ pthread_mutex_lock (&iobuf_pool->mutex);
+ {
+ /* most eligible arena for picking an iobuf */
+ iobuf_arena = __iobuf_select_arena (iobuf_pool,
+ iobuf_pool->default_page_size);
+ if (!iobuf_arena) {
+ gf_log (THIS->name, GF_LOG_WARNING, "arena not found");
+ goto unlock;
+ }
+
+ iobuf = __iobuf_get (iobuf_arena,
+ iobuf_pool->default_page_size);
+ if (!iobuf) {
+ gf_log (THIS->name, GF_LOG_WARNING, "iobuf not found");
+ goto unlock;
+ }
+
+ __iobuf_ref (iobuf);
+ }
+unlock:
+ pthread_mutex_unlock (&iobuf_pool->mutex);
+
+out:
+ return iobuf;
+}
void
__iobuf_put (struct iobuf *iobuf, struct iobuf_arena *iobuf_arena)
{
struct iobuf_pool *iobuf_pool = NULL;
+ int index = 0;
+
+ GF_VALIDATE_OR_GOTO ("iobuf", iobuf_arena, out);
+ GF_VALIDATE_OR_GOTO ("iobuf", iobuf, out);
iobuf_pool = iobuf_arena->iobuf_pool;
+ index = gf_iobuf_get_arena_index (iobuf_arena->page_size);
+ if (index == -1) {
+ gf_log ("iobuf", GF_LOG_DEBUG, "freeing the iobuf (%p) "
+ "allocated with standard calloc()", iobuf);
+
+ /* free up properly without bothering about lists and all */
+ LOCK_DESTROY (&iobuf->lock);
+ GF_FREE (iobuf->free_ptr);
+ GF_FREE (iobuf);
+ return;
+ }
+
if (iobuf_arena->passive_cnt == 0) {
list_del (&iobuf_arena->list);
- list_add_tail (&iobuf_arena->list, &iobuf_pool->arenas.list);
+ list_add_tail (&iobuf_arena->list, &iobuf_pool->arenas[index]);
}
list_del_init (&iobuf->list);
@@ -393,8 +686,11 @@ __iobuf_put (struct iobuf *iobuf, struct iobuf_arena *iobuf_arena)
if (iobuf_arena->active_cnt == 0) {
list_del (&iobuf_arena->list);
- list_add_tail (&iobuf_arena->list, &iobuf_pool->purge.list);
+ list_add_tail (&iobuf_arena->list, &iobuf_pool->purge[index]);
+ __iobuf_arena_prune (iobuf_pool, iobuf_arena, index);
}
+out:
+ return;
}
@@ -404,16 +700,19 @@ iobuf_put (struct iobuf *iobuf)
struct iobuf_arena *iobuf_arena = NULL;
struct iobuf_pool *iobuf_pool = NULL;
- if (!iobuf)
- return;
+ GF_VALIDATE_OR_GOTO ("iobuf", iobuf, out);
iobuf_arena = iobuf->iobuf_arena;
- if (!iobuf_arena)
+ if (!iobuf_arena) {
+ gf_log (THIS->name, GF_LOG_WARNING, "arena not found");
return;
+ }
iobuf_pool = iobuf_arena->iobuf_pool;
- if (!iobuf_pool)
+ if (!iobuf_pool) {
+ gf_log (THIS->name, GF_LOG_WARNING, "iobuf pool not found");
return;
+ }
pthread_mutex_lock (&iobuf_pool->mutex);
{
@@ -421,7 +720,8 @@ iobuf_put (struct iobuf *iobuf)
}
pthread_mutex_unlock (&iobuf_pool->mutex);
- iobuf_pool_prune (iobuf_pool);
+out:
+ return;
}
@@ -430,8 +730,7 @@ iobuf_unref (struct iobuf *iobuf)
{
int ref = 0;
- if (!iobuf)
- return;
+ GF_VALIDATE_OR_GOTO ("iobuf", iobuf, out);
LOCK (&iobuf->lock);
{
@@ -442,14 +741,16 @@ iobuf_unref (struct iobuf *iobuf)
if (!ref)
iobuf_put (iobuf);
+
+out:
+ return;
}
struct iobuf *
iobuf_ref (struct iobuf *iobuf)
{
- if (!iobuf)
- return NULL;
+ GF_VALIDATE_OR_GOTO ("iobuf", iobuf, out);
LOCK (&iobuf->lock);
{
@@ -457,6 +758,7 @@ iobuf_ref (struct iobuf *iobuf)
}
UNLOCK (&iobuf->lock);
+out:
return iobuf;
}
@@ -482,8 +784,7 @@ iobref_new ()
struct iobref *
iobref_ref (struct iobref *iobref)
{
- if (!iobref)
- return NULL;
+ GF_VALIDATE_OR_GOTO ("iobuf", iobref, out);
LOCK (&iobref->lock);
{
@@ -491,6 +792,7 @@ iobref_ref (struct iobref *iobref)
}
UNLOCK (&iobref->lock);
+out:
return iobref;
}
@@ -501,10 +803,9 @@ iobref_destroy (struct iobref *iobref)
int i = 0;
struct iobuf *iobuf = NULL;
- if (!iobref)
- return;
+ GF_VALIDATE_OR_GOTO ("iobuf", iobref, out);
- for (i = 0; i < 8; i++) {
+ for (i = 0; i < GF_IOBREF_IOBUF_COUNT; i++) {
iobuf = iobref->iobrefs[i];
iobref->iobrefs[i] = NULL;
@@ -513,6 +814,9 @@ iobref_destroy (struct iobref *iobref)
}
GF_FREE (iobref);
+
+out:
+ return;
}
@@ -521,8 +825,7 @@ iobref_unref (struct iobref *iobref)
{
int ref = 0;
- if (!iobref)
- return;
+ GF_VALIDATE_OR_GOTO ("iobuf", iobref, out);
LOCK (&iobref->lock);
{
@@ -532,6 +835,32 @@ iobref_unref (struct iobref *iobref)
if (!ref)
iobref_destroy (iobref);
+
+out:
+ return;
+}
+
+
+void
+iobref_clear (struct iobref *iobref)
+{
+ int i = 0;
+
+ GF_VALIDATE_OR_GOTO ("iobuf", iobref, out);
+
+ for (; i < GF_IOBREF_IOBUF_COUNT; i++) {
+ if (iobref->iobrefs[i] != NULL) {
+ iobuf_unref (iobref->iobrefs[i]);
+ } else {
+ /** iobuf's are attched serially */
+ break;
+ }
+ }
+
+ iobref_unref (iobref);
+
+ out:
+ return;
}
@@ -541,7 +870,10 @@ __iobref_add (struct iobref *iobref, struct iobuf *iobuf)
int i = 0;
int ret = -ENOMEM;
- for (i = 0; i < 8; i++) {
+ GF_VALIDATE_OR_GOTO ("iobuf", iobref, out);
+ GF_VALIDATE_OR_GOTO ("iobuf", iobuf, out);
+
+ for (i = 0; i < GF_IOBREF_IOBUF_COUNT; i++) {
if (iobref->iobrefs[i] == NULL) {
iobref->iobrefs[i] = iobuf_ref (iobuf);
ret = 0;
@@ -549,6 +881,7 @@ __iobref_add (struct iobref *iobref, struct iobuf *iobuf)
}
}
+out:
return ret;
}
@@ -556,13 +889,10 @@ __iobref_add (struct iobref *iobref, struct iobuf *iobuf)
int
iobref_add (struct iobref *iobref, struct iobuf *iobuf)
{
- int ret = 0;
+ int ret = -EINVAL;
- if (!iobref)
- return -EINVAL;
-
- if (!iobuf)
- return -EINVAL;
+ GF_VALIDATE_OR_GOTO ("iobuf", iobref, out);
+ GF_VALIDATE_OR_GOTO ("iobuf", iobuf, out);
LOCK (&iobref->lock);
{
@@ -570,6 +900,7 @@ iobref_add (struct iobref *iobref, struct iobuf *iobuf)
}
UNLOCK (&iobref->lock);
+out:
return ret;
}
@@ -578,12 +909,15 @@ int
iobref_merge (struct iobref *to, struct iobref *from)
{
int i = 0;
- int ret = 0;
+ int ret = -1;
struct iobuf *iobuf = NULL;
+ GF_VALIDATE_OR_GOTO ("iobuf", to, out);
+ GF_VALIDATE_OR_GOTO ("iobuf", from, out);
+
LOCK (&from->lock);
{
- for (i = 0; i < 8; i++) {
+ for (i = 0; i < GF_IOBREF_IOBUF_COUNT; i++) {
iobuf = from->iobrefs[i];
if (!iobuf)
@@ -597,6 +931,7 @@ iobref_merge (struct iobref *to, struct iobref *from)
}
UNLOCK (&from->lock);
+out:
return ret;
}
@@ -606,16 +941,19 @@ iobuf_size (struct iobuf *iobuf)
{
size_t size = 0;
- if (!iobuf)
- goto out;
+ GF_VALIDATE_OR_GOTO ("iobuf", iobuf, out);
- if (!iobuf->iobuf_arena)
+ if (!iobuf->iobuf_arena) {
+ gf_log (THIS->name, GF_LOG_WARNING, "arena not found");
goto out;
+ }
- if (!iobuf->iobuf_arena->iobuf_pool)
+ if (!iobuf->iobuf_arena->iobuf_pool) {
+ gf_log (THIS->name, GF_LOG_WARNING, "pool not found");
goto out;
+ }
- size = iobuf->iobuf_arena->iobuf_pool->page_size;
+ size = iobuf->iobuf_arena->page_size;
out:
return size;
}
@@ -627,113 +965,136 @@ iobref_size (struct iobref *iobref)
size_t size = 0;
int i = 0;
- if (!iobref)
- goto out;
+ GF_VALIDATE_OR_GOTO ("iobuf", iobref, out);
LOCK (&iobref->lock);
{
- for (i = 0; i < 8; i++) {
+ for (i = 0; i < GF_IOBREF_IOBUF_COUNT; i++) {
if (iobref->iobrefs[i])
size += iobuf_size (iobref->iobrefs[i]);
}
}
UNLOCK (&iobref->lock);
+
out:
return size;
}
-void
+void
iobuf_info_dump (struct iobuf *iobuf, const char *key_prefix)
{
char key[GF_DUMP_MAX_BUF_LEN];
struct iobuf my_iobuf;
int ret = 0;
- if (!iobuf)
- return;
+ GF_VALIDATE_OR_GOTO ("iobuf", iobuf, out);
memset(&my_iobuf, 0, sizeof(my_iobuf));
-
+
ret = TRY_LOCK(&iobuf->lock);
if (ret) {
- gf_log("", GF_LOG_WARNING, "Unable to dump iobuf"
- " errno: %d", errno);
return;
}
memcpy(&my_iobuf, iobuf, sizeof(my_iobuf));
UNLOCK(&iobuf->lock);
- gf_proc_dump_build_key(key, key_prefix,"ref");
+ gf_proc_dump_build_key(key, key_prefix,"ref");
gf_proc_dump_write(key, "%d", my_iobuf.ref);
- gf_proc_dump_build_key(key, key_prefix,"ptr");
+ gf_proc_dump_build_key(key, key_prefix,"ptr");
gf_proc_dump_write(key, "%p", my_iobuf.ptr);
+out:
+ return;
}
-void
+void
iobuf_arena_info_dump (struct iobuf_arena *iobuf_arena, const char *key_prefix)
{
- char key[GF_DUMP_MAX_BUF_LEN];
- int i = 1;
+ char key[GF_DUMP_MAX_BUF_LEN];
+ int i = 1;
struct iobuf *trav;
- if (!iobuf_arena)
- return;
+ GF_VALIDATE_OR_GOTO ("iobuf", iobuf_arena, out);
gf_proc_dump_build_key(key, key_prefix,"mem_base");
gf_proc_dump_write(key, "%p", iobuf_arena->mem_base);
- gf_proc_dump_build_key(key, key_prefix, "active_cnt");
+ gf_proc_dump_build_key(key, key_prefix, "active_cnt");
gf_proc_dump_write(key, "%d", iobuf_arena->active_cnt);
- gf_proc_dump_build_key(key, key_prefix, "passive_cnt");
+ gf_proc_dump_build_key(key, key_prefix, "passive_cnt");
gf_proc_dump_write(key, "%d", iobuf_arena->passive_cnt);
- list_for_each_entry (trav, &iobuf_arena->active.list, list) {
+ gf_proc_dump_build_key(key, key_prefix, "alloc_cnt");
+ gf_proc_dump_write(key, "%"PRIu64, iobuf_arena->alloc_cnt);
+ gf_proc_dump_build_key(key, key_prefix, "max_active");
+ gf_proc_dump_write(key, "%"PRIu64, iobuf_arena->max_active);
+ gf_proc_dump_build_key(key, key_prefix, "page_size");
+ gf_proc_dump_write(key, "%"PRIu64, iobuf_arena->page_size);
+ list_for_each_entry (trav, &iobuf_arena->active.list, list) {
gf_proc_dump_build_key(key, key_prefix,"active_iobuf.%d", i++);
gf_proc_dump_add_section(key);
iobuf_info_dump(trav, key);
}
+out:
+ return;
}
void
iobuf_stats_dump (struct iobuf_pool *iobuf_pool)
{
-
char msg[1024];
struct iobuf_arena *trav = NULL;
int i = 1;
+ int j = 0;
int ret = -1;
- if (!iobuf_pool)
- return;
+ GF_VALIDATE_OR_GOTO ("iobuf", iobuf_pool, out);
memset(msg, 0, sizeof(msg));
ret = pthread_mutex_trylock(&iobuf_pool->mutex);
if (ret) {
- gf_log("", GF_LOG_WARNING, "Unable to dump iobuf pool"
- " errno: %d", errno);
return;
}
gf_proc_dump_add_section("iobuf.global");
- gf_proc_dump_write("iobuf.global.iobuf_pool","%p", iobuf_pool);
- gf_proc_dump_write("iobuf.global.iobuf_pool.page_size", "%d",
- iobuf_pool->page_size);
- gf_proc_dump_write("iobuf.global.iobuf_pool.arena_size", "%d",
- iobuf_pool->arena_size);
- gf_proc_dump_write("iobuf.global.iobuf_pool.arena_cnt", "%d",
- iobuf_pool->arena_cnt);
-
- list_for_each_entry (trav, &iobuf_pool->arenas.list, list) {
- snprintf(msg, sizeof(msg), "iobuf.global.iobuf_pool.arena.%d",
- i);
- gf_proc_dump_add_section(msg);
- iobuf_arena_info_dump(trav,msg);
- i++;
- }
-
+ gf_proc_dump_write("iobuf_pool","%p", iobuf_pool);
+ gf_proc_dump_write("iobuf_pool.default_page_size", "%d",
+ iobuf_pool->default_page_size);
+ gf_proc_dump_write("iobuf_pool.arena_size", "%d",
+ iobuf_pool->arena_size);
+ gf_proc_dump_write("iobuf_pool.arena_cnt", "%d",
+ iobuf_pool->arena_cnt);
+ gf_proc_dump_write("iobuf_pool.request_misses", "%"PRId64,
+ iobuf_pool->request_misses);
+
+ for (j = 0; j < IOBUF_ARENA_MAX_INDEX; j++) {
+ list_for_each_entry (trav, &iobuf_pool->arenas[j], list) {
+ snprintf(msg, sizeof(msg),
+ "arena.%d", i);
+ gf_proc_dump_add_section(msg);
+ iobuf_arena_info_dump(trav,msg);
+ i++;
+ }
+ list_for_each_entry (trav, &iobuf_pool->purge[j], list) {
+ snprintf(msg, sizeof(msg),
+ "purge.%d", i);
+ gf_proc_dump_add_section(msg);
+ iobuf_arena_info_dump(trav,msg);
+ i++;
+ }
+ list_for_each_entry (trav, &iobuf_pool->filled[j], list) {
+ snprintf(msg, sizeof(msg),
+ "filled.%d", i);
+ gf_proc_dump_add_section(msg);
+ iobuf_arena_info_dump(trav,msg);
+ i++;
+ }
+
+ }
+
pthread_mutex_unlock(&iobuf_pool->mutex);
+out:
return;
}
@@ -741,7 +1102,12 @@ iobuf_stats_dump (struct iobuf_pool *iobuf_pool)
void
iobuf_to_iovec(struct iobuf *iob, struct iovec *iov)
{
+ GF_VALIDATE_OR_GOTO ("iobuf", iob, out);
+ GF_VALIDATE_OR_GOTO ("iobuf", iov, out);
+
iov->iov_base = iobuf_ptr (iob);
iov->iov_len = iobuf_pagesize (iob);
-}
+out:
+ return;
+}
diff --git a/libglusterfs/src/iobuf.h b/libglusterfs/src/iobuf.h
index fc8ff623a..5595309e1 100644
--- a/libglusterfs/src/iobuf.h
+++ b/libglusterfs/src/iobuf.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
#ifndef _IOBUF_H_
@@ -26,6 +17,9 @@
#include <sys/mman.h>
#include <sys/uio.h>
+#define GF_VARIABLE_IOBUF_COUNT 32
+#define GF_IOBREF_IOBUF_COUNT 16
+
/* Lets try to define the new anonymous mapping
* flag, in case the system is still using the
* now deprecated MAP_ANON flag.
@@ -37,6 +31,11 @@
#define MAP_ANONYMOUS MAP_ANON
#endif
+#define GF_ALIGN_BUF(ptr,bound) ((void *)((unsigned long)(ptr + bound - 1) & \
+ (unsigned long)(~(bound - 1))))
+
+#define GF_IOBUF_ALIGN_SIZE 512
+
/* one allocatable unit for the consumers of the IOBUF API */
/* each unit hosts @page_size bytes of memory */
struct iobuf;
@@ -49,6 +48,10 @@ struct iobuf_arena;
/* expandable and contractable pool of memory, internally broken into arenas */
struct iobuf_pool;
+struct iobuf_init_config {
+ size_t pagesize;
+ int32_t num_pages;
+};
struct iobuf {
union {
@@ -64,6 +67,9 @@ struct iobuf {
int ref; /* 0 == passive, >0 == active */
void *ptr; /* usable memory region by the consumer */
+
+ void *free_ptr; /* in case of stdalloc, this is the
+ one to be freed */
};
@@ -75,6 +81,13 @@ struct iobuf_arena {
struct iobuf_arena *prev;
};
};
+
+ size_t page_size; /* size of all iobufs in this arena */
+ size_t arena_size; /* this is equal to
+ (iobuf_pool->arena_size / page_size)
+ * page_size */
+ size_t page_count;
+
struct iobuf_pool *iobuf_pool;
void *mem_base;
@@ -86,25 +99,34 @@ struct iobuf_arena {
int passive_cnt;
struct iobuf passive; /* head node iobuf
(unused by itself) */
+ uint64_t alloc_cnt; /* total allocs in this pool */
+ int max_active; /* max active buffers at a given time */
};
struct iobuf_pool {
pthread_mutex_t mutex;
- size_t page_size; /* size of all iobufs in this pool */
- size_t arena_size; /* size of memory region in arena */
+ size_t arena_size; /* size of memory region in
+ arena */
+ size_t default_page_size; /* default size of iobuf */
int arena_cnt;
- struct iobuf_arena arenas; /* head node arena
- (unused by itself) */
- struct iobuf_arena filled; /* arenas without free iobufs */
- struct iobuf_arena purge; /* arenas which can be purged */
-};
+ struct list_head arenas[GF_VARIABLE_IOBUF_COUNT];
+ /* array of arenas. Each element of the array is a list of arenas
+ holding iobufs of particular page_size */
+ struct list_head filled[GF_VARIABLE_IOBUF_COUNT];
+ /* array of arenas without free iobufs */
+ struct list_head purge[GF_VARIABLE_IOBUF_COUNT];
+ /* array of of arenas which can be purged */
+
+ uint64_t request_misses; /* mostly the requests for higher
+ value of iobufs */
+};
-struct iobuf_pool *iobuf_pool_new (size_t arena_size, size_t page_size);
+struct iobuf_pool *iobuf_pool_new (void);
void iobuf_pool_destroy (struct iobuf_pool *iobuf_pool);
struct iobuf *iobuf_get (struct iobuf_pool *iobuf_pool);
void iobuf_unref (struct iobuf *iobuf);
@@ -113,14 +135,14 @@ void iobuf_pool_destroy (struct iobuf_pool *iobuf_pool);
void iobuf_to_iovec(struct iobuf *iob, struct iovec *iov);
#define iobuf_ptr(iob) ((iob)->ptr)
-#define iobpool_pagesize(iobpool) ((iobpool)->page_size)
-#define iobuf_pagesize(iob) (iobpool_pagesize((iob)->iobuf_arena->iobuf_pool))
+#define iobpool_default_pagesize(iobpool) ((iobpool)->default_page_size)
+#define iobuf_pagesize(iob) (iob->iobuf_arena->page_size)
struct iobref {
gf_lock_t lock;
int ref;
- struct iobuf *iobrefs[8];
+ struct iobuf *iobrefs[GF_IOBREF_IOBUF_COUNT];
};
struct iobref *iobref_new ();
@@ -128,10 +150,12 @@ struct iobref *iobref_ref (struct iobref *iobref);
void iobref_unref (struct iobref *iobref);
int iobref_add (struct iobref *iobref, struct iobuf *iobuf);
int iobref_merge (struct iobref *to, struct iobref *from);
-
+void iobref_clear (struct iobref *iobref);
size_t iobuf_size (struct iobuf *iobuf);
size_t iobref_size (struct iobref *iobref);
void iobuf_stats_dump (struct iobuf_pool *iobuf_pool);
+struct iobuf *
+iobuf_get2 (struct iobuf_pool *iobuf_pool, size_t page_size);
#endif /* !_IOBUF_H_ */
diff --git a/libglusterfs/src/latency.c b/libglusterfs/src/latency.c
index bc2409138..b22f72950 100644
--- a/libglusterfs/src/latency.c
+++ b/libglusterfs/src/latency.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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.
*/
@@ -35,87 +26,87 @@ gf_set_fop_from_fn_pointer (call_frame_t *frame, struct xlator_fops *fops, void
{
glusterfs_fop_t fop = -1;
- if (fops->stat == fn)
+ if (fops->stat == *(fop_stat_t *)&fn)
fop = GF_FOP_STAT;
- else if (fops->readlink == fn)
+ else if (fops->readlink == *(fop_readlink_t *)&fn)
fop = GF_FOP_READLINK;
- else if (fops->mknod == fn)
+ else if (fops->mknod == *(fop_mknod_t *)&fn)
fop = GF_FOP_MKNOD;
- else if (fops->mkdir == fn)
+ else if (fops->mkdir == *(fop_mkdir_t *)&fn)
fop = GF_FOP_MKDIR;
- else if (fops->unlink == fn)
+ else if (fops->unlink == *(fop_unlink_t *)&fn)
fop = GF_FOP_UNLINK;
- else if (fops->rmdir == fn)
+ else if (fops->rmdir == *(fop_rmdir_t *)&fn)
fop = GF_FOP_RMDIR;
- else if (fops->symlink == fn)
+ else if (fops->symlink == *(fop_symlink_t *)&fn)
fop = GF_FOP_SYMLINK;
- else if (fops->rename == fn)
+ else if (fops->rename == *(fop_rename_t *)&fn)
fop = GF_FOP_RENAME;
- else if (fops->link == fn)
+ else if (fops->link == *(fop_link_t *)&fn)
fop = GF_FOP_LINK;
- else if (fops->truncate == fn)
+ else if (fops->truncate == *(fop_truncate_t *)&fn)
fop = GF_FOP_TRUNCATE;
- else if (fops->open == fn)
+ else if (fops->open == *(fop_open_t *)&fn)
fop = GF_FOP_OPEN;
- else if (fops->readv == fn)
+ else if (fops->readv == *(fop_readv_t *)&fn)
fop = GF_FOP_READ;
- else if (fops->writev == fn)
+ else if (fops->writev == *(fop_writev_t *)&fn)
fop = GF_FOP_WRITE;
- else if (fops->statfs == fn)
+ else if (fops->statfs == *(fop_statfs_t *)&fn)
fop = GF_FOP_STATFS;
- else if (fops->flush == fn)
+ else if (fops->flush == *(fop_flush_t *)&fn)
fop = GF_FOP_FLUSH;
- else if (fops->fsync == fn)
+ else if (fops->fsync == *(fop_fsync_t *)&fn)
fop = GF_FOP_FSYNC;
- else if (fops->setxattr == fn)
+ else if (fops->setxattr == *(fop_setxattr_t *)&fn)
fop = GF_FOP_SETXATTR;
- else if (fops->getxattr == fn)
+ else if (fops->getxattr == *(fop_getxattr_t *)&fn)
fop = GF_FOP_GETXATTR;
- else if (fops->removexattr == fn)
+ else if (fops->removexattr == *(fop_removexattr_t *)&fn)
fop = GF_FOP_REMOVEXATTR;
- else if (fops->opendir == fn)
+ else if (fops->opendir == *(fop_opendir_t *)&fn)
fop = GF_FOP_OPENDIR;
- else if (fops->fsyncdir == fn)
+ else if (fops->fsyncdir == *(fop_fsyncdir_t *)&fn)
fop = GF_FOP_FSYNCDIR;
- else if (fops->access == fn)
+ else if (fops->access == *(fop_access_t *)&fn)
fop = GF_FOP_ACCESS;
- else if (fops->create == fn)
+ else if (fops->create == *(fop_create_t *)&fn)
fop = GF_FOP_CREATE;
- else if (fops->ftruncate == fn)
+ else if (fops->ftruncate == *(fop_ftruncate_t *)&fn)
fop = GF_FOP_FTRUNCATE;
- else if (fops->fstat == fn)
+ else if (fops->fstat == *(fop_fstat_t *)&fn)
fop = GF_FOP_FSTAT;
- else if (fops->lk == fn)
+ else if (fops->lk == *(fop_lk_t *)&fn)
fop = GF_FOP_LK;
- else if (fops->lookup == fn)
+ else if (fops->lookup == *(fop_lookup_t *)&fn)
fop = GF_FOP_LOOKUP;
- else if (fops->readdir == fn)
+ else if (fops->readdir == *(fop_readdir_t *)&fn)
fop = GF_FOP_READDIR;
- else if (fops->inodelk == fn)
+ else if (fops->inodelk == *(fop_inodelk_t *)&fn)
fop = GF_FOP_INODELK;
- else if (fops->finodelk == fn)
+ else if (fops->finodelk == *(fop_finodelk_t *)&fn)
fop = GF_FOP_FINODELK;
- else if (fops->entrylk == fn)
+ else if (fops->entrylk == *(fop_entrylk_t *)&fn)
fop = GF_FOP_ENTRYLK;
- else if (fops->fentrylk == fn)
+ else if (fops->fentrylk == *(fop_fentrylk_t *)&fn)
fop = GF_FOP_FENTRYLK;
- else if (fops->xattrop == fn)
+ else if (fops->xattrop == *(fop_xattrop_t *)&fn)
fop = GF_FOP_XATTROP;
- else if (fops->fxattrop == fn)
+ else if (fops->fxattrop == *(fop_fxattrop_t *)&fn)
fop = GF_FOP_FXATTROP;
- else if (fops->fgetxattr == fn)
+ else if (fops->fgetxattr == *(fop_fgetxattr_t *)&fn)
fop = GF_FOP_FGETXATTR;
- else if (fops->fsetxattr == fn)
+ else if (fops->fsetxattr == *(fop_fsetxattr_t *)&fn)
fop = GF_FOP_FSETXATTR;
- else if (fops->rchecksum == fn)
+ else if (fops->rchecksum == *(fop_rchecksum_t *)&fn)
fop = GF_FOP_RCHECKSUM;
- else if (fops->setattr == fn)
+ else if (fops->setattr == *(fop_setattr_t *)&fn)
fop = GF_FOP_SETATTR;
- else if (fops->fsetattr == fn)
+ else if (fops->fsetattr == *(fop_fsetattr_t *)&fn)
fop = GF_FOP_FSETATTR;
- else if (fops->readdirp == fn)
+ else if (fops->readdirp == *(fop_readdirp_t *)&fn)
fop = GF_FOP_READDIRP;
- else if (fops->getspec == fn)
+ else if (fops->getspec == *(fop_getspec_t *)&fn)
fop = GF_FOP_GETSPEC;
else
fop = -1;
@@ -140,11 +131,27 @@ gf_update_latency (call_frame_t *frame)
lat = &frame->this->latencies[frame->op];
- lat->total += elapsed;
+ lat->total += elapsed;
lat->count++;
lat->mean = lat->mean + (elapsed - lat->mean) / lat->count;
}
+void
+gf_latency_begin (call_frame_t *frame, void *fn)
+{
+ gf_set_fop_from_fn_pointer (frame, frame->this->fops, fn);
+
+ gettimeofday (&frame->begin, NULL);
+}
+
+
+void
+gf_latency_end (call_frame_t *frame)
+{
+ gettimeofday (&frame->end, NULL);
+
+ gf_update_latency (frame);
+}
void
gf_proc_dump_latency_info (xlator_t *xl)
@@ -157,26 +164,25 @@ gf_proc_dump_latency_info (xlator_t *xl)
gf_proc_dump_add_section (key_prefix);
for (i = 0; i < GF_FOP_MAXVALUE; i++) {
- gf_proc_dump_build_key (key, key_prefix, gf_fop_list[i]);
+ gf_proc_dump_build_key (key, key_prefix,
+ (char *)gf_fop_list[i]);
gf_proc_dump_write (key, "%.03f,%"PRId64",%.03f",
xl->latencies[i].mean,
xl->latencies[i].count,
- xl->latencies[i].total);
+ xl->latencies[i].total);
}
+
+ memset (xl->latencies, 0, sizeof (xl->latencies));
}
void
-gf_latency_toggle (int signum)
+gf_latency_toggle (int signum, glusterfs_ctx_t *ctx)
{
- glusterfs_ctx_t *ctx = NULL;
-
- ctx = glusterfs_ctx_get ();
-
if (ctx) {
ctx->measure_latency = !ctx->measure_latency;
- gf_log ("[core]", GF_LOG_NORMAL,
+ gf_log ("[core]", GF_LOG_INFO,
"Latency measurement turned %s",
ctx->measure_latency ? "on" : "off");
}
diff --git a/libglusterfs/src/latency.h b/libglusterfs/src/latency.h
index 610f12550..81acbf484 100644
--- a/libglusterfs/src/latency.h
+++ b/libglusterfs/src/latency.h
@@ -1,25 +1,17 @@
/*
- Copyright (c) 2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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 __LATENCY_H__
#define __LATENCY_H__
+#include "glusterfs.h"
typedef struct fop_latency {
uint64_t min; /* min time for the call (microseconds) */
@@ -31,6 +23,6 @@ typedef struct fop_latency {
} fop_latency_t;
void
-gf_latency_toggle (int signum);
+gf_latency_toggle (int signum, glusterfs_ctx_t *ctx);
#endif /* __LATENCY_H__ */
diff --git a/libglusterfs/src/list.h b/libglusterfs/src/list.h
index d4851dfec..392c22ceb 100644
--- a/libglusterfs/src/list.h
+++ b/libglusterfs/src/list.h
@@ -1,26 +1,16 @@
/*
- Copyright (c) 2008-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ Copyright (c) 2008-2014 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 _LLIST_H
#define _LLIST_H
-
struct list_head {
struct list_head *next;
struct list_head *prev;
@@ -54,6 +44,31 @@ list_add_tail (struct list_head *new, struct list_head *head)
}
+/* This function will insert the element to the list in a order.
+ Order will be based on the compare function provided as a input.
+ If element to be inserted in ascending order compare should return:
+ 0: if both the arguments are equal
+ >0: if first argument is greater than second argument
+ <0: if first argument is less than second argument */
+static inline void
+list_add_order (struct list_head *new, struct list_head *head,
+ int (*compare)(struct list_head *, struct list_head *))
+{
+ struct list_head *pos = head->prev;
+
+ while ( pos != head ) {
+ if (compare(new, pos) >= 0)
+ break;
+
+ /* Iterate the list in the reverse order. This will have
+ better efficiency if the elements are inserted in the
+ ascending order */
+ pos = pos->prev;
+ }
+
+ list_add (new, pos);
+}
+
static inline void
list_del (struct list_head *old)
{
@@ -120,6 +135,7 @@ list_splice (struct list_head *list, struct list_head *head)
}
+/* Splice moves @list to the head of the list at @head. */
static inline void
list_splice_init (struct list_head *list, struct list_head *head)
{
@@ -131,11 +147,43 @@ list_splice_init (struct list_head *list, struct list_head *head)
}
+static inline void
+__list_append (struct list_head *list, struct list_head *head)
+{
+ (head->prev)->next = (list->next);
+ (list->next)->prev = (head->prev);
+ (head->prev) = (list->prev);
+ (list->prev)->next = head;
+}
+
+
+static inline void
+list_append (struct list_head *list, struct list_head *head)
+{
+ if (list_empty (list))
+ return;
+
+ __list_append (list, head);
+}
+
+
+/* Append moves @list to the end of @head */
+static inline void
+list_append_init (struct list_head *list, struct list_head *head)
+{
+ if (list_empty (list))
+ return;
+
+ __list_append (list, head);
+ INIT_LIST_HEAD (list);
+}
+
+
#define list_entry(ptr, type, member) \
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
-#define list_for_each(pos, head) \
+#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
@@ -151,4 +199,16 @@ list_splice_init (struct list_head *list, struct list_head *head)
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))
+#define list_for_each_entry_reverse(pos, head, member) \
+ for (pos = list_entry((head)->prev, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.prev, typeof(*pos), member))
+
+
+#define list_for_each_entry_safe_reverse(pos, n, head, member) \
+ for (pos = list_entry((head)->prev, typeof(*pos), member), \
+ n = list_entry(pos->member.prev, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.prev, typeof(*n), member))
+
#endif /* _LLIST_H */
diff --git a/libglusterfs/src/lkowner.h b/libglusterfs/src/lkowner.h
new file mode 100644
index 000000000..969d13e50
--- /dev/null
+++ b/libglusterfs/src/lkowner.h
@@ -0,0 +1,83 @@
+/*
+ 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.
+*/
+
+#ifndef _LK_OWNER_H
+#define _LK_OWNER_H
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#define GF_MAX_LOCK_OWNER_LEN 1024 /* 1kB as per NLM */
+
+/* 16strings-16strings-... */
+#define GF_LKOWNER_BUF_SIZE ((GF_MAX_LOCK_OWNER_LEN * 2) + \
+ (GF_MAX_LOCK_OWNER_LEN / 8))
+
+typedef struct gf_lkowner_ {
+ int len;
+ char data[GF_MAX_LOCK_OWNER_LEN];
+} gf_lkowner_t;
+
+
+/* LKOWNER to string functions */
+static inline void
+lkowner_unparse (gf_lkowner_t *lkowner, char *buf, int buf_len)
+{
+ int i = 0;
+ int j = 0;
+
+ for (i = 0; i < lkowner->len; i++) {
+ if (i && !(i % 8)) {
+ buf[j] = '-';
+ j++;
+ }
+ sprintf (&buf[j], "%02hhx", lkowner->data[i]);
+ j += 2;
+ if (j == buf_len)
+ break;
+ }
+ if (j < buf_len)
+ buf[j] = '\0';
+}
+
+static inline void
+set_lk_owner_from_ptr (gf_lkowner_t *lkowner, void *data)
+{
+ int i = 0;
+ int j = 0;
+
+ lkowner->len = sizeof (unsigned long);
+ for (i = 0, j = 0; i < lkowner->len; i++, j += 8) {
+ lkowner->data[i] = (char)((((unsigned long)data) >> j) & 0xff);
+ }
+}
+
+static inline void
+set_lk_owner_from_uint64 (gf_lkowner_t *lkowner, uint64_t data)
+{
+ int i = 0;
+ int j = 0;
+
+ lkowner->len = 8;
+ for (i = 0, j = 0; i < lkowner->len; i++, j += 8) {
+ lkowner->data[i] = (char)((data >> j) & 0xff);
+ }
+}
+
+/* Return true if the locks have the same owner */
+static inline int
+is_same_lkowner (gf_lkowner_t *l1, gf_lkowner_t *l2)
+{
+ return ((l1->len == l2->len) && !memcmp(l1->data, l2->data, l1->len));
+}
+
+#endif /* _LK_OWNER_H */
diff --git a/libglusterfs/src/locking.h b/libglusterfs/src/locking.h
index c5043aa14..79c6992af 100644
--- a/libglusterfs/src/locking.h
+++ b/libglusterfs/src/locking.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
#ifndef _LOCKING_H
diff --git a/libglusterfs/src/logging.c b/libglusterfs/src/logging.c
index 5b89aafb4..5deb90cda 100644
--- a/libglusterfs/src/logging.c
+++ b/libglusterfs/src/logging.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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
@@ -31,9 +22,22 @@
#include <string.h>
#include <stdlib.h>
+#ifdef GF_USE_SYSLOG
+#include <libintl.h>
+#include <syslog.h>
+#include <sys/stat.h>
+#include "gf-error-codes.h"
+
+#define GF_JSON_MSG_LENGTH 8192
+#define GF_SYSLOG_CEE_FORMAT \
+ "@cee: {\"msg\": \"%s\", \"gf_code\": \"%u\", \"gf_message\": \"%s\"}"
+#define GF_LOG_CONTROL_FILE "/etc/glusterfs/logger.conf"
+#endif /* GF_USE_SYSLOG */
+
#include "xlator.h"
#include "logging.h"
#include "defaults.h"
+#include "glusterfs.h"
#ifdef GF_LINUX_HOST_OS
#include <syslog.h>
@@ -43,49 +47,44 @@
#include <execinfo.h>
#endif
+/* Ideally this should get moved to logging.h */
+struct _msg_queue {
+ struct list_head msgs;
+};
-static pthread_mutex_t logfile_mutex;
-static char *filename = NULL;
-static uint8_t logrotate = 0;
-static FILE *logfile = NULL;
-static gf_loglevel_t loglevel = GF_LOG_MAX;
-static int gf_log_syslog = 0;
-
-char gf_log_xl_log_set;
-gf_loglevel_t gf_log_loglevel; /* extern'd */
-FILE *gf_log_logfile;
-
-static char *cmd_log_filename = NULL;
-static FILE *cmdlogfile = NULL;
+struct _log_msg {
+ const char *msg;
+ struct list_head queue;
+};
void
gf_log_logrotate (int signum)
{
- logrotate = 1;
+ THIS->ctx->log.logrotate = 1;
}
void
gf_log_enable_syslog (void)
{
- gf_log_syslog = 1;
+ THIS->ctx->log.gf_log_syslog = 1;
}
void
gf_log_disable_syslog (void)
{
- gf_log_syslog = 0;
+ THIS->ctx->log.gf_log_syslog = 0;
}
gf_loglevel_t
gf_log_get_loglevel (void)
{
- return loglevel;
+ return THIS->ctx->log.loglevel;
}
void
gf_log_set_loglevel (gf_loglevel_t level)
{
- gf_log_loglevel = loglevel = level;
+ THIS->ctx->log.loglevel = level;
}
@@ -104,151 +103,506 @@ gf_log_set_xl_loglevel (void *this, gf_loglevel_t level)
xlator_t *xl = this;
if (!xl)
return;
- gf_log_xl_log_set = 1;
+ xl->ctx->log.gf_log_xl_log_set = 1;
xl->loglevel = level;
}
void
gf_log_fini (void)
{
- pthread_mutex_destroy (&logfile_mutex);
+ pthread_mutex_destroy (&THIS->ctx->log.logfile_mutex);
}
-int
-gf_log_init (const char *file)
+#ifdef GF_USE_SYSLOG
+/**
+ * gf_get_error_message -function to get error message for given error code
+ * @error_code: error code defined by log book
+ *
+ * @return: success: string
+ * failure: NULL
+ */
+const char *
+gf_get_error_message (int error_code) {
+ return _gf_get_message (error_code);
+}
+
+
+/**
+ * gf_openlog -function to open syslog specific to gluster based on
+ * existence of file /etc/glusterfs/logger.conf
+ * @ident: optional identification string similar to openlog()
+ * @option: optional value to option to openlog(). Passing -1 uses
+ * 'LOG_PID | LOG_NDELAY' as default
+ * @facility: optional facility code similar to openlog(). Passing -1
+ * uses LOG_DAEMON as default
+ *
+ * @return: void
+ */
+void
+gf_openlog (const char *ident, int option, int facility)
{
- if (!file){
- fprintf (stderr, "gf_log_init: no filename specified\n");
- return -1;
- }
-
- pthread_mutex_init (&logfile_mutex, NULL);
-
- filename = gf_strdup (file);
- if (!filename) {
- fprintf (stderr, "gf_log_init: strdup error\n");
- return -1;
- }
-
- logfile = fopen (file, "a");
- if (!logfile){
- fprintf (stderr,
- "gf_log_init: failed to open logfile \"%s\" (%s)\n",
- file,
- strerror (errno));
- return -1;
- }
+ int _option = option;
+ int _facility = facility;
-#ifdef GF_LINUX_HOST_OS
- /* For the 'syslog' output. one can grep 'GlusterFS' in syslog
- for serious logs */
- openlog ("GlusterFS", LOG_PID, LOG_DAEMON);
-#endif
+ if (-1 == _option) {
+ _option = LOG_PID | LOG_NDELAY;
+ }
+ if (-1 == _facility) {
+ _facility = LOG_LOCAL1;
+ }
- gf_log_logfile = logfile;
+ setlocale(LC_ALL, "");
+ bindtextdomain("gluster", "/usr/share/locale");
+ textdomain("gluster");
- return 0;
+ openlog(ident, _option, _facility);
}
-/*
- * Initialize logging to a central server.
- * If successful, log messages will be written both to
- * the local file and to the remote server.
+/**
+ * _json_escape -function to convert string to json encoded string
+ * @str: input string
+ * @buf: buffer to store encoded string
+ * @len: length of @buf
+ *
+ * @return: success: last unprocessed character position by pointer in @str
+ * failure: NULL
+ *
+ * Internal function. Heavily inspired by _ul_str_escape() function in
+ * libumberlog
+ *
+ * Sample output:
+ * [1] str = "devel error"
+ * buf = "devel error"
+ * [2] str = "devel error"
+ * buf = "devel\terror"
+ * [3] str = "I/O error on "/tmp/foo" file"
+ * buf = "I/O error on \"/tmp/foo\" file"
+ * [4] str = "I/O erroron /tmp/bar file"
+ * buf = "I/O error\u001bon /tmp/bar file"
+ *
*/
+char *
+_json_escape(const char *str, char *buf, size_t len)
+{
+ static const unsigned char json_exceptions[UCHAR_MAX + 1] =
+ {
+ [0x01] = 1, [0x02] = 1, [0x03] = 1, [0x04] = 1,
+ [0x05] = 1, [0x06] = 1, [0x07] = 1, [0x08] = 1,
+ [0x09] = 1, [0x0a] = 1, [0x0b] = 1, [0x0c] = 1,
+ [0x0d] = 1, [0x0e] = 1, [0x0f] = 1, [0x10] = 1,
+ [0x11] = 1, [0x12] = 1, [0x13] = 1, [0x14] = 1,
+ [0x15] = 1, [0x16] = 1, [0x17] = 1, [0x18] = 1,
+ [0x19] = 1, [0x1a] = 1, [0x1b] = 1, [0x1c] = 1,
+ [0x1d] = 1, [0x1e] = 1, [0x1f] = 1,
+ ['\\'] = 1, ['"'] = 1
+ };
+ static const char json_hex_chars[16] = "0123456789abcdef";
+ unsigned char *p = NULL;
+ size_t pos = 0;
+
+ if (!str || !buf || len <= 0) {
+ return NULL;
+ }
-static int __central_log_enabled = 0;
-
-struct _msg_queue {
- struct list_head msgs;
-};
+ for (p = (unsigned char *)str;
+ *p && (pos + 1) < len;
+ p++)
+ {
+ if (json_exceptions[*p] == 0) {
+ buf[pos++] = *p;
+ continue;
+ }
-struct _log_msg {
- const char *msg;
- struct list_head queue;
-};
+ if ((pos + 2) >= len) {
+ break;
+ }
+ switch (*p)
+ {
+ case '\b':
+ buf[pos++] = '\\';
+ buf[pos++] = 'b';
+ break;
+ case '\n':
+ buf[pos++] = '\\';
+ buf[pos++] = 'n';
+ break;
+ case '\r':
+ buf[pos++] = '\\';
+ buf[pos++] = 'r';
+ break;
+ case '\t':
+ buf[pos++] = '\\';
+ buf[pos++] = 't';
+ break;
+ case '\\':
+ buf[pos++] = '\\';
+ buf[pos++] = '\\';
+ break;
+ case '"':
+ buf[pos++] = '\\';
+ buf[pos++] = '"';
+ break;
+ default:
+ if ((pos + 6) >= len) {
+ buf[pos] = '\0';
+ return (char *)p;
+ }
+ buf[pos++] = '\\';
+ buf[pos++] = 'u';
+ buf[pos++] = '0';
+ buf[pos++] = '0';
+ buf[pos++] = json_hex_chars[(*p) >> 4];
+ buf[pos++] = json_hex_chars[(*p) & 0xf];
+ break;
+ }
+ }
+ buf[pos] = '\0';
+ return (char *)p;
+}
-void
-gf_log_lock (void)
+/**
+ * gf_syslog -function to submit message to syslog specific to gluster
+ * @error_code: error code defined by log book
+ * @facility_priority: facility_priority of syslog()
+ * @format: optional format string to syslog()
+ *
+ * @return: void
+ */
+void
+gf_syslog (int error_code, int facility_priority, char *format, ...)
{
- pthread_mutex_lock (&logfile_mutex);
+ char *msg = NULL;
+ char json_msg[GF_JSON_MSG_LENGTH];
+ GF_UNUSED char *p = NULL;
+ const char *error_message = NULL;
+ char json_error_message[GF_JSON_MSG_LENGTH];
+ va_list ap;
+
+ error_message = gf_get_error_message (error_code);
+
+ va_start (ap, format);
+ if (format) {
+ vasprintf (&msg, format, ap);
+ p = _json_escape (msg, json_msg, GF_JSON_MSG_LENGTH);
+ if (error_message) {
+ p = _json_escape (error_message, json_error_message,
+ GF_JSON_MSG_LENGTH);
+ syslog (facility_priority, GF_SYSLOG_CEE_FORMAT,
+ json_msg, error_code, json_error_message);
+ } else {
+ /* ignore the error code because no error message for it
+ and use normal syslog */
+ syslog (facility_priority, "%s", msg);
+ }
+ free (msg);
+ } else {
+ if (error_message) {
+ /* no user message: treat error_message as msg */
+ syslog (facility_priority, GF_SYSLOG_CEE_FORMAT,
+ json_error_message, error_code,
+ json_error_message);
+ } else {
+ /* cannot produce log as neither error_message nor
+ msg available */
+ }
+ }
+ va_end (ap);
}
+#endif /* GF_USE_SYSLOG */
-
-void
-gf_log_unlock (void)
+void
+gf_log_globals_init (void *data)
{
- pthread_mutex_unlock (&logfile_mutex);
+ glusterfs_ctx_t *ctx = data;
+
+ pthread_mutex_init (&ctx->log.logfile_mutex, NULL);
+
+ ctx->log.loglevel = GF_LOG_INFO;
+ ctx->log.gf_log_syslog = 1;
+ ctx->log.sys_log_level = GF_LOG_CRITICAL;
+
+#ifndef GF_USE_SYSLOG
+#ifdef GF_LINUX_HOST_OS
+ /* For the 'syslog' output. one can grep 'GlusterFS' in syslog
+ for serious logs */
+ openlog ("GlusterFS", LOG_PID, LOG_DAEMON);
+#endif
+#endif
}
+int
+gf_log_init (void *data, const char *file, const char *ident)
+{
+ glusterfs_ctx_t *ctx = NULL;
+ int fd = -1;
+
+ ctx = data;
+
+#if defined(GF_USE_SYSLOG)
+ {
+ /* use default ident and option */
+ /* TODO: make FACILITY configurable than LOG_DAEMON */
+ struct stat buf;
+
+ if (stat (GF_LOG_CONTROL_FILE, &buf) == 0) {
+ /* use syslog logging */
+ ctx->log.log_control_file_found = 1;
+ if (ident) {
+ /* we need to keep this value as */
+ /* syslog uses it on every logging */
+ ctx->log.ident = gf_strdup (ident);
+ gf_openlog (ctx->log.ident, -1, LOG_DAEMON);
+ } else {
+ gf_openlog (NULL, -1, LOG_DAEMON);
+ }
+ } else {
+ /* use old style logging */
+ ctx->log.log_control_file_found = 0;
+ }
+ }
+#endif
+
+ if (!file){
+ fprintf (stderr, "ERROR: no filename specified\n");
+ return -1;
+ }
+
+ if (strcmp (file, "-") == 0) {
+ ctx->log.gf_log_logfile = stderr;
+ ctx->log.logfile = stderr;
+ return 0;
+ }
+
+ ctx->log.filename = gf_strdup (file);
+ if (!ctx->log.filename) {
+ fprintf (stderr, "ERROR: updating log-filename failed: %s\n",
+ strerror (errno));
+ return -1;
+ }
+
+ fd = open (file, O_CREAT | O_RDONLY, S_IRUSR | S_IWUSR);
+ if (fd < 0) {
+ fprintf (stderr, "ERROR: failed to create logfile \"%s\" (%s)\n",
+ file, strerror (errno));
+ return -1;
+ }
+ close (fd);
+
+ ctx->log.logfile = fopen (file, "a");
+ if (!ctx->log.logfile){
+ fprintf (stderr, "ERROR: failed to open logfile \"%s\" (%s)\n",
+ file, strerror (errno));
+ return -1;
+ }
+
+ ctx->log.gf_log_logfile = ctx->log.logfile;
+
+ return 0;
+}
void
-gf_log_cleanup (void)
+set_sys_log_level (gf_loglevel_t level)
{
- pthread_mutex_destroy (&logfile_mutex);
+ THIS->ctx->log.sys_log_level = level;
}
int
+_gf_log_nomem (const char *domain, const char *file,
+ const char *function, int line, gf_loglevel_t level,
+ size_t size)
+{
+ const char *basename = NULL;
+ xlator_t *this = NULL;
+ struct timeval tv = {0,};
+ int ret = 0;
+ char msg[8092] = {0,};
+ char timestr[256] = {0,};
+ char callstr[4096] = {0,};
+ glusterfs_ctx_t *ctx = NULL;
+
+ this = THIS;
+ ctx = this->ctx;
+
+ if (ctx->log.gf_log_xl_log_set) {
+ if (this->loglevel && (level > this->loglevel))
+ goto out;
+ }
+ if (level > ctx->log.loglevel)
+ goto out;
+
+ static char *level_strings[] = {"", /* NONE */
+ "M", /* EMERGENCY */
+ "A", /* ALERT */
+ "C", /* CRITICAL */
+ "E", /* ERROR */
+ "W", /* WARNING */
+ "N", /* NOTICE */
+ "I", /* INFO */
+ "D", /* DEBUG */
+ "T", /* TRACE */
+ ""};
+
+ if (!domain || !file || !function) {
+ fprintf (stderr,
+ "logging: %s:%s():%d: invalid argument\n",
+ __FILE__, __PRETTY_FUNCTION__, __LINE__);
+ return -1;
+ }
+
+ basename = strrchr (file, '/');
+ if (basename)
+ basename++;
+ else
+ basename = file;
+
+#if HAVE_BACKTRACE
+ /* Print 'calling function' */
+ do {
+ void *array[5];
+ char **callingfn = NULL;
+ size_t bt_size = 0;
+
+ bt_size = backtrace (array, 5);
+ if (bt_size)
+ callingfn = backtrace_symbols (&array[2], bt_size-2);
+ if (!callingfn)
+ break;
+
+ if (bt_size == 5)
+ snprintf (callstr, 4096, "(-->%s (-->%s (-->%s)))",
+ callingfn[2], callingfn[1], callingfn[0]);
+ if (bt_size == 4)
+ snprintf (callstr, 4096, "(-->%s (-->%s))",
+ callingfn[1], callingfn[0]);
+ if (bt_size == 3)
+ snprintf (callstr, 4096, "(-->%s)", callingfn[0]);
+
+ free (callingfn);
+ } while (0);
+#endif /* HAVE_BACKTRACE */
+
+#if defined(GF_USE_SYSLOG)
+ if (ctx->log.log_control_file_found)
+ {
+ int priority;
+ /* treat GF_LOG_TRACE and GF_LOG_NONE as LOG_DEBUG and
+ other level as is */
+ if (GF_LOG_TRACE == level || GF_LOG_NONE == level) {
+ priority = LOG_DEBUG;
+ } else {
+ priority = level - 1;
+ }
+ gf_syslog (GF_ERR_DEV, priority,
+ "[%s:%d:%s] %s %s: no memory "
+ "available for size (%"GF_PRI_SIZET")",
+ basename, line, function, callstr, domain,
+ size);
+ goto out;
+ }
+#endif /* GF_USE_SYSLOG */
+ ret = gettimeofday (&tv, NULL);
+ if (-1 == ret)
+ goto out;
+ gf_time_fmt (timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT);
+ snprintf (timestr + strlen (timestr), sizeof timestr - strlen (timestr),
+ ".%"GF_PRI_SUSECONDS, tv.tv_usec);
+
+ ret = sprintf (msg, "[%s] %s [%s:%d:%s] %s %s: no memory "
+ "available for size (%"GF_PRI_SIZET")",
+ timestr, level_strings[level],
+ basename, line, function, callstr,
+ domain, size);
+ if (-1 == ret) {
+ goto out;
+ }
+
+ pthread_mutex_lock (&ctx->log.logfile_mutex);
+ {
+ if (ctx->log.logfile) {
+ fprintf (ctx->log.logfile, "%s\n", msg);
+ } else {
+ fprintf (stderr, "%s\n", msg);
+ }
+
+#ifdef GF_LINUX_HOST_OS
+ /* We want only serious log in 'syslog', not our debug
+ and trace logs */
+ if (ctx->log.gf_log_syslog && level &&
+ (level <= ctx->log.sys_log_level))
+ syslog ((level-1), "%s\n", msg);
+#endif
+ }
+
+ pthread_mutex_unlock (&ctx->log.logfile_mutex);
+out:
+ return ret;
+ }
+
+int
_gf_log_callingfn (const char *domain, const char *file, const char *function,
int line, gf_loglevel_t level, const char *fmt, ...)
{
- const char *basename = NULL;
- struct tm *tm = NULL;
+ const char *basename = NULL;
xlator_t *this = NULL;
char *str1 = NULL;
char *str2 = NULL;
char *msg = NULL;
- char timestr[256] = {0,};
- char callstr[4096] = {0,};
+ char timestr[256] = {0,};
+ char callstr[4096] = {0,};
struct timeval tv = {0,};
size_t len = 0;
int ret = 0;
- gf_loglevel_t xlator_loglevel = 0;
- va_list ap;
-
- if (!logfile)
- return -1;
+ va_list ap;
+ glusterfs_ctx_t *ctx = NULL;
this = THIS;
+ ctx = this->ctx;
- xlator_loglevel = this->loglevel;
- if (xlator_loglevel == 0)
- xlator_loglevel = loglevel;
-
- if (level > xlator_loglevel)
+ if (ctx->log.gf_log_xl_log_set) {
+ if (this->loglevel && (level > this->loglevel))
+ goto out;
+ }
+ if (level > ctx->log.loglevel)
goto out;
- static char *level_strings[] = {"", /* NONE */
+ static char *level_strings[] = {"", /* NONE */
"M", /* EMERGENCY */
"A", /* ALERT */
- "C", /* CRITICAL */
- "E", /* ERROR */
- "W", /* WARNING */
- "N", /* NOTICE */
- "I", /* INFO/NORMAL */
- "D", /* DEBUG */
+ "C", /* CRITICAL */
+ "E", /* ERROR */
+ "W", /* WARNING */
+ "N", /* NOTICE */
+ "I", /* INFO */
+ "D", /* DEBUG */
"T", /* TRACE */
- ""};
+ ""};
- if (!domain || !file || !function || !fmt) {
- fprintf (stderr,
- "logging: %s:%s():%d: invalid argument\n",
- __FILE__, __PRETTY_FUNCTION__, __LINE__);
- return -1;
- }
+ if (!domain || !file || !function || !fmt) {
+ fprintf (stderr,
+ "logging: %s:%s():%d: invalid argument\n",
+ __FILE__, __PRETTY_FUNCTION__, __LINE__);
+ return -1;
+ }
+
+ basename = strrchr (file, '/');
+ if (basename)
+ basename++;
+ else
+ basename = file;
#if HAVE_BACKTRACE
- /* Print 'calling function' */
- do {
- void *array[5];
+ /* Print 'calling function' */
+ do {
+ void *array[5];
char **callingfn = NULL;
- size_t size = 0;
+ size_t size = 0;
- size = backtrace (array, 5);
+ size = backtrace (array, 5);
if (size)
callingfn = backtrace_symbols (&array[2], size-2);
if (!callingfn)
@@ -264,322 +618,355 @@ _gf_log_callingfn (const char *domain, const char *file, const char *function,
snprintf (callstr, 4096, "(-->%s)", callingfn[0]);
free (callingfn);
- } while (0);
+ } while (0);
#endif /* HAVE_BACKTRACE */
+#if defined(GF_USE_SYSLOG)
+ if (ctx->log.log_control_file_found)
+ {
+ int priority;
+ /* treat GF_LOG_TRACE and GF_LOG_NONE as LOG_DEBUG and
+ other level as is */
+ if (GF_LOG_TRACE == level || GF_LOG_NONE == level) {
+ priority = LOG_DEBUG;
+ } else {
+ priority = level - 1;
+ }
+
+ va_start (ap, fmt);
+ vasprintf (&str2, fmt, ap);
+ va_end (ap);
+
+ gf_syslog (GF_ERR_DEV, priority,
+ "[%s:%d:%s] %s %d-%s: %s",
+ basename, line, function,
+ callstr,
+ ((this->graph) ? this->graph->id:0), domain,
+ str2);
+
+ goto out;
+ }
+#endif /* GF_USE_SYSLOG */
ret = gettimeofday (&tv, NULL);
if (-1 == ret)
goto out;
+ va_start (ap, fmt);
+ gf_time_fmt (timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT);
+ snprintf (timestr + strlen (timestr), sizeof timestr - strlen (timestr),
+ ".%"GF_PRI_SUSECONDS, tv.tv_usec);
- tm = localtime (&tv.tv_sec);
+ ret = gf_asprintf (&str1, "[%s] %s [%s:%d:%s] %s %d-%s: ",
+ timestr, level_strings[level],
+ basename, line, function, callstr,
+ ((this->graph) ? this->graph->id:0), domain);
+ if (-1 == ret) {
+ goto out;
+ }
- pthread_mutex_lock (&logfile_mutex);
- {
- va_start (ap, fmt);
+ ret = vasprintf (&str2, fmt, ap);
+ if (-1 == ret) {
+ goto out;
+ }
- strftime (timestr, 256, "%Y-%m-%d %H:%M:%S", tm);
- snprintf (timestr + strlen (timestr), 256 - strlen (timestr),
- ".%"GF_PRI_SUSECONDS, tv.tv_usec);
+ va_end (ap);
- basename = strrchr (file, '/');
- if (basename)
- basename++;
- else
- basename = file;
+ len = strlen (str1);
+ msg = GF_MALLOC (len + strlen (str2) + 1, gf_common_mt_char);
- ret = gf_asprintf (&str1, "[%s] %s [%s:%d:%s] %s %s: ",
- timestr, level_strings[level],
- basename, line, function, callstr,
- domain);
- if (-1 == ret) {
- goto unlock;
- }
+ strcpy (msg, str1);
+ strcpy (msg + len, str2);
- ret = vasprintf (&str2, fmt, ap);
- if (-1 == ret) {
- goto unlock;
+ pthread_mutex_lock (&ctx->log.logfile_mutex);
+ {
+ if (ctx->log.logfile) {
+ fprintf (ctx->log.logfile, "%s\n", msg);
+ } else {
+ fprintf (stderr, "%s\n", msg);
}
- va_end (ap);
-
- len = strlen (str1);
- msg = GF_MALLOC (len + strlen (str2) + 1, gf_common_mt_char);
-
- strcpy (msg, str1);
- strcpy (msg + len, str2);
-
- fprintf (logfile, "%s\n", msg);
- fflush (logfile);
-
#ifdef GF_LINUX_HOST_OS
/* We want only serious log in 'syslog', not our debug
and trace logs */
- if (gf_log_syslog && level && (level <= GF_LOG_ERROR))
+ if (ctx->log.gf_log_syslog && level &&
+ (level <= ctx->log.sys_log_level))
syslog ((level-1), "%s\n", msg);
#endif
- }
+ }
-unlock:
- pthread_mutex_unlock (&logfile_mutex);
+ pthread_mutex_unlock (&ctx->log.logfile_mutex);
- if (msg) {
- GF_FREE (msg);
- }
+out:
+ GF_FREE (msg);
- if (str1)
- GF_FREE (str1);
+ GF_FREE (str1);
- if (str2)
- FREE (str2);
+ FREE (str2);
-out:
return ret;
}
int
_gf_log (const char *domain, const char *file, const char *function, int line,
- gf_loglevel_t level, const char *fmt, ...)
+ gf_loglevel_t level, const char *fmt, ...)
{
- const char *basename = NULL;
- FILE *new_logfile = NULL;
- va_list ap;
- struct tm *tm = NULL;
- char timestr[256];
+ const char *basename = NULL;
+ FILE *new_logfile = NULL;
+ va_list ap;
+ char timestr[256] = {0,};
struct timeval tv = {0,};
-
- char *str1 = NULL;
- char *str2 = NULL;
- char *msg = NULL;
- size_t len = 0;
- int ret = 0;
- xlator_t *this = NULL;
- gf_loglevel_t xlator_loglevel = 0;
-
- if (!logfile)
- return -1;
+ char *str1 = NULL;
+ char *str2 = NULL;
+ char *msg = NULL;
+ size_t len = 0;
+ int ret = 0;
+ int fd = -1;
+ xlator_t *this = NULL;
+ glusterfs_ctx_t *ctx = NULL;
this = THIS;
+ ctx = this->ctx;
- xlator_loglevel = this->loglevel;
- if (xlator_loglevel == 0)
- xlator_loglevel = loglevel;
-
- if (level > xlator_loglevel)
+ if (ctx->log.gf_log_xl_log_set) {
+ if (this->loglevel && (level > this->loglevel))
+ goto out;
+ }
+ if (level > ctx->log.loglevel)
goto out;
- static char *level_strings[] = {"", /* NONE */
+ static char *level_strings[] = {"", /* NONE */
"M", /* EMERGENCY */
"A", /* ALERT */
- "C", /* CRITICAL */
- "E", /* ERROR */
- "W", /* WARNING */
- "N", /* NOTICE */
- "I", /* INFO/NORMAL */
- "D", /* DEBUG */
+ "C", /* CRITICAL */
+ "E", /* ERROR */
+ "W", /* WARNING */
+ "N", /* NOTICE */
+ "I", /* INFO */
+ "D", /* DEBUG */
"T", /* TRACE */
- ""};
+ ""};
- if (!domain || !file || !function || !fmt) {
- fprintf (stderr,
- "logging: %s:%s():%d: invalid argument\n",
- __FILE__, __PRETTY_FUNCTION__, __LINE__);
- return -1;
- }
+ if (!domain || !file || !function || !fmt) {
+ fprintf (stderr,
+ "logging: %s:%s():%d: invalid argument\n",
+ __FILE__, __PRETTY_FUNCTION__, __LINE__);
+ return -1;
+ }
+ basename = strrchr (file, '/');
+ if (basename)
+ basename++;
+ else
+ basename = file;
+
+#if defined(GF_USE_SYSLOG)
+ if (ctx->log.log_control_file_found)
+ {
+ int priority;
+ /* treat GF_LOG_TRACE and GF_LOG_NONE as LOG_DEBUG and
+ other level as is */
+ if (GF_LOG_TRACE == level || GF_LOG_NONE == level) {
+ priority = LOG_DEBUG;
+ } else {
+ priority = level - 1;
+ }
- if (logrotate) {
- logrotate = 0;
+ va_start (ap, fmt);
+ vasprintf (&str2, fmt, ap);
+ va_end (ap);
- new_logfile = fopen (filename, "a");
- if (!new_logfile) {
- gf_log ("logrotate", GF_LOG_CRITICAL,
- "failed to open logfile %s (%s)",
- filename, strerror (errno));
- goto log;
- }
+ gf_syslog (GF_ERR_DEV, priority,
+ "[%s:%d:%s] %d-%s: %s",
+ basename, line, function,
+ ((this->graph) ? this->graph->id:0), domain, str2);
+ goto err;
+ }
+#endif /* GF_USE_SYSLOG */
+
+ if (ctx->log.logrotate) {
+ ctx->log.logrotate = 0;
+
+ fd = open (ctx->log.filename,
+ O_CREAT | O_RDONLY, S_IRUSR | S_IWUSR);
+ if (fd < 0) {
+ gf_log ("logrotate", GF_LOG_ERROR,
+ "%s", strerror (errno));
+ return -1;
+ }
+ close (fd);
+
+ new_logfile = fopen (ctx->log.filename, "a");
+ if (!new_logfile) {
+ gf_log ("logrotate", GF_LOG_CRITICAL,
+ "failed to open logfile %s (%s)",
+ ctx->log.filename, strerror (errno));
+ goto log;
+ }
- fclose (logfile);
- gf_log_logfile = logfile = new_logfile;
- }
+ pthread_mutex_lock (&ctx->log.logfile_mutex);
+ {
+ if (ctx->log.logfile)
+ fclose (ctx->log.logfile);
+
+ ctx->log.gf_log_logfile = ctx->log.logfile = new_logfile;
+ }
+ pthread_mutex_unlock (&ctx->log.logfile_mutex);
+
+ }
log:
ret = gettimeofday (&tv, NULL);
if (-1 == ret)
goto out;
+ va_start (ap, fmt);
+ gf_time_fmt (timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT);
+ snprintf (timestr + strlen (timestr), sizeof timestr - strlen (timestr),
+ ".%"GF_PRI_SUSECONDS, tv.tv_usec);
- tm = localtime (&tv.tv_sec);
-
- pthread_mutex_lock (&logfile_mutex);
- {
- va_start (ap, fmt);
-
- strftime (timestr, 256, "%Y-%m-%d %H:%M:%S", tm);
- snprintf (timestr + strlen (timestr), 256 - strlen (timestr),
- ".%"GF_PRI_SUSECONDS, tv.tv_usec);
-
- basename = strrchr (file, '/');
- if (basename)
- basename++;
- else
- basename = file;
+ ret = gf_asprintf (&str1, "[%s] %s [%s:%d:%s] %d-%s: ",
+ timestr, level_strings[level],
+ basename, line, function,
+ ((this->graph)?this->graph->id:0), domain);
+ if (-1 == ret) {
+ goto err;
+ }
- ret = gf_asprintf (&str1, "[%s] %s [%s:%d:%s] %s: ",
- timestr, level_strings[level],
- basename, line, function,
- domain);
- if (-1 == ret) {
- goto unlock;
- }
+ ret = vasprintf (&str2, fmt, ap);
+ if (-1 == ret) {
+ goto err;
+ }
- ret = vasprintf (&str2, fmt, ap);
- if (-1 == ret) {
- goto unlock;
- }
+ va_end (ap);
- va_end (ap);
+ len = strlen (str1);
+ msg = GF_MALLOC (len + strlen (str2) + 1, gf_common_mt_char);
- len = strlen (str1);
- msg = GF_MALLOC (len + strlen (str2) + 1, gf_common_mt_char);
+ strcpy (msg, str1);
+ strcpy (msg + len, str2);
- strcpy (msg, str1);
- strcpy (msg + len, str2);
+ pthread_mutex_lock (&ctx->log.logfile_mutex);
+ {
- fprintf (logfile, "%s\n", msg);
- fflush (logfile);
+ if (ctx->log.logfile) {
+ fprintf (ctx->log.logfile, "%s\n", msg);
+ fflush (ctx->log.logfile);
+ } else {
+ fprintf (stderr, "%s\n", msg);
+ fflush (stderr);
+ }
#ifdef GF_LINUX_HOST_OS
/* We want only serious log in 'syslog', not our debug
and trace logs */
- if (gf_log_syslog && level && (level <= GF_LOG_ERROR))
+ if (ctx->log.gf_log_syslog && level &&
+ (level <= ctx->log.sys_log_level))
syslog ((level-1), "%s\n", msg);
#endif
- }
+ }
-unlock:
- pthread_mutex_unlock (&logfile_mutex);
+ pthread_mutex_unlock (&ctx->log.logfile_mutex);
- if (msg) {
- if ((ret != -1) && __central_log_enabled &&
- ((glusterfs_central_log_flag_get ()) == 0)) {
+err:
+ GF_FREE (msg);
- glusterfs_central_log_flag_set ();
- {
- //gf_log_central (msg);
- }
- glusterfs_central_log_flag_unset ();
- }
- GF_FREE (msg);
- }
+ GF_FREE (str1);
- if (str1)
- GF_FREE (str1);
-
- if (str2)
- FREE (str2);
+ FREE (str2);
out:
- return (0);
+ return (0);
}
-
-struct _client_log {
- char *identifier;
- FILE *file;
- struct list_head list;
-};
-
-struct _client_log *client_logs = NULL;
-
-
-static void
-client_log_init (struct _client_log *cl, char *identifier)
+int
+_gf_log_eh (const char *function, const char *fmt, ...)
{
- int ret = 0;
- char *path = NULL;
+ int ret = -1;
+ va_list ap;
+ char *str1 = NULL;
+ char *str2 = NULL;
+ char *msg = NULL;
+ xlator_t *this = NULL;
- cl->identifier = identifier;
+ this = THIS;
- ret = gf_asprintf (&path, "%s.client-%s", filename, identifier);
+ ret = gf_asprintf (&str1, "[%d] %s: ",
+ ((this->graph)?this->graph->id:0),
+ function);
if (-1 == ret) {
- return;
+ goto out;
}
- cl->file = fopen (path, "a");
- GF_FREE (path);
-
- INIT_LIST_HEAD (&cl->list);
-}
+ va_start (ap, fmt);
-static FILE *
-__logfile_for_client (char *identifier)
-{
- struct _client_log *client = NULL;
-
- if (!client_logs) {
- client = GF_CALLOC (1, sizeof (*client),
- gf_common_mt_client_log);
- if (!client)
- return NULL;
+ ret = vasprintf (&str2, fmt, ap);
+ if (-1 == ret) {
+ goto out;
+ }
- client_log_init (client, identifier);
+ va_end (ap);
- client_logs = client;
+ msg = GF_MALLOC (strlen (str1) + strlen (str2) + 1, gf_common_mt_char);
+ if (!msg) {
+ ret = -1;
+ goto out;
}
- list_for_each_entry (client, &client_logs->list, list) {
- if (!strcmp (client->identifier, identifier))
- break;
- }
+ strcpy (msg, str1);
+ strcat (msg, str2);
- if (!client) {
- client = GF_CALLOC (1, sizeof (*client),
- gf_common_mt_client_log);
- if (!client)
- return NULL;
+ ret = eh_save_history (this->history, msg);
- client_log_init (client, identifier);
+out:
+ GF_FREE (str1);
- list_add_tail (&client->list, &client_logs->list);
- }
+ /* Use FREE instead of GF_FREE since str2 was allocated by vasprintf */
+ if (str2)
+ FREE (str2);
- return client->file;
+ return ret;
}
-
int
-gf_log_from_client (const char *msg, char *identifier)
+gf_cmd_log_init (const char *filename)
{
- FILE *client_log = NULL;
-
- client_log = __logfile_for_client (identifier);
+ int fd = -1;
+ xlator_t *this = NULL;
+ glusterfs_ctx_t *ctx = NULL;
- fprintf (client_log, "%s\n", msg);
- fflush (client_log);
-
- return 0;
-}
+ this = THIS;
+ ctx = this->ctx;
-int
-gf_cmd_log_init (const char *filename)
-{
if (!filename){
- gf_log ("glusterd",GF_LOG_CRITICAL, "gf_cmd_log_init: no "
+ gf_log (this->name, GF_LOG_CRITICAL, "gf_cmd_log_init: no "
"filename specified\n");
return -1;
}
- cmd_log_filename = gf_strdup (filename);
- if (!filename) {
- gf_log ("glusterd",GF_LOG_CRITICAL, "gf_cmd_log_init: strdup"
- " error\n");
+ ctx->log.cmd_log_filename = gf_strdup (filename);
+ if (!ctx->log.cmd_log_filename) {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "gf_cmd_log_init: strdup error\n");
return -1;
}
+ /* close and reopen cmdlogfile for log rotate*/
+ if (ctx->log.cmdlogfile) {
+ fclose (ctx->log.cmdlogfile);
+ ctx->log.cmdlogfile = NULL;
+ }
- cmdlogfile = fopen (cmd_log_filename, "a");
- if (!cmdlogfile){
- gf_log ("glusterd", GF_LOG_CRITICAL,
- "gf_cmd_log_init: failed to open logfile \"%s\" "
- "(%s)\n", cmd_log_filename, strerror (errno));
+ fd = open (ctx->log.cmd_log_filename,
+ O_CREAT | O_RDONLY, S_IRUSR | S_IWUSR);
+ if (fd < 0) {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "%s", strerror (errno));
+ return -1;
+ }
+ close (fd);
+
+ ctx->log.cmdlogfile = fopen (ctx->log.cmd_log_filename, "a");
+ if (!ctx->log.cmdlogfile){
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "gf_cmd_log_init: failed to open logfile \"%s\" "
+ "(%s)\n", ctx->log.cmd_log_filename, strerror (errno));
return -1;
}
return 0;
@@ -588,46 +975,44 @@ gf_cmd_log_init (const char *filename)
int
gf_cmd_log (const char *domain, const char *fmt, ...)
{
- va_list ap;
- struct tm *tm = NULL;
- char timestr[256];
+ va_list ap;
+ char timestr[64];
struct timeval tv = {0,};
- char *str1 = NULL;
- char *str2 = NULL;
- char *msg = NULL;
- size_t len = 0;
- int ret = 0;
-
- if (!cmdlogfile)
+ char *str1 = NULL;
+ char *str2 = NULL;
+ char *msg = NULL;
+ size_t len = 0;
+ int ret = 0;
+ glusterfs_ctx_t *ctx = NULL;
+
+ ctx = THIS->ctx;
+ if (!ctx->log.cmdlogfile)
return -1;
if (!domain || !fmt) {
gf_log ("glusterd", GF_LOG_TRACE,
- "logging: invalid argument\n");
+ "logging: invalid argument\n");
return -1;
}
ret = gettimeofday (&tv, NULL);
if (ret == -1)
goto out;
-
- tm = localtime (&tv.tv_sec);
-
va_start (ap, fmt);
- strftime (timestr, 256, "%Y-%m-%d %H:%M:%S", tm);
+ gf_time_fmt (timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT);
snprintf (timestr + strlen (timestr), 256 - strlen (timestr),
".%"GF_PRI_SUSECONDS, tv.tv_usec);
ret = gf_asprintf (&str1, "[%s] %s : ",
- timestr, domain);
+ timestr, domain);
if (ret == -1) {
- goto out;
+ goto out;
}
ret = vasprintf (&str2, fmt, ap);
if (ret == -1) {
- goto out;
+ goto out;
}
va_end (ap);
@@ -638,20 +1023,15 @@ gf_cmd_log (const char *domain, const char *fmt, ...)
strcpy (msg, str1);
strcpy (msg + len, str2);
- fprintf (cmdlogfile, "%s\n", msg);
- fflush (cmdlogfile);
+ fprintf (ctx->log.cmdlogfile, "%s\n", msg);
+ fflush (ctx->log.cmdlogfile);
out:
- if (msg) {
- GF_FREE (msg);
- }
+ GF_FREE (msg);
- if (str1)
- GF_FREE (str1);
+ GF_FREE (str1);
- if (str2)
- FREE (str2);
+ FREE (str2);
return (0);
-
}
diff --git a/libglusterfs/src/logging.h b/libglusterfs/src/logging.h
index 39fdff155..cc806a767 100644
--- a/libglusterfs/src/logging.h
+++ b/libglusterfs/src/logging.h
@@ -1,22 +1,12 @@
/*
- Copyright (c) 2006-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
+ 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.
+*/
#ifndef __LOGGING_H__
#define __LOGGING_H__
@@ -29,21 +19,23 @@
#include <stdint.h>
#include <stdio.h>
#include <stdarg.h>
+#include <pthread.h>
#ifdef GF_DARWIN_HOST_OS
#define GF_PRI_FSBLK "u"
#define GF_PRI_DEV PRId32
#define GF_PRI_NLINK PRIu16
-#define GF_PRI_SUSECONDS PRId32
+#define GF_PRI_SUSECONDS "06d"
#else
#define GF_PRI_FSBLK PRIu64
#define GF_PRI_DEV PRIu64
#define GF_PRI_NLINK PRIu32
-#define GF_PRI_SUSECONDS "ld"
+#define GF_PRI_SUSECONDS "06ld"
#endif
#define GF_PRI_BLKSIZE PRId32
#define GF_PRI_SIZET "zu"
+
#if 0
/* Syslog definitions :-) */
#define LOG_EMERG 0 /* system is unusable */
@@ -57,62 +49,95 @@
#endif
typedef enum {
- GF_LOG_NONE,
+ GF_LOG_NONE,
GF_LOG_EMERG,
GF_LOG_ALERT,
- GF_LOG_CRITICAL, /* fatal errors */
- GF_LOG_ERROR, /* major failures (not necessarily fatal) */
- GF_LOG_WARNING, /* info about normal operation */
+ GF_LOG_CRITICAL, /* fatal errors */
+ GF_LOG_ERROR, /* major failures (not necessarily fatal) */
+ GF_LOG_WARNING, /* info about normal operation */
GF_LOG_NOTICE,
- GF_LOG_INFO, /* Normal information */
-#define GF_LOG_NORMAL GF_LOG_INFO
- GF_LOG_DEBUG, /* internal errors */
+ GF_LOG_INFO, /* Normal information */
+ GF_LOG_DEBUG, /* internal errors */
GF_LOG_TRACE, /* full trace of operation */
} gf_loglevel_t;
-#define GF_LOG_MAX GF_LOG_DEBUG
+#define DEFAULT_LOG_FILE_DIRECTORY DATADIR "/log/glusterfs"
+#define DEFAULT_LOG_LEVEL GF_LOG_INFO
+
+typedef struct gf_log_handle_ {
+ pthread_mutex_t logfile_mutex;
+ uint8_t logrotate;
+ gf_loglevel_t loglevel;
+ int gf_log_syslog;
+ gf_loglevel_t sys_log_level;
+ char gf_log_xl_log_set;
+ char *filename;
+ FILE *logfile;
+ FILE *gf_log_logfile;
+ char *cmd_log_filename;
+ FILE *cmdlogfile;
+#ifdef GF_USE_SYSLOG
+ int log_control_file_found;
+ char *ident;
+#endif /* GF_USE_SYSLOG */
+
+} gf_log_handle_t;
+
+void gf_log_globals_init (void *ctx);
+int gf_log_init (void *data, const char *filename, const char *ident);
+
+void gf_log_logrotate (int signum);
+
+void gf_log_cleanup (void);
+
+int _gf_log (const char *domain, const char *file,
+ const char *function, int32_t line, gf_loglevel_t level,
+ const char *fmt, ...)
+ __attribute__ ((__format__ (__printf__, 6, 7)));
+int _gf_log_callingfn (const char *domain, const char *file,
+ const char *function, int32_t line, gf_loglevel_t level,
+ const char *fmt, ...)
+ __attribute__ ((__format__ (__printf__, 6, 7)));
+
+int _gf_log_nomem (const char *domain, const char *file,
+ const char *function, int line, gf_loglevel_t level,
+ size_t size);
-extern gf_loglevel_t gf_log_loglevel;
-extern char gf_log_xl_log_set;
+int _gf_log_eh (const char *function, const char *fmt, ...);
-#define gf_log(dom, levl, fmt...) do { \
- if ((levl > gf_log_loglevel) && !gf_log_xl_log_set) \
- break; \
+
+
+#define FMT_WARN(fmt...) do { if (0) printf (fmt); } while (0)
+
+#define gf_log(dom, levl, fmt...) do { \
+ FMT_WARN (fmt); \
_gf_log (dom, __FILE__, __FUNCTION__, __LINE__, \
levl, ##fmt); \
} while (0)
+#define gf_log_eh(fmt...) do { \
+ FMT_WARN (fmt); \
+ _gf_log_eh (__FUNCTION__, ##fmt); \
+ } while (0)
+
#define gf_log_callingfn(dom, levl, fmt...) do { \
- if ((levl > gf_log_loglevel) && !gf_log_xl_log_set) \
- break; \
+ FMT_WARN (fmt); \
_gf_log_callingfn (dom, __FILE__, __FUNCTION__, __LINE__, \
levl, ##fmt); \
} while (0)
-/* Log once in GF_UNIVERSAL_ANSWER times */
-#define GF_LOG_OCCASIONALLY(var, args...) if (!(var++%GF_UNIVERSAL_ANSWER)) { \
- gf_log (args); \
- }
-
-
-void
-gf_log_logrotate (int signum);
-
-int gf_log_init (const char *filename);
-void gf_log_cleanup (void);
-int
-_gf_log (const char *domain, const char *file, const char *function,
- int32_t line, gf_loglevel_t level, const char *fmt, ...);
-int
-_gf_log_callingfn (const char *domain, const char *file, const char *function,
- int32_t line, gf_loglevel_t level, const char *fmt, ...);
+/* No malloc or calloc should be called in this function */
+#define gf_log_nomem(dom, levl, size) do { \
+ _gf_log_nomem (dom, __FILE__, __FUNCTION__, __LINE__, \
+ levl, size); \
+ } while (0)
-int
-gf_log_from_client (const char *msg, char *identifier);
-void gf_log_lock (void);
-void gf_log_unlock (void);
+/* Log once in GF_UNIVERSAL_ANSWER times */
+#define GF_LOG_OCCASIONALLY(var, args...) if (!(var++%GF_UNIVERSAL_ANSWER)) { \
+ gf_log (args); \
+ }
void gf_log_disable_syslog (void);
void gf_log_enable_syslog (void);
@@ -121,18 +146,20 @@ void gf_log_set_loglevel (gf_loglevel_t level);
gf_loglevel_t gf_log_get_xl_loglevel (void *xl);
void gf_log_set_xl_loglevel (void *xl, gf_loglevel_t level);
-#define GF_DEBUG(xl, format, args...) \
- gf_log ((xl)->name, GF_LOG_DEBUG, format, ##args)
-#define GF_INFO(xl, format, args...) \
- gf_log ((xl)->name, GF_LOG_INFO, format, ##args)
-#define GF_WARNING(xl, format, args...) \
- gf_log ((xl)->name, GF_LOG_WARNING, format, ##args)
-#define GF_ERROR(xl, format, args...) \
- gf_log ((xl)->name, GF_LOG_ERROR, format, ##args)
+int gf_cmd_log (const char *domain, const char *fmt, ...)
+ __attribute__ ((__format__ (__printf__, 2, 3)));
+
+int gf_cmd_log_init (const char *filename);
+
+void set_sys_log_level (gf_loglevel_t level);
-int
-gf_cmd_log (const char *domain, const char *fmt, ...);
+#define GF_DEBUG(xl, format, args...) \
+ gf_log ((xl)->name, GF_LOG_DEBUG, format, ##args)
+#define GF_INFO(xl, format, args...) \
+ gf_log ((xl)->name, GF_LOG_INFO, format, ##args)
+#define GF_WARNING(xl, format, args...) \
+ gf_log ((xl)->name, GF_LOG_WARNING, format, ##args)
+#define GF_ERROR(xl, format, args...) \
+ gf_log ((xl)->name, GF_LOG_ERROR, format, ##args)
-int
-gf_cmd_log_init (const char *filename);
#endif /* __LOGGING_H__ */
diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c
index 17d2e0dd2..b901dd7a8 100644
--- a/libglusterfs/src/mem-pool.c
+++ b/libglusterfs/src/mem-pool.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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 "mem-pool.h"
@@ -24,45 +15,33 @@
#include <stdarg.h>
#define GF_MEM_POOL_LIST_BOUNDARY (sizeof(struct list_head))
-#define GF_MEM_POOL_PAD_BOUNDARY (GF_MEM_POOL_LIST_BOUNDARY + sizeof(int))
+#define GF_MEM_POOL_PTR (sizeof(struct mem_pool*))
+#define GF_MEM_POOL_PAD_BOUNDARY (GF_MEM_POOL_LIST_BOUNDARY + GF_MEM_POOL_PTR + sizeof(int))
#define mem_pool_chunkhead2ptr(head) ((head) + GF_MEM_POOL_PAD_BOUNDARY)
#define mem_pool_ptr2chunkhead(ptr) ((ptr) - GF_MEM_POOL_PAD_BOUNDARY)
#define is_mem_chunk_in_use(ptr) (*ptr == 1)
+#define mem_pool_from_ptr(ptr) ((ptr) + GF_MEM_POOL_LIST_BOUNDARY)
-#define GF_MEM_HEADER_SIZE (4 + sizeof (size_t) + sizeof (xlator_t *) + 4)
-#define GF_MEM_TRAILER_SIZE 4
+#define GF_MEM_HEADER_SIZE (4 + sizeof (size_t) + sizeof (xlator_t *) + 4 + 8)
+#define GF_MEM_TRAILER_SIZE 8
#define GF_MEM_HEADER_MAGIC 0xCAFEBABE
#define GF_MEM_TRAILER_MAGIC 0xBAADF00D
#define GLUSTERFS_ENV_MEM_ACCT_STR "GLUSTERFS_DISABLE_MEM_ACCT"
-static int gf_mem_acct_enable = 1;
-
-int
-gf_mem_acct_is_enabled ()
-{
- return gf_mem_acct_enable;
-}
-
void
-gf_mem_acct_enable_set ()
+gf_mem_acct_enable_set (void *data)
{
- char *opt = NULL;
- long val = -1;
+ glusterfs_ctx_t *ctx = NULL;
- opt = getenv (GLUSTERFS_ENV_MEM_ACCT_STR);
-
- if (!opt)
- return;
+ ctx = data;
- val = strtol (opt, NULL, 0);
+ GF_ASSERT (ctx);
- if (val)
- gf_mem_acct_enable = 0;
- else
- gf_mem_acct_enable = 1;
+ ctx->mem_acct_enable = 1;
+ return;
}
void
@@ -77,28 +56,23 @@ gf_mem_set_acct_info (xlator_t *xl, char **alloc_ptr,
ptr = (char *) (*alloc_ptr);
- if (!xl) {
- GF_ASSERT (0);
- }
+ GF_ASSERT (xl != NULL);
- if (!(xl->mem_acct.rec)) {
- GF_ASSERT (0);
- }
+ GF_ASSERT (xl->mem_acct.rec != NULL);
- if (type > xl->mem_acct.num_types) {
- GF_ASSERT (0);
- }
+ GF_ASSERT (type <= xl->mem_acct.num_types);
LOCK(&xl->mem_acct.rec[type].lock);
{
xl->mem_acct.rec[type].size += size;
xl->mem_acct.rec[type].num_allocs++;
+ xl->mem_acct.rec[type].total_allocs++;
xl->mem_acct.rec[type].max_size =
- max (xl->mem_acct.rec[type].max_size,
- xl->mem_acct.rec[type].size);
+ max (xl->mem_acct.rec[type].max_size,
+ xl->mem_acct.rec[type].size);
xl->mem_acct.rec[type].max_num_allocs =
- max (xl->mem_acct.rec[type].max_num_allocs,
- xl->mem_acct.rec[type].num_allocs);
+ max (xl->mem_acct.rec[type].max_num_allocs,
+ xl->mem_acct.rec[type].num_allocs);
}
UNLOCK(&xl->mem_acct.rec[type].lock);
@@ -110,6 +84,7 @@ gf_mem_set_acct_info (xlator_t *xl, char **alloc_ptr,
ptr += sizeof (xlator_t *);
*(uint32_t *)(ptr) = GF_MEM_HEADER_MAGIC;
ptr = ptr + 4;
+ ptr = ptr + 8; //padding
*(uint32_t *) (ptr + size) = GF_MEM_TRAILER_MAGIC;
*alloc_ptr = (void *)ptr;
@@ -125,7 +100,7 @@ __gf_calloc (size_t nmemb, size_t size, uint32_t type)
char *ptr = NULL;
xlator_t *xl = NULL;
- if (!gf_mem_acct_enable)
+ if (!THIS->ctx->mem_acct_enable)
return CALLOC (nmemb, size);
xl = THIS;
@@ -135,9 +110,10 @@ __gf_calloc (size_t nmemb, size_t size, uint32_t type)
ptr = calloc (1, tot_size);
- if (!ptr)
+ if (!ptr) {
+ gf_log_nomem ("", GF_LOG_ALERT, tot_size);
return NULL;
-
+ }
gf_mem_set_acct_info (xl, &ptr, req_size, type);
return (void *)ptr;
@@ -150,7 +126,7 @@ __gf_malloc (size_t size, uint32_t type)
char *ptr = NULL;
xlator_t *xl = NULL;
- if (!gf_mem_acct_enable)
+ if (!THIS->ctx->mem_acct_enable)
return MALLOC (size);
xl = THIS;
@@ -158,9 +134,10 @@ __gf_malloc (size_t size, uint32_t type)
tot_size = size + GF_MEM_HEADER_SIZE + GF_MEM_TRAILER_SIZE;
ptr = malloc (tot_size);
- if (!ptr)
+ if (!ptr) {
+ gf_log_nomem ("", GF_LOG_ALERT, tot_size);
return NULL;
-
+ }
gf_mem_set_acct_info (xl, &ptr, size, type);
return (void *)ptr;
@@ -174,10 +151,12 @@ __gf_realloc (void *ptr, size_t size)
xlator_t *xl = NULL;
uint32_t type = 0;
+ if (!THIS->ctx->mem_acct_enable)
+ return REALLOC (ptr, size);
tot_size = size + GF_MEM_HEADER_SIZE + GF_MEM_TRAILER_SIZE;
- orig_ptr = (char *)ptr - 4;
+ orig_ptr = (char *)ptr - 8 - 4;
GF_ASSERT (*(uint32_t *)orig_ptr == GF_MEM_HEADER_MAGIC);
@@ -188,8 +167,10 @@ __gf_realloc (void *ptr, size_t size)
type = *(uint32_t *)orig_ptr;
ptr = realloc (orig_ptr, tot_size);
- if (!ptr)
+ if (!ptr) {
+ gf_log_nomem ("", GF_LOG_ALERT, tot_size);
return NULL;
+ }
gf_mem_set_acct_info (xl, (char **)&ptr, size, type);
@@ -200,44 +181,39 @@ int
gf_vasprintf (char **string_ptr, const char *format, va_list arg)
{
va_list arg_save;
- char *str = NULL;
- int size = 0;
- int rv = 0;
+ char *str = NULL;
+ int size = 0;
+ int rv = 0;
- if (!string_ptr || !format)
- return -1;
+ if (!string_ptr || !format)
+ return -1;
va_copy (arg_save, arg);
- size = vsnprintf (NULL, 0, format, arg);
- size++;
- str = GF_MALLOC (size, gf_common_mt_asprintf);
- if (str == NULL) {
- /*
- * Strictly speaking, GNU asprintf doesn't do this,
- * but the caller isn't checking the return value.
- */
- gf_log ("libglusterfs", GF_LOG_CRITICAL,
- "failed to allocate memory");
- return -1;
- }
- rv = vsnprintf (str, size, format, arg_save);
-
- *string_ptr = str;
- return (rv);
+ size = vsnprintf (NULL, 0, format, arg);
+ size++;
+ str = GF_MALLOC (size, gf_common_mt_asprintf);
+ if (str == NULL) {
+ /* log is done in GF_MALLOC itself */
+ return -1;
+ }
+ rv = vsnprintf (str, size, format, arg_save);
+
+ *string_ptr = str;
+ return (rv);
}
int
gf_asprintf (char **string_ptr, const char *format, ...)
{
- va_list arg;
- int rv = 0;
+ va_list arg;
+ int rv = 0;
- va_start (arg, format);
- rv = gf_vasprintf (string_ptr, format, arg);
- va_end (arg);
+ va_start (arg, format);
+ rv = gf_vasprintf (string_ptr, format, arg);
+ va_end (arg);
- return rv;
+ return rv;
}
void
@@ -248,7 +224,7 @@ __gf_free (void *free_ptr)
uint32_t type = 0;
xlator_t *xl = NULL;
- if (!gf_mem_acct_enable) {
+ if (!THIS->ctx->mem_acct_enable) {
FREE (free_ptr);
return;
}
@@ -256,23 +232,18 @@ __gf_free (void *free_ptr)
if (!free_ptr)
return;
+ ptr = (char *)free_ptr - 8 - 4;
- ptr = (char *)free_ptr - 4;
-
- if (GF_MEM_HEADER_MAGIC != *(uint32_t *)ptr) {
- //Possible corruption, assert here
- GF_ASSERT (0);
- }
+ //Possible corruption, assert here
+ GF_ASSERT (GF_MEM_HEADER_MAGIC == *(uint32_t *)ptr);
*(uint32_t *)ptr = 0;
ptr = ptr - sizeof(xlator_t *);
memcpy (&xl, ptr, sizeof(xlator_t *));
- if (!xl) {
- //gf_free expects xl to be available
- GF_ASSERT (0);
- }
+ //gf_free expects xl to be available
+ GF_ASSERT (xl != NULL);
if (!xl->mem_acct.rec) {
ptr = (char *)free_ptr - GF_MEM_HEADER_SIZE;
@@ -285,11 +256,10 @@ __gf_free (void *free_ptr)
ptr = ptr - 4;
type = *(uint32_t *)ptr;
- if (GF_MEM_TRAILER_MAGIC != *(uint32_t *)
- ((char *)free_ptr + req_size)) {
- // This points to a memory overrun
- GF_ASSERT (0);
- }
+ // This points to a memory overrun
+ GF_ASSERT (GF_MEM_TRAILER_MAGIC ==
+ *(uint32_t *)((char *)free_ptr + req_size));
+
*(uint32_t *) ((char *)free_ptr + req_size) = 0;
LOCK (&xl->mem_acct.rec[type].lock);
@@ -306,47 +276,68 @@ free:
struct mem_pool *
mem_pool_new_fn (unsigned long sizeof_type,
- unsigned long count)
+ unsigned long count, char *name)
{
- struct mem_pool *mem_pool = NULL;
- unsigned long padded_sizeof_type = 0;
- void *pool = NULL;
- int i = 0;
- struct list_head *list = NULL;
-
- if (!sizeof_type || !count) {
- gf_log ("mem-pool", GF_LOG_ERROR, "invalid argument");
- return NULL;
- }
+ struct mem_pool *mem_pool = NULL;
+ unsigned long padded_sizeof_type = 0;
+ void *pool = NULL;
+ int i = 0;
+ int ret = 0;
+ struct list_head *list = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+
+ if (!sizeof_type || !count) {
+ gf_log_callingfn ("mem-pool", GF_LOG_ERROR, "invalid argument");
+ return NULL;
+ }
padded_sizeof_type = sizeof_type + GF_MEM_POOL_PAD_BOUNDARY;
- mem_pool = GF_CALLOC (sizeof (*mem_pool), 1, gf_common_mt_mem_pool);
- if (!mem_pool)
- return NULL;
+ mem_pool = GF_CALLOC (sizeof (*mem_pool), 1, gf_common_mt_mem_pool);
+ if (!mem_pool)
+ return NULL;
+
+ ret = gf_asprintf (&mem_pool->name, "%s:%s", THIS->name, name);
+ if (ret < 0)
+ return NULL;
+
+ if (!mem_pool->name) {
+ GF_FREE (mem_pool);
+ return NULL;
+ }
- LOCK_INIT (&mem_pool->lock);
- INIT_LIST_HEAD (&mem_pool->list);
+ LOCK_INIT (&mem_pool->lock);
+ INIT_LIST_HEAD (&mem_pool->list);
+ INIT_LIST_HEAD (&mem_pool->global_list);
- mem_pool->padded_sizeof_type = padded_sizeof_type;
- mem_pool->cold_count = count;
+ mem_pool->padded_sizeof_type = padded_sizeof_type;
+ mem_pool->cold_count = count;
mem_pool->real_sizeof_type = sizeof_type;
pool = GF_CALLOC (count, padded_sizeof_type, gf_common_mt_long);
- if (!pool) {
+ if (!pool) {
+ GF_FREE (mem_pool->name);
GF_FREE (mem_pool);
- return NULL;
+ return NULL;
}
- for (i = 0; i < count; i++) {
- list = pool + (i * (padded_sizeof_type));
- INIT_LIST_HEAD (list);
- list_add_tail (list, &mem_pool->list);
- }
+ for (i = 0; i < count; i++) {
+ list = pool + (i * (padded_sizeof_type));
+ INIT_LIST_HEAD (list);
+ list_add_tail (list, &mem_pool->list);
+ }
+
+ mem_pool->pool = pool;
+ mem_pool->pool_end = pool + (count * (padded_sizeof_type));
- mem_pool->pool = pool;
- mem_pool->pool_end = pool + (count * (padded_sizeof_type));
+ /* add this pool to the global list */
+ ctx = THIS->ctx;
+ if (!ctx)
+ goto out;
- return mem_pool;
+ list_add (&mem_pool->global_list, &ctx->mempool_list);
+
+out:
+ return mem_pool;
}
void*
@@ -355,7 +346,7 @@ mem_get0 (struct mem_pool *mem_pool)
void *ptr = NULL;
if (!mem_pool) {
- gf_log ("mem-pool", GF_LOG_ERROR, "invalid argument");
+ gf_log_callingfn ("mem-pool", GF_LOG_ERROR, "invalid argument");
return NULL;
}
@@ -370,35 +361,41 @@ mem_get0 (struct mem_pool *mem_pool)
void *
mem_get (struct mem_pool *mem_pool)
{
- struct list_head *list = NULL;
- void *ptr = NULL;
+ struct list_head *list = NULL;
+ void *ptr = NULL;
int *in_use = NULL;
+ struct mem_pool **pool_ptr = NULL;
- if (!mem_pool) {
- gf_log ("mem-pool", GF_LOG_ERROR, "invalid argument");
- return NULL;
- }
+ if (!mem_pool) {
+ gf_log_callingfn ("mem-pool", GF_LOG_ERROR, "invalid argument");
+ return NULL;
+ }
- LOCK (&mem_pool->lock);
- {
- if (mem_pool->cold_count) {
- list = mem_pool->list.next;
- list_del (list);
+ LOCK (&mem_pool->lock);
+ {
+ mem_pool->alloc_count++;
+ if (mem_pool->cold_count) {
+ list = mem_pool->list.next;
+ list_del (list);
- mem_pool->hot_count++;
- mem_pool->cold_count--;
+ mem_pool->hot_count++;
+ mem_pool->cold_count--;
- ptr = list;
- in_use = (ptr + GF_MEM_POOL_LIST_BOUNDARY);
+ if (mem_pool->max_alloc < mem_pool->hot_count)
+ mem_pool->max_alloc = mem_pool->hot_count;
+
+ ptr = list;
+ in_use = (ptr + GF_MEM_POOL_LIST_BOUNDARY +
+ GF_MEM_POOL_PTR);
*in_use = 1;
goto fwd_addr_out;
- }
+ }
/* This is a problem area. If we've run out of
* chunks in our slab above, we need to allocate
* enough memory to service this request.
- * The problem is, these indvidual chunks will fail
+ * The problem is, these individual chunks will fail
* the first address range check in __is_member. Now, since
* we're not allocating a full second slab, we wont have
* enough info perform the range check in __is_member.
@@ -415,83 +412,104 @@ mem_get (struct mem_pool *mem_pool)
* because it is too much work knowing that a better slab
* allocator is coming RSN.
*/
- ptr = MALLOC (mem_pool->real_sizeof_type);
+ mem_pool->pool_misses++;
+ mem_pool->curr_stdalloc++;
+ if (mem_pool->max_stdalloc < mem_pool->curr_stdalloc)
+ mem_pool->max_stdalloc = mem_pool->curr_stdalloc;
+ ptr = GF_CALLOC (1, mem_pool->padded_sizeof_type,
+ gf_common_mt_mem_pool);
/* Memory coming from the heap need not be transformed from a
* chunkhead to a usable pointer since it is not coming from
* the pool.
*/
- goto unlocked_out;
- }
+ }
fwd_addr_out:
+ pool_ptr = mem_pool_from_ptr (ptr);
+ *pool_ptr = (struct mem_pool *)mem_pool;
ptr = mem_pool_chunkhead2ptr (ptr);
-unlocked_out:
UNLOCK (&mem_pool->lock);
- return ptr;
+ return ptr;
}
static int
__is_member (struct mem_pool *pool, void *ptr)
{
- if (!pool || !ptr) {
- gf_log ("mem-pool", GF_LOG_ERROR, "invalid argument");
- return -1;
- }
+ if (!pool || !ptr) {
+ gf_log_callingfn ("mem-pool", GF_LOG_ERROR, "invalid argument");
+ return -1;
+ }
- if (ptr < pool->pool || ptr >= pool->pool_end)
- return 0;
+ if (ptr < pool->pool || ptr >= pool->pool_end)
+ return 0;
- if ((mem_pool_ptr2chunkhead (ptr) - pool->pool)
- % pool->padded_sizeof_type)
- return -1;
+ if ((mem_pool_ptr2chunkhead (ptr) - pool->pool)
+ % pool->padded_sizeof_type)
+ return -1;
- return 1;
+ return 1;
}
void
-mem_put (struct mem_pool *pool, void *ptr)
+mem_put (void *ptr)
{
- struct list_head *list = NULL;
- int *in_use = NULL;
- void *head = NULL;
-
- if (!pool || !ptr) {
- gf_log ("mem-pool", GF_LOG_ERROR, "invalid argument");
- return;
- }
-
- LOCK (&pool->lock);
- {
-
- switch (__is_member (pool, ptr))
- {
- case 1:
- list = head = mem_pool_ptr2chunkhead (ptr);
- in_use = (head + GF_MEM_POOL_LIST_BOUNDARY);
- if (!is_mem_chunk_in_use(in_use)) {
- gf_log_callingfn ("mem-pool", GF_LOG_CRITICAL,
- "mem_put called on freed ptr %p of mem "
- "pool %p", ptr, pool);
- break;
- }
- pool->hot_count--;
- pool->cold_count++;
- *in_use = 0;
- list_add (list, &pool->list);
- break;
- case -1:
+ struct list_head *list = NULL;
+ int *in_use = NULL;
+ void *head = NULL;
+ struct mem_pool **tmp = NULL;
+ struct mem_pool *pool = NULL;
+
+ if (!ptr) {
+ gf_log_callingfn ("mem-pool", GF_LOG_ERROR, "invalid argument");
+ return;
+ }
+
+ list = head = mem_pool_ptr2chunkhead (ptr);
+ tmp = mem_pool_from_ptr (head);
+ if (!tmp) {
+ gf_log_callingfn ("mem-pool", GF_LOG_ERROR,
+ "ptr header is corrupted");
+ return;
+ }
+
+ pool = *tmp;
+ if (!pool) {
+ gf_log_callingfn ("mem-pool", GF_LOG_ERROR,
+ "mem-pool ptr is NULL");
+ return;
+ }
+ LOCK (&pool->lock);
+ {
+
+ switch (__is_member (pool, ptr))
+ {
+ case 1:
+ in_use = (head + GF_MEM_POOL_LIST_BOUNDARY +
+ GF_MEM_POOL_PTR);
+ if (!is_mem_chunk_in_use(in_use)) {
+ gf_log_callingfn ("mem-pool", GF_LOG_CRITICAL,
+ "mem_put called on freed ptr %p of mem "
+ "pool %p", ptr, pool);
+ break;
+ }
+ pool->hot_count--;
+ pool->cold_count++;
+ *in_use = 0;
+ list_add (list, &pool->list);
+ break;
+ case -1:
/* For some reason, the address given is within
* the address range of the mem-pool but does not align
* with the expected start of a chunk that includes
* the list headers also. Sounds like a problem in
* layers of clouds up above us. ;)
*/
- abort ();
- break;
- case 0:
+ abort ();
+ break;
+ case 0:
/* The address is outside the range of the mem-pool. We
* assume here that this address was allocated at a
* point when the mem-pool was out of chunks in mem_get
@@ -500,24 +518,30 @@ mem_put (struct mem_pool *pool, void *ptr)
* not have enough info to distinguish between the two
* situations.
*/
- FREE (ptr);
- break;
- default:
- /* log error */
- break;
- }
- }
- UNLOCK (&pool->lock);
+ pool->curr_stdalloc--;
+ GF_FREE (list);
+ break;
+ default:
+ /* log error */
+ break;
+ }
+ }
+ UNLOCK (&pool->lock);
}
-
void
mem_pool_destroy (struct mem_pool *pool)
{
if (!pool)
return;
+ gf_log (THIS->name, GF_LOG_INFO, "size=%lu max=%d total=%"PRIu64,
+ pool->padded_sizeof_type, pool->max_alloc, pool->alloc_count);
+
+ list_del (&pool->global_list);
+
LOCK_DESTROY (&pool->lock);
+ GF_FREE (pool->name);
GF_FREE (pool->pool);
GF_FREE (pool);
diff --git a/libglusterfs/src/mem-pool.h b/libglusterfs/src/mem-pool.h
index 6b09d6221..31f49f75c 100644
--- a/libglusterfs/src/mem-pool.h
+++ b/libglusterfs/src/mem-pool.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
#ifndef _MEM_POOL_H_
@@ -22,6 +13,7 @@
#include "list.h"
#include "locking.h"
+#include "logging.h"
#include "mem-types.h"
#include <stdlib.h>
#include <inttypes.h>
@@ -29,15 +21,6 @@
#include <stdarg.h>
-#define MALLOC(size) malloc(size)
-#define CALLOC(cnt,size) calloc(cnt,size)
-
-#define FREE(ptr) \
- if (ptr != NULL) { \
- free ((void *)ptr); \
- ptr = (void *)0xeeeeeeee; \
- }
-
struct mem_acct {
uint32_t num_types;
struct mem_acct_rec *rec;
@@ -47,6 +30,7 @@ struct mem_acct_rec {
size_t size;
size_t max_size;
uint32_t num_allocs;
+ uint32_t total_allocs;
uint32_t max_num_allocs;
gf_lock_t lock;
};
@@ -67,17 +51,82 @@ gf_vasprintf (char **string_ptr, const char *format, va_list arg);
int
gf_asprintf (char **string_ptr, const char *format, ...);
+void
+__gf_free (void *ptr);
+
+
+static inline
+void* __gf_default_malloc (size_t size)
+{
+ void *ptr = NULL;
+
+ ptr = malloc (size);
+ if (!ptr)
+ gf_log_nomem ("", GF_LOG_ALERT, size);
+
+ return ptr;
+}
+
+static inline
+void* __gf_default_calloc (int cnt, size_t size)
+{
+ void *ptr = NULL;
+
+ ptr = calloc (cnt, size);
+ if (!ptr)
+ gf_log_nomem ("", GF_LOG_ALERT, (cnt * size));
+
+ return ptr;
+}
+
+static inline
+void* __gf_default_realloc (void *oldptr, size_t size)
+{
+ void *ptr = NULL;
+
+ ptr = realloc (oldptr, size);
+ if (!ptr)
+ gf_log_nomem ("", GF_LOG_ALERT, size);
+
+ return ptr;
+}
+
+#define MALLOC(size) __gf_default_malloc(size)
+#define CALLOC(cnt,size) __gf_default_calloc(cnt,size)
+#define REALLOC(ptr,size) __gf_default_realloc(ptr,size)
+
+#define FREE(ptr) \
+ if (ptr != NULL) { \
+ free ((void *)ptr); \
+ ptr = (void *)0xeeeeeeee; \
+ }
+
#define GF_CALLOC(nmemb, size, type) __gf_calloc (nmemb, size, type)
#define GF_MALLOC(size, type) __gf_malloc (size, type)
#define GF_REALLOC(ptr, size) __gf_realloc (ptr, size)
-void
-__gf_free (void *ptr);
+#define GF_FREE(free_ptr) __gf_free (free_ptr)
+static inline
+char *gf_strndup (const char *src, size_t len)
+{
+ char *dup_str = NULL;
-#define GF_FREE(free_ptr) __gf_free (free_ptr);
+ if (!src) {
+ goto out;
+ }
+
+ dup_str = GF_CALLOC (1, len + 1, gf_common_mt_strdup);
+ if (!dup_str) {
+ goto out;
+ }
+
+ memcpy (dup_str, src, len);
+out:
+ return dup_str;
+}
static inline
char * gf_strdup (const char *src)
@@ -98,31 +147,50 @@ char * gf_strdup (const char *src)
return dup_str;
}
+static inline void *
+gf_memdup (const void *src, size_t size)
+{
+ void *dup_mem = NULL;
+
+ dup_mem = GF_CALLOC(1, size, gf_common_mt_strdup);
+ if (!dup_mem)
+ goto out;
+ memcpy (dup_mem, src, size);
+
+out:
+ return dup_mem;
+}
struct mem_pool {
- struct list_head list;
- int hot_count;
- int cold_count;
- gf_lock_t lock;
- unsigned long padded_sizeof_type;
- void *pool;
- void *pool_end;
+ struct list_head list;
+ int hot_count;
+ int cold_count;
+ gf_lock_t lock;
+ unsigned long padded_sizeof_type;
+ void *pool;
+ void *pool_end;
int real_sizeof_type;
+ uint64_t alloc_count;
+ uint64_t pool_misses;
+ int max_alloc;
+ int curr_stdalloc;
+ int max_stdalloc;
+ char *name;
+ struct list_head global_list;
};
struct mem_pool *
-mem_pool_new_fn (unsigned long sizeof_type, unsigned long count);
+mem_pool_new_fn (unsigned long sizeof_type, unsigned long count, char *name);
-#define mem_pool_new(type,count) mem_pool_new_fn (sizeof(type), count)
+#define mem_pool_new(type,count) mem_pool_new_fn (sizeof(type), count, #type)
-void mem_put (struct mem_pool *pool, void *ptr);
+void mem_put (void *ptr);
void *mem_get (struct mem_pool *pool);
void *mem_get0 (struct mem_pool *pool);
void mem_pool_destroy (struct mem_pool *pool);
-int gf_mem_acct_is_enabled ();
-void gf_mem_acct_enable_set ();
+void gf_mem_acct_enable_set (void *ctx);
#endif /* _MEM_POOL_H */
diff --git a/libglusterfs/src/mem-types.h b/libglusterfs/src/mem-types.h
index 9e857901b..666bd120a 100644
--- a/libglusterfs/src/mem-types.h
+++ b/libglusterfs/src/mem-types.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
+ 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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 __MEM_TYPES_H__
@@ -22,81 +13,113 @@
enum gf_common_mem_types_ {
- gf_common_mt_call_stub_t = 0,
- gf_common_mt_dnscache6 = 1,
- gf_common_mt_data_pair_t = 2,
- gf_common_mt_data_t = 3,
- gf_common_mt_dict_t = 4,
- gf_common_mt_event_pool = 5,
- gf_common_mt_reg = 6,
- gf_common_mt_pollfd = 7,
- gf_common_mt_epoll_event = 8,
- gf_common_mt_fdentry_t = 9,
- gf_common_mt_fdtable_t = 10,
- gf_common_mt_fd_t = 11,
- gf_common_mt_fd_ctx = 12,
- gf_common_mt_gf_dirent_t = 13,
- gf_common_mt_glusterfs_ctx_t = 14,
- gf_common_mt_dentry_t = 15,
- gf_common_mt_inode_t = 16,
- gf_common_mt_inode_ctx = 17,
- gf_common_mt_list_head = 18,
- gf_common_mt_inode_table_t = 19,
- gf_common_mt_xlator_t = 20,
- gf_common_mt_xlator_list_t = 21,
- gf_common_mt_log_msg = 22,
- gf_common_mt_client_log = 23,
- gf_common_mt_volume_opt_list_t = 24,
- gf_common_mt_gf_hdr_common_t = 25,
- gf_common_mt_call_frame_t = 26,
- gf_common_mt_call_stack_t = 27,
- gf_common_mt_gf_timer_t = 28,
- gf_common_mt_gf_timer_registry_t= 29,
- gf_common_mt_transport = 30,
- gf_common_mt_transport_msg = 31,
- gf_common_mt_auth_handle_t = 32,
- gf_common_mt_iobuf = 33,
- gf_common_mt_iobuf_arena = 34,
- gf_common_mt_iobref = 35,
- gf_common_mt_iobuf_pool = 36,
- gf_common_mt_iovec = 37,
- gf_common_mt_memdup = 38,
- gf_common_mt_asprintf = 39,
- gf_common_mt_strdup = 40,
- gf_common_mt_socket_private_t = 41,
- gf_common_mt_ioq = 42,
- gf_common_mt_transport_t = 43,
- gf_common_mt_socket_local_t = 44,
- gf_common_mt_char = 45,
- gf_common_mt_rbthash_table_t = 46,
- gf_common_mt_rbthash_bucket = 47,
- gf_common_mt_mem_pool = 48,
- gf_common_mt_long = 49,
- gf_common_mt_rpcsvc_auth_list = 50,
- gf_common_mt_rpcsvc_t = 51,
- gf_common_mt_rpcsvc_conn_t = 52,
- gf_common_mt_rpcsvc_program_t = 53,
- gf_common_mt_rpcsvc_listener_t = 54,
- gf_common_mt_rpcsvc_wrapper_t = 55,
- gf_common_mt_rpcsvc_stage_t = 56,
- gf_common_mt_rpcclnt_t = 57,
- gf_common_mt_rpcclnt_savedframe_t = 58,
- gf_common_mt_rpc_trans_t = 59,
- gf_common_mt_rpc_trans_pollin_t = 60,
- gf_common_mt_rpc_trans_handover_t = 61,
- gf_common_mt_rpc_trans_reqinfo_t= 62,
- gf_common_mt_rpc_trans_rsp_t = 63,
- gf_common_mt_glusterfs_graph_t = 64,
- gf_common_mt_rdma_private_t = 65,
- gf_common_mt_rdma_ioq_t = 66,
- gf_common_mt_rpc_transport_t = 67,
- gf_common_mt_rdma_local_t = 68,
- gf_common_mt_rdma_post_t = 69,
- gf_common_mt_qpent = 70,
- gf_common_mt_rdma_device_t = 71,
- gf_common_mt_rdma_context_t = 72,
- gf_common_mt_sge = 73,
- gf_common_mt_rpcclnt_cb_program_t = 74,
- gf_common_mt_end = 75
+ gf_common_mt_call_stub_t = 0,
+ gf_common_mt_dnscache6 = 1,
+ gf_common_mt_data_pair_t = 2,
+ gf_common_mt_data_t = 3,
+ gf_common_mt_dict_t = 4,
+ gf_common_mt_event_pool = 5,
+ gf_common_mt_reg = 6,
+ gf_common_mt_pollfd = 7,
+ gf_common_mt_epoll_event = 8,
+ gf_common_mt_fdentry_t = 9,
+ gf_common_mt_fdtable_t = 10,
+ gf_common_mt_fd_t = 11,
+ gf_common_mt_fd_ctx = 12,
+ gf_common_mt_gf_dirent_t = 13,
+ gf_common_mt_glusterfs_ctx_t = 14,
+ gf_common_mt_dentry_t = 15,
+ gf_common_mt_inode_t = 16,
+ gf_common_mt_inode_ctx = 17,
+ gf_common_mt_list_head = 18,
+ gf_common_mt_inode_table_t = 19,
+ gf_common_mt_xlator_t = 20,
+ gf_common_mt_xlator_list_t = 21,
+ gf_common_mt_log_msg = 22,
+ gf_common_mt_client_log = 23,
+ gf_common_mt_volume_opt_list_t = 24,
+ gf_common_mt_gf_hdr_common_t = 25,
+ gf_common_mt_call_frame_t = 26,
+ gf_common_mt_call_stack_t = 27,
+ gf_common_mt_gf_timer_t = 28,
+ gf_common_mt_gf_timer_registry_t = 29,
+ gf_common_mt_transport = 30,
+ gf_common_mt_transport_msg = 31,
+ gf_common_mt_auth_handle_t = 32,
+ gf_common_mt_iobuf = 33,
+ gf_common_mt_iobuf_arena = 34,
+ gf_common_mt_iobref = 35,
+ gf_common_mt_iobuf_pool = 36,
+ gf_common_mt_iovec = 37,
+ gf_common_mt_memdup = 38,
+ gf_common_mt_asprintf = 39,
+ gf_common_mt_strdup = 40,
+ gf_common_mt_socket_private_t = 41,
+ gf_common_mt_ioq = 42,
+ gf_common_mt_transport_t = 43,
+ gf_common_mt_socket_local_t = 44,
+ gf_common_mt_char = 45,
+ gf_common_mt_rbthash_table_t = 46,
+ gf_common_mt_rbthash_bucket = 47,
+ gf_common_mt_mem_pool = 48,
+ gf_common_mt_long = 49,
+ gf_common_mt_rpcsvc_auth_list = 50,
+ gf_common_mt_rpcsvc_t = 51,
+ gf_common_mt_rpcsvc_conn_t = 52,
+ gf_common_mt_rpcsvc_program_t = 53,
+ gf_common_mt_rpcsvc_listener_t = 54,
+ gf_common_mt_rpcsvc_wrapper_t = 55,
+ gf_common_mt_rpcsvc_stage_t = 56,
+ gf_common_mt_rpcclnt_t = 57,
+ gf_common_mt_rpcclnt_savedframe_t = 58,
+ gf_common_mt_rpc_trans_t = 59,
+ gf_common_mt_rpc_trans_pollin_t = 60,
+ gf_common_mt_rpc_trans_handover_t = 61,
+ gf_common_mt_rpc_trans_reqinfo_t = 62,
+ gf_common_mt_rpc_trans_rsp_t = 63,
+ gf_common_mt_glusterfs_graph_t = 64,
+ gf_common_mt_rdma_private_t = 65,
+ gf_common_mt_rdma_ioq_t = 66,
+ gf_common_mt_rpc_transport_t = 67,
+ gf_common_mt_rdma_local_t = 68,
+ gf_common_mt_rdma_post_t = 69,
+ gf_common_mt_qpent = 70,
+ gf_common_mt_rdma_device_t = 71,
+ gf_common_mt_rdma_context_t = 72,
+ gf_common_mt_sge = 73,
+ gf_common_mt_rpcclnt_cb_program_t = 74,
+ gf_common_mt_libxl_marker_local = 75,
+ gf_common_mt_graph_buf = 76,
+ gf_common_mt_trie_trie = 77,
+ gf_common_mt_trie_data = 78,
+ gf_common_mt_trie_node = 79,
+ gf_common_mt_trie_buf = 80,
+ gf_common_mt_trie_end = 81,
+ gf_common_mt_run_argv = 82,
+ gf_common_mt_run_logbuf = 83,
+ gf_common_mt_fd_lk_ctx_t = 84,
+ gf_common_mt_fd_lk_ctx_node_t = 85,
+ gf_common_mt_buffer_t = 86,
+ gf_common_mt_circular_buffer_t = 87,
+ gf_common_mt_eh_t = 88,
+ gf_common_mt_store_handle_t = 89,
+ gf_common_mt_store_iter_t = 90,
+ gf_common_mt_drc_client_t = 91,
+ gf_common_mt_drc_globals_t = 92,
+ gf_common_mt_drc_rbtree_node_t = 93,
+ gf_common_mt_iov_base_t = 94,
+ gf_common_mt_groups_t = 95,
+ gf_common_mt_cliententry_t = 96,
+ gf_common_mt_clienttable_t = 97,
+ gf_common_mt_client_t = 98,
+ gf_common_mt_client_ctx = 99,
+ gf_common_mt_lock_table = 100,
+ gf_common_mt_locker = 101,
+ gf_common_mt_auxgids = 102,
+ gf_common_mt_syncopctx = 103,
+ gf_common_mt_uuid_t = 104,
+ gf_common_mt_mgmt_v3_lock_obj_t = 105,
+ gf_common_mt_txn_opinfo_obj_t = 106,
+ gf_common_mt_end = 107
};
#endif
diff --git a/libglusterfs/src/options.c b/libglusterfs/src/options.c
new file mode 100644
index 000000000..842b6413a
--- /dev/null
+++ b/libglusterfs/src/options.c
@@ -0,0 +1,1127 @@
+/*
+ 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.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include <fnmatch.h>
+
+#include "xlator.h"
+#include "defaults.h"
+
+#define GF_OPTION_LIST_EMPTY(_opt) (_opt->value[0] == NULL)
+
+
+static int
+xlator_option_validate_path (xlator_t *xl, const char *key, const char *value,
+ volume_option_t *opt, char **op_errstr)
+{
+ int ret = -1;
+ char errstr[256];
+
+ if (strstr (value, "../")) {
+ snprintf (errstr, 256,
+ "invalid path given '%s'",
+ value);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+
+ /* Make sure the given path is valid */
+ if (value[0] != '/') {
+ snprintf (errstr, 256,
+ "option %s %s: '%s' is not an "
+ "absolute path name",
+ key, value, value);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (ret && op_errstr)
+ *op_errstr = gf_strdup (errstr);
+ return ret;
+}
+
+static int
+xlator_option_validate_int (xlator_t *xl, const char *key, const char *value,
+ volume_option_t *opt, char **op_errstr)
+{
+ long long inputll = 0;
+ int ret = -1;
+ char errstr[256];
+
+ /* Check the range */
+ if (gf_string2longlong (value, &inputll) != 0) {
+ snprintf (errstr, 256,
+ "invalid number format \"%s\" in option \"%s\"",
+ value, key);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+
+ if ((opt->min == 0) && (opt->max == 0) &&
+ (opt->validate == GF_OPT_VALIDATE_BOTH)) {
+ gf_log (xl->name, GF_LOG_TRACE,
+ "no range check required for 'option %s %s'",
+ key, value);
+ ret = 0;
+ goto out;
+ }
+
+ if ((opt->validate == GF_OPT_VALIDATE_MIN)) {
+ if (inputll < opt->min) {
+ snprintf (errstr, 256,
+ "'%lld' in 'option %s %s' is smaller than "
+ "minimum value '%.0f'", inputll, key,
+ value, opt->min);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+ } else if ((opt->validate == GF_OPT_VALIDATE_MAX)) {
+ if ((inputll > opt->max)) {
+ snprintf (errstr, 256,
+ "'%lld' in 'option %s %s' is greater than "
+ "maximum value '%.0f'", inputll, key,
+ value, opt->max);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+ } else if ((inputll < opt->min) || (inputll > opt->max)) {
+ snprintf (errstr, 256,
+ "'%lld' in 'option %s %s' is out of range "
+ "[%.0f - %.0f]",
+ inputll, key, value, opt->min, opt->max);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (ret && op_errstr)
+ *op_errstr = gf_strdup (errstr);
+ return ret;
+}
+
+
+static int
+xlator_option_validate_sizet (xlator_t *xl, const char *key, const char *value,
+ volume_option_t *opt, char **op_errstr)
+{
+ uint64_t size = 0;
+ int ret = 0;
+ char errstr[256];
+
+ /* Check the range */
+ if (gf_string2bytesize (value, &size) != 0) {
+ snprintf (errstr, 256,
+ "invalid number format \"%s\" in option \"%s\"",
+ value, key);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ ret = -1;
+ goto out;
+ }
+
+ if ((opt->min == 0) && (opt->max == 0)) {
+ gf_log (xl->name, GF_LOG_TRACE,
+ "no range check required for 'option %s %s'",
+ key, value);
+ goto out;
+ }
+
+ if ((size < opt->min) || (size > opt->max)) {
+ if ((strncmp (key, "cache-size", 10) == 0) &&
+ (size > opt->max)) {
+ snprintf (errstr, 256, "Cache size %"PRId64" is out of "
+ "range [%.0f - %.0f]",
+ size, opt->min, opt->max);
+ gf_log (xl->name, GF_LOG_WARNING, "%s", errstr);
+ } else {
+ snprintf (errstr, 256,
+ "'%"PRId64"' in 'option %s %s' "
+ "is out of range [%.0f - %.0f]",
+ size, key, value, opt->min, opt->max);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ ret = -1;
+ }
+ }
+
+out:
+ if (ret && op_errstr)
+ *op_errstr = gf_strdup (errstr);
+ return ret;
+}
+
+
+static int
+xlator_option_validate_bool (xlator_t *xl, const char *key, const char *value,
+ volume_option_t *opt, char **op_errstr)
+{
+ int ret = -1;
+ char errstr[256];
+ gf_boolean_t bool;
+
+
+ /* Check if the value is one of
+ '0|1|on|off|no|yes|true|false|enable|disable' */
+
+ if (gf_string2boolean (value, &bool) != 0) {
+ snprintf (errstr, 256,
+ "option %s %s: '%s' is not a valid boolean value",
+ key, value, value);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (ret && op_errstr)
+ *op_errstr = gf_strdup (errstr);
+ return ret;
+}
+
+
+static int
+xlator_option_validate_xlator (xlator_t *xl, const char *key, const char *value,
+ volume_option_t *opt, char **op_errstr)
+{
+ int ret = -1;
+ char errstr[256];
+ xlator_t *xlopt = NULL;
+
+
+ /* Check if the value is one of the xlators */
+ xlopt = xl;
+ while (xlopt->prev)
+ xlopt = xlopt->prev;
+
+ while (xlopt) {
+ if (strcmp (value, xlopt->name) == 0) {
+ ret = 0;
+ break;
+ }
+ xlopt = xlopt->next;
+ }
+
+ if (!xlopt) {
+ snprintf (errstr, 256,
+ "option %s %s: '%s' is not a valid volume name",
+ key, value, value);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (ret && op_errstr)
+ *op_errstr = gf_strdup (errstr);
+ return ret;
+}
+
+void
+set_error_str (char *errstr, size_t len, volume_option_t *opt, const char *key,
+ const char *value)
+{
+ int i = 0;
+ char given_array[4096] = {0,};
+
+ for (i = 0; (i < ZR_OPTION_MAX_ARRAY_SIZE) && opt->value[i];) {
+ strcat (given_array, opt->value[i]);
+ if (((++i) < ZR_OPTION_MAX_ARRAY_SIZE) &&
+ (opt->value[i]))
+ strcat (given_array, ", ");
+ else
+ strcat (given_array, ".");
+ }
+ snprintf (errstr, len, "option %s %s: '%s' is not valid "
+ "(possible options are %s)", key, value, value, given_array);
+ return;
+}
+
+int
+is_all_whitespaces (const char *value)
+{
+ int i = 0;
+ size_t len = 0;
+
+ if (value == NULL)
+ return -1;
+
+ len = strlen (value);
+
+ for (i = 0; i < len; i++) {
+ if (value[i] == ' ')
+ continue;
+ else
+ return 0;
+ }
+
+ return 1;
+}
+
+static int
+xlator_option_validate_str (xlator_t *xl, const char *key, const char *value,
+ volume_option_t *opt, char **op_errstr)
+{
+ int ret = -1;
+ int i = 0;
+ char errstr[4096] = {0,};
+
+ /* Check if the '*str' is valid */
+ if (GF_OPTION_LIST_EMPTY(opt)) {
+ ret = 0;
+ goto out;
+ }
+
+ if (is_all_whitespaces (value) == 1)
+ goto out;
+
+ for (i = 0; (i < ZR_OPTION_MAX_ARRAY_SIZE) && opt->value[i]; i++) {
+ #ifdef GF_DARWIN_HOST_OS
+ if (fnmatch (opt->value[i], value, 0) == 0) {
+ ret = 0;
+ break;
+ }
+ #else
+ if (fnmatch (opt->value[i], value, FNM_EXTMATCH) == 0) {
+ ret = 0;
+ break;
+ }
+ #endif
+ }
+
+ if ((i == ZR_OPTION_MAX_ARRAY_SIZE) || (!opt->value[i]))
+ goto out;
+ /* enter here only if
+ * 1. reached end of opt->value array and haven't
+ * validated input
+ * OR
+ * 2. valid input list is less than
+ * ZR_OPTION_MAX_ARRAY_SIZE and input has not
+ * matched all possible input values.
+ */
+
+ ret = 0;
+
+out:
+ if (ret) {
+ set_error_str (errstr, sizeof (errstr), opt, key, value);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ if (op_errstr)
+ *op_errstr = gf_strdup (errstr);
+ }
+ return ret;
+}
+
+
+static int
+xlator_option_validate_percent (xlator_t *xl, const char *key, const char *value,
+ volume_option_t *opt, char **op_errstr)
+{
+ double percent = 0;
+ int ret = -1;
+ char errstr[256];
+
+ /* Check if the value is valid percentage */
+ if (gf_string2percent (value, &percent) != 0) {
+ snprintf (errstr, 256,
+ "invalid percent format \"%s\" in \"option %s\"",
+ value, key);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+
+ if ((percent < 0.0) || (percent > 100.0)) {
+ snprintf (errstr, 256,
+ "'%lf' in 'option %s %s' is out of range [0 - 100]",
+ percent, key, value);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (ret && op_errstr)
+ *op_errstr = gf_strdup (errstr);
+ return ret;
+}
+
+static int
+xlator_option_validate_percent_or_sizet (xlator_t *xl, const char *key,
+ const char *value,
+ volume_option_t *opt, char **op_errstr)
+{
+ int ret = -1;
+ char errstr[256];
+ uint64_t size = 0;
+ gf_boolean_t is_percent = _gf_false;
+
+ if (gf_string2percent_or_bytesize (value, &size, &is_percent) == 0) {
+ if (is_percent) {
+ ret = 0;
+ goto out;
+ }
+ /* Check the range */
+ if ((opt->min == 0) && (opt->max == 0)) {
+ gf_log (xl->name, GF_LOG_TRACE,
+ "no range check required for "
+ "'option %s %s'",
+ key, value);
+ ret = 0;
+ goto out;
+ }
+ if ((size < opt->min) || (size > opt->max)) {
+ snprintf (errstr, 256,
+ "'%"PRId64"' in 'option %s %s'"
+ " is out of range [%.0f - %.0f]",
+ size, key, value, opt->min, opt->max);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+ ret = 0;
+ goto out;
+ }
+
+ /* If control reaches here, invalid argument */
+
+ snprintf (errstr, 256,
+ "invalid number format \"%s\" in \"option %s\"",
+ value, key);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+
+
+out:
+ if (ret && op_errstr)
+ *op_errstr = gf_strdup (errstr);
+ return ret;
+}
+
+
+static int
+xlator_option_validate_time (xlator_t *xl, const char *key, const char *value,
+ volume_option_t *opt, char **op_errstr)
+{
+ int ret = -1;
+ char errstr[256];
+ uint32_t input_time = 0;
+
+ /* Check if the value is valid time */
+ if (gf_string2time (value, &input_time) != 0) {
+ snprintf (errstr, 256,
+ "invalid time format \"%s\" in "
+ "\"option %s\"",
+ value, key);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+
+ if ((opt->min == 0) && (opt->max == 0)) {
+ gf_log (xl->name, GF_LOG_TRACE,
+ "no range check required for "
+ "'option %s %s'",
+ key, value);
+ ret = 0;
+ goto out;
+ }
+
+ if ((input_time < opt->min) || (input_time > opt->max)) {
+ snprintf (errstr, 256,
+ "'%"PRIu32"' in 'option %s %s' is "
+ "out of range [%.0f - %.0f]",
+ input_time, key, value,
+ opt->min, opt->max);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (ret && op_errstr)
+ *op_errstr = gf_strdup (errstr);
+ return ret;
+}
+
+
+static int
+xlator_option_validate_double (xlator_t *xl, const char *key, const char *value,
+ volume_option_t *opt, char **op_errstr)
+{
+ double input = 0.0;
+ int ret = -1;
+ char errstr[256];
+
+ /* Check the range */
+ if (gf_string2double (value, &input) != 0) {
+ snprintf (errstr, 256,
+ "invalid number format \"%s\" in option \"%s\"",
+ value, key);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+
+ if ((opt->min == 0) && (opt->max == 0) &&
+ (opt->validate == GF_OPT_VALIDATE_BOTH)) {
+ gf_log (xl->name, GF_LOG_TRACE,
+ "no range check required for 'option %s %s'",
+ key, value);
+ ret = 0;
+ goto out;
+ }
+
+ if ((opt->validate == GF_OPT_VALIDATE_MIN)) {
+ if (input < opt->min) {
+ snprintf (errstr, 256,
+ "'%f' in 'option %s %s' is smaller than "
+ "minimum value '%f'", input, key,
+ value, opt->min);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+ } else if ((opt->validate == GF_OPT_VALIDATE_MAX)) {
+ if ((input > opt->max)) {
+ snprintf (errstr, 256,
+ "'%f' in 'option %s %s' is greater than "
+ "maximum value '%f'", input, key,
+ value, opt->max);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+ } else if ((input < opt->min) || (input > opt->max)) {
+ snprintf (errstr, 256,
+ "'%f' in 'option %s %s' is out of range "
+ "[%f - %f]",
+ input, key, value, opt->min, opt->max);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (ret && op_errstr)
+ *op_errstr = gf_strdup (errstr);
+ return ret;
+}
+
+
+static int
+xlator_option_validate_addr (xlator_t *xl, const char *key, const char *value,
+ volume_option_t *opt, char **op_errstr)
+{
+ int ret = -1;
+ char errstr[256];
+
+ if (!valid_internet_address ((char *)value, _gf_false)) {
+ snprintf (errstr, 256,
+ "option %s %s: '%s' is not a valid internet-address,"
+ " it does not conform to standards.",
+ key, value, value);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ if (op_errstr)
+ *op_errstr = gf_strdup (errstr);
+ }
+
+ ret = 0;
+
+ return ret;
+}
+
+static int
+xlator_option_validate_addr_list (xlator_t *xl, const char *key,
+ const char *value, volume_option_t *opt,
+ char **op_errstr)
+{
+ int ret = -1;
+ char *dup_val = NULL;
+ char *addr_tok = NULL;
+ char *save_ptr = NULL;
+ char errstr[4096] = {0,};
+
+ dup_val = gf_strdup (value);
+ if (!dup_val)
+ goto out;
+
+ addr_tok = strtok_r (dup_val, ",", &save_ptr);
+ if (addr_tok == NULL)
+ goto out;
+ while (addr_tok) {
+ if (!valid_internet_address (addr_tok, _gf_true))
+ goto out;
+
+ addr_tok = strtok_r (NULL, ",", &save_ptr);
+ }
+ ret = 0;
+
+out:
+ if (ret) {
+ snprintf (errstr, sizeof (errstr), "option %s %s: '%s' is not "
+ "a valid internet-address-list", key, value, value);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ if (op_errstr)
+ *op_errstr = gf_strdup (errstr);
+ }
+ GF_FREE (dup_val);
+
+ return ret;
+}
+
+/*XXX: the rules to validate are as per block-size required for stripe xlator */
+static int
+gf_validate_size (const char *sizestr, volume_option_t *opt)
+{
+ uint64_t value = 0;
+ int ret = 0;
+
+ GF_ASSERT (opt);
+
+ if (gf_string2bytesize (sizestr, &value) != 0 ||
+ value < opt->min ||
+ value % 512) {
+ ret = -1;
+ goto out;
+ }
+
+ out:
+ gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+static int
+gf_validate_number (const char *numstr, volume_option_t *opt)
+{
+ int32_t value;
+ return gf_string2int32 (numstr, &value);
+}
+
+/* Parses the string to be of the form <key1>:<value1>,<key2>:<value2>... *
+ * takes two optional validaters key_validator and value_validator */
+static int
+validate_list_elements (const char *string, volume_option_t *opt,
+ int (key_validator)( const char *),
+ int (value_validator)( const char *, volume_option_t *))
+{
+
+ char *dup_string = NULL;
+ char *str_sav = NULL;
+ char *substr_sav = NULL;
+ char *str_ptr = NULL;
+ char *key = NULL;
+ char *value = NULL;
+ int ret = 0;
+
+ GF_ASSERT (string);
+
+ dup_string = gf_strdup (string);
+ if (NULL == dup_string)
+ goto out;
+
+ str_ptr = strtok_r (dup_string, ",", &str_sav);
+ if (str_ptr == NULL) {
+ ret = -1;
+ goto out;
+ }
+ while (str_ptr) {
+
+ key = strtok_r (str_ptr, ":", &substr_sav);
+ if (!key ||
+ (key_validator && key_validator(key))) {
+ ret = -1;
+ gf_log (THIS->name, GF_LOG_WARNING,
+ "invalid list '%s', key '%s' not valid.",
+ string, key);
+ goto out;
+ }
+
+ value = strtok_r (NULL, ":", &substr_sav);
+ if (!value ||
+ (value_validator && value_validator(value, opt))) {
+ ret = -1;
+ gf_log (THIS->name, GF_LOG_WARNING,
+ "invalid list '%s', value '%s' not valid.",
+ string, key);
+ goto out;
+ }
+
+ str_ptr = strtok_r (NULL, ",", &str_sav);
+ substr_sav = NULL;
+ }
+
+ out:
+ GF_FREE (dup_string);
+ gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+static int
+xlator_option_validate_priority_list (xlator_t *xl, const char *key,
+ const char *value, volume_option_t *opt,
+ char **op_errstr)
+{
+ int ret =0;
+ char errstr[1024] = {0, };
+
+ GF_ASSERT (value);
+
+ ret = validate_list_elements (value, opt, NULL, &gf_validate_number);
+ if (ret) {
+ snprintf (errstr, 1024,
+ "option %s %s: '%s' is not a valid "
+ "priority-list", key, value, value);
+ *op_errstr = gf_strdup (errstr);
+ }
+
+ return ret;
+}
+
+static int
+xlator_option_validate_size_list (xlator_t *xl, const char *key,
+ const char *value, volume_option_t *opt,
+ char **op_errstr)
+{
+
+ int ret = 0;
+ char errstr[1024] = {0, };
+
+ GF_ASSERT (value);
+
+ ret = gf_validate_size (value, opt);
+ if (ret)
+ ret = validate_list_elements (value, opt, NULL, &gf_validate_size);
+
+ if (ret) {
+ snprintf (errstr, 1024,
+ "option %s %s: '%s' is not a valid "
+ "size-list", key, value, value);
+ *op_errstr = gf_strdup (errstr);
+ }
+
+ return ret;
+
+}
+
+static int
+xlator_option_validate_any (xlator_t *xl, const char *key, const char *value,
+ volume_option_t *opt, char **op_errstr)
+{
+ return 0;
+}
+
+typedef int (xlator_option_validator_t) (xlator_t *xl, const char *key,
+ const char *value,
+ volume_option_t *opt, char **operrstr);
+
+int
+xlator_option_validate (xlator_t *xl, char *key, char *value,
+ volume_option_t *opt, char **op_errstr)
+{
+ int ret = -1;
+ xlator_option_validator_t *validate;
+ xlator_option_validator_t *validators[] = {
+ [GF_OPTION_TYPE_PATH] = xlator_option_validate_path,
+ [GF_OPTION_TYPE_INT] = xlator_option_validate_int,
+ [GF_OPTION_TYPE_SIZET] = xlator_option_validate_sizet,
+ [GF_OPTION_TYPE_BOOL] = xlator_option_validate_bool,
+ [GF_OPTION_TYPE_XLATOR] = xlator_option_validate_xlator,
+ [GF_OPTION_TYPE_STR] = xlator_option_validate_str,
+ [GF_OPTION_TYPE_PERCENT] = xlator_option_validate_percent,
+ [GF_OPTION_TYPE_PERCENT_OR_SIZET] =
+ xlator_option_validate_percent_or_sizet,
+ [GF_OPTION_TYPE_TIME] = xlator_option_validate_time,
+ [GF_OPTION_TYPE_DOUBLE] = xlator_option_validate_double,
+ [GF_OPTION_TYPE_INTERNET_ADDRESS] = xlator_option_validate_addr,
+ [GF_OPTION_TYPE_INTERNET_ADDRESS_LIST] =
+ xlator_option_validate_addr_list,
+ [GF_OPTION_TYPE_PRIORITY_LIST] =
+ xlator_option_validate_priority_list,
+ [GF_OPTION_TYPE_SIZE_LIST] = xlator_option_validate_size_list,
+ [GF_OPTION_TYPE_ANY] = xlator_option_validate_any,
+ [GF_OPTION_TYPE_MAX] = NULL,
+ };
+
+ if (opt->type < 0 || opt->type >= GF_OPTION_TYPE_MAX) {
+ gf_log (xl->name, GF_LOG_ERROR,
+ "unknown option type '%d'", opt->type);
+ goto out;
+ }
+
+ validate = validators[opt->type];
+
+ ret = validate (xl, key, value, opt, op_errstr);
+out:
+ return ret;
+}
+
+
+volume_option_t *
+xlator_volume_option_get_list (volume_opt_list_t *vol_list, const char *key)
+{
+ volume_option_t *opt = NULL;
+ volume_opt_list_t *opt_list = NULL;
+ volume_option_t *found = NULL;
+ int index = 0;
+ int i = 0;
+ char *cmp_key = NULL;
+
+ if (!vol_list->given_opt) {
+ opt_list = list_entry (vol_list->list.next, volume_opt_list_t,
+ list);
+ opt = opt_list->given_opt;
+ } else
+ opt = vol_list->given_opt;
+
+ for (index = 0; opt[index].key[0]; index++) {
+ for (i = 0; i < ZR_VOLUME_MAX_NUM_KEY; i++) {
+ cmp_key = opt[index].key[i];
+ if (!cmp_key)
+ break;
+ if (fnmatch (cmp_key, key, FNM_NOESCAPE) == 0) {
+ found = &opt[index];
+ goto out;
+ }
+ }
+ }
+out:
+ return found;
+}
+
+
+volume_option_t *
+xlator_volume_option_get (xlator_t *xl, const char *key)
+{
+ volume_opt_list_t *vol_list = NULL;
+ volume_option_t *found = NULL;
+
+ list_for_each_entry (vol_list, &xl->volume_options, list) {
+ found = xlator_volume_option_get_list (vol_list, key);
+ if (found)
+ break;
+ }
+
+ return found;
+}
+
+
+static int
+xl_opt_validate (dict_t *dict, char *key, data_t *value, void *data)
+{
+ xlator_t *xl = NULL;
+ volume_opt_list_t *vol_opt = NULL;
+ volume_option_t *opt = NULL;
+ int ret = 0;
+ char *errstr = NULL;
+
+ struct {
+ xlator_t *this;
+ volume_opt_list_t *vol_opt;
+ char *errstr;
+ } *stub;
+
+ stub = data;
+ xl = stub->this;
+ vol_opt = stub->vol_opt;
+
+ opt = xlator_volume_option_get_list (vol_opt, key);
+ if (!opt)
+ return 0;
+
+ ret = xlator_option_validate (xl, key, value->data, opt, &errstr);
+ if (ret)
+ gf_log (xl->name, GF_LOG_WARNING, "validate of %s returned %d",
+ key, ret);
+
+ if (errstr)
+ /* possible small leak of previously set stub->errstr */
+ stub->errstr = errstr;
+
+ if (fnmatch (opt->key[0], key, FNM_NOESCAPE) != 0) {
+ gf_log (xl->name, GF_LOG_WARNING, "option '%s' is deprecated, "
+ "preferred is '%s', continuing with correction",
+ key, opt->key[0]);
+ dict_set (dict, opt->key[0], value);
+ dict_del (dict, key);
+ }
+ return 0;
+}
+
+
+int
+xlator_options_validate_list (xlator_t *xl, dict_t *options,
+ volume_opt_list_t *vol_opt, char **op_errstr)
+{
+ int ret = 0;
+ struct {
+ xlator_t *this;
+ volume_opt_list_t *vol_opt;
+ char *errstr;
+ } stub;
+
+ stub.this = xl;
+ stub.vol_opt = vol_opt;
+ stub.errstr = NULL;
+
+ dict_foreach (options, xl_opt_validate, &stub);
+ if (stub.errstr) {
+ ret = -1;
+ if (op_errstr)
+ *op_errstr = stub.errstr;
+ }
+
+ return ret;
+}
+
+
+int
+xlator_options_validate (xlator_t *xl, dict_t *options, char **op_errstr)
+{
+ int ret = 0;
+ volume_opt_list_t *vol_opt = NULL;
+
+
+ if (!xl) {
+ gf_log (THIS->name, GF_LOG_DEBUG, "'this' not a valid ptr");
+ ret = -1;
+ goto out;
+ }
+
+ if (list_empty (&xl->volume_options))
+ goto out;
+
+ list_for_each_entry (vol_opt, &xl->volume_options, list) {
+ ret = xlator_options_validate_list (xl, options, vol_opt,
+ op_errstr);
+ }
+out:
+ return ret;
+}
+
+
+int
+xlator_validate_rec (xlator_t *xlator, char **op_errstr)
+{
+ int ret = -1;
+ xlator_list_t *trav = NULL;
+ xlator_t *old_THIS = NULL;
+
+ GF_VALIDATE_OR_GOTO ("xlator", xlator, out);
+
+ trav = xlator->children;
+
+ while (trav) {
+ if (xlator_validate_rec (trav->xlator, op_errstr)) {
+ gf_log ("xlator", GF_LOG_WARNING, "validate_rec failed");
+ goto out;
+ }
+
+ trav = trav->next;
+ }
+
+ if (xlator_dynload (xlator))
+ gf_log (xlator->name, GF_LOG_DEBUG, "Did not load the symbols");
+
+ old_THIS = THIS;
+ THIS = xlator;
+
+ /* Need this here, as this graph has not yet called init() */
+ if (!xlator->mem_acct.num_types) {
+ if (!xlator->mem_acct_init)
+ xlator->mem_acct_init = default_mem_acct_init;
+ xlator->mem_acct_init (xlator);
+ }
+
+ ret = xlator_options_validate (xlator, xlator->options, op_errstr);
+ THIS = old_THIS;
+
+ if (ret) {
+ gf_log (xlator->name, GF_LOG_INFO, "%s", *op_errstr);
+ goto out;
+ }
+
+ gf_log (xlator->name, GF_LOG_DEBUG, "Validated options");
+
+ ret = 0;
+out:
+ return ret;
+}
+
+
+int
+graph_reconf_validateopt (glusterfs_graph_t *graph, char **op_errstr)
+{
+ xlator_t *xlator = NULL;
+ int ret = -1;
+
+ GF_ASSERT (graph);
+
+ xlator = graph->first;
+
+ ret = xlator_validate_rec (xlator, op_errstr);
+
+ return ret;
+}
+
+
+static int
+xlator_reconfigure_rec (xlator_t *old_xl, xlator_t *new_xl)
+{
+ xlator_list_t *trav1 = NULL;
+ xlator_list_t *trav2 = NULL;
+ int32_t ret = -1;
+ xlator_t *old_THIS = NULL;
+
+ GF_VALIDATE_OR_GOTO ("xlator", old_xl, out);
+ GF_VALIDATE_OR_GOTO ("xlator", new_xl, out);
+
+ trav1 = old_xl->children;
+ trav2 = new_xl->children;
+
+ while (trav1 && trav2) {
+ ret = xlator_reconfigure_rec (trav1->xlator, trav2->xlator);
+ if (ret)
+ goto out;
+
+ gf_log (trav1->xlator->name, GF_LOG_DEBUG, "reconfigured");
+
+ trav1 = trav1->next;
+ trav2 = trav2->next;
+ }
+
+ if (old_xl->reconfigure) {
+ old_THIS = THIS;
+ THIS = old_xl;
+
+ ret = old_xl->reconfigure (old_xl, new_xl->options);
+
+ THIS = old_THIS;
+
+ if (ret)
+ goto out;
+ } else {
+ gf_log (old_xl->name, GF_LOG_DEBUG, "No reconfigure() found");
+ }
+
+ ret = 0;
+out:
+ return ret;
+}
+
+
+int
+xlator_tree_reconfigure (xlator_t *old_xl, xlator_t *new_xl)
+{
+ xlator_t *new_top = NULL;
+ xlator_t *old_top = NULL;
+
+ GF_ASSERT (old_xl);
+ GF_ASSERT (new_xl);
+
+ old_top = old_xl;
+ new_top = new_xl;
+
+ return xlator_reconfigure_rec (old_top, new_top);
+}
+
+
+int
+xlator_option_info_list (volume_opt_list_t *list, char *key,
+ char **def_val, char **descr)
+{
+ int ret = -1;
+ volume_option_t *opt = NULL;
+
+
+ opt = xlator_volume_option_get_list (list, key);
+ if (!opt)
+ goto out;
+
+ if (def_val)
+ *def_val = opt->default_value;
+ if (descr)
+ *descr = opt->description;
+
+ ret = 0;
+out:
+ return ret;
+}
+
+
+static int
+pass (char *in, char **out)
+{
+ *out = in;
+ return 0;
+}
+
+
+static int
+xl_by_name (char *in, xlator_t **out)
+{
+ xlator_t *xl = NULL;
+
+ xl = xlator_search_by_name (THIS, in);
+
+ if (!xl)
+ return -1;
+ *out = xl;
+ return 0;
+}
+
+
+static int
+pc_or_size (char *in, double *out)
+{
+ double pc = 0;
+ int ret = 0;
+ uint64_t size = 0;
+
+ if (gf_string2percent (in, &pc) == 0) {
+ if (pc > 100.0) {
+ ret = gf_string2bytesize (in, &size);
+ if (!ret)
+ *out = size;
+ } else {
+ *out = pc;
+ }
+ } else {
+ ret = gf_string2bytesize (in, &size);
+ if (!ret)
+ *out = size;
+ }
+ return ret;
+}
+
+DEFINE_INIT_OPT(char *, str, pass);
+DEFINE_INIT_OPT(uint64_t, uint64, gf_string2uint64);
+DEFINE_INIT_OPT(int64_t, int64, gf_string2int64);
+DEFINE_INIT_OPT(uint32_t, uint32, gf_string2uint32);
+DEFINE_INIT_OPT(int32_t, int32, gf_string2int32);
+DEFINE_INIT_OPT(uint64_t, size, gf_string2bytesize);
+DEFINE_INIT_OPT(double, percent, gf_string2percent);
+DEFINE_INIT_OPT(double, percent_or_size, pc_or_size);
+DEFINE_INIT_OPT(gf_boolean_t, bool, gf_string2boolean);
+DEFINE_INIT_OPT(xlator_t *, xlator, xl_by_name);
+DEFINE_INIT_OPT(char *, path, pass);
+DEFINE_INIT_OPT(double, double, gf_string2double);
+
+
+
+DEFINE_RECONF_OPT(char *, str, pass);
+DEFINE_RECONF_OPT(uint64_t, uint64, gf_string2uint64);
+DEFINE_RECONF_OPT(int64_t, int64, gf_string2int64);
+DEFINE_RECONF_OPT(uint32_t, uint32, gf_string2uint32);
+DEFINE_RECONF_OPT(int32_t, int32, gf_string2int32);
+DEFINE_RECONF_OPT(uint64_t, size, gf_string2bytesize);
+DEFINE_RECONF_OPT(double, percent, gf_string2percent);
+DEFINE_RECONF_OPT(double, percent_or_size, pc_or_size);
+DEFINE_RECONF_OPT(gf_boolean_t, bool, gf_string2boolean);
+DEFINE_RECONF_OPT(xlator_t *, xlator, xl_by_name);
+DEFINE_RECONF_OPT(char *, path, pass);
+DEFINE_RECONF_OPT(double, double, gf_string2double);
diff --git a/libglusterfs/src/options.h b/libglusterfs/src/options.h
new file mode 100644
index 000000000..e2a25baa9
--- /dev/null
+++ b/libglusterfs/src/options.h
@@ -0,0 +1,259 @@
+/*
+ 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.
+*/
+
+#ifndef _OPTIONS_H
+#define _OPTIONS_H
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include "xlator.h"
+/* Add possible new type of option you may need */
+typedef enum {
+ GF_OPTION_TYPE_ANY = 0,
+ GF_OPTION_TYPE_STR,
+ GF_OPTION_TYPE_INT,
+ GF_OPTION_TYPE_SIZET,
+ GF_OPTION_TYPE_PERCENT,
+ GF_OPTION_TYPE_PERCENT_OR_SIZET,
+ GF_OPTION_TYPE_BOOL,
+ GF_OPTION_TYPE_XLATOR,
+ GF_OPTION_TYPE_PATH,
+ GF_OPTION_TYPE_TIME,
+ GF_OPTION_TYPE_DOUBLE,
+ GF_OPTION_TYPE_INTERNET_ADDRESS,
+ GF_OPTION_TYPE_INTERNET_ADDRESS_LIST,
+ GF_OPTION_TYPE_PRIORITY_LIST,
+ GF_OPTION_TYPE_SIZE_LIST,
+ GF_OPTION_TYPE_MAX,
+} volume_option_type_t;
+
+typedef enum {
+ GF_OPT_VALIDATE_BOTH = 0,
+ GF_OPT_VALIDATE_MIN,
+ GF_OPT_VALIDATE_MAX,
+} opt_validate_type_t;
+
+#define ZR_VOLUME_MAX_NUM_KEY 4
+#define ZR_OPTION_MAX_ARRAY_SIZE 64
+
+/* Each translator should define this structure */
+typedef struct volume_options {
+ char *key[ZR_VOLUME_MAX_NUM_KEY];
+ /* different key, same meaning */
+ volume_option_type_t type;
+ double min; /* 0 means no range */
+ double max; /* 0 means no range */
+ char *value[ZR_OPTION_MAX_ARRAY_SIZE];
+ /* If specified, will check for one of
+ the value from this array */
+ char *default_value;
+ char *description; /* about the key */
+ /* Required for int options where only the min value
+ * is given and is 0. This will cause validation not to
+ * happen
+ */
+ opt_validate_type_t validate;
+} volume_option_t;
+
+
+typedef struct vol_opt_list {
+ struct list_head list;
+ volume_option_t *given_opt;
+} volume_opt_list_t;
+
+
+int xlator_tree_reconfigure (xlator_t *old_xl, xlator_t *new_xl);
+int xlator_validate_rec (xlator_t *xlator, char **op_errstr);
+int graph_reconf_validateopt (glusterfs_graph_t *graph, char **op_errstr);
+int xlator_option_info_list (volume_opt_list_t *list, char *key,
+ char **def_val, char **descr);
+/*
+int validate_xlator_volume_options (xlator_t *xl, dict_t *options,
+ volume_option_t *opt, char **op_errstr);
+*/
+int xlator_options_validate_list (xlator_t *xl, dict_t *options,
+ volume_opt_list_t *list, char **op_errstr);
+int xlator_option_validate (xlator_t *xl, char *key, char *value,
+ volume_option_t *opt, char **op_errstr);
+int xlator_options_validate (xlator_t *xl, dict_t *options, char **errstr);
+volume_option_t *
+xlator_volume_option_get (xlator_t *xl, const char *key);
+
+volume_option_t *
+xlator_volume_option_get_list (volume_opt_list_t *vol_list, const char *key);
+
+
+#define DECLARE_INIT_OPT(type_t, type) \
+int \
+xlator_option_init_##type (xlator_t *this, dict_t *options, char *key, \
+ type_t *val_p);
+
+DECLARE_INIT_OPT(char *, str);
+DECLARE_INIT_OPT(uint64_t, uint64);
+DECLARE_INIT_OPT(int64_t, int64);
+DECLARE_INIT_OPT(uint32_t, uint32);
+DECLARE_INIT_OPT(int32_t, int32);
+DECLARE_INIT_OPT(uint64_t, size);
+DECLARE_INIT_OPT(double, percent);
+DECLARE_INIT_OPT(double, percent_or_size);
+DECLARE_INIT_OPT(gf_boolean_t, bool);
+DECLARE_INIT_OPT(xlator_t *, xlator);
+DECLARE_INIT_OPT(char *, path);
+DECLARE_INIT_OPT(double, double);
+
+
+#define DEFINE_INIT_OPT(type_t, type, conv) \
+int \
+xlator_option_init_##type (xlator_t *this, dict_t *options, char *key, \
+ type_t *val_p) \
+{ \
+ int ret = 0; \
+ volume_option_t *opt = NULL; \
+ char *def_value = NULL; \
+ char *set_value = NULL; \
+ char *value = NULL; \
+ xlator_t *old_THIS = NULL; \
+ \
+ opt = xlator_volume_option_get (this, key); \
+ if (!opt) { \
+ gf_log (this->name, GF_LOG_WARNING, \
+ "unknown option: %s", key); \
+ ret = -1; \
+ return ret; \
+ } \
+ def_value = opt->default_value; \
+ ret = dict_get_str (options, key, &set_value); \
+ \
+ if (def_value) \
+ value = def_value; \
+ if (set_value) \
+ value = set_value; \
+ if (!value) { \
+ gf_log (this->name, GF_LOG_TRACE, "option %s not set", \
+ key); \
+ *val_p = (type_t)0; \
+ return 0; \
+ } \
+ if (value == def_value) { \
+ gf_log (this->name, GF_LOG_TRACE, \
+ "option %s using default value %s", \
+ key, value); \
+ } else { \
+ gf_log (this->name, GF_LOG_DEBUG, \
+ "option %s using set value %s", \
+ key, value); \
+ } \
+ old_THIS = THIS; \
+ THIS = this; \
+ ret = conv (value, val_p); \
+ THIS = old_THIS; \
+ if (ret) \
+ return ret; \
+ ret = xlator_option_validate (this, key, value, opt, NULL); \
+ return ret; \
+}
+
+#define GF_OPTION_INIT(key, val, type, err_label) do { \
+ int val_ret = 0; \
+ val_ret = xlator_option_init_##type (THIS, THIS->options, \
+ key, &(val)); \
+ if (val_ret) \
+ goto err_label; \
+ } while (0)
+
+
+
+#define DECLARE_RECONF_OPT(type_t, type) \
+int \
+xlator_option_reconf_##type (xlator_t *this, dict_t *options, char *key,\
+ type_t *val_p);
+
+DECLARE_RECONF_OPT(char *, str);
+DECLARE_RECONF_OPT(uint64_t, uint64);
+DECLARE_RECONF_OPT(int64_t, int64);
+DECLARE_RECONF_OPT(uint32_t, uint32);
+DECLARE_RECONF_OPT(int32_t, int32);
+DECLARE_RECONF_OPT(uint64_t, size);
+DECLARE_RECONF_OPT(double, percent);
+DECLARE_RECONF_OPT(double, percent_or_size);
+DECLARE_RECONF_OPT(gf_boolean_t, bool);
+DECLARE_RECONF_OPT(xlator_t *, xlator);
+DECLARE_RECONF_OPT(char *, path);
+DECLARE_RECONF_OPT(double, double);
+
+
+#define DEFINE_RECONF_OPT(type_t, type, conv) \
+int \
+xlator_option_reconf_##type (xlator_t *this, dict_t *options, char *key, \
+ type_t *val_p) \
+{ \
+ int ret = 0; \
+ volume_option_t *opt = NULL; \
+ char *def_value = NULL; \
+ char *set_value = NULL; \
+ char *value = NULL; \
+ xlator_t *old_THIS = NULL; \
+ \
+ opt = xlator_volume_option_get (this, key); \
+ if (!opt) { \
+ gf_log (this->name, GF_LOG_WARNING, \
+ "unknown option: %s", key); \
+ ret = -1; \
+ return ret; \
+ } \
+ def_value = opt->default_value; \
+ ret = dict_get_str (options, key, &set_value); \
+ \
+ if (def_value) \
+ value = def_value; \
+ if (set_value) \
+ value = set_value; \
+ if (!value) { \
+ gf_log (this->name, GF_LOG_TRACE, "option %s not set", \
+ key); \
+ *val_p = (type_t)0; \
+ return 0; \
+ } \
+ if (value == def_value) { \
+ gf_log (this->name, GF_LOG_TRACE, \
+ "option %s using default value %s", \
+ key, value); \
+ } else { \
+ gf_log (this->name, GF_LOG_DEBUG, \
+ "option %s using set value %s", \
+ key, value); \
+ } \
+ old_THIS = THIS; \
+ THIS = this; \
+ ret = conv (value, val_p); \
+ THIS = old_THIS; \
+ if (ret) \
+ return ret; \
+ ret = xlator_option_validate (this, key, value, opt, NULL); \
+ return ret; \
+}
+
+#define GF_OPTION_RECONF(key, val, opt, type, err_label) do { \
+ int val_ret = 0; \
+ val_ret = xlator_option_reconf_##type (THIS, opt, key, \
+ &(val)); \
+ if (val_ret) \
+ goto err_label; \
+ } while (0)
+
+
+#endif /* !_OPTIONS_H */
diff --git a/libglusterfs/src/rbthash.c b/libglusterfs/src/rbthash.c
index 3a45d9fb6..0d7b9e521 100644
--- a/libglusterfs/src/rbthash.c
+++ b/libglusterfs/src/rbthash.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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.
*/
@@ -124,7 +115,6 @@ rbthash_table_init (int buckets, rbt_hasher_t hfunc,
newtab->buckets = GF_CALLOC (buckets, sizeof (struct rbthash_bucket),
gf_common_mt_rbthash_bucket);
if (!newtab->buckets) {
- gf_log (GF_RBTHASH, GF_LOG_ERROR, "Failed to allocate memory");
goto free_newtab;
}
@@ -142,6 +132,7 @@ rbthash_table_init (int buckets, rbt_hasher_t hfunc,
}
LOCK_INIT (&newtab->tablelock);
+ INIT_LIST_HEAD (&newtab->list);
newtab->numbuckets = buckets;
ret = __rbthash_init_buckets (newtab, buckets);
@@ -189,10 +180,10 @@ rbthash_init_entry (rbthash_table_t *tbl, void *data, void *key, int keylen)
entry->data = data;
entry->key = GF_CALLOC (keylen, sizeof (char), gf_common_mt_char);
if (!entry->key) {
- gf_log (GF_RBTHASH, GF_LOG_ERROR, "Memory allocation failed");
goto free_entry;
}
+ INIT_LIST_HEAD (&entry->list);
memcpy (entry->key, key, keylen);
entry->keylen = keylen;
entry->keyhash = tbl->hashfunc (entry->key, entry->keylen);
@@ -201,7 +192,7 @@ rbthash_init_entry (rbthash_table_t *tbl, void *data, void *key, int keylen)
ret = 0;
free_entry:
if (ret == -1) {
- mem_put (tbl->entrypool, entry);
+ mem_put (entry);
entry = NULL;
}
@@ -217,20 +208,26 @@ rbthash_deinit_entry (rbthash_table_t *tbl, rbthash_entry_t *entry)
if (!entry)
return;
- if (entry->key)
- GF_FREE (entry->key);
+ GF_FREE (entry->key);
if (tbl) {
if ((entry->data) && (tbl->dfunc))
tbl->dfunc (entry->data);
- mem_put (tbl->entrypool, entry);
+
+ LOCK (&tbl->tablelock);
+ {
+ list_del_init (&entry->list);
+ }
+ UNLOCK (&tbl->tablelock);
+
+ mem_put (entry);
}
return;
}
-inline struct rbthash_bucket *
+static inline struct rbthash_bucket *
rbthash_entry_bucket (rbthash_table_t *tbl, rbthash_entry_t * entry)
{
int nbucket = 0;
@@ -294,11 +291,17 @@ rbthash_insert (rbthash_table_t *tbl, void *data, void *key, int keylen)
rbthash_deinit_entry (tbl, entry);
}
+ LOCK (&tbl->tablelock);
+ {
+ list_add_tail (&entry->list, &tbl->list);
+ }
+ UNLOCK (&tbl->tablelock);
+
err:
return ret;
}
-inline struct rbthash_bucket *
+static inline struct rbthash_bucket *
rbthash_key_bucket (rbthash_table_t *tbl, void *key, int keylen)
{
uint32_t keyhash = 0;
@@ -378,7 +381,14 @@ rbthash_remove (rbthash_table_t *tbl, void *key, int keylen)
GF_FREE (entry->key);
dataref = entry->data;
- mem_put (tbl->entrypool, entry);
+
+ LOCK (&tbl->tablelock);
+ {
+ list_del_init (&entry->list);
+ }
+ UNLOCK (&tbl->tablelock);
+
+ mem_put (entry);
return dataref;
}
@@ -424,3 +434,25 @@ rbthash_table_destroy (rbthash_table_t *tbl)
GF_FREE (tbl);
}
+
+void
+rbthash_table_traverse (rbthash_table_t *tbl, rbt_traverse_t traverse,
+ void *mydata)
+{
+ rbthash_entry_t *entry = NULL;
+
+ if ((tbl == NULL) || (traverse == NULL)) {
+ goto out;
+ }
+
+ LOCK (&tbl->tablelock);
+ {
+ list_for_each_entry (entry, &tbl->list, list) {
+ traverse (entry->data, mydata);
+ }
+ }
+ UNLOCK (&tbl->tablelock);
+
+out:
+ return;
+}
diff --git a/libglusterfs/src/rbthash.h b/libglusterfs/src/rbthash.h
index 73b5b8e30..b093ce998 100644
--- a/libglusterfs/src/rbthash.h
+++ b/libglusterfs/src/rbthash.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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 __RBTHASH_TABLE_H_
@@ -24,6 +15,7 @@
#include "mem-pool.h"
#include "logging.h"
#include "common-utils.h"
+#include "list.h"
#include <pthread.h>
@@ -38,12 +30,14 @@ struct rbthash_bucket {
typedef struct rbthash_entry {
void *data;
void *key;
- int keylen;
- uint32_t keyhash;
+ int keylen;
+ uint32_t keyhash;
+ struct list_head list;
} rbthash_entry_t;
typedef uint32_t (*rbt_hasher_t) (void *data, int len);
typedef void (*rbt_data_destroyer_t) (void *data);
+typedef void (*rbt_traverse_t) (void *data, void *mydata);
typedef struct rbthash_table {
int size;
@@ -54,6 +48,7 @@ typedef struct rbthash_table {
rbt_hasher_t hashfunc;
rbt_data_destroyer_t dfunc;
gf_boolean_t pool_alloced;
+ struct list_head list;
} rbthash_table_t;
extern rbthash_table_t *
@@ -75,4 +70,8 @@ rbthash_replace (rbthash_table_t *tbl, void *key, int keylen, void *newdata);
extern void
rbthash_table_destroy (rbthash_table_t *tbl);
+
+extern void
+rbthash_table_traverse (rbthash_table_t *tbl, rbt_traverse_t traverse,
+ void *mydata);
#endif
diff --git a/libglusterfs/src/run.c b/libglusterfs/src/run.c
new file mode 100644
index 000000000..4fd2a3a0d
--- /dev/null
+++ b/libglusterfs/src/run.c
@@ -0,0 +1,513 @@
+/*
+ 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.
+*/
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <assert.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <sys/resource.h>
+
+#ifdef RUN_STANDALONE
+#define GF_CALLOC(n, s, t) calloc(n, s)
+#define GF_ASSERT(cond) assert(cond)
+#define GF_REALLOC(p, s) realloc(p, s)
+#define GF_FREE(p) free(p)
+#define gf_strdup(s) strdup(s)
+#define gf_vasprintf(p, f, va) vasprintf(p, f, va)
+#define gf_loglevel_t int
+#define gf_log(dom, levl, fmt, args...) printf("LOG: " fmt "\n", ##args)
+#define LOG_DEBUG 0
+#ifdef __linux__
+#define GF_LINUX_HOST_OS
+#endif
+#else /* ! RUN_STANDALONE */
+#include "glusterfs.h"
+#include "common-utils.h"
+#endif
+
+#include "run.h"
+
+void
+runinit (runner_t *runner)
+{
+ int i = 0;
+
+ runner->argvlen = 64;
+ runner->argv = GF_CALLOC (runner->argvlen,
+ sizeof (*runner->argv),
+ gf_common_mt_run_argv);
+ runner->runerr = runner->argv ? 0 : errno;
+ runner->chpid = -1;
+ for (i = 0; i < 3; i++) {
+ runner->chfd[i] = -1;
+ runner->chio[i] = NULL;
+ }
+}
+
+FILE *
+runner_chio (runner_t *runner, int fd)
+{
+ GF_ASSERT (fd > 0 && fd < 3);
+
+ if ((fd > 0) && (fd < 3))
+ return runner->chio[fd];
+
+ return NULL;
+}
+
+static void
+runner_insert_arg (runner_t *runner, char *arg)
+{
+ int i = 0;
+
+ GF_ASSERT (arg);
+
+ if (runner->runerr)
+ return;
+
+ for (i = 0; i < runner->argvlen; i++) {
+ if (runner->argv[i] == NULL)
+ break;
+ }
+ GF_ASSERT (i < runner->argvlen);
+
+ if (i == runner->argvlen - 1) {
+ runner->argv = GF_REALLOC (runner->argv,
+ runner->argvlen * 2 * sizeof (*runner->argv));
+ if (!runner->argv) {
+ runner->runerr = errno;
+ return;
+ }
+ memset (/* "+" is aware of the type of its left side,
+ * no need to multiply with type-size */
+ runner->argv + runner->argvlen,
+ 0, runner->argvlen * sizeof (*runner->argv));
+ runner->argvlen *= 2;
+ }
+
+ runner->argv[i] = arg;
+}
+
+void
+runner_add_arg (runner_t *runner, const char *arg)
+{
+ arg = gf_strdup (arg);
+ if (!arg) {
+ runner->runerr = errno;
+ return;
+ }
+
+ runner_insert_arg (runner, (char *)arg);
+}
+
+static void
+runner_va_add_args (runner_t *runner, va_list argp)
+{
+ const char *arg;
+
+ while ((arg = va_arg (argp, const char *)))
+ runner_add_arg (runner, arg);
+}
+
+void
+runner_add_args (runner_t *runner, ...)
+{
+ va_list argp;
+
+ va_start (argp, runner);
+ runner_va_add_args (runner, argp);
+ va_end (argp);
+}
+
+void
+runner_argprintf (runner_t *runner, const char *format, ...)
+{
+ va_list argva;
+ char *arg = NULL;
+ int ret = 0;
+
+ va_start (argva, format);
+ ret = gf_vasprintf (&arg, format, argva);
+ va_end (argva);
+
+ if (ret < 0) {
+ runner->runerr = errno;
+ return;
+ }
+
+ runner_insert_arg (runner, arg);
+}
+
+void
+runner_log (runner_t *runner, const char *dom, gf_loglevel_t lvl,
+ const char *msg)
+{
+ char *buf = NULL;
+ size_t len = 0;
+ int i = 0;
+
+ if (runner->runerr)
+ return;
+
+ for (i = 0;; i++) {
+ if (runner->argv[i] == NULL)
+ break;
+ len += (strlen (runner->argv[i]) + 1);
+ }
+
+ buf = GF_CALLOC (1, len + 1, gf_common_mt_run_logbuf);
+ if (!buf) {
+ runner->runerr = errno;
+ return;
+ }
+ for (i = 0;; i++) {
+ if (runner->argv[i] == NULL)
+ break;
+ strcat (buf, runner->argv[i]);
+ strcat (buf, " ");
+ }
+ if (len > 0)
+ buf[len - 1] = '\0';
+
+ gf_log_callingfn (dom, lvl, "%s: %s", msg, buf);
+
+ GF_FREE (buf);
+}
+
+void
+runner_redir (runner_t *runner, int fd, int tgt_fd)
+{
+ GF_ASSERT (fd > 0 && fd < 3);
+
+ if ((fd > 0) && (fd < 3))
+ runner->chfd[fd] = (tgt_fd >= 0) ? tgt_fd : -2;
+}
+
+int
+runner_start (runner_t *runner)
+{
+ int pi[3][2] = {{-1, -1}, {-1, -1}, {-1, -1}};
+ int xpi[2];
+ int ret = 0;
+ int errno_priv = 0;
+ int i = 0;
+ sigset_t set;
+
+ if (runner->runerr) {
+ errno = runner->runerr;
+ return -1;
+ }
+
+ GF_ASSERT (runner->argv[0]);
+
+ /* set up a channel to child to communicate back
+ * possible execve(2) failures
+ */
+ ret = pipe(xpi);
+ if (ret != -1)
+ ret = fcntl (xpi[1], F_SETFD, FD_CLOEXEC);
+
+ for (i = 0; i < 3; i++) {
+ if (runner->chfd[i] != -2)
+ continue;
+ ret = pipe (pi[i]);
+ if (ret != -1) {
+ runner->chio[i] = fdopen (pi[i][i ? 0 : 1], i ? "r" : "w");
+ if (!runner->chio[i])
+ ret = -1;
+ }
+ }
+
+ if (ret != -1)
+ runner->chpid = fork ();
+ switch (runner->chpid) {
+ case -1:
+ errno_priv = errno;
+ close (xpi[0]);
+ close (xpi[1]);
+ for (i = 0; i < 3; i++) {
+ close (pi[i][0]);
+ close (pi[i][1]);
+ }
+ errno = errno_priv;
+ return -1;
+ case 0:
+ for (i = 0; i < 3; i++)
+ close (pi[i][i ? 0 : 1]);
+ close (xpi[0]);
+ ret = 0;
+
+ for (i = 0; i < 3; i++) {
+ if (ret == -1)
+ break;
+ switch (runner->chfd[i]) {
+ case -1:
+ /* no redir */
+ break;
+ case -2:
+ /* redir to pipe */
+ ret = dup2 (pi[i][i ? 1 : 0], i);
+ break;
+ default:
+ /* redir to file */
+ ret = dup2 (runner->chfd[i], i);
+ }
+ }
+
+ if (ret != -1 ) {
+#ifdef GF_LINUX_HOST_OS
+ DIR *d = NULL;
+ struct dirent *de = NULL;
+ char *e = NULL;
+
+ d = opendir ("/proc/self/fd");
+ if (d) {
+ while ((de = readdir (d))) {
+ i = strtoul (de->d_name, &e, 10);
+ if (*e == '\0' && i > 2 &&
+ i != dirfd (d) && i != xpi[1])
+ close (i);
+ }
+ closedir (d);
+ } else
+ ret = -1;
+#else
+ struct rlimit rl;
+ ret = getrlimit (RLIMIT_NOFILE, &rl);
+ GF_ASSERT (ret == 0);
+
+ for (i = 3; i < rl.rlim_cur; i++) {
+ if (i != xpi[1])
+ close (i);
+ }
+#endif
+ }
+
+ if (ret != -1) {
+ /* save child from inheriting our singal handling */
+ sigemptyset (&set);
+ sigprocmask (SIG_SETMASK, &set, NULL);
+
+ execvp (runner->argv[0], runner->argv);
+ }
+ ret = write (xpi[1], &errno, sizeof (errno));
+ _exit (1);
+ }
+
+ errno_priv = errno;
+ for (i = 0; i < 3; i++)
+ close (pi[i][i ? 1 : 0]);
+ close (xpi[1]);
+ if (ret == -1) {
+ for (i = 0; i < 3; i++) {
+ if (runner->chio[i]) {
+ fclose (runner->chio[i]);
+ runner->chio[i] = NULL;
+ }
+ }
+ } else {
+ ret = read (xpi[0], (char *)&errno_priv, sizeof (errno_priv));
+ close (xpi[0]);
+ if (ret <= 0)
+ return 0;
+ GF_ASSERT (ret == sizeof (errno_priv));
+ }
+ errno = errno_priv;
+ return -1;
+}
+
+int
+runner_end_reuse (runner_t *runner)
+{
+ int i = 0;
+ int ret = -1;
+ int chstat = 0;
+
+ if (runner->chpid > 0) {
+ if (waitpid (runner->chpid, &chstat, 0) == runner->chpid)
+ ret = chstat;
+ }
+
+ for (i = 0; i < 3; i++) {
+ if (runner->chio[i]) {
+ fclose (runner->chio[i]);
+ runner->chio[i] = NULL;
+ }
+ }
+
+ return ret;
+}
+
+int
+runner_end (runner_t *runner)
+{
+ int i = 0;
+ int ret = -1;
+ char **p = NULL;
+
+ ret = runner_end_reuse (runner);
+
+ if (runner->argv) {
+ for (p = runner->argv; *p; p++)
+ GF_FREE (*p);
+ GF_FREE (runner->argv);
+ }
+ for (i = 0; i < 3; i++)
+ close (runner->chfd[i]);
+
+ return ret;
+}
+
+static int
+runner_run_generic (runner_t *runner, int (*rfin)(runner_t *runner))
+{
+ int ret = 0;
+
+ ret = runner_start (runner);
+
+ return -(rfin (runner) || ret);
+}
+
+int
+runner_run (runner_t *runner)
+{
+ return runner_run_generic (runner, runner_end);
+}
+
+
+int
+runner_run_nowait (runner_t *runner)
+{
+ int pid;
+
+ pid = fork ();
+
+ if (!pid) {
+ setsid ();
+ _exit (runner_start (runner));
+ }
+
+ if (pid > 0)
+ runner->chpid = pid;
+ return runner_end (runner);
+}
+
+
+int
+runner_run_reuse (runner_t *runner)
+{
+ return runner_run_generic (runner, runner_end_reuse);
+}
+
+int
+runcmd (const char *arg, ...)
+{
+ runner_t runner;
+ va_list argp;
+
+ runinit (&runner);
+ /* ISO C requires a named argument before '...' */
+ runner_add_arg (&runner, arg);
+
+ va_start (argp, arg);
+ runner_va_add_args (&runner, argp);
+ va_end (argp);
+
+ return runner_run (&runner);
+}
+
+#ifdef RUN_DO_TESTS
+static void
+TBANNER (const char *txt)
+{
+ printf("######\n### testing %s\n", txt);
+}
+
+int
+main (int argc, char **argv)
+{
+ runner_t runner;
+ char buf[80];
+ char *wdbuf;;
+ int ret;
+ int fd;
+ long pathmax = pathconf ("/", _PC_PATH_MAX);
+ struct timeval tv = {0,};
+ struct timeval *tvp = NULL;
+
+ wdbuf = malloc (pathmax);
+ assert (wdbuf);
+ getcwd (wdbuf, pathmax);
+
+ TBANNER ("basic functionality");
+ runcmd ("echo", "a", "b", NULL);
+
+ TBANNER ("argv extension");
+ runcmd ("echo", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
+ "11", "12", "13", "14", "15", "16", "17", "18", "19", "20",
+ "21", "22", "23", "24", "25", "26", "27", "28", "29", "30",
+ "31", "32", "33", "34", "35", "36", "37", "38", "39", "40",
+ "41", "42", "43", "44", "45", "46", "47", "48", "49", "50",
+ "51", "52", "53", "54", "55", "56", "57", "58", "59", "60",
+ "61", "62", "63", "64", "65", "66", "67", "68", "69", "70",
+ "71", "72", "73", "74", "75", "76", "77", "78", "79", "80",
+ "81", "82", "83", "84", "85", "86", "87", "88", "89", "90",
+ "91", "92", "93", "94", "95", "96", "97", "98", "99", "100", NULL);
+
+ TBANNER ("add_args, argprintf, log, and popen-style functionality");
+ runinit (&runner);
+ runner_add_args (&runner, "echo", "pid:", NULL);
+ runner_argprintf (&runner, "%d\n", getpid());
+ runner_add_arg (&runner, "wd:");
+ runner_add_arg (&runner, wdbuf);
+ runner_redir (&runner, 1, RUN_PIPE);
+ runner_start (&runner);
+ runner_log (&runner, "(x)", LOG_DEBUG, "starting program");
+ while (fgets (buf, sizeof(buf), runner_chio (&runner, 1)))
+ printf ("got: %s", buf);
+ runner_end (&runner);
+
+ TBANNER ("execve error reporting");
+ ret = runcmd ("bafflavvitty", NULL);
+ printf ("%d %d [%s]\n", ret, errno, strerror (errno));
+
+ TBANNER ("output redirection");
+ fd = mkstemp ("/tmp/foof");
+ assert (fd != -1);
+ runinit (&runner);
+ runner_add_args (&runner, "echo", "foo", NULL);
+ runner_redir (&runner, 1, fd);
+ ret = runner_run (&runner);
+ printf ("%d", ret);
+ if (ret != 0)
+ printf (" %d [%s]", errno, strerror (errno));
+ putchar ('\n');
+
+ if (argc > 1) {
+ tv.tv_sec = strtoul (argv[1], NULL, 10);
+ if (tv.tv_sec > 0)
+ tvp = &tv;
+ select (0, 0, 0, 0, tvp);
+ }
+
+ return 0;
+}
+#endif
diff --git a/libglusterfs/src/run.h b/libglusterfs/src/run.h
new file mode 100644
index 000000000..d7554ef6d
--- /dev/null
+++ b/libglusterfs/src/run.h
@@ -0,0 +1,194 @@
+/*
+ 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.
+*/
+
+#ifndef __RUN_H__
+#define __RUN_H__
+
+#define RUN_PIPE -1
+
+struct runner {
+ char **argv;
+ unsigned argvlen;
+ int runerr;
+ pid_t chpid;
+ int chfd[3];
+ FILE *chio[3];
+};
+
+typedef struct runner runner_t;
+
+/**
+ * initialize runner_t instance.
+ *
+ * @param runner pointer to runner_t instance
+ */
+void runinit (runner_t *runner);
+
+/**
+ * get FILE pointer to which child's stdio is redirected.
+ *
+ * @param runner pointer to runner_t instance
+ * @param fd specifies which standard file descriptor is
+ * is asked for
+ *
+ * @see runner_redir()
+ */
+FILE *runner_chio (runner_t *runner, int fd);
+
+/**
+ * add an argument.
+ *
+ * 'arg' is duplicated.
+ *
+ * Errors are deferred, no error handling is necessary.
+ *
+ * @param runner pointer to runner_t instance
+ * @param arg command line argument
+ */
+void runner_add_arg (runner_t *runner, const char *arg);
+
+/**
+ * add a sequence of arguments.
+ *
+ * Variadic function, calls runner_add_arg() on each vararg.
+ * Argument sequence MUST be NULL terminated.
+ *
+ * Errors are deferred, no error handling is necessary.
+ *
+ * @param runner pointer to runner_t instance
+ *
+ * @see runner_add_arg()
+ */
+void runner_add_args (runner_t *runner, ...);
+
+/**
+ * add an argument with printf style formatting.
+ *
+ * Errors are deferred, no error handling is necessary.
+ *
+ * @param runner pointer to runner_t instance
+ * @param format printf style format specifier
+ */
+void runner_argprintf (runner_t *runner, const char *format, ...);
+
+/**
+ * log a message about the command to be run.
+ *
+ * @param runner pointer to runner_t instance
+ *
+ * @param dom log domain
+ * @param lvl log level
+ * @param msg message with which the command is prefixed in log
+ *
+ * @see gf_log()
+ */
+void runner_log (runner_t *runner, const char *dom, gf_loglevel_t lvl,
+ const char *msg);
+
+/**
+ * set up redirection for child.
+ *
+ * @param runner pointer to runner_t instance
+ *
+ * @param fd fd of child to redirect (0, 1, or 2)
+ * @param tgt_fd fd on parent side to redirect to.
+ * Note that runner_end() will close tgt_fd,
+ * if user needs it in another context it should
+ * be dup'd beforehand.
+ * RUN_PIPE can be used for requiring a
+ * pipe from child to parent. The FILE
+ * created for this purpose will be
+ * accessible via runner_chio() (after
+ * runner_start() has been invoked).
+ *
+ * @see runner_start(), dup(2), runner_chio(), runner_start()
+ */
+void
+runner_redir (runner_t *runner, int fd, int tgt_fd);
+
+/**
+ * spawn child with accumulated arg list.
+ *
+ * @param runner pointer to runner_t instance
+ *
+ * @return 0 on succesful spawn
+ * -1 on failure (either due to earlier errors or execve(2) failing)
+ *
+ * @see runner_cout()
+ */
+int runner_start (runner_t *runner);
+
+/**
+ * complete operation and free resources.
+ *
+ * If child exists, waits for it. Redirections will be closed.
+ * Dynamically allocated memory shall be freed.
+ *
+ * @param runner pointer to runner_t instance
+ *
+ * @return 0 if child terminated successfully
+ * -1 if there is no running child
+ * n > 0 if child failed; value to be interpreted as status
+ * in waitpid(2)
+ *
+ * @see waitpid(2)
+ */
+int runner_end (runner_t *runner);
+
+/**
+ * variant of runner_end() which does not free internal data
+ * so that the runner instance can be run again.
+ *
+ * @see runner_end()
+ */
+int runner_end_reuse (runner_t *runner);
+
+/**
+ * spawn and child, take it to completion and free resources.
+ *
+ * Essentially it's a concatenation of runner_start() and runner_end()
+ * with simplified return semantics.
+ *
+ * @param runner pointer to runner_t instance
+ *
+ * @return 0 on success
+ * -1 on failuire
+ *
+ * @see runner_start(), runner_end()
+ */
+int runner_run (runner_t *runner);
+
+/**
+ * variant for runner_run() which does not wait for acknowledgement
+ * from child, and always assumes it succeeds.
+ */
+int runner_run_nowait (runner_t *runner);
+
+/**
+ * variant of runner_run() which does not free internal data
+ * so that the runner instance can be run again.
+ *
+ * @see runner_run()
+ */
+int runner_run_reuse (runner_t *runner);
+
+/**
+ * run a command with args.
+ *
+ * Variadic function, child process is spawned with
+ * the given sequence of args and waited for.
+ * Argument sequence MUST be NULL terminated.
+ *
+ * @return 0 on success
+ * -1 on failure
+ */
+int runcmd (const char *arg, ...);
+
+#endif
diff --git a/libglusterfs/src/scheduler.c b/libglusterfs/src/scheduler.c
deleted file mode 100644
index dc49d22d2..000000000
--- a/libglusterfs/src/scheduler.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- Copyright (c) 2006-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include <dlfcn.h>
-#include <netdb.h>
-#include "xlator.h"
-#include "scheduler.h"
-#include "list.h"
-
-struct sched_ops *
-get_scheduler (xlator_t *xl, const char *name)
-{
- struct sched_ops *tmp_sched = NULL;
- volume_opt_list_t *vol_opt = NULL;
- char *sched_file = NULL;
- void *handle = NULL;
- int ret = 0;
-
- if (name == NULL) {
- gf_log ("scheduler", GF_LOG_ERROR,
- "'name' not specified, EINVAL");
- return NULL;
- }
-
- ret = gf_asprintf (&sched_file, "%s/%s.so", SCHEDULERDIR, name);
- if (-1 == ret) {
- gf_log ("scheduler", GF_LOG_ERROR, "asprintf failed");
- return NULL;
- }
-
- gf_log ("scheduler", GF_LOG_DEBUG,
- "attempt to load file %s.so", name);
-
- handle = dlopen (sched_file, RTLD_LAZY);
- if (!handle) {
- gf_log ("scheduler", GF_LOG_ERROR,
- "dlopen(%s): %s", sched_file, dlerror ());
- GF_FREE(sched_file);
- return NULL;
- }
-
- tmp_sched = dlsym (handle, "sched");
- if (!tmp_sched) {
- gf_log ("scheduler", GF_LOG_ERROR,
- "dlsym(sched) on %s", dlerror ());
- GF_FREE(sched_file);
- return NULL;
- }
-
- vol_opt = GF_CALLOC (1, sizeof (volume_opt_list_t),
- gf_common_mt_volume_opt_list_t);
- vol_opt->given_opt = dlsym (handle, "options");
- if (vol_opt->given_opt == NULL) {
- gf_log ("scheduler", GF_LOG_DEBUG,
- "volume option validation not specified");
- } else {
- list_add_tail (&vol_opt->list, &xl->volume_options);
- if (validate_xlator_volume_options (xl, vol_opt->given_opt)
- == -1) {
- gf_log ("scheduler", GF_LOG_ERROR,
- "volume option validation failed");
- GF_FREE(sched_file);
- return NULL;
- }
- }
- GF_FREE(sched_file);
- GF_FREE (vol_opt);
-
- return tmp_sched;
-}
diff --git a/libglusterfs/src/scheduler.h b/libglusterfs/src/scheduler.h
deleted file mode 100644
index 556cdae15..000000000
--- a/libglusterfs/src/scheduler.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- Copyright (c) 2006-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _SCHEDULER_H
-#define _SCHEDULER_H
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "xlator.h"
-
-struct sched_ops {
- int32_t (*init) (xlator_t *this);
- void (*fini) (xlator_t *this);
- void (*update) (xlator_t *this);
- xlator_t *(*schedule) (xlator_t *this, const void *path);
- void (*notify) (xlator_t *xl, int32_t event, void *data);
- int32_t (*mem_acct_init) (xlator_t *this);
-};
-
-extern struct sched_ops *get_scheduler (xlator_t *xl, const char *name);
-
-#endif /* _SCHEDULER_H */
diff --git a/libglusterfs/src/stack.c b/libglusterfs/src/stack.c
index b2659c57f..37b338f51 100644
--- a/libglusterfs/src/stack.c
+++ b/libglusterfs/src/stack.c
@@ -1,27 +1,18 @@
/*
- Copyright (c) 2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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 "statedump.h"
#include "stack.h"
static inline
-int call_frames_count (call_frame_t *call_frame)
+int call_frames_count (call_frame_t *call_frame)
{
call_frame_t *pos;
int32_t count = 0;
@@ -35,15 +26,53 @@ int call_frames_count (call_frame_t *call_frame)
return count;
}
+call_frame_t *
+create_frame (xlator_t *xl, call_pool_t *pool)
+{
+ call_stack_t *stack = NULL;
+
+ if (!xl || !pool) {
+ return NULL;
+ }
+
+ stack = mem_get0 (pool->stack_mem_pool);
+ if (!stack)
+ return NULL;
+
+ stack->pool = pool;
+ stack->frames.root = stack;
+ stack->frames.this = xl;
+ stack->ctx = xl->ctx;
+
+ if (stack->ctx->measure_latency) {
+ if (gettimeofday (&stack->tv, NULL) == -1)
+ gf_log ("stack", GF_LOG_ERROR, "gettimeofday () failed."
+ " (%s)", strerror (errno));
+ memcpy (&stack->frames.begin, &stack->tv, sizeof (stack->tv));
+ }
+
+ LOCK (&pool->lock);
+ {
+ list_add (&stack->all_frames, &pool->all_frames);
+ pool->cnt++;
+ }
+ UNLOCK (&pool->lock);
+
+ LOCK_INIT (&stack->frames.lock);
+ LOCK_INIT (&stack->stack_lock);
+
+ return &stack->frames;
+}
+
void
gf_proc_dump_call_frame (call_frame_t *call_frame, const char *key_buf,...)
{
-
+
char prefix[GF_DUMP_MAX_BUF_LEN];
va_list ap;
- char key[GF_DUMP_MAX_BUF_LEN];
call_frame_t my_frame;
int ret = -1;
+ char timestr[256] = {0,};
if (!call_frame)
return;
@@ -53,28 +82,49 @@ gf_proc_dump_call_frame (call_frame_t *call_frame, const char *key_buf,...)
memset(prefix, 0, sizeof(prefix));
memset(&my_frame, 0, sizeof(my_frame));
va_start(ap, key_buf);
- vsnprintf(prefix, GF_DUMP_MAX_BUF_LEN, key_buf, ap);
+ vsnprintf(prefix, GF_DUMP_MAX_BUF_LEN, key_buf, ap);
va_end(ap);
ret = TRY_LOCK(&call_frame->lock);
- if (ret) {
- gf_log("", GF_LOG_WARNING, "Unable to dump call frame"
- " errno: %d", errno);
- return;
- }
+ if (ret)
+ goto out;
memcpy(&my_frame, call_frame, sizeof(my_frame));
UNLOCK(&call_frame->lock);
- gf_proc_dump_build_key(key, prefix,"ref_count");
- gf_proc_dump_write(key, "%d", my_frame.ref_count);
- gf_proc_dump_build_key(key, prefix,"translator");
- gf_proc_dump_write(key, "%s", my_frame.this->name);
- gf_proc_dump_build_key(key, prefix,"complete");
- gf_proc_dump_write(key, "%d", my_frame.complete);
- if (my_frame.parent) {
- gf_proc_dump_build_key(key, prefix,"parent");
- gf_proc_dump_write(key, "%s", my_frame.parent->this->name);
+ if (my_frame.this->ctx->measure_latency) {
+ gf_time_fmt (timestr, sizeof timestr, my_frame.begin.tv_sec,
+ gf_timefmt_FT);
+ snprintf (timestr + strlen (timestr),
+ sizeof timestr - strlen (timestr),
+ ".%"GF_PRI_SUSECONDS, my_frame.begin.tv_usec);
+ gf_proc_dump_write("frame-creation-time", "%s", timestr);
+ }
+
+ gf_proc_dump_write("ref_count", "%d", my_frame.ref_count);
+ gf_proc_dump_write("translator", "%s", my_frame.this->name);
+ gf_proc_dump_write("complete", "%d", my_frame.complete);
+ if (my_frame.parent)
+ gf_proc_dump_write("parent", "%s", my_frame.parent->this->name);
+
+ if (my_frame.wind_from)
+ gf_proc_dump_write("wind_from", "%s", my_frame.wind_from);
+
+ if (my_frame.wind_to)
+ gf_proc_dump_write("wind_to", "%s", my_frame.wind_to);
+
+ if (my_frame.unwind_from)
+ gf_proc_dump_write("unwind_from", "%s", my_frame.unwind_from);
+
+ if (my_frame.unwind_to)
+ gf_proc_dump_write("unwind_to", "%s", my_frame.unwind_to);
+
+ ret = 0;
+out:
+ if (ret) {
+ gf_proc_dump_write("Unable to dump the frame information",
+ "(Lock acquisition failed) %p", my_frame);
+ return;
}
}
@@ -86,7 +136,7 @@ gf_proc_dump_call_stack (call_stack_t *call_stack, const char *key_buf,...)
va_list ap;
call_frame_t *trav;
int32_t cnt, i;
- char key[GF_DUMP_MAX_BUF_LEN];
+ char timestr[256] = {0,};
if (!call_stack)
return;
@@ -97,28 +147,32 @@ gf_proc_dump_call_stack (call_stack_t *call_stack, const char *key_buf,...)
memset(prefix, 0, sizeof(prefix));
va_start(ap, key_buf);
- vsnprintf(prefix, GF_DUMP_MAX_BUF_LEN, key_buf, ap);
+ vsnprintf(prefix, GF_DUMP_MAX_BUF_LEN, key_buf, ap);
va_end(ap);
- gf_proc_dump_build_key(key, prefix,"uid");
- gf_proc_dump_write(key, "%d", call_stack->uid);
- gf_proc_dump_build_key(key, prefix,"gid");
- gf_proc_dump_write(key, "%d", call_stack->gid);
- gf_proc_dump_build_key(key, prefix,"pid");
- gf_proc_dump_write(key, "%d", call_stack->pid);
- gf_proc_dump_build_key(key, prefix,"unique");
- gf_proc_dump_write(key, "%Ld", call_stack->unique);
+ if (call_stack->ctx->measure_latency) {
+ gf_time_fmt (timestr, sizeof timestr, call_stack->tv.tv_sec,
+ gf_timefmt_FT);
+ snprintf (timestr + strlen (timestr),
+ sizeof timestr - strlen (timestr),
+ ".%"GF_PRI_SUSECONDS, call_stack->tv.tv_usec);
+ gf_proc_dump_write("callstack-creation-time", "%s", timestr);
+ }
+
+ gf_proc_dump_write("uid", "%d", call_stack->uid);
+ gf_proc_dump_write("gid", "%d", call_stack->gid);
+ gf_proc_dump_write("pid", "%d", call_stack->pid);
+ gf_proc_dump_write("unique", "%Ld", call_stack->unique);
+ gf_proc_dump_write("lk-owner", "%s", lkowner_utoa (&call_stack->lk_owner));
- gf_proc_dump_build_key(key, prefix,"op");
if (call_stack->type == GF_OP_TYPE_FOP)
- gf_proc_dump_write(key, "%s", gf_fop_list[call_stack->op]);
- else if (call_stack->type == GF_OP_TYPE_MGMT)
- gf_proc_dump_write(key, "%s", gf_mgmt_list[call_stack->op]);
+ gf_proc_dump_write("op", "%s",
+ (char *)gf_fop_list[call_stack->op]);
+ else
+ gf_proc_dump_write("op", "stack");
- gf_proc_dump_build_key(key, prefix,"type");
- gf_proc_dump_write(key, "%d", call_stack->type);
- gf_proc_dump_build_key(key, prefix,"cnt");
- gf_proc_dump_write(key, "%d", cnt);
+ gf_proc_dump_write("type", "%d", call_stack->type);
+ gf_proc_dump_write("cnt", "%d", cnt);
trav = &call_stack->frames;
@@ -126,7 +180,7 @@ gf_proc_dump_call_stack (call_stack_t *call_stack, const char *key_buf,...)
if (trav) {
gf_proc_dump_add_section("%s.frame.%d", prefix, i);
gf_proc_dump_call_frame(trav, "%s.frame.%d", prefix, i);
- trav = trav->next;
+ trav = trav->next;
}
}
}
@@ -134,25 +188,24 @@ gf_proc_dump_call_stack (call_stack_t *call_stack, const char *key_buf,...)
void
gf_proc_dump_pending_frames (call_pool_t *call_pool)
{
-
+
call_stack_t *trav = NULL;
int i = 1;
int ret = -1;
+ gf_boolean_t section_added = _gf_true;
if (!call_pool)
return;
ret = TRY_LOCK (&(call_pool->lock));
- if (ret) {
- gf_log("", GF_LOG_WARNING, "Unable to dump call pool"
- " errno: %d", errno);
- return;
- }
+ if (ret)
+ goto out;
+
-
gf_proc_dump_add_section("global.callpool");
- gf_proc_dump_write("global.callpool","%p", call_pool);
- gf_proc_dump_write("global.callpool.cnt","%d", call_pool->cnt);
+ section_added = _gf_true;
+ gf_proc_dump_write("callpool_address","%p", call_pool);
+ gf_proc_dump_write("callpool.cnt","%d", call_pool->cnt);
list_for_each_entry (trav, &call_pool->all_frames, all_frames) {
@@ -160,6 +213,220 @@ gf_proc_dump_pending_frames (call_pool_t *call_pool)
gf_proc_dump_call_stack(trav, "global.callpool.stack.%d", i);
i++;
}
- UNLOCK (&(call_pool->lock));
+ UNLOCK (&(call_pool->lock));
+
+ ret = 0;
+out:
+ if (ret) {
+ if (_gf_false == section_added)
+ gf_proc_dump_add_section("global.callpool");
+ gf_proc_dump_write("Unable to dump the callpool",
+ "(Lock acquisition failed) %p",
+ call_pool);
+ }
+ return;
+}
+
+void
+gf_proc_dump_call_frame_to_dict (call_frame_t *call_frame,
+ char *prefix, dict_t *dict)
+{
+ int ret = -1;
+ char key[GF_DUMP_MAX_BUF_LEN] = {0,};
+ call_frame_t tmp_frame = {0,};
+
+ if (!call_frame || !dict)
+ return;
+
+ ret = TRY_LOCK (&call_frame->lock);
+ if (ret)
+ return;
+ memcpy (&tmp_frame, call_frame, sizeof (tmp_frame));
+ UNLOCK (&call_frame->lock);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.refcount", prefix);
+ ret = dict_set_int32 (dict, key, tmp_frame.ref_count);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.translator", prefix);
+ ret = dict_set_dynstr (dict, key, gf_strdup (tmp_frame.this->name));
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.complete", prefix);
+ ret = dict_set_int32 (dict, key, tmp_frame.complete);
+ if (ret)
+ return;
+
+ if (tmp_frame.parent) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.parent", prefix);
+ ret = dict_set_dynstr (dict, key,
+ gf_strdup (tmp_frame.parent->this->name));
+ if (ret)
+ return;
+ }
+
+ if (tmp_frame.wind_from) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.windfrom", prefix);
+ ret = dict_set_dynstr (dict, key,
+ gf_strdup (tmp_frame.wind_from));
+ if (ret)
+ return;
+ }
+
+ if (tmp_frame.wind_to) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.windto", prefix);
+ ret = dict_set_dynstr (dict, key,
+ gf_strdup (tmp_frame.wind_to));
+ if (ret)
+ return;
+ }
+
+ if (tmp_frame.unwind_from) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.unwindfrom", prefix);
+ ret = dict_set_dynstr (dict, key,
+ gf_strdup (tmp_frame.unwind_from));
+ if (ret)
+ return;
+ }
+
+ if (tmp_frame.unwind_to) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.unwind_to", prefix);
+ ret = dict_set_dynstr (dict, key,
+ gf_strdup (tmp_frame.unwind_to));
+ }
+
+ return;
+}
+
+void
+gf_proc_dump_call_stack_to_dict (call_stack_t *call_stack,
+ char *prefix, dict_t *dict)
+{
+ int ret = -1;
+ char key[GF_DUMP_MAX_BUF_LEN] = {0,};
+ call_frame_t *trav = NULL;
+ int count = 0;
+ int i = 0;
+
+ if (!call_stack || !dict)
+ return;
+
+ count = call_frames_count (&call_stack->frames);
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.uid", prefix);
+ ret = dict_set_int32 (dict, key, call_stack->uid);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.gid", prefix);
+ ret = dict_set_int32 (dict, key, call_stack->gid);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.pid", prefix);
+ ret = dict_set_int32 (dict, key, call_stack->pid);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.unique", prefix);
+ ret = dict_set_uint64 (dict, key, call_stack->unique);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.op", prefix);
+ if (call_stack->type == GF_OP_TYPE_FOP)
+ ret = dict_set_str (dict, key,
+ (char *)gf_fop_list[call_stack->op]);
+ else
+ ret = dict_set_str (dict, key, "other");
+
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.type", prefix);
+ ret = dict_set_int32 (dict, key, call_stack->type);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.count", prefix);
+ ret = dict_set_int32 (dict, key, count);
+ if (ret)
+ return;
+
+ trav = &call_stack->frames;
+ for (i = 0; i < count; i++) {
+ if (trav) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "%s.frame%d",
+ prefix, i);
+ gf_proc_dump_call_frame_to_dict (trav, key, dict);
+ trav = trav->next;
+ }
+ }
+
+ return;
+}
+
+void
+gf_proc_dump_pending_frames_to_dict (call_pool_t *call_pool, dict_t *dict)
+{
+ int ret = -1;
+ call_stack_t *trav = NULL;
+ char key[GF_DUMP_MAX_BUF_LEN] = {0,};
+ int i = 0;
+
+ if (!call_pool || !dict)
+ return;
+
+ ret = TRY_LOCK (&call_pool->lock);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_WARNING, "Unable to dump call pool"
+ " to dict. errno: %d", errno);
+ return;
+ }
+
+ ret = dict_set_int32 (dict, "callpool.count", call_pool->cnt);
+ if (ret)
+ goto out;
+
+ list_for_each_entry (trav, &call_pool->all_frames, all_frames) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "callpool.stack%d", i);
+ gf_proc_dump_call_stack_to_dict (trav, key, dict);
+ i++;
+ }
+
+out:
+ UNLOCK (&call_pool->lock);
+
+ return;
}
+gf_boolean_t
+__is_fuse_call (call_frame_t *frame)
+{
+ gf_boolean_t is_fuse_call = _gf_false;
+ GF_ASSERT (frame);
+ GF_ASSERT (frame->root);
+
+ if (NFS_PID != frame->root->pid)
+ is_fuse_call = _gf_true;
+ return is_fuse_call;
+}
diff --git a/libglusterfs/src/stack.h b/libglusterfs/src/stack.h
index b06470bf5..f2d2ef950 100644
--- a/libglusterfs/src/stack.h
+++ b/libglusterfs/src/stack.h
@@ -1,20 +1,11 @@
-/*
- Copyright (c) 2006-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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.
*/
/*
@@ -34,8 +25,8 @@ struct _call_stack_t;
typedef struct _call_stack_t call_stack_t;
struct _call_frame_t;
typedef struct _call_frame_t call_frame_t;
-struct _call_pool_t;
-typedef struct _call_pool_t call_pool_t;
+struct call_pool;
+typedef struct call_pool call_pool_t;
#include <sys/time.h>
@@ -44,109 +35,124 @@ typedef struct _call_pool_t call_pool_t;
#include "list.h"
#include "common-utils.h"
#include "globals.h"
+#include "lkowner.h"
+#include "client_t.h"
+#define NFS_PID 1
+#define LOW_PRIO_PROC_PID -1
typedef int32_t (*ret_fn_t) (call_frame_t *frame,
- call_frame_t *prev_frame,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- ...);
-
-struct _call_pool_t {
- union {
- struct list_head all_frames;
- struct {
- call_stack_t *next_call;
- call_stack_t *prev_call;
- } all_stacks;
- };
- int64_t cnt;
- gf_lock_t lock;
- struct mem_pool *frame_mem_pool;
- struct mem_pool *stack_mem_pool;
+ call_frame_t *prev_frame,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ ...);
+
+struct call_pool {
+ union {
+ struct list_head all_frames;
+ struct {
+ call_stack_t *next_call;
+ call_stack_t *prev_call;
+ } all_stacks;
+ };
+ int64_t cnt;
+ gf_lock_t lock;
+ struct mem_pool *frame_mem_pool;
+ struct mem_pool *stack_mem_pool;
};
struct _call_frame_t {
- call_stack_t *root; /* stack root */
- call_frame_t *parent; /* previous BP */
- call_frame_t *next;
- call_frame_t *prev; /* maintainence list */
- void *local; /* local variables */
- xlator_t *this; /* implicit object */
- ret_fn_t ret; /* op_return address */
- int32_t ref_count;
- gf_lock_t lock;
- void *cookie; /* unique cookie */
- gf_boolean_t complete;
-
- glusterfs_fop_t op;
+ call_stack_t *root; /* stack root */
+ call_frame_t *parent; /* previous BP */
+ call_frame_t *next;
+ call_frame_t *prev; /* maintenance list */
+ void *local; /* local variables */
+ xlator_t *this; /* implicit object */
+ ret_fn_t ret; /* op_return address */
+ int32_t ref_count;
+ gf_lock_t lock;
+ void *cookie; /* unique cookie */
+ gf_boolean_t complete;
+
+ glusterfs_fop_t op;
struct timeval begin; /* when this frame was created */
struct timeval end; /* when this frame completed */
+ const char *wind_from;
+ const char *wind_to;
+ const char *unwind_from;
+ const char *unwind_to;
};
+#define SMALL_GROUP_COUNT 128
+
struct _call_stack_t {
- union {
- struct list_head all_frames;
- struct {
- call_stack_t *next_call;
- call_stack_t *prev_call;
- };
- };
- call_pool_t *pool;
- void *trans;
- uint64_t unique;
- void *state; /* pointer to request state */
- uid_t uid;
- gid_t gid;
- pid_t pid;
- uint32_t ngrps;
- uint32_t groups[GF_REQUEST_MAXGROUPS];
- uint64_t lk_owner;
-
- call_frame_t frames;
-
- int32_t op;
- int8_t type;
+ union {
+ struct list_head all_frames;
+ struct {
+ call_stack_t *next_call;
+ call_stack_t *prev_call;
+ };
+ };
+ call_pool_t *pool;
+ gf_lock_t stack_lock;
+ client_t *client;
+ uint64_t unique;
+ void *state; /* pointer to request state */
+ uid_t uid;
+ gid_t gid;
+ pid_t pid;
+ uint16_t ngrps;
+ uint32_t groups_small[SMALL_GROUP_COUNT];
+ uint32_t *groups_large;
+ uint32_t *groups;
+ gf_lkowner_t lk_owner;
+ glusterfs_ctx_t *ctx;
+
+ call_frame_t frames;
+
+ int32_t op;
+ int8_t type;
+ struct timeval tv;
};
-#define frame_set_uid_gid(frm, u, g) \
- do { \
- if (frm) { \
- (frm)->root->uid = u; \
- (frm)->root->gid = g; \
- (frm)->root->ngrps = 0; \
- } \
- } while (0); \
+#define frame_set_uid_gid(frm, u, g) \
+ do { \
+ if (frm) { \
+ (frm)->root->uid = u; \
+ (frm)->root->gid = g; \
+ (frm)->root->ngrps = 0; \
+ } \
+ } while (0); \
+
struct xlator_fops;
void
-gf_set_fop_from_fn_pointer (call_frame_t *frame, struct xlator_fops *fops,
- void *fn);
+gf_latency_begin (call_frame_t *frame, void *fn);
void
-gf_update_latency (call_frame_t *frame);
+gf_latency_end (call_frame_t *frame);
static inline void
FRAME_DESTROY (call_frame_t *frame)
{
- void *local = NULL;
- if (frame->next)
- frame->next->prev = frame->prev;
- if (frame->prev)
- frame->prev->next = frame->next;
- if (frame->local) {
- local = frame->local;
- frame->local = NULL;
-
- }
-
- LOCK_DESTROY (&frame->lock);
- mem_put (frame->root->pool->frame_mem_pool, frame);
-
- if (local)
- GF_FREE (local);
+ void *local = NULL;
+ if (frame->next)
+ frame->next->prev = frame->prev;
+ if (frame->prev)
+ frame->prev->next = frame->next;
+ if (frame->local) {
+ local = frame->local;
+ frame->local = NULL;
+
+ }
+
+ LOCK_DESTROY (&frame->lock);
+ mem_put (frame);
+
+ if (local)
+ mem_put (local);
}
@@ -155,101 +161,171 @@ STACK_DESTROY (call_stack_t *stack)
{
void *local = NULL;
- LOCK (&stack->pool->lock);
- {
- list_del_init (&stack->all_frames);
- stack->pool->cnt--;
- }
- UNLOCK (&stack->pool->lock);
+ LOCK (&stack->pool->lock);
+ {
+ list_del_init (&stack->all_frames);
+ stack->pool->cnt--;
+ }
+ UNLOCK (&stack->pool->lock);
- if (stack->frames.local) {
- local = stack->frames.local;
- stack->frames.local = NULL;
- }
+ if (stack->frames.local) {
+ local = stack->frames.local;
+ stack->frames.local = NULL;
+ }
- LOCK_DESTROY (&stack->frames.lock);
+ LOCK_DESTROY (&stack->frames.lock);
+ LOCK_DESTROY (&stack->stack_lock);
- while (stack->frames.next) {
- FRAME_DESTROY (stack->frames.next);
- }
- mem_put (stack->pool->stack_mem_pool, stack);
+ while (stack->frames.next) {
+ FRAME_DESTROY (stack->frames.next);
+ }
+
+ GF_FREE (stack->groups_large);
- if (local)
- GF_FREE (local);
+ mem_put (stack);
+
+ if (local)
+ mem_put (local);
}
+static inline void
+STACK_RESET (call_stack_t *stack)
+{
+ void *local = NULL;
+
+ if (stack->frames.local) {
+ local = stack->frames.local;
+ stack->frames.local = NULL;
+ }
+
+ while (stack->frames.next) {
+ FRAME_DESTROY (stack->frames.next);
+ }
+
+ if (local)
+ mem_put (local);
+}
#define cbk(x) cbk_##x
+#define FRAME_SU_DO(frm, local_type) \
+ do { \
+ local_type *__local = (frm)->local; \
+ __local->uid = frm->root->uid; \
+ __local->gid = frm->root->gid; \
+ frm->root->uid = 0; \
+ frm->root->gid = 0; \
+ } while (0); \
+
+#define FRAME_SU_UNDO(frm, local_type) \
+ do { \
+ local_type *__local = (frm)->local; \
+ frm->root->uid = __local->uid; \
+ frm->root->gid = __local->gid; \
+ } while (0); \
+
/* make a call */
-#define STACK_WIND(frame, rfn, obj, fn, params ...) \
- do { \
- call_frame_t *_new = NULL; \
+#define STACK_WIND(frame, rfn, obj, fn, params ...) \
+ do { \
+ call_frame_t *_new = NULL; \
xlator_t *old_THIS = NULL; \
\
- _new = mem_get0 (frame->root->pool->frame_mem_pool); \
+ _new = mem_get0 (frame->root->pool->frame_mem_pool); \
if (!_new) { \
gf_log ("stack", GF_LOG_ERROR, "alloc failed"); \
break; \
} \
- typeof(fn##_cbk) tmp_cbk = rfn; \
- _new->root = frame->root; \
- _new->next = frame->root->frames.next; \
- _new->prev = &frame->root->frames; \
- if (frame->root->frames.next) \
- frame->root->frames.next->prev = _new; \
- frame->root->frames.next = _new; \
- _new->this = obj; \
- _new->ret = (ret_fn_t) tmp_cbk; \
- _new->parent = frame; \
- _new->cookie = _new; \
- LOCK_INIT (&_new->lock); \
- frame->ref_count++; \
+ typeof(fn##_cbk) tmp_cbk = rfn; \
+ _new->root = frame->root; \
+ _new->this = obj; \
+ _new->ret = (ret_fn_t) tmp_cbk; \
+ _new->parent = frame; \
+ _new->cookie = _new; \
+ _new->wind_from = __FUNCTION__; \
+ _new->wind_to = #fn; \
+ _new->unwind_to = #rfn; \
+ \
+ LOCK_INIT (&_new->lock); \
+ LOCK(&frame->root->stack_lock); \
+ { \
+ _new->next = frame->root->frames.next; \
+ _new->prev = &frame->root->frames; \
+ if (frame->root->frames.next) \
+ frame->root->frames.next->prev = _new; \
+ frame->root->frames.next = _new; \
+ frame->ref_count++; \
+ } \
+ UNLOCK(&frame->root->stack_lock); \
old_THIS = THIS; \
THIS = obj; \
- fn (_new, obj, params); \
+ if (frame->this->ctx->measure_latency) \
+ gf_latency_begin (_new, fn); \
+ fn (_new, obj, params); \
THIS = old_THIS; \
- } while (0)
+ } while (0)
+
+
+/* make a call without switching frames */
+#define STACK_WIND_TAIL(frame, obj, fn, params ...) \
+ do { \
+ xlator_t *old_THIS = NULL; \
+ \
+ frame->this = obj; \
+ frame->wind_to = #fn; \
+ old_THIS = THIS; \
+ THIS = obj; \
+ fn (frame, obj, params); \
+ THIS = old_THIS; \
+ } while (0)
/* make a call with a cookie */
-#define STACK_WIND_COOKIE(frame, rfn, cky, obj, fn, params ...) \
- do { \
+#define STACK_WIND_COOKIE(frame, rfn, cky, obj, fn, params ...) \
+ do { \
call_frame_t *_new = NULL; \
xlator_t *old_THIS = NULL; \
\
- _new = mem_get0 (frame->root->pool->frame_mem_pool); \
+ _new = mem_get0 (frame->root->pool->frame_mem_pool); \
if (!_new) { \
gf_log ("stack", GF_LOG_ERROR, "alloc failed"); \
break; \
} \
- typeof(fn##_cbk) tmp_cbk = rfn; \
- _new->root = frame->root; \
- _new->next = frame->root->frames.next; \
- _new->prev = &frame->root->frames; \
- if (frame->root->frames.next) \
- frame->root->frames.next->prev = _new; \
- frame->root->frames.next = _new; \
- _new->this = obj; \
- _new->ret = (ret_fn_t) tmp_cbk; \
- _new->parent = frame; \
- _new->cookie = cky; \
- LOCK_INIT (&_new->lock); \
- frame->ref_count++; \
- fn##_cbk = rfn; \
+ typeof(fn##_cbk) tmp_cbk = rfn; \
+ _new->root = frame->root; \
+ _new->this = obj; \
+ _new->ret = (ret_fn_t) tmp_cbk; \
+ _new->parent = frame; \
+ _new->cookie = cky; \
+ _new->wind_from = __FUNCTION__; \
+ _new->wind_to = #fn; \
+ _new->unwind_to = #rfn; \
+ LOCK_INIT (&_new->lock); \
+ LOCK(&frame->root->stack_lock); \
+ { \
+ frame->ref_count++; \
+ _new->next = frame->root->frames.next; \
+ _new->prev = &frame->root->frames; \
+ if (frame->root->frames.next) \
+ frame->root->frames.next->prev = _new; \
+ frame->root->frames.next = _new; \
+ } \
+ UNLOCK(&frame->root->stack_lock); \
+ fn##_cbk = rfn; \
old_THIS = THIS; \
THIS = obj; \
- fn (_new, obj, params); \
+ if (obj->ctx->measure_latency) \
+ gf_latency_begin (_new, fn); \
+ fn (_new, obj, params); \
THIS = old_THIS; \
- } while (0)
+ } while (0)
/* return from function */
-#define STACK_UNWIND(frame, params ...) \
- do { \
- ret_fn_t fn = NULL; \
- call_frame_t *_parent = NULL; \
+#define STACK_UNWIND(frame, params ...) \
+ do { \
+ ret_fn_t fn = NULL; \
+ call_frame_t *_parent = NULL; \
xlator_t *old_THIS = NULL; \
if (!frame) { \
gf_log ("stack", GF_LOG_CRITICAL, "!frame"); \
@@ -257,20 +333,27 @@ STACK_DESTROY (call_stack_t *stack)
} \
fn = frame->ret; \
_parent = frame->parent; \
- _parent->ref_count--; \
+ LOCK(&frame->root->stack_lock); \
+ { \
+ _parent->ref_count--; \
+ } \
+ UNLOCK(&frame->root->stack_lock); \
old_THIS = THIS; \
THIS = _parent->this; \
frame->complete = _gf_true; \
- fn (_parent, frame->cookie, _parent->this, params); \
+ frame->unwind_from = __FUNCTION__; \
+ if (frame->this->ctx->measure_latency) \
+ gf_latency_end (frame); \
+ fn (_parent, frame->cookie, _parent->this, params); \
THIS = old_THIS; \
- } while (0)
+ } while (0)
/* return from function in type-safe way */
#define STACK_UNWIND_STRICT(op, frame, params ...) \
- do { \
- fop_##op##_cbk_t fn = NULL; \
- call_frame_t *_parent = NULL; \
+ do { \
+ fop_##op##_cbk_t fn = NULL; \
+ call_frame_t *_parent = NULL; \
xlator_t *old_THIS = NULL; \
\
if (!frame) { \
@@ -279,88 +362,101 @@ STACK_DESTROY (call_stack_t *stack)
} \
fn = (fop_##op##_cbk_t )frame->ret; \
_parent = frame->parent; \
- _parent->ref_count--; \
+ LOCK(&frame->root->stack_lock); \
+ { \
+ _parent->ref_count--; \
+ } \
+ UNLOCK(&frame->root->stack_lock); \
old_THIS = THIS; \
THIS = _parent->this; \
frame->complete = _gf_true; \
- fn (_parent, frame->cookie, _parent->this, params); \
+ frame->unwind_from = __FUNCTION__; \
+ if (frame->this->ctx->measure_latency) \
+ gf_latency_end (frame); \
+ fn (_parent, frame->cookie, _parent->this, params); \
THIS = old_THIS; \
- } while (0)
+ } while (0)
+
+
+static inline int
+call_stack_alloc_groups (call_stack_t *stack, int ngrps)
+{
+ if (ngrps <= SMALL_GROUP_COUNT) {
+ stack->groups = stack->groups_small;
+ } else {
+ stack->groups_large = GF_CALLOC (sizeof (gid_t), ngrps,
+ gf_common_mt_groups_t);
+ if (!stack->groups_large)
+ return -1;
+ stack->groups = stack->groups_large;
+ }
+ stack->ngrps = ngrps;
+
+ return 0;
+}
static inline call_frame_t *
copy_frame (call_frame_t *frame)
{
- call_stack_t *newstack = NULL;
- call_stack_t *oldstack = NULL;
+ call_stack_t *newstack = NULL;
+ call_stack_t *oldstack = NULL;
- if (!frame) {
- return NULL;
- }
+ if (!frame) {
+ return NULL;
+ }
- newstack = mem_get0 (frame->root->pool->stack_mem_pool);
+ newstack = mem_get0 (frame->root->pool->stack_mem_pool);
if (newstack == NULL) {
return NULL;
}
- oldstack = frame->root;
+ oldstack = frame->root;
- newstack->uid = oldstack->uid;
- newstack->gid = oldstack->gid;
- newstack->pid = oldstack->pid;
+ newstack->uid = oldstack->uid;
+ newstack->gid = oldstack->gid;
+ newstack->pid = oldstack->pid;
newstack->ngrps = oldstack->ngrps;
- memcpy (newstack->groups, oldstack->groups,
- sizeof (uint32_t) * GF_REQUEST_MAXGROUPS);
- newstack->unique = oldstack->unique;
-
- newstack->frames.this = frame->this;
- newstack->frames.root = newstack;
- newstack->pool = oldstack->pool;
- newstack->lk_owner = oldstack->lk_owner;
-
- LOCK_INIT (&newstack->frames.lock);
-
- LOCK (&oldstack->pool->lock);
- {
- list_add (&newstack->all_frames, &oldstack->all_frames);
- newstack->pool->cnt++;
- }
- UNLOCK (&oldstack->pool->lock);
-
- return &newstack->frames;
-}
-
-
-static inline call_frame_t *
-create_frame (xlator_t *xl, call_pool_t *pool)
-{
- call_stack_t *stack = NULL;
-
- if (!xl || !pool) {
+ newstack->op = oldstack->op;
+ newstack->type = oldstack->type;
+ if (call_stack_alloc_groups (newstack, oldstack->ngrps) != 0) {
+ mem_put (newstack);
return NULL;
}
+ memcpy (newstack->groups, oldstack->groups,
+ sizeof (gid_t) * oldstack->ngrps);
+ newstack->unique = oldstack->unique;
- stack = mem_get0 (pool->stack_mem_pool);
- if (!stack)
- return NULL;
-
- stack->pool = pool;
- stack->frames.root = stack;
- stack->frames.this = xl;
+ newstack->frames.this = frame->this;
+ newstack->frames.root = newstack;
+ newstack->pool = oldstack->pool;
+ newstack->lk_owner = oldstack->lk_owner;
+ newstack->ctx = oldstack->ctx;
+
+ if (newstack->ctx->measure_latency) {
+ if (gettimeofday (&newstack->tv, NULL) == -1)
+ gf_log ("stack", GF_LOG_ERROR, "gettimeofday () failed."
+ " (%s)", strerror (errno));
+ memcpy (&newstack->frames.begin, &newstack->tv,
+ sizeof (newstack->tv));
+ }
- LOCK (&pool->lock);
- {
- list_add (&stack->all_frames, &pool->all_frames);
- pool->cnt++;
- }
- UNLOCK (&pool->lock);
+ LOCK_INIT (&newstack->frames.lock);
+ LOCK_INIT (&newstack->stack_lock);
- LOCK_INIT (&stack->frames.lock);
+ LOCK (&oldstack->pool->lock);
+ {
+ list_add (&newstack->all_frames, &oldstack->all_frames);
+ newstack->pool->cnt++;
+ }
+ UNLOCK (&oldstack->pool->lock);
- return &stack->frames;
+ return &newstack->frames;
}
-void
-gf_proc_dump_pending_frames(call_pool_t *call_pool);
-
+void gf_proc_dump_pending_frames(call_pool_t *call_pool);
+void gf_proc_dump_pending_frames_to_dict (call_pool_t *call_pool,
+ dict_t *dict);
+call_frame_t *create_frame (xlator_t *xl, call_pool_t *pool);
+gf_boolean_t __is_fuse_call (call_frame_t *frame);
#endif /* _STACK_H */
diff --git a/libglusterfs/src/statedump.c b/libglusterfs/src/statedump.c
index d3e1272c5..8175faba4 100644
--- a/libglusterfs/src/statedump.c
+++ b/libglusterfs/src/statedump.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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 <stdarg.h>
@@ -23,16 +14,23 @@
#include "iobuf.h"
#include "statedump.h"
#include "stack.h"
+#include "common-utils.h"
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif /* MALLOC_H */
+/* We don't want gf_log in this function because it may cause
+ 'deadlock' with statedump. This is because statedump happens
+ inside a signal handler and cannot afford to block on a lock.*/
+#ifdef gf_log
+# undef gf_log
+#endif
-#define GF_PROC_DUMP_IS_OPTION_ENABLED(opt) \
+#define GF_PROC_DUMP_IS_OPTION_ENABLED(opt) \
(dump_options.dump_##opt == _gf_true)
-#define GF_PROC_DUMP_IS_XL_OPTION_ENABLED(opt)\
+#define GF_PROC_DUMP_IS_XL_OPTION_ENABLED(opt) \
(dump_options.xl_options.dump_##opt == _gf_true)
extern xlator_t global_xlator;
@@ -45,35 +43,29 @@ gf_dump_options_t dump_options;
static void
gf_proc_dump_lock (void)
{
- pthread_mutex_lock (&gf_proc_dump_mutex);
+ pthread_mutex_lock (&gf_proc_dump_mutex);
}
static void
gf_proc_dump_unlock (void)
{
- pthread_mutex_unlock (&gf_proc_dump_mutex);
+ pthread_mutex_unlock (&gf_proc_dump_mutex);
}
-
static int
-gf_proc_dump_open (void)
+gf_proc_dump_open (char *tmpname)
{
- char path[256];
int dump_fd = -1;
- memset (path, 0, sizeof (path));
- snprintf (path, sizeof (path), "%s.%d", GF_DUMP_LOGFILE_ROOT, getpid ());
-
- dump_fd = open (path, O_CREAT|O_RDWR|O_TRUNC|O_APPEND, 0600);
- if (dump_fd < 0)
+ dump_fd = mkstemp (tmpname);
+ if (dump_fd < 0)
return -1;
- gf_dump_fd = dump_fd;
+ gf_dump_fd = dump_fd;
return 0;
}
-
static void
gf_proc_dump_close (void)
{
@@ -81,16 +73,54 @@ gf_proc_dump_close (void)
gf_dump_fd = -1;
}
+static int
+gf_proc_dump_set_path (char *dump_options_file)
+{
+ int ret = -1;
+ FILE *fp = NULL;
+ char buf[256];
+ char *key = NULL, *value = NULL;
+ char *saveptr = NULL;
-void
+ fp = fopen (dump_options_file, "r");
+ if (!fp)
+ goto out;
+
+ ret = fscanf (fp, "%s", buf);
+
+ while (ret != EOF) {
+ key = strtok_r (buf, "=", &saveptr);
+ if (!key) {
+ ret = fscanf (fp, "%s", buf);
+ continue;
+ }
+
+ value = strtok_r (NULL, "=", &saveptr);
+
+ if (!value) {
+ ret = fscanf (fp, "%s", buf);
+ continue;
+ }
+ if (!strcmp (key, "path")) {
+ dump_options.dump_path = gf_strdup (value);
+ break;
+ }
+ }
+
+out:
+ if (fp)
+ fclose (fp);
+ return ret;
+}
+
+int
gf_proc_dump_add_section (char *key, ...)
{
char buf[GF_DUMP_MAX_BUF_LEN];
va_list ap;
- int ret;
- GF_ASSERT(key);
+ GF_ASSERT(key);
memset (buf, 0, sizeof(buf));
snprintf (buf, GF_DUMP_MAX_BUF_LEN, "\n[");
@@ -100,20 +130,19 @@ gf_proc_dump_add_section (char *key, ...)
va_end (ap);
snprintf (buf + strlen(buf),
GF_DUMP_MAX_BUF_LEN - strlen (buf), "]\n");
- ret = write (gf_dump_fd, buf, strlen (buf));
+ return write (gf_dump_fd, buf, strlen (buf));
}
-void
+int
gf_proc_dump_write (char *key, char *value,...)
{
char buf[GF_DUMP_MAX_BUF_LEN];
int offset = 0;
- va_list ap;
- int ret;
+ va_list ap;
- GF_ASSERT (key);
+ GF_ASSERT (key);
offset = strlen (key);
@@ -127,14 +156,12 @@ gf_proc_dump_write (char *key, char *value,...)
offset = strlen (buf);
snprintf (buf + offset, GF_DUMP_MAX_BUF_LEN - offset, "\n");
- ret = write (gf_dump_fd, buf, strlen (buf));
+ return write (gf_dump_fd, buf, strlen (buf));
}
static void
gf_proc_dump_xlator_mem_info (xlator_t *xl)
{
- char key[GF_DUMP_MAX_BUF_LEN];
- char prefix[GF_DUMP_MAX_BUF_LEN];
int i = 0;
struct mem_acct rec = {0,};
@@ -144,26 +171,61 @@ gf_proc_dump_xlator_mem_info (xlator_t *xl)
if (!xl->mem_acct.rec)
return;
- gf_proc_dump_add_section ("%s.%s - Memory usage", xl->type,xl->name);
+ gf_proc_dump_add_section ("%s.%s - Memory usage", xl->type, xl->name);
gf_proc_dump_write ("num_types", "%d", xl->mem_acct.num_types);
for (i = 0; i < xl->mem_acct.num_types; i++) {
- if (!(memcmp (&xl->mem_acct.rec[i], &rec,
- sizeof (struct mem_acct))))
- continue;
-
- gf_proc_dump_add_section ("%s.%s - usage-type %d", xl->type,
- xl->name,i);
- gf_proc_dump_build_key (prefix, "memusage", "%s.%s.type.%d",
- xl->type, xl->name, i);
- gf_proc_dump_build_key (key, prefix, "size");
- gf_proc_dump_write (key, "%u", xl->mem_acct.rec[i].size);
- gf_proc_dump_build_key (key, prefix, "num_allocs");
- gf_proc_dump_write (key, "%u", xl->mem_acct.rec[i].num_allocs);
- gf_proc_dump_build_key (key, prefix, "max_size");
- gf_proc_dump_write (key, "%u", xl->mem_acct.rec[i].max_size);
- gf_proc_dump_build_key (key, prefix, "max_num_allocs");
- gf_proc_dump_write (key, "%u", xl->mem_acct.rec[i].max_num_allocs);
+ if (!(memcmp (&xl->mem_acct.rec[i], &rec,
+ sizeof (struct mem_acct))))
+ continue;
+
+ gf_proc_dump_add_section ("%s.%s - usage-type %d memusage",
+ xl->type, xl->name, i);
+ gf_proc_dump_write ("size", "%u", xl->mem_acct.rec[i].size);
+ gf_proc_dump_write ("num_allocs", "%u",
+ xl->mem_acct.rec[i].num_allocs);
+ gf_proc_dump_write ("max_size", "%u",
+ xl->mem_acct.rec[i].max_size);
+ gf_proc_dump_write ("max_num_allocs", "%u",
+ xl->mem_acct.rec[i].max_num_allocs);
+ gf_proc_dump_write ("total_allocs", "%u",
+ xl->mem_acct.rec[i].total_allocs);
+ }
+
+ return;
+}
+
+static void
+gf_proc_dump_xlator_mem_info_only_in_use (xlator_t *xl)
+{
+ int i = 0;
+
+ if (!xl)
+ return;
+
+ if (!xl->mem_acct.rec)
+ return;
+
+ gf_proc_dump_add_section ("%s.%s - Memory usage", xl->type, xl->name);
+ gf_proc_dump_write ("num_types", "%d", xl->mem_acct.num_types);
+
+ for (i = 0; i < xl->mem_acct.num_types; i++) {
+ if (!xl->mem_acct.rec[i].size)
+ continue;
+
+ gf_proc_dump_add_section ("%s.%s - usage-type %d", xl->type,
+ xl->name,i);
+
+ gf_proc_dump_write ("size", "%u",
+ xl->mem_acct.rec[i].size);
+ gf_proc_dump_write ("max_size", "%u",
+ xl->mem_acct.rec[i].max_size);
+ gf_proc_dump_write ("num_allocs", "%u",
+ xl->mem_acct.rec[i].num_allocs);
+ gf_proc_dump_write ("max_num_allocs", "%u",
+ xl->mem_acct.rec[i].max_num_allocs);
+ gf_proc_dump_write ("total_allocs", "%u",
+ xl->mem_acct.rec[i].total_allocs);
}
return;
@@ -197,124 +259,242 @@ gf_proc_dump_mem_info ()
}
-void gf_proc_dump_latency_info (xlator_t *xl);
+void
+gf_proc_dump_mem_info_to_dict (dict_t *dict)
+{
+ if (!dict)
+ return;
+#ifdef HAVE_MALLOC_STATS
+ struct mallinfo info;
+ int ret = -1;
+
+ memset (&info, 0, sizeof(struct mallinfo));
+ info = mallinfo ();
+
+ ret = dict_set_int32 (dict, "mallinfo.arena", info.arena);
+ if (ret)
+ return;
+
+ ret = dict_set_int32 (dict, "mallinfo.ordblks", info.ordblks);
+ if (ret)
+ return;
+
+ ret = dict_set_int32 (dict, "mallinfo.smblks", info.smblks);
+ if (ret)
+ return;
+
+ ret = dict_set_int32 (dict, "mallinfo.hblks", info.hblks);
+ if (ret)
+ return;
+
+ ret = dict_set_int32 (dict, "mallinfo.hblkhd", info.hblkhd);
+ if (ret)
+ return;
+
+ ret = dict_set_int32 (dict, "mallinfo.usmblks", info.usmblks);
+ if (ret)
+ return;
+
+ ret = dict_set_int32 (dict, "mallinfo.fsmblks", info.fsmblks);
+ if (ret)
+ return;
+
+ ret = dict_set_int32 (dict, "mallinfo.uordblks", info.uordblks);
+ if (ret)
+ return;
+
+ ret = dict_set_int32 (dict, "mallinfo.fordblks", info.fordblks);
+ if (ret)
+ return;
+
+ ret = dict_set_int32 (dict, "mallinfo.keepcost", info.keepcost);
+ if (ret)
+ return;
+#endif
+ return;
+}
+
+void
+gf_proc_dump_mempool_info (glusterfs_ctx_t *ctx)
+{
+ struct mem_pool *pool = NULL;
+
+ gf_proc_dump_add_section ("mempool");
+
+ list_for_each_entry (pool, &ctx->mempool_list, global_list) {
+ gf_proc_dump_write ("-----", "-----");
+ gf_proc_dump_write ("pool-name", "%s", pool->name);
+ gf_proc_dump_write ("hot-count", "%d", pool->hot_count);
+ gf_proc_dump_write ("cold-count", "%d", pool->cold_count);
+ gf_proc_dump_write ("padded_sizeof", "%lu",
+ pool->padded_sizeof_type);
+ gf_proc_dump_write ("alloc-count", "%"PRIu64, pool->alloc_count);
+ gf_proc_dump_write ("max-alloc", "%d", pool->max_alloc);
+
+ gf_proc_dump_write ("pool-misses", "%"PRIu64, pool->pool_misses);
+ gf_proc_dump_write ("max-stdalloc", "%d", pool->max_stdalloc);
+ }
+}
void
-gf_proc_dump_xlator_info (xlator_t *this_xl)
+gf_proc_dump_mempool_info_to_dict (glusterfs_ctx_t *ctx, dict_t *dict)
{
- glusterfs_ctx_t *ctx = NULL;
- xlator_t *fuse_xlator, *this_xlator;
-
- if (!this_xl)
+ struct mem_pool *pool = NULL;
+ char key[GF_DUMP_MAX_BUF_LEN] = {0,};
+ int count = 0;
+ int ret = -1;
+
+ if (!ctx || !dict)
return;
-
- ctx = glusterfs_ctx_get ();
- if (!ctx)
- return;
- if (ctx->master){
+ list_for_each_entry (pool, &ctx->mempool_list, global_list) {
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "pool%d.name", count);
+ ret = dict_set_str (dict, key, pool->name);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "pool%d.hotcount", count);
+ ret = dict_set_int32 (dict, key, pool->hot_count);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "pool%d.coldcount", count);
+ ret = dict_set_int32 (dict, key, pool->cold_count);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "pool%d.paddedsizeof", count);
+ ret = dict_set_uint64 (dict, key, pool->padded_sizeof_type);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "pool%d.alloccount", count);
+ ret = dict_set_uint64 (dict, key, pool->alloc_count);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "pool%d.max_alloc", count);
+ ret = dict_set_int32 (dict, key, pool->max_alloc);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "pool%d.max-stdalloc", count);
+ ret = dict_set_int32 (dict, key, pool->max_stdalloc);
+ if (ret)
+ return;
+
+ memset (key, 0, sizeof (key));
+ snprintf (key, sizeof (key), "pool%d.pool-misses", count);
+ ret = dict_set_uint64 (dict, key, pool->pool_misses);
+ if (ret)
+ return;
+ count++;
+ }
+ ret = dict_set_int32 (dict, "mempool-count", count);
- fuse_xlator = (xlator_t *) ctx->master;
+ return;
+}
- if (!fuse_xlator->dumpops)
- return;
+void gf_proc_dump_latency_info (xlator_t *xl);
- if (fuse_xlator->dumpops->priv &&
- GF_PROC_DUMP_IS_XL_OPTION_ENABLED (priv))
- fuse_xlator->dumpops->priv (fuse_xlator);
-
- if (fuse_xlator->dumpops->inode &&
- GF_PROC_DUMP_IS_XL_OPTION_ENABLED (inode)) {
-
- if (!ctx->active)
- return;
- this_xlator = (xlator_t *) ctx->active->top;
-
- if (this_xlator && this_xlator->itable)
- inode_table_dump (this_xlator->itable,
- "xlator.mount.fuse.itable");
- else
- return;
- }
-
- if (fuse_xlator->dumpops->fd &&
- GF_PROC_DUMP_IS_XL_OPTION_ENABLED (fd))
- fuse_xlator->dumpops->fd (fuse_xlator);
- }
-
+void
+gf_proc_dump_xlator_info (xlator_t *top)
+{
+ xlator_t *trav = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ char itable_key[1024] = {0,};
+
+ if (!top)
+ return;
+
+ ctx = top->ctx;
- while (this_xl) {
-
- if (ctx->measure_latency)
- gf_proc_dump_latency_info (this_xl);
+ trav = top;
+ while (trav) {
- gf_proc_dump_xlator_mem_info(this_xl);
+ if (ctx->measure_latency)
+ gf_proc_dump_latency_info (trav);
+
+ gf_proc_dump_xlator_mem_info(trav);
+
+ if (GF_PROC_DUMP_IS_XL_OPTION_ENABLED (inode) &&
+ (trav->itable)) {
+ snprintf (itable_key, 1024, "%d.%s.itable",
+ ctx->graph_id, trav->name);
+ }
- if (!this_xl->dumpops) {
- this_xl = this_xl->next;
+ if (!trav->dumpops) {
+ trav = trav->next;
continue;
}
- if (this_xl->dumpops->priv &&
+ if (trav->dumpops->priv &&
GF_PROC_DUMP_IS_XL_OPTION_ENABLED (priv))
- this_xl->dumpops->priv (this_xl);
-
- if (this_xl->dumpops->inode &&
- GF_PROC_DUMP_IS_XL_OPTION_ENABLED (inode))
- this_xl->dumpops->inode (this_xl);
-
-
- if (this_xl->dumpops->fd &&
+ trav->dumpops->priv (trav);
+
+ if (GF_PROC_DUMP_IS_XL_OPTION_ENABLED (inode) &&
+ (trav->dumpops->inode))
+ trav->dumpops->inode (trav);
+
+ if (trav->dumpops->fd &&
GF_PROC_DUMP_IS_XL_OPTION_ENABLED (fd))
- this_xl->dumpops->fd (this_xl);
-
- this_xl = this_xl->next;
+ trav->dumpops->fd (trav);
+
+ if (trav->dumpops->history &&
+ GF_PROC_DUMP_IS_XL_OPTION_ENABLED (history))
+ trav->dumpops->history (trav);
+
+ trav = trav->next;
}
return;
}
-static int
-gf_proc_dump_parse_set_option (char *key, char *value)
+
+static void
+gf_proc_dump_oldgraph_xlator_info (xlator_t *top)
{
- gf_boolean_t *opt_key = NULL;
- gf_boolean_t opt_value = _gf_false;
- char buf[GF_DUMP_MAX_BUF_LEN];
+ xlator_t *trav = NULL;
- if (!strncasecmp (key, "mem", 3)) {
- opt_key = &dump_options.dump_mem;
- } else if (!strncasecmp (key, "iobuf", 5)) {
- opt_key = &dump_options.dump_iobuf;
- } else if (!strncasecmp (key, "callpool", 8)) {
- opt_key = &dump_options.dump_callpool;
- } else if (!strncasecmp (key, "priv", 4)) {
- opt_key = &dump_options.xl_options.dump_priv;
- } else if (!strncasecmp (key, "fd", 2)) {
- opt_key = &dump_options.xl_options.dump_fd;
- } else if (!strncasecmp (key, "inode", 5)) {
- opt_key = &dump_options.xl_options.dump_inode;
- } else if (!strncasecmp (key, "inodectx", strlen ("inodectx"))) {
- opt_key = &dump_options.xl_options.dump_inodectx;
- } else if (!strncasecmp (key, "fdctx", strlen ("fdctx"))) {
- opt_key = &dump_options.xl_options.dump_fdctx;
- }
+ if (!top)
+ return;
- if (!opt_key) {
- //None of dump options match the key, return back
- snprintf (buf, sizeof (buf), "[Warning]:None of the options "
- "matched key : %s\n", key);
- write (gf_dump_fd, buf, strlen (buf));
+ trav = top;
+ while (trav) {
+ gf_proc_dump_xlator_mem_info_only_in_use (trav);
- return -1;
- }
+ if (GF_PROC_DUMP_IS_XL_OPTION_ENABLED (inode) &&
+ (trav->itable)) {
+ /*TODO: dump inode table info if necessary by
+ printing the graph id (taken by glusterfs_cbtx_t)
+ in the key
+ */
+ }
- opt_value = (strncasecmp (value, "yes", 3) ?
- _gf_false: _gf_true);
+ if (!trav->dumpops) {
+ trav = trav->next;
+ continue;
+ }
- GF_PROC_DUMP_SET_OPTION (*opt_key, opt_value);
+ if (GF_PROC_DUMP_IS_XL_OPTION_ENABLED (inode) &&
+ (trav->dumpops->inode))
+ trav->dumpops->inode (trav);
- return 0;
-}
+ if (trav->dumpops->fd &&
+ GF_PROC_DUMP_IS_XL_OPTION_ENABLED (fd))
+ trav->dumpops->fd (trav);
+ trav = trav->next;
+ }
+
+ return;
+}
static int
gf_proc_dump_enable_all_options ()
@@ -329,6 +509,46 @@ gf_proc_dump_enable_all_options ()
GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_inodectx,
_gf_true);
GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_fdctx, _gf_true);
+ GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_history,
+ _gf_true);
+
+ return 0;
+}
+
+gf_boolean_t
+is_gf_proc_dump_all_disabled ()
+{
+ gf_boolean_t all_disabled = _gf_true;
+
+ GF_CHECK_DUMP_OPTION_ENABLED (dump_options.dump_mem, all_disabled, out);
+ GF_CHECK_DUMP_OPTION_ENABLED (dump_options.dump_iobuf, all_disabled, out);
+ GF_CHECK_DUMP_OPTION_ENABLED (dump_options.dump_callpool, all_disabled,
+ out);
+ GF_CHECK_DUMP_OPTION_ENABLED (dump_options.xl_options.dump_priv,
+ all_disabled, out);
+ GF_CHECK_DUMP_OPTION_ENABLED (dump_options.xl_options.dump_inode,
+ all_disabled, out);
+ GF_CHECK_DUMP_OPTION_ENABLED (dump_options.xl_options.dump_fd,
+ all_disabled, out);
+ GF_CHECK_DUMP_OPTION_ENABLED (dump_options.xl_options.dump_inodectx,
+ all_disabled, out);
+ GF_CHECK_DUMP_OPTION_ENABLED (dump_options.xl_options.dump_fdctx,
+ all_disabled, out);
+ GF_CHECK_DUMP_OPTION_ENABLED (dump_options.xl_options.dump_history,
+ all_disabled, out);
+
+out:
+ return all_disabled;
+}
+
+/* These options are dumped by default if glusterdump.options
+ file exists and it is emtpty
+*/
+static int
+gf_proc_dump_enable_default_options ()
+{
+ GF_PROC_DUMP_SET_OPTION (dump_options.dump_mem, _gf_true);
+ GF_PROC_DUMP_SET_OPTION (dump_options.dump_callpool, _gf_true);
return 0;
}
@@ -342,40 +562,113 @@ gf_proc_dump_disable_all_options ()
GF_PROC_DUMP_SET_OPTION (dump_options.dump_callpool, _gf_false);
GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_priv, _gf_false);
GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_inode,
- _gf_false);
+ _gf_false);
GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_fd, _gf_false);
GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_inodectx,
_gf_false);
GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_fdctx, _gf_false);
-
+ GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_history,
+ _gf_false);
return 0;
}
static int
+gf_proc_dump_parse_set_option (char *key, char *value)
+{
+ gf_boolean_t *opt_key = NULL;
+ gf_boolean_t opt_value = _gf_false;
+ char buf[GF_DUMP_MAX_BUF_LEN];
+ int ret = -1;
+
+ if (!strcasecmp (key, "all")) {
+ (void)gf_proc_dump_enable_all_options ();
+ return 0;
+ } else if (!strcasecmp (key, "mem")) {
+ opt_key = &dump_options.dump_mem;
+ } else if (!strcasecmp (key, "iobuf")) {
+ opt_key = &dump_options.dump_iobuf;
+ } else if (!strcasecmp (key, "callpool")) {
+ opt_key = &dump_options.dump_callpool;
+ } else if (!strcasecmp (key, "priv")) {
+ opt_key = &dump_options.xl_options.dump_priv;
+ } else if (!strcasecmp (key, "fd")) {
+ opt_key = &dump_options.xl_options.dump_fd;
+ } else if (!strcasecmp (key, "inode")) {
+ opt_key = &dump_options.xl_options.dump_inode;
+ } else if (!strcasecmp (key, "inodectx")) {
+ opt_key = &dump_options.xl_options.dump_inodectx;
+ } else if (!strcasecmp (key, "fdctx")) {
+ opt_key = &dump_options.xl_options.dump_fdctx;
+ } else if (!strcasecmp (key, "history")) {
+ opt_key = &dump_options.xl_options.dump_history;
+ }
+
+ if (!opt_key) {
+ //None of dump options match the key, return back
+ snprintf (buf, sizeof (buf), "[Warning]:None of the options "
+ "matched key : %s\n", key);
+ ret = write (gf_dump_fd, buf, strlen (buf));
+
+ if (ret >= 0)
+ ret = -1;
+ goto out;
+
+ }
+
+ opt_value = (strncasecmp (value, "yes", 3) ?
+ _gf_false: _gf_true);
+
+ GF_PROC_DUMP_SET_OPTION (*opt_key, opt_value);
+
+ ret = 0;
+out:
+ return ret;
+}
+
+static int
gf_proc_dump_options_init ()
{
int ret = -1;
FILE *fp = NULL;
char buf[256];
- char dumpbuf[GF_DUMP_MAX_BUF_LEN];
char *key = NULL, *value = NULL;
char *saveptr = NULL;
-
-
- fp = fopen (GF_DUMP_OPTIONFILE, "r");
-
+ char dump_option_file[PATH_MAX];
+
+ /* glusterd will create a file glusterdump.<pid>.options and
+ sets the statedump options for the process and the file is removed
+ after the statedump is taken. Direct issue of SIGUSR1 does not have
+ mechanism for considering the statedump options. So to have a way
+ of configuring the statedump of all the glusterfs processes through
+ both cli command and SIGUSR1, glusterdump.options file is searched
+ and the options mentioned in it are given the higher priority.
+ */
+ snprintf (dump_option_file, sizeof (dump_option_file),
+ DEFAULT_VAR_RUN_DIRECTORY
+ "/glusterdump.options");
+ fp = fopen (dump_option_file, "r");
if (!fp) {
- //ENOENT, return success
- (void) gf_proc_dump_enable_all_options ();
- return 0;
+ snprintf (dump_option_file, sizeof (dump_option_file),
+ DEFAULT_VAR_RUN_DIRECTORY
+ "/glusterdump.%d.options", getpid ());
+
+ fp = fopen (dump_option_file, "r");
+
+ if (!fp) {
+ //ENOENT, return success
+ (void) gf_proc_dump_enable_all_options ();
+ return 0;
+ }
}
(void) gf_proc_dump_disable_all_options ();
+ // swallow the errors if setting statedump file path is failed.
+ ret = gf_proc_dump_set_path (dump_option_file);
+
ret = fscanf (fp, "%s", buf);
while (ret != EOF) {
-
key = strtok_r (buf, "=", &saveptr);
if (!key) {
ret = fscanf (fp, "%s", buf);
@@ -389,49 +682,128 @@ gf_proc_dump_options_init ()
continue;
}
- snprintf (dumpbuf, sizeof (dumpbuf), "[Debug]:key=%s, value=%s\n",key,value);
- write (gf_dump_fd, dumpbuf, strlen (dumpbuf));
-
gf_proc_dump_parse_set_option (key, value);
-
}
+ if (is_gf_proc_dump_all_disabled ())
+ (void) gf_proc_dump_enable_default_options ();
+
+ if (fp)
+ fclose (fp);
+
return 0;
}
void
-gf_proc_dump_info (int signum)
+gf_proc_dump_info (int signum, glusterfs_ctx_t *ctx)
{
- int ret = -1;
- glusterfs_ctx_t *ctx = NULL;
+ int i = 0;
+ int ret = -1;
+ glusterfs_graph_t *trav = NULL;
+ char brick_name[PATH_MAX] = {0,};
+ char timestr[256] = {0,};
+ char sign_string[512] = {0,};
+ char tmp_dump_name[PATH_MAX] = {0,};
+ char path[PATH_MAX] = {0,};
+ struct timeval tv = {0,};
-
gf_proc_dump_lock ();
- ret = gf_proc_dump_open ();
- if (ret < 0)
+
+ if (!ctx)
goto out;
+ if (ctx->cmd_args.brick_name) {
+ GF_REMOVE_SLASH_FROM_PATH (ctx->cmd_args.brick_name, brick_name);
+ } else
+ strncpy (brick_name, "glusterdump", sizeof (brick_name));
+
ret = gf_proc_dump_options_init ();
-
if (ret < 0)
goto out;
- if (GF_PROC_DUMP_IS_OPTION_ENABLED (mem))
+ snprintf (path, sizeof (path), "%s/%s.%d.dump.%"PRIu64,
+ ((dump_options.dump_path != NULL)?dump_options.dump_path:
+ ((ctx->statedump_path != NULL)?ctx->statedump_path:
+ DEFAULT_VAR_RUN_DIRECTORY)), brick_name, getpid(),
+ (uint64_t) time (NULL));
+
+ snprintf (tmp_dump_name, PATH_MAX, "%s/dumpXXXXXX",
+ ((dump_options.dump_path != NULL)?dump_options.dump_path:
+ ((ctx->statedump_path != NULL)?ctx->statedump_path:
+ DEFAULT_VAR_RUN_DIRECTORY)));
+
+ ret = gf_proc_dump_open (tmp_dump_name);
+ if (ret < 0)
+ goto out;
+
+ //continue even though gettimeofday() has failed
+ ret = gettimeofday (&tv, NULL);
+ if (0 == ret) {
+ gf_time_fmt (timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT);
+ snprintf (timestr + strlen (timestr),
+ sizeof timestr - strlen (timestr),
+ ".%"GF_PRI_SUSECONDS, tv.tv_usec);
+ }
+
+ snprintf (sign_string, sizeof (sign_string), "DUMP-START-TIME: %s\n",
+ timestr);
+
+ //swallow the errors of write for start and end marker
+ ret = write (gf_dump_fd, sign_string, strlen (sign_string));
+
+ memset (sign_string, 0, sizeof (sign_string));
+ memset (timestr, 0, sizeof (timestr));
+ memset (&tv, 0, sizeof (tv));
+
+ if (GF_PROC_DUMP_IS_OPTION_ENABLED (mem)) {
gf_proc_dump_mem_info ();
+ gf_proc_dump_mempool_info (ctx);
+ }
+
+ if (GF_PROC_DUMP_IS_OPTION_ENABLED (iobuf))
+ iobuf_stats_dump (ctx->iobuf_pool);
+ if (GF_PROC_DUMP_IS_OPTION_ENABLED (callpool))
+ gf_proc_dump_pending_frames (ctx->pool);
+
+ if (ctx->master) {
+ gf_proc_dump_add_section ("fuse");
+ gf_proc_dump_xlator_info (ctx->master);
+ }
+
+ if (ctx->active) {
+ gf_proc_dump_add_section ("active graph - %d", ctx->graph_id);
+ gf_proc_dump_xlator_info (ctx->active->top);
+ }
+
+ i = 0;
+ list_for_each_entry (trav, &ctx->graphs, list) {
+ if (trav == ctx->active)
+ continue;
+
+ gf_proc_dump_add_section ("oldgraph[%d]", i);
- ctx = glusterfs_ctx_get ();
-
- if (ctx) {
- if (GF_PROC_DUMP_IS_OPTION_ENABLED (iobuf))
- iobuf_stats_dump (ctx->iobuf_pool);
- if (GF_PROC_DUMP_IS_OPTION_ENABLED (callpool))
- gf_proc_dump_pending_frames (ctx->pool);
- gf_proc_dump_xlator_info (ctx->active->top);
+ gf_proc_dump_oldgraph_xlator_info (trav->top);
+ i++;
+ }
+ ret = gettimeofday (&tv, NULL);
+ if (0 == ret) {
+ gf_time_fmt (timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT);
+ snprintf (timestr + strlen (timestr),
+ sizeof timestr - strlen (timestr),
+ ".%"GF_PRI_SUSECONDS, tv.tv_usec);
}
- gf_proc_dump_close ();
+ snprintf (sign_string, sizeof (sign_string), "\nDUMP-END-TIME: %s",
+ timestr);
+ ret = write (gf_dump_fd, sign_string, strlen (sign_string));
+
out:
+ if (gf_dump_fd != -1)
+ gf_proc_dump_close ();
+ rename (tmp_dump_name, path);
+ GF_FREE (dump_options.dump_path);
+ dump_options.dump_path = NULL;
gf_proc_dump_unlock ();
return;
@@ -441,23 +813,21 @@ out:
void
gf_proc_dump_fini (void)
{
- pthread_mutex_destroy (&gf_proc_dump_mutex);
+ pthread_mutex_destroy (&gf_proc_dump_mutex);
}
void
gf_proc_dump_init ()
{
- pthread_mutex_init (&gf_proc_dump_mutex, NULL);
+ pthread_mutex_init (&gf_proc_dump_mutex, NULL);
- return;
+ return;
}
void
gf_proc_dump_cleanup (void)
{
- pthread_mutex_destroy (&gf_proc_dump_mutex);
+ pthread_mutex_destroy (&gf_proc_dump_mutex);
}
-
-
diff --git a/libglusterfs/src/statedump.h b/libglusterfs/src/statedump.h
index 5e106d897..8342b120a 100644
--- a/libglusterfs/src/statedump.h
+++ b/libglusterfs/src/statedump.h
@@ -1,42 +1,29 @@
/*
- Copyright (c) 2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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 STATEDUMP_H
-#define STATEDUMP_H
+#define STATEDUMP_H
#include <stdarg.h>
#include "inode.h"
#define GF_DUMP_MAX_BUF_LEN 4096
-#define GF_DUMP_LOGFILE_ROOT "/tmp/glusterdump"
-#define GF_DUMP_LOGFILE_ROOT_LEN 256
-
-#define GF_DUMP_OPTIONFILE "/tmp/glusterdump.input"
-
typedef struct gf_dump_xl_options_ {
gf_boolean_t dump_priv;
gf_boolean_t dump_inode;
gf_boolean_t dump_fd;
gf_boolean_t dump_inodectx;
gf_boolean_t dump_fdctx;
+ gf_boolean_t dump_history;
} gf_dump_xl_options_t;
typedef struct gf_dump_options_ {
@@ -44,6 +31,7 @@ typedef struct gf_dump_options_ {
gf_boolean_t dump_iobuf;
gf_boolean_t dump_callpool;
gf_dump_xl_options_t xl_options; //options for all xlators
+ char *dump_path;
} gf_dump_options_t;
extern gf_dump_options_t dump_options;
@@ -58,43 +46,49 @@ void _gf_proc_dump_build_key (char *key, const char *prefix, char *fmt,...)
va_start(ap, fmt);
vsnprintf(buf, GF_DUMP_MAX_BUF_LEN, fmt, ap);
va_end(ap);
- snprintf(key, GF_DUMP_MAX_BUF_LEN, "%s.%s", prefix, buf);
+ snprintf(key, GF_DUMP_MAX_BUF_LEN, "%s.%s", prefix, buf);
}
-#define gf_proc_dump_build_key(key, key_prefix, fmt...) \
-{\
- _gf_proc_dump_build_key(key, key_prefix, ##fmt);\
-}
+#define gf_proc_dump_build_key(key, key_prefix, fmt...) \
+ { \
+ _gf_proc_dump_build_key(key, key_prefix, ##fmt); \
+ }
#define GF_PROC_DUMP_SET_OPTION(opt,val) opt = val
-void
-gf_proc_dump_init();
+#define GF_CHECK_DUMP_OPTION_ENABLED(option_dump, var, label) \
+ do { \
+ if (option_dump == _gf_true) { \
+ var = _gf_false; \
+ goto label; \
+ } \
+ } while (0);
+
+void gf_proc_dump_init();
+
+void gf_proc_dump_fini(void);
+
+void gf_proc_dump_cleanup(void);
+
+void gf_proc_dump_info(int signum, glusterfs_ctx_t *ctx);
+
+int gf_proc_dump_add_section(char *key,...);
-void
-gf_proc_dump_fini(void);
+int gf_proc_dump_write(char *key, char *value,...);
-void
-gf_proc_dump_cleanup(void);
+void inode_table_dump(inode_table_t *itable, char *prefix);
-void
-gf_proc_dump_info(int signum);
+void inode_table_dump_to_dict (inode_table_t *itable, char *prefix, dict_t *dict);
-void
-gf_proc_dump_add_section(char *key,...);
+void fdtable_dump(fdtable_t *fdtable, char *prefix);
-void
-gf_proc_dump_write(char *key, char *value,...);
+void fdtable_dump_to_dict (fdtable_t *fdtable, char *prefix, dict_t *dict);
-void
-inode_table_dump(inode_table_t *itable, char *prefix);
+void inode_dump(inode_t *inode, char *prefix);
-void
-fdtable_dump(fdtable_t *fdtable, char *prefix);
+void gf_proc_dump_mem_info_to_dict (dict_t *dict);
-void
-inode_dump(inode_t *inode, char *prefix);
+void gf_proc_dump_mempool_info_to_dict (glusterfs_ctx_t *ctx, dict_t *dict);
-void
-glusterd_init (int sig);
+void glusterd_init (int sig);
#endif /* STATEDUMP_H */
diff --git a/libglusterfs/src/store.c b/libglusterfs/src/store.c
new file mode 100644
index 000000000..1e6601837
--- /dev/null
+++ b/libglusterfs/src/store.c
@@ -0,0 +1,709 @@
+/*
+ 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 _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include <inttypes.h>
+#include <libgen.h>
+
+#include "glusterfs.h"
+#include "store.h"
+#include "dict.h"
+#include "xlator.h"
+
+int32_t
+gf_store_mkdir (char *path)
+{
+ int32_t ret = -1;
+
+ ret = mkdir (path, 0777);
+
+ if ((-1 == ret) && (EEXIST != errno)) {
+ gf_log ("", GF_LOG_ERROR, "mkdir() failed on path %s,"
+ "errno: %s", path, strerror (errno));
+ } else {
+ ret = 0;
+ }
+
+ return ret;
+}
+
+int32_t
+gf_store_handle_create_on_absence (gf_store_handle_t **shandle,
+ char *path)
+{
+ GF_ASSERT (shandle);
+ int32_t ret = 0;
+
+ if (*shandle == NULL) {
+ ret = gf_store_handle_new (path, shandle);
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to create store"
+ " handle for path: %s", path);
+ }
+ }
+ return ret;
+}
+
+int32_t
+gf_store_mkstemp (gf_store_handle_t *shandle)
+{
+ int fd = -1;
+ char tmppath[PATH_MAX] = {0,};
+
+ GF_ASSERT (shandle);
+ GF_ASSERT (shandle->path);
+
+ snprintf (tmppath, sizeof (tmppath), "%s.tmp", shandle->path);
+ fd = open (tmppath, O_RDWR | O_CREAT | O_TRUNC | O_SYNC, 0600);
+ if (fd <= 0) {
+ gf_log ("", GF_LOG_ERROR, "Failed to open %s, error: %s",
+ tmppath, strerror (errno));
+ }
+
+ return fd;
+}
+
+int
+gf_store_sync_direntry (char *path)
+{
+ int ret = -1;
+ int dirfd = -1;
+ char *dir = NULL;
+ char *pdir = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ dir = gf_strdup (path);
+ if (!dir)
+ goto out;
+
+ pdir = dirname (dir);
+ dirfd = open (pdir, O_RDONLY);
+ if (dirfd == -1) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to open directory "
+ "%s, due to %s", pdir, strerror (errno));
+ goto out;
+ }
+
+ ret = fsync (dirfd);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to fsync %s, due to "
+ "%s", pdir, strerror (errno));
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (dirfd >= 0) {
+ ret = close (dirfd);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to close "
+ "%s, due to %s", pdir, strerror (errno));
+ }
+ }
+
+ if (dir)
+ GF_FREE (dir);
+
+ return ret;
+}
+
+int32_t
+gf_store_rename_tmppath (gf_store_handle_t *shandle)
+{
+ int32_t ret = -1;
+ char tmppath[PATH_MAX] = {0,};
+
+ GF_ASSERT (shandle);
+ GF_ASSERT (shandle->path);
+
+ snprintf (tmppath, sizeof (tmppath), "%s.tmp", shandle->path);
+ ret = rename (tmppath, shandle->path);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Failed to rename %s to %s, "
+ "error: %s", tmppath, shandle->path, strerror (errno));
+ goto out;
+ }
+
+ ret = gf_store_sync_direntry (tmppath);
+out:
+ return ret;
+}
+
+int32_t
+gf_store_unlink_tmppath (gf_store_handle_t *shandle)
+{
+ int32_t ret = -1;
+ char tmppath[PATH_MAX] = {0,};
+
+ GF_ASSERT (shandle);
+ GF_ASSERT (shandle->path);
+
+ snprintf (tmppath, sizeof (tmppath), "%s.tmp", shandle->path);
+ ret = unlink (tmppath);
+ if (ret && (errno != ENOENT)) {
+ gf_log ("", GF_LOG_ERROR, "Failed to mv %s to %s, error: %s",
+ tmppath, shandle->path, strerror (errno));
+ } else {
+ ret = 0;
+ }
+
+ return ret;
+}
+
+int
+gf_store_read_and_tokenize (FILE *file, char *str, char **iter_key,
+ char **iter_val, gf_store_op_errno_t *store_errno)
+{
+ int32_t ret = -1;
+ char *savetok = NULL;
+ char *key = NULL;
+ char *value = NULL;
+ char *temp = NULL;
+ size_t str_len = 0;
+
+ GF_ASSERT (file);
+ GF_ASSERT (str);
+ GF_ASSERT (iter_key);
+ GF_ASSERT (iter_val);
+ GF_ASSERT (store_errno);
+
+ temp = fgets (str, PATH_MAX, file);
+ if (temp == NULL || feof (file)) {
+ ret = -1;
+ *store_errno = GD_STORE_EOF;
+ goto out;
+ }
+
+ str_len = strlen(str);
+ str[str_len - 1] = '\0';
+ /* Truncate the "\n", as fgets stores "\n" in str */
+
+ key = strtok_r (str, "=", &savetok);
+ if (!key) {
+ ret = -1;
+ *store_errno = GD_STORE_KEY_NULL;
+ goto out;
+ }
+
+ value = strtok_r (NULL, "=", &savetok);
+ if (!value) {
+ ret = -1;
+ *store_errno = GD_STORE_VALUE_NULL;
+ goto out;
+ }
+
+ *iter_key = key;
+ *iter_val = value;
+ *store_errno = GD_STORE_SUCCESS;
+ ret = 0;
+out:
+ return ret;
+}
+
+int32_t
+gf_store_retrieve_value (gf_store_handle_t *handle, char *key, char **value)
+{
+ int32_t ret = -1;
+ char *scan_str = NULL;
+ char *iter_key = NULL;
+ char *iter_val = NULL;
+ char *free_str = NULL;
+ struct stat st = {0,};
+ gf_store_op_errno_t store_errno = GD_STORE_SUCCESS;
+
+ GF_ASSERT (handle);
+
+ if (handle->locked == F_ULOCK)
+ /* no locking is used handle->fd gets closed() after usage */
+ handle->fd = open (handle->path, O_RDWR);
+ else
+ /* handle->fd is valid already, kept open for lockf() */
+ lseek (handle->fd, 0, SEEK_SET);
+
+ if (handle->fd == -1) {
+ gf_log ("", GF_LOG_ERROR, "Unable to open file %s errno: %s",
+ handle->path, strerror (errno));
+ goto out;
+ }
+ if (!handle->read)
+ handle->read = fdopen (dup(handle->fd), "r");
+ else
+ fseek (handle->read, 0, SEEK_SET);
+
+ if (!handle->read) {
+ gf_log ("", GF_LOG_ERROR, "Unable to open file %s errno: %s",
+ handle->path, strerror (errno));
+ goto out;
+ }
+
+ ret = fstat (handle->fd, &st);
+ if (ret < 0) {
+ gf_log ("", GF_LOG_WARNING, "stat on file %s failed",
+ handle->path);
+ ret = -1;
+ store_errno = GD_STORE_STAT_FAILED;
+ goto out;
+ }
+
+ /* "st.st_size + 1" is used as we are fetching each
+ * line of a file using fgets, fgets will append "\0"
+ * to the end of the string
+ */
+ scan_str = GF_CALLOC (1, st.st_size + 1,
+ gf_common_mt_char);
+
+ if (scan_str == NULL) {
+ ret = -1;
+ store_errno = GD_STORE_ENOMEM;
+ goto out;
+ }
+
+ free_str = scan_str;
+
+ do {
+ ret = gf_store_read_and_tokenize (handle->read, scan_str,
+ &iter_key, &iter_val,
+ &store_errno);
+ if (ret < 0) {
+ gf_log ("", GF_LOG_TRACE, "error while reading key "
+ "'%s': %s", key,
+ gf_store_strerror (store_errno));
+ goto out;
+ }
+
+ gf_log ("", GF_LOG_TRACE, "key %s read", iter_key);
+
+ if (!strcmp (key, iter_key)) {
+ gf_log ("", GF_LOG_DEBUG, "key %s found", key);
+ ret = 0;
+ if (iter_val)
+ *value = gf_strdup (iter_val);
+ goto out;
+ }
+ } while (1);
+out:
+ if (handle->read) {
+ fclose (handle->read);
+ handle->read = NULL;
+ }
+
+ if (handle->fd > 0 && handle->locked == F_ULOCK) {
+ /* only invalidate handle->fd if not locked */
+ close (handle->fd);
+ }
+
+ GF_FREE (free_str);
+
+ return ret;
+}
+
+int32_t
+gf_store_save_value (int fd, char *key, char *value)
+{
+ int32_t ret = -1;
+ int dup_fd = -1;
+ FILE *fp = NULL;
+
+ GF_ASSERT (fd > 0);
+ GF_ASSERT (key);
+ GF_ASSERT (value);
+
+ dup_fd = dup (fd);
+ if (dup_fd == -1)
+ goto out;
+
+ fp = fdopen (dup_fd, "a+");
+ if (fp == NULL) {
+ gf_log ("", GF_LOG_WARNING, "fdopen failed.");
+ ret = -1;
+ goto out;
+ }
+
+ ret = fprintf (fp, "%s=%s\n", key, value);
+ if (ret < 0) {
+ gf_log ("", GF_LOG_WARNING, "Unable to store key: %s,"
+ "value: %s, error: %s", key, value,
+ strerror (errno));
+ ret = -1;
+ goto out;
+ }
+
+ ret = fflush (fp);
+ if (feof (fp)) {
+ gf_log ("", GF_LOG_WARNING,
+ "fflush failed, error: %s",
+ strerror (errno));
+ ret = -1;
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (fp)
+ fclose (fp);
+
+ gf_log ("", GF_LOG_DEBUG, "returning: %d", ret);
+ return ret;
+}
+
+int32_t
+gf_store_handle_new (char *path, gf_store_handle_t **handle)
+{
+ int32_t ret = -1;
+ gf_store_handle_t *shandle = NULL;
+ int fd = -1;
+ char *spath = NULL;
+
+ shandle = GF_CALLOC (1, sizeof (*shandle), gf_common_mt_store_handle_t);
+ if (!shandle)
+ goto out;
+
+ spath = gf_strdup (path);
+
+ if (!spath)
+ goto out;
+
+ fd = open (path, O_RDWR | O_CREAT | O_APPEND, 0600);
+ if (fd <= 0) {
+ gf_log ("", GF_LOG_ERROR, "Failed to open file: %s, error: %s",
+ path, strerror (errno));
+ goto out;
+ }
+
+ ret = gf_store_sync_direntry (spath);
+ if (ret)
+ goto out;
+
+ shandle->path = spath;
+ shandle->locked = F_ULOCK;
+ *handle = shandle;
+
+ ret = 0;
+out:
+ if (fd > 0)
+ close (fd);
+
+ if (ret == -1) {
+ GF_FREE (spath);
+ GF_FREE (shandle);
+ }
+
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+gf_store_handle_retrieve (char *path, gf_store_handle_t **handle)
+{
+ int32_t ret = -1;
+ struct stat statbuf = {0};
+
+ ret = stat (path, &statbuf);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Path corresponding to "
+ "%s, returned error: (%s)",
+ path, strerror (errno));
+ goto out;
+ }
+ ret = gf_store_handle_new (path, handle);
+out:
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int32_t
+gf_store_handle_destroy (gf_store_handle_t *handle)
+{
+ int32_t ret = -1;
+
+ if (!handle) {
+ ret = 0;
+ goto out;
+ }
+
+ GF_FREE (handle->path);
+
+ GF_FREE (handle);
+
+ ret = 0;
+
+out:
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+
+ return ret;
+}
+
+int32_t
+gf_store_iter_new (gf_store_handle_t *shandle, gf_store_iter_t **iter)
+{
+ int32_t ret = -1;
+ FILE *fp = NULL;
+ gf_store_iter_t *tmp_iter = NULL;
+
+ GF_ASSERT (shandle);
+ GF_ASSERT (iter);
+
+ fp = fopen (shandle->path, "r");
+ if (!fp) {
+ gf_log ("", GF_LOG_ERROR, "Unable to open file %s errno: %d",
+ shandle->path, errno);
+ goto out;
+ }
+
+ tmp_iter = GF_CALLOC (1, sizeof (*tmp_iter),
+ gf_common_mt_store_iter_t);
+ if (!tmp_iter)
+ goto out;
+
+ strncpy (tmp_iter->filepath, shandle->path, sizeof (tmp_iter->filepath));
+ tmp_iter->filepath[sizeof (tmp_iter->filepath) - 1] = 0;
+ tmp_iter->file = fp;
+
+ *iter = tmp_iter;
+ tmp_iter = NULL;
+ ret = 0;
+
+out:
+ if (ret && fp)
+ fclose (fp);
+
+ GF_FREE (tmp_iter);
+
+ gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
+ return ret;
+}
+
+int32_t
+gf_store_validate_key_value (char *storepath, char *key, char *val,
+ gf_store_op_errno_t *op_errno)
+{
+ int ret = 0;
+
+ GF_ASSERT (op_errno);
+ GF_ASSERT (storepath);
+
+ if ((key == NULL) && (val == NULL)) {
+ ret = -1;
+ gf_log ("", GF_LOG_ERROR, "Glusterd store may be corrupted, "
+ "Invalid key and value (null) in %s", storepath);
+ *op_errno = GD_STORE_KEY_VALUE_NULL;
+ } else if (key == NULL) {
+ ret = -1;
+ gf_log ("", GF_LOG_ERROR, "Glusterd store may be corrupted, "
+ "Invalid key (null) in %s", storepath);
+ *op_errno = GD_STORE_KEY_NULL;
+ } else if (val == NULL) {
+ ret = -1;
+ gf_log ("", GF_LOG_ERROR, "Glusterd store may be corrupted, "
+ "Invalid value (null) for key %s in %s", key,
+ storepath);
+ *op_errno = GD_STORE_VALUE_NULL;
+ } else {
+ ret = 0;
+ *op_errno = GD_STORE_SUCCESS;
+ }
+
+ return ret;
+}
+
+int32_t
+gf_store_iter_get_next (gf_store_iter_t *iter, char **key, char **value,
+ gf_store_op_errno_t *op_errno)
+{
+ int32_t ret = -1;
+ char *scan_str = NULL;
+ char *iter_key = NULL;
+ char *iter_val = NULL;
+ struct stat st = {0,};
+ gf_store_op_errno_t store_errno = GD_STORE_SUCCESS;
+
+ GF_ASSERT (iter);
+ GF_ASSERT (key);
+ GF_ASSERT (value);
+
+ ret = stat (iter->filepath, &st);
+ if (ret < 0) {
+ gf_log ("", GF_LOG_WARNING, "stat on file failed");
+ ret = -1;
+ store_errno = GD_STORE_STAT_FAILED;
+ goto out;
+ }
+
+ /* "st.st_size + 1" is used as we are fetching each
+ * line of a file using fgets, fgets will append "\0"
+ * to the end of the string
+ */
+ scan_str = GF_CALLOC (1, st.st_size + 1,
+ gf_common_mt_char);
+ if (!scan_str) {
+ ret = -1;
+ store_errno = GD_STORE_ENOMEM;
+ goto out;
+ }
+
+ ret = gf_store_read_and_tokenize (iter->file, scan_str,
+ &iter_key, &iter_val,
+ &store_errno);
+ if (ret < 0) {
+ goto out;
+ }
+
+ ret = gf_store_validate_key_value (iter->filepath, iter_key,
+ iter_val, &store_errno);
+ if (ret)
+ goto out;
+
+ *key = gf_strdup (iter_key);
+ if (!*key) {
+ ret = -1;
+ store_errno = GD_STORE_ENOMEM;
+ goto out;
+ }
+ *value = gf_strdup (iter_val);
+ if (!*value) {
+ ret = -1;
+ store_errno = GD_STORE_ENOMEM;
+ goto out;
+ }
+ ret = 0;
+
+out:
+ GF_FREE (scan_str);
+ if (ret) {
+ GF_FREE (*key);
+ GF_FREE (*value);
+ *key = NULL;
+ *value = NULL;
+ }
+ if (op_errno)
+ *op_errno = store_errno;
+
+ gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
+ return ret;
+}
+
+int32_t
+gf_store_iter_get_matching (gf_store_iter_t *iter, char *key, char **value)
+{
+ int32_t ret = -1;
+ char *tmp_key = NULL;
+ char *tmp_value = NULL;
+
+ ret = gf_store_iter_get_next (iter, &tmp_key, &tmp_value, NULL);
+ while (!ret) {
+ if (!strncmp (key, tmp_key, strlen (key))){
+ *value = tmp_value;
+ GF_FREE (tmp_key);
+ goto out;
+ }
+ GF_FREE (tmp_key);
+ tmp_key = NULL;
+ GF_FREE (tmp_value);
+ tmp_value = NULL;
+ ret = gf_store_iter_get_next (iter, &tmp_key, &tmp_value,
+ NULL);
+ }
+out:
+ return ret;
+}
+
+int32_t
+gf_store_iter_destroy (gf_store_iter_t *iter)
+{
+ int32_t ret = -1;
+
+ if (!iter)
+ return 0;
+
+ /* gf_store_iter_new will not return a valid iter object with iter->file
+ * being NULL*/
+ ret = fclose (iter->file);
+ if (ret)
+ gf_log ("", GF_LOG_ERROR, "Unable to close file: %s, ret: %d, "
+ "errno: %d" ,iter->filepath, ret, errno);
+
+ GF_FREE (iter);
+ return ret;
+}
+
+char*
+gf_store_strerror (gf_store_op_errno_t op_errno)
+{
+ switch (op_errno) {
+ case GD_STORE_SUCCESS:
+ return "Success";
+ case GD_STORE_KEY_NULL:
+ return "Invalid Key";
+ case GD_STORE_VALUE_NULL:
+ return "Invalid Value";
+ case GD_STORE_KEY_VALUE_NULL:
+ return "Invalid Key and Value";
+ case GD_STORE_EOF:
+ return "No data";
+ case GD_STORE_ENOMEM:
+ return "No memory";
+ default:
+ return "Invalid errno";
+ }
+ return "Invalid errno";
+}
+
+int
+gf_store_lock (gf_store_handle_t *sh)
+{
+ int ret;
+
+ GF_ASSERT (sh);
+ GF_ASSERT (sh->path);
+ GF_ASSERT (sh->locked == F_ULOCK);
+
+ sh->fd = open (sh->path, O_RDWR);
+ if (sh->fd == -1) {
+ gf_log ("", GF_LOG_ERROR, "Failed to open '%s': %s", sh->path,
+ strerror (errno));
+ return -1;
+ }
+
+ ret = lockf (sh->fd, F_LOCK, 0);
+ if (ret)
+ gf_log ("", GF_LOG_ERROR, "Failed to gain lock on '%s': %s",
+ sh->path, strerror (errno));
+ else
+ /* sh->locked is protected by the lockf(sh->fd) above */
+ sh->locked = F_LOCK;
+
+ return ret;
+}
+
+void
+gf_store_unlock (gf_store_handle_t *sh)
+{
+ GF_ASSERT (sh);
+ GF_ASSERT (sh->locked == F_LOCK);
+
+ sh->locked = F_ULOCK;
+ lockf (sh->fd, F_ULOCK, 0);
+ close (sh->fd);
+}
+
+int
+gf_store_locked_local (gf_store_handle_t *sh)
+{
+ GF_ASSERT (sh);
+
+ return (sh->locked == F_LOCK);
+}
diff --git a/libglusterfs/src/store.h b/libglusterfs/src/store.h
new file mode 100644
index 000000000..337103ff7
--- /dev/null
+++ b/libglusterfs/src/store.h
@@ -0,0 +1,112 @@
+/*
+ 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 _GLUSTERD_STORE_H_
+#define _GLUSTERD_STORE_H_
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "glusterfs.h"
+
+struct gf_store_handle_ {
+ char *path;
+ int fd;
+ FILE *read;
+ int locked; /* state of lockf() */
+};
+
+typedef struct gf_store_handle_ gf_store_handle_t;
+
+struct gf_store_iter_ {
+ FILE *file;
+ char filepath[PATH_MAX];
+};
+
+typedef struct gf_store_iter_ gf_store_iter_t;
+
+typedef enum {
+ GD_STORE_SUCCESS,
+ GD_STORE_KEY_NULL,
+ GD_STORE_VALUE_NULL,
+ GD_STORE_KEY_VALUE_NULL,
+ GD_STORE_EOF,
+ GD_STORE_ENOMEM,
+ GD_STORE_STAT_FAILED
+} gf_store_op_errno_t;
+
+int32_t
+gf_store_mkdir (char *path);
+
+int32_t
+gf_store_handle_create_on_absence (gf_store_handle_t **shandle, char *path);
+
+int32_t
+gf_store_mkstemp (gf_store_handle_t *shandle);
+
+int
+gf_store_sync_direntry (char *path);
+
+int32_t
+gf_store_rename_tmppath (gf_store_handle_t *shandle);
+
+int32_t
+gf_store_unlink_tmppath (gf_store_handle_t *shandle);
+
+int
+gf_store_read_and_tokenize (FILE *file, char *str, char **iter_key,
+ char **iter_val, gf_store_op_errno_t *store_errno);
+
+int32_t
+gf_store_retrieve_value (gf_store_handle_t *handle, char *key, char **value);
+
+int32_t
+gf_store_save_value (int fd, char *key, char *value);
+
+int32_t
+gf_store_handle_new (char *path, gf_store_handle_t **handle);
+
+int
+gf_store_handle_retrieve (char *path, gf_store_handle_t **handle);
+
+int32_t
+gf_store_handle_destroy (gf_store_handle_t *handle);
+
+int32_t
+gf_store_iter_new (gf_store_handle_t *shandle, gf_store_iter_t **iter);
+
+int32_t
+gf_store_validate_key_value (char *storepath, char *key, char *val,
+ gf_store_op_errno_t *op_errno);
+
+int32_t
+gf_store_iter_get_next (gf_store_iter_t *iter, char **key, char **value,
+ gf_store_op_errno_t *op_errno);
+
+int32_t
+gf_store_iter_get_matching (gf_store_iter_t *iter, char *key, char **value);
+
+int32_t
+gf_store_iter_destroy (gf_store_iter_t *iter);
+
+char*
+gf_store_strerror (gf_store_op_errno_t op_errno);
+
+int
+gf_store_lock (gf_store_handle_t *sh);
+
+void
+gf_store_unlock (gf_store_handle_t *sh);
+
+int
+gf_store_locked_local (gf_store_handle_t *sh);
+
+#endif
diff --git a/libglusterfs/src/syncop.c b/libglusterfs/src/syncop.c
index 6b46a14d3..c1620bb70 100644
--- a/libglusterfs/src/syncop.c
+++ b/libglusterfs/src/syncop.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
#ifndef _CONFIG_H
@@ -24,57 +15,250 @@
#include "syncop.h"
-call_frame_t *
-syncop_create_frame ()
+int
+syncopctx_setfsuid (void *uid)
{
- struct synctask *task = NULL;
- struct call_frame_t *frame = NULL;
-
- task = synctask_get ();
+ struct syncopctx *opctx = NULL;
+ int ret = 0;
+
+ /* In args check */
+ if (!uid) {
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
+
+ opctx = syncopctx_getctx ();
+
+ /* alloc for this thread the first time */
+ if (!opctx) {
+ opctx = GF_CALLOC (1, sizeof (*opctx), gf_common_mt_syncopctx);
+ if (!opctx) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = syncopctx_setctx (opctx);
+ if (ret != 0) {
+ GF_FREE (opctx);
+ opctx = NULL;
+ goto out;
+ }
+ }
+
+out:
+ if (opctx && uid) {
+ opctx->uid = *(uid_t *)uid;
+ opctx->valid |= SYNCOPCTX_UID;
+ }
+
+ return ret;
+}
- if (task) {
- frame = task->opaque;
- }
+int
+syncopctx_setfsgid (void *gid)
+{
+ struct syncopctx *opctx = NULL;
+ int ret = 0;
+
+ /* In args check */
+ if (!gid) {
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
+
+ opctx = syncopctx_getctx ();
+
+ /* alloc for this thread the first time */
+ if (!opctx) {
+ opctx = GF_CALLOC (1, sizeof (*opctx), gf_common_mt_syncopctx);
+ if (!opctx) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = syncopctx_setctx (opctx);
+ if (ret != 0) {
+ GF_FREE (opctx);
+ opctx = NULL;
+ goto out;
+ }
+ }
+
+out:
+ if (opctx && gid) {
+ opctx->gid = *(gid_t *)gid;
+ opctx->valid |= SYNCOPCTX_GID;
+ }
+
+ return ret;
+}
- return (call_frame_t *)frame;
+int
+syncopctx_setfsgroups (int count, const void *groups)
+{
+ struct syncopctx *opctx = NULL;
+ gid_t *tmpgroups = NULL;
+ int ret = 0;
+
+ /* In args check */
+ if (count != 0 && !groups) {
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
+
+ opctx = syncopctx_getctx ();
+
+ /* alloc for this thread the first time */
+ if (!opctx) {
+ opctx = GF_CALLOC (1, sizeof (*opctx), gf_common_mt_syncopctx);
+ if (!opctx) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = syncopctx_setctx (opctx);
+ if (ret != 0) {
+ GF_FREE (opctx);
+ opctx = NULL;
+ goto out;
+ }
+ }
+
+ /* resize internal groups as required */
+ if (count && opctx->grpsize < count) {
+ if (opctx->groups) {
+ tmpgroups = GF_REALLOC (opctx->groups,
+ (sizeof (gid_t) * count));
+ /* NOTE: Not really required to zero the reallocation,
+ * as ngrps controls the validity of data,
+ * making a note irrespective */
+ if (tmpgroups == NULL) {
+ opctx->grpsize = 0;
+ GF_FREE (opctx->groups);
+ opctx->groups = NULL;
+ ret = -1;
+ goto out;
+ }
+ }
+ else {
+ tmpgroups = GF_CALLOC (count, sizeof (gid_t),
+ gf_common_mt_syncopctx);
+ if (tmpgroups == NULL) {
+ opctx->grpsize = 0;
+ ret = -1;
+ goto out;
+ }
+ }
+
+ opctx->groups = tmpgroups;
+ opctx->grpsize = count;
+ }
+
+ /* copy out the groups passed */
+ if (count)
+ memcpy (opctx->groups, groups, (sizeof (gid_t) * count));
+
+ /* set/reset the ngrps, this is where reset of groups is handled */
+ opctx->ngrps = count;
+ opctx->valid |= SYNCOPCTX_GROUPS;
+
+out:
+ return ret;
}
-void
-synctask_yield (struct synctask *task)
+static void
+__run (struct synctask *task)
{
- struct syncenv *env = NULL;
+ struct syncenv *env = NULL;
env = task->env;
- if (swapcontext (&task->ctx, &env->sched) < 0) {
- gf_log ("syncop", GF_LOG_ERROR,
- "swapcontext failed (%s)", strerror (errno));
+ list_del_init (&task->all_tasks);
+ switch (task->state) {
+ case SYNCTASK_INIT:
+ case SYNCTASK_SUSPEND:
+ break;
+ case SYNCTASK_RUN:
+ gf_log (task->xl->name, GF_LOG_DEBUG,
+ "re-running already running task");
+ env->runcount--;
+ break;
+ case SYNCTASK_WAIT:
+ env->waitcount--;
+ break;
+ case SYNCTASK_DONE:
+ gf_log (task->xl->name, GF_LOG_WARNING,
+ "running completed task");
+ return;
+ case SYNCTASK_ZOMBIE:
+ gf_log (task->xl->name, GF_LOG_WARNING,
+ "attempted to wake up zombie!!");
+ return;
}
+
+ list_add_tail (&task->all_tasks, &env->runq);
+ env->runcount++;
+ task->state = SYNCTASK_RUN;
}
-void
-synctask_yawn (struct synctask *task)
+static void
+__wait (struct synctask *task)
{
- struct syncenv *env = NULL;
+ struct syncenv *env = NULL;
- env = task->env;
+ env = task->env;
- pthread_mutex_lock (&env->mutex);
- {
- list_del_init (&task->all_tasks);
- list_add (&task->all_tasks, &env->waitq);
+ list_del_init (&task->all_tasks);
+ switch (task->state) {
+ case SYNCTASK_INIT:
+ case SYNCTASK_SUSPEND:
+ break;
+ case SYNCTASK_RUN:
+ env->runcount--;
+ break;
+ case SYNCTASK_WAIT:
+ gf_log (task->xl->name, GF_LOG_WARNING,
+ "re-waiting already waiting task");
+ env->waitcount--;
+ break;
+ case SYNCTASK_DONE:
+ gf_log (task->xl->name, GF_LOG_WARNING,
+ "running completed task");
+ return;
+ case SYNCTASK_ZOMBIE:
+ gf_log (task->xl->name, GF_LOG_WARNING,
+ "attempted to sleep a zombie!!");
+ return;
}
- pthread_mutex_unlock (&env->mutex);
+
+ list_add_tail (&task->all_tasks, &env->waitq);
+ env->waitcount++;
+ task->state = SYNCTASK_WAIT;
}
void
-synctask_zzzz (struct synctask *task)
+synctask_yield (struct synctask *task)
{
- synctask_yawn (task);
+ xlator_t *oldTHIS = THIS;
- synctask_yield (task);
+#if defined(__NetBSD__) && defined(_UC_TLSBASE)
+ /* Preserve pthread private pointer through swapcontex() */
+ task->proc->sched.uc_flags &= ~_UC_TLSBASE;
+#endif
+
+ if (task->state != SYNCTASK_DONE)
+ task->state = SYNCTASK_SUSPEND;
+ if (swapcontext (&task->ctx, &task->proc->sched) < 0) {
+ gf_log ("syncop", GF_LOG_ERROR,
+ "swapcontext failed (%s)", strerror (errno));
+ }
+
+ THIS = oldTHIS;
}
@@ -87,28 +271,30 @@ synctask_wake (struct synctask *task)
pthread_mutex_lock (&env->mutex);
{
- list_del_init (&task->all_tasks);
- list_add_tail (&task->all_tasks, &env->runq);
+ task->woken = 1;
+
+ if (task->slept)
+ __run (task);
+
+ pthread_cond_broadcast (&env->cond);
}
pthread_mutex_unlock (&env->mutex);
-
- pthread_cond_broadcast (&env->cond);
}
-
void
-synctask_wrap (struct synctask *task)
+synctask_wrap (struct synctask *old_task)
{
- int ret;
+ struct synctask *task = NULL;
- ret = task->syncfn (task->opaque);
- task->synccbk (ret, task->opaque);
+ /* Do not trust the pointer received. It may be
+ wrong and can lead to crashes. */
- /* cannot destroy @task right here as we are
- in the execution stack of @task itself
- */
- task->complete = 1;
- synctask_wake (task);
+ task = synctask_get ();
+ task->ret = task->syncfn (task->opaque);
+ if (task->synccbk)
+ task->synccbk (task->ret, task->frame, task->opaque);
+
+ task->state = SYNCTASK_DONE;
synctask_yield (task);
}
@@ -120,29 +306,88 @@ synctask_destroy (struct synctask *task)
if (!task)
return;
- if (task->stack)
- FREE (task->stack);
+ FREE (task->stack);
+
+ if (task->opframe)
+ STACK_DESTROY (task->opframe->root);
+
+ if (task->synccbk == NULL) {
+ pthread_mutex_destroy (&task->mutex);
+ pthread_cond_destroy (&task->cond);
+ }
+
FREE (task);
}
+void
+synctask_done (struct synctask *task)
+{
+ if (task->synccbk) {
+ synctask_destroy (task);
+ return;
+ }
+
+ pthread_mutex_lock (&task->mutex);
+ {
+ task->state = SYNCTASK_ZOMBIE;
+ task->done = 1;
+ pthread_cond_broadcast (&task->cond);
+ }
+ pthread_mutex_unlock (&task->mutex);
+}
+
+
int
-synctask_new (struct syncenv *env, synctask_fn_t fn, synctask_cbk_t cbk,
- void *opaque)
+synctask_setid (struct synctask *task, uid_t uid, gid_t gid)
+{
+ if (!task)
+ return -1;
+
+ if (uid != -1)
+ task->uid = uid;
+
+ if (gid != -1)
+ task->gid = gid;
+
+ return 0;
+}
+
+
+struct synctask *
+synctask_create (struct syncenv *env, synctask_fn_t fn, synctask_cbk_t cbk,
+ call_frame_t *frame, void *opaque)
{
struct synctask *newtask = NULL;
+ xlator_t *this = THIS;
+
+ VALIDATE_OR_GOTO (env, err);
+ VALIDATE_OR_GOTO (fn, err);
newtask = CALLOC (1, sizeof (*newtask));
if (!newtask)
- return -ENOMEM;
+ return NULL;
+ newtask->frame = frame;
+ if (!frame) {
+ newtask->opframe = create_frame (this, this->ctx->pool);
+ } else {
+ newtask->opframe = copy_frame (frame);
+ }
+ if (!newtask->opframe)
+ goto err;
newtask->env = env;
- newtask->xl = THIS;
+ newtask->xl = this;
newtask->syncfn = fn;
newtask->synccbk = cbk;
newtask->opaque = opaque;
+ /* default to the uid/gid of the passed frame */
+ newtask->uid = newtask->opframe->root->uid;
+ newtask->gid = newtask->opframe->root->gid;
+
INIT_LIST_HEAD (&newtask->all_tasks);
+ INIT_LIST_HEAD (&newtask->waitq);
if (getcontext (&newtask->ctx) < 0) {
gf_log ("syncop", GF_LOG_ERROR,
@@ -161,35 +406,114 @@ synctask_new (struct syncenv *env, synctask_fn_t fn, synctask_cbk_t cbk,
newtask->ctx.uc_stack.ss_sp = newtask->stack;
newtask->ctx.uc_stack.ss_size = env->stacksize;
- makecontext (&newtask->ctx, (void *) synctask_wrap, 2, newtask);
+ makecontext (&newtask->ctx, (void (*)(void)) synctask_wrap, 2, newtask);
+
+ newtask->state = SYNCTASK_INIT;
+
+ newtask->slept = 1;
+
+ if (!cbk) {
+ pthread_mutex_init (&newtask->mutex, NULL);
+ pthread_cond_init (&newtask->cond, NULL);
+ newtask->done = 0;
+ }
synctask_wake (newtask);
+ /*
+ * Make sure someone's there to execute anything we just put on the
+ * run queue.
+ */
+ syncenv_scale(env);
- return 0;
+ return newtask;
err:
if (newtask) {
- if (newtask->stack)
- FREE (newtask->stack);
+ FREE (newtask->stack);
+ if (newtask->opframe)
+ STACK_DESTROY (newtask->opframe->root);
FREE (newtask);
}
- return -1;
+
+ return NULL;
+}
+
+
+int
+synctask_join (struct synctask *task)
+{
+ int ret = 0;
+
+ pthread_mutex_lock (&task->mutex);
+ {
+ while (!task->done)
+ pthread_cond_wait (&task->cond, &task->mutex);
+ }
+ pthread_mutex_unlock (&task->mutex);
+
+ ret = task->ret;
+
+ synctask_destroy (task);
+
+ return ret;
+}
+
+
+int
+synctask_new (struct syncenv *env, synctask_fn_t fn, synctask_cbk_t cbk,
+ call_frame_t *frame, void *opaque)
+{
+ struct synctask *newtask = NULL;
+ int ret = 0;
+
+ newtask = synctask_create (env, fn, cbk, frame, opaque);
+ if (!newtask)
+ return -1;
+
+ if (!cbk)
+ ret = synctask_join (newtask);
+
+ return ret;
}
struct synctask *
-syncenv_task (struct syncenv *env)
+syncenv_task (struct syncproc *proc)
{
+ struct syncenv *env = NULL;
struct synctask *task = NULL;
+ struct timespec sleep_till = {0, };
+ int ret = 0;
+
+ env = proc->env;
pthread_mutex_lock (&env->mutex);
{
- while (list_empty (&env->runq))
- pthread_cond_wait (&env->cond, &env->mutex);
+ while (list_empty (&env->runq)) {
+ sleep_till.tv_sec = time (NULL) + SYNCPROC_IDLE_TIME;
+ ret = pthread_cond_timedwait (&env->cond, &env->mutex,
+ &sleep_till);
+ if (!list_empty (&env->runq))
+ break;
+ if ((ret == ETIMEDOUT) &&
+ (env->procs > env->procmin)) {
+ task = NULL;
+ env->procs--;
+ memset (proc, 0, sizeof (*proc));
+ goto unlock;
+ }
+ }
task = list_entry (env->runq.next, struct synctask, all_tasks);
list_del_init (&task->all_tasks);
+ env->runcount--;
+
+ task->woken = 0;
+ task->slept = 0;
+
+ task->proc = proc;
}
+unlock:
pthread_mutex_unlock (&env->mutex);
return task;
@@ -206,30 +530,51 @@ synctask_switchto (struct synctask *task)
synctask_set (task);
THIS = task->xl;
- if (swapcontext (&env->sched, &task->ctx) < 0) {
+#if defined(__NetBSD__) && defined(_UC_TLSBASE)
+ /* Preserve pthread private pointer through swapcontex() */
+ task->ctx.uc_flags &= ~_UC_TLSBASE;
+#endif
+
+ if (swapcontext (&task->proc->sched, &task->ctx) < 0) {
gf_log ("syncop", GF_LOG_ERROR,
"swapcontext failed (%s)", strerror (errno));
}
-}
+ if (task->state == SYNCTASK_DONE) {
+ synctask_done (task);
+ return;
+ }
+
+ pthread_mutex_lock (&env->mutex);
+ {
+ if (task->woken) {
+ __run (task);
+ } else {
+ task->slept = 1;
+ __wait (task);
+ }
+ }
+ pthread_mutex_unlock (&env->mutex);
+}
void *
syncenv_processor (void *thdata)
{
struct syncenv *env = NULL;
+ struct syncproc *proc = NULL;
struct synctask *task = NULL;
- env = thdata;
+ proc = thdata;
+ env = proc->env;
for (;;) {
- task = syncenv_task (env);
-
- if (task->complete) {
- synctask_destroy (task);
- continue;
- }
+ task = syncenv_task (proc);
+ if (!task)
+ break;
synctask_switchto (task);
+
+ syncenv_scale (env);
}
return NULL;
@@ -237,6 +582,45 @@ syncenv_processor (void *thdata)
void
+syncenv_scale (struct syncenv *env)
+{
+ int diff = 0;
+ int scale = 0;
+ int i = 0;
+ int ret = 0;
+
+ pthread_mutex_lock (&env->mutex);
+ {
+ if (env->procs > env->runcount)
+ goto unlock;
+
+ scale = env->runcount;
+ if (scale > env->procmax)
+ scale = env->procmax;
+ if (scale > env->procs)
+ diff = scale - env->procs;
+ while (diff) {
+ diff--;
+ for (; (i < env->procmax); i++) {
+ if (env->proc[i].processor == 0)
+ break;
+ }
+
+ env->proc[i].env = env;
+ ret = gf_thread_create (&env->proc[i].processor, NULL,
+ syncenv_processor, &env->proc[i]);
+ if (ret)
+ break;
+ env->procs++;
+ i++;
+ }
+ }
+unlock:
+ pthread_mutex_unlock (&env->mutex);
+}
+
+
+void
syncenv_destroy (struct syncenv *env)
{
@@ -244,10 +628,19 @@ syncenv_destroy (struct syncenv *env)
struct syncenv *
-syncenv_new (size_t stacksize)
+syncenv_new (size_t stacksize, int procmin, int procmax)
{
struct syncenv *newenv = NULL;
int ret = 0;
+ int i = 0;
+
+ if (!procmin || procmin < 0)
+ procmin = SYNCENV_PROC_MIN;
+ if (!procmax || procmax > SYNCENV_PROC_MAX)
+ procmax = SYNCENV_PROC_MAX;
+
+ if (procmin > procmax)
+ return NULL;
newenv = CALLOC (1, sizeof (*newenv));
@@ -263,9 +656,17 @@ syncenv_new (size_t stacksize)
newenv->stacksize = SYNCENV_DEFAULT_STACKSIZE;
if (stacksize)
newenv->stacksize = stacksize;
-
- ret = pthread_create (&newenv->processor, NULL,
- syncenv_processor, newenv);
+ newenv->procmin = procmin;
+ newenv->procmax = procmax;
+
+ for (i = 0; i < newenv->procmin; i++) {
+ newenv->proc[i].env = newenv;
+ ret = gf_thread_create (&newenv->proc[i].processor, NULL,
+ syncenv_processor, &newenv->proc[i]);
+ if (ret)
+ break;
+ newenv->procs++;
+ }
if (ret != 0)
syncenv_destroy (newenv);
@@ -274,13 +675,275 @@ syncenv_new (size_t stacksize)
}
+int
+synclock_init (synclock_t *lock)
+{
+ if (!lock)
+ return -1;
+
+ pthread_cond_init (&lock->cond, 0);
+ lock->lock = 0;
+ INIT_LIST_HEAD (&lock->waitq);
+
+ return pthread_mutex_init (&lock->guard, 0);
+}
+
+
+int
+synclock_destroy (synclock_t *lock)
+{
+ if (!lock)
+ return -1;
+
+ pthread_cond_destroy (&lock->cond);
+ return pthread_mutex_destroy (&lock->guard);
+}
+
+
+static int
+__synclock_lock (struct synclock *lock)
+{
+ struct synctask *task = NULL;
+
+ if (!lock)
+ return -1;
+
+ task = synctask_get ();
+
+ while (lock->lock) {
+ if (task) {
+ /* called within a synctask */
+ list_add_tail (&task->waitq, &lock->waitq);
+ pthread_mutex_unlock (&lock->guard);
+ synctask_yield (task);
+ /* task is removed from waitq in unlock,
+ * under lock->guard.*/
+ pthread_mutex_lock (&lock->guard);
+ } else {
+ /* called by a non-synctask */
+ pthread_cond_wait (&lock->cond, &lock->guard);
+ }
+ }
+
+ lock->lock = _gf_true;
+ lock->owner = task;
+
+ return 0;
+}
+
+
+int
+synclock_lock (synclock_t *lock)
+{
+ int ret = 0;
+
+ pthread_mutex_lock (&lock->guard);
+ {
+ ret = __synclock_lock (lock);
+ }
+ pthread_mutex_unlock (&lock->guard);
+
+ return ret;
+}
+
+
+int
+synclock_trylock (synclock_t *lock)
+{
+ int ret = 0;
+
+ errno = 0;
+
+ pthread_mutex_lock (&lock->guard);
+ {
+ if (lock->lock) {
+ errno = EBUSY;
+ ret = -1;
+ goto unlock;
+ }
+
+ ret = __synclock_lock (lock);
+ }
+unlock:
+ pthread_mutex_unlock (&lock->guard);
+
+ return ret;
+}
+
+
+static int
+__synclock_unlock (synclock_t *lock)
+{
+ struct synctask *task = NULL;
+ struct synctask *curr = NULL;
+
+ if (!lock)
+ return -1;
+
+ curr = synctask_get ();
+
+ if (lock->owner != curr) {
+ /* warn ? */
+ }
+
+ lock->lock = _gf_false;
+
+ /* There could be both synctasks and non synctasks
+ waiting (or none, or either). As a mid-approach
+ between maintaining too many waiting counters
+ at one extreme and a thundering herd on unlock
+ at the other, call a cond_signal (which wakes
+ one waiter) and first synctask waiter. So at
+ most we have two threads waking up to grab the
+ just released lock.
+ */
+ pthread_cond_signal (&lock->cond);
+ if (!list_empty (&lock->waitq)) {
+ task = list_entry (lock->waitq.next, struct synctask, waitq);
+ list_del_init (&task->waitq);
+ synctask_wake (task);
+ }
+
+ return 0;
+}
+
+
+int
+synclock_unlock (synclock_t *lock)
+{
+ int ret = 0;
+
+ pthread_mutex_lock (&lock->guard);
+ {
+ ret = __synclock_unlock (lock);
+ }
+ pthread_mutex_unlock (&lock->guard);
+
+ return ret;
+}
+
+/* Barriers */
+
+int
+syncbarrier_init (struct syncbarrier *barrier)
+{
+ if (!barrier) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ pthread_cond_init (&barrier->cond, 0);
+ barrier->count = 0;
+ INIT_LIST_HEAD (&barrier->waitq);
+
+ return pthread_mutex_init (&barrier->guard, 0);
+}
+
+
+int
+syncbarrier_destroy (struct syncbarrier *barrier)
+{
+ if (!barrier) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ pthread_cond_destroy (&barrier->cond);
+ return pthread_mutex_destroy (&barrier->guard);
+}
+
+
+static int
+__syncbarrier_wait (struct syncbarrier *barrier, int waitfor)
+{
+ struct synctask *task = NULL;
+
+ if (!barrier) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ task = synctask_get ();
+
+ while (barrier->count < waitfor) {
+ if (task) {
+ /* called within a synctask */
+ list_add_tail (&task->waitq, &barrier->waitq);
+ pthread_mutex_unlock (&barrier->guard);
+ synctask_yield (task);
+ pthread_mutex_lock (&barrier->guard);
+ } else {
+ /* called by a non-synctask */
+ pthread_cond_wait (&barrier->cond, &barrier->guard);
+ }
+ }
+
+ barrier->count = 0;
+
+ return 0;
+}
+
+
+int
+syncbarrier_wait (struct syncbarrier *barrier, int waitfor)
+{
+ int ret = 0;
+
+ pthread_mutex_lock (&barrier->guard);
+ {
+ ret = __syncbarrier_wait (barrier, waitfor);
+ }
+ pthread_mutex_unlock (&barrier->guard);
+
+ return ret;
+}
+
+
+static int
+__syncbarrier_wake (struct syncbarrier *barrier)
+{
+ struct synctask *task = NULL;
+
+ if (!barrier) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ barrier->count++;
+
+ pthread_cond_signal (&barrier->cond);
+ if (!list_empty (&barrier->waitq)) {
+ task = list_entry (barrier->waitq.next, struct synctask, waitq);
+ list_del_init (&task->waitq);
+ synctask_wake (task);
+ }
+
+ return 0;
+}
+
+
+int
+syncbarrier_wake (struct syncbarrier *barrier)
+{
+ int ret = 0;
+
+ pthread_mutex_lock (&barrier->guard);
+ {
+ ret = __syncbarrier_wake (barrier);
+ }
+ pthread_mutex_unlock (&barrier->guard);
+
+ return ret;
+}
+
+
/* FOPS */
int
syncop_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno, inode_t *inode,
- struct iatt *iatt, dict_t *xattr, struct iatt *parent)
+ struct iatt *iatt, dict_t *xdata, struct iatt *parent)
{
struct syncargs *args = NULL;
@@ -291,8 +954,9 @@ syncop_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret == 0) {
args->iatt1 = *iatt;
- args->xattr = xattr;
args->iatt2 = *parent;
+ if (xdata)
+ args->xdata = dict_ref (xdata);
}
__wake (args);
@@ -302,20 +966,22 @@ syncop_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
-syncop_lookup (xlator_t *subvol, loc_t *loc, dict_t *xattr_req,
- struct iatt *iatt, dict_t **xattr_rsp, struct iatt *parent)
+syncop_lookup (xlator_t *subvol, loc_t *loc, dict_t *xdata_req,
+ struct iatt *iatt, dict_t **xdata_rsp, struct iatt *parent)
{
struct syncargs args = {0, };
SYNCOP (subvol, (&args), syncop_lookup_cbk, subvol->fops->lookup,
- loc, xattr_req);
+ loc, xdata_req);
if (iatt)
*iatt = args.iatt1;
- if (xattr_rsp)
- *xattr_rsp = args.xattr;
if (parent)
*parent = args.iatt2;
+ if (xdata_rsp)
+ *xdata_rsp = args.xdata;
+ else if (args.xdata)
+ dict_unref (args.xdata);
errno = args.op_errno;
return args.op_ret;
@@ -331,17 +997,20 @@ entry_copy (gf_dirent_t *source)
sink->d_off = source->d_off;
sink->d_ino = source->d_ino;
sink->d_type = source->d_type;
+ sink->d_stat = source->d_stat;
+ if (source->inode)
+ sink->inode = inode_ref (source->inode);
return sink;
}
int32_t
syncop_readdirp_cbk (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- gf_dirent_t *entries)
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ gf_dirent_t *entries, dict_t *xdata)
{
struct syncargs *args = NULL;
gf_dirent_t *entry = NULL;
@@ -375,18 +1044,79 @@ syncop_readdirp_cbk (call_frame_t *frame,
int
syncop_readdirp (xlator_t *subvol,
- fd_t *fd,
- size_t size,
- off_t off,
+ fd_t *fd,
+ size_t size,
+ off_t off,
+ dict_t *dict,
gf_dirent_t *entries)
{
struct syncargs args = {0, };
SYNCOP (subvol, (&args), syncop_readdirp_cbk, subvol->fops->readdirp,
- fd, size, off);
+ fd, size, off, dict);
+
+ if (entries)
+ list_splice_init (&args.entries.list, &entries->list);
+ /* TODO: need to free all the 'args.entries' in 'else' case */
+
+ errno = args.op_errno;
+ return args.op_ret;
+
+}
+
+int32_t
+syncop_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)
+{
+ struct syncargs *args = NULL;
+ gf_dirent_t *entry = NULL;
+ gf_dirent_t *tmp = NULL;
+
+ int count = 0;
+
+ args = cookie;
+
+ INIT_LIST_HEAD (&args->entries.list);
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ if (op_ret >= 0) {
+ list_for_each_entry (entry, &entries->list, list) {
+ tmp = entry_copy (entry);
+ gf_log (this->name, GF_LOG_TRACE,
+ "adding entry=%s, count=%d",
+ tmp->d_name, count);
+ list_add_tail (&tmp->list, &(args->entries.list));
+ count++;
+ }
+ }
+
+ __wake (args);
+
+ return 0;
+
+}
+
+int
+syncop_readdir (xlator_t *subvol,
+ fd_t *fd,
+ size_t size,
+ off_t off,
+ gf_dirent_t *entries)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_readdir_cbk, subvol->fops->readdir,
+ fd, size, off, NULL);
if (entries)
list_splice_init (&args.entries.list, &entries->list);
+ /* TODO: need to free all the 'args.entries' in 'else' case */
errno = args.op_errno;
return args.op_ret;
@@ -399,7 +1129,7 @@ syncop_opendir_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- fd_t *fd)
+ fd_t *fd, dict_t *xdata)
{
struct syncargs *args = NULL;
@@ -421,17 +1151,100 @@ syncop_opendir (xlator_t *subvol,
struct syncargs args = {0, };
SYNCOP (subvol, (&args), syncop_opendir_cbk, subvol->fops->opendir,
- loc, fd);
+ loc, fd, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+
+}
+
+int
+syncop_fsyncdir_cbk (call_frame_t *frame, void* cookie, xlator_t *this,
+ int op_ret, int op_errno, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_fsyncdir (xlator_t *subvol, fd_t *fd, int datasync)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_fsyncdir_cbk, subvol->fops->fsyncdir,
+ fd, datasync, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+int
+syncop_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_removexattr (xlator_t *subvol, loc_t *loc, const char *name)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_removexattr_cbk, subvol->fops->removexattr,
+ loc, name, NULL);
errno = args.op_errno;
return args.op_ret;
+}
+
+int
+syncop_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
}
+int
+syncop_fremovexattr (xlator_t *subvol, fd_t *fd, const char *name)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_fremovexattr_cbk,
+ subvol->fops->fremovexattr, fd, name, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
int
syncop_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno)
+ int op_ret, int op_errno, dict_t *xdata)
{
struct syncargs *args = NULL;
@@ -452,7 +1265,105 @@ syncop_setxattr (xlator_t *subvol, loc_t *loc, dict_t *dict, int32_t flags)
struct syncargs args = {0, };
SYNCOP (subvol, (&args), syncop_setxattr_cbk, subvol->fops->setxattr,
- loc, dict, flags);
+ loc, dict, flags, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+int
+syncop_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
+}
+
+
+int
+syncop_fsetxattr (xlator_t *subvol, fd_t *fd, dict_t *dict, int32_t flags)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_fsetxattr_cbk, subvol->fops->fsetxattr,
+ fd, dict, flags, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+int
+syncop_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, dict_t *dict, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (op_ret >= 0)
+ args->xattr = dict_ref (dict);
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_listxattr (xlator_t *subvol, loc_t *loc, dict_t **dict)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_getxattr_cbk, subvol->fops->getxattr,
+ loc, NULL, NULL);
+
+ if (dict)
+ *dict = args.xattr;
+ else if (args.xattr)
+ dict_unref (args.xattr);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+int
+syncop_getxattr (xlator_t *subvol, loc_t *loc, dict_t **dict, const char *key)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_getxattr_cbk, subvol->fops->getxattr,
+ loc, key, NULL);
+
+ if (dict)
+ *dict = args.xattr;
+ else if (args.xattr)
+ dict_unref (args.xattr);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+int
+syncop_fgetxattr (xlator_t *subvol, fd_t *fd, dict_t **dict, const char *key)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_getxattr_cbk, subvol->fops->fgetxattr,
+ fd, key, NULL);
+
+ if (dict)
+ *dict = args.xattr;
+ else if (args.xattr)
+ dict_unref (args.xattr);
errno = args.op_errno;
return args.op_ret;
@@ -460,8 +1371,8 @@ syncop_setxattr (xlator_t *subvol, loc_t *loc, dict_t *dict, int32_t flags)
int
syncop_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- struct statvfs *buf)
+ int32_t op_ret, int32_t op_errno,
+ struct statvfs *buf, dict_t *xdata)
{
struct syncargs *args = NULL;
@@ -488,7 +1399,7 @@ syncop_statfs (xlator_t *subvol, loc_t *loc, struct statvfs *buf)
struct syncargs args = {0, };
SYNCOP (subvol, (&args), syncop_statfs_cbk, subvol->fops->statfs,
- loc);
+ loc, NULL);
if (buf)
*buf = args.statvfs_buf;
@@ -500,7 +1411,7 @@ syncop_statfs (xlator_t *subvol, loc_t *loc, struct statvfs *buf)
int
syncop_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno,
- struct iatt *preop, struct iatt *postop)
+ struct iatt *preop, struct iatt *postop, dict_t *xdata)
{
struct syncargs *args = NULL;
@@ -527,7 +1438,26 @@ syncop_setattr (xlator_t *subvol, loc_t *loc, struct iatt *iatt, int valid,
struct syncargs args = {0, };
SYNCOP (subvol, (&args), syncop_setattr_cbk, subvol->fops->setattr,
- loc, iatt, valid);
+ loc, iatt, valid, NULL);
+
+ if (preop)
+ *preop = args.iatt1;
+ if (postop)
+ *postop = args.iatt2;
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+
+int
+syncop_fsetattr (xlator_t *subvol, fd_t *fd, struct iatt *iatt, int valid,
+ struct iatt *preop, struct iatt *postop)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_setattr_cbk, subvol->fops->fsetattr,
+ fd, iatt, valid, NULL);
if (preop)
*preop = args.iatt1;
@@ -538,3 +1468,770 @@ syncop_setattr (xlator_t *subvol, loc_t *loc, struct iatt *iatt, int valid,
return args.op_ret;
}
+
+int32_t
+syncop_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)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_open (xlator_t *subvol, loc_t *loc, int32_t flags, fd_t *fd)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_open_cbk, subvol->fops->open,
+ loc, flags, fd, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+
+}
+
+
+int32_t
+syncop_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)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ INIT_LIST_HEAD (&args->entries.list);
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ if (args->op_ret >= 0) {
+ if (iobref)
+ args->iobref = iobref_ref (iobref);
+ args->vector = iov_dup (vector, count);
+ args->count = count;
+ }
+
+ __wake (args);
+
+ return 0;
+
+}
+
+int
+syncop_readv (xlator_t *subvol, fd_t *fd, size_t size, off_t off,
+ uint32_t flags, struct iovec **vector, int *count,
+ struct iobref **iobref)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_readv_cbk, subvol->fops->readv,
+ fd, size, off, flags, NULL);
+
+ if (args.op_ret < 0)
+ goto out;
+
+ if (vector)
+ *vector = args.vector;
+ else
+ GF_FREE (args.vector);
+
+ if (count)
+ *count = args.count;
+
+ /* Do we need a 'ref' here? */
+ if (iobref)
+ *iobref = args.iobref;
+ else if (args.iobref)
+ iobref_unref (args.iobref);
+
+out:
+ errno = args.op_errno;
+ return args.op_ret;
+
+}
+
+int
+syncop_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_writev (xlator_t *subvol, fd_t *fd, const struct iovec *vector,
+ int32_t count, off_t offset, struct iobref *iobref,
+ uint32_t flags)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_writev_cbk, subvol->fops->writev,
+ fd, (struct iovec *) vector, count, offset, flags, iobref,
+ NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+int syncop_write (xlator_t *subvol, fd_t *fd, const char *buf, int size,
+ off_t offset, struct iobref *iobref, uint32_t flags)
+{
+ struct syncargs args = {0,};
+ struct iovec vec = {0,};
+
+ vec.iov_len = size;
+ vec.iov_base = (void *)buf;
+
+ SYNCOP (subvol, (&args), syncop_writev_cbk, subvol->fops->writev,
+ fd, &vec, 1, offset, flags, iobref, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+
+int
+syncop_close (fd_t *fd)
+{
+ if (fd)
+ fd_unref (fd);
+ return 0;
+}
+
+int32_t
+syncop_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)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ if (buf)
+ args->iatt1 = *buf;
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_create (xlator_t *subvol, loc_t *loc, int32_t flags, mode_t mode,
+ fd_t *fd, dict_t *xdata, struct iatt *iatt)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_create_cbk, subvol->fops->create,
+ loc, flags, mode, 0, fd, xdata);
+
+ errno = args.op_errno;
+ if (iatt)
+ *iatt = args.iatt1;
+
+ return args.op_ret;
+
+}
+
+int
+syncop_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_unlink (xlator_t *subvol, loc_t *loc)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_unlink_cbk, subvol->fops->unlink, loc,
+ 0, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+int
+syncop_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_rmdir (xlator_t *subvol, loc_t *loc)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_rmdir_cbk, subvol->fops->rmdir, loc,
+ 0, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+
+int
+syncop_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)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
+}
+
+
+int
+syncop_link (xlator_t *subvol, loc_t *oldloc, loc_t *newloc)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_link_cbk, subvol->fops->link,
+ oldloc, newloc, NULL);
+
+ errno = args.op_errno;
+
+ return args.op_ret;
+}
+
+
+int
+syncop_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)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
+}
+
+
+int
+syncop_rename (xlator_t *subvol, loc_t *oldloc, loc_t *newloc)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_rename_cbk, subvol->fops->rename,
+ oldloc, newloc, NULL);
+
+ errno = args.op_errno;
+
+ return args.op_ret;
+}
+
+
+int
+syncop_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_ftruncate (xlator_t *subvol, fd_t *fd, off_t offset)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_ftruncate_cbk, subvol->fops->ftruncate,
+ fd, offset, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+int
+syncop_truncate (xlator_t *subvol, loc_t *loc, off_t offset)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_ftruncate_cbk, subvol->fops->truncate,
+ loc, offset, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+int
+syncop_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)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
+
+}
+
+int
+syncop_fsync (xlator_t *subvol, fd_t *fd, int dataonly)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_fsync_cbk, subvol->fops->fsync,
+ fd, dataonly, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+
+}
+
+
+int
+syncop_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
+
+}
+
+int
+syncop_flush (xlator_t *subvol, fd_t *fd)
+{
+ struct syncargs args = {0};
+
+ SYNCOP (subvol, (&args), syncop_flush_cbk, subvol->fops->flush,
+ fd, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+
+}
+
+int
+syncop_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *stbuf, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (op_ret == 0)
+ args->iatt1 = *stbuf;
+
+ __wake (args);
+
+ return 0;
+
+}
+
+int
+syncop_fstat (xlator_t *subvol, fd_t *fd, struct iatt *stbuf)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_fstat_cbk, subvol->fops->fstat,
+ fd, NULL);
+
+ if (stbuf)
+ *stbuf = args.iatt1;
+
+ errno = args.op_errno;
+ return args.op_ret;
+
+}
+
+int
+syncop_stat (xlator_t *subvol, loc_t *loc, struct iatt *stbuf)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_fstat_cbk, subvol->fops->stat,
+ loc, NULL);
+
+ if (stbuf)
+ *stbuf = args.iatt1;
+
+ errno = args.op_errno;
+ return args.op_ret;
+
+}
+
+int32_t
+syncop_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)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (buf)
+ args->iatt1 = *buf;
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_symlink (xlator_t *subvol, loc_t *loc, const char *newpath, dict_t *dict,
+ struct iatt *iatt)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_symlink_cbk, subvol->fops->symlink,
+ newpath, loc, 0, dict);
+
+ errno = args.op_errno;
+ if (iatt)
+ *iatt = args.iatt1;
+
+ return args.op_ret;
+
+}
+
+int
+syncop_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, const char *path,
+ struct iatt *stbuf, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ if ((op_ret != -1) && path)
+ args->buffer = gf_strdup (path);
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_readlink (xlator_t *subvol, loc_t *loc, char **buffer, size_t size)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_readlink_cbk, subvol->fops->readlink,
+ loc, size, NULL);
+
+ if (buffer)
+ *buffer = args.buffer;
+ else GF_FREE (args.buffer);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+int
+syncop_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)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ if (buf)
+ args->iatt1 = *buf;
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_mknod (xlator_t *subvol, loc_t *loc, mode_t mode, dev_t rdev,
+ dict_t *dict, struct iatt *iatt)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_mknod_cbk, subvol->fops->mknod,
+ loc, mode, rdev, 0, dict);
+
+ errno = args.op_errno;
+ if (iatt)
+ *iatt = args.iatt1;
+
+ return args.op_ret;
+
+}
+
+
+int
+syncop_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)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (buf)
+ args->iatt1 = *buf;
+
+ __wake (args);
+
+ return 0;
+}
+
+
+int
+syncop_mkdir (xlator_t *subvol, loc_t *loc, mode_t mode, dict_t *dict,
+ struct iatt *iatt)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_mkdir_cbk, subvol->fops->mkdir,
+ loc, mode, 0, dict);
+
+ errno = args.op_errno;
+ if (iatt)
+ *iatt = args.iatt1;
+
+ return args.op_ret;
+
+}
+
+int
+syncop_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_access (xlator_t *subvol, loc_t *loc, int32_t mask)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_access_cbk, subvol->fops->access,
+ loc, mask, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+
+int
+syncop_fallocate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_fallocate(xlator_t *subvol, fd_t *fd, int32_t keep_size, off_t offset,
+ size_t len)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_fallocate_cbk, subvol->fops->fallocate,
+ fd, keep_size, offset, len, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+
+int
+syncop_discard_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_discard(xlator_t *subvol, fd_t *fd, off_t offset, size_t len)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_discard_cbk, subvol->fops->discard,
+ fd, offset, len, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+int
+syncop_zerofill_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_zerofill(xlator_t *subvol, fd_t *fd, off_t offset, size_t len)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_zerofill_cbk, subvol->fops->zerofill,
+ fd, offset, len, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+
+int
+syncop_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, struct gf_flock *flock,
+ dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (flock)
+ args->flock = *flock;
+ __wake (args);
+
+ return 0;
+}
+
+
+int
+syncop_lk (xlator_t *subvol, fd_t *fd, int cmd, struct gf_flock *flock)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_lk_cbk, subvol->fops->lk,
+ fd, cmd, flock, NULL);
+
+ errno = args.op_errno;
+ *flock = args.flock;
+
+ return args.op_ret;
+}
diff --git a/libglusterfs/src/syncop.h b/libglusterfs/src/syncop.h
index 12d97010a..f790981f0 100644
--- a/libglusterfs/src/syncop.h
+++ b/libglusterfs/src/syncop.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
#ifndef _SYNCOP_H
@@ -30,46 +21,112 @@
#include <pthread.h>
#include <ucontext.h>
+#define SYNCENV_PROC_MAX 16
+#define SYNCENV_PROC_MIN 2
+#define SYNCPROC_IDLE_TIME 600
+
+/*
+ * Flags for syncopctx valid elements
+ */
+#define SYNCOPCTX_UID 0x00000001
+#define SYNCOPCTX_GID 0x00000002
+#define SYNCOPCTX_GROUPS 0x00000004
struct synctask;
+struct syncproc;
struct syncenv;
-typedef int (*synctask_cbk_t) (int ret, void *opaque);
+typedef int (*synctask_cbk_t) (int ret, call_frame_t *frame, void *opaque);
typedef int (*synctask_fn_t) (void *opaque);
+typedef enum {
+ SYNCTASK_INIT = 0,
+ SYNCTASK_RUN,
+ SYNCTASK_SUSPEND,
+ SYNCTASK_WAIT,
+ SYNCTASK_DONE,
+ SYNCTASK_ZOMBIE,
+} synctask_state_t;
+
/* for one sequential execution of @syncfn */
struct synctask {
struct list_head all_tasks;
struct syncenv *env;
xlator_t *xl;
+ call_frame_t *frame;
+ call_frame_t *opframe;
synctask_cbk_t synccbk;
synctask_fn_t syncfn;
+ synctask_state_t state;
void *opaque;
void *stack;
- int complete;
+ int woken;
+ int slept;
+ int ret;
+
+ uid_t uid;
+ gid_t gid;
ucontext_t ctx;
+ struct syncproc *proc;
+
+ pthread_mutex_t mutex; /* for synchronous spawning of synctask */
+ pthread_cond_t cond;
+ int done;
+
+ struct list_head waitq; /* can wait only "once" at a time */
};
-/* hosts the scheduler thread and framework for executing synctasks */
-struct syncenv {
+
+struct syncproc {
pthread_t processor;
+ ucontext_t sched;
+ struct syncenv *env;
struct synctask *current;
+};
+
+/* hosts the scheduler thread and framework for executing synctasks */
+struct syncenv {
+ struct syncproc proc[SYNCENV_PROC_MAX];
+ int procs;
struct list_head runq;
+ int runcount;
struct list_head waitq;
+ int waitcount;
+
+ int procmin;
+ int procmax;
pthread_mutex_t mutex;
pthread_cond_t cond;
- ucontext_t sched;
size_t stacksize;
};
+struct synclock {
+ pthread_mutex_t guard; /* guard the remaining members, pair @cond */
+ pthread_cond_t cond; /* waiting non-synctasks */
+ struct list_head waitq; /* waiting synctasks */
+ gf_boolean_t lock; /* _gf_true or _gf_false, lock status */
+ struct synctask *owner; /* NULL if current owner is not a synctask */
+};
+typedef struct synclock synclock_t;
+
+
+struct syncbarrier {
+ pthread_mutex_t guard; /* guard the remaining members, pair @cond */
+ pthread_cond_t cond; /* waiting non-synctasks */
+ struct list_head waitq; /* waiting synctasks */
+ int count; /* count the number of wakes */
+};
+typedef struct syncbarrier syncbarrier_t;
+
+
struct syncargs {
int op_ret;
int op_errno;
@@ -78,104 +135,278 @@ struct syncargs {
dict_t *xattr;
gf_dirent_t entries;
struct statvfs statvfs_buf;
+ struct iovec *vector;
+ int count;
+ struct iobref *iobref;
+ char *buffer;
+ dict_t *xdata;
+ struct gf_flock flock;
+
+ /* some more _cbk needs */
+ uuid_t uuid;
+ char *errstr;
+ dict_t *dict;
+ pthread_mutex_t lock_dict;
+
+ syncbarrier_t barrier;
/* do not touch */
+ struct synctask *task;
pthread_mutex_t mutex;
- char complete;
pthread_cond_t cond;
- struct synctask *task;
+ int done;
};
+struct syncopctx {
+ unsigned int valid; /* valid flags for elements that are set */
+ uid_t uid;
+ gid_t gid;
+ int grpsize;
+ int ngrps;
+ gid_t *groups;
+};
-#define __yawn(args) do { \
- struct synctask *task = NULL; \
- \
- task = synctask_get (); \
- if (task) { \
- args->task = task; \
- synctask_yawn (task); \
- } else { \
- pthread_mutex_init (&args->mutex, NULL); \
- pthread_cond_init (&args->cond, NULL); \
- } \
-} while (0)
-
-
-#define __yield(args) do { \
- if (args->task) { \
- synctask_yield (args->task); \
- } else { \
- pthread_mutex_lock (&args->mutex); \
- { \
- while (!args->complete) \
- pthread_cond_wait (&args->cond, \
- &args->mutex); \
- } \
- pthread_mutex_unlock (&args->mutex); \
- \
- pthread_mutex_destroy (&args->mutex); \
- pthread_cond_destroy (&args->cond); \
- } \
-} while (0)
-
-
-#define __wake(args) do { \
- if (args->task) { \
- synctask_wake (args->task); \
- } else { \
- pthread_mutex_lock (&args->mutex); \
- { \
- args->complete = 1; \
- pthread_cond_broadcast (&args->cond); \
- } \
- pthread_mutex_unlock (&args->mutex); \
- } \
-} while (0)
+#define __yawn(args) do { \
+ args->task = synctask_get (); \
+ if (args->task) \
+ break; \
+ pthread_mutex_init (&args->mutex, NULL); \
+ pthread_cond_init (&args->cond, NULL); \
+ args->done = 0; \
+ } while (0)
+
+
+#define __wake(args) do { \
+ if (args->task) { \
+ synctask_wake (args->task); \
+ } else { \
+ pthread_mutex_lock (&args->mutex); \
+ { \
+ args->done = 1; \
+ pthread_cond_signal (&args->cond); \
+ } \
+ pthread_mutex_unlock (&args->mutex); \
+ } \
+ } while (0)
+
+
+#define __yield(args) do { \
+ if (args->task) { \
+ synctask_yield (args->task); \
+ } else { \
+ pthread_mutex_lock (&args->mutex); \
+ { \
+ while (!args->done) \
+ pthread_cond_wait (&args->cond, \
+ &args->mutex); \
+ } \
+ pthread_mutex_unlock (&args->mutex); \
+ pthread_mutex_destroy (&args->mutex); \
+ pthread_cond_destroy (&args->cond); \
+ } \
+ } while (0)
#define SYNCOP(subvol, stb, cbk, op, params ...) do { \
- call_frame_t *frame = NULL; \
+ struct synctask *task = NULL; \
+ call_frame_t *frame = NULL; \
+ \
+ task = synctask_get (); \
+ stb->task = task; \
+ if (task) \
+ frame = task->opframe; \
+ else \
+ frame = syncop_create_frame (THIS); \
+ \
+ if (task) { \
+ frame->root->uid = task->uid; \
+ frame->root->gid = task->gid; \
+ } \
+ \
+ __yawn (stb); \
\
- frame = syncop_create_frame (); \
+ STACK_WIND_COOKIE (frame, cbk, (void *)stb, subvol, \
+ op, params); \
\
- __yawn (stb); \
- STACK_WIND_COOKIE (frame, cbk, (void *)stb, subvol, op, params);\
- __yield (stb); \
-} while (0)
+ __yield (stb); \
+ if (task) \
+ STACK_RESET (frame->root); \
+ else \
+ STACK_DESTROY (frame->root); \
+ } while (0)
-#define SYNCENV_DEFAULT_STACKSIZE (16 * 1024)
+#define SYNCENV_DEFAULT_STACKSIZE (2 * 1024 * 1024)
-struct syncenv * syncenv_new ();
+struct syncenv * syncenv_new (size_t stacksize, int procmin, int procmax);
void syncenv_destroy (struct syncenv *);
+void syncenv_scale (struct syncenv *env);
-int synctask_new (struct syncenv *, synctask_fn_t, synctask_cbk_t, void *);
-void synctask_zzzz (struct synctask *task);
-void synctask_yawn (struct synctask *task);
+int synctask_new (struct syncenv *, synctask_fn_t, synctask_cbk_t, call_frame_t* frame, void *);
+struct synctask *synctask_create (struct syncenv *, synctask_fn_t,
+ synctask_cbk_t, call_frame_t *, void *);
+int synctask_join (struct synctask *task);
void synctask_wake (struct synctask *task);
void synctask_yield (struct synctask *task);
+void synctask_waitfor (struct synctask *task, int count);
+
+#define synctask_barrier_init(args) syncbarrier_init (&args->barrier)
+#define synctask_barrier_wait(args, n) syncbarrier_wait (&args->barrier, n)
+#define synctask_barrier_wake(args) syncbarrier_wake (&args->barrier)
+
+int synctask_setid (struct synctask *task, uid_t uid, gid_t gid);
+#define SYNCTASK_SETID(uid, gid) synctask_setid (synctask_get(), uid, gid);
+
+int syncopctx_setfsuid (void *uid);
+int syncopctx_setfsgid (void *gid);
+int syncopctx_setfsgroups (int count, const void *groups);
+
+static inline call_frame_t *
+syncop_create_frame (xlator_t *this)
+{
+ call_frame_t *frame = NULL;
+ int ngrps = -1;
+ struct syncopctx *opctx = NULL;
+
+ frame = create_frame (this, this->ctx->pool);
+ if (!frame)
+ return NULL;
+
+ frame->root->pid = getpid ();
+
+ opctx = syncopctx_getctx ();
+ if (opctx && (opctx->valid & SYNCOPCTX_UID))
+ frame->root->uid = opctx->uid;
+ else
+ frame->root->uid = geteuid ();
+
+ if (opctx && (opctx->valid & SYNCOPCTX_GID))
+ frame->root->gid = opctx->gid;
+ else
+ frame->root->gid = getegid ();
+
+ if (opctx && (opctx->valid & SYNCOPCTX_GROUPS)) {
+ ngrps = opctx->ngrps;
+
+ if (ngrps != 0 && opctx->groups != NULL) {
+ if (call_stack_alloc_groups (frame->root, ngrps) != 0) {
+ STACK_DESTROY (frame->root);
+ return NULL;
+ }
+
+ memcpy (frame->root->groups, opctx->groups,
+ (sizeof (gid_t) * ngrps));
+ }
+ }
+ else {
+ ngrps = getgroups (0, 0);
+ if (ngrps < 0) {
+ STACK_DESTROY (frame->root);
+ return NULL;
+ }
+
+ if (call_stack_alloc_groups (frame->root, ngrps) != 0) {
+ STACK_DESTROY (frame->root);
+ return NULL;
+ }
+
+ if (getgroups (ngrps, frame->root->groups) < 0) {
+ STACK_DESTROY (frame->root);
+ return NULL;
+ }
+ }
+
+ return frame;
+}
+
+int synclock_init (synclock_t *lock);
+int synclock_destory (synclock_t *lock);
+int synclock_lock (synclock_t *lock);
+int synclock_trylock (synclock_t *lock);
+int synclock_unlock (synclock_t *lock);
+
+
+int syncbarrier_init (syncbarrier_t *barrier);
+int syncbarrier_wait (syncbarrier_t *barrier, int waitfor);
+int syncbarrier_wake (syncbarrier_t *barrier);
+int syncbarrier_destroy (syncbarrier_t *barrier);
int syncop_lookup (xlator_t *subvol, loc_t *loc, dict_t *xattr_req,
/* out */
struct iatt *iatt, dict_t **xattr_rsp, struct iatt *parent);
int syncop_readdirp (xlator_t *subvol, fd_t *fd, size_t size, off_t off,
+ dict_t *dict,
/* out */
gf_dirent_t *entries);
-int
-syncop_opendir (xlator_t *subvol,
- loc_t *loc,
- fd_t *fd);
+int syncop_readdir (xlator_t *subvol, fd_t *fd, size_t size, off_t off,
+ gf_dirent_t *entries);
+
+int syncop_opendir (xlator_t *subvol, loc_t *loc, fd_t *fd);
int syncop_setattr (xlator_t *subvol, loc_t *loc, struct iatt *iatt, int valid,
/* out */
struct iatt *preop, struct iatt *postop);
-int
-syncop_statfs (xlator_t *subvol, loc_t *loc, struct statvfs *buf);
+int syncop_fsetattr (xlator_t *subvol, fd_t *fd, struct iatt *iatt, int valid,
+ /* out */
+ struct iatt *preop, struct iatt *postop);
-int
-syncop_setxattr (xlator_t *subvol, loc_t *loc, dict_t *dict, int32_t flags);
+int syncop_statfs (xlator_t *subvol, loc_t *loc, struct statvfs *buf);
+
+int syncop_setxattr (xlator_t *subvol, loc_t *loc, dict_t *dict, int32_t flags);
+int syncop_fsetxattr (xlator_t *subvol, fd_t *fd, dict_t *dict, int32_t flags);
+int syncop_listxattr (xlator_t *subvol, loc_t *loc, dict_t **dict);
+int syncop_getxattr (xlator_t *xl, loc_t *loc, dict_t **dict, const char *key);
+int syncop_fgetxattr (xlator_t *xl, fd_t *fd, dict_t **dict, const char *key);
+int syncop_removexattr (xlator_t *subvol, loc_t *loc, const char *name);
+int syncop_fremovexattr (xlator_t *subvol, fd_t *fd, const char *name);
+
+int syncop_create (xlator_t *subvol, loc_t *loc, int32_t flags, mode_t mode,
+ fd_t *fd, dict_t *dict, struct iatt *iatt);
+int syncop_open (xlator_t *subvol, loc_t *loc, int32_t flags, fd_t *fd);
+int syncop_close (fd_t *fd);
+
+int syncop_write (xlator_t *subvol, fd_t *fd, const char *buf, int size,
+ off_t offset, struct iobref *iobref, uint32_t flags);
+int syncop_writev (xlator_t *subvol, fd_t *fd, const struct iovec *vector,
+ int32_t count, off_t offset, struct iobref *iobref,
+ uint32_t flags);
+int syncop_readv (xlator_t *subvol, fd_t *fd, size_t size, off_t off,
+ uint32_t flags,
+ /* out */
+ struct iovec **vector, int *count, struct iobref **iobref);
+
+int syncop_ftruncate (xlator_t *subvol, fd_t *fd, off_t offset);
+int syncop_truncate (xlator_t *subvol, loc_t *loc, off_t offset);
+
+int syncop_unlink (xlator_t *subvol, loc_t *loc);
+int syncop_rmdir (xlator_t *subvol, loc_t *loc);
+
+int syncop_fsync (xlator_t *subvol, fd_t *fd, int dataonly);
+int syncop_flush (xlator_t *subvol, fd_t *fd);
+int syncop_fstat (xlator_t *subvol, fd_t *fd, struct iatt *stbuf);
+int syncop_stat (xlator_t *subvol, loc_t *loc, struct iatt *stbuf);
+
+int syncop_symlink (xlator_t *subvol, loc_t *loc, const char *newpath,
+ dict_t *dict, struct iatt *iatt);
+int syncop_readlink (xlator_t *subvol, loc_t *loc, char **buffer, size_t size);
+int syncop_mknod (xlator_t *subvol, loc_t *loc, mode_t mode, dev_t rdev,
+ dict_t *dict, struct iatt *iatt);
+int syncop_mkdir (xlator_t *subvol, loc_t *loc, mode_t mode, dict_t *dict,
+ struct iatt *iatt);
+int syncop_link (xlator_t *subvol, loc_t *oldloc, loc_t *newloc);
+int syncop_fsyncdir (xlator_t *subvol, fd_t *fd, int datasync);
+int syncop_access (xlator_t *subvol, loc_t *loc, int32_t mask);
+int syncop_fallocate(xlator_t *subvol, fd_t *fd, int32_t keep_size, off_t offset,
+ size_t len);
+int syncop_discard(xlator_t *subvol, fd_t *fd, off_t offset, size_t len);
+
+int syncop_zerofill(xlator_t *subvol, fd_t *fd, off_t offset, size_t len);
+
+int syncop_rename (xlator_t *subvol, loc_t *oldloc, loc_t *newloc);
+
+int syncop_lk (xlator_t *subvol, fd_t *fd, int cmd, struct gf_flock *flock);
#endif /* _SYNCOP_H */
diff --git a/libglusterfs/src/syscall.c b/libglusterfs/src/syscall.c
index c0855f1d1..e8954cc23 100644
--- a/libglusterfs/src/syscall.c
+++ b/libglusterfs/src/syscall.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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
@@ -64,14 +55,14 @@ sys_readdir (DIR *dir)
}
-ssize_t
+ssize_t
sys_readlink (const char *path, char *buf, size_t bufsiz)
{
return readlink (path, buf, bufsiz);
}
-int
+int
sys_closedir (DIR *dir)
{
return closedir (dir);
@@ -85,28 +76,31 @@ sys_mknod (const char *pathname, mode_t mode, dev_t dev)
}
-int
+int
sys_mkdir (const char *pathname, mode_t mode)
{
return mkdir (pathname, mode);
}
-int
+int
sys_unlink (const char *pathname)
{
+#ifdef GF_SOLARIS_HOST_OS
+ return solaris_unlink (pathname);
+#endif
return unlink (pathname);
}
-int
+int
sys_rmdir (const char *pathname)
{
return rmdir (pathname);
}
-int
+int
sys_symlink (const char *oldpath, const char *newpath)
{
return symlink (oldpath, newpath);
@@ -116,11 +110,14 @@ sys_symlink (const char *oldpath, const char *newpath)
int
sys_rename (const char *oldpath, const char *newpath)
{
+#ifdef GF_SOLARIS_HOST_OS
+ return solaris_rename (oldpath, newpath);
+#endif
return rename (oldpath, newpath);
}
-int
+int
sys_link (const char *oldpath, const char *newpath)
{
return link (oldpath, newpath);
@@ -141,7 +138,7 @@ sys_fchmod (int fd, mode_t mode)
}
-int
+int
sys_chown (const char *path, uid_t owner, gid_t group)
{
return chown (path, owner, group);
@@ -162,21 +159,21 @@ sys_lchown (const char *path, uid_t owner, gid_t group)
}
-int
+int
sys_truncate (const char *path, off_t length)
{
return truncate (path, length);
}
-int
+int
sys_ftruncate (int fd, off_t length)
{
return ftruncate (fd, length);
}
-int
+int
sys_utimes (const char *filename, const struct timeval times[2])
{
return utimes (filename, times);
@@ -211,7 +208,7 @@ sys_read (int fd, void *buf, size_t count)
}
-ssize_t
+ssize_t
sys_write (int fd, const void *buf, size_t count)
{
return write (fd, buf, count);
@@ -232,21 +229,26 @@ sys_statvfs (const char *path, struct statvfs *buf)
}
-int
+int
sys_close (int fd)
{
- return close (fd);
+ int ret = -1;
+
+ if (fd >= 0)
+ ret = close (fd);
+
+ return ret;
}
-int
+int
sys_fsync (int fd)
{
return fsync (fd);
}
-int
+int
sys_fdatasync (int fd)
{
#ifdef HAVE_FDATASYNC
@@ -257,44 +259,44 @@ sys_fdatasync (int fd)
}
-int
-sys_lsetxattr (const char *path, const char *name, const void *value,
- size_t size, int flags)
+int
+sys_lsetxattr (const char *path, const char *name, const void *value,
+ size_t size, int flags)
{
-
-#ifdef GF_LINUX_HOST_OS
+
+#if defined(GF_LINUX_HOST_OS) || defined(__NetBSD__)
return lsetxattr (path, name, value, size, flags);
#endif
#ifdef GF_BSD_HOST_OS
- return extattr_set_link (path, EXTATTR_NAMESPACE_USER,
+ return extattr_set_link (path, EXTATTR_NAMESPACE_USER,
name, value, size);
#endif
-
+
#ifdef GF_SOLARIS_HOST_OS
return solaris_setxattr (path, name, value, size, flags);
#endif
#ifdef GF_DARWIN_HOST_OS
- return setxattr (path, name, value, size, 0,
+ return setxattr (path, name, value, size, 0,
flags|XATTR_NOFOLLOW);
#endif
-
+
}
ssize_t
-sys_llistxattr (const char *path, char *list, size_t size)
+sys_llistxattr (const char *path, char *list, size_t size)
{
-
-#ifdef GF_LINUX_HOST_OS
+
+#if defined(GF_LINUX_HOST_OS) || defined(__NetBSD__)
return llistxattr (path, list, size);
#endif
#ifdef GF_BSD_HOST_OS
return extattr_list_link (path, EXTATTR_NAMESPACE_USER, list, size);
#endif
-
+
#ifdef GF_SOLARIS_HOST_OS
return solaris_listxattr (path, list, size);
#endif
@@ -302,23 +304,23 @@ sys_llistxattr (const char *path, char *list, size_t size)
#ifdef GF_DARWIN_HOST_OS
return listxattr (path, list, size, XATTR_NOFOLLOW);
#endif
-
+
}
ssize_t
-sys_lgetxattr (const char *path, const char *name, void *value, size_t size)
+sys_lgetxattr (const char *path, const char *name, void *value, size_t size)
{
-
-#ifdef GF_LINUX_HOST_OS
+
+#if defined(GF_LINUX_HOST_OS) || defined(__NetBSD__)
return lgetxattr (path, name, value, size);
#endif
#ifdef GF_BSD_HOST_OS
- return extattr_get_link (path, EXTATTR_NAMESPACE_USER, name, value,
+ return extattr_get_link (path, EXTATTR_NAMESPACE_USER, name, value,
size);
#endif
-
+
#ifdef GF_SOLARIS_HOST_OS
return solaris_getxattr (path, name, value, size);
#endif
@@ -330,19 +332,19 @@ sys_lgetxattr (const char *path, const char *name, void *value, size_t size)
}
-ssize_t
-sys_fgetxattr (int filedes, const char *name, void *value, size_t size)
+ssize_t
+sys_fgetxattr (int filedes, const char *name, void *value, size_t size)
{
-
-#ifdef GF_LINUX_HOST_OS
+
+#if defined(GF_LINUX_HOST_OS) || defined(__NetBSD__)
return fgetxattr (filedes, name, value, size);
#endif
#ifdef GF_BSD_HOST_OS
- return extattr_get_fd (filedes, EXTATTR_NAMESPACE_USER, name,
+ return extattr_get_fd (filedes, EXTATTR_NAMESPACE_USER, name,
value, size);
#endif
-
+
#ifdef GF_SOLARIS_HOST_OS
return solaris_fgetxattr (filedes, name, value, size);
#endif
@@ -354,20 +356,46 @@ sys_fgetxattr (int filedes, const char *name, void *value, size_t size)
}
-int
-sys_fsetxattr (int filedes, const char *name, const void *value,
+int
+sys_fremovexattr (int filedes, const char *name)
+{
+
+#if defined(GF_LINUX_HOST_OS) || defined(__NetBSD__)
+ return fremovexattr (filedes, name);
+#endif
+
+ errno = ENOSYS;
+ return -1;
+#if 0 /* TODO: to port to other OSes, fill in each of below */
+#ifdef GF_BSD_HOST_OS
+ return extattr_remove_fd (filedes, EXTATTR_NAMESPACE_USER, name);
+#endif
+
+#ifdef GF_SOLARIS_HOST_OS
+ return solaris_fremovexattr (filedes, name);
+#endif
+
+#ifdef GF_DARWIN_HOST_OS
+ return fremovexattr (filedes, name, 0);
+#endif
+#endif
+}
+
+
+int
+sys_fsetxattr (int filedes, const char *name, const void *value,
size_t size, int flags)
{
-#ifdef GF_LINUX_HOST_OS
+#if defined(GF_LINUX_HOST_OS) || defined(__NetBSD__)
return fsetxattr (filedes, name, value, size, flags);
#endif
#ifdef GF_BSD_HOST_OS
- return extattr_set_fd (filedes, EXTATTR_NAMESPACE_USER, name,
+ return extattr_set_fd (filedes, EXTATTR_NAMESPACE_USER, name,
value, size);
#endif
-
+
#ifdef GF_SOLARIS_HOST_OS
return solaris_fsetxattr (filedes, name, value, size, flags);
#endif
@@ -379,11 +407,11 @@ sys_fsetxattr (int filedes, const char *name, const void *value,
}
-ssize_t
-sys_flistxattr (int filedes, char *list, size_t size)
+ssize_t
+sys_flistxattr (int filedes, char *list, size_t size)
{
-
-#ifdef GF_LINUX_HOST_OS
+
+#if defined(GF_LINUX_HOST_OS) || defined(__NetBSD__)
return flistxattr (filedes, list, size);
#endif
@@ -402,18 +430,18 @@ sys_flistxattr (int filedes, char *list, size_t size)
}
-int
+int
sys_lremovexattr (const char *path, const char *name)
{
-
-#ifdef GF_LINUX_HOST_OS
+
+#if defined(GF_LINUX_HOST_OS) || defined(__NetBSD__)
return lremovexattr (path, name);
#endif
#ifdef GF_BSD_HOST_OS
return extattr_delete_link (path, EXTATTR_NAMESPACE_USER, name);
#endif
-
+
#ifdef GF_SOLARIS_HOST_OS
return solaris_removexattr (path, name);
#endif
@@ -425,8 +453,31 @@ sys_lremovexattr (const char *path, const char *name)
}
-int
+int
sys_access (const char *pathname, int mode)
{
return access (pathname, mode);
}
+
+
+int
+sys_fallocate(int fd, int mode, off_t offset, off_t len)
+{
+#ifdef HAVE_FALLOCATE
+ return fallocate(fd, mode, offset, len);
+#endif
+
+#ifdef HAVE_POSIX_FALLOCATE
+ if (mode) {
+ /* keep size not supported */
+ errno = EOPNOTSUPP;
+ return -1;
+ }
+
+ return posix_fallocate(fd, offset, len);
+#endif
+
+ errno = ENOSYS;
+ return -1;
+}
+
diff --git a/libglusterfs/src/syscall.h b/libglusterfs/src/syscall.h
index de1044cdb..f1c9f58c3 100644
--- a/libglusterfs/src/syscall.h
+++ b/libglusterfs/src/syscall.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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 __SYSCALL_H__
@@ -140,9 +131,14 @@ int
sys_lremovexattr (const char *path, const char *name);
int
+sys_fremovexattr (int filedes, const char *name);
+
+int
sys_access (const char *pathname, int mode);
int
sys_ftruncate (int fd, off_t length);
+int sys_fallocate(int fd, int mode, off_t offset, off_t len);
+
#endif /* __SYSCALL_H__ */
diff --git a/libglusterfs/src/timer.c b/libglusterfs/src/timer.c
index b926644ff..a059cc212 100644
--- a/libglusterfs/src/timer.c
+++ b/libglusterfs/src/timer.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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.
*/
#ifndef _CONFIG_H
@@ -26,42 +17,38 @@
#include "logging.h"
#include "common-utils.h"
#include "globals.h"
-
-#define TS(tv) ((((unsigned long long) tv.tv_sec) * 1000000) + (tv.tv_usec))
+#include "timespec.h"
gf_timer_t *
gf_timer_call_after (glusterfs_ctx_t *ctx,
- struct timeval delta,
+ struct timespec delta,
gf_timer_cbk_t callbk,
void *data)
{
gf_timer_registry_t *reg = NULL;
gf_timer_t *event = NULL;
gf_timer_t *trav = NULL;
- unsigned long long at = 0L;
-
+ uint64_t at = 0;
+
if (ctx == NULL)
{
- gf_log ("timer", GF_LOG_ERROR, "invalid argument");
+ gf_log_callingfn ("timer", GF_LOG_ERROR, "invalid argument");
return NULL;
}
reg = gf_timer_registry_init (ctx);
if (!reg) {
- gf_log ("timer", GF_LOG_ERROR, "!reg");
+ gf_log_callingfn ("timer", GF_LOG_ERROR, "!reg");
return NULL;
}
event = GF_CALLOC (1, sizeof (*event), gf_common_mt_gf_timer_t);
if (!event) {
- gf_log ("timer", GF_LOG_CRITICAL, "Not enough memory");
return NULL;
}
- gettimeofday (&event->at, NULL);
- event->at.tv_usec = ((event->at.tv_usec + delta.tv_usec) % 1000000);
- event->at.tv_sec += ((event->at.tv_usec + delta.tv_usec) / 1000000);
- event->at.tv_sec += delta.tv_sec;
+ timespec_now (&event->at);
+ timespec_adjust_delta (&event->at, delta);
at = TS (event->at);
event->callbk = callbk;
event->data = data;
@@ -89,10 +76,10 @@ gf_timer_call_stale (gf_timer_registry_t *reg,
{
if (reg == NULL || event == NULL)
{
- gf_log ("timer", GF_LOG_ERROR, "invalid argument");
+ gf_log_callingfn ("timer", GF_LOG_ERROR, "invalid argument");
return 0;
}
-
+
event->next->prev = event->prev;
event->prev->next = event->next;
event->next = &reg->stale;
@@ -108,13 +95,13 @@ gf_timer_call_cancel (glusterfs_ctx_t *ctx,
gf_timer_t *event)
{
gf_timer_registry_t *reg = NULL;
-
+
if (ctx == NULL || event == NULL)
{
- gf_log ("timer", GF_LOG_ERROR, "invalid argument");
+ gf_log_callingfn ("timer", GF_LOG_ERROR, "invalid argument");
return 0;
}
-
+
reg = gf_timer_registry_init (ctx);
if (!reg) {
gf_log ("timer", GF_LOG_ERROR, "!reg");
@@ -137,13 +124,14 @@ void *
gf_timer_proc (void *ctx)
{
gf_timer_registry_t *reg = NULL;
-
+ const struct timespec sleepts = {.tv_sec = 1, .tv_nsec = 0, };
+
if (ctx == NULL)
{
- gf_log ("timer", GF_LOG_ERROR, "invalid argument");
+ gf_log_callingfn ("timer", GF_LOG_ERROR, "invalid argument");
return NULL;
}
-
+
reg = gf_timer_registry_init (ctx);
if (!reg) {
gf_log ("timer", GF_LOG_ERROR, "!reg");
@@ -151,14 +139,14 @@ gf_timer_proc (void *ctx)
}
while (!reg->fin) {
- unsigned long long now;
- struct timeval now_tv;
+ uint64_t now;
+ struct timespec now_ts;
gf_timer_t *event = NULL;
- gettimeofday (&now_tv, NULL);
- now = TS (now_tv);
+ timespec_now (&now_ts);
+ now = TS (now_ts);
while (1) {
- unsigned long long at;
+ uint64_t at;
char need_cbk = 0;
pthread_mutex_lock (&reg->lock);
@@ -179,7 +167,7 @@ gf_timer_proc (void *ctx)
else
break;
}
- usleep (1000000);
+ nanosleep (&sleepts, NULL);
}
pthread_mutex_lock (&reg->lock);
@@ -203,7 +191,7 @@ gf_timer_registry_t *
gf_timer_registry_init (glusterfs_ctx_t *ctx)
{
if (ctx == NULL) {
- gf_log ("timer", GF_LOG_ERROR, "invalid argument");
+ gf_log_callingfn ("timer", GF_LOG_ERROR, "invalid argument");
return NULL;
}
@@ -222,7 +210,7 @@ gf_timer_registry_init (glusterfs_ctx_t *ctx)
reg->stale.prev = &reg->stale;
ctx->timer = reg;
- pthread_create (&reg->th, NULL, gf_timer_proc, ctx);
+ gf_thread_create (&reg->th, NULL, gf_timer_proc, ctx);
}
out:
return ctx->timer;
diff --git a/libglusterfs/src/timer.h b/libglusterfs/src/timer.h
index 4598029dc..2f963adbf 100644
--- a/libglusterfs/src/timer.h
+++ b/libglusterfs/src/timer.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
+ 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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 _TIMER_H
@@ -33,19 +24,19 @@
typedef void (*gf_timer_cbk_t) (void *);
struct _gf_timer {
- struct _gf_timer *next, *prev;
- struct timeval at;
- gf_timer_cbk_t callbk;
- void *data;
- xlator_t *xl;
+ struct _gf_timer *next, *prev;
+ struct timespec at;
+ gf_timer_cbk_t callbk;
+ void *data;
+ xlator_t *xl;
};
struct _gf_timer_registry {
- pthread_t th;
- char fin;
- struct _gf_timer stale;
- struct _gf_timer active;
- pthread_mutex_t lock;
+ pthread_t th;
+ char fin;
+ struct _gf_timer stale;
+ struct _gf_timer active;
+ pthread_mutex_t lock;
};
typedef struct _gf_timer gf_timer_t;
@@ -53,13 +44,13 @@ typedef struct _gf_timer_registry gf_timer_registry_t;
gf_timer_t *
gf_timer_call_after (glusterfs_ctx_t *ctx,
- struct timeval delta,
- gf_timer_cbk_t cbk,
- void *data);
+ struct timespec delta,
+ gf_timer_cbk_t cbk,
+ void *data);
int32_t
gf_timer_call_cancel (glusterfs_ctx_t *ctx,
- gf_timer_t *event);
+ gf_timer_t *event);
void *
gf_timer_proc (void *data);
diff --git a/libglusterfs/src/timespec.c b/libglusterfs/src/timespec.c
new file mode 100644
index 000000000..a0c281a1e
--- /dev/null
+++ b/libglusterfs/src/timespec.c
@@ -0,0 +1,68 @@
+/*
+ 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.
+*/
+
+#include <stdio.h>
+#include <inttypes.h>
+#if defined GF_LINUX_HOST_OS || defined GF_SOLARIS_HOST_OS || defined GF_BSD_HOST_OS
+#include <time.h>
+#include <sys/time.h>
+#endif
+
+#if defined GF_DARWIN_HOST_OS
+#include <mach/mach_time.h>
+#endif
+
+#include "logging.h"
+#include "time.h"
+
+
+void tv2ts (struct timeval tv, struct timespec *ts)
+{
+ ts->tv_sec = tv.tv_sec;
+ ts->tv_nsec = tv.tv_usec * 1000;
+}
+
+void timespec_now (struct timespec *ts)
+{
+#if defined GF_LINUX_HOST_OS || defined GF_SOLARIS_HOST_OS || defined GF_BSD_HOST_OS
+
+ if (0 == clock_gettime(CLOCK_MONOTONIC, ts))
+ return;
+ else {
+ struct timeval tv;
+ if (0 == gettimeofday(&tv, NULL))
+ tv2ts(tv, ts);
+ }
+#elif defined GF_DARWIN_HOST_OS
+ mach_timebase_info_data_t tb = { 0 };
+ static double timebase = 0.0;
+ uint64_t time = 0;
+ mach_timebase_info (&tb);
+
+ timebase *= info.numer;
+ timebase /= info.denom;
+
+ time = mach_absolute_time();
+ time *= timebase;
+
+ ts->tv_sec = (time * NANO);
+ ts->tv_nsec = (time - (ts.tv_sec * GIGA));
+
+#endif /* Platform verification */
+ gf_log_callingfn ("timer", GF_LOG_DEBUG, "%"PRIu64".%09"PRIu64,
+ ts->tv_sec, ts->tv_nsec);
+}
+
+void timespec_adjust_delta (struct timespec *ts, struct timespec delta)
+{
+ ts->tv_nsec = ((ts->tv_nsec + delta.tv_nsec) % 1000000000);
+ ts->tv_sec += ((ts->tv_nsec + delta.tv_nsec) / 1000000000);
+ ts->tv_sec += delta.tv_sec;
+}
diff --git a/libglusterfs/src/timespec.h b/libglusterfs/src/timespec.h
new file mode 100644
index 000000000..490255df9
--- /dev/null
+++ b/libglusterfs/src/timespec.h
@@ -0,0 +1,24 @@
+/*
+ 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 __INCLUDE_TIMESPEC_H__
+#define __INCLUDE_TIMESPEC_H__
+
+#include <stdint.h>
+
+#define TS(ts) ((ts.tv_sec * 1000000000LL) + ts.tv_nsec)
+#define NANO (+1.0E-9)
+#define GIGA UINT64_C(1000000000)
+
+void tv2ts (struct timeval tv, struct timespec *ts);
+void timespec_now (struct timespec *ts);
+void timespec_adjust_delta (struct timespec *ts, struct timespec delta);
+
+#endif /* __INCLUDE_TIMESPEC_H__ */
diff --git a/libglusterfs/src/trie.c b/libglusterfs/src/trie.c
new file mode 100644
index 000000000..f96bbebf6
--- /dev/null
+++ b/libglusterfs/src/trie.c
@@ -0,0 +1,387 @@
+/*
+ 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "common-utils.h"
+#include "trie.h"
+
+#define DISTANCE_EDIT 1
+#define DISTANCE_INS 1
+#define DISTANCE_DEL 1
+
+
+struct trienode {
+ char id;
+ char eow;
+ int depth;
+ void *data;
+ struct trie *trie;
+ struct trienode *parent;
+ struct trienode *subnodes[255];
+};
+
+struct trie {
+ struct trienode root;
+ int nodecnt;
+ size_t len;
+};
+
+
+trie_t *
+trie_new ()
+{
+ trie_t *trie = NULL;
+
+ trie = GF_CALLOC (1, sizeof (*trie), gf_common_mt_trie_trie);
+ if (!trie)
+ return NULL;
+
+ trie->root.trie = trie;
+
+ return trie;
+}
+
+
+static trienode_t *
+trie_subnode (trienode_t *node, int id)
+{
+ trienode_t *subnode = NULL;
+
+ subnode = node->subnodes[id];
+ if (!subnode) {
+ subnode = GF_CALLOC (1, sizeof (*subnode),
+ gf_common_mt_trie_node);
+ if (!subnode)
+ return NULL;
+
+ subnode->id = id;
+ subnode->depth = node->depth + 1;
+ node->subnodes[id] = subnode;
+ subnode->parent = node;
+ subnode->trie = node->trie;
+ node->trie->nodecnt++;
+ }
+
+ return subnode;
+}
+
+
+int
+trie_add (trie_t *trie, const char *dword)
+{
+ trienode_t *node = NULL;
+ int i = 0;
+ char id = 0;
+ trienode_t *subnode = NULL;
+
+ node = &trie->root;
+
+ for (i = 0; i < strlen (dword); i++) {
+ id = dword[i];
+
+ subnode = trie_subnode (node, id);
+ if (!subnode)
+ return -1;
+ node = subnode;
+ }
+
+ node->eow = 1;
+
+ return 0;
+}
+
+static void
+trienode_free (trienode_t *node)
+{
+ trienode_t *trav = NULL;
+ int i = 0;
+
+ for (i = 0; i < 255; i++) {
+ trav = node->subnodes[i];
+
+ if (trav)
+ trienode_free (trav);
+ }
+
+ GF_FREE (node->data);
+ GF_FREE (node);
+}
+
+
+void
+trie_destroy (trie_t *trie)
+{
+ trienode_free ((trienode_t *)trie);
+}
+
+
+void
+trie_destroy_bynode (trienode_t *node)
+{
+ trie_destroy (node->trie);
+}
+
+
+static int
+trienode_walk (trienode_t *node, int (*fn)(trienode_t *node, void *data),
+ void *data, int eowonly)
+{
+ trienode_t *trav = NULL;
+ int i = 0;
+ int cret = 0;
+ int ret = 0;
+
+ if (!eowonly || node->eow)
+ ret = fn (node, data);
+
+ if (ret)
+ goto out;
+
+ for (i = 0; i < 255; i++) {
+ trav = node->subnodes[i];
+ if (!trav)
+ continue;
+
+ cret = trienode_walk (trav, fn, data, eowonly);
+ if (cret < 0) {
+ ret = cret;
+ goto out;
+ }
+ ret += cret;
+ }
+
+out:
+ return ret;
+}
+
+
+static int
+trie_walk (trie_t *trie, int (*fn)(trienode_t *node, void *data),
+ void *data, int eowonly)
+{
+ return trienode_walk (&trie->root, fn, data, eowonly);
+}
+
+
+static void
+print_node (trienode_t *node, char **buf)
+{
+ if (!node->parent)
+ return;
+
+ if (node->parent) {
+ print_node (node->parent, buf);
+ *(*buf)++ = node->id;
+ }
+}
+
+
+int
+trienode_get_word (trienode_t *node, char **bufp)
+{
+ char *buf = NULL;
+
+ buf = GF_CALLOC (1, node->depth + 1, gf_common_mt_trie_buf);
+ if (!buf)
+ return -1;
+ *bufp = buf;
+
+ print_node (node, &buf);
+
+ return 0;
+}
+
+
+static int
+calc_dist (trienode_t *node, void *data)
+{
+ const char *word = NULL;
+ int i = 0;
+ int *row = NULL;
+ int *uprow = NULL;
+ int distu = 0;
+ int distl = 0;
+ int distul = 0;
+
+ word = data;
+
+ node->data = GF_CALLOC (node->trie->len, sizeof (int),
+ gf_common_mt_trie_data);
+ if (!node->data)
+ return -1;
+ row = node->data;
+
+ if (!node->parent) {
+ for (i = 0; i < node->trie->len; i++)
+ row[i] = i+1;
+
+ return 0;
+ }
+
+ uprow = node->parent->data;
+
+ distu = node->depth; /* up node */
+ distul = node->parent->depth; /* up-left node */
+
+ for (i = 0; i < node->trie->len; i++) {
+ distl = uprow[i]; /* left node */
+
+ if (word[i] == node->id)
+ row[i] = distul;
+ else
+ row[i] = min ((distul + DISTANCE_EDIT),
+ min ((distu + DISTANCE_DEL),
+ (distl + DISTANCE_INS)));
+
+ distu = row[i];
+ distul = distl;
+ }
+
+ return 0;
+}
+
+
+int
+trienode_get_dist (trienode_t *node)
+{
+ int *row = NULL;
+
+ row = node->data;
+
+ return row[node->trie->len - 1];
+}
+
+
+struct trienodevec_w {
+ struct trienodevec *vec;
+ const char *word;
+};
+
+
+static void
+trienodevec_clear (struct trienodevec *nodevec)
+{
+ memset(nodevec->nodes, 0, sizeof (*nodevec->nodes) * nodevec->cnt);
+}
+
+
+static int
+collect_closest (trienode_t *node, void *data)
+{
+ struct trienodevec_w *nodevec_w = NULL;
+ struct trienodevec *nodevec = NULL;
+ int dist = 0;
+ int i = 0;
+
+ nodevec_w = data;
+ nodevec = nodevec_w->vec;
+
+ if (calc_dist (node, (void *)nodevec_w->word))
+ return -1;
+
+ if (!node->eow || !nodevec->cnt)
+ return 0;
+
+ dist = trienode_get_dist (node);
+
+ /*
+ * I thought that when descending further after some dictionary word dw,
+ * if we see that child's distance is bigger than it was for dw, then we
+ * can prune this branch, as it can contain only worse nodes.
+ *
+ * This conjecture fails, see eg:
+ *
+ * d("AB", "B") = 1;
+ * d("AB", "BA") = 2;
+ * d("AB", "BAB") = 1;
+ *
+ * -- if both "B" and "BAB" are in dict., then pruning at "BA" * would
+ * miss "BAB".
+ *
+ * (example courtesy of Richard Bann <richardbann at gmail.com>)
+
+ if (node->parent->eow && dist > trienode_get_dist (node->parent))
+ return 1;
+
+ */
+
+ if (nodevec->nodes[0] &&
+ dist < trienode_get_dist (nodevec->nodes[0])) {
+ /* improving over the findings so far */
+ trienodevec_clear (nodevec);
+ nodevec->nodes[0] = node;
+ } else if (!nodevec->nodes[0] ||
+ dist == trienode_get_dist (nodevec->nodes[0])) {
+ /* as good as the best so far, add if there is free space */
+ for (i = 0; i < nodevec->cnt; i++) {
+ if (!nodevec->nodes[i]) {
+ nodevec->nodes[i] = node;
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+int
+trie_measure (trie_t *trie, const char *word, trienode_t **nodes,
+ int nodecnt)
+{
+ struct trienodevec nodevec = {0,};
+
+ nodevec.nodes = nodes;
+ nodevec.cnt = nodecnt;
+
+ return trie_measure_vec (trie, word, &nodevec);
+}
+
+
+int
+trie_measure_vec (trie_t *trie, const char *word, struct trienodevec *nodevec)
+{
+ struct trienodevec_w nodevec_w = {0,};
+ int ret = 0;
+
+ trie->len = strlen (word);
+
+ trienodevec_clear (nodevec);
+ nodevec_w.vec = nodevec;
+ nodevec_w.word = word;
+
+ ret = trie_walk (trie, collect_closest, &nodevec_w, 0);
+ if (ret > 0)
+ ret = 0;
+
+ return ret;
+}
+
+
+static int
+trienode_reset (trienode_t *node, void *data)
+{
+ GF_FREE (node->data);
+
+ return 0;
+}
+
+
+void
+trie_reset_search (trie_t *trie)
+{
+ trie->len = 0;
+
+ trie_walk (trie, trienode_reset, NULL, 0);
+}
diff --git a/libglusterfs/src/trie.h b/libglusterfs/src/trie.h
new file mode 100644
index 000000000..0356e6621
--- /dev/null
+++ b/libglusterfs/src/trie.h
@@ -0,0 +1,51 @@
+/*
+ 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.
+*/
+
+#ifndef _TRIE_H_
+#define _TRIE_H_
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+struct trienode;
+typedef struct trienode trienode_t;
+
+struct trie;
+typedef struct trie trie_t;
+
+struct trienodevec {
+ trienode_t **nodes;
+ unsigned cnt;
+};
+
+
+trie_t *trie_new ();
+
+int trie_add (trie_t *trie, const char *word);
+
+void trie_destroy (trie_t *trie);
+
+void trie_destroy_bynode (trienode_t *node);
+
+int trie_measure (trie_t *trie, const char *word, trienode_t **nodes,
+ int nodecnt);
+
+int trie_measure_vec (trie_t *trie, const char *word,
+ struct trienodevec *nodevec);
+
+void trie_reset_search (trie_t *trie);
+
+int trienode_get_dist (trienode_t *node);
+
+int trienode_get_word (trienode_t *node, char **buf);
+
+#endif
diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c
index d5883f316..a277c58a8 100644
--- a/libglusterfs/src/xlator.c
+++ b/libglusterfs/src/xlator.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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
@@ -28,774 +19,264 @@
#include <fnmatch.h>
#include "defaults.h"
-
#define SET_DEFAULT_FOP(fn) do { \
- if (!xl->fops->fn) \
- xl->fops->fn = default_##fn; \
- } while (0)
+ if (!xl->fops->fn) \
+ xl->fops->fn = default_##fn; \
+ } while (0)
#define SET_DEFAULT_CBK(fn) do { \
- if (!xl->cbks->fn) \
- xl->cbks->fn = default_##fn; \
- } while (0)
+ if (!xl->cbks->fn) \
+ xl->cbks->fn = default_##fn; \
+ } while (0)
-#define GF_OPTION_LIST_EMPTY(_opt) (_opt->value[0] == NULL)
-
static void
fill_defaults (xlator_t *xl)
{
- if (xl == NULL) {
- gf_log ("xlator", GF_LOG_DEBUG, "invalid argument");
- return;
- }
-
- SET_DEFAULT_FOP (create);
- SET_DEFAULT_FOP (open);
- SET_DEFAULT_FOP (stat);
- SET_DEFAULT_FOP (readlink);
- SET_DEFAULT_FOP (mknod);
- SET_DEFAULT_FOP (mkdir);
- SET_DEFAULT_FOP (unlink);
- SET_DEFAULT_FOP (rmdir);
- SET_DEFAULT_FOP (symlink);
- SET_DEFAULT_FOP (rename);
- SET_DEFAULT_FOP (link);
- SET_DEFAULT_FOP (truncate);
- SET_DEFAULT_FOP (readv);
- SET_DEFAULT_FOP (writev);
- SET_DEFAULT_FOP (statfs);
- SET_DEFAULT_FOP (flush);
- SET_DEFAULT_FOP (fsync);
- SET_DEFAULT_FOP (setxattr);
- SET_DEFAULT_FOP (getxattr);
- SET_DEFAULT_FOP (fsetxattr);
- SET_DEFAULT_FOP (fgetxattr);
- SET_DEFAULT_FOP (removexattr);
- SET_DEFAULT_FOP (opendir);
- SET_DEFAULT_FOP (readdir);
- SET_DEFAULT_FOP (readdirp);
- SET_DEFAULT_FOP (fsyncdir);
- SET_DEFAULT_FOP (access);
- SET_DEFAULT_FOP (ftruncate);
- SET_DEFAULT_FOP (fstat);
- SET_DEFAULT_FOP (lk);
- SET_DEFAULT_FOP (inodelk);
- SET_DEFAULT_FOP (finodelk);
- SET_DEFAULT_FOP (entrylk);
- SET_DEFAULT_FOP (fentrylk);
- SET_DEFAULT_FOP (lookup);
- SET_DEFAULT_FOP (rchecksum);
- SET_DEFAULT_FOP (xattrop);
- SET_DEFAULT_FOP (fxattrop);
+ if (xl == NULL) {
+ gf_log_callingfn ("xlator", GF_LOG_WARNING, "invalid argument");
+ return;
+ }
+
+ SET_DEFAULT_FOP (create);
+ SET_DEFAULT_FOP (open);
+ SET_DEFAULT_FOP (stat);
+ SET_DEFAULT_FOP (readlink);
+ SET_DEFAULT_FOP (mknod);
+ SET_DEFAULT_FOP (mkdir);
+ SET_DEFAULT_FOP (unlink);
+ SET_DEFAULT_FOP (rmdir);
+ SET_DEFAULT_FOP (symlink);
+ SET_DEFAULT_FOP (rename);
+ SET_DEFAULT_FOP (link);
+ SET_DEFAULT_FOP (truncate);
+ SET_DEFAULT_FOP (readv);
+ SET_DEFAULT_FOP (writev);
+ SET_DEFAULT_FOP (statfs);
+ SET_DEFAULT_FOP (flush);
+ SET_DEFAULT_FOP (fsync);
+ SET_DEFAULT_FOP (setxattr);
+ SET_DEFAULT_FOP (getxattr);
+ SET_DEFAULT_FOP (fsetxattr);
+ SET_DEFAULT_FOP (fgetxattr);
+ SET_DEFAULT_FOP (removexattr);
+ SET_DEFAULT_FOP (fremovexattr);
+ SET_DEFAULT_FOP (opendir);
+ SET_DEFAULT_FOP (readdir);
+ SET_DEFAULT_FOP (readdirp);
+ SET_DEFAULT_FOP (fsyncdir);
+ SET_DEFAULT_FOP (access);
+ SET_DEFAULT_FOP (ftruncate);
+ SET_DEFAULT_FOP (fstat);
+ SET_DEFAULT_FOP (lk);
+ SET_DEFAULT_FOP (inodelk);
+ SET_DEFAULT_FOP (finodelk);
+ SET_DEFAULT_FOP (entrylk);
+ SET_DEFAULT_FOP (fentrylk);
+ SET_DEFAULT_FOP (lookup);
+ SET_DEFAULT_FOP (rchecksum);
+ SET_DEFAULT_FOP (xattrop);
+ SET_DEFAULT_FOP (fxattrop);
SET_DEFAULT_FOP (setattr);
SET_DEFAULT_FOP (fsetattr);
+ SET_DEFAULT_FOP (fallocate);
+ SET_DEFAULT_FOP (discard);
+ SET_DEFAULT_FOP (zerofill);
SET_DEFAULT_FOP (getspec);
- SET_DEFAULT_CBK (release);
- SET_DEFAULT_CBK (releasedir);
- SET_DEFAULT_CBK (forget);
+ SET_DEFAULT_CBK (release);
+ SET_DEFAULT_CBK (releasedir);
+ SET_DEFAULT_CBK (forget);
- if (!xl->notify)
- xl->notify = default_notify;
+ if (!xl->notify)
+ xl->notify = default_notify;
if (!xl->mem_acct_init)
xl->mem_acct_init = default_mem_acct_init;
- return;
+ return;
}
-/* RFC 1123 & 952 */
-static char
-valid_host_name (char *address, int length)
-{
- int i = 0;
- char ret = 1;
- if ((length > 75) || (length == 1)) {
- ret = 0;
- goto out;
- }
+int
+xlator_set_type_virtual (xlator_t *xl, const char *type)
+{
+ GF_VALIDATE_OR_GOTO ("xlator", xl, out);
+ GF_VALIDATE_OR_GOTO ("xlator", type, out);
- if (!isalnum (address[length - 1])) {
- ret = 0;
- goto out;
- }
+ xl->type = gf_strdup (type);
- for (i = 0; i < length; i++) {
- if (!isalnum (address[i]) && (address[i] != '.')
- && (address[i] != '-')) {
- ret = 0;
- goto out;
- }
- }
+ if (xl->type)
+ return 0;
out:
- return ret;
+ return -1;
}
-static char
-valid_ipv4_address (char *address, int length)
-{
- int octets = 0;
- int value = 0;
- char *tmp = NULL, *ptr = NULL, *prev = NULL, *endptr = NULL;
- char ret = 1;
-
- tmp = gf_strdup (address);
- prev = tmp;
- prev = strtok_r (tmp, ".", &ptr);
-
- while (prev != NULL)
- {
- octets++;
- value = strtol (prev, &endptr, 10);
- if ((value > 255) || (value < 0) || (endptr != NULL)) {
- ret = 0;
- goto out;
- }
-
- prev = strtok_r (NULL, ".", &ptr);
- }
- if (octets != 4) {
- ret = 0;
- }
+int
+xlator_volopt_dynload (char *xlator_type, void **dl_handle,
+ volume_opt_list_t *opt_list)
+{
+ int ret = -1;
+ char *name = NULL;
+ void *handle = NULL;
-out:
- GF_FREE (tmp);
- return ret;
-}
+ GF_VALIDATE_OR_GOTO ("xlator", xlator_type, out);
-static char
-valid_ipv6_address (char *address, int length)
-{
- int hex_numbers = 0;
- int value = 0;
- char *tmp = NULL, *ptr = NULL, *prev = NULL, *endptr = NULL;
- char ret = 1;
-
- tmp = gf_strdup (address);
- prev = strtok_r (tmp, ":", &ptr);
-
- 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);
- }
-
- if (hex_numbers > 8) {
- ret = 0;
+ ret = gf_asprintf (&name, "%s/%s.so", XLATORDIR, xlator_type);
+ if (-1 == ret) {
+ gf_log ("xlator", GF_LOG_ERROR, "asprintf failed");
+ goto out;
}
-out:
- GF_FREE (tmp);
- return ret;
-}
+ ret = -1;
-static char
-valid_internet_address (char *address)
-{
- char ret = 0;
- int length = 0;
+ gf_log ("xlator", GF_LOG_TRACE, "attempt to load file %s", name);
- if (address == NULL) {
+ handle = dlopen (name, RTLD_NOW|RTLD_GLOBAL);
+ if (!handle) {
+ gf_log ("xlator", GF_LOG_WARNING, "%s", dlerror ());
goto out;
}
- length = strlen (address);
- if (length == 0) {
+ if (!(opt_list->given_opt = dlsym (handle, "options"))) {
+ dlerror ();
+ gf_log ("xlator", GF_LOG_ERROR,
+ "Failed to load xlator opt table");
goto out;
}
- if (valid_ipv4_address (address, length)
- || valid_ipv6_address (address, length)
- || valid_host_name (address, length)) {
- ret = 1;
- }
-
-out:
- return ret;
-}
-
-int
-_volume_option_value_validate (xlator_t *xl,
- data_pair_t *pair,
- volume_option_t *opt)
-{
- int i = 0;
- int ret = -1;
- uint64_t input_size = 0;
- long long inputll = 0;
-
- /* Key is valid, validate the option */
- switch (opt->type) {
- case GF_OPTION_TYPE_PATH:
- {
- if (strstr (pair->value->data, "../")) {
- gf_log (xl->name, GF_LOG_ERROR,
- "invalid path given '%s'",
- pair->value->data);
- ret = -1;
- goto out;
- }
-
- /* Make sure the given path is valid */
- if (pair->value->data[0] != '/') {
- gf_log (xl->name, GF_LOG_WARNING,
- "option %s %s: '%s' is not an "
- "absolute path name",
- pair->key, pair->value->data,
- pair->value->data);
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_INT:
- {
- /* Check the range */
- if (gf_string2longlong (pair->value->data,
- &inputll) != 0) {
- gf_log (xl->name, GF_LOG_ERROR,
- "invalid number format \"%s\" in "
- "\"option %s\"",
- pair->value->data, pair->key);
- goto out;
- }
-
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "no range check required for "
- "'option %s %s'",
- pair->key, pair->value->data);
- ret = 0;
- break;
- }
- if ((inputll < opt->min) ||
- (inputll > opt->max)) {
- gf_log (xl->name, GF_LOG_WARNING,
- "'%lld' in 'option %s %s' is out of "
- "range [%"PRId64" - %"PRId64"]",
- inputll, pair->key,
- pair->value->data,
- opt->min, opt->max);
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_SIZET:
- {
- /* Check the range */
- if (gf_string2bytesize (pair->value->data,
- &input_size) != 0) {
- gf_log (xl->name, GF_LOG_ERROR,
- "invalid size format \"%s\" in "
- "\"option %s\"",
- pair->value->data, pair->key);
- goto out;
- }
-
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "no range check required for "
- "'option %s %s'",
- pair->key, pair->value->data);
- ret = 0;
- break;
- }
- if ((input_size < opt->min) ||
- (input_size > opt->max)) {
- gf_log (xl->name, GF_LOG_WARNING,
- "'%"PRId64"' in 'option %s %s' is "
- "out of range [%"PRId64" - %"PRId64"]",
- input_size, pair->key,
- pair->value->data,
- opt->min, opt->max);
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_BOOL:
- {
- /* Check if the value is one of
- '0|1|on|off|no|yes|true|false|enable|disable' */
- gf_boolean_t bool_value;
- if (gf_string2boolean (pair->value->data,
- &bool_value) != 0) {
- gf_log (xl->name, GF_LOG_ERROR,
- "option %s %s: '%s' is not a valid "
- "boolean value",
- pair->key, pair->value->data,
- pair->value->data);
- goto out;
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_XLATOR:
- {
- /* Check if the value is one of the xlators */
- xlator_t *xlopt = xl;
- while (xlopt->prev)
- xlopt = xlopt->prev;
-
- while (xlopt) {
- if (strcmp (pair->value->data,
- xlopt->name) == 0) {
- ret = 0;
- break;
- }
- xlopt = xlopt->next;
- }
- if (!xlopt) {
- gf_log (xl->name, GF_LOG_ERROR,
- "option %s %s: '%s' is not a "
- "valid volume name",
- pair->key, pair->value->data,
- pair->value->data);
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_STR:
- {
- /* Check if the '*str' is valid */
- if (GF_OPTION_LIST_EMPTY(opt)) {
- ret = 0;
- goto out;
- }
-
- for (i = 0; (i < ZR_OPTION_MAX_ARRAY_SIZE) &&
- opt->value[i]; i++) {
- if (fnmatch (opt->value[i], pair->value->data,
- FNM_EXTMATCH) == 0) {
- ret = 0;
- break;
- }
- }
-
- if ((i == ZR_OPTION_MAX_ARRAY_SIZE)
- || ((i < ZR_OPTION_MAX_ARRAY_SIZE)
- && (!opt->value[i]))) {
- /* enter here only if
- * 1. reached end of opt->value array and haven't
- * validated input
- * OR
- * 2. valid input list is less than
- * ZR_OPTION_MAX_ARRAY_SIZE and input has not
- * matched all possible input values.
- */
- char given_array[4096] = {0,};
- for (i = 0; (i < ZR_OPTION_MAX_ARRAY_SIZE) &&
- opt->value[i]; i++) {
- strcat (given_array, opt->value[i]);
- strcat (given_array, ", ");
- }
-
- gf_log (xl->name, GF_LOG_ERROR,
- "option %s %s: '%s' is not valid "
- "(possible options are %s)",
- pair->key, pair->value->data,
- pair->value->data, given_array);
-
- goto out;
- }
- }
- break;
- case GF_OPTION_TYPE_PERCENT:
- {
- uint32_t percent = 0;
-
-
- /* Check if the value is valid percentage */
- if (gf_string2percent (pair->value->data,
- &percent) != 0) {
- gf_log (xl->name, GF_LOG_ERROR,
- "invalid percent format \"%s\" "
- "in \"option %s\"",
- pair->value->data, pair->key);
- goto out;
- }
-
- if ((percent < 0) || (percent > 100)) {
- gf_log (xl->name, GF_LOG_ERROR,
- "'%d' in 'option %s %s' is out of "
- "range [0 - 100]",
- percent, pair->key,
- pair->value->data);
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_PERCENT_OR_SIZET:
- {
- uint32_t percent = 0;
- uint64_t input_size = 0;
-
- /* Check if the value is valid percentage */
- if (gf_string2percent (pair->value->data,
- &percent) == 0) {
- if (percent > 100) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "value given was greater than 100, "
- "assuming this is actually a size");
- if (gf_string2bytesize (pair->value->data,
- &input_size) == 0) {
- /* Check the range */
- if ((opt->min == 0) &&
- (opt->max == 0)) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "no range check "
- "required for "
- "'option %s %s'",
- pair->key,
- pair->value->data);
- // It is a size
- ret = 0;
- goto out;
- }
- if ((input_size < opt->min) ||
- (input_size > opt->max)) {
- gf_log (xl->name, GF_LOG_ERROR,
- "'%"PRId64"' in "
- "'option %s %s' is out"
- " of range [%"PRId64""
- "- %"PRId64"]",
- input_size, pair->key,
- pair->value->data,
- opt->min, opt->max);
- }
- // It is a size
- ret = 0;
- goto out;
- } else {
- // It's not a percent or size
- gf_log (xl->name, GF_LOG_ERROR,
- "invalid number format \"%s\" "
- "in \"option %s\"",
- pair->value->data, pair->key);
- }
-
- }
- // It is a percent
- ret = 0;
- goto out;
- } else {
- if (gf_string2bytesize (pair->value->data,
- &input_size) == 0) {
- /* Check the range */
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "no range check required for "
- "'option %s %s'",
- pair->key, pair->value->data);
- // It is a size
- ret = 0;
- goto out;
- }
- if ((input_size < opt->min) ||
- (input_size > opt->max)) {
- gf_log (xl->name, GF_LOG_ERROR,
- "'%"PRId64"' in 'option %s %s'"
- " is out of range [%"PRId64" -"
- " %"PRId64"]",
- input_size, pair->key,
- pair->value->data,
- opt->min, opt->max);
- }
- } else {
- // It's not a percent or size
- gf_log (xl->name, GF_LOG_ERROR,
- "invalid number format \"%s\" "
- "in \"option %s\"",
- pair->value->data, pair->key);
- }
- //It is a size
- ret = 0;
- goto out;
- }
+ *dl_handle = handle;
- }
- break;
- case GF_OPTION_TYPE_TIME:
- {
- uint32_t input_time = 0;
-
- /* Check if the value is valid percentage */
- if (gf_string2time (pair->value->data,
- &input_time) != 0) {
- gf_log (xl->name,
- GF_LOG_ERROR,
- "invalid time format \"%s\" in "
- "\"option %s\"",
- pair->value->data, pair->key);
- goto out;
- }
-
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "no range check required for "
- "'option %s %s'",
- pair->key, pair->value->data);
- ret = 0;
- goto out;
- }
- if ((input_time < opt->min) ||
- (input_time > opt->max)) {
- gf_log (xl->name, GF_LOG_ERROR,
- "'%"PRIu32"' in 'option %s %s' is "
- "out of range [%"PRId64" - %"PRId64"]",
- input_time, pair->key,
- pair->value->data,
- opt->min, opt->max);
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_DOUBLE:
- {
- double input_time = 0.0;
-
- /* Check if the value is valid double */
- if (gf_string2double (pair->value->data,
- &input_time) != 0) {
- gf_log (xl->name,
- GF_LOG_ERROR,
- "invalid time format \"%s\" in \"option %s\"",
- pair->value->data, pair->key);
- goto out;
- }
-
- if (input_time < 0.0) {
- gf_log (xl->name,
- GF_LOG_ERROR,
- "invalid time format \"%s\" in \"option %s\"",
- pair->value->data, pair->key);
- goto out;
- }
-
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "no range check required for 'option %s %s'",
- pair->key, pair->value->data);
- ret = 0;
- goto out;
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_INTERNET_ADDRESS:
- {
- if (valid_internet_address (pair->value->data)) {
- ret = 0;
- } else {
- gf_log (xl->name, GF_LOG_ERROR, "internet address '%s'"
- " does not conform to standards.",
- pair->value->data);
- goto out;
- }
- }
- break;
- case GF_OPTION_TYPE_ANY:
- /* NO CHECK */
- ret = 0;
- break;
- }
-
-out:
- return ret;
-}
-
-int
-validate_xlator_volume_options (xlator_t *xl, volume_option_t *opt)
-{
- int i = 0;
- int ret = -1;
- int index = 0;
- volume_option_t *trav = NULL;
- data_pair_t *pairs = NULL;
-
- if (!opt) {
- ret = 0;
- goto out;
- }
-
- /* First search for not supported options, if any report error */
- pairs = xl->options->members_list;
- while (pairs) {
- ret = -1;
- for (index = 0;
- opt[index].key && opt[index].key[0] ; index++) {
- trav = &(opt[index]);
- for (i = 0 ;
- (i < ZR_VOLUME_MAX_NUM_KEY) &&
- trav->key[i]; i++) {
- /* Check if the key is valid */
- if (fnmatch (trav->key[i],
- pairs->key, FNM_NOESCAPE) == 0) {
- ret = 0;
- break;
- }
- }
- if (!ret) {
- if (i) {
- gf_log (xl->name, GF_LOG_WARNING,
- "option '%s' is deprecated, "
- "preferred is '%s', continuing"
- " with correction",
- trav->key[i], trav->key[0]);
- /* TODO: some bytes lost */
- pairs->key = gf_strdup (trav->key[0]);
- }
- break;
- }
- }
- if (!ret) {
- ret = _volume_option_value_validate (xl, pairs, trav);
- if (-1 == ret) {
- goto out;
- }
- }
-
- pairs = pairs->next;
- }
-
- ret = 0;
+ ret = 0;
out:
- return ret;
-}
-
-int32_t
-xlator_set_type_virtual (xlator_t *xl, const char *type)
-{
- if (xl == NULL || type == NULL) {
- gf_log ("xlator", GF_LOG_DEBUG, "invalid argument");
- return -1;
- }
+ GF_FREE (name);
- xl->type = gf_strdup (type);
+ gf_log ("xlator", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
- if (xl->type)
- return 0;
- else
- return -1;
}
-int32_t
+int
xlator_dynload (xlator_t *xl)
{
- int ret = 0;
- char *name = NULL;
- void *handle = NULL;
- volume_opt_list_t *vol_opt = NULL;
+ int ret = -1;
+ char *name = NULL;
+ void *handle = NULL;
+ volume_opt_list_t *vol_opt = NULL;
+ class_methods_t *vtbl = NULL;
+
+ GF_VALIDATE_OR_GOTO ("xlator", xl, out);
- ret = gf_asprintf (&name, "%s/%s.so", XLATORDIR, xl->type);
+ INIT_LIST_HEAD (&xl->volume_options);
+
+ ret = gf_asprintf (&name, "%s/%s.so", XLATORDIR, xl->type);
if (-1 == ret) {
gf_log ("xlator", GF_LOG_ERROR, "asprintf failed");
- return -1;
+ goto out;
}
- gf_log ("xlator", GF_LOG_TRACE, "attempt to load file %s", name);
+ ret = -1;
- handle = dlopen (name, RTLD_NOW|RTLD_GLOBAL);
- if (!handle) {
- gf_log ("xlator", GF_LOG_DEBUG, "%s", dlerror ());
- GF_FREE (name);
- return -1;
- }
+ gf_log ("xlator", GF_LOG_TRACE, "attempt to load file %s", name);
+
+ handle = dlopen (name, RTLD_NOW|RTLD_GLOBAL);
+ if (!handle) {
+ gf_log ("xlator", GF_LOG_WARNING, "%s", dlerror ());
+ goto out;
+ }
xl->dlhandle = handle;
- if (!(xl->fops = dlsym (handle, "fops"))) {
- gf_log ("xlator", GF_LOG_DEBUG, "dlsym(fops) on %s",
- dlerror ());
- GF_FREE (name);
- return -1;
- }
+ if (!(xl->fops = dlsym (handle, "fops"))) {
+ gf_log ("xlator", GF_LOG_WARNING, "dlsym(fops) on %s",
+ dlerror ());
+ goto out;
+ }
- if (!(xl->cbks = dlsym (handle, "cbks"))) {
- gf_log ("xlator", GF_LOG_DEBUG, "dlsym(cbks) on %s",
- dlerror ());
- GF_FREE (name);
- return -1;
- }
+ if (!(xl->cbks = dlsym (handle, "cbks"))) {
+ gf_log ("xlator", GF_LOG_WARNING, "dlsym(cbks) on %s",
+ dlerror ());
+ goto out;
+ }
- if (!(xl->init = dlsym (handle, "init"))) {
- gf_log ("xlator", GF_LOG_DEBUG, "dlsym(init) on %s",
- dlerror ());
- GF_FREE (name);
- return -1;
- }
+ /*
+ * If class_methods exists, its contents override any definitions of
+ * init or fini for that translator. Otherwise, we fall back to the
+ * older method of looking for init and fini directly.
+ */
+ vtbl = dlsym(handle,"class_methods");
+ if (vtbl) {
+ xl->init = vtbl->init;
+ xl->fini = vtbl->fini;
+ xl->reconfigure = vtbl->reconfigure;
+ xl->notify = vtbl->notify;
+ }
+ else {
+ if (!(*VOID(&xl->init) = dlsym (handle, "init"))) {
+ gf_log ("xlator", GF_LOG_WARNING, "dlsym(init) on %s",
+ dlerror ());
+ goto out;
+ }
- if (!(xl->fini = dlsym (handle, "fini"))) {
- gf_log ("xlator", GF_LOG_DEBUG, "dlsym(fini) on %s",
- dlerror ());
- GF_FREE (name);
- return -1;
- }
+ if (!(*VOID(&(xl->fini)) = dlsym (handle, "fini"))) {
+ gf_log ("xlator", GF_LOG_WARNING, "dlsym(fini) on %s",
+ dlerror ());
+ goto out;
+ }
+ if (!(*VOID(&(xl->reconfigure)) = dlsym (handle,
+ "reconfigure"))) {
+ gf_log ("xlator", GF_LOG_TRACE,
+ "dlsym(reconfigure) on %s -- neglecting",
+ dlerror());
+ }
+ if (!(*VOID(&(xl->notify)) = dlsym (handle, "notify"))) {
+ gf_log ("xlator", GF_LOG_TRACE,
+ "dlsym(notify) on %s -- neglecting",
+ dlerror ());
+ }
- if (!(xl->notify = dlsym (handle, "notify"))) {
- gf_log ("xlator", GF_LOG_DEBUG,
- "dlsym(notify) on %s -- neglecting", dlerror ());
- }
+ }
- if (!(xl->dumpops = dlsym (handle, "dumpops"))) {
- gf_log ("xlator", GF_LOG_DEBUG,
- "dlsym(dumpops) on %s -- neglecting", dlerror ());
- }
+ if (!(xl->dumpops = dlsym (handle, "dumpops"))) {
+ gf_log ("xlator", GF_LOG_TRACE,
+ "dlsym(dumpops) on %s -- neglecting", dlerror ());
+ }
- if (!(xl->mem_acct_init = dlsym (handle, "mem_acct_init"))) {
- gf_log (xl->name, GF_LOG_DEBUG,
+ if (!(*VOID(&(xl->mem_acct_init)) = dlsym (handle, "mem_acct_init"))) {
+ gf_log (xl->name, GF_LOG_TRACE,
"dlsym(mem_acct_init) on %s -- neglecting",
dlerror ());
}
- if (!(xl->reconfigure = dlsym (handle, "reconfigure"))) {
- gf_log ("xlator", GF_LOG_DEBUG,
- "dlsym(reconfigure) on %s -- neglecting",
- dlerror());
- }
-
- if (!(xl->validate_options = dlsym (handle, "validate_options"))) {
- gf_log ("xlator", GF_LOG_DEBUG,
- "dlsym(validate_options) on %s -- neglecting",
- dlerror());
- }
-
-
- INIT_LIST_HEAD (&xl->volume_options);
-
- vol_opt = GF_CALLOC (1, sizeof (volume_opt_list_t),
+ vol_opt = GF_CALLOC (1, sizeof (volume_opt_list_t),
gf_common_mt_volume_opt_list_t);
if (!vol_opt) {
- GF_FREE (name);
- return -1;
+ goto out;
}
- if (!(vol_opt->given_opt = dlsym (handle, "options"))) {
- dlerror ();
- gf_log (xl->name, GF_LOG_DEBUG,
- "Strict option validation not enforced -- neglecting");
- }
- list_add_tail (&vol_opt->list, &xl->volume_options);
+ if (!(vol_opt->given_opt = dlsym (handle, "options"))) {
+ dlerror ();
+ gf_log (xl->name, GF_LOG_TRACE,
+ "Strict option validation not enforced -- neglecting");
+ }
+ INIT_LIST_HEAD (&vol_opt->list);
+ list_add_tail (&vol_opt->list, &xl->volume_options);
+
+ fill_defaults (xl);
- fill_defaults (xl);
+ ret = 0;
- GF_FREE (name);
- return 0;
+out:
+ GF_FREE (name);
+ return ret;
}
-int32_t
+int
xlator_set_type (xlator_t *xl, const char *type)
{
int ret = 0;
@@ -810,54 +291,77 @@ xlator_set_type (xlator_t *xl, const char *type)
void
xlator_foreach (xlator_t *this,
- void (*fn)(xlator_t *each,
- void *data),
- void *data)
+ void (*fn)(xlator_t *each,
+ void *data),
+ void *data)
{
- xlator_t *first = NULL;
+ xlator_t *first = NULL;
+ xlator_t *old_THIS = NULL;
- if (this == NULL || fn == NULL || data == NULL) {
- gf_log ("xlator", GF_LOG_DEBUG, "invalid argument");
- return;
- }
+ GF_VALIDATE_OR_GOTO ("xlator", this, out);
+ GF_VALIDATE_OR_GOTO ("xlator", fn, out);
- first = this;
+ first = this;
- while (first->prev)
- first = first->prev;
+ while (first->prev)
+ first = first->prev;
- while (first) {
- fn (first, data);
- first = first->next;
+ while (first) {
+ old_THIS = THIS;
+ THIS = first;
+
+ fn (first, data);
+
+ THIS = old_THIS;
+ first = first->next;
+ }
+
+out:
+ return;
+}
+
+
+void
+xlator_foreach_depth_first (xlator_t *this,
+ void (*fn)(xlator_t *each, void *data),
+ void *data)
+{
+ xlator_list_t *subv = NULL;
+
+ subv = this->children;
+
+ while (subv) {
+ xlator_foreach_depth_first (subv->xlator, fn, data);
+ subv = subv->next;
}
+
+ fn (this, data);
}
xlator_t *
xlator_search_by_name (xlator_t *any, const char *name)
{
- xlator_t *search = NULL;
+ xlator_t *search = NULL;
- if (any == NULL || name == NULL) {
- gf_log ("xlator", GF_LOG_DEBUG, "invalid argument");
- return NULL;
- }
+ GF_VALIDATE_OR_GOTO ("xlator", any, out);
+ GF_VALIDATE_OR_GOTO ("xlator", name, out);
- search = any;
+ search = any;
- while (search->prev)
- search = search->prev;
+ while (search->prev)
+ search = search->prev;
- while (search) {
- if (!strcmp (search->name, name))
- break;
- search = search->next;
- }
+ while (search) {
+ if (!strcmp (search->name, name))
+ break;
+ search = search->next;
+ }
- return search;
+out:
+ return search;
}
-
static int
__xlator_init(xlator_t *xl)
{
@@ -878,20 +382,15 @@ __xlator_init(xlator_t *xl)
int
xlator_init (xlator_t *xl)
{
- int32_t ret = 0;
+ int32_t ret = -1;
- if (xl == NULL) {
- gf_log ("xlator", GF_LOG_DEBUG, "invalid argument");
- return 0;
- }
-
- ret = -1;
+ GF_VALIDATE_OR_GOTO ("xlator", xl, out);
if (xl->mem_acct_init)
xl->mem_acct_init (xl);
if (!xl->init) {
- gf_log (xl->name, GF_LOG_DEBUG, "No init() found");
+ gf_log (xl->name, GF_LOG_WARNING, "No init() found");
goto out;
}
@@ -909,133 +408,52 @@ xlator_init (xlator_t *xl)
ret = 0;
out:
- return ret;
+ return ret;
}
static void
xlator_fini_rec (xlator_t *xl)
{
- xlator_list_t *trav = NULL;
-
- if (xl == NULL) {
- gf_log ("xlator", GF_LOG_DEBUG, "invalid argument");
- return;
- }
-
- trav = xl->children;
-
- while (trav) {
- if (!trav->xlator->init_succeeded) {
- break;
- }
-
- xlator_fini_rec (trav->xlator);
- gf_log (trav->xlator->name, GF_LOG_DEBUG, "fini done");
- trav = trav->next;
- }
-
- if (xl->init_succeeded) {
- if (xl->fini) {
- xl->fini (xl);
- } else {
- gf_log (xl->name, GF_LOG_DEBUG, "No fini() found");
- }
- xl->init_succeeded = 0;
- }
-}
-
-static int
-xlator_reconfigure_rec (xlator_t *old_xl, xlator_t *new_xl)
-{
- xlator_list_t *trav1 = NULL;
- xlator_list_t *trav2 = NULL;
- int32_t ret = 0;
-
- if (old_xl == NULL || new_xl == NULL) {
- gf_log ("xlator", GF_LOG_DEBUG, "invalid argument");
- return -1;
- }
+ xlator_list_t *trav = NULL;
+ xlator_t *old_THIS = NULL;
- trav1 = old_xl->children;
- trav2 = new_xl->children;
+ GF_VALIDATE_OR_GOTO ("xlator", xl, out);
- while (trav1 && trav2) {
- ret = xlator_reconfigure_rec (trav1->xlator, trav2->xlator);
+ trav = xl->children;
- if (ret)
- goto out;
-
- gf_log (trav1->xlator->name, GF_LOG_DEBUG, "reconfigured");
-
- trav1 = trav1->next;
- trav2 = trav2->next;
- }
+ while (trav) {
+ if (!trav->xlator->init_succeeded) {
+ break;
+ }
- if (old_xl->reconfigure) {
- ret = old_xl->reconfigure (old_xl, new_xl->options);
- if (ret)
- goto out;
+ xlator_fini_rec (trav->xlator);
+ gf_log (trav->xlator->name, GF_LOG_DEBUG, "fini done");
+ trav = trav->next;
}
- else
- gf_log (old_xl->name, GF_LOG_DEBUG, "No reconfigure() found");
-
-out:
- return ret;
-}
-int
-xlator_validate_rec (xlator_t *xlator, char **op_errstr)
-{
- xlator_list_t *trav = NULL;
-
- if (xlator == NULL ) {
- gf_log ("xlator", GF_LOG_DEBUG, "invalid argument");
- return -1;
- }
+ if (xl->init_succeeded) {
+ if (xl->fini) {
+ old_THIS = THIS;
+ THIS = xl;
- trav = xlator->children;
+ xl->fini (xl);
- while (trav) {
- if (xlator_validate_rec (trav->xlator, op_errstr) )
- return -1;
+ if (xl->local_pool)
+ mem_pool_destroy (xl->local_pool);
- trav = trav->next;
- }
-
- if (xlator_dynload (xlator))
- gf_log ("", GF_LOG_DEBUG, "Did not load the symbols");
-
- if (xlator->validate_options) {
- if (xlator->validate_options (xlator, xlator->options,
- op_errstr)) {
- gf_log ("", GF_LOG_DEBUG, *op_errstr);
- return -1;
+ THIS = old_THIS;
+ } else {
+ gf_log (xl->name, GF_LOG_DEBUG, "No fini() found");
}
- gf_log (xlator->name, GF_LOG_DEBUG, "Validated option");
-
+ xl->init_succeeded = 0;
}
-
- gf_log (xlator->name, GF_LOG_DEBUG, "No validate_options() found");
- return 0;
+out:
+ return;
}
-int
-graph_reconf_validateopt (glusterfs_graph_t *graph,
- char **op_errstr)
-{
- xlator_t *xlator = NULL;
- int ret = -1;
-
- GF_ASSERT (graph);
-
- xlator = graph->first;
- ret = xlator_validate_rec (xlator, op_errstr);
-
- return ret;
-}
int
xlator_notify (xlator_t *xl, int event, void *data, ...)
{
@@ -1059,18 +477,17 @@ xlator_mem_acct_init (xlator_t *xl, int num_types)
int i = 0;
int ret = 0;
- if (!gf_mem_acct_is_enabled())
- return 0;
-
if (!xl)
return -1;
+ if (!xl->ctx->mem_acct_enable)
+ return 0;
+
xl->mem_acct.num_types = num_types;
- xl->mem_acct.rec = calloc(num_types, sizeof(struct mem_acct_rec));
+ xl->mem_acct.rec = CALLOC(num_types, sizeof(struct mem_acct_rec));
if (!xl->mem_acct.rec) {
- gf_log("xlator", GF_LOG_ERROR, "Out of Memory");
return -1;
}
@@ -1081,62 +498,72 @@ xlator_mem_acct_init (xlator_t *xl, int num_types)
}
}
- gf_log(xl->name, GF_LOG_DEBUG, "Allocated mem_acct_rec for %d types",
- num_types);
-
return 0;
}
+
void
xlator_tree_fini (xlator_t *xl)
{
- xlator_t *top = NULL;
+ xlator_t *top = NULL;
- if (xl == NULL) {
- gf_log ("xlator", GF_LOG_DEBUG, "invalid argument");
- return;
- }
+ GF_VALIDATE_OR_GOTO ("xlator", xl, out);
+
+ top = xl;
+ xlator_fini_rec (top);
- top = xl;
- xlator_fini_rec (top);
+out:
+ return;
}
int
-xlator_tree_reconfigure (xlator_t *old_xl, xlator_t *new_xl)
+xlator_list_destroy (xlator_list_t *list)
{
- xlator_t *new_top = NULL;
- xlator_t *old_top = NULL;
-
- GF_ASSERT (old_xl);
- GF_ASSERT (new_xl);
+ xlator_list_t *next = NULL;
- old_top = old_xl;
- new_top = new_xl;
+ while (list) {
+ next = list->next;
+ GF_FREE (list);
+ list = next;
+ }
- return xlator_reconfigure_rec (old_top, new_top);
+ return 0;
}
int
xlator_tree_free (xlator_t *tree)
{
- xlator_t *trav = tree, *prev = tree;
-
- if (!tree) {
- gf_log ("parser", GF_LOG_ERROR, "Translator tree not found");
- return -1;
- }
-
- while (prev) {
- trav = prev->next;
- dict_destroy (prev->options);
- GF_FREE (prev->name);
- GF_FREE (prev->type);
- GF_FREE (prev);
- prev = trav;
- }
-
- return 0;
+ volume_opt_list_t *vol_opt = NULL;
+ volume_opt_list_t *tmp = NULL;
+ xlator_t *trav = tree;
+ xlator_t *prev = tree;
+
+ if (!tree) {
+ gf_log ("parser", GF_LOG_ERROR, "Translator tree not found");
+ return -1;
+ }
+
+ while (prev) {
+ trav = prev->next;
+ if (prev->dlhandle)
+ dlclose (prev->dlhandle);
+ dict_unref (prev->options);
+ GF_FREE (prev->name);
+ GF_FREE (prev->type);
+ xlator_list_destroy (prev->children);
+ xlator_list_destroy (prev->parents);
+
+ list_for_each_entry_safe (vol_opt, tmp, &prev->volume_options,
+ list) {
+ list_del_init (&vol_opt->list);
+ GF_FREE (vol_opt);
+ }
+ GF_FREE (prev);
+ prev = trav;
+ }
+
+ return 0;
}
@@ -1151,56 +578,126 @@ loc_wipe (loc_t *loc)
GF_FREE ((char *)loc->path);
loc->path = NULL;
}
-
+
if (loc->parent) {
inode_unref (loc->parent);
loc->parent = NULL;
}
-}
+ memset (loc, 0, sizeof (*loc));
+}
int
-loc_copy (loc_t *dst, loc_t *src)
+loc_path (loc_t *loc, const char *bname)
{
- int ret = -1;
+ int ret = 0;
- dst->ino = src->ino;
+ if (loc->path)
+ goto out;
- if (src->inode)
- dst->inode = inode_ref (src->inode);
+ ret = -1;
- if (src->parent)
- dst->parent = inode_ref (src->parent);
+ if (bname && !strlen (bname))
+ bname = NULL;
- dst->path = gf_strdup (src->path);
+ if (!bname)
+ goto inode_path;
- if (!dst->path)
- goto out;
+ if (loc->parent && !uuid_is_null (loc->parent->gfid)) {
+ ret = inode_path (loc->parent, bname, (char**)&loc->path);
+ } else if (!uuid_is_null (loc->pargfid)) {
+ ret = gf_asprintf ((char**)&loc->path, INODE_PATH_FMT"/%s",
+ uuid_utoa (loc->pargfid), bname);
+ }
- dst->name = strrchr (dst->path, '/');
- if (dst->name)
- dst->name++;
+ if (loc->path)
+ goto out;
- ret = 0;
+inode_path:
+ if (loc->inode && !uuid_is_null (loc->inode->gfid)) {
+ ret = inode_path (loc->inode, NULL, (char **)&loc->path);
+ } else if (!uuid_is_null (loc->gfid)) {
+ ret = gf_asprintf ((char**)&loc->path, INODE_PATH_FMT,
+ uuid_utoa (loc->gfid));
+ }
out:
- return ret;
+ return ret;
}
+void
+loc_gfid (loc_t *loc, uuid_t gfid)
+{
+ if (!gfid)
+ goto out;
+ uuid_clear (gfid);
+
+ if (!loc)
+ goto out;
+ else if (!uuid_is_null (loc->gfid))
+ uuid_copy (gfid, loc->gfid);
+ else if (loc->inode && (!uuid_is_null (loc->inode->gfid)))
+ uuid_copy (gfid, loc->inode->gfid);
+out:
+ return;
+}
+
+char*
+loc_gfid_utoa (loc_t *loc)
+{
+ uuid_t gfid;
+ loc_gfid (loc, gfid);
+ return uuid_utoa (gfid);
+}
int
-xlator_list_destroy (xlator_list_t *list)
+loc_copy (loc_t *dst, loc_t *src)
{
- xlator_list_t *next = NULL;
+ int ret = -1;
- while (list) {
- next = list->next;
- GF_FREE (list);
- list = next;
+ GF_VALIDATE_OR_GOTO ("xlator", dst, err);
+ GF_VALIDATE_OR_GOTO ("xlator", src, err);
+
+ uuid_copy (dst->gfid, src->gfid);
+ uuid_copy (dst->pargfid, src->pargfid);
+ uuid_copy (dst->gfid, src->gfid);
+
+ if (src->inode)
+ dst->inode = inode_ref (src->inode);
+
+ if (src->parent)
+ dst->parent = inode_ref (src->parent);
+
+ if (src->path) {
+ dst->path = gf_strdup (src->path);
+
+ if (!dst->path)
+ goto out;
+
+ if (src->name)
+ dst->name = strrchr (dst->path, '/');
+ if (dst->name)
+ dst->name++;
}
- return 0;
+ ret = 0;
+out:
+ if (ret == -1)
+ loc_wipe (dst);
+
+err:
+ return ret;
}
+gf_boolean_t
+loc_is_root (loc_t *loc)
+{
+ if (loc && __is_root_gfid (loc->gfid)) {
+ return _gf_true;
+ } else if (loc && loc->inode && __is_root_gfid (loc->inode->gfid)) {
+ return _gf_true;
+ }
+ return _gf_false;
+}
int
xlator_destroy (xlator_t *xl)
@@ -1211,10 +708,8 @@ xlator_destroy (xlator_t *xl)
if (!xl)
return 0;
- if (xl->name)
- GF_FREE (xl->name);
- if (xl->type)
- GF_FREE (xl->type);
+ GF_FREE (xl->name);
+ GF_FREE (xl->type);
if (xl->dlhandle)
dlclose (xl->dlhandle);
if (xl->options)
@@ -1233,6 +728,8 @@ xlator_destroy (xlator_t *xl)
return 0;
}
+
+
int
is_gf_log_command (xlator_t *this, const char *name, char *value)
{
@@ -1276,6 +773,7 @@ is_gf_log_command (xlator_t *this, const char *name, char *value)
ret = 0;
goto out;
}
+
if (!strcmp (name, "trusted.glusterfs.fuse.set-log-level")) {
/* */
gf_log (this->name, gf_log_get_xl_loglevel (this),
@@ -1286,7 +784,7 @@ is_gf_log_command (xlator_t *this, const char *name, char *value)
goto out;
}
- ctx = glusterfs_ctx_get();
+ ctx = this->ctx;
if (!ctx)
goto out;
if (!ctx->active)
@@ -1309,6 +807,7 @@ out:
return ret;
}
+
int
glusterd_check_log_level (const char *value)
{
@@ -1331,8 +830,9 @@ glusterd_check_log_level (const char *value)
}
if (log_level == -1)
- gf_log ("", GF_LOG_ERROR, "Invalid log-level. possible values "
+ gf_log (THIS->name, GF_LOG_ERROR, "Invalid log-level. possible values "
"are DEBUG|WARNING|ERROR|CRITICAL|NONE|TRACE");
return log_level;
}
+
diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h
index e583e8c13..b57e5873e 100644
--- a/libglusterfs/src/xlator.h
+++ b/libglusterfs/src/xlator.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 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 Affero 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero 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 _XLATOR_H
@@ -29,7 +20,7 @@
#include <stdint.h>
#include <inttypes.h>
-
+#include "event-history.h"
#include "logging.h"
#include "common-utils.h"
#include "dict.h"
@@ -64,7 +55,7 @@ typedef struct _loc loc_t;
typedef int32_t (*event_notify_fn_t) (xlator_t *this, int32_t event, void *data,
- ...);
+ ...);
#include "list.h"
#include "gf-dirent.h"
@@ -74,22 +65,32 @@ typedef int32_t (*event_notify_fn_t) (xlator_t *this, int32_t event, void *data,
#include "fd.h"
#include "globals.h"
#include "iatt.h"
+#include "options.h"
+#include "client_t.h"
+
struct _loc {
- const char *path;
- const char *name;
- ino_t ino;
- inode_t *inode;
- inode_t *parent;
+ const char *path;
+ const char *name;
+ inode_t *inode;
+ inode_t *parent;
+ /* Currently all location based operations are through 'gfid' of inode.
+ * But the 'inode->gfid' only gets set in higher most layer (as in,
+ * 'fuse', 'protocol/server', or 'nfs/server'). So if translators want
+ * to send fops on a inode before the 'inode->gfid' is set, they have to
+ * make use of below 'gfid' fields
+ */
+ uuid_t gfid;
+ uuid_t pargfid;
};
typedef int32_t (*fop_getspec_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- char *spec_data);
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ char *spec_data);
typedef int32_t (*fop_rchecksum_cbk_t) (call_frame_t *frame,
void *cookie,
@@ -97,301 +98,308 @@ typedef int32_t (*fop_rchecksum_cbk_t) (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
uint32_t weak_checksum,
- uint8_t *strong_checksum);
+ uint8_t *strong_checksum,
+ dict_t *xdata);
typedef int32_t (*fop_getspec_t) (call_frame_t *frame,
- xlator_t *this,
- const char *key,
- int32_t flag);
+ xlator_t *this,
+ const char *key,
+ int32_t flag);
typedef int32_t (*fop_rchecksum_t) (call_frame_t *frame,
xlator_t *this,
fd_t *fd, off_t offset,
- int32_t len);
+ int32_t len, dict_t *xdata);
typedef int32_t (*fop_lookup_cbk_t) (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 *xattr,
+ 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);
typedef int32_t (*fop_stat_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *buf);
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct iatt *buf, dict_t *xdata);
typedef int32_t (*fop_fstat_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *buf);
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct iatt *buf, dict_t *xdata);
typedef int32_t (*fop_truncate_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *prebuf,
- struct iatt *postbuf);
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata);
typedef int32_t (*fop_ftruncate_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *prebuf,
- struct iatt *postbuf);
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata);
typedef int32_t (*fop_access_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno);
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno, dict_t *xdata);
typedef int32_t (*fop_readlink_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- const char *path,
- struct iatt *buf);
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ const char *path,
+ struct iatt *buf, dict_t *xdata);
typedef int32_t (*fop_mknod_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- inode_t *inode,
+ 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);
+ struct iatt *postparent, dict_t *xdata);
typedef int32_t (*fop_mkdir_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- inode_t *inode,
+ 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);
+ struct iatt *postparent, dict_t *xdata);
typedef int32_t (*fop_unlink_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
typedef int32_t (*fop_rmdir_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
struct iatt *preparent,
- struct iatt *postparent);
+ struct iatt *postparent, dict_t *xdata);
typedef int32_t (*fop_symlink_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- inode_t *inode,
+ 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);
+ struct iatt *postparent, dict_t *xdata);
typedef int32_t (*fop_rename_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *buf,
+ 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);
+ struct iatt *postnewparent, dict_t *xdata);
typedef int32_t (*fop_link_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- inode_t *inode,
+ 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);
+ struct iatt *postparent, dict_t *xdata);
typedef int32_t (*fop_create_cbk_t) (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,
+ 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);
+ struct iatt *postparent, dict_t *xdata);
typedef int32_t (*fop_open_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- fd_t *fd);
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ fd_t *fd, dict_t *xdata);
typedef int32_t (*fop_readv_cbk_t) (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);
+ 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);
typedef int32_t (*fop_writev_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *prebuf,
- struct iatt *postbuf);
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata);
typedef int32_t (*fop_flush_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno);
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno, dict_t *xdata);
typedef int32_t (*fop_fsync_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
struct iatt *prebuf,
- struct iatt *postbuf);
+ struct iatt *postbuf, dict_t *xdata);
typedef int32_t (*fop_opendir_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- fd_t *fd);
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ fd_t *fd, dict_t *xdata);
typedef int32_t (*fop_fsyncdir_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno);
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno, dict_t *xdata);
typedef int32_t (*fop_statfs_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- struct statvfs *buf);
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct statvfs *buf, dict_t *xdata);
typedef int32_t (*fop_setxattr_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno);
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno, dict_t *xdata);
typedef int32_t (*fop_getxattr_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- dict_t *dict);
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ dict_t *dict, dict_t *xdata);
typedef int32_t (*fop_fsetxattr_cbk_t) (call_frame_t *frame,
void *cookie,
xlator_t *this,
int32_t op_ret,
- int32_t op_errno);
+ int32_t op_errno, dict_t *xdata);
typedef int32_t (*fop_fgetxattr_cbk_t) (call_frame_t *frame,
void *cookie,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- dict_t *dict);
+ dict_t *dict, dict_t *xdata);
typedef int32_t (*fop_removexattr_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno);
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno, dict_t *xdata);
+
+typedef int32_t (*fop_fremovexattr_cbk_t) (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno, dict_t *xdata);
typedef int32_t (*fop_lk_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- struct gf_flock *flock);
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct gf_flock *flock, dict_t *xdata);
typedef int32_t (*fop_inodelk_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno);
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno, dict_t *xdata);
typedef int32_t (*fop_finodelk_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno);
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno, dict_t *xdata);
typedef int32_t (*fop_entrylk_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno);
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno, dict_t *xdata);
typedef int32_t (*fop_fentrylk_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno);
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno, dict_t *xdata);
typedef int32_t (*fop_readdir_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- gf_dirent_t *entries);
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ gf_dirent_t *entries, dict_t *xdata);
typedef int32_t (*fop_readdirp_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- gf_dirent_t *entries);
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ gf_dirent_t *entries, dict_t *xdata);
typedef int32_t (*fop_xattrop_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- dict_t *xattr);
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ dict_t *xattr, dict_t *xdata);
typedef int32_t (*fop_fxattrop_cbk_t) (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- dict_t *xattr);
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ dict_t *xattr, dict_t *xdata);
typedef int32_t (*fop_setattr_cbk_t) (call_frame_t *frame,
@@ -400,7 +408,7 @@ typedef int32_t (*fop_setattr_cbk_t) (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *preop_stbuf,
- struct iatt *postop_stbuf);
+ struct iatt *postop_stbuf, dict_t *xdata);
typedef int32_t (*fop_fsetattr_cbk_t) (call_frame_t *frame,
void *cookie,
@@ -408,72 +416,95 @@ typedef int32_t (*fop_fsetattr_cbk_t) (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *preop_stbuf,
- struct iatt *postop_stbuf);
+ struct iatt *postop_stbuf, dict_t *xdata);
+
+typedef int32_t (*fop_fallocate_cbk_t) (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct iatt *preop_stbuf,
+ struct iatt *postop_stbuf, dict_t *xdata);
+
+typedef int32_t (*fop_discard_cbk_t) (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct iatt *preop_stbuf,
+ struct iatt *postop_stbuf, dict_t *xdata);
+
+typedef int32_t (*fop_zerofill_cbk_t) (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct iatt *preop_stbuf,
+ struct iatt *postop_stbuf, dict_t *xdata);
typedef int32_t (*fop_lookup_t) (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- dict_t *xattr_req);
+ xlator_t *this,
+ loc_t *loc,
+ dict_t *xdata);
typedef int32_t (*fop_stat_t) (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc);
+ xlator_t *this,
+ loc_t *loc, dict_t *xdata);
typedef int32_t (*fop_fstat_t) (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd);
+ xlator_t *this,
+ fd_t *fd, dict_t *xdata);
typedef int32_t (*fop_truncate_t) (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- off_t offset);
+ xlator_t *this,
+ loc_t *loc,
+ off_t offset, dict_t *xdata);
typedef int32_t (*fop_ftruncate_t) (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- off_t offset);
+ xlator_t *this,
+ fd_t *fd,
+ off_t offset, dict_t *xdata);
typedef int32_t (*fop_access_t) (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- int32_t mask);
+ xlator_t *this,
+ loc_t *loc,
+ int32_t mask, dict_t *xdata);
typedef int32_t (*fop_readlink_t) (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- size_t size);
+ xlator_t *this,
+ loc_t *loc,
+ size_t size, dict_t *xdata);
typedef int32_t (*fop_mknod_t) (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, dev_t rdev,
- dict_t *params);
+ loc_t *loc, mode_t mode, dev_t rdev,
+ mode_t umask, dict_t *xdata);
-typedef int32_t (*fop_mkdir_t) (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, dict_t *params);
+typedef int32_t (*fop_mkdir_t) (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ mode_t mode, mode_t umask, dict_t *xdata);
-typedef int32_t (*fop_unlink_t) (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc);
+typedef int32_t (*fop_unlink_t) (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, int xflags, dict_t *xdata);
typedef int32_t (*fop_rmdir_t) (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int flags);
+ loc_t *loc, int xflags, dict_t *xdata);
typedef int32_t (*fop_symlink_t) (call_frame_t *frame, xlator_t *this,
- const char *linkname, loc_t *loc,
- dict_t *params);
+ const char *linkname, loc_t *loc,
+ mode_t umask, dict_t *xdata);
typedef int32_t (*fop_rename_t) (call_frame_t *frame,
- xlator_t *this,
- loc_t *oldloc,
- loc_t *newloc);
+ xlator_t *this,
+ loc_t *oldloc,
+ loc_t *newloc, dict_t *xdata);
typedef int32_t (*fop_link_t) (call_frame_t *frame,
- xlator_t *this,
- loc_t *oldloc,
- loc_t *newloc);
+ xlator_t *this,
+ loc_t *oldloc,
+ loc_t *newloc, dict_t *xdata);
typedef int32_t (*fop_create_t) (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int32_t flags, mode_t mode,
- fd_t *fd, dict_t *params);
+ loc_t *loc, int32_t flags, mode_t mode,
+ mode_t umask, fd_t *fd, dict_t *xdata);
/* Tell subsequent writes on the fd_t to fsync after every writev fop without
* requiring a fsync fop.
@@ -484,243 +515,283 @@ typedef int32_t (*fop_create_t) (call_frame_t *frame, xlator_t *this,
*/
#define GF_OPEN_NOWB 0x02
-typedef int32_t (*fop_open_t) (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- int32_t flags,
- fd_t *fd,
- int32_t wbflags);
+typedef int32_t (*fop_open_t) (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, int32_t flags,
+ fd_t *fd, dict_t *xdata);
typedef int32_t (*fop_readv_t) (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- size_t size,
- off_t offset);
+ xlator_t *this,
+ fd_t *fd,
+ size_t size,
+ off_t offset,
+ uint32_t flags, dict_t *xdata);
typedef int32_t (*fop_writev_t) (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- struct iovec *vector,
- int32_t count,
- off_t offset,
- struct iobref *iobref);
+ xlator_t *this,
+ fd_t *fd,
+ struct iovec *vector,
+ int32_t count,
+ off_t offset,
+ uint32_t flags,
+ struct iobref *iobref, dict_t *xdata);
typedef int32_t (*fop_flush_t) (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd);
+ xlator_t *this,
+ fd_t *fd, dict_t *xdata);
typedef int32_t (*fop_fsync_t) (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- int32_t datasync);
+ xlator_t *this,
+ fd_t *fd,
+ int32_t datasync, dict_t *xdata);
typedef int32_t (*fop_opendir_t) (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- fd_t *fd);
+ xlator_t *this,
+ loc_t *loc,
+ fd_t *fd, dict_t *xdata);
typedef int32_t (*fop_fsyncdir_t) (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- int32_t datasync);
+ xlator_t *this,
+ fd_t *fd,
+ int32_t datasync, dict_t *xdata);
typedef int32_t (*fop_statfs_t) (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc);
+ xlator_t *this,
+ loc_t *loc, dict_t *xdata);
typedef int32_t (*fop_setxattr_t) (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- dict_t *dict,
- int32_t flags);
+ xlator_t *this,
+ loc_t *loc,
+ dict_t *dict,
+ int32_t flags, dict_t *xdata);
typedef int32_t (*fop_getxattr_t) (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- const char *name);
+ xlator_t *this,
+ loc_t *loc,
+ const char *name, dict_t *xdata);
typedef int32_t (*fop_fsetxattr_t) (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
dict_t *dict,
- int32_t flags);
+ int32_t flags, dict_t *xdata);
typedef int32_t (*fop_fgetxattr_t) (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- const char *name);
+ const char *name, dict_t *xdata);
typedef int32_t (*fop_removexattr_t) (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- const char *name);
+ xlator_t *this,
+ loc_t *loc,
+ const char *name, dict_t *xdata);
+
+typedef int32_t (*fop_fremovexattr_t) (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ const char *name, dict_t *xdata);
typedef int32_t (*fop_lk_t) (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- int32_t cmd,
- struct gf_flock *flock);
+ xlator_t *this,
+ fd_t *fd,
+ int32_t cmd,
+ struct gf_flock *flock, dict_t *xdata);
typedef int32_t (*fop_inodelk_t) (call_frame_t *frame,
- xlator_t *this,
+ xlator_t *this,
const char *volume,
- loc_t *loc,
- int32_t cmd,
- struct gf_flock *flock);
+ loc_t *loc,
+ int32_t cmd,
+ struct gf_flock *flock, dict_t *xdata);
typedef int32_t (*fop_finodelk_t) (call_frame_t *frame,
- xlator_t *this,
+ xlator_t *this,
const char *volume,
- fd_t *fd,
- int32_t cmd,
- struct gf_flock *flock);
+ fd_t *fd,
+ int32_t cmd,
+ struct gf_flock *flock, dict_t *xdata);
typedef int32_t (*fop_entrylk_t) (call_frame_t *frame,
- xlator_t *this,
+ xlator_t *this,
const char *volume, loc_t *loc,
- const char *basename, entrylk_cmd cmd,
- entrylk_type type);
+ const char *basename, entrylk_cmd cmd,
+ entrylk_type type, dict_t *xdata);
typedef int32_t (*fop_fentrylk_t) (call_frame_t *frame,
- xlator_t *this,
+ xlator_t *this,
const char *volume, fd_t *fd,
- const char *basename, entrylk_cmd cmd,
- entrylk_type type);
+ const char *basename, entrylk_cmd cmd,
+ entrylk_type type, dict_t *xdata);
typedef int32_t (*fop_readdir_t) (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- size_t size,
- off_t offset);
+ xlator_t *this,
+ fd_t *fd,
+ size_t size,
+ off_t offset, dict_t *xdata);
typedef int32_t (*fop_readdirp_t) (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- size_t size,
- off_t offset);
+ xlator_t *this,
+ fd_t *fd,
+ size_t size,
+ off_t offset,
+ dict_t *xdata);
typedef int32_t (*fop_xattrop_t) (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- gf_xattrop_flags_t optype,
- dict_t *xattr);
+ xlator_t *this,
+ loc_t *loc,
+ gf_xattrop_flags_t optype,
+ dict_t *xattr, dict_t *xdata);
typedef int32_t (*fop_fxattrop_t) (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- gf_xattrop_flags_t optype,
- dict_t *xattr);
+ xlator_t *this,
+ fd_t *fd,
+ gf_xattrop_flags_t optype,
+ dict_t *xattr, dict_t *xdata);
typedef int32_t (*fop_setattr_t) (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
struct iatt *stbuf,
- int32_t valid);
+ int32_t valid, dict_t *xdata);
typedef int32_t (*fop_fsetattr_t) (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
struct iatt *stbuf,
- int32_t valid);
+ int32_t valid, dict_t *xdata);
+typedef int32_t (*fop_fallocate_t) (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ int32_t keep_size,
+ off_t offset,
+ size_t len,
+ dict_t *xdata);
+
+typedef int32_t (*fop_discard_t) (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ off_t offset,
+ size_t len,
+ dict_t *xdata);
+typedef int32_t (*fop_zerofill_t) (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ off_t offset,
+ size_t len,
+ dict_t *xdata);
struct xlator_fops {
- fop_lookup_t lookup;
- fop_stat_t stat;
- fop_fstat_t fstat;
- fop_truncate_t truncate;
- fop_ftruncate_t ftruncate;
- fop_access_t access;
- fop_readlink_t readlink;
- fop_mknod_t mknod;
- fop_mkdir_t mkdir;
- fop_unlink_t unlink;
- fop_rmdir_t rmdir;
- fop_symlink_t symlink;
- fop_rename_t rename;
- fop_link_t link;
- fop_create_t create;
- fop_open_t open;
- fop_readv_t readv;
- fop_writev_t writev;
- fop_flush_t flush;
- fop_fsync_t fsync;
- fop_opendir_t opendir;
- fop_readdir_t readdir;
- fop_readdirp_t readdirp;
- fop_fsyncdir_t fsyncdir;
- fop_statfs_t statfs;
- fop_setxattr_t setxattr;
- fop_getxattr_t getxattr;
- fop_fsetxattr_t fsetxattr;
- fop_fgetxattr_t fgetxattr;
- fop_removexattr_t removexattr;
- fop_lk_t lk;
- fop_inodelk_t inodelk;
- fop_finodelk_t finodelk;
- fop_entrylk_t entrylk;
- fop_fentrylk_t fentrylk;
- fop_rchecksum_t rchecksum;
- fop_xattrop_t xattrop;
- fop_fxattrop_t fxattrop;
+ fop_lookup_t lookup;
+ fop_stat_t stat;
+ fop_fstat_t fstat;
+ fop_truncate_t truncate;
+ fop_ftruncate_t ftruncate;
+ fop_access_t access;
+ fop_readlink_t readlink;
+ fop_mknod_t mknod;
+ fop_mkdir_t mkdir;
+ fop_unlink_t unlink;
+ fop_rmdir_t rmdir;
+ fop_symlink_t symlink;
+ fop_rename_t rename;
+ fop_link_t link;
+ fop_create_t create;
+ fop_open_t open;
+ fop_readv_t readv;
+ fop_writev_t writev;
+ fop_flush_t flush;
+ fop_fsync_t fsync;
+ fop_opendir_t opendir;
+ fop_readdir_t readdir;
+ fop_readdirp_t readdirp;
+ fop_fsyncdir_t fsyncdir;
+ fop_statfs_t statfs;
+ fop_setxattr_t setxattr;
+ fop_getxattr_t getxattr;
+ fop_fsetxattr_t fsetxattr;
+ fop_fgetxattr_t fgetxattr;
+ fop_removexattr_t removexattr;
+ fop_fremovexattr_t fremovexattr;
+ fop_lk_t lk;
+ fop_inodelk_t inodelk;
+ fop_finodelk_t finodelk;
+ fop_entrylk_t entrylk;
+ fop_fentrylk_t fentrylk;
+ fop_rchecksum_t rchecksum;
+ fop_xattrop_t xattrop;
+ fop_fxattrop_t fxattrop;
fop_setattr_t setattr;
fop_fsetattr_t fsetattr;
fop_getspec_t getspec;
-
- /* these entries are used for a typechecking hack in STACK_WIND _only_ */
- fop_lookup_cbk_t lookup_cbk;
- fop_stat_cbk_t stat_cbk;
- fop_fstat_cbk_t fstat_cbk;
- fop_truncate_cbk_t truncate_cbk;
- fop_ftruncate_cbk_t ftruncate_cbk;
- fop_access_cbk_t access_cbk;
- fop_readlink_cbk_t readlink_cbk;
- fop_mknod_cbk_t mknod_cbk;
- fop_mkdir_cbk_t mkdir_cbk;
- fop_unlink_cbk_t unlink_cbk;
- fop_rmdir_cbk_t rmdir_cbk;
- fop_symlink_cbk_t symlink_cbk;
- fop_rename_cbk_t rename_cbk;
- fop_link_cbk_t link_cbk;
- fop_create_cbk_t create_cbk;
- fop_open_cbk_t open_cbk;
- fop_readv_cbk_t readv_cbk;
- fop_writev_cbk_t writev_cbk;
- fop_flush_cbk_t flush_cbk;
- fop_fsync_cbk_t fsync_cbk;
- fop_opendir_cbk_t opendir_cbk;
- fop_readdir_cbk_t readdir_cbk;
- fop_readdirp_cbk_t readdirp_cbk;
- fop_fsyncdir_cbk_t fsyncdir_cbk;
- fop_statfs_cbk_t statfs_cbk;
- fop_setxattr_cbk_t setxattr_cbk;
- fop_getxattr_cbk_t getxattr_cbk;
- fop_fsetxattr_cbk_t fsetxattr_cbk;
- fop_fgetxattr_cbk_t fgetxattr_cbk;
- fop_removexattr_cbk_t removexattr_cbk;
- fop_lk_cbk_t lk_cbk;
- fop_inodelk_cbk_t inodelk_cbk;
- fop_finodelk_cbk_t finodelk_cbk;
- fop_entrylk_cbk_t entrylk_cbk;
- fop_fentrylk_cbk_t fentrylk_cbk;
- fop_rchecksum_cbk_t rchecksum_cbk;
- fop_xattrop_cbk_t xattrop_cbk;
- fop_fxattrop_cbk_t fxattrop_cbk;
+ fop_fallocate_t fallocate;
+ fop_discard_t discard;
+ fop_zerofill_t zerofill;
+
+ /* these entries are used for a typechecking hack in STACK_WIND _only_ */
+ fop_lookup_cbk_t lookup_cbk;
+ fop_stat_cbk_t stat_cbk;
+ fop_fstat_cbk_t fstat_cbk;
+ fop_truncate_cbk_t truncate_cbk;
+ fop_ftruncate_cbk_t ftruncate_cbk;
+ fop_access_cbk_t access_cbk;
+ fop_readlink_cbk_t readlink_cbk;
+ fop_mknod_cbk_t mknod_cbk;
+ fop_mkdir_cbk_t mkdir_cbk;
+ fop_unlink_cbk_t unlink_cbk;
+ fop_rmdir_cbk_t rmdir_cbk;
+ fop_symlink_cbk_t symlink_cbk;
+ fop_rename_cbk_t rename_cbk;
+ fop_link_cbk_t link_cbk;
+ fop_create_cbk_t create_cbk;
+ fop_open_cbk_t open_cbk;
+ fop_readv_cbk_t readv_cbk;
+ fop_writev_cbk_t writev_cbk;
+ fop_flush_cbk_t flush_cbk;
+ fop_fsync_cbk_t fsync_cbk;
+ fop_opendir_cbk_t opendir_cbk;
+ fop_readdir_cbk_t readdir_cbk;
+ fop_readdirp_cbk_t readdirp_cbk;
+ fop_fsyncdir_cbk_t fsyncdir_cbk;
+ fop_statfs_cbk_t statfs_cbk;
+ fop_setxattr_cbk_t setxattr_cbk;
+ fop_getxattr_cbk_t getxattr_cbk;
+ fop_fsetxattr_cbk_t fsetxattr_cbk;
+ fop_fgetxattr_cbk_t fgetxattr_cbk;
+ fop_removexattr_cbk_t removexattr_cbk;
+ fop_fremovexattr_cbk_t fremovexattr_cbk;
+ fop_lk_cbk_t lk_cbk;
+ fop_inodelk_cbk_t inodelk_cbk;
+ fop_finodelk_cbk_t finodelk_cbk;
+ fop_entrylk_cbk_t entrylk_cbk;
+ fop_fentrylk_cbk_t fentrylk_cbk;
+ fop_rchecksum_cbk_t rchecksum_cbk;
+ fop_xattrop_cbk_t xattrop_cbk;
+ fop_fxattrop_cbk_t fxattrop_cbk;
fop_setattr_cbk_t setattr_cbk;
fop_fsetattr_cbk_t fsetattr_cbk;
fop_getspec_cbk_t getspec_cbk;
+ fop_fallocate_cbk_t fallocate_cbk;
+ fop_discard_cbk_t discard_cbk;
+ fop_zerofill_cbk_t zerofill_cbk;
};
typedef int32_t (*cbk_forget_t) (xlator_t *this,
- inode_t *inode);
+ inode_t *inode);
typedef int32_t (*cbk_release_t) (xlator_t *this,
- fd_t *fd);
+ fd_t *fd);
+
+typedef int32_t (*cbk_invalidate_t)(xlator_t *this, inode_t *inode);
+
+typedef int32_t (*cbk_client_t)(xlator_t *this, client_t *client);
struct xlator_cbks {
- cbk_forget_t forget;
- cbk_release_t release;
- cbk_release_t releasedir;
+ cbk_forget_t forget;
+ cbk_release_t release;
+ cbk_release_t releasedir;
+ cbk_invalidate_t invalidate;
+ cbk_client_t client_destroy;
+ cbk_client_t client_disconnect;
};
typedef int32_t (*dumpop_priv_t) (xlator_t *this);
@@ -733,82 +804,61 @@ typedef int32_t (*dumpop_inodectx_t) (xlator_t *this, inode_t *ino);
typedef int32_t (*dumpop_fdctx_t) (xlator_t *this, fd_t *fd);
+typedef int32_t (*dumpop_priv_to_dict_t) (xlator_t *this, dict_t *dict);
+
+typedef int32_t (*dumpop_inode_to_dict_t) (xlator_t *this, dict_t *dict);
+
+typedef int32_t (*dumpop_fd_to_dict_t) (xlator_t *this, dict_t *dict);
+
+typedef int32_t (*dumpop_inodectx_to_dict_t) (xlator_t *this, inode_t *ino,
+ dict_t *dict);
+
+typedef int32_t (*dumpop_fdctx_to_dict_t) (xlator_t *this, fd_t *fd,
+ dict_t *dict);
+
+typedef int32_t (*dumpop_eh_t) (xlator_t *this);
+
struct xlator_dumpops {
- dumpop_priv_t priv;
- dumpop_inode_t inode;
- dumpop_fd_t fd;
- dumpop_inodectx_t inodectx;
- dumpop_fdctx_t fdctx;
+ dumpop_priv_t priv;
+ dumpop_inode_t inode;
+ dumpop_fd_t fd;
+ dumpop_inodectx_t inodectx;
+ dumpop_fdctx_t fdctx;
+ dumpop_priv_to_dict_t priv_to_dict;
+ dumpop_inode_to_dict_t inode_to_dict;
+ dumpop_fd_to_dict_t fd_to_dict;
+ dumpop_inodectx_to_dict_t inodectx_to_dict;
+ dumpop_fdctx_to_dict_t fdctx_to_dict;
+ dumpop_eh_t history;
};
typedef struct xlator_list {
- xlator_t *xlator;
- struct xlator_list *next;
+ xlator_t *xlator;
+ struct xlator_list *next;
} xlator_list_t;
-/* Add possible new type of option you may need */
-typedef enum {
- GF_OPTION_TYPE_ANY = 0,
- GF_OPTION_TYPE_STR,
- GF_OPTION_TYPE_INT,
- GF_OPTION_TYPE_SIZET,
- GF_OPTION_TYPE_PERCENT,
- GF_OPTION_TYPE_PERCENT_OR_SIZET,
- GF_OPTION_TYPE_BOOL,
- GF_OPTION_TYPE_XLATOR,
- GF_OPTION_TYPE_PATH,
- GF_OPTION_TYPE_TIME,
- GF_OPTION_TYPE_DOUBLE,
- GF_OPTION_TYPE_INTERNET_ADDRESS,
-} volume_option_type_t;
-
-
-#define ZR_VOLUME_MAX_NUM_KEY 4
-#define ZR_OPTION_MAX_ARRAY_SIZE 64
-
-/* Each translator should define this structure */
-typedef struct volume_options {
- char *key[ZR_VOLUME_MAX_NUM_KEY];
- /* different key, same meaning */
- volume_option_type_t type;
- int64_t min; /* -1 means no range */
- int64_t max; /* -1 means no range */
- char *value[ZR_OPTION_MAX_ARRAY_SIZE];
- /* If specified, will check for one of
- the value from this array */
- char *description; /* about the key */
-} volume_option_t;
-
-
-typedef struct vol_opt_list {
- struct list_head list;
- volume_option_t *given_opt;
-} volume_opt_list_t;
-
struct _xlator {
- /* Built during parsing */
- char *name;
- char *type;
- xlator_t *next;
- xlator_t *prev;
- xlator_list_t *parents;
- xlator_list_t *children;
- dict_t *options;
-
- /* Set after doing dlopen() */
+ /* Built during parsing */
+ char *name;
+ char *type;
+ xlator_t *next;
+ xlator_t *prev;
+ xlator_list_t *parents;
+ xlator_list_t *children;
+ dict_t *options;
+
+ /* Set after doing dlopen() */
void *dlhandle;
- struct xlator_fops *fops;
- struct xlator_cbks *cbks;
- struct xlator_dumpops *dumpops;
- struct list_head volume_options; /* list of volume_option_t */
+ struct xlator_fops *fops;
+ struct xlator_cbks *cbks;
+ struct xlator_dumpops *dumpops;
+ struct list_head volume_options; /* list of volume_option_t */
- void (*fini) (xlator_t *this);
- int32_t (*init) (xlator_t *this);
+ void (*fini) (xlator_t *this);
+ int32_t (*init) (xlator_t *this);
int32_t (*reconfigure) (xlator_t *this, dict_t *options);
int32_t (*mem_acct_init) (xlator_t *this);
- int32_t (*validate_options) (xlator_t *this, dict_t *options,
- char **op_errstr);
event_notify_fn_t notify;
gf_loglevel_t loglevel; /* Log level for translator */
@@ -816,18 +866,43 @@ struct _xlator {
/* for latency measurement */
fop_latency_t latencies[GF_FOP_MAXVALUE];
- /* Misc */
- glusterfs_ctx_t *ctx;
- glusterfs_graph_t *graph; /* not set for fuse */
- inode_table_t *itable;
- char init_succeeded;
- void *private;
+ /* Misc */
+ eh_t *history; /* event history context */
+ glusterfs_ctx_t *ctx;
+ glusterfs_graph_t *graph; /* not set for fuse */
+ inode_table_t *itable;
+ char init_succeeded;
+ void *private;
struct mem_acct mem_acct;
+ uint64_t winds;
+ char switched;
+
+ /* for the memory pool of 'frame->local' */
+ struct mem_pool *local_pool;
+ gf_boolean_t is_autoloaded;
};
+typedef struct {
+ int32_t (*init) (xlator_t *this);
+ void (*fini) (xlator_t *this);
+ int32_t (*reconfigure) (xlator_t *this,
+ dict_t *options);
+ event_notify_fn_t notify;
+} class_methods_t;
+
#define xlator_has_parent(xl) (xl->parents != NULL)
-int validate_xlator_volume_options (xlator_t *xl, volume_option_t *opt);
+#define XLATOR_NOTIFY(_xl, params ...) \
+ do { \
+ xlator_t *_old_THIS = NULL; \
+ \
+ _old_THIS = THIS; \
+ THIS = _xl; \
+ \
+ ret = _xl->notify (_xl, params);\
+ \
+ THIS = _old_THIS; \
+ } while (0);
int32_t xlator_set_type_virtual (xlator_t *xl, const char *type);
@@ -836,7 +911,7 @@ int32_t xlator_set_type (xlator_t *xl, const char *type);
int32_t xlator_dynload (xlator_t *xl);
xlator_t *file_to_xlator_tree (glusterfs_ctx_t *ctx,
- FILE *fp);
+ FILE *fp);
int xlator_notify (xlator_t *this, int32_t event, void *data, ...);
int xlator_init (xlator_t *this);
@@ -848,9 +923,14 @@ int32_t xlator_tree_free (xlator_t *xl);
void xlator_tree_fini (xlator_t *xl);
void xlator_foreach (xlator_t *this,
- void (*fn) (xlator_t *each,
- void *data),
- void *data);
+ void (*fn) (xlator_t *each,
+ void *data),
+ void *data);
+
+void xlator_foreach_depth_first (xlator_t *this,
+ void (*fn) (xlator_t *each,
+ void *data),
+ void *data);
xlator_t *xlator_search_by_name (xlator_t *any, const char *name);
@@ -859,19 +939,22 @@ void inode_destroy_notify (inode_t *inode, const char *xlname);
int loc_copy (loc_t *dst, loc_t *src);
#define loc_dup(src, dst) loc_copy(dst, src)
void loc_wipe (loc_t *loc);
+int loc_path (loc_t *loc, const char *bname);
+void loc_gfid (loc_t *loc, uuid_t gfid);
+char* loc_gfid_utoa (loc_t *loc);
+gf_boolean_t loc_is_root (loc_t *loc);
int xlator_mem_acct_init (xlator_t *xl, int num_types);
-int xlator_tree_reconfigure (xlator_t *old_xl, xlator_t *new_xl);
int is_gf_log_command (xlator_t *trans, const char *name, char *value);
-int xlator_validate_rec (xlator_t *xlator, char **op_errstr);
-int graph_reconf_validateopt (glusterfs_graph_t *graph, char **op_errstr);
int glusterd_check_log_level (const char *value);
-
-#define GF_STAT_PRINT_FMT_STR "%"PRIx64",%"PRIx64",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx64",%"PRIx64",%"PRIx32",%"PRIx64",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32"\n"
-
-#define GF_STAT_SCAN_FMT_STR "%"SCNx64",%"SCNx64",%"SCNx32",%"SCNx32",%"SCNx32",%"SCNx32",%"SCNx64",%"SCNx64",%"SCNx32",%"SCNx64",%"SCNx32",%"SCNx32",%"SCNx32",%"SCNx32",%"SCNx32",%"SCNx32"\n"
-
-#define GF_STATFS_PRINT_FMT_STR "%"PRIx32",%"PRIx32",%"PRIx64",%"PRIx64",%"PRIx64",%"PRIx64",%"PRIx64",%"PRIx64",%"PRIx32",%"PRIx32",%"PRIx32"\n"
-
-#define GF_STATFS_SCAN_FMT_STR "%"SCNx32",%"SCNx32",%"SCNx64",%"SCNx64",%"SCNx64",%"SCNx64",%"SCNx64",%"SCNx64",%"SCNx32",%"SCNx32",%"SCNx32"\n"
-
+int xlator_volopt_dynload (char *xlator_type, void **dl_handle,
+ volume_opt_list_t *vol_opt_handle);
+enum gf_hdsk_event_notify_op {
+ GF_EN_DEFRAG_STATUS,
+ GF_EN_MAX,
+};
+gf_boolean_t
+is_graph_topology_equal (glusterfs_graph_t *graph1, glusterfs_graph_t *graph2);
+int
+glusterfs_volfile_reconfigure (int oldvollen, FILE *newvolfile_fp,
+ glusterfs_ctx_t *ctx, const char *oldvolfile);
#endif /* _XLATOR_H */