xref: /linux/fs/qnx4/bitmap.c (revision 891ddb95d06e9dc260500f02438a5cff1ba6650a)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  * QNX4 file system, Linux implementation.
31da177e4SLinus Torvalds  *
41da177e4SLinus Torvalds  * Version : 0.2.1
51da177e4SLinus Torvalds  *
61da177e4SLinus Torvalds  * Using parts of the xiafs filesystem.
71da177e4SLinus Torvalds  *
81da177e4SLinus Torvalds  * History :
91da177e4SLinus Torvalds  *
101da177e4SLinus Torvalds  * 28-05-1998 by Richard Frowijn : first release.
111da177e4SLinus Torvalds  * 20-06-1998 by Frank Denis : basic optimisations.
121da177e4SLinus Torvalds  * 25-06-1998 by Frank Denis : qnx4_is_free, qnx4_set_bitmap, qnx4_bmap .
131da177e4SLinus Torvalds  * 28-06-1998 by Frank Denis : qnx4_free_inode (to be fixed) .
141da177e4SLinus Torvalds  */
151da177e4SLinus Torvalds 
161da177e4SLinus Torvalds #include <linux/buffer_head.h>
171da177e4SLinus Torvalds #include <linux/bitops.h>
18964f5369SAl Viro #include "qnx4.h"
191da177e4SLinus Torvalds 
207a1119b1SAdrian Bunk #if 0
211da177e4SLinus Torvalds int qnx4_new_block(struct super_block *sb)
221da177e4SLinus Torvalds {
231da177e4SLinus Torvalds 	return 0;
241da177e4SLinus Torvalds }
257a1119b1SAdrian Bunk #endif  /*  0  */
261da177e4SLinus Torvalds 
271da177e4SLinus Torvalds static void count_bits(register const char *bmPart, register int size,
281da177e4SLinus Torvalds 		       int *const tf)
291da177e4SLinus Torvalds {
301da177e4SLinus Torvalds 	char b;
311da177e4SLinus Torvalds 	int tot = *tf;
321da177e4SLinus Torvalds 
331da177e4SLinus Torvalds 	if (size > QNX4_BLOCK_SIZE) {
341da177e4SLinus Torvalds 		size = QNX4_BLOCK_SIZE;
351da177e4SLinus Torvalds 	}
361da177e4SLinus Torvalds 	do {
371da177e4SLinus Torvalds 		b = *bmPart++;
381da177e4SLinus Torvalds 		if ((b & 1) == 0)
391da177e4SLinus Torvalds 			tot++;
401da177e4SLinus Torvalds 		if ((b & 2) == 0)
411da177e4SLinus Torvalds 			tot++;
421da177e4SLinus Torvalds 		if ((b & 4) == 0)
431da177e4SLinus Torvalds 			tot++;
441da177e4SLinus Torvalds 		if ((b & 8) == 0)
451da177e4SLinus Torvalds 			tot++;
461da177e4SLinus Torvalds 		if ((b & 16) == 0)
471da177e4SLinus Torvalds 			tot++;
481da177e4SLinus Torvalds 		if ((b & 32) == 0)
491da177e4SLinus Torvalds 			tot++;
501da177e4SLinus Torvalds 		if ((b & 64) == 0)
511da177e4SLinus Torvalds 			tot++;
521da177e4SLinus Torvalds 		if ((b & 128) == 0)
531da177e4SLinus Torvalds 			tot++;
541da177e4SLinus Torvalds 		size--;
551da177e4SLinus Torvalds 	} while (size != 0);
561da177e4SLinus Torvalds 	*tf = tot;
571da177e4SLinus Torvalds }
581da177e4SLinus Torvalds 
591da177e4SLinus Torvalds unsigned long qnx4_count_free_blocks(struct super_block *sb)
601da177e4SLinus Torvalds {
611da177e4SLinus Torvalds 	int start = le32_to_cpu(qnx4_sb(sb)->BitMap->di_first_xtnt.xtnt_blk) - 1;
621da177e4SLinus Torvalds 	int total = 0;
631da177e4SLinus Torvalds 	int total_free = 0;
641da177e4SLinus Torvalds 	int offset = 0;
651da177e4SLinus Torvalds 	int size = le32_to_cpu(qnx4_sb(sb)->BitMap->di_size);
661da177e4SLinus Torvalds 	struct buffer_head *bh;
671da177e4SLinus Torvalds 
681da177e4SLinus Torvalds 	while (total < size) {
691da177e4SLinus Torvalds 		if ((bh = sb_bread(sb, start + offset)) == NULL) {
70*891ddb95SAnders Larsen 			printk(KERN_ERR "qnx4: I/O error in counting free blocks\n");
711da177e4SLinus Torvalds 			break;
721da177e4SLinus Torvalds 		}
731da177e4SLinus Torvalds 		count_bits(bh->b_data, size - total, &total_free);
741da177e4SLinus Torvalds 		brelse(bh);
751da177e4SLinus Torvalds 		total += QNX4_BLOCK_SIZE;
761da177e4SLinus Torvalds 		offset++;
771da177e4SLinus Torvalds 	}
781da177e4SLinus Torvalds 
791da177e4SLinus Torvalds 	return total_free;
801da177e4SLinus Torvalds }
81