patch-2.1.106 linux/fs/minix/bitmap.c

Next file: linux/fs/minix/inode.c
Previous file: linux/fs/isofs/namei.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.105/linux/fs/minix/bitmap.c linux/fs/minix/bitmap.c
@@ -36,16 +36,17 @@
 
 	if (numblocks==0 || !(bh=map[numblocks-1]))
 		return(0);
-	i = (numbits-(numblocks-1)*BLOCK_SIZE*8)/8;
+	i = ((numbits-(numblocks-1)*BLOCK_SIZE*8)/16)*2;
 	for (j=0; j<i; j++) {
 		sum += nibblemap[bh->b_data[j] & 0xf]
 			+ nibblemap[(bh->b_data[j]>>4) & 0xf];
 	}
 
-	i = numbits%8;
+	i = numbits%16;
 	if (i!=0) {
-		i = bh->b_data[j] | ~((1<<i) - 1);
+		i = *(__u16 *)(&bh->b_data[j]) | ~((1<<i) - 1);
 		sum += nibblemap[i & 0xf] + nibblemap[(i>>4) & 0xf];
+		sum += nibblemap[(i>>8) & 0xf] + nibblemap[(i>>12) & 0xf];
 	}
 	return(sum);
 }
@@ -71,11 +72,11 @@
 	zone = block - sb->u.minix_sb.s_firstdatazone + 1;
 	bit = zone & 8191;
 	zone >>= 13;
-	bh = sb->u.minix_sb.s_zmap[zone];
-	if (!bh) {
+	if (zone >= sb->u.minix_sb.s_zmap_blocks) {
 		printk("minix_free_block: nonexistent bitmap buffer\n");
 		return;
 	}
+	bh = sb->u.minix_sb.s_zmap[zone];
 	if (!minix_clear_bit(bit,bh->b_data))
 		printk("free_block (%s:%d): bit already cleared\n",
 		       kdevname(sb->s_dev), block);
@@ -94,11 +95,13 @@
 	}
 repeat:
 	j = 8192;
-	for (i=0 ; i<64 ; i++)
-		if ((bh=sb->u.minix_sb.s_zmap[i]) != NULL)
-			if ((j=minix_find_first_zero_bit(bh->b_data, 8192)) < 8192)
-				break;
-	if (i>=64 || !bh || j>=8192)
+	bh = NULL;
+	for (i = 0; i < sb->u.minix_sb.s_zmap_blocks; i++) {
+		bh = sb->u.minix_sb.s_zmap[i];
+		if ((j = minix_find_first_zero_bit(bh->b_data, 8192)) < 8192)
+			break;
+	}
+	if (!bh || j >= 8192)
 		return 0;
 	if (minix_set_bit(j,bh->b_data)) {
 		printk("new_block: bit already set");
@@ -134,7 +137,7 @@
 	int ino, block;
 
 	ino = inode->i_ino;
-	if (!ino || ino >= inode->i_sb->u.minix_sb.s_ninodes) {
+	if (!ino || ino > inode->i_sb->u.minix_sb.s_ninodes) {
 		printk("Bad inode number on dev %s: %d is out of range\n",
 		       kdevname(inode->i_dev), ino);
 		return 0;
@@ -162,7 +165,7 @@
 	int ino, block;
 
 	ino = inode->i_ino;
-	if (!ino || ino >= inode->i_sb->u.minix_sb.s_ninodes) {
+	if (!ino || ino > inode->i_sb->u.minix_sb.s_ninodes) {
 		printk("Bad inode number on dev %s: %d is out of range\n",
 		       kdevname(inode->i_dev), ino);
 		return 0;
@@ -218,15 +221,16 @@
 		printk("free_inode: inode on nonexistent device\n");
 		return;
 	}
-	if (inode->i_ino < 1 || inode->i_ino >= inode->i_sb->u.minix_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;
 	}
 	ino = inode->i_ino;
-	if (!(bh=inode->i_sb->u.minix_sb.s_imap[ino >> 13])) {
+	if ((ino >> 13) >= inode->i_sb->u.minix_sb.s_imap_blocks) {
 		printk("free_inode: nonexistent imap in superblock\n");
 		return;
 	}
+	bh = inode->i_sb->u.minix_sb.s_imap[ino >> 13];
 	minix_clear_inode(inode);
 	clear_inode(inode);
 	if (!minix_clear_bit(ino & 8191, bh->b_data))
@@ -247,10 +251,12 @@
 	inode->i_sb = sb;
 	inode->i_flags = inode->i_sb->s_flags;
 	j = 8192;
-	for (i=0 ; i<8 ; i++)
-		if ((bh = inode->i_sb->u.minix_sb.s_imap[i]) != NULL)
-			if ((j=minix_find_first_zero_bit(bh->b_data, 8192)) < 8192)
-				break;
+	bh = NULL;
+	for (i = 0; i < sb->u.minix_sb.s_imap_blocks; i++) {
+		bh = inode->i_sb->u.minix_sb.s_imap[i];
+		if ((j = minix_find_first_zero_bit(bh->b_data, 8192)) < 8192)
+			break;
+	}
 	if (!bh || j >= 8192) {
 		iput(inode);
 		return NULL;
@@ -262,7 +268,7 @@
 	}
 	mark_buffer_dirty(bh, 1);
 	j += i*8192;
-	if (!j || j >= inode->i_sb->u.minix_sb.s_ninodes) {
+	if (!j || j > inode->i_sb->u.minix_sb.s_ninodes) {
 		iput(inode);
 		return NULL;
 	}

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov