Core: vfs-dir stuff re-implemented
authorLiu Aleaxander <Aleaxander@gmail.com>
Fri, 28 Aug 2009 10:27:51 +0000 (18:27 +0800)
committerLiu Aleaxander <Aleaxander@gmail.com>
Fri, 28 Aug 2009 10:27:51 +0000 (18:27 +0800)
We fist make it simple, as told by hpa. Here're the changes:
1, The DIR structure changed, just a file pointer included.
2. So, the open/close/read-dir stuff in com32/lib/ changed again.
3. We read one stuff from every readdir call.

Signed-off-by: Liu Aleaxander <Aleaxander@gmail.com>
13 files changed:
com32/include/dirent.h
com32/lib/closedir.c
com32/lib/opendir.c
com32/lib/readdir.c
com32/modules/dir.c
com32/rosh/rosh.c
core/comboot.inc
core/dir.c
core/extern.inc
core/fs.c
core/fs/fat/fat.c
core/include/dir.h
core/include/fs.h

index 0fc2e13..d2bfd62 100644 (file)
@@ -22,11 +22,10 @@ struct dirent {
     char d_name[NAME_MAX + 1];
 };
 
+struct file;
+
 typedef struct {
-    uint16_t dd_stat;
-    uint16_t dd_sect;
-    uint64_t dd_offset;
-    char dd_name[NAME_MAX + 1];
+       struct file *dd_dir;
 } DIR;
 
 __extern DIR *opendir(const char *);
index dcf1704..9e43dd4 100644 (file)
@@ -16,15 +16,13 @@ int closedir(DIR * dir)
     int rv = -1;
        
     if (dir) {
-       /*
-         com32sys_t regs;
-         memset(&regs, 0, sizeof regs);
-         regs.eax.w[0] = 0x0022;
-         regs.esi.l = OFFS_WRT(dir, 0);
-         __com32.cs_intcall(0x22, &regs, &regs);
-       */
-       free(dir);
-       rv = 0;
+               com32sys_t regs;
+               memset(&regs, 0, sizeof regs);
+               regs.eax.w[0] = 0x0022;
+               regs.esi.l = (uint32_t)dir;
+               __com32.cs_intcall(0x22, &regs, &regs);
+               free(dir);
+               rv = 0;
        }
        
        return rv;
index 669a04a..70f74c1 100644 (file)
@@ -27,12 +27,9 @@ DIR *opendir(const char *pathname)
     if (!(regs.eflags.l & EFLAGS_CF)) {
         /* Initialization: malloc() then zero */
         newdir = calloc(1, sizeof(DIR));
-        strcpy(newdir->dd_name, pathname);
-        newdir->dd_sect = regs.eax.l;
-        newdir->dd_offset = 0;
-        newdir->dd_stat = 0;
+               newdir->dd_dir = (struct file *)regs.eax.l;
     }
-
+       
     /* We're done */
     return newdir;
 }
index 7fca476..6c95bd6 100644 (file)
 
 struct dirent *readdir(DIR * dir)
 {
-    struct dirent *newde = NULL;;
+    struct dirent *newde;
     com32sys_t regs;
            
-    if ((dir !=NULL) && (dir->dd_sect != 0) && (dir->dd_stat != 0xffff)) {
        memset(&regs, 0, sizeof(regs));         
        regs.eax.w[0] = 0x0021;
        regs.esi.l = (uint32_t)dir;
        __com32.cs_intcall(0x22, &regs, &regs);
        newde = (struct dirent *)(regs.eax.l);
-    }
        
     return newde;
 }
index a3c9815..badc37d 100644 (file)
@@ -20,6 +20,7 @@ int main(int argc, char *argv[])
        }
        
        dir = opendir(argv[1]);
