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

1.1       root        1: /*
1.1.1.3   root        2:  *  linux/fs/minix/bitmap.c
1.1       root        3:  *
1.1.1.5   root        4:  *  Copyright (C) 1991, 1992  Linus Torvalds
1.1       root        5:  */
                      6: 
                      7: /* bitmap.c contains the code that handles the inode and block bitmaps */
                      8: 
                      9: #include <linux/sched.h>
                     10: #include <linux/minix_fs.h>
                     11: #include <linux/kernel.h>
1.1.1.5   root       12: #include <linux/string.h>
1.1       root       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.1.6 ! root       76: void minix_free_block(int dev, int block)
1.1       root       77: {
                     78:        struct super_block * sb;
                     79:        struct buffer_head * bh;
                     80:        unsigned int bit,zone;
                     81: 
1.1.1.6 ! root       82:        if (!(sb = get_super(dev))) {
        !            83:                printk("trying to free block on nonexistent device\n");
        !            84:                return;
        !            85:        }
        !            86:        if (block < sb->u.minix_sb.s_firstdatazone ||
        !            87:            block >= sb->u.minix_sb.s_nzones) {
        !            88:                printk("trying to free block not in datazone\n");
        !            89:                return;
        !            90:        }
1.1.1.5   root       91:        bh = get_hash_table(dev,block,BLOCK_SIZE);
1.1.1.6 ! root       92:        if (bh)
1.1       root       93:                bh->b_dirt=0;
1.1.1.6 ! root       94:        brelse(bh);
1.1.1.5   root       95:        zone = block - sb->u.minix_sb.s_firstdatazone + 1;
1.1       root       96:        bit = zone & 8191;
                     97:        zone >>= 13;
1.1.1.5   root       98:        bh = sb->u.minix_sb.s_zmap[zone];
1.1.1.6 ! root       99:        if (!bh) {
        !           100:                printk("minix_free_block: nonexistent bitmap buffer\n");
        !           101:                return;
        !           102:        }
1.1       root      103:        if (clear_bit(bit,bh->b_data))
                    104:                printk("free_block (%04x:%d): bit already cleared\n",dev,block);
                    105:        bh->b_dirt = 1;
1.1.1.6 ! root      106:        return;
1.1       root      107: }
                    108: 
                    109: int minix_new_block(int dev)
                    110: {
                    111:        struct buffer_head * bh;
                    112:        struct super_block * sb;
                    113:        int i,j;
                    114: 
1.1.1.6 ! root      115:        if (!(sb = get_super(dev))) {
        !           116:                printk("trying to get new block from nonexistant device\n");
        !           117:                return 0;
        !           118:        }
        !           119: repeat:
1.1       root      120:        j = 8192;
                    121:        for (i=0 ; i<8 ; i++)
1.1.1.5   root      122:                if (bh=sb->u.minix_sb.s_zmap[i])
1.1       root      123:                        if ((j=find_first_zero(bh->b_data))<8192)
                    124:                                break;
                    125:        if (i>=8 || !bh || j>=8192)
                    126:                return 0;
1.1.1.6 ! root      127:        if (set_bit(j,bh->b_data)) {
        !           128:                printk("new_block: bit already set");
        !           129:                goto repeat;
        !           130:        }
1.1       root      131:        bh->b_dirt = 1;
1.1.1.5   root      132:        j += i*8192 + sb->u.minix_sb.s_firstdatazone-1;
                    133:        if (j >= sb->u.minix_sb.s_nzones)
1.1       root      134:                return 0;
1.1.1.6 ! root      135:        if (!(bh=getblk(dev,j,BLOCK_SIZE))) {
        !           136:                printk("new_block: cannot get block");
        !           137:                return 0;
        !           138:        }
        !           139:        if (bh->b_count != 1) {
        !           140:                printk("new block: count is != 1");
        !           141:                return 0;
        !           142:        }
1.1       root      143:        clear_block(bh->b_data);
                    144:        bh->b_uptodate = 1;
                    145:        bh->b_dirt = 1;
                    146:        brelse(bh);
                    147:        return j;
                    148: }
                    149: 
