diff --git a/repos/dde_rump/run/rump_ext2.run b/repos/dde_rump/run/rump_ext2.run index 8800307..9bd0809 100644 --- a/repos/dde_rump/run/rump_ext2.run +++ b/repos/dde_rump/run/rump_ext2.run @@ -24,8 +24,8 @@ build $build_components # # Build EXT2-file-system image # -catch { exec $dd if=/dev/zero of=bin/ext2.raw bs=1M count=16 } -catch { exec $mke2fs -F bin/ext2.raw } +#catch { exec $dd if=/dev/zero of=bin/ext2.raw bs=1M count=16 } +#catch { exec $mke2fs -F bin/ext2.raw } create_boot_directory @@ -60,7 +60,7 @@ append config { - + @@ -96,4 +96,4 @@ append qemu_args " -m 256 -nographic" run_genode_until {.*child "test-libc_vfs" exited with exit value 0.*} 60 -exec rm -f bin/ext2.raw +#exec rm -f bin/ext2.raw diff --git a/repos/dde_rump/src/server/rump_fs/Ext2Filesystem.cc b/repos/dde_rump/src/server/rump_fs/Ext2Filesystem.cc new file mode 100644 index 0000000..18db68d --- /dev/null +++ b/repos/dde_rump/src/server/rump_fs/Ext2Filesystem.cc @@ -0,0 +1,625 @@ +#include "Ext2Filesystem.h" +#include "Ext2Directory.h" +#include "Ext2File.h" + +Ext2Filesystem::Ext2Filesystem(Genode::Allocator &md_alloc) : + m_alloc(md_alloc),m_pSuperblock(0), m_pGroupDescriptors(), m_BlockSize(0), m_InodeSize(0), + m_nGroupDescriptors(0){ +} + +Ext2Filesystem::~Ext2Filesystem() +{ + if(m_pRoot) + m_alloc.free((void*)m_pRoot,sizeof(File*)); +} + +bool Ext2Filesystem::initialise() +{ + m_pSuperblock=new (&m_alloc)Superblock; +File_system::readb(2,2,buff); + + + Genode::memcpy((void*)m_pSuperblock,(void*)buff,1024); + +PERR("Ext2 Magic Number :: %x\n",m_pSuperblock->s_magic); +PERR(" Ext2 rev level :: %lu\n",m_pSuperblock->s_rev_level); + // Read correctly? + if (m_pSuperblock->s_magic != 0xef53) + { + PERR("Ext2: Superblock not found on device : device 0 " ); + + } + + // Clean? + if (m_pSuperblock->s_state != 1) + { + PDBG("Ext2: filesystem on device dev :: 0 is not clean."); + } + + m_InodeSize = sizeof(Inode); + +PERR("Ext2 :: block size %d :: First data block %lu \n",1024<s_log_block_size,m_pSuperblock->s_first_data_block); + // Calculate the block size. + m_BlockSize = 1024 << m_pSuperblock->s_log_block_size; + + + + // Where is the group descriptor table? + uint32_t gdBlock = m_pSuperblock->s_first_data_block + 1; + + // How many group descriptors do we have? Round up the result. + uint32_t inodeCount = m_pSuperblock->s_inodes_count; +PERR("Ext2 Free Inodes Count :: %lu\n", m_pSuperblock->s_free_inodes_count); + uint32_t inodesPerGroup = m_pSuperblock->s_inodes_per_group; + m_nGroupDescriptors = (inodeCount / inodesPerGroup) + (inodeCount % inodesPerGroup); + + + // Add an entry to the group descriptor tree for each GD. + PERR("\nExt2 Inodes per group:: %lu Inode Count %lu :: Inode size %lu \n",inodesPerGroup,inodeCount,m_InodeSize); + + m_pGroupDescriptors = new (&m_alloc)GroupDesc*[m_nGroupDescriptors]; + for (size_t i = 0; i < m_nGroupDescriptors; i++) + { + uintptr_t idx = (i * sizeof(GroupDesc)) / m_BlockSize; + uintptr_t off = (i * sizeof(GroupDesc)) % m_BlockSize; + + //uintptr_t block = readBlock(gdBlock+idx); + //m_pGroupDescriptors[i] = reinterpret_cast(block+off); +m_pGroupDescriptors[i]=new (&m_alloc)GroupDesc; +//char temp[1024]; +File_system::readb(2,2*(gdBlock+idx),buff); +//PERR("\n%lu %d\n",gdBlock, idx); +Genode::memcpy((void*)m_pGroupDescriptors[i],(void*)(buff+off),sizeof(GroupDesc)); +//m_pGroupDescriptors[i]=reinterpret_cast(temp+off); +//PERR("\n\n::%d\n\n",i); +} +//PERR("\n\n Desc :: %u %lu %lu %lu \n\n",m_nGroupDescriptors,m_pGroupDescriptors[0]->bg_block_bitmap,m_pGroupDescriptors[0]->bg_inode_bitmap,m_pGroupDescriptors[0]->bg_inode_table); + +//PERR("\n\n Desc :: %u %d %d %d \n\n",m_nGroupDescriptors,m_pGroupDescriptors[1]->bg_block_bitmap,m_pGroupDescriptors[1]->bg_inode_bitmap,m_pGroupDescriptors[1]->bg_inode_table); + + + // Create our bitmap arrays and tables. + + m_pInodeTables = new (&m_alloc)char*[m_nGroupDescriptors]; + m_pInodeBitmaps = new (&m_alloc)char*[m_nGroupDescriptors]; + m_pBlockBitmaps = new (&m_alloc)char*[m_nGroupDescriptors]; + +for(size_t i=0;i< m_nGroupDescriptors;i++){ +m_pBlockBitmaps[i]=new (&m_alloc)char[sizeof(m_BlockSize)]; + m_pInodeBitmaps[i]=new (&m_alloc)char[sizeof(m_BlockSize)]; +} + + //uint32_t inodesPerGroup = m_pSuperblock->s_inodes_per_group; + size_t nBlocks = (inodesPerGroup * m_InodeSize) / m_BlockSize; + if ((inodesPerGroup * m_InodeSize) / m_BlockSize) + nBlocks ++; +for(size_t i=0;i(newInode), 0, m_InodeSize); + newInode->i_mode = mask | type; + //PDBG(" start 1 \n"); + // If we have a value to store, and it's small enough, use the block indices. + + Ext2Directory *pE2Parent = reinterpret_cast(parent); +//PDBG("start 2\n"); + // Create the new File object. + File *pFile = 0; + switch (type) + { + case EXT2_S_IFREG: + pFile = new (&m_alloc)Ext2File(filename, inode_num, newInode, this, parent); + break; + case EXT2_S_IFDIR: + { + + Ext2Directory *pE2Dir = new (&m_alloc)Ext2Directory(filename, inode_num, newInode, this, parent); + pFile = pE2Dir; + + Inode *parentInode = getInode(pE2Parent->getInodeNumber()); + + // Create dot and dotdot entries. +char current[2]={'.','\0'}; +char previous[3]={'.','.','\0'}; + Ext2Directory *pDot = new (&m_alloc)Ext2Directory(current, inode_num, newInode, this, pE2Dir); + Ext2Directory *pDotDot = new (&m_alloc)Ext2Directory(previous,pE2Parent->getInodeNumber(), parentInode, this, pE2Dir); + + // Add created dot/dotdot entries to the new directory. + pE2Dir->addEntry(current, pDot, EXT2_S_IFDIR); + pE2Dir->addEntry(previous, pDotDot, EXT2_S_IFDIR); + break; + } + default: + PERR("EXT2: Unrecognised file type: %x ",type); + break; + } + + // Else case from earlier. + if (Genode::strlen(value) && Genode::strlen(value) >= 4*15) + { + const char *pStr = value; + pFile->write(0ULL, Genode::strlen(value), reinterpret_cast(pStr)); + } + + // Add to the parent directory. + if (!pE2Parent->addEntry(filename, pFile, type)) + { + + PERR("EXT2: Internal error adding directory entry."); + + return false; + } + + + + // Write updated inodes. + writeInode(inode_num); +PERR("Writing Inode back :: number %lu :: Filename %s\n", inode_num, filename); + writeInode(pE2Parent->getInodeNumber()); +PERR("Parent Inode Number :: %lu \n", pE2Parent->getInodeNumber()); +pE2Parent->listEntries(); + + return true; +} + +bool Ext2Filesystem::createFile(File *parent, char* filename, uint32_t mask) +{ +return true; + // return createNode(parent, filename, mask, String(""), EXT2_S_IFREG); +} + + +bool Ext2Filesystem::createDirectory(File* parent, char* filename) +{ + +char *temp=new (&m_alloc)char[1]; +temp='\0'; + if (!createNode(parent, filename, 0755,temp , EXT2_S_IFDIR)) + return false; + return true; +} + + +bool Ext2Filesystem::remove(File* parent, File* file) +{ + + + + if (!parent->isDirectory()) + { + +PERR("I0 Error in remove :: Ext2Filesystem.cc"); + return false; + } + + Ext2Node *pNode = 0; + char* filename=new (&m_alloc)char[256]; + if (file->isDirectory()) + { + Ext2Directory *pDirectory = static_cast(file); + pNode = pDirectory; +Genode::memcpy(filename,pDirectory->getName(),sizeof(char)*256); + } + else + { + Ext2File *pFile = static_cast(file); + pNode = pFile; + Genode::memcpy(filename,pFile->getName(),sizeof(char)*256); + + } + + Ext2Directory *pE2Parent = reinterpret_cast(parent); + + return pE2Parent->removeEntry(filename, pNode); + + +} + + + +char* Ext2Filesystem::readBlock(uint32_t block) +{ + + File_system::readb(2,2*block,(char*)buff); + return buff; +} + + +void Ext2Filesystem::writeBlock(uint32_t block, char *tem) +{ + if (block != 0) + File_system::writeb(2,2*block,(char*)tem); +} + +uint32_t Ext2Filesystem::findFreeBlock(uint32_t inode) +{ + inode--; // Inode zero is undefined, so it's not used. + + uint32_t group = inode / m_pSuperblock->s_inodes_per_group; + + for (; group < m_nGroupDescriptors; group++) + { + // Any free blocks here? + GroupDesc *pDesc = m_pGroupDescriptors[group]; + if (!pDesc->bg_free_blocks_count) + { + // No blocks free in this group. + continue; + } + + ensureFreeBlockBitmapLoaded(group); + + // 8 blocks per byte - i == bitmap offset in bytes. + //Vector &list = m_pBlockBitmaps[group]; + for (size_t i = 0; + i < (m_pSuperblock->s_blocks_per_group) / 8; + i += sizeof(uint8_t)) + { + // Calculate block index into the bitmap. + //size_t idx = i / (m_BlockSize * 8); + size_t off = i % (m_BlockSize * 8); + + // Grab the specific block for the bitmap. + /// \todo Endianness - to ensure correct operation, must ptr be + /// little endian? + //size_t block = &m_pBlockBitmaps[group][off]; + uint32_t *ptr = reinterpret_cast (&m_pBlockBitmaps[group][off] ); + uint8_t tmp = *ptr; + + // Bitmap full of bits? Skip it. + if (tmp == ~0U) + continue; + + // Check each bit in this field. + for (size_t j = 0; j < 8; j++, tmp >>= 1) + { + // Free? + if ((tmp & 1) == 0) + { + // This block is free! Mark used. + *ptr |= (1 << j); + pDesc->bg_free_blocks_count--; + + //File_system::writeb(2,2,(char*)m_pSuperblock); + //since bit maps are cached not writing back these are written back only once while closing filesystem + + // File_system::writeb(2,2*(m_pGroupDescriptors[group]->bg_block_bitmap),(char*)&m_pBlockBitmaps[group]); + + // First block of this group... + uint32_t block = group * m_pSuperblock->s_blocks_per_group; + // Blocks skipped so far (i == offset in bytes)... + block += i * 8; + // Blocks skipped so far (j == bits ie blocks)... + block += j; + // Return block. + return block; + } + } + + // Shouldn't get here - if there were no available blocks here it should + // have hit the "continue" above! + + } + } + + return 0; +} + +uint32_t Ext2Filesystem::findFreeInode() +{ + for (uint32_t group = 0; group < m_nGroupDescriptors; group++) + { + // Any free inodes here? + GroupDesc *pDesc = m_pGroupDescriptors[group]; + if (!pDesc->bg_free_inodes_count) + { + // No inodes free in this group. + continue; + } + + // Make sure this block group's inode bitmap has been loaded. + ensureFreeInodeBitmapLoaded(group); + + // 8 inodes per byte - i == bitmap offset in bytes. + + for (size_t i = 0; + i < m_pSuperblock->s_inodes_per_group / 8; + i += sizeof(char)) + { + // Calculate block index into the bitmap. + // size_t idx = i / (m_BlockSize * 8); + size_t off = i % (m_BlockSize * 8); + + // Grab the specific block for the bitmap. + + + + //size_t block = &m_pInodeBitmaps[group][off]; + uint32_t *ptr = reinterpret_cast (&m_pInodeBitmaps[group][off] ); + uint8_t tmp = *ptr; +PDBG("FREE INODE BITMAP 8 BITS IN HEX %x \n",tmp); + // If all bits set, avoid searching the bitmap. + if (tmp == ~0U) + continue; + + // Check each bit for free inode. + for (size_t j = 0; j < 8; j++, tmp >>= 1) + { + // Free? + if ((tmp & 1) == 0) + { + // This inode is free! Mark used. + *ptr |= (1 << j); + pDesc->bg_free_inodes_count--; + + // Update superblock. +PERR("Free inodes count before ::%lu \n", m_pSuperblock->s_free_inodes_count); + m_pSuperblock->s_free_inodes_count--; +PERR(" Free Inode Count after using Inode :: %lu\n", m_pSuperblock->s_free_inodes_count); + +File_system::writeb(2,2,(char*)m_pSuperblock); +File_system::readb(2,2,buff); + + +PERR("Free inodes count again after writing to block :: %lu GEN CHECKING READ AND WRITE TO BLOCK DEVICES\n", ((Superblock*)(buff))->s_free_inodes_count); + + //since bit maps are cached not writing back these are written back only once while closing filesystem + +//File_system::writeb(2,2*(m_pGroupDescriptors[group]->bg_inode_bitmap),(char*)&m_pInodeBitmaps[group]); + + + + + + // First inode of this group... + uint32_t inode = group * m_pSuperblock->s_inodes_per_group; + // Inodes skipped so far (i == offset in bytes)... + inode += i * 8; + // Inodes skipped so far (j == bits ie inodes)... + // Note: inodes start counting at one, not zero. + inode += j + 1; + // Return inode. + return inode; + } + } + + + } + } + + return 0; +} + + + +void Ext2Filesystem::releaseBlock(uint32_t block) +{ + uint32_t blocksPerGroup = m_pSuperblock->s_blocks_per_group; + uint32_t group = block / blocksPerGroup; + uint32_t index = block % blocksPerGroup; + + ensureFreeBlockBitmapLoaded(group); + + // Free block. + GroupDesc *pDesc = m_pGroupDescriptors[group]; + pDesc->bg_free_blocks_count++; + m_pSuperblock->s_free_blocks_count++; + + // Index = block offset from the start of this block. + // size_t bitmapField = (index / 8) / m_BlockSize; + size_t bitmapOffset = (index / 8) % m_BlockSize; + + + size_t diskBlock = m_pBlockBitmaps[group][bitmapOffset]; + uint8_t *ptr = reinterpret_cast (diskBlock ); + *ptr &= ~(1 << (index % 8)); + + + //since bit maps are cached not writing back these are written back only once while closing filesystem + +//File_system::writeb(2,2,(char*)m_pSuperblock); +//File_system::writeb(2,2*(m_pGroupDescriptors[group]->bg_block_bitmap),(char*)&m_pBlockBitmaps[group]); + + + +} + + + +bool Ext2Filesystem::releaseInode(uint32_t inode) +{ + //Inode *pInode = getInode(inode); + --inode; // Inode zero is undefined, so it's not used. + + uint32_t inodesPerGroup = m_pSuperblock->s_inodes_per_group; + uint32_t group = inode / inodesPerGroup; + uint32_t index = inode % inodesPerGroup; + + bool bRemove = decreaseInodeRefcount(inode + 1); + + // Do we need to free this inode? + if (bRemove) + { + ensureFreeInodeBitmapLoaded(group); + // Free inode. + GroupDesc *pDesc = m_pGroupDescriptors[group]; + pDesc->bg_free_inodes_count++; + m_pSuperblock->s_free_inodes_count++; + + // Index = inode offset from the start of this block. + // size_t bitmapField = (index / 8) / m_BlockSize; + size_t bitmapOffset = (index / 8) % m_BlockSize; + + // size_t block = &m_pInodeBitmaps[group][bitmapOffset]; + uint8_t *ptr = reinterpret_cast (&m_pInodeBitmaps[group][bitmapOffset] ); + *ptr &= ~(1 << (index % 8)); + + //since bit maps are cached not writing back these are written back only once while closing filesystem + + // File_system::writeb(2,2,(char*)m_pSuperblock); +//File_system::writeb(2,2*(m_pGroupDescriptors[group]->bg_inode_bitmap),(char*)&m_pInodeBitmaps[group]); + } + + writeInode(inode); + return bRemove; +} + +Inode *Ext2Filesystem::getInode(uint32_t inode) +{ + inode--; // Inode zero is undefined, so it's not used. + uint32_t inodesPerGroup = m_pSuperblock->s_inodes_per_group; + uint32_t group = inode / inodesPerGroup; + uint32_t index = inode % inodesPerGroup; +PERR("loading Inode \n"); + ensureInodeTableLoaded(group); + //Vector &list = m_pInodeTables[group]; + + size_t blockNum = (index * m_InodeSize) / m_BlockSize; + size_t blockOff = (index * m_InodeSize) % m_BlockSize; + + //size_t block = &m_pInodeTables[group][blockNum*m_BlockSize]; + + Inode *pInode = reinterpret_cast (&m_pInodeTables[group][blockNum*m_BlockSize+blockOff]); + + return pInode; +} + +void Ext2Filesystem::writeInode(uint32_t inode) +{ + inode--; // Inode zero is undefined, so it's not used. + + uint32_t inodesPerGroup = (m_pSuperblock->s_inodes_per_group); + uint32_t group = inode / inodesPerGroup; + uint32_t index = inode % inodesPerGroup; + + //ensureInodeTableLoaded(group); + + size_t blockNum = (index * m_InodeSize) / m_BlockSize; + //since bit maps are cached not writing back these are written back only once while closing filesystem + +File_system::writeb(2,2*((m_pGroupDescriptors[group]->bg_inode_table) + blockNum), (char*)&m_pInodeTables[group][blockNum*m_BlockSize]); + + +} + + +void Ext2Filesystem::ensureFreeBlockBitmapLoaded(size_t group) +{ + + if(Bbitmap[group]=='Y') return; +Bbitmap[group]='Y'; + +File_system::readb(2,2*(m_pGroupDescriptors[group]->bg_block_bitmap),m_pBlockBitmaps[group]); +} + +void Ext2Filesystem::ensureFreeInodeBitmapLoaded(size_t group) +{ + +if(Ibitmap[group]=='Y') return; +Ibitmap[group]='Y'; + +// m_pInodeBitmaps[group]=new (&m_alloc)char[sizeof(m_BlockSize)]; + + File_system::readb(2,2*(m_pGroupDescriptors[group]->bg_inode_bitmap) ,m_pInodeBitmaps[group]); + +} + +void Ext2Filesystem::ensureInodeTableLoaded(size_t group) +{ + + + if(Itable[group]=='Y') return; +Itable[group]='Y'; + + // Determine how many blocks to load to bring in the full inode table. + uint32_t inodesPerGroup = m_pSuperblock->s_inodes_per_group; + size_t nBlocks = (inodesPerGroup * m_InodeSize) / m_BlockSize; + if ((inodesPerGroup * m_InodeSize) / m_BlockSize) + nBlocks ++; + //m_pInodeTables[group]=new (&m_alloc)char[nBlocks*m_BlockSize]; + // Load each block in the inode table. + PERR("loading Inode tables\n"); + File_system::readb(nBlocks*2,2*(m_pGroupDescriptors[group]->bg_inode_table),m_pInodeTables[group]); + +} + +void Ext2Filesystem::increaseInodeRefcount(uint32_t inode) +{ + Inode *pInode = getInode(inode); + if (!pInode) + return; + + uint32_t current_count = pInode->i_links_count; + pInode->i_links_count = current_count + 1; + + writeInode(inode); +} + +bool Ext2Filesystem::decreaseInodeRefcount(uint32_t inode) +{ + Inode *pInode = getInode(inode); + if (!pInode) + return true; // No inode found - but didn't decrement to zero. + + uint32_t current_count = pInode->i_links_count; + bool bRemove = current_count <= 1; + if (current_count) + pInode->i_links_count = current_count - 1; + + writeInode(inode); + return bRemove; +} + + + diff --git a/repos/dde_rump/src/server/rump_fs/Ext2Filesystem.h b/repos/dde_rump/src/server/rump_fs/Ext2Filesystem.h new file mode 100644 index 0000000..1cb04ac --- /dev/null +++ b/repos/dde_rump/src/server/rump_fs/Ext2Filesystem.h @@ -0,0 +1,133 @@ +#ifndef EXT2FILESYSTEM_H +#define EXT2FILESYSTEM_H +#include +#include +#include +#include +extern "C" { +#include +#include +} +#include +#include + +#include "file_system.h" +#include "Filesystem.h" + + + + +#include "ext2.h" +//#include + +/** This class provides an implementation of the second extended filesystem. */ +class Ext2Filesystem : public Filesystem +{ + + + // friend class Ext2File; + friend class Ext2Node; + friend class Ext2Directory; + + + +public: + Ext2Filesystem(Genode::Allocator &md_alloc); + + virtual ~Ext2Filesystem(); + + // + // Filesystem interface. + // + virtual bool initialise(); + //static Filesystem *probe(Disk *pDisk); + //static Filesystem *probe(Genode::Allocator &md_alloc); +Genode::Allocator &m_alloc; + +char *ext2allocateMemory(size_t size); +void ext2releaseMemory(char *temp,size_t size); + + + virtual File* getRoot(); + + //virtual String getVolumeLabel(); +/** Size of a block. */ + uint32_t m_BlockSize; +protected: + virtual bool createFile(File* parent, char* filename, uint32_t mask); + virtual bool createDirectory(File* parent, char* filename); + //virtual bool createSymlink(File* parent, char* filename, char* value); + virtual bool remove(File* parent, File* file); + +private: + virtual bool createNode(File* parent, char* filename, uint32_t mask, char* value, size_t type); + + /** Inaccessible copy constructor and operator= */ + Ext2Filesystem(const Ext2Filesystem&); + void operator =(const Ext2Filesystem&); + + /** Reads a block of data from the disk. */ + char* readBlock(uint32_t block); + /** Writes a block of data to the disk. */ + void writeBlock(uint32_t block,char* buff); + + uint32_t findFreeBlock(uint32_t inode); + uint32_t findFreeInode(); + + void releaseBlock(uint32_t block); + /** Releases the given inode, returns true if the inode had no more links. */ + bool releaseInode(uint32_t inode); + + Inode *getInode(uint32_t num); + void writeInode(uint32_t num); + + void ensureFreeBlockBitmapLoaded(size_t group); + void ensureFreeInodeBitmapLoaded(size_t group); + void ensureInodeTableLoaded(size_t group); + + bool checkOptionalFeature(size_t feature); + bool checkRequiredFeature(size_t feature); + bool checkReadOnlyFeature(size_t feature); + + void increaseInodeRefcount(uint32_t inode); + bool decreaseInodeRefcount(uint32_t inode); + + /** Our superblock. */ + Superblock *m_pSuperblock; + + /** Group descriptors, in a tree because each GroupDesc* may be in a different block. */ + GroupDesc **m_pGroupDescriptors; + + /** Inode tables, indexed by group descriptor. */ + // vector *m_pInodeTables; +char **m_pInodeTables; +char **m_pInodeBitmaps; +char **m_pBlockBitmaps; + /** Free inode bitmaps, indexed by group descriptor. */ + //vector *m_pInodeBitmaps; + /** Free block bitmaps, indexed by group descriptor. */ + //vector *m_pBlockBitmaps; + + + + /** Size of an Inode. */ + uint32_t m_InodeSize; + + /** Number of group descriptors. */ + size_t m_nGroupDescriptors; + +//In testing only two groups so size of 2 later can be expaned +char Ibitmap[2]; +char Bbitmap[2]; +char Itable[2]; + /** Write lock - we're finding some inodes and updating the superblock and block group structures. */ + // Mutex m_WriteLock; + + /** The root filesystem node. */ + File *m_pRoot; + +}; + + + +#endif diff --git a/repos/dde_rump/src/server/rump_fs/directory.h b/repos/dde_rump/src/server/rump_fs/directory.h index c03d095..44194c0 100644 --- a/repos/dde_rump/src/server/rump_fs/directory.h +++ b/repos/dde_rump/src/server/rump_fs/directory.h @@ -31,7 +31,7 @@ namespace File_system { class File_system::Directory : public Node { - private: + public: enum { BUFFER_SIZE = 4096 }; @@ -43,26 +43,12 @@ class File_system::Directory : public Node unsigned long _inode(char const *path, bool create) { - int ret; - - if (create) { - mode_t ugo = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; - ret = rump_sys_mkdir(path, ugo); - if (ret == -1) - throw No_space(); - } - - struct stat s; - - ret = rump_sys_lstat(path, &s); - if (ret == -1) - throw Lookup_failed(); - return s.st_ino; + return 5; } int _open(char const *path) { - struct stat s; + /*struct stat s; int ret = rump_sys_lstat(path, &s); if (ret == -1 || !S_ISDIR(s.st_mode)) throw Lookup_failed(); @@ -71,7 +57,8 @@ class File_system::Directory : public Node if (fd == -1) throw Lookup_failed(); - return fd; + return fd;*/ + return 23; } static char *_buffer() @@ -90,17 +77,20 @@ class File_system::Directory : public Node _path(path, "./"), _alloc(alloc) { +//PERR("dir start\n"); Node::name(basename(path)); +//PERR("dir conss\n"); } virtual ~Directory() { - rump_sys_close(_fd); + } File * file(char const *name, Mode mode, bool create) { - return new (&_alloc) File(_fd, name, mode, create); +//PERR("READ3\n"); + return new (&_alloc) File(_fd, name, mode, create); } Symlink * symlink(char const *name, bool create) @@ -110,144 +100,54 @@ class File_system::Directory : public Node Directory * subdir(char const *path, bool create) { +//PERR("i am in \n"); Path dir_path(path, _path.base()); +//PERR("subdir start\n"); Directory *dir = new (&_alloc) Directory(_alloc, dir_path.base(), create); +//PERR("done\n"); return dir; } Node * node(char const *path) { - Path node_path(path, _path.base()); + + Path node_path(path, _path.base()); - struct stat s; - int ret = rump_sys_lstat(node_path.base(), &s); - if (ret == -1) - throw Lookup_failed(); + // struct stat s; Node *node = 0; - if (S_ISDIR(s.st_mode)) + node = new (&_alloc) Directory(_alloc, node_path.base(), false); - else if (S_ISREG(s.st_mode)) - node = new (&_alloc) File(node_path.base(), STAT_ONLY); - else if (S_ISLNK(s.st_mode)) - node = new (&_alloc)Symlink(node_path.base()); - else - throw Lookup_failed(); + + return node; } size_t read(char *dst, size_t len, seek_off_t seek_offset) { - if (len < sizeof(Directory_entry)) { - PERR("read buffer too small for directory entry"); - return 0; - } - - if (seek_offset % sizeof(Directory_entry)) { - PERR("seek offset not aligned to sizeof(Directory_entry)"); - return 0; - } - - seek_off_t index = seek_offset / sizeof(Directory_entry); - - int bytes; - rump_sys_lseek(_fd, 0, SEEK_SET); - - struct dirent *dent = 0; - seek_off_t i = 0; - char *buf = _buffer(); - do { - bytes = rump_sys_getdents(_fd, buf, BUFFER_SIZE); - void *current, *end; - for (current = buf, end = &buf[bytes]; - current < end; - current = _DIRENT_NEXT((dirent *)current), i++) - if (i == index) { - dent = (dirent *)current; - break; - } - } while(bytes && !dent); - - if (!dent) - return 0; - - /* - * Build absolute path, this becomes necessary as our 'Path' class strips - * trailing dots, which will not work for '.' and '..' directories. - */ - size_t base_len = strlen(_path.base()); - char path[dent->d_namlen + base_len + 2]; - - memcpy(path, _path.base(), base_len); - path[base_len] = '/'; - strncpy(path + base_len + 1, dent->d_name, dent->d_namlen + 1); - - /* - * We cannot use 'd_type' member of 'dirent' here since the EXT2 - * implementation sets the type to unkown. Hence we use stat. - */ - struct stat s; - rump_sys_lstat(path, &s); - - Directory_entry *e = (Directory_entry *)(dst); - if (S_ISDIR(s.st_mode)) - e->type = Directory_entry::TYPE_DIRECTORY; - else if (S_ISREG(s.st_mode)) - e->type = Directory_entry::TYPE_FILE; - else if (S_ISLNK(s.st_mode)) - e->type = Directory_entry::TYPE_SYMLINK; - else - return 0; - - strncpy(e->name, dent->d_name, dent->d_namlen + 1); - return sizeof(Directory_entry); +//PERR("READ\n"); +return 0; } size_t write(char const *src, size_t len, seek_off_t seek_offset) { /* writing to directory nodes is not supported */ +//PERR("READ2\n"); return 0; - } + +} size_t num_entries() const { - int bytes = 0; - int count = 0; - - rump_sys_lseek(_fd, 0, SEEK_SET); - - char *buf = _buffer(); - do { - bytes = rump_sys_getdents(_fd, buf, BUFFER_SIZE); - void *current, *end; - for (current = buf, end = &buf[bytes]; - current < end; - current = _DIRENT_NEXT((dirent *)current), count++) { } - } while(bytes); - - return count; + return 0; } void unlink(char const *path) { - Path node_path(path, _path.base()); - - struct stat s; - int ret = rump_sys_lstat(node_path.base(), &s); - if (ret == -1) - throw Lookup_failed(); - - if (S_ISDIR(s.st_mode)) - ret = rump_sys_rmdir(node_path.base()); - else if (S_ISREG(s.st_mode) || S_ISLNK(s.st_mode)) - ret = rump_sys_unlink(node_path.base()); - else - throw Lookup_failed(); - - if (ret == -1) - PERR("Error during unlink of %s", node_path.base()); + + //PERR("Error during unlink of %s", node_path.base()); } }; diff --git a/repos/dde_rump/src/server/rump_fs/ext2.h b/repos/dde_rump/src/server/rump_fs/ext2.h new file mode 100644 index 0000000..ac18c35 --- /dev/null +++ b/repos/dde_rump/src/server/rump_fs/ext2.h @@ -0,0 +1,145 @@ +#ifndef EXT2_H +#define EXT2_H +extern "C" { +#include +#include +} + +#define EXT2_UNKNOWN 0x0 +#define EXT2_FILE 0x1 +#define EXT2_DIRECTORY 0x2 +#define EXT2_CHAR_DEV 0x3 +#define EXT2_BLOCK_DEV 0x4 +#define EXT2_FIFO 0x5 +#define EXT2_SOCKET 0x6 +#define EXT2_SYMLINK 0x7 +#define EXT2_MAX 0x8 + +#define EXT2_STATE_CLEAN 1 +#define EXT2_STATE_UNCLEAN 2 + +#define EXT2_S_IFSOCK 0xC000 +#define EXT2_S_IFLNK 0xA000 +#define EXT2_S_IFREG 0x8000 +#define EXT2_S_IFBLK 0x6000 +#define EXT2_S_IFDIR 0x4000 +#define EXT2_S_IFCHR 0x2000 +#define EXT2_S_IFIFO 0x1000 + +#define EXT2_S_IRUSR 0x0100 +#define EXT2_S_IWUSR 0x0080 +#define EXT2_S_IXUSR 0x0040 +#define EXT2_S_IRGRP 0x0020 +#define EXT2_S_IWGRP 0x0010 +#define EXT2_S_IXGRP 0x0008 +#define EXT2_S_IROTH 0x0004 +#define EXT2_S_IWOTH 0x0002 +#define EXT2_S_IXOTH 0x0001 + +#define EXT2_BAD_INO 0x01 // Bad blocks inode +#define EXT2_ROOT_INO 0x02 // root directory inode +#define EXT2_ACL_IDX_INO 0x03 // ACL index inode (deprecated?) +#define EXT2_ACL_DATA_INO 0x04 // ACL data inode (deprecated?) +#define EXT2_BOOT_LOADER_INO 0x05 // boot loader inode +#define EXT2_UNDEL_DIR_INO 0x06 + + + +/** The Ext2 superblock structure. */ +struct Superblock +{ + uint32_t s_inodes_count; + uint32_t s_blocks_count; + uint32_t s_r_blocks_count; + uint32_t s_free_blocks_count; + uint32_t s_free_inodes_count; + uint32_t s_first_data_block; + uint32_t s_log_block_size; + uint32_t s_log_frag_size; + uint32_t s_blocks_per_group; + uint32_t s_frags_per_group; + uint32_t s_inodes_per_group; + uint32_t s_mtime; + uint32_t s_wtime; + uint16_t s_mnt_count; + uint16_t s_max_mnt_count; + uint16_t s_magic; + uint16_t s_state; + uint16_t s_errors; + uint16_t s_minor_rev_level; + uint32_t s_lastcheck; + uint32_t s_checkinterval; + uint32_t s_creator_os; + uint32_t s_rev_level; + uint16_t s_def_resuid; + uint16_t s_def_resgid; +// -- EXT2_DYNAMIC_REV Specific -- + uint32_t s_first_ino; + uint16_t s_inode_size; + uint16_t s_block_group_nr; + uint32_t s_feature_compat; + uint32_t s_feature_incompat; + uint32_t s_feature_ro_compat; + char s_uuid[16]; + + char s_volume_name[16]; + char s_last_mounted[64]; + uint32_t s_algo_bitmap; +// -- Performance Hints -- + uint8_t s_prealloc_blocks; + uint8_t s_prealloc_dir_blocks; + uint16_t alignment; +// -- Journaling Support -- + char s_journal_uuid[16]; + uint32_t s_journal_inum; + uint32_t s_journal_dev; + uint32_t s_last_orphan; +} __attribute__((packed)); + +/** The ext2 block group descriptor structure */ +struct GroupDesc +{ + uint32_t bg_block_bitmap; + uint32_t bg_inode_bitmap; + uint32_t bg_inode_table; + uint16_t bg_free_blocks_count; + uint16_t bg_free_inodes_count; + uint16_t bg_used_dirs_count; + uint16_t bg_pad; + uint8_t bg_reserved[12]; +} __attribute__((packed)); + +/** An ext2 Inode. */ +struct Inode +{ + uint16_t i_mode; + uint16_t i_uid; + uint32_t i_size; + uint32_t i_atime; + uint32_t i_ctime; + uint32_t i_mtime; + uint32_t i_dtime; + uint16_t i_gid; + uint16_t i_links_count; + uint32_t i_blocks; + uint32_t i_flags; + uint32_t i_osd1; + uint32_t i_block[15]; + uint32_t i_generation; + uint32_t i_file_acl; + uint32_t i_dir_acl; // Top 32-bits of file size. + uint32_t i_faddr; + uint8_t i_osd2[12]; +} __attribute__((packed)); + +/** An ext2 directory entry. */ +struct Dir +{ + uint32_t d_inode; + uint16_t d_reclen; + uint8_t d_namelen; + uint8_t d_file_type; + char d_name[256]; +} __attribute__((packed)); + +#endif diff --git a/repos/dde_rump/src/server/rump_fs/file.h b/repos/dde_rump/src/server/rump_fs/file.h index 38a4923..a29aa6f 100644 --- a/repos/dde_rump/src/server/rump_fs/file.h +++ b/repos/dde_rump/src/server/rump_fs/file.h @@ -42,52 +42,25 @@ class File_system::File : public Node unsigned long _inode(int dir, char const *name, bool create) { - int ret; + - if (create) { - mode_t ugo = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; - ret = rump_sys_mknodat(dir, name, S_IFREG | ugo, 0); - if (ret == -1 && errno != EEXIST) - throw No_space(); - } - - struct stat s; - - ret = rump_sys_fstatat(dir, name, &s, 0); - if (ret == -1) - throw Lookup_failed(); - - return s.st_ino; + return 4; } unsigned long _inode_path(char const *path) { - int ret; - struct stat s; - - ret = rump_sys_stat(path, &s); - if (ret == -1) - throw Lookup_failed(); - - return s.st_ino; - } + return 4;} int _open(int dir, char const *name, Mode mode) { - int fd = rump_sys_openat(dir, name, _access_mode(mode)); - if (fd == -1) - throw Lookup_failed(); - - return fd; + + return 4; } int _open_path(char const *path, Mode mode) { - int fd = rump_sys_open(path, _access_mode(mode)); - if (fd == -1) - throw Lookup_failed(); - - return fd; + + return 4; } public: @@ -110,44 +83,28 @@ class File_system::File : public Node Node::name(basename(path)); } - virtual ~File() { rump_sys_close(_fd); } + virtual ~File() { } size_t read(char *dst, size_t len, seek_off_t seek_offset) { - ssize_t ret = rump_sys_pread(_fd, dst, len, seek_offset); + ssize_t ret = 0; return ret == -1 ? 0 : ret; } size_t write(char const *src, size_t len, seek_off_t seek_offset) { - /* should we append? */ - if (seek_offset == ~0ULL) { - off_t off = rump_sys_lseek(_fd, 0, SEEK_END); - if (off == -1) - return 0; - seek_offset = off; - } - - ssize_t ret = rump_sys_pwrite(_fd, src, len, seek_offset); - return ret == -1 ? 0 : ret; + return 0; } file_size_t length() const { - struct stat s; - - if(rump_sys_fstat(_fd, &s) < 0) - return 0; - - return s.st_size; + return 0; } void truncate(file_size_t size) { - rump_sys_ftruncate(_fd, size); - - mark_as_updated(); + } }; diff --git a/repos/dde_rump/src/server/rump_fs/file_system.cc b/repos/dde_rump/src/server/rump_fs/file_system.cc index 98436ed..51e1109 100644 --- a/repos/dde_rump/src/server/rump_fs/file_system.cc +++ b/repos/dde_rump/src/server/rump_fs/file_system.cc @@ -15,141 +15,163 @@ #include #include -#include + #include #include #include +#include +#include +#include -/** - * We define our own fs arg structure to fit all sizes, we assume that 'fspec' - * is the only valid argument and all other fields are unused. - */ -struct fs_args -{ - char *fspec; - char pad[150]; - - fs_args() { Genode::memset(pad, 0, sizeof(pad)); } -}; +//===========================/ +#include "ext2.h" -namespace File_system { - class Sync; -}; +char buff[1025]; -static char const *fs_types[] = { RUMP_MOUNT_CD9660, RUMP_MOUNT_EXT2FS, - RUMP_MOUNT_FFS, RUMP_MOUNT_MSDOS, - RUMP_MOUNT_NTFS, RUMP_MOUNT_UDF, 0 }; -static char _fs_type[10]; static bool _supports_symlinks; +using namespace Genode; +//================================= + +Superblock sb_ext2_main; + +Superblock sb_ext2_main2; + +static bool const verbose = false; + +static Genode::Allocator_avl _block_alloc(Genode::env()->heap()); +static size_t _blk_size = 0; +static Block::sector_t _blk_cnt = 0; +static Block::Session::Tx::Source *_source; +static Block::Connection *_block_connection; -static bool _check_type(char const *type) -{ - for (int i = 0; fs_types[i]; i++) - if (!Genode::strcmp(type, fs_types[i])) - return true; - return false; -} -static void _print_types() -{ - PERR("fs types:"); - for (int i = 0; fs_types[i]; i++) - PERR("\t%s", fs_types[i]); -} static bool check_symlinks() { - if (!Genode::strcmp(_fs_type, RUMP_MOUNT_EXT2FS)) - return true; - - if (!Genode::strcmp(_fs_type, RUMP_MOUNT_FFS)) - return true; + return false; } -static bool check_read_only() +/*static bool check_read_only() { - if (!Genode::strcmp(_fs_type, RUMP_MOUNT_CD9660)) - return true; + //if (!Genode::strcmp(_fs_type, RUMP_MOUNT_CD9660)) + //return true; return false; } +*/ -class File_system::Sync : public Genode::Thread<1024 * sizeof(Genode::addr_t)> -{ - private: - - Timer::Connection _timer; - Genode::Signal_rpc_member _sync_dispatcher; - - void _process_sync(unsigned) - { - /* sync through front-end */ - rump_sys_sync(); - /* sync Genode back-end */ - rump_io_backend_sync(); - } - - protected: - - void entry() - { - while (1) { - _timer.msleep(1000); - /* send sync request, this goes to server entry point thread */ - Genode::Signal_transmitter(_sync_dispatcher).submit(); - } - } - - public: - - Sync(Server::Entrypoint &ep) - : - Thread("rump_fs_sync"), - _sync_dispatcher(ep, *this, &Sync::_process_sync) - { - start(); - } -}; void File_system::init(Server::Entrypoint &ep) { - if (!Genode::config()->xml_node().attribute("fs").value(_fs_type, 10) || - !_check_type(_fs_type)) { - PERR("Invalid or no file system given (use \'\"/>)"); - _print_types(); - throw Genode::Exception(); - } - PINF("Using %s as file system", _fs_type); - /* start rump kernel */ - rump_init(); - /* register block device */ - rump_pub_etfs_register(GENODE_DEVICE, GENODE_BLOCK_SESSION, RUMP_ETFS_BLK); - /* mount into extra-terrestrial-file system */ - struct fs_args args; - int opts = check_read_only() ? RUMP_MNT_RDONLY : 0; + PDBG("disk_initialize(drv=%u) called.", 0); + +_block_connection = new (Genode::env()->heap()) Block::Connection(&_block_alloc); + // Block::Connection _block_connection(&_block_alloc); + + _source = _block_connection->tx(); - args.fspec = (char *)GENODE_DEVICE; - if (rump_sys_mount(_fs_type, "/", opts, &args, sizeof(args)) == -1) { - PERR("Mounting '%s' file system failed (errno %u)", _fs_type, errno); - throw Genode::Exception(); + Block::Session::Operations ops; + _block_connection->info(&_blk_cnt, &_blk_size, &ops); + + /* check for read- and write-capability */ + if (!ops.supported(Block::Packet_descriptor::READ)) { + PERR("Block device not readable!"); + //destroy(env()->heap(), _block_connection); + } + if (!ops.supported(Block::Packet_descriptor::WRITE)) { + PINF("Block device not writeable!"); } + PDBG("We have %llu blocks with a size of %zu bytes", + _blk_cnt, _blk_size); + + + + + /* check support for symlinks */ _supports_symlinks = check_symlinks(); - new (Genode::env()->heap()) Sync(ep); + //new (Genode::env()->heap()) Sync(ep); +} + +void File_system::readb(int count,int sector, char *buff){ +//PERR(" i came here e"); +int drv = 0; + +//int sector = 2; //TODO: block count implement + + PDBG("disk_read(drv=%u, buff=%p, sector=%u, count=%u) called.", + drv, buff, (unsigned int)sector, count); +for(int i=0;ialloc_packet( 2*_blk_size), + Block::Packet_descriptor::READ, sector+i, 2); +//PERR("dd\n"); + _source->submit_packet(p); +//PERR("dd1\n"); + p = _source->get_acked_packet(); +//PERR("yo\n"); + /* check for success of operation */ + if (!p.succeeded()) { + PERR("Could not read block(s)"); + _source->release_packet(p); + return ; + } + + +//PERR("takkuva \n"); + memcpy((void*)(buff+512*i), _source->packet_content(p), 1024); + + +//PDBG("%x\n",sb_ext2_main.s_mnt_count); + + //PDBG("read() successful, contents of buff = \n"); + + //for (unsigned int i = 0; i < count * _blk_size; i++) + //PDBG("%8x: %2x %c", i, buff[i], buff[i] >= 32 ? buff[i] : '-'); +//PERR("tret\n"); + _source->release_packet(p); + +//PERR("pettu\n"); } +PDBG("Block Read successful\n"); +} +void File_system::writeb(int count,int sector, char *buff){ + + +//int drv = 0; + +//int sector = 2; //TODO: block count implement + + +PERR("writing back data to block device\n"); +/* allocate packet-descriptor for writing */ + Block::Packet_descriptor p(_source->alloc_packet(count * _blk_size), + Block::Packet_descriptor::WRITE, sector, count); + memcpy(_source->packet_content(p), (void*)buff, count * _blk_size); + + _source->submit_packet(p); + p = _source->get_acked_packet(); +if (!p.succeeded()) { + PERR("Could not read block(s)"); + } + + _source->release_packet(p); + +} bool File_system::supports_symlinks() { return _supports_symlinks; } diff --git a/repos/dde_rump/src/server/rump_fs/file_system.h b/repos/dde_rump/src/server/rump_fs/file_system.h index 7484baa..1148fad 100644 --- a/repos/dde_rump/src/server/rump_fs/file_system.h +++ b/repos/dde_rump/src/server/rump_fs/file_system.h @@ -21,18 +21,19 @@ extern "C" { #include #include #include -#include -#include } #include #include - +#include "ext2.h" namespace File_system { void init(Server::Entrypoint &ep); bool supports_symlinks(); +void readb(int,int, char*); +void writeb(int,int, char*); } extern int errno; - +extern Superblock sb_ext2_main; +extern char buff[1025]; #endif /* _FILE_SYSTEM_H_ */ diff --git a/repos/dde_rump/src/server/rump_fs/main.cc b/repos/dde_rump/src/server/rump_fs/main.cc index 98370f2..678b129 100644 --- a/repos/dde_rump/src/server/rump_fs/main.cc +++ b/repos/dde_rump/src/server/rump_fs/main.cc @@ -20,6 +20,10 @@ #include #include #include "file_system.h" +#include "Ext2Filesystem.h" +#include "Ext2Directory.h" +#include "Ext2Node.h" +#include "RadixTree.h" #include "directory.h" #include "node_handle_registry.h" @@ -30,9 +34,13 @@ namespace File_system { struct Session_component; } + + +Filesystem *pFs; + class File_system::Session_component : public Session_rpc_object { - private: + public: Allocator &_md_alloc; Directory &_root; @@ -53,6 +61,7 @@ class File_system::Session_component : public Session_rpc_object */ void _process_packet_op(Packet_descriptor &packet, Node &node) { +//PERR("1\n"); void * const content = tx_sink()->packet_content(packet); size_t const length = packet.length(); seek_off_t const offset = packet.position(); @@ -78,10 +87,12 @@ class File_system::Session_component : public Session_rpc_object packet.length(res_length); packet.succeeded(res_length > 0); +//PERR("1end\n"); } void _process_packet() { +//PERR("2start\n"); Packet_descriptor packet = tx_sink()->get_packet(); /* assume failure by default */ @@ -100,7 +111,8 @@ class File_system::Session_component : public Session_rpc_object * checked for 'ready_to_ack' in '_process_packets'. */ tx_sink()->acknowledge_packet(packet); - } +//PERR("2end\n"); +} /** * Called by signal dispatcher, executed in the context of the main @@ -108,7 +120,8 @@ class File_system::Session_component : public Session_rpc_object */ void _process_packets(unsigned) { - while (tx_sink()->packet_avail()) { +//PERR("3s\n"); + while (tx_sink()->packet_avail()) { /* * Make sure that the '_process_packet' function does not @@ -127,18 +140,22 @@ class File_system::Session_component : public Session_rpc_object _process_packet(); } - } + +//PERR("3end\n"); +} /** * Check if string represents a valid path (must start with '/') */ static void _assert_valid_path(char const *path) { - if (!path || path[0] != '/') { +//PERR("4s\n"); + if (!path || path[0] != '/') { PWRN("malformed path '%s'", path); throw Lookup_failed(); } - } +//PERR("4end\n"); + } public: @@ -161,9 +178,11 @@ class File_system::Session_component : public Session_rpc_object * Register '_process_packets' dispatch function as signal * handler for packet-avail and ready-to-ack signals. */ - _tx.sigh_packet_avail(_process_packet_dispatcher); +//PERR("5s %s\n", root_dir); + _tx.sigh_packet_avail(_process_packet_dispatcher); _tx.sigh_ready_to_ack(_process_packet_dispatcher); - } +//PERR("5e\n"); + } /** * Destructor @@ -181,7 +200,9 @@ class File_system::Session_component : public Session_rpc_object File_handle file(Dir_handle dir_handle, Name const &name, Mode mode, bool create) { - if (!valid_name(name.string())) + +//PERR("6s\n"); +if (!valid_name(name.string())) throw Invalid_name(); Directory *dir = _handle_registry.lookup(dir_handle); @@ -192,7 +213,8 @@ class File_system::Session_component : public Session_rpc_object File *file = dir->file(name.string(), mode, create); return _handle_registry.alloc(file); - } +//PERR("FILE\n"); +} Symlink_handle symlink(Dir_handle dir_handle, Name const &name, bool create) { @@ -208,13 +230,24 @@ class File_system::Session_component : public Session_rpc_object throw Permission_denied(); Symlink *link = dir->symlink(name.string(), create); +//PERR("SYMLINK\n"); return _handle_registry.alloc(link); } Dir_handle dir(Path const &path, bool create) { +//PERR("ikada"); char const *path_str = path.string(); - _assert_valid_path(path_str); +char *temp=new (&_md_alloc)char[Genode::strlen(path_str)+1]; +Genode::memcpy(temp,path_str,Genode::strlen(path_str)+1); +PDBG(" Creating Directory \n"); +PERR("\n %s \n",temp); +pFs->Filesystem::createDirectory(temp); +//PERR("\n Removing Directory :: \n"); +//PDBG("\n %s \n",path_str); +//pFs->Filesystem::remove(temp); + +_assert_valid_path(path_str); /* skip leading '/' */ path_str++; @@ -224,15 +257,16 @@ class File_system::Session_component : public Session_rpc_object if (!path.is_valid_string()) throw Name_too_long(); - +//PERR("%s - 1\n", path); Directory *dir = _root.subdir(path_str, create); +//PERR("DIR\n"); return _handle_registry.alloc(dir); } Node_handle node(Path const &path) { char const *path_str = path.string(); - +//PERR("NODE\n"); _assert_valid_path(path_str); Node *node = _root.node(path_str + 1); Node_handle h = _handle_registry.alloc(node); @@ -251,6 +285,7 @@ class File_system::Session_component : public Session_rpc_object /* destruct node */ if (node) destroy(&_md_alloc, node); +//PERR("CLOSE"); } Status status(Node_handle node_handle) @@ -283,12 +318,14 @@ class File_system::Session_component : public Session_rpc_object return s; } +//PERR("STATUS\n"); return Status(); + } void control(Node_handle, Control) { - PERR("%s not implemented", __func__); + //PERR("%s not implemented", __func__); } void unlink(Dir_handle dir_handle, Name const &name) @@ -301,6 +338,7 @@ class File_system::Session_component : public Session_rpc_object Directory *dir = _handle_registry.lookup(dir_handle); dir->unlink(name.string()); +//PERR("unlink \n"); } void truncate(File_handle file_handle, file_size_t size) @@ -310,6 +348,7 @@ class File_system::Session_component : public Session_rpc_object File *file = _handle_registry.lookup(file_handle); file->truncate(size); +//PERR("truncate funcs\n"); } void move(Dir_handle, Name const &, Dir_handle, Name const &) @@ -322,7 +361,7 @@ class File_system::Session_component : public Session_rpc_object _handle_registry.sigh(node_handle, sigh); } - void sync() { rump_sys_sync(); } + void sync() { } }; class File_system::Root : public Root_component @@ -397,6 +436,8 @@ class File_system::Root : public Root_component * and communication buffer. */ size_t session_size = sizeof(Session_component) + tx_buf_size; +PERR("insufficient 'ram_quota', got %zd, need %zd", + ram_quota, session_size); if (max((size_t)4096, session_size) > ram_quota) { PERR("insufficient 'ram_quota', got %zd, need %zd", ram_quota, session_size); @@ -445,9 +486,16 @@ struct File_system::Main ep(ep), resource_dispatcher(ep, *this, &Main::resource_handler) { - File_system::init(ep); + env()->parent()->announce(ep.manage(fs_root)); env()->parent()->resource_avail_sigh(resource_dispatcher); + File_system::init(ep); +pFs=new (&sliced_heap)Ext2Filesystem((sliced_heap)); + pFs->initialise(); + RadixTree::m_alloc = &sliced_heap; + Ext2Directory::m_alloc=&sliced_heap; +Ext2Node::m_alloc=&sliced_heap; +Filesystem::m_alloc=&sliced_heap; } }; @@ -455,8 +503,11 @@ struct File_system::Main /********************** ** Server framework ** **********************/ - +Genode::Allocator *RadixTree::m_alloc; +Genode::Allocator *Ext2Node::m_alloc; +Genode::Allocator *Ext2Directory::m_alloc; +Genode::Allocator *Filesystem::m_alloc; char const * Server::name() { return "rump_fs_ep"; } Genode::size_t Server::stack_size() { return 4 * 1024 * sizeof(long); } -void Server::construct(Server::Entrypoint &ep) { static File_system::Main inst(ep); } +void Server::construct(Server::Entrypoint &ep) {PERR("creating server\n"); static File_system::Main inst(ep); PERR("created server\n");} diff --git a/repos/dde_rump/src/server/rump_fs/symlink.h b/repos/dde_rump/src/server/rump_fs/symlink.h index b4dcf55..7696407 100644 --- a/repos/dde_rump/src/server/rump_fs/symlink.h +++ b/repos/dde_rump/src/server/rump_fs/symlink.h @@ -48,17 +48,12 @@ class File_system::Symlink : public Node size_t write(char const *src, size_t len, seek_off_t seek_offset) { - if (!_create) - return 0; - - int ret = rump_sys_symlink(src, _path.base()); - return ret == -1 ? 0 : ret; + return 0; } size_t read(char *dst, size_t len, seek_off_t seek_offset) { - int ret = rump_sys_readlink(_path.base(), dst, len); - return ret == -1 ? 0 : ret; + return 0; } file_size_t length() diff --git a/repos/dde_rump/src/server/rump_fs/target.mk b/repos/dde_rump/src/server/rump_fs/target.mk index 56fd8f4..13d8072 100644 --- a/repos/dde_rump/src/server/rump_fs/target.mk +++ b/repos/dde_rump/src/server/rump_fs/target.mk @@ -1,5 +1,5 @@ TARGET = rump_fs -SRC_CC = main.cc file_system.cc random.cc +SRC_CC = main.cc file_system.cc random.cc Ext2Filesystem.cc RadixTree.cc Ext2Directory.cc Ext2File.cc Ext2Node.cc Directory.cc File.cc Filesystem.cc LIBS = rump rump_fs server startup diff --git a/repos/libports/src/test/libc_ffat/main.cc b/repos/libports/src/test/libc_ffat/main.cc index 36ddb8f..8576e49 100644 --- a/repos/libports/src/test/libc_ffat/main.cc +++ b/repos/libports/src/test/libc_ffat/main.cc @@ -27,12 +27,12 @@ #define CALL_AND_CHECK(ret, operation, condition, info_string, ...) \ - printf("calling " #operation " " info_string "\n", ##__VA_ARGS__); \ + PERR("calling " #operation " " info_string "\n", ##__VA_ARGS__); \ ret = operation; \ if (condition) { \ - printf(#operation " succeeded\n"); \ + PERR(#operation " succeeded\n"); \ } else { \ - printf(#operation " failed, " #ret "=%ld, errno=%d\n", (long)ret, errno); \ + PERR(#operation " failed, " #ret "=%ld, errno=%d\n", (long)ret, errno); \ return -1; \ } @@ -41,7 +41,7 @@ int main(int argc, char *argv[]) { int ret, fd; ssize_t count; - +PERR("hai\n"); char const *dir_name = "testdir"; char const *dir_name2 = "testdir2"; char const *file_name = "test.tst"; @@ -58,6 +58,7 @@ int main(int argc, char *argv[]) Genode::config()->xml_node().sub_node("iterations").attribute("value").value(&iterations); } catch(...) { } +PERR("Entering VFS\n"); for (unsigned int i = 0; i < iterations; i++) { /* create directory (short name) */