socsvn commit: r224051 - soc2011/gk/ino64-head/tools/regression/readdir-lint

gk at FreeBSD.org gk at FreeBSD.org
Fri Jul 8 15:49:53 UTC 2011


Author: gk
Date: Fri Jul  8 15:49:51 2011
New Revision: 224051
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=224051

Log:
  Update readdir-lint, support building on old systems without dirent.d_off

Modified:
  soc2011/gk/ino64-head/tools/regression/readdir-lint/Makefile
  soc2011/gk/ino64-head/tools/regression/readdir-lint/readdir-lint.c

Modified: soc2011/gk/ino64-head/tools/regression/readdir-lint/Makefile
==============================================================================
--- soc2011/gk/ino64-head/tools/regression/readdir-lint/Makefile	Fri Jul  8 15:49:39 2011	(r224050)
+++ soc2011/gk/ino64-head/tools/regression/readdir-lint/Makefile	Fri Jul  8 15:49:51 2011	(r224051)
@@ -4,6 +4,10 @@
 
 PROG=	readdir-lint
 NO_MAN=
-DEBUG_FLAGS= -O0 -g -I${.CURDIR}/../../../sys
+NO_WERROR=
+DEBUG_FLAGS= -O0 -g -I/usr/src/sys
+
+# disable dirent.d_off
+# CFLAGS+= -DNO_DIRENT_OFF
 
 .include <bsd.prog.mk>

Modified: soc2011/gk/ino64-head/tools/regression/readdir-lint/readdir-lint.c
==============================================================================
--- soc2011/gk/ino64-head/tools/regression/readdir-lint/readdir-lint.c	Fri Jul  8 15:49:39 2011	(r224050)
+++ soc2011/gk/ino64-head/tools/regression/readdir-lint/readdir-lint.c	Fri Jul  8 15:49:51 2011	(r224051)
@@ -40,21 +40,26 @@
 #define HAVE_GETPROGNAME
 #endif
 
+#ifdef NO_DIRENT_OFF
+#define d_off			d_fileno
+#endif
+
 #define	DIRSIZE_MAX		(4*1024*1024)
 #define	DIRSIZE_ENTRY		(sizeof(struct dirent))
 #define	DIRSIZE_MIN		((sizeof (struct dirent) - (MAXNAMLEN+1)) + 4)
 #define	DIRSIZE_BLOCK		512
 #define	DIRSIZE_PAGE		4096
 
-#define DIRENT_MAX		512
+#define DIRENT_HDRSIZE		(sizeof(struct dirent) - MAXNAMLEN - 1)
 
 #define DP_NEXT(a)		((struct dirent *)(((char *)(a)) + a->d_reclen))
 
