|
|
1.1 root 1: /*
1.1.1.2 root 2: * linux/fs/super.c
3: *
4: * (C) 1991 Linus Torvalds
5: */
6:
7: /*
1.1 root 8: * super.c contains code to handle the super-block tables.
9: */
10: #include <linux/config.h>
11: #include <linux/sched.h>
1.1.1.5 root 12: #include <linux/minix_fs.h>
1.1 root 13: #include <linux/kernel.h>
1.1.1.2 root 14: #include <asm/system.h>
15:
16: #include <errno.h>
17: #include <sys/stat.h>
18:
19: int sync_dev(int dev);
20: void wait_for_keypress(void);
1.1 root 21:
22: /* set_bit uses setb, as gas doesn't recognize setc */
23: #define set_bit(bitnr,addr) ({ \
24: register int __res __asm__("ax"); \
25: __asm__("bt %2,%3;setb %%al":"=a" (__res):"a" (0),"r" (bitnr),"m" (*(addr))); \
26: __res; })
27:
28: struct super_block super_block[NR_SUPER];
1.1.1.2 root 29: /* this is initialized in init/main.c */
30: int ROOT_DEV = 0;
1.1 root 31:
1.1.1.6 ! root 32: /* Move into include file later */
! 33:
! 34: static struct file_system_type file_systems[] = {
! 35: {minix_read_super,"minix"},
! 36: {NULL,NULL}
! 37: };
! 38:
! 39: /* end of include file */
! 40:
! 41: struct file_system_type *get_fs_type(char *name)
! 42: {
! 43: int a;
! 44:
! 45: for(a = 0 ; file_systems[a].read_super ; a++)
! 46: if (!strcmp(name,file_systems[a].name))
! 47: return(&file_systems[a]);
! 48: return(NULL);
! 49: }
! 50:
! 51: void lock_super(struct super_block * sb)
1.1 root 52: {
1.1.1.2 root 53: cli();
54: while (sb->s_lock)
55: sleep_on(&(sb->s_wait));
56: sb->s_lock = 1;
57: sti();
58: }
59:
1.1.1.6 ! root 60: void free_super(struct super_block * sb)
1.1.1.2 root 61: {
62: cli();
63: sb->s_lock = 0;
64: wake_up(&(sb->s_wait));
65: sti();
66: }
67:
1.1.1.6 ! root 68: void wait_on_super(struct super_block * sb)
1.1.1.2 root 69: {
70: cli();
71: while (sb->s_lock)
72: sleep_on(&(sb->s_wait));
73: sti();
74: }
75:
76: struct super_block * get_super(int dev)
77: {
78: struct super_block * s;
79:
80: if (!dev)
81: return NULL;
82: s = 0+super_block;
83: while (s < NR_SUPER+super_block)
84: if (s->s_dev == dev) {
85: wait_on_super(s);
86: if (s->s_dev == dev)
87: return s;
88: s = 0+super_block;
89: } else
90: s++;
91: return NULL;
92: }
93:
94: void put_super(int dev)
95: {
96: struct super_block * sb;
97:
98: if (dev == ROOT_DEV) {
99: printk("root diskette changed: prepare for armageddon\n\r");
100: return;
101: }
102: if (!(sb = get_super(dev)))
103: return;
1.1.1.5 root 104: if (sb->s_covered) {
1.1.1.2 root 105: printk("Mounted disk changed - tssk, tssk\n\r");
106: return;
107: }
1.1.1.6 ! root 108: if (sb->s_op && sb->s_op->put_super)
! 109: sb->s_op->put_super(sb);
1.1.1.2 root 110: }
111:
1.1.1.6 ! root 112: static struct super_block * read_super(int dev,char *name,void *data)
1.1.1.2 root 113: {
114: struct super_block * s;
1.1.1.6 ! root 115: struct file_system_type *type;
1.1 root 116:
1.1.1.2 root 117: if (!dev)
1.1 root 118: return NULL;
1.1.1.2 root 119: check_disk_change(dev);
120: if (s = get_super(dev))
121: return s;
1.1.1.6 ! root 122: if (!(type=get_fs_type(name))) {
! 123: printk("get fs type failed %s\n",name);
! 124: return NULL;
! 125: }
1.1.1.2 root 126: for (s = 0+super_block ;; s++) {
127: if (s >= NR_SUPER+super_block)
128: return NULL;
129: if (!s->s_dev)
130: break;
131: }
132: s->s_dev = dev;
1.1.1.6 ! root 133: if (!type->read_super(s,data))
! 134: return(NULL);
! 135: s->s_dev = dev;
1.1.1.5 root 136: s->s_covered = NULL;
1.1.1.2 root 137: s->s_time = 0;
138: s->s_rd_only = 0;
139: s->s_dirt = 0;
1.1.1.6 ! root 140: return(s);
1.1.1.2 root 141: }
142:
143: int sys_umount(char * dev_name)
144: {
1.1.1.5 root 145: struct inode * inode;
1.1.1.2 root 146: struct super_block * sb;
147: int dev;
148:
149: if (!(inode=namei(dev_name)))
150: return -ENOENT;
1.1.1.5 root 151: dev = inode->i_rdev;
1.1.1.2 root 152: if (!S_ISBLK(inode->i_mode)) {
153: iput(inode);
154: return -ENOTBLK;
155: }
156: iput(inode);
157: if (dev==ROOT_DEV)
158: return -EBUSY;
1.1.1.5 root 159: if (!(sb=get_super(dev)) || !(sb->s_covered))
1.1.1.2 root 160: return -ENOENT;
1.1.1.5 root 161: if (!sb->s_covered->i_mount)
1.1.1.2 root 162: printk("Mounted inode has i_mount=0\n");
1.1.1.6 ! root 163: for (inode = inode_table+0 ; inode < inode_table+NR_INODE ; inode++)
1.1.1.2 root 164: if (inode->i_dev==dev && inode->i_count)
1.1.1.5 root 165: if (inode == sb->s_mounted && inode->i_count == 1)
166: continue;
167: else
1.1.1.3 root 168: return -EBUSY;
1.1.1.5 root 169: sb->s_covered->i_mount=0;
170: iput(sb->s_covered);
171: sb->s_covered = NULL;
172: iput(sb->s_mounted);
173: sb->s_mounted = NULL;
1.1.1.6 ! root 174: put_super(dev);
! 175: sync_dev(dev);
1.1.1.2 root 176: return 0;
177: }
178:
179: int sys_mount(char * dev_name, char * dir_name, int rw_flag)
180: {
1.1.1.5 root 181: struct inode * dev_i, * dir_i;
1.1.1.2 root 182: struct super_block * sb;
183: int dev;
184:
185: if (!(dev_i=namei(dev_name)))
186: return -ENOENT;
1.1.1.5 root 187: dev = dev_i->i_rdev;
1.1.1.2 root 188: if (!S_ISBLK(dev_i->i_mode)) {
189: iput(dev_i);
190: return -EPERM;
191: }
192: iput(dev_i);
193: if (!(dir_i=namei(dir_name)))
194: return -ENOENT;
1.1.1.5 root 195: if (dir_i->i_count != 1 || dir_i->i_ino == MINIX_ROOT_INO) {
1.1.1.2 root 196: iput(dir_i);
197: return -EBUSY;
198: }
199: if (!S_ISDIR(dir_i->i_mode)) {
200: iput(dir_i);
201: return -EPERM;
202: }
1.1.1.6 ! root 203: if (dir_i->i_mount) {
1.1.1.2 root 204: iput(dir_i);
1.1.1.6 ! root 205: return -EPERM;
1.1.1.2 root 206: }
1.1.1.6 ! root 207: if (!(sb=read_super(dev,"minix",NULL))) {
1.1.1.2 root 208: iput(dir_i);
209: return -EBUSY;
210: }
1.1.1.6 ! root 211: if (sb->s_covered) {
1.1.1.5 root 212: iput(dir_i);
1.1.1.6 ! root 213: return -EBUSY;
1.1.1.5 root 214: }
1.1.1.6 ! root 215: sb->s_covered = dir_i;
! 216: dir_i->i_mount = 1;
! 217: dir_i->i_dirt = 1; /* NOTE! we don't iput(dir_i) */
1.1.1.2 root 218: return 0; /* we do that in umount */
1.1 root 219: }
220:
221: void mount_root(void)
222: {
223: int i,free;
224: struct super_block * p;
1.1.1.5 root 225: struct inode * mi;
1.1 root 226:
1.1.1.5 root 227: if (32 != sizeof (struct minix_inode))
1.1 root 228: panic("bad i-node size");
229: for(i=0;i<NR_FILE;i++)
230: file_table[i].f_count=0;
1.1.1.2 root 231: if (MAJOR(ROOT_DEV) == 2) {
232: printk("Insert root floppy and press ENTER");
233: wait_for_keypress();
234: }
235: for(p = &super_block[0] ; p < &super_block[NR_SUPER] ; p++) {
1.1 root 236: p->s_dev = 0;
1.1.1.2 root 237: p->s_lock = 0;
238: p->s_wait = NULL;
239: }
1.1.1.6 ! root 240: if (!(p=read_super(ROOT_DEV,"minix",NULL)))
1.1 root 241: panic("Unable to mount root");
1.1.1.6 ! root 242: /*wait_for_keypress();
1.1.1.5 root 243: if (!(mi=iget(ROOT_DEV,MINIX_ROOT_INO)))
1.1 root 244: panic("Unable to read root i-node");
1.1.1.6 ! root 245: wait_for_keypress();*/
! 246: mi=p->s_mounted;
1.1 root 247: mi->i_count += 3 ; /* NOTE! it is logically used 4 times, not 1 */
1.1.1.5 root 248: p->s_mounted = p->s_covered = mi;
1.1 root 249: current->pwd = mi;
250: current->root = mi;
251: free=0;
252: i=p->s_nzones;
253: while (-- i >= 0)
254: if (!set_bit(i&8191,p->s_zmap[i>>13]->b_data))
255: free++;
256: printk("%d/%d free blocks\n\r",free,p->s_nzones);
257: free=0;
258: i=p->s_ninodes+1;
259: while (-- i >= 0)
260: if (!set_bit(i&8191,p->s_imap[i>>13]->b_data))
261: free++;
262: printk("%d/%d free inodes\n\r",free,p->s_ninodes);
263: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.