shithub: diskcheck

Download patch

ref: 3bc9c2fe9c978cfbe371fac4eb4c7cd092bedeae
author: Tevo <estevan.cps@gmail.com>
date: Tue Sep 1 21:25:23 EDT 2020

Initial commit

--- /dev/null
+++ b/TODO
@@ -1,0 +1,5 @@
+- Cleanup code
+- Non-destructive read/write and read-only tests
+- Verbosity level and progress/error messages
+- `aux/statusbar`-compatible output
+- Write man page
\ No newline at end of file
--- /dev/null
+++ b/checkdisk.c
@@ -1,0 +1,92 @@
+#include <u.h>
+#include <libc.h>
+
+const uint PATTERNS[] = { 0xC0A11E5C, 0xDEADBEEF, 0xB16B00B5, 0x00000000 };
+
+void
+usage(void)
+{
+	fprint(2, "usage: %s [-s start] [-t threshold] disk\n", argv0);
+	exits("usage");
+}
+
+void*
+emalloc(ulong size)
+{
+	void *buf = malloc(size);
+	if(buf == nil)
+		sysfatal("malloc: %r");
+	return buf;
+}
+
+void
+repeat(void *dbuf, uint pat, ulong size)
+{
+	uchar *buf = (uchar*)dbuf;
+	for(int c = 0; c < size; c++)
+		buf[c] = (uchar)(pat >> c%sizeof(pat));
+}
+
+int
+chkdsk(int fd, int bsize, vlong seek, int thr)
+{
+	void *buf = emalloc(bsize), 
+		 *pat = emalloc(bsize);
+	int pos = seek, read, bad = 0;
+	for(int c = 0; c < sizeof(PATTERNS); c++)
+	{
+		repeat(pat, PATTERNS[c], bsize);
+		while((read = pread(fd, buf, bsize, pos)) != 0)
+		{
+			pwrite(fd, pat, read, pos);
+			pread(fd, buf, read, pos);
+			if(memcmp(buf, pat, read) != 0)
+			{
+				print("%d\n", pos);
+				bad++;
+			}
+			if(thr > 0 && bad >= thr)
+			{
+				goto cleanup; /* Need the goto to break out of the outer loop */
+			}
+			pos += read;
+		}
+	}
+	cleanup:
+	free(buf);
+	free(pat);
+	return bad;
+}
+
+void
+main(int argc, char **argv)
+{
+	int thr = 0, bsize = 512, diskfd;
+	vlong seek = 0;
+
+	ARGBEGIN {
+	case 's':
+		seek = atoll(EARGF(usage()));
+		break;
+	case 't':
+		thr = atoi(EARGF(usage()));
+		if(thr < 0)
+			usage();
+		break;
+	default:
+		usage();
+		break;
+	} ARGEND;
+
+	if(argc != 1)
+		usage();
+
+	if((diskfd = open(argv[0], ORDWR)) < 0)
+		sysfatal("open: %r");
+
+	chkdsk(diskfd, bsize, seek, thr);
+
+	close(diskfd);
+
+	exits(0);
+}
--- /dev/null
+++ b/mkfile
@@ -1,0 +1,18 @@
+</$objtype/mkfile
+
+SRC=checkdisk.c
+
+%.$O: %.c
+	$CC $CFLAGS -o $target $prereq
+
+$O.out: ${SRC:%.c=%.$O}
+	$LD $LFLAGS -o $target $prereq
+
+clean nuke:V:
+	rm -f [$OS].out *.[$OS]
+
+install:V: $O.out
+	cp $O.out /$objtype/bin/disk/check
+
+uninstall:V:
+	rm -f /$objtype/bin/disk/check