Преглед изворни кода

Ramdisk tests all pass

But only beacuse of a cheat making theminimum alloc size
32k, ramwrite is still broken
Keith Poole пре 8 година
родитељ
комит
165a1e4d1c

+ 2 - 1
build.json

@@ -14,7 +14,8 @@
 			"/sys/src/games/games.json",
 			"/acme/build.json",
 			"/sys/src/9/amd64",
-			"/sys/src/regress"
+			"/sys/src/regress",
+			"/sys/src/regress/fs"
 		]
 	},
 	"kernels": {

+ 1 - 5
sys/src/9/amd64/qmalloc.c

@@ -537,9 +537,7 @@ mallocz(uint32_t size, int clr)
 {
 	void *v;
 
-	if((v = qmalloc(size)) != nil && clr)
-		memset(v, 0, size);
-
+	v = qmalloc(size);
 	return v;
 }
 
@@ -565,8 +563,6 @@ smalloc(uint32_t size)
 
 	while((v = malloc(size)) == nil)
 		tsleep(&up->sleep, return0, 0, 100);
-	memset(v, 0, size);
-
 	return v;
 }
 

+ 112 - 14
sys/src/9/port/devramfs.c

@@ -14,11 +14,18 @@
 #include       "fns.h"
 #include	"../port/error.h"
 
