diff options
45 files changed, 585 insertions, 145 deletions
diff --git a/libglusterfs/src/call-stub.c b/libglusterfs/src/call-stub.c index 8761b40a0c6..8b28dc9bec6 100644 --- a/libglusterfs/src/call-stub.c +++ b/libglusterfs/src/call-stub.c @@ -1810,7 +1810,8 @@ fop_readdirp_stub (call_frame_t *frame, fop_readdirp_t fn, fd_t *fd, size_t size, - off_t off) + off_t off, + dict_t *dict) { call_stub_t *stub = NULL; @@ -1821,6 +1822,7 @@ fop_readdirp_stub (call_frame_t *frame, stub->args.readdirp.fd = fd_ref (fd); stub->args.readdirp.size = size; stub->args.readdirp.off = off; + stub->args.readdirp.dict = dict; out: return stub; @@ -2438,7 +2440,8 @@ call_resume_wind (call_stub_t *stub) stub->frame->this, stub->args.readdirp.fd, stub->args.readdirp.size, - stub->args.readdirp.off); + stub->args.readdirp.off, + stub->args.readdirp.dict); break; } diff --git a/libglusterfs/src/call-stub.h b/libglusterfs/src/call-stub.h index 01b6cdd1b38..4b03dbfe209 100644 --- a/libglusterfs/src/call-stub.h +++ b/libglusterfs/src/call-stub.h @@ -502,6 +502,7 @@ typedef struct { fd_t *fd; size_t size; off_t off; + dict_t *dict; } readdirp; struct { fop_readdirp_cbk_t fn; @@ -1022,10 +1023,11 @@ fop_readdir_stub (call_frame_t *frame, call_stub_t * fop_readdirp_stub (call_frame_t *frame, - fop_readdir_t fn, + fop_readdirp_t fn, fd_t *fd, size_t size, - off_t off); + off_t off, + dict_t *dict); call_stub_t * fop_readdirp_cbk_stub (call_frame_t *frame, diff --git a/libglusterfs/src/defaults.c b/libglusterfs/src/defaults.c index 392819ca9d1..828f266b38e 100644 --- a/libglusterfs/src/defaults.c +++ b/libglusterfs/src/defaults.c @@ -750,10 +750,10 @@ default_readdir_resume (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t default_readdirp_resume (call_frame_t *frame, xlator_t *this, fd_t *fd, - size_t size, off_t off) + size_t size, off_t off, dict_t *dict) { STACK_WIND (frame, default_readdirp_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->readdirp, fd, size, off); + FIRST_CHILD(this)->fops->readdirp, fd, size, off, dict); return 0; } @@ -1117,10 +1117,10 @@ default_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t default_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, - size_t size, off_t off) + size_t size, off_t off, dict_t *dict) { STACK_WIND (frame, default_readdirp_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->readdirp, fd, size, off); + FIRST_CHILD(this)->fops->readdirp, fd, size, off, dict); return 0; } diff --git a/libglusterfs/src/defaults.h b/libglusterfs/src/defaults.h index a312901a779..fe04cbf9205 100644 --- a/libglusterfs/src/defaults.h +++ b/libglusterfs/src/defaults.h @@ -206,7 +206,7 @@ int32_t 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); + size_t size, off_t off, dict_t *dict); int32_t default_xattrop (call_frame_t *frame, xlator_t *this, @@ -418,9 +418,9 @@ int32_t default_readdir_resume (call_frame_t *frame, size_t size, off_t off); int32_t default_readdirp_resume (call_frame_t *frame, - xlator_t *this, - fd_t *fd, - size_t size, off_t off); + xlator_t *this, + fd_t *fd, + size_t size, off_t off, dict_t *dict); int32_t default_xattrop_resume (call_frame_t *frame, xlator_t *this, diff --git a/libglusterfs/src/gf-dirent.c b/libglusterfs/src/gf-dirent.c index 4c85db3f3cf..8d15b040553 100644 --- a/libglusterfs/src/gf-dirent.c +++ b/libglusterfs/src/gf-dirent.c @@ -31,26 +31,6 @@ #include "xlator.h" gf_dirent_t * -gf_dirent_for_namelen (int len) -{ - gf_dirent_t *gf_dirent = NULL; - - /* TODO: use mem-pool */ - gf_dirent = CALLOC (len, sizeof(char)); - if (!gf_dirent) - return NULL; - - INIT_LIST_HEAD (&gf_dirent->list); - - gf_dirent->d_off = 0; - gf_dirent->d_ino = -1; - gf_dirent->d_type = 0; - - return gf_dirent; -} - - -gf_dirent_t * gf_dirent_for_name (const char *name) { gf_dirent_t *gf_dirent = NULL; @@ -86,7 +66,36 @@ gf_dirent_free (gf_dirent_t *entries) return; list_for_each_entry_safe (entry, tmp, &entries->list, list) { + if (entry->dict) + dict_unref (entry->dict); + if (entry->inode) + inode_unref (entry->inode); + list_del (&entry->list); GF_FREE (entry); } } + +/* TODO: Currently, with this function, we will be breaking the + policy of 1-1 mapping of kernel nlookup refs with our inode_t's + nlookup count. + Need more thoughts before finalizing this function +*/ +int +gf_link_inodes_from_dirent (xlator_t *this, inode_t *parent, + gf_dirent_t *entries) +{ + gf_dirent_t *entry = NULL; + inode_t *link_inode = NULL; + + list_for_each_entry (entry, &entries->list, list) { + if (entry->inode) { + link_inode = inode_link (entry->inode, parent, + entry->d_name, &entry->d_stat); + inode_lookup (link_inode); + inode_unref (link_inode); + } + } + + return 0; +} diff --git a/libglusterfs/src/gf-dirent.h b/libglusterfs/src/gf-dirent.h index db1dac83566..29b4aba8036 100644 --- a/libglusterfs/src/gf-dirent.h +++ b/libglusterfs/src/gf-dirent.h @@ -27,6 +27,7 @@ #endif #include "iatt.h" +#include "inode.h" #define gf_dirent_size(name) (sizeof (gf_dirent_t) + strlen (name) + 1) @@ -51,12 +52,15 @@ struct _gf_dirent_t { uint32_t d_len; uint32_t d_type; struct iatt d_stat; + dict_t *dict; + inode_t *inode; char d_name[0]; }; gf_dirent_t *gf_dirent_for_name (const char *name); void gf_dirent_free (gf_dirent_t *entries); -gf_dirent_t * gf_dirent_for_namelen (int len); +int gf_link_inodes_from_dirent (xlator_t *this, inode_t *parent, + gf_dirent_t *entries); #endif /* _GF_DIRENT_H */ diff --git a/libglusterfs/src/syncop.c b/libglusterfs/src/syncop.c index 99956bfb7ee..2771bdea5b6 100644 --- a/libglusterfs/src/syncop.c +++ b/libglusterfs/src/syncop.c @@ -394,12 +394,13 @@ syncop_readdirp (xlator_t *subvol, fd_t *fd, size_t size, off_t off, + dict_t *dict, gf_dirent_t *entries) { struct syncargs args = {0, }; SYNCOP (subvol, (&args), syncop_readdirp_cbk, subvol->fops->readdirp, - fd, size, off); + fd, size, off, dict); if (entries) list_splice_init (&args.entries.list, &entries->list); diff --git a/libglusterfs/src/syncop.h b/libglusterfs/src/syncop.h index 9d9c5a9ccf7..b4cdafd535c 100644 --- a/libglusterfs/src/syncop.h +++ b/libglusterfs/src/syncop.h @@ -165,6 +165,7 @@ int syncop_lookup (xlator_t *subvol, loc_t *loc, dict_t *xattr_req, struct iatt *iatt, dict_t **xattr_rsp, struct iatt *parent); int syncop_readdirp (xlator_t *subvol, fd_t *fd, size_t size, off_t off, + dict_t *dict, /* out */ gf_dirent_t *entries); diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h index c86e8718cac..fab3b4468d8 100644 --- a/libglusterfs/src/xlator.h +++ b/libglusterfs/src/xlator.h @@ -606,7 +606,8 @@ typedef int32_t (*fop_readdirp_t) (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, - off_t offset); + off_t offset, + dict_t *dict); typedef int32_t (*fop_xattrop_t) (call_frame_t *frame, xlator_t *this, diff --git a/rpc/xdr/src/glusterfs3-xdr.c b/rpc/xdr/src/glusterfs3-xdr.c index 62cff241d77..fc3237872b5 100644 --- a/rpc/xdr/src/glusterfs3-xdr.c +++ b/rpc/xdr/src/glusterfs3-xdr.c @@ -1137,6 +1137,8 @@ xdr_gfs3_readdirp_req (XDR *xdrs, gfs3_readdirp_req *objp) return FALSE; if (!xdr_u_int (xdrs, &objp->size)) return FALSE; + if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0)) + return FALSE; return TRUE; } @@ -1667,6 +1669,8 @@ xdr_gfs3_dirplist (XDR *xdrs, gfs3_dirplist *objp) return FALSE; if (!xdr_gf_iatt (xdrs, &objp->stat)) return FALSE; + if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0)) + return FALSE; if (!xdr_pointer (xdrs, (char **)&objp->nextentry, sizeof (gfs3_dirplist), (xdrproc_t) xdr_gfs3_dirplist)) return FALSE; return TRUE; diff --git a/rpc/xdr/src/glusterfs3-xdr.h b/rpc/xdr/src/glusterfs3-xdr.h index d9cf7926f96..4955b423e13 100644 --- a/rpc/xdr/src/glusterfs3-xdr.h +++ b/rpc/xdr/src/glusterfs3-xdr.h @@ -550,6 +550,10 @@ struct gfs3_readdirp_req { quad_t fd; u_quad_t offset; u_int size; + struct { + u_int dict_len; + char *dict_val; + } dict; }; typedef struct gfs3_readdirp_req gfs3_readdirp_req; @@ -777,6 +781,10 @@ struct gfs3_dirplist { u_int d_type; char *name; struct gf_iatt stat; + struct { + u_int dict_len; + char *dict_val; + } dict; struct gfs3_dirplist *nextentry; }; typedef struct gfs3_dirplist gfs3_dirplist; diff --git a/rpc/xdr/src/glusterfs3-xdr.x b/rpc/xdr/src/glusterfs3-xdr.x index 131feff1bab..69dc7068240 100644 --- a/rpc/xdr/src/glusterfs3-xdr.x +++ b/rpc/xdr/src/glusterfs3-xdr.x @@ -419,6 +419,7 @@ struct gfs3_finodelk_req { hyper fd; unsigned hyper offset; unsigned int size; + opaque dict<>; } ; @@ -605,6 +606,7 @@ struct gfs3_dirplist { unsigned int d_type; string name<>; struct gf_iatt stat; + opaque dict<>; struct gfs3_dirplist *nextentry; }; diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index 83b91cd3ed1..c9a8b59554a 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -957,6 +957,11 @@ afr_local_cleanup (afr_local_t *local, xlator_t *this) if (local->cont.opendir.checksum) GF_FREE (local->cont.opendir.checksum); } + + { /* readdirp */ + if (local->cont.readdir.dict) + dict_unref (local->cont.readdir.dict); + } } diff --git a/xlators/cluster/afr/src/afr-dir-read.c b/xlators/cluster/afr/src/afr-dir-read.c index d41102e7eea..389515e3c36 100644 --- a/xlators/cluster/afr/src/afr-dir-read.c +++ b/xlators/cluster/afr/src/afr-dir-read.c @@ -570,7 +570,8 @@ afr_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, children[next_call_child], children[next_call_child]->fops->readdirp, local->fd, - local->cont.readdir.size, 0); + local->cont.readdir.size, 0, + local->cont.readdir.dict); return 0; } } @@ -612,7 +613,8 @@ afr_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, (void *) (long) read_child, children[call_child], children[call_child]->fops->readdirp, - local->fd, local->cont.readdir.size, offset); + local->fd, local->cont.readdir.size, offset, + local->cont.readdir.dict); return 0; } } else { @@ -628,7 +630,7 @@ out: int32_t afr_do_readdir (call_frame_t *frame, xlator_t *this, - fd_t *fd, size_t size, off_t offset, int whichop) + fd_t *fd, size_t size, off_t offset, int whichop, dict_t *dict) { afr_private_t * priv = NULL; xlator_t ** children = NULL; @@ -673,6 +675,7 @@ afr_do_readdir (call_frame_t *frame, xlator_t *this, local->fd = fd_ref (fd); local->cont.readdir.size = size; + local->cont.readdir.dict = (dict)? dict_ref (dict) : NULL; if (priv->strict_readdir) { ret = fd_ctx_get (fd, this, &ctx); @@ -709,7 +712,7 @@ afr_do_readdir (call_frame_t *frame, xlator_t *this, (void *) (long) call_child, children[call_child], children[call_child]->fops->readdirp, fd, - size, offset); + size, offset, dict); ret = 0; out: @@ -723,16 +726,16 @@ int32_t afr_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset) { - afr_do_readdir (frame, this, fd, size, offset, GF_FOP_READDIR); + afr_do_readdir (frame, this, fd, size, offset, GF_FOP_READDIR, NULL); return 0; } int32_t afr_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, - off_t offset) + off_t offset, dict_t *dict) { - afr_do_readdir (frame, this, fd, size, offset, GF_FOP_READDIRP); + afr_do_readdir (frame, this, fd, size, offset, GF_FOP_READDIRP, dict); return 0; } diff --git a/xlators/cluster/afr/src/afr-dir-read.h b/xlators/cluster/afr/src/afr-dir-read.h index 6a6bc635414..7e50a1c8cc8 100644 --- a/xlators/cluster/afr/src/afr-dir-read.h +++ b/xlators/cluster/afr/src/afr-dir-read.h @@ -35,7 +35,7 @@ afr_readdir (call_frame_t *frame, xlator_t *this, int32_t afr_readdirp (call_frame_t *frame, xlator_t *this, - fd_t *fd, size_t size, off_t offset); + fd_t *fd, size_t size, off_t offset, dict_t *dict); int32_t afr_checksum (call_frame_t *frame, xlator_t *this, diff --git a/xlators/cluster/afr/src/afr-self-heal-entry.c b/xlators/cluster/afr/src/afr-self-heal-entry.c index ba29656e2cd..ed1c51a2172 100644 --- a/xlators/cluster/afr/src/afr-self-heal-entry.c +++ b/xlators/cluster/afr/src/afr-self-heal-entry.c @@ -832,7 +832,7 @@ afr_sh_entry_expunge_subvol (call_frame_t *frame, xlator_t *this, STACK_WIND (frame, afr_sh_entry_expunge_readdir_cbk, priv->children[active_src], priv->children[active_src]->fops->readdirp, - sh->healing_fd, sh->block_size, sh->offset); + sh->healing_fd, sh->block_size, sh->offset, NULL); return 0; } @@ -1889,7 +1889,7 @@ afr_sh_entry_impunge_subvol (call_frame_t *frame, xlator_t *this, STACK_WIND (frame, afr_sh_entry_impunge_readdir_cbk, priv->children[active_src], priv->children[active_src]->fops->readdirp, - sh->healing_fd, sh->block_size, sh->offset); + sh->healing_fd, sh->block_size, sh->offset, 0); return 0; } diff --git a/xlators/cluster/afr/src/afr-self-heald.c b/xlators/cluster/afr/src/afr-self-heald.c index f360ec33df8..186d7dd26a5 100644 --- a/xlators/cluster/afr/src/afr-self-heald.c +++ b/xlators/cluster/afr/src/afr-self-heald.c @@ -177,7 +177,7 @@ _crawl_directory (loc_t *loc, pid_t pid) goto out; } - while (syncop_readdirp (this, fd, 131072, offset, &entries)) { + while (syncop_readdirp (this, fd, 131072, offset, NULL, &entries)) { ret = 0; free_entries = _gf_true; if (afr_up_children_count (priv->child_up, diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h index 0ff3000857c..889828a6fa6 100644 --- a/xlators/cluster/afr/src/afr.h +++ b/xlators/cluster/afr/src/afr.h @@ -495,7 +495,7 @@ typedef struct _afr_local { int32_t op_errno; size_t size; off_t offset; - + dict_t *dict; gf_boolean_t failed; int last_index; } readdir; diff --git a/xlators/cluster/afr/src/pump.c b/xlators/cluster/afr/src/pump.c index 73389009d68..357aa9f295f 100644 --- a/xlators/cluster/afr/src/pump.c +++ b/xlators/cluster/afr/src/pump.c @@ -362,7 +362,7 @@ gf_pump_traverse_directory (loc_t *loc) "pump opendir on %s returned=%d", loc->path, ret); - while (syncop_readdirp (this, fd, 131072, offset, &entries)) { + while (syncop_readdirp (this, fd, 131072, offset, NULL, &entries)) { free_entries = _gf_true; if (list_empty (&entries.list)) { @@ -2195,11 +2195,8 @@ pump_readdir (call_frame_t *frame, static int32_t -pump_readdirp (call_frame_t *frame, - xlator_t *this, - fd_t *fd, - size_t size, - off_t off) +pump_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, + size_t size, off_t off, dict_t *dict) { afr_private_t *priv = NULL; priv = this->private; @@ -2208,10 +2205,10 @@ pump_readdirp (call_frame_t *frame, default_readdirp_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, - fd, size, off); + fd, size, off, dict); return 0; } - afr_readdirp (frame, this, fd, size, off); + afr_readdirp (frame, this, fd, size, off, dict); return 0; } diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index d371fc442da..a16ed7b6c50 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -2616,7 +2616,8 @@ done: STACK_WIND (frame, dht_readdirp_cbk, next_subvol, next_subvol->fops->readdirp, - local->fd, local->size, next_offset); + local->fd, local->size, next_offset, + local->xattr_req); return 0; } @@ -2730,7 +2731,7 @@ unwind: int dht_do_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, - off_t yoff, int whichop) + off_t yoff, int whichop, dict_t *dict) { dht_local_t *local = NULL; int op_errno = -1; @@ -2750,6 +2751,7 @@ dht_do_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, local->fd = fd_ref (fd); local->size = size; + local->xattr_req = (dict)? dict_ref (dict) : NULL; dht_deitransform (this, yoff, &xvol, (uint64_t *)&xoff); @@ -2759,7 +2761,7 @@ dht_do_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, fd, size, xoff); else STACK_WIND (frame, dht_readdirp_cbk, xvol, xvol->fops->readdirp, - fd, size, xoff); + fd, size, xoff, dict); return 0; @@ -2794,15 +2796,15 @@ dht_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, op = GF_FOP_READDIRP; out: - dht_do_readdir (frame, this, fd, size, yoff, op); + dht_do_readdir (frame, this, fd, size, yoff, op, 0); return 0; } int dht_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, - off_t yoff) + off_t yoff, dict_t *dict) { - dht_do_readdir (frame, this, fd, size, yoff, GF_FOP_READDIRP); + dht_do_readdir (frame, this, fd, size, yoff, GF_FOP_READDIRP, dict); return 0; } @@ -3988,7 +3990,7 @@ dht_rmdir_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, STACK_WIND (frame, dht_rmdir_readdirp_cbk, prev->this, prev->this->fops->readdirp, - local->fd, 4096, 0); + local->fd, 4096, 0, NULL); return 0; diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h index 791cf633507..8a0765b63f9 100644 --- a/xlators/cluster/dht/src/dht-common.h +++ b/xlators/cluster/dht/src/dht-common.h @@ -555,7 +555,7 @@ int32_t dht_readdir (call_frame_t *frame, int32_t dht_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, - size_t size, off_t off); + size_t size, off_t off, dict_t *dict); int32_t dht_xattrop (call_frame_t *frame, xlator_t *this, diff --git a/xlators/cluster/stripe/src/stripe.c b/xlators/cluster/stripe/src/stripe.c index 15cfb8f60e9..086f07f92ca 100644 --- a/xlators/cluster/stripe/src/stripe.c +++ b/xlators/cluster/stripe/src/stripe.c @@ -3563,6 +3563,7 @@ stripe_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this, stripe_local_t *local = NULL; struct iovec *final_vec = NULL; struct iatt tmp_stbuf = {0,}; + struct iatt *tmp_stbuf_p = NULL; //need it for a warning struct iobref *tmp_iobref = NULL; stripe_fd_ctx_t *fctx = NULL; @@ -3660,7 +3661,8 @@ stripe_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this, GF_FREE (mlocal->replies); tmp_iobref = mlocal->iobref; /* work around for nfs truncated read. Bug 3774 */ - WIPE (&tmp_stbuf); + tmp_stbuf_p = &tmp_stbuf; + WIPE (tmp_stbuf_p); STRIPE_STACK_UNWIND (readv, mframe, op_ret, op_errno, final_vec, final_count, &tmp_stbuf, tmp_iobref); @@ -4348,7 +4350,7 @@ out: } int32_t stripe_readdirp (call_frame_t *frame, xlator_t *this, - fd_t *fd, size_t size, off_t off) + fd_t *fd, size_t size, off_t off, dict_t *dict) { stripe_local_t *local = NULL; stripe_private_t *priv = NULL; @@ -4390,7 +4392,7 @@ stripe_readdirp (call_frame_t *frame, xlator_t *this, goto err; STACK_WIND (frame, stripe_readdirp_cbk, trav->xlator, - trav->xlator->fops->readdirp, fd, size, off); + trav->xlator->fops->readdirp, fd, size, off, dict); return 0; err: op_errno = (op_errno == -1) ? errno : op_errno; diff --git a/xlators/debug/error-gen/src/error-gen.c b/xlators/debug/error-gen/src/error-gen.c index 909dc681ebe..7e776332f09 100644 --- a/xlators/debug/error-gen/src/error-gen.c +++ b/xlators/debug/error-gen/src/error-gen.c @@ -1807,7 +1807,7 @@ error_gen_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int error_gen_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, - off_t off) + off_t off, dict_t *dict) { int op_errno = 0; eg_t *egp = NULL; @@ -1828,7 +1828,7 @@ error_gen_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, STACK_WIND (frame, error_gen_readdirp_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, - fd, size, off); + fd, size, off, dict); return 0; } diff --git a/xlators/debug/io-stats/src/io-stats.c b/xlators/debug/io-stats/src/io-stats.c index d216cc549ec..923470b8757 100644 --- a/xlators/debug/io-stats/src/io-stats.c +++ b/xlators/debug/io-stats/src/io-stats.c @@ -2220,7 +2220,7 @@ io_stats_opendir (call_frame_t *frame, xlator_t *this, int io_stats_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, - off_t offset) + off_t offset, dict_t *dict) { frame->local = fd->inode; START_FOP_LATENCY (frame); @@ -2228,7 +2228,7 @@ io_stats_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, STACK_WIND (frame, io_stats_readdirp_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, - fd, size, offset); + fd, size, offset, dict); return 0; } diff --git a/xlators/debug/trace/src/trace.c b/xlators/debug/trace/src/trace.c index 88e413c1d71..91d069fd1eb 100644 --- a/xlators/debug/trace/src/trace.c +++ b/xlators/debug/trace/src/trace.c @@ -1986,20 +1986,21 @@ trace_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd) int trace_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, - off_t offset) + off_t offset, dict_t *dict) { if (trace_fop_names[GF_FOP_READDIRP].enabled) { gf_log (this->name, GF_LOG_INFO, - "%"PRId64": gfid=%s fd=%p, size=%"GF_PRI_SIZET", offset=%"PRId64, + "%"PRId64": gfid=%s fd=%p, size=%"GF_PRI_SIZET", " + "offset=%"PRId64" dict=%p", frame->root->unique, uuid_utoa (fd->inode->gfid), - fd, size, offset); + fd, size, offset, dict); frame->local = fd->inode->gfid; } STACK_WIND (frame, trace_readdirp_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, - fd, size, offset); + fd, size, offset, dict); return 0; } diff --git a/xlators/features/locks/src/posix.c b/xlators/features/locks/src/posix.c index 0914d16df41..9025feb950a 100644 --- a/xlators/features/locks/src/posix.c +++ b/xlators/features/locks/src/posix.c @@ -1496,6 +1496,67 @@ out: return 0; } +int +pl_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int op_ret, int op_errno, gf_dirent_t *entries) +{ + pl_local_t *local = NULL; + gf_dirent_t *entry = NULL; + + local = frame->local; + + if (op_ret <= 0) + goto unwind; + + list_for_each_entry (entry, &entries->list, list) { + if (local->entrylk_count_req) + pl_entrylk_xattr_fill (this, entry->inode, entry->dict); + if (local->inodelk_count_req) + pl_inodelk_xattr_fill (this, entry->inode, entry->dict); + if (local->posixlk_count_req) + pl_posixlk_xattr_fill (this, entry->inode, entry->dict); + } + +unwind: + frame->local = NULL; + STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries); + + if (local) + GF_FREE (local); + + return 0; +} + +int +pl_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t offset, dict_t *dict) +{ + pl_local_t *local = NULL; + + local = GF_CALLOC (1, sizeof (*local), gf_locks_mt_pl_local_t); + GF_VALIDATE_OR_GOTO (this->name, local, out); + + if (dict) { + if (dict_get (dict, GLUSTERFS_ENTRYLK_COUNT)) + local->entrylk_count_req = 1; + if (dict_get (dict, GLUSTERFS_INODELK_COUNT)) + local->inodelk_count_req = 1; + if (dict_get (dict, GLUSTERFS_POSIXLK_COUNT)) + local->posixlk_count_req = 1; + } + + frame->local = local; + + STACK_WIND (frame, pl_readdirp_cbk, + FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, + fd, size, offset, dict); + + return 0; +out: + STACK_UNWIND_STRICT (readdirp, frame, -1, ENOMEM, NULL); + return 0; +} + void pl_dump_lock (char *str, int size, struct gf_flock *flock, @@ -1920,6 +1981,8 @@ struct xlator_fops fops = { .fentrylk = pl_fentrylk, .flush = pl_flush, .opendir = pl_opendir, + + .readdirp = pl_readdirp, }; struct xlator_dumpops dumpops = { diff --git a/xlators/features/marker/src/marker-quota.c b/xlators/features/marker/src/marker-quota.c index 227c4951b35..6f324aca361 100644 --- a/xlators/features/marker/src/marker-quota.c +++ b/xlators/features/marker/src/marker-quota.c @@ -2129,9 +2129,11 @@ mq_req_xattr (xlator_t *this, int32_t ret = -1; GF_VALIDATE_OR_GOTO ("marker", this, out); - GF_VALIDATE_OR_GOTO ("marker", loc, out); GF_VALIDATE_OR_GOTO ("marker", dict, out); + if (!loc) + goto set_size; + //if not "/" then request contribution if (strcmp (loc->path, "/") == 0) goto set_size; diff --git a/xlators/features/marker/src/marker.c b/xlators/features/marker/src/marker.c index 93b1518cb7e..291e24bdc6b 100644 --- a/xlators/features/marker/src/marker.c +++ b/xlators/features/marker/src/marker.c @@ -2188,6 +2188,47 @@ err: return 0; } +int +marker_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int op_ret, int op_errno, gf_dirent_t *entries) +{ + gf_dirent_t *entry = NULL; + + if (op_ret <= 0) + goto unwind; + + list_for_each_entry (entry, &entries->list, list) { + /* TODO: fill things */ + } + +unwind: + STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries); + + return 0; +} +int +marker_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t offset, dict_t *dict) +{ + marker_conf_t *priv = NULL; + + priv = this->private; + + if (priv->feature_enabled == 0) + goto wind; + + if ((priv->feature_enabled & GF_QUOTA) && dict) + mq_req_xattr (this, NULL, dict); + +wind: + STACK_WIND (frame, marker_readdirp_cbk, + FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, + fd, size, offset, dict); + + return 0; +} + + int32_t mem_acct_init (xlator_t *this) { @@ -2479,7 +2520,8 @@ struct xlator_fops fops = { .setattr = marker_setattr, .fsetattr = marker_fsetattr, .removexattr = marker_removexattr, - .getxattr = marker_getxattr + .getxattr = marker_getxattr, + .readdirp = marker_readdirp, }; struct xlator_cbks cbks = { diff --git a/xlators/features/quiesce/src/quiesce.c b/xlators/features/quiesce/src/quiesce.c index 84df12a31ff..57b2cdeacb0 100644 --- a/xlators/features/quiesce/src/quiesce.c +++ b/xlators/features/quiesce/src/quiesce.c @@ -661,7 +661,8 @@ quiesce_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if ((op_ret == -1) && (op_errno == ENOTCONN)) { /* Re-transmit (by putting in the queue) */ stub = fop_readdirp_stub (frame, default_readdirp_resume, - local->fd, local->size, local->offset); + local->fd, local->size, local->offset, + local->dict); if (!stub) { STACK_UNWIND_STRICT (readdirp, frame, -1, ENOMEM, NULL); @@ -2257,7 +2258,7 @@ quiesce_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, - off_t off) + off_t off, dict_t *dict) { quiesce_priv_t *priv = NULL; call_stub_t *stub = NULL; @@ -2270,17 +2271,19 @@ quiesce_readdirp (call_frame_t *frame, local->fd = fd_ref (fd); local->size = size; local->offset = off; + local->dict = dict_ref (dict); frame->local = local; STACK_WIND (frame, quiesce_readdirp_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, - fd, size, off); + fd, size, off, dict); return 0; } - stub = fop_readdirp_stub (frame, default_readdirp_resume, fd, size, off); + stub = fop_readdirp_stub (frame, default_readdirp_resume, fd, size, + off, dict); if (!stub) { STACK_UNWIND_STRICT (readdirp, frame, -1, ENOMEM, NULL); return 0; diff --git a/xlators/features/quota/src/quota.c b/xlators/features/quota/src/quota.c index b2f53048f84..79172999ac7 100644 --- a/xlators/features/quota/src/quota.c +++ b/xlators/features/quota/src/quota.c @@ -2815,6 +2815,47 @@ quota_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc) } +int +quota_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int op_ret, int op_errno, gf_dirent_t *entries) +{ + gf_dirent_t *entry = NULL; + + if (op_ret <= 0) + goto unwind; + + list_for_each_entry (entry, &entries->list, list) { + /* TODO: fill things */ + } + +unwind: + STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries); + + return 0; +} +int +quota_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t offset, dict_t *dict) +{ + int ret = 0; + + if (dict) { + ret = dict_set_uint64 (dict, QUOTA_SIZE_KEY, 0); + if (ret < 0) { + goto err; + } + } + + STACK_WIND (frame, quota_readdirp_cbk, + FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, + fd, size, offset, dict); + return 0; +err: + STACK_UNWIND_STRICT (readdirp, frame, -1, EINVAL, NULL); + return 0; +} + + int32_t mem_acct_init (xlator_t *this) { @@ -3020,7 +3061,8 @@ struct xlator_fops fops = { .fsetattr = quota_fsetattr, .mknod = quota_mknod, .setxattr = quota_setxattr, - .fsetxattr = quota_fsetxattr + .fsetxattr = quota_fsetxattr, + .readdirp = quota_readdirp, }; struct xlator_cbks cbks = { diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index 7409488c1f9..4aee4963761 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -2385,6 +2385,9 @@ fuse_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, send_fuse_data (this, finh, buf, size); + /* TODO: */ + /* gf_link_inodes_from_dirent (this, state->fd->inode, entries); */ + out: free_fuse_state (state); STACK_DESTROY (frame->root); diff --git a/xlators/nfs/server/src/nfs-fops.c b/xlators/nfs/server/src/nfs-fops.c index c6199d129eb..5c4ce2f96f4 100644 --- a/xlators/nfs/server/src/nfs-fops.c +++ b/xlators/nfs/server/src/nfs-fops.c @@ -610,7 +610,7 @@ nfs_fop_readdirp (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *dirfd, nfs_fop_handle_local_init (frame, nfsx, nfl, cbk, local, ret, err); STACK_WIND_COOKIE (frame, nfs_fop_readdirp_cbk, xl, xl, - xl->fops->readdirp, dirfd, bufsize, offset); + xl->fops->readdirp, dirfd, bufsize, offset, 0); ret = 0; err: diff --git a/xlators/performance/io-cache/src/io-cache.c b/xlators/performance/io-cache/src/io-cache.c index 009e7cf28e1..65df006cfe4 100644 --- a/xlators/performance/io-cache/src/io-cache.c +++ b/xlators/performance/io-cache/src/io-cache.c @@ -1409,6 +1409,35 @@ ioc_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, return 0; } +int +ioc_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int op_ret, int op_errno, gf_dirent_t *entries) +{ + gf_dirent_t *entry = NULL; + + if (op_ret <= 0) + goto unwind; + + list_for_each_entry (entry, &entries->list, list) { + /* TODO: fill things */ + } + +unwind: + STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries); + + return 0; +} +int +ioc_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t offset, dict_t *dict) +{ + STACK_WIND (frame, ioc_readdirp_cbk, + FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, + fd, size, offset, dict); + + return 0; +} + int32_t ioc_get_priority_list (const char *opt_str, struct list_head *first) { @@ -1924,7 +1953,9 @@ struct xlator_fops fops = { .lookup = ioc_lookup, .lk = ioc_lk, .setattr = ioc_setattr, - .mknod = ioc_mknod + .mknod = ioc_mknod, + + .readdirp = ioc_readdirp, }; diff --git a/xlators/performance/io-threads/src/io-threads.c b/xlators/performance/io-threads/src/io-threads.c index d6d0ada23e4..e4077478182 100644 --- a/xlators/performance/io-threads/src/io-threads.c +++ b/xlators/performance/io-threads/src/io-threads.c @@ -1840,23 +1840,23 @@ iot_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int iot_readdirp_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd, - size_t size, off_t offset) + size_t size, off_t offset, dict_t *dict) { STACK_WIND (frame, iot_readdirp_cbk, FIRST_CHILD (this), - FIRST_CHILD (this)->fops->readdirp, fd, size, offset); + FIRST_CHILD (this)->fops->readdirp, fd, size, offset, dict); return 0; } int iot_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, - off_t offset) + off_t offset, dict_t *dict) { call_stub_t *stub = NULL; int ret = -1; stub = fop_readdirp_stub (frame, iot_readdirp_wrapper, fd, size, - offset); + offset, dict); if (!stub) { gf_log (this->private, GF_LOG_ERROR,"cannot get readdir stub" "(out of memory)"); diff --git a/xlators/performance/stat-prefetch/src/stat-prefetch.c b/xlators/performance/stat-prefetch/src/stat-prefetch.c index 73cc3a955d8..827a9f99d28 100644 --- a/xlators/performance/stat-prefetch/src/stat-prefetch.c +++ b/xlators/performance/stat-prefetch/src/stat-prefetch.c @@ -1351,8 +1351,8 @@ out: int32_t -sp_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, - off_t off) +sp_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t off, dict_t *dict) { sp_cache_t *cache = NULL; sp_local_t *local = NULL; @@ -1401,7 +1401,7 @@ sp_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, } STACK_WIND (frame, sp_readdir_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->readdirp, fd, size, off); + FIRST_CHILD(this)->fops->readdirp, fd, size, off, dict); return 0; @@ -1414,6 +1414,12 @@ unwind: return 0; } +int32_t +sp_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t off) +{ + return sp_readdirp (frame, this, fd, size, off, NULL); +} int32_t sp_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, @@ -4215,7 +4221,7 @@ out: struct xlator_fops fops = { .lookup = sp_lookup, .readdir = sp_readdir, - .readdirp = sp_readdir, + .readdirp = sp_readdirp, .open = sp_open, .create = sp_create, .opendir = sp_opendir, diff --git a/xlators/protocol/client/src/client-helpers.c b/xlators/protocol/client/src/client-helpers.c index 2a12573e2bb..5759f30624e 100644 --- a/xlators/protocol/client/src/client-helpers.c +++ b/xlators/protocol/client/src/client-helpers.c @@ -154,15 +154,21 @@ out: } int -unserialize_rsp_direntp (struct gfs3_readdirp_rsp *rsp, gf_dirent_t *entries) +unserialize_rsp_direntp (xlator_t *this, fd_t *fd, + struct gfs3_readdirp_rsp *rsp, gf_dirent_t *entries) { struct gfs3_dirplist *trav = NULL; + char *buf = NULL; gf_dirent_t *entry = NULL; + inode_table_t *itable = NULL; int entry_len = 0; int ret = -1; trav = rsp->reply; + if (fd) + itable = fd->inode->table; + while (trav) { entry_len = gf_dirent_size (trav->name); entry = GF_CALLOC (1, entry_len, gf_common_mt_gf_dirent_t); @@ -178,6 +184,28 @@ unserialize_rsp_direntp (struct gfs3_readdirp_rsp *rsp, gf_dirent_t *entries) strcpy (entry->d_name, trav->name); + if (trav->dict.dict_val) { + /* Dictionary is sent along with response */ + buf = memdup (trav->dict.dict_val, trav->dict.dict_len); + if (!buf) + goto out; + + ret = dict_unserialize (buf, trav->dict.dict_len, + &entry->dict); + if (ret < 0) { + gf_log (THIS->name, GF_LOG_WARNING, + "failed to unserialize xattr dict"); + errno = EINVAL; + goto out; + } + entry->dict->extra_free = buf; + buf = NULL; + } + + entry->inode = inode_find (itable, entry->d_stat.ia_gfid); + if (!entry->inode) + entry->inode = inode_new (itable); + list_add_tail (&entry->list, &entries->list); trav = trav->nextentry; diff --git a/xlators/protocol/client/src/client.c b/xlators/protocol/client/src/client.c index 87a4603c191..8e823bec4e8 100644 --- a/xlators/protocol/client/src/client.c +++ b/xlators/protocol/client/src/client.c @@ -1671,7 +1671,7 @@ out: int32_t client_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, - size_t size, off_t off) + size_t size, off_t off, dict_t *dict) { int ret = -1; clnt_conf_t *conf = NULL; @@ -1685,6 +1685,7 @@ client_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, args.fd = fd; args.size = size; args.offset = off; + args.xattr_req = dict; proc = &conf->fops->proctable[GF_FOP_READDIRP]; if (!proc) { diff --git a/xlators/protocol/client/src/client.h b/xlators/protocol/client/src/client.h index 6d0b6491a10..00b743a3c70 100644 --- a/xlators/protocol/client/src/client.h +++ b/xlators/protocol/client/src/client.h @@ -184,7 +184,8 @@ int protocol_client_reopendir (xlator_t *this, clnt_fd_ctx_t *fdctx); int protocol_client_reopen (xlator_t *this, clnt_fd_ctx_t *fdctx); int unserialize_rsp_dirent (struct gfs3_readdir_rsp *rsp, gf_dirent_t *entries); -int unserialize_rsp_direntp (struct gfs3_readdirp_rsp *rsp, gf_dirent_t *entries); +int unserialize_rsp_direntp (xlator_t *this, fd_t *fd, + struct gfs3_readdirp_rsp *rsp, gf_dirent_t *entries); int clnt_readdir_rsp_cleanup (gfs3_readdir_rsp *rsp); int clnt_readdirp_rsp_cleanup (gfs3_readdirp_rsp *rsp); diff --git a/xlators/protocol/client/src/client3_1-fops.c b/xlators/protocol/client/src/client3_1-fops.c index 036e297de38..d34ffc20031 100644 --- a/xlators/protocol/client/src/client3_1-fops.c +++ b/xlators/protocol/client/src/client3_1-fops.c @@ -1914,12 +1914,12 @@ int client3_1_readdirp_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { - call_frame_t *frame = NULL; - gfs3_readdirp_rsp rsp = {0,}; - int32_t ret = 0; - clnt_local_t *local = NULL; - gf_dirent_t entries; - xlator_t *this = NULL; + call_frame_t *frame = NULL; + gfs3_readdirp_rsp rsp = {0,}; + int32_t ret = 0; + clnt_local_t *local = NULL; + gf_dirent_t entries; + xlator_t *this = NULL; this = THIS; @@ -1943,7 +1943,7 @@ client3_1_readdirp_cbk (struct rpc_req *req, struct iovec *iov, int count, INIT_LIST_HEAD (&entries.list); if (rsp.op_ret > 0) { - unserialize_rsp_direntp (&rsp, &entries); + unserialize_rsp_direntp (this, local->fd, &rsp, &entries); } out: @@ -5073,6 +5073,7 @@ client3_1_readdirp (call_frame_t *frame, xlator_t *this, struct iovec *rsphdr = NULL; struct iovec vector[MAX_IOVEC] = {{0}, }; clnt_local_t *local = NULL; + size_t dict_len = 0; if (!frame || !this || !data) goto unwind; @@ -5085,23 +5086,23 @@ client3_1_readdirp (call_frame_t *frame, xlator_t *this, readdirp_rsp_size = xdr_sizeof ((xdrproc_t) xdr_gfs3_readdirp_rsp, &rsp) + args->size; + local = GF_CALLOC (1, sizeof (*local), + gf_client_mt_clnt_local_t); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + frame->local = local; + if ((readdirp_rsp_size + GLUSTERFS_RPC_REPLY_SIZE + GLUSTERFS_RDMA_MAX_HEADER_SIZE) > (GLUSTERFS_RDMA_INLINE_THRESHOLD)) { - local = GF_CALLOC (1, sizeof (*local), - gf_client_mt_clnt_local_t); - if (!local) { - op_errno = ENOMEM; - goto unwind; - } - frame->local = local; - rsp_iobref = iobref_new (); if (rsp_iobref == NULL) { goto unwind; } - /* TODO: what is the size we should send ? */ + /* TODO: what is the size we should send ? */ rsp_iobuf = iobuf_get (this->ctx->iobuf_pool); if (rsp_iobuf == NULL) { goto unwind; @@ -5111,19 +5112,33 @@ client3_1_readdirp (call_frame_t *frame, xlator_t *this, iobuf_unref (rsp_iobuf); rsphdr = &vector[0]; rsphdr->iov_base = iobuf_ptr (rsp_iobuf); - rsphdr->iov_len - = iobuf_pagesize (rsp_iobuf); + rsphdr->iov_len = iobuf_pagesize (rsp_iobuf); count = 1; rsp_iobuf = NULL; local->iobref = rsp_iobref; rsp_iobref = NULL; } + local->fd = fd_ref (args->fd); + req.size = args->size; req.offset = args->offset; req.fd = remote_fd; memcpy (req.gfid, args->fd->inode->gfid, 16); + if (args->dict) { + ret = dict_allocate_and_serialize (args->dict, + &req.dict.dict_val, + &dict_len); + if (ret < 0) { + gf_log (this->name, GF_LOG_WARNING, + "failed to get serialized dict"); + op_errno = EINVAL; + goto unwind; + } + req.dict.dict_len = dict_len; + } + ret = client_submit_request (this, &req, frame, conf->fops, GFS3_OP_READDIRP, client3_1_readdirp_cbk, NULL, diff --git a/xlators/protocol/server/src/server-helpers.c b/xlators/protocol/server/src/server-helpers.c index 43f60e0e2e4..4980424d350 100644 --- a/xlators/protocol/server/src/server-helpers.c +++ b/xlators/protocol/server/src/server-helpers.c @@ -1327,11 +1327,40 @@ serialize_rsp_direntp (gf_dirent_t *entries, gfs3_readdirp_rsp *rsp) trav->d_off = entry->d_off; trav->d_len = entry->d_len; trav->d_type = entry->d_type; - //trav->name = memdup (entry->d_name, entry->d_len + 1); trav->name = entry->d_name; gf_stat_from_iatt (&trav->stat, &entry->d_stat); + /* if 'dict' is present, pack it */ + if (entry->dict) { + trav->dict.dict_len = dict_serialized_length (entry->dict); + if (trav->dict.dict_len < 0) { + gf_log (THIS->name, GF_LOG_ERROR, + "failed to get serialized length " + "of reply dict"); + errno = EINVAL; + trav->dict.dict_len = 0; + goto out; + } + + trav->dict.dict_val = GF_CALLOC (1, trav->dict.dict_len, + gf_server_mt_rsp_buf_t); + if (!trav->dict.dict_val) { + errno = ENOMEM; + trav->dict.dict_len = 0; + goto out; + } + + ret = dict_serialize (entry->dict, trav->dict.dict_val); + if (ret < 0) { + gf_log (THIS->name, GF_LOG_ERROR, + "failed to serialize reply dict"); + errno = -ret; + trav->dict.dict_len = 0; + goto out; + } + } + if (prev) prev->nextentry = trav; else diff --git a/xlators/protocol/server/src/server.h b/xlators/protocol/server/src/server.h index f261752171d..92785c5a9d6 100644 --- a/xlators/protocol/server/src/server.h +++ b/xlators/protocol/server/src/server.h @@ -154,7 +154,7 @@ struct _server_state { fd_t *fd; dict_t *params; - int flags; + int32_t flags; int wbflags; struct iovec payload_vector[MAX_IOVEC]; int payload_count; diff --git a/xlators/protocol/server/src/server3_1-fops.c b/xlators/protocol/server/src/server3_1-fops.c index c2ab3590ed2..482c242d5ce 100644 --- a/xlators/protocol/server/src/server3_1-fops.c +++ b/xlators/protocol/server/src/server3_1-fops.c @@ -1038,7 +1038,6 @@ server_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this, gf_stat_from_iatt (&rsp.preparent, preparent); gf_stat_from_iatt (&rsp.postparent, postparent); - link_inode = inode_link (inode, state->loc2.parent, state->loc2.name, stbuf); inode_unref (link_inode); @@ -1738,6 +1737,10 @@ server_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, op_errno = ENOMEM; goto out; } + + /* TODO: need more clear thoughts before calling this function. */ + /* gf_link_inodes_from_dirent (this, state->fd->inode, entries); */ + } else { /* (op_ret == 0) is valid, and means EOF, don't log for that */ gf_log (this->name, (op_ret) ? GF_LOG_INFO : GF_LOG_TRACE, @@ -2132,7 +2135,7 @@ server_readdirp_resume (call_frame_t *frame, xlator_t *bound_xl) STACK_WIND (frame, server_readdirp_cbk, bound_xl, bound_xl->fops->readdirp, state->fd, state->size, - state->offset); + state->offset, state->dict); return 0; err: @@ -3979,10 +3982,10 @@ server_readdirp (rpcsvc_request_t *req) { server_state_t *state = NULL; call_frame_t *frame = NULL; + char *buf = NULL; gfs3_readdirp_req args = {{0,},}; size_t headers_size = 0; int ret = -1; - if (!req) return ret; @@ -4023,6 +4026,29 @@ server_readdirp (rpcsvc_request_t *req) state->offset = args.offset; memcpy (state->resolve.gfid, args.gfid, 16); + if (args.dict.dict_len) { + /* Unserialize the dictionary */ + state->dict = dict_new (); + + buf = memdup (args.dict.dict_val, args.dict.dict_len); + if (buf == NULL) { + goto out; + } + + ret = dict_unserialize (buf, args.dict.dict_len, + &state->dict); + if (ret < 0) { + gf_log (state->conn->bound_xl->name, GF_LOG_ERROR, + "%"PRId64": failed to unserialize req-buffer " + " to dictionary", frame->root->unique); + goto out; + } + + state->dict->extra_free = buf; + + buf = NULL; + } + ret = 0; resolve_and_resume (frame, server_readdirp_resume); out: diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c index 31a4e667d17..346e6a7a640 100644 --- a/xlators/storage/posix/src/posix-helpers.c +++ b/xlators/storage/posix/src/posix-helpers.c @@ -170,7 +170,7 @@ _posix_xattr_get_set (dict_t *xattr_req, } } else if (!strcmp (key, GLUSTERFS_OPEN_FD_COUNT)) { loc = filler->loc; - if (!list_empty (&loc->inode->fd_list)) { + if (loc && !list_empty (&loc->inode->fd_list)) { ret = dict_set_uint32 (filler->xattr, key, 1); if (ret < 0) gf_log (filler->this->name, GF_LOG_WARNING, diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index 7f82431e88b..f895aec2b06 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -3386,10 +3386,27 @@ out: return count; } +dict_t * +posix_entry_xattr_fill (xlator_t *this, inode_t *inode, + fd_t *fd, char *name, dict_t *dict, + struct iatt *stbuf) +{ + loc_t tmp_loc = {0,}; + char *entry_path = NULL; + + /* if we don't send the 'loc', open-fd-count be a problem. */ + tmp_loc.inode = inode; + + MAKE_HANDLE_PATH (entry_path, this, fd->inode->gfid, name); + + return posix_lookup_xattr_fill (this, entry_path, + &tmp_loc, dict, stbuf); + +} int32_t posix_do_readdir (call_frame_t *frame, xlator_t *this, - fd_t *fd, size_t size, off_t off, int whichop) + fd_t *fd, size_t size, off_t off, int whichop, dict_t *dict) { struct posix_fd *pfd = NULL; DIR *dir = NULL; @@ -3400,6 +3417,7 @@ posix_do_readdir (call_frame_t *frame, xlator_t *this, gf_dirent_t entries; struct iatt stbuf = {0, }; gf_dirent_t *tmp_entry = NULL; + inode_table_t *itable = NULL; #ifdef IGNORE_READDIRP_ATTRS uuid_t gfid; ia_type_t entry_type = 0; @@ -3432,33 +3450,47 @@ posix_do_readdir (call_frame_t *frame, xlator_t *this, /* pick ENOENT to indicate EOF */ op_errno = errno; + op_ret = count; + + if (whichop != GF_FOP_READDIRP) + goto out; - if (whichop == GF_FOP_READDIRP) { - list_for_each_entry (tmp_entry, &entries.list, list) { + itable = fd->inode->table; + + list_for_each_entry (tmp_entry, &entries.list, list) { #ifdef IGNORE_READDIRP_ATTRS - ret = inode_grep_for_gfid (fd->inode->table, fd->inode, - tmp_entry->d_name, gfid, - &entry_type); - if (ret == 0) { - memset (&stbuf, 0, sizeof (stbuf)); - uuid_copy (stbuf.ia_gfid, gfid); - posix_fill_ino_from_gfid (this, &stbuf); - stbuf.ia_type = entry_type; - } else { - posix_istat (this, fd->inode->gfid, - tmp_entry->d_name, &stbuf); - } -#else + ret = inode_grep_for_gfid (fd->inode->table, fd->inode, + tmp_entry->d_name, gfid, + &entry_type); + if (ret == 0) { + memset (&stbuf, 0, sizeof (stbuf)); + uuid_copy (stbuf.ia_gfid, gfid); + posix_fill_ino_from_gfid (this, &stbuf); + stbuf.ia_type = entry_type; + } else { posix_istat (this, fd->inode->gfid, tmp_entry->d_name, &stbuf); + } +#else + posix_istat (this, fd->inode->gfid, + tmp_entry->d_name, &stbuf); #endif - if (stbuf.ia_ino) - tmp_entry->d_ino = stbuf.ia_ino; - tmp_entry->d_stat = stbuf; + if (stbuf.ia_ino) + tmp_entry->d_ino = stbuf.ia_ino; + + if (dict) { + tmp_entry->inode = inode_find (itable, stbuf.ia_gfid); + if (!tmp_entry->inode) + tmp_entry->inode = inode_new (itable); + + tmp_entry->dict = + posix_entry_xattr_fill (this, tmp_entry->inode, + fd, tmp_entry->d_name, + dict, &stbuf); } - } - op_ret = count; + tmp_entry->d_stat = stbuf; + } out: STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, &entries); @@ -3473,16 +3505,16 @@ int32_t posix_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off) { - posix_do_readdir (frame, this, fd, size, off, GF_FOP_READDIR); + posix_do_readdir (frame, this, fd, size, off, GF_FOP_READDIR, NULL); return 0; } int32_t posix_readdirp (call_frame_t *frame, xlator_t *this, - fd_t *fd, size_t size, off_t off) + fd_t *fd, size_t size, off_t off, dict_t *dict) { - posix_do_readdir (frame, this, fd, size, off, GF_FOP_READDIRP); + posix_do_readdir (frame, this, fd, size, off, GF_FOP_READDIRP, dict); return 0; } diff --git a/xlators/system/posix-acl/src/posix-acl.c b/xlators/system/posix-acl/src/posix-acl.c index 9a425ff13dd..8c84231476e 100644 --- a/xlators/system/posix-acl/src/posix-acl.c +++ b/xlators/system/posix-acl/src/posix-acl.c @@ -1427,8 +1427,62 @@ int posix_acl_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, gf_dirent_t *entries) { - if (op_ret != 0) + gf_dirent_t *entry = NULL; + struct posix_acl *acl_access = NULL; + struct posix_acl *acl_default = NULL; + struct posix_acl *old_access = NULL; + struct posix_acl *old_default = NULL; + data_t *data = NULL; + int ret = 0; + + if (op_ret <= 0) goto unwind; + + list_for_each_entry (entry, &entries->list, list) { + /* Update the inode ctx */ + if (!entry->dict || !entry->inode) + continue; + + ret = posix_acl_get (entry->inode, this, + &old_access, &old_default); + + data = dict_get (entry->dict, POSIX_ACL_ACCESS_XATTR); + if (!data) + goto acl_default; + + if (old_access && + posix_acl_matches_xattr (this, old_access, data->data, + data->len)) { + acl_access = posix_acl_ref (this, old_access); + } else { + acl_access = posix_acl_from_xattr (this, data->data, + data->len); + } + + acl_default: + data = dict_get (entry->dict, POSIX_ACL_DEFAULT_XATTR); + if (!data) + goto acl_set; + + if (old_default && + posix_acl_matches_xattr (this, old_default, data->data, + data->len)) { + acl_default = posix_acl_ref (this, old_default); + } else { + acl_default = posix_acl_from_xattr (this, data->data, + data->len); + } + + acl_set: + posix_acl_ctx_update (entry->inode, this, &entry->d_stat); + + ret = posix_acl_set (entry->inode, this, + acl_access, acl_default); + if (ret) + gf_log (this->name, GF_LOG_WARNING, + "failed to set ACL in context"); + } + unwind: STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries); return 0; @@ -1437,16 +1491,33 @@ unwind: int posix_acl_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, - off_t offset) + off_t offset, dict_t *dict) { + int ret = 0; + if (acl_permits (frame, fd->inode, POSIX_ACL_READ)) goto green; else goto red; green: + if (dict) { + ret = dict_set_int8 (dict, POSIX_ACL_ACCESS_XATTR, 0); + if (ret) + gf_log (this->name, GF_LOG_WARNING, + "failed to set key %s", + POSIX_ACL_ACCESS_XATTR); + + ret = dict_set_int8 (dict, POSIX_ACL_DEFAULT_XATTR, 0); + if (ret) + gf_log (this->name, GF_LOG_WARNING, + "failed to set key %s", + POSIX_ACL_DEFAULT_XATTR); + } + STACK_WIND (frame, posix_acl_readdirp_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, - fd, size, offset); + fd, size, offset, dict); + return 0; red: STACK_UNWIND_STRICT (readdirp, frame, -1, EACCES, NULL); |