Import backup from 2005-12-30

This commit is contained in:
Josh Holtrop 2005-12-30 22:00:00 -05:00
parent 761e3f0483
commit 712337c485
34 changed files with 1588 additions and 123 deletions

BIN
e2fs Normal file

Binary file not shown.

1
initrd/link Symbolic link
View File

@ -0,0 +1 @@
test_file

View File

@ -12,7 +12,7 @@ CPPFLAGS=-fleading-underscore -fno-builtin -nostdlib -nostartfiles -nodefaultlib
# -S -masm=intel
CC=gcc
CXX=g++
CXXFLAGS=-fno-rtti -fno-exceptions
CXXFLAGS=-fno-rtti -fno-exceptions -D_HOS_CPP_
# Linker Information:
LD=ld
@ -27,7 +27,8 @@ OBJS=boot.o lang/lang_a.o \
devices.o block/ramdisk.o fs/vfs.o fs/FileSystem.o fs/VFSMount.o \
fs/ext2/ext2.o fs/sysfs/sysfs.o fs/sysfs/sysfs_entry.o \
sys/pci.o fs/OpenFile.o fs/OpenDirectory.o \
fs/ext2/Ext2OpenDirectory.o fs/ext2/Ext2OpenFile.o
fs/ext2/Ext2OpenDirectory.o fs/ext2/Ext2OpenFile.o \
fs/ext2/Ext2BlockCache.o
CSRC=kernel.c mm/mm.c mm/vmm.c lang/conv.c display/kout.c \
display/display.c sys/pic.c char/keyboard.c lang/lang.c \
sys/pci_classes.c
@ -36,7 +37,7 @@ CXXSRC=lang/string.cpp lang/new.cpp char/misc_char.cpp char/vconsole.cpp \
fs/ext2/ext2.cpp fs/sysfs/sysfs.cpp fs/sysfs/sysfs_entry.cpp \
sys/pci.cpp proc/proc.cpp proc/hash.cpp fs/OpenFile.cpp \
fs/OpenDirectory.cpp fs/ext2/Ext2OpenDirectory.cpp \
fs/ext2/Ext2OpenFile.cpp
fs/ext2/Ext2OpenFile.cpp fs/ext2/Ext2BlockCache.cpp
.PHONY: all depend clean html
@ -94,15 +95,16 @@ block/ramdisk.o: lang/lang.h block/ramdisk.h devices.h
devices.o: hos_defines.h devices.h char/misc_char.h char/misc_char.h
devices.o: char/vconsole.h block/ramdisk.h
fs/vfs.o: hos_defines.h display/kout.h functions.h sys/io.h lang/lang.h
fs/vfs.o: fs/vfs.h devices.h lang/string.h lang/vector.h fs/FileSystem.h
fs/vfs.o: fs/OpenFile.h fs/OpenDirectory.h fs/VFSMount.h fs/FileSystem.h
fs/vfs.o: fs/vfs.h fs/ext2/ext2.h
fs/vfs.o: fs/vfs.h devices.h fs/FileSystem.h fs/OpenDirectory.h fs/OpenFile.h
fs/vfs.o: lang/string.h fs/VFSMount.h fs/FileSystem.h fs/ext2/ext2.h fs/vfs.h
fs/vfs.o: lang/vector.h
fs/ext2/ext2.o: display/kout.h hos_defines.h mm/vmm.h multiboot.h lang/lang.h
fs/ext2/ext2.o: fs/ext2/ext2.h fs/vfs.h devices.h
fs/ext2/ext2.o: fs/ext2/ext2.h fs/vfs.h devices.h fs/ext2/Ext2OpenDirectory.h
fs/ext2/ext2.o: fs/OpenDirectory.h fs/vfs.h fs/OpenFile.h lang/string.h
fs/ext2/ext2.o: fs/ext2/Ext2OpenFile.h fs/OpenFile.h
fs/sysfs/sysfs.o: display/kout.h hos_defines.h fs/vfs.h devices.h
fs/sysfs/sysfs.o: fs/sysfs/sysfs.h fs/FileSystem.h fs/OpenFile.h
fs/sysfs/sysfs.o: fs/OpenDirectory.h fs/vfs.h lang/string.h lang/vector.h
fs/sysfs/sysfs.o: fs/VFSMount.h fs/FileSystem.h fs/sysfs/sysfs_entry.h
fs/sysfs/sysfs.o: fs/sysfs/sysfs.h fs/sysfs/sysfs_entry.h lang/vector.h
fs/sysfs/sysfs.o: lang/string.h
fs/sysfs/sysfs_entry.o: fs/sysfs/sysfs_entry.h lang/vector.h hos_defines.h
fs/sysfs/sysfs_entry.o: lang/string.h
sys/pci.o: hos_defines.h display/kout.h sys/io.h sys/pci.h lang/vector.h
@ -112,6 +114,9 @@ proc/proc.o: lang/vector.h
proc/hash.o: hos_defines.h proc/hash.h lang/vector.h display/kout.h mm/vmm.h
proc/hash.o: multiboot.h
fs/OpenFile.o: fs/OpenFile.h hos_defines.h
fs/OpenDirectory.o: fs/OpenDirectory.h fs/vfs.h hos_defines.h devices.h
fs/OpenDirectory.o: lang/string.h lang/vector.h fs/FileSystem.h fs/OpenFile.h
fs/OpenDirectory.o: fs/VFSMount.h fs/FileSystem.h fs/vfs.h
fs/OpenDirectory.o: fs/vfs.h hos_defines.h devices.h fs/OpenDirectory.h
fs/OpenDirectory.o: fs/OpenFile.h lang/string.h
fs/ext2/Ext2OpenDirectory.o: display/kout.h hos_defines.h lang/lang.h
fs/ext2/Ext2OpenDirectory.o: fs/vfs.h devices.h fs/ext2/Ext2OpenDirectory.h
fs/ext2/Ext2OpenDirectory.o: fs/OpenDirectory.h fs/vfs.h fs/OpenFile.h
fs/ext2/Ext2OpenDirectory.o: lang/string.h fs/ext2/ext2.h

View File

@ -12,7 +12,7 @@ CPPFLAGS=-fleading-underscore -fno-builtin -nostdlib -nostartfiles -nodefaultlib
# -S -masm=intel
CC=gcc
CXX=g++
CXXFLAGS=-fno-rtti -fno-exceptions
CXXFLAGS=-fno-rtti -fno-exceptions -D_HOS_CPP_
# Linker Information:
LD=ld
@ -27,7 +27,8 @@ OBJS=boot.o lang/lang_a.o \
devices.o block/ramdisk.o fs/vfs.o fs/FileSystem.o fs/VFSMount.o \
fs/ext2/ext2.o fs/sysfs/sysfs.o fs/sysfs/sysfs_entry.o \
sys/pci.o fs/OpenFile.o fs/OpenDirectory.o \
fs/ext2/Ext2OpenDirectory.o fs/ext2/Ext2OpenFile.o
fs/ext2/Ext2OpenDirectory.o fs/ext2/Ext2OpenFile.o \
fs/ext2/Ext2BlockCache.o
CSRC=kernel.c mm/mm.c mm/vmm.c lang/conv.c display/kout.c \
display/display.c sys/pic.c char/keyboard.c lang/lang.c \
sys/pci_classes.c
@ -36,7 +37,7 @@ CXXSRC=lang/string.cpp lang/new.cpp char/misc_char.cpp char/vconsole.cpp \
fs/ext2/ext2.cpp fs/sysfs/sysfs.cpp fs/sysfs/sysfs_entry.cpp \
sys/pci.cpp proc/proc.cpp proc/hash.cpp fs/OpenFile.cpp \
fs/OpenDirectory.cpp fs/ext2/Ext2OpenDirectory.cpp \
fs/ext2/Ext2OpenFile.cpp
fs/ext2/Ext2OpenFile.cpp fs/ext2/Ext2BlockCache.cpp
.PHONY: all depend clean html
@ -93,16 +94,16 @@ block/ramdisk.o: functions.h hos_defines.h sys/io.h mm/vmm.h multiboot.h
block/ramdisk.o: lang/lang.h block/ramdisk.h devices.h
devices.o: hos_defines.h devices.h char/misc_char.h char/misc_char.h
devices.o: char/vconsole.h block/ramdisk.h
fs/vfs.o: hos_defines.h display/kout.h functions.h sys/io.h fs/vfs.h
fs/vfs.o: devices.h lang/string.h fs/FileSystem.h fs/OpenFile.h
fs/vfs.o: fs/OpenDirectory.h fs/VFSMount.h fs/FileSystem.h fs/vfs.h
fs/vfs.o: fs/ext2/ext2.h lang/vector.h
fs/vfs.o: hos_defines.h display/kout.h functions.h sys/io.h lang/lang.h
fs/vfs.o: fs/vfs.h devices.h lang/string.h lang/vector.h fs/FileSystem.h
fs/vfs.o: fs/OpenFile.h fs/OpenDirectory.h fs/VFSMount.h fs/FileSystem.h
fs/vfs.o: fs/vfs.h fs/ext2/ext2.h
fs/ext2/ext2.o: display/kout.h hos_defines.h mm/vmm.h multiboot.h lang/lang.h
fs/ext2/ext2.o: fs/ext2/ext2.h fs/vfs.h devices.h
fs/sysfs/sysfs.o: display/kout.h hos_defines.h fs/vfs.h devices.h
fs/sysfs/sysfs.o: fs/sysfs/sysfs.h fs/FileSystem.h fs/OpenFile.h
fs/sysfs/sysfs.o: fs/OpenDirectory.h fs/vfs.h lang/string.h fs/VFSMount.h
fs/sysfs/sysfs.o: fs/FileSystem.h lang/vector.h fs/sysfs/sysfs_entry.h
fs/sysfs/sysfs.o: fs/OpenDirectory.h fs/vfs.h lang/string.h lang/vector.h
fs/sysfs/sysfs.o: fs/VFSMount.h fs/FileSystem.h fs/sysfs/sysfs_entry.h
fs/sysfs/sysfs_entry.o: fs/sysfs/sysfs_entry.h lang/vector.h hos_defines.h
fs/sysfs/sysfs_entry.o: lang/string.h
sys/pci.o: hos_defines.h display/kout.h sys/io.h sys/pci.h lang/vector.h
@ -111,7 +112,7 @@ proc/proc.o: functions.h sys/io.h display/kout.h proc/proc.h proc/hash.h
proc/proc.o: lang/vector.h
proc/hash.o: hos_defines.h proc/hash.h lang/vector.h display/kout.h mm/vmm.h
proc/hash.o: multiboot.h
fs/OpenFile.o: fs/OpenFile.h
fs/OpenFile.o: fs/OpenFile.h hos_defines.h
fs/OpenDirectory.o: fs/OpenDirectory.h fs/vfs.h hos_defines.h devices.h
fs/OpenDirectory.o: lang/string.h fs/FileSystem.h fs/OpenFile.h fs/VFSMount.h
fs/OpenDirectory.o: fs/FileSystem.h fs/vfs.h
fs/OpenDirectory.o: lang/string.h lang/vector.h fs/FileSystem.h fs/OpenFile.h
fs/OpenDirectory.o: fs/VFSMount.h fs/FileSystem.h fs/vfs.h

