diff --git a/bootmain.c b/bootmain.c index 1882aa8..6494c16 100644 --- a/bootmain.c +++ b/bootmain.c @@ -12,7 +12,7 @@ // BOOT UP STEPS // * when the CPU boots it loads the BIOS into memory and executes it // -// * the BIOS intializes devices, sets of the interrupt routines, and +// * the BIOS intializes devices, sets up the interrupt routines, and // reads the first sector of the boot device(e.g., hard-drive) // into memory and jumps to it. // diff --git a/fs.c b/fs.c index e47b6fa..a6e1787 100644 --- a/fs.c +++ b/fs.c @@ -475,6 +475,7 @@ namecmp(const char *s, const char *t) // Look for a directory entry in a directory. // If found, set *poff to byte offset of entry. +// Caller must have already locked dp. struct uinode* dirlookup(struct inode *dp, char *name, uint *poff) { @@ -483,7 +484,7 @@ dirlookup(struct inode *dp, char *name, uint *poff) struct dirent *de; if(dp->type != T_DIR) - return 0; + panic("dirlookup not DIR"); for(off = 0; off < dp->size; off += BSIZE){ bp = bread(dp->dev, bmap(dp, off / BSIZE, 0)); @@ -558,7 +559,7 @@ dirlink(struct inode *dp, char *name, uint ino) // // Examples: // skipelem("a/bb/c", name) = "bb/c", setting name = "a" -// skipelem("///a/bb", name) = "b", setting name="a" +// skipelem("///a/bb", name) = "bb", setting name="a" // skipelem("", name) = skipelem("////", name) = 0 // static char* @@ -617,14 +618,15 @@ _namei(char *path, int parent, char *name) if((ipu = dirlookup(dp, name, &off)) == 0){ iput(iunlock(dp)); - iput(ipu); return 0; } iput(iunlock(dp)); dpu = ipu; } - if(parent) + if(parent){ + iput(dpu); return 0; + } return dpu; } diff --git a/mkfs.c b/mkfs.c index 462c270..b367f61 100644 --- a/mkfs.c +++ b/mkfs.c @@ -8,8 +8,8 @@ #include "param.h" #include "fs.h" -int nblocks = 1008; -int ninodes = 100; +int nblocks = 995; +int ninodes = 200; int size = 1024; int fsfd; diff --git a/param.h b/param.h index 7ceecb5..343288c 100644 --- a/param.h +++ b/param.h @@ -6,6 +6,6 @@ #define NFILE 100 // open files per system #define NBUF 10 // size of disk block cache #define NREQUEST NBUF // outstanding disk requests -#define NINODE 100 // maximum number of active i-nodes +#define NINODE 50 // maximum number of active i-nodes #define NDEV 10 // maximum major device number #define ROOTDEV 1 // device number of file system root disk diff --git a/proc.h b/proc.h index 9750c15..137bda3 100644 --- a/proc.h +++ b/proc.h @@ -43,19 +43,15 @@ struct proc { char name[16]; // Process name (debugging) }; -// Process memory is laid out contiguously: +// Process memory is laid out contiguously, low addresses first: // text // original data and bss // fixed-size stack // expandable heap -// If xv6 was only for uniprocessors, this could be -// struct proc *cp; -// Instead we have an array curproc, one per -// processor, and #define cp to the right element -// in the array. In general such preprocessor -// subterfuge is to be avoided, but cp is used -// so often that having the shorthand is worth the ugliness. +// Arrange that cp point to the struct proc that this +// CPU is currently running. Such preprocessor +// subterfuge can be confusing, but saves a lot of typing. extern struct proc *curproc[NCPU]; // Current (running) process per CPU #define cp (curproc[cpu()]) // Current process on this CPU diff --git a/runoff b/runoff index 092c8b6..3869391 100755 --- a/runoff +++ b/runoff @@ -18,7 +18,7 @@ files=`grep -v '^#' runoff.list | awk '{print $1}'` n=99 for i in $files do - runoff1 -n $n $i >fmt/$i + ./runoff1 -n $n $i >fmt/$i nn=`tail -1 fmt/$i | sed 's/ .*//; s/^0*//'` if [ "x$nn" != x ]; then n=$nn diff --git a/usertests.c b/usertests.c index 7132666..3a9cd9a 100644 --- a/usertests.c +++ b/usertests.c @@ -1096,6 +1096,99 @@ rmdot(void) printf(1, "rmdot ok\n"); } +void +dirfile(void) +{ + int fd; + + printf(1, "dir vs file\n"); + + fd = open("dirfile", O_CREATE); + if(fd < 0){ + printf(1, "create dirfile failed\n"); + exit(); + } + close(fd); + if(chdir("dirfile") == 0){ + printf(1, "chdir dirfile succeeded!\n"); + exit(); + } + fd = open("dirfile/xx", 0); + if(fd >= 0){ + printf(1, "create dirfile/xx succeeded!\n"); + exit(); + } + fd = open("dirfile/xx", O_CREATE); + if(fd >= 0){ + printf(1, "create dirfile/xx succeeded!\n"); + exit(); + } + if(mkdir("dirfile/xx") == 0){ + printf(1, "mkdir dirfile/xx succeeded!\n"); + exit(); + } + if(unlink("dirfile/xx") == 0){ + printf(1, "unlink dirfile/xx succeeded!\n"); + exit(); + } + if(link("README", "dirfile/xx") == 0){ + printf(1, "link to dirfile/xx succeeded!\n"); + exit(); + } + if(unlink("dirfile") != 0){ + printf(1, "unlink dirfile failed!\n"); + exit(); + } + + fd = open(".", O_RDWR); + if(fd >= 0){ + printf(1, "open . for writing succeeded!\n"); + exit(); + } + fd = open(".", 0); + if(write(fd, "x", 1) > 0){ + printf(1, "write . succeeded!\n"); + exit(); + } + close(fd); + + printf(1, "dir vs file OK\n"); +} + +// test that iput() is called at the end of _namei() +void +iref(void) +{ + int i, fd; + + printf(1, "empty file name\n"); + + // the 50 is NINODE + for(i = 0; i < 50 + 1; i++){ + if(mkdir("irefd") != 0){ + printf(1, "mkdir irefd failed\n"); + exit(); + } + if(chdir("irefd") != 0){ + printf(1, "chdir irefd failed\n"); + exit(); + } + + mkdir(""); + link("README", ""); + fd = open("", O_CREATE); + if(fd >= 0) + close(fd); + fd = open("xx", O_CREATE); + if(fd >= 0) + close(fd); + unlink("xx"); + } + + chdir("/"); + printf(1, "empty file name OK\n"); +} + int main(int argc, char *argv[]) { @@ -1128,6 +1221,8 @@ main(int argc, char *argv[]) createdelete(); twofiles(); sharedfd(); + dirfile(); + iref(); exectest();