patch-2.1.120 linux/fs/qnx4/bitmap.c
Next file: linux/fs/qnx4/dir.c
Previous file: linux/fs/qnx4/TODO
Back to the patch index
Back to the overall index
- Lines: 197
- Date:
Tue Sep 1 10:43:13 1998
- Orig file:
v2.1.119/linux/fs/qnx4/bitmap.c
- Orig date:
Wed Dec 31 16:00:00 1969
diff -u --recursive --new-file v2.1.119/linux/fs/qnx4/bitmap.c linux/fs/qnx4/bitmap.c
@@ -0,0 +1,196 @@
+/*
+ * QNX4 file system, Linux implementation.
+ *
+ * Version : 0.1
+ *
+ * Using parts of the xiafs filesystem.
+ *
+ * History :
+ *
+ * 28-05-1998 by Richard Frowijn : first release.
+ * 20-06-1998 by Frank Denis : basic optimisations.
+ * 25-06-1998 by Frank Denis : qnx4_is_free, qnx4_set_bitmap, qnx4_bmap .
+ * 28-06-1998 by Frank Denis : qnx4_free_inode (to be fixed) .
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/qnx4_fs.h>
+#include <linux/stat.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+#include <asm/bitops.h>
+
+int qnx4_new_block(struct super_block *sb)
+{
+ return 0;
+}
+
+void count_bits(const register char *bmPart, register int size,
+ int *const tf)
+{
+ char b;
+ int tot = *tf;
+
+ if (size > QNX4_BLOCK_SIZE) {
+ size = QNX4_BLOCK_SIZE;
+ }
+ do {
+ b = *bmPart++;
+ if ((b & 1) == 0)
+ tot++;
+ if ((b & 2) == 0)
+ tot++;
+ if ((b & 4) == 0)
+ tot++;
+ if ((b & 8) == 0)
+ tot++;
+ if ((b & 16) == 0)
+ tot++;
+ if ((b & 32) == 0)
+ tot++;
+ if ((b & 64) == 0)
+ tot++;
+ if ((b & 128) == 0)
+ tot++;
+ size--;
+ } while (size != 0);
+ *tf = tot;
+}
+
+unsigned long qnx4_count_free_blocks(struct super_block *sb)
+{
+ int start = sb->u.qnx4_sb.BitMap->di_first_xtnt.xtnt_blk - 1;
+ int total = 0;
+ int total_free = 0;
+ int offset = 0;
+ int size = sb->u.qnx4_sb.BitMap->di_size;
+ struct buffer_head *bh;
+
+ while (total < size) {
+ if ((bh = bread(sb->s_dev, start + offset, QNX4_BLOCK_SIZE)) == NULL) {
+ printk("qnx4: I/O error in counting free blocks\n");
+ break;
+ }
+ count_bits(bh->b_data, size - total, &total_free);
+ brelse(bh);
+ total += QNX4_BLOCK_SIZE;
+ }
+
+ return total_free;
+}
+
+unsigned long qnx4_count_free_inodes(struct super_block *sb)
+{
+ return qnx4_count_free_blocks(sb) * QNX4_INODES_PER_BLOCK; /* FIXME */
+}
+
+int qnx4_is_free(struct super_block *sb, int block)
+{
+ int start = sb->u.qnx4_sb.BitMap->di_first_xtnt.xtnt_blk - 1;
+ int size = sb->u.qnx4_sb.BitMap->di_size;
+ struct buffer_head *bh;
+ const char *g;
+ int ret = -EIO;
+
+ start += block / (QNX4_BLOCK_SIZE * 8);
+ QNX4DEBUG(("qnx4: is_free requesting block [%lu], bitmap in block [%lu]\n",
+ (unsigned long) block, (unsigned long) start));
+ (void) size; /* CHECKME */
+ bh = bread(sb->s_dev, start, QNX4_BLOCK_SIZE);
+ if (bh == NULL) {
+ return -EIO;
+ }
+ g = bh->b_data + (block % QNX4_BLOCK_SIZE);
+ if (((*g) & (1 << (block % 8))) == 0) {
+ QNX4DEBUG(("qnx4: is_free -> block is free\n"));
+ ret = 1;
+ } else {
+ QNX4DEBUG(("qnx4: is_free -> block is busy\n"));
+ ret = 0;
+ }
+ brelse(bh);
+
+ return ret;
+}
+
+int qnx4_bmap(struct inode *inode, int block)
+{
+ QNX4DEBUG(("qnx4: bmap on block [%d]\n", block));
+ if (block < 0) {
+ return 0;
+ }
+ return !qnx4_is_free(inode->i_sb, block);
+}
+
+#ifdef CONFIG_QNX4FS_RW
+
+int qnx4_set_bitmap(struct super_block *sb, int block, int busy)
+{
+ int start = sb->u.qnx4_sb.BitMap->di_first_xtnt.xtnt_blk - 1;
+ int size = sb->u.qnx4_sb.BitMap->di_size;
+ struct buffer_head *bh;
+ char *g;
+
+ start += block / (QNX4_BLOCK_SIZE * 8);
+ QNX4DEBUG(("qnx4: set_bitmap requesting block [%lu], bitmap in block [%lu]\n",
+ (unsigned long) block, (unsigned long) start));
+ (void) size; /* CHECKME */
+ bh = bread(sb->s_dev, start, QNX4_BLOCK_SIZE);
+ if (bh == NULL) {
+ return -EIO;
+ }
+ g = bh->b_data + (block % QNX4_BLOCK_SIZE);
+ if (busy == 0) {
+ (*g) &= ~(1 << (block % 8));
+ } else {
+ (*g) |= (1 << (block % 8));
+ }
+ mark_buffer_dirty(bh, 1);
+ brelse(bh);
+
+ return 0;
+}
+
+static void qnx4_clear_inode(struct inode *inode)
+{
+ struct qnx4_inode_info *qnx4_ino = &inode->u.qnx4_i;
+
+ memset(qnx4_ino->i_reserved, 0, sizeof qnx4_ino->i_reserved);
+ qnx4_ino->i_size = 0;
+ qnx4_ino->i_num_xtnts = 0;
+ qnx4_ino->i_mode = 0;
+ qnx4_ino->i_status = 0;
+}
+
+void qnx4_free_inode(struct inode *inode)
+{
+ if (!inode) {
+ return;
+ }
+ if (!inode->i_dev) {
+ printk("free_inode: inode has no device\n");
+ return;
+ }
+ if (inode->i_count > 1) {
+ printk("free_inode: inode has count=%d\n", inode->i_count);
+ return;
+ }
+ if (inode->i_nlink) {
+ printk("free_inode: inode has nlink=%d\n", inode->i_nlink);
+ return;
+ }
+ if (!inode->i_sb) {
+ printk("free_inode: inode on nonexistent device\n");
+ return;
+ }
+ if (inode->i_ino < 1) {
+ printk("free_inode: inode 0 or nonexistent inode\n");
+ return;
+ }
+ qnx4_clear_inode(inode);
+ clear_inode(inode);
+}
+
+#endif
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov