summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src
diff options
context:
space:
mode:
Diffstat (limited to 'libglusterfs/src')
-rw-r--r--libglusterfs/src/Makefile.am39
-rw-r--r--libglusterfs/src/byte-order.h23
-rw-r--r--libglusterfs/src/call-stub.c3522
-rw-r--r--libglusterfs/src/call-stub.h939
-rw-r--r--libglusterfs/src/checksum.c53
-rw-r--r--libglusterfs/src/checksum.h27
-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.c1323
-rw-r--r--libglusterfs/src/common-utils.h234
-rw-r--r--libglusterfs/src/compat-errno.c19
-rw-r--r--libglusterfs/src/compat-errno.h23
-rw-r--r--libglusterfs/src/compat.c40
-rw-r--r--libglusterfs/src/compat.h48
-rw-r--r--libglusterfs/src/ctx.c48
-rw-r--r--libglusterfs/src/daemon.c19
-rw-r--r--libglusterfs/src/daemon.h21
-rw-r--r--libglusterfs/src/defaults.c789
-rw-r--r--libglusterfs/src/defaults.h393
-rw-r--r--libglusterfs/src/dict.c679
-rw-r--r--libglusterfs/src/dict.h77
-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.c859
-rw-r--r--libglusterfs/src/event.h60
-rw-r--r--libglusterfs/src/fd-lk.c490
-rw-r--r--libglusterfs/src/fd-lk.h70
-rw-r--r--libglusterfs/src/fd.c312
-rw-r--r--libglusterfs/src/fd.h59
-rw-r--r--libglusterfs/src/gf-dirent.c19
-rw-r--r--libglusterfs/src/gf-dirent.h22
-rw-r--r--libglusterfs/src/gidcache.c192
-rw-r--r--libglusterfs/src/gidcache.h53
-rw-r--r--libglusterfs/src/globals.c297
-rw-r--r--libglusterfs/src/globals.h58
-rw-r--r--libglusterfs/src/glusterfs-acl.h81
-rw-r--r--libglusterfs/src/glusterfs.h255
-rw-r--r--libglusterfs/src/graph-print.c51
-rw-r--r--libglusterfs/src/graph-utils.h21
-rw-r--r--libglusterfs/src/graph.c282
-rw-r--r--libglusterfs/src/graph.l24
-rw-r--r--libglusterfs/src/graph.y166
-rw-r--r--libglusterfs/src/hashfn.c19
-rw-r--r--libglusterfs/src/hashfn.h21
-rw-r--r--libglusterfs/src/iatt.h39
-rw-r--r--libglusterfs/src/inode.c446
-rw-r--r--libglusterfs/src/inode.h92
-rw-r--r--libglusterfs/src/iobuf.c143
-rw-r--r--libglusterfs/src/iobuf.h53
-rw-r--r--libglusterfs/src/latency.c128
-rw-r--r--libglusterfs/src/latency.h22
-rw-r--r--libglusterfs/src/list.h61
-rw-r--r--libglusterfs/src/lkowner.h21
-rw-r--r--libglusterfs/src/locking.h19
-rw-r--r--libglusterfs/src/logging.c864
-rw-r--r--libglusterfs/src/logging.h123
-rw-r--r--libglusterfs/src/mem-pool.c120
-rw-r--r--libglusterfs/src/mem-pool.h65
-rw-r--r--libglusterfs/src/mem-types.h44
-rw-r--r--libglusterfs/src/options.c558
-rw-r--r--libglusterfs/src/options.h63
-rw-r--r--libglusterfs/src/rbthash.c26
-rw-r--r--libglusterfs/src/rbthash.h19
-rw-r--r--libglusterfs/src/run.c85
-rw-r--r--libglusterfs/src/run.h29
-rw-r--r--libglusterfs/src/scheduler.c91
-rw-r--r--libglusterfs/src/scheduler.h41
-rw-r--r--libglusterfs/src/stack.c144
-rw-r--r--libglusterfs/src/stack.h154
-rw-r--r--libglusterfs/src/statedump.c287
-rw-r--r--libglusterfs/src/statedump.h31
-rw-r--r--libglusterfs/src/store.c709
-rw-r--r--libglusterfs/src/store.h112
-rw-r--r--libglusterfs/src/syncop.c1380
-rw-r--r--libglusterfs/src/syncop.h329
-rw-r--r--libglusterfs/src/syscall.c49
-rw-r--r--libglusterfs/src/syscall.h21
-rw-r--r--libglusterfs/src/timer.c46
-rw-r--r--libglusterfs/src/timer.h23
-rw-r--r--libglusterfs/src/timespec.c68
-rw-r--r--libglusterfs/src/timespec.h24
-rw-r--r--libglusterfs/src/trie.c25
-rw-r--r--libglusterfs/src/trie.h19
-rw-r--r--libglusterfs/src/xlator.c289
-rw-r--r--libglusterfs/src/xlator.h310
89 files changed, 13579 insertions, 7652 deletions
diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am
index 34543f622..907399ae6 100644
--- a/libglusterfs/src/Makefile.am
+++ b/libglusterfs/src/Makefile.am
@@ -1,11 +1,10 @@
-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@
@@ -16,36 +15,42 @@ 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 \
- $(CONTRIBDIR)/md5/md5.c $(CONTRIBDIR)/rbtree/rb.c rbthash.c latency.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
+ 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
+
+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 \
+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)/md5/md5.h $(CONTRIBDIR)/rbtree/rb.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
+ $(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
y.tab.h: graph.y
- $(YACC) -d $(srcdir)/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 e325e522d..4101db2c7 100644
--- a/libglusterfs/src/byte-order.h
+++ b/libglusterfs/src/byte-order.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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
diff --git a/libglusterfs/src/call-stub.c b/libglusterfs/src/call-stub.c
index cdae9df25..ac79cf071 100644
--- a/libglusterfs/src/call-stub.c
+++ b/libglusterfs/src/call-stub.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -22,9 +13,9 @@
#include "config.h"
#endif
+#include <openssl/md5.h>
#include <inttypes.h>
-#include "md5.h"
#include "call-stub.h"
#include "mem-types.h"
@@ -46,16 +37,16 @@ stub_new (call_frame_t *frame,
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;
}
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;
@@ -65,26 +56,22 @@ fop_lookup_stub (call_frame_t *frame,
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;
}
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;
@@ -93,27 +80,25 @@ fop_lookup_cbk_stub (call_frame_t *frame,
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;
+ stub->fn_cbk.lookup = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
if (inode)
- stub->args.lookup_cbk.inode = inode_ref (inode);
+ stub->args_cbk.inode = inode_ref (inode);
if (buf)
- stub->args.lookup_cbk.buf = *buf;
- if (dict)
- stub->args.lookup_cbk.dict = dict_ref (dict);
+ 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;
}
-
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;
@@ -123,19 +108,19 @@ fop_stat_stub (call_frame_t *frame,
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;
}
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;
@@ -144,20 +129,21 @@ fop_stat_cbk_stub (call_frame_t *frame,
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;
+ 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.stat_cbk.buf = *buf;
+ stub->args_cbk.stat = *buf;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (xdata);
out:
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;
@@ -166,21 +152,21 @@ fop_fstat_stub (call_frame_t *frame,
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);
+ stub->args.fd = fd_ref (fd);
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
out:
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;
@@ -189,23 +175,21 @@ fop_fstat_cbk_stub (call_frame_t *frame,
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;
+ stub->fn_cbk.fstat = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
if (buf)
- stub->args.fstat_cbk.buf = *buf;
+ stub->args_cbk.stat = *buf;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (xdata);
out:
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;
@@ -215,21 +199,20 @@ fop_truncate_stub (call_frame_t *frame,
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;
}
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;
@@ -238,23 +221,23 @@ fop_truncate_cbk_stub (call_frame_t *frame,
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;
+ stub->fn_cbk.truncate = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
if (prebuf)
- stub->args.truncate_cbk.prebuf = *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;
}
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;
@@ -263,23 +246,22 @@ fop_ftruncate_stub (call_frame_t *frame,
stub = stub_new (frame, 1, GF_FOP_FTRUNCATE);
GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.ftruncate.fn = fn;
+ stub->fn.ftruncate = fn;
if (fd)
- stub->args.ftruncate.fd = fd_ref (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;
}
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;
@@ -288,23 +270,24 @@ fop_ftruncate_cbk_stub (call_frame_t *frame,
stub = stub_new (frame, 0, GF_FOP_FTRUNCATE);
GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.ftruncate_cbk.fn = fn;
- stub->args.ftruncate_cbk.op_ret = op_ret;
- stub->args.ftruncate_cbk.op_errno = op_errno;
+ stub->fn_cbk.ftruncate = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
if (prebuf)
- stub->args.ftruncate_cbk.prebuf = *prebuf;
+ stub->args_cbk.prestat = *prebuf;
if (postbuf)
- stub->args.ftruncate_cbk.postbuf = *postbuf;
+ stub->args_cbk.poststat = *postbuf;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (xdata);
+
out:
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;
@@ -314,19 +297,19 @@ fop_access_stub (call_frame_t *frame,
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;
}
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;
@@ -335,19 +318,19 @@ fop_access_cbk_stub (call_frame_t *frame,
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;
}
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;
@@ -357,21 +340,20 @@ fop_readlink_stub (call_frame_t *frame,
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;
}
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;
@@ -380,21 +362,23 @@ fop_readlink_cbk_stub (call_frame_t *frame,
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;
+ stub->fn_cbk.readlink = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
if (path)
- stub->args.readlink_cbk.buf = gf_strdup (path);
- if (sbuf)
- stub->args.readlink_cbk.sbuf = *sbuf;
+ 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;
}
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;
@@ -404,26 +388,23 @@ fop_mknod_stub (call_frame_t *frame, fop_mknod_t fn,
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;
}
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;
@@ -432,17 +413,20 @@ fop_mknod_cbk_stub (call_frame_t *frame,
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;
+ stub->fn_cbk.mknod = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
if (inode)
- stub->args.mknod_cbk.inode = inode_ref (inode);
+ stub->args_cbk.inode = inode_ref (inode);
if (buf)
- stub->args.mknod_cbk.buf = *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;
}
@@ -450,7 +434,7 @@ out:
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;
@@ -460,25 +444,23 @@ fop_mkdir_stub (call_frame_t *frame, fop_mkdir_t fn,
stub = stub_new (frame, 1, GF_FOP_MKDIR);
GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.mkdir.fn = fn;
- loc_copy (&stub->args.mkdir.loc, loc);
- stub->args.mkdir.mode = mode;
- if (params)
- stub->args.mkdir.params = dict_ref (params);
+ stub->fn.mkdir = fn;
+ loc_copy (&stub->args.loc, loc);
+ stub->args.mode = mode;
+ stub->args.umask = umask;
+
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
out:
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;
@@ -487,26 +469,27 @@ fop_mkdir_cbk_stub (call_frame_t *frame,
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;
+ stub->fn_cbk.mkdir = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
if (inode)
- stub->args.mkdir_cbk.inode = inode_ref (inode);
+ stub->args_cbk.inode = inode_ref (inode);
if (buf)
- stub->args.mkdir_cbk.buf = *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;
}
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;
@@ -516,20 +499,21 @@ fop_unlink_stub (call_frame_t *frame,
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;
}
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;
@@ -538,13 +522,15 @@ fop_unlink_cbk_stub (call_frame_t *frame,
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;
}
@@ -553,7 +539,7 @@ out:
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;
@@ -563,21 +549,21 @@ fop_rmdir_stub (call_frame_t *frame, fop_rmdir_t fn,
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;
}
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;
@@ -586,13 +572,15 @@ fop_rmdir_cbk_stub (call_frame_t *frame,
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;
}
@@ -600,7 +588,7 @@ out:
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;
@@ -611,25 +599,23 @@ fop_symlink_stub (call_frame_t *frame, fop_symlink_t fn,
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;
}
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;
@@ -638,27 +624,27 @@ fop_symlink_cbk_stub (call_frame_t *frame,
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;
+ stub->fn_cbk.symlink = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
if (inode)
- stub->args.symlink_cbk.inode = inode_ref (inode);
+ stub->args_cbk.inode = inode_ref (inode);
if (buf)
- stub->args.symlink_cbk.buf = *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;
}
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;
@@ -669,24 +655,22 @@ fop_rename_stub (call_frame_t *frame,
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;
}
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;
@@ -695,29 +679,29 @@ fop_rename_cbk_stub (call_frame_t *frame,
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;
+ stub->fn_cbk.rename = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
if (buf)
- stub->args.rename_cbk.buf = *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;
}
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;
@@ -728,24 +712,23 @@ fop_link_stub (call_frame_t *frame,
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;
}
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;
@@ -754,17 +737,19 @@ fop_link_cbk_stub (call_frame_t *frame,
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;
+ stub->fn_cbk.link = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
if (inode)
- stub->args.link_cbk.inode = inode_ref (inode);
+ stub->args_cbk.inode = inode_ref (inode);
if (buf)
- stub->args.link_cbk.buf = *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;
}
@@ -773,7 +758,7 @@ out:
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 *stub = NULL;
@@ -783,29 +768,26 @@ fop_create_stub (call_frame_t *frame, fop_create_t fn,
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;
+ 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.create.fd = fd_ref (fd);
- if (params)
- stub->args.create.params = dict_ref (params);
+ stub->args.fd = fd_ref (fd);
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
out:
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;
@@ -814,30 +796,29 @@ fop_create_cbk_stub (call_frame_t *frame,
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;
+ stub->fn_cbk.create = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
if (fd)
- stub->args.create_cbk.fd = fd_ref (fd);
+ stub->args_cbk.fd = fd_ref (fd);
if (inode)
- stub->args.create_cbk.inode = inode_ref (inode);
+ stub->args_cbk.inode = inode_ref (inode);
if (buf)
- stub->args.create_cbk.buf = *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;
}
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;
@@ -847,24 +828,22 @@ fop_open_stub (call_frame_t *frame,
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;
+ stub->fn.open = fn;
+ loc_copy (&stub->args.loc, loc);
+ stub->args.flags = flags;
if (fd)
- stub->args.open.fd = fd_ref (fd);
+ stub->args.fd = fd_ref (fd);
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
out:
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;
@@ -873,22 +852,22 @@ fop_open_cbk_stub (call_frame_t *frame,
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;
+ stub->fn_cbk.open = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
if (fd)
- stub->args.open_cbk.fd = fd_ref (fd);
+ stub->args_cbk.fd = fd_ref (fd);
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (xdata);
out:
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, uint32_t flags)
+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;
@@ -897,28 +876,25 @@ fop_readv_stub (call_frame_t *frame,
stub = stub_new (frame, 1, GF_FOP_READ);
GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.readv.fn = fn;
+ stub->fn.readv = fn;
if (fd)
- stub->args.readv.fd = fd_ref (fd);
- stub->args.readv.size = size;
- stub->args.readv.off = off;
- stub->args.readv.flags = flags;
+ stub->args.fd = fd_ref (fd);
+ stub->args.size = size;
+ stub->args.offset = off;
+ stub->args.flags = flags;
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
out:
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;
@@ -927,28 +903,26 @@ fop_readv_cbk_stub (call_frame_t *frame,
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;
+ 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.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->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;
}
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, uint32_t flags,
- 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;
@@ -958,28 +932,25 @@ fop_writev_stub (call_frame_t *frame,
stub = stub_new (frame, 1, GF_FOP_WRITE);
GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.writev.fn = fn;
+ stub->fn.writev = 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.flags = flags;
- stub->args.writev.iobref = iobref_ref (iobref);
-
+ 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;
}
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;
@@ -988,23 +959,23 @@ fop_writev_cbk_stub (call_frame_t *frame,
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;
+ 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.writev_cbk.postbuf = *postbuf;
+ 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;
}
-
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;
@@ -1013,20 +984,19 @@ fop_flush_stub (call_frame_t *frame,
stub = stub_new (frame, 1, GF_FOP_FLUSH);
GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.flush.fn = fn;
+ stub->fn.flush = fn;
if (fd)
- stub->args.flush.fd = fd_ref (fd);
+ stub->args.fd = fd_ref (fd);
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
out:
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;
@@ -1035,21 +1005,19 @@ fop_flush_cbk_stub (call_frame_t *frame,
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;
}
-
-
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;
@@ -1058,22 +1026,21 @@ fop_fsync_stub (call_frame_t *frame,
stub = stub_new (frame, 1, GF_FOP_FSYNC);
GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.fsync.fn = fn;
+ stub->fn.fsync = fn;
if (fd)
- stub->args.fsync.fd = fd_ref (fd);
- stub->args.fsync.datasync = datasync;
+ stub->args.fd = fd_ref (fd);
+ stub->args.datasync = datasync;
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
out:
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;
@@ -1082,22 +1049,23 @@ fop_fsync_cbk_stub (call_frame_t *frame,
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;
}
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;
@@ -1107,22 +1075,21 @@ fop_opendir_stub (call_frame_t *frame,
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);
+ stub->fn.opendir = fn;
+ loc_copy (&stub->args.loc, loc);
if (fd)
- stub->args.opendir.fd = fd_ref (fd);
+ stub->args.fd = fd_ref (fd);
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
out:
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;
@@ -1131,22 +1098,22 @@ fop_opendir_cbk_stub (call_frame_t *frame,
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);
+ stub->args_cbk.fd = fd_ref (fd);
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (xdata);
out:
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;
@@ -1155,21 +1122,20 @@ fop_fsyncdir_stub (call_frame_t *frame,
stub = stub_new (frame, 1, GF_FOP_FSYNCDIR);
GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.fsyncdir.fn = fn;
+ stub->fn.fsyncdir = fn;
if (fd)
- stub->args.fsyncdir.fd = fd_ref (fd);
- stub->args.fsyncdir.datasync = datasync;
+ stub->args.fd = fd_ref (fd);
+ stub->args.datasync = datasync;
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
out:
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;
@@ -1178,18 +1144,19 @@ fop_fsyncdir_cbk_stub (call_frame_t *frame,
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;
}
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;
@@ -1199,20 +1166,19 @@ fop_statfs_stub (call_frame_t *frame,
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;
}
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;
@@ -1221,22 +1187,22 @@ fop_statfs_cbk_stub (call_frame_t *frame,
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;
+ 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.statfs_cbk.buf = *buf;
+ stub->args_cbk.statvfs = *buf;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (xdata);
out:
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;
@@ -1246,12 +1212,14 @@ fop_setxattr_stub (call_frame_t *frame,
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);
+ stub->fn.setxattr = fn;
+ loc_copy (&stub->args.loc, loc);
/* TODO */
if (dict)
- stub->args.setxattr.dict = dict_ref (dict);
- stub->args.setxattr.flags = flags;
+ stub->args.xattr = dict_ref (dict);
+ stub->args.flags = flags;
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
out:
return stub;
}
@@ -1261,7 +1229,7 @@ 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 *stub = NULL;
@@ -1270,18 +1238,19 @@ fop_setxattr_cbk_stub (call_frame_t *frame,
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;
}
+
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;
@@ -1291,22 +1260,22 @@ fop_getxattr_stub (call_frame_t *frame,
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);
+ stub->args.name = gf_strdup (name);
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
out:
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;
@@ -1315,23 +1284,22 @@ fop_getxattr_cbk_stub (call_frame_t *frame,
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;
+ stub->fn_cbk.getxattr = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
/* TODO */
if (dict)
- stub->args.getxattr_cbk.dict = dict_ref (dict);
+ stub->args_cbk.xattr = dict_ref (dict);
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (xdata);
out:
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;
@@ -1341,23 +1309,22 @@ fop_fsetxattr_stub (call_frame_t *frame,
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;
+ stub->args.xattr = dict_ref (dict);
+ stub->args.flags = flags;
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
out:
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;
@@ -1366,19 +1333,19 @@ fop_fsetxattr_cbk_stub (call_frame_t *frame,
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;
}
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;
@@ -1388,22 +1355,22 @@ fop_fgetxattr_stub (call_frame_t *frame,
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);
+ stub->args.name = gf_strdup (name);
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
out:
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;
@@ -1412,23 +1379,22 @@ fop_fgetxattr_cbk_stub (call_frame_t *frame,
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);
+ stub->args_cbk.xattr = dict_ref (dict);
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (xdata);
out:
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;
@@ -1439,19 +1405,19 @@ fop_removexattr_stub (call_frame_t *frame,
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;
}
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;
@@ -1460,18 +1426,19 @@ fop_removexattr_cbk_stub (call_frame_t *frame,
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;
}
+
call_stub_t *
-fop_fremovexattr_stub (call_frame_t *frame,
- fop_fremovexattr_t fn,
- fd_t *fd,
- const char *name)
+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;
@@ -1482,19 +1449,19 @@ fop_fremovexattr_stub (call_frame_t *frame,
stub = stub_new (frame, 1, GF_FOP_FREMOVEXATTR);
GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.fremovexattr.fn = fn;
- stub->args.fremovexattr.fd = fd_ref (fd);
- stub->args.fremovexattr.name = gf_strdup (name);
+ 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;
}
call_stub_t *
-fop_fremovexattr_cbk_stub (call_frame_t *frame,
- fop_fremovexattr_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno)
+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;
@@ -1503,19 +1470,20 @@ fop_fremovexattr_cbk_stub (call_frame_t *frame,
stub = stub_new (frame, 0, GF_FOP_FREMOVEXATTR);
GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.fremovexattr_cbk.fn = fn;
- stub->args.fremovexattr_cbk.op_ret = op_ret;
- stub->args.fremovexattr_cbk.op_errno = op_errno;
+ 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)
+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;
@@ -1525,23 +1493,22 @@ fop_lk_stub (call_frame_t *frame,
stub = stub_new (frame, 1, GF_FOP_LK);
GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.lk.fn = fn;
+ stub->fn.lk = fn;
if (fd)
- stub->args.lk.fd = fd_ref (fd);
- stub->args.lk.cmd = cmd;
- stub->args.lk.lock = *lock;
+ 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;
}
call_stub_t *
-fop_lk_cbk_stub (call_frame_t *frame,
- fop_lk_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct gf_flock *lock)
-
+fop_lk_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;
@@ -1550,18 +1517,22 @@ fop_lk_cbk_stub (call_frame_t *frame,
stub = stub_new (frame, 0, 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;
+ 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.lk_cbk.lock = *lock;
+ stub->args_cbk.lock = *lock;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (xdata);
out:
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)
+ const char *volume, loc_t *loc, int32_t cmd,
+ struct gf_flock *lock, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1571,21 +1542,24 @@ fop_inodelk_stub (call_frame_t *frame, fop_inodelk_t fn,
stub = stub_new (frame, 1, GF_FOP_INODELK);
GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.inodelk.fn = fn;
+ stub->fn.inodelk = fn;
if (volume)
- stub->args.inodelk.volume = gf_strdup (volume);
+ stub->args.volume = gf_strdup (volume);
- loc_copy (&stub->args.inodelk.loc, loc);
- stub->args.inodelk.cmd = cmd;
- stub->args.inodelk.lock = *lock;
+ 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;
@@ -1594,10 +1568,12 @@ fop_inodelk_cbk_stub (call_frame_t *frame, fop_inodelk_cbk_t fn,
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;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (xdata);
out:
return stub;
}
@@ -1605,7 +1581,8 @@ out:
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;
@@ -1615,17 +1592,19 @@ fop_finodelk_stub (call_frame_t *frame, fop_finodelk_t fn,
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);
+ stub->args.fd = fd_ref (fd);
if (volume)
- stub->args.finodelk.volume = gf_strdup (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;
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
out:
return stub;
}
@@ -1633,7 +1612,7 @@ out:
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;
@@ -1642,10 +1621,12 @@ fop_finodelk_cbk_stub (call_frame_t *frame, fop_inodelk_cbk_t fn,
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;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (xdata);
out:
return stub;
}
@@ -1654,7 +1635,7 @@ out:
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)
+ entrylk_cmd cmd, entrylk_type type, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1663,25 +1644,29 @@ fop_entrylk_stub (call_frame_t *frame, fop_entrylk_t fn,
stub = stub_new (frame, 1, GF_FOP_ENTRYLK);
GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.entrylk.fn = fn;
+ stub->fn.entrylk = fn;
if (volume)
- stub->args.entrylk.volume = gf_strdup (volume);
+ stub->args.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);
+ stub->args.name = gf_strdup (name);
+ 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;
@@ -1690,10 +1675,12 @@ fop_entrylk_cbk_stub (call_frame_t *frame, fop_entrylk_cbk_t fn,
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;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (xdata);
out:
return stub;
}
@@ -1702,7 +1689,7 @@ out:
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)
+ entrylk_cmd cmd, entrylk_type type, dict_t *xdata)
{
call_stub_t *stub = NULL;
@@ -1711,25 +1698,28 @@ fop_fentrylk_stub (call_frame_t *frame, fop_fentrylk_t fn,
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);
+ 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;
+ stub->args.fd = fd_ref (fd);
+ stub->args.entrylkcmd = cmd;
+ stub->args.entrylktype = type;
if (name)
- stub->args.fentrylk.name = gf_strdup (name);
+ stub->args.name = gf_strdup (name);
+ 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;
@@ -1738,21 +1728,21 @@ fop_fentrylk_cbk_stub (call_frame_t *frame, fop_fentrylk_cbk_t fn,
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;
+ 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;
@@ -1762,14 +1752,10 @@ fop_readdirp_cbk_stub (call_frame_t *frame,
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.
- */
GF_VALIDATE_OR_GOTO ("call-stub", entries, out);
if (op_ret > 0) {
@@ -1780,21 +1766,23 @@ fop_readdirp_cbk_stub (call_frame_t *frame,
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.readdirp_cbk.entries.list);
+ &stub->args_cbk.entries.list);
}
}
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (xdata);
out:
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;
@@ -1804,14 +1792,10 @@ fop_readdir_cbk_stub (call_frame_t *frame,
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.
- */
GF_VALIDATE_OR_GOTO ("call-stub", entries, out);
if (op_ret > 0) {
@@ -1823,62 +1807,61 @@ fop_readdir_cbk_stub (call_frame_t *frame,
stub_entry->d_ino = entry->d_ino;
list_add_tail (&stub_entry->list,
- &stub->args.readdir_cbk.entries.list);
+ &stub->args_cbk.entries.list);
}
}
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (xdata);
out:
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;
stub = stub_new (frame, 1, GF_FOP_READDIR);
GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.readdir.fn = fn;
- stub->args.readdir.fd = fd_ref (fd);
- stub->args.readdir.size = size;
- stub->args.readdir.off = off;
+ stub->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,
- dict_t *dict)
+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;
stub = stub_new (frame, 1, GF_FOP_READDIRP);
GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.readdirp.fn = fn;
- stub->args.readdirp.fd = fd_ref (fd);
- stub->args.readdirp.size = size;
- stub->args.readdirp.off = off;
- stub->args.readdirp.dict = dict;
-
+ 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;
@@ -1888,22 +1871,22 @@ fop_rchecksum_stub (call_frame_t *frame,
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;
}
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;
@@ -1912,28 +1895,27 @@ fop_rchecksum_cbk_stub (call_frame_t *frame,
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.rchecksum_cbk.strong_checksum =
- memdup (strong_checksum, MD5_DIGEST_LEN);
+ stub->args_cbk.strong_checksum =
+ memdup (strong_checksum, MD5_DIGEST_LENGTH);
}
+
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (xdata);
out:
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;
@@ -1942,21 +1924,21 @@ fop_xattrop_cbk_stub (call_frame_t *frame,
stub = stub_new (frame, 0, GF_FOP_XATTROP);
GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.xattrop_cbk.fn = fn;
- stub->args.xattrop_cbk.op_ret = op_ret;
- stub->args.xattrop_cbk.op_errno = op_errno;
+ 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;
}
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);
@@ -1964,23 +1946,23 @@ fop_fxattrop_cbk_stub (call_frame_t *frame,
stub = stub_new (frame, 0, GF_FOP_FXATTROP);
GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.fxattrop_cbk.fn = fn;
- stub->args.fxattrop_cbk.op_ret = op_ret;
- stub->args.fxattrop_cbk.op_errno = op_errno;
+ stub->fn_cbk.fxattrop = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
if (xattr)
- stub->args.fxattrop_cbk.xattr = dict_ref (xattr);
+ stub->args_cbk.xattr = dict_ref (xattr);
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (xdata);
out:
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;
@@ -1990,23 +1972,24 @@ fop_xattrop_stub (call_frame_t *frame,
stub = stub_new (frame, 1, GF_FOP_XATTROP);
GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.xattrop.fn = fn;
+ stub->fn.xattrop = 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);
+ 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;
@@ -2016,25 +1999,25 @@ fop_fxattrop_stub (call_frame_t *frame,
stub = stub_new (frame, 1, GF_FOP_FXATTROP);
GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.fxattrop.fn = fn;
+ stub->fn.fxattrop = 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);
+ 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;
@@ -2043,27 +2026,28 @@ fop_setattr_cbk_stub (call_frame_t *frame,
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;
}
+
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;
@@ -2072,25 +2056,26 @@ fop_fsetattr_cbk_stub (call_frame_t *frame,
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;
}
+
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;
@@ -2100,25 +2085,26 @@ fop_setattr_stub (call_frame_t *frame,
stub = stub_new (frame, 1, GF_FOP_SETATTR);
GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- stub->args.setattr.fn = fn;
+ stub->fn.setattr = 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;
}
+
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;
@@ -2128,1779 +2114,695 @@ fop_fsetattr_stub (call_frame_t *frame,
stub = stub_new (frame, 1, GF_FOP_FSETATTR);
GF_VALIDATE_OR_GOTO ("call-stub", stub, 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;
}
-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)
{
+ call_stub_t *stub = NULL;
+
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+
+ stub = stub_new (frame, 0, GF_FOP_FALLOCATE);
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;
- }
+ stub->fn_cbk.fallocate = fn;
- case GF_FOP_MKNOD:
- {
- stub->args.mknod.fn (stub->frame, stub->frame->this,
- &stub->args.mknod.loc,
- stub->args.mknod.mode,
- stub->args.mknod.rdev,
- stub->args.mknod.params);
- }
- break;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
- 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;
+ 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_UNLINK:
- {
- stub->args.unlink.fn (stub->frame,
- stub->frame->this,
- &stub->args.unlink.loc);
- }
- break;
+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;
- case GF_FOP_RMDIR:
- {
- stub->args.rmdir.fn (stub->frame, stub->frame->this,
- &stub->args.rmdir.loc,
- stub->args.rmdir.flags);
- }
- break;
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", fn, out);
- case GF_FOP_SYMLINK:
- {
- stub->args.symlink.fn (stub->frame,
- stub->frame->this,
- stub->args.symlink.linkname,
- &stub->args.symlink.loc,
- stub->args.symlink.params);
- }
- break;
+ stub = stub_new (frame, 1, GF_FOP_FALLOCATE);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- case GF_FOP_RENAME:
- {
- stub->args.rename.fn (stub->frame,
- stub->frame->this,
- &stub->args.rename.old,
- &stub->args.rename.new);
- }
- break;
+ stub->fn.fallocate = fn;
- case GF_FOP_LINK:
- {
- stub->args.link.fn (stub->frame,
- stub->frame->this,
- &stub->args.link.oldloc,
- &stub->args.link.newloc);
- }
- break;
+ if (fd)
+ stub->args.fd = fd_ref (fd);
- case GF_FOP_TRUNCATE:
- {
- stub->args.truncate.fn (stub->frame,
- stub->frame->this,
- &stub->args.truncate.loc,
- stub->args.truncate.off);
- break;
- }
+ stub->args.flags = mode;
+ stub->args.offset = offset;
+ stub->args.size = len;
- 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,
- stub->args.readv.flags);
- break;
- }
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
+out:
+ return stub;
- 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.flags,
- 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;
- }
+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;
- case GF_FOP_FSYNC:
- {
- stub->args.fsync.fn (stub->frame,
- stub->frame->this,
- stub->args.fsync.fd,
- stub->args.fsync.datasync);
- break;
- }
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- case GF_FOP_SETXATTR:
- {
- stub->args.setxattr.fn (stub->frame,
- stub->frame->this,
- &stub->args.setxattr.loc,
- stub->args.setxattr.dict,
- stub->args.setxattr.flags);
- break;
- }
+ stub = stub_new (frame, 0, GF_FOP_DISCARD);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- case GF_FOP_GETXATTR:
- {
- stub->args.getxattr.fn (stub->frame,
- stub->frame->this,
- &stub->args.getxattr.loc,
- stub->args.getxattr.name);
- break;
- }
+ stub->fn_cbk.discard = fn;
- case GF_FOP_FSETXATTR:
- {
- stub->args.fsetxattr.fn (stub->frame,
- stub->frame->this,
- stub->args.fsetxattr.fd,
- stub->args.fsetxattr.dict,
- stub->args.fsetxattr.flags);
- break;
- }
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
- case GF_FOP_FGETXATTR:
- {
- stub->args.fgetxattr.fn (stub->frame,
- stub->frame->this,
- stub->args.fgetxattr.fd,
- stub->args.fgetxattr.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_REMOVEXATTR:
- {
- stub->args.removexattr.fn (stub->frame,
- stub->frame->this,
- &stub->args.removexattr.loc,
- stub->args.removexattr.name);
- break;
- }
+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;
- case GF_FOP_FREMOVEXATTR:
- {
- stub->args.fremovexattr.fn (stub->frame,
- stub->frame->this,
- stub->args.fremovexattr.fd,
- stub->args.fremovexattr.name);
- break;
- }
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", fn, out);
- case GF_FOP_OPENDIR:
- {
- stub->args.opendir.fn (stub->frame,
- stub->frame->this,
- &stub->args.opendir.loc,
- stub->args.opendir.fd);
- break;
- }
+ stub = stub_new (frame, 1, GF_FOP_DISCARD);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- case GF_FOP_FSYNCDIR:
- {
- stub->args.fsyncdir.fn (stub->frame,
- stub->frame->this,
- stub->args.fsyncdir.fd,
- stub->args.fsyncdir.datasync);
- break;
- }
+ stub->fn.discard = fn;
- case GF_FOP_ACCESS:
- {
- stub->args.access.fn (stub->frame,
- stub->frame->this,
- &stub->args.access.loc,
- stub->args.access.mask);
- break;
- }
+ if (fd)
+ stub->args.fd = fd_ref (fd);
- case GF_FOP_FTRUNCATE:
- {
- stub->args.ftruncate.fn (stub->frame,
- stub->frame->this,
- stub->args.ftruncate.fd,
- stub->args.ftruncate.off);
- break;
- }
+ stub->args.offset = offset;
+ stub->args.size = len;
- case GF_FOP_FSTAT:
- {
- stub->args.fstat.fn (stub->frame,
- stub->frame->this,
- stub->args.fstat.fd);
- break;
- }
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
+out:
+ return stub;
- 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;
- }
+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;
- 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;
- }
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- 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;
- }
+ stub = stub_new (frame, 0, GF_FOP_ZEROFILL);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- 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;
- }
+ stub->fn_cbk.zerofill = fn;
- break;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
- case GF_FOP_LOOKUP:
- {
- stub->args.lookup.fn (stub->frame,
- stub->frame->this,
- &stub->args.lookup.loc,
- stub->args.lookup.xattr_req);
- 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_RCHECKSUM:
- {
- stub->args.rchecksum.fn (stub->frame,
- stub->frame->this,
- stub->args.rchecksum.fd,
- stub->args.rchecksum.offset,
- stub->args.rchecksum.len);
- 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_READDIR:
- {
- stub->args.readdir.fn (stub->frame,
- stub->frame->this,
- stub->args.readdir.fd,
- stub->args.readdir.size,
- stub->args.readdir.off);
- break;
- }
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", fn, out);
- case GF_FOP_READDIRP:
- {
- stub->args.readdirp.fn (stub->frame,
- stub->frame->this,
- stub->args.readdirp.fd,
- stub->args.readdirp.size,
- stub->args.readdirp.off,
- stub->args.readdirp.dict);
- break;
- }
+ stub = stub_new (frame, 1, GF_FOP_ZEROFILL);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, 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->fn.zerofill = fn;
- 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);
+ if (fd)
+ stub->args.fd = fd_ref (fd);
- break;
- }
- case GF_FOP_SETATTR:
- {
- stub->args.setattr.fn (stub->frame,
- stub->frame->this,
- &stub->args.setattr.loc,
- &stub->args.setattr.stbuf,
- stub->args.setattr.valid);
- break;
- }
- case GF_FOP_FSETATTR:
- {
- stub->args.fsetattr.fn (stub->frame,
- stub->frame->this,
- stub->args.fsetattr.fd,
- &stub->args.fsetattr.stbuf,
- stub->args.fsetattr.valid);
- break;
- }
- default:
- {
- gf_log_callingfn ("call-stub", GF_LOG_ERROR,
- "Invalid value of FOP (%d)",
- stub->fop);
- break;
- }
+ stub->args.offset = offset;
+ stub->args.size = len;
- }
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
out:
- return;
-}
+ return stub;
+}
static void
-call_resume_unwind (call_stub_t *stub)
+call_resume_wind (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);
+ 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:
- {
- 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);
-
+ 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:
- {
- 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->fn.stat (stub->frame, stub->frame->this,
+ &stub->args.loc, stub->args.xdata);
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.readlink (stub->frame, stub->frame->this,
+ &stub->args.loc, stub->args.size,
+ stub->args.xdata);
break;
- }
-
case GF_FOP_MKNOD:
- {
- if (!stub->args.mknod_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.mknod_cbk.op_ret,
- stub->args.mknod_cbk.op_errno,
- stub->args.mknod_cbk.inode,
- &stub->args.mknod_cbk.buf,
- &stub->args.mknod_cbk.preparent,
- &stub->args.mknod_cbk.postparent);
- else
- stub->args.mknod_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.mknod_cbk.op_ret,
- stub->args.mknod_cbk.op_errno,
- stub->args.mknod_cbk.inode,
- &stub->args.mknod_cbk.buf,
- &stub->args.mknod_cbk.preparent,
- &stub->args.mknod_cbk.postparent);
- break;
- }
-
+ stub->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:
- {
- if (!stub->args.mkdir_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.mkdir_cbk.op_ret,
- stub->args.mkdir_cbk.op_errno,
- stub->args.mkdir_cbk.inode,
- &stub->args.mkdir_cbk.buf,
- &stub->args.mkdir_cbk.preparent,
- &stub->args.mkdir_cbk.postparent);
- else
- stub->args.mkdir_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.mkdir_cbk.op_ret,
- stub->args.mkdir_cbk.op_errno,
- stub->args.mkdir_cbk.inode,
- &stub->args.mkdir_cbk.buf,
- &stub->args.mkdir_cbk.preparent,
- &stub->args.mkdir_cbk.postparent);
-
- if (stub->args.mkdir_cbk.inode)
- inode_unref (stub->args.mkdir_cbk.inode);
-
- break;
- }
-
+ stub->fn.mkdir (stub->frame, stub->frame->this,
+ &stub->args.loc, stub->args.mode,
+ stub->args.umask, stub->args.xdata);
+ 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;
- }
-
+ stub->fn.unlink (stub->frame, stub->frame->this,
+ &stub->args.loc, stub->args.xflag,
+ stub->args.xdata);
+ 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;
- }
-
+ stub->fn.rmdir (stub->frame, stub->frame->this,
+ &stub->args.loc, stub->args.flags,
+ stub->args.xdata);
+ 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;
-
+ 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:
- {
- if (!stub->args.rename_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.rename_cbk.op_ret,
- stub->args.rename_cbk.op_errno,
- &stub->args.rename_cbk.buf,
- &stub->args.rename_cbk.preoldparent,
- &stub->args.rename_cbk.postoldparent,
- &stub->args.rename_cbk.prenewparent,
- &stub->args.rename_cbk.postnewparent);
- else
- stub->args.rename_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.rename_cbk.op_ret,
- stub->args.rename_cbk.op_errno,
- &stub->args.rename_cbk.buf,
- &stub->args.rename_cbk.preoldparent,
- &stub->args.rename_cbk.postoldparent,
- &stub->args.rename_cbk.prenewparent,
- &stub->args.rename_cbk.postnewparent);
- break;
- }
-
+ stub->fn.rename (stub->frame, stub->frame->this,
+ &stub->args.loc, &stub->args.loc2,
+ stub->args.xdata);
+ 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;
- }
-
+ stub->fn.link (stub->frame, stub->frame->this,
+ &stub->args.loc, &stub->args.loc2,
+ stub->args.xdata);
+ 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);
+ stub->fn.truncate (stub->frame, stub->frame->this,
+ &stub->args.loc, stub->args.offset,
+ stub->args.xdata);
break;
- }
-
case GF_FOP_READ:
- {
- if (!stub->args.readv_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.readv_cbk.op_ret,
- stub->args.readv_cbk.op_errno,
- stub->args.readv_cbk.vector,
- stub->args.readv_cbk.count,
- &stub->args.readv_cbk.stbuf,
- stub->args.readv_cbk.iobref);
- else
- stub->args.readv_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.readv_cbk.op_ret,
- stub->args.readv_cbk.op_errno,
- stub->args.readv_cbk.vector,
- stub->args.readv_cbk.count,
- &stub->args.readv_cbk.stbuf,
- stub->args.readv_cbk.iobref);
- }
- break;
-
+ stub->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:
- {
- 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);
+ 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:
- {
- 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;
-
+ stub->fn.statfs (stub->frame, stub->frame->this,
+ &stub->args.loc, stub->args.xdata);
+ 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);
-
+ stub->fn.flush (stub->frame, stub->frame->this,
+ stub->args.fd, stub->args.xdata);
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);
+ stub->fn.fsync (stub->frame, stub->frame->this,
+ stub->args.fd, stub->args.datasync,
+ stub->args.xdata);
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->fn.setxattr (stub->frame, stub->frame->this,
+ &stub->args.loc, stub->args.xattr,
+ stub->args.flags, stub->args.xdata);
break;
- }
-
case GF_FOP_GETXATTR:
- {
- if (!stub->args.getxattr_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);
+ stub->fn.getxattr (stub->frame, stub->frame->this,
+ &stub->args.loc, stub->args.name,
+ stub->args.xdata);
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);
-
+ stub->fn.fsetxattr (stub->frame, stub->frame->this,
+ stub->args.fd, stub->args.xattr,
+ stub->args.flags, stub->args.xdata);
break;
- }
-
case GF_FOP_FGETXATTR:
- {
- if (!stub->args.fgetxattr_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);
+ stub->fn.fgetxattr (stub->frame, stub->frame->this,
+ stub->args.fd, stub->args.name,
+ stub->args.xdata);
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);
-
+ stub->fn.removexattr (stub->frame, stub->frame->this,
+ &stub->args.loc, stub->args.name,
+ stub->args.xdata);
break;
- }
-
case GF_FOP_FREMOVEXATTR:
- {
- if (!stub->args.fremovexattr_cbk.fn)
- STACK_UNWIND (stub->frame,
- stub->args.fremovexattr_cbk.op_ret,
- stub->args.fremovexattr_cbk.op_errno);
- else
- stub->args.fremovexattr_cbk.fn (stub->frame,
- stub->frame->cookie,
- stub->frame->this,
- stub->args.fremovexattr_cbk.op_ret,
- stub->args.fremovexattr_cbk.op_errno);
-
+ stub->fn.fremovexattr (stub->frame, stub->frame->this,
+ stub->args.fd, stub->args.name,
+ stub->args.xdata);
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);
+ stub->fn.opendir (stub->frame, stub->frame->this,
+ &stub->args.loc, stub->args.fd,
+ stub->args.xdata);
break;
- }
-
case GF_FOP_FSYNCDIR:
- {
- if (!stub->args.fsyncdir_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);
+ stub->fn.fsyncdir (stub->frame, stub->frame->this,
+ stub->args.fd, stub->args.datasync,
+ stub->args.xdata);
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);
-
+ stub->fn.access (stub->frame, stub->frame->this,
+ &stub->args.loc, stub->args.mask,
+ stub->args.xdata);
break;
- }
case GF_FOP_FTRUNCATE:
- {
- if (!stub->args.ftruncate_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);
+ stub->fn.ftruncate (stub->frame, stub->frame->this,
+ stub->args.fd, stub->args.offset,
+ stub->args.xdata);
break;
- }
-
case GF_FOP_FSTAT:
- {
- if (!stub->args.fstat_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);
-
+ stub->fn.fstat (stub->frame, stub->frame->this,
+ stub->args.fd, stub->args.xdata);
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);
+ stub->fn.lk (stub->frame, stub->frame->this,
+ stub->args.fd, stub->args.cmd,
+ &stub->args.lock, stub->args.xdata);
break;
- }
-
case GF_FOP_INODELK:
- {
- if (!stub->args.inodelk_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);
+ stub->fn.inodelk (stub->frame, stub->frame->this,
+ stub->args.volume, &stub->args.loc,
+ stub->args.cmd, &stub->args.lock,
+ stub->args.xdata);
break;
- }
-
case GF_FOP_FINODELK:
- {
- if (!stub->args.finodelk_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);
+ stub->fn.finodelk (stub->frame, stub->frame->this,
+ stub->args.volume, stub->args.fd,
+ stub->args.cmd, &stub->args.lock,
+ stub->args.xdata);
break;
- }
-
case GF_FOP_ENTRYLK:
- {
- if (!stub->args.entrylk_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);
+ stub->fn.entrylk (stub->frame, stub->frame->this,
+ stub->args.volume, &stub->args.loc,
+ stub->args.name, stub->args.entrylkcmd,
+ stub->args.entrylktype, stub->args.xdata);
break;
- }
-
case GF_FOP_FENTRYLK:
- {
- if (!stub->args.fentrylk_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;
- }
-
+ 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:
- {
- 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);
-
+ stub->fn.lookup (stub->frame, stub->frame->this,
+ &stub->args.loc, stub->args.xdata);
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->fn.rchecksum (stub->frame, stub->frame->this,
+ stub->args.fd, stub->args.offset,
+ stub->args.size, stub->args.xdata);
break;
- }
-
case GF_FOP_READDIR:
- {
- if (!stub->args.readdir_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.readdir (stub->frame, stub->frame->this,
+ stub->args.fd, stub->args.size,
+ stub->args.offset, stub->args.xdata);
break;
- }
-
case GF_FOP_READDIRP:
- {
- if (!stub->args.readdirp_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);
-
+ 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:
- {
- 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);
-
+ stub->fn.xattrop (stub->frame, stub->frame->this,
+ &stub->args.loc, stub->args.optype,
+ stub->args.xattr, stub->args.xdata);
break;
- }
case GF_FOP_FXATTROP:
- {
- if (!stub->args.fxattrop_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);
-
+ 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:
- {
- 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);
+ 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_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);
+ 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_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_wind (call_stub_t *stub)
+call_resume_unwind (call_stub_t *stub)
{
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+
switch (stub->fop) {
case GF_FOP_OPEN:
- {
- loc_wipe (&stub->args.open.loc);
- if (stub->args.open.fd)
- fd_unref (stub->args.open.fd);
+ STUB_UNWIND (stub, open, stub->args_cbk.fd,
+ stub->args_cbk.xdata);
break;
- }
case GF_FOP_CREATE:
- {
- loc_wipe (&stub->args.create.loc);
- if (stub->args.create.fd)
- fd_unref (stub->args.create.fd);
- if (stub->args.create.params)
- dict_unref (stub->args.create.params);
+ 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:
- {
- loc_wipe (&stub->args.stat.loc);
+ STUB_UNWIND (stub, stat, &stub->args_cbk.stat,
+ stub->args_cbk.xdata);
break;
- }
case GF_FOP_READLINK:
- {
- loc_wipe (&stub->args.readlink.loc);
- break;
- }
-
+ STUB_UNWIND (stub, readlink, stub->args_cbk.buf,
+ &stub->args_cbk.stat, stub->args.xdata);
+ break;
case GF_FOP_MKNOD:
- {
- loc_wipe (&stub->args.mknod.loc);
- if (stub->args.mknod.params)
- dict_unref (stub->args.mknod.params);
- }
- break;
-
+ STUB_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:
- {
- loc_wipe (&stub->args.mkdir.loc);
- if (stub->args.mkdir.params)
- dict_unref (stub->args.mkdir.params);
- }
- break;
-
+ STUB_UNWIND (stub, mkdir, stub->args_cbk.inode,
+ &stub->args_cbk.stat, &stub->args_cbk.preparent,
+ &stub->args_cbk.postparent, stub->args_cbk.xdata);
+ break;
case GF_FOP_UNLINK:
- {
- loc_wipe (&stub->args.unlink.loc);
- }
- break;
-
+ STUB_UNWIND (stub, unlink, &stub->args_cbk.preparent,
+ &stub->args_cbk.postparent, stub->args_cbk.xdata);
+ break;
case GF_FOP_RMDIR:
- {
- loc_wipe (&stub->args.rmdir.loc);
- }
- break;
-
+ STUB_UNWIND (stub, rmdir, &stub->args_cbk.preparent,
+ &stub->args_cbk.postparent, stub->args_cbk.xdata);
+ break;
case GF_FOP_SYMLINK:
- {
- GF_FREE ((char *)stub->args.symlink.linkname);
- loc_wipe (&stub->args.symlink.loc);
- if (stub->args.symlink.params)
- dict_unref (stub->args.symlink.params);
- }
- break;
-
+ STUB_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:
- {
- loc_wipe (&stub->args.rename.old);
- loc_wipe (&stub->args.rename.new);
- }
- break;
-
+ STUB_UNWIND (stub, rename, &stub->args_cbk.stat,
+ &stub->args_cbk.preparent,
+ &stub->args_cbk.postparent,
+ &stub->args_cbk.preparent2,
+ &stub->args_cbk.postparent2,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_LINK:
- {
- loc_wipe (&stub->args.link.oldloc);
- loc_wipe (&stub->args.link.newloc);
- }
- break;
-
+ STUB_UNWIND (stub, link, stub->args_cbk.inode,
+ &stub->args_cbk.stat, &stub->args_cbk.preparent,
+ &stub->args_cbk.postparent, stub->args_cbk.xdata);
+ break;
case GF_FOP_TRUNCATE:
- {
- loc_wipe (&stub->args.truncate.loc);
- break;
- }
-
+ STUB_UNWIND (stub, truncate, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
case GF_FOP_READ:
- {
- if (stub->args.readv.fd)
- fd_unref (stub->args.readv.fd);
- break;
- }
-
+ STUB_UNWIND (stub, readv, stub->args_cbk.vector,
+ stub->args_cbk.count, &stub->args_cbk.stat,
+ stub->args_cbk.iobref, stub->args_cbk.xdata);
+ break;
case GF_FOP_WRITE:
- {
- struct iobref *iobref = stub->args.writev.iobref;
- if (stub->args.writev.fd)
- fd_unref (stub->args.writev.fd);
- GF_FREE (stub->args.writev.vector);
- if (iobref)
- iobref_unref (iobref);
- break;
- }
-
+ STUB_UNWIND (stub, writev, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
case GF_FOP_STATFS:
- {
- loc_wipe (&stub->args.statfs.loc);
- break;
- }
+ STUB_UNWIND (stub, statfs, &stub->args_cbk.statvfs,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_FLUSH:
- {
- if (stub->args.flush.fd)
- fd_unref (stub->args.flush.fd);
- break;
- }
-
+ STUB_UNWIND (stub, flush, stub->args_cbk.xdata);
+ break;
case GF_FOP_FSYNC:
- {
- if (stub->args.fsync.fd)
- fd_unref (stub->args.fsync.fd);
- break;
- }
-
+ STUB_UNWIND (stub, fsync, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
case GF_FOP_SETXATTR:
- {
- loc_wipe (&stub->args.setxattr.loc);
- if (stub->args.setxattr.dict)
- dict_unref (stub->args.setxattr.dict);
- break;
- }
-
+ STUB_UNWIND (stub, setxattr, stub->args_cbk.xdata);
+ break;
case GF_FOP_GETXATTR:
- {
- if (stub->args.getxattr.name)
- GF_FREE ((char *)stub->args.getxattr.name);
- loc_wipe (&stub->args.getxattr.loc);
- break;
- }
-
+ STUB_UNWIND (stub, getxattr, stub->args_cbk.xattr,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_FSETXATTR:
- {
- fd_unref (stub->args.fsetxattr.fd);
- if (stub->args.fsetxattr.dict)
- dict_unref (stub->args.fsetxattr.dict);
- break;
- }
-
+ STUB_UNWIND (stub, fsetxattr, stub->args_cbk.xdata);
+ break;
case GF_FOP_FGETXATTR:
- {
- if (stub->args.fgetxattr.name)
- GF_FREE ((char *)stub->args.fgetxattr.name);
- fd_unref (stub->args.fgetxattr.fd);
- break;
- }
-
+ STUB_UNWIND (stub, fgetxattr, stub->args_cbk.xattr,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_REMOVEXATTR:
- {
- loc_wipe (&stub->args.removexattr.loc);
- GF_FREE ((char *)stub->args.removexattr.name);
- break;
- }
-
+ STUB_UNWIND (stub, removexattr, stub->args_cbk.xdata);
+ break;
case GF_FOP_FREMOVEXATTR:
- {
- fd_unref (stub->args.fremovexattr.fd);
- GF_FREE ((char *)stub->args.fremovexattr.name);
- break;
- }
-
+ STUB_UNWIND (stub, fremovexattr, stub->args_cbk.xdata);
+ break;
case GF_FOP_OPENDIR:
- {
- loc_wipe (&stub->args.opendir.loc);
- if (stub->args.opendir.fd)
- fd_unref (stub->args.opendir.fd);
- break;
- }
-
+ STUB_UNWIND (stub, opendir, stub->args_cbk.fd,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_FSYNCDIR:
- {
- if (stub->args.fsyncdir.fd)
- fd_unref (stub->args.fsyncdir.fd);
+ STUB_UNWIND (stub, fsyncdir, stub->args_cbk.xdata);
break;
- }
-
case GF_FOP_ACCESS:
- {
- loc_wipe (&stub->args.access.loc);
+ STUB_UNWIND (stub, access, stub->args_cbk.xdata);
break;
- }
-
case GF_FOP_FTRUNCATE:
- {
- if (stub->args.ftruncate.fd)
- fd_unref (stub->args.ftruncate.fd);
+ STUB_UNWIND (stub, ftruncate, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
break;
- }
-
case GF_FOP_FSTAT:
- {
- if (stub->args.fstat.fd)
- fd_unref (stub->args.fstat.fd);
+ STUB_UNWIND (stub, fstat, &stub->args_cbk.stat,
+ stub->args_cbk.xdata);
break;
- }
-
case GF_FOP_LK:
- {
- if (stub->args.lk.fd)
- fd_unref (stub->args.lk.fd);
- break;
- }
-
+ STUB_UNWIND (stub, lk, &stub->args_cbk.lock,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_INODELK:
- {
- if (stub->args.inodelk.volume)
- GF_FREE ((char *)stub->args.inodelk.volume);
-
- loc_wipe (&stub->args.inodelk.loc);
+ STUB_UNWIND (stub, inodelk, stub->args_cbk.xdata);
break;
- }
case GF_FOP_FINODELK:
- {
- if (stub->args.finodelk.volume)
- GF_FREE ((char *)stub->args.finodelk.volume);
-
- if (stub->args.finodelk.fd)
- fd_unref (stub->args.finodelk.fd);
+ STUB_UNWIND (stub, finodelk, stub->args_cbk.xdata);
break;
- }
case GF_FOP_ENTRYLK:
- {
- if (stub->args.entrylk.volume)
- GF_FREE ((char *)stub->args.entrylk.volume);
-
- if (stub->args.entrylk.name)
- GF_FREE ((char *)stub->args.entrylk.name);
- loc_wipe (&stub->args.entrylk.loc);
- break;
- }
+ STUB_UNWIND (stub, entrylk, stub->args_cbk.xdata);
+ break;
case GF_FOP_FENTRYLK:
- {
- if (stub->args.fentrylk.volume)
- GF_FREE ((char *)stub->args.fentrylk.volume);
-
- if (stub->args.fentrylk.name)
- GF_FREE ((char *)stub->args.fentrylk.name);
-
- if (stub->args.fentrylk.fd)
- fd_unref (stub->args.fentrylk.fd);
+ STUB_UNWIND (stub, fentrylk, stub->args_cbk.xdata);
break;
- }
-
case GF_FOP_LOOKUP:
- {
- loc_wipe (&stub->args.lookup.loc);
- if (stub->args.lookup.xattr_req)
- dict_unref (stub->args.lookup.xattr_req);
+ STUB_UNWIND (stub, lookup, stub->args_cbk.inode,
+ &stub->args_cbk.stat, stub->args_cbk.xdata,
+ &stub->args_cbk.postparent);
break;
- }
-
case GF_FOP_RCHECKSUM:
- {
- if (stub->args.rchecksum.fd)
- fd_unref (stub->args.rchecksum.fd);
- break;
- }
-
+ STUB_UNWIND (stub, rchecksum, stub->args_cbk.weak_checksum,
+ stub->args_cbk.strong_checksum, stub->args_cbk.xdata);
+ break;
case GF_FOP_READDIR:
- {
- if (stub->args.readdir.fd)
- fd_unref (stub->args.readdir.fd);
- break;
- }
-
+ STUB_UNWIND (stub, readdir, &stub->args_cbk.entries,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_READDIRP:
- {
- if (stub->args.readdirp.fd)
- fd_unref (stub->args.readdirp.fd);
+ STUB_UNWIND (stub, readdir, &stub->args_cbk.entries,
+ stub->args_cbk.xdata);
break;
- }
-
case GF_FOP_XATTROP:
- {
- loc_wipe (&stub->args.xattrop.loc);
- dict_unref (stub->args.xattrop.xattr);
- break;
- }
+ STUB_UNWIND (stub, xattrop, stub->args_cbk.xattr,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_FXATTROP:
- {
- if (stub->args.fxattrop.fd)
- fd_unref (stub->args.fxattrop.fd);
- dict_unref (stub->args.fxattrop.xattr);
- break;
- }
+ STUB_UNWIND (stub, fxattrop, stub->args_cbk.xattr,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_SETATTR:
- {
- loc_wipe (&stub->args.setattr.loc);
+ STUB_UNWIND (stub, setattr, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
break;
- }
case GF_FOP_FSETATTR:
- {
- if (stub->args.fsetattr.fd)
- fd_unref (stub->args.fsetattr.fd);
+ STUB_UNWIND (stub, fsetattr, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
+ case GF_FOP_FALLOCATE:
+ STUB_UNWIND(stub, fallocate, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
+ case GF_FOP_DISCARD:
+ STUB_UNWIND(stub, discard, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
+ case GF_FOP_ZEROFILL:
+ STUB_UNWIND(stub, zerofill, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
break;
- }
+
default:
- {
gf_log_callingfn ("call-stub", GF_LOG_ERROR,
"Invalid value of FOP (%d)",
stub->fop);
break;
}
- }
+out:
+ return;
}
static void
-call_stub_destroy_unwind (call_stub_t *stub)
+call_stub_wipe_args (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;
-
- 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:
- break;
-
- case GF_FOP_RMDIR:
- break;
-
- case GF_FOP_SYMLINK:
- {
- if (stub->args.symlink_cbk.inode)
- inode_unref (stub->args.symlink_cbk.inode);
- }
- break;
-
- case GF_FOP_RENAME:
- break;
-
- case GF_FOP_LINK:
- {
- if (stub->args.link_cbk.inode)
- inode_unref (stub->args.link_cbk.inode);
- }
- break;
-
- case GF_FOP_TRUNCATE:
- 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:
- break;
-
- case GF_FOP_STATFS:
- break;
-
- case GF_FOP_FLUSH:
- break;
-
- case GF_FOP_FSYNC:
- break;
-
- case GF_FOP_SETXATTR:
- break;
-
- case GF_FOP_GETXATTR:
- {
- if (stub->args.getxattr_cbk.dict)
- dict_unref (stub->args.getxattr_cbk.dict);
- }
- break;
+ loc_wipe (&stub->args.loc);
- case GF_FOP_FSETXATTR:
- break;
+ loc_wipe (&stub->args.loc2);
- case GF_FOP_FGETXATTR:
- {
- if (stub->args.fgetxattr_cbk.dict)
- dict_unref (stub->args.fgetxattr_cbk.dict);
- }
- break;
+ if (stub->args.fd)
+ fd_unref (stub->args.fd);
- case GF_FOP_REMOVEXATTR:
- break;
- case GF_FOP_FREMOVEXATTR:
- break;
+ GF_FREE ((char *)stub->args.linkname);
- case GF_FOP_OPENDIR:
- {
- if (stub->args.opendir_cbk.fd)
- fd_unref (stub->args.opendir_cbk.fd);
- }
- break;
+ GF_FREE (stub->args.vector);
- case GF_FOP_FSYNCDIR:
- break;
+ if (stub->args.iobref)
+ iobref_unref (stub->args.iobref);
- case GF_FOP_ACCESS:
- break;
+ if (stub->args.xattr)
+ dict_unref (stub->args.xattr);
- case GF_FOP_FTRUNCATE:
- break;
+ GF_FREE ((char *)stub->args.name);
- case GF_FOP_FSTAT:
- break;
+ GF_FREE ((char *)stub->args.volume);
- case GF_FOP_LK:
- break;
+ if (stub->args.xdata)
+ dict_unref (stub->args.xdata);
+}
- case GF_FOP_INODELK:
- break;
- case GF_FOP_FINODELK:
- break;
+static void
+call_stub_wipe_args_cbk (call_stub_t *stub)
+{
+ if (stub->args_cbk.inode)
+ inode_unref (stub->args_cbk.inode);
- case GF_FOP_ENTRYLK:
- break;
+ GF_FREE ((char *)stub->args_cbk.buf);
- case GF_FOP_FENTRYLK:
- break;
+ GF_FREE (stub->args_cbk.vector);
- case GF_FOP_LOOKUP:
- {
- if (stub->args.lookup_cbk.inode)
- inode_unref (stub->args.lookup_cbk.inode);
+ if (stub->args_cbk.iobref)
+ iobref_unref (stub->args_cbk.iobref);
- if (stub->args.lookup_cbk.dict)
- dict_unref (stub->args.lookup_cbk.dict);
- }
- break;
+ if (stub->args_cbk.fd)
+ fd_unref (stub->args_cbk.fd);
- case GF_FOP_RCHECKSUM:
- {
- if (stub->args.rchecksum_cbk.op_ret >= 0) {
- GF_FREE (stub->args.rchecksum_cbk.strong_checksum);
- }
- }
- break;
+ if (stub->args_cbk.xattr)
+ dict_unref (stub->args_cbk.xattr);
- case GF_FOP_READDIR:
- {
- if (stub->args.readdir_cbk.op_ret > 0) {
- gf_dirent_free (&stub->args.readdir_cbk.entries);
- }
- }
- break;
+ GF_FREE (stub->args_cbk.strong_checksum);
- case GF_FOP_READDIRP:
- {
- if (stub->args.readdirp_cbk.op_ret > 0) {
- gf_dirent_free (&stub->args.readdirp_cbk.entries);
- }
- }
- break;
+ if (stub->args_cbk.xdata)
+ dict_unref (stub->args_cbk.xdata);
- 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;
- }
-
- case GF_FOP_FSETATTR:
- {
- break;
- }
-
- default:
- {
- gf_log_callingfn ("call-stub", GF_LOG_ERROR,
- "Invalid value of FOP (%d)",
- stub->fop);
- break;
- }
- }
+ if (!list_empty (&stub->args_cbk.entries.list))
+ gf_dirent_free (&stub->args_cbk.entries);
}
@@ -3909,18 +2811,19 @@ call_stub_destroy (call_stub_t *stub)
{
GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
- if (stub->wind) {
- call_stub_destroy_wind (stub);
- } else {
- call_stub_destroy_unwind (stub);
- }
+ if (stub->wind)
+ call_stub_wipe_args (stub);
+ else
+ call_stub_wipe_args_cbk (stub);
stub->stub_mem_pool = NULL;
+
mem_put (stub);
out:
return;
}
+
void
call_resume (call_stub_t *stub)
{
@@ -3945,3 +2848,26 @@ call_resume (call_stub_t *stub)
out:
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 081f6d200..45bef8044 100644
--- a/libglusterfs/src/call-stub.h
+++ b/libglusterfs/src/call-stub.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CALL_STUB_H_
@@ -34,576 +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;
- uint32_t flags;
- } 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;
- uint32_t flags;
- 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;
-
-
- /* fremovexattr */
- struct {
- fop_fremovexattr_t fn;
- fd_t *fd;
- const char *name;
- } fremovexattr;
- struct {
- fop_fremovexattr_cbk_t fn;
- int32_t op_ret, op_errno;
- } fremovexattr_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;
- dict_t *dict;
- } 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,
@@ -612,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,
@@ -647,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,
@@ -661,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,
@@ -687,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,
@@ -701,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,
@@ -715,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,
@@ -728,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,
@@ -740,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,
@@ -754,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,
@@ -771,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,
@@ -787,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,
@@ -803,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,
@@ -811,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, uint32_t flags);
+ off_t off, uint32_t flags, dict_t *xdata);
call_stub_t *
fop_readv_cbk_stub (call_frame_t *frame,
@@ -835,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,
@@ -844,7 +422,7 @@ fop_writev_stub (call_frame_t *frame,
struct iovec *vector,
int32_t count,
off_t off, uint32_t flags,
- struct iobref *iobref);
+ struct iobref *iobref, dict_t *xdata);
call_stub_t *
fop_writev_cbk_stub (call_frame_t *frame,
@@ -852,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,
@@ -877,177 +455,177 @@ 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);
+ 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);
+ 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);
+ 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);
+ 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,
@@ -1055,27 +633,27 @@ fop_readdirp_stub (call_frame_t *frame,
fd_t *fd,
size_t size,
off_t off,
- dict_t *dict);
+ 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,
@@ -1083,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,
@@ -1124,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,
@@ -1139,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 cea782293..e14a3044c 100644
--- a/libglusterfs/src/checksum.c
+++ b/libglusterfs/src/checksum.c
@@ -1,28 +1,17 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
-#include <inttypes.h>
+#include <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 3542036bf..bf7eeede8 100644
--- a/libglusterfs/src/checksum.h
+++ b/libglusterfs/src/checksum.h
@@ -1,27 +1,20 @@
/*
- Copyright (c) 2010-2011 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 General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef __CHECKSUM_H__
#define __CHECKSUM_H__
-uint32_t gf_rsync_weak_checksum (char *buf, int32_t len);
+uint32_t
+gf_rsync_weak_checksum (unsigned char *buf, size_t len);
-void gf_rsync_strong_checksum (char *buf, int32_t len, uint8_t *sum);
+void
+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 068bd8460..827475282 100644
--- a/libglusterfs/src/common-utils.c
+++ b/libglusterfs/src/common-utils.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -52,8 +43,9 @@
#include "glusterfs.h"
#include "stack.h"
#include "globals.h"
-#include "md5.h"
#include "lkowner.h"
+#include "syscall.h"
+#include <ifaddrs.h>
#ifndef AI_ADDRCONFIG
#define AI_ADDRCONFIG 0
@@ -67,6 +59,99 @@ struct dnscache6 {
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)
@@ -123,7 +208,9 @@ gf_resolve_ip6 (const char *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);
if (-1 == ret) {
@@ -192,28 +279,101 @@ err:
}
+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);
+ ctx = THIS->ctx;
+ xld.logfp = ctx->log.gf_log_logfile;
- fprintf (gf_log_logfile, "Given volfile:\n");
- fprintf (gf_log_logfile,
+ fprintf (ctx->log.gf_log_logfile, "Final graph:\n");
+ fprintf (ctx->log.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+---------------------------------------"
+
+ xlator_foreach_depth_first (graph->top, xldump, &xld);
+
+ fprintf (ctx->log.gf_log_logfile,
+ "+---------------------------------------"
"---------------------------------------+\n");
- fflush (gf_log_logfile);
- fseek (specfp, 0L, SEEK_SET);
+ fflush (ctx->log.gf_log_logfile);
}
static void
@@ -348,26 +508,31 @@ out:
/* 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);
+ 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;
{
- 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);
@@ -375,10 +540,10 @@ gf_print_trace (int32_t signum)
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",
+ else
+ sprintf (msg,"frame : type(%d) op(%d)\n",
tmp->root->type,
- gf_mgmt_list[tmp->root->op]);
+ tmp->root->op);
ret = write (fd, msg, strlen (msg));
if (ret < 0)
@@ -404,9 +569,7 @@ gf_print_trace (int32_t signum)
{
/* 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;
@@ -562,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;
@@ -616,6 +778,8 @@ gf_string2time (const char *str, uint32_t *n)
old_errno = errno;
errno = 0;
value = strtol (str, &tail, 0);
+ if (str == tail)
+ errno = EINVAL;
if (errno == ERANGE || errno == EINVAL)
return -1;
@@ -634,11 +798,10 @@ gf_string2time (const char *str, uint32_t *n)
return 0;
}
-
int
-gf_string2percent (const char *str, uint32_t *n)
+gf_string2percent (const char *str, double *n)
{
- unsigned long value = 0;
+ double value = 0;
char *tail = NULL;
int old_errno = 0;
const char *s = NULL;
@@ -659,7 +822,9 @@ gf_string2percent (const char *str, uint32_t *n)
old_errno = errno;
errno = 0;
- value = strtol (str, &tail, 0);
+ value = strtod (str, &tail);
+ if (str == tail)
+ errno = EINVAL;
if (errno == ERANGE || errno == EINVAL)
return -1;
@@ -693,6 +858,8 @@ _gf_string2long (const char *str, long *n, int base)
old_errno = errno;
errno = 0;
value = strtol (str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
if (errno == ERANGE || errno == EINVAL)
return -1;
@@ -733,6 +900,8 @@ _gf_string2ulong (const char *str, unsigned long *n, int base)
old_errno = errno;
errno = 0;
value = strtoul (str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
if (errno == ERANGE || errno == EINVAL)
return -1;
@@ -773,6 +942,8 @@ _gf_string2uint (const char *str, unsigned int *n, int base)
old_errno = errno;
errno = 0;
value = strtoul (str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
if (errno == ERANGE || errno == EINVAL)
return -1;
@@ -804,6 +975,8 @@ _gf_string2double (const char *str, double *n)
old_errno = errno;
errno = 0;
value = strtod (str, &tail);
+ if (str == tail)
+ errno = EINVAL;
if (errno == ERANGE || errno == EINVAL)
return -1;
@@ -835,6 +1008,8 @@ _gf_string2longlong (const char *str, long long *n, int base)
old_errno = errno;
errno = 0;
value = strtoll (str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
if (errno == ERANGE || errno == EINVAL)
return -1;
@@ -875,6 +1050,8 @@ _gf_string2ulonglong (const char *str, unsigned long long *n, int base)
old_errno = errno;
errno = 0;
value = strtoull (str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
if (errno == ERANGE || errno == EINVAL)
return -1;
@@ -948,7 +1125,7 @@ gf_string2int8 (const char *str, int8_t *n)
if (rv != 0)
return rv;
- if (l >= INT8_MIN && l <= INT8_MAX) {
+ if ((l >= INT8_MIN) && (l <= INT8_MAX)) {
*n = (int8_t) l;
return 0;
}
@@ -967,7 +1144,7 @@ gf_string2int16 (const char *str, int16_t *n)
if (rv != 0)
return rv;
- if (l >= INT16_MIN && l <= INT16_MAX) {
+ if ((l >= INT16_MIN) && (l <= INT16_MAX)) {
*n = (int16_t) l;
return 0;
}
@@ -986,7 +1163,7 @@ gf_string2int32 (const char *str, int32_t *n)
if (rv != 0)
return rv;
- if (l >= INT32_MIN && l <= INT32_MAX) {
+ if ((l >= INT32_MIN) && (l <= INT32_MAX)) {
*n = (int32_t) l;
return 0;
}
@@ -1005,7 +1182,7 @@ gf_string2int64 (const char *str, int64_t *n)
if (rv != 0)
return rv;
- if (l >= INT64_MIN && l <= INT64_MAX) {
+ if ((l >= INT64_MIN) && (l <= INT64_MAX)) {
*n = (int64_t) l;
return 0;
}
@@ -1217,7 +1394,7 @@ err:
int
gf_string2bytesize (const char *str, uint64_t *n)
{
- uint64_t value = 0ULL;
+ double value = 0.0;
char *tail = NULL;
int old_errno = 0;
const char *s = NULL;
@@ -1238,7 +1415,9 @@ gf_string2bytesize (const char *str, uint64_t *n)
old_errno = errno;
errno = 0;
- value = strtoull (str, &tail, 10);
+ value = strtod (str, &tail);
+ if (str == tail)
+ errno = EINVAL;
if (errno == ERANGE || errno == EINVAL)
return -1;
@@ -1262,7 +1441,77 @@ gf_string2bytesize (const char *str, uint64_t *n)
return -1;
}
- *n = value;
+ if ((UINT64_MAX - value) < 0) {
+ errno = ERANGE;
+ return -1;
+ }
+
+ *n = (uint64_t) value;
+
+ 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;
}
@@ -1528,64 +1777,112 @@ get_nth_word (const char *str, int n)
return word;
}
-/* RFC 1123 & 952 */
-
-/* The functions below validate given internet addresses and
- * wildcard internet address for correctness.
- * All return 1 on success and 0 on failure
- */
-
+/* 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;
- char ret = 0;
- int flag = 0;
+ int i = 0;
+ int str_len = 0;
+ char ret = 1;
+ char *dup_addr = NULL;
+ char *temp_str = NULL;
+ char *save_ptr = NULL;
- if ((length > 255) || (length == 1))
+ if ((length > _POSIX_HOST_NAME_MAX) || (length < 1)) {
+ ret = 0;
goto out;
+ }
- if (!isalnum (address[length - 1]))
+ dup_addr = gf_strdup (address);
+ if (!dup_addr) {
+ ret = 0;
goto out;
+ }
- for (i = 0; i < length; i++) {
- if (!isalnum (address[i]) && (address[i] != '.')
- && (address[i] != '-'))
- goto out;
+ if (!isalnum (dup_addr[length - 1]) && (dup_addr[length - 1] != '*')) {
+ ret = 0;
+ goto out;
+ }
- if (isalpha(address[i]))
- flag = 1;
+ /* Check for consecutive dots, which is invalid in a hostname and is
+ * ignored by strtok()
+ */
+ if (strstr (dup_addr, "..")) {
+ ret = 0;
+ goto out;
}
- if (flag)
- ret = 1;
+ /* 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)
+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 = 0;
+ 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++;
- value = strtol (prev, &endptr, 10);
- if ((value > 255) || (value < 0) ||
- (endptr != NULL && *endptr != '\0'))
- goto out;
+ 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)
- ret = 1;
+ if ((octets > 4) || (octets < 4 && !is_wildcard)) {
+ ret = 0;
+ }
out:
GF_FREE (tmp);
@@ -1593,27 +1890,55 @@ out:
}
char
-valid_ipv6_address (char *address, int length)
+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 = 0;
+ 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++;
- value = strtol (prev, &endptr, 16);
- if ((value > 0xffff) || (value < 0)
- || (endptr != NULL && *endptr != '\0'))
- goto out;
+ 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)
- ret = 1;
+ if ((hex_numbers > 8) || (hex_numbers < 8 && !is_wildcard
+ && !is_compressed)) {
+ ret = 0;
+ }
out:
GF_FREE (tmp);
@@ -1621,7 +1946,7 @@ out:
}
char
-valid_internet_address (char *address)
+valid_internet_address (char *address, gf_boolean_t wildcard_acc)
{
char ret = 0;
int length = 0;
@@ -1635,8 +1960,8 @@ valid_internet_address (char *address)
if (length == 0)
goto out;
- if (valid_ipv4_address (address, length)
- || valid_ipv6_address (address, length)
+ if (valid_ipv4_address (address, length, wildcard_acc)
+ || valid_ipv6_address (address, length, wildcard_acc)
|| valid_host_name (address, length))
ret = 1;
@@ -1644,109 +1969,55 @@ out:
return ret;
}
-char
-valid_ipv4_wildcard_check (char *address)
+/**
+ * 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)
{
- char ret = 0;
- int octets = 0;
- char *tmp = NULL;
- char *prev = NULL;
- char *endptr = NULL;
- int value = 0;
- int is_wildcard = 0;
-
- tmp = gf_strdup (address);
- prev = strtok (tmp, ".");
-
- while (prev != NULL) {
- octets++;
-
- if (!strcmp (prev, "*")) {
- is_wildcard = 1;
- } else {
- value = strtol (prev, &endptr, 10);
-
- if ((value > 255) || (value < 0) ||
- (endptr != NULL && *endptr != '\0'))
- goto out;
- }
- prev = strtok (NULL, ".");
+ if (!a || !b) {
+ gf_log ("common-utils", GF_LOG_ERROR, "Invalid arguments"
+ " to gf_sock_union_equal_addr");
+ return _gf_false;
}
- if (is_wildcard && (octets <= 4))
- ret = 1;
-
-out:
- if (tmp)
- GF_FREE (tmp);
- return ret;
-
-}
+ if (a->storage.ss_family != b->storage.ss_family)
+ return _gf_false;
-char
-valid_ipv6_wildcard_check (char *address)
-{
- char ret = 0;
- int hex_numbers = 0;
- int value = 0;
- char *tmp = NULL;
- char *prev = NULL;
- char *endptr = NULL;
- int is_wildcard = 0;
-
- tmp = gf_strdup (address);
- prev = strtok (tmp, ":");
-
- while (prev != NULL) {
- hex_numbers++;
-
- if (!strcmp (prev, "*")) {
- is_wildcard = 1;
- } else {
- value = strtol (prev, &endptr, 16);
-
- if ((value > 0xffff) || (value < 0) ||
- (endptr != NULL && *endptr != '\0'))
- goto out;
- }
- prev = strtok (NULL, ":");
- }
-
- if (is_wildcard && (hex_numbers <= 8))
- ret = 1;
-out:
- if (tmp)
- GF_FREE (tmp);
- return ret;
-}
+ 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;
-char
-valid_wildcard_internet_address (char *address)
-{
- char ret = 0;
+ 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;
- if (address == NULL) {
- gf_log_callingfn (THIS->name, GF_LOG_WARNING,
- "argument invalid");
- goto out;
+ default:
+ gf_log ("common-utils", GF_LOG_DEBUG,
+ "Unsupported/invalid address family");
+ break;
}
- if (strlen (address) == 0)
- goto out;
-
- if (valid_ipv4_wildcard_check (address) ||
- valid_ipv6_wildcard_check (address))
- ret = 1;
-
-out:
- return ret;
+ return _gf_false;
}
/*Thread safe conversion function*/
char *
uuid_utoa (uuid_t uuid)
{
- char *uuid_buffer = glusterfs_uuid_buf_get();
+ char *uuid_buffer = glusterfs_uuid_buf_get(THIS->ctx);
uuid_unparse (uuid, uuid_buffer);
return uuid_buffer;
}
@@ -1765,7 +2036,7 @@ uuid_utoa_r (uuid_t uuid, char *dst)
char *
lkowner_utoa (gf_lkowner_t *lkowner)
{
- char *lkowner_buffer = glusterfs_lkowner_buf_get();
+ char *lkowner_buffer = glusterfs_lkowner_buf_get(THIS->ctx);
lkowner_unparse (lkowner, lkowner_buffer, GF_LKOWNER_BUF_SIZE);
return lkowner_buffer;
}
@@ -1780,19 +2051,6 @@ lkowner_utoa_r (gf_lkowner_t *lkowner, char *dst, int len)
return dst;
}
-void _get_md5_str (char *out_str, size_t outlen,
- const uint8_t *input, int n)
-{
- uint8_t out[MD5_DIGEST_LEN] = {0};
- int j = 0;
-
- GF_ASSERT (outlen >= (2*MD5_DIGEST_LEN + 1));
- get_md5 (out, input, n);
- for (j = 0; j < MD5_DIGEST_LEN; j++)
- snprintf(out_str + j * 2, outlen-j*2, "%02x", out[j]);
-
-}
-
void* gf_array_elem (void *a, int index, size_t elem_size)
{
uint8_t* ptr = a;
@@ -1855,8 +2113,7 @@ gf_is_str_int (const char *value)
}
out:
- if (fptr)
- GF_FREE (fptr);
+ GF_FREE (fptr);
return flag;
}
@@ -1866,9 +2123,9 @@ out:
*/
inline int32_t
-gf_roundup_power_of_two (uint32_t nr)
+gf_roundup_power_of_two (int32_t nr)
{
- uint32_t result = 1;
+ int32_t result = 1;
if (nr < 0) {
gf_log ("common-utils", GF_LOG_WARNING,
@@ -1889,13 +2146,8 @@ out:
* power of two is returned.
*/
-/*
- * 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 (uint32_t nr)
+gf_roundup_next_power_of_two (int32_t nr)
{
int32_t result = 1;
@@ -1998,10 +2250,659 @@ get_mem_size ()
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_client_pid_check (gf_client_pid_t npid)
+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)
{
- return ( (npid > GF_CLIENT_PID_MIN) && (npid < GF_CLIENT_PID_MAX) )
- ? 0 : -1;
+ 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 63566fb53..3c99a4212 100644
--- a/libglusterfs/src/common-utils.h
+++ b/libglusterfs/src/common-utils.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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,6 +23,7 @@
#include <string.h>
#include <assert.h>
#include <pthread.h>
+#include <openssl/md5.h>
#ifndef GF_BSD_HOST_OS
#include <alloca.h>
#endif
@@ -69,9 +61,13 @@ 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"
+
#define WIPE(statp) do { typeof(*statp) z = {0,}; if (statp) *statp = z; } while (0)
#define IS_EXT_FS(fs_name) \
@@ -79,6 +75,12 @@ void trap (void);
!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,
@@ -97,7 +99,7 @@ enum _gf_client_pid
GF_CLIENT_PID_MAX = 0,
GF_CLIENT_PID_GSYNCD = -1,
GF_CLIENT_PID_HADOOP = -2,
- GF_CLIENT_PID_MIN = -3
+ GF_CLIENT_PID_DEFRAG = -3,
};
typedef enum _gf_boolean gf_boolean_t;
@@ -108,15 +110,14 @@ 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; \
@@ -126,7 +127,7 @@ extern char *gf_mgmt_list[GF_MGMT_MAXVALUE];
"invalid argument: " #arg); \
goto label; \
} \
- } while (0);
+ } while (0)
#define GF_VALIDATE_OR_GOTO(name,arg,label) do { \
if (!arg) { \
@@ -135,7 +136,7 @@ extern char *gf_mgmt_list[GF_MGMT_MAXVALUE];
"invalid argument: " #arg); \
goto label; \
} \
- } while (0);
+ } while (0)
#define GF_VALIDATE_OR_GOTO_WITH_ERROR(name, arg, label, errno, error) do { \
if (!arg) { \
@@ -144,15 +145,15 @@ extern char *gf_mgmt_list[GF_MGMT_MAXVALUE];
"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) \
+ GF_ASSERT (0); \
errno = error; \
goto label; \
} \
- }while (0);
+ }while (0)
#define GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO(name,arg,label) \
do { \
@@ -163,7 +164,7 @@ extern char *gf_mgmt_list[GF_MGMT_MAXVALUE];
"invalid argument: " #arg); \
goto label; \
} \
- } while (0);
+ } while (0)
#define GF_REMOVE_SLASH_FROM_PATH(path, string) \
do { \
@@ -173,28 +174,44 @@ extern char *gf_mgmt_list[GF_MGMT_MAXVALUE];
if (string[i-1] == '/') \
string[i-1] = '-'; \
} \
- } while (0); \
-
+ } while (0)
-#define GF_IF_INTERNAL_XATTR_GOTO(pattern, dict, trav, op_errno, label) \
- do{ \
+#define GF_IF_INTERNAL_XATTR_GOTO(pattern, dict, op_errno, label) \
+ do { \
if (!dict) { \
- gf_log (THIS->name, GF_LOG_ERROR, \
+ gf_log (this->name, GF_LOG_ERROR, \
"setxattr dict is null"); \
goto label; \
} \
- trav = dict->members_list; \
- while (trav) { \
- if (!fnmatch (pattern, trav->key, 0)) { \
- gf_log (THIS->name, GF_LOG_ERROR, \
- "attempt to set internal" \
- " xattr: %s", trav->key); \
- op_errno = EPERM; \
- goto label; \
- } \
- trav = trav->next; \
+ 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); \
+ } 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)
@@ -208,7 +225,7 @@ extern char *gf_mgmt_list[GF_MGMT_MAXVALUE];
gf_log_callingfn ("", GF_LOG_ERROR, \
"Assertion failed: " #x); \
} \
- } while (0);
+ } while (0)
#endif
#define GF_UUID_ASSERT(u) \
@@ -250,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;
@@ -330,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)
{
@@ -375,19 +451,52 @@ 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
*/
-int32_t gf_roundup_power_of_two (uint32_t 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 (uint32_t nr);
+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,
@@ -421,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);
@@ -442,20 +553,20 @@ void skip_word (char **str);
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);
-char valid_ipv6_address (char *address, int length);
-char valid_internet_address (char *address);
+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 _get_md5_str (char *out_str, size_t outlen,
- const uint8_t *input, int n);
void gf_array_insertionsort (void *a, int l, int r, size_t elem_size,
gf_cmp cmp);
int gf_is_str_int (const char *value);
@@ -466,5 +577,18 @@ 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_client_pid_check (gf_client_pid_t npid);
+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 2aeb3d805..fd5cc49ce 100644
--- a/libglusterfs/src/compat-errno.c
+++ b/libglusterfs/src/compat-errno.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
diff --git a/libglusterfs/src/compat-errno.h b/libglusterfs/src/compat-errno.h
index a61457960..65e52081d 100644
--- a/libglusterfs/src/compat-errno.h
+++ b/libglusterfs/src/compat-errno.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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__
diff --git a/libglusterfs/src/compat.c b/libglusterfs/src/compat.c
index 20e165a7a..eb6d8d4b7 100644
--- a/libglusterfs/src/compat.c
+++ b/libglusterfs/src/compat.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -151,8 +142,7 @@ done:
*path = export_path;
}
out:
- if (freeptr)
- GF_FREE (freeptr);
+ GF_FREE (freeptr);
if (ret && export_path)
GF_FREE (export_path);
@@ -204,8 +194,7 @@ solaris_xattr_resolve_path (const char *real_path, char **path)
*path = gf_strdup (xattr_path);
}
out:
- if (export_path)
- GF_FREE (export_path);
+ GF_FREE (export_path);
if (*path)
return 0;
else
@@ -239,8 +228,7 @@ solaris_setxattr(const char *path, const char* key, const char *value,
path, errno);
ret = -1;
}
- if (mapped_path)
- GF_FREE (mapped_path);
+ GF_FREE (mapped_path);
return ret;
}
@@ -306,8 +294,7 @@ solaris_listxattr(const char *path, char *list, size_t size)
close (attrdirfd);
}
out:
- if (mapped_path)
- GF_FREE (mapped_path);
+ GF_FREE (mapped_path);
return len;
}
@@ -389,8 +376,7 @@ solaris_removexattr(const char *path, const char* key)
ret = -1;
}
- if (mapped_path)
- GF_FREE (mapped_path);
+ GF_FREE (mapped_path);
return ret;
}
@@ -430,8 +416,7 @@ solaris_getxattr(const char *path,
errno = ENODATA;
ret = -1;
}
- if (mapped_path)
- GF_FREE (mapped_path);
+ GF_FREE (mapped_path);
return ret;
}
@@ -503,8 +488,7 @@ int solaris_unlink (const char *path)
}
out:
- if (mapped_path)
- GF_FREE (mapped_path);
+ GF_FREE (mapped_path);
return unlink (path);
}
diff --git a/libglusterfs/src/compat.h b/libglusterfs/src/compat.h
index cb71d32ce..2bd982541 100644
--- a/libglusterfs/src/compat.h
+++ b/libglusterfs/src/compat.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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,6 +32,12 @@
#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
@@ -116,13 +113,6 @@ enum {
#define F_SETLK64 F_SETLK
#define F_SETLKW64 F_SETLKW
-#ifdef __NetBSD__
-char *basename_r(const char *);
-char *dirname_r(char *);
-
-#define basename(path) basename_r(path)
-#define dirname(path) dirname_r(path)
-#endif /* __NetBSD__ */
#endif /* GF_BSD_HOST_OS */
#ifdef GF_DARWIN_HOST_OS
@@ -350,6 +340,18 @@ dirent_size (struct dirent *entry)
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 */
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
index 778196164..348e3ad40 100644
--- a/libglusterfs/src/daemon.c
+++ b/libglusterfs/src/daemon.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#include <fcntl.h>
diff --git a/libglusterfs/src/daemon.h b/libglusterfs/src/daemon.h
index bf1d67cca..80836a326 100644
--- a/libglusterfs/src/daemon.h
+++ b/libglusterfs/src/daemon.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010-2011 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 General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _DAEMON_H
diff --git a/libglusterfs/src/defaults.c b/libglusterfs/src/defaults.c
index f3a8d2832..2ebb25150 100644
--- a/libglusterfs/src/defaults.c
+++ b/libglusterfs/src/defaults.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
/* 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,93 +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);
+ 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)
+ int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
{
- STACK_UNWIND_STRICT (fremovexattr, 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;
}
@@ -381,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)
{
@@ -438,266 +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,
- uint32_t flags, 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,
- flags, 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, uint32_t flags)
+ 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, flags);
+ 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)
+ const char *name, dict_t *xdata)
{
STACK_WIND (frame, default_fremovexattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fremovexattr, fd, name);
+ 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;
}
@@ -705,376 +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, dict_t *dict)
+ 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, dict);
+ 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, uint32_t flags,
- struct iobref *iobref)
+ struct iobref *iobref, dict_t *xdata)
{
- STACK_WIND (frame, default_writev_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->writev, fd, vector, count, off,
- flags, 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, uint32_t flags)
+ 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, flags);
+ 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)
+ const char *name, dict_t *xdata)
{
- STACK_WIND (frame, default_fremovexattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fremovexattr, fd, name);
+ 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;
}
@@ -1082,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, dict_t *dict)
+ 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, dict);
+ 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;
}
@@ -1198,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;
}
@@ -1205,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;
}
@@ -1223,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;
}
@@ -1235,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;
diff --git a/libglusterfs/src/defaults.h b/libglusterfs/src/defaults.h
index f30bd8332..0747027bc 100644
--- a/libglusterfs/src/defaults.h
+++ b/libglusterfs/src/defaults.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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,84 +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,
- uint32_t flags);
+ uint32_t flags, dict_t *xdata);
int32_t default_writev (call_frame_t *frame,
xlator_t *this,
@@ -127,218 +131,224 @@ int32_t default_writev (call_frame_t *frame,
int32_t count,
off_t offset,
uint32_t flags,
- struct iobref *iobref);
+ 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);
+ 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, dict_t *dict);
+ 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, uint32_t flags);
+ off_t offset, uint32_t flags, dict_t *xdata);
int32_t default_writev_resume (call_frame_t *frame,
xlator_t *this,
@@ -346,345 +356,362 @@ int32_t default_writev_resume (call_frame_t *frame,
struct iovec *vector,
int32_t count,
off_t offset, uint32_t flags,
- struct iobref *iobref);
+ 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);
+ 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, dict_t *dict);
+ 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);
+ 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,
diff --git a/libglusterfs/src/dict.c b/libglusterfs/src/dict.c
index fd9dd1cd7..3b7ddce5e 100644
--- a/libglusterfs/src/dict.c
+++ b/libglusterfs/src/dict.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#include <unistd.h>
@@ -23,6 +14,7 @@
#include <stdio.h>
#include <inttypes.h>
#include <limits.h>
+#include <fnmatch.h>
#ifndef _CONFIG_H
#define _CONFIG_H
@@ -36,23 +28,14 @@
#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);
- return data_pair_ptr;
-}
+#include "globals.h"
data_t *
get_new_data ()
{
data_t *data = NULL;
- data = (data_t *) GF_CALLOC (1, sizeof (data_t), gf_common_mt_data_t);
+ data = mem_get0 (THIS->ctx->dict_data_pool);
if (!data) {
return NULL;
}
@@ -64,19 +47,39 @@ get_new_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) {
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->members) {
- GF_FREE (dict);
- return NULL;
+ 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);
@@ -143,13 +146,11 @@ data_destroy (data_t *data)
else
GF_FREE (data->data);
}
- if (data->vec)
- GF_FREE (data->vec);
}
data->len = 0xbabababa;
if (!data->is_const)
- GF_FREE (data);
+ mem_put (data);
}
}
@@ -162,9 +163,7 @@ data_copy (data_t *old)
return NULL;
}
- data_t *newdata = (data_t *) GF_CALLOC (1, sizeof (*newdata),
- gf_common_mt_data_t);
-
+ data_t *newdata = mem_get0 (THIS->ctx->dict_data_pool);
if (!newdata) {
return NULL;
}
@@ -176,12 +175,6 @@ data_copy (data_t *old)
if (!newdata->data)
goto err_out;
}
- if (old->vec) {
- newdata->vec = memdup (old->vec, old->len * (sizeof (void *) +
- sizeof (size_t)));
- if (!newdata->vec)
- goto err_out;
- }
}
LOCK_INIT (&newdata->lock);
@@ -189,11 +182,8 @@ data_copy (data_t *old)
err_out:
- if (newdata->data)
- FREE (newdata->data);
- if (newdata->vec)
- FREE (newdata->vec);
- GF_FREE (newdata);
+ FREE (newdata->data);
+ mem_put (newdata);
return NULL;
}
@@ -219,7 +209,7 @@ _dict_lookup (dict_t *this, char *key)
}
int32_t
-dict_lookup (dict_t *this, char *key, data_pair_t **data)
+dict_lookup (dict_t *this, char *key, data_t **data)
{
if (!this || !key || !data) {
gf_log_callingfn ("dict", GF_LOG_WARNING,
@@ -227,22 +217,22 @@ dict_lookup (dict_t *this, char *key, data_pair_t **data)
return -1;
}
+ data_pair_t *tmp = NULL;
LOCK (&this->lock);
{
- *data = _dict_lookup (this, key);
+ tmp = _dict_lookup (this, key);
}
UNLOCK (&this->lock);
- if (*data)
- return 0;
- else
+
+ if (!tmp)
return -1;
+ *data = tmp->value;
+ return 0;
}
static int32_t
-_dict_set (dict_t *this,
- char *key,
- data_t *value)
+_dict_set (dict_t *this, char *key, data_t *value, gf_boolean_t replace)
{
int hashval;
data_pair_t *pair;
@@ -261,34 +251,54 @@ _dict_set (dict_t *this,
tmp = SuperFastHash (key, strlen (key));
hashval = (tmp % this->hash_size);
- pair = _dict_lookup (this, key);
- if (pair) {
- data_t *unref_data = pair->value;
- pair->value = data_ref (value);
- data_unref (unref_data);
- if (key_free)
- GF_FREE (key);
- /* Indicates duplicate key */
- return 0;
- }
- pair = (data_pair_t *) GF_CALLOC (1, sizeof (*pair),
- gf_common_mt_data_pair_t);
- if (!pair) {
- return -1;
- }
+ /* Search for a existing key if 'replace' is asked for */
+ if (replace) {
+ pair = _dict_lookup (this, key);
- pair->key = (char *) GF_CALLOC (1, strlen (key) + 1,
- gf_common_mt_char);
- if (!pair->key) {
- GF_FREE (pair);
+ 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;
+ }
+ }
- if (key_free)
- GF_FREE (key);
- return -1;
+ 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;
}
- strcpy (pair->key, key);
+ 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];
@@ -321,7 +331,28 @@ dict_set (dict_t *this,
LOCK (&this->lock);
- ret = _dict_set (this, key, value);
+ ret = _dict_set (this, key, value, 1);
+
+ UNLOCK (&this->lock);
+
+ return ret;
+}
+
+
+int32_t
+dict_add (dict_t *this, char *key, data_t *value)
+{
+ int32_t ret;
+
+ if (!this || !value) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING,
+ "!this || !value for key=%s", key);
+ return -1;
+ }
+
+ LOCK (&this->lock);
+
+ ret = _dict_set (this, key, value, 0);
UNLOCK (&this->lock);
@@ -385,7 +416,12 @@ dict_del (dict_t *this, char *key)
pair->next->prev = pair->prev;
GF_FREE (pair->key);
- GF_FREE (pair);
+ if (pair == &this->free_pair) {
+ this->free_pair_in_use = _gf_false;
+ }
+ else {
+ mem_put (pair);
+ }
this->count--;
break;
}
@@ -416,19 +452,21 @@ dict_destroy (dict_t *this)
pair = pair->next;
data_unref (prev->value);
GF_FREE (prev->key);
- GF_FREE (prev);
+ if (prev != &this->free_pair) {
+ mem_put (prev);
+ }
prev = pair;
}
- GF_FREE (this->members);
+ if (this->members != &this->members_internal) {
+ mem_put (this->members);
+ }
- if (this->extra_free)
- GF_FREE (this->extra_free);
- if (this->extra_stdfree)
- free (this->extra_stdfree);
+ GF_FREE (this->extra_free);
+ free (this->extra_stdfree);
if (!this->is_static)
- GF_FREE (this);
+ mem_put (this);
return;
}
@@ -509,236 +547,6 @@ data_ref (data_t *this)
return this;
}
-/*
- Serialization format:
- ----
- Count:8
- Key_len:8:Value_len:8
- Key
- Value
- .
- .
- .
-*/
-
-int32_t
-dict_serialized_length_old (dict_t *this)
-{
-
- if (!this) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is NULL");
- return -1;
- }
-
- 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--;
- }
-
- return len;
-}
-
-int32_t
-dict_serialize_old (dict_t *this, char *buf)
-{
- if (!this || !buf) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is NULL");
- return -1;
- }
-
- 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);
-}
-
-
-dict_t *
-dict_unserialize_old (char *buf, int32_t size, dict_t **fill)
-{
- int32_t ret = 0;
- int32_t cnt = 0;
-
- if (!buf || !fill || !(*fill)) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "buf is 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;
- }
-
- 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);
- }
-
- goto ret;
-
-err:
- GF_FREE (*fill);
- *fill = NULL;
-
-ret:
- return *fill;
-}
-
-
-int32_t
-dict_iovec_len (dict_t *this)
-{
- if (!this) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is NULL");
- return -1;
- }
-
- int32_t len = 0;
- data_pair_t *pair = this->members_list;
-
- len++; /* initial header */
- while (pair) {
- len++; /* pair header */
- len++; /* key */
-
- if (pair->value->vec)
- len += pair->value->len;
- else
- len++;
- pair = pair->next;
- }
-
- return len;
-}
-
-int32_t
-dict_to_iovec (dict_t *this,
- struct iovec *vec,
- int32_t count)
-{
- if (!this || !vec) {
- gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is NULL");
- return -1;
- }
-
- int32_t i = 0;
- data_pair_t *pair = this->members_list;
-
- vec[0].iov_len = 9;
- if (vec[0].iov_base)
- sprintf (vec[0].iov_base,
- "%08"PRIx64"\n",
- (int64_t)this->count);
- i++;
-
- while (pair) {
- int64_t keylen = strlen (pair->key) + 1;
- int64_t vallen = 0;
-
- if (pair->value->vec) {
- int i;
-
- for (i=0; i<pair->value->len; i++) {
- vallen += pair->value->vec[i].iov_len;
- }
- } else {
- vallen = pair->value->len;
- }
-
- 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++;
- }
-
- pair = pair->next;
- }
-
- return 0;
-}
-
data_t *
int_to_data (int64_t value)
{
@@ -1088,6 +896,8 @@ data_to_int32 (data_t *data)
int16_t
data_to_int16 (data_t *data)
{
+ int16_t value = 0;
+
if (!data) {
gf_log_callingfn ("dict", GF_LOG_WARNING, "data is NULL");
return -1;
@@ -1100,14 +910,25 @@ data_to_int16 (data_t *data)
memcpy (str, data->data, data->len);
str[data->len] = '\0';
- return strtol (str, NULL, 0);
+ errno = 0;
+ value = 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)
{
- int32_t value = 0;
+ int8_t value = 0;
if (!data) {
gf_log_callingfn ("dict", GF_LOG_WARNING, "data is NULL");
@@ -1121,15 +942,16 @@ data_to_int8 (data_t *data)
memcpy (str, data->data, data->len);
str[data->len] = '\0';
- errno = 0;
- value = strtol (str, NULL, 0);
+ errno = 0;
+ value = strtol (str, NULL, 0);
- if ((SCHAR_MAX > value) || (SCHAR_MIN < value)) {
- errno = ERANGE;
+ if ((value > SCHAR_MAX) || (value < SCHAR_MIN)) {
+ errno = ERANGE;
gf_log_callingfn ("dict", GF_LOG_WARNING,
- "Error in data conversion: detected overflow");
+ "Error in data conversion: "
+ "detected overflow");
return -1;
- }
+ }
return (int8_t)value;
}
@@ -1169,6 +991,8 @@ data_to_uint32 (data_t *data)
uint16_t
data_to_uint16 (data_t *data)
{
+ uint16_t value = 0;
+
if (!data)
return -1;
@@ -1179,7 +1003,18 @@ data_to_uint16 (data_t *data)
memcpy (str, data->data, data->len);
str[data->len] = '\0';
- return strtol (str, NULL, 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
@@ -1243,47 +1078,141 @@ data_to_bin (data_t *data)
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),
+ 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;
+ 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;
}
-static void
+/**
+ * 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 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 void
+static int
_remove (dict_t *dict,
char *key,
data_t *value,
void *unused)
{
dict_del ((dict_t *)dict, key);
+ return 0;
}
@@ -2330,7 +2259,6 @@ _dict_serialized_length (dict_t *this)
int ret = -EINVAL;
int count = 0;
int len = 0;
- int i = 0;
data_pair_t * pair = NULL;
len = DICT_HDR_LEN;
@@ -2365,28 +2293,15 @@ _dict_serialized_length (dict_t *this)
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;
}
+ len += pair->value->len;
+
pair = pair->next;
count--;
}
@@ -2661,6 +2576,7 @@ dict_unserialize (char *orig_buf, int32_t size, dict_t **fill)
"available (%lu) < required (%lu)",
(long)(orig_buf + size),
(long)(buf + vallen));
+ goto out;
}
value = get_new_data ();
value->len = vallen;
@@ -2668,7 +2584,7 @@ dict_unserialize (char *orig_buf, int32_t size, dict_t **fill)
value->is_static = 0;
buf += vallen;
- dict_set (*fill, key, value);
+ dict_add (*fill, key, value);
}
ret = 0;
@@ -2689,7 +2605,7 @@ out:
*/
int32_t
-dict_allocate_and_serialize (dict_t *this, char **buf, size_t *length)
+dict_allocate_and_serialize (dict_t *this, char **buf, u_int *length)
{
int ret = -EINVAL;
ssize_t len = 0;
@@ -2826,3 +2742,40 @@ dict_serialize_value_with_delim (dict_t *this, char *buf, int32_t *serz_len,
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 8e81e539b..9b41b5a7d 100644
--- a/libglusterfs/src/dict.h
+++ b/libglusterfs/src/dict.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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
@@ -38,13 +29,11 @@ typedef struct _data_pair data_pair_t;
#define GF_PROTOCOL_DICT_SERIALIZE(this,from_dict,to,len,ope,labl) do { \
int ret = 0; \
- size_t dictlen = 0; \
\
if (!from_dict) \
break; \
\
- ret = dict_allocate_and_serialize (from_dict, to, \
- &dictlen); \
+ 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)", \
@@ -52,32 +41,25 @@ typedef struct _data_pair data_pair_t;
ope = EINVAL; \
goto labl; \
} \
- len = dictlen; \
} while (0)
#define GF_PROTOCOL_DICT_UNSERIALIZE(xl,to,buff,len,ret,ope,labl) do { \
- char *buf = NULL; \
if (!len) \
break; \
to = dict_new(); \
GF_VALIDATE_OR_GOTO (xl->name, to, labl); \
\
- buf = memdup (buff, len); \
- GF_VALIDATE_OR_GOTO (xl->name, buf, labl); \
- \
- ret = dict_unserialize (buf, len, &to); \
+ ret = dict_unserialize (buff, len, &to); \
if (ret < 0) { \
gf_log (xl->name, GF_LOG_WARNING, \
"failed to unserialize dictionary (%s)", \
(#to)); \
\
ope = EINVAL; \
- GF_FREE (buf); \
goto labl; \
} \
\
- to->extra_free = buf; \
} while (0)
struct _data {
@@ -85,7 +67,6 @@ struct _data {
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;
@@ -109,13 +90,20 @@ struct _dict {
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);
@@ -124,10 +112,7 @@ int32_t dict_serialized_length (dict_t *dict);
int32_t dict_serialize (dict_t *dict, char *buf);
int32_t dict_unserialize (char *buf, int32_t size, dict_t **fill);
-int32_t dict_allocate_and_serialize (dict_t *this, char **buf, size_t *length);
-
-int32_t dict_iovec_len (dict_t *dict);
-int32_t dict_to_iovec (dict_t *dict, struct iovec *vec, int32_t count);
+int32_t dict_allocate_and_serialize (dict_t *this, char **buf, u_int *length);
void dict_destroy (dict_t *dict);
void dict_unref (dict_t *dict);
@@ -135,7 +120,7 @@ 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_pair_t **data);
+int32_t dict_lookup (dict_t *this, char *key, data_t **data);
/*
TODO: provide converts for differnt byte sizes, signedness, and void *
*/
@@ -178,16 +163,26 @@ 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);
+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);
@@ -237,4 +232,6 @@ 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 c117a4ae2..0197e7948 100644
--- a/libglusterfs/src/event.c
+++ b/libglusterfs/src/event.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#include <sys/poll.h>
@@ -35,851 +26,17 @@
#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) {
- 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;
-
- 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;
-}
-
-
-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)
- 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) {
- if (event_pool->evcache)
- GF_FREE (event_pool->evcache);
-
- event_pool->evcache = events = NULL;
-
- event_pool->evcache_size =
- event_pool->used + 256;
-
- events = GF_CALLOC (event_pool->evcache_size,
- sizeof (struct epoll_event),
- gf_common_mt_epoll_event);
- if (!events)
- break;
-
- event_pool->evcache = events;
- }
- }
- pthread_mutex_unlock (&event_pool->mutex);
-
- ret = epoll_wait (event_pool->fd, event_pool->evcache,
- event_pool->evcache_size, -1);
-
- if (ret == 0)
- /* timeout */
- continue;
-
- if (ret == -1 && errno == EINTR)
- /* sys call */
- continue;
-
- size = ret;
-
- for (i = 0; i < size; i++) {
- if (!events || !events[i].events)
- continue;
-
- ret = event_dispatch_epoll_handler (event_pool,
- events, i);
- }
- }
-
-out:
- return ret;
-}
-
-
-static struct event_ops event_ops_epoll = {
- .new = event_pool_new_epoll,
- .event_register = event_register_epoll,
- .event_select_on = event_select_on_epoll,
- .event_unregister = event_unregister_epoll,
- .event_dispatch = event_dispatch_epoll
-};
-
-#endif
struct event_pool *
event_pool_new (int count)
{
struct event_pool *event_pool = NULL;
+ extern struct event_ops event_ops_poll;
#ifdef HAVE_SYS_EPOLL_H
+ extern struct event_ops event_ops_epoll;
+
event_pool = event_ops_epoll.new (count);
if (event_pool) {
diff --git a/libglusterfs/src/event.h b/libglusterfs/src/event.h
index 0e87f0cd7..7ed182492 100644
--- a/libglusterfs/src/event.h
+++ b/libglusterfs/src/event.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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,8 +21,8 @@
struct event_pool;
struct event_ops;
struct event_data {
- int fd;
- int idx;
+ int fd;
+ int idx;
} __attribute__ ((__packed__, __may_alias__));
@@ -39,28 +30,27 @@ 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 {
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 62a70c457..36cc4d056 100644
--- a/libglusterfs/src/fd.c
+++ b/libglusterfs/src/fd.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#include "fd.h"
@@ -130,7 +121,7 @@ gf_fd_fdtable_alloc (void)
}
-fdentry_t *
+static fdentry_t *
__gf_fd_fdtable_get_all_fds (fdtable_t *fdtable, uint32_t *count)
{
fdentry_t *fdentries = NULL;
@@ -168,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)
{
@@ -309,6 +347,54 @@ unlock_out:
}
+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)
{
@@ -401,7 +487,7 @@ fd_destroy (fd_t *fd)
goto out;
if (IA_ISDIR (fd->inode->ia_type)) {
- for (i = 0; i < fd->xl_count; i++) {
+ for (i = 0; i < fd->xl_count; i++) {
if (fd->_ctx[i].key) {
xl = fd->_ctx[i].xl_key;
old_THIS = THIS;
@@ -427,8 +513,14 @@ fd_destroy (fd_t *fd)
LOCK_DESTROY (&fd->lock);
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;
+ fd_lk_ctx_unref (fd->lk_ctx);
mem_put (fd);
out:
return;
@@ -463,7 +555,9 @@ fd_unref (fd_t *fd)
fd_t *
__fd_bind (fd_t *fd)
{
+ list_del_init (&fd->inode_list);
list_add (&fd->inode_list, &fd->inode->fd_list);
+ fd->inode->fd_count++;
return fd;
}
@@ -488,7 +582,7 @@ fd_bind (fd_t *fd)
static fd_t *
-__fd_create (inode_t *inode, pid_t pid)
+__fd_create (inode_t *inode, uint64_t pid)
{
fd_t *fd = NULL;
@@ -505,11 +599,12 @@ __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) {
- mem_put (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;
@@ -518,6 +613,13 @@ __fd_create (inode_t *inode, pid_t pid)
LOCK_INIT (&fd->lock);
out:
return fd;
+
+free_fd_ctx:
+ GF_FREE (fd->_ctx);
+free_fd:
+ mem_put (fd);
+
+ return NULL;
}
@@ -526,6 +628,21 @@ 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;
@@ -538,7 +655,7 @@ out:
static fd_t *
-__fd_lookup (inode_t *inode, pid_t pid)
+__fd_lookup (inode_t *inode, uint64_t pid)
{
fd_t *iter_fd = NULL;
fd_t *fd = NULL;
@@ -548,6 +665,12 @@ __fd_lookup (inode_t *inode, pid_t pid)
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;
@@ -570,6 +693,25 @@ fd_lookup (inode_t *inode, pid_t pid)
LOCK (&inode->lock);
{
+ fd = __fd_lookup (inode, (uint64_t)pid);
+ }
+ UNLOCK (&inode->lock);
+
+ return fd;
+}
+
+fd_t *
+fd_lookup_uint64 (inode_t *inode, uint64_t pid)
+{
+ fd_t *fd = NULL;
+
+ if (!inode) {
+ gf_log_callingfn ("fd", GF_LOG_WARNING, "!inode");
+ return NULL;
+ }
+
+ LOCK (&inode->lock);
+ {
fd = __fd_lookup (inode, pid);
}
UNLOCK (&inode->lock);
@@ -577,25 +719,48 @@ fd_lookup (inode_t *inode, pid_t pid)
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;
-fd_t *
+ 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 (inode, -1);
+ 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, -1);
+ fd = __fd_create (inode, 0);
if (!fd)
return NULL;
+ fd->anonymous = _gf_true;
+
__fd_bind (fd);
- }
- __fd_ref (fd);
+ __fd_ref (fd);
+ }
return fd;
}
@@ -615,11 +780,28 @@ fd_anonymous (inode_t *inode)
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->pid == -1);
+ return (fd && fd->anonymous);
}
@@ -641,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;
@@ -662,9 +847,33 @@ __fd_ctx_set (fd_t *fd, xlator_t *xlator, uint64_t value)
}
if (set_idx == -1) {
- gf_log_callingfn ("", GF_LOG_WARNING, "%p %s", fd, xlator->name);
- 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;
@@ -797,9 +1006,16 @@ fd_dump (fd_t *fd, char *prefix)
return;
memset(key, 0, sizeof(key));
- gf_proc_dump_write("pid", "%d", fd->pid);
+ 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, "inode", NULL);
+ gf_proc_dump_add_section(key);
+ inode_dump (fd->inode, key);
+ }
+
}
@@ -829,10 +1045,8 @@ fdtable_dump (fdtable_t *fdtable, char *prefix)
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");
@@ -852,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;
}
@@ -870,15 +1090,13 @@ 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) {
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];
}
}
@@ -890,7 +1108,7 @@ unlock:
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)
@@ -899,9 +1117,7 @@ unlock:
}
out:
- if (fd_ctx != NULL) {
- GF_FREE (fd_ctx);
- }
+ GF_FREE (fd_ctx);
return;
}
diff --git a/libglusterfs/src/fd.h b/libglusterfs/src/fd.h
index d4cd9bd06..c1b9157d8 100644
--- a/libglusterfs/src/fd.h
+++ b/libglusterfs/src/fd.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _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,12 +41,8 @@ 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;
struct list_head inode_list;
@@ -59,6 +51,8 @@ struct _fd {
'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;
@@ -92,7 +86,7 @@ typedef struct _fdtable fdtable_t;
#include "xlator.h"
-inline void
+void
gf_fd_put (fdtable_t *fdtable, int32_t fd);
@@ -117,6 +111,10 @@ gf_fd_fdtable_destroy (fdtable_t *fdtable);
fd_t *
+__fd_ref (fd_t *fd);
+
+
+fd_t *
fd_ref (fd_t *fd);
@@ -127,10 +125,17 @@ 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);
@@ -159,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);
@@ -168,13 +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);
#endif /* _FD_H */
diff --git a/libglusterfs/src/gf-dirent.c b/libglusterfs/src/gf-dirent.c
index 8d15b0405..bb028c967 100644
--- a/libglusterfs/src/gf-dirent.c
+++ b/libglusterfs/src/gf-dirent.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
diff --git a/libglusterfs/src/gf-dirent.h b/libglusterfs/src/gf-dirent.h
index 29b4aba80..588d522db 100644
--- a/libglusterfs/src/gf-dirent.h
+++ b/libglusterfs/src/gf-dirent.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
@@ -54,9 +45,10 @@ struct _gf_dirent_t {
struct iatt d_stat;
dict_t *dict;
inode_t *inode;
- char d_name[0];
+ 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);
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 9355a3a46..259c5c885 100644
--- a/libglusterfs/src/globals.c
+++ b/libglusterfs/src/globals.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -28,115 +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) {
- gf_log_callingfn ("", GF_LOG_WARNING, "init called again");
- goto out;
- }
-
- glusterfs_ctx = CALLOC (1, sizeof (*glusterfs_ctx));
- if (!glusterfs_ctx) {
- ret = -1;
- goto out;
- }
-
- INIT_LIST_HEAD (&glusterfs_ctx->graphs);
- INIT_LIST_HEAD (&glusterfs_ctx->mempool_list);
- 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);
}
@@ -153,7 +103,6 @@ glusterfs_this_init ()
global_xlator.name = "glusterfs";
global_xlator.type = "global";
- global_xlator.ctx = glusterfs_ctx;
INIT_LIST_HEAD (&global_xlator.volume_options);
@@ -176,8 +125,6 @@ __glusterfs_this_location ()
ret = pthread_setspecific (this_xlator_key, this_location);
if (ret != 0) {
- gf_log ("", GF_LOG_WARNING, "pthread setspecific failed");
-
FREE (this_location);
this_location = NULL;
goto out;
@@ -219,10 +166,55 @@ glusterfs_this_set (xlator_t *this)
return 0;
}
-/* SYNCTASK */
+/* SYNCOPCTX */
+static pthread_key_t syncopctx_key;
-static pthread_key_t synctask_key;
+static void
+syncopctx_key_destroy (void *ptr)
+{
+ struct syncopctx *opctx = ptr;
+ if (opctx) {
+ if (opctx->groups)
+ GF_FREE (opctx->groups);
+
+ GF_FREE (opctx);
+ }
+
+ return;
+}
+
+void *
+syncopctx_getctx ()
+{
+ void *opctx = NULL;
+
+ opctx = pthread_getspecific (syncopctx_key);
+
+ return opctx;
+}
+
+int
+syncopctx_setctx (void *ctx)
+{
+ int ret = 0;
+
+ ret = pthread_setspecific (syncopctx_key, ctx);
+
+ return ret;
+}
+
+static int
+syncopctx_init (void)
+{
+ int ret;
+
+ ret = pthread_key_create (&syncopctx_key, syncopctx_key_destroy);
+
+ return ret;
+}
+
+/* SYNCTASK */
int
synctask_init ()
@@ -234,7 +226,6 @@ synctask_init ()
return ret;
}
-
void *
synctask_get ()
{
@@ -258,13 +249,10 @@ synctask_set (void *synctask)
//UUID_BUFFER
-static pthread_key_t uuid_buf_key;
-static char global_uuid_buf[GF_UUID_BUF_SIZE];
void
glusterfs_uuid_buf_destroy (void *ptr)
{
- if (ptr)
- FREE (ptr);
+ FREE (ptr);
}
int
@@ -287,7 +275,7 @@ glusterfs_uuid_buf_get ()
if(!buf) {
buf = MALLOC (GF_UUID_BUF_SIZE);
ret = pthread_setspecific (uuid_buf_key, (void *) buf);
- if(ret)
+ if (ret)
buf = global_uuid_buf;
}
return buf;
@@ -295,13 +283,10 @@ glusterfs_uuid_buf_get ()
/* LKOWNER_BUFFER */
-static pthread_key_t lkowner_buf_key;
-static char global_lkowner_buf[GF_LKOWNER_BUF_SIZE];
void
glusterfs_lkowner_buf_destroy (void *ptr)
{
- if (ptr)
- FREE (ptr);
+ FREE (ptr);
}
int
@@ -324,27 +309,18 @@ glusterfs_lkowner_buf_get ()
if(!buf) {
buf = MALLOC (GF_LKOWNER_BUF_SIZE);
ret = pthread_setspecific (lkowner_buf_key, (void *) buf);
- if(ret)
+ if (ret)
buf = global_lkowner_buf;
}
return buf;
}
int
-glusterfs_globals_init ()
+glusterfs_globals_init (glusterfs_ctx_t *ctx)
{
int ret = 0;
- gf_op_list_init ();
-
- gf_log_globals_init ();
-
- ret = glusterfs_ctx_init ();
- if (ret) {
- gf_log ("", GF_LOG_CRITICAL,
- "ERROR: glusterfs context init failed");
- goto out;
- }
+ gf_log_globals_init (ctx);
ret = glusterfs_this_init ();
if (ret) {
@@ -367,42 +343,19 @@ glusterfs_globals_init ()
goto out;
}
- gf_mem_acct_enable_set ();
-
ret = synctask_init ();
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+1][64] = {
- "Invalid event",
- "Parent Up",
- "Poll In",
- "Poll Out",
- "Poll Err",
- "Child Up",
- "Child Down",
- "Child Connecting",
- "Child Modified",
- "Transport Cleanup",
- "Transport Connected",
- "Volfile Modified",
- "New Volfile",
- "Translator Info",
- "Trigger Volume Heal",
- "Authentication Failed",
- "Invalid event",
-};
-
-/* 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 86e1f0324..3085db21c 100644
--- a/libglusterfs/src/globals.h
+++ b/libglusterfs/src/globals.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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,33 +13,50 @@
#define GF_DEFAULT_BASE_PORT 24007
-#include "glusterfs.h"
-
-/* CTX */
-#define CTX (glusterfs_ctx_get())
-
-glusterfs_ctx_t *glusterfs_ctx_get ();
+#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 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"
/* THIS */
#define THIS (*__glusterfs_this_location())
-#define GF_UUID_BUF_SIZE 50
-
xlator_t **__glusterfs_this_location ();
xlator_t *glusterfs_this_get ();
int glusterfs_this_set (xlator_t *);
+/* 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 8360077ec..2f1e12ee7 100644
--- a/libglusterfs/src/glusterfs.h
+++ b/libglusterfs/src/glusterfs.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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,16 +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
@@ -72,27 +70,63 @@
#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 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"
@@ -109,16 +143,29 @@
#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))
-/* TODO: Should we use PATH-MAX? On some systems it may save space */
-#define ZR_PATH_MAX 4096
+#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 200
+#define GF_MAX_AUX_GROUPS 65536
+
+#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 {
@@ -153,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,
@@ -168,6 +215,9 @@ typedef enum {
GF_FOP_RELEASEDIR,
GF_FOP_GETSPEC,
GF_FOP_FREMOVEXATTR,
+ GF_FOP_FALLOCATE,
+ GF_FOP_DISCARD,
+ GF_FOP_ZEROFILL,
GF_FOP_MAXVALUE,
} glusterfs_fop_t;
@@ -217,21 +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_ARRAY64
+ GF_XATTROP_ADD_ARRAY,
+ GF_XATTROP_ADD_ARRAY64,
+ GF_XATTROP_OR_ARRAY,
+ GF_XATTROP_AND_ARRAY
} gf_xattrop_flags_t;
@@ -240,68 +292,79 @@ 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;
+ char *pid_file;
char *sock_file;
- int no_daemon_mode;
- char *run_id;
- int debug_mode;
+ 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;
+ 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;
+ /* key args */
+ char *mount_point;
+ char *volfile_id;
/* required for portmap */
int brick_port;
@@ -326,17 +389,19 @@ struct _glusterfs_graph {
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 */
@@ -350,21 +415,34 @@ struct _glusterfs_ctx {
int graph_id; /* Incremented per graph, value should
indicate how many times the graph has
got changed */
- pid_t mtab_pid; /* pid of the process which updates the mtab */
+ 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 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;
+ 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,
@@ -379,14 +457,14 @@ typedef enum {
GF_EVENT_VOLFILE_MODIFIED,
GF_EVENT_GRAPH_NEW,
GF_EVENT_TRANSLATOR_INFO,
- GF_EVENT_TRIGGER_HEAL,
+ 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;
-/* gf_lkowner_t is defined in lkowner.h */
-#include "lkowner.h"
-
struct gf_flock {
short l_type;
short l_whence;
@@ -396,9 +474,6 @@ struct gf_flock {
gf_lkowner_t l_owner;
};
-
-extern char *glusterfs_strevent (glusterfs_event_t ev);
-
#define GF_MUST_CHECK __attribute__((warn_unused_result))
/*
* Some macros (e.g. ALLOC_OR_GOTO) set variables in function scope, but the
diff --git a/libglusterfs/src/graph-print.c b/libglusterfs/src/graph-print.c
index 432f9a1de..d860d63b3 100644
--- a/libglusterfs/src/graph-print.c
+++ b/libglusterfs/src/graph-print.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -33,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
@@ -89,19 +81,31 @@ gpprintf (struct gf_printer *gp, const char *format, ...)
return ret;
}
-static int
-glusterfs_graph_print (struct gf_printer *gp, glusterfs_graph_t *graph)
-{
#define GPPRINTF(gp, fmt, ...) do { \
ret = gpprintf (gp, fmt, ## __VA_ARGS__); \
if (ret == -1) \
goto out; \
else \
- len += ret; \
+ gp->len += ret; \
} while (0)
+static int
+_print_volume_options (dict_t *d, char *k, data_t *v,
+ void *tmp)
+{
+ 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;
@@ -114,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,6 +137,7 @@ glusterfs_graph_print (struct gf_printer *gp, glusterfs_graph_t *graph)
}
out:
+ len = gp->len;
if (ret == -1) {
gf_log ("graph-print", GF_LOG_ERROR, "printing failed");
diff --git a/libglusterfs/src/graph-utils.h b/libglusterfs/src/graph-utils.h
index d125fbe0d..207664fdb 100644
--- a/libglusterfs/src/graph-utils.h
+++ b/libglusterfs/src/graph-utils.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010-2011 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 General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _GRAPH_H_
diff --git a/libglusterfs/src/graph.c b/libglusterfs/src/graph.c
index 830c88363..e76df1ca5 100644
--- a/libglusterfs/src/graph.c
+++ b/libglusterfs/src/graph.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -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");
@@ -131,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;
@@ -157,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",
@@ -187,7 +176,7 @@ glusterfs_graph_acl (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
return 0;
ret = glusterfs_graph_insert (graph, ctx, "system/posix-acl",
- "posix-acl-autoload");
+ "posix-acl-autoload", 1);
return ret;
}
@@ -203,7 +192,7 @@ glusterfs_graph_worm (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
return 0;
ret = glusterfs_graph_insert (graph, ctx, "features/worm",
- "worm-autoload");
+ "worm-autoload", 1);
return ret;
}
@@ -219,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)
@@ -310,7 +314,7 @@ glusterfs_graph_init (glusterfs_graph_t *graph)
}
-static void
+static int
_log_if_unknown_option (dict_t *dict, char *key, data_t *value, void *data)
{
volume_option_t *found = NULL;
@@ -325,7 +329,7 @@ _log_if_unknown_option (dict_t *dict, char *key, data_t *value, void *data)
"option '%s' is not recognized", key);
}
- return;
+ return 0;
}
@@ -349,8 +353,7 @@ 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,
@@ -364,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);
@@ -454,6 +456,14 @@ glusterfs_graph_prepare (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
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) {
trav->ctx = ctx;
@@ -505,11 +515,14 @@ 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) {
- gf_log ("graph", GF_LOG_ERROR, "graph new notification failed");
- 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 */
@@ -522,18 +535,204 @@ glusterfs_graph_activate (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
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);
}
@@ -541,5 +740,12 @@ glusterfs_graph_reconfigure (glusterfs_graph_t *oldgraph,
int
glusterfs_graph_destroy (glusterfs_graph_t *graph)
{
+ 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 04fff2582..e4eba9cbe 100644
--- a/libglusterfs/src/graph.l
+++ b/libglusterfs/src/graph.l
@@ -1,23 +1,13 @@
/*
- Copyright (c) 2006-2011 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 General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
-
%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 62c57dd6c..a220abeb9 100644
--- a/libglusterfs/src/graph.y
+++ b/libglusterfs/src/graph.y
@@ -1,23 +1,13 @@
/*
- Copyright (c) 2006-2011 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 General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
-
%token VOLUME_BEGIN VOLUME_END OPTION NEWLINE SUBVOLUME ID WHITESPACE COMMENT TYPE STRING_TOK
%{
@@ -28,6 +18,7 @@
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <pthread.h>
#define RELAX_POISONING
@@ -47,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 ();
%}
@@ -88,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;
}
@@ -100,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;
}
@@ -112,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;
}
@@ -125,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;
@@ -139,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;
}
@@ -159,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;
}
@@ -204,7 +195,7 @@ out:
static int
volume_type (char *type)
{
- extern int yylineno;
+ extern int graphyylineno;
int32_t ret = 0;
if (!type) {
@@ -218,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;
}
@@ -235,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;
@@ -252,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;
}
@@ -271,7 +262,7 @@ out:
static int
volume_sub (char *sub)
{
- extern int yylineno;
+ extern int graphyylineno;
xlator_t *trav = NULL;
int ret = 0;
@@ -293,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;
}
@@ -301,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;
}
@@ -338,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'");
}
@@ -386,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;
@@ -491,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;
}
@@ -532,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);
@@ -539,7 +532,7 @@ out:
}
-extern FILE *yyin;
+extern FILE *graphyyin;
glusterfs_graph_t *
glusterfs_graph_new ()
@@ -563,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 b5752956c..f79165b22 100644
--- a/libglusterfs/src/hashfn.c
+++ b/libglusterfs/src/hashfn.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#include <stdint.h>
diff --git a/libglusterfs/src/hashfn.h b/libglusterfs/src/hashfn.h
index af306745b..06ae37e79 100644
--- a/libglusterfs/src/hashfn.h
+++ b/libglusterfs/src/hashfn.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2011 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 General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef __HASHFN_H__
diff --git a/libglusterfs/src/iatt.h b/libglusterfs/src/iatt.h
index b84eaa379..60ae59047 100644
--- a/libglusterfs/src/iatt.h
+++ b/libglusterfs/src/iatt.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
@@ -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)
{
@@ -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 4685ec8d2..15e0ccf78 100644
--- a/libglusterfs/src/inode.c
+++ b/libglusterfs/src/inode.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -143,8 +134,7 @@ __dentry_unset (dentry_t *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);
@@ -320,7 +310,7 @@ __inode_destroy (inode_t *inode)
goto noctx;
}
- 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;
@@ -538,10 +528,9 @@ __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),
+ newi->_ctx = GF_CALLOC (1,
+ (sizeof (struct _inode_ctx) * table->ctxcount),
gf_common_mt_inode_ctx);
-
if (newi->_ctx == NULL) {
LOCK_DESTROY (&newi->lock);
mem_put (newi);
@@ -660,6 +649,50 @@ inode_grep (inode_table_t *table, inode_t *parent, const char *name)
return inode;
}
+
+inode_t *
+inode_resolve (inode_table_t *table, char *path)
+{
+ 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;
+}
+
+
int
inode_grep_for_gfid (inode_table_t *table, inode_t *parent, const char *name,
uuid_t gfid, ia_type_t *type)
@@ -795,24 +828,36 @@ __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->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;
@@ -902,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)
@@ -1038,8 +1131,9 @@ __inode_path (inode_t *inode, const char *name, char **bufp)
int len = 0;
char *buf = NULL;
- if (!inode) {
- gf_log_callingfn (THIS->name, GF_LOG_WARNING, "inode not found");
+ if (!inode || uuid_is_null (inode->gfid)) {
+ GF_ASSERT (0);
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "invalid inode");
return -1;
}
@@ -1096,7 +1190,7 @@ __inode_path (inode_t *inode, const char *name, char **bufp)
if (!__is_root_gfid (itrav->gfid)) {
snprintf (&buf[i-GFID_STR_PFX_LEN], GFID_STR_PFX_LEN,
- "<gfid:%s>", uuid_utoa (itrav->gfid));
+ INODE_PATH_FMT, uuid_utoa (itrav->gfid));
buf[i-1] = '>';
}
@@ -1108,9 +1202,7 @@ __inode_path (inode_t *inode, const char *name, char **bufp)
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, "/");
@@ -1206,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;
}
@@ -1223,6 +1315,7 @@ 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;
@@ -1254,7 +1347,9 @@ inode_table_new (size_t lru_limit, xlator_t *xl)
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)
goto out;
@@ -1286,10 +1381,8 @@ inode_table_new (size_t lru_limit, xlator_t *xl)
out:
if (ret) {
if (new) {
- if (new->inode_hash)
- GF_FREE (new->inode_hash);
- if (new->name_hash)
- GF_FREE (new->name_hash);
+ GF_FREE (new->inode_hash);
+ GF_FREE (new->name_hash);
if (new->dentry_pool)
mem_pool_destroy (new->dentry_pool);
if (new->inode_pool)
@@ -1355,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;
@@ -1374,7 +1466,7 @@ __inode_ctx_set2 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p,
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 (set_idx == -1)
set_idx = index;
@@ -1401,6 +1493,18 @@ 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_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,
@@ -1420,34 +1524,97 @@ inode_ctx_set2 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p,
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);
+
+ return ret;
+}
+
int
__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;
}
@@ -1470,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,
@@ -1483,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;
@@ -1508,6 +1710,97 @@ unlock:
return ret;
}
+/* 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)
+{
+ int index = 0;
+ int ret = 0;
+
+ if (!inode || !xlator)
+ return -1;
+
+ 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_reset2 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p,
+ uint64_t *value2_p)
+{
+ 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_reset1 (inode_t *inode, xlator_t *xlator, uint64_t *value2_p)
+{
+ 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_reset0 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p)
+{
+ 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)
@@ -1517,10 +1810,6 @@ inode_dump (inode_t *inode, char *prefix)
int i = 0;
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)
@@ -1536,43 +1825,36 @@ inode_dump (inode_t *inode, char *prefix)
{
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) {
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) {
- 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)
@@ -1581,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;
}
@@ -1650,7 +1918,7 @@ inode_dump_to_dict (inode_t *inode, char *prefix, dict_t *dict)
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "%s.gfid", prefix);
- ret = dict_set_str (dict, key, gf_strdup (uuid_utoa (inode->gfid)));
+ ret = dict_set_dynstr (dict, key, gf_strdup (uuid_utoa (inode->gfid)));
if (ret)
goto out;
diff --git a/libglusterfs/src/inode.h b/libglusterfs/src/inode.h
index 7dda0401d..a88976265 100644
--- a/libglusterfs/src/inode.h
+++ b/libglusterfs/src/inode.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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,7 +19,8 @@
#include <stdint.h>
#include <sys/types.h>
-#define DEFAULT_INODE_MEMPOOL_ENTRIES 16384
+#define DEFAULT_INODE_MEMPOOL_ENTRIES 32 * 1024
+#define INODE_PATH_FMT "<gfid:%s>"
struct _inode_table;
typedef struct _inode_table inode_table_t;
@@ -64,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 */
};
@@ -80,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;
@@ -95,6 +90,7 @@ 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 */
ia_type_t ia_type; /* what kind of file */
struct list_head fd_list; /* list of open files on this inode */
@@ -139,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);
@@ -162,6 +161,11 @@ __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_set2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
uint64_t *value2);
@@ -180,26 +184,66 @@ int
inode_ctx_del2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
uint64_t *value2);
-#define __inode_ctx_set(i,x,v_p) __inode_ctx_set2(i,x,v_p,0)
-#define inode_ctx_set(i,x,v_p) inode_ctx_set2(i,x,v_p,0)
+int
+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_set0 (inode_t *inode, xlator_t *xlator, uint64_t *value1);
+
+int
+__inode_ctx_set0 (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_get0 (inode_t *inode, xlator_t *xlator, uint64_t *value1);
+
+int
+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_set2 (inode, this, &v, 0);
+ 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_set2(inode, this, &v, 0);
+ return inode_ctx_set0 (inode, this, &v);
}
-#define __inode_ctx_get(i,x,v) __inode_ctx_get2(i,x,v,0)
-#define inode_ctx_get(i,x,v) inode_ctx_get2(i,x,v,0)
+#define __inode_ctx_set(i,x,v_p) __inode_ctx_set0(i,x,v_p)
-#define inode_ctx_del(i,x,v) inode_ctx_del2(i,x,v,0)
+#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);
diff --git a/libglusterfs/src/iobuf.c b/libglusterfs/src/iobuf.c
index 93bc7732e..a89e96267 100644
--- a/libglusterfs/src/iobuf.c
+++ b/libglusterfs/src/iobuf.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
@@ -317,6 +308,31 @@ 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 (void)
@@ -333,7 +349,7 @@ iobuf_pool_new (void)
goto out;
pthread_mutex_init (&iobuf_pool->mutex, NULL);
- for (i = 0; i < IOBUF_ARENA_MAX_INDEX; i++) {
+ 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]);
@@ -351,6 +367,9 @@ iobuf_pool_new (void)
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:
@@ -509,6 +528,50 @@ out:
}
struct iobuf *
+iobuf_get_from_stdalloc (struct iobuf_pool *iobuf_pool, size_t page_size)
+{
+ 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;
@@ -521,10 +584,17 @@ iobuf_get2 (struct iobuf_pool *iobuf_pool, size_t page_size)
rounded_size = gf_iobuf_get_pagesize (page_size);
if (rounded_size == -1) {
- gf_log ("iobuf", GF_LOG_ERROR, "page_size (%zu) of "
- "iobufs in arena being requested is greater than max "
- "available", page_size);
- return NULL;
+ /* 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);
@@ -593,9 +663,13 @@ __iobuf_put (struct iobuf *iobuf, struct iobuf_arena *iobuf_arena)
index = gf_iobuf_get_arena_index (iobuf_arena->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", iobuf_arena->page_size);
+ 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;
}
@@ -767,6 +841,29 @@ out:
}
+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;
+}
+
+
int
__iobref_add (struct iobref *iobref, struct iobuf *iobuf)
{
@@ -967,6 +1064,8 @@ iobuf_stats_dump (struct iobuf_pool *iobuf_pool)
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) {
diff --git a/libglusterfs/src/iobuf.h b/libglusterfs/src/iobuf.h
index d0f868286..5595309e1 100644
--- a/libglusterfs/src/iobuf.h
+++ b/libglusterfs/src/iobuf.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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_
@@ -40,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;
@@ -71,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 */
};
@@ -113,21 +112,17 @@ struct iobuf_pool {
int arena_cnt;
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
- */
+ /* 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
- */
+ /* array of arenas without free iobufs */
struct list_head purge[GF_VARIABLE_IOBUF_COUNT];
- /*
- array of of arenas which can be
- purged
- */
+ /* array of of arenas which can be purged */
+
+ uint64_t request_misses; /* mostly the requests for higher
+ value of iobufs */
};
@@ -155,7 +150,7 @@ 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);
diff --git a/libglusterfs/src/latency.c b/libglusterfs/src/latency.c
index dfce235c0..b22f72950 100644
--- a/libglusterfs/src/latency.c
+++ b/libglusterfs/src/latency.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
@@ -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;
@@ -145,6 +136,22 @@ gf_update_latency (call_frame_t *frame)
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,23 +164,22 @@ 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);
}
+
+ 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_INFO,
diff --git a/libglusterfs/src/latency.h b/libglusterfs/src/latency.h
index 70499d4ba..81acbf484 100644
--- a/libglusterfs/src/latency.h
+++ b/libglusterfs/src/latency.h
@@ -1,25 +1,17 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef __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 db4e1ab30..392c22ceb 100644
--- a/libglusterfs/src/list.h
+++ b/libglusterfs/src/list.h
@@ -1,26 +1,16 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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)
{
@@ -184,4 +199,16 @@ list_append_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
index 5fee17b3d..969d13e50 100644
--- a/libglusterfs/src/lkowner.h
+++ b/libglusterfs/src/lkowner.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2012 Red Hat <http://www.redhat.com/>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _LK_OWNER_H
@@ -49,7 +40,7 @@ lkowner_unparse (gf_lkowner_t *lkowner, char *buf, int buf_len)
buf[j] = '-';
j++;
}
- sprintf (&buf[j], "%02x", lkowner->data[i]);
+ sprintf (&buf[j], "%02hhx", lkowner->data[i]);
j += 2;
if (j == buf_len)
break;
diff --git a/libglusterfs/src/locking.h b/libglusterfs/src/locking.h
index 44ea12eee..79c6992af 100644
--- a/libglusterfs/src/locking.h
+++ b/libglusterfs/src/locking.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _LOCKING_H
diff --git a/libglusterfs/src/logging.c b/libglusterfs/src/logging.c
index 5485260bc..5deb90cda 100644
--- a/libglusterfs/src/logging.c
+++ b/libglusterfs/src/logging.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#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,50 +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_INFO;
-static int gf_log_syslog = 1;
-static gf_loglevel_t sys_log_level = GF_LOG_CRITICAL;
-
-char gf_log_xl_log_set;
-gf_loglevel_t gf_log_loglevel = GF_LOG_INFO; /* 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;
}
@@ -105,98 +103,312 @@ 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);
+}
+
+
+#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)
+{
+ int _option = option;
+ int _facility = facility;
+
+ if (-1 == _option) {
+ _option = LOG_PID | LOG_NDELAY;
+ }
+ if (-1 == _facility) {
+ _facility = LOG_LOCAL1;
+ }
+
+ setlocale(LC_ALL, "");
+ bindtextdomain("gluster", "/usr/share/locale");
+ textdomain("gluster");
+
+ openlog(ident, _option, _facility);
}
+/**
+ * _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;
+ }
+
+ for (p = (unsigned char *)str;
+ *p && (pos + 1) < len;
+ p++)
+ {
+ if (json_exceptions[*p] == 0) {
+ buf[pos++] = *p;
+ continue;
+ }
+
+ 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;
+}
+
+
+/**
+ * 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, ...)
+{
+ 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_globals_init (void)
+gf_log_globals_init (void *data)
{
- pthread_mutex_init (&logfile_mutex, NULL);
+ 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 (const char *file)
+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) {
- gf_log_logfile = stderr;
-
+ ctx->log.gf_log_logfile = stderr;
+ ctx->log.logfile = stderr;
return 0;
}
- filename = gf_strdup (file);
- if (!filename) {
+ ctx->log.filename = gf_strdup (file);
+ if (!ctx->log.filename) {
fprintf (stderr, "ERROR: updating log-filename failed: %s\n",
strerror (errno));
return -1;
}
- logfile = fopen (file, "a");
- if (!logfile){
+ 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;
}
- gf_log_logfile = logfile;
+ ctx->log.gf_log_logfile = ctx->log.logfile;
return 0;
}
-
-
-struct _msg_queue {
- struct list_head msgs;
-};
-
-struct _log_msg {
- const char *msg;
- struct list_head queue;
-};
-
-
-void
-gf_log_lock (void)
-{
- pthread_mutex_lock (&logfile_mutex);
-}
-
-
-void
-gf_log_unlock (void)
-{
- pthread_mutex_unlock (&logfile_mutex);
-}
-
-
-void
-gf_log_cleanup (void)
-{
- pthread_mutex_destroy (&logfile_mutex);
-}
-
void
set_sys_log_level (gf_loglevel_t level)
{
- sys_log_level = level;
+ THIS->ctx->log.sys_log_level = level;
}
int
@@ -205,22 +417,23 @@ _gf_log_nomem (const char *domain, const char *file,
size_t size)
{
const char *basename = NULL;
- struct tm *tm = NULL;
xlator_t *this = NULL;
struct timeval tv = {0,};
int ret = 0;
- char msg[8092];
- char timestr[256];
- char callstr[4096];
+ char msg[8092] = {0,};
+ char timestr[256] = {0,};
+ char callstr[4096] = {0,};
+ glusterfs_ctx_t *ctx = NULL;
this = THIS;
+ ctx = this->ctx;
- if (gf_log_xl_log_set) {
+ if (ctx->log.gf_log_xl_log_set) {
if (this->loglevel && (level > this->loglevel))
goto out;
- else if (level > gf_log_loglevel)
- goto out;
}
+ if (level > ctx->log.loglevel)
+ goto out;
static char *level_strings[] = {"", /* NONE */
"M", /* EMERGENCY */
@@ -241,6 +454,12 @@ _gf_log_nomem (const char *domain, const char *file,
return -1;
}
+ basename = strrchr (file, '/');
+ if (basename)
+ basename++;
+ else
+ basename = file;
+
#if HAVE_BACKTRACE
/* Print 'calling function' */
do {
@@ -267,36 +486,45 @@ _gf_log_nomem (const char *domain, const char *file,
} 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);
- tm = localtime (&tv.tv_sec);
+ 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 (&logfile_mutex);
+ pthread_mutex_lock (&ctx->log.logfile_mutex);
{
- 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 = 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 unlock;
- }
-
- if (logfile) {
- fprintf (logfile, "%s\n", msg);
- fflush (logfile);
+ if (ctx->log.logfile) {
+ fprintf (ctx->log.logfile, "%s\n", msg);
} else {
fprintf (stderr, "%s\n", msg);
}
@@ -304,13 +532,13 @@ _gf_log_nomem (const char *domain, const char *file,
#ifdef GF_LINUX_HOST_OS
/* We want only serious log in 'syslog', not our debug
and trace logs */
- if (gf_log_syslog && level && (level <= sys_log_level))
+ 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);
out:
return ret;
}
@@ -320,7 +548,6 @@ _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;
xlator_t *this = NULL;
char *str1 = NULL;
char *str2 = NULL;
@@ -331,15 +558,17 @@ _gf_log_callingfn (const char *domain, const char *file, const char *function,
size_t len = 0;
int ret = 0;
va_list ap;
+ glusterfs_ctx_t *ctx = NULL;
this = THIS;
+ ctx = this->ctx;
- if (gf_log_xl_log_set) {
+ if (ctx->log.gf_log_xl_log_set) {
if (this->loglevel && (level > this->loglevel))
goto out;
- else if (level > gf_log_loglevel)
- goto out;
}
+ if (level > ctx->log.loglevel)
+ goto out;
static char *level_strings[] = {"", /* NONE */
"M", /* EMERGENCY */
@@ -360,6 +589,12 @@ _gf_log_callingfn (const char *domain, const char *file, const char *function,
return -1;
}
+ basename = strrchr (file, '/');
+ if (basename)
+ basename++;
+ else
+ basename = file;
+
#if HAVE_BACKTRACE
/* Print 'calling function' */
do {
@@ -386,50 +621,65 @@ _gf_log_callingfn (const char *domain, const char *file, const char *function,
} 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);
-
- 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] %s %d-%s: ",
- timestr, level_strings[level],
- basename, line, function, callstr,
- ((this->graph) ? this->graph->id:0), domain);
- if (-1 == ret) {
- goto unlock;
- }
+ 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;
+ }
- ret = vasprintf (&str2, fmt, ap);
- if (-1 == ret) {
- goto unlock;
- }
+ ret = vasprintf (&str2, fmt, ap);
+ if (-1 == ret) {
+ goto out;
+ }
- 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);
- if (logfile) {
- fprintf (logfile, "%s\n", msg);
- fflush (logfile);
+ pthread_mutex_lock (&ctx->log.logfile_mutex);
+ {
+ if (ctx->log.logfile) {
+ fprintf (ctx->log.logfile, "%s\n", msg);
} else {
fprintf (stderr, "%s\n", msg);
}
@@ -437,25 +687,21 @@ _gf_log_callingfn (const char *domain, const char *file, const char *function,
#ifdef GF_LINUX_HOST_OS
/* We want only serious log in 'syslog', not our debug
and trace logs */
- if (gf_log_syslog && level && (level <= sys_log_level))
+ 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;
}
@@ -463,28 +709,29 @@ int
_gf_log (const char *domain, const char *file, const char *function, int line,
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;
+ 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;
- if (gf_log_xl_log_set) {
+ if (ctx->log.gf_log_xl_log_set) {
if (this->loglevel && (level > this->loglevel))
goto out;
- else if (level > gf_log_loglevel)
- goto out;
}
+ if (level > ctx->log.loglevel)
+ goto out;
static char *level_strings[] = {"", /* NONE */
"M", /* EMERGENCY */
@@ -505,124 +752,221 @@ _gf_log (const char *domain, const char *file, const char *function, int line,
return -1;
}
+ basename = strrchr (file, '/');
+ if (basename)
+ basename++;
+ else
+ basename = file;
- if (logrotate) {
- logrotate = 0;
+#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;
+ }
- new_logfile = fopen (filename, "a");
+ va_start (ap, fmt);
+ vasprintf (&str2, fmt, ap);
+ va_end (ap);
+
+ 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)",
- filename, strerror (errno));
+ ctx->log.filename, strerror (errno));
goto log;
}
- if (logfile)
- fclose (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);
- gf_log_logfile = logfile = new_logfile;
}
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);
+ 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;
+ }
- 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 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);
+ {
- if (logfile) {
- 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 <= sys_log_level))
+ 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);
- }
+err:
+ GF_FREE (msg);
- if (str1)
- GF_FREE (str1);
+ GF_FREE (str1);
- if (str2)
- FREE (str2);
+ FREE (str2);
out:
return (0);
}
+int
+_gf_log_eh (const char *function, const char *fmt, ...)
+{
+ int ret = -1;
+ va_list ap;
+ char *str1 = NULL;
+ char *str2 = NULL;
+ char *msg = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ ret = gf_asprintf (&str1, "[%d] %s: ",
+ ((this->graph)?this->graph->id:0),
+ function);
+ if (-1 == ret) {
+ goto out;
+ }
+
+ va_start (ap, fmt);
+
+ ret = vasprintf (&str2, fmt, ap);
+ if (-1 == ret) {
+ goto out;
+ }
+
+ va_end (ap);
+
+ msg = GF_MALLOC (strlen (str1) + strlen (str2) + 1, gf_common_mt_char);
+ if (!msg) {
+ ret = -1;
+ goto out;
+ }
+
+ strcpy (msg, str1);
+ strcat (msg, str2);
+
+ ret = eh_save_history (this->history, msg);
+
+out:
+ GF_FREE (str1);
+
+ /* Use FREE instead of GF_FREE since str2 was allocated by vasprintf */
+ if (str2)
+ FREE (str2);
+
+ return ret;
+}
int
gf_cmd_log_init (const char *filename)
{
+ int fd = -1;
+ xlator_t *this = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+
+ this = THIS;
+ ctx = this->ctx;
+
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 (!cmd_log_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 (cmdlogfile) {
- fclose (cmdlogfile);
- cmdlogfile = NULL;
+ 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,
+
+ 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", cmd_log_filename, strerror (errno));
+ "(%s)\n", ctx->log.cmd_log_filename, strerror (errno));
return -1;
}
return 0;
@@ -631,17 +975,18 @@ 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;
@@ -654,11 +999,8 @@ gf_cmd_log (const char *domain, const char *fmt, ...)
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);
@@ -681,19 +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 cb23cb54f..cc806a767 100644
--- a/libglusterfs/src/logging.h
+++ b/libglusterfs/src/logging.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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__
@@ -28,6 +19,7 @@
#include <stdint.h>
#include <stdio.h>
#include <stdarg.h>
+#include <pthread.h>
#ifdef GF_DARWIN_HOST_OS
#define GF_PRI_FSBLK "u"
@@ -43,6 +35,7 @@
#define GF_PRI_BLKSIZE PRId32
#define GF_PRI_SIZET "zu"
+
#if 0
/* Syslog definitions :-) */
#define LOG_EMERG 0 /* system is unusable */
@@ -68,25 +61,67 @@ typedef enum {
GF_LOG_TRACE, /* full trace of operation */
} gf_loglevel_t;
-extern gf_loglevel_t gf_log_loglevel;
-extern char gf_log_xl_log_set;
+#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);
+
+int _gf_log_eh (const char *function, const char *fmt, ...);
+
+
#define FMT_WARN(fmt...) do { if (0) printf (fmt); } while (0)
#define gf_log(dom, levl, fmt...) do { \
FMT_WARN (fmt); \
- \
- if ((levl > gf_log_loglevel) && !gf_log_xl_log_set) \
- break; \
_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 { \
FMT_WARN (fmt); \
- \
- if ((levl > gf_log_loglevel) && !gf_log_xl_log_set) \
- break; \
_gf_log_callingfn (dom, __FILE__, __FUNCTION__, __LINE__, \
levl, ##fmt); \
} while (0)
@@ -94,8 +129,6 @@ extern char gf_log_xl_log_set;
/* No malloc or calloc should be called in this function */
#define gf_log_nomem(dom, levl, size) do { \
- if ((levl > gf_log_loglevel) && !gf_log_xl_log_set) \
- break; \
_gf_log_nomem (dom, __FILE__, __FUNCTION__, __LINE__, \
levl, size); \
} while (0)
@@ -106,31 +139,6 @@ extern char gf_log_xl_log_set;
gf_log (args); \
}
-
-void gf_log_logrotate (int signum);
-
-void gf_log_globals_init (void);
-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, ...)
- __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);
-
-int gf_log_from_client (const char *msg, char *identifier);
-
-void gf_log_lock (void);
-void gf_log_unlock (void);
-
void gf_log_disable_syslog (void);
void gf_log_enable_syslog (void);
gf_loglevel_t gf_log_get_loglevel (void);
@@ -138,6 +146,13 @@ 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);
+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);
+
#define GF_DEBUG(xl, format, args...) \
gf_log ((xl)->name, GF_LOG_DEBUG, format, ##args)
#define GF_INFO(xl, format, args...) \
@@ -147,10 +162,4 @@ void gf_log_set_xl_loglevel (void *xl, gf_loglevel_t level);
#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);
#endif /* __LOGGING_H__ */
diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c
index f94723ba3..b901dd7a8 100644
--- a/libglusterfs/src/mem-pool.c
+++ b/libglusterfs/src/mem-pool.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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"
@@ -39,37 +30,18 @@
#define GLUSTERFS_ENV_MEM_ACCT_STR "GLUSTERFS_DISABLE_MEM_ACCT"
-static int gf_mem_acct_enable = 0;
-
-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;
-
-#ifdef DEBUG
- gf_mem_acct_enable = 1;
- return;
-#endif
-
- opt = getenv (GLUSTERFS_ENV_MEM_ACCT_STR);
+ glusterfs_ctx_t *ctx = NULL;
- 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
@@ -84,17 +56,11 @@ 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);
{
@@ -134,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;
@@ -160,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;
@@ -185,7 +151,7 @@ __gf_realloc (void *ptr, size_t size)
xlator_t *xl = NULL;
uint32_t type = 0;
- if (!gf_mem_acct_enable)
+ if (!THIS->ctx->mem_acct_enable)
return REALLOC (ptr, size);
tot_size = size + GF_MEM_HEADER_SIZE + GF_MEM_TRAILER_SIZE;
@@ -258,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;
}
@@ -268,20 +234,16 @@ __gf_free (void *free_ptr)
ptr = (char *)free_ptr - 8 - 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;
@@ -294,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);
@@ -326,7 +287,7 @@ mem_pool_new_fn (unsigned long sizeof_type,
glusterfs_ctx_t *ctx = NULL;
if (!sizeof_type || !count) {
- gf_log ("mem-pool", GF_LOG_ERROR, "invalid argument");
+ gf_log_callingfn ("mem-pool", GF_LOG_ERROR, "invalid argument");
return NULL;
}
padded_sizeof_type = sizeof_type + GF_MEM_POOL_PAD_BOUNDARY;
@@ -369,7 +330,7 @@ mem_pool_new_fn (unsigned long sizeof_type,
mem_pool->pool_end = pool + (count * (padded_sizeof_type));
/* add this pool to the global list */
- ctx = glusterfs_ctx_get ();
+ ctx = THIS->ctx;
if (!ctx)
goto out;
@@ -385,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;
}
@@ -406,7 +367,7 @@ mem_get (struct mem_pool *mem_pool)
struct mem_pool **pool_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;
}
@@ -451,10 +412,12 @@ mem_get (struct mem_pool *mem_pool)
* because it is too much work knowing that a better slab
* allocator is coming RSN.
*/
+ 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);
- gf_log_callingfn ("mem-pool", GF_LOG_DEBUG, "Mem pool is full. "
- "Callocing mem");
/* Memory coming from the heap need not be transformed from a
* chunkhead to a usable pointer since it is not coming from
@@ -475,7 +438,7 @@ static int
__is_member (struct mem_pool *pool, void *ptr)
{
if (!pool || !ptr) {
- gf_log ("mem-pool", GF_LOG_ERROR, "invalid argument");
+ gf_log_callingfn ("mem-pool", GF_LOG_ERROR, "invalid argument");
return -1;
}
@@ -500,20 +463,22 @@ mem_put (void *ptr)
struct mem_pool *pool = NULL;
if (!ptr) {
- gf_log ("mem-pool", GF_LOG_ERROR, "invalid argument");
+ 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 ("mem-pool", GF_LOG_ERROR, "ptr header is corrupted");
+ gf_log_callingfn ("mem-pool", GF_LOG_ERROR,
+ "ptr header is corrupted");
return;
}
pool = *tmp;
if (!pool) {
- gf_log ("mem-pool", GF_LOG_ERROR, "mem-pool ptr is NULL");
+ gf_log_callingfn ("mem-pool", GF_LOG_ERROR,
+ "mem-pool ptr is NULL");
return;
}
LOCK (&pool->lock);
@@ -553,6 +518,7 @@ mem_put (void *ptr)
* not have enough info to distinguish between the two
* situations.
*/
+ pool->curr_stdalloc--;
GF_FREE (list);
break;
default:
diff --git a/libglusterfs/src/mem-pool.h b/libglusterfs/src/mem-pool.h
index a23b12202..31f49f75c 100644
--- a/libglusterfs/src/mem-pool.h
+++ b/libglusterfs/src/mem-pool.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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_
@@ -116,7 +107,26 @@ void* __gf_default_realloc (void *oldptr, size_t size)
#define GF_REALLOC(ptr, size) __gf_realloc (ptr, size)
-#define GF_FREE(free_ptr) __gf_free (free_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;
+
+ 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)
@@ -137,6 +147,21 @@ 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;
@@ -147,7 +172,10 @@ struct mem_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;
};
@@ -163,7 +191,6 @@ 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 b8c61d689..666bd120a 100644
--- a/libglusterfs/src/mem-types.h
+++ b/libglusterfs/src/mem-types.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef __MEM_TYPES_H__
@@ -106,6 +97,29 @@ enum gf_common_mem_types_ {
gf_common_mt_trie_end = 81,
gf_common_mt_run_argv = 82,
gf_common_mt_run_logbuf = 83,
- gf_common_mt_end = 84
+ 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
index b8d3b6ae5..842b6413a 100644
--- a/libglusterfs/src/options.c
+++ b/libglusterfs/src/options.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -62,7 +53,6 @@ out:
return ret;
}
-
static int
xlator_option_validate_int (xlator_t *xl, const char *key, const char *value,
volume_option_t *opt, char **op_errstr)
@@ -80,18 +70,37 @@ xlator_option_validate_int (xlator_t *xl, const char *key, const char *value,
goto out;
}
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (xl->name, GF_LOG_DEBUG,
+ 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 ((inputll < opt->min) || (inputll > opt->max)) {
+ 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 "
- "[%"PRId64" - %"PRId64"]",
+ "[%.0f - %.0f]",
inputll, key, value, opt->min, opt->max);
gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
goto out;
@@ -110,7 +119,7 @@ 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 = -1;
+ int ret = 0;
char errstr[256];
/* Check the range */
@@ -119,37 +128,34 @@ xlator_option_validate_sizet (xlator_t *xl, const char *key, const char *value,
"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_DEBUG,
+ 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)) {
- if (strncmp (key, "cache-size", 10) == 0) {
+ if ((strncmp (key, "cache-size", 10) == 0) &&
+ (size > opt->max)) {
snprintf (errstr, 256, "Cache size %"PRId64" is out of "
- "range [%"PRId64" - %"PRId64"]",
+ "range [%.0f - %.0f]",
size, opt->min, opt->max);
- //*op_errstr = gf_strdup (errstr);
gf_log (xl->name, GF_LOG_WARNING, "%s", errstr);
- ret = 0;
- goto out;
} else {
snprintf (errstr, 256,
"'%"PRId64"' in 'option %s %s' "
- "is out of range [%"PRId64" - %"PRId64"]",
+ "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 = -1;
}
}
- ret = 0;
out:
if (ret && op_errstr)
*op_errstr = gf_strdup (errstr);
@@ -222,6 +228,46 @@ out:
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,
@@ -229,8 +275,7 @@ xlator_option_validate_str (xlator_t *xl, const char *key, const char *value,
{
int ret = -1;
int i = 0;
- char errstr[256];
- char given_array[4096] = {0,};
+ char errstr[4096] = {0,};
/* Check if the '*str' is valid */
if (GF_OPTION_LIST_EMPTY(opt)) {
@@ -238,6 +283,9 @@ xlator_option_validate_str (xlator_t *xl, const char *key, const char *value,
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) {
@@ -252,7 +300,8 @@ xlator_option_validate_str (xlator_t *xl, const char *key, const char *value,
#endif
}
- if ((i <= ZR_OPTION_MAX_ARRAY_SIZE) && (!opt->value[i])) {
+ 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
@@ -262,26 +311,15 @@ xlator_option_validate_str (xlator_t *xl, const char *key, const char *value,
* matched all possible input values.
*/
- 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, 256,
- "option %s %s: '%s' is not valid "
- "(possible options are %s)",
- key, value, value, given_array);
- gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
- goto out;
- }
-
ret = 0;
+
out:
- if (ret && op_errstr)
- *op_errstr = gf_strdup (errstr);
+ 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;
}
@@ -290,10 +328,9 @@ static int
xlator_option_validate_percent (xlator_t *xl, const char *key, const char *value,
volume_option_t *opt, char **op_errstr)
{
- int ret = -1;
- char errstr[256];
- uint32_t percent = 0;
-
+ double percent = 0;
+ int ret = -1;
+ char errstr[256];
/* Check if the value is valid percentage */
if (gf_string2percent (value, &percent) != 0) {
@@ -304,9 +341,9 @@ xlator_option_validate_percent (xlator_t *xl, const char *key, const char *value
goto out;
}
- if ((percent < 0) || (percent > 100)) {
+ if ((percent < 0.0) || (percent > 100.0)) {
snprintf (errstr, 256,
- "'%d' in 'option %s %s' is out of range [0 - 100]",
+ "'%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;
@@ -319,8 +356,6 @@ out:
return ret;
}
-
-/* TODO: clean this up */
static int
xlator_option_validate_percent_or_sizet (xlator_t *xl, const char *key,
const char *value,
@@ -328,88 +363,43 @@ xlator_option_validate_percent_or_sizet (xlator_t *xl, const char *key,
{
int ret = -1;
char errstr[256];
- uint32_t percent = 0;
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);
- /* Check if the value is valid percentage */
- if (gf_string2percent (value, &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 (value, &size) == 0) {
- /* Check the range */
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "no range check rquired for "
- "'option %s %s'",
- key, value);
- // It is a size
- ret = 0;
- goto out;
- }
- if ((size < opt->min) || (size > opt->max)) {
- snprintf (errstr, 256,
- "'%"PRId64"' in 'option %s %s' "
- "is out of range [%"PRId64" - "
- "%"PRId64"]",
- size, key, value,
- opt->min, opt->max);
- gf_log (xl->name, GF_LOG_ERROR, "%s",
- errstr);
- goto out;
- }
- // It is a size
- ret = 0;
- goto out;
- } else {
- // It's not a percent or size
- snprintf (errstr, 256,
- "invalid number format \"%s\" "
- "in \"option %s\"",
- value, key);
- gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
- goto out;
- }
- }
- // It is a percent
- ret = 0;
- goto out;
- } else {
- if (gf_string2bytesize (value, &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'",
- key, value);
- // It is a size
- ret = 0;
- goto out;
- }
- if ((size < opt->min) || (size > opt->max)) {
- snprintf (errstr, 256,
- "'%"PRId64"' in 'option %s %s'"
- " is out of range [%"PRId64" -"
- " %"PRId64"]",
- size, key, value, opt->min, opt->max);
- gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
- goto out;
- }
- } else {
- // It's not a percent or size
- snprintf (errstr, 256,
- "invalid number format \"%s\" in \"option %s\"",
- value, key);
- gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
- goto out;
- }
- //It is a size
- ret = 0;
- goto out;
- }
- ret = 0;
out:
if (ret && op_errstr)
*op_errstr = gf_strdup (errstr);
@@ -425,7 +415,7 @@ xlator_option_validate_time (xlator_t *xl, const char *key, const char *value,
char errstr[256];
uint32_t input_time = 0;
- /* Check if the value is valid percentage */
+ /* Check if the value is valid time */
if (gf_string2time (value, &input_time) != 0) {
snprintf (errstr, 256,
"invalid time format \"%s\" in "
@@ -436,7 +426,7 @@ xlator_option_validate_time (xlator_t *xl, const char *key, const char *value,
}
if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (xl->name, GF_LOG_DEBUG,
+ gf_log (xl->name, GF_LOG_TRACE,
"no range check required for "
"'option %s %s'",
key, value);
@@ -447,7 +437,7 @@ xlator_option_validate_time (xlator_t *xl, const char *key, const char *value,
if ((input_time < opt->min) || (input_time > opt->max)) {
snprintf (errstr, 256,
"'%"PRIu32"' in 'option %s %s' is "
- "out of range [%"PRId64" - %"PRId64"]",
+ "out of range [%.0f - %.0f]",
input_time, key, value,
opt->min, opt->max);
gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
@@ -466,35 +456,55 @@ static int
xlator_option_validate_double (xlator_t *xl, const char *key, const char *value,
volume_option_t *opt, char **op_errstr)
{
- int ret = -1;
- char errstr[256];
- double val = 0.0;
-
- /* Check if the value is valid double */
- if (gf_string2double (value, &val) != 0) {
- snprintf (errstr, 256,
- "invalid double \"%s\" in \"option %s\"",
- value, key);
- gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
- goto out;
- }
+ double input = 0.0;
+ int ret = -1;
+ char errstr[256];
- if (val < 0.0) {
+ /* Check the range */
+ if (gf_string2double (value, &input) != 0) {
snprintf (errstr, 256,
- "invalid double \"%s\" in \"option %s\"",
+ "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)) {
- gf_log (xl->name, GF_LOG_DEBUG,
+ 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)
@@ -510,10 +520,11 @@ xlator_option_validate_addr (xlator_t *xl, const char *key, const char *value,
int ret = -1;
char errstr[256];
- if (!valid_internet_address ((char *)value)) {
+ if (!valid_internet_address ((char *)value, _gf_false)) {
snprintf (errstr, 256,
- "internet address '%s' does not conform to standards.",
- value);
+ "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);
@@ -524,6 +535,178 @@ xlator_option_validate_addr (xlator_t *xl, const char *key, const char *value,
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,
@@ -532,7 +715,6 @@ xlator_option_validate_any (xlator_t *xl, const char *key, const char *value,
return 0;
}
-
typedef int (xlator_option_validator_t) (xlator_t *xl, const char *key,
const char *value,
volume_option_t *opt, char **operrstr);
@@ -556,6 +738,11 @@ xlator_option_validate (xlator_t *xl, char *key, char *value,
[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,
};
@@ -574,7 +761,7 @@ out:
}
-static volume_option_t *
+volume_option_t *
xlator_volume_option_get_list (volume_opt_list_t *vol_list, const char *key)
{
volume_option_t *opt = NULL;
@@ -591,7 +778,7 @@ xlator_volume_option_get_list (volume_opt_list_t *vol_list, const char *key)
} else
opt = vol_list->given_opt;
- for (index = 0; opt[index].key && opt[index].key[0]; index++) {
+ 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)
@@ -623,7 +810,7 @@ xlator_volume_option_get (xlator_t *xl, const char *key)
}
-static void
+static int
xl_opt_validate (dict_t *dict, char *key, data_t *value, void *data)
{
xlator_t *xl = NULL;
@@ -644,7 +831,7 @@ xl_opt_validate (dict_t *dict, char *key, data_t *value, void *data)
opt = xlator_volume_option_get_list (vol_opt, key);
if (!opt)
- return;
+ return 0;
ret = xlator_option_validate (xl, key, value->data, opt, &errstr);
if (ret)
@@ -662,7 +849,7 @@ xl_opt_validate (dict_t *dict, char *key, data_t *value, void *data)
dict_set (dict, opt->key[0], value);
dict_del (dict, key);
}
- return;
+ return 0;
}
@@ -867,11 +1054,8 @@ out:
static int
-not_null (char *in, char **out)
+pass (char *in, char **out)
{
- if (!in || !out)
- return -1;
-
*out = in;
return 0;
}
@@ -892,46 +1076,52 @@ xl_by_name (char *in, xlator_t **out)
static int
-pc_or_size (char *in, uint64_t *out)
+pc_or_size (char *in, double *out)
{
- uint32_t pc = 0;
+ double pc = 0;
int ret = 0;
+ uint64_t size = 0;
if (gf_string2percent (in, &pc) == 0) {
- if (pc > 100) {
- ret = gf_string2bytesize (in, out);
+ if (pc > 100.0) {
+ ret = gf_string2bytesize (in, &size);
+ if (!ret)
+ *out = size;
} else {
*out = pc;
}
} else {
- ret = gf_string2bytesize (in, out);
+ ret = gf_string2bytesize (in, &size);
+ if (!ret)
+ *out = size;
}
return ret;
}
-
-DEFINE_INIT_OPT(char *, str, not_null);
+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(uint32_t, percent, gf_string2percent);
-DEFINE_INIT_OPT(uint64_t, percent_or_size, pc_or_size);
+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, not_null);
+DEFINE_INIT_OPT(char *, path, pass);
+DEFINE_INIT_OPT(double, double, gf_string2double);
-DEFINE_RECONF_OPT(char *, str, not_null);
+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(uint32_t, percent, gf_string2percent);
-DEFINE_RECONF_OPT(uint64_t, percent_or_size, pc_or_size);
+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, not_null);
+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
index 40089ac63..e2a25baa9 100644
--- a/libglusterfs/src/options.h
+++ b/libglusterfs/src/options.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _OPTIONS_H
@@ -44,25 +35,38 @@ typedef enum {
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];
+ char *key[ZR_VOLUME_MAX_NUM_KEY];
/* different key, same meaning */
- volume_option_type_t type;
- int64_t min; /* 0 means no range */
- int64_t max; /* 0 means no range */
- char *value[ZR_OPTION_MAX_ARRAY_SIZE];
+ 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 */
+ 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;
@@ -89,6 +93,9 @@ 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 \
@@ -101,11 +108,12 @@ 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(uint32_t, percent);
-DECLARE_INIT_OPT(uint64_t, percent_or_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) \
@@ -137,10 +145,11 @@ xlator_option_init_##type (xlator_t *this, dict_t *options, char *key, \
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_DEBUG, \
+ gf_log (this->name, GF_LOG_TRACE, \
"option %s using default value %s", \
key, value); \
} else { \
@@ -179,11 +188,12 @@ 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(uint32_t, percent);
-DECLARE_RECONF_OPT(uint64_t, percent_or_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) \
@@ -215,6 +225,7 @@ xlator_option_reconf_##type (xlator_t *this, dict_t *options, char *key, \
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) { \
diff --git a/libglusterfs/src/rbthash.c b/libglusterfs/src/rbthash.c
index beda672d0..0d7b9e521 100644
--- a/libglusterfs/src/rbthash.c
+++ b/libglusterfs/src/rbthash.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
@@ -217,8 +208,7 @@ 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))
@@ -237,7 +227,7 @@ rbthash_deinit_entry (rbthash_table_t *tbl, rbthash_entry_t *entry)
}
-inline struct rbthash_bucket *
+static inline struct rbthash_bucket *
rbthash_entry_bucket (rbthash_table_t *tbl, rbthash_entry_t * entry)
{
int nbucket = 0;
@@ -311,7 +301,7 @@ 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;
diff --git a/libglusterfs/src/rbthash.h b/libglusterfs/src/rbthash.h
index 02a65b4a8..b093ce998 100644
--- a/libglusterfs/src/rbthash.h
+++ b/libglusterfs/src/rbthash.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef __RBTHASH_TABLE_H_
diff --git a/libglusterfs/src/run.c b/libglusterfs/src/run.c
index 46bb37d73..4fd2a3a0d 100644
--- a/libglusterfs/src/run.c
+++ b/libglusterfs/src/run.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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
@@ -30,7 +21,9 @@
#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)
@@ -74,7 +67,10 @@ runner_chio (runner_t *runner, int fd)
{
GF_ASSERT (fd > 0 && fd < 3);
- return runner->chio[fd];
+ if ((fd > 0) && (fd < 3))
+ return runner->chio[fd];
+
+ return NULL;
}
static void
@@ -191,7 +187,7 @@ runner_log (runner_t *runner, const char *dom, gf_loglevel_t lvl,
if (len > 0)
buf[len - 1] = '\0';
- gf_log (dom, lvl, "%s: %s", msg, buf);
+ gf_log_callingfn (dom, lvl, "%s: %s", msg, buf);
GF_FREE (buf);
}
@@ -201,7 +197,8 @@ runner_redir (runner_t *runner, int fd, int tgt_fd)
{
GF_ASSERT (fd > 0 && fd < 3);
- runner->chfd[fd] = (tgt_fd >= 0) ? tgt_fd : -2;
+ if ((fd > 0) && (fd < 3))
+ runner->chfd[fd] = (tgt_fd >= 0) ? tgt_fd : -2;
}
int
@@ -293,7 +290,11 @@ runner_start (runner_t *runner)
} else
ret = -1;
#else
- for (i = 3; i < 65536; i++) {
+ 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);
}
@@ -364,9 +365,11 @@ runner_end (runner_t *runner)
ret = runner_end_reuse (runner);
- for (p = runner->argv; *p; p++)
- GF_FREE (*p);
- GF_FREE (runner->argv);
+ 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]);
@@ -379,10 +382,8 @@ runner_run_generic (runner_t *runner, int (*rfin)(runner_t *runner))
int ret = 0;
ret = runner_start (runner);
- if (ret != 0)
- return -1;
- return rfin (runner) ? -1 : 0;
+ return -(rfin (runner) || ret);
}
int
@@ -391,6 +392,25 @@ 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)
{
@@ -422,7 +442,7 @@ TBANNER (const char *txt)
}
int
-main ()
+main (int argc, char **argv)
{
runner_t runner;
char buf[80];
@@ -430,6 +450,8 @@ main ()
int ret;
int fd;
long pathmax = pathconf ("/", _PC_PATH_MAX);
+ struct timeval tv = {0,};
+ struct timeval *tvp = NULL;
wdbuf = malloc (pathmax);
assert (wdbuf);
@@ -468,7 +490,7 @@ main ()
printf ("%d %d [%s]\n", ret, errno, strerror (errno));
TBANNER ("output redirection");
- fd = open ("/tmp/foof", O_WRONLY|O_CREAT|O_TRUNC, 0600);
+ fd = mkstemp ("/tmp/foof");
assert (fd != -1);
runinit (&runner);
runner_add_args (&runner, "echo", "foo", NULL);
@@ -479,6 +501,13 @@ main ()
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
index 70b61aff8..d7554ef6d 100644
--- a/libglusterfs/src/run.h
+++ b/libglusterfs/src/run.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ 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__
@@ -175,6 +166,12 @@ int runner_end_reuse (runner_t *runner);
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.
*
diff --git a/libglusterfs/src/scheduler.c b/libglusterfs/src/scheduler.c
deleted file mode 100644
index f27875dc2..000000000
--- a/libglusterfs/src/scheduler.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _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 acb6597b9..000000000
--- a/libglusterfs/src/scheduler.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _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 29b44aedf..37b338f51 100644
--- a/libglusterfs/src/stack.c
+++ b/libglusterfs/src/stack.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#include "statedump.h"
@@ -35,6 +26,44 @@ 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,...)
{
@@ -43,6 +72,7 @@ gf_proc_dump_call_frame (call_frame_t *call_frame, const char *key_buf,...)
va_list ap;
call_frame_t my_frame;
int ret = -1;
+ char timestr[256] = {0,};
if (!call_frame)
return;
@@ -56,15 +86,21 @@ gf_proc_dump_call_frame (call_frame_t *call_frame, const char *key_buf,...)
va_end(ap);
ret = TRY_LOCK(&call_frame->lock);
- if (ret) {
- gf_log("", GF_LOG_WARNING, "Unable to dump call frame"
- " errno: %s", strerror (errno));
- return;
- }
+ if (ret)
+ goto out;
memcpy(&my_frame, call_frame, sizeof(my_frame));
UNLOCK(&call_frame->lock);
+ 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);
@@ -82,6 +118,14 @@ gf_proc_dump_call_frame (call_frame_t *call_frame, const char *key_buf,...)
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;
+ }
}
@@ -92,6 +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 timestr[256] = {0,};
if (!call_stack)
return;
@@ -105,15 +150,26 @@ gf_proc_dump_call_stack (call_stack_t *call_stack, const char *key_buf,...)
vsnprintf(prefix, GF_DUMP_MAX_BUF_LEN, key_buf, ap);
va_end(ap);
+ 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));
if (call_stack->type == GF_OP_TYPE_FOP)
- gf_proc_dump_write("op", "%s", gf_fop_list[call_stack->op]);
- else if (call_stack->type == GF_OP_TYPE_MGMT)
- gf_proc_dump_write("op", "%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_write("type", "%d", call_stack->type);
gf_proc_dump_write("cnt", "%d", cnt);
@@ -136,19 +192,18 @@ 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");
+ section_added = _gf_true;
gf_proc_dump_write("callpool_address","%p", call_pool);
gf_proc_dump_write("callpool.cnt","%d", call_pool->cnt);
@@ -159,6 +214,17 @@ gf_proc_dump_pending_frames (call_pool_t *call_pool)
i++;
}
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
@@ -186,7 +252,7 @@ gf_proc_dump_call_frame_to_dict (call_frame_t *call_frame,
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "%s.translator", prefix);
- ret = dict_set_str (dict, key, gf_strdup (tmp_frame.this->name));
+ ret = dict_set_dynstr (dict, key, gf_strdup (tmp_frame.this->name));
if (ret)
return;
@@ -199,7 +265,7 @@ gf_proc_dump_call_frame_to_dict (call_frame_t *call_frame,
if (tmp_frame.parent) {
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "%s.parent", prefix);
- ret = dict_set_str (dict, key,
+ ret = dict_set_dynstr (dict, key,
gf_strdup (tmp_frame.parent->this->name));
if (ret)
return;
@@ -208,7 +274,8 @@ gf_proc_dump_call_frame_to_dict (call_frame_t *call_frame,
if (tmp_frame.wind_from) {
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "%s.windfrom", prefix);
- ret = dict_set_str (dict, key, gf_strdup (tmp_frame.wind_from));
+ ret = dict_set_dynstr (dict, key,
+ gf_strdup (tmp_frame.wind_from));
if (ret)
return;
}
@@ -216,7 +283,8 @@ gf_proc_dump_call_frame_to_dict (call_frame_t *call_frame,
if (tmp_frame.wind_to) {
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "%s.windto", prefix);
- ret = dict_set_str (dict, key, gf_strdup (tmp_frame.wind_to));
+ ret = dict_set_dynstr (dict, key,
+ gf_strdup (tmp_frame.wind_to));
if (ret)
return;
}
@@ -224,7 +292,8 @@ gf_proc_dump_call_frame_to_dict (call_frame_t *call_frame,
if (tmp_frame.unwind_from) {
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "%s.unwindfrom", prefix);
- ret = dict_set_str (dict, key, gf_strdup (tmp_frame.unwind_from));
+ ret = dict_set_dynstr (dict, key,
+ gf_strdup (tmp_frame.unwind_from));
if (ret)
return;
}
@@ -232,7 +301,8 @@ gf_proc_dump_call_frame_to_dict (call_frame_t *call_frame,
if (tmp_frame.unwind_to) {
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "%s.unwind_to", prefix);
- ret = dict_set_str (dict, key, gf_strdup (tmp_frame.unwind_to));
+ ret = dict_set_dynstr (dict, key,
+ gf_strdup (tmp_frame.unwind_to));
}
return;
@@ -281,10 +351,10 @@ gf_proc_dump_call_stack_to_dict (call_stack_t *call_stack,
snprintf (key, sizeof (key), "%s.op", prefix);
if (call_stack->type == GF_OP_TYPE_FOP)
ret = dict_set_str (dict, key,
- gf_fop_list[call_stack->op]);
- else if (call_stack->type == GF_OP_TYPE_MGMT)
- ret = dict_set_str (dict, key,
- gf_mgmt_list[call_stack->op]);
+ (char *)gf_fop_list[call_stack->op]);
+ else
+ ret = dict_set_str (dict, key, "other");
+
if (ret)
return;
diff --git a/libglusterfs/src/stack.h b/libglusterfs/src/stack.h
index c84040576..f2d2ef950 100644
--- a/libglusterfs/src/stack.h
+++ b/libglusterfs/src/stack.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
/*
@@ -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>
@@ -45,6 +36,7 @@ typedef struct _call_pool_t call_pool_t;
#include "common-utils.h"
#include "globals.h"
#include "lkowner.h"
+#include "client_t.h"
#define NFS_PID 1
#define LOW_PRIO_PROC_PID -1
@@ -55,7 +47,7 @@ typedef int32_t (*ret_fn_t) (call_frame_t *frame,
int32_t op_errno,
...);
-struct _call_pool_t {
+struct call_pool {
union {
struct list_head all_frames;
struct {
@@ -91,6 +83,8 @@ struct _call_frame_t {
const char *unwind_to;
};
+#define SMALL_GROUP_COUNT 128
+
struct _call_stack_t {
union {
struct list_head all_frames;
@@ -101,20 +95,24 @@ struct _call_stack_t {
};
call_pool_t *pool;
gf_lock_t stack_lock;
- void *trans;
+ 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[GF_MAX_AUX_GROUPS];
+ 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;
};
@@ -131,11 +129,10 @@ struct _call_stack_t {
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)
@@ -155,7 +152,7 @@ FRAME_DESTROY (call_frame_t *frame)
mem_put (frame);
if (local)
- GF_FREE (local);
+ mem_put (local);
}
@@ -177,16 +174,37 @@ STACK_DESTROY (call_stack_t *stack)
}
LOCK_DESTROY (&stack->frames.lock);
+ LOCK_DESTROY (&stack->stack_lock);
while (stack->frames.next) {
FRAME_DESTROY (stack->frames.next);
}
+
+ GF_FREE (stack->groups_large);
+
mem_put (stack);
if (local)
- GF_FREE (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
@@ -227,6 +245,7 @@ STACK_DESTROY (call_stack_t *stack)
_new->wind_from = __FUNCTION__; \
_new->wind_to = #fn; \
_new->unwind_to = #rfn; \
+ \
LOCK_INIT (&_new->lock); \
LOCK(&frame->root->stack_lock); \
{ \
@@ -240,11 +259,27 @@ STACK_DESTROY (call_stack_t *stack)
UNLOCK(&frame->root->stack_lock); \
old_THIS = THIS; \
THIS = obj; \
+ if (frame->this->ctx->measure_latency) \
+ gf_latency_begin (_new, fn); \
fn (_new, obj, params); \
THIS = old_THIS; \
} 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 { \
@@ -279,6 +314,8 @@ STACK_DESTROY (call_stack_t *stack)
fn##_cbk = rfn; \
old_THIS = THIS; \
THIS = obj; \
+ if (obj->ctx->measure_latency) \
+ gf_latency_begin (_new, fn); \
fn (_new, obj, params); \
THIS = old_THIS; \
} while (0)
@@ -305,6 +342,8 @@ STACK_DESTROY (call_stack_t *stack)
THIS = _parent->this; \
frame->complete = _gf_true; \
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)
@@ -332,11 +371,31 @@ STACK_DESTROY (call_stack_t *stack)
THIS = _parent->this; \
frame->complete = _gf_true; \
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)
+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)
{
@@ -360,14 +419,27 @@ copy_frame (call_frame_t *frame)
newstack->ngrps = oldstack->ngrps;
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) * GF_MAX_AUX_GROUPS);
+ sizeof (gid_t) * oldstack->ngrps);
newstack->unique = oldstack->unique;
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_INIT (&newstack->frames.lock);
LOCK_INIT (&newstack->stack_lock);
@@ -382,39 +454,9 @@ copy_frame (call_frame_t *frame)
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) {
- return NULL;
- }
-
- stack = mem_get0 (pool->stack_mem_pool);
- if (!stack)
- return NULL;
-
- stack->pool = pool;
- stack->frames.root = stack;
- stack->frames.this = xl;
-
- 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_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 8c6fe9215..8175faba4 100644
--- a/libglusterfs/src/statedump.c
+++ b/libglusterfs/src/statedump.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#include <stdarg.h>
@@ -30,7 +21,8 @@
#endif /* MALLOC_H */
/* We don't want gf_log in this function because it may cause
- 'deadlock' with statedump */
+ '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
@@ -61,17 +53,12 @@ gf_proc_dump_unlock (void)
pthread_mutex_unlock (&gf_proc_dump_mutex);
}
-
static int
-gf_proc_dump_open (char *dump_dir, char *brickname)
+gf_proc_dump_open (char *tmpname)
{
- char path[PATH_MAX] = {0,};
int dump_fd = -1;
- snprintf (path, sizeof (path), "%s/%s.%d.dump", (dump_dir ?
- dump_dir : "/tmp"), brickname, getpid());
-
- dump_fd = open (path, O_CREAT|O_RDWR|O_TRUNC|O_APPEND, 0600);
+ dump_fd = mkstemp (tmpname);
if (dump_fd < 0)
return -1;
@@ -79,7 +66,6 @@ gf_proc_dump_open (char *dump_dir, char *brickname)
return 0;
}
-
static void
gf_proc_dump_close (void)
{
@@ -87,6 +73,45 @@ 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;
+
+ 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, ...)
@@ -305,6 +330,9 @@ gf_proc_dump_mempool_info (glusterfs_ctx_t *ctx)
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);
}
}
@@ -356,6 +384,17 @@ gf_proc_dump_mempool_info_to_dict (glusterfs_ctx_t *ctx, dict_t *dict)
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);
@@ -375,7 +414,7 @@ gf_proc_dump_xlator_info (xlator_t *top)
if (!top)
return;
- ctx = glusterfs_ctx_get ();
+ ctx = top->ctx;
trav = top;
while (trav) {
@@ -389,8 +428,6 @@ gf_proc_dump_xlator_info (xlator_t *top)
(trav->itable)) {
snprintf (itable_key, 1024, "%d.%s.itable",
ctx->graph_id, trav->name);
-
- inode_table_dump (trav->itable, itable_key);
}
if (!trav->dumpops) {
@@ -410,6 +447,10 @@ gf_proc_dump_xlator_info (xlator_t *top)
GF_PROC_DUMP_IS_XL_OPTION_ENABLED (fd))
trav->dumpops->fd (trav);
+ if (trav->dumpops->history &&
+ GF_PROC_DUMP_IS_XL_OPTION_ENABLED (history))
+ trav->dumpops->history (trav);
+
trav = trav->next;
}
@@ -420,24 +461,20 @@ static void
gf_proc_dump_oldgraph_xlator_info (xlator_t *top)
{
xlator_t *trav = NULL;
- glusterfs_ctx_t *ctx = NULL;
- char itable_key[1024] = {0,};
if (!top)
return;
- ctx = glusterfs_ctx_get ();
-
trav = top;
while (trav) {
gf_proc_dump_xlator_mem_info_only_in_use (trav);
if (GF_PROC_DUMP_IS_XL_OPTION_ENABLED (inode) &&
(trav->itable)) {
- snprintf (itable_key, 1024, "%d.%s.itable",
- ctx->graph_id, trav->name);
-
- inode_table_dump (trav->itable, itable_key);
+ /*TODO: dump inode table info if necessary by
+ printing the graph id (taken by glusterfs_cbtx_t)
+ in the key
+ */
}
if (!trav->dumpops) {
@@ -472,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;
}
@@ -490,7 +567,8 @@ gf_proc_dump_disable_all_options ()
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;
}
@@ -502,25 +580,27 @@ gf_proc_dump_parse_set_option (char *key, char *value)
char buf[GF_DUMP_MAX_BUF_LEN];
int ret = -1;
- if (!strncasecmp (key, "all", 3)) {
+ if (!strcasecmp (key, "all")) {
(void)gf_proc_dump_enable_all_options ();
return 0;
- } else if (!strncasecmp (key, "mem", 3)) {
+ } else if (!strcasecmp (key, "mem")) {
opt_key = &dump_options.dump_mem;
- } else if (!strncasecmp (key, "iobuf", 5)) {
+ } else if (!strcasecmp (key, "iobuf")) {
opt_key = &dump_options.dump_iobuf;
- } else if (!strncasecmp (key, "callpool", 8)) {
+ } else if (!strcasecmp (key, "callpool")) {
opt_key = &dump_options.dump_callpool;
- } else if (!strncasecmp (key, "priv", 4)) {
+ } else if (!strcasecmp (key, "priv")) {
opt_key = &dump_options.xl_options.dump_priv;
- } else if (!strncasecmp (key, "fd", 2)) {
+ } else if (!strcasecmp (key, "fd")) {
opt_key = &dump_options.xl_options.dump_fd;
- } else if (!strncasecmp (key, "inode", 5)) {
+ } else if (!strcasecmp (key, "inode")) {
opt_key = &dump_options.xl_options.dump_inode;
- } else if (!strncasecmp (key, "inodectx", strlen ("inodectx"))) {
+ } else if (!strcasecmp (key, "inodectx")) {
opt_key = &dump_options.xl_options.dump_inodectx;
- } else if (!strncasecmp (key, "fdctx", strlen ("fdctx"))) {
+ } 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) {
@@ -529,11 +609,9 @@ gf_proc_dump_parse_set_option (char *key, char *value)
"matched key : %s\n", key);
ret = write (gf_dump_fd, buf, strlen (buf));
- /* warning suppression */
- if (ret >= 0) {
+ if (ret >= 0)
ret = -1;
- goto out;
- }
+ goto out;
}
@@ -548,33 +626,49 @@ out:
}
static int
-gf_proc_dump_options_init (char *dump_name)
+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;
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),
- "/tmp/glusterdump.%d.options", getpid ());
-
+ 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);
@@ -588,28 +682,33 @@ gf_proc_dump_options_init (char *dump_name)
continue;
}
- snprintf (dumpbuf, sizeof (dumpbuf), "[Debug]:key=%s, value=%s\n",key,value);
- ret = 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 i = 0;
- int ret = -1;
- glusterfs_ctx_t *ctx = NULL;
- glusterfs_graph_t *trav = NULL;
- char brick_name[PATH_MAX] = {0,};
+ 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 ();
- ctx = glusterfs_ctx_get ();
if (!ctx)
goto out;
@@ -618,14 +717,44 @@ gf_proc_dump_info (int signum)
} else
strncpy (brick_name, "glusterdump", sizeof (brick_name));
- ret = gf_proc_dump_options_init (brick_name);
+ ret = gf_proc_dump_options_init ();
if (ret < 0)
goto out;
- ret = gf_proc_dump_open (ctx->statedump_path, brick_name);
+ 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);
@@ -657,8 +786,24 @@ gf_proc_dump_info (int signum)
i++;
}
- gf_proc_dump_close ();
+ 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), "\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;
diff --git a/libglusterfs/src/statedump.h b/libglusterfs/src/statedump.h
index cdeb5b7fc..8342b120a 100644
--- a/libglusterfs/src/statedump.h
+++ b/libglusterfs/src/statedump.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
@@ -32,6 +23,7 @@ typedef struct gf_dump_xl_options_ {
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_ {
@@ -39,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;
@@ -63,13 +56,21 @@ void _gf_proc_dump_build_key (char *key, const char *prefix, char *fmt,...)
#define GF_PROC_DUMP_SET_OPTION(opt,val) opt = val
+#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);
+void gf_proc_dump_info(int signum, glusterfs_ctx_t *ctx);
int gf_proc_dump_add_section(char *key,...);
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 7b6f78248..c1620bb70 100644
--- a/libglusterfs/src/syncop.c
+++ b/libglusterfs/src/syncop.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2013 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -24,57 +15,250 @@
#include "syncop.h"
-call_frame_t *
-syncop_create_frame ()
+int
+syncopctx_setfsuid (void *uid)
{
- struct synctask *task = NULL;
- 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->frame;
- }
+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,33 +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 *old_task)
{
- int ret;
struct synctask *task = NULL;
/* Do not trust the pointer received. It may be
wrong and can lead to crashes. */
task = synctask_get ();
- ret = task->syncfn (task->opaque);
- task->synccbk (ret, task->frame, task->opaque);
+ task->ret = task->syncfn (task->opaque);
+ if (task->synccbk)
+ task->synccbk (task->ret, task->frame, task->opaque);
- /* cannot destroy @task right here as we are
- in the execution stack of @task itself
- */
- task->complete = 1;
- synctask_wake (task);
+ task->state = SYNCTASK_DONE;
synctask_yield (task);
}
@@ -125,36 +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,
- call_frame_t *frame, 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);
- VALIDATE_OR_GOTO (cbk, err);
- VALIDATE_OR_GOTO (frame, 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->syncfn = fn;
newtask->synccbk = cbk;
newtask->opaque = opaque;
- newtask->frame = frame;
+
+ /* 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,
@@ -173,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;
@@ -218,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;
@@ -249,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)
{
@@ -256,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));
@@ -275,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);
@@ -286,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;
@@ -304,8 +955,8 @@ syncop_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret == 0) {
args->iatt1 = *iatt;
args->iatt2 = *parent;
- if (xattr)
- args->xattr = dict_ref (xattr);
+ if (xdata)
+ args->xdata = dict_ref (xdata);
}
__wake (args);
@@ -315,22 +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 (parent)
*parent = args.iatt2;
- if (xattr_rsp)
- *xattr_rsp = args.xattr;
- else if (args.xattr)
- dict_unref (args.xattr);
+ if (xdata_rsp)
+ *xdata_rsp = args.xdata;
+ else if (args.xdata)
+ dict_unref (args.xdata);
errno = args.op_errno;
return args.op_ret;
@@ -348,6 +999,8 @@ entry_copy (gf_dirent_t *source)
sink->d_type = source->d_type;
sink->d_stat = source->d_stat;
+ if (source->inode)
+ sink->inode = inode_ref (source->inode);
return sink;
}
@@ -357,7 +1010,7 @@ syncop_readdirp_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- gf_dirent_t *entries)
+ gf_dirent_t *entries, dict_t *xdata)
{
struct syncargs *args = NULL;
gf_dirent_t *entry = NULL;
@@ -412,12 +1065,71 @@ syncop_readdirp (xlator_t *subvol,
}
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;
+
+}
+
+int32_t
syncop_opendir_cbk (call_frame_t *frame,
void *cookie,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- fd_t *fd)
+ fd_t *fd, dict_t *xdata)
{
struct syncargs *args = NULL;
@@ -439,7 +1151,7 @@ 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;
@@ -447,8 +1159,36 @@ syncop_opendir (xlator_t *subvol,
}
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)
+ int op_ret, int op_errno, dict_t *xdata)
{
struct syncargs *args = NULL;
@@ -468,7 +1208,7 @@ 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);
+ loc, name, NULL);
errno = args.op_errno;
return args.op_ret;
@@ -476,7 +1216,7 @@ syncop_removexattr (xlator_t *subvol, loc_t *loc, const char *name)
int
syncop_fremovexattr_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;
@@ -496,7 +1236,7 @@ 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);
+ subvol->fops->fremovexattr, fd, name, NULL);
errno = args.op_errno;
return args.op_ret;
@@ -504,7 +1244,7 @@ syncop_fremovexattr (xlator_t *subvol, fd_t *fd, const char *name)
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;
@@ -525,7 +1265,7 @@ 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;
@@ -533,7 +1273,7 @@ syncop_setxattr (xlator_t *subvol, loc_t *loc, dict_t *dict, int32_t flags)
int
syncop_fsetxattr_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;
@@ -554,7 +1294,7 @@ 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);
+ fd, dict, flags, NULL);
errno = args.op_errno;
return args.op_ret;
@@ -562,7 +1302,7 @@ syncop_fsetxattr (xlator_t *subvol, fd_t *fd, dict_t *dict, int32_t flags)
int
syncop_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, dict_t *dict)
+ int op_ret, int op_errno, dict_t *dict, dict_t *xdata)
{
struct syncargs *args = NULL;
@@ -584,7 +1324,7 @@ 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);
+ loc, NULL, NULL);
if (dict)
*dict = args.xattr;
@@ -601,7 +1341,7 @@ 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);
+ loc, key, NULL);
if (dict)
*dict = args.xattr;
@@ -618,7 +1358,7 @@ 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);
+ fd, key, NULL);
if (dict)
*dict = args.xattr;
@@ -632,7 +1372,7 @@ syncop_fgetxattr (xlator_t *subvol, fd_t *fd, dict_t **dict, const char *key)
int
syncop_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct statvfs *buf)
+ struct statvfs *buf, dict_t *xdata)
{
struct syncargs *args = NULL;
@@ -659,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;
@@ -671,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;
@@ -698,7 +1438,7 @@ 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;
@@ -717,7 +1457,7 @@ syncop_fsetattr (xlator_t *subvol, fd_t *fd, struct iatt *iatt, int valid,
struct syncargs args = {0, };
SYNCOP (subvol, (&args), syncop_setattr_cbk, subvol->fops->fsetattr,
- fd, iatt, valid);
+ fd, iatt, valid, NULL);
if (preop)
*preop = args.iatt1;
@@ -731,7 +1471,7 @@ syncop_fsetattr (xlator_t *subvol, fd_t *fd, struct iatt *iatt, int valid,
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)
+ int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
{
struct syncargs *args = NULL;
@@ -740,9 +1480,6 @@ syncop_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
args->op_ret = op_ret;
args->op_errno = op_errno;
- if (op_ret != -1)
- fd_ref (fd);
-
__wake (args);
return 0;
@@ -754,7 +1491,7 @@ 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, 0);
+ loc, flags, fd, NULL);
errno = args.op_errno;
return args.op_ret;
@@ -765,7 +1502,8 @@ syncop_open (xlator_t *subvol, loc_t *loc, int32_t flags, fd_t *fd)
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)
+ int32_t count, struct iatt *stbuf, struct iobref *iobref,
+ dict_t *xdata)
{
struct syncargs *args = NULL;
@@ -797,11 +1535,14 @@ syncop_readv (xlator_t *subvol, fd_t *fd, size_t size, off_t off,
struct syncargs args = {0, };
SYNCOP (subvol, (&args), syncop_readv_cbk, subvol->fops->readv,
- fd, size, off, flags);
+ fd, size, off, flags, NULL);
+
+ if (args.op_ret < 0)
+ goto out;
if (vector)
*vector = args.vector;
- else if (args.vector)
+ else
GF_FREE (args.vector);
if (count)
@@ -813,6 +1554,7 @@ syncop_readv (xlator_t *subvol, fd_t *fd, size_t size, off_t off,
else if (args.iobref)
iobref_unref (args.iobref);
+out:
errno = args.op_errno;
return args.op_ret;
@@ -821,7 +1563,7 @@ syncop_readv (xlator_t *subvol, fd_t *fd, size_t size, off_t off,
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)
+ struct iatt *postbuf, dict_t *xdata)
{
struct syncargs *args = NULL;
@@ -836,14 +1578,15 @@ syncop_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
int
-syncop_writev (xlator_t *subvol, fd_t *fd, struct iovec *vector,
+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, vector, count, offset, flags, iobref);
+ fd, (struct iovec *) vector, count, offset, flags, iobref,
+ NULL);
errno = args.op_errno;
return args.op_ret;
@@ -859,7 +1602,7 @@ int syncop_write (xlator_t *subvol, fd_t *fd, const char *buf, int size,
vec.iov_base = (void *)buf;
SYNCOP (subvol, (&args), syncop_writev_cbk, subvol->fops->writev,
- fd, &vec, 1, offset, flags, iobref);
+ fd, &vec, 1, offset, flags, iobref, NULL);
errno = args.op_errno;
return args.op_ret;
@@ -878,7 +1621,7 @@ 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)
+ struct iatt *postparent, dict_t *xdata)
{
struct syncargs *args = NULL;
@@ -887,8 +1630,8 @@ syncop_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
args->op_ret = op_ret;
args->op_errno = op_errno;
- if (op_ret != -1)
- fd_ref (fd);
+ if (buf)
+ args->iatt1 = *buf;
__wake (args);
@@ -897,14 +1640,17 @@ syncop_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
syncop_create (xlator_t *subvol, loc_t *loc, int32_t flags, mode_t mode,
- fd_t *fd, dict_t *dict)
+ 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, fd, dict);
+ loc, flags, mode, 0, fd, xdata);
errno = args.op_errno;
+ if (iatt)
+ *iatt = args.iatt1;
+
return args.op_ret;
}
@@ -912,7 +1658,7 @@ syncop_create (xlator_t *subvol, loc_t *loc, int32_t flags, mode_t mode,
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)
+ struct iatt *postparent, dict_t *xdata)
{
struct syncargs *args = NULL;
@@ -931,16 +1677,114 @@ syncop_unlink (xlator_t *subvol, loc_t *loc)
{
struct syncargs args = {0, };
- SYNCOP (subvol, (&args), syncop_unlink_cbk, subvol->fops->unlink, loc);
+ 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)
+ struct iatt *postbuf, dict_t *xdata)
{
struct syncargs *args = NULL;
@@ -960,7 +1804,7 @@ 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);
+ fd, offset, NULL);
errno = args.op_errno;
return args.op_ret;
@@ -972,7 +1816,7 @@ 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);
+ loc, offset, NULL);
errno = args.op_errno;
return args.op_ret;
@@ -981,7 +1825,7 @@ syncop_truncate (xlator_t *subvol, loc_t *loc, off_t offset)
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)
+ struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata)
{
struct syncargs *args = NULL;
@@ -997,12 +1841,43 @@ syncop_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
int
-syncop_fsync (xlator_t *subvol, fd_t *fd)
+syncop_fsync (xlator_t *subvol, fd_t *fd, int dataonly)
{
struct syncargs args = {0, };
SYNCOP (subvol, (&args), syncop_fsync_cbk, subvol->fops->fsync,
- fd, 0);
+ 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;
@@ -1011,7 +1886,7 @@ syncop_fsync (xlator_t *subvol, fd_t *fd)
int
syncop_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *stbuf)
+ int32_t op_ret, int32_t op_errno, struct iatt *stbuf, dict_t *xdata)
{
struct syncargs *args = NULL;
@@ -1034,7 +1909,7 @@ 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);
+ fd, NULL);
if (stbuf)
*stbuf = args.iatt1;
@@ -1050,7 +1925,7 @@ 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);
+ loc, NULL);
if (stbuf)
*stbuf = args.iatt1;
@@ -1064,7 +1939,7 @@ 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)
+ struct iatt *postparent, dict_t *xdata)
{
struct syncargs *args = NULL;
@@ -1072,6 +1947,8 @@ syncop_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
args->op_ret = op_ret;
args->op_errno = op_errno;
+ if (buf)
+ args->iatt1 = *buf;
__wake (args);
@@ -1079,14 +1956,18 @@ syncop_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
int
-syncop_symlink (xlator_t *subvol, loc_t *loc, char *newpath, dict_t *dict)
+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, dict);
+ newpath, loc, 0, dict);
errno = args.op_errno;
+ if (iatt)
+ *iatt = args.iatt1;
+
return args.op_ret;
}
@@ -1094,7 +1975,7 @@ syncop_symlink (xlator_t *subvol, loc_t *loc, char *newpath, dict_t *dict)
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)
+ struct iatt *stbuf, dict_t *xdata)
{
struct syncargs *args = NULL;
@@ -1117,12 +1998,11 @@ 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);
+ loc, size, NULL);
if (buffer)
*buffer = args.buffer;
- else if (args.buffer)
- GF_FREE (args.buffer);
+ else GF_FREE (args.buffer);
errno = args.op_errno;
return args.op_ret;
@@ -1132,7 +2012,7 @@ 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)
+ struct iatt *postparent, dict_t *xdata)
{
struct syncargs *args = NULL;
@@ -1141,6 +2021,9 @@ syncop_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
args->op_ret = op_ret;
args->op_errno = op_errno;
+ if (buf)
+ args->iatt1 = *buf;
+
__wake (args);
return 0;
@@ -1148,14 +2031,207 @@ syncop_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
syncop_mknod (xlator_t *subvol, loc_t *loc, mode_t mode, dev_t rdev,
- dict_t *dict)
+ dict_t *dict, struct iatt *iatt)
{
struct syncargs args = {0, };
SYNCOP (subvol, (&args), syncop_mknod_cbk, subvol->fops->mknod,
- loc, mode, rdev, dict);
+ 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 627fb6197..f790981f0 100644
--- a/libglusterfs/src/syncop.h
+++ b/libglusterfs/src/syncop.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _SYNCOP_H
@@ -30,8 +21,19 @@
#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;
@@ -40,37 +42,91 @@ 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;
@@ -83,82 +139,197 @@ struct syncargs {
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); \
- } \
+#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 __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); \
- } \
+#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 __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 __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); \
\
- frame = syncop_create_frame (); \
+ if (task) { \
+ frame->root->uid = task->uid; \
+ frame->root->gid = task->gid; \
+ } \
\
__yawn (stb); \
- STACK_WIND_COOKIE (frame, cbk, (void *)stb, subvol, op, params); \
+ \
+ STACK_WIND_COOKIE (frame, cbk, (void *)stb, subvol, \
+ op, params); \
+ \
__yield (stb); \
+ if (task) \
+ STACK_RESET (frame->root); \
+ else \
+ STACK_DESTROY (frame->root); \
} while (0)
#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, call_frame_t* frame, void *);
-void synctask_zzzz (struct synctask *task);
-void synctask_yawn (struct synctask *task);
+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 */
@@ -169,6 +340,9 @@ int syncop_readdirp (xlator_t *subvol, fd_t *fd, size_t size, off_t off,
/* out */
gf_dirent_t *entries);
+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,
@@ -190,13 +364,13 @@ 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);
+ 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, struct iovec *vector,
+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,
@@ -208,14 +382,31 @@ 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 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, char *newpath, dict_t *dict);
+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);
+ 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 8e2d56b8d..e8954cc23 100644
--- a/libglusterfs/src/syscall.c
+++ b/libglusterfs/src/syscall.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -241,7 +232,12 @@ sys_statvfs (const char *path, struct statvfs *buf)
int
sys_close (int fd)
{
- return close (fd);
+ int ret = -1;
+
+ if (fd >= 0)
+ ret = close (fd);
+
+ return ret;
}
@@ -462,3 +458,26 @@ 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 f5325b4cd..f1c9f58c3 100644
--- a/libglusterfs/src/syscall.h
+++ b/libglusterfs/src/syscall.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef __SYSCALL_H__
@@ -148,4 +139,6 @@ 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 d8f53a8d1..a059cc212 100644
--- a/libglusterfs/src/timer.c
+++ b/libglusterfs/src/timer.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -26,19 +17,18 @@
#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)
{
@@ -57,10 +47,8 @@ gf_timer_call_after (glusterfs_ctx_t *ctx,
if (!event) {
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;
@@ -136,7 +124,7 @@ void *
gf_timer_proc (void *ctx)
{
gf_timer_registry_t *reg = NULL;
- const struct timespec sleepts = {.tv_sec = 1, .tv_nsec = 0, };
+ const struct timespec sleepts = {.tv_sec = 1, .tv_nsec = 0, };
if (ctx == NULL)
{
@@ -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);
@@ -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 3f1dc7adb..2f963adbf 100644
--- a/libglusterfs/src/timer.h
+++ b/libglusterfs/src/timer.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _TIMER_H
@@ -34,7 +25,7 @@ typedef void (*gf_timer_cbk_t) (void *);
struct _gf_timer {
struct _gf_timer *next, *prev;
- struct timeval at;
+ struct timespec at;
gf_timer_cbk_t callbk;
void *data;
xlator_t *xl;
@@ -53,7 +44,7 @@ typedef struct _gf_timer_registry gf_timer_registry_t;
gf_timer_t *
gf_timer_call_after (glusterfs_ctx_t *ctx,
- struct timeval delta,
+ struct timespec delta,
gf_timer_cbk_t cbk,
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
index 0572bfd3e..f96bbebf6 100644
--- a/libglusterfs/src/trie.c
+++ b/libglusterfs/src/trie.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#include <stdio.h>
@@ -123,8 +114,7 @@ trienode_free (trienode_t *node)
trienode_free (trav);
}
- if (node->data)
- GF_FREE (node->data);
+ GF_FREE (node->data);
GF_FREE (node);
}
@@ -382,8 +372,7 @@ trie_measure_vec (trie_t *trie, const char *word, struct trienodevec *nodevec)
static int
trienode_reset (trienode_t *node, void *data)
{
- if (node->data)
- GF_FREE (node->data);
+ GF_FREE (node->data);
return 0;
}
diff --git a/libglusterfs/src/trie.h b/libglusterfs/src/trie.h
index 2c2e05320..0356e6621 100644
--- a/libglusterfs/src/trie.h
+++ b/libglusterfs/src/trie.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2007-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _TRIE_H_
diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c
index 428357633..a277c58a8 100644
--- a/libglusterfs/src/xlator.c
+++ b/libglusterfs/src/xlator.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -88,6 +79,9 @@ fill_defaults (xlator_t *xl)
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);
@@ -128,18 +122,9 @@ xlator_volopt_dynload (char *xlator_type, void **dl_handle,
int ret = -1;
char *name = NULL;
void *handle = NULL;
- volume_opt_list_t *vol_opt = NULL;
GF_VALIDATE_OR_GOTO ("xlator", xlator_type, out);
- GF_ASSERT (dl_handle);
-
- if (*dl_handle)
- if (dlclose (*dl_handle))
- gf_log ("xlator", GF_LOG_WARNING, "Unable to close "
- "previously opened handle( may be stale)."
- "Ignoring the invalid handle");
-
ret = gf_asprintf (&name, "%s/%s.so", XLATORDIR, xlator_type);
if (-1 == ret) {
gf_log ("xlator", GF_LOG_ERROR, "asprintf failed");
@@ -155,28 +140,20 @@ xlator_volopt_dynload (char *xlator_type, void **dl_handle,
gf_log ("xlator", GF_LOG_WARNING, "%s", dlerror ());
goto out;
}
- *dl_handle = handle;
-
- vol_opt = GF_CALLOC (1, sizeof (volume_opt_list_t),
- gf_common_mt_volume_opt_list_t);
-
- if (!vol_opt) {
- goto out;
- }
-
- if (!(vol_opt->given_opt = dlsym (handle, "options"))) {
+ if (!(opt_list->given_opt = dlsym (handle, "options"))) {
dlerror ();
- gf_log ("xlator", GF_LOG_DEBUG,
- "Strict option validation not enforced -- neglecting");
+ gf_log ("xlator", GF_LOG_ERROR,
+ "Failed to load xlator opt table");
+ goto out;
}
- opt_list->given_opt = vol_opt->given_opt;
- INIT_LIST_HEAD (&vol_opt->list);
- list_add_tail (&vol_opt->list, &opt_list->list);
+ *dl_handle = handle;
ret = 0;
out:
+ GF_FREE (name);
+
gf_log ("xlator", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
@@ -190,7 +167,7 @@ xlator_dynload (xlator_t *xl)
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);
@@ -225,40 +202,55 @@ xlator_dynload (xlator_t *xl)
goto out;
}
- if (!(xl->init = dlsym (handle, "init"))) {
- gf_log ("xlator", GF_LOG_WARNING, "dlsym(init) on %s",
- dlerror ());
- goto out;
- }
+ /*
+ * 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_WARNING, "dlsym(fini) on %s",
- dlerror ());
- goto out;
- }
+ 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,
+ 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());
- }
-
vol_opt = GF_CALLOC (1, sizeof (volume_opt_list_t),
gf_common_mt_volume_opt_list_t);
@@ -268,9 +260,10 @@ xlator_dynload (xlator_t *xl)
if (!(vol_opt->given_opt = dlsym (handle, "options"))) {
dlerror ();
- gf_log (xl->name, GF_LOG_DEBUG,
+ 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);
@@ -278,8 +271,7 @@ xlator_dynload (xlator_t *xl)
ret = 0;
out:
- if (name)
- GF_FREE (name);
+ GF_FREE (name);
return ret;
}
@@ -329,6 +321,24 @@ out:
}
+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)
{
@@ -352,7 +362,6 @@ out:
return search;
}
-
static int
__xlator_init(xlator_t *xl)
{
@@ -430,6 +439,9 @@ xlator_fini_rec (xlator_t *xl)
xl->fini (xl);
+ if (xl->local_pool)
+ mem_pool_destroy (xl->local_pool);
+
THIS = old_THIS;
} else {
gf_log (xl->name, GF_LOG_DEBUG, "No fini() found");
@@ -465,12 +477,12 @@ 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));
@@ -504,10 +516,26 @@ out:
return;
}
+int
+xlator_list_destroy (xlator_list_t *list)
+{
+ xlator_list_t *next = NULL;
+
+ while (list) {
+ next = list->next;
+ GF_FREE (list);
+ list = next;
+ }
+
+ return 0;
+}
+
int
xlator_tree_free (xlator_t *tree)
{
+ volume_opt_list_t *vol_opt = NULL;
+ volume_opt_list_t *tmp = NULL;
xlator_t *trav = tree;
xlator_t *prev = tree;
@@ -518,9 +546,19 @@ xlator_tree_free (xlator_t *tree)
while (prev) {
trav = prev->next;
- dict_destroy (prev->options);
+ 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;
}
@@ -549,6 +587,67 @@ loc_wipe (loc_t *loc)
memset (loc, 0, sizeof (*loc));
}
+int
+loc_path (loc_t *loc, const char *bname)
+{
+ int ret = 0;
+
+ if (loc->path)
+ goto out;
+
+ ret = -1;
+
+ if (bname && !strlen (bname))
+ bname = NULL;
+
+ if (!bname)
+ goto inode_path;
+
+ 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);
+ }
+
+ if (loc->path)
+ goto out;
+
+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;
+}
+
+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
loc_copy (loc_t *dst, loc_t *src)
@@ -560,6 +659,7 @@ loc_copy (loc_t *dst, loc_t *src)
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);
@@ -567,45 +667,38 @@ loc_copy (loc_t *dst, loc_t *src)
if (src->parent)
dst->parent = inode_ref (src->parent);
- dst->path = gf_strdup (src->path);
+ if (src->path) {
+ dst->path = gf_strdup (src->path);
- if (!dst->path)
- goto out;
+ if (!dst->path)
+ goto out;
- dst->name = strrchr (dst->path, '/');
- if (dst->name)
- dst->name++;
+ if (src->name)
+ dst->name = strrchr (dst->path, '/');
+ if (dst->name)
+ dst->name++;
+ }
ret = 0;
out:
- if (ret == -1) {
- if (dst->inode)
- inode_unref (dst->inode);
-
- if (dst->parent)
- inode_unref (dst->parent);
- }
+ if (ret == -1)
+ loc_wipe (dst);
err:
return ret;
}
-
-int
-xlator_list_destroy (xlator_list_t *list)
+gf_boolean_t
+loc_is_root (loc_t *loc)
{
- xlator_list_t *next = NULL;
-
- while (list) {
- next = list->next;
- GF_FREE (list);
- list = next;
+ 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 0;
+ return _gf_false;
}
-
int
xlator_destroy (xlator_t *xl)
{
@@ -615,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)
@@ -693,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)
diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h
index c8eff3353..b57e5873e 100644
--- a/libglusterfs/src/xlator.h
+++ b/libglusterfs/src/xlator.h
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#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"
@@ -75,6 +66,7 @@ typedef int32_t (*event_notify_fn_t) (xlator_t *this, int32_t event, void *data,
#include "globals.h"
#include "iatt.h"
#include "options.h"
+#include "client_t.h"
struct _loc {
@@ -106,7 +98,8 @@ 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,
@@ -117,7 +110,7 @@ typedef int32_t (*fop_getspec_t) (call_frame_t *frame,
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,
@@ -127,7 +120,7 @@ typedef int32_t (*fop_lookup_cbk_t) (call_frame_t *frame,
int32_t op_errno,
inode_t *inode,
struct iatt *buf,
- dict_t *xattr,
+ dict_t *xdata,
struct iatt *postparent);
typedef int32_t (*fop_stat_cbk_t) (call_frame_t *frame,
@@ -135,14 +128,14 @@ typedef int32_t (*fop_stat_cbk_t) (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct iatt *buf);
+ 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);
+ struct iatt *buf, dict_t *xdata);
typedef int32_t (*fop_truncate_cbk_t) (call_frame_t *frame,
void *cookie,
@@ -150,7 +143,7 @@ typedef int32_t (*fop_truncate_cbk_t) (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *prebuf,
- struct iatt *postbuf);
+ struct iatt *postbuf, dict_t *xdata);
typedef int32_t (*fop_ftruncate_cbk_t) (call_frame_t *frame,
void *cookie,
@@ -158,13 +151,13 @@ typedef int32_t (*fop_ftruncate_cbk_t) (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *prebuf,
- struct iatt *postbuf);
+ 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);
+ int32_t op_errno, dict_t *xdata);
typedef int32_t (*fop_readlink_cbk_t) (call_frame_t *frame,
void *cookie,
@@ -172,7 +165,7 @@ typedef int32_t (*fop_readlink_cbk_t) (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
const char *path,
- struct iatt *buf);
+ struct iatt *buf, dict_t *xdata);
typedef int32_t (*fop_mknod_cbk_t) (call_frame_t *frame,
void *cookie,
@@ -182,7 +175,7 @@ typedef int32_t (*fop_mknod_cbk_t) (call_frame_t *frame,
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,
@@ -192,7 +185,7 @@ typedef int32_t (*fop_mkdir_cbk_t) (call_frame_t *frame,
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,
@@ -200,7 +193,7 @@ typedef int32_t (*fop_unlink_cbk_t) (call_frame_t *frame,
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,
@@ -208,7 +201,7 @@ typedef int32_t (*fop_rmdir_cbk_t) (call_frame_t *frame,
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,
@@ -218,7 +211,7 @@ typedef int32_t (*fop_symlink_cbk_t) (call_frame_t *frame,
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,
@@ -229,7 +222,7 @@ typedef int32_t (*fop_rename_cbk_t) (call_frame_t *frame,
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,
@@ -239,7 +232,7 @@ typedef int32_t (*fop_link_cbk_t) (call_frame_t *frame,
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,
@@ -250,14 +243,14 @@ typedef int32_t (*fop_create_cbk_t) (call_frame_t *frame,
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);
+ fd_t *fd, dict_t *xdata);
typedef int32_t (*fop_readv_cbk_t) (call_frame_t *frame,
void *cookie,
@@ -267,7 +260,7 @@ typedef int32_t (*fop_readv_cbk_t) (call_frame_t *frame,
struct iovec *vector,
int32_t count,
struct iatt *stbuf,
- struct iobref *iobref);
+ struct iobref *iobref, dict_t *xdata);
typedef int32_t (*fop_writev_cbk_t) (call_frame_t *frame,
void *cookie,
@@ -275,13 +268,13 @@ typedef int32_t (*fop_writev_cbk_t) (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *prebuf,
- struct iatt *postbuf);
+ 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);
+ int32_t op_errno, dict_t *xdata);
typedef int32_t (*fop_fsync_cbk_t) (call_frame_t *frame,
void *cookie,
@@ -289,124 +282,124 @@ typedef int32_t (*fop_fsync_cbk_t) (call_frame_t *frame,
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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ dict_t *xattr, dict_t *xdata);
typedef int32_t (*fop_setattr_cbk_t) (call_frame_t *frame,
@@ -415,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,
@@ -423,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);
+ dict_t *xdata);
typedef int32_t (*fop_stat_t) (call_frame_t *frame,
xlator_t *this,
- loc_t *loc);
+ loc_t *loc, dict_t *xdata);
typedef int32_t (*fop_fstat_t) (call_frame_t *frame,
xlator_t *this,
- fd_t *fd);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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.
@@ -499,19 +515,16 @@ 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,
- uint32_t flags);
+ uint32_t flags, dict_t *xdata);
typedef int32_t (*fop_writev_t) (call_frame_t *frame,
xlator_t *this,
@@ -520,132 +533,152 @@ typedef int32_t (*fop_writev_t) (call_frame_t *frame,
int32_t count,
off_t offset,
uint32_t flags,
- struct iobref *iobref);
+ struct iobref *iobref, dict_t *xdata);
typedef int32_t (*fop_flush_t) (call_frame_t *frame,
xlator_t *this,
- fd_t *fd);
+ 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);
+ 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);
+ 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);
+ int32_t datasync, dict_t *xdata);
typedef int32_t (*fop_statfs_t) (call_frame_t *frame,
xlator_t *this,
- loc_t *loc);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ struct gf_flock *flock, dict_t *xdata);
typedef int32_t (*fop_inodelk_t) (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);
typedef int32_t (*fop_finodelk_t) (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);
typedef int32_t (*fop_entrylk_t) (call_frame_t *frame,
xlator_t *this,
const char *volume, loc_t *loc,
const char *basename, entrylk_cmd cmd,
- entrylk_type type);
+ entrylk_type type, dict_t *xdata);
typedef int32_t (*fop_fentrylk_t) (call_frame_t *frame,
xlator_t *this,
const char *volume, fd_t *fd,
const char *basename, entrylk_cmd cmd,
- entrylk_type type);
+ 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);
+ 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,
- dict_t *dict);
+ 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);
+ 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);
+ 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;
@@ -690,6 +723,9 @@ struct xlator_fops {
fop_setattr_t setattr;
fop_fsetattr_t fsetattr;
fop_getspec_t getspec;
+ 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;
@@ -734,6 +770,9 @@ struct xlator_fops {
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,
@@ -742,10 +781,17 @@ typedef int32_t (*cbk_forget_t) (xlator_t *this,
typedef int32_t (*cbk_release_t) (xlator_t *this,
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);
@@ -770,6 +816,8 @@ typedef int32_t (*dumpop_inodectx_to_dict_t) (xlator_t *this, inode_t *ino,
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;
@@ -781,6 +829,7 @@ struct xlator_dumpops {
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 {
@@ -818,16 +867,43 @@ struct _xlator {
fop_latency_t latencies[GF_FOP_MAXVALUE];
/* 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)
+#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);
int32_t xlator_set_type (xlator_t *xl, const char *type);
@@ -851,6 +927,11 @@ void xlator_foreach (xlator_t *this,
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);
void inode_destroy_notify (inode_t *inode, const char *xlname);
@@ -858,9 +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 is_gf_log_command (xlator_t *trans, const char *name, char *value);
int glusterd_check_log_level (const char *value);
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 */