7#include <sys/kassert.h>
9#include <sys/spinlock.h>
11#include <sys/bufcache.h>
13#include <sys/dirent.h>
14#include <sys/thread.h>
45 VFS *fs = VFS_Alloc();
56 Alert(o2fs,
"Disk cache read failed\n");
63 Alert(o2fs,
"Invalid file system\n");
69 Alert(o2fs,
"Unsupported file system version\n");
82 Alert(o2fs,
"Bitmap read failed\n");
83 for (i = 0; i < 16; i++)
92 DLOG(o2fs,
"File system mounted\n");
108 Alert(o2fs,
"Mount failed");
135 for (
int i = 0; i < 16; i++) {
145 for (
int b = 0; b < fs->
blksize; b++) {
146 for (
int bi = 0; bi < 8; bi++) {
147 if (((bitmap[b] >> bi) & 0x1) == 0) {
149 bitmap[b] |= (1 << bi);
161 DLOG(o2fs,
"BAlloc %lu\n", blk);
168 Alert(o2fs,
"Out of space!\n");
187 DLOG(o2fs,
"BFree %lu\n", block);
192 char *bitmap = bentry->
buffer;
195 bitmap[bytoff] &= ~(1 << bitoff);
219 Alert(o2fs,
"disk read error\n");
225 Alert(o2fs,
"bad BNode magic\n");
231 Alert(o2fs,
"unsupported BNode version\n");
273 for (
int i = blkstart; i < ((filesz + vfs->
blksize - 1) / vfs->
blksize); i++) {
274 if (bn->direct[i].offset != 0)
282 bn->direct[i].offset = blkno * vfs->
blksize;
286 DLOG(o2fs,
"Growing: %d\n", filesz);
368 Alert(o2fs,
"disk read error\n");
374 Alert(o2fs,
"bad BNode magic\n");
380 Alert(o2fs,
"unsupported BNode version\n");
423 BNode *dirBN = dirEntry->buffer;
424 uint64_t blocks = (dirBN->
size + sb->blockSize - 1) / sb->blockSize;
427 DLOG(o2fs,
"Lookup %lld %d\n", dirBN->
size, blocks);
429 for (b = 0; b < blocks; b++) {
432 int entryPerBlock = sb->blockSize /
sizeof(
BDirEntry);
441 for (e = 0; e < entryPerBlock; e++) {
445 if (
strcmp((
char *)dir[e].name, name) == 0) {
487 BNode *fileBN = fileEntry->buffer;
489 DLOG(o2fs,
"O2FS %p %d\n", fileBN, fileBN->
size);
491 statinfo->
st_ino = fileEntry->diskOffset;
493 statinfo->
st_blocks = (fileBN->
size + sb->blockSize - 1) / sb->blockSize;
519 BNode *fileBN = fileEntry->buffer;
520 uint64_t blocks = (fileBN->
size + sb->blockSize - 1) / sb->blockSize;
523 DLOG(o2fs,
"Read %lld %d\n", fileBN->
size, blocks);
525 if (off > fileBN->
size) {
529 if (off +
len > fileBN->
size) {
535 uint64_t bOff = off % sb->blockSize;
539 if (bOff +
len > sb->blockSize) {
540 bLen = sb->blockSize - bOff;
585 BNode *fileBN = fileEntry->buffer;
586 uint64_t blocks = (fileBN->
size + sb->blockSize - 1) / sb->blockSize;
589 DLOG(o2fs,
"Write %lld %d\n", fileBN->
size, blocks);
593 if (fileBN->
size < (off+
len)) {
601 uint64_t bOff = off % sb->blockSize;
605 if (bOff +
len > sb->blockSize) {
606 bLen = sb->blockSize - bOff;
615 DLOG(o2fs,
"WRITE %lx %lx %lld\n",
buf, entry->
buffer, bLen);
655 while (
len >=
sizeof(de)) {
656 if (*off == fileBN->size)
658 if (*off > fileBN->size)
663 status =
O2FS_Read(fn, &dirEntry, *off,
sizeof(dirEntry));
664 if (status !=
sizeof(dirEntry)) {
665 kprintf(
"Unexpected error reading directory: %d\n", status);
668 if (
strncmp((
char *)&dirEntry.magic[0],
BDIR_MAGIC,
sizeof(dirEntry.magic)) != 0) {
673 strcpy(de.d_name, (
char *)dirEntry.name);
679 *off +=
sizeof(dirEntry);
int BufCache_Write(BufCacheEntry *entry)
int BufCache_Read(Disk *disk, uint64_t diskOffset, BufCacheEntry **entry)
void BufCache_Release(BufCacheEntry *entry)
int Copy_Out(void *fromkernel, uintptr_t touser, uintptr_t len)
#define NOT_IMPLEMENTED()
#define DLOG(_module, _format,...)
#define Alert(_module, _format,...)
#define VLOG(_module, _format,...)
int kprintf(const char *fmt,...)
void O2FSDumpDirEntry(BDirEntry *entry)
void O2FSRetainVNode(VNode *vn)
int O2FS_Write(VNode *fn, void *buf, uint64_t off, uint64_t len)
void O2FSBFree(VFS *fs, uint64_t block)
uint64_t O2FSBAlloc(VFS *fs)
void O2FSReleaseVNode(VNode *vn)
int O2FS_Unmount(VFS *fs)
int O2FS_Stat(VNode *fn, struct stat *statinfo)
int O2FSResolveBuf(VNode *vn, uint64_t b, BufCacheEntry **dentp)
int O2FS_Lookup(VNode *dn, VNode **fn, const char *name)
int O2FSGrowVNode(VNode *vn, uint64_t filesz)
static VFSOp O2FSOperations
VNode * O2FSLoadVNode(VFS *fs, ObjID *objid)
VFS * O2FS_Mount(Disk *disk)
int O2FS_GetRoot(VFS *fs, VNode **dn)
int O2FS_Read(VNode *fn, void *buf, uint64_t off, uint64_t len)
int O2FS_ReadDir(VNode *fn, void *buf, uint64_t len, uint64_t *off)
int O2FS_Close(VNode *fn)
uint8_t name[MAXNAMELEN+1]
#define O2FS_VERSION_MINOR
#define O2FS_VERSION_MAJOR
#define SPINLOCK_TYPE_NORMAL
void Spinlock_Destroy(Spinlock *lock)
void Spinlock_Init(Spinlock *lock, const char *name, uint64_t type)
int strcmp(const char *s1, const char *s2)
char * strcpy(char *to, const char *from)
int memcmp(const void *b1, const void *b2, size_t len)
void * memcpy(void *dst, const void *src, size_t len)
int strncmp(const char *s1, const char *s2, size_t len)