提交 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 = \
exec.o\
file.o\
fs.o\
namecache.o\
ide.o\
ioapic.o\
kalloc.o\
......
......@@ -43,6 +43,7 @@ int filewrite(struct file*, char*, int n);
int dirlink(struct inode*, char*, uint);
struct inode* dirlookup(struct inode*, char*, uint*);
struct inode* ialloc(uint, short);
struct inode* iget(uint dev, uint inum);
struct inode* idup(struct inode*);
void iinit(void);
void ilock(struct inode*);
......@@ -197,6 +198,12 @@ int copyin(struct vmap *, uint, void*, uint);
int pagefault(struct vmap *, uint, uint);
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
#define NELEM(x) (sizeof(x)/sizeof((x)[0]))
#define NULL 0
......@@ -146,8 +146,6 @@ iinit(void)
}
}
static struct inode* iget(uint dev, uint inum);
//PAGEBREAK!
// Allocate a new inode with the given type on device dev.
struct inode*
......@@ -195,7 +193,7 @@ iupdate(struct inode *ip)
// Find the inode with number inum on device dev
// and return the in-memory copy.
static struct inode*
struct inode*
iget(uint dev, uint inum)
{
struct inode *ip, *empty;
......@@ -587,21 +585,30 @@ namex(char *path, int nameiparent, char *name)
ip = idup(proc->cwd);
while((path = skipelem(path, name)) != 0){
ilock(ip);
if(ip->type != T_DIR){
iunlockput(ip);
return 0;
}
if(nameiparent && *path == '\0'){
// Stop one level early.
iunlock(ip);
return ip;
}
if((next = dirlookup(ip, name, 0)) == 0){
// XXX do we need to ilock(ip)?
// hopefully not, would be nice to have
// lock-free namecache hits.
next = 0;
if(nameiparent == 0)
next = nc_lookup(ip, name);
if(next == 0){
ilock(ip);
if(ip->type != T_DIR){
iunlockput(ip);
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);
return 0;
}
iunlockput(ip);
ip = next;
}
if(nameiparent){
......
......@@ -105,8 +105,12 @@ kalloc(void)
}
if (r == 0) {
cprintf("kalloc: out of memory");
kmemprint();
return 0;
#if 0
panic("out of memory");
#endif
}
mtrace_label_register(mtrace_label_block,
......@@ -182,7 +186,7 @@ morecore(uint nu)
nu = 512; // we allocate nu * sizeof(Header)
}
p = kalloc();
if(p == (char*)-1)
if(p == 0)
return 0;
hp = (Header*)p;
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)
// Allocate kernel stack if possible.
if((p->kstack = kalloc()) == 0){
p->state = UNUSED;
kmfree(p);
return 0;
}
sp = p->kstack + KSTACKSIZE;
......
......@@ -205,6 +205,7 @@ sys_unlink(void)
dp->nlink--;
iupdate(dp);
}
nc_invalidate(dp, name);
iunlockput(dp);
ip->nlink--;
......
......@@ -259,13 +259,13 @@ struct {
struct vmnode *
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];
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");
}
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->npages = npg;
n->ref = 0;
......@@ -347,10 +347,10 @@ vmn_copy(struct vmnode *n)
struct vmap *
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];
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].va_type = PRIVATE;
m->e[j].lock.name = "vma";
......@@ -369,7 +369,7 @@ vmap_alloc(void)
static void
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)
vmn_decref(m->e[i].n);
}
......@@ -398,7 +398,7 @@ vmap_overlap(struct vmap *m, uint start, uint len)
if(start + len < start)
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].va_end <= m->e[i].va_start)
panic("vmap_overlap bad vma");
......@@ -421,7 +421,7 @@ vmap_insert(struct vmap *m, struct vmnode *n, uint va_start)
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)
continue;
__sync_fetch_and_add(&n->ref, 1);
......@@ -442,7 +442,7 @@ vmap_remove(struct vmap *m, uint va_start, uint len)
{
acquire(&m->lock);
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].va_start != va_start || m->e[i].va_end != va_end) {
release(&m->lock);
......@@ -481,7 +481,7 @@ vmap_copy(struct vmap *m, int share)
return 0;
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)
continue;
c->e[i].va_start = m->e[i].va_start;
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论