Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 29 Apr 2021 14:39:10 +0000
From:      Rick Macklem <rmacklem@uoguelph.ca>
To:        "N.J. Mann" <njm@njm.me.uk>, "freebsd-fs@freebsd.org" <freebsd-fs@freebsd.org>
Subject:   Re: readdir() -> d_type always zero on NFS v3 mounted filesystems
Message-ID:  <YQXPR0101MB096836625A188C6751B3F5E6DD5F9@YQXPR0101MB0968.CANPRD01.PROD.OUTLOOK.COM>
In-Reply-To: <2E84A420CCC10A73504624DE@triton.njm.me.uk>
References:  <2E84A420CCC10A73504624DE@triton.njm.me.uk>

next in thread | previous in thread | raw e-mail | index | archive | help
N.J. Mann wrote:=0A=
>I recently changed over from using svn to gitup to update /usr/ports=0A=
>on my local system and have been experiencing problems since.  At first=0A=
>either a kernel issue or a configuration issue.  I originally posted=0A=
>about the problem to the freebsd-ports mailing list:=0A=
>https://lists.freebsd.org/pipermail/freebsd-ports/2021-April/120929.html=
=0A=
>=0A=
>Since then I have dug deeper and come to the conclusion that it is not a=
=0A=
>problem with gitup.=0A=
>=0A=
>The issue I am seeing is that gitup is unable to delete files and=0A=
>directories, even complete ports, which have been removed from the=0A=
>repository.  gitup basically does the following:=0A=
>=0A=
>prune_tree(base_path)=0A=
>{=0A=
>if ((directory =3D opendir(base_path)) !=3D NULL) {=0A=
>    while ((entry =3D readdir(directory)) !=3D NULL) {=0A=
>        snprintf(full_path, sizeof(full_path), "%s/%s", base_path, entry->=
d_name);=0A=
>        if (entry->d_type =3D=3D DT_DIR) {=0A=
>            prune_tree(full_path);=0A=
>        } else {=0A=
>            if ((remove(full_path) !=3D 0) && (errno !=3D ENOENT))=0A=
>                 err(EXIT_FAILURE, "prune_tree: cannot remove %s", full_pa=
th);=0A=
>            }=0A=
>        }=0A=
>        closedir(directory);=0A=
>        if (rmdir(base_path) !=3D 0)=0A=
>            err(EXIT_FAILURE, "prune_tree: cannot remove %s", base_path);=
=0A=
>    }=0A=
>}=0A=
=0A=
The code should check for d_type =3D=3D DT_UNKNOWN and then do=0A=
stat() to find out the type, as Ronald noted.=0A=
--> The d_type is normally filled in if you use the "rdirplus"=0A=
      NFS mount option,  which might work around the issue.=0A=
=0A=
rick=0A=
=0A=
         closedir()=0A=
=0A=
=0A=
When gitup is run on either a UFS or ZFS file system this works.  However,=
=0A=
when I run it on a NFS v3 mounted filesystem it fails.  Liberal addition=0A=
of printf's shows that for non-NFS mounted filesystems d_type contains the=
=0A=
correct value for each file/directory, but for NFS mounted file systems it=
=0A=
is zero - other fields such as d_name and d_namlen are correct.  While=0A=
debugging this I added a call to stat() and that always returns the correct=
=0A=
values.=0A=
=0A=
At this point I started digging in libc and quickly found that readdir()=0A=
is basically a wrapper around a system call.  Digging in the kernel I=0A=
quickly got out of my depth and hence my posting here.  I then wrote a=0A=
simple test programme which also shows the issue.  I have attached the=0A=
source for the test programme and the output from two runs, the first on=0A=
an NFS mounted file system and the second on a local UFS file system.=0A=
=0A=
Before gitup started failing I had not seen any failures like this and that=
=0A=
was why I initially assumed this must be a gitup issue.  I now believe this=
=0A=
is either a kernel issue or a confuration issue.=0A=
=0A=
My configuration is as follows:=0A=
=0A=
file server:=0A=
  /exports/ports - ZFS file system for FreeBSD ports repo exported via NFS=
=0A=
  /remote/ports  - FreeBSD ports repo NFS (v3 rw,tcp) mounted from /export/=
ports=0A=
                   on file server=0A=
  /usr/ports     - symbolic link to /remote/ports=0A=
client machines:=0A=
  /remote/ports  - FreeBSD ports repo NFS (v3 ro,tcp) mounted from /export/=
ports=0A=
                   on file server=0A=
  /usr/ports     - symbolic link to /remote/ports=0A=
=0A=
I run gitup in /remote/ports on the file server and then pkg, portmaster, &=
.c,=0A=
in /usr/ports on the file server and then the client machines.  All systems=
 are=0A=
running 11-STABLE from about 12 days ago - I usually update every couple of=
 weeks.=0A=
=0A=
Any assistance, suggestions, patches, clue bats, will be gratefully accepte=
d.=0A=
=0A=
=0A=
Regards,=0A=
        Nick.=0A=
--=0A=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?YQXPR0101MB096836625A188C6751B3F5E6DD5F9>