core: VFS cleanups: add a persistent generic struct file
authorH. Peter Anvin <hpa@zytor.com>
Wed, 12 Aug 2009 00:25:43 +0000 (17:25 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Wed, 12 Aug 2009 00:25:43 +0000 (17:25 -0700)
Major cleanups to the VFS layer:
- add a persistent generic "struct file"
- pass "struct file *" to getfssec
- add a close_file method
- use VFS-assigned indicies instead of pointers as file handles.
  This allows the file structures to be allocated from high memory.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
12 files changed:
core/comboot.inc
core/diskfs.inc
core/ext2.c
core/extern.inc
core/fat.c
core/fs.c
core/getc.inc
core/include/fs.h
core/iso9660.c
core/isolinux.asm
core/pxe.c
core/pxelinux.asm

index 007c383..fb0f57f 100644 (file)
@@ -63,7 +63,7 @@
 
 ; Looks like a COMBOOT image but too large
 comboot_too_large:
-               call close_file
+               pm_call close_file
                mov si,err_comlarge
                call writestr
                jmp enter_command
@@ -547,7 +547,7 @@ comapi_read:
 ;
 comapi_close:
                mov si,P_SI
-               call close_file
+               pm_call close_file
                clc
                ret
 
index 87e1bfe..474657a 100644 (file)
@@ -28,9 +28,6 @@ retry_count   equ 16                  ; How patient are we with the disk?
 %assign HIGHMEM_SLOP 0                 ; Avoid this much memory near the top
 LDLINUX_MAGIC  equ 0x3eb202fe          ; A random number to identify ourselves with
 
-MAX_OPEN_LG2   equ 6                   ; log2(Max number of open files)
-MAX_OPEN       equ (1 << MAX_OPEN_LG2)
-
 SECTOR_SHIFT   equ 9
 SECTOR_SIZE    equ (1 << SECTOR_SHIFT)
 
index b57f1e7..91eff8f 100644 (file)
@@ -8,9 +8,6 @@
 
 #define FILENAME_MAX_LG2 8
 #define FILENAME_MAX     (1 << FILENAME_MAX_LG2)
-/* The size of open_file_t in extlinux is double of in others */
-#define MAX_OPEN_LG2     (6 - 1)  
-#define MAX_OPEN         (1 << MAX_OPEN_LG2)
 #define MAX_SYMLINKS     64
 #define SYMLINK_SECTORS  2
 
@@ -26,7 +23,7 @@ struct open_file_t {
     uint32_t pad[3];          /* pad to 2^5 == 0x20 bytes */
 };
 
-static struct open_file_t __bss16 Files[MAX_OPEN];
+static struct open_file_t Files[MAX_OPEN];
 
 static char SymlinkBuf[SYMLINK_SECTORS * SECTOR_SIZE + 64];
 
@@ -84,19 +81,22 @@ static struct open_file_t *allocate_file(void)
 
 
 /**
- * close_file:
+ * ext2_close_file:
  *
  * Deallocates a file structure point by FILE
  *
  * @param: file, the file structure we want deallocate
  *
  */
-static void close_file(struct open_file_t *file)
+static inline void close_pvt(struct open_file_t *of)
 {
-    if (file)
-        file->file_bytesleft = 0;
+    of->file_bytesleft = 0;
 }
 
+static void ext2_close_file(struct file *file)
+{
+    close_pvt(file->open_file);
+}
 
 /**
  * mangle_name:
@@ -495,13 +495,14 @@ static void getlinsec_ext(struct fs_info *fs, char *buf,
  * @return: ECX(of regs), number of bytes read
  *
  */
-static uint32_t ext2_getfssec(struct fs_info *fs, char *buf, 
-                       void *open_file, int sectors, int *have_more)
+static uint32_t ext2_getfssec(struct file *gfile, char *buf,
+                             int sectors, bool *have_more)
 {
     int sector_left, next_sector, sector_idx;
     int frag_start, con_sec_cnt;
     int bytes_read = sectors << SECTOR_SHIFT;
-    struct open_file_t *file = (struct open_file_t *)open_file;
+    struct open_file_t *file = gfile->open_file;
+    struct fs_info *fs = gfile->fs;
     
     sector_left = (file->file_bytesleft + SECTOR_SIZE - 1) >> SECTOR_SHIFT;
     if (sectors > sector_left)
@@ -528,7 +529,7 @@ static uint32_t ext2_getfssec(struct fs_info *fs, char *buf,
             
             sector_idx ++;
             next_sector ++;
-        }while(next_sector == linsector(fs, sector_idx));                
+        } while (next_sector == linsector(fs, sector_idx));                
         
 #if 0   
         printf("You are reading data stored at sector --0x%x--0x%x\n", 
@@ -537,13 +538,14 @@ static uint32_t ext2_getfssec(struct fs_info *fs, char *buf,
         getlinsec_ext(fs, buf, frag_start, con_sec_cnt);
         buf += con_sec_cnt << 9;
         file->file_sector += con_sec_cnt;  /* next sector index */
-    }while(sectors);
+    } while(sectors);
     
     if (bytes_read >= file->file_bytesleft) { 
         bytes_read = file->file_bytesleft;
-        *have_more = 0;
-    } else
-        *have_more = 1;    
+       *have_more = 0;
+    } else {
+        *have_more = 1;
+    }    
     file->file_bytesleft -= bytes_read;
 
     return bytes_read;
