[Gluster-devel] Invalid DIR * usage in quota xlator
J. Bruce Fields
bfields at fieldses.org
Wed Oct 15 17:02:00 UTC 2014
On Mon, Oct 13, 2014 at 08:57:11AM +0000, Emmanuel Dreyfus wrote:
> On Mon, Oct 13, 2014 at 01:42:38PM +0530, Pranith Kumar Karampuri wrote:
> > >No bug here, just suboptimal behavior, both in glusterfs and NetBSD FUSE.
> > oh!, but shouldn't it get op_ret = 0 instead of op_ret -1, op_errno EINVAL?
>
> It happens because of thei change I introduced:
> seekdir (dir, (long)off);
> #ifndef GF_LINUX_HOST_OS
> if (telldir(dir) != off) {
> gf_log (THIS->name, GF_LOG_ERROR,
> "seekdir(%ld) failed on dir=%p: "
> "Invalid argument (offset reused from "
> "another DIR * structure?)", (long)off, dir);
> errno = EINVAL;
> count = -1;
> goto out;
> }
> #endif /* GF_LINUX_HOST_OS */
>
> The idea is to catch wrong opendir/closedir usage, and the errno = EINVAL
> is critical in such a situation to avoid an infinite loop. On the other
> hand it also fires for last entry. I did not notice it before because
> this EINVAL will not reach calling process, but it may cause trouble
> for internal glusterfs usage.
>
> I see an easy way yo fix it (patch below)
> - when posix xlator detects EOF, return an offset of -1 in last entry.
> - When called with an offset of -1, immediatly return op_ret = 0 with no entry
You're assuming no filesystem uses -1 as a cookie?
Might be true, but it's taking a small chance.
--b.
>
> What do you think?
> diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix
> index 6b12d39..3e539bb 100644
> --- a/xlators/storage/posix/src/posix.c
> +++ b/xlators/storage/posix/src/posix.c
> @@ -79,6 +79,10 @@ extern char *marker_xattrs[];
> #define SET_TO_OLD_FS_ID()
>
> #endif
> +
> +/* offset < sizeof(struct dirent) cannot be valid */
> +#define INVALID_DIRENT_OFFSET sizeof (void *)
> +
> int
> posix_forget (xlator_t *this, inode_t *inode)
> {
> @@ -4851,6 +4855,10 @@ posix_fill_readdir (fd_t *fd, DIR *dir, off_t off, size_t
> int len = 0;
> int ret = 0;
>
> + /* EOF was previously detected */
> + if (off == INVALID_DIRENT_OFFSET)
> + goto out;
> +
> if (skip_dirs) {
> len = posix_handle_path (this, fd->inode->gfid, NULL, NULL, 0);
> hpath = alloca (len + 256); /* NAME_MAX */
> @@ -4969,9 +4977,12 @@ posix_fill_readdir (fd_t *fd, DIR *dir, off_t off, size_t
> count ++;
> }
>
> - if ((!readdir (dir) && (errno == 0)))
> + if ((!readdir (dir) && (errno == 0))) {
> /* Indicate EOF */
> errno = ENOENT;
> + /* Set invalid offset for later detection */
> + this_entry->d_off = INVALID_DIRENT_OFFSET;
> + }
> out:
> return count;
> }
>
>
> --
> Emmanuel Dreyfus
> manu at netbsd.org
> _______________________________________________
> Gluster-devel mailing list
> Gluster-devel at gluster.org
> http://supercolony.gluster.org/mailman/listinfo/gluster-devel
More information about the Gluster-devel
mailing list