Annotation of linux/fs/ext/bitmap.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

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