[Bug 253428] getdirentries does not work correctly on NFS mounts

bugzilla-noreply at freebsd.org bugzilla-noreply at freebsd.org
Thu Feb 11 04:07:50 UTC 2021


https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=253428

            Bug ID: 253428
           Summary: getdirentries does not work correctly on NFS mounts
           Product: Base System
           Version: CURRENT
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Some People
          Priority: ---
         Component: kern
          Assignee: bugs at FreeBSD.org
          Reporter: asomers at FreeBSD.org
 Attachment #222358 text/plain
         mime type:

Created attachment 222358
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=222358&action=edit
test program demonstrating getdirentries's output.

r318736, the 64-bit inode project, added a d_off field to struct dirent. 
According to the man page, each entry's d_off field can be used with lseek(2)
to position the directory descriptor to the next entry.  That works for UFS,
devfs, ZFS, and tmpfs.  But the NFS client always returns 0 for d_off.

Secondly, getdirentries is supposed to return the length of valid data in the
buffer.  For UFS, devfs, ZFS, and tmpfs it does it correctly.  But for NFS, it
always returns the size of the buffer.

Steps to Reproduce:
1) Compile the attached program with cc -o getdirentries -Wall getdirentries.c
2) sudo mount -t tmpfs tmpfs /mnt
3) cd /mnt
4) sudo touch foo bar baz
5) /path/to/getdirentries 0
  len=160
  name=. d_reclen=32 d_off=1
  name=.. d_reclen=32 d_off=15397777
  name=bar d_reclen=32 d_off=15397785
  name=baz d_reclen=32 d_off=250872870
  name=foo d_reclen=32 d_off=2
6) /path/to/getdirentries 1
  name=.. d_reclen=32 d_off=15397777
  name=bar d_reclen=32 d_off=15397785
  name=baz d_reclen=32 d_off=250872870
  name=foo d_reclen=32 d_off=2
Notice that we supplied the first entry's d_off value, and getdirentries
returned a buffer starting with the second entry.
7) cd /path/to/some/NFS/mount
8) touch foo bar baz
9) /path/to/getdirentries 0
  len=8192
  name=. d_reclen=40 d_off=0
  name=.. d_reclen=40 d_off=0
  name=bar d_reclen=40 d_off=0
  name=foo d_reclen=40 d_off=0
  name=baz d_reclen=352 d_off=0
  name= d_reclen=512 d_off=0
  name= d_reclen=512 d_off=0
  name= d_reclen=512 d_off=0
  name= d_reclen=512 d_off=0
  name= d_reclen=512 d_off=0
  name= d_reclen=512 d_off=0
  name= d_reclen=512 d_off=0
  name= d_reclen=512 d_off=0
  name= d_reclen=512 d_off=0
  name= d_reclen=512 d_off=0
  name= d_reclen=512 d_off=0
  name= d_reclen=512 d_off=0
  name= d_reclen=512 d_off=0
  name= d_reclen=512 d_off=0
  name= d_reclen=512 d_off=0
Notice the long tail of "" entries.  That's because the returned length is
equal to the size of the buffer.  Also, notice that d_off is always 0. 
Obviously, it can't be supplied to lseek.

Observed with NFS v4.2 on a FreeBSD 14.0-CURRENT amd64 client with a
13.0-ALPHA1 server.

-- 
You are receiving this mail because:
You are the assignee for the bug.


More information about the freebsd-bugs mailing list