diff --git a/fs/Makefile b/fs/Makefile index d6e31f539656c7aefa9741891944e05d59974a46..3b1cea3c1d2f8e8c3ec97cf56347d2da10e1b06f 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -3,7 +3,7 @@ LD := ld CCFLAG := -I../include -nostdinc -ffreestanding -Wall -fomit-frame-pointer -fno-stack-protector -fno-pic -c -m32 LDFLAG := -Ttext 0x0 -s --oformat binary -m elf_i386 INCDIR := ../include -OBJS := read_write.o buffer.o super.o open.o +OBJS := read_write.o buffer.o super.o open.o file_table.o inode.o fs.o : $(OBJS) $(LD) -m elf_i386 -r -o $@ $^ @@ -20,6 +20,12 @@ super.o : super.c open.o : open.c $(GCC) $(CCFLAG) -o $@ $< +file_table.o : file_table.c + $(GCC) $(CCFLAG) -o $@ $< + +inode.o : inode.c + $(GCC) $(CCFLAG) -o $@ $< + clean : rm *.o diff --git a/fs/file_table.c b/fs/file_table.c new file mode 100644 index 0000000000000000000000000000000000000000..94460f24797d35432f2508918f9ac5e1b185607a --- /dev/null +++ b/fs/file_table.c @@ -0,0 +1,4 @@ +#include + +struct file file_table[NR_FILE]; + diff --git a/fs/inode.c b/fs/inode.c new file mode 100644 index 0000000000000000000000000000000000000000..5e3a65bd7ea624644c67a3534ff4df0ea2dbc793 --- /dev/null +++ b/fs/inode.c @@ -0,0 +1,130 @@ +#include +#include + +#include +#include +#include +#include + +extern struct super_block sb; + +struct m_inode inode_table[NR_INODE]={{0,},}; + +static void read_inode(struct m_inode * inode); +static void write_inode(struct m_inode * inode); + +static inline void wait_on_inode(struct m_inode * inode) { + cli(); + while(inode->i_lock) { + sleep_on(&inode->i_wait); + } + sti(); +} + +static inline void lock_inode(struct m_inode * inode) { + cli(); + while(inode->i_lock) { + sleep_on(&inode->i_wait); + } + inode->i_lock = 1; + sti(); +} + +static inline void unlock_inode(struct m_inode * inode) { + inode->i_lock=0; + wake_up(&inode->i_wait); +} + +struct m_inode * get_empty_inode() { + struct m_inode * inode; + static struct m_inode * last_inode = inode_table; + int i; + + do { + inode = NULL; + for (i = NR_INODE; i ; i--) { + if (++last_inode >= inode_table + NR_INODE) + last_inode = inode_table; + + if (!last_inode->i_count) { + inode = last_inode; + if (!inode->i_dirt && !inode->i_lock) + break; + } + } + + if (!inode) { + for (i=0 ; ii_dirt) { + write_inode(inode); + wait_on_inode(inode); + } + } while (inode->i_count); + + memset(inode,0,sizeof(*inode)); + inode->i_count = 1; + return inode; +} + +struct m_inode * iget(int dev, int nr) { + struct m_inode * inode, * empty; + if (!dev) + printk("iget with dev==0"); + + inode = inode_table; + while (inode < NR_INODE+inode_table) { + if (inode->i_dev != dev || inode->i_num != nr) { + inode++; + continue; + } + wait_on_inode(inode); + if (inode->i_dev != dev || inode->i_num != nr) { + inode++; + continue; + } + inode->i_count++; + return inode; + } + + empty = get_empty_inode(); + if (!empty) + return NULL; + + inode=empty; + inode->i_dev = dev; + inode->i_num = nr; + read_inode(inode); + return inode; +} + +static void read_inode(struct m_inode * inode) { + struct super_block * psb; + struct buffer_head * bh; + int block; + + psb = &sb; + lock_inode(inode); + block = 2 + psb->s_imap_blocks + psb->s_zmap_blocks + + (inode->i_num-1)/INODES_PER_BLOCK; + + if (!(bh=bread(inode->i_dev,block))) + printk("unable to read i-node block"); + + + *(struct d_inode *)inode = + ((struct d_inode *)bh->b_data) + [(inode->i_num-1)%INODES_PER_BLOCK]; + + brelse(bh); + unlock_inode(inode); +} + +static void write_inode(struct m_inode * inode) { +} + diff --git a/fs/super.c b/fs/super.c index 9874821b82ab8d839b120634eda968917c5358c7..94ddeb234bed1ea67bf3a92c53054d4b4fc748ad 100644 --- a/fs/super.c +++ b/fs/super.c @@ -5,6 +5,11 @@ #include +#define test_bit(bitnr,addr) ({ \ +register int __res __asm__("ax"); \ +__asm__("bt %2,%3;setb %%al":"=a" (__res):"a" (0),"r" (bitnr),"m" (*(addr))); \ +__res; }) + int ROOT_DEV = 0; struct super_block sb; @@ -64,7 +69,35 @@ struct super_block * read_super(int dev) { } void mount_root() { + int i,free; struct super_block * p; - if (!(p=read_super(ROOT_DEV))) + struct m_inode * mi; + + for(i=0;ii_count += 3 ; + p->s_isup = p->s_imount = mi; + current->pwd = mi; + current->root = mi; + + free = 0; + i = p->s_nzones; + while (-- i >= 0) + if (!test_bit(i&8191,p->s_zmap[i>>13]->b_data)) + free++; + + printk("%d/%d free blocks\n\r",free,p->s_nzones); + free=0; + i=p->s_ninodes+1; + while (-- i >= 0) + if (!test_bit(i&8191,p->s_imap[i>>13]->b_data)) + free++; + printk("%d/%d free inodes\n\r",free,p->s_ninodes); } diff --git a/include/const.h b/include/const.h new file mode 100644 index 0000000000000000000000000000000000000000..5ff6b4aa2a4c70ffca518bafcd79c82530c99d48 --- /dev/null +++ b/include/const.h @@ -0,0 +1,15 @@ +#ifndef _CONST_H +#define _CONST_H + +#define BUFFER_END 0x200000 + +#define I_TYPE 0170000 +#define I_DIRECTORY 0040000 +#define I_REGULAR 0100000 +#define I_BLOCK_SPECIAL 0060000 +#define I_CHAR_SPECIAL 0020000 +#define I_NAMED_PIPE 0010000 +#define I_SET_UID_BIT 0004000 +#define I_SET_GID_BIT 0002000 + +#endif diff --git a/include/linux/fs.h b/include/linux/fs.h index 0f6b282c0616fe91a647d17d47dab6f55d11da3f..8fb66451dc0f62d92419e45f4a92c2daca7bb37e 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -13,11 +13,18 @@ void buffer_init(long buffer_end); #define MAJOR(a) (((unsigned)(a))>>8) #define MINOR(a) ((a)&0xff) +#define NAME_LEN 14 +#define ROOT_INO 1 + #define I_MAP_SLOTS 8 #define Z_MAP_SLOTS 8 #define SUPER_MAGIC 0x137F +#define NR_OPEN 20 +#define NR_INODE 32 +#define NR_FILE 64 +#define NR_SUPER 8 #define NR_HASH 307 #define BLOCK_SIZE 1024 @@ -25,6 +32,9 @@ void buffer_init(long buffer_end); #define NULL ((void *) 0) #endif +#define INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct d_inode))) +#define DIR_ENTRIES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct dir_entry))) + struct buffer_head { char * b_data; unsigned long b_blocknr; @@ -40,6 +50,48 @@ struct buffer_head { struct buffer_head * b_next_free; }; +struct d_inode { + unsigned short i_mode; + unsigned short i_uid; + unsigned long i_size; + unsigned long i_time; + unsigned char i_gid; + unsigned char i_nlinks; + unsigned short i_zone[9]; +}; + +struct m_inode { + unsigned short i_mode; + unsigned short i_uid; + unsigned long i_size; + unsigned long i_time; + unsigned char i_gid; + unsigned char i_nlinks; + unsigned short i_zone[9]; + + struct task_struct * i_wait; + struct task_struct * i_wait2; + unsigned long i_atime; + unsigned long i_ctime; + unsigned short i_dev; + unsigned short i_num; + unsigned short i_count; + unsigned char i_lock; + unsigned char i_dirt; + unsigned char i_pipe; + unsigned char i_mount; + unsigned char i_seek; + unsigned char i_update; +}; + +struct file { + unsigned short f_mode; + unsigned short f_flags; + unsigned short f_count; + struct m_inode * f_inode; + off_t f_pos; +}; + struct super_block { unsigned short s_ninodes; unsigned short s_nzones; @@ -72,8 +124,10 @@ struct d_super_block { unsigned short s_magic; }; -extern inline void wait_on_buffer(struct buffer_head* bh); +extern struct file file_table[NR_FILE]; +extern struct m_inode * iget(int dev,int nr); +extern inline void wait_on_buffer(struct buffer_head* bh); extern struct buffer_head * getblk(int dev, int block); extern void ll_rw_block(int rw, struct buffer_head * bh); extern void brelse(struct buffer_head * buf); diff --git a/include/linux/sched.h b/include/linux/sched.h index 44fe15e10d860f3697a152f25229bc8491dbda32..217d5cb889e0c1f399b1440917ece01f4337e0ae 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -78,7 +78,17 @@ struct task_struct { long counter; long priority; long pid; - struct task_struct *p_pptr, *p_cptr, *p_ysptr, *p_osptr;; + struct task_struct *p_pptr, *p_cptr, *p_ysptr, *p_osptr; + /* file info */ + int tty; + unsigned short umask; + struct m_inode * pwd; + struct m_inode * root; + struct m_inode * executable; + struct m_inode * library; + unsigned long close_on_exec; + struct file * filp[NR_OPEN]; + struct desc_struct ldt[3]; struct tss_struct tss; }; @@ -90,6 +100,8 @@ struct task_struct { 15, \ 0, \ &init_task.task, 0, 0, 0,\ + -1,0022,NULL,NULL,NULL,NULL,0, \ + {NULL,}, \ { \ {0, 0}, \ {0xfff, 0xc0fa00}, \ diff --git a/kernel/blk_drv/blk.h b/kernel/blk_drv/blk.h index e07a0a97ef10ceae5183621f34456705189399eb..1e4d7b54bfb428b7cd52cee93d180a84de3eeda7 100644 --- a/kernel/blk_drv/blk.h +++ b/kernel/blk_drv/blk.h @@ -18,9 +18,9 @@ struct request { }; #define IN_ORDER(s1,s2) \ -((s1)->cmd<(s2)->cmd || (s1)->cmd==(s2)->cmd && \ +((s1)->cmd<(s2)->cmd || ((s1)->cmd==(s2)->cmd && \ ((s1)->dev < (s2)->dev || ((s1)->dev == (s2)->dev && \ -(s1)->sector < (s2)->sector))) +(s1)->sector < (s2)->sector)))) struct blk_dev_struct { void (*request_fn)(void); diff --git a/kernel/fork.c b/kernel/fork.c index 206ac4ebde3de30c7196b0c80ab3ae2fc666c0a0..24ada8a3ec4f7807d6b190628da5355f3481daa4 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -36,6 +36,8 @@ int copy_process(int nr,long ebp,long edi,long esi,long gs,long none, long fs,long es,long ds, long eip,long cs,long eflags,long esp,long ss) { struct task_struct *p; + int i; + struct file *f; p = (struct task_struct *) get_free_page(); if (!p) @@ -81,6 +83,33 @@ int copy_process(int nr,long ebp,long edi,long esi,long gs,long none, return -EAGAIN; } + for (i = 0; i < NR_OPEN; i++) { + p->filp[i] = current->filp[i]; + if ((f = p->filp[i])) + f->f_count++; + } + + p->tty = current->tty; + p->umask = current->umask; + + p->pwd = current->pwd; + if (current->pwd) + current->pwd->i_count++; + + p->root = current->root; + if (current->root) + current->root->i_count++; + + p->executable = current->executable; + if (current->executable) + current->executable->i_count++; + + p->library = current->library; + if (current->library) + current->library->i_count++; + + p->close_on_exec = current->close_on_exec; + set_tss_desc(gdt+(nr<<1)+FIRST_TSS_ENTRY,&(p->tss)); set_ldt_desc(gdt+(nr<<1)+FIRST_LDT_ENTRY,&(p->ldt));