Annotation of linux/fs/minix/bitmap.c, revision 1.1.1.3

1.1       root        1: /*
1.1.1.3 ! root        2:  *  linux/fs/minix/bitmap.c
1.1       root        3:  *
                      4:  *  (C) 1991  Linus Torvalds
                      5:  */
                      6: 
                      7: /* bitmap.c contains the code that handles the inode and block bitmaps */
1.1.1.2   root        8: #include <linux/string.h>
1.1       root        9: 
                     10: #include <linux/sched.h>
                     11: #include <linux/minix_fs.h>
                     12: #include <linux/kernel.h>
                     13: 
                     14: #define clear_block(addr) \
                     15: __asm__("cld\n\t" \
                     16:        "rep\n\t" \
                     17:        "stosl" \
                     18:        ::"a" (0),"c" (BLOCK_SIZE/4),"D" ((long) (addr)):"cx","di")
                     19: 
                     20: #define set_bit(nr,addr) ({\
                     21: char res; \
                     22: __asm__ __volatile__("btsl %1,%2\n\tsetb %0": \
                     23: "=q" (res):"r" (nr),"m" (*(addr))); \
                     24: res;})
                     25: 
                     26: #define clear_bit(nr,addr) ({\
                     27: char res; \
                     28: __asm__ __volatile__("btrl %1,%2\n\tsetnb %0": \
                     29: "=q" (res):"r" (nr),"m" (*(addr))); \
                     30: res;})
                     31: 
                     32: #define find_first_zero(addr) ({ \
                     33: int __res; \
                     34: __asm__("cld\n" \
                     35:        "1:\tlodsl\n\t" \
                     36:        "notl %%eax\n\t" \
                     37:        "bsfl %%eax,%%edx\n\t" \
                     38:        "jne 2f\n\t" \
                     39:        "addl $32,%%ecx\n\t" \
                     40:        "cmpl $8192,%%ecx\n\t" \
                     41:        "jl 1b\n\t" \
                     42:        "xorl %%edx,%%edx\n" \
                     43:        "2:\taddl %%edx,%%ecx" \
                     44:        :"=c" (__res):"0" (0),"S" (addr):"ax","dx","si"); \
                     45: __res;})
                     46: 
1.1.1.3 ! root       47: static int nibblemap[] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 };
        !            48: 
        !            49: static unsigned long count_used(struct buffer_head *map[], unsigned numblocks,
        !            50:        unsigned numbits)
        !            51: {
        !            52:        unsigned i, j, end, sum = 0;
        !            53:        struct buffer_head *bh;
        !            54:   
        !            55:        for (i=0; (i<numblocks) && numbits; i++) {
        !            56:                if (!(bh=map[i])) 
        !            57:                        return(0);
        !            58:                if (numbits >= (8*BLOCK_SIZE)) { 
        !            59:                        end = BLOCK_SIZE;
        !            60:                        numbits -= 8*BLOCK_SIZE;
        !            61:                } else {
        !            62:                        int tmp;
        !            63:                        end = numbits >> 3;
        !            64:                        numbits &= 0x7;
        !            65:                        tmp = bh->b_data[end] & ((1<<numbits)-1);
        !            66:                        sum += nibblemap[tmp&0xf] + nibblemap[(tmp>>4)&0xf];
        !            67:                        numbits = 0;
        !            68:                }  
        !            69:                for (j=0; j<end; j++)
        !            70:                        sum += nibblemap[bh->b_data[j] & 0xf] 
        !            71:                                + nibblemap[(bh->b_data[j]>>4)&0xf];
        !            72:        }
        !            73:        return(sum);
        !            74: }
        !            75: 
1.1       root       76: int minix_free_block(int dev, int block)
                     77: {
                     78:        struct super_block * sb;
                     79:        struct buffer_head * bh;
                     80:        unsigned int bit,zone;
                     81: 
                     82:        if (!(sb = get_super(dev)))
                     83:                panic("trying to free block on nonexistent device");
                     84:        if (block < sb->s_firstdatazone || block >= sb->s_nzones)
                     85:                panic("trying to free block not in datazone");
                     86:        bh = get_hash_table(dev,block);
                     87:        if (bh) {
                     88:                if (bh->b_count > 1) {
                     89:                        brelse(bh);
                     90:                        return 0;
                     91:                }
                     92:                bh->b_dirt=0;
                     93:                bh->b_uptodate=0;
                     94:                if (bh->b_count)
                     95:                        brelse(bh);
                     96:        }
                     97:        zone = block - sb->s_firstdatazone + 1;
                     98:        bit = zone & 8191;
                     99:        zone >>= 13;
                    100:        bh = sb->s_zmap[zone];
                    101:        if (clear_bit(bit,bh->b_data))
                    102:                printk("free_block (%04x:%d): bit already cleared\n",dev,block);
                    103:        bh->b_dirt = 1;
                    104:        return 1;
                    105: }
                    106: 
                    107: int minix_new_block(int dev)
                    108: {
                    109:        struct buffer_head * bh;
                    110:        struct super_block * sb;
                    111:        int i,j;
                    112: 
                    113:        if (!(sb = get_super(dev)))
                    114:                panic("trying to get new block from nonexistant device");
                    115:        j = 8192;
                    116:        for (i=0 ; i<8 ; i++)
                    117:                if (bh=sb->s_zmap[i])
                    118:                        if ((j=find_first_zero(bh->b_data))<8192)
                    119:                                break;
                    120:        if (i>=8 || !bh || j>=8192)
                    121:                return 0;
                    122:        if (set_bit(j,bh->b_data))
                    123:                panic("new_block: bit already set");
                    124:        bh->b_dirt = 1;
                    125:        j += i*8192 + sb->s_firstdatazone-1;
                    126:        if (j >= sb->s_nzones)
                    127:                return 0;
                    128:        if (!(bh=getblk(dev,j)))
                    129:                panic("new_block: cannot get block");
                    130:        if (bh->b_count != 1)
                    131:                panic("new block: count is != 1");
                    132:        clear_block(bh->b_data);
                    133:        bh->b_uptodate = 1;
                    134:        bh->b_dirt = 1;
                    135:        brelse(bh);
                    136:        return j;
                    137: }
                    138: 
