From 12abb1a56164a0d71fb7a76a465c912409f2f60b Mon Sep 17 00:00:00 2001 From: Robert Morris Date: Fri, 14 Oct 2011 10:23:23 -0400 Subject: [PATCH 1/2] don't let dirty blocks be evicted from cache! --- bio.c | 4 ++-- file.c | 8 ++++++-- log.c | 1 + sysfile.c | 6 ++++++ 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/bio.c b/bio.c index 88b0964..de1d0f2 100644 --- a/bio.c +++ b/bio.c @@ -79,9 +79,9 @@ bget(uint dev, uint sector) } } - // Not cached; recycle some existing buffer. + // Not cached; recycle some non-busy and clean buffer. for(b = bcache.head.prev; b != &bcache.head; b = b->prev){ - if((b->flags & B_BUSY) == 0){ + if((b->flags & B_BUSY) == 0 && (b->flags & B_DIRTY) == 0){ b->dev = dev; b->sector = sector; b->flags = B_BUSY; diff --git a/file.c b/file.c index 3fd2cbe..53c5af2 100644 --- a/file.c +++ b/file.c @@ -1,3 +1,7 @@ +// +// File descriptors +// + #include "types.h" #include "defs.h" #include "param.h" @@ -87,7 +91,7 @@ filestat(struct file *f, struct stat *st) return -1; } -// Read from file f. Addr is kernel address. +// Read from file f. int fileread(struct file *f, char *addr, int n) { @@ -108,7 +112,7 @@ fileread(struct file *f, char *addr, int n) } //PAGEBREAK! -// Write to file f. Addr is kernel address. +// Write to file f. int filewrite(struct file *f, char *addr, int n) { diff --git a/log.c b/log.c index 5b827de..1814edc 100644 --- a/log.c +++ b/log.c @@ -177,6 +177,7 @@ log_write(struct buf *b) brelse(lbuf); if (i == log.lh.n) log.lh.n++; + b->flags |= B_DIRTY; // XXX prevent eviction } //PAGEBREAK! diff --git a/sysfile.c b/sysfile.c index 9de3d86..e6d08e8 100644 --- a/sysfile.c +++ b/sysfile.c @@ -1,3 +1,9 @@ +// +// File-system system calls. +// Mostly argument checking, since we don't trust +// user code, and calls into file.c and fs.c. +// + #include "types.h" #include "defs.h" #include "param.h" From 9d59eb015141697da616a4b98ac27cf4269cd780 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Fri, 17 Feb 2012 23:20:13 -0500 Subject: [PATCH 2/2] Make fetchint and fetchstr use proc instead of taking a struct proc Previously, these were inconsistent: they used their struct proc argument for bounds checking, but always copied the argument from the current address space (and hence the current process). Drop the struct proc argument and always use the current proc. Suggested by Carmi Merimovich. --- defs.h | 4 ++-- syscall.c | 18 +++++++++--------- sysfile.c | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/defs.h b/defs.h index efbbe3d..7f1e88d 100644 --- a/defs.h +++ b/defs.h @@ -142,8 +142,8 @@ char* strncpy(char*, const char*, int); int argint(int, int*); int argptr(int, char**, int); int argstr(int, char**); -int fetchint(struct proc*, uint, int*); -int fetchstr(struct proc*, uint, char**); +int fetchint(uint, int*); +int fetchstr(uint, char**); void syscall(void); // timer.c diff --git a/syscall.c b/syscall.c index 0918da7..45f758e 100644 --- a/syscall.c +++ b/syscall.c @@ -13,28 +13,28 @@ // library system call function. The saved user %esp points // to a saved program counter, and then the first argument. -// Fetch the int at addr from process p. +// Fetch the int at addr from the current process. int -fetchint(struct proc *p, uint addr, int *ip) +fetchint(uint addr, int *ip) { - if(addr >= p->sz || addr+4 > p->sz) + if(addr >= proc->sz || addr+4 > proc->sz) return -1; *ip = *(int*)(addr); return 0; } -// Fetch the nul-terminated string at addr from process p. +// Fetch the nul-terminated string at addr from the current process. // Doesn't actually copy the string - just sets *pp to point at it. // Returns length of string, not including nul. int -fetchstr(struct proc *p, uint addr, char **pp) +fetchstr(uint addr, char **pp) { char *s, *ep; - if(addr >= p->sz) + if(addr >= proc->sz) return -1; *pp = (char*)addr; - ep = (char*)p->sz; + ep = (char*)proc->sz; for(s = *pp; s < ep; s++) if(*s == 0) return s - *pp; @@ -45,7 +45,7 @@ fetchstr(struct proc *p, uint addr, char **pp) int argint(int n, int *ip) { - return fetchint(proc, proc->tf->esp + 4 + 4*n, ip); + return fetchint(proc->tf->esp + 4 + 4*n, ip); } // Fetch the nth word-sized system call argument as a pointer @@ -74,7 +74,7 @@ argstr(int n, char **pp) int addr; if(argint(n, &addr) < 0) return -1; - return fetchstr(proc, addr, pp); + return fetchstr(addr, pp); } extern int sys_chdir(void); diff --git a/sysfile.c b/sysfile.c index e6d08e8..64f2b33 100644 --- a/sysfile.c +++ b/sysfile.c @@ -388,13 +388,13 @@ sys_exec(void) for(i=0;; i++){ if(i >= NELEM(argv)) return -1; - if(fetchint(proc, uargv+4*i, (int*)&uarg) < 0) + if(fetchint(uargv+4*i, (int*)&uarg) < 0) return -1; if(uarg == 0){ argv[i] = 0; break; } - if(fetchstr(proc, uarg, &argv[i]) < 0) + if(fetchstr(uarg, &argv[i]) < 0) return -1; } return exec(path, argv);