+#define WARN_NOISE		10
 #define WARNX(var, fmt, ...)					\
 	do {							\
-		if ((var) == 0) {				\
+		if ((var) < WARN_NOISE) {			\
 			printf(fmt "\n", ## __VA_ARGS__ );	\
-			var = 1;				\
+			var++;					\
 		}						\
 	} while (0)
 
@@ -64,12 +69,16 @@
 
 #ifdef HAVE_DIRENT_NAMLEN
 static int warn_nameterm;
+static int warn_namelen;
 #endif
-static int warn_noerr;
+#ifndef NO_DIRENT_OFF
 static int warn_seekoff;
-static int warn_zeroino;
 static int warn_zerooff;
+#endif
+static int warn_noerr;
+static int warn_zeroino;
 static int warn_reclen;
+static int warn_overflow;
 
 struct dirbuf {
 	struct dirent *dp, *begin, *end;
@@ -115,9 +124,11 @@
 	off_t seekoff;
 	int rv;
 
+	memset(dir->begin, 0xAA, dir->bufsize);
 	rv = getdirentries(dir->fd, (char *)dir->begin, dir->bufsize, &dir->base);
 	if (opt_verbose >= 3)
-		printf("dir_read %d: len=%d base=%ld\n", dir->fd, rv, dir->base);
+		printf("dir_read %d: len=%d base=%ld\n",
+		    dir->fd, rv, dir->base);
 	if (rv == -1)
 		return (rv);
 	if (rv == 0) {
@@ -125,36 +136,61 @@
 		dir->dp = NULL;
 		dir->end = NULL;
 	} else {
+		if (rv > (int)dir->bufsize)
+			WARNX(warn_overflow, "Buffer overflow: buffer size %zd,"
+			    " %d bytes written", dir->bufsize, rv);
 		dir->dp = dir->begin;
 		dir->end = (struct dirent *)((char *)dir->begin + rv);
 		seekoff = dir_offset(dir);
 		for (di = dir->dp; di < dir->end; di = DP_NEXT(di)) {
 			if (di->d_reclen <= 0 ||
 			    di->d_reclen > (char *)dir->end - (char *)di) {
-				WARNX(warn_reclen, "Invalid entry size: %d", di->d_reclen);
-				dir->end = di;
-				break;
+				WARNX(warn_reclen, "Invalid entry size: %d, "
+				    "space left %d: d_fileno=%ju d_off=%08jx",
+				    di->d_reclen,
+				    (int)((char *)dir->end - (char *)di),
+				    (uintmax_t)di->d_fileno,
+				    (uintmax_t)di->d_off);
+				if (di->d_reclen <= 0) {
+					rv -= (char *)dir->end - (char *)di;
+					dir->end = di;
+					break;
+				}
+
+				di->d_reclen = (char *)dir->end - (char *)di;
 			}
 #ifdef HAVE_DIRENT_NAMLEN
-			if (di->d_namlen > MAXNAMLEN)
-				errx(1, "Ivalid name lenghth: %d", di->d_namlen);
+			if (di->d_namlen > MAXNAMLEN || di->d_namlen >=
+			    di->d_reclen - DIRENT_HDRSIZE)
+				WARNX(warn_namelen, "Ivalid name length: %d "
+				    "(reclen %d, max %d)",
+				    di->d_namlen, di->d_reclen,
+				    di->d_reclen - (int)DIRENT_HDRSIZE);
 			if (di->d_name[di->d_namlen] != '\0') {
 				di->d_name[di->d_namlen] = '\0';
-				WARNX(warn_nameterm, "Entry names are not NUL-terminated");
+				WARNX(warn_nameterm,
+				    "Entry names are not NUL-terminated");
 			}
 #else
 #endif
 			if (di->d_fileno == 0) {
-				WARNX(warn_zeroino, "Zero d_fileno: %08jx %s",
-				    (uintmax_t)di->d_off, di->d_name);
+				WARNX(warn_zeroino,
+				    "Zero d_fileno: 0x%08jx #%ju %s",
+				    (uintmax_t)di->d_off,
+				    (uintmax_t)di->d_fileno, di->d_name);
 			}
+#ifndef NO_DIRENT_OFF
 			if (di->d_off == 0)
-				WARNX(warn_zerooff, "Zero d_off: %ju %s",
+				WARNX(warn_zerooff,
+				    "Zero d_off: 0x%08jx #%ju %s",
+				    (uintmax_t)di->d_off,
 				    (uintmax_t)di->d_fileno, di->d_name);
 			if (DP_NEXT(di) >= dir->end && di->d_off != seekoff) {
-				WARNX(warn_seekoff, "Directory(%zd) and last entry offsets mismatch: %ju -- %ju",
-				    dir->bufsize, (uintmax_t)seekoff, (uintmax_t)di->d_off);
+				WARNX(warn_seekoff, "Directory and last "
+				    "entry offsets mismatch: %08jx -- %08jx",
+				    (uintmax_t)seekoff, (uintmax_t)di->d_off);
 			}
+#endif
 		}
 	}
 
@@ -196,6 +232,9 @@
 	int rv;
 
 	rv = lseek(dir->fd, off, SEEK_SET);
+	if (opt_verbose >= 3)
+		printf("dir_seek %d: offset 0x%08jx, result %d\n",
+		    dir->fd, (uintmax_t)off, rv);
 	if (rv == -1)
 		err(3, "seek(%jd, SEEK_SET)", (uintmax_t)off);
 	dir->dp = NULL;
@@ -213,19 +252,27 @@
 	dp2 = dir2->dp;
 
 	if (dir1->eof != dir2->eof)
-		errx(3, "Invalid EOF: %d %ld -- %d %ld",
+		errx(3, "Invalid EOF: %d base: 0x%08lx -- %d base: 0x%08lx",
 		    dir1->eof, dir1->base, dir2->eof, dir2->base);
 	else if (dir1->eof)
 		return (1);
 	if (opt_verbose >= 2)
-		printf("   %08jx (%d bytes) %-12s -- %08jx (%d bytes) %-12s\n",
-		    (uintmax_t)dp1->d_off, dp1->d_reclen, dp1->d_name,
-		    (uintmax_t)dp2->d_off, dp2->d_reclen, dp2->d_name);
+		printf("   0x%08jx #%-8ju %-12s (reclen %d) -- "
+		    "0x%08jx #%-8ju %-12s (reclen %d)\n",
+		    (uintmax_t)dp1->d_off, (uintmax_t)dp1->d_fileno,
+		    dp1->d_name, dp1->d_reclen,
+		    (uintmax_t)dp2->d_off, (uintmax_t)dp2->d_fileno,
+		    dp2->d_name, dp2->d_reclen);
 	if (strcmp(dp1->d_name, dp2->d_name) != 0 ||
-	    dp1->d_off != dp2->d_off)
-		printf("Entries mismatch: %08jx (%d bytes) %-12s -- %08jx (%d bytes) %-12s\n",
-		    (uintmax_t)dp1->d_off, dp1->d_reclen, dp1->d_name,
-		    (uintmax_t)dp2->d_off, dp2->d_reclen, dp2->d_name);
+	    dp1->d_fileno != dp2->d_fileno ||
+	    dp1->d_off != dp2->d_off) {
+		printf("Entries mismatch: 0x%08jx #%-8ju %-12s (reclen %d) "
+		    "-- 0x%08jx #%-8ju %-12s (reclen %d)\n",
+		    (uintmax_t)dp1->d_off, (uintmax_t)dp1->d_fileno,
+		    dp1->d_name, dp1->d_reclen,
+		    (uintmax_t)dp2->d_off, (uintmax_t)dp2->d_fileno,
+		    dp2->d_name, dp2->d_reclen);
+	}
 
 	return (0);
 }
@@ -266,31 +313,44 @@
 }
 
 static void
-test_minbufsize(struct dirbuf *dir_expect, struct dirbuf *dir)
+test_minbufsize(struct dirbuf *dir_expect, struct dirbuf *dir, int fuzzy)
 {
-	int len;
+	off_t prevoff;
+	int len, cnt;
 
 	if (opt_skip > 0) {
 		opt_skip--;
 		return;
 	}
 
-	printf("Test minimal buffer size\n");
+	printf("Test minimal buffer size (fuzzy %d)\n", fuzzy);
 	dir_init(dir, opt_path, DIRSIZE_ENTRY);
 	dir_seek(dir_expect, 0);
 	dir_read(dir_expect);
+	cnt = 0;
 	while(!dir_expect->eof) {
-		off_t prevoff = dir_offset(dir);
-
+		cnt++;
+#ifndef NO_DIRENT_OFF
+		if (fuzzy >= 2 && cnt % fuzzy == 0) {
+			dir_seek(dir, dir_expect->dp->d_off);
+			dir_next(dir_expect);
+			continue;
+		}
+#endif
+		prevoff = dir_offset(dir);
 		for (dir->bufsize = DIRSIZE_MIN; dir->bufsize <= DIRSIZE_ENTRY;
 		    dir->bufsize += 4) {
 			len = dir_readx(dir);
 			if (len <= 0) {
 				if (prevoff != dir_offset(dir))
-					errx(2, "Directory offset changed but no data read: %jd %jd",
-					    (uintmax_t)prevoff, (uintmax_t)dir_offset(dir));
+					errx(2, "Directory offset changed but "
+					    "no data read: 0x%08jx 0x%08jx",
+					    (uintmax_t)prevoff,
+					    (uintmax_t)dir_offset(dir));
 				if (len == 0) {
-					WARNX(warn_noerr, "EINVAL expected for small buffer read, 0 byte result");
+					WARNX(warn_noerr,
+					    "EINVAL expected for small buffer "
+					    "read, 0 byte result");
 					continue;
 				}
 				if (errno == EINVAL)
@@ -298,20 +358,25 @@
 				err(1, "Directory read");
 			}
 			if (opt_verbose >= 1)
-				printf("   min size %08jx (%d of %zd bytes) %s\n",
-				    (uintmax_t)dir->dp->d_off, dir->dp->d_reclen, dir->bufsize,
-				    dir->dp->d_name);
+				printf("   min size: 0x%08jx #%-8ju %s "
+				    "(buffer: %d of %zd bytes)\n",
+				    (uintmax_t)dir->dp->d_off,
+				    (uintmax_t)dir->dp->d_fileno,
+				    dir->dp->d_name,
+				    dir->dp->d_reclen, dir->bufsize);
 			break;
 		}
 		if (dir->bufsize > DIRSIZE_ENTRY) {
-			errx(2, "Couldn't read entry at offset %jd",
+			errx(2, "Couldn't read entry at offset 0x%08jx",
 			    (uintmax_t)dir_offset(dir));
 		}
 		dir->eof = 0;
 		if (dir_cmpent(dir_expect, dir) != 0)
 			break;
+#ifndef NO_DIRENT_OFF
+		dir_seek(dir, dir_expect->dp->d_off);
+#endif
 		dir_next(dir_expect);
-		dir_seek(dir, dir->dp->d_off);
 	}
 	dir_destroy(dir);
 }
@@ -363,7 +428,11 @@
 		errx(1, "Directory is too large");
 
 	test_bufsize(&dir_max, &dir_i);
-	test_minbufsize(&dir_max, &dir_i);
+	test_minbufsize(&dir_max, &dir_i, 0);
+#ifndef NO_DIRENT_OFF
+	test_minbufsize(&dir_max, &dir_i, 2);
+	test_minbufsize(&dir_max, &dir_i, 5);
+#endif
 
 	return (0);
 }


More information about the svn-soc-all mailing list