getdirentries cookies usage outside of UFS

Bryan Drewery bdrewery at
Sat Apr 12 02:04:08 UTC 2014

Recently I was working on a compat syscall for sys_getdirentries() that
converts between our dirent and the FreeBSD dirent struct. We had never
tried using this on TMPFS and when we did ran into weird issues (hence
my recent commits to TMPFS to clarify some of the getdirentries() code).
We were not using cookies, so I referenced the Linux compat module
(linux_file.c getdents_common())

I ran across this code:

>     /*
>      * When using cookies, the vfs has the option of reading from
>      * a different offset than that supplied (UFS truncates the
>      * offset to a block boundary to make sure that it never reads
>      * partway through a directory entry, even if the directory
>      * has been compacted).
>      */
>     while (len > 0 && ncookies > 0 && *cookiep <= off) {
>             bdp = (struct dirent *) inp;
>             len -= bdp->d_reclen;
>             inp += bdp->d_reclen;
>             cookiep++;
>             ncookies--;
>     } 

At first it looked innocuous but then it occurred to me it was the root
of the issue I was having as it was eating my cookies based on their
value, despite tmpfs cookies being random hash values that have no
sequential relation. So I looked at how NFS was handling the same code
and found this lovely hack from r216691:

> not_zfs = strcmp(vp->v_mount->mnt_vfc->vfc_name, "zfs");
>  while (cpos < cend && ncookies > 0 &&
>      (dp->d_fileno == 0 || dp->d_type == DT_WHT ||
>       (not_zfs != 0 && ((u_quad_t)(*cookiep)) <= toff))) {
>          cpos += dp->d_reclen;
>          dp = (struct dirent *)cpos;
>          cookiep++;
>          ncookies--;
>  }

I ended up doing the opposite, only running the code if getting dirents
from "ufs".

So there's multiple issue here.

1. NFS is broken on TMPFS. I can see why it's gone so long unnoticed,
why would you do that? Still probably worth fixing.

2. Linux and SVR4 getdirentries() are both broken on TMPFS/ZFS. I am
surprised Linux+ZFS has not been noticed by now. I am aware the SVR4 is
full of other bugs too. I ran across many just reviewing the
getdirentries code alone.

Do any other file systems besides UFS do this offset/cookie
truncation/rewind? If UFS is the only one it may be acceptable to change
this zfs check to !ufs and add it to the other modules. If we don't like
that, or there are potentially other file systems doing this too, how
about adding a flag to somewhere to indicate the file system has
monotonically increasing offsets and needs this rewind support. I'm not
sure where that is best done, struct vfsconf?

Bryan Drewery

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 553 bytes
Desc: OpenPGP digital signature
URL: <>

More information about the freebsd-fs mailing list