+       printf("back from in main ...? \n");
        if (dir == NULL) {
                printf("Unable to read dir: %s\n", argv[1]);
                return 0;
index c634a94..862497b 100644 (file)
@@ -428,8 +428,7 @@ void rosh_dir_arg(const char *ifilstr, const char *pwdstr)
            filepos = 0;
             d = opendir(filestr);
            if (d != NULL) {
-               printf("DIR:'%s'    %08x %8d\n", d->dd_name, (int)d->dd_sect, 
-                      d->dd_offset);
+                       //printf("DIR:'%s'    %08x %8d\n", d->dd_name, (int)d->dd_sect, d->dd_offset);
                de = readdir(d);
                while (de != NULL) {
                    filepos++;
index b078aa5..7f9b3a9 100644 (file)
@@ -900,6 +900,7 @@ comapi_getcwd:
 ; INT 22h AX=0020h     Open directory
 ;
 %if IS_SYSLINUX
+               global comapi_opendir
 comapi_opendir:
                mov es,P_ES
                mov si,P_SI
@@ -909,8 +910,6 @@ comapi_opendir:
                cmp eax,0
                jz comapi_err   ; Found nothing
                 mov P_EAX,eax
-               mov P_CX,SECTOR_SIZE
-               mov P_SI,si
                clc
                ret
 %else
@@ -933,7 +932,10 @@ comapi_readdir     equ comapi_err
 ;
 ; INT 22h AX=0022h     Close directory
 ;
-comapi_closedir        equ comapi_close
+comapi_closedir:
+               mov esi,P_ESI    ; The address of DIR structure
+               pm_call closedir
+               ret
 
 ;
 ; INT 22h AX=0023h     Query shuffler size
index 0701125..1bc8a26 100644 (file)
@@ -4,42 +4,15 @@
 #include <fs.h>
 #include <core.h>
 
-/* The dir log structure, to log the status of the dir_buf. */
-struct dir_log {
-    int offset;   /* how far from the dir_buf */
-    int index;    /* which dir entry have we go */
-};
-static struct dir_log log = {0, 0};
-
-/* The dir buffer used by fill_dir to store the newly read dirs*/
-#define DB_SIZE 2048
-char dir_buf[DB_SIZE];
+extern struct fs_info *this_fs;
 
+/* 
+ * open dir, return the file structure pointer in _eax_, or NULL if failed 
+ */
 void opendir(com32sys_t *regs)
 {      
-    int ds = regs->ds; /* save ds */
-       
-    regs->ds = regs->es;
-    regs->es = ds;
-    mangle_name(regs);
-    regs->ds = ds;  /* restore ds */
-    searchdir(regs);   
-}
-
-/*
- * Fill the dir buffer; return 1 for not full, 0 for full
- */
-int fill_dir(struct dirent *de)
-{
-    int de_len = de->d_reclen;
-    if (log.offset + de_len <= DB_SIZE) {
-       memcpy(dir_buf + log.offset, de, de_len);
-       log.offset += de_len;
-       log.index ++;
-       return 1;
-    }
-
-       return 0;
+       this_fs->fs_ops->opendir(regs);
+       regs->eax.l = (uint32_t)handle_to_file(regs->esi.w[0]); 
 }
 
 /*
@@ -50,35 +23,22 @@ int fill_dir(struct dirent *de)
  */
 void readdir(com32sys_t *regs)
 {
-    extern struct fs_info *this_fs;
-    DIR *dir = (DIR *)regs->esi.l;     
+       DIR *dir = (DIR *)regs->esi.l;  
     struct dirent *de = NULL;
-    static int offset;
-       
-       /* If we haven't fill the dir buffer, fill it */
-    if (log.index == 0) {
-       this_fs->fs_ops->readdir(this_fs, dir);
-       if (log.offset == 0) {
-               regs->eax.l = 0;
-               return;
-       }
-       offset = 0; /* reset the _offset_ */
-    }
-       
-    if (offset < log.offset) {
-       de = (struct dirent *)(dir_buf + offset);
-       offset += de->d_reclen;
-    } 
-    if (offset >= log.offset) /* reach the end of buffer, reset it */
-       memset(&log, 0, sizeof log);
        
+       if (dir->dd_dir)
+               de = this_fs->fs_ops->readdir(dir->dd_dir);
+       else
+               de = NULL;
+
     /* Return the newly read de in _eax_ register */
     regs->eax.l = (uint32_t)de;
 }
 
 void closedir(com32sys_t *regs)
 {
-    regs->esi.w[0] = 0;
+    DIR *dir = (DIR *)regs->esi.l;
+       _close_file(dir->dd_dir);
 }
 
 
index 37024ec..20adb76 100644 (file)
@@ -17,6 +17,6 @@
         extern unmangle_name, close_file
 
         ; dir.c
-        extern opendir, readdir, readdir
+        extern opendir, readdir, closedir
 
 %endif ; EXTERN_INC
index 1730378..b6e112a 100644 (file)
--- a/core/fs.c
+++ b/core/fs.c
@@ -9,7 +9,18 @@ struct fs_info *this_fs = NULL;
 struct fs_info fs;
 
 /* Actual file structures (we don't have malloc yet...) */
-static struct file Files[MAX_OPEN];
+struct file files[MAX_OPEN];
+/*
+ * Convert between a 16-bit file handle and a file structure
+ */
+inline uint16_t file_to_handle(struct file *file)
+{
+    return file ? (file - files)+1 : 0;
+}
+inline struct file *handle_to_file(uint16_t handle)
+{
+    return handle ? &files[handle-1] : NULL;
+}
 
 /*
  * Get an empty file structure
@@ -17,7 +28,7 @@ static struct file Files[MAX_OPEN];
 static struct file *alloc_file(void)
 {
     int i;
-    struct file *file = Files;
+    struct file *file = files;
 
     for (i = 0; i < MAX_OPEN; i++) {
        if (!file->open_file)
@@ -36,25 +47,13 @@ static inline void free_file(struct file *file)
     memset(file, 0, sizeof *file);
 }
 
-static void _close_file(struct file *file)
+void _close_file(struct file *file)
 {
     if (file->open_file)
        file->fs->fs_ops->close_file(file);
     free_file(file);
 }
 
-/*
- * Convert between a 16-bit file handle and a file structure
- */
-static inline uint16_t file_to_handle(struct file *file)
-{
-    return file ? (file - Files)+1 : 0;
-}
-static inline struct file *handle_to_file(uint16_t handle)
-{
-    return handle ? &Files[handle-1] : NULL;
-}
-
 void load_config(com32sys_t *regs)
 {
     this_fs->fs_ops->load_config(regs);
index f219995..a254042 100644 (file)
@@ -659,12 +659,7 @@ static void vfat_searchdir(char *filename, struct file *file)
     if (attr & 0x10) {
        found_dir:
         open_file = alloc_fill_dir(dir_sector);
-        /* 
-         * for dir, we use the file->file_len to store the sector number 
-         * where the dir is. 
-         */
-        file_len  = dir_sector;         
-    } else if ((attr & 0x18) || (file_len == 0)) {
+       } else if ((attr & 0x18) || (file_len == 0)) {
     fail:
         file_len = 0;
         open_file = NULL;
@@ -677,14 +672,22 @@ static void vfat_searchdir(char *filename, struct file *file)
     file->open_file = open_file;
 }
 
-
-
+/*
+ * The open dir function, just call the searchdir function  directly. 
+ * I don't think we need call the mangle_name function first 
+ */
+void vfat_opendir(com32sys_t *regs)
+{
+       char *src = MK_PTR(regs->es, regs->esi.w[0]);
+       char *dst = MK_PTR(regs->ds, regs->edi.w[0]);
+       strcpy(dst, src);
+       searchdir(regs);        
+}
 
 /*
- * read one file from a directory
- * return 1 if error, or 0 if success
+ * read one file from a directory; return the newly read de structure
  */
-void vfat_readdir(struct fs_info *fs, DIR *dir) 
+struct dirent* vfat_readdir(struct file *dir)
 {
     uint32_t sector, sec_off;      
     /* make it to be 1 to check if we have met a long name entry before */
@@ -693,32 +696,33 @@ void vfat_readdir(struct fs_info *fs, DIR *dir)
     uint8_t  checksum = 0;
     uint8_t  entries_left;  
     int i;
-       int not_full = 1;
-    struct dirent de;
+       static struct dirent de;
     char *de_name = de.d_name;        
     struct cache_struct  *cs;
     struct fat_dir_entry *fat_dir;
-    struct fat_long_name_entry *long_dir;    
-
-    sector  = dir->dd_sect;
-    sec_off = dir->dd_offset;
+    struct fat_long_name_entry *long_dir;
+       struct open_file_t *file = dir->open_file;
+       struct fs_info *fs = dir->fs;
+       
+    sector  = file->file_sector;
+    sec_off = file->file_bytesleft;
     if (!sector)
-        return 1;    
+        return NULL;
     entries_left = (SECTOR_SIZE - sec_off) >> 5;
     cs = get_cache_block(this_fs->fs_dev, sector);
     fat_dir = (struct fat_dir_entry *)(cs->data + sec_off);/* resume last position in sector */
     
-    while (not_full) {
+    while (1) {
                if (!entries_left) {
             sector = nextsector(fs, sector);
             if (!sector)
-                goto end;
+                return NULL;
             cs = get_cache_block(fs->fs_dev, sector);
             fat_dir = (struct fat_dir_entry *)cs->data;
         }
                
         if (fat_dir->name[0] == 0)
-                       goto end;
+                       return NULL;
         if  (fat_dir->attr == FAT_ATTR_LONG_NAME) {
             /* it's a long name */
             long_dir = (struct fat_long_name_entry *)fat_dir;
@@ -747,13 +751,10 @@ void vfat_readdir(struct fs_info *fs, DIR *dir)
             
             if (!id) {
                                /* Got a long name match */
-                               //if (get_checksum(fat_dir->name) != checksum)
-                               //goto next_entry;
+                               if (get_checksum(fat_dir->name) != checksum)
+                                       goto next_entry;
                                
-                               /* reset _id_ and _checksum_ */
-                               id = 1;
-                               checksum = 0;
-                               goto fill;
+                               break;
                        }
             
             if (fat_dir->attr & FAT_ATTR_VOLUME_ID ||
@@ -777,33 +778,29 @@ void vfat_readdir(struct fs_info *fs, DIR *dir)
             else
                 *de_name = '\0';      
            
-               fill:
-                       de.d_type = fat_dir->attr;
-                       de.d_reclen = DIR_REC_LEN(de.d_name);
-                       not_full = fill_dir(&de);
-                       de_name = de.d_name;    /* reset the de_name pointer */
+                       break;
         }
         
     next_entry:
                entries_left --;
         fat_dir ++;
     }
-    
-    /* dir buffer filled, now it's time to update the DIR structure */
+       /* found what we want, fill the de structure */
+       de.d_reclen = DIR_REC_LEN(de.d_name);
+       de.d_type = fat_dir->attr;
+
+       /* update the DIR structure */
+    entries_left--;
        if (!entries_left) {
-        sector = nextsector(fs, sector);
-        if (!sector)
-            return 1;
-        dir->dd_offset = 0;
+               sector = nextsector(fs, sector);
+               file->file_bytesleft = 0;
     } else {
-        dir->dd_offset = SECTOR_SIZE - (entries_left << 5);
+        file->file_bytesleft = SECTOR_SIZE - (entries_left << 5);
        }
-    dir->dd_sect = sector;     
-       return;
-
- end:
-       /* Reach the end of this directory */
-       dir->dd_stat = -1;
+    file->file_sector = sector;        
+       
+       return &de;
 }
 
 static void vfat_load_config(com32sys_t *regs)
@@ -898,5 +895,6 @@ const struct fs_ops vfat_fs_ops = {
     .mangle_name   = vfat_mangle_name,
     .unmangle_name = generic_unmangle_name,
     .load_config   = vfat_load_config,
+       .opendir       = vfat_opendir,
        .readdir       = vfat_readdir
 };
index 454ca48..04f0d09 100644 (file)
@@ -6,6 +6,7 @@
 #include <string.h>
 #include <com32.h>
 #include "disk.h"
+#include "fs.h"
 
 struct dirent {
        uint32_t d_ino;
@@ -15,18 +16,13 @@ struct dirent {
        char d_name[256];
 };
 
+struct file;
+
 typedef struct {
-       uint16_t dd_stat;
-       uint16_t dd_sect;
-       sector_t dd_offset;
-       char dd_name[256];
+       struct file *dd_dir;
 } DIR;
 
 #define DIR_REC_LEN(name) (12 + strlen(name) + 1 + 3) & ~3
 
-/*
- * funtions 
- */
-int fill_dir(struct dirent *);
 
 #endif /* dir.h */
index d16a568..a8b0294 100644 (file)
@@ -52,7 +52,8 @@ struct fs_ops {
     void     (*load_config)(com32sys_t *);
 
        /* the _dir_ stuff */
-       void     (*readdir)(struct fs_info *, DIR *);
+       void     (*opendir)(com32sys_t *);
+       struct dirent * (*readdir)(struct file *);
 };
 
 enum dev_type {CHS, EDD};
@@ -92,7 +93,8 @@ static inline bool not_whitespace(char c)
  */
 void mangle_name(com32sys_t *);
 void searchdir(com32sys_t *);
-
-
+void _close_file(struct file *);
+inline uint16_t file_to_handle(struct file *);
+inline struct file *handle_to_file(uint16_t);
 
 #endif /* FS_H */