Cleanup and commenting source code
This commit is contained in:
parent
88cbddb3ad
commit
f86e4ad966
@ -40,9 +40,9 @@ src_amd64 = [
|
||||
|
||||
src_common = [
|
||||
"kern/copy.c",
|
||||
"kern/bufcache.c",
|
||||
"kern/debug.c",
|
||||
"kern/disk.c",
|
||||
"kern/diskcache.c",
|
||||
"kern/handle.c",
|
||||
"kern/ktime.c",
|
||||
"kern/ktimer.c",
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
#include <sys/thread.h>
|
||||
#include <sys/disk.h>
|
||||
#include <sys/diskcache.h>
|
||||
#include <sys/bufcache.h>
|
||||
#include <sys/vfs.h>
|
||||
#include <sys/elf64.h>
|
||||
|
||||
@ -163,7 +163,7 @@ void Machine_Init()
|
||||
PS2_Init();
|
||||
PCI_Init();
|
||||
IDE_Init();
|
||||
DiskCache_Init();
|
||||
BufCache_Init();
|
||||
|
||||
Disk *root = Disk_GetByID(0, 0);
|
||||
if (!root)
|
||||
|
@ -57,8 +57,17 @@ Console_Getc()
|
||||
Spinlock_Unlock(&consoles.keyLock);
|
||||
|
||||
// Support serial debugging if interrupts are disabled
|
||||
if (Serial_HasData())
|
||||
return Serial_Getc();
|
||||
if (Serial_HasData()) {
|
||||
char key = Serial_Getc();
|
||||
switch (key) {
|
||||
case '\r':
|
||||
return '\n';
|
||||
case 0x7f:
|
||||
return '\b';
|
||||
default:
|
||||
return key;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,7 +157,7 @@ Console_Read(Handle *handle, void *buf, uint64_t off, uint64_t len)
|
||||
{
|
||||
char c = Console_Getc();
|
||||
Console_Putc(c);
|
||||
CopyOut(&c, b+i, 1);
|
||||
Copy_Out(&c, b+i, 1);
|
||||
}
|
||||
|
||||
return len;
|
||||
@ -164,7 +173,7 @@ Console_Write(Handle *handle, void *buf, uint64_t off, uint64_t len)
|
||||
|
||||
while (len > nbytes) {
|
||||
uint64_t chunksz = len > 512 ? 512 : len;
|
||||
CopyIn(b + nbytes, &kbuf, chunksz);
|
||||
Copy_In(b + nbytes, &kbuf, chunksz);
|
||||
nbytes += chunksz;
|
||||
|
||||
for (i = 0; i < chunksz; i++)
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include <sys/kmem.h>
|
||||
#include <sys/spinlock.h>
|
||||
#include <sys/disk.h>
|
||||
#include <sys/diskcache.h>
|
||||
#include <sys/bufcache.h>
|
||||
#include <sys/vfs.h>
|
||||
#include <sys/dirent.h>
|
||||
#include <sys/thread.h>
|
||||
@ -43,7 +43,7 @@ O2FS_Mount(Disk *disk)
|
||||
{
|
||||
int status;
|
||||
VFS *fs = VFS_Alloc();
|
||||
DiskCacheEntry *entry;
|
||||
BufCacheEntry *entry;
|
||||
SuperBlock *sb;
|
||||
|
||||
ASSERT(sizeof(BDirEntry) == 512);
|
||||
@ -51,7 +51,7 @@ O2FS_Mount(Disk *disk)
|
||||
if (!fs)
|
||||
return NULL;
|
||||
|
||||
status = DiskCache_Read(disk, 0, &entry);
|
||||
status = BufCache_Read(disk, 0, &entry);
|
||||
if (status < 0) {
|
||||
Alert(o2fs, "O2FS: Disk cache read failed\n");
|
||||
return NULL;
|
||||
@ -61,13 +61,13 @@ O2FS_Mount(Disk *disk)
|
||||
sb = entry->buffer;
|
||||
if (memcmp(sb->magic, SUPERBLOCK_MAGIC, 8) != 0) {
|
||||
Alert(o2fs, "O2FS: Invalid file system\n");
|
||||
DiskCache_Release(entry);
|
||||
BufCache_Release(entry);
|
||||
return NULL;
|
||||
}
|
||||
if (sb->versionMajor != O2FS_VERSION_MAJOR ||
|
||||
sb->versionMinor != O2FS_VERSION_MINOR) {
|
||||
Alert(o2fs, "O2FS: Unsupported file system version\n");
|
||||
DiskCache_Release(entry);
|
||||
BufCache_Release(entry);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -87,7 +87,7 @@ O2FS_Mount(Disk *disk)
|
||||
status = O2FS_GetRoot(fs, &fs->root);
|
||||
if (status < 0) {
|
||||
Alert(o2fs, "O2FS: Mount failed");
|
||||
DiskCache_Release(entry);
|
||||
BufCache_Release(entry);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -107,9 +107,9 @@ O2FSLoadVNode(VFS *fs, ObjID *objid)
|
||||
int status;
|
||||
VNode *vn;
|
||||
BNode *bn;
|
||||
DiskCacheEntry *entry;
|
||||
BufCacheEntry *entry;
|
||||
|
||||
status = DiskCache_Read(fs->disk, objid->offset, &entry);
|
||||
status = BufCache_Read(fs->disk, objid->offset, &entry);
|
||||
if (status < 0) {
|
||||
Alert(o2fs, "O2FS: disk read error\n");
|
||||
return NULL;
|
||||
@ -118,13 +118,13 @@ O2FSLoadVNode(VFS *fs, ObjID *objid)
|
||||
bn = entry->buffer;
|
||||
if (memcmp(&bn->magic, BNODE_MAGIC, 8) != 0) {
|
||||
Alert(o2fs, "O2FS: bad BNode magic\n");
|
||||
DiskCache_Release(entry);
|
||||
BufCache_Release(entry);
|
||||
return NULL;
|
||||
}
|
||||
if (bn->versionMajor != O2FS_VERSION_MAJOR ||
|
||||
bn->versionMinor != O2FS_VERSION_MINOR) {
|
||||
Alert(o2fs, "O2FS: unsupported BNode version\n");
|
||||
DiskCache_Release(entry);
|
||||
BufCache_Release(entry);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -154,7 +154,7 @@ O2FSReleaseVNode(VNode *vn)
|
||||
{
|
||||
vn->refCount--;
|
||||
if (vn->refCount == 0) {
|
||||
DiskCache_Release(vn->fsptr);
|
||||
BufCache_Release(vn->fsptr);
|
||||
Spinlock_Destroy(&vn->lock);
|
||||
VNode_Free(vn);
|
||||
}
|
||||
@ -165,7 +165,7 @@ O2FS_GetRoot(VFS *fs, VNode **dn)
|
||||
{
|
||||
int status;
|
||||
VNode *vn;
|
||||
DiskCacheEntry *entry;
|
||||
BufCacheEntry *entry;
|
||||
BNode *bn;
|
||||
|
||||
if (fs->root) {
|
||||
@ -174,7 +174,7 @@ O2FS_GetRoot(VFS *fs, VNode **dn)
|
||||
return 0;
|
||||
}
|
||||
|
||||
status = DiskCache_Read(fs->disk, fs->fsval, &entry);
|
||||
status = BufCache_Read(fs->disk, fs->fsval, &entry);
|
||||
if (status < 0) {
|
||||
Alert(o2fs, "O2FS: disk read error\n");
|
||||
return status;
|
||||
@ -183,13 +183,13 @@ O2FS_GetRoot(VFS *fs, VNode **dn)
|
||||
bn = entry->buffer;
|
||||
if (memcmp(&bn->magic, BNODE_MAGIC, 8) != 0) {
|
||||
Alert(o2fs, "O2FS: bad BNode magic\n");
|
||||
DiskCache_Release(entry);
|
||||
BufCache_Release(entry);
|
||||
return -1;
|
||||
}
|
||||
if (bn->versionMajor != O2FS_VERSION_MAJOR ||
|
||||
bn->versionMinor != O2FS_VERSION_MINOR) {
|
||||
Alert(o2fs, "O2FS: unsupported BNode version\n");
|
||||
DiskCache_Release(entry);
|
||||
BufCache_Release(entry);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -217,9 +217,9 @@ O2FS_Lookup(VNode *dn, VNode **fn, const char *name)
|
||||
{
|
||||
int status;
|
||||
VFS *vfs = dn->vfs;
|
||||
DiskCacheEntry *sbEntry = (DiskCacheEntry *)vfs->fsptr;
|
||||
BufCacheEntry *sbEntry = (BufCacheEntry *)vfs->fsptr;
|
||||
SuperBlock *sb = sbEntry->buffer;
|
||||
DiskCacheEntry *dirEntry = (DiskCacheEntry *)dn->fsptr;
|
||||
BufCacheEntry *dirEntry = (BufCacheEntry *)dn->fsptr;
|
||||
BNode *dirBN = dirEntry->buffer;
|
||||
uint64_t blocks = (dirBN->size + sb->blockSize - 1) / sb->blockSize;
|
||||
uint64_t b;
|
||||
@ -230,9 +230,9 @@ O2FS_Lookup(VNode *dn, VNode **fn, const char *name)
|
||||
// Read block
|
||||
int e;
|
||||
int entryPerBlock = sb->blockSize / sizeof(BDirEntry);
|
||||
DiskCacheEntry *entry;
|
||||
BufCacheEntry *entry;
|
||||
BDirEntry *dir;
|
||||
status = DiskCache_Read(dn->disk, dirBN->direct[b].offset, &entry);
|
||||
status = BufCache_Read(dn->disk, dirBN->direct[b].offset, &entry);
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
@ -248,7 +248,7 @@ O2FS_Lookup(VNode *dn, VNode **fn, const char *name)
|
||||
}
|
||||
}
|
||||
|
||||
DiskCache_Release(entry);
|
||||
BufCache_Release(entry);
|
||||
}
|
||||
|
||||
return -1;
|
||||
@ -270,9 +270,9 @@ int
|
||||
O2FS_Stat(VNode *fn, struct stat *statinfo)
|
||||
{
|
||||
VFS *vfs = fn->vfs;
|
||||
DiskCacheEntry *sbEntry = (DiskCacheEntry *)vfs->fsptr;
|
||||
BufCacheEntry *sbEntry = (BufCacheEntry *)vfs->fsptr;
|
||||
SuperBlock *sb = sbEntry->buffer;
|
||||
DiskCacheEntry *fileEntry = (DiskCacheEntry *)fn->fsptr;
|
||||
BufCacheEntry *fileEntry = (BufCacheEntry *)fn->fsptr;
|
||||
BNode *fileBN = fileEntry->buffer;
|
||||
|
||||
statinfo->st_size = fileBN->size;
|
||||
@ -288,9 +288,9 @@ O2FS_Read(VNode *fn, void *buf, uint64_t off, uint64_t len)
|
||||
{
|
||||
int status;
|
||||
VFS *vfs = fn->vfs;
|
||||
DiskCacheEntry *sbEntry = (DiskCacheEntry *)vfs->fsptr;
|
||||
BufCacheEntry *sbEntry = (BufCacheEntry *)vfs->fsptr;
|
||||
SuperBlock *sb = sbEntry->buffer;
|
||||
DiskCacheEntry *fileEntry = (DiskCacheEntry *)fn->fsptr;
|
||||
BufCacheEntry *fileEntry = (BufCacheEntry *)fn->fsptr;
|
||||
BNode *fileBN = fileEntry->buffer;
|
||||
uint64_t blocks = (fileBN->size + sb->blockSize - 1) / sb->blockSize;
|
||||
uint64_t readBytes = 0;
|
||||
@ -309,7 +309,7 @@ O2FS_Read(VNode *fn, void *buf, uint64_t off, uint64_t len)
|
||||
uint64_t b = off / sb->blockSize;
|
||||
uint64_t bOff = off % sb->blockSize;
|
||||
uint64_t bLen;
|
||||
DiskCacheEntry *entry;
|
||||
BufCacheEntry *entry;
|
||||
|
||||
if (bOff + len > sb->blockSize) {
|
||||
bLen = sb->blockSize - bOff;
|
||||
@ -317,12 +317,12 @@ O2FS_Read(VNode *fn, void *buf, uint64_t off, uint64_t len)
|
||||
bLen = len;
|
||||
}
|
||||
|
||||
status = DiskCache_Read(fn->disk, fileBN->direct[b].offset, &entry);
|
||||
status = BufCache_Read(fn->disk, fileBN->direct[b].offset, &entry);
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
memcpy(buf, entry->buffer + bOff, bLen);
|
||||
DiskCache_Release(entry);
|
||||
BufCache_Release(entry);
|
||||
|
||||
readBytes += bLen;
|
||||
buf += bLen;
|
||||
@ -348,7 +348,7 @@ O2FS_ReadDir(VNode *fn, void *buf, uint64_t len, uint64_t *off)
|
||||
{
|
||||
int count = 0;
|
||||
int status;
|
||||
DiskCacheEntry *fileEntry = (DiskCacheEntry *)fn->fsptr;
|
||||
BufCacheEntry *fileEntry = (BufCacheEntry *)fn->fsptr;
|
||||
BNode *fileBN = fileEntry->buffer;
|
||||
BDirEntry dirEntry;
|
||||
struct dirent de;
|
||||
@ -370,7 +370,7 @@ O2FS_ReadDir(VNode *fn, void *buf, uint64_t len, uint64_t *off)
|
||||
// XXX: Validation and fill in all fields
|
||||
strcpy(de.d_name, (char *)dirEntry.name);
|
||||
|
||||
status = CopyOut(&de, (uintptr_t)buf, sizeof(de));
|
||||
status = Copy_Out(&de, (uintptr_t)buf, sizeof(de));
|
||||
if (status != 0)
|
||||
return status;
|
||||
|
||||
|
23
sys/include/bufcache.h
Normal file
23
sys/include/bufcache.h
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
#ifndef __SYS_BUFCACHE_H__
|
||||
#define __SYS_BUFCACHE_H__
|
||||
|
||||
#include <sys/queue.h>
|
||||
|
||||
typedef struct BufCacheEntry {
|
||||
Disk *disk;
|
||||
uint64_t diskOffset;
|
||||
uint64_t refCount;
|
||||
void *buffer;
|
||||
TAILQ_ENTRY(BufCacheEntry) htEntry;
|
||||
TAILQ_ENTRY(BufCacheEntry) lruEntry;
|
||||
} BufCacheEntry;
|
||||
|
||||
void BufCache_Init();
|
||||
int BufCache_Alloc(Disk *disk, uint64_t diskOffset, BufCacheEntry **entry);
|
||||
void BufCache_Release(BufCacheEntry *entry);
|
||||
int BufCache_Read(Disk *disk, uint64_t diskOffset, BufCacheEntry **entry);
|
||||
int BufCache_Write(BufCacheEntry *entry);
|
||||
|
||||
#endif /* __SYS_BUFCACHE_H__ */
|
||||
|
@ -1,23 +0,0 @@
|
||||
|
||||
#ifndef __SYS_DISKCACHE_H__
|
||||
#define __SYS_DISKCACHE_H__
|
||||
|
||||
#include <sys/queue.h>
|
||||
|
||||
typedef struct DiskCacheEntry {
|
||||
Disk *disk;
|
||||
uint64_t diskOffset;
|
||||
uint64_t refCount;
|
||||
void *buffer;
|
||||
TAILQ_ENTRY(DiskCacheEntry) htEntry;
|
||||
TAILQ_ENTRY(DiskCacheEntry) lruEntry;
|
||||
} DiskCacheEntry;
|
||||
|
||||
void DiskCache_Init();
|
||||
int DiskCache_Alloc(Disk *disk, uint64_t diskOffset, DiskCacheEntry **entry);
|
||||
void DiskCache_Release(DiskCacheEntry *entry);
|
||||
int DiskCache_Read(Disk *disk, uint64_t diskOffset, DiskCacheEntry **entry);
|
||||
int DiskCache_Write(DiskCacheEntry *entry);
|
||||
|
||||
#endif /* __SYS_DISKCACHE_H__ */
|
||||
|
@ -28,6 +28,9 @@
|
||||
#define SYSCALL_STAT 0x1D
|
||||
#define SYSCALL_READDIR 0x1E
|
||||
|
||||
// IPC
|
||||
#define SYSCALL_PIPE 0x20
|
||||
|
||||
// Threading
|
||||
#define SYSCALL_THREADCREATE 0x30
|
||||
#define SYSCALL_GETTID 0x31
|
||||
|
@ -123,11 +123,11 @@ uint64_t Handle_Add(Process *proc, Handle *handle);
|
||||
void Handle_Remove(Process *proc, Handle *handle);
|
||||
Handle *Handle_Lookup(Process *proc, uint64_t fd);
|
||||
|
||||
// CopyIn/CopyOut Functions
|
||||
int CopyIn(uintptr_t fromuser, void *tokernel, uintptr_t len);
|
||||
int CopyOut(void *fromkernel, uintptr_t touser, uintptr_t len);
|
||||
int CopyStrIn(uintptr_t fromuser, void *tokernel, uintptr_t len);
|
||||
int CopyStrOut(void *fromkernel, uintptr_t touser, uintptr_t len);
|
||||
// Copy_In/Copy_Out Functions
|
||||
int Copy_In(uintptr_t fromuser, void *tokernel, uintptr_t len);
|
||||
int Copy_Out(void *fromkernel, uintptr_t touser, uintptr_t len);
|
||||
int Copy_StrIn(uintptr_t fromuser, void *tokernel, uintptr_t len);
|
||||
int Copy_StrOut(void *fromkernel, uintptr_t touser, uintptr_t len);
|
||||
|
||||
#endif /* __SYS_THREAD_H__ */
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022 Ali Mashtizadeh
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
@ -8,55 +12,55 @@
|
||||
#include <sys/kmem.h>
|
||||
#include <sys/spinlock.h>
|
||||
#include <sys/disk.h>
|
||||
#include <sys/diskcache.h>
|
||||
#include <sys/bufcache.h>
|
||||
|
||||
Spinlock cacheLock;
|
||||
XMem *diskBuf;
|
||||
|
||||
static TAILQ_HEAD(CacheHashTable, DiskCacheEntry) *hashTable;
|
||||
static TAILQ_HEAD(LRUCacheList, DiskCacheEntry) lruList;
|
||||
static TAILQ_HEAD(CacheHashTable, BufCacheEntry) *hashTable;
|
||||
static TAILQ_HEAD(LRUCacheList, BufCacheEntry) lruList;
|
||||
static uint64_t cacheHit;
|
||||
static uint64_t cacheMiss;
|
||||
static uint64_t cacheAlloc;
|
||||
static Slab cacheEntrySlab;
|
||||
|
||||
DEFINE_SLAB(DiskCacheEntry, &cacheEntrySlab);
|
||||
DEFINE_SLAB(BufCacheEntry, &cacheEntrySlab);
|
||||
|
||||
#define CACHESIZE (16*1024*1024)
|
||||
#define HASHTABLEENTRIES 128
|
||||
#define BLOCKSIZE (16*1024)
|
||||
|
||||
void
|
||||
DiskCache_Init()
|
||||
BufCache_Init()
|
||||
{
|
||||
int i;
|
||||
|
||||
Spinlock_Init(&cacheLock, "DiskCache Lock", SPINLOCK_TYPE_NORMAL);
|
||||
Spinlock_Init(&cacheLock, "BufCache Lock", SPINLOCK_TYPE_NORMAL);
|
||||
|
||||
diskBuf = XMem_New();
|
||||
if (!diskBuf)
|
||||
Panic("DiskCache: Cannot create XMem region\n");
|
||||
Panic("BufCache: Cannot create XMem region\n");
|
||||
|
||||
if (!XMem_Allocate(diskBuf, CACHESIZE))
|
||||
Panic("DiskCache: Cannot back XMem region\n");
|
||||
Panic("BufCache: Cannot back XMem region\n");
|
||||
|
||||
TAILQ_INIT(&lruList);
|
||||
|
||||
hashTable = PAlloc_AllocPage();
|
||||
if (!hashTable)
|
||||
Panic("DiskCache: Cannot allocate hash table\n");
|
||||
Panic("BufCache: Cannot allocate hash table\n");
|
||||
for (i = 0; i < HASHTABLEENTRIES; i++) {
|
||||
TAILQ_INIT(&hashTable[i]);
|
||||
TAILQ_INIT(&hashTable[i]);
|
||||
}
|
||||
|
||||
Slab_Init(&cacheEntrySlab, "DiskCacheEntry Slab", sizeof(DiskCacheEntry), 16);
|
||||
Slab_Init(&cacheEntrySlab, "BufCacheEntry Slab", sizeof(BufCacheEntry), 16);
|
||||
|
||||
// Initialize cache
|
||||
uintptr_t bufBase = XMem_GetBase(diskBuf);
|
||||
for (i = 0; i < CACHESIZE/BLOCKSIZE; i++) {
|
||||
DiskCacheEntry *e = DiskCacheEntry_Alloc();
|
||||
BufCacheEntry *e = BufCacheEntry_Alloc();
|
||||
if (!e) {
|
||||
Panic("DiskCache: Cannot allocate cache entry\n");
|
||||
Panic("BufCache: Cannot allocate cache entry\n");
|
||||
}
|
||||
|
||||
memset(e, 0, sizeof(*e));
|
||||
@ -71,10 +75,10 @@ DiskCache_Init()
|
||||
}
|
||||
|
||||
static int
|
||||
DiskCacheLookup(Disk *disk, uint64_t diskOffset, DiskCacheEntry **entry)
|
||||
BufCacheLookup(Disk *disk, uint64_t diskOffset, BufCacheEntry **entry)
|
||||
{
|
||||
struct CacheHashTable *table;
|
||||
DiskCacheEntry *e;
|
||||
BufCacheEntry *e;
|
||||
|
||||
// Check hash table
|
||||
table = &hashTable[diskOffset % HASHTABLEENTRIES];
|
||||
@ -94,15 +98,15 @@ DiskCacheLookup(Disk *disk, uint64_t diskOffset, DiskCacheEntry **entry)
|
||||
}
|
||||
|
||||
static int
|
||||
DiskCacheAlloc(Disk *disk, uint64_t diskOffset, DiskCacheEntry **entry)
|
||||
BufCacheAlloc(Disk *disk, uint64_t diskOffset, BufCacheEntry **entry)
|
||||
{
|
||||
struct CacheHashTable *table;
|
||||
DiskCacheEntry *e;
|
||||
BufCacheEntry *e;
|
||||
|
||||
// Allocate from LRU list
|
||||
e = TAILQ_FIRST(&lruList);
|
||||
if (e == NULL) {
|
||||
kprintf("DiskCache: No space left!\n");
|
||||
kprintf("BufCache: No space left!\n");
|
||||
return -1;
|
||||
}
|
||||
TAILQ_REMOVE(&lruList, e, lruEntry);
|
||||
@ -126,16 +130,24 @@ DiskCacheAlloc(Disk *disk, uint64_t diskOffset, DiskCacheEntry **entry)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* BufCache_Alloc --
|
||||
*
|
||||
* Allocate a buffer cache entry.
|
||||
*
|
||||
* Results:
|
||||
* Returns 0 if successful and sets the entry, otherwise returns an error code.
|
||||
*/
|
||||
int
|
||||
DiskCache_Alloc(Disk *disk, uint64_t diskOffset, DiskCacheEntry **entry)
|
||||
BufCache_Alloc(Disk *disk, uint64_t diskOffset, BufCacheEntry **entry)
|
||||
{
|
||||
int status;
|
||||
|
||||
Spinlock_Lock(&cacheLock);
|
||||
|
||||
status = DiskCacheLookup(disk, diskOffset, entry);
|
||||
status = BufCacheLookup(disk, diskOffset, entry);
|
||||
if (*entry == NULL) {
|
||||
status = DiskCacheAlloc(disk, diskOffset, entry);
|
||||
status = BufCacheAlloc(disk, diskOffset, entry);
|
||||
}
|
||||
|
||||
cacheAlloc++;
|
||||
@ -145,39 +157,56 @@ DiskCache_Alloc(Disk *disk, uint64_t diskOffset, DiskCacheEntry **entry)
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* BufCache_Release --
|
||||
*
|
||||
* Release a buffer cache entry. If no other references are held the
|
||||
* buffer cache entry is placed on the LRU list.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*/
|
||||
void
|
||||
DiskCache_Release(DiskCacheEntry *entry)
|
||||
BufCache_Release(BufCacheEntry *entry)
|
||||
{
|
||||
Spinlock_Lock(&cacheLock);
|
||||
|
||||
entry->refCount--;
|
||||
if (entry->refCount == 0) {
|
||||
TAILQ_INSERT_TAIL(&lruList, entry, lruEntry);
|
||||
TAILQ_INSERT_TAIL(&lruList, entry, lruEntry);
|
||||
}
|
||||
|
||||
Spinlock_Unlock(&cacheLock);
|
||||
}
|
||||
|
||||
/*
|
||||
* BufCache_Read --
|
||||
*
|
||||
* Read block from disk into the buffer cache.
|
||||
*
|
||||
* Results:
|
||||
* Returns 0 if successful, otherwise an error code is returned.
|
||||
*/
|
||||
int
|
||||
DiskCache_Read(Disk *disk, uint64_t diskOffset, DiskCacheEntry **entry)
|
||||
BufCache_Read(Disk *disk, uint64_t diskOffset, BufCacheEntry **entry)
|
||||
{
|
||||
int status;
|
||||
void *buf;
|
||||
SGArray sga;
|
||||
|
||||
Spinlock_Lock(&cacheLock);
|
||||
status = DiskCacheLookup(disk, diskOffset, entry);
|
||||
status = BufCacheLookup(disk, diskOffset, entry);
|
||||
if (*entry != NULL) {
|
||||
cacheHit++;
|
||||
Spinlock_Unlock(&cacheLock);
|
||||
return status;
|
||||
cacheHit++;
|
||||
Spinlock_Unlock(&cacheLock);
|
||||
return status;
|
||||
}
|
||||
cacheMiss++;
|
||||
|
||||
status = DiskCacheAlloc(disk, diskOffset, entry);
|
||||
status = BufCacheAlloc(disk, diskOffset, entry);
|
||||
if (status != 0) {
|
||||
Spinlock_Unlock(&cacheLock);
|
||||
return status;
|
||||
Spinlock_Unlock(&cacheLock);
|
||||
return status;
|
||||
}
|
||||
|
||||
buf = (*entry)->buffer;
|
||||
@ -194,8 +223,16 @@ DiskCache_Read(Disk *disk, uint64_t diskOffset, DiskCacheEntry **entry)
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* BufCache_Write --
|
||||
*
|
||||
* Write a buffer cache entry to disk.
|
||||
*
|
||||
* Results:
|
||||
* Returns 0 if successful, otherwise an error code is returned.
|
||||
*/
|
||||
int
|
||||
DiskCache_Write(DiskCacheEntry *entry)
|
||||
BufCache_Write(BufCacheEntry *entry)
|
||||
{
|
||||
void *buf = entry->buffer;
|
||||
SGArray sga;
|
||||
@ -207,12 +244,12 @@ DiskCache_Write(DiskCacheEntry *entry)
|
||||
}
|
||||
|
||||
static void
|
||||
Debug_DiskCache(int argc, const char *argv[])
|
||||
Debug_BufCache(int argc, const char *argv[])
|
||||
{
|
||||
kprintf("Hits: %lld\n", cacheHit);
|
||||
kprintf("Misses: %lld\n", cacheMiss);
|
||||
kprintf("Allocations: %lld\n", cacheAlloc);
|
||||
}
|
||||
|
||||
REGISTER_DBGCMD(diskcache, "Display disk cache statistics", Debug_DiskCache);
|
||||
REGISTER_DBGCMD(diskcache, "Display disk cache statistics", Debug_BufCache);
|
||||
|
@ -1,4 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022 Ali Mashtizadeh
|
||||
* All rights reserved.
|
||||
* Generic Copyin/Copyout routines
|
||||
*/
|
||||
|
||||
@ -13,84 +15,128 @@
|
||||
extern int copy_unsafe(void *to_addr, void *from_addr, uintptr_t len);
|
||||
extern int copystr_unsafe(void *to_addr, void *from_addr, uintptr_t len);
|
||||
|
||||
/*
|
||||
* Copy_In --
|
||||
* Safely copy memory from userspace. Prevents userspace pointers from
|
||||
* reading kernel memory.
|
||||
*
|
||||
* Results:
|
||||
* Returns EFAULT if the address is invalid or causes a fault.
|
||||
*
|
||||
* Side effects:
|
||||
* Kernel page fault may have occurred.
|
||||
*/
|
||||
int
|
||||
CopyIn(uintptr_t fromuser, void *tokernel, uintptr_t len)
|
||||
Copy_In(uintptr_t fromuser, void *tokernel, uintptr_t len)
|
||||
{
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
// Kernel space
|
||||
if (fromuser >= MEM_USERSPACE_TOP) {
|
||||
kprintf("CopyIn: address exceeds userspace top\n");
|
||||
kprintf("Copy_In: address exceeds userspace top\n");
|
||||
return EFAULT;
|
||||
}
|
||||
|
||||
// Wrap around
|
||||
if (len > (MEM_USERSPACE_TOP - fromuser)) {
|
||||
kprintf("CopyIn: length exceeds userspace top\n");
|
||||
kprintf("Copy_In: length exceeds userspace top\n");
|
||||
return EFAULT;
|
||||
}
|
||||
|
||||
return copy_unsafe(tokernel, (void *)fromuser, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy_Out --
|
||||
* Safely copy memory to userspace. Prevents userspace pointers from
|
||||
* writing kernel memory.
|
||||
*
|
||||
* Results:
|
||||
* Returns EFAULT if the address is invalid or causes a fault.
|
||||
*
|
||||
* Side effects:
|
||||
* Kernel page fault may have occurred.
|
||||
*/
|
||||
int
|
||||
CopyOut(void *fromkernel, uintptr_t touser, uintptr_t len)
|
||||
Copy_Out(void *fromkernel, uintptr_t touser, uintptr_t len)
|
||||
{
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
// Kernel space
|
||||
if (touser >= MEM_USERSPACE_TOP) {
|
||||
kprintf("CopyOut: address exceeds userspace top\n");
|
||||
kprintf("Copy_Out: address exceeds userspace top\n");
|
||||
return EFAULT;
|
||||
}
|
||||
|
||||
// Wrap around
|
||||
if (len > (MEM_USERSPACE_TOP - touser)) {
|
||||
kprintf("CopyOut: length exceeds userspace top\n");
|
||||
kprintf("Copy_Out: length exceeds userspace top\n");
|
||||
return EFAULT;
|
||||
}
|
||||
|
||||
return copy_unsafe((void *)touser, fromkernel, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy_StrIn --
|
||||
* Safely copy a string from userspace. Prevents userspace pointers from
|
||||
* reading kernel memory.
|
||||
*
|
||||
* Results:
|
||||
* Returns EFAULT if the address is invalid or causes a fault.
|
||||
*
|
||||
* Side effects:
|
||||
* Kernel page fault may have occurred.
|
||||
*/
|
||||
int
|
||||
CopyStrIn(uintptr_t fromuser, void *tokernel, uintptr_t len)
|
||||
Copy_StrIn(uintptr_t fromuser, void *tokernel, uintptr_t len)
|
||||
{
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
// Kernel space
|
||||
if (fromuser >= MEM_USERSPACE_TOP) {
|
||||
kprintf("CopyStrIn: address exceeds userspace top\n");
|
||||
kprintf("Copy_StrIn: address exceeds userspace top\n");
|
||||
return EFAULT;
|
||||
}
|
||||
|
||||
// Wrap around
|
||||
if (len > (MEM_USERSPACE_TOP - fromuser)) {
|
||||
kprintf("CopyStrIn: length exceeds userspace top\n");
|
||||
kprintf("Copy_StrIn: length exceeds userspace top\n");
|
||||
return EFAULT;
|
||||
}
|
||||
|
||||
return copystr_unsafe(tokernel, (void *)fromuser, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy_StrOut --
|
||||
* Safely copy a string to userspace. Prevents userspace pointers from
|
||||
* writing kernel memory.
|
||||
*
|
||||
* Results:
|
||||
* Returns EFAULT if the address is invalid or causes a fault.
|
||||
*
|
||||
* Side effects:
|
||||
* Kernel page fault may have occurred.
|
||||
*/
|
||||
int
|
||||
CopyStrOut(void *fromkernel, uintptr_t touser, uintptr_t len)
|
||||
Copy_StrOut(void *fromkernel, uintptr_t touser, uintptr_t len)
|
||||
{
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
// Kernel space
|
||||
if (touser >= MEM_USERSPACE_TOP) {
|
||||
kprintf("CopyStrOut: address exceeds userspace top\n");
|
||||
kprintf("Copy_StrOut: address exceeds userspace top\n");
|
||||
return EFAULT;
|
||||
}
|
||||
|
||||
// Wrap around
|
||||
if (len > (MEM_USERSPACE_TOP - touser)) {
|
||||
kprintf("CopyStrOut: length exceeds userspace top\n");
|
||||
kprintf("Copy_StrOut: length exceeds userspace top\n");
|
||||
return EFAULT;
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ Syscall_Spawn(uint64_t user_path)
|
||||
Thread *thr;
|
||||
Thread *cur;
|
||||
|
||||
status = CopyStrIn(user_path, &path, sizeof(path));
|
||||
status = Copy_StrIn(user_path, &path, sizeof(path));
|
||||
if (status != 0)
|
||||
return SYSCALL_PACK(status, 0);
|
||||
|
||||
@ -246,7 +246,7 @@ Syscall_Open(uint64_t user_path, uint64_t flags)
|
||||
int status;
|
||||
char path[256];
|
||||
|
||||
status = CopyStrIn(user_path, &path, sizeof(path));
|
||||
status = Copy_StrIn(user_path, &path, sizeof(path));
|
||||
if (status != 0) {
|
||||
Thread_Release(cur);
|
||||
return status;
|
||||
@ -301,7 +301,7 @@ Syscall_Stat(uint64_t user_path, uint64_t user_stat)
|
||||
char path[256];
|
||||
struct stat sb;
|
||||
|
||||
status = CopyStrIn(user_path, &path, sizeof(path));
|
||||
status = Copy_StrIn(user_path, &path, sizeof(path));
|
||||
if (status != 0) {
|
||||
return status;
|
||||
}
|
||||
@ -312,7 +312,7 @@ Syscall_Stat(uint64_t user_path, uint64_t user_stat)
|
||||
return status;
|
||||
}
|
||||
|
||||
status = CopyOut(&sb, user_stat, sizeof(struct stat));
|
||||
status = Copy_Out(&sb, user_stat, sizeof(struct stat));
|
||||
if (status != 0) {
|
||||
return status;
|
||||
}
|
||||
@ -333,7 +333,7 @@ Syscall_ReadDir(uint64_t fd, char *user_buf, size_t len, uintptr_t user_off)
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
status = CopyIn(user_off, &offset, sizeof(offset));
|
||||
status = Copy_In(user_off, &offset, sizeof(offset));
|
||||
if (status != 0) {
|
||||
Thread_Release(cur);
|
||||
return status;
|
||||
@ -350,7 +350,7 @@ Syscall_ReadDir(uint64_t fd, char *user_buf, size_t len, uintptr_t user_off)
|
||||
return rstatus;
|
||||
}
|
||||
|
||||
status = CopyOut(&offset, user_off, sizeof(offset));
|
||||
status = Copy_Out(&offset, user_off, sizeof(offset));
|
||||
if (status != 0) {
|
||||
Thread_Release(cur);
|
||||
return status;
|
||||
@ -480,7 +480,7 @@ Syscall_NICStat(uint64_t nicNo, uint64_t user_stat)
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
status = CopyOut(nic, user_stat, sizeof(NIC));
|
||||
status = Copy_Out(nic, user_stat, sizeof(NIC));
|
||||
if (status != 0) {
|
||||
return status;
|
||||
}
|
||||
@ -495,7 +495,7 @@ Syscall_NICSend(uint64_t nicNo, uint64_t user_mbuf)
|
||||
NIC *nic;
|
||||
MBuf mbuf;
|
||||
|
||||
status = CopyIn(user_mbuf, &mbuf, sizeof(mbuf));
|
||||
status = Copy_In(user_mbuf, &mbuf, sizeof(mbuf));
|
||||
if (status != 0) {
|
||||
return SYSCALL_PACK(status, 0);
|
||||
}
|
||||
@ -519,7 +519,7 @@ Syscall_NICRecv(uint64_t nicNo, uint64_t user_mbuf)
|
||||
NIC *nic;
|
||||
MBuf mbuf;
|
||||
|
||||
status = CopyIn(user_mbuf, &mbuf, sizeof(mbuf));
|
||||
status = Copy_In(user_mbuf, &mbuf, sizeof(mbuf));
|
||||
if (status != 0) {
|
||||
return SYSCALL_PACK(status, 0);
|
||||
}
|
||||
@ -542,7 +542,7 @@ Syscall_SysCtl(uint64_t user_node, uint64_t user_oldval, uint64_t user_newval)
|
||||
uint64_t status;
|
||||
char node[64];
|
||||
|
||||
status = CopyStrIn(user_node, &node, sizeof(node));
|
||||
status = Copy_StrIn(user_node, &node, sizeof(node));
|
||||
if (status != 0) {
|
||||
return status;
|
||||
}
|
||||
@ -555,17 +555,17 @@ Syscall_SysCtl(uint64_t user_node, uint64_t user_oldval, uint64_t user_newval)
|
||||
switch (scType) {
|
||||
case SYSCTL_TYPE_STR: {
|
||||
SysCtlString *scStr = SysCtl_GetObject(node);
|
||||
status = CopyOut(scStr, user_oldval, sizeof(*scStr));
|
||||
status = Copy_Out(scStr, user_oldval, sizeof(*scStr));
|
||||
break;
|
||||
}
|
||||
case SYSCTL_TYPE_INT: {
|
||||
SysCtlInt *scInt = SysCtl_GetObject(node);
|
||||
status = CopyOut(scInt, user_oldval, sizeof(*scInt));
|
||||
status = Copy_Out(scInt, user_oldval, sizeof(*scInt));
|
||||
break;
|
||||
}
|
||||
case SYSCTL_TYPE_BOOL: {
|
||||
SysCtlBool *scBool = SysCtl_GetObject(node);
|
||||
status = CopyOut(scBool, user_oldval, sizeof(scBool));
|
||||
status = Copy_Out(scBool, user_oldval, sizeof(scBool));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@ -584,7 +584,7 @@ Syscall_SysCtl(uint64_t user_node, uint64_t user_oldval, uint64_t user_newval)
|
||||
switch (scType) {
|
||||
case SYSCTL_TYPE_STR: {
|
||||
SysCtlString scStr;
|
||||
status = CopyIn(user_newval, &scStr, sizeof(scStr));
|
||||
status = Copy_In(user_newval, &scStr, sizeof(scStr));
|
||||
if (status != 0) {
|
||||
return status;
|
||||
}
|
||||
@ -593,7 +593,7 @@ Syscall_SysCtl(uint64_t user_node, uint64_t user_oldval, uint64_t user_newval)
|
||||
}
|
||||
case SYSCTL_TYPE_INT: {
|
||||
SysCtlInt scInt;
|
||||
status = CopyIn(user_newval, &scInt, sizeof(scInt));
|
||||
status = Copy_In(user_newval, &scInt, sizeof(scInt));
|
||||
if (status != 0) {
|
||||
return status;
|
||||
}
|
||||
@ -602,7 +602,7 @@ Syscall_SysCtl(uint64_t user_node, uint64_t user_oldval, uint64_t user_newval)
|
||||
}
|
||||
case SYSCTL_TYPE_BOOL: {
|
||||
SysCtlBool scBool;
|
||||
status = CopyIn(user_newval, &scBool, sizeof(scBool));
|
||||
status = Copy_In(user_newval, &scBool, sizeof(scBool));
|
||||
if (status != 0) {
|
||||
return status;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user