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

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

unix.superglobalmegacorp.com

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