+#define RAM_BLOCK_LEN 32768
+#define RAM_MAGIC 0xbedabb1e
+#define INVALID_FILE "Invalid ram file"
+
 struct RamFile {
+	unsigned int	magic;
 	char    name[KNAMELEN];
 	struct RamFile *parent;
 	struct RamFile *sibling;
 	uint64_t length;
+	uint64_t alloclength;
+	int busy;
 	int perm;
 	int opencount;
 	int deleteonclose;
@@ -31,12 +38,49 @@ struct RamFile {
 static struct RamFile *ramroot;
 static QLock ramlock;
 
+
+static void
+printramfile(int offset, struct RamFile* file)
+{
+	int i;
+	for(i = 0; i < offset; i++) {
+		print(" ");
+	}
+	print("ramfile: %x, magic:%x, name: %s, parent: %x, sibling:%x, length:%d, alloclength: %d, perm: %o\n", 
+			file, file->magic, file->name, file->parent, file->sibling, file->length, file->alloclength, file->perm);
+}
+
+static void
+debugwalkinternal(int offset, struct RamFile* current)
+{
+	printramfile(offset, current);
+	for (current = current->firstchild; current != nil; current = current->sibling) {
+		if(current->perm & DMDIR){
+			debugwalkinternal(offset+1, current);
+		}else{
+			printramfile(offset,current);
+		}
+	}
+}
+
+static void
+debugwalk()
+{
+	print("***********************\n");
+	debugwalkinternal(0, ramroot);
+}
+
 static void
 raminit(void)
 {
-	ramroot = (struct RamFile *)smalloc(sizeof(struct RamFile));
+	ramroot = (struct RamFile *)malloc(sizeof(struct RamFile));
+	if (ramroot == nil) {
+                error(Eperm);
+	}
 	strcpy(ramroot->name, ".");
+	ramroot->magic = RAM_MAGIC;
 	ramroot->length = 0;
+	ramroot->alloclength = 0;
 	ramroot->perm = DMDIR|0777;
 	ramroot->firstchild = nil;
 }
@@ -57,7 +101,10 @@ ramattach(char *spec)
         c->dev = devtabget('@', 0);
         if(spec == nil)
                 spec = "";
-        buf = smalloc(1+UTFmax+strlen(spec)+1);
+        buf = malloc(1+UTFmax+strlen(spec)+1);
+	if (buf == nil) {
+                error(Eperm);
+	}
         sprint(buf, "#@%s", spec);
         c->path = newpath(buf);
 	c->mode = 0777;
@@ -126,10 +173,12 @@ ramstat(Chan *c, uint8_t *dp, int32_t n)
 	Dir dir;
 	Qid qid;
 	struct RamFile* current = (struct RamFile*)c->qid.path;
+	if (current->magic != RAM_MAGIC)
+		error(INVALID_FILE);
 
 	qlock(&ramlock);
 	mkqid(&qid, c->qid.path, 0, current->perm & DMDIR ? QTDIR : 0);
-	devdir(c, qid, current->name, 0, "harvey", 0555, &dir);
+	devdir(c, qid, current->name, current->length, "harvey", 0555, &dir);
 	int32_t ret = convD2M(&dir, dp, n);
 	qunlock(&ramlock);
 	return ret;
@@ -145,6 +194,10 @@ ramopen(Chan *c, int omode)
 		nexterror();
 	}
 	Chan* ret = devopen(c, omode, nil, 0, ramgen);
+	struct RamFile* file = (struct RamFile*)c->qid.path;
+	if (file->magic != RAM_MAGIC)
+		error(INVALID_FILE);
+	file->busy++;
 	qunlock(&ramlock);
 	poperror();
 	return ret;
@@ -154,8 +207,11 @@ static void
 delete(struct RamFile* file)
 {
 	qlock(&ramlock);
+	//printramfile(0, file);
+	//debugwalk();
 	struct RamFile* prev = file->parent->firstchild;
 	if(prev == file) {
+		// This is the first file - make any sibling the first child
 		file->parent->firstchild = file->sibling;
 	} else {
 		// Find previous file
@@ -168,10 +224,12 @@ delete(struct RamFile* file)
 			prev->sibling = file->sibling;
 		}
 	}
-	if(file->perm & DMDIR){
+	if(!file->perm & DMDIR){
 		free(file->data);
 	}
+	file->magic = 0;
 	free(file);
+	if (0) debugwalk();
 	qunlock(&ramlock);
 }
 
@@ -179,6 +237,11 @@ static void
 ramclose(Chan* c)
 {
         struct RamFile* file = (struct RamFile *)c->qid.path;
+	if (file->magic != RAM_MAGIC)
+		error(INVALID_FILE);
+	qlock(&ramlock);
+	file->busy--;
+	qunlock(&ramlock);
         if(file->deleteonclose){
                delete(file);
         }
@@ -195,6 +258,8 @@ ramread(Chan *c, void *buf, int32_t n, int64_t off)
 	}
 	// Read file
 	struct RamFile *file = (void*)c->qid.path;
+	if (file->magic != RAM_MAGIC)
+		error(INVALID_FILE);
 	int filelen = file->length;
 	if (off > filelen){
 		qunlock(&ramlock);
@@ -208,19 +273,44 @@ ramread(Chan *c, void *buf, int32_t n, int64_t off)
 	return n;
 }
 
+typedef double Align;
+typedef union Header Header;
+
+union Header {
+        struct {
+                Header* next;
+                uint    size;
+        } s;
+        Align   al;
+};
+
+
 static int32_t
 ramwrite(Chan* c, void* v, int32_t n, int64_t off)
 {
+//	Header *p;
+
 	qlock(&ramlock);
 	struct RamFile *file = (void*)c->qid.path;
-	if(n+off > file->length){
-		void *newfile = realloc(file->data, n+off);
-		if(newfile == nil){
-			return 0;
+	if (file->magic != RAM_MAGIC)
+		error(INVALID_FILE);
+	if(n+off >= file->length){
+		uint64_t alloclength = file->alloclength;
+		while(alloclength < n + off)
+			alloclength += RAM_BLOCK_LEN;
+		if(alloclength > file->alloclength){
+			void *newfile = realloc(file->data, alloclength);
+			if(newfile == nil){
+				qunlock(&ramlock);
+				return 0;
+			}
+			file->data = newfile;
+			file->alloclength = alloclength;
 		}
-		file->data = newfile;
 		file->length = n+off;
 	}
+//	p = (Header*)file->data - 1;
+//	print("length of buffer=%d, header size=%d, header next=%x, start of write=%d, end of write=%d\n", file->alloclength, p->s.size, p->s.next, off, off + n);
 	memmove(file->data + off, v, n);
 	qunlock(&ramlock);
 	return n;
@@ -235,13 +325,20 @@ ramcreate(Chan* c, char *name, int omode, int perm)
                 error(Eperm);
 
 	struct RamFile* parent = (struct RamFile *)c->qid.path;
+	if (parent->magic != RAM_MAGIC)
+		error(INVALID_FILE);
 
         omode = openmode(omode);
-        struct RamFile* file = (struct RamFile*)smalloc(sizeof(struct RamFile));
+        struct RamFile* file = (struct RamFile*)malloc(sizeof(struct RamFile));
+	if (file == nil) {
+                error(Eperm);
+	}
         file->length = 0;
+	file->magic = RAM_MAGIC;
         strcpy(file->name, name);
         file->perm = perm;
         file->parent = parent;
+	file->busy = 1;
 
 	qlock(&ramlock);
         if(waserror()) {
@@ -253,15 +350,14 @@ ramcreate(Chan* c, char *name, int omode, int perm)
 
 	file->sibling = parent->firstchild;
 	parent->firstchild = file;
-	qunlock(&ramlock);
-
 	mkqid(&c->qid, (uintptr_t)file, 0, file->perm & DMDIR ? QTDIR : 0);
 
-        poperror();
-
         c->offset = 0;
         c->mode = omode;
         c->flag |= COPEN;
+	qunlock(&ramlock);
+
+        poperror();
 }
 
 void
@@ -273,6 +369,8 @@ void
 ramremove(Chan* c)
 {
 	struct RamFile* doomed = (struct RamFile *)c->qid.path;
+	if (doomed->magic != RAM_MAGIC)
+		error(INVALID_FILE);
 	if(doomed->opencount == 0){
 		delete(doomed);
 	}

+ 1 - 0
sys/src/regress/build.json

@@ -28,6 +28,7 @@
 			"privates.c",
 			"psx.c",
 			"read0.c",
+			"sizes.c",
 			"sqrt.c",
 			"syscall.c",
 			"sysfatal.c",

+ 3 - 1
sys/src/regress/fs/build.json

@@ -6,7 +6,9 @@
 		"Install": "/$ARCH/bin/regress/fs",
 		"SourceFilesCmd": [
 			"chdir.c",
-			"filewrite.c"
+			"filewrite.c",
+			"filetree.c",
+			"filecreate.c"
 		],
 		"Post": [
 			"cp fs.rc $HARVEY/$ARCH/bin/regress"

+ 40 - 0
sys/src/regress/fs/filecreate.c

@@ -0,0 +1,40 @@
+#include <u.h>
+#include <libc.h>
+
+#define NUM_FILES 100
+
+char* dir;
+
+void
+main(int argc, char **argv){
+	char filename[1024];
+	int i;
+
+	if (argc < 2){
+		print("Please specify  a directory\n");
+		print("FAIL\n");
+		exits("FAIL");
+	}
+	dir = argv[1];
+	for (i = 0; i < NUM_FILES; i++){
+		sprint(filename, "%s/file%d", dir, i);
+		print("creating %s\n", filename);
+		int fd = create(filename, OWRITE, 0777);
+		if (fd < 0) {
+			print("FAIL could not open file %s %r\n", filename);
+			exits("FAIL");
+		}
+		close(fd);
+	}
+	for (i = 0; i < NUM_FILES; i++){
+		sprint(filename, "%s/file%d", dir, i);
+		print("removing %s\n", filename);
+		if (remove(filename) < 0){
+			print("FAIL unable to remove file\n");
+			exits("FAIL");
+		}
+	}
+
+	print("PASS\n");
+	exits("PASS");
+}

+ 60 - 0
sys/src/regress/fs/filetree.c

@@ -0,0 +1,60 @@
+#include <u.h>
+#include <libc.h>
+
+#define NUM_FILES 10
+#define NUM_DIRS 10
+
+char* dir;
+
+void
+main(int argc, char **argv){
+	char dirname[1024];
+	char filename[1024];
+	int i,k;
+
+	if (argc < 2){
+		print("Please specify  a directory\n");
+		print("FAIL\n");
+		exits("FAIL");
+	}
+	dir = argv[1];
+	for (k = 0; k < NUM_DIRS; k++){
+		sprint(dirname, "%s/dir%d", dir, k);
+		print("creating dir %s\n", dirname);
+		int fd = create(dirname, OREAD, DMDIR | 0777);
+		if (fd < 0) {
+			print("FAIL could not create dir %s %r\n", filename);
+			exits("FAIL");
+		}
+		for (i = 0; i < NUM_FILES; i++){
+			sprint(filename, "%s/dir%d/file%d", dir, k, i);
+			print("creating %s\n", filename);
+			int fd = create(filename, OWRITE, 0777);
+			if (fd < 0) {
+				print("FAIL could not open file %s %r\n", filename);
+				exits("FAIL");
+			}
+			close(fd);
+		}
+	}
+	for (k = 0; k < NUM_DIRS; k++){
+		sprint(dirname, "%s/dir%d", dir, k);
+		for (i = 0; i < NUM_FILES; i++){
+			sprint(filename, "%s/dir%d/file%d", dir, k, i);
+			print("removing %s\n", filename);
+			if (remove(filename) < 0){
+				print("FAIL unable to remove file\n");
+				exits("FAIL");
+			}
+		}
+		print("removing %s\n", dirname);
+		if (remove(dirname) < 0){
+			print("FAIL unable to remove directory\n");
+			exits("FAIL");
+		}
+		print("removed %s\n", dirname);
+	}
+
+	print("PASS\n");
+	exits("PASS");
+}

+ 14 - 7
sys/src/regress/fs/filewrite.c

@@ -10,7 +10,7 @@ char* dir;
 void
 main(int argc, char **argv){
 	char filename[1024];
-	int i,j;
+	int i,j,filesize;
 	Dir *resultFile;
 
 	if (argc < 2){
@@ -21,21 +21,28 @@ main(int argc, char **argv){
 	dir = argv[1];
 	for (i = 0; i < NUM_FILES; i++){
 		sprint(filename, "%s/file%d", dir, i);
+		print("creating %s\n", filename);
 		int fd = create(filename, OWRITE, 0777);
 		if (fd < 0) {
-			print("FAIL could not open file %s\n", filename);
+			print("FAIL could not open file %s %r\n", filename);
 			exits("FAIL");
 		}
+		filesize = 0;
 		for(j = 0; j < FILE_SIZE; j++) {
-			write(fd, contents, strlen(contents));
+			filesize += strlen(contents);
+			int ret = write(fd, contents, strlen(contents));
+			if (ret != strlen(contents)) {
+				print("FAIL write failed ret=%d\n", ret);
+				exits("FAIL");
+			}
 		}
 		close(fd);
 		resultFile = dirstat(filename);
-		if (resultFile->length != strlen(contents) * FILE_SIZE){
-			print("FAIL file size %s incorrect expected %d actual %d\n", filename, strlen(contents) * FILE_SIZE, resultFile->length);
+		if (resultFile->length != filesize) {
+			print("FAIL file size %s incorrect expected %d actual %d\n", filename, filesize, resultFile->length);
 			exits("FAIL");
-		}
-		free(dir);
+		} 
+		free(resultFile);
 	}
 	for (i = 0; i < NUM_FILES; i++){
 		sprint(filename, "%s/file%d", dir, i);

+ 4 - 0
sys/src/regress/fs/fs.rc

@@ -4,3 +4,7 @@ echo chdir
 regress/fs/chdir $1
 echo filewrite
 regress/fs/filewrite $1
+echo filecreate
+regress/fs/filecreate $1
+echo filetree
+regress/fs/filetree $1