Annotation of linux/fs/super.c, revision 1.1.1.9

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.