fix 'got status' reporting all directories on NFS mounts as unversioned Problem found and fix tested by Ted Bullock. ok millert, naddy
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
diff --git a/lib/fileindex.c b/lib/fileindex.c
index 71a058b..6ea3dea 100644
--- a/lib/fileindex.c
+++ b/lib/fileindex.c
@@ -1022,28 +1022,15 @@ walk_dir(struct got_pathlist_entry **next, struct got_fileindex *fileindex,
struct dirent *de = dle->data;
DIR *subdir = NULL;
int subdirfd = -1;
- int type;
*next = NULL;
- if (de->d_type == DT_UNKNOWN) {
- /* Occurs on NFS mounts without "readdir plus" RPC. */
- char *dir_path;
- if (asprintf(&dir_path, "%s/%s", rootpath, path) == -1)
- return got_error_from_errno("asprintf");
- err = got_path_dirent_type(&type, dir_path, de);
- free(dir_path);
- if (err)
- return err;
- } else
- type = de->d_type;
-
/* Must traverse ignored directories if they contain tracked files. */
- if (type == DT_DIR && ignore &&
+ if (de->d_type == DT_DIR && ignore &&
have_tracked_file_in_dir(fileindex, path))
ignore = 0;
- if (type == DT_DIR && !ignore) {
+ if (de->d_type == DT_DIR && !ignore) {
char *subpath;
char *subdirpath;
struct got_pathlist_head subdirlist;
@@ -1099,6 +1086,28 @@ walk_dir(struct got_pathlist_entry **next, struct got_fileindex *fileindex,
}
static const struct got_error *
+dirent_type_fixup(struct dirent *de, const char *rootpath, const char *path)
+{
+ const struct got_error *err;
+ char *dir_path;
+ int type;
+
+ if (de->d_type != DT_UNKNOWN)
+ return NULL;
+
+ /* DT_UNKNOWN occurs on NFS mounts without "readdir plus" RPC. */
+ if (asprintf(&dir_path, "%s/%s", rootpath, path) == -1)
+ return got_error_from_errno("asprintf");
+ err = got_path_dirent_type(&type, dir_path, de);
+ free(dir_path);
+ if (err)
+ return err;
+
+ de->d_type = type;
+ return NULL;
+}
+
+static const struct got_error *
diff_fileindex_dir(struct got_fileindex *fileindex,
struct got_fileindex_entry **ie, struct got_pathlist_head *dirlist,
int dirfd, const char *rootpath, const char *path,
@@ -1123,6 +1132,9 @@ diff_fileindex_dir(struct got_fileindex *fileindex,
char *de_path;
int cmp;
de = dle->data;
+ err = dirent_type_fixup(de, rootpath, path);
+ if (err)
+ break;
if (asprintf(&de_path, "%s/%s", path,
de->d_name) == -1) {
err = got_error_from_errno("asprintf");
@@ -1162,6 +1174,9 @@ diff_fileindex_dir(struct got_fileindex *fileindex,
*ie = walk_fileindex(fileindex, *ie);
} else if (dle) {
de = dle->data;
+ err = dirent_type_fixup(de, rootpath, path);
+ if (err)
+ break;
err = cb->diff_new(&ignore, cb_arg, de, path, dirfd);
if (err)
break;