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