1.1.1.3 ! root      139: unsigned long minix_count_free_blocks(struct super_block *sb)
        !           140: {
        !           141:        return (sb->s_nzones - count_used(sb->s_zmap,sb->s_zmap_blocks,sb->s_nzones))
        !           142:                 << sb->s_log_zone_size;
        !           143: }
        !           144: 
1.1       root      145: void minix_free_inode(struct inode * inode)
                    146: {
                    147:        struct buffer_head * bh;
                    148: 
                    149:        if (!inode)
                    150:                return;
                    151:        if (!inode->i_dev) {
                    152:                memset(inode,0,sizeof(*inode));
                    153:                return;
                    154:        }
                    155:        if (inode->i_count>1) {
                    156:                printk("free_inode: inode has count=%d\n",inode->i_count);
                    157:                return;
                    158:        }
                    159:        if (inode->i_nlink) {
                    160:                printk("free_inode: inode has nlink=%d\n",inode->i_nlink);
                    161:                return;
                    162:        }
                    163:        if (!inode->i_sb) {
                    164:                printk("free_inode: inode on nonexistent device\n");
                    165:                return;
                    166:        }
                    167:        if (inode->i_ino < 1 || inode->i_ino > inode->i_sb->s_ninodes) {
                    168:                printk("free_inode: inode 0 or nonexistent inode\n");
                    169:                return;
                    170:        }
                    171:        if (!(bh=inode->i_sb->s_imap[inode->i_ino>>13])) {
                    172:                printk("free_inode: nonexistent imap in superblock\n");
                    173:                return;
                    174:        }
                    175:        if (clear_bit(inode->i_ino&8191,bh->b_data))
                    176:                printk("free_inode: bit already cleared.\n\r");
                    177:        bh->b_dirt = 1;
                    178:        memset(inode,0,sizeof(*inode));
                    179: }
                    180: 
                    181: struct inode * minix_new_inode(int dev)
                    182: {
                    183:        struct inode * inode;
                    184:        struct buffer_head * bh;
                    185:        int i,j;
                    186: 
                    187:        if (!(inode=get_empty_inode()))
                    188:                return NULL;
                    189:        if (!(inode->i_sb = get_super(dev))) {
                    190:                printk("new_inode: unknown device\n");
                    191:                iput(inode);
                    192:                return NULL;
                    193:        }
                    194:        j = 8192;
                    195:        for (i=0 ; i<8 ; i++)
                    196:                if (bh=inode->i_sb->s_imap[i])
                    197:                        if ((j=find_first_zero(bh->b_data))<8192)
                    198:                                break;
                    199:        if (!bh || j >= 8192 || j+i*8192 > inode->i_sb->s_ninodes) {
                    200:                iput(inode);
                    201:                return NULL;
                    202:        }
                    203:        if (set_bit(j,bh->b_data)) {    /* shouldn't happen */
                    204:                printk("new_inode: bit already set");
                    205:                iput(inode);
                    206:                return NULL;
                    207:        }
                    208:        bh->b_dirt = 1;
                    209:        inode->i_count = 1;
                    210:        inode->i_nlink = 1;
                    211:        inode->i_dev = dev;
                    212:        inode->i_uid = current->euid;
                    213:        inode->i_gid = current->egid;
                    214:        inode->i_dirt = 1;
                    215:        inode->i_ino = j + i*8192;
                    216:        inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
1.1.1.2   root      217:        inode->i_op = NULL;
1.1       root      218:        return inode;
                    219: }
1.1.1.3 ! root      220: 
        !           221: unsigned long minix_count_free_inodes(struct super_block *sb)
        !           222: {
        !           223:        return sb->s_ninodes - count_used(sb->s_imap,sb->s_imap_blocks,sb->s_ninodes);
        !           224: }

unix.superglobalmegacorp.com

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