@@ -557,21 +559,28 @@ static uint32_t ext2_getfssec(struct fs_info *fs, char *buf,
  * find a dir entry, if find return it or return NULL
  *
  */
-static struct ext2_dir_entry* find_dir_entry(struct fs_info *fs, struct open_file_t *file,char *filename)
+static struct ext2_dir_entry* find_dir_entry(struct fs_info *fs,
+                                            struct open_file_t *file,
+                                            char *filename)
 {
-    int   have_more;
+    bool have_more;
     char *EndBlock = trackbuf + (SecPerClust << SECTOR_SHIFT);;
     struct ext2_dir_entry *de;
+    struct file xfile;
+
+    /* Fake out a VFS file structure */
+    xfile.fs        = fs;
+    xfile.open_file = file;
     
     /* read a clust at a time */
-    ext2_getfssec(fs, trackbuf, file, SecPerClust, &have_more);        
+    ext2_getfssec(&xfile, trackbuf, SecPerClust, &have_more);        
     de = (struct ext2_dir_entry *)trackbuf;        
     
     while (1) {
         if ((char *)de >= (char *)EndBlock) {
             if (!have_more) 
                 return NULL;
-            ext2_getfssec(fs, trackbuf, file,SecPerClust,&have_more);
+            ext2_getfssec(&xfile, trackbuf, SecPerClust, &have_more);
             de = (struct ext2_dir_entry *)trackbuf;
         }
         
@@ -595,25 +604,29 @@ static struct ext2_dir_entry* find_dir_entry(struct fs_info *fs, struct open_fil
 }
 
 
-static chardo_symlink(struct fs_info *fs, struct open_file_t *file, 
-                 uint32_t file_len, char *filename)
+static char *do_symlink(struct fs_info *fs, struct open_file_t *file, 
+                       uint32_t file_len, char *filename)
 {
-    int  flag, have_more;
+    int  flag;
+    bool have_more;
     
     char *SymlinkTmpBuf = trackbuf;
     char *lnk_end;
-    char *SymlinkTmpBufEnd = trackbuf + SYMLINK_SECTORS * SECTOR_SIZE+64;  
+    char *SymlinkTmpBufEnd = trackbuf + SYMLINK_SECTORS * SECTOR_SIZE+64;
+    struct file xfile;
+    xfile.fs = fs;
+    xfile.open_file = file;
     
     flag = this_inode.i_file_acl ? SecPerClust : 0;    
     if (this_inode.i_blocks == flag) {
         /* fast symlink */
-        close_file(file);          /* we've got all we need */
+        close_pvt(file);          /* we've got all we need */
         memcpy(SymlinkTmpBuf, this_inode.i_block, file_len);
         lnk_end = SymlinkTmpBuf + file_len;
         
     } else {                           
         /* slow symlink */
-        ext2_getfssec(fs, SymlinkTmpBuf,file,SYMLINK_SECTORS,&have_more);
+        ext2_getfssec(&xfile, SymlinkTmpBuf, SYMLINK_SECTORS, &have_more);
         lnk_end = SymlinkTmpBuf + file_len;
     }
     
@@ -695,7 +708,7 @@ static void ext2_searchdir(char *filename, struct file *file)
         
         inr = de->d_inode;
         filename += de->d_name_len;
-        close_file(open_file);
+        close_pvt(open_file);
         goto open;
     }    
     
@@ -721,7 +734,7 @@ static void ext2_searchdir(char *filename, struct file *file)
     
     /* Otherwise, something bad ... */
  err:
-    close_file(open_file);
+    close_pvt(open_file);
  err_noclose:
     file_len = 0;
     open_file = NULL;
@@ -794,9 +807,11 @@ static int ext2_fs_init(struct fs_info *fs)
 
 const struct fs_ops ext2_fs_ops = {
     .fs_name       = "ext2",
+    .fs_flags      = 0,
     .fs_init       = ext2_fs_init,
     .searchdir     = ext2_searchdir,
     .getfssec      = ext2_getfssec,
+    .close_file    = ext2_close_file,
     .mangle_name   = ext2_mangle_name,
     .unmangle_name = ext2_unmangle_name,
     .load_config   = ext2_load_config
index eb238be..d944bb1 100644 (file)
@@ -14,7 +14,7 @@
 
        ; fs.c
        extern fs_init, searchdir, getfssec, mangle_name, load_config
-        extern unmangle_name
+        extern unmangle_name, close_file
 
 %if IS_SYSLINUX
         ; fat.c
index c184730..83dc908 100644 (file)
@@ -9,8 +9,6 @@
 
 #define FILENAME_MAX_LG2 8
 #define FILENAME_MAX     (1 << FILENAME_MAX_LG2)
-#define MAX_OPEN_LG2     6
-#define MAX_OPEN         (1 << MAX_OPEN_LG2)
 #define ROOT_DIR_WORD    0x002f
 
 /* file structure. This holds the information for each currently open file */
@@ -20,7 +18,7 @@ struct open_file_t {
     uint32_t file_left;      /* number of sectors left */
 };
 
-static struct open_file_t __bss16 Files[MAX_OPEN];
+static struct open_file_t Files[MAX_OPEN];
 
 extern uint8_t SecPerClust;
 
@@ -105,12 +103,15 @@ static struct open_file_t *alloc_fill_dir(sector_t sector)
 
 
 /* Deallocates a file structure */
-static void close_file(struct open_file_t *file)
+static inline void close_pvt(struct open_file_t *of)
 {
-    if ( file )
-        file->file_sector = 0;
+    of->file_sector = 0;
 }
 
+static void vfat_close_file(struct file *file)
+{
+    close_pvt(file->open_file);
+}
 
 
 /* Deallocates a directory structure */
@@ -321,11 +322,12 @@ static void __getfssec(struct fs_info *fs, char *buf, struct open_file_t *file,
  * @return: number of bytes read
  *
  */
-static uint32_t vfat_getfssec(struct fs_info *fs, char *buf, 
-                  void *open_file, int sectors, int *have_more)
+static uint32_t vfat_getfssec(struct file *gfile, char *buf, int sectors,
+                             bool *have_more)
 {
     uint32_t bytes_read = sectors << SECTOR_SHIFT;
-    struct open_file_t *file = (struct open_file_t *)open_file;
+    struct open_file_t *file = gfile->open_file;
+    struct fs_info *fs = gfile->fs;
     
     if ( sectors > file->file_left )
         sectors = file->file_left;
@@ -669,8 +671,7 @@ static void vfat_searchdir(char *filename, struct file *file)
     char  *p;        
     struct open_file_t *open_file = NULL;
 
-    if (file->fs != this_fs)
-        this_fs = file->fs;
+    this_fs = file->fs;
     
     dir_sector = CurrentDir;
     if ( *filename == '/' ) {
@@ -699,9 +700,10 @@ static void vfat_searchdir(char *filename, struct file *file)
         
         mangle_dos_name(MangleBuf, filename);
         /* close it before open a new dir file */
-        close_file(open_file);
+       if (open_file)
+           close_pvt(open_file);
         open_file = search_dos_dir(file->fs, MangleBuf, dir_sector, &file_len, &attr);
-        if (! open_file) 
+        if (!open_file) 
             goto fail;
 
         dir_sector = open_file->file_sector;
@@ -721,8 +723,8 @@ static void vfat_searchdir(char *filename, struct file *file)
         open_file->file_left = ( file_len + SECTOR_SIZE -1 ) >> SECTOR_SHIFT;
     }
 
-    file->file_len = file_len;
-    file->open_file = (void *)open_file;
+    file->file_len  = file_len;
+    file->open_file = open_file;
 }
 
 
@@ -869,13 +871,13 @@ void vfat_readdir(com32sys_t *regs)/*
 
 static void vfat_load_config(com32sys_t *regs)
 {
-    char syslinux_cfg1[] = "/boot/syslinux/syslinux.cfg";
-    char syslinux_cfg2[] = "/syslinux/syslinux.cfg";
-    char syslinux_cfg3[] = "/syslinux.cfg";
-    char config_name[] = "syslinux.cfg";
+    static const char syslinux_cfg1[] = "/boot/syslinux/syslinux.cfg";
+    static const char syslinux_cfg2[] = "/syslinux/syslinux.cfg";
+    static const char syslinux_cfg3[] = "/syslinux.cfg";
+    static const char config_name[] = "syslinux.cfg";
     
-
-    char *syslinux_cfg[]= {syslinux_cfg1, syslinux_cfg2, syslinux_cfg3};
+    const char * const syslinux_cfg[] =
+       { syslinux_cfg1, syslinux_cfg2, syslinux_cfg3 };
     com32sys_t oregs;
     int i = 0;
     
@@ -907,12 +909,10 @@ static void vfat_load_config(com32sys_t *regs)
     CurrentDir = PrevDir;
 }
  
-static inline void bsr(uint8_t *res, int num)
+static inline __constfunc uint32_t bsr(uint32_t num)
 {
-        int i = 0;
-        while (num >>= 1)
-                i ++;
-        *res = i;
+    asm("bsrl %1,%0" : "=r" (num) : "rm" (num));
+    return num;
 }
 
 /* init. the fs meta data, return the block size in bits */
@@ -934,7 +934,7 @@ static int vfat_fs_init(struct fs_info *fs)
     RootDirSize = (fat.bxRootDirEnts+SECTOR_SIZE/32-1) >> (SECTOR_SHIFT-5);
     DataArea = RootDirArea + RootDirSize;
     
-    bsr(&ClustShift, fat.bxSecPerClust);
+    ClustShift = bsr(fat.bxSecPerClust);
     ClustByteShift = ClustShift + SECTOR_SHIFT;
     ClustMask = fat.bxSecPerClust - 1;
     ClustSize = fat.bxSecPerClust << SECTOR_SHIFT;    
@@ -953,9 +953,11 @@ static int vfat_fs_init(struct fs_info *fs)
         
 const struct fs_ops vfat_fs_ops = {
     .fs_name       = "vfat",
+    .fs_flags      = 0,
     .fs_init       = vfat_fs_init,
     .searchdir     = vfat_searchdir,
     .getfssec      = vfat_getfssec,
+    .close_file    = vfat_close_file,
     .mangle_name   = vfat_mangle_name,
     .unmangle_name = vfat_unmangle_name,
     .load_config   = vfat_load_config
index 0bfa155..c4bf038 100644 (file)
--- a/core/fs.c
+++ b/core/fs.c
@@ -4,11 +4,55 @@
 #include "fs.h"
 #include "cache.h"
 
-
-/* The this fs pointer */
+/* The currently mounted filesystem */
 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];
+
+/*
+ * Get an empty file structure
+ */
+static struct file *alloc_file(void)
+{
+    int i;
+    struct file *file = Files;
+
+    for (i = 0; i < MAX_OPEN; i++) {
+       if (!file->open_file)
+           return file;
+    }
+
+    return NULL;
+}
+
+/*
+ * Close and free a file structure
+ */
+static inline void free_file(struct file *file)
+{
+    memset(file, 0, sizeof *file);
+}
+
+static 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)
 {
@@ -17,8 +61,8 @@ void load_config(com32sys_t *regs)
 
 void mangle_name(com32sys_t *regs)
 {
-    char *src = (char *)MK_PTR(regs->ds, regs->esi.w[0]);
-    char *dst = (char *)MK_PTR(regs->es, regs->edi.w[0]);
+    char *src = MK_PTR(regs->ds, regs->esi.w[0]);
+    char *dst = MK_PTR(regs->es, regs->edi.w[0]);
 
     this_fs->fs_ops->mangle_name(dst, src);
 }
@@ -39,21 +83,28 @@ void unmangle_name(com32sys_t *regs)
 void getfssec(com32sys_t *regs)
 {
     int sectors;
-    int have_more;
+    bool have_more;
     uint32_t bytes_read;
     char *buf;
-    struct file file;
+    struct file *file;
+    uint16_t handle;
     
     sectors = regs->ecx.w[0];
-    buf = (char *)MK_PTR(regs->es, regs->ebx.w[0]);
-    file.open_file = MK_PTR(regs->ds, regs->esi.w[0]); 
-    file.fs = this_fs;
 
-    bytes_read = this_fs->fs_ops->getfssec(file.fs, buf, file.open_file, sectors, &have_more);
+    handle = regs->esi.w[0];
+    file = handle_to_file(handle);
+
+    buf = MK_PTR(regs->es, regs->ebx.w[0]);
+    bytes_read = file->fs->fs_ops->getfssec(file, buf, sectors, &have_more);
     
-    /* if we reach the EOF, set the si to be NULL */
-    if (!have_more)
+    /*
+     * If we reach EOF, the filesystem driver will have already closed
+     * the underlying file... this really should be cleaner.
+     */
+    if (!have_more) {
+       _close_file(file);
         regs->esi.w[0] = 0;
+    }
     
     regs->ecx.l = bytes_read;
 }
@@ -62,24 +113,42 @@ void getfssec(com32sys_t *regs)
 void searchdir(com32sys_t *regs)
 {
     char *filename = (char *)MK_PTR(regs->ds, regs->edi.w[0]);;
-    struct file file;
+    struct file *file;
         
-#if 1    
+#if 0
     printf("filename: %s\n", filename);
 #endif
 
-    memset(&file, 0, sizeof file);
-    file.fs = this_fs;
-    
-    this_fs->fs_ops->searchdir(filename, &file);
-    regs->esi.w[0] = OFFS_WRT(file.open_file, 0);
-    regs->eax.l = file.file_len;
-    if (file.open_file)
-        regs->eflags.l &= ~EFLAGS_ZF;
-    else
-        regs->eflags.l |= EFLAGS_ZF;
+    file = alloc_file();
+
+    if (file) {
+       file->fs = this_fs;
+       file->fs->fs_ops->searchdir(filename, file);
+
+       if (file->open_file) {
+           regs->esi.w[0]  = file_to_handle(file);
+           regs->eax.l     = file->file_len;
+           regs->eflags.l &= ~EFLAGS_ZF;
+           return;
+       }
+    }
+
+    /* failure... */
+    regs->esi.w[0]  = 0;
+    regs->eax.l     = 0;
+    regs->eflags.l |= EFLAGS_ZF;
 }
 
+void close_file(com32sys_t *regs)
+{
+    uint16_t handle = regs->esi.w[0];
+    struct file *file;
+
+    if (handle) {
+       file = handle_to_file(handle);
+       _close_file(file);
+    }
+}
 
 /*
  * it will do:
@@ -92,16 +161,18 @@ void searchdir(com32sys_t *regs)
 void fs_init(com32sys_t *regs)
 {
     int blk_shift;
-    struct fs_ops *ops = (struct fs_ops*)regs->eax.l;
-    
+    const struct fs_ops *ops = (const struct fs_ops *)regs->eax.l;
+
     /* set up the fs stucture */    
-    fs.fs_name = ops->fs_name;
     fs.fs_ops = ops;
-    if (!strcmp(fs.fs_name, "pxe"))
-        fs.fs_dev = NULL;
+
+    /* this is a total hack... */
+    if (ops->fs_flags & FS_NODEV)
+        fs.fs_dev = NULL;      /* Non-device filesystem */
     else 
-        fs.fs_dev = device_init(regs->edx.b[0], regs->edx.b[1], regs->ecx.l, \
-                            regs->esi.w[0], regs->edi.w[0]);
+        fs.fs_dev = device_init(regs->edx.b[0], regs->edx.b[1], regs->ecx.l,
+                               regs->esi.w[0], regs->edi.w[0]);
+
     this_fs = &fs;
 
     /* invoke the fs-specific init code */
index 0aa140b..48b9f77 100644 (file)
@@ -83,24 +83,11 @@ openfd:
 .ret:          ret
 
 .stack_full:
-               call close_file
+               pm_call close_file
                xor ax,ax               ; ZF <- 1
                pop bx
                ret
                
-;
-; close_file:
-;           Deallocates a file structure (pointer in SI)
-;           Assumes CS == DS.
-;
-close_file:
-               and si,si
-               jz .closed
-               mov dword [si],0                ; First dword == file_bytesleft
-               xor si,si
-.closed:       ret
-
-
 getc:
                push bx
                push si
@@ -191,7 +178,7 @@ close:
                push si
                mov bx,[CurrentGetC]
                mov si,[bx+gc_file]
-               call close_file
+               pm_call close_file
                add bx,getc_file_size
                mov [CurrentGetC],bx
                pop si
index ca4e281..21e1349 100644 (file)
@@ -7,26 +7,41 @@
 #include "core.h"
 #include "disk.h"
 
+/*
+ * Maximum number of open files.  This is *currently* constrained by the
+ * fact that PXE needs to be able to fit all its packet buffers into a
+ * 64K segment; this should be fixed by moving the packet buffers to high
+ * memory.
+ */
+#define MAX_OPEN_LG2   5
+#define MAX_OPEN       (1 << MAX_OPEN_LG2)
+
 struct fs_info {
-    char *fs_name;
-    struct fs_ops *fs_ops;
+    const struct fs_ops *fs_ops;
     struct device *fs_dev;
 };
 
+struct open_file_t;            /* Filesystem private structure */
+
 struct file {
-    void*    open_file; /* points to the fs-specific open_file_t */
-    struct   fs_info *fs;
+    struct open_file_t *open_file; /* Filesystem private data */
+    struct fs_info *fs;
     uint32_t file_len;
 };
 
+enum fs_flags {
+    FS_NODEV = 1,
+};
 
 struct fs_ops {
     /* in fact, we use fs_ops structure to find the right fs */
-    char *fs_name;
+    const char *fs_name;
+    enum fs_flags fs_flags;
     
     int      (*fs_init)(struct fs_info *);
     void     (*searchdir)(char *, struct file *);
-    uint32_t (*getfssec)(struct fs_info *, char *, void * , int, int *);
+    uint32_t (*getfssec)(struct file *, char *, int, bool *);
+    void     (*close_file)(struct file *);
     void     (*mangle_name)(char *, char *);
     int      (*unmangle_name)(char *, char *);
     void     (*load_config)(com32sys_t *);
index c7e4041..583513c 100644 (file)
@@ -10,8 +10,6 @@
 
 #define FILENAME_MAX_LG2 8
 #define FILENAME_MAX     (1 << FILENAME_MAX_LG2)
-#define MAX_OPEN_LG2     6
-#define MAX_OPEN         (1 << MAX_OPEN_LG2)
 #define ISO_SECTOR_SHIFT 11
 #define ISO_SECTOR_SIZE  (1 << ISO_SECTOR_SHIFT)
 #define ROOT_DIR_WORD    0x002f
@@ -24,7 +22,7 @@ struct open_file_t {
         uint32_t file_left;
 };
 
-static struct open_file_t __bss16 Files[MAX_OPEN];
+static struct open_file_t Files[MAX_OPEN];
 
 struct dir_t {
         uint32_t dir_lba;        /* Directory start (LBA) */
@@ -73,10 +71,14 @@ static struct open_file_t *allocate_file(void)
  * Deallocates a file structure 
  *
  */
-static void close_file(struct open_file_t *file)
+static inline void close_pvt(struct open_file_t *file)
 {
-    if (file)
-        file->file_sector = 0;
+    file->file_sector = 0;
+}
+
+static void iso_close_file(struct file *file)
+{
+    close_pvt(file->open_file);
 }
 
 /**
@@ -373,7 +375,7 @@ static int do_search_dir(struct fs_info *fs, struct dir_t *dir,
         *res = dir;
         
         /* we can close it now */
-        close_file(file); 
+        close_pvt(file); 
                 
         /* Mark we got a directory */
         return 1;        
@@ -452,7 +454,7 @@ static void iso_searchdir(char *filename, struct file *file)
         goto found;
     }
  err:
-    close_file(open_file);
+    close_pvt(open_file);
     file_len = 0;
     open_file = NULL;
  
@@ -535,7 +537,7 @@ static int iso_fs_init(struct fs_info *fs)
     CurrentDir.dir_len    = open_file->file_bytesleft;
     CurrentDir.dir_clust  = open_file->file_left;
     CurrentDir.dir_lba    = open_file->file_sector;
-    close_file(open_file);
+    close_pvt(open_file);
     
 #ifdef DEBUG
     printf("isolinux directory at LBA = 0x%x\n", CurrentDir.dir_lba);
@@ -548,9 +550,11 @@ static int iso_fs_init(struct fs_info *fs)
 
 const struct fs_ops iso_fs_ops = {
     .fs_name       = "iso",
+    .fs_flags      = 0,
     .fs_init       = iso_fs_init,
     .searchdir     = iso_searchdir,
     .getfssec      = iso_getfssec,
+    .close_file    = iso_close_file,
     .mangle_name   = iso_mangle_name,
     .unmangle_name = iso_unmangle_name,
     .load_config   = iso_load_config
index 91541bc..2816dd8 100644 (file)
@@ -32,8 +32,6 @@ NULLFILE      equ 0                   ; Zero byte == null file name
 NULLOFFSET     equ 0                   ; Position in which to look
 retry_count    equ 6                   ; How patient are we with the BIOS?
 %assign HIGHMEM_SLOP 128*1024          ; Avoid this much memory near the top
-MAX_OPEN_LG2   equ 6                   ; log2(Max number of open files)
-MAX_OPEN       equ (1 << MAX_OPEN_LG2)
 SECTOR_SHIFT   equ 11                  ; 2048 bytes/sector (El Torito requirement)
 SECTOR_SIZE    equ (1 << SECTOR_SHIFT)
 
index 033e9ba..0b5102a 100644 (file)
@@ -6,15 +6,13 @@
 #include <minmax.h>
 #include <sys/cpu.h>
 
-#define MAX_OPEN_LG2       5
-#define MAX_OPEN           (1 << MAX_OPEN_LG2)
 #define FILENAME_MAX_LG2   7
 #define FILENAME_MAX       (1 << FILENAME_MAX_LG2)
 
 #define GPXE 1
 #define USE_PXE_PROVIDED_STACK 0
 
-static struct open_file_t __bss16 Files[MAX_OPEN];
+static struct open_file_t Files[MAX_OPEN];
 
 static char *err_nopxe     = "No !PXE or PXENV+ API found; we're dead...\n";
 static char *err_pxefailed = "PXE API call failed, error ";
@@ -99,10 +97,20 @@ static struct open_file_t *allocate_socket(void)
  */
 static void free_socket(struct open_file_t *file)
 {
-    /* tftp_pktbuf is not cleared */
+    /* tftp_nextport and tftp_pktbuf are not cleared */
     memset(file, 0, offsetof(struct open_file_t, tftp_nextport));
 }
 
+static void pxe_close_file(struct file *file)
+{
+    /*
+     * XXX: we really should see if the connection is open as send
+     * a courtesy ERROR packet so the server knows the connection is
+     * dead.
+     */
+    free_socket(file->open_file);
+}
+
 /**
  * Take a nubmer of bytes in memory and convert to lower-case hxeadecimal 
  *
@@ -650,17 +658,14 @@ static void fill_buffer(struct open_file_t *file)
  * @return: the bytes read
  *
  */
-static uint32_t pxe_getfssec(struct fs_info *fs, char *buf, 
-                      void *open_file, int blocks, int *have_more)
+static uint32_t pxe_getfssec(struct file *gfile, char *buf, 
+                            int blocks, bool *have_more)
 {
-    struct open_file_t *file = (struct open_file_t *)open_file;
+    struct open_file_t *file = gfile->open_file;
     int count = blocks;
     int chunk;
     int bytes_read = 0;
 
-    sti();    
-    fs = NULL;      /* drop the compile warning message */
-
     count <<= TFTP_BLOCKSIZE_LG2;
     while (count) {
         fill_buffer(file);         /* If we have no 'fresh' buffer, get it */              
@@ -684,10 +689,9 @@ static uint32_t pxe_getfssec(struct fs_info *fs, char *buf,
         *have_more = 1;
     } else if (file->tftp_goteof) {
         /* 
-         * The socket is closed and the buffer dranined
-         * close socket structure and re-init for next user
+         * The socket is closed and the buffer drained; the caller will
+        * call close_file and therefore free the socket.
          */
-        free_socket(file);
         *have_more = 0;
     }
     
@@ -1544,9 +1548,11 @@ static int pxe_fs_init(struct fs_info *fs)
     
 const struct fs_ops pxe_fs_ops = {
     .fs_name       = "pxe",
+    .fs_flags      = FS_NODEV,
     .fs_init       = pxe_fs_init,
     .searchdir     = pxe_searchdir,
     .getfssec      = pxe_getfssec,
+    .close_file    = pxe_close_file,
     .mangle_name   = pxe_mangle_name,
     .unmangle_name = pxe_unmangle_name,
     .load_config   = pxe_load_config
index 06e5206..2e8b319 100644 (file)
@@ -35,17 +35,7 @@ NULLFILE     equ 0                   ; Zero byte == null file name
 NULLOFFSET     equ 4                   ; Position in which to look
 REBOOT_TIME    equ 5*60                ; If failure, time until full reset
 %assign HIGHMEM_SLOP 128*1024          ; Avoid this much memory near the top
-MAX_OPEN_LG2   equ 5                   ; log2(Max number of open sockets)
-MAX_OPEN       equ (1 << MAX_OPEN_LG2)
-PKTBUF_SIZE    equ (65536/MAX_OPEN)    ; Per-socket packet buffer size
 TFTP_PORT      equ htons(69)           ; Default TFTP port
-; Desired TFTP block size
-; For Ethernet MTU is normally 1500.  Unfortunately there seems to
-; be a fair number of networks with "substandard" MTUs which break.
-; The code assumes TFTP_LARGEBLK <= 2K.
-TFTP_MTU       equ 1440
-TFTP_LARGEBLK  equ (TFTP_MTU-20-8-4)   ; MTU - IP hdr - UDP hdr - TFTP hdr
-; Standard TFTP block size
 TFTP_BLOCKSIZE_LG2 equ 9               ; log2(bytes/block)
 TFTP_BLOCKSIZE equ (1 << TFTP_BLOCKSIZE_LG2)
 
@@ -764,30 +754,8 @@ BaseStack  dd StackTop             ; ESP of base stack
                dw 0                    ; SS of base stack
 KeepPXE                db 0                    ; Should PXE be kept around?
 
-;
-; TFTP commands
-;
-tftp_tail      db 'octet', 0                           ; Octet mode
-tsize_str      db 'tsize' ,0                           ; Request size
-tsize_len      equ ($-tsize_str)
-               db '0', 0
-blksize_str    db 'blksize', 0                         ; Request large blocks
-blksize_len    equ ($-blksize_str)
-               asciidec TFTP_LARGEBLK
-               db 0
-tftp_tail_len  equ ($-tftp_tail)
-
                alignz 2
 ;
-; Options negotiation parsing table (string pointer, string len, offset
-; into socket structure)
-;
-tftp_opt_table:
-               dw tsize_str, tsize_len, tftp_filesize
-               dw blksize_str, blksize_len, tftp_blksize
-tftp_opts      equ ($-tftp_opt_table)/6
-
-;
 ; Error packet to return on TFTP protocol error
 ; Most of our errors are OACK parsing errors, so use that error code
 ;