|
|
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.2 root 32: static void lock_super(struct super_block * sb)
1.1 root 33: {
1.1.1.2 root 34: cli();
35: while (sb->s_lock)
36: sleep_on(&(sb->s_wait));
37: sb->s_lock = 1;
38: sti();
39: }
40:
41: static void free_super(struct super_block * sb)
42: {
43: cli();
44: sb->s_lock = 0;
45: wake_up(&(sb->s_wait));
46: sti();
47: }
48:
49: static void wait_on_super(struct super_block * sb)
50: {
51: cli();
52: while (sb->s_lock)
53: sleep_on(&(sb->s_wait));
54: sti();
55: }
56:
57: struct super_block * get_super(int dev)
58: {
59: struct super_block * s;
60:
61: if (!dev)
62: return NULL;
63: s = 0+super_block;
64: while (s < NR_SUPER+super_block)
65: if (s->s_dev == dev) {
66: wait_on_super(s);
67: if (s->s_dev == dev)
68: return s;
69: s = 0+super_block;
70: } else
71: s++;
72: return NULL;
73: }
74:
75: void put_super(int dev)
76: {
77: struct super_block * sb;
78: int i;
79:
80: if (dev == ROOT_DEV) {
81: printk("root diskette changed: prepare for armageddon\n\r");
82: return;
83: }
84: if (!(sb = get_super(dev)))
85: return;
1.1.1.5 ! root 86: if (sb->s_covered) {
1.1.1.2 root 87: printk("Mounted disk changed - tssk, tssk\n\r");
88: return;
89: }
90: lock_super(sb);
91: sb->s_dev = 0;
1.1.1.5 ! root 92: for(i=0;i<MINIX_I_MAP_SLOTS;i++)
1.1.1.2 root 93: brelse(sb->s_imap[i]);
1.1.1.5 ! root 94: for(i=0;i<MINIX_Z_MAP_SLOTS;i++)
1.1.1.2 root 95: brelse(sb->s_zmap[i]);
96: free_super(sb);
97: return;
98: }
99:
100: static struct super_block * read_super(int dev)
101: {
102: struct super_block * s;
1.1 root 103: struct buffer_head * bh;
104: int i,block;
105:
1.1.1.2 root 106: if (!dev)
1.1 root 107: return NULL;
1.1.1.2 root 108: check_disk_change(dev);
109: if (s = get_super(dev))
110: return s;
111: for (s = 0+super_block ;; s++) {
112: if (s >= NR_SUPER+super_block)
113: return NULL;
114: if (!s->s_dev)
115: break;
116: }
117: s->s_dev = dev;
1.1.1.5 ! root 118: s->s_mounted = NULL;
! 119: s->s_covered = NULL;
1.1.1.2 root 120: s->s_time = 0;
121: s->s_rd_only = 0;
122: s->s_dirt = 0;
123: lock_super(s);
124: if (!(bh = bread(dev,1))) {
125: s->s_dev=0;
126: free_super(s);
1.1 root 127: return NULL;
1.1.1.2 root 128: }
1.1.1.5 ! root 129: *((struct minix_super_block *) s) =
! 130: *((struct minix_super_block *) bh->b_data);
1.1 root 131: brelse(bh);
1.1.1.5 ! root 132: if (s->s_magic != MINIX_SUPER_MAGIC) {
1.1.1.2 root 133: s->s_dev = 0;
134: free_super(s);
1.1 root 135: return NULL;
136: }
1.1.1.5 ! root 137: for (i=0;i < MINIX_I_MAP_SLOTS;i++)
1.1.1.2 root 138: s->s_imap[i] = NULL;
1.1.1.5 ! root 139: for (i=0;i < MINIX_Z_MAP_SLOTS;i++)
1.1.1.2 root 140: s->s_zmap[i] = NULL;
1.1 root 141: block=2;
1.1.1.2 root 142: for (i=0 ; i < s->s_imap_blocks ; i++)
143: if (s->s_imap[i]=bread(dev,block))
1.1 root 144: block++;
145: else
146: break;
1.1.1.2 root 147: for (i=0 ; i < s->s_zmap_blocks ; i++)
148: if (s->s_zmap[i]=bread(dev,block))
1.1 root 149: block++;
150: else
151: break;
1.1.1.2 root 152: if (block != 2+s->s_imap_blocks+s->s_zmap_blocks) {
1.1.1.5 ! root 153: for(i=0;i<MINIX_I_MAP_SLOTS;i++)
1.1.1.2 root 154: brelse(s->s_imap[i]);
1.1.1.5 ! root 155: for(i=0;i<MINIX_Z_MAP_SLOTS;i++)
1.1.1.2 root 156: brelse(s->s_zmap[i]);
157: s->s_dev=0;
158: free_super(s);
1.1 root 159: return NULL;
160: }
1.1.1.2 root 161: s->s_imap[0]->b_data[0] |= 1;
162: s->s_zmap[0]->b_data[0] |= 1;
163: free_super(s);
164: return s;
165: }
166:
167: int sys_umount(char * dev_name)
168: {
1.1.1.5 ! root 169: struct inode * inode;
1.1.1.2 root 170: struct super_block * sb;
171: int dev;
172:
173: if (!(inode=namei(dev_name)))
174: return -ENOENT;
1.1.1.5 ! root 175: dev = inode->i_rdev;
1.1.1.2 root 176: if (!S_ISBLK(inode->i_mode)) {
177: iput(inode);
178: return -ENOTBLK;
179: }
180: iput(inode);
181: if (dev==ROOT_DEV)
182: return -EBUSY;
1.1.1.5 ! root 183: if (!(sb=get_super(dev)) || !(sb->s_covered))
1.1.1.2 root 184: return -ENOENT;
1.1.1.5 ! root 185: if (!sb->s_covered->i_mount)
1.1.1.2 root 186: printk("Mounted inode has i_mount=0\n");
1.1.1.3 root 187: for (inode=inode_table+0 ; inode<inode_table+NR_INODE ; inode++)
1.1.1.2 root 188: if (inode->i_dev==dev && inode->i_count)
1.1.1.5 ! root 189: if (inode == sb->s_mounted && inode->i_count == 1)
! 190: continue;
! 191: else
1.1.1.3 root 192: return -EBUSY;
1.1.1.5 ! root 193: sb->s_covered->i_mount=0;
! 194: iput(sb->s_covered);
! 195: sb->s_covered = NULL;
! 196: iput(sb->s_mounted);
! 197: sb->s_mounted = NULL;
1.1.1.2 root 198: put_super(dev);
199: sync_dev(dev);
200: return 0;
201: }
202:
203: int sys_mount(char * dev_name, char * dir_name, int rw_flag)
204: {
1.1.1.5 ! root 205: struct inode * dev_i, * dir_i;
1.1.1.2 root 206: struct super_block * sb;
207: int dev;
208:
209: if (!(dev_i=namei(dev_name)))
210: return -ENOENT;
1.1.1.5 ! root 211: dev = dev_i->i_rdev;
1.1.1.2 root 212: if (!S_ISBLK(dev_i->i_mode)) {
213: iput(dev_i);
214: return -EPERM;
215: }
216: iput(dev_i);
217: if (!(dir_i=namei(dir_name)))
218: return -ENOENT;
1.1.1.5 ! root 219: if (dir_i->i_count != 1 || dir_i->i_ino == MINIX_ROOT_INO) {
1.1.1.2 root 220: iput(dir_i);
221: return -EBUSY;
222: }
223: if (!S_ISDIR(dir_i->i_mode)) {
224: iput(dir_i);
225: return -EPERM;
226: }
227: if (!(sb=read_super(dev))) {
228: iput(dir_i);
229: return -EBUSY;
230: }
1.1.1.5 ! root 231: if (sb->s_covered) {
1.1.1.2 root 232: iput(dir_i);
233: return -EBUSY;
234: }
235: if (dir_i->i_mount) {
236: iput(dir_i);
237: return -EPERM;
238: }
1.1.1.5 ! root 239: if (!(sb->s_mounted = iget(dev,MINIX_ROOT_INO))) {
! 240: iput(dir_i);
! 241: return -EPERM;
! 242: }
! 243: sb->s_covered=dir_i;
1.1.1.2 root 244: dir_i->i_mount=1;
245: dir_i->i_dirt=1; /* NOTE! we don't iput(dir_i) */
246: return 0; /* we do that in umount */
1.1 root 247: }
248:
249: void mount_root(void)
250: {
251: int i,free;
252: struct super_block * p;
1.1.1.5 ! root 253: struct inode * mi;
1.1 root 254:
1.1.1.5 ! root 255: if (32 != sizeof (struct minix_inode))
1.1 root 256: panic("bad i-node size");
257: for(i=0;i<NR_FILE;i++)
258: file_table[i].f_count=0;
1.1.1.2 root 259: if (MAJOR(ROOT_DEV) == 2) {
260: printk("Insert root floppy and press ENTER");
261: wait_for_keypress();
262: }
263: for(p = &super_block[0] ; p < &super_block[NR_SUPER] ; p++) {
1.1 root 264: p->s_dev = 0;
1.1.1.2 root 265: p->s_lock = 0;
266: p->s_wait = NULL;
267: }
268: if (!(p=read_super(ROOT_DEV)))
1.1 root 269: panic("Unable to mount root");
1.1.1.5 ! root 270: if (!(mi=iget(ROOT_DEV,MINIX_ROOT_INO)))
1.1 root 271: panic("Unable to read root i-node");
272: mi->i_count += 3 ; /* NOTE! it is logically used 4 times, not 1 */
1.1.1.5 ! root 273: p->s_mounted = p->s_covered = mi;
1.1 root 274: current->pwd = mi;
275: current->root = mi;
276: free=0;
277: i=p->s_nzones;
278: while (-- i >= 0)
279: if (!set_bit(i&8191,p->s_zmap[i>>13]->b_data))
280: free++;
281: printk("%d/%d free blocks\n\r",free,p->s_nzones);
282: free=0;
283: i=p->s_ninodes+1;
284: while (-- i >= 0)
285: if (!set_bit(i&8191,p->s_imap[i>>13]->b_data))
286: free++;
287: printk("%d/%d free inodes\n\r",free,p->s_ninodes);
288: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.