core: get xattrs also as part of readdirp
readdirp_req() call sends a dict_t * as an argument, which contains all the xattr keys for which the entries got in readdirp_rsp() are having xattr value filled dictionary. Change-Id: I8b7e1290740ea3e884e67d19156ce849227167c0 Signed-off-by: Amar Tumballi <amar@gluster.com> BUG: 765785 Reviewed-on: http://review.gluster.com/771 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Anand Avati <avati@gluster.com>
This commit is contained in:
parent
b02afc6d00
commit
cf8486cbef
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -30,26 +30,6 @@
|
||||
#include "compat.h"
|
||||
#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)
|
||||
{
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 = {
|
||||
|
@ -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;
|
||||
|
@ -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 = {
|
||||
|
@ -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;
|
||||
|
@ -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 = {
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
@ -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)");
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
list_for_each_entry (tmp_entry, &entries.list, list) {
|
||||
if (whichop != GF_FOP_READDIRP)
|
||||
goto out;
|
||||
|
||||
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);
|
||||
#endif
|
||||
if (stbuf.ia_ino)
|
||||
tmp_entry->d_ino = stbuf.ia_ino;
|
||||
tmp_entry->d_stat = 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;
|
||||
|
||||
op_ret = count;
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user