View File

@ -3,8 +3,6 @@
// Date: 08/20/04
// Modified: 05/11/05
#define _HOS_CPP_ _HOS_CPP_
extern "C"
{
#include "functions.h"

View File

@ -4,8 +4,6 @@
// Date: 05/11/05
// Modified: 05/11/05
#define _HOS_CPP_ _HOS_CPP_
#include "hos_defines.h"
#include "devices.h"
#include "misc_char.h"

View File

@ -3,8 +3,6 @@
// Date: 08/02/04
// Modified: 05/11/05
#define _HOS_CPP_ _HOS_CPP_
extern "C"
{
#include "hos_defines.h"

View File

@ -4,8 +4,6 @@
// Date: 05/11/05
// Modified: 05/11/05
#define _HOS_CPP_ _HOS_CPP_
#include "hos_defines.h"
#include "devices.h"
#include "char/misc_char.h"

View File

@ -4,19 +4,18 @@
// Date: 06/21/05
// Modified: 06/21/05
#include "vfs.h"
#include "FileSystem.h"
#include "OpenFile.h"
#include "OpenDirectory.h"
#include "hos_defines.h"
FileSystem::FileSystem() {}
FileSystem::~FileSystem() {}
u32_t FileSystem::totalBlocks() {return 0;}
u32_t FileSystem::freeBlocks() {return 0;};
u32_t FileSystem::totalInodes() {return 0;};
u32_t FileSystem::freeInodes() {return 0;};
u32_t FileSystem::getRootInodeNumber() {return 0;};
u32_t FileSystem::freeBlocks() {return 0;}
u32_t FileSystem::totalInodes() {return 0;}
u32_t FileSystem::freeInodes() {return 0;}
u32_t FileSystem::getRootInodeNumber() {return 0;}
OpenFile *FileSystem::openFile(u32_t inum) {return NULL;};
OpenDirectory *FileSystem::openDirectory(u32_t inum) {return NULL;};
int FileSystem::stat(u32_t inum, vfs_stat_t *buf) {return -1;};
OpenDirectory *FileSystem::openDirectory(u32_t inum, int mode) {return NULL;}
OpenFile *FileSystem::openFile(u32_t inum, int mode) {return NULL;}
int FileSystem::stat(u32_t inum, vfs_stat_t *buf) {return -1;}
int FileSystem::link_deref(u32_t inum, char *buf) {return -1;}

View File

@ -8,8 +8,9 @@
#define __HOS_FILESYSTEM__ __HOS_FILESYSTEM__
#include "hos_defines.h"
#include "OpenFile.h"
#include "vfs.h"
#include "OpenDirectory.h"
#include "OpenFile.h"
class FileSystem
{
@ -25,9 +26,10 @@ public:
virtual u32_t getRootInodeNumber();
virtual OpenFile *openFile(u32_t inum);
virtual OpenDirectory *openDirectory(u32_t inum);
virtual OpenDirectory *openDirectory(u32_t inum, int mode);
virtual OpenFile *openFile(u32_t inum, int mode);
virtual int stat(u32_t inum, vfs_stat_t *buf);
virtual int link_deref(u32_t inum, char *buf);
};
#endif

View File

@ -2,10 +2,14 @@
// Author: Josh Holtrop
// Date: 12/19/05
#include "vfs.h"
#include "OpenDirectory.h"
#include "lang/string.h"
OpenDirectory::OpenDirectory() {}
OpenDirectory::~OpenDirectory() {}
int OpenDirectory::seek(int pos, int mode) { return -1; }
int OpenDirectory::read(vfs_dir_entry_t *ent) { return -1; }
int OpenDirectory::write(vfs_dir_entry_t *ent) { return -1; }
int OpenDirectory::create(char *name, int mode, u32_t permissions, u32_t dev)
{ return -1; }
int OpenDirectory::unlink(char *name) { return -1; }

View File

@ -6,6 +6,7 @@
#define __HOS_OPENDIRECTORY_H__ __HOS_OPENDIRECTORY_H__
#include "vfs.h"
#include "lang/string.h"
class OpenDirectory
{
@ -14,7 +15,8 @@ public:
virtual ~OpenDirectory();
virtual int seek(int pos, int mode);
virtual int read(vfs_dir_entry_t *ent);
virtual int write(vfs_dir_entry_t *ent);
virtual int create(char *name, int mode, u32_t permissions, u32_t dev);
virtual int unlink(char *name);
};
#endif

View File

@ -3,3 +3,11 @@
// Date: 12/19/05
#include "OpenFile.h"
OpenFile::OpenFile() {}
OpenFile::~OpenFile() {}
int OpenFile::seek(int pos, int mode) { return -1; }
int OpenFile::read() { return -1; }
int OpenFile::read(void *buf, u32_t num) { return -1; }
int OpenFile::write(int chr) { return -1; }
int OpenFile::write(void *ptr, u32_t num) { return -1; }

View File

@ -8,11 +8,11 @@ extern "C" {
#include "display/kout.h"
}
#include "vfs.h"
#include "VFSMount.h"
#include "hos_defines.h"
#include "devices.h"
#include "lang/string.h"
#include "fs/vfs.h"
VFSMount::VFSMount(device_t dev, string fsType, FileSystem *fs,
string mountPoint,

View File

@ -10,7 +10,6 @@
#include "lang/string.h"
#include "devices.h"
#include "FileSystem.h"
#include "fs/vfs.h"
class VFSMount
{

View File

@ -0,0 +1,147 @@
// Ext2BlockCache.cpp
// Author: Josh Holtrop
// Date: 12/29/05
// Modified: 12/29/05
#include "fs/vfs.h"
#include "Ext2BlockCache.h"
extern "C" {
#include "display/kout.h"
}
Ext2BlockCache::Ext2BlockCache(Ext2fs *fs, u32_t inum)
{
myFS = fs;
myInum = inum;
myInodeDirty = 0;
fs->readInode(inum, &myInode);
myBlockSize = 1024 << fs->getSuper()->s_log_block_size;
for (int i = 0; i < 3; i++)
{
myCache[i] = new u8_t[myBlockSize];
myCacheAddress[i] = 0;
myCacheDirty[i] = 0;
}
}
Ext2BlockCache::~Ext2BlockCache()
{
for (int i = 0; i < 3; i++)
{
if (myCacheDirty[i])
myFS->writeBlock(myCacheAddress[i], myCache[i]);
delete[] myCache[i];
}
if (myInodeDirty)
myFS->writeInode(myInum, &myInode);
}
int Ext2BlockCache::readBlock(u32_t blockNum, void *buf)
{
u32_t fsblock = getFSBlock(blockNum, 0);
if (fsblock == 0)
return -1;
return myFS->readBlock(fsblock, buf);
}
int Ext2BlockCache::writeBlock(u32_t blockNum, void *buf)
{
u32_t fsblock = getFSBlock(blockNum, 1);
if (fsblock == 0)
return -1;
return myFS->writeBlock(fsblock, buf);
}
void Ext2BlockCache::setCache(u32_t level, u32_t fsblock)
{
if (myCacheAddress[level] == fsblock)
return;
if (myCacheDirty[level])
myFS->writeBlock(myCacheAddress[level], myCache[level]);
myCacheAddress[level] = fsblock;
myCacheDirty[level] = 0;
myFS->readBlock(fsblock, myCache[level]);
}
u32_t Ext2BlockCache::getFSBlock(u32_t blockNum, int create)
{
if (blockNum < 12) /* direct pointer */
{
if (create && myInode.i_block[blockNum] == 0)
{
myInode.i_block[blockNum] = myFS->allocBlock();
myInodeDirty = 1;
}
return myInode.i_block[blockNum];
}
blockNum -= 12;
if (blockNum < myBlockSize) /* i_block[12] */
{
if (create && myInode.i_block[12] == 0)
{
myInode.i_block[12] = myFS->allocBlock();
myInodeDirty = 1;
}
setCache(0, myInode.i_block[12]);
/* blockNum indexes cache 0 */
if (create && myCache[0][blockNum] == 0)
{
myCache[0][blockNum] = myFS->allocBlock();
myCacheDirty[0] = 1;
}
return myCache[0][blockNum];
}
blockNum -= myBlockSize;
if (blockNum < (myBlockSize * myBlockSize)) /* i_block[13] */
{
if (create && myInode.i_block[13] == 0)
{
myInode.i_block[13] = myFS->allocBlock();
myInodeDirty = 1;
}
setCache(0, myInode.i_block[13]);
/* blockNum / myBlockSize indexes cache 0 */
if (create && myCache[0][blockNum / myBlockSize] == 0)
{
myCache[0][blockNum / myBlockSize] = myFS->allocBlock();
myCacheDirty[0] = 1;
}
setCache(1, myCache[0][blockNum / myBlockSize]);
/* blockNum % myBlockSize indexes cache 1 */
if (create && myCache[1][blockNum % myBlockSize] == 0)
{
myCache[1][blockNum % myBlockSize] = myFS->allocBlock();
myCacheDirty[1] = 1;
}
return myCache[1][blockNum % myBlockSize];
}
blockNum -= (myBlockSize * myBlockSize); /* i_block[14] */
if (create && myInode.i_block[14] == 0)
{
myInode.i_block[14] = myFS->allocBlock();
myInodeDirty = 1;
}
setCache(0, myInode.i_block[14]);
/* blockNum / (myBlockSize^2) indexes cache 0 */
if (create && myCache[0][blockNum / (myBlockSize * myBlockSize)] == 0)
{
myCache[0][blockNum / (myBlockSize * myBlockSize)] = myFS->allocBlock();
myCacheDirty[0] = 1;
}
setCache(1, myCache[0][blockNum / (myBlockSize * myBlockSize)]);
/* blockNum / myBlockSize indexes cache 1 */
if (create && myCache[1][blockNum / myBlockSize] == 0)
{
myCache[1][blockNum / myBlockSize] = myFS->allocBlock();
myCacheDirty[1] = 1;
}
setCache(2, myCache[1][blockNum / myBlockSize]);
/* blockNum % myBlockSize indexes cache 2 */
if (create && myCache[2][blockNum % myBlockSize] == 0)
{
myCache[2][blockNum % myBlockSize] = myFS->allocBlock();
myCacheDirty[2] = 1;
}
return myCache[2][blockNum % myBlockSize];
}

View File

@ -0,0 +1,34 @@
// Ext2BlockCache.h
// Author: Josh Holtrop
// Date: 12/29/05
// Modified: 12/29/05
#ifndef __HOS_EXT2BLOCKCACHE_H__
#define __HOS_EXT2BLOCKCACHE_H__ __HOS_EXT2BLOCKCACHE_H__
#include "fs/vfs.h"
#include "ext2.h"
class Ext2BlockCache
{
protected:
Ext2fs *myFS;
u32_t myInum;
ext2_inode_t myInode;
u32_t myBlockSize;
u8_t *myCache[3];
u8_t myCacheAddress[3];
u8_t myCacheDirty[3];
u32_t myInodeDirty;
void setCache(u32_t level, u32_t fsblock);
u32_t getFSBlock(u32_t block, int create);
public:
Ext2BlockCache(Ext2fs *fs, u32_t inum);
~Ext2BlockCache();
int readBlock(u32_t blockNum, void *buf);
int writeBlock(u32_t blockNum, void *buf);
};
#endif

View File

@ -3,32 +3,224 @@
// Date: 12/26/05
// Modified: 12/26/05
#include "Ext2OpenDirectory.h"
extern "C" {
#include "display/kout.h"
#include "lang/lang.h"
}
Ext2OpenDirectory::Ext2OpenDirectory()
#include "fs/vfs.h"
#include "Ext2OpenDirectory.h"
#include "Ext2OpenFile.h"
#include "ext2.h"
Ext2OpenDirectory::Ext2OpenDirectory(Ext2fs *fs, u32_t inum, int mode)
{
myPosition = 0;
myFS = fs;
myInum = inum;
myMode = mode;
myCache = new Ext2BlockCache(fs, inum);
fs->readInode(inum, &myInode);
u32_t size = myInode.i_size;
u32_t logBlockSize = fs->getSuper()->s_log_block_size;
myBlockSize = 1024 << logBlockSize;
if (size % myBlockSize)
size += myBlockSize - (size % myBlockSize);
myBlocks = size >> (10 + logBlockSize);
myBuffer = new u8_t[size];
if ((mode & VFS_MODE_RW_MASK) == VFS_MODE_READ)
readDirectory();
}
/* destroy an open ext2 directory object */
Ext2OpenDirectory::~Ext2OpenDirectory()
{
delete myCache;
if ((myMode & VFS_MODE_RW_MASK) == VFS_MODE_READ)
delete[] myBuffer;
}
void Ext2OpenDirectory::readDirectory()
{
/* read in the entire directory */
for (u32_t i = 0; i < myBlocks; i++)
myCache->readBlock(i, myBuffer + i * myBlockSize);
}
/* seek absolute or relative, only positive direction */
int Ext2OpenDirectory::seek(int pos, int mode)
{
if (mode == SEEK_ABSOLUTE)
myPosition = 0;
if (pos > 0)
{
while (myPosition < myInode.i_size)
{
ext2_dir_entry_t *de =
(ext2_dir_entry_t *) (myBuffer + myPosition);
myPosition += de->length;
pos--;
if (pos < 1)
return 0;
}
return -1;
}
return -2;
}
/* read a directory entry from the directory */
int Ext2OpenDirectory::read(vfs_dir_entry_t *ent)
{
if ((myMode & VFS_MODE_RW_MASK) != VFS_MODE_READ)
return -1;
if (myPosition >= myInode.i_size)
return EOF;
ext2_dir_entry_t *de = (ext2_dir_entry_t *) (myBuffer + myPosition);
ent->inum = de->inode;
memcpy(ent->name, de->name, de->name_length);
ent->name[de->name_length] = 0;
myPosition += de->length;
return 0;
}
int Ext2OpenDirectory::write(vfs_dir_entry_t *ent)
int Ext2OpenDirectory::create(char *name, int mode, u32_t permissions, u32_t dev)
{
if ((myMode & VFS_MODE_RW_MASK) != VFS_MODE_WRITE)
return -1;
readDirectory();
myPosition = 0;
u32_t name_length = strlen(name);
while (myPosition < myInode.i_size)
{
ext2_dir_entry_t *de =
(ext2_dir_entry_t *) (myBuffer + myPosition);
if (name_length == de->name_length && !strncmp(name, de->name, name_length))
return -2; /* entry already exists */
myPosition += de->length;
}
u32_t newInode = myFS->allocInode();
if (newInode == 0)
return -3; /* no free inodes! */
/* initialize the inode */
ext2_inode_t in;
memset(&in, 0, sizeof(ext2_inode_t));
u32_t ext2_mode;
switch(mode)
{
case VFS_FT_DIR: ext2_mode = EXT2_I_MODE_DIR; break;
case VFS_FT_CHAR: ext2_mode = EXT2_I_MODE_CHAR;
in.i_block[0] = dev; break;
case VFS_FT_BLOCK: ext2_mode = EXT2_I_MODE_BLOCK;
in.i_block[0] = dev; break;
case VFS_FT_FIFO: ext2_mode = EXT2_I_MODE_FIFO; break;
case VFS_FT_SOCK: ext2_mode = EXT2_I_MODE_SOCK; break;
case VFS_FT_SYMLINK: ext2_mode = EXT2_I_MODE_SYM; break;
case VFS_FT_FILE:
default: ext2_mode = EXT2_I_MODE_FILE; break;
}
in.i_mode = ext2_mode | (permissions & EXT2_I_MODE_ATTR_MASK);
in.i_links_count = 1;
myFS->writeInode(newInode, &in);
u32_t entryLength = name_length + 8;
if (entryLength & 0x3)
entryLength = (entryLength + 4) & 0xFFFFFFFC; /* multiple of 4 bytes */
myPosition = 0;
for (;;)
{
ext2_dir_entry_t *de =
(ext2_dir_entry_t *) (myBuffer + myPosition);
u32_t thisEntryLength = de->name_length + 8;
if (thisEntryLength & 0x3)
thisEntryLength = (thisEntryLength + 4) & 0xFFFFFFFC;
if (de->length - thisEntryLength >= entryLength)
{
/* There is room in this entry for the new one */
u32_t newLength = de->length - entryLength;
de->length = entryLength;
u32_t firstPosition = myPosition;
myPosition += de->length;
de = (ext2_dir_entry_t *) (myBuffer + myPosition);
de->length = newLength;
de->name_length = name_length;
de->inode = newInode;
memcpy(de->name, name, name_length);
writeInclusiveRange(firstPosition,
myPosition + entryLength - 1);
return 0;
}
if (myPosition + de->length >= myInode.i_size)
{
if (myFS->getSuper()->s_free_blocks_count < 2)
return -4; /* out of space on device */
/* This is the last entry, we need to add a block */
myBlocks++;
u8_t *newBuffer = new u8_t[myBlockSize * myBlocks];
memcpy(newBuffer, myBuffer, myBlockSize * (myBlocks - 1));
delete[] myBuffer;
myBuffer = newBuffer;
de = (ext2_dir_entry_t *) (myBuffer + myPosition);
u32_t thisEntryLength = de->name_length + 8;
if (thisEntryLength & 0x3)
thisEntryLength = (thisEntryLength + 4) & 0xFFFFFFFC;
u32_t leftovers = de->length - thisEntryLength;
de->length -= leftovers;
u32_t firstPosition = myPosition;
myPosition += thisEntryLength;
de = (ext2_dir_entry_t *) (myBuffer + myPosition);
de->length = myBlockSize + leftovers;
de->name_length = name_length;
de->inode = newInode;
memcpy(de->name, name, name_length);
writeInclusiveRange(firstPosition,
myPosition + myBlockSize + leftovers - 1);
return 0;
}
myPosition += de->length;
}
}
void Ext2OpenDirectory::writeInclusiveRange(u32_t first, u32_t last)
{
u32_t firstBlock = first / myBlockSize;
u32_t lastBlock = last / myBlockSize;
for (u32_t i = firstBlock; i <= lastBlock; i++)
myCache->writeBlock(i, myBuffer + i * myBlockSize);
}
int Ext2OpenDirectory::unlink(char *name)
{
if ((myMode & VFS_MODE_RW_MASK) != VFS_MODE_WRITE)
return -1;
readDirectory();
myPosition = 0;
u32_t lastPosition = 0;
u32_t name_length = strlen(name);
while (myPosition < myInode.i_size)
{
ext2_dir_entry_t *de =
(ext2_dir_entry_t *) (myBuffer + myPosition);
if (name_length == de->name_length && !strncmp(name, de->name, name_length))
{
ext2_inode_t inode;
myFS->readInode(de->inode, &inode);
if ((inode.i_mode & EXT2_I_MODE_TYPE_MASK) == EXT2_I_MODE_DIR)
{
if (myFS->attemptRemoveDir(de->inode))
return -3; /* can't unlink non-empty directory */
}
/* found entry to unlink
add the space to entry at lastPosition */
myFS->unlink(de->inode);
ext2_dir_entry_t *lde =
(ext2_dir_entry_t *) (myBuffer + lastPosition);
lde->length += de->length;
writeInclusiveRange(lastPosition, lastPosition + 8);
return 0;
}
lastPosition = myPosition;
myPosition += de->length;
}
return -2; /* entry not found */
}

View File

@ -6,18 +6,32 @@
#ifndef __HOS_EXT2OPENDIRECTORY__
#define __HOS_EXT2OPENDIRECTORY__ __HOS_EXT2OPENDIRECTORY__
#include "fs/OpenDirectory.h"
#include "ext2.h"
#include "Ext2BlockCache.h"
class Ext2OpenDirectory : public OpenDirectory
{
private:
int myPosition;
u32_t myPosition;
Ext2fs *myFS;
int myMode;
u32_t myInum;
u8_t *myBuffer;
u32_t myBlocks;
u32_t myBlockSize;
Ext2BlockCache *myCache;
ext2_inode_t myInode;
void readDirectory();
void writeInclusiveRange(u32_t first, u32_t last);
public:
Ext2OpenDirectory();
Ext2OpenDirectory(Ext2fs *fs, u32_t inum, int mode);
~Ext2OpenDirectory();
int seek(int pos, int mode);
int read(vfs_dir_entry_t *ent);
int write(vfs_dir_entry_t *ent);
int create(char *name, int mode, u32_t permissions, u32_t dev);
int unlink(char *name);
};
#endif

View File

@ -1,5 +1,21 @@
// Ext2OpenFile.h
// Ext2OpenFile.cpp
// Author: Josh Holtrop
// Date: 12/26/05
// Modified: 12/26/05
#include "Ext2OpenFile.h"
Ext2OpenFile::Ext2OpenFile(Ext2fs *fs, u32_t inum, int mode)
{
myMode = mode;
myFS = fs;
myInum = inum;
myCache = new Ext2BlockCache(fs, inum);
fs->readInode(inum, &myInode);
}
Ext2OpenFile::~Ext2OpenFile()
{
delete myCache;
}

View File

@ -6,10 +6,22 @@
#ifndef __HOS_EXT2OPENFILE__
#define __HOS_EXT2OPENFILE__ __HOS_EXT2OPENFILE__
#include "ext2.h"
#include "fs/OpenFile.h"
#include "Ext2BlockCache.h"
class Ext2OpenFile : public OpenFile
{
protected:
Ext2fs *myFS;
u32_t myInum;
int myMode;
Ext2BlockCache *myCache;
ext2_inode_t myInode;
public:
Ext2OpenFile(Ext2fs *fs, u32_t inum, int mode);
~Ext2OpenFile();
};

View File

@ -4,7 +4,17 @@
// Date: 05/10/05
// Modified: 05/10/05
#define _HOS_CPP_ _HOS_CPP_
/* example ext2 filesystem block group structure containing superblock and group descriptors:
* block offset description #blocks
* ------------ ----------- -------
* 0 superblock 1
* 1 group descriptors gd_blocks = ceil(ceil[s_blocks_count / s_blocks_per_group] / (1024 >> [5 - s_log_block_size]))
* gd_blocks+1 block bitmap block 1
* gd_blocks+2 inode bitmap block 1
* gd_blocks+3 inode table itblocks = ceil[s_inodes_per_group / (1024 >> [7 - s_log_block_size])]
* gd_blocks+3+itblocks data blocks s_blocks_per_group - gd_blocks - itblocks - 3
*/
extern "C" {
#include "display/kout.h"
@ -16,12 +26,14 @@ extern "C" {
#include "Ext2OpenDirectory.h"
#include "Ext2OpenFile.h"
/* initialize the ext2 filesystem driver */
int ext2_init()
{
vfs_register("ext2", ext2__mount_func);
return 0;
}
/* a function to mount an ext2 filesystem and return a pointer to it */
FileSystem *ext2__mount_func(device_t dev)
{
ext2_super_block_t *super =
@ -37,41 +49,60 @@ FileSystem *ext2__mount_func(device_t dev)
return fs;
}
/* constructor for an actual ext2 filesystem object */
Ext2fs::Ext2fs(ext2_super_block_t *super, device_t dev)
{
myDevice = dev;
memcpy(&mySuper, super, sizeof(ext2_super_block_t));
mySuperDirty = 0;
kprintf("Blocks: %d (%d free), Inodes: %d (%d free) Creator OS:\n",
mySuper.s_blocks_count,
mySuper.s_free_blocks_count,
mySuper.s_inodes_count,
mySuper.s_free_inodes_count,
mySuper.s_creator_os);
myNumGroups = /* ceil[blocks_count / blocks_per_group] */
(mySuper.s_blocks_count + mySuper.s_blocks_per_group - 1)
/ mySuper.s_blocks_per_group;
myGroupDescriptorsPerBlock = 1024 >> (5 - mySuper.s_log_block_size);
myGroupDescriptorBlocks = /* ceil[num_groups / groupDescriptorsPerBlock] */
(myNumGroups + myGroupDescriptorsPerBlock - 1)
/ myGroupDescriptorsPerBlock;
myInodesPerBlock = 1024 >> (7 - mySuper.s_log_block_size);
myInodeTableBlocks = /* ceil[inodes_per_group / inodePerBlock] */
(mySuper.s_inodes_per_group + myInodesPerBlock - 1)
/ myInodesPerBlock;
/* test/debug code */
OpenDirectory *od = openDirectory(2, VFS_MODE_WRITE);
kprintf("TEST: %d\n", od->unlink("link"));
kprintf("TEST: %d\n", od->create("test", VFS_FT_FILE, 0640, 0));
kprintf("TEST: %d\n", od->create("Block File baby", VFS_FT_BLOCK, 0666, 5 << 8 | 3));
kprintf("TEST: %d\n", od->create("Character-File", VFS_FT_CHAR, 0644, 130 << 8 | 42));
delete od;
}
/* this destructor destroys an ext2 filesystem that was mounted */
Ext2fs::~Ext2fs()
{
if (mySuperDirty)
block_write(DEV_MAJOR(myDevice), DEV_MINOR(myDevice), 2, 2, &mySuper);
}
/* return the total number of 512-blocks on the filesystem */
u32_t Ext2fs::totalBlocks()
{
return mySuper.s_blocks_count << (mySuper.s_log_block_size + 1);
return mySuper.s_blocks_count >> (mySuper.s_log_block_size + 1);
}
/* return the number of free 512-blocks on the filesystem */
u32_t Ext2fs::freeBlocks()
{
return mySuper.s_free_blocks_count << (mySuper.s_log_block_size + 1);
return mySuper.s_free_blocks_count >> (mySuper.s_log_block_size + 1);
}
/* return the total number of inodes on the filesystem */
u32_t Ext2fs::totalInodes()
{
return mySuper.s_inodes_count;
}
/* return the free number of inodes on the filesystem */
u32_t Ext2fs::freeInodes()
{
return mySuper.s_free_inodes_count;
@ -83,17 +114,396 @@ u32_t Ext2fs::getRootInodeNumber()
return 2;
}
OpenDirectory *Ext2fs::openDirectory(u32_t inum)
{
return NULL;
}
OpenFile *Ext2fs::openFile(u32_t inum)
/* open a directory */
OpenDirectory *Ext2fs::openDirectory(u32_t inum, int mode)
{
ext2_inode_t inode;
readInode(inum, &inode);
if ((inode.i_mode & EXT2_I_MODE_TYPE_MASK) == EXT2_I_MODE_DIR)
return new Ext2OpenDirectory(this, inum, mode);
return NULL;
}
/* stat an inode */
int Ext2fs::stat(u32_t inum, vfs_stat_t *buf)
{
ext2_inode_t inode;
if (readInode(inum, &inode))
return -1;
buf->dev = 0;
switch(inode.i_mode & EXT2_I_MODE_TYPE_MASK)
{
case EXT2_I_MODE_FIFO: buf->type = VFS_FT_FIFO; break;
case EXT2_I_MODE_CHAR: buf->type = VFS_FT_CHAR;
buf->dev = inode.i_block[0]; break;
case EXT2_I_MODE_DIR: buf->type = VFS_FT_DIR; break;
case EXT2_I_MODE_BLOCK: buf->type = VFS_FT_BLOCK;
buf->dev = inode.i_block[0]; break;
case EXT2_I_MODE_FILE: buf->type = VFS_FT_FILE; break;
case EXT2_I_MODE_SYM: buf->type = VFS_FT_SYMLINK; break;
case EXT2_I_MODE_SOCK: buf->type = VFS_FT_SOCK; break;
default: buf->type = VFS_FT_UNKNOWN;
}
buf->size = inode.i_size;
buf->inode = inum;
buf->permissions = inode.i_mode & EXT2_I_MODE_ATTR_MASK;
buf->uid = inode.i_uid;
buf->gid = inode.i_gid;
buf->atime = inode.i_atime;
buf->mtime = inode.i_mtime;
buf->ctime = inode.i_ctime;
buf->links = inode.i_links_count;
return 0;
}
/* dereference a symbolink link */
int Ext2fs::link_deref(u32_t inum, char *buf)
{
ext2_inode_t inode;
if (readInode(inum, &inode))
return -1; /* Couldn't read inode */
if ((inode.i_mode & EXT2_I_MODE_TYPE_MASK) != EXT2_I_MODE_SYM)
return -2;
if (inode.i_size > VFS_MAX_PATH_LENGTH)
return -3;
if (inode.i_size < 61)
{
memcpy(buf, inode.i_block, inode.i_size);
buf[inode.i_size] = 0;
return 0;
}
char *block = new char[1024 << mySuper.s_log_block_size];
readBlock(inode.i_block[0], block);
memcpy(buf, block, inode.i_size);
buf[inode.i_size] = 0;
delete[] block;
return 0;
}
/*************************** internal functions ***************************/
/* read an inode from the disk into memory */
int Ext2fs::readInode(u32_t inum, ext2_inode_t *buf)
{
if (inodeStatus(inum) != 1)
return -1;
inum--; /* turn inode number into a 0-based index */
u32_t group = inum / mySuper.s_inodes_per_group;
u32_t index = inum % mySuper.s_inodes_per_group;
ext2_group_desc_t group_desc;
readGroupDescriptor(group, &group_desc);
ext2_inode_t *inode_block = new ext2_inode_t[8 << mySuper.s_log_block_size];
readBlock(group_desc.bg_inode_table +
(index >> (3 + mySuper.s_log_block_size)), inode_block);
u32_t inode_block_index = index % (8 << mySuper.s_log_block_size);
memcpy(buf, inode_block + inode_block_index, sizeof(ext2_inode_t));
delete[] inode_block;
return 0;
}
/* write an inode from memory onto the disk */
int Ext2fs::writeInode(u32_t inum, ext2_inode_t *buf)
{
if (inodeStatus(inum) != 1)
return -1;
inum--; /* turn inode number into a 0-based index */
u32_t group = inum / mySuper.s_inodes_per_group;
u32_t index = inum % mySuper.s_inodes_per_group;
ext2_group_desc_t group_desc;
readGroupDescriptor(group, &group_desc);
ext2_inode_t *inode_block = new ext2_inode_t[8 << mySuper.s_log_block_size];
u32_t block_num = group_desc.bg_inode_table +
(index >> (3 + mySuper.s_log_block_size));
readBlock(block_num, inode_block);
u32_t inode_block_index = index % (8 << mySuper.s_log_block_size);
memcpy(inode_block + inode_block_index, buf, sizeof(ext2_inode_t));
writeBlock(block_num, inode_block);
delete[] inode_block;
return 0;
}
/* read the group descriptor for a given group number */
int Ext2fs::readGroupDescriptor(u32_t group, ext2_group_desc_t *buf)
{
if (group >= myNumGroups)
return -1;
ext2_group_desc_t *gd_block =
new ext2_group_desc_t[myGroupDescriptorsPerBlock];
readBlock(mySuper.s_first_data_block + 1 +
(group / myGroupDescriptorsPerBlock), gd_block);
memcpy(buf, gd_block + (group % myGroupDescriptorsPerBlock),
sizeof(ext2_group_desc_t));
delete[] gd_block;
return 0;
}
/* write the group descriptor for a given group number */
int Ext2fs::writeGroupDescriptor(u32_t group, ext2_group_desc_t *buf)
{
if (group >= myNumGroups)
return -1;
ext2_group_desc_t *gd_block =
new ext2_group_desc_t[myGroupDescriptorsPerBlock];
u32_t block_num = mySuper.s_first_data_block + 1 +
(group / myGroupDescriptorsPerBlock);
readBlock(block_num, gd_block);
memcpy(gd_block + (group % myGroupDescriptorsPerBlock), buf,
sizeof(ext2_group_desc_t));
writeBlock(block_num, gd_block);
delete[] gd_block;
return 0;
}
/* read a data block from the block device */
int Ext2fs::readBlock(u32_t blockNum, void *buf)
{
return block_read(DEV_MAJOR(myDevice), DEV_MINOR(myDevice),
blockNum << (mySuper.s_log_block_size + 1),
2 << mySuper.s_log_block_size,
buf);
}
/* write a data block to the block device */
int Ext2fs::writeBlock(u32_t blockNum, void *buf)
{
return block_write(DEV_MAJOR(myDevice), DEV_MINOR(myDevice),
blockNum << (mySuper.s_log_block_size + 1),
2 << mySuper.s_log_block_size,
buf);
}
/* check the status of an inode (1-based inode number)
* -1: invalid inode number
* 0: free inode
* 1: allocated (used) inode
*/
int Ext2fs::inodeStatus(u32_t inum)
{
if (inum < 1 || inum > mySuper.s_inodes_count)
return -1; /* invalid inode number */
inum--; /* turn inode number into a 0-based index */
u32_t group = inum / mySuper.s_inodes_per_group;
u32_t index = inum % mySuper.s_inodes_per_group;
ext2_group_desc_t group_desc;
readGroupDescriptor(group, &group_desc);
u8_t *bitmap_block = new u8_t[1024 << mySuper.s_log_block_size];
readBlock(group_desc.bg_inode_bitmap +
(index >> (13 + mySuper.s_log_block_size)), bitmap_block);
u32_t bitmap_index = index % (8192 << mySuper.s_log_block_size);
int inode_status = (bitmap_block[bitmap_index >> 3] >> (bitmap_index & 0x7)) & 1;
delete[] bitmap_block;
return inode_status;
}
/* check the status of a block
* -1: invalid block number
* 0: free block
* 1: allocated (used) block
*/
int Ext2fs::blockStatus(u32_t bnum)
{
if (bnum < mySuper.s_first_data_block)
return 1;
if (bnum >= mySuper.s_blocks_count)
return -1; /* invalid inode number */
bnum -= mySuper.s_first_data_block;
u32_t group = bnum / mySuper.s_blocks_per_group;
u32_t index = bnum % mySuper.s_blocks_per_group;
ext2_group_desc_t group_desc;
readGroupDescriptor(group, &group_desc);
u8_t *bitmap_block = new u8_t[1024 << mySuper.s_log_block_size];
readBlock(group_desc.bg_block_bitmap +
(index >> (13 + mySuper.s_log_block_size)), bitmap_block);
u32_t bitmap_index = index % (8192 << mySuper.s_log_block_size);
int block_status = (bitmap_block[bitmap_index >> 3] >> (bitmap_index & 0x7)) & 1;
delete[] bitmap_block;
return block_status;
}
/* allocate an inode, return number (0 on failure) */
u32_t Ext2fs::allocInode()
{
ext2_group_desc_t gd;
for (unsigned int bg = 0; bg < myNumGroups; bg++)
{
readGroupDescriptor(bg, &gd);
if (gd.bg_free_inodes_count)
{
u32_t index = allocFromBitmap(gd.bg_inode_bitmap,
mySuper.s_inodes_per_group);
if (index == 0xFFFFFFFF)
return 0;
gd.bg_free_inodes_count--;
writeGroupDescriptor(bg, &gd);
mySuper.s_free_inodes_count--;
mySuperDirty = 1;
return (bg * mySuper.s_inodes_per_group) + index + 1;
}
}
return 0;
}
/* allocate a block, return number (0 on failure) */
u32_t Ext2fs::allocBlock()
{
ext2_group_desc_t gd;
for (unsigned int bg = 0; bg < myNumGroups; bg++)
{
readGroupDescriptor(bg, &gd);
if (gd.bg_free_blocks_count)
{
u32_t index = allocFromBitmap(gd.bg_block_bitmap,
mySuper.s_blocks_per_group);
if (index == 0xFFFFFFFF)
return 0;
gd.bg_free_blocks_count--;
writeGroupDescriptor(bg, &gd);
mySuper.s_free_blocks_count--;
mySuperDirty = 1;
return (bg * mySuper.s_blocks_per_group) + index +
mySuper.s_first_data_block;
}
}
return 0;
}
/* free an inode, return error code */
int Ext2fs::freeInode(u32_t inum)
{
if (inum < 11 || inum > mySuper.s_inodes_count)
return -1;
if (inodeStatus(inum) != 1)
return -2;
inum--; /* now 0-based */
ext2_group_desc_t gd;
u32_t group_num = inum / mySuper.s_inodes_per_group;
readGroupDescriptor(group_num, &gd);
freeFromBitmap(gd.bg_inode_bitmap, inum % mySuper.s_inodes_per_group);
gd.bg_free_inodes_count++;
mySuper.s_free_inodes_count++;
mySuperDirty = 1;
writeGroupDescriptor(group_num, &gd);
return 0;
}
/* free a block, return error code */
int Ext2fs::freeBlock(u32_t bnum)
{
if (bnum < mySuper.s_first_data_block || bnum >= mySuper.s_blocks_count)
return -1;
if (blockStatus(bnum) != 1)
return -2;
bnum -= mySuper.s_first_data_block; /* now 0-based */
ext2_group_desc_t gd;
u32_t group_num = bnum / mySuper.s_blocks_per_group;
readGroupDescriptor(group_num, &gd);
freeFromBitmap(gd.bg_block_bitmap, bnum % mySuper.s_blocks_per_group);
gd.bg_free_blocks_count++;
mySuper.s_free_blocks_count++;
mySuperDirty = 1;
writeGroupDescriptor(group_num, &gd);
return 0;
}
/* allocate a node from a bitmap, return the index, 0xFFFFFFFF on failure */
u32_t Ext2fs::allocFromBitmap(u32_t blockNum, u32_t maxBits)
{
u8_t *block = new u8_t[1024 << mySuper.s_log_block_size];
u8_t *blockPtr = block;
u32_t maxBytes = (maxBits + 7) >> 3;
readBlock(blockNum, block);
for (u32_t idx = 0; idx < maxBytes; idx++)
{
if (*blockPtr != 0xFF)
{
for (u32_t bit = 0; bit < 8; bit++)
{
if ( !((*blockPtr) & (1 << bit)) )
{
u32_t nodeIndex = (idx << 3) + bit;
if (nodeIndex < maxBits)
{
*blockPtr |= (1 << bit);
writeBlock(blockNum, block);
return nodeIndex;
}
return 0xFFFFFFFF;
}
}
break;
}
blockPtr++;
}
delete[] block;
return 0xFFFFFFFF;
}
/* free a node from a bitmap */
void Ext2fs::freeFromBitmap(u32_t blockNum, u32_t node)
{
u8_t *block = new u8_t[1024 << mySuper.s_log_block_size];
readBlock(blockNum, block);
u8_t *blockPtr = block + (node >> 3);
*blockPtr &= ((1 << (node & 0x7)) ^ 0xFF);
writeBlock(blockNum, block);
delete[] block;
}
/* this function is called when a file is opened for writing and truncates
* the inode. the function notifies any file handles open on this inode that
* the inode was truncated
*/
void Ext2fs::notifyTruncatedFiles(u32_t inum)
{
// TODO: notify open files
}
/* unlink an inode:
* decrement i_links_count
* if it is zero, free the inode
* if not, write the inode back
*/
void Ext2fs::unlink(u32_t inum)
{
ext2_inode_t inode;
readInode(inum, &inode);
inode.i_links_count--;
if (inode.i_links_count)
{
writeInode(inum, &inode);
return;
}
freeBlocksFromInode(inum);
freeInode(inum);
}
int Ext2fs::attemptRemoveDir(u32_t inum)
{
vfs_dir_entry_t dentry, dentry2;
OpenDirectory *od = openDirectory(inum, VFS_MODE_READ);
if (od->read(&dentry))
{
delete od;
return -1;
}
if (od->read(&dentry2))
{
delete od;
return -1;
}
if (!od->read(&dentry))
{
delete od;
return -1;
}
delete od;
unlink(dentry.inode);
unlink(dentry2.inode);
}
void Ext2fs::freeBlocksFromInode(u32_t inum)
{
}

View File

@ -117,7 +117,7 @@ typedef struct
u32_t i_dtime; // Deletion time
u16_t i_gid; // Group ID
u16_t i_links_count; // Links count
u32_t i_blocks; // Blocks count
u32_t i_blocks; // Disk Blocks count (512)
u32_t i_flags; // File flags
u32_t i_reserved1;
u32_t i_block[15]; // Pointers to blocks (12 direct, single, double, triple indirect)
@ -136,24 +136,36 @@ typedef struct
u32_t inode; // inode number
u16_t length; // directory entry length
u8_t name_length; // name length
u8_t file_type; // File type
u8_t file_type; // File type (used???)
char name[EXT2_NAME_LEN];
} ext2_dir_entry_t;
#ifdef _HOS_CPP_
#include "Ext2OpenDirectory.h"
#include "Ext2OpenFile.h"
int ext2_init();
FileSystem *ext2__mount_func(device_t dev);
class Ext2fs : public FileSystem
{
protected:
/* my data members */
device_t myDevice;
int mySuperDirty;
ext2_super_block_t mySuper;
u32_t myNumGroups;
u32_t myGroupDescriptorBlocks;
u32_t myInodeTableBlocks;
u32_t myGroupDescriptorsPerBlock;
u32_t myInodesPerBlock;
/* my functions */
int readGroupDescriptor(u32_t group, ext2_group_desc_t *buf);
int writeGroupDescriptor(u32_t group, ext2_group_desc_t *buf);
int inodeStatus(u32_t inum);
int blockStatus(u32_t bnum);
u32_t allocFromBitmap(u32_t blockNum, u32_t max);
void freeFromBitmap(u32_t blockNum, u32_t node);
public:
Ext2fs(ext2_super_block_t *super, device_t dev);
~Ext2fs();
@ -162,9 +174,27 @@ public:
u32_t totalInodes();
u32_t freeInodes();
u32_t getRootInodeNumber();
OpenDirectory *openDirectory(u32_t inum);
OpenFile *openFile(u32_t inum);
OpenDirectory *openDirectory(u32_t inum, int mode);
int stat(u32_t inum, vfs_stat_t *buf);
int readBlock(u32_t blockNum, void *buf);
int writeBlock(u32_t blockNum, void *buf);
int link_deref(u32_t inum, char *buf);
int readInode(u32_t inum, ext2_inode_t *buf);
int writeInode(u32_t inum, ext2_inode_t *buf);
void notifyTruncatedFiles(u32_t inum);
u32_t allocInode();
u32_t allocBlock();
int freeInode(u32_t inum);
int freeBlock(u32_t bnum);
void unlink(u32_t inum);
int attemptRemoveDir(u32_t inum);
void freeBlocksFromInode(u32_t inum);
/* inlined functions */
inline u32_t numGroups() { return myNumGroups; }
inline u32_t groupDescriptorBlocks() { return myGroupDescriptorBlocks; }
inline u32_t inodeTableBlocks() { return myInodeTableBlocks; }
inline ext2_super_block_t *getSuper() { return &mySuper; }
};
#endif

View File

@ -0,0 +1,332 @@
// lookup a file name in a directory and store the directory entry for it
int ext2_dir_lookup(vfs_mount_t *mount, u32_t dir_inode, char *fileName, ext2_dir_entry_t *direntry)
{
ext2_open_dir_t *dir = ext2_open_dir(mount, dir_inode);
if (!dir)
return -1; // bad directory inode number
ext2_dir_entry_t dentry;
while (!ext2_dir_read_entry(mount, dir, &dentry))
{
char *dentryName = kcalloc(1, dentry.name_length + 1);
memcpy(dentryName, dentry.name, dentry.name_length);
int res = strcmp(fileName, dentryName);
kfree(dentryName);
if (!res)
{
*direntry = dentry;
ext2_close_dir(mount, dir);
return 0;
}
}
ext2_close_dir(mount, dir);
return -2;
}
// open a directory by inode number for reading
ext2_open_dir_t *ext2_open_dir(vfs_mount_t *mount, u32_t inode_number)
{
ext2_open_dir_t *open_dir = New(ext2_open_dir_t);
ext2_open_inode_t *open_inode = ext2_open_inode(mount, inode_number);
if (!open_inode)
{
kfree(open_dir);
return NULL;
}
if ((open_inode->inode.i_mode & EXT2_I_MODE_TYPE_MASK) != EXT2_I_MODE_DIR)
{
ext2_close_inode(mount, open_inode);
kfree(open_dir);
return NULL;
}
open_dir->open_inode = open_inode;
open_dir->position = 0;
return open_dir;
}
int ext2_dir_read_entry(vfs_mount_t *mount, ext2_open_dir_t *open_dir, ext2_dir_entry_t *dentry)
{
ext2_super_block_t *super = mount->super;
if (open_dir->position >= open_dir->open_inode->inode.i_size)
return -1; // EOF
u32_t dir_block = open_dir->position >> (10 + super->s_log_block_size);
char *block = kmalloc(2048 << super->s_log_block_size);
ext2_inode_seek(mount, open_dir->open_inode, dir_block);
if (ext2_read_inode_block(mount, open_dir->open_inode, block))
ext2_read_inode_block(mount, open_dir->open_inode, block + (1024 << super->s_log_block_size));
ext2_dir_entry_t *dir_entry = (ext2_dir_entry_t *)(block + open_dir->position % (1024 << super->s_log_block_size));
if (!dir_entry->inode)
{
kfree(block);
return -2; // EOF
}
memcpy(dentry, dir_entry, min(dir_entry->length, sizeof(ext2_dir_entry_t)));
open_dir->position += dir_entry->length;
kfree(block);
return 0;
}
int ext2_close_dir(vfs_mount_t *mount, ext2_open_dir_t *open_dir)
{
ext2_close_inode(mount, open_dir->open_inode);
kfree(open_dir);
return 0;
}
// open an inode for reading
ext2_open_inode_t *ext2_open_inode(vfs_mount_t *mount, u32_t inode_number)
{
ext2_open_inode_t *open_inode = New(ext2_open_inode_t);
if ( ext2_read_inode(mount, inode_number, &(open_inode->inode)) )
{
kfree(open_inode);
return NULL;
}
open_inode->block = 0;
open_inode->block_pointers = NULL;
open_inode->block_pointers_start = 0;
mount->refs++;
return open_inode;
}
// seek to a certain block of an open inode
int ext2_inode_seek(vfs_mount_t *mount, ext2_open_inode_t *open_inode, u32_t block_number)
{
ext2_super_block_t *super = mount->super;
if (open_inode->inode.i_size <= (block_number << (10 + super->s_log_block_size)))
return -1; // at or past EOF
open_inode->block = block_number;
return 0;
}
// returns number of bytes read
int ext2_read_inode_block(vfs_mount_t *mount, ext2_open_inode_t *open_inode, void *block)
{
ext2_super_block_t *super = mount->super;
if (open_inode->inode.i_size <= (open_inode->block << (10 + super->s_log_block_size)))
return 0; // at or past EOF
u32_t leftover_bytes = open_inode->inode.i_size - (open_inode->block << (10 + super->s_log_block_size));
u32_t block_number = ext2_block_number(mount, open_inode);
block_read(mount->major, mount->minor, ext2_FSToDiskBlock(block_number, super),
2 << super->s_log_block_size, block);
open_inode->block++;
return min(leftover_bytes, 1024 << super->s_log_block_size);
}
// close an open inode
int ext2_close_inode(vfs_mount_t *mount, ext2_open_inode_t *open_inode)
{
mount->refs--;
if (open_inode->block_pointers)
kfree(open_inode->block_pointers); // free the block pointers cache
kfree(open_inode);
return 0;
}
// transform open_inode->block (a relative block number) to an absolute block number for the filesystem
u32_t ext2_block_number(vfs_mount_t *mount, ext2_open_inode_t *open_inode)
{
if (open_inode->block < 12)
return open_inode->inode.i_block[open_inode->block];
ext2_super_block_t *super = mount->super;
int pointersPerBlock = 256 << super->s_log_block_size;
if (open_inode->block_pointers && // there is a block pointers cache block allocated
(open_inode->block >= open_inode->block_pointers_start) && // and the block number is in it
(open_inode->block < (open_inode->block_pointers_start + pointersPerBlock)))
return open_inode->block_pointers[open_inode->block - open_inode->block_pointers_start];
u32_t rel_block = open_inode->block - 12;
if (!open_inode->block_pointers)
open_inode->block_pointers = kmalloc(pointersPerBlock << 2);
if (rel_block < pointersPerBlock) // indirect block in i_block[12]
{
block_read(mount->major, mount->minor, ext2_FSToDiskBlock(open_inode->inode.i_block[12], super),
2 << super->s_log_block_size, open_inode->block_pointers);
open_inode->block_pointers_start = 12;
return open_inode->block_pointers[rel_block];
}
rel_block -= pointersPerBlock;
if (rel_block < (pointersPerBlock * pointersPerBlock)) // double-indirect block in i_block[13]
{
block_read(mount->major, mount->minor, ext2_FSToDiskBlock(open_inode->inode.i_block[13], super),
2 << super->s_log_block_size, open_inode->block_pointers);
u32_t real_block = open_inode->block_pointers[rel_block / pointersPerBlock];
block_read(mount->major, mount->minor, ext2_FSToDiskBlock(real_block, super),
2 << super->s_log_block_size, open_inode->block_pointers);
open_inode->block_pointers_start = 12 + pointersPerBlock + rel_block - (rel_block % pointersPerBlock);
return open_inode->block_pointers[rel_block % pointersPerBlock];
}
// this code shouldn't run unless we are dealing with a 65+mb file ...
rel_block -= pointersPerBlock * pointersPerBlock;
block_read(mount->major, mount->minor, ext2_FSToDiskBlock(open_inode->inode.i_block[14], super),
2 << super->s_log_block_size, open_inode->block_pointers);
u32_t index_1 = rel_block / (pointersPerBlock * pointersPerBlock);
u32_t leftover_1 = rel_block % (pointersPerBlock * pointersPerBlock);
u32_t block_1 = open_inode->block_pointers[index_1];
block_read(mount->major, mount->minor, ext2_FSToDiskBlock(block_1, super),
2 << super->s_log_block_size, open_inode->block_pointers);
u32_t index_2 = leftover_1 / pointersPerBlock;
u32_t leftover_2 = leftover_1 % pointersPerBlock;
u32_t block_2 = open_inode->block_pointers[index_2];
block_read(mount->major, mount->minor, ext2_FSToDiskBlock(block_2, super),
2 << super->s_log_block_size, open_inode->block_pointers);
open_inode->block_pointers_start = 12 + (pointersPerBlock + 1) * pointersPerBlock + rel_block - (rel_block % pointersPerBlock);
return open_inode->block_pointers[leftover_2];
}
int ext2_resize_inode(vfs_mount_t *mount, u32_t inode_number, u32_t new_size)
{
ext2_inode_t inode;
if ( ext2_read_inode(mount, inode_number, &inode) )
return -1;
ext2_super_block_t *super = mount->super;
int current_blocks = (inode.i_size + (1024 << super->s_log_block_size) - 1) >> (10 + super->s_log_block_size);
int new_blocks = (new_size + (1024 << super->s_log_block_size) - 1) >> (10 + super->s_log_block_size);
if ( new_blocks == current_blocks )
return 0;
// TODO: resize
u32_t block_size = 1024 << super->s_log_block_size;
u32_t pointers_per_block = block_size >> 2;
u32_t *pointer_cache1 = kmalloc(3 * block_size);
u32_t *pointer_cache2 = pointer_cache1 + pointers_per_block;
u32_t *pointer_cache3 = pointer_cache2 + pointers_per_block;
u32_t c1_start, c2_start, c3_start;
c1_start = c2_start = c3_start = 0;
while (new_blocks < current_blocks) // delete, decrease current_blocks
{
current_blocks--;
// now delete block number current_blocks
}
while (current_blocks < new_blocks) // add, increase current_blocks
{
}
}
/***************** VFS INTERFACE FUNCTIONS *******************/
// VFS interface function to open a directory
int ext2__open_dir(vfs_mount_t *mount, u32_t inode_number, vfs_open_file_t *dir)
{
if (ext2_inode_status(mount, inode_number) != 1)
return -1;
ext2_open_dir_t *open_dir = ext2_open_dir(mount, inode_number);
if (!open_dir)
return -2;
dir->fs_data = open_dir;
return 0;
}
// VFS interface function to read a directory entry from an open directory
int ext2__read_dir(vfs_mount_t *mount, vfs_open_file_t *dir, vfs_dir_entry_t *dentry)
{
ext2_dir_entry_t t_dentry;
int status = ext2_dir_read_entry(mount, dir->fs_data, &t_dentry);
if (status)
return status;
memcpy(dentry->name, t_dentry.name, t_dentry.name_length);
dentry->name[t_dentry.name_length] = 0;
dentry->inode_number = t_dentry.inode;
return 0;
}
// VFS interface function to close an open directory
int ext2__close_dir(vfs_mount_t *mount, vfs_open_file_t *dir)
{
return ext2_close_dir(mount, dir->fs_data);
}
// VFS interface function to open a file for reading a byte at a time
int ext2__open_file(vfs_mount_t *mount, u32_t inode_number, vfs_open_file_t *open_file)
{
if (ext2_inode_status(mount, inode_number) != 1)
return -1;
return 0;
}
// VFS interface function to read a byte from an open file
int ext2__read_file(vfs_mount_t *mount, vfs_open_file_t *open_file)
{
return 0;
}
// VFS interface function to close a byte-file
int ext2__close_file(vfs_mount_t *mount, vfs_open_file_t *open_file)
{
return 0;
}
// VFS interface function to open a file for reading 512-byte blocks at a time
int ext2__open_block_file(vfs_mount_t *mount, u32_t inode_number, vfs_open_file_t *open_file)
{
if (ext2_inode_status(mount, inode_number) != 1)
return -1;
ext2_open_inode_t *open_inode = ext2_open_inode(mount, inode_number);
if (!open_inode)
return -2;
if ((open_inode->inode.i_mode & EXT2_I_MODE_TYPE_MASK) != EXT2_I_MODE_FILE)
{
ext2_close_inode(mount, open_inode);
return -3;
}
ext2__open_block_file_t *open_block_file = New(ext2__open_block_file_t);
open_block_file->open_inode = open_inode;
open_block_file->block = 0;
open_file->fs_data = open_block_file;
return 0;
}
// VFS interface function to read a block from an open block file
// returns the number of bytes read
int ext2__read_block_file(vfs_mount_t *mount, vfs_open_file_t *open_file, void *buffer)
{
ext2_super_block_t *super = mount->super;
ext2__open_block_file_t *open_block_file = open_file->fs_data;
if (ext2_inode_seek(mount, open_block_file->open_inode, ext2_diskToFSBlock(open_block_file->block, super)))
return 0; // EOF
u8_t *block = kmalloc(1024 << super->s_log_block_size);
u32_t file_position_read = (1024 << super->s_log_block_size) * open_block_file->open_inode->block;
u32_t file_position_want = open_block_file->block << 9;
u32_t data_offset = file_position_want - file_position_read;
int bytes_read = ext2_read_inode_block(mount, open_block_file->open_inode, block);
if (bytes_read <= data_offset)
{
kfree(block);
return 0; // EOF
}
memcpy(buffer, block + data_offset, min(512, bytes_read - data_offset));
kfree(block);
open_block_file->block++;
return min(512, bytes_read - data_offset);
}
// VFS interface function to seek to a certain block number of an open block file
int ext2__block_file_seek(vfs_mount_t *mount, vfs_open_file_t *open_file, u32_t block_number)
{
ext2__open_block_file_t *open_block_file = open_file->fs_data;
return ext2_inode_seek(mount, open_block_file->open_inode, ext2_FSToDiskBlock(block_number, mount->super));
}
// VFS interface function to close an open block file
int ext2__close_block_file(vfs_mount_t *mount, vfs_open_file_t *open_file)
{
ext2__open_block_file_t *open_block_file = open_file->fs_data;
ext2_close_inode(mount, open_block_file->open_inode);
kfree(open_block_file);
return 0;
}

View File

@ -0,0 +1,241 @@
// ext2.h
// Author: Josh Holtrop
// Date: 08/22/04
// Modified: 12/24/04
#ifndef __HOS_EXT2_H__
#define __HOS_EXT2_H__ __HOS_EXT2_H__
#include "hos_defines.h"
#include "fs/devices.h"
#include "fs/vfs.h"
#define EXT2_MAGIC 0xEF53
#define EXT2_NAME_LEN 255
#define EXT2_I_MODE_ATTR_MASK 0x0FFF
#define EXT2_I_MODE_OX 0x0001
#define EXT2_I_MODE_OW 0x0002
#define EXT2_I_MODE_OR 0x0004
#define EXT2_I_MODE_GX 0x0008
#define EXT2_I_MODE_GW 0x0010
#define EXT2_I_MODE_GR 0x0020
#define EXT2_I_MODE_UX 0x0040
#define EXT2_I_MODE_UW 0x0080
#define EXT2_I_MODE_UR 0x0100
#define EXT2_I_MODE_STICKY 0x0200
#define EXT2_I_MODE_SGID 0x0400
#define EXT2_I_MODE_SUID 0x0800
#define EXT2_I_MODE_TYPE_MASK 0xF000
#define EXT2_I_MODE_FIFO 0x1000
#define EXT2_I_MODE_CHAR 0x2000
#define EXT2_I_MODE_DIR 0x4000
#define EXT2_I_MODE_BLOCK 0x6000
#define EXT2_I_MODE_FILE 0x8000
#define EXT2_I_MODE_SYM 0xA000
#define EXT2_I_MODE_SOCK 0xC000
#define EXT2_I_FLAGS_SEC_DEL 0x01
#define EXT2_I_FLAGS_UNDELETE 0x02
#define EXT2_I_FLAGS_COMPRESS 0x04
#define EXT2_I_FLAGS_SYNC 0x08
#define EXT2_I_FLAGS_IMMUTABLE 0x10
#define EXT2_I_FLAGS_APPEND 0x20
#define EXT2_I_FLAGS_NODUMP 0x40
#define EXT2_INODE_BAD_BLOCKS 1
#define EXT2_INODE_ROOT 2
#define EXT2_INODE_ACL_INDEX 3
#define EXT2_INODE_ACL_DATA 4
#define EXT2_INODE_BOOT_LOADER 5
#define EXT2_INODE_UNDELETE_DIR 6
#define EXT2_INODE_AVAIL 11
#define EXT2_FT_UNKNOWN 0
#define EXT2_FT_FILE 1
#define EXT2_FT_DIR 2
#define EXT2_FT_CHAR 3
#define EXT2_FT_BLOCK 4
#define EXT2_FT_FIFO 5
#define EXT2_FT_SOCK 6
#define EXT2_FT_SYMLINK 7
#define EXT2_FT_MAX 8
typedef struct
{
u32_t s_inodes_count; /* Inodes count */
u32_t s_blocks_count; /* Blocks count */
u32_t s_r_blocks_count; /* Reserved blocks count */
u32_t s_free_blocks_count; /* Free blocks count */
u32_t s_free_inodes_count; /* Free inodes count */
u32_t s_first_data_block; /* First Data Block */
u32_t s_log_block_size; /* Block size: 0->1024, 1->2048, 2->4096 */
int s_log_frag_size; /* Fragment size */
u32_t s_blocks_per_group; /* # Blocks per group */
u32_t s_frags_per_group; /* # Fragments per group */
u32_t s_inodes_per_group; /* # Inodes per group */
u32_t s_mtime; /* Mount time */
u32_t s_wtime; /* Write time */
u16_t s_mnt_count; /* Mount count */
short s_max_mnt_count; /* Maximal mount count */
u16_t s_magic; /* Magic signature */
u16_t s_state; /* File system state */
u16_t s_errors; /* Behaviour when detecting errors */
u16_t s_minor_rev_level; /* minor revision level */
u32_t s_lastcheck; /* time of last check */
u32_t s_checkinterval; /* max. time between checks */
u32_t s_creator_os; /* OS */
u32_t s_rev_level; /* Revision level */
u16_t s_def_resuid; /* Default uid for reserved blocks */
u16_t s_def_resgid; /* Default gid for reserved blocks */
u32_t s_reserved[235];
} ext2_super_block_t;
typedef struct
{
u32_t bg_block_bitmap; // Blocks bitmap block
u32_t bg_inode_bitmap; // Inode bitmap block
u32_t bg_inode_table; // Inode table block
u16_t bg_free_blocks_count; // Free blocks count
u16_t bg_free_inodes_count; // Free Inodes count
u16_t bg_used_dirs_count; // Directories count
u16_t bg_pad1;
u32_t bg_reserved[3];
} ext2_group_desc_t;
typedef struct
{
u16_t i_mode; // File mode
u16_t i_uid; // Owner UID
u32_t i_size; // Size in bytes
u32_t i_atime; // Access time
u32_t i_ctime; // Creation time
u32_t i_mtime; // Modification time
u32_t i_dtime; // Deletion time
u16_t i_gid; // Group ID
u16_t i_links_count; // Links count
u32_t i_blocks; // Blocks count
u32_t i_flags; // File flags
u32_t i_reserved1;
u32_t i_block[15]; // Pointers to blocks (12 direct, single, double, triple indirect)
u32_t i_version; // File version (for NFS)
u32_t i_file_acl; // File ACL
u32_t i_dir_acl; // Directory ACL
u32_t i_faddr; // Fragment address
u8_t i_frag; // Fragment number
u8_t i_fsize; // Fragment size
u16_t i_pad1;
u32_t i_reserved2[2];
} ext2_inode_t;
typedef struct
{
u32_t inode; // inode number
u16_t length; // directory entry length
u8_t name_length; // name length
u8_t file_type; // File type
char name[EXT2_NAME_LEN];
} ext2_dir_entry_t;
typedef struct
{
ext2_inode_t inode;
u32_t block;
u32_t *block_pointers;
u32_t block_pointers_start;
} ext2_open_inode_t;
typedef struct
{
ext2_open_inode_t *open_inode;
u32_t position;
} ext2_open_dir_t;
typedef struct
{
ext2_open_inode_t *open_inode;
u32_t position;
u32_t buffer_start;
u32_t buffer_bytes;
u8_t *buffer;
} ext2__open_file_t;
typedef struct
{
ext2_open_inode_t *open_inode;
u32_t block;
} ext2__open_block_file_t;
static inline u32_t ext2_diskToFSBlock(u32_t block, ext2_super_block_t *super)
{
// convert # of disk blocks to # of filesystem blocks
return block >> (super->s_log_block_size + 1);
}
static inline u32_t ext2_FSToDiskBlock(u32_t block, ext2_super_block_t *super)
{
// convert # of filesystem blocks to # of disk blocks
return block << (super->s_log_block_size + 1);
}
int ext2_init(int fsID);
int ext2_read_inode(vfs_mount_t *mount, u32_t inode, ext2_inode_t *dat);
int ext2_write_inode(vfs_mount_t *mount, u32_t inode, ext2_inode_t *dat);
ext2_group_desc_t ext2_get_group_desc(vfs_mount_t *mount, u32_t group);
void ext2_write_group_desc(vfs_mount_t *mount, u32_t group_num, ext2_group_desc_t *gd);
ext2_open_inode_t *ext2_open_inode(vfs_mount_t *mount, u32_t inode_number);
int ext2_close_inode(vfs_mount_t *mount, ext2_open_inode_t *open_inode);
int ext2_read_inode_block(vfs_mount_t *mount, ext2_open_inode_t *open_inode, void *block);
u32_t ext2_block_number(vfs_mount_t *mount, ext2_open_inode_t *open_inode);
int ext2_inode_seek(vfs_mount_t *mount, ext2_open_inode_t *open_inode, u32_t block_number);
int ext2_inode_status(vfs_mount_t *mount, u32_t inode_number);
int ext2_block_status(vfs_mount_t *mount, u32_t block_number);
u32_t ext2_alloc_inode(vfs_mount_t *mount);
int ext2_free_inode(vfs_mount_t *mount, u32_t inode_number);
u32_t ext2_alloc_block(vfs_mount_t *mount);
int ext2_free_block(vfs_mount_t *mount, u32_t block_number);
u32_t ext2_reserve_node(vfs_mount_t *mount, u32_t bitmap_block_num, u32_t bitmap_size);
int ext2_free_node(vfs_mount_t *mount, u32_t bitmap_block_num, u32_t node_number);
int ext2_num_block_groups(ext2_super_block_t *super);
void ext2_write_super(vfs_mount_t *mount);
int ext2_resize_inode(vfs_mount_t *mount, u32_t inode_number, u32_t new_size);
ext2_open_dir_t *ext2_open_dir(vfs_mount_t *mount, u32_t inode_number);
int ext2_dir_read_entry(vfs_mount_t *mount, ext2_open_dir_t *open_dir, ext2_dir_entry_t *dentry);
int ext2_close_dir(vfs_mount_t *mount, ext2_open_dir_t *open_dir);
int ext2_dir_lookup(vfs_mount_t *mount, u32_t dir_inode, char *fileName, ext2_dir_entry_t *direntry);
void *ext2_mount_super(major_t major, minor_t minor);
int ext2_umount_super(vfs_mount_t *mount);
int ext2_stat(vfs_mount_t *mount, u32_t inode_number, vfs_stat_t *stat);
u32_t ext2__get_root_dir_inode(vfs_mount_t *mount);
int ext2__link_deref(vfs_mount_t *mount, u32_t link_inode, char *link);
int ext2__free_inodes(vfs_mount_t *mount);
int ext2__total_inodes(vfs_mount_t *mount);
int ext2__free_blocks(vfs_mount_t *mount);
int ext2__total_blocks(vfs_mount_t *mount);
int ext2__open_dir(vfs_mount_t *mount, u32_t inode_number, vfs_open_file_t *dir);
int ext2__read_dir(vfs_mount_t *mount, vfs_open_file_t *dir, vfs_dir_entry_t *dentry);
int ext2__close_dir(vfs_mount_t *mount, vfs_open_file_t *dir);
int ext2__open_file(vfs_mount_t *mount, u32_t inode_number, vfs_open_file_t *open_file);
int ext2__read_file(vfs_mount_t *mount, vfs_open_file_t *open_file);
int ext2__close_file(vfs_mount_t *mount, vfs_open_file_t *open_file);
int ext2__open_block_file(vfs_mount_t *mount, u32_t inode_number, vfs_open_file_t *open_file);
int ext2__read_block_file(vfs_mount_t *mount, vfs_open_file_t *open_file, void *buffer);
int ext2__block_file_seek(vfs_mount_t *mount, vfs_open_file_t *open_file, u32_t block_number);
int ext2__close_block_file(vfs_mount_t *mount, vfs_open_file_t *open_file);
#endif

View File

@ -4,8 +4,6 @@
// Date: 06/27/05
// Modified: 06/27/05
#define _HOS_CPP_ _HOS_CPP_
extern "C" {
#include "display/kout.h"
}

View File

@ -4,8 +4,6 @@
// Date: 06/27/05
// Modified: 06/27/05
#define _HOS_CPP_ _HOS_CPP_
#include "sysfs_entry.h"
#include "lang/string.h"

View File

@ -4,8 +4,6 @@
// Date: 05/10/05
// Modified: 12/26/05
#define _HOS_CPP_ _HOS_CPP_
extern "C" {
#include "hos_defines.h"
#include "display/kout.h"
@ -26,13 +24,15 @@ extern "C" {
FileSystem *vfs_attempt_mount(device_t device, char *fsType);
mount_func_t vfs_get_mount_func(const string & fsName);
inode_num_t vfs_get_inode(const string & path);
inode_num_t vfs_get_dir_inode(const string & path);
inode_num_t vfs_get_inode_rel(const string & path, inode_num_t start_dir);
inode_num_t vfs_get_dir_entry_inode(inode_num_t dir, const string & fname);
int vfs_stat_inode(inode_num_t inum, vfs_stat_t *statptr);
int vfs_link_deref_inode(inode_num_t inum, char *link);
VFSMount *vfs_get_mount(u32_t mt_id);
vector<string> vfs_split_dirs(const string & path);
OpenDirectory *vfs_open_directory_inode(inode_num_t inum);
OpenFile *vfs_open_file_inode(inode_num_t inum);
OpenDirectory *vfs_open_directory_inode(inode_num_t inum, int mode);
OpenFile *vfs_open_file_inode(inode_num_t inum, int mode);
void vfs_close_directory_real(OpenDirectory *o);
void vfs_close_file_real(OpenFile *o);
inode_num_t vfs_get_real_inode(inode_num_t inum);
@ -140,23 +140,33 @@ int vfs_stat(char *name, vfs_stat_t *buff)
{
string sname = string(name);
inode_num_t inum;
if ((inum = vfs_get_inode(sname)) == 0)
if ((inum = vfs_get_inode(sname)) == 0ULL)
return -502;
return vfs_stat_inode(inum, buff);
}
/* dereference a symbolic link */
int vfs_link_deref(char *name, char *buff)
{
string sname = string(name);
inode_num_t inum;
if ((inum = vfs_get_inode(sname)) == 0ULL)
return -502;
return vfs_link_deref_inode(inum, buff);
}
void *vfs_open_dir(char *name)
{
string sname(name);
inode_num_t inum = vfs_get_inode(sname);
return (void *) vfs_open_directory_inode(inum);
return (void *) vfs_open_directory_inode(inum, VFS_MODE_READ);
}
void *vfs_open_file(char *name)
void *vfs_open_file(char *name, int mode)
{
string sname(name);
inode_num_t inum = vfs_get_inode(sname);
return (void *) vfs_open_file_inode(inum);
return (void *) vfs_open_file_inode(inum, mode);
}
void vfs_close_dir(void *o)
@ -175,12 +185,6 @@ int vfs_read_dir(void *o, vfs_dir_entry_t *dirent)
return odir->read(dirent);
}
int vfs_write_dir(void *o, vfs_dir_entry_t *dirent)
{
OpenDirectory *odir = (OpenDirectory *) o;
return odir->write(dirent);
}
int vfs_seek_dir(void *o, int pos, int mode)
{
OpenDirectory *odir = (OpenDirectory *) o;
@ -238,6 +242,19 @@ inode_num_t vfs_get_inode(const string & path)
return vfs_get_inode_rel(path, 0ULL);
}
/* Just get the inode of the directory containing the file */
inode_num_t vfs_get_dir_inode(const string & path)
{
vector<string> paths = vfs_split_dirs(path);
string dirPath("");
for (unsigned int i = 0; i < paths.size()-1; i++)
{
dirPath += "/";
dirPath += paths[i];
}
return vfs_get_inode_rel(dirPath, 0ULL);
}
/* Trace file name to inode starting from this directory (recursive) */
inode_num_t vfs_get_inode_rel(const string & path, inode_num_t start_dir)
{
@ -257,7 +274,7 @@ inode_num_t vfs_get_inode_rel(const string & path, inode_num_t start_dir)
/* return the inode of a directory entry in the directory pointed to by dir */
inode_num_t vfs_get_dir_entry_inode(inode_num_t dir, const string & fname)
{
OpenDirectory *odir = vfs_open_directory_inode(dir);
OpenDirectory *odir = vfs_open_directory_inode(dir, VFS_MODE_READ);
if (odir == NULL)
return 0ULL;
vfs_dir_entry_t dir_ent;
@ -337,24 +354,34 @@ int vfs_stat_inode(inode_num_t inum, vfs_stat_t *statptr)
return mt->myFS->stat((u32_t)inum, statptr);
}
/* FS function: dereference a link by inode number, return error code */
int vfs_link_deref_inode(inode_num_t inum, char *link)
{
inum = vfs_get_real_inode(inum);
VFSMount *mt = vfs_get_mount(inum >> 32);
if (mt == NULL)
return -501;
return mt->myFS->link_deref((u32_t)inum, link);
}
/* FS function: open a directory based on the inode number */
OpenDirectory *vfs_open_directory_inode(inode_num_t inum)
OpenDirectory *vfs_open_directory_inode(inode_num_t inum, int mode)
{
inum = vfs_get_real_inode(inum);
VFSMount *mt = vfs_get_mount(inum >> 32);
if (mt == NULL)
return NULL;
return mt->myFS->openDirectory((u32_t)inum);
return mt->myFS->openDirectory((u32_t)inum, mode);
}
/* FS function: open a file based on the inode number */
OpenFile *vfs_open_file_inode(inode_num_t inum)
OpenFile *vfs_open_file_inode(inode_num_t inum, int mode)
{
inum = vfs_get_real_inode(inum);
VFSMount *mt = vfs_get_mount(inum >> 32);
if (mt == NULL)
return NULL;
return mt->myFS->openFile((u32_t)inum);
return mt->myFS->openFile((u32_t)inum, mode);
}
/* FS function: close a directory */

View File

@ -32,11 +32,19 @@
#define EOF 0x100
#define VFS_MAX_FILENAME 255
#define VFS_MAX_PATH_LENGTH 1024
#define SEEK_ABSOLUTE 0
#define SEEK_RELATIVE 1
#define SEEK_END 2
#define VFS_MODE_RW_MASK 0x1
#define VFS_MODE_READ 0x0
#define VFS_MODE_WRITE 0x1
#define VFS_MODE_WRITE_MASK 0x2
#define VFS_MODE_TRUNCATE 0x0
#define VFS_MODE_APPEND 0x2
#include "hos_defines.h"
#include "devices.h"
@ -82,13 +90,13 @@ int vfs_init();
int vfs_mount(device_t device, char *fsType, char *mountPoint);
int vfs_umount(device_t dev);
int vfs_stat(char *name, vfs_stat_t *buff);
int vfs_link_deref(char *name, char *buff);
int vfs_get_mount_info(unsigned int mountNum, vfs_mount_info_t *infoptr);
void *vfs_open_dir(char *name);
void *vfs_open_file(char *name);
void *vfs_open_file(char *name, int mode);
void vfs_close_dir(void *o);
void vfs_close_file(void *o);
int vfs_read_dir(void *o, vfs_dir_entry_t *dirent);
int vfs_write_dir(void *o, vfs_dir_entry_t *dirent);
int vfs_seek_dir(void *o, int pos, int mode);
int vfs_read_file(void *o);
int vfs_read_file_block(void *o, void *buf, u32_t num);

View File

@ -159,12 +159,12 @@ void k_init()
}
*/ }
vfs_mount_info_t mt_info;
vfs_get_mount_info(0, &mt_info);
kprintf("%s, %s, %d, %d, %d, %d\n", mt_info.fs, mt_info.mountPoint, mt_info.totalBlocks, mt_info.freeBlocks, mt_info.totalInodes, mt_info.freeInodes);
// vfs_mount_info_t mt_info;
// vfs_get_mount_info(0, &mt_info);
// kprintf("%s, %s, %d, %d, %d, %d\n", mt_info.fs, mt_info.mountPoint, mt_info.totalBlocks, mt_info.freeBlocks, mt_info.totalInodes, mt_info.freeInodes);
void *root = vfs_open_dir("///");
char name[256];
char name[VFS_MAX_PATH_LENGTH];
if (root)
{
vfs_dir_entry_t dentry;
@ -194,8 +194,7 @@ void k_init()
if (fstat.type == VFS_FT_SYMLINK)
{
char *link = kmalloc(4096);
//vfs_link_deref(dentry.inode, link);
strcpy(link, "[a link]");
vfs_link_deref(name, link);
kprintf(" -> %s", link);
kfree(link);
}

View File

@ -4,8 +4,6 @@
// Modified: 08/28/05
// Implements a basic hash table (u32_t -> void*)
#define __HOS_CPP__
#include "hos_defines.h"
#include "hash.h"
#include "lang/vector.h"

View File

@ -3,8 +3,6 @@
// Date; 08/18/05
// Modified: 08/18/05
#define __HOS_CPP__
extern "C" {
#include "hos_defines.h"

View File

@ -6,7 +6,7 @@
#ifndef __HOS_PROC_H__
#define __HOS_PROC_H__ __HOS_PROC_H__
#ifdef __HOS_CPP__
#ifdef _HOS_CPP_
extern "C" {
#endif
@ -81,7 +81,7 @@ void copy_into_address_space(u32_t dest_addr,
process_t *p);
void zero_address_space(u32_t dest_addr, u32_t pages, process_t *p);
#ifdef __HOS_CPP__
#ifdef _HOS_CPP_
}
#endif

View File

@ -3,8 +3,6 @@
// Date: 07/13/05
// Modified: 07/17/05
#define _HOS_CPP_
extern "C" {
#include "hos_defines.h"
#include "display/kout.h"