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