]> Zhao Yanbai Git Server - kernel.git/commitdiff
add ext2 read inode and search file in directory
authorAceVest <zhaoyanbai@126.com>
Thu, 10 Jul 2014 15:02:51 +0000 (23:02 +0800)
committerAceVest <zhaoyanbai@126.com>
Thu, 10 Jul 2014 15:02:51 +0000 (23:02 +0800)
fs/ext2.c
include/ext2.h
lib/libc.S

index 45cf95ad75c75507250fc4b37e8b9d67ab38c69c..ffd6ef4c2b94f01c5b19c4cbeae44c244ca189d2 100644 (file)
--- a/fs/ext2.c
+++ b/fs/ext2.c
@@ -8,15 +8,95 @@
  */
 #include "system.h"
 #include "fs.h"
+#include "mm.h"
 #include "ext2.h"
 
 struct {
     ext2_sb_t ext2_sb;
+    ext2_gd_t *ext2_gd;
 } ext2_fs;
 
 extern void blk_rw(dev_t dev, u64_t offset, u32_t scnt, char *buf);
 
-#define BLKRW(offset, blkcnt, buf) do { blk_rw(system.root_dev, offset, (blkcnt)*EXT2_BLOCK_SIZE, buf); } while(0)
+#define BLKRW(blkid, blkcnt, buf) do { blk_rw(system.root_dev, (blkid)*EXT2_BLOCK_SIZE, (blkcnt)*EXT2_BLOCK_SIZE, buf); } while(0)
+
+kmem_cache_t *ext2_block_cache;
+kmem_cache_t *ext2_inode_cache;
+
+ext2_inode_t ext2_root_inode;
+
+void *ext2_alloc_block()
+{
+    return (void *) kmem_cache_alloc(ext2_block_cache, 0);
+}
+
+void *ext2_free_block(void *blk)
+{
+    kmem_cache_free(ext2_block_cache, blk);
+}
+
+void *ext2_alloc_inode()
+{
+    return (void *) kmem_cache_alloc(ext2_inode_cache, 0);
+}
+
+#define ext2_gd(n) ((ext2_gd_t*)(EXT2_GD) + (n))
+void ext2_read_inode(unsigned int ino, ext2_inode_t *inode)
+{
+    void *blk = ext2_alloc_block();
+    assert(blk != 0);
+
+    unsigned int in;    // inode number
+    unsigned int gn;    // group number
+    unsigned int gi;    // inode index in group
+
+    gn = (ino-1) / EXT2_INODES_PER_GROUP;
+    gi = (ino-1) % EXT2_INODES_PER_GROUP;
+
+    unsigned int blkid = gi / EXT2_INODES_PER_BLOCK; // inode blkid
+    unsigned int inoff = gi % EXT2_INODES_PER_BLOCK; // inode offset
+
+    blkid += ext2_gd(gn)->bg_inode_table;
+    inoff *= EXT2_INODE_SIZE;
+
+    printk("group %u %u blkid %u blkoff %u\n", gn, gi, blkid, inoff);
+
+    BLKRW(blkid, 1, blk);
+
+    memcpy(inode, blk+inoff, EXT2_INODE_SIZE);
+
+    ext2_free_block(blk);
+}
+
+unsigned int ext2_search_indir(const char *name, const ext2_inode_t *inode)
+{
+    unsigned int ino = 0;
+
+    void *blk = ext2_alloc_block();
+    assert(blk != 0);
+
+    BLKRW(inode->i_block[0], 1, blk); // only support the first direct blocks
+
+    ext2_dirent_t *dirent = (ext2_dirent_t *) blk;
+    while(dirent->name_len != 0)
+    {
+        dirent->name[dirent->name_len] = 0;
+        printk("  dirent %s inode %u rec_len %u name_len %u type %02d\n",
+            dirent->name, dirent->inode, dirent->rec_len, dirent->name_len, dirent->file_type);
+
+        if(strcmp(name, dirent->name) == 0)
+        {
+            ino = dirent->inode;
+            break;
+        }
+
+        dirent = (ext2_dirent_t *) (((unsigned int)dirent) + dirent->rec_len);
+    }
+    
+    ext2_free_block(blk);
+
+    return ino;
+}
 
 void ext2_setup_fs()
 {
@@ -26,7 +106,7 @@ void ext2_setup_fs()
     if(buf == 0)
         panic("out of memory");
 
-    BLKRW(EXT2_SB_OFFSET, 1, buf);
+    BLKRW(1, 1, buf);   // now blocksize == 1024, so blkid == 1
 
     memcpy(EXT2_SB, buf, sizeof(*(EXT2_SB)));
 
@@ -42,6 +122,42 @@ void ext2_setup_fs()
     printk(" block size %u log block size %u first data block %u\n",
         EXT2_BLOCK_SIZE, EXT2_SB->s_log_block_size, EXT2_SB->s_first_data_block);
     printk(" blocks per group %u inodes per group %u\n", EXT2_SB->s_blocks_per_group, EXT2_SB->s_inodes_per_group);
+
+
+    ext2_block_cache = kmem_cache_create("ext2_block_cache", EXT2_BLOCK_SIZE, EXT2_BLOCK_SIZE);
+    if(0 == ext2_block_cache)
+        panic("setup ext2 block cache failed. out of memory");
+
+    ext2_inode_cache = kmem_cache_create("ext2_inode_cache", EXT2_INODE_SIZE, EXT2_INODE_SIZE);
+    if(0 == ext2_inode_cache)
+        panic("setup ext2 inode cache failed. out of memory");
+
+    ext2_fs.ext2_gd = ext2_alloc_block();
+    assert(ext2_fs.ext2_gd != 0);
+
+    BLKRW(EXT2_SB->s_first_data_block+1, 1, (char *)ext2_fs.ext2_gd);
+
+    unsigned int gps = EXT2_SB->s_blocks_count / EXT2_SB->s_blocks_per_group;
+    gps += (EXT2_SB->s_blocks_count % EXT2_SB->s_blocks_per_group) ? 1 : 0;
+    unsigned int i;
+    for(i=0; i<gps; ++i)
+    {
+        printk("  [%2u] inode table %u free blocks %u free inode %u used dir %u\n",
+            i, ext2_gd(i)->bg_inode_table, ext2_gd(i)->bg_free_blocks_count, ext2_gd(i)->bg_free_inodes_count, ext2_gd(i)->bg_used_dirs_count);
+    }
+
+
+    ext2_read_inode(2, &ext2_root_inode);
+    printk("root inode size %u \n", ext2_root_inode.i_size);
+    printk("root blocks %u \n", ext2_root_inode.i_blocks);
+
+    static ext2_inode_t boot_inode;
+    static ext2_inode_t krnl_inode;
+
+    ext2_read_inode(ext2_search_indir("boot", &ext2_root_inode), &boot_inode);
+    ext2_read_inode(ext2_search_indir("Kernel", &boot_inode), &krnl_inode);
+    printk("krnl inode size %u \n", krnl_inode.i_size);
+    printk("krnl blocks %u \n", krnl_inode.i_blocks);
 }
 
 
