diff options
Diffstat (limited to 'libglusterfs/src')
56 files changed, 6764 insertions, 3581 deletions
diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am index d0a617e7b..907399ae6 100644 --- a/libglusterfs/src/Makefile.am +++ b/libglusterfs/src/Makefile.am @@ -4,7 +4,7 @@ libglusterfs_la_CFLAGS = -Wall $(GF_CFLAGS) \ libglusterfs_la_CPPFLAGS = $(GF_CPPFLAGS) -D__USE_FILE_OFFSET64 \ -DXLATORDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator\" \ - -I$(CONTRIBDIR)/rbtree + -I$(top_srcdir)/rpc/rpc-lib/src/ -I$(CONTRIBDIR)/rbtree libglusterfs_la_LIBADD = @LEXLIB@ @@ -15,42 +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)/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 fd-lk.c circ-buff.c \ - event-history.c gidcache.c ctx.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 \ - event-poll.c event-epoll.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)/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 fd-lk.h circ-buff.h event-history.h gidcache.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/call-stub.c b/libglusterfs/src/call-stub.c index 0ca5bf7f1..ac79cf071 100644 --- a/libglusterfs/src/call-stub.c +++ b/libglusterfs/src/call-stub.c @@ -37,15 +37,15 @@ 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, +fop_lookup_stub (call_frame_t *frame, fop_lookup_t fn, loc_t *loc, dict_t *xdata) { call_stub_t *stub = NULL; @@ -56,11 +56,11 @@ 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; - loc_copy (&stub->args.lookup.loc, loc); + loc_copy (&stub->args.loc, loc); if (xdata) - stub->xdata = dict_ref (xdata); + stub->args.xdata = dict_ref (xdata); out: return stub; @@ -68,14 +68,10 @@ out: 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 *xdata, - 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; @@ -84,27 +80,24 @@ 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; + stub->args_cbk.stat = *buf; if (postparent) - stub->args.lookup_cbk.postparent = *postparent; + stub->args_cbk.postparent = *postparent; if (xdata) - stub->xdata = dict_ref (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, +fop_stat_stub (call_frame_t *frame, fop_stat_t fn, loc_t *loc, dict_t *xdata) { call_stub_t *stub = NULL; @@ -115,21 +108,18 @@ 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->xdata = dict_ref (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, +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; @@ -139,22 +129,20 @@ 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->xdata = dict_ref (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, +fop_fstat_stub (call_frame_t *frame, fop_fstat_t fn, fd_t *fd, dict_t *xdata) { call_stub_t *stub = NULL; @@ -164,23 +152,20 @@ 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->xdata = dict_ref (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, +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; @@ -190,26 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -219,24 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -245,26 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -273,26 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -301,15 +270,15 @@ 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->xdata = dict_ref (xdata); + stub->args_cbk.xdata = dict_ref (xdata); out: return stub; @@ -317,10 +286,8 @@ out: call_stub_t * -fop_access_stub (call_frame_t *frame, - fop_access_t fn, - loc_t *loc, - int32_t mask, dict_t *xdata) +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; @@ -330,22 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -354,22 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -379,24 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -405,16 +362,15 @@ 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->xdata = dict_ref (xdata); - + stub->args_cbk.xdata = dict_ref (xdata); out: return stub; } @@ -432,28 +388,23 @@ fop_mknod_stub (call_frame_t *frame, fop_mknod_t fn, loc_t *loc, mode_t mode, 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; - stub->args.mknod.umask = umask; + 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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -462,19 +413,19 @@ 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->xdata = dict_ref (xdata); + stub->args_cbk.xdata = dict_ref (xdata); out: return stub; @@ -493,27 +444,22 @@ 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; - stub->args.mkdir.umask = umask; + stub->fn.mkdir = fn; + loc_copy (&stub->args.loc, loc); + stub->args.mode = mode; + stub->args.umask = umask; if (xdata) - stub->xdata = dict_ref (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, +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; @@ -523,28 +469,26 @@ 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->xdata = dict_ref (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, +fop_unlink_stub (call_frame_t *frame, fop_unlink_t fn, loc_t *loc, int xflag, dict_t *xdata) { call_stub_t *stub = NULL; @@ -555,24 +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->args.unlink.xflag = xflag; + stub->fn.unlink = fn; + loc_copy (&stub->args.loc, loc); + stub->args.xflag = xflag; if (xdata) - stub->xdata = dict_ref (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, dict_t *xdata) +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; @@ -581,16 +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->xdata = dict_ref (xdata); - + stub->args_cbk.xdata = dict_ref (xdata); out: return stub; } @@ -609,24 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -635,16 +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->xdata = dict_ref (xdata); - + stub->args_cbk.xdata = dict_ref (xdata); out: return stub; } @@ -663,27 +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); - stub->args.symlink.umask = umask; - loc_copy (&stub->args.symlink.loc, loc); + stub->fn.symlink = fn; + stub->args.linkname = gf_strdup (linkname); + stub->args.umask = umask; + loc_copy (&stub->args.loc, loc); if (xdata) - stub->xdata = dict_ref (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, dict_t *xdata) +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; @@ -692,30 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -726,27 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -755,32 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -791,27 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -820,20 +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->xdata = dict_ref (xdata); - + stub->args_cbk.xdata = dict_ref (xdata); out: return stub; } @@ -852,31 +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->args.create.umask = umask; + 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); + stub->args.fd = fd_ref (fd); if (xdata) - stub->xdata = dict_ref (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, dict_t *xdata) +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; @@ -885,33 +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->xdata = dict_ref (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, - dict_t *xdata) +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; @@ -921,24 +828,21 @@ 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->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->xdata = dict_ref (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, +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; @@ -948,25 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -975,29 +876,24 @@ 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->xdata = dict_ref (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, +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; @@ -1007,31 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -1041,29 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -1072,25 +959,22 @@ 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->xdata = dict_ref (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, +fop_flush_stub (call_frame_t *frame, fop_flush_t fn, fd_t *fd, dict_t *xdata) { call_stub_t *stub = NULL; @@ -1100,22 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -1124,24 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -1150,25 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -1177,24 +1049,22 @@ 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->xdata = dict_ref (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, +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; @@ -1205,23 +1075,20 @@ 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->xdata = dict_ref (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, +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; @@ -1231,25 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -1258,23 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -1283,20 +1144,18 @@ 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->xdata = dict_ref (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, +fop_statfs_stub (call_frame_t *frame, fop_statfs_t fn, loc_t *loc, dict_t *xdata) { call_stub_t *stub = NULL; @@ -1307,21 +1166,18 @@ 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->xdata = dict_ref (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, +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; @@ -1331,24 +1187,21 @@ 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->xdata = dict_ref (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, +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; @@ -1359,15 +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->xdata = dict_ref (xdata); - + stub->args.xdata = dict_ref (xdata); out: return stub; } @@ -1386,21 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -1410,24 +1260,21 @@ 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->xdata = dict_ref (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, +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; @@ -1437,26 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -1466,26 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -1494,22 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -1519,24 +1355,21 @@ 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->xdata = dict_ref (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, +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; @@ -1546,26 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -1576,22 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -1600,21 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -1625,22 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -1649,21 +1470,19 @@ 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->xdata = dict_ref (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, +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; @@ -1674,24 +1493,21 @@ 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->xdata = dict_ref (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, +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; @@ -1701,18 +1517,18 @@ 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->xdata = dict_ref (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, @@ -1726,21 +1542,21 @@ 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->xdata = dict_ref (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, dict_t *xdata) @@ -1752,13 +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->xdata = dict_ref (xdata); - + stub->args_cbk.xdata = dict_ref (xdata); out: return stub; } @@ -1777,20 +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->xdata = dict_ref (xdata); - + stub->args.xdata = dict_ref (xdata); out: return stub; } @@ -1807,13 +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->xdata = dict_ref (xdata); - + stub->args_cbk.xdata = dict_ref (xdata); out: return stub; } @@ -1831,25 +1644,26 @@ 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->xdata = dict_ref (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, dict_t *xdata) @@ -1861,13 +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->xdata = dict_ref (xdata); - + stub->args_cbk.xdata = dict_ref (xdata); out: return stub; } @@ -1885,25 +1698,25 @@ 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->xdata = dict_ref (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, dict_t *xdata) @@ -1915,23 +1728,20 @@ 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->xdata = dict_ref (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, +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; @@ -1942,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) { @@ -1960,23 +1766,22 @@ 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->xdata = dict_ref (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, +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; @@ -1987,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) { @@ -2006,21 +1807,19 @@ 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->xdata = dict_ref (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, +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; @@ -2028,47 +1827,41 @@ fop_readdir_stub (call_frame_t *frame, 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->xdata = dict_ref (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 *xdata) +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->fn.readdirp = fn; + stub->args.fd = fd_ref (fd); + stub->args.size = size; + stub->args.offset = off; if (xdata) - stub->xdata = dict_ref (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, dict_t *xdata) +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; @@ -2078,25 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -2105,31 +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 = + stub->args_cbk.strong_checksum = memdup (strong_checksum, MD5_DIGEST_LENGTH); } - if (xdata) - stub->xdata = dict_ref (xdata); + 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, dict_t *xdata) +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; @@ -2138,23 +1924,20 @@ 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->xdata = dict_ref (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, +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; @@ -2163,25 +1946,22 @@ 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->xdata = dict_ref (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, +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; @@ -2192,25 +1972,23 @@ 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->xdata = dict_ref (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, +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; @@ -2221,28 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -2251,30 +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->xdata = dict_ref (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, dict_t *xdata) +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; @@ -2283,27 +2056,25 @@ 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->xdata = dict_ref (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, +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; @@ -2314,27 +2085,25 @@ 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->xdata = dict_ref (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, +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; @@ -2345,1766 +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->xdata = dict_ref (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->xdata); - 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.umask, - stub->args.create.fd, - stub->xdata); - break; - } - case GF_FOP_STAT: - { - stub->args.stat.fn (stub->frame, - stub->frame->this, - &stub->args.stat.loc, stub->xdata); - break; - } - case GF_FOP_READLINK: - { - stub->args.readlink.fn (stub->frame, - stub->frame->this, - &stub->args.readlink.loc, - stub->args.readlink.size, stub->xdata); - 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.umask, stub->xdata); - } - 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.umask, stub->xdata); - } - 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, - stub->args.unlink.xflag, stub->xdata); - } - 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, stub->xdata); - } - 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.umask, stub->xdata); - } - 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, stub->xdata); - } - 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, stub->xdata); - } - 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, stub->xdata); - 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, stub->xdata); - 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, stub->xdata); - break; - } +} - case GF_FOP_STATFS: - { - stub->args.statfs.fn (stub->frame, - stub->frame->this, - &stub->args.statfs.loc, stub->xdata); - break; - } - case GF_FOP_FLUSH: - { - stub->args.flush.fn (stub->frame, - stub->frame->this, - stub->args.flush.fd, stub->xdata); - 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, stub->xdata); - 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, stub->xdata); - 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, stub->xdata); - 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, stub->xdata); - 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, stub->xdata); - 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, stub->xdata); - 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, stub->xdata); - 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, stub->xdata); - 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, stub->xdata); - 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, stub->xdata); - 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, stub->xdata); - 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, stub->xdata); - 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, stub->xdata); - 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, stub->xdata); - 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, stub->xdata); - 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, stub->xdata); - 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, stub->xdata); - 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->xdata); - 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, stub->xdata); - 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, stub->xdata); - 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->xdata); - 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->xdata); + 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, stub->xdata); + 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, stub->xdata); - 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, stub->xdata); - 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, stub->xdata); - 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->xdata); + 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, stub->xdata); - 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->xdata); - + 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, stub->xdata); - 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->xdata); - + 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, stub->xdata); - 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->xdata); - + 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, stub->xdata); - 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, stub->xdata); - 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, stub->xdata); - 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, stub->xdata); - - 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, stub->xdata); - 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, stub->xdata); - 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, stub->xdata); - 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, stub->xdata); - 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, stub->xdata); - 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, stub->xdata); - } - 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, stub->xdata); - 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, stub->xdata); - 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, stub->xdata); - 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, stub->xdata); - 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, stub->xdata); - 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->xdata); + 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, stub->xdata); - 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, stub->xdata); - } - 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, stub->xdata); - 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->xdata); + 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), stub->xdata); - 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), stub->xdata); - } - 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, stub->xdata); - 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->xdata); - + 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, stub->xdata); - 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->xdata); + 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, stub->xdata); - - 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->xdata); - + 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, stub->xdata); - 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->xdata); + 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, stub->xdata); - - 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->xdata); - + 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, stub->xdata); - 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->xdata); + 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, stub->xdata); - 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->xdata); - + 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, stub->xdata); - 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->xdata); - + 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, stub->xdata); - 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->xdata); + 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, stub->xdata); - 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->xdata); + 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, stub->xdata); - 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->xdata); - + 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, stub->xdata); - 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->xdata); + 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, stub->xdata); - 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->xdata); - + 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, stub->xdata); - 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->xdata); + 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, stub->xdata); - - 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->xdata); + 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, stub->xdata); - - 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->xdata); + 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, stub->xdata); - - 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->xdata); + 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, stub->xdata); - - 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, stub->xdata); - 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->xdata, - &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->xdata, - &stub->args.lookup_cbk.postparent); - /* FIXME NULL should not be passed */ - - 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, stub->xdata); - 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, stub->xdata); - - 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, stub->xdata); - 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, stub->xdata); - - 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, stub->xdata); - 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, stub->xdata); - - 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, stub->xdata); - 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, stub->xdata); - - 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, stub->xdata); - 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, stub->xdata); - - 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, stub->xdata); - 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->xdata); + 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, stub->xdata); - 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->xdata); + 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) { - if (stub->xdata) - dict_unref (stub->xdata); + 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); + 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); - } - 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); - } - 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); - } - 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: - { - 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: - { - 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: - { - 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: - { - 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: - { - GF_FREE ((char *)stub->args.entrylk.volume); - - 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: - { - GF_FREE ((char *)stub->args.fentrylk.volume); - - 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); + 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) { - if (stub->xdata) - dict_unref (stub->xdata); + loc_wipe (&stub->args.loc); - 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: - { - 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; + loc_wipe (&stub->args.loc2); - case GF_FOP_SYMLINK: - { - if (stub->args.symlink_cbk.inode) - inode_unref (stub->args.symlink_cbk.inode); - } - break; + if (stub->args.fd) + fd_unref (stub->args.fd); - case GF_FOP_RENAME: - break; + GF_FREE ((char *)stub->args.linkname); - case GF_FOP_LINK: - { - if (stub->args.link_cbk.inode) - inode_unref (stub->args.link_cbk.inode); - } - break; + GF_FREE (stub->args.vector); - case GF_FOP_TRUNCATE: - break; + if (stub->args.iobref) + iobref_unref (stub->args.iobref); - 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 (stub->args.xattr) + dict_unref (stub->args.xattr); - if (iobref) { - iobref_unref (iobref); - } - } - } - break; + GF_FREE ((char *)stub->args.name); - case GF_FOP_WRITE: - break; + GF_FREE ((char *)stub->args.volume); - 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; - - case GF_FOP_FSETXATTR: - break; - - case GF_FOP_FGETXATTR: - { - if (stub->args.fgetxattr_cbk.dict) - dict_unref (stub->args.fgetxattr_cbk.dict); - } - break; - - case GF_FOP_REMOVEXATTR: - break; - case GF_FOP_FREMOVEXATTR: - break; - - case GF_FOP_OPENDIR: - { - if (stub->args.opendir_cbk.fd) - fd_unref (stub->args.opendir_cbk.fd); - } - break; - - case GF_FOP_FSYNCDIR: - break; - - case GF_FOP_ACCESS: - break; - - case GF_FOP_FTRUNCATE: - break; - - case GF_FOP_FSTAT: - break; - - case GF_FOP_LK: - break; - - case GF_FOP_INODELK: - break; - - case GF_FOP_FINODELK: - break; + if (stub->args.xdata) + dict_unref (stub->args.xdata); +} - case GF_FOP_ENTRYLK: - break; - case GF_FOP_FENTRYLK: - break; - - case GF_FOP_LOOKUP: - { - if (stub->args.lookup_cbk.inode) - inode_unref (stub->args.lookup_cbk.inode); - } - 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_RCHECKSUM: - { - if (stub->args.rchecksum_cbk.op_ret >= 0) { - GF_FREE (stub->args.rchecksum_cbk.strong_checksum); - } - } - break; + GF_FREE ((char *)stub->args_cbk.buf); - 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.vector); - 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.iobref) + iobref_unref (stub->args_cbk.iobref); - case GF_FOP_XATTROP: - { - if (stub->args.xattrop_cbk.xattr) - dict_unref (stub->args.xattrop_cbk.xattr); - } - break; + if (stub->args_cbk.fd) + fd_unref (stub->args_cbk.fd); - case GF_FOP_FXATTROP: - { - if (stub->args.fxattrop_cbk.xattr) - dict_unref (stub->args.fxattrop_cbk.xattr); - } - break; + if (stub->args_cbk.xattr) + dict_unref (stub->args_cbk.xattr); - case GF_FOP_SETATTR: - { - break; - } + GF_FREE (stub->args_cbk.strong_checksum); - case GF_FOP_FSETATTR: - { - break; - } + if (stub->args_cbk.xdata) + dict_unref (stub->args_cbk.xdata); - 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); } @@ -4113,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) { @@ -4149,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 633fc4cbb..45bef8044 100644 --- a/libglusterfs/src/call-stub.h +++ b/libglusterfs/src/call-stub.h @@ -26,568 +26,158 @@ typedef struct { call_frame_t *frame; glusterfs_fop_t fop; struct mem_pool *stub_mem_pool; /* pointer to stub mempool in ctx_t */ - dict_t *xdata; /* common accross all the fops */ union { - /* lookup */ - struct { - fop_lookup_t fn; - loc_t loc; - } lookup; - struct { - fop_lookup_cbk_t fn; - int32_t op_ret, op_errno; - inode_t *inode; - struct iatt buf; - 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; - mode_t umask; - } 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; - mode_t umask; - } 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; - int xflag; - } 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; - mode_t umask; - } 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; - mode_t umask; - } 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; - } 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; - } 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, @@ -1129,6 +719,49 @@ fop_fsetattr_cbk_stub (call_frame_t *frame, struct iatt *statpre, 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/circ-buff.c b/libglusterfs/src/circ-buff.c index 65bbd5d45..484ce7dc9 100644 --- a/libglusterfs/src/circ-buff.c +++ b/libglusterfs/src/circ-buff.c @@ -10,6 +10,17 @@ #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) @@ -29,7 +40,8 @@ __cb_add_entry_buffer (buffer_t *buffer, void *item) if (buffer->cb[buffer->w_index]) { ptr = buffer->cb[buffer->w_index]; if (ptr->data) { - GF_FREE (ptr->data); + cb_destroy_data (ptr, + buffer->destroy_buffer_data); ptr->data = NULL; GF_FREE (ptr); } @@ -50,7 +62,7 @@ __cb_add_entry_buffer (buffer_t *buffer, void *item) gf_log_callingfn ("", GF_LOG_WARNING, "getting time of" "the day failed"); buffer->w_index++; - buffer->w_index %= buffer->size_buffer - 1; + buffer->w_index %= buffer->size_buffer; //used_buffer size cannot be greater than the total buffer size if (buffer->used_len < buffer->size_buffer) @@ -90,22 +102,35 @@ void cb_buffer_dump (buffer_t *buffer, void *data, int (fn) (circular_buffer_t *buffer, void *data)) { - int i = 0; + 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) { - for (i = (buffer->w_index - 1) ; entries < - buffer->used_len ; entries++) { - entry = buffer->cb[i]; + 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); - if (0 == i) - i = buffer->used_len - 1; else - i = (i - 1) % (buffer->used_len - 1); + 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++) { @@ -118,7 +143,8 @@ cb_buffer_dump (buffer_t *buffer, void *data, } buffer_t * -cb_buffer_new (size_t buffer_size, gf_boolean_t use_once) +cb_buffer_new (size_t buffer_size, gf_boolean_t use_once, + void (*destroy_buffer_data) (void *data)) { buffer_t *buffer = NULL; @@ -144,6 +170,7 @@ cb_buffer_new (size_t buffer_size, gf_boolean_t use_once) 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: @@ -153,12 +180,18 @@ out: void cb_buffer_destroy (buffer_t *buffer) { - int i = 0; - + int i = 0; + circular_buffer_t *ptr = NULL; if (buffer) { if (buffer->cb) { for (i = 0; i < buffer->used_len ; i++) { - GF_FREE (buffer->cb[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); } diff --git a/libglusterfs/src/circ-buff.h b/libglusterfs/src/circ-buff.h index 5b5acc387..e3459f5e3 100644 --- a/libglusterfs/src/circ-buff.h +++ b/libglusterfs/src/circ-buff.h @@ -38,7 +38,7 @@ struct _buffer { /* indicates the amount of circular buffer used. */ circular_buffer_t **cb; - + void (*destroy_buffer_data) (void *data); pthread_mutex_t lock; }; @@ -51,7 +51,8 @@ void cb_buffer_show (buffer_t *buffer); buffer_t * -cb_buffer_new (size_t buffer_size,gf_boolean_t use_buffer_once); +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); 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 22f138614..827475282 100644 --- a/libglusterfs/src/common-utils.c +++ b/libglusterfs/src/common-utils.c @@ -44,6 +44,8 @@ #include "stack.h" #include "globals.h" #include "lkowner.h" +#include "syscall.h" +#include <ifaddrs.h> #ifndef AI_ADDRCONFIG #define AI_ADDRCONFIG 0 @@ -57,6 +59,16 @@ 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. */ @@ -113,6 +125,35 @@ out: } int +gf_lstat_dir (const char *path, struct stat *stbuf_in) +{ + int ret = -1; + struct stat stbuf = {0,}; + + if (path == NULL) { + errno = EINVAL; + goto out; + } + + ret = sys_lstat (path, &stbuf); + if (ret) + goto out; + + if (!S_ISDIR (stbuf.st_mode)) { + errno = ENOTDIR; + ret = -1; + goto out; + } + ret = 0; + +out: + if (!ret && stbuf_in) + *stbuf_in = stbuf; + + return ret; +} + +int log_base2 (unsigned long x) { int val = 0; @@ -238,30 +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) { - int lcount = 0; - char data[GF_UNIT_KB]; glusterfs_ctx_t *ctx; + struct xldump xld = {0, }; - ctx = THIS->ctx; - fseek (specfp, 0L, SEEK_SET); + ctx = THIS->ctx; + xld.logfp = ctx->log.gf_log_logfile; - fprintf (ctx->log.gf_log_logfile, "Given volfile:\n"); + 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 (ctx->log.gf_log_logfile, "%3d: %s", lcount, data); - } + + xlator_foreach_depth_first (graph->top, xldump, &xld); + fprintf (ctx->log.gf_log_logfile, - "\n+---------------------------------------" + "+---------------------------------------" "---------------------------------------+\n"); fflush (ctx->log.gf_log_logfile); - fseek (specfp, 0L, SEEK_SET); } static void @@ -1013,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; } @@ -1032,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; } @@ -1051,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; } @@ -1070,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; } @@ -1329,6 +1441,11 @@ gf_string2bytesize (const char *str, uint64_t *n) return -1; } + if ((UINT64_MAX - value) < 0) { + errno = ERANGE; + return -1; + } + *n = (uint64_t) value; return 0; @@ -1339,7 +1456,7 @@ gf_string2percent_or_bytesize (const char *str, uint64_t *n, gf_boolean_t *is_percent) { - uint64_t value = 0ULL; + double value = 0ULL; char *tail = NULL; int old_errno = 0; const char *s = NULL; @@ -1361,7 +1478,7 @@ gf_string2percent_or_bytesize (const char *str, old_errno = errno; errno = 0; - value = strtoull (str, &tail, 10); + value = strtod (str, &tail); if (str == tail) errno = EINVAL; @@ -1388,7 +1505,13 @@ gf_string2percent_or_bytesize (const char *str, return -1; } - *n = value; + /* 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; } @@ -1678,6 +1801,19 @@ valid_host_name (char *address, int length) goto out; } + if (!isalnum (dup_addr[length - 1]) && (dup_addr[length - 1] != '*')) { + ret = 0; + goto out; + } + + /* Check for consecutive dots, which is invalid in a hostname and is + * ignored by strtok() + */ + if (strstr (dup_addr, "..")) { + ret = 0; + goto out; + } + /* gen-name */ temp_str = strtok_r (dup_addr, ".", &save_ptr); do { @@ -1714,8 +1850,13 @@ valid_ipv4_address (char *address, int length, gf_boolean_t wildcard_acc) tmp = gf_strdup (address); - /* To prevent cases where last character is '.' */ + /* + * 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; @@ -1828,6 +1969,50 @@ out: return ret; } +/** + * gf_sock_union_equal_addr - check if two given gf_sock_unions have same addr + * + * @param a - first sock union + * @param b - second sock union + * @return _gf_true if a and b have same ipv{4,6} addr, _gf_false otherwise + */ +gf_boolean_t +gf_sock_union_equal_addr (union gf_sock_union *a, + union gf_sock_union *b) +{ + if (!a || !b) { + gf_log ("common-utils", GF_LOG_ERROR, "Invalid arguments" + " to gf_sock_union_equal_addr"); + return _gf_false; + } + + if (a->storage.ss_family != b->storage.ss_family) + return _gf_false; + + switch (a->storage.ss_family) { + case AF_INET: + if (a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr) + return _gf_true; + else + return _gf_false; + + case AF_INET6: + if (memcmp ((void *)(&a->sin6.sin6_addr), + (void *)(&b->sin6.sin6_addr), + sizeof (a->sin6.sin6_addr))) + return _gf_false; + else + return _gf_true; + + default: + gf_log ("common-utils", GF_LOG_DEBUG, + "Unsupported/invalid address family"); + break; + } + + return _gf_false; +} + /*Thread safe conversion function*/ char * uuid_utoa (uuid_t uuid) @@ -2251,17 +2436,11 @@ gf_process_reserved_ports (gf_boolean_t *ports) goto out; } - blocked_port = strtok_r (ports_info, ",",&tmp); - if (!blocked_port || !strcmp (blocked_port, ports_info)) { - if (!blocked_port) - blocked_port = ports_info; - gf_ports_reserved (blocked_port, ports); - blocked_port = strtok_r (NULL, ",", &tmp); - } + blocked_port = strtok_r (ports_info, ",\n",&tmp); while (blocked_port) { gf_ports_reserved (blocked_port, ports); - blocked_port = strtok_r (NULL, ",", &tmp); + blocked_port = strtok_r (NULL, ",\n", &tmp); } ret = 0; @@ -2337,3 +2516,393 @@ gf_ports_reserved (char *blocked_port, gf_boolean_t *ports) 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 b89a988c6..3c99a4212 100644 --- a/libglusterfs/src/common-utils.h +++ b/libglusterfs/src/common-utils.h @@ -23,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 @@ -30,7 +31,6 @@ void trap (void); #define GF_UNIVERSAL_ANSWER 42 /* :O */ -#define TMP_MAX 238328 /* To solve type punned error */ #define VOID(ptr) ((void **) ((void *) ptr)) @@ -66,6 +66,8 @@ void trap (void); #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) \ @@ -76,7 +78,7 @@ void trap (void); /* Defining this here as it is needed by glusterd for setting * nfs port in volume status. */ -#define GF_NFS3_PORT 38467 +#define GF_NFS3_PORT 2049 #define GF_CLIENT_PORT_CEILING 1024 enum _gf_boolean @@ -108,8 +110,9 @@ 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_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))) @@ -483,6 +486,9 @@ mkdir_p (char *path, mode_t mode, gf_boolean_t allow_symlinks); * nr */ +int +gf_lstat_dir (const char *path, struct stat *stbuf_in); + int32_t gf_roundup_power_of_two (int32_t nr); /* @@ -553,6 +559,8 @@ 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); @@ -575,5 +583,12 @@ 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.h b/libglusterfs/src/compat.h index 3d0cee1a9..2bd982541 100644 --- a/libglusterfs/src/compat.h +++ b/libglusterfs/src/compat.h @@ -32,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 diff --git a/libglusterfs/src/defaults.c b/libglusterfs/src/defaults.c index 5bac845c1..2ebb25150 100644 --- a/libglusterfs/src/defaults.c +++ b/libglusterfs/src/defaults.c @@ -455,6 +455,35 @@ default_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } 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) { @@ -862,6 +891,37 @@ default_fsetattr_resume (call_frame_t *frame, xlator_t *this, fd_t *fd, 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 @@ -1266,6 +1326,36 @@ default_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, 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; +} + int32_t default_forget (xlator_t *this, inode_t *inode) diff --git a/libglusterfs/src/defaults.h b/libglusterfs/src/defaults.h index 8a9de7899..0747027bc 100644 --- a/libglusterfs/src/defaults.h +++ b/libglusterfs/src/defaults.h @@ -243,6 +243,25 @@ int32_t default_fsetattr (call_frame_t *frame, struct iatt *stbuf, 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_resume (call_frame_t *frame, xlator_t *this, @@ -453,6 +472,25 @@ int32_t default_fsetattr_resume (call_frame_t *frame, struct iatt *stbuf, 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 @@ -663,6 +701,18 @@ 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, 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, int32_t op_ret, int32_t op_errno, char *spec_data); diff --git a/libglusterfs/src/dict.c b/libglusterfs/src/dict.c index a8cdeaf28..3b7ddce5e 100644 --- a/libglusterfs/src/dict.c +++ b/libglusterfs/src/dict.c @@ -896,7 +896,7 @@ data_to_int32 (data_t *data) int16_t data_to_int16 (data_t *data) { - int16_t value = 0; + int16_t value = 0; if (!data) { gf_log_callingfn ("dict", GF_LOG_WARNING, "data is NULL"); @@ -910,16 +910,16 @@ data_to_int16 (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 ((SHRT_MAX > value) || (SHRT_MIN < value)) { - errno = ERANGE; + if ((value > SHRT_MAX) || (value < SHRT_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 (int16_t)value; } @@ -928,7 +928,7 @@ data_to_int16 (data_t *data) 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"); @@ -942,16 +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; } @@ -1180,8 +1180,10 @@ dict_keys_join (void *value, int size, dict_t *dict, while (pairs) { next = pairs->next; - if (filter_fn && filter_fn (pairs->key)) - continue; + if (filter_fn && filter_fn (pairs->key)){ + pairs = next; + continue; + } if (value && (size > len)) strncpy (value + len, pairs->key, size - len); @@ -2574,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; diff --git a/libglusterfs/src/dict.h b/libglusterfs/src/dict.h index c7606352c..9b41b5a7d 100644 --- a/libglusterfs/src/dict.h +++ b/libglusterfs/src/dict.h @@ -234,5 +234,4 @@ GF_MUST_CHECK int dict_serialize_value_with_delim (dict_t *this, char *buf, int3 char delimiter); void dict_dump (dict_t *dict); - #endif diff --git a/libglusterfs/src/event-history.c b/libglusterfs/src/event-history.c index fe511caeb..82baa521a 100644 --- a/libglusterfs/src/event-history.c +++ b/libglusterfs/src/event-history.c @@ -11,7 +11,8 @@ #include "event-history.h" eh_t * -eh_new (size_t buffer_size, gf_boolean_t use_buffer_once) +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; @@ -22,7 +23,8 @@ eh_new (size_t buffer_size, gf_boolean_t use_buffer_once) goto out; } - buffer = cb_buffer_new (buffer_size, use_buffer_once); + 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); diff --git a/libglusterfs/src/event-history.h b/libglusterfs/src/event-history.h index b1750bbae..b64f63b5e 100644 --- a/libglusterfs/src/event-history.h +++ b/libglusterfs/src/event-history.h @@ -32,7 +32,8 @@ 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); +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); diff --git a/libglusterfs/src/fd-lk.c b/libglusterfs/src/fd-lk.c index fff4aa996..caf2bb38e 100644 --- a/libglusterfs/src/fd-lk.c +++ b/libglusterfs/src/fd-lk.c @@ -380,8 +380,8 @@ _fd_lk_insert_and_merge (fd_lk_ctx_t *lk_ctx, return; } else { sum = _fd_lk_add_locks (entry, lock); - sum->fl_type = entry->fl_type; - sum->user_flock.l_type = entry->fl_type; + 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; @@ -391,6 +391,8 @@ _fd_lk_insert_and_merge (fd_lk_ctx_t *lk_ctx, _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; @@ -407,7 +409,7 @@ _fd_lk_insert_and_merge (fd_lk_ctx_t *lk_ctx, if (lock->fl_type != F_UNLCK) { _fd_lk_insert_lock (lk_ctx, lock); } else { - _fd_lk_destroy_lock_list (lk_ctx); + _fd_lk_destroy_lock (lock); } } diff --git a/libglusterfs/src/fd.c b/libglusterfs/src/fd.c index 0c3a52621..36cc4d056 100644 --- a/libglusterfs/src/fd.c +++ b/libglusterfs/src/fd.c @@ -513,6 +513,11 @@ 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); @@ -552,6 +557,7 @@ __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; } @@ -774,6 +780,23 @@ 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) diff --git a/libglusterfs/src/fd.h b/libglusterfs/src/fd.h index 54290b198..c1b9157d8 100644 --- a/libglusterfs/src/fd.h +++ b/libglusterfs/src/fd.h @@ -134,6 +134,9 @@ 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); diff --git a/libglusterfs/src/gidcache.c b/libglusterfs/src/gidcache.c index c55ed2581..c5bdda925 100644 --- a/libglusterfs/src/gidcache.c +++ b/libglusterfs/src/gidcache.c @@ -35,6 +35,21 @@ int gid_cache_init(gid_cache_t *cache, uint32_t timeout) } /* + * 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. diff --git a/libglusterfs/src/gidcache.h b/libglusterfs/src/gidcache.h index f904f26eb..9379f8e8b 100644 --- a/libglusterfs/src/gidcache.h +++ b/libglusterfs/src/gidcache.h @@ -45,6 +45,7 @@ typedef struct { } 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 *); diff --git a/libglusterfs/src/globals.c b/libglusterfs/src/globals.c index 05ff52c2c..259c5c885 100644 --- a/libglusterfs/src/globals.c +++ b/libglusterfs/src/globals.c @@ -19,6 +19,7 @@ #include "globals.h" #include "xlator.h" #include "mem-pool.h" +#include "syncop.h" const char *gf_fop_list[GF_FOP_MAXVALUE] = { [GF_FOP_NULL] = "NULL", @@ -67,6 +68,9 @@ const char *gf_fop_list[GF_FOP_MAXVALUE] = { [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 */ @@ -121,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; @@ -164,6 +166,54 @@ glusterfs_this_set (xlator_t *this) return 0; } +/* SYNCOPCTX */ +static pthread_key_t syncopctx_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 @@ -176,7 +226,6 @@ synctask_init () return ret; } - void * synctask_get () { @@ -300,6 +349,13 @@ glusterfs_globals_init (glusterfs_ctx_t *ctx) "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; } diff --git a/libglusterfs/src/globals.h b/libglusterfs/src/globals.h index e13902b29..3085db21c 100644 --- a/libglusterfs/src/globals.h +++ b/libglusterfs/src/globals.h @@ -13,6 +13,25 @@ #define GF_DEFAULT_BASE_PORT 24007 +#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 */ @@ -22,6 +41,10 @@ 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 *); 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 74e6847a0..2f1e12ee7 100644 --- a/libglusterfs/src/glusterfs.h +++ b/libglusterfs/src/glusterfs.h @@ -32,6 +32,7 @@ #include <arpa/inet.h> #include <sys/poll.h> #include <pthread.h> +#include <limits.h> /* For PATH_MAX */ #include "list.h" #include "logging.h" @@ -69,6 +70,7 @@ #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" @@ -83,9 +85,12 @@ #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, \ @@ -93,24 +98,33 @@ #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 */ @@ -120,9 +134,6 @@ #define RB_PUMP_CMD_ABORT "glusterfs.pump.abort" #define RB_PUMP_CMD_STATUS "glusterfs.pump.status" -#define POSIX_ACL_DEFAULT_XATTR "system.posix_acl_default" -#define POSIX_ACL_ACCESS_XATTR "system.posix_acl_access" - #define GLUSTERFS_RDMA_INLINE_THRESHOLD (2048) #define GLUSTERFS_RDMA_MAX_HEADER_SIZE (228) /* (sizeof (rdma_header_t) \ + RDMA_MAX_SEGMENTS \ @@ -132,15 +143,16 @@ #define GLUSTERFS_RPC_REPLY_SIZE 24 #define ZR_FILE_CONTENT_REQUEST(key) (!strncmp(key, ZR_FILE_CONTENT_STR, \ - ZR_FILE_CONTENT_STRLEN)) + ZR_FILE_CONTENT_STRLEN)) #define DEFAULT_VAR_RUN_DIRECTORY DATADIR "/run/gluster" +#define GF_REPLICATE_TRASH_DIR ".landfill" /* GlusterFS's maximum supported Auxilary GIDs */ /* TODO: Keeping it to 200, so that we can fit in 2KB buffer for auth data * in RPC server code, if there is ever need for having more aux-gids, then * we have to add aux-gid in payload of actors */ -#define GF_MAX_AUX_GROUPS 200 +#define GF_MAX_AUX_GROUPS 65536 #define GF_UUID_BUF_SIZE 50 @@ -148,6 +160,13 @@ #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 { GF_FOP_NULL = 0, @@ -181,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, @@ -196,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; @@ -245,20 +267,20 @@ typedef enum { typedef enum { - ENTRYLK_LOCK, - ENTRYLK_UNLOCK, - ENTRYLK_LOCK_NB + ENTRYLK_LOCK, + ENTRYLK_UNLOCK, + ENTRYLK_LOCK_NB } entrylk_cmd; typedef enum { - ENTRYLK_RDLCK, - ENTRYLK_WRLCK + ENTRYLK_RDLCK, + ENTRYLK_WRLCK } entrylk_type; typedef enum { - GF_XATTROP_ADD_ARRAY, + GF_XATTROP_ADD_ARRAY, GF_XATTROP_ADD_ARRAY64, GF_XATTROP_OR_ARRAY, GF_XATTROP_AND_ARRAY @@ -274,65 +296,75 @@ typedef enum { #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; - int fopen_keep_cache; - int gid_timeout; - 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_negative_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; + 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; @@ -360,16 +392,16 @@ 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 */ @@ -385,12 +417,12 @@ struct _glusterfs_ctx { got changed */ pid_t mnt_pid; /* pid of the mount agent */ int process_mode; /*mode in which process is runninng*/ - struct syncenv *env; /* The env pointer to the synctasks */ + struct 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; @@ -400,9 +432,12 @@ struct _glusterfs_ctx { call to fsd-mgmt */ gf_log_handle_t log; /* all logging related variables */ - int mem_acct_enable; + int mem_acct_enable; int daemon_pipe[2]; + + struct client_disconnect *client_disconnect; + struct clienttable *clienttable; }; typedef struct _glusterfs_ctx glusterfs_ctx_t; @@ -426,6 +461,7 @@ typedef enum { GF_EVENT_AUTH_FAILED, GF_EVENT_VOLUME_DEFRAG, GF_EVENT_PARENT_DOWN, + GF_EVENT_VOLUME_BARRIER_OP, GF_EVENT_MAXVAL, } glusterfs_event_t; diff --git a/libglusterfs/src/graph.c b/libglusterfs/src/graph.c index 8a84d4cbc..e76df1ca5 100644 --- a/libglusterfs/src/graph.c +++ b/libglusterfs/src/graph.c @@ -213,6 +213,21 @@ glusterfs_graph_mac_compat (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx) 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) @@ -441,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; @@ -514,6 +537,184 @@ glusterfs_graph_activate (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx) 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) { @@ -539,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 ff34f6ef1..e4eba9cbe 100644 --- a/libglusterfs/src/graph.l +++ b/libglusterfs/src/graph.l @@ -70,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 a640f2402..a220abeb9 100644 --- a/libglusterfs/src/graph.y +++ b/libglusterfs/src/graph.y @@ -18,6 +18,7 @@ #include <sys/mman.h> #include <sys/types.h> #include <sys/wait.h> +#include <pthread.h> #define RELAX_POISONING @@ -37,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 (); %} @@ -78,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; } @@ -90,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; } @@ -102,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; } @@ -115,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; @@ -129,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; } @@ -149,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; } @@ -194,7 +195,7 @@ out: static int volume_type (char *type) { - extern int yylineno; + extern int graphyylineno; int32_t ret = 0; if (!type) { @@ -208,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; } @@ -225,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; @@ -242,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; } @@ -261,7 +262,7 @@ out: static int volume_sub (char *sub) { - extern int yylineno; + extern int graphyylineno; xlator_t *trav = NULL; int ret = 0; @@ -283,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; } @@ -291,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; } @@ -328,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'"); } @@ -376,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; @@ -481,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; } @@ -522,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); @@ -529,7 +532,7 @@ out: } -extern FILE *yyin; +extern FILE *graphyyin; glusterfs_graph_t * glusterfs_graph_new () @@ -553,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 temporary 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/inode.c b/libglusterfs/src/inode.c index 886491292..15e0ccf78 100644 --- a/libglusterfs/src/inode.c +++ b/libglusterfs/src/inode.c @@ -310,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; @@ -528,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); @@ -1316,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; @@ -1466,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; @@ -1493,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, @@ -1512,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; } @@ -1562,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, @@ -1575,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; @@ -1600,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) @@ -1624,17 +1825,19 @@ 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]; } } @@ -1651,7 +1854,7 @@ 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) diff --git a/libglusterfs/src/inode.h b/libglusterfs/src/inode.h index 20e28f682..a88976265 100644 --- a/libglusterfs/src/inode.h +++ b/libglusterfs/src/inode.h @@ -56,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 */ }; @@ -72,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; @@ -87,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 */ @@ -157,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); @@ -175,29 +184,66 @@ int inode_ctx_del2 (inode_t *inode, xlator_t *xlator, uint64_t *value1, uint64_t *value2); -inode_t * -inode_resolve (inode_table_t *table, char *path); +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); -#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) 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 86bf697e8..a89e96267 100644 --- a/libglusterfs/src/iobuf.c +++ b/libglusterfs/src/iobuf.c @@ -841,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) { diff --git a/libglusterfs/src/iobuf.h b/libglusterfs/src/iobuf.h index b9c2a3807..5595309e1 100644 --- a/libglusterfs/src/iobuf.h +++ b/libglusterfs/src/iobuf.h @@ -150,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 9fe76efa0..b22f72950 100644 --- a/libglusterfs/src/latency.c +++ b/libglusterfs/src/latency.c @@ -26,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 == *(fop_stat_t *)fn) + if (fops->stat == *(fop_stat_t *)&fn) fop = GF_FOP_STAT; - else if (fops->readlink == *(fop_readlink_t *)fn) + else if (fops->readlink == *(fop_readlink_t *)&fn) fop = GF_FOP_READLINK; - else if (fops->mknod == *(fop_mknod_t *)fn) + else if (fops->mknod == *(fop_mknod_t *)&fn) fop = GF_FOP_MKNOD; - else if (fops->mkdir == *(fop_mkdir_t *)fn) + else if (fops->mkdir == *(fop_mkdir_t *)&fn) fop = GF_FOP_MKDIR; - else if (fops->unlink == *(fop_unlink_t *)fn) + else if (fops->unlink == *(fop_unlink_t *)&fn) fop = GF_FOP_UNLINK; - else if (fops->rmdir == *(fop_rmdir_t *)fn) + else if (fops->rmdir == *(fop_rmdir_t *)&fn) fop = GF_FOP_RMDIR; - else if (fops->symlink == *(fop_symlink_t *)fn) + else if (fops->symlink == *(fop_symlink_t *)&fn) fop = GF_FOP_SYMLINK; - else if (fops->rename == *(fop_rename_t *)fn) + else if (fops->rename == *(fop_rename_t *)&fn) fop = GF_FOP_RENAME; - else if (fops->link == *(fop_link_t *)fn) + else if (fops->link == *(fop_link_t *)&fn) fop = GF_FOP_LINK; - else if (fops->truncate == *(fop_truncate_t *)fn) + else if (fops->truncate == *(fop_truncate_t *)&fn) fop = GF_FOP_TRUNCATE; - else if (fops->open == *(fop_open_t *)fn) + else if (fops->open == *(fop_open_t *)&fn) fop = GF_FOP_OPEN; - else if (fops->readv == *(fop_readv_t *)fn) + else if (fops->readv == *(fop_readv_t *)&fn) fop = GF_FOP_READ; - else if (fops->writev == *(fop_writev_t *)fn) + else if (fops->writev == *(fop_writev_t *)&fn) fop = GF_FOP_WRITE; - else if (fops->statfs == *(fop_statfs_t *)fn) + else if (fops->statfs == *(fop_statfs_t *)&fn) fop = GF_FOP_STATFS; - else if (fops->flush == *(fop_flush_t *)fn) + else if (fops->flush == *(fop_flush_t *)&fn) fop = GF_FOP_FLUSH; - else if (fops->fsync == *(fop_fsync_t *)fn) + else if (fops->fsync == *(fop_fsync_t *)&fn) fop = GF_FOP_FSYNC; - else if (fops->setxattr == *(fop_setxattr_t *)fn) + else if (fops->setxattr == *(fop_setxattr_t *)&fn) fop = GF_FOP_SETXATTR; - else if (fops->getxattr == *(fop_getxattr_t *)fn) + else if (fops->getxattr == *(fop_getxattr_t *)&fn) fop = GF_FOP_GETXATTR; - else if (fops->removexattr == *(fop_removexattr_t *)fn) + else if (fops->removexattr == *(fop_removexattr_t *)&fn) fop = GF_FOP_REMOVEXATTR; - else if (fops->opendir == *(fop_opendir_t *)fn) + else if (fops->opendir == *(fop_opendir_t *)&fn) fop = GF_FOP_OPENDIR; - else if (fops->fsyncdir == *(fop_fsyncdir_t *)fn) + else if (fops->fsyncdir == *(fop_fsyncdir_t *)&fn) fop = GF_FOP_FSYNCDIR; - else if (fops->access == *(fop_access_t *)fn) + else if (fops->access == *(fop_access_t *)&fn) fop = GF_FOP_ACCESS; - else if (fops->create == *(fop_create_t *)fn) + else if (fops->create == *(fop_create_t *)&fn) fop = GF_FOP_CREATE; - else if (fops->ftruncate == *(fop_ftruncate_t *)fn) + else if (fops->ftruncate == *(fop_ftruncate_t *)&fn) fop = GF_FOP_FTRUNCATE; - else if (fops->fstat == *(fop_fstat_t *)fn) + else if (fops->fstat == *(fop_fstat_t *)&fn) fop = GF_FOP_FSTAT; - else if (fops->lk == *(fop_lk_t *)fn) + else if (fops->lk == *(fop_lk_t *)&fn) fop = GF_FOP_LK; - else if (fops->lookup == *(fop_lookup_t *)fn) + else if (fops->lookup == *(fop_lookup_t *)&fn) fop = GF_FOP_LOOKUP; - else if (fops->readdir == *(fop_readdir_t *)fn) + else if (fops->readdir == *(fop_readdir_t *)&fn) fop = GF_FOP_READDIR; - else if (fops->inodelk == *(fop_inodelk_t *)fn) + else if (fops->inodelk == *(fop_inodelk_t *)&fn) fop = GF_FOP_INODELK; - else if (fops->finodelk == *(fop_finodelk_t *)fn) + else if (fops->finodelk == *(fop_finodelk_t *)&fn) fop = GF_FOP_FINODELK; - else if (fops->entrylk == *(fop_entrylk_t *)fn) + else if (fops->entrylk == *(fop_entrylk_t *)&fn) fop = GF_FOP_ENTRYLK; - else if (fops->fentrylk == *(fop_fentrylk_t *)fn) + else if (fops->fentrylk == *(fop_fentrylk_t *)&fn) fop = GF_FOP_FENTRYLK; - else if (fops->xattrop == *(fop_xattrop_t *)fn) + else if (fops->xattrop == *(fop_xattrop_t *)&fn) fop = GF_FOP_XATTROP; - else if (fops->fxattrop == *(fop_fxattrop_t *)fn) + else if (fops->fxattrop == *(fop_fxattrop_t *)&fn) fop = GF_FOP_FXATTROP; - else if (fops->fgetxattr == *(fop_fgetxattr_t *)fn) + else if (fops->fgetxattr == *(fop_fgetxattr_t *)&fn) fop = GF_FOP_FGETXATTR; - else if (fops->fsetxattr == *(fop_fsetxattr_t *)fn) + else if (fops->fsetxattr == *(fop_fsetxattr_t *)&fn) fop = GF_FOP_FSETXATTR; - else if (fops->rchecksum == *(fop_rchecksum_t *)fn) + else if (fops->rchecksum == *(fop_rchecksum_t *)&fn) fop = GF_FOP_RCHECKSUM; - else if (fops->setattr == *(fop_setattr_t *)fn) + else if (fops->setattr == *(fop_setattr_t *)&fn) fop = GF_FOP_SETATTR; - else if (fops->fsetattr == *(fop_fsetattr_t *)fn) + else if (fops->fsetattr == *(fop_fsetattr_t *)&fn) fop = GF_FOP_FSETATTR; - else if (fops->readdirp == *(fop_readdirp_t *)fn) + else if (fops->readdirp == *(fop_readdirp_t *)&fn) fop = GF_FOP_READDIRP; - else if (fops->getspec == *(fop_getspec_t *)fn) + else if (fops->getspec == *(fop_getspec_t *)&fn) fop = GF_FOP_GETSPEC; else fop = -1; @@ -136,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) @@ -156,6 +172,8 @@ gf_proc_dump_latency_info (xlator_t *xl) xl->latencies[i].count, xl->latencies[i].total); } + + memset (xl->latencies, 0, sizeof (xl->latencies)); } diff --git a/libglusterfs/src/list.h b/libglusterfs/src/list.h index 35fccdf25..392c22ceb 100644 --- a/libglusterfs/src/list.h +++ b/libglusterfs/src/list.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> + 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 @@ -11,7 +11,6 @@ #ifndef _LLIST_H #define _LLIST_H - struct list_head { struct list_head *next; struct list_head *prev; @@ -45,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) { @@ -175,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/logging.c b/libglusterfs/src/logging.c index 65613f985..5deb90cda 100644 --- a/libglusterfs/src/logging.c +++ b/libglusterfs/src/logging.c @@ -22,6 +22,18 @@ #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" @@ -102,6 +114,207 @@ gf_log_fini (void) } +#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 *data) { @@ -113,21 +326,47 @@ gf_log_globals_init (void *data) ctx->log.gf_log_syslog = 1; ctx->log.sys_log_level = GF_LOG_CRITICAL; +#ifndef GF_USE_SYSLOG #ifdef GF_LINUX_HOST_OS /* For the 'syslog' output. one can grep 'GlusterFS' in syslog for serious logs */ openlog ("GlusterFS", LOG_PID, LOG_DAEMON); #endif +#endif } int -gf_log_init (void *data, const char *file) +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; @@ -135,7 +374,7 @@ gf_log_init (void *data, const char *file) if (strcmp (file, "-") == 0) { ctx->log.gf_log_logfile = stderr; - + ctx->log.logfile = stderr; return 0; } @@ -215,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 { @@ -241,6 +486,25 @@ _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; @@ -248,12 +512,6 @@ _gf_log_nomem (const char *domain, const char *file, snprintf (timestr + strlen (timestr), sizeof timestr - 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], @@ -331,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 { @@ -357,6 +621,32 @@ _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; @@ -365,12 +655,6 @@ _gf_log_callingfn (const char *domain, const char *file, const char *function, snprintf (timestr + strlen (timestr), sizeof timestr - 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, @@ -468,6 +752,35 @@ _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 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] %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; @@ -509,12 +822,6 @@ log: snprintf (timestr + strlen (timestr), sizeof timestr - 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, diff --git a/libglusterfs/src/logging.h b/libglusterfs/src/logging.h index c45246e44..cc806a767 100644 --- a/libglusterfs/src/logging.h +++ b/libglusterfs/src/logging.h @@ -19,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" @@ -34,6 +35,7 @@ #define GF_PRI_BLKSIZE PRId32 #define GF_PRI_SIZET "zu" + #if 0 /* Syslog definitions :-) */ #define LOG_EMERG 0 /* system is unusable */ @@ -59,6 +61,9 @@ typedef enum { GF_LOG_TRACE, /* full trace of operation */ } gf_loglevel_t; +#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; @@ -71,11 +76,15 @@ typedef struct gf_log_handle_ { 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); +int gf_log_init (void *data, const char *filename, const char *ident); void gf_log_logrotate (int signum); diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c index 755e73944..b901dd7a8 100644 --- a/libglusterfs/src/mem-pool.c +++ b/libglusterfs/src/mem-pool.c @@ -33,22 +33,13 @@ void gf_mem_acct_enable_set (void *data) { - char *opt = NULL; - long val = -1; glusterfs_ctx_t *ctx = NULL; ctx = data; - if (ctx->mem_acct_enable) { - return; - } + GF_ASSERT (ctx); - opt = getenv (GLUSTERFS_ENV_MEM_ACCT_STR); - if (opt) { - val = strtol (opt, NULL, 0); - if (val) - ctx->mem_acct_enable = 1; - } + ctx->mem_acct_enable = 1; return; } @@ -427,8 +418,6 @@ mem_get (struct mem_pool *mem_pool) 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 diff --git a/libglusterfs/src/mem-pool.h b/libglusterfs/src/mem-pool.h index 939b4f2a7..31f49f75c 100644 --- a/libglusterfs/src/mem-pool.h +++ b/libglusterfs/src/mem-pool.h @@ -148,7 +148,7 @@ char * gf_strdup (const char *src) } static inline void * -gf_memdup (const void *src, void *dst, size_t size) +gf_memdup (const void *src, size_t size) { void *dup_mem = NULL; diff --git a/libglusterfs/src/mem-types.h b/libglusterfs/src/mem-types.h index 12379bf31..666bd120a 100644 --- a/libglusterfs/src/mem-types.h +++ b/libglusterfs/src/mem-types.h @@ -102,6 +102,24 @@ enum gf_common_mem_types_ { gf_common_mt_buffer_t = 86, gf_common_mt_circular_buffer_t = 87, gf_common_mt_eh_t = 88, - gf_common_mt_end = 89 + 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 5d436bab3..842b6413a 100644 --- a/libglusterfs/src/options.c +++ b/libglusterfs/src/options.c @@ -761,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; @@ -1098,7 +1098,6 @@ pc_or_size (char *in, double *out) return ret; } - DEFINE_INIT_OPT(char *, str, pass); DEFINE_INIT_OPT(uint64_t, uint64, gf_string2uint64); DEFINE_INIT_OPT(int64_t, int64, gf_string2int64); diff --git a/libglusterfs/src/options.h b/libglusterfs/src/options.h index 64c2c64ef..e2a25baa9 100644 --- a/libglusterfs/src/options.h +++ b/libglusterfs/src/options.h @@ -93,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 \ diff --git a/libglusterfs/src/run.c b/libglusterfs/src/run.c index ebe7f3962..4fd2a3a0d 100644 --- a/libglusterfs/src/run.c +++ b/libglusterfs/src/run.c @@ -187,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); } diff --git a/libglusterfs/src/stack.c b/libglusterfs/src/stack.c index 5349eaa0b..37b338f51 100644 --- a/libglusterfs/src/stack.c +++ b/libglusterfs/src/stack.c @@ -26,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,...) { @@ -34,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; @@ -47,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); @@ -73,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; + } } @@ -83,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; @@ -96,6 +150,15 @@ 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); @@ -129,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); @@ -152,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 diff --git a/libglusterfs/src/stack.h b/libglusterfs/src/stack.h index b14b08dbb..f2d2ef950 100644 --- a/libglusterfs/src/stack.h +++ b/libglusterfs/src/stack.h @@ -25,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> @@ -36,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 @@ -46,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 { @@ -82,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; @@ -92,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; }; @@ -122,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) @@ -173,6 +179,9 @@ STACK_DESTROY (call_stack_t *stack) while (stack->frames.next) { FRAME_DESTROY (stack->frames.next); } + + GF_FREE (stack->groups_large); + mem_put (stack); if (local) @@ -236,6 +245,7 @@ STACK_RESET (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); \ { \ @@ -249,6 +259,8 @@ STACK_RESET (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) @@ -302,6 +314,8 @@ STACK_RESET (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) @@ -328,6 +342,8 @@ STACK_RESET (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) @@ -355,11 +371,31 @@ STACK_RESET (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) { @@ -383,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); @@ -405,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/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 c8a9b5848..c1620bb70 100644 --- a/libglusterfs/src/syncop.c +++ b/libglusterfs/src/syncop.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> + 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 @@ -15,6 +15,160 @@ #include "syncop.h" +int +syncopctx_setfsuid (void *uid) +{ + 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; +} + +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; +} + +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; +} + static void __run (struct synctask *task) { @@ -23,27 +177,31 @@ __run (struct synctask *task) env = task->env; list_del_init (&task->all_tasks); - switch (task->state) { - case SYNCTASK_INIT: + switch (task->state) { + case SYNCTASK_INIT: case SYNCTASK_SUSPEND: - break; - case SYNCTASK_RUN: - gf_log (task->xl->name, GF_LOG_WARNING, - "re-running already running task"); - env->runcount--; - break; - case SYNCTASK_WAIT: - env->waitcount--; - break; - case SYNCTASK_DONE: + 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, - "running completed task"); - break; - } + "attempted to wake up zombie!!"); + return; + } list_add_tail (&task->all_tasks, &env->runq); - env->runcount++; - task->state = SYNCTASK_RUN; + env->runcount++; + task->state = SYNCTASK_RUN; } @@ -55,46 +213,52 @@ __wait (struct synctask *task) env = task->env; list_del_init (&task->all_tasks); - switch (task->state) { - case SYNCTASK_INIT: + 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: + 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, - "running completed task"); - break; - } + "attempted to sleep a zombie!!"); + return; + } list_add_tail (&task->all_tasks, &env->waitq); - env->waitcount++; - task->state = SYNCTASK_WAIT; + env->waitcount++; + task->state = SYNCTASK_WAIT; } void synctask_yield (struct synctask *task) { - xlator_t *oldTHIS = THIS; + xlator_t *oldTHIS = THIS; #if defined(__NetBSD__) && defined(_UC_TLSBASE) - /* Preserve pthread private pointer through swapcontex() */ - task->proc->sched.uc_flags &= ~_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; + THIS = oldTHIS; } @@ -111,10 +275,10 @@ synctask_wake (struct synctask *task) if (task->slept) __run (task); + + pthread_cond_broadcast (&env->cond); } pthread_mutex_unlock (&env->mutex); - - pthread_cond_broadcast (&env->cond); } void @@ -127,8 +291,8 @@ synctask_wrap (struct synctask *old_task) task = synctask_get (); task->ret = task->syncfn (task->opaque); - if (task->synccbk) - task->synccbk (task->ret, task->frame, task->opaque); + if (task->synccbk) + task->synccbk (task->ret, task->frame, task->opaque); task->state = SYNCTASK_DONE; @@ -147,9 +311,10 @@ synctask_destroy (struct synctask *task) if (task->opframe) STACK_DESTROY (task->opframe->root); - pthread_mutex_destroy (&task->mutex); - - pthread_cond_destroy (&task->cond); + if (task->synccbk == NULL) { + pthread_mutex_destroy (&task->mutex); + pthread_cond_destroy (&task->cond); + } FREE (task); } @@ -158,34 +323,50 @@ synctask_destroy (struct synctask *task) void synctask_done (struct synctask *task) { - if (task->synccbk) { - synctask_destroy (task); - return; - } + if (task->synccbk) { + synctask_destroy (task); + return; + } - pthread_mutex_lock (&task->mutex); - { - task->done = 1; - pthread_cond_broadcast (&task->cond); - } - pthread_mutex_unlock (&task->mutex); + 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; - int ret = 0; VALIDATE_OR_GOTO (env, err); VALIDATE_OR_GOTO (fn, err); newtask = CALLOC (1, sizeof (*newtask)); if (!newtask) - return -ENOMEM; + return NULL; newtask->frame = frame; if (!frame) { @@ -198,10 +379,15 @@ synctask_new (struct syncenv *env, synctask_fn_t fn, synctask_cbk_t cbk, newtask->env = env; newtask->xl = this; newtask->syncfn = fn; - newtask->synccbk = cbk; + newtask->synccbk = cbk; newtask->opaque = opaque; + /* default to the uid/gid of the passed frame */ + newtask->uid = newtask->opframe->root->uid; + newtask->gid = newtask->opframe->root->gid; + INIT_LIST_HEAD (&newtask->all_tasks); + INIT_LIST_HEAD (&newtask->waitq); if (getcontext (&newtask->ctx) < 0) { gf_log ("syncop", GF_LOG_ERROR, @@ -222,15 +408,15 @@ synctask_new (struct syncenv *env, synctask_fn_t fn, synctask_cbk_t cbk, makecontext (&newtask->ctx, (void (*)(void)) synctask_wrap, 2, newtask); - newtask->state = SYNCTASK_INIT; + newtask->state = SYNCTASK_INIT; newtask->slept = 1; - if (!cbk) { - pthread_mutex_init (&newtask->mutex, NULL); - pthread_cond_init (&newtask->cond, NULL); - newtask->done = 0; - } + if (!cbk) { + pthread_mutex_init (&newtask->mutex, NULL); + pthread_cond_init (&newtask->cond, NULL); + newtask->done = 0; + } synctask_wake (newtask); /* @@ -239,21 +425,7 @@ synctask_new (struct syncenv *env, synctask_fn_t fn, synctask_cbk_t cbk, */ syncenv_scale(env); - if (!cbk) { - pthread_mutex_lock (&newtask->mutex); - { - while (!newtask->done) { - pthread_cond_wait (&newtask->cond, &newtask->mutex); - } - } - pthread_mutex_unlock (&newtask->mutex); - - ret = newtask->ret; - - synctask_destroy (newtask); - } - - return ret; + return newtask; err: if (newtask) { FREE (newtask->stack); @@ -261,19 +433,58 @@ err: 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 syncproc *proc) { - struct syncenv *env = NULL; + struct syncenv *env = NULL; struct synctask *task = NULL; struct timespec sleep_till = {0, }; int ret = 0; - env = proc->env; + env = proc->env; pthread_mutex_lock (&env->mutex); { @@ -284,7 +495,7 @@ syncenv_task (struct syncproc *proc) if (!list_empty (&env->runq)) break; if ((ret == ETIMEDOUT) && - (env->procs > SYNCENV_PROC_MIN)) { + (env->procs > env->procmin)) { task = NULL; env->procs--; memset (proc, 0, sizeof (*proc)); @@ -295,9 +506,12 @@ syncenv_task (struct syncproc *proc) task = list_entry (env->runq.next, struct synctask, all_tasks); list_del_init (&task->all_tasks); - env->runcount--; + env->runcount--; - task->proc = proc; + task->woken = 0; + task->slept = 0; + + task->proc = proc; } unlock: pthread_mutex_unlock (&env->mutex); @@ -316,12 +530,9 @@ synctask_switchto (struct synctask *task) synctask_set (task); THIS = task->xl; - task->woken = 0; - task->slept = 0; - #if defined(__NetBSD__) && defined(_UC_TLSBASE) - /* Preserve pthread private pointer through swapcontex() */ - task->ctx.uc_flags &= ~_UC_TLSBASE; + /* Preserve pthread private pointer through swapcontex() */ + task->ctx.uc_flags &= ~_UC_TLSBASE; #endif if (swapcontext (&task->proc->sched, &task->ctx) < 0) { @@ -363,7 +574,7 @@ syncenv_processor (void *thdata) synctask_switchto (task); - syncenv_scale (env); + syncenv_scale (env); } return NULL; @@ -373,39 +584,39 @@ syncenv_processor (void *thdata) void syncenv_scale (struct syncenv *env) { - int diff = 0; + int diff = 0; int scale = 0; - int i = 0; - int ret = 0; + int i = 0; + int ret = 0; - pthread_mutex_lock (&env->mutex); - { - if (env->procs > env->runcount) - goto unlock; + pthread_mutex_lock (&env->mutex); + { + if (env->procs > env->runcount) + goto unlock; scale = env->runcount; - if (scale > SYNCENV_PROC_MAX) - scale = SYNCENV_PROC_MAX; + if (scale > env->procmax) + scale = env->procmax; if (scale > env->procs) diff = scale - env->procs; while (diff) { diff--; - for (; (i < SYNCENV_PROC_MAX); i++) { + for (; (i < env->procmax); i++) { if (env->proc[i].processor == 0) break; } - env->proc[i].env = env; - ret = pthread_create (&env->proc[i].processor, NULL, - syncenv_processor, &env->proc[i]); - if (ret) - break; - env->procs++; + 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); + pthread_mutex_unlock (&env->mutex); } @@ -417,12 +628,20 @@ 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)); if (!newenv) @@ -437,11 +656,13 @@ syncenv_new (size_t stacksize) newenv->stacksize = SYNCENV_DEFAULT_STACKSIZE; if (stacksize) newenv->stacksize = stacksize; + newenv->procmin = procmin; + newenv->procmax = procmax; - for (i = 0; i < SYNCENV_PROC_MIN; i++) { + for (i = 0; i < newenv->procmin; i++) { newenv->proc[i].env = newenv; - ret = pthread_create (&newenv->proc[i].processor, NULL, - syncenv_processor, &newenv->proc[i]); + ret = gf_thread_create (&newenv->proc[i].processor, NULL, + syncenv_processor, &newenv->proc[i]); if (ret) break; newenv->procs++; @@ -454,6 +675,268 @@ 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 */ @@ -516,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; } @@ -1101,7 +1586,7 @@ syncop_writev (xlator_t *subvol, fd_t *fd, const struct iovec *vector, SYNCOP (subvol, (&args), syncop_writev_cbk, subvol->fops->writev, fd, (struct iovec *) vector, count, offset, flags, iobref, - NULL); + NULL); errno = args.op_errno; return args.op_ret; @@ -1145,6 +1630,9 @@ syncop_create_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; @@ -1152,7 +1640,7 @@ 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 *xdata) + fd_t *fd, dict_t *xdata, struct iatt *iatt) { struct syncargs args = {0, }; @@ -1160,6 +1648,9 @@ syncop_create (xlator_t *subvol, loc_t *loc, int32_t flags, mode_t mode, loc, flags, mode, 0, fd, xdata); errno = args.op_errno; + if (iatt) + *iatt = args.iatt1; + return args.op_ret; } @@ -1225,8 +1716,8 @@ syncop_rmdir (xlator_t *subvol, loc_t *loc) 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, + 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; @@ -1258,10 +1749,10 @@ syncop_link (xlator_t *subvol, loc_t *oldloc, loc_t *newloc) 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) + 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; @@ -1456,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); @@ -1463,7 +1956,8 @@ syncop_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } int -syncop_symlink (xlator_t *subvol, loc_t *loc, const 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, }; @@ -1471,6 +1965,9 @@ syncop_symlink (xlator_t *subvol, loc_t *loc, const char *newpath, dict_t *dict) newpath, loc, 0, dict); errno = args.op_errno; + if (iatt) + *iatt = args.iatt1; + return args.op_ret; } @@ -1524,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; @@ -1531,7 +2031,7 @@ 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, }; @@ -1539,6 +2039,9 @@ syncop_mknod (xlator_t *subvol, loc_t *loc, mode_t mode, dev_t rdev, loc, mode, rdev, 0, dict); errno = args.op_errno; + if (iatt) + *iatt = args.iatt1; + return args.op_ret; } @@ -1556,6 +2059,8 @@ syncop_mkdir_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); @@ -1564,7 +2069,8 @@ syncop_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int -syncop_mkdir (xlator_t *subvol, loc_t *loc, mode_t mode, dict_t *dict) +syncop_mkdir (xlator_t *subvol, loc_t *loc, mode_t mode, dict_t *dict, + struct iatt *iatt) { struct syncargs args = {0, }; @@ -1572,6 +2078,9 @@ syncop_mkdir (xlator_t *subvol, loc_t *loc, mode_t mode, dict_t *dict) loc, mode, 0, dict); errno = args.op_errno; + if (iatt) + *iatt = args.iatt1; + return args.op_ret; } @@ -1602,3 +2111,127 @@ syncop_access (xlator_t *subvol, loc_t *loc, int32_t mask) 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 6e900e8d0..f790981f0 100644 --- a/libglusterfs/src/syncop.h +++ b/libglusterfs/src/syncop.h @@ -25,6 +25,13 @@ #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; @@ -36,11 +43,12 @@ typedef int (*synctask_fn_t) (void *opaque); typedef enum { - SYNCTASK_INIT = 0, - SYNCTASK_RUN, + SYNCTASK_INIT = 0, + SYNCTASK_RUN, SYNCTASK_SUSPEND, - SYNCTASK_WAIT, - SYNCTASK_DONE, + SYNCTASK_WAIT, + SYNCTASK_DONE, + SYNCTASK_ZOMBIE, } synctask_state_t; /* for one sequential execution of @syncfn */ @@ -52,19 +60,24 @@ struct synctask { call_frame_t *opframe; synctask_cbk_t synccbk; synctask_fn_t syncfn; - synctask_state_t state; + synctask_state_t state; void *opaque; void *stack; int woken; int slept; - int ret; + int ret; + + uid_t uid; + gid_t gid; ucontext_t ctx; - struct syncproc *proc; + struct syncproc *proc; - pthread_mutex_t mutex; /* for synchronous spawning of synctask */ - pthread_cond_t cond; - int done; + 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 */ }; @@ -85,6 +98,9 @@ struct syncenv { struct list_head waitq; int waitcount; + int procmin; + int procmax; + pthread_mutex_t mutex; pthread_cond_t cond; @@ -92,6 +108,25 @@ struct syncenv { }; +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; @@ -105,45 +140,58 @@ struct syncargs { 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; - pthread_cond_t cond; + pthread_mutex_t mutex; + pthread_cond_t cond; 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 { \ - if (!args->task) { \ - pthread_mutex_init (&args->mutex, NULL); \ - pthread_cond_init (&args->cond, NULL); \ - args->done = 0; \ - } \ - } while (0) +#define __yawn(args) do { \ + args->task = synctask_get (); \ + if (args->task) \ + break; \ + pthread_mutex_init (&args->mutex, NULL); \ + pthread_cond_init (&args->cond, NULL); \ + args->done = 0; \ + } while (0) -#define __wake(args) do { \ - if (args->task) { \ - synctask_wake (args->task); \ - } else { \ - pthread_mutex_lock (&args->mutex); \ - { \ - args->done = 1; \ - pthread_cond_signal (&args->cond); \ - } \ - pthread_mutex_unlock (&args->mutex); \ - } \ - } while (0) +#define __wake(args) do { \ + if (args->task) { \ + synctask_wake (args->task); \ + } else { \ + pthread_mutex_lock (&args->mutex); \ + { \ + args->done = 1; \ + pthread_cond_signal (&args->cond); \ + } \ + pthread_mutex_unlock (&args->mutex); \ + } \ + } while (0) #define __yield(args) do { \ - if (args->task) { \ + if (args->task) { \ synctask_yield (args->task); \ } else { \ pthread_mutex_lock (&args->mutex); \ @@ -161,39 +209,127 @@ struct syncargs { #define SYNCOP(subvol, stb, cbk, op, params ...) do { \ struct synctask *task = NULL; \ - call_frame_t *frame = NULL; \ + call_frame_t *frame = NULL; \ \ task = synctask_get (); \ stb->task = task; \ - if (task) \ - frame = task->opframe; \ - else \ - frame = create_frame (THIS, THIS->ctx->pool); \ - \ - __yawn (stb); \ + if (task) \ + frame = task->opframe; \ + else \ + frame = syncop_create_frame (THIS); \ + \ + if (task) { \ + frame->root->uid = task->uid; \ + frame->root->gid = task->gid; \ + } \ + \ + __yawn (stb); \ \ - STACK_WIND_COOKIE (frame, cbk, (void *)stb, subvol, \ - op, params); \ - if (task) \ - task->state = SYNCTASK_SUSPEND; \ - \ - __yield (stb); \ - if (task) \ - STACK_RESET (frame->root); \ - else \ - STACK_DESTROY (frame->root); \ + 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 *); +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 */ @@ -228,7 +364,7 @@ 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); @@ -254,15 +390,23 @@ int syncop_fstat (xlator_t *subvol, fd_t *fd, struct iatt *stbuf); int syncop_stat (xlator_t *subvol, loc_t *loc, struct iatt *stbuf); int syncop_symlink (xlator_t *subvol, loc_t *loc, const char *newpath, - dict_t *dict); + 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); -int syncop_mkdir (xlator_t *subvol, loc_t *loc, mode_t mode, 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 bb834dbfd..e8954cc23 100644 --- a/libglusterfs/src/syscall.c +++ b/libglusterfs/src/syscall.c @@ -458,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 d5c6ce5f6..f1c9f58c3 100644 --- a/libglusterfs/src/syscall.h +++ b/libglusterfs/src/syscall.h @@ -139,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 ae40142ad..a059cc212 100644 --- a/libglusterfs/src/timer.c +++ b/libglusterfs/src/timer.c @@ -17,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) { @@ -48,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; @@ -127,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) { @@ -142,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 (®->lock); @@ -213,7 +210,7 @@ gf_timer_registry_init (glusterfs_ctx_t *ctx) reg->stale.prev = ®->stale; ctx->timer = reg; - pthread_create (®->th, NULL, gf_timer_proc, ctx); + gf_thread_create (®->th, NULL, gf_timer_proc, ctx); } out: return ctx->timer; diff --git a/libglusterfs/src/timer.h b/libglusterfs/src/timer.h index 2954f6aff..2f963adbf 100644 --- a/libglusterfs/src/timer.h +++ b/libglusterfs/src/timer.h @@ -25,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; @@ -44,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/xlator.c b/libglusterfs/src/xlator.c index 22c81f81b..a277c58a8 100644 --- a/libglusterfs/src/xlator.c +++ b/libglusterfs/src/xlator.c @@ -79,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); @@ -119,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"); @@ -146,25 +140,15 @@ 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: @@ -183,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); @@ -218,21 +202,42 @@ xlator_dynload (xlator_t *xl) goto out; } - if (!(*VOID(&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 (!(*VOID(&(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 (!(*VOID(&(xl->notify)) = dlsym (handle, "notify"))) { - gf_log ("xlator", GF_LOG_TRACE, - "dlsym(notify) on %s -- neglecting", dlerror ()); } if (!(xl->dumpops = dlsym (handle, "dumpops"))) { @@ -246,12 +251,6 @@ xlator_dynload (xlator_t *xl) dlerror ()); } - if (!(*VOID(&(xl->reconfigure)) = dlsym (handle, "reconfigure"))) { - gf_log ("xlator", GF_LOG_TRACE, - "dlsym(reconfigure) on %s -- neglecting", - dlerror()); - } - vol_opt = GF_CALLOC (1, sizeof (volume_opt_list_t), gf_common_mt_volume_opt_list_t); @@ -264,6 +263,7 @@ xlator_dynload (xlator_t *xl) 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); @@ -321,36 +321,31 @@ out: } -xlator_t * -xlator_search_by_name (xlator_t *any, const char *name) +void +xlator_foreach_depth_first (xlator_t *this, + void (*fn)(xlator_t *each, void *data), + void *data) { - xlator_t *search = NULL; + xlator_list_t *subv = NULL; - GF_VALIDATE_OR_GOTO ("xlator", any, out); - GF_VALIDATE_OR_GOTO ("xlator", name, out); - - search = any; - - while (search->prev) - search = search->prev; + subv = this->children; - while (search) { - if (!strcmp (search->name, name)) - break; - search = search->next; - } + while (subv) { + xlator_foreach_depth_first (subv->xlator, fn, data); + subv = subv->next; + } -out: - return search; + fn (this, data); } + xlator_t * -xlator_search_by_xl_type (xlator_t *any, const char *type) +xlator_search_by_name (xlator_t *any, const char *name) { xlator_t *search = NULL; GF_VALIDATE_OR_GOTO ("xlator", any, out); - GF_VALIDATE_OR_GOTO ("xlator", type, out); + GF_VALIDATE_OR_GOTO ("xlator", name, out); search = any; @@ -358,7 +353,7 @@ xlator_search_by_xl_type (xlator_t *any, const char *type) search = search->prev; while (search) { - if (!strcmp (search->type, type)) + if (!strcmp (search->name, name)) break; search = search->next; } @@ -521,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; @@ -535,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; } @@ -603,6 +624,31 @@ 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) { @@ -642,22 +688,17 @@ 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) { diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h index 1e21b63c5..b57e5873e 100644 --- a/libglusterfs/src/xlator.h +++ b/libglusterfs/src/xlator.h @@ -66,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 { @@ -417,6 +418,30 @@ typedef int32_t (*fop_fsetattr_cbk_t) (call_frame_t *frame, struct iatt *preop_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, @@ -634,6 +659,26 @@ typedef int32_t (*fop_fsetattr_t) (call_frame_t *frame, struct iatt *stbuf, 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; @@ -678,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; @@ -722,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, @@ -732,11 +783,15 @@ typedef int32_t (*cbk_release_t) (xlator_t *this, 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_invalidate_t invalidate; + 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); @@ -827,6 +882,14 @@ struct _xlator { 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 ...) \ @@ -864,8 +927,12 @@ 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); -xlator_t *xlator_search_by_xl_type (xlator_t *any, const char *type); void inode_destroy_notify (inode_t *inode, const char *xlname); @@ -873,6 +940,9 @@ 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); @@ -882,5 +952,9 @@ 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 */ |
