--- linux/fs/minix/bitmap.c 2018/04/24 18:03:52 1.1.1.1 +++ linux/fs/minix/bitmap.c 2018/04/24 18:14:31 1.1.1.6 @@ -1,15 +1,15 @@ /* - * linux/fs/bitmap.c + * linux/fs/minix/bitmap.c * - * (C) 1991 Linus Torvalds + * Copyright (C) 1991, 1992 Linus Torvalds */ /* bitmap.c contains the code that handles the inode and block bitmaps */ -#include #include #include #include +#include #define clear_block(addr) \ __asm__("cld\n\t" \ @@ -44,35 +44,66 @@ __asm__("cld\n" \ :"=c" (__res):"0" (0),"S" (addr):"ax","dx","si"); \ __res;}) -int minix_free_block(int dev, int block) +static int nibblemap[] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 }; + +static unsigned long count_used(struct buffer_head *map[], unsigned numblocks, + unsigned numbits) +{ + unsigned i, j, end, sum = 0; + struct buffer_head *bh; + + for (i=0; (i= (8*BLOCK_SIZE)) { + end = BLOCK_SIZE; + numbits -= 8*BLOCK_SIZE; + } else { + int tmp; + end = numbits >> 3; + numbits &= 0x7; + tmp = bh->b_data[end] & ((1<>4)&0xf]; + numbits = 0; + } + for (j=0; jb_data[j] & 0xf] + + nibblemap[(bh->b_data[j]>>4)&0xf]; + } + return(sum); +} + +void minix_free_block(int dev, int block) { struct super_block * sb; struct buffer_head * bh; unsigned int bit,zone; - if (!(sb = get_super(dev))) - panic("trying to free block on nonexistent device"); - if (block < sb->s_firstdatazone || block >= sb->s_nzones) - panic("trying to free block not in datazone"); - bh = get_hash_table(dev,block); - if (bh) { - if (bh->b_count > 1) { - brelse(bh); - return 0; - } - bh->b_dirt=0; - bh->b_uptodate=0; - if (bh->b_count) - brelse(bh); + if (!(sb = get_super(dev))) { + printk("trying to free block on nonexistent device\n"); + return; } - zone = block - sb->s_firstdatazone + 1; + if (block < sb->u.minix_sb.s_firstdatazone || + block >= sb->u.minix_sb.s_nzones) { + printk("trying to free block not in datazone\n"); + return; + } + bh = get_hash_table(dev,block,BLOCK_SIZE); + if (bh) + bh->b_dirt=0; + brelse(bh); + zone = block - sb->u.minix_sb.s_firstdatazone + 1; bit = zone & 8191; zone >>= 13; - bh = sb->s_zmap[zone]; + bh = sb->u.minix_sb.s_zmap[zone]; + if (!bh) { + printk("minix_free_block: nonexistent bitmap buffer\n"); + return; + } if (clear_bit(bit,bh->b_data)) printk("free_block (%04x:%d): bit already cleared\n",dev,block); bh->b_dirt = 1; - return 1; + return; } int minix_new_block(int dev) @@ -81,25 +112,34 @@ int minix_new_block(int dev) struct super_block * sb; int i,j; - if (!(sb = get_super(dev))) - panic("trying to get new block from nonexistant device"); + if (!(sb = get_super(dev))) { + printk("trying to get new block from nonexistant device\n"); + return 0; + } +repeat: j = 8192; for (i=0 ; i<8 ; i++) - if (bh=sb->s_zmap[i]) + if (bh=sb->u.minix_sb.s_zmap[i]) if ((j=find_first_zero(bh->b_data))<8192) break; if (i>=8 || !bh || j>=8192) return 0; - if (set_bit(j,bh->b_data)) - panic("new_block: bit already set"); + if (set_bit(j,bh->b_data)) { + printk("new_block: bit already set"); + goto repeat; + } bh->b_dirt = 1; - j += i*8192 + sb->s_firstdatazone-1; - if (j >= sb->s_nzones) + j += i*8192 + sb->u.minix_sb.s_firstdatazone-1; + if (j >= sb->u.minix_sb.s_nzones) + return 0; + if (!(bh=getblk(dev,j,BLOCK_SIZE))) { + printk("new_block: cannot get block"); return 0; - if (!(bh=getblk(dev,j))) - panic("new_block: cannot get block"); - if (bh->b_count != 1) - panic("new block: count is != 1"); + } + if (bh->b_count != 1) { + printk("new block: count is != 1"); + return 0; + } clear_block(bh->b_data); bh->b_uptodate = 1; bh->b_dirt = 1; @@ -107,6 +147,12 @@ int minix_new_block(int dev) return j; } +unsigned long minix_count_free_blocks(struct super_block *sb) +{ + 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)) + << sb->u.minix_sb.s_log_zone_size; +} + void minix_free_inode(struct inode * inode) { struct buffer_head * bh; @@ -129,11 +175,11 @@ void minix_free_inode(struct inode * ino printk("free_inode: inode on nonexistent device\n"); return; } - if (inode->i_ino < 1 || inode->i_ino > inode->i_sb->s_ninodes) { + if (inode->i_ino < 1 || inode->i_ino > inode->i_sb->u.minix_sb.s_ninodes) { printk("free_inode: inode 0 or nonexistent inode\n"); return; } - if (!(bh=inode->i_sb->s_imap[inode->i_ino>>13])) { + if (!(bh=inode->i_sb->u.minix_sb.s_imap[inode->i_ino>>13])) { printk("free_inode: nonexistent imap in superblock\n"); return; } @@ -156,12 +202,13 @@ struct inode * minix_new_inode(int dev) iput(inode); return NULL; } + inode->i_flags = inode->i_sb->s_flags; j = 8192; for (i=0 ; i<8 ; i++) - if (bh=inode->i_sb->s_imap[i]) + if (bh=inode->i_sb->u.minix_sb.s_imap[i]) if ((j=find_first_zero(bh->b_data))<8192) break; - if (!bh || j >= 8192 || j+i*8192 > inode->i_sb->s_ninodes) { + if (!bh || j >= 8192 || j+i*8192 > inode->i_sb->u.minix_sb.s_ninodes) { iput(inode); return NULL; } @@ -179,6 +226,12 @@ struct inode * minix_new_inode(int dev) inode->i_dirt = 1; inode->i_ino = j + i*8192; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; - inode->i_op = &minix_inode_operations; + inode->i_op = NULL; + inode->i_blocks = inode->i_blksize = 0; return inode; } + +unsigned long minix_count_free_inodes(struct super_block *sb) +{ + 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); +}