1.1.1.3   root      150: unsigned long minix_count_free_blocks(struct super_block *sb)
                    151: {
1.1.1.5   root      152:        return (sb->u.minix_sb.s_nzones - count_used(sb->u.minix_sb.s_zmap,sb->u.minix_sb.s_zmap_blocks,sb->u.minix_sb.s_nzones))
                    153:                 << sb->u.minix_sb.s_log_zone_size;
1.1.1.3   root      154: }
                    155: 
1.1       root      156: void minix_free_inode(struct inode * inode)
                    157: {
                    158:        struct buffer_head * bh;
                    159: 
                    160:        if (!inode)
                    161:                return;
                    162:        if (!inode->i_dev) {
                    163:                memset(inode,0,sizeof(*inode));
                    164:                return;
                    165:        }
                    166:        if (inode->i_count>1) {
                    167:                printk("free_inode: inode has count=%d\n",inode->i_count);
                    168:                return;
                    169:        }
                    170:        if (inode->i_nlink) {
                    171:                printk("free_inode: inode has nlink=%d\n",inode->i_nlink);
                    172:                return;
                    173:        }
                    174:        if (!inode->i_sb) {
                    175:                printk("free_inode: inode on nonexistent device\n");
                    176:                return;
                    177:        }
1.1.1.5   root      178:        if (inode->i_ino < 1 || inode->i_ino > inode->i_sb->u.minix_sb.s_ninodes) {
1.1       root      179:                printk("free_inode: inode 0 or nonexistent inode\n");
                    180:                return;
                    181:        }
1.1.1.5   root      182:        if (!(bh=inode->i_sb->u.minix_sb.s_imap[inode->i_ino>>13])) {
1.1       root      183:                printk("free_inode: nonexistent imap in superblock\n");
                    184:                return;
                    185:        }
                    186:        if (clear_bit(inode->i_ino&8191,bh->b_data))
                    187:                printk("free_inode: bit already cleared.\n\r");
                    188:        bh->b_dirt = 1;
                    189:        memset(inode,0,sizeof(*inode));
                    190: }
                    191: 
                    192: struct inode * minix_new_inode(int dev)
                    193: {
                    194:        struct inode * inode;
                    195:        struct buffer_head * bh;
                    196:        int i,j;
                    197: 
                    198:        if (!(inode=get_empty_inode()))
                    199:                return NULL;
                    200:        if (!(inode->i_sb = get_super(dev))) {
                    201:                printk("new_inode: unknown device\n");
                    202:                iput(inode);
                    203:                return NULL;
                    204:        }
1.1.1.5   root      205:        inode->i_flags = inode->i_sb->s_flags;
1.1       root      206:        j = 8192;
                    207:        for (i=0 ; i<8 ; i++)
1.1.1.5   root      208:                if (bh=inode->i_sb->u.minix_sb.s_imap[i])
1.1       root      209:                        if ((j=find_first_zero(bh->b_data))<8192)
                    210:                                break;
1.1.1.5   root      211:        if (!bh || j >= 8192 || j+i*8192 > inode->i_sb->u.minix_sb.s_ninodes) {
1.1       root      212:                iput(inode);
                    213:                return NULL;
                    214:        }
                    215:        if (set_bit(j,bh->b_data)) {    /* shouldn't happen */
                    216:                printk("new_inode: bit already set");
                    217:                iput(inode);
                    218:                return NULL;
                    219:        }
                    220:        bh->b_dirt = 1;
                    221:        inode->i_count = 1;
                    222:        inode->i_nlink = 1;
                    223:        inode->i_dev = dev;
                    224:        inode->i_uid = current->euid;
                    225:        inode->i_gid = current->egid;
                    226:        inode->i_dirt = 1;
                    227:        inode->i_ino = j + i*8192;
                    228:        inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
1.1.1.2   root      229:        inode->i_op = NULL;
1.1.1.6 ! root      230:        inode->i_blocks = inode->i_blksize = 0;
1.1       root      231:        return inode;
                    232: }
1.1.1.3   root      233: 
                    234: unsigned long minix_count_free_inodes(struct super_block *sb)
                    235: {
1.1.1.5   root      236:        return sb->u.minix_sb.s_ninodes - count_used(sb->u.minix_sb.s_imap,sb->u.minix_sb.s_imap_blocks,sb->u.minix_sb.s_ninodes);
1.1.1.3   root      237: }

unix.superglobalmegacorp.com

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