readdir() -> d_type always zero on NFS v3 mounted filesystems

N.J. Mann njm at njm.me.uk
Sun May 2 09:57:52 UTC 2021


Hi Rick,


On Thursday, April 29, 2021 14:39:10 +0000 Rick Macklem <rmacklem at uoguelph.ca> wrote:
> N.J. Mann wrote:
>> I recently changed over from using svn to gitup to update /usr/ports
>> on my local system and have been experiencing problems since.  At first
>> either a kernel issue or a configuration issue.  I originally posted
>> about the problem to the freebsd-ports mailing list:
>> https://lists.freebsd.org/pipermail/freebsd-ports/2021-April/120929.html
>> 
>> Since then I have dug deeper and come to the conclusion that it is not a
>> problem with gitup.
>> 
>> The issue I am seeing is that gitup is unable to delete files and
>> directories, even complete ports, which have been removed from the
>> repository.  gitup basically does the following:
>> 
>> prune_tree(base_path)
>> {
>> if ((directory = opendir(base_path)) != NULL) {
>>    while ((entry = readdir(directory)) != NULL) {
>>        snprintf(full_path, sizeof(full_path), "%s/%s", base_path, entry->d_name);
>>        if (entry->d_type == DT_DIR) {
>>            prune_tree(full_path);
>>        } else {
>>            if ((remove(full_path) != 0) && (errno != ENOENT))
>>                 err(EXIT_FAILURE, "prune_tree: cannot remove %s", full_path);
>>            }
>>        }
>>        closedir(directory);
>>        if (rmdir(base_path) != 0)
>>            err(EXIT_FAILURE, "prune_tree: cannot remove %s", base_path);
>>    }
>> }
> 
> The code should check for d_type == DT_UNKNOWN and then do
> stat() to find out the type, as Ronald noted.
> --> The d_type is normally filled in if you use the "rdirplus"
>       NFS mount option,  which might work around the issue.

I tried adding "rdirplus" and indeed that fixes the issue.  I was unaware of
"rdirplus" since somehow I neglected to read the mount_nfs man page.  :-(
I always say you never stop learning.  :-)

I have made and tested a new patch for gitup which replaces the use of d_type
with a call to stat().  It works fine in my setup without "rdirplus" set and
so I think it is the best way forward.  I will pass it on to the author of
gitup and see what he says.

Thanks for the help.


Regards,
        Nick.
-- 



More information about the freebsd-fs mailing list