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

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

unix.superglobalmegacorp.com

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