From 55f55db6500835e95b324a2f28144c6a3dc55c62 Mon Sep 17 00:00:00 2001 From: Shehjar Tikoo Date: Fri, 2 Oct 2009 03:07:53 +0000 Subject: core: Separate readdirp and readdir fops Signed-off-by: Anand V. Avati BUG: 292 (Separate readdirp functionality from readdir fop) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=292 --- libglusterfs/src/call-stub.c | 109 ++++++++++++++++++++++++++++++++++++++++ libglusterfs/src/call-stub.h | 27 ++++++++++ libglusterfs/src/common-utils.c | 1 + libglusterfs/src/defaults.c | 27 ++++++++++ libglusterfs/src/defaults.h | 7 ++- libglusterfs/src/glusterfs.h | 1 + libglusterfs/src/protocol.h | 12 +++++ libglusterfs/src/xlator.c | 1 + libglusterfs/src/xlator.h | 15 ++++++ 9 files changed, 199 insertions(+), 1 deletion(-) (limited to 'libglusterfs/src') diff --git a/libglusterfs/src/call-stub.c b/libglusterfs/src/call-stub.c index bc7d556c2..a56ed95f0 100644 --- a/libglusterfs/src/call-stub.c +++ b/libglusterfs/src/call-stub.c @@ -2051,6 +2051,48 @@ out: } +call_stub_t * +fop_readdirp_cbk_stub (call_frame_t *frame, + fop_readdirp_cbk_t fn, + int32_t op_ret, + int32_t op_errno, + gf_dirent_t *entries) +{ + call_stub_t *stub = NULL; + gf_dirent_t *stub_entry = NULL, *entry = NULL; + + GF_VALIDATE_OR_GOTO ("call-stub", frame, out); + + stub = stub_new (frame, 0, GF_FOP_READDIRP); + GF_VALIDATE_OR_GOTO ("call-stub", stub, out); + + stub->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); + + /* This check must come after the init of head above + * so we're sure the list is empty for list_empty. + */ + if (!entries) + goto out; + + if (op_ret > 0) { + list_for_each_entry (entry, &entries->list, list) { + stub_entry = gf_dirent_for_name (entry->d_name); + ERR_ABORT (stub_entry); + stub_entry->d_off = entry->d_off; + stub_entry->d_ino = entry->d_ino; + + list_add_tail (&stub_entry->list, + &stub->args.readdirp_cbk.entries.list); + } + } +out: + return stub; +} + + call_stub_t * fop_readdir_cbk_stub (call_frame_t *frame, fop_readdir_cbk_t fn, @@ -2109,6 +2151,25 @@ fop_readdir_stub (call_frame_t *frame, 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) +{ + call_stub_t *stub = NULL; + + stub = stub_new (frame, 1, GF_FOP_READDIRP); + stub->args.readdirp.fn = fn; + stub->args.readdirp.fd = fd_ref (fd); + stub->args.readdirp.size = size; + stub->args.readdirp.off = off; + + return stub; +} + call_stub_t * fop_checksum_stub (call_frame_t *frame, fop_checksum_t fn, @@ -2936,6 +2997,17 @@ call_resume_wind (call_stub_t *stub) stub->args.readdir.off); break; } + + case GF_FOP_READDIRP: + { + stub->args.readdirp.fn (stub->frame, + stub->frame->this, + stub->args.readdirp.fd, + stub->args.readdirp.size, + stub->args.readdirp.off); + break; + } + case GF_FOP_XATTROP: { stub->args.xattrop.fn (stub->frame, @@ -3834,6 +3906,27 @@ call_resume_unwind (call_stub_t *stub) break; } + case GF_FOP_READDIRP: + { + if (!stub->args.readdirp_cbk.fn) + STACK_UNWIND (stub->frame, + stub->args.readdirp_cbk.op_ret, + stub->args.readdirp_cbk.op_errno, + &stub->args.readdirp_cbk.entries); + else + stub->args.readdirp_cbk.fn (stub->frame, + stub->frame->cookie, + stub->frame->this, + stub->args.readdirp_cbk.op_ret, + stub->args.readdirp_cbk.op_errno, + &stub->args.readdirp_cbk.entries); + + if (stub->args.readdirp_cbk.op_ret > 0) + gf_dirent_free (&stub->args.readdirp_cbk.entries); + + break; + } + case GF_FOP_XATTROP: { if (!stub->args.xattrop_cbk.fn) @@ -4268,6 +4361,14 @@ call_stub_destroy_wind (call_stub_t *stub) fd_unref (stub->args.readdir.fd); break; } + + case GF_FOP_READDIRP: + { + if (stub->args.readdirp.fd) + fd_unref (stub->args.readdirp.fd); + break; + } + case GF_FOP_XATTROP: { loc_wipe (&stub->args.xattrop.loc); @@ -4538,6 +4639,14 @@ call_stub_destroy_unwind (call_stub_t *stub) } break; + case GF_FOP_READDIRP: + { + if (stub->args.readdirp_cbk.op_ret > 0) { + gf_dirent_free (&stub->args.readdirp_cbk.entries); + } + } + break; + case GF_FOP_XATTROP: { if (stub->args.xattrop_cbk.xattr) diff --git a/libglusterfs/src/call-stub.h b/libglusterfs/src/call-stub.h index 88e26c24f..ae414026f 100644 --- a/libglusterfs/src/call-stub.h +++ b/libglusterfs/src/call-stub.h @@ -581,6 +581,19 @@ typedef struct { 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; + /* checksum */ struct { fop_checksum_t fn; @@ -1229,6 +1242,20 @@ fop_readdir_stub (call_frame_t *frame, size_t size, off_t off); +call_stub_t * +fop_readdirp_stub (call_frame_t *frame, + fop_readdir_t fn, + fd_t *fd, + size_t size, + off_t off); + +call_stub_t * +fop_readdirp_cbk_stub (call_frame_t *frame, + fop_readdir_cbk_t fn, + int32_t op_ret, + int32_t op_errno, + gf_dirent_t *entries); + call_stub_t * fop_readdir_cbk_stub (call_frame_t *frame, fop_readdir_cbk_t fn, diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c index 49ea724b2..59ac5386e 100644 --- a/libglusterfs/src/common-utils.c +++ b/libglusterfs/src/common-utils.c @@ -219,6 +219,7 @@ gf_global_variable_init() gf_fop_list[GF_FOP_RCHECKSUM] = "RCHECKSUM"; gf_fop_list[GF_FOP_SETATTR] = "SETATTR"; gf_fop_list[GF_FOP_FSETATTR] = "FSETATTR"; + gf_fop_list[GF_FOP_READDIRP] = "READDIRP"; gf_mop_list[GF_MOP_SETVOLUME] = "SETVOLUME"; /* 0 */ gf_mop_list[GF_MOP_GETVOLUME] = "GETVOLUME"; /* 1 */ diff --git a/libglusterfs/src/defaults.c b/libglusterfs/src/defaults.c index a21630103..89c010cd3 100644 --- a/libglusterfs/src/defaults.c +++ b/libglusterfs/src/defaults.c @@ -1492,6 +1492,18 @@ default_readdir_cbk (call_frame_t *frame, } +int32_t +default_readdirp_cbk (call_frame_t *frame, + void *cookie, + xlator_t *this, + int32_t op_ret, + int32_t op_errno, + gf_dirent_t *entries) +{ + STACK_UNWIND (frame, op_ret, op_errno, entries); + return 0; +} + int32_t default_readdir (call_frame_t *frame, xlator_t *this, @@ -1508,6 +1520,21 @@ default_readdir (call_frame_t *frame, } +int32_t +default_readdirp (call_frame_t *frame, + xlator_t *this, + fd_t *fd, + size_t size, + off_t off) +{ + STACK_WIND (frame, + default_readdirp_cbk, + FIRST_CHILD(this), + FIRST_CHILD(this)->fops->readdir, + fd, size, off); + return 0; +} + int32_t default_lock_notify_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno) diff --git a/libglusterfs/src/defaults.h b/libglusterfs/src/defaults.h index 2c167d97e..6ef9cf571 100644 --- a/libglusterfs/src/defaults.h +++ b/libglusterfs/src/defaults.h @@ -260,7 +260,12 @@ int32_t default_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off); - + +int32_t default_readdirp (call_frame_t *frame, + xlator_t *this, + fd_t *fd, + size_t size, off_t off); + int32_t default_setdents (call_frame_t *frame, xlator_t *this, fd_t *fd, diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h index d1d30a492..bea33f81a 100644 --- a/libglusterfs/src/glusterfs.h +++ b/libglusterfs/src/glusterfs.h @@ -126,6 +126,7 @@ typedef enum { GF_FOP_RCHECKSUM, GF_FOP_SETATTR, GF_FOP_FSETATTR, + GF_FOP_READDIRP, GF_FOP_MAXVALUE, } glusterfs_fop_t; diff --git a/libglusterfs/src/protocol.h b/libglusterfs/src/protocol.h index 59ebaf2bc..f163d0ed4 100644 --- a/libglusterfs/src/protocol.h +++ b/libglusterfs/src/protocol.h @@ -639,6 +639,18 @@ typedef struct { } __attribute__((packed)) gf_fop_readdir_rsp_t; +typedef struct { + uint64_t ino; + int64_t fd; + uint64_t offset; + uint32_t size; +} __attribute__((packed)) gf_fop_readdirp_req_t; +typedef struct { + uint32_t size; + char buf[0]; +} __attribute__((packed)) gf_fop_readdirp_rsp_t; + + typedef struct { uint64_t ino; uint32_t mask; diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c index 90c9d5cdc..879ddd76d 100644 --- a/libglusterfs/src/xlator.c +++ b/libglusterfs/src/xlator.c @@ -82,6 +82,7 @@ fill_defaults (xlator_t *xl) SET_DEFAULT_FOP (removexattr); SET_DEFAULT_FOP (opendir); SET_DEFAULT_FOP (readdir); + SET_DEFAULT_FOP (readdirp); SET_DEFAULT_FOP (fsyncdir); SET_DEFAULT_FOP (access); SET_DEFAULT_FOP (ftruncate); diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h index a00d4975d..f71d5dea9 100644 --- a/libglusterfs/src/xlator.h +++ b/libglusterfs/src/xlator.h @@ -475,6 +475,13 @@ typedef int32_t (*fop_readdir_cbk_t) (call_frame_t *frame, int32_t op_errno, gf_dirent_t *entries); +typedef int32_t (*fop_readdirp_cbk_t) (call_frame_t *frame, + void *cookie, + xlator_t *this, + int32_t op_ret, + int32_t op_errno, + gf_dirent_t *entries); + typedef int32_t (*fop_xattrop_cbk_t) (call_frame_t *frame, void *cookie, xlator_t *this, @@ -750,6 +757,12 @@ typedef int32_t (*fop_readdir_t) (call_frame_t *frame, size_t size, off_t offset); +typedef int32_t (*fop_readdirp_t) (call_frame_t *frame, + xlator_t *this, + fd_t *fd, + size_t size, + off_t offset); + typedef int32_t (*fop_xattrop_t) (call_frame_t *frame, xlator_t *this, loc_t *loc, @@ -811,6 +824,7 @@ struct xlator_fops { fop_fsync_t fsync; fop_opendir_t opendir; fop_readdir_t readdir; + fop_readdirp_t readdirp; fop_fsyncdir_t fsyncdir; fop_statfs_t statfs; fop_setxattr_t setxattr; @@ -862,6 +876,7 @@ struct xlator_fops { fop_fsync_cbk_t fsync_cbk; fop_opendir_cbk_t opendir_cbk; fop_readdir_cbk_t readdir_cbk; + fop_readdirp_cbk_t readdirp_cbk; fop_fsyncdir_cbk_t fsyncdir_cbk; fop_statfs_cbk_t statfs_cbk; fop_setxattr_cbk_t setxattr_cbk; -- cgit