MFC: r283273
The NFS client wasn't handling getdirentries(2) requests for sizes that are not an exact multiple of DIRBLKSIZ correctly. Fortunately readdir(3) always uses an exact multiple of DIRBLKSIZ, so few applications were affected. This patch fixes this problem by reducing the size of the directory read to an exact multiple of DIRBLKSIZ.
This commit is contained in:
parent
b8022a7806
commit
7e70fa5ddf
@ -2211,7 +2211,7 @@ nfs_readdir(struct vop_readdir_args *ap)
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct nfsnode *np = VTONFS(vp);
|
||||
struct uio *uio = ap->a_uio;
|
||||
ssize_t tresid;
|
||||
ssize_t tresid, left;
|
||||
int error = 0;
|
||||
struct vattr vattr;
|
||||
|
||||
@ -2239,6 +2239,17 @@ nfs_readdir(struct vop_readdir_args *ap)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* NFS always guarantees that directory entries don't straddle
|
||||
* DIRBLKSIZ boundaries. As such, we need to limit the size
|
||||
* to an exact multiple of DIRBLKSIZ, to avoid copying a partial
|
||||
* directory entry.
|
||||
*/
|
||||
left = uio->uio_resid % DIRBLKSIZ;
|
||||
if (left == uio->uio_resid)
|
||||
return (EINVAL);
|
||||
uio->uio_resid -= left;
|
||||
|
||||
/*
|
||||
* Call ncl_bioread() to do the real work.
|
||||
*/
|
||||
@ -2250,6 +2261,9 @@ nfs_readdir(struct vop_readdir_args *ap)
|
||||
if (ap->a_eofflag != NULL)
|
||||
*ap->a_eofflag = 1;
|
||||
}
|
||||
|
||||
/* Add the partial DIRBLKSIZ (left) back in. */
|
||||
uio->uio_resid += left;
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user