index 4a4d52530dcfcdb21a06420905a6aa84f005f6d9..7583166489b0335aed7012393260d6b50b3adc8a 100644 (file)
@@ -33,6 +33,7 @@
 #define EXT2_MIN_BLOCK_LOG_SIZE 10
 
 #define EXT2_SB                 (&ext2_fs.ext2_sb)
+#define EXT2_GD                 (ext2_fs.ext2_gd)
 #define EXT2_BLOCK_SIZE        (EXT2_MIN_BLOCK_SIZE << (EXT2_SB)->s_log_block_size)
 
 #define EXT2_SECT_PER_BLOCK    (EXT2_BLOCK_SIZE/512)
@@ -141,14 +142,13 @@ typedef struct ext2_group_descriptor
     u16    bg_used_dirs_count;
     u16    bg_pad;
     u32    bg_reserved[3];
-} GroupDesc,*pGroupDesc;
+} ext2_gd_t;
 
 #define EXT2_NDIR_BLOCKS    (12)
-#define EXT2_IND_BLOCK        (EXT2_NDIR_BLOCKS)
-#define EXT2_DIND_BLOCK        (EXT2_IND_BLOCK + 1)
-#define EXT2_TIND_BLOCK        (EXT2_DIND_BLOCK + 1)
-#define EXT2_N_BLOCKS        (EXT2_TIND_BLOCK + 1)
-
+#define EXT2_IND_BLOCK      (EXT2_NDIR_BLOCKS)
+#define EXT2_DIND_BLOCK     (EXT2_IND_BLOCK  + 1)
+#define EXT2_TIND_BLOCK     (EXT2_DIND_BLOCK + 1)
+#define EXT2_N_BLOCKS       (EXT2_TIND_BLOCK + 1)
 
 typedef struct ext2_inode
 {
@@ -169,7 +169,7 @@ typedef struct ext2_inode
     u32    i_file_acl;
     u32    i_dir_acl;
     u32    i_faddr;
-    u8    i_osd2[12];
+    u8     i_osd2[12];
 } ext2_inode_t; 
 
 
index 2bd52c163c6e2c1540f6d977fa3bc5de0c8c0227..90807bafa4cf00da2598149af8b5223441d1ceb1 100644 (file)
@@ -16,7 +16,7 @@ _start:
     call main
 
 
-    add $12, %esp
+    addl    $12, %esp
 
     nop
     nop