|
|
1.1 root 1: /*
1.1.1.2 root 2: * linux/fs/super.c
3: *
1.1.1.10 root 4: * Copyright (C) 1991, 1992 Linus Torvalds
1.1.1.2 root 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.11! root 13: #include <linux/proc_fs.h>
1.1.1.9 root 14: #include <linux/ext_fs.h>
1.1.1.10 root 15: #include <linux/msdos_fs.h>
1.1 root 16: #include <linux/kernel.h>
1.1.1.8 root 17: #include <linux/stat.h>
1.1.1.10 root 18: #include <linux/errno.h>
19:
1.1.1.2 root 20: #include <asm/system.h>
1.1.1.7 root 21: #include <asm/segment.h>
1.1.1.2 root 22:
23: int sync_dev(int dev);
24: void wait_for_keypress(void);
1.1.1.11! root 25: void fcntl_init_locks(void);
1.1 root 26:
27: /* set_bit uses setb, as gas doesn't recognize setc */
28: #define set_bit(bitnr,addr) ({ \
29: register int __res __asm__("ax"); \
30: __asm__("bt %2,%3;setb %%al":"=a" (__res):"a" (0),"r" (bitnr),"m" (*(addr))); \
31: __res; })
32:
33: struct super_block super_block[NR_SUPER];
1.1.1.2 root 34: /* this is initialized in init/main.c */
35: int ROOT_DEV = 0;
1.1 root 36:
1.1.1.6 root 37: /* Move into include file later */
38:
39: static struct file_system_type file_systems[] = {
40: {minix_read_super,"minix"},
1.1.1.9 root 41: {ext_read_super,"ext"},
1.1.1.10 root 42: {msdos_read_super,"msdos"},
1.1.1.11! root 43: {proc_read_super,"proc"},
1.1.1.6 root 44: {NULL,NULL}
45: };
46:
47: /* end of include file */
48:
49: struct file_system_type *get_fs_type(char *name)
50: {
51: int a;
52:
53: for(a = 0 ; file_systems[a].read_super ; a++)
54: if (!strcmp(name,file_systems[a].name))
55: return(&file_systems[a]);
56: return(NULL);
57: }
58:
59: void lock_super(struct super_block * sb)
1.1 root 60: {
1.1.1.2 root 61: cli();
62: while (sb->s_lock)
63: sleep_on(&(sb->s_wait));
64: sb->s_lock = 1;
65: sti();
66: }
67:
1.1.1.6 root 68: void free_super(struct super_block * sb)
1.1.1.2 root 69: {
70: sb->s_lock = 0;
71: wake_up(&(sb->s_wait));
72: }
73:
1.1.1.6 root 74: void wait_on_super(struct super_block * sb)
1.1.1.2 root 75: {
76: cli();
77: while (sb->s_lock)
78: sleep_on(&(sb->s_wait));
79: sti();
80: }
81:
82: struct super_block * get_super(int dev)
83: {
84: struct super_block * s;
85:
86: if (!dev)
87: return NULL;
88: s = 0+super_block;
89: while (s < NR_SUPER+super_block)
90: if (s->s_dev == dev) {
91: wait_on_super(s);
92: if (s->s_dev == dev)
93: return s;
94: s = 0+super_block;
95: } else
96: s++;
97: return NULL;
98: }
99:
100: void put_super(int dev)
101: {
102: struct super_block * sb;
103:
104: if (dev == ROOT_DEV) {
105: printk("root diskette changed: prepare for armageddon\n\r");
106: return;
107: }
108: if (!(sb = get_super(dev)))
109: return;
1.1.1.5 root 110: if (sb->s_covered) {
1.1.1.2 root 111: printk("Mounted disk changed - tssk, tssk\n\r");
112: return;
113: }
1.1.1.6 root 114: if (sb->s_op && sb->s_op->put_super)
115: sb->s_op->put_super(sb);
1.1.1.2 root 116: }
117:
1.1.1.10 root 118: static struct super_block * read_super(int dev,char *name,int flags,void *data)
1.1.1.2 root 119: {
120: struct super_block * s;
1.1.1.6 root 121: struct file_system_type *type;
1.1 root 122:
1.1.1.2 root 123: if (!dev)
1.1 root 124: return NULL;
1.1.1.2 root 125: check_disk_change(dev);
126: if (s = get_super(dev))
127: return s;
1.1.1.11! root 128: if (!(type = get_fs_type(name))) {
1.1.1.6 root 129: printk("get fs type failed %s\n",name);
130: return NULL;
131: }
1.1.1.2 root 132: for (s = 0+super_block ;; s++) {
133: if (s >= NR_SUPER+super_block)
134: return NULL;
135: if (!s->s_dev)
136: break;
137: }
138: s->s_dev = dev;
1.1.1.10 root 139: s->s_flags = flags;
1.1.1.11! root 140: if (!type->read_super(s,data)) {
! 141: s->s_dev = 0;
! 142: return NULL;
! 143: }
1.1.1.6 root 144: s->s_dev = dev;
1.1.1.5 root 145: s->s_covered = NULL;
1.1.1.2 root 146: s->s_rd_only = 0;
147: s->s_dirt = 0;
1.1.1.11! root 148: return s;
1.1.1.2 root 149: }
150:
1.1.1.10 root 151: static int do_umount(int dev)
1.1.1.2 root 152: {
153: struct super_block * sb;
1.1.1.10 root 154: struct inode * inode;
1.1.1.2 root 155:
156: if (dev==ROOT_DEV)
157: return -EBUSY;
1.1.1.5 root 158: if (!(sb=get_super(dev)) || !(sb->s_covered))
1.1.1.2 root 159: return -ENOENT;
1.1.1.5 root 160: if (!sb->s_covered->i_mount)
1.1.1.2 root 161: printk("Mounted inode has i_mount=0\n");
1.1.1.6 root 162: for (inode = inode_table+0 ; inode < inode_table+NR_INODE ; inode++)
1.1.1.2 root 163: if (inode->i_dev==dev && inode->i_count)
1.1.1.5 root 164: if (inode == sb->s_mounted && inode->i_count == 1)
165: continue;
166: else
1.1.1.3 root 167: return -EBUSY;
1.1.1.5 root 168: sb->s_covered->i_mount=0;
169: iput(sb->s_covered);
170: sb->s_covered = NULL;
171: iput(sb->s_mounted);
172: sb->s_mounted = NULL;
1.1.1.9 root 173: if (sb->s_op && sb->s_op->write_super && sb->s_dirt)
174: sb->s_op->write_super (sb);
1.1.1.6 root 175: put_super(dev);
1.1.1.2 root 176: return 0;
177: }
178:
1.1.1.10 root 179: int sys_umount(char * dev_name)
1.1.1.2 root 180: {
1.1.1.10 root 181: struct inode * inode;
182: int dev,retval;
1.1.1.2 root 183:
1.1.1.7 root 184: if (!suser())
185: return -EPERM;
1.1.1.11! root 186: retval = namei(dev_name,&inode);
! 187: if (retval)
! 188: return retval;
1.1.1.10 root 189: dev = inode->i_rdev;
190: if (!S_ISBLK(inode->i_mode)) {
191: iput(inode);
192: return -ENOTBLK;
1.1.1.2 root 193: }
1.1.1.10 root 194: retval = do_umount(dev);
195: if (!retval && MAJOR(dev) < MAX_BLKDEV &&
196: blkdev_fops[MAJOR(dev)]->release)
197: blkdev_fops[MAJOR(dev)]->release(inode,NULL);
198: iput(inode);
199: if (retval) return retval;
200: sync_dev(dev);
201: return 0;
202: }
203:
204: /*
205: * do_mount() does the actual mounting after sys_mount has done the ugly
206: * parameter parsing. When enough time has gone by, and everything uses the
207: * new mount() parameters, sys_mount() can then be cleaned up.
208: *
209: * We cannot mount a filesystem if it has active, used, or dirty inodes.
210: * We also have to flush all inode-data for this device, as the new mount
211: * might need new info.
212: */
213: static int do_mount(int dev, const char * dir, char * type, int flags, void * data)
214: {
215: struct inode * inode, * dir_i;
216: struct super_block * sb;
1.1.1.11! root 217: int error;
1.1.1.10 root 218:
1.1.1.11! root 219: error = namei(dir,&dir_i);
! 220: if (error)
! 221: return error;
1.1.1.10 root 222: if (dir_i->i_count != 1 || dir_i->i_mount) {
1.1.1.2 root 223: iput(dir_i);
224: return -EBUSY;
225: }
226: if (!S_ISDIR(dir_i->i_mode)) {
227: iput(dir_i);
228: return -EPERM;
229: }
1.1.1.10 root 230: for (inode = inode_table+0 ; inode < inode_table+NR_INODE ; inode++) {
231: if (inode->i_dev != dev)
232: continue;
233: if (inode->i_count || inode->i_dirt || inode->i_lock) {
234: iput(dir_i);
235: return -EBUSY;
236: }
237: inode->i_dev = 0;
238: }
239: sb = read_super(dev,type,flags,data);
240: if (!sb || sb->s_covered) {
1.1.1.2 root 241: iput(dir_i);
1.1.1.10 root 242: return -EBUSY;
243: }
244: sb->s_flags = flags;
245: sb->s_covered = dir_i;
246: dir_i->i_mount = 1;
247: return 0; /* we don't iput(dir_i) - see umount */
248: }
249:
250: /*
251: * Flags is a 16-bit value that allows up to 16 non-fs dependent flags to
252: * be given to the mount() call (ie: read-only, no-dev, no-suid etc).
253: *
254: * data is a (void *) that can point to any structure up to 4095 bytes, which
255: * can contain arbitrary fs-dependent information (or be NULL).
256: *
257: * NOTE! As old versions of mount() didn't use this setup, the flags has to have
258: * a special 16-bit magic number in the hight word: 0xC0ED. If this magic word
259: * isn't present, the flags and data info isn't used, as the syscall assumes we
260: * are talking to an older version that didn't understand them.
261: */
262: int sys_mount(char * dev_name, char * dir_name, char * type,
263: unsigned long new_flags, void *data)
264: {
265: struct inode * inode;
266: int dev;
1.1.1.11! root 267: int retval;
1.1.1.10 root 268: char tmp[100],*t;
269: int i;
270: unsigned long flags = 0;
271: unsigned long page = 0;
272:
273: if (!suser())
1.1.1.6 root 274: return -EPERM;
1.1.1.11! root 275: retval = namei(dev_name,&inode);
! 276: if (retval)
! 277: return retval;
1.1.1.10 root 278: dev = inode->i_rdev;
279: if (!S_ISBLK(inode->i_mode))
280: retval = -EPERM;
281: else if (IS_NODEV(inode))
282: retval = -EACCES;
283: if (!retval && blkdev_fops[MAJOR(dev)]->open)
284: retval = blkdev_fops[MAJOR(dev)]->open(inode,NULL);
285: if (retval) {
286: iput(inode);
287: return retval;
288: }
289: if ((new_flags & 0xffff0000) == 0xC0ED0000) {
290: flags = new_flags & 0xffff;
291: if (data && (unsigned long) data < TASK_SIZE)
292: page = get_free_page(GFP_KERNEL);
293: }
294: if (page) {
295: i = TASK_SIZE - (unsigned long) data;
296: if (i < 0 || i > 4095)
297: i = 4095;
298: memcpy_fromfs((void *) page,data,i);
1.1.1.2 root 299: }
1.1.1.7 root 300: if (type) {
1.1.1.10 root 301: for (i = 0 ; i < 100 ; i++)
302: if (!(tmp[i] = get_fs_byte(type++)))
303: break;
1.1.1.7 root 304: t = tmp;
305: } else
306: t = "minix";
1.1.1.10 root 307: retval = do_mount(dev,dir_name,t,flags,(void *) page);
308: free_page(page);
309: if (retval && blkdev_fops[MAJOR(dev)]->release)
310: blkdev_fops[MAJOR(dev)]->release(inode,NULL);
311: iput(inode);
312: return retval;
1.1 root 313: }
314:
315: void mount_root(void)
316: {
1.1.1.10 root 317: int i;
318: struct file_system_type * fs_type = file_systems;
1.1 root 319: struct super_block * p;
1.1.1.5 root 320: struct inode * mi;
1.1 root 321:
1.1.1.5 root 322: if (32 != sizeof (struct minix_inode))
1.1 root 323: panic("bad i-node size");
324: for(i=0;i<NR_FILE;i++)
325: file_table[i].f_count=0;
1.1.1.11! root 326: fcntl_init_locks();
1.1.1.2 root 327: if (MAJOR(ROOT_DEV) == 2) {
328: printk("Insert root floppy and press ENTER");
329: wait_for_keypress();
330: }
331: for(p = &super_block[0] ; p < &super_block[NR_SUPER] ; p++) {
1.1 root 332: p->s_dev = 0;
1.1.1.10 root 333: p->s_blocksize = 0;
1.1.1.2 root 334: p->s_lock = 0;
335: p->s_wait = NULL;
1.1.1.10 root 336: p->s_mounted = p->s_covered = NULL;
337: }
338: while (fs_type->read_super && fs_type->name) {
339: p = read_super(ROOT_DEV,fs_type->name,0,NULL);
340: if (p) {
341: mi = p->s_mounted;
342: mi->i_count += 3 ; /* NOTE! it is logically used 4 times, not 1 */
343: p->s_covered = mi;
344: p->s_flags = 0;
345: current->pwd = mi;
346: current->root = mi;
347: return;
348: }
349: fs_type++;
1.1.1.2 root 350: }
1.1.1.10 root 351: panic("Unable to mount root");
1.1 root 352: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.