提交 0c0ab855 创建 作者: Frans Kaashoek's avatar Frans Kaashoek

Merge branch 'scale' of ssh://amsterdam.csail.mit.edu/home/am0/6.828/xv6 into scale

...@@ -5,6 +5,7 @@ OBJS = \ ...@@ -5,6 +5,7 @@ OBJS = \
exec.o\ exec.o\
file.o\ file.o\
fs.o\ fs.o\
namecache.o\
ide.o\ ide.o\
ioapic.o\ ioapic.o\
kalloc.o\ kalloc.o\
......
...@@ -43,6 +43,7 @@ int filewrite(struct file*, char*, int n); ...@@ -43,6 +43,7 @@ int filewrite(struct file*, char*, int n);
int dirlink(struct inode*, char*, uint); int dirlink(struct inode*, char*, uint);
struct inode* dirlookup(struct inode*, char*, uint*); struct inode* dirlookup(struct inode*, char*, uint*);
struct inode* ialloc(uint, short); struct inode* ialloc(uint, short);
struct inode* iget(uint dev, uint inum);
struct inode* idup(struct inode*); struct inode* idup(struct inode*);
void iinit(void); void iinit(void);
void ilock(struct inode*); void ilock(struct inode*);
...@@ -197,6 +198,12 @@ int copyin(struct vmap *, uint, void*, uint); ...@@ -197,6 +198,12 @@ int copyin(struct vmap *, uint, void*, uint);
int pagefault(struct vmap *, uint, uint); int pagefault(struct vmap *, uint, uint);
void clearpages(pde_t *pgdir, void *begin, void *end); void clearpages(pde_t *pgdir, void *begin, void *end);
// namecache.c
void nc_init();
struct inode * nc_lookup(struct inode *, char *);
void nc_insert(struct inode *, char *, struct inode *);
void nc_invalidate(struct inode *dir, char *name);
// number of elements in fixed-size array // number of elements in fixed-size array
#define NELEM(x) (sizeof(x)/sizeof((x)[0])) #define NELEM(x) (sizeof(x)/sizeof((x)[0]))
#define NULL 0 #define NULL 0
...@@ -146,8 +146,6 @@ iinit(void) ...@@ -146,8 +146,6 @@ iinit(void)
} }
} }
static struct inode* iget(uint dev, uint inum);
//PAGEBREAK! //PAGEBREAK!
// Allocate a new inode with the given type on device dev. // Allocate a new inode with the given type on device dev.
struct inode* struct inode*
...@@ -195,7 +193,7 @@ iupdate(struct inode *ip) ...@@ -195,7 +193,7 @@ iupdate(struct inode *ip)
// Find the inode with number inum on device dev // Find the inode with number inum on device dev
// and return the in-memory copy. // and return the in-memory copy.
static struct inode* struct inode*
iget(uint dev, uint inum) iget(uint dev, uint inum)
{ {
struct inode *ip, *empty; struct inode *ip, *empty;
...@@ -587,21 +585,30 @@ namex(char *path, int nameiparent, char *name) ...@@ -587,21 +585,30 @@ namex(char *path, int nameiparent, char *name)
ip = idup(proc->cwd); ip = idup(proc->cwd);
while((path = skipelem(path, name)) != 0){ while((path = skipelem(path, name)) != 0){
ilock(ip); // XXX do we need to ilock(ip)?
if(ip->type != T_DIR){ // hopefully not, would be nice to have
iunlockput(ip); // lock-free namecache hits.
return 0; next = 0;
} if(nameiparent == 0)
if(nameiparent && *path == '\0'){ next = nc_lookup(ip, name);
// Stop one level early. if(next == 0){
iunlock(ip); ilock(ip);
return ip; if(ip->type != T_DIR){
} iunlockput(ip);
if((next = dirlookup(ip, name, 0)) == 0){ return 0;
}
if(nameiparent && *path == '\0'){
// Stop one level early.
iunlock(ip);
return ip;
}
if((next = dirlookup(ip, name, 0)) == 0){
iunlockput(ip);
return 0;
}
nc_insert(ip, name, next);
iunlockput(ip); iunlockput(ip);
return 0;
} }
iunlockput(ip);
ip = next; ip = next;
} }
if(nameiparent){ if(nameiparent){
......
...@@ -105,8 +105,12 @@ kalloc(void) ...@@ -105,8 +105,12 @@ kalloc(void)
} }
if (r == 0) { if (r == 0) {
cprintf("kalloc: out of memory");
kmemprint(); kmemprint();
return 0;
#if 0
panic("out of memory"); panic("out of memory");
#endif
} }
mtrace_label_register(mtrace_label_block, mtrace_label_register(mtrace_label_block,
...@@ -182,7 +186,7 @@ morecore(uint nu) ...@@ -182,7 +186,7 @@ morecore(uint nu)
nu = 512; // we allocate nu * sizeof(Header) nu = 512; // we allocate nu * sizeof(Header)
} }
p = kalloc(); p = kalloc();
if(p == (char*)-1) if(p == 0)
return 0; return 0;
hp = (Header*)p; hp = (Header*)p;
hp->s.size = nu; hp->s.size = nu;
......
//
// file-system name cache
//
// to do:
// use ns.c namespaces
// invalidation (for rename, unlink)
// does directory inum need to be locked?
// need a lock to make table lookup and iget atomic?
// insert when file created, not just looked up
//
#include "types.h"
#include "defs.h"
#include "param.h"
#include "stat.h"
#include "mmu.h"
#include "spinlock.h"
#include "condvar.h"
#include "queue.h"
#include "proc.h"
#include "buf.h"
#include "fs.h"
#include "file.h"
struct spinlock nc_lock;
// map the tuple <dev,dinum,name> to cinum;
struct nce {
int valid;
uint dev;
uint dinum; // directory inumber
char name[DIRSIZ];
uint cinum; // child inumber
};
#define NCE 32
struct nce nce[NCE];
void
nc_init()
{
initlock(&nc_lock, "namecache");
}
// nc_lock must be held
struct nce *
nc_lookup1(struct inode *dir, char *name)
{
for(int i = 0; i < NCE; i++){
struct nce *e = &nce[i];
if(e->valid && e->dev == dir->dev && e->dinum == dir->inum &&
namecmp(name, e->name) == 0){
return e;
}
}
return 0;
}
struct inode *
nc_lookup(struct inode *dir, char *name)
{
uint inum = 0;
acquire(&nc_lock);
struct nce *e = nc_lookup1(dir, name);
if(e)
inum = e->cinum;
release(&nc_lock);
if(inum)
return iget(dir->dev, inum);
else
return 0;
}
void
nc_insert(struct inode *dir, char *name, struct inode *ip)
{
acquire(&nc_lock);
struct nce *e = nc_lookup1(dir, name);
if(e){
if(e->cinum != ip->inum)
panic("nc_insert change");
release(&nc_lock);
return;
}
for(int i = 0; i < NCE; i++){
e = &nce[i];
if(e->valid == 0){
e->valid = 1;
e->dev = dir->dev;
e->dinum = dir->inum;
strncpy(e->name, name, DIRSIZ);
e->cinum = ip->inum;
break;
}
}
release(&nc_lock);
}
void
nc_invalidate(struct inode *dir, char *name)
{
acquire(&nc_lock);
struct nce *e = nc_lookup1(dir, name);
if(e)
e->valid = 0;
release(&nc_lock);
}
...@@ -63,7 +63,7 @@ allocproc(void) ...@@ -63,7 +63,7 @@ allocproc(void)
// Allocate kernel stack if possible. // Allocate kernel stack if possible.
if((p->kstack = kalloc()) == 0){ if((p->kstack = kalloc()) == 0){
p->state = UNUSED; kmfree(p);
return 0; return 0;
} }
sp = p->kstack + KSTACKSIZE; sp = p->kstack + KSTACKSIZE;
......
...@@ -205,6 +205,7 @@ sys_unlink(void) ...@@ -205,6 +205,7 @@ sys_unlink(void)
dp->nlink--; dp->nlink--;
iupdate(dp); iupdate(dp);
} }
nc_invalidate(dp, name);
iunlockput(dp); iunlockput(dp);
ip->nlink--; ip->nlink--;
......
...@@ -259,13 +259,13 @@ struct { ...@@ -259,13 +259,13 @@ struct {
struct vmnode * struct vmnode *
vmn_alloc(uint npg, uint type) vmn_alloc(uint npg, uint type)
{ {
for(uint i = 0; i < sizeof(vmnodes.n) / sizeof(vmnodes.n[0]); i++) { for(uint i = 0; i < NELEM(vmnodes.n); i++) {
struct vmnode *n = &vmnodes.n[i]; struct vmnode *n = &vmnodes.n[i];
if(n->alloc == 0 && __sync_bool_compare_and_swap(&n->alloc, 0, 1)) { if(n->alloc == 0 && __sync_bool_compare_and_swap(&n->alloc, 0, 1)) {
if(npg > sizeof(n->page) / sizeof(n->page[0])) { if(npg > NELEM(n->page)) {
panic("vmnode too big\n"); panic("vmnode too big\n");
} }
for (uint i = 0; i < sizeof(n->page) / sizeof(n->page[0]); i++) for (uint i = 0; i < NELEM(n->page); i++)
n->page[i] = 0; n->page[i] = 0;
n->npages = npg; n->npages = npg;
n->ref = 0; n->ref = 0;
...@@ -347,10 +347,10 @@ vmn_copy(struct vmnode *n) ...@@ -347,10 +347,10 @@ vmn_copy(struct vmnode *n)
struct vmap * struct vmap *
vmap_alloc(void) vmap_alloc(void)
{ {
for(uint i = 0; i < sizeof(vmaps.m) / sizeof(vmaps.m[0]); i++) { for(uint i = 0; i < NELEM(vmaps.m); i++) {
struct vmap *m = &vmaps.m[i]; struct vmap *m = &vmaps.m[i];
if(m->alloc == 0 && __sync_bool_compare_and_swap(&m->alloc, 0, 1)) { if(m->alloc == 0 && __sync_bool_compare_and_swap(&m->alloc, 0, 1)) {
for(uint j = 0; j < sizeof(m->e) / sizeof(m->e[0]); j++){ for(uint j = 0; j < NELEM(m->e); j++){
m->e[j].n = 0; m->e[j].n = 0;
m->e[j].va_type = PRIVATE; m->e[j].va_type = PRIVATE;
m->e[j].lock.name = "vma"; m->e[j].lock.name = "vma";
...@@ -369,7 +369,7 @@ vmap_alloc(void) ...@@ -369,7 +369,7 @@ vmap_alloc(void)
static void static void
vmap_free(struct vmap *m) vmap_free(struct vmap *m)
{ {
for(uint i = 0; i < sizeof(m->e) / sizeof(m->e[0]); i++) { for(uint i = 0; i < NELEM(m->e); i++) {
if(m->e[i].n) if(m->e[i].n)
vmn_decref(m->e[i].n); vmn_decref(m->e[i].n);
} }
...@@ -398,7 +398,7 @@ vmap_overlap(struct vmap *m, uint start, uint len) ...@@ -398,7 +398,7 @@ vmap_overlap(struct vmap *m, uint start, uint len)
if(start + len < start) if(start + len < start)
panic("vmap_overlap bad len"); panic("vmap_overlap bad len");
for(uint i = 0; i < sizeof(m->e) / sizeof(m->e[0]); i++){ for(uint i = 0; i < NELEM(m->e); i++){
if(m->e[i].n){ if(m->e[i].n){
if(m->e[i].va_end <= m->e[i].va_start) if(m->e[i].va_end <= m->e[i].va_start)
panic("vmap_overlap bad vma"); panic("vmap_overlap bad vma");
...@@ -421,7 +421,7 @@ vmap_insert(struct vmap *m, struct vmnode *n, uint va_start) ...@@ -421,7 +421,7 @@ vmap_insert(struct vmap *m, struct vmnode *n, uint va_start)
return -1; return -1;
} }
for(uint i = 0; i < sizeof(m->e) / sizeof(m->e[0]); i++) { for(uint i = 0; i < NELEM(m->e); i++) {
if(m->e[i].n) if(m->e[i].n)
continue; continue;
__sync_fetch_and_add(&n->ref, 1); __sync_fetch_and_add(&n->ref, 1);
...@@ -442,7 +442,7 @@ vmap_remove(struct vmap *m, uint va_start, uint len) ...@@ -442,7 +442,7 @@ vmap_remove(struct vmap *m, uint va_start, uint len)
{ {
acquire(&m->lock); acquire(&m->lock);
uint va_end = va_start + len; uint va_end = va_start + len;
for(uint i = 0; i < sizeof(m->e) / sizeof(m->e[0]); i++) { for(uint i = 0; i < NELEM(m->e); i++) {
if(m->e[i].n && (m->e[i].va_start < va_end && m->e[i].va_end > va_start)) { if(m->e[i].n && (m->e[i].va_start < va_end && m->e[i].va_end > va_start)) {
if(m->e[i].va_start != va_start || m->e[i].va_end != va_end) { if(m->e[i].va_start != va_start || m->e[i].va_end != va_end) {
release(&m->lock); release(&m->lock);
...@@ -481,7 +481,7 @@ vmap_copy(struct vmap *m, int share) ...@@ -481,7 +481,7 @@ vmap_copy(struct vmap *m, int share)
return 0; return 0;
acquire(&m->lock); acquire(&m->lock);
for(uint i = 0; i < sizeof(m->e) / sizeof(m->e[0]); i++) { for(uint i = 0; i < NELEM(m->e); i++) {
if(m->e[i].n == 0) if(m->e[i].n == 0)
continue; continue;
c->e[i].va_start = m->e[i].va_start; c->e[i].va_start = m->e[i].va_start;
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论