mirror of
https://github.com/opnsense/src.git
synced 2026-06-10 17:22:46 -04:00
devfs readdir: handle short buffer same as UFS
Return EINVAL if this is the first dirent encountered with the short buffer, or EJUSTRETURN if something was already copied out. This is needed to pass eof check in vop_readdir_post(): we are not at eof but resid was not advanced. Reported and tested by: pho (previous version) Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D51667
This commit is contained in:
parent
d5ec97156d
commit
011efaa5cd
1 changed files with 8 additions and 1 deletions
|
|
@ -1450,6 +1450,7 @@ devfs_readdir(struct vop_readdir_args *ap)
|
|||
struct devfs_mount *dmp;
|
||||
off_t off;
|
||||
int *tmp_ncookies = NULL;
|
||||
ssize_t startresid;
|
||||
|
||||
if (ap->a_vp->v_type != VDIR)
|
||||
return (ENOTDIR);
|
||||
|
|
@ -1482,6 +1483,7 @@ devfs_readdir(struct vop_readdir_args *ap)
|
|||
error = 0;
|
||||
de = ap->a_vp->v_data;
|
||||
off = 0;
|
||||
startresid = uio->uio_resid;
|
||||
TAILQ_FOREACH(dd, &de->de_dlist, de_list) {
|
||||
KASSERT(dd->de_cdp != (void *)0xdeadc0de, ("%s %d\n", __func__, __LINE__));
|
||||
if (dd->de_flags & (DE_COVERED | DE_WHITEOUT))
|
||||
|
|
@ -1494,8 +1496,13 @@ devfs_readdir(struct vop_readdir_args *ap)
|
|||
de = dd;
|
||||
dp = dd->de_dirent;
|
||||
MPASS(dp->d_reclen == GENERIC_DIRSIZ(dp));
|
||||
if (dp->d_reclen > uio->uio_resid)
|
||||
if (dp->d_reclen > uio->uio_resid) {
|
||||
/* Nothing was copied out, return EINVAL. */
|
||||
if (uio->uio_resid == startresid)
|
||||
error = EINVAL;
|
||||
/* Otherwise stop. */
|
||||
break;
|
||||
}
|
||||
dp->d_fileno = de->de_inode;
|
||||
/* NOTE: d_off is the offset for the *next* entry. */
|
||||
dp->d_off = off + dp->d_reclen;
|
||||
|
|
|
|||
Loading…
Reference in a new issue