[Bugs] [Bug 1581345] New: posix unwinds readdirp calls with readdir signature
bugzilla at redhat.com
bugzilla at redhat.com
Tue May 22 14:34:58 UTC 2018
https://bugzilla.redhat.com/show_bug.cgi?id=1581345
Bug ID: 1581345
Summary: posix unwinds readdirp calls with readdir signature
Product: GlusterFS
Version: mainline
Component: posix
Assignee: bugs at gluster.org
Reporter: rabhat at redhat.com
CC: bugs at gluster.org
Description of problem:
As of now, posix xlator unwinds the readdirp calls with readdir signature.
This from functionality point of view might not impact the application or any
feature. But if a xlator sitting above posix in the xlator stack (graph)
expects the metadata and/or dictionary contents (for some of the internal
xattrs used by other xlators in the graph) along with each directory entry,
then such xlators might not be able to get those information. And they have to
rely on a explicit lookup call to come OR they have to send a explicit lookup
or getxattr operation themselves for getting the required metadata and the
xattr values respectively.
This is what the current implementation of the function posix_do_readdir does
(used by both posix_readdir and posix_readdirp)
"
int32_t
posix_do_readdir (call_frame_t *frame, xlator_t *this,
fd_t *fd, size_t size, off_t off, int whichop, dict_t *dict)
{
struct posix_fd *pfd = NULL;
DIR *dir = NULL;
int ret = -1;
int count = 0;
int32_t op_ret = -1;
int32_t op_errno = 0;
gf_dirent_t entries;
int32_t skip_dirs = 0;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
VALIDATE_OR_GOTO (fd, out);
INIT_LIST_HEAD (&entries.list);
ret = posix_fd_ctx_get (fd, this, &pfd, &op_errno);
if (ret < 0) {
gf_msg (this->name, GF_LOG_WARNING, op_errno, P_MSG_PFD_NULL,
"pfd is NULL, fd=%p", fd);
goto out;
}
dir = pfd->dir;
if (!dir) {
gf_msg (this->name, GF_LOG_WARNING, EINVAL, P_MSG_PFD_NULL,
"dir is NULL for fd=%p", fd);
op_errno = EINVAL;
goto out;
}
/* When READDIR_FILTER option is set to on, we can filter out
* directory's entry from the entry->list.
*/
ret = dict_get_int32 (dict, GF_READDIR_SKIP_DIRS, &skip_dirs);
LOCK (&fd->lock);
{
/* posix_fill_readdir performs multiple separate individual
readdir() calls to fill up the buffer.
In case of NFS where the same anonymous FD is shared between
different applications, reading a common directory can
result in the anonymous fd getting re-used unsafely between
the two readdir requests (in two different io-threads).
It would also help, in the future, to replace the loop
around readdir() with a single large getdents() call.
*/
count = posix_fill_readdir (fd, dir, off, size, &entries, this,
skip_dirs);
}
UNLOCK (&fd->lock);
/* pick ENOENT to indicate EOF */
op_errno = errno;
op_ret = count;
if (whichop != GF_FOP_READDIRP)
goto out;
posix_readdirp_fill (this, fd, &entries, dict);
out:
STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, &entries, NULL);
======> unwinding with readdir signature without checking whether the incoming
fop was readdir or readdirp.
gf_dirent_free (&entries);
return 0;
}
The similar behavior is there in the function posix_readdirp as well.
"
int32_t
posix_readdirp (call_frame_t *frame, xlator_t *this,
fd_t *fd, size_t size, off_t off, dict_t *dict)
{
gf_dirent_t entries;
int32_t op_ret = -1, op_errno = 0;
gf_dirent_t *entry = NULL;
if ((dict != NULL) && (dict_get (dict, GET_ANCESTRY_DENTRY_KEY))) {
INIT_LIST_HEAD (&entries.list);
op_ret = posix_get_ancestry (this, fd->inode, &entries, NULL,
POSIX_ANCESTRY_DENTRY,
&op_errno, dict);
if (op_ret >= 0) {
op_ret = 0;
list_for_each_entry (entry, &entries.list, list) {
op_ret++;
}
}
STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno,&entries,
NULL);
===> posix_readdirp is unwinding with readdir signature.
gf_dirent_free (&entries);
return 0;
}
posix_do_readdir (frame, this, fd, size, off, GF_FOP_READDIRP, dict);
return 0;
}
"
Version-Release number of selected component (if applicable):
How reproducible:
Steps to Reproduce:
1.
2.
3.
Actual results:
Expected results:
Additional info:
--
You are receiving this mail because:
You are on the CC list for the bug.
You are the assignee for the bug.
More information about the Bugs
mailing list