shithub: riscv

Download patch

ref: 3edac8032702e5fb30dd78591ec0d104f83cfa33
parent: f59ef5e8e7661dc06924bf8fea625ae69d59e40e
parent: 347bb2a7a7110e55debd5ebe57ba03bbe315c5ba
author: spew <devnull@localhost>
date: Mon Mar 27 05:57:08 EDT 2017

hjfs: merge start of hjfs check implementation

--- /dev/null
+++ b/sys/src/cmd/hjfs/check.c
@@ -1,0 +1,70 @@
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include "dat.h"
+#include "fns.h"
+
+extern Fs *fsmain;
+
+static void
+checkdir(FLoc *l, Buf *b)
+{
+	Buf *c;
+	Dentry *d;
+	uvlong i, r;
+
+	d = getdent(l, b);
+	for(i = 0; i < d->size; i++){
+		if(getblk(fsmain, l, b, i, &r, GBREAD) <= 0) {
+			dprint("hjfs: directory %s in block %ulld at index %d has a bad block reference at %ulld\n", d->name, l->blk, l->deind, i);
+			continue;
+		}
+		c = getbuf(fsmain->d, r, TDENTRY, 0);
+		if(c == nil) {
+			dprint("hjfs: directory %s in block %ulld at index %d has a block %ulld that is not a directory entry\n", d->name, l->blk, l->deind, i);
+			continue;
+		}
+	}
+}
+
+static void
+checkfile(FLoc*, Buf*)
+{}
+
+int
+checkblk(uvlong blk)
+{
+	Dentry *d;
+	Buf *b;
+	FLoc l;
+	int i, type;
+
+	b = getbuf(fsmain->d, blk, TDONTCARE, 0);
+	if(b == nil)
+		return -1;
+	switch(type = b->type){
+	case TRAW:
+		break;
+	case TSUPERBLOCK:
+		dprint("hjfs: checkblk: should not have found superblock at %ulld\n", blk);
+		break;
+	case TDENTRY:
+		l.blk = blk;
+		for(i = 0; i < DEPERBLK; i++){
+			d = &b->de[i];
+			l.deind = i;
+			l.Qid = d->Qid;
+			if((d->type & QTDIR) != 0)
+				checkdir(&l, b);
+			else
+				checkfile(&l, b);
+		}
+		break;
+	case TINDIR:
+		break;
+	case TREF:
+		break;
+	}
+	putbuf(b);
+	return type;
+}
--- a/sys/src/cmd/hjfs/cons.c
+++ b/sys/src/cmd/hjfs/cons.c
@@ -104,6 +104,38 @@
 }
 
 int
+cmdcheck(int, char**)
+{
+	uvlong fblk, fend, blk;
+	int j;
+	Buf *b, *sb;
+
+	wlock(fsmain);
+	sb = getbuf(fsmain->d, SUPERBLK, TSUPERBLOCK, 0);
+	if(sb == nil){
+		wunlock(fsmain);
+		return -1;
+	}
+	fblk = sb->sb.fstart;
+	fend = sb->sb.fend;
+	putbuf(sb);
+
+	for(blk = 0; fblk < fend; fblk++){
+		b = getbuf(fsmain->d, fblk, TREF, 0);
+		if(b == nil){
+			blk += REFPERBLK;
+			continue;
+		}
+		for(j = 0; j < REFPERBLK; j++, blk++)
+			if(b->refs[j] == 0)
+				checkblk(blk);
+		putbuf(b);
+	}
+	wunlock(fsmain);
+	return 1;
+}
+
+int
 cmddisallow(int, char **)
 {
 	fsmain->flags &= ~(FSNOPERM | FSCHOWN);
--- a/sys/src/cmd/hjfs/dat.h
+++ b/sys/src/cmd/hjfs/dat.h
@@ -79,6 +79,11 @@
 enum {
 	DENTRYSIZ = NAMELEN + 4 * sizeof(ushort) + 13 + (3 + NDIRECT + NINDIRECT) * sizeof(uvlong),
 	DEPERBLK = RBLOCK / DENTRYSIZ,
+	/* Given any opportunity to make a breaking change to hjfs,
+	 * make this 12 an 8. Indirect offsets to blocks used to
+	 * hold an incrementing  4 byte generation number. That
+	 * design has changed.
+	 */
 	OFFPERBLK = RBLOCK / 12,
 	REFSIZ = 3,
 	REFPERBLK = RBLOCK / REFSIZ,
@@ -185,8 +190,8 @@
 	CHREAD = 1,
 	CHWRITE = 2,
 	CHRCLOSE = 4,
-	CHFDUMP = 1,
 
+	CHFDUMP = 1,
 	CHFNOLOCK = 2,
 	CHFRO = 4,
 	CHFNOPERM = 8,
--- a/sys/src/cmd/hjfs/fns.h
+++ b/sys/src/cmd/hjfs/fns.h
@@ -54,3 +54,4 @@
 void	workerinit(void);
 void	writeusers(Fs *);
 void	readusers(Fs *);
+int	checkblk(uvlong);
--- a/sys/src/cmd/hjfs/fs1.c
+++ b/sys/src/cmd/hjfs/fs1.c
@@ -211,7 +211,7 @@
 error:
 	if(ch != nil)
 		chanclunk(ch);
-	dprint("writeusers: %r\n");
+	dprint("hjfs: writeusers: %r\n");
 }
 
 void
@@ -449,7 +449,7 @@
 		if((l->flags & LGONE) != 0){
 			/*
 			 * safe to unlock here, the file is gone and
-			 * we'r the last reference.
+			 * we're the last reference.
 			 */
 			qunlock(&fs->loctree);
 			b = getbuf(fs->d, l->blk, TDENTRY, 0);
--- a/sys/src/cmd/hjfs/fs2.c
+++ b/sys/src/cmd/hjfs/fs2.c
@@ -100,7 +100,6 @@
 	return p - name < NAMELEN;
 }
 
-
 int
 chancreat(Chan *ch, char *name, int perm, int mode)
 {
--- a/sys/src/cmd/hjfs/mkfile
+++ b/sys/src/cmd/hjfs/mkfile
@@ -13,6 +13,7 @@
 	9p.$O\
 	dump.$O\
 	cons.$O\
+	check.$O\
 
 HFILES=\
 	dat.h\