diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/fs/devfs/devfs_vnops.c | 24 | ||||
-rw-r--r-- | sys/kern/vfs_subr.c | 4 |
2 files changed, 28 insertions, 0 deletions
diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c index 7fbcad0..d567ea5 100644 --- a/sys/fs/devfs/devfs_vnops.c +++ b/sys/fs/devfs/devfs_vnops.c @@ -797,6 +797,7 @@ devfs_readdir(struct vop_readdir_args *ap) struct devfs_dirent *de; struct devfs_mount *dmp; off_t off, oldoff; + int *tmp_ncookies = NULL; if (ap->a_vp->v_type != VDIR) return (ENOTDIR); @@ -805,6 +806,21 @@ devfs_readdir(struct vop_readdir_args *ap) if (uio->uio_offset < 0) return (EINVAL); + /* + * XXX: This is a temporary hack to get around this filesystem not + * supporting cookies. We store the location of the ncookies pointer + * in a temporary variable before calling vfs_subr.c:vfs_read_dirent() + * and set the number of cookies to 0. We then set the pointer to + * NULL so that vfs_read_dirent doesn't try to call realloc() on + * ap->a_cookies. Later in this function, we restore the ap->a_ncookies + * pointer to its original location before returning to the caller. + */ + if (ap->a_ncookies != NULL) { + tmp_ncookies = ap->a_ncookies; + *ap->a_ncookies = 0; + ap->a_ncookies = NULL; + } + dmp = VFSTODEVFS(ap->a_vp->v_mount); sx_xlock(&dmp->dm_lock); devfs_populate(dmp); @@ -833,6 +849,14 @@ devfs_readdir(struct vop_readdir_args *ap) } sx_xunlock(&dmp->dm_lock); uio->uio_offset = off; + + /* + * Restore ap->a_ncookies if it wasn't originally NULL in the first + * place. + */ + if (tmp_ncookies != NULL) + ap->a_ncookies = tmp_ncookies; + return (error); } diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 6ad6507..6f5f375 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -3875,6 +3875,10 @@ vfs_read_dirent(struct vop_readdir_args *ap, struct dirent *dp, off_t off) } if (ap->a_ncookies == NULL) return (0); + + KASSERT(ap->a_cookies, + ("NULL ap->a_cookies value with non-NULL ap->a_ncookies!")); + *ap->a_cookies = realloc(*ap->a_cookies, (*ap->a_ncookies + 1) * sizeof(u_long), M_TEMP, M_WAITOK | M_ZERO); (*ap->a_cookies)[*ap->a_ncookies] = off; |