From: Steinar H. Gunderson Date: Sun, 21 Mar 2021 14:48:55 +0000 (+0100) Subject: Make updatedb understand DT_UNKNOWN. X-Git-Tag: 1.1.6~3 X-Git-Url: https://git.sesse.net/?p=plocate;a=commitdiff_plain;h=4a70122ed746cb67c6f6a10cbf400627e7b03c29 Make updatedb understand DT_UNKNOWN. Some filesystems don't know from getdents() whether an entry is a file or a directory without a stat(). I had assumed this was only an issue for obscure operating systems, so I removed it (mlocate's updatedb supported it), but evidently older versions of XFS has this issue, too, so add back checking. Reported by Marcel Partap. --- diff --git a/updatedb.cpp b/updatedb.cpp index 895b071..8d524c6 100644 --- a/updatedb.cpp +++ b/updatedb.cpp @@ -628,7 +628,23 @@ int scan(const string &path, int fd, dev_t parent_dev, dir_time modified, dir_ti entry e; e.name = de->d_name; - e.is_directory = (de->d_type == DT_DIR); + if (de->d_type == DT_UNKNOWN) { + // Evidently some file systems, like older versions of XFS + // (mkfs.xfs -m crc=0 -n ftype=0), can return this, + // and we need a stat(). If we wanted to optimize for this, + // we could probably defer it to later (we're stat-ing directories + // when recursing), but this is rare, and not really worth it -- + // the second stat() will be cached anyway. + struct stat buf; + if (fstatat(fd, de->d_name, &buf, AT_SYMLINK_NOFOLLOW) == 0 && + S_ISDIR(buf.st_mode)) { + e.is_directory = true; + } else { + e.is_directory = false; + } + } else { + e.is_directory = (de->d_type == DT_DIR); + } if (conf_verbose) { printf("%s/%s\n", path.c_str(), de->d_name);