Index: lib/libc/sys/getdirentries.2 =================================================================== --- lib/libc/sys/getdirentries.2 +++ lib/libc/sys/getdirentries.2 @@ -28,7 +28,7 @@ .\" @(#)getdirentries.2 8.2 (Berkeley) 5/3/95 .\" $FreeBSD$ .\" -.Dd May 28, 2017 +.Dd Nov 12, 2018 .Dt GETDIRENTRIES 2 .Os .Sh NAME @@ -88,6 +88,11 @@ have the same .Fa d_fileno . The +.Fa d_off +entry is the distance from the start of the directory to the start of the +.I next +dirent. +The .Fa d_reclen entry is the length, in bytes, of the directory record. The @@ -140,7 +145,10 @@ .Fa basep .Po Fn getdirentries only -.Pc +.Pc , +a value returned in the +.Fa d_off +field, or zero. .Sh RETURN VALUES If successful, the number of bytes actually transferred is returned. Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c =================================================================== --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c @@ -1105,6 +1105,8 @@ strcpy(entry.d_name, snapname); entry.d_namlen = strlen(entry.d_name); entry.d_reclen = sizeof(entry); + /* NOTE: d_off is the offset for the *next* entry. */ + entry.d_off = cookie + dots_offset; error = vfs_read_dirent(ap, &entry, uio->uio_offset); if (error != 0) { if (error == ENAMETOOLONG) Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c =================================================================== --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c @@ -2529,8 +2529,8 @@ */ eodp->ed_ino = objnum; eodp->ed_reclen = reclen; - /* NOTE: ed_off is the offset for the *next* entry */ - next = &(eodp->ed_off); + /* NOTE: ed_off is the offset for the *next* entry. */ + next = &eodp->ed_off; eodp->ed_eflags = zap.za_normalization_conflict ? ED_CASE_CONFLICT : 0; (void) strncpy(eodp->ed_name, zap.za_name, @@ -2543,6 +2543,8 @@ odp->d_ino = objnum; odp->d_reclen = reclen; odp->d_namlen = strlen(zap.za_name); + /* NOTE: d_off is the offset for the *next* entry. */ + next = &odp->d_off; (void) strlcpy(odp->d_name, zap.za_name, odp->d_namlen + 1); odp->d_type = type; odp = (dirent64_t *)((intptr_t)odp + reclen); @@ -2567,6 +2569,9 @@ offset += 1; } + /* Fill the offset right after advancing the cursor. */ + if (next != NULL) + *next = offset; if (cooks != NULL) { *cooks++ = offset; ncooks--; Index: sys/fs/cd9660/cd9660_vnops.c =================================================================== --- sys/fs/cd9660/cd9660_vnops.c +++ sys/fs/cd9660/cd9660_vnops.c @@ -576,6 +576,8 @@ entryoffsetinblock; idp->curroff += reclen; + /* NOTE: d_off is the offset of *next* entry. */ + idp->current.d_off = idp->curroff; switch (imp->iso_ftype) { case ISO_FTYPE_RRIP: Index: sys/fs/devfs/devfs_vnops.c =================================================================== --- sys/fs/devfs/devfs_vnops.c +++ sys/fs/devfs/devfs_vnops.c @@ -1355,6 +1355,8 @@ if (dp->d_reclen > uio->uio_resid) break; dp->d_fileno = de->de_inode; + /* NOTE: d_off is the offset for the *next* entry. */ + dp->d_off = off + dp->d_reclen; if (off >= uio->uio_offset) { error = vfs_read_dirent(ap, dp, off); if (error) Index: sys/fs/ext2fs/ext2_lookup.c =================================================================== --- sys/fs/ext2fs/ext2_lookup.c +++ sys/fs/ext2fs/ext2_lookup.c @@ -224,6 +224,8 @@ dstdp.d_reclen = GENERIC_DIRSIZ(&dstdp); bcopy(dp->e2d_name, dstdp.d_name, dstdp.d_namlen); dstdp.d_name[dstdp.d_namlen] = '\0'; + /* NOTE: d_off is the offset of the *next* entry. */ + dstdp.d_off = offset + dp->e2d_reclen; if (dstdp.d_reclen > uio->uio_resid) { if (uio->uio_resid == startresid) error = EINVAL; Index: sys/fs/fdescfs/fdesc_vnops.c =================================================================== --- sys/fs/fdescfs/fdesc_vnops.c +++ sys/fs/fdescfs/fdesc_vnops.c @@ -574,6 +574,8 @@ dp->d_fileno = i + FD_DESC; break; } + /* NOTE: d_off is the offset of the *next* entry. */ + dp->d_off = UIO_MX * (i + 1); if (dp->d_namlen != 0) { /* * And ship to userland Index: sys/fs/msdosfs/msdosfs_vnops.c =================================================================== --- sys/fs/msdosfs/msdosfs_vnops.c +++ sys/fs/msdosfs/msdosfs_vnops.c @@ -1558,6 +1558,8 @@ break; } dirbuf.d_reclen = GENERIC_DIRSIZ(&dirbuf); + /* NOTE: d_off is the offset of the *next* entry. */ + dirbuf.d_off = offset + sizeof(struct direntry); if (uio->uio_resid < dirbuf.d_reclen) goto out; error = uiomove(&dirbuf, dirbuf.d_reclen, uio); @@ -1681,6 +1683,8 @@ mbnambuf_flush(&nb, &dirbuf); chksum = -1; dirbuf.d_reclen = GENERIC_DIRSIZ(&dirbuf); + /* NOTE: d_off is the offset of the *next* entry. */ + dirbuf.d_off = offset + sizeof(struct direntry); if (uio->uio_resid < dirbuf.d_reclen) { brelse(bp); goto out; Index: sys/fs/nandfs/nandfs_vnops.c =================================================================== --- sys/fs/nandfs/nandfs_vnops.c +++ sys/fs/nandfs/nandfs_vnops.c @@ -1233,6 +1233,8 @@ dirent.d_namlen = name_len; strncpy(dirent.d_name, ndirent->name, name_len); dirent.d_reclen = GENERIC_DIRSIZ(&dirent); + /* NOTE: d_off is the offset of the *next* entry. */ + dirent.d_off = diroffset + ndirent->rec_len; DPRINTF(READDIR, ("copying `%*.*s`\n", name_len, name_len, dirent.d_name)); } Index: sys/fs/pseudofs/pseudofs_vnops.c =================================================================== --- sys/fs/pseudofs/pseudofs_vnops.c +++ sys/fs/pseudofs/pseudofs_vnops.c @@ -830,6 +830,8 @@ pfsent->entry.d_name[i] = pn->pn_name[i]; pfsent->entry.d_name[i] = 0; pfsent->entry.d_namlen = i; + /* NOTE: d_off is the offset of the *next* entry. */ + pfsent->entry.d_off = offset + PFS_DELEN; switch (pn->pn_type) { case pfstype_procdir: KASSERT(p != NULL, Index: sys/fs/udf/udf_vnops.c =================================================================== --- sys/fs/udf/udf_vnops.c +++ sys/fs/udf/udf_vnops.c @@ -846,6 +846,7 @@ dir.d_name[1] = '\0'; dir.d_namlen = 1; dir.d_reclen = GENERIC_DIRSIZ(&dir); + dir.d_off = 1; uiodir.dirent = &dir; error = udf_uiodir(&uiodir, dir.d_reclen, uio, 1); if (error) @@ -858,6 +859,7 @@ dir.d_name[2] = '\0'; dir.d_namlen = 2; dir.d_reclen = GENERIC_DIRSIZ(&dir); + dir.d_off = 2; uiodir.dirent = &dir; error = udf_uiodir(&uiodir, dir.d_reclen, uio, 2); } else { @@ -867,6 +869,7 @@ dir.d_type = (fid->file_char & UDF_FILE_CHAR_DIR) ? DT_DIR : DT_UNKNOWN; dir.d_reclen = GENERIC_DIRSIZ(&dir); + dir.d_off = ds->this_off; uiodir.dirent = &dir; error = udf_uiodir(&uiodir, dir.d_reclen, uio, ds->this_off); Index: sys/ufs/ufs/ufs_vnops.c =================================================================== --- sys/ufs/ufs/ufs_vnops.c +++ sys/ufs/ufs/ufs_vnops.c @@ -2218,6 +2218,8 @@ dstdp.d_reclen = GENERIC_DIRSIZ(&dstdp); bcopy(dp->d_name, dstdp.d_name, dstdp.d_namlen); dstdp.d_name[dstdp.d_namlen] = '\0'; + /* NOTE: d_off is the offset of the *next* entry. */ + dstdp.d_off = offset + dp->d_reclen; if (dstdp.d_reclen > uio->uio_resid) { if (uio->uio_resid == startresid) error = EINVAL;