aboutsummaryrefslogtreecommitdiff
path: root/linux/fs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux/fs/super.c')
-rw-r--r--linux/fs/super.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/linux/fs/super.c b/linux/fs/super.c
new file mode 100644
index 0000000..d832289
--- /dev/null
+++ b/linux/fs/super.c
@@ -0,0 +1,102 @@
+/*
+ * super.c contains code to handle the super-block tables.
+ */
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+
+/* set_bit uses setb, as gas doesn't recognize setc */
+#define set_bit(bitnr,addr) ({ \
+register int __res __asm__("ax"); \
+__asm__("bt %2,%3;setb %%al":"=a" (__res):"a" (0),"r" (bitnr),"m" (*(addr))); \
+__res; })
+
+struct super_block super_block[NR_SUPER];
+
+struct super_block * do_mount(int dev)
+{
+ struct super_block * p;
+ struct buffer_head * bh;
+ int i,block;
+
+ for(p = &super_block[0] ; p < &super_block[NR_SUPER] ; p++ )
+ if (!(p->s_dev))
+ break;
+ p->s_dev = -1; /* mark it in use */
+ if (p >= &super_block[NR_SUPER])
+ return NULL;
+ if (!(bh = bread(dev,1)))
+ return NULL;
+ *p = *((struct super_block *) bh->b_data);
+ brelse(bh);
+ if (p->s_magic != SUPER_MAGIC) {
+ p->s_dev = 0;
+ return NULL;
+ }
+ for (i=0;i<I_MAP_SLOTS;i++)
+ p->s_imap[i] = NULL;
+ for (i=0;i<Z_MAP_SLOTS;i++)
+ p->s_zmap[i] = NULL;
+ block=2;
+ for (i=0 ; i < p->s_imap_blocks ; i++)
+ if (p->s_imap[i]=bread(dev,block))
+ block++;
+ else
+ break;
+ for (i=0 ; i < p->s_zmap_blocks ; i++)
+ if (p->s_zmap[i]=bread(dev,block))
+ block++;
+ else
+ break;
+ if (block != 2+p->s_imap_blocks+p->s_zmap_blocks) {
+ for(i=0;i<I_MAP_SLOTS;i++)
+ brelse(p->s_imap[i]);
+ for(i=0;i<Z_MAP_SLOTS;i++)
+ brelse(p->s_zmap[i]);
+ p->s_dev=0;
+ return NULL;
+ }
+ p->s_imap[0]->b_data[0] |= 1;
+ p->s_zmap[0]->b_data[0] |= 1;
+ p->s_dev = dev;
+ p->s_isup = NULL;
+ p->s_imount = NULL;
+ p->s_time = 0;
+ p->s_rd_only = 0;
+ p->s_dirt = 0;
+ return p;
+}
+
+void mount_root(void)
+{
+ int i,free;
+ struct super_block * p;
+ struct m_inode * mi;
+
+ if (32 != sizeof (struct d_inode))
+ panic("bad i-node size");
+ for(i=0;i<NR_FILE;i++)
+ file_table[i].f_count=0;
+ for(p = &super_block[0] ; p < &super_block[NR_SUPER] ; p++)
+ p->s_dev = 0;
+ if (!(p=do_mount(ROOT_DEV)))
+ panic("Unable to mount root");
+ if (!(mi=iget(ROOT_DEV,1)))
+ panic("Unable to read root i-node");
+ mi->i_count += 3 ; /* NOTE! it is logically used 4 times, not 1 */
+ p->s_isup = p->s_imount = mi;
+ current->pwd = mi;
+ current->root = mi;
+ free=0;
+ i=p->s_nzones;
+ while (-- i >= 0)
+ if (!set_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 (!set_bit(i&8191,p->s_imap[i>>13]->b_data))
+ free++;
+ printk("%d/%d free inodes\n\r",free,p->s_ninodes);
+}