linux/fs/qnx4/bitmap.c
<<
>>
Prefs
   1/*
   2 * QNX4 file system, Linux implementation.
   3 *
   4 * Version : 0.2.1
   5 *
   6 * Using parts of the xiafs filesystem.
   7 *
   8 * History :
   9 *
  10 * 28-05-1998 by Richard Frowijn : first release.
  11 * 20-06-1998 by Frank Denis : basic optimisations.
  12 * 25-06-1998 by Frank Denis : qnx4_is_free, qnx4_set_bitmap, qnx4_bmap .
  13 * 28-06-1998 by Frank Denis : qnx4_free_inode (to be fixed) .
  14 */
  15
  16#include <linux/time.h>
  17#include <linux/fs.h>
  18#include <linux/qnx4_fs.h>
  19#include <linux/stat.h>
  20#include <linux/kernel.h>
  21#include <linux/string.h>
  22#include <linux/buffer_head.h>
  23#include <linux/bitops.h>
  24
  25#if 0
  26int qnx4_new_block(struct super_block *sb)
  27{
  28        return 0;
  29}
  30#endif  /*  0  */
  31
  32static void count_bits(register const char *bmPart, register int size,
  33                       int *const tf)
  34{
  35        char b;
  36        int tot = *tf;
  37
  38        if (size > QNX4_BLOCK_SIZE) {
  39                size = QNX4_BLOCK_SIZE;
  40        }
  41        do {
  42                b = *bmPart++;
  43                if ((b & 1) == 0)
  44                        tot++;
  45                if ((b & 2) == 0)
  46                        tot++;
  47                if ((b & 4) == 0)
  48                        tot++;
  49                if ((b & 8) == 0)
  50                        tot++;
  51                if ((b & 16) == 0)
  52                        tot++;
  53                if ((b & 32) == 0)
  54                        tot++;
  55                if ((b & 64) == 0)
  56                        tot++;
  57                if ((b & 128) == 0)
  58                        tot++;
  59                size--;
  60        } while (size != 0);
  61        *tf = tot;
  62}
  63
  64unsigned long qnx4_count_free_blocks(struct super_block *sb)
  65{
  66        int start = le32_to_cpu(qnx4_sb(sb)->BitMap->di_first_xtnt.xtnt_blk) - 1;
  67        int total = 0;
  68        int total_free = 0;
  69        int offset = 0;
  70        int size = le32_to_cpu(qnx4_sb(sb)->BitMap->di_size);
  71        struct buffer_head *bh;
  72
  73        while (total < size) {
  74                if ((bh = sb_bread(sb, start + offset)) == NULL) {
  75                        printk("qnx4: I/O error in counting free blocks\n");
  76                        break;
  77                }
  78                count_bits(bh->b_data, size - total, &total_free);
  79                brelse(bh);
  80                total += QNX4_BLOCK_SIZE;
  81                offset++;
  82        }
  83
  84        return total_free;
  85}
  86
  87#ifdef CONFIG_QNX4FS_RW
  88
  89int qnx4_is_free(struct super_block *sb, long block)
  90{
  91        int start = le32_to_cpu(qnx4_sb(sb)->BitMap->di_first_xtnt.xtnt_blk) - 1;
  92        int size = le32_to_cpu(qnx4_sb(sb)->BitMap->di_size);
  93        struct buffer_head *bh;
  94        const char *g;
  95        int ret = -EIO;
  96
  97        start += block / (QNX4_BLOCK_SIZE * 8);
  98        QNX4DEBUG(("qnx4: is_free requesting block [%lu], bitmap in block [%lu]\n",
  99                   (unsigned long) block, (unsigned long) start));
 100        (void) size;            /* CHECKME */
 101        bh = sb_bread(sb, start);
 102        if (bh == NULL) {
 103                return -EIO;
 104        }
 105        g = bh->b_data + (block % QNX4_BLOCK_SIZE);
 106        if (((*g) & (1 << (block % 8))) == 0) {
 107                QNX4DEBUG(("qnx4: is_free -> block is free\n"));
 108                ret = 1;
 109        } else {
 110                QNX4DEBUG(("qnx4: is_free -> block is busy\n"));
 111                ret = 0;
 112        }
 113        brelse(bh);
 114
 115        return ret;
 116}
 117
 118int qnx4_set_bitmap(struct super_block *sb, long block, int busy)
 119{
 120        int start = le32_to_cpu(qnx4_sb(sb)->BitMap->di_first_xtnt.xtnt_blk) - 1;
 121        int size = le32_to_cpu(qnx4_sb(sb)->BitMap->di_size);
 122        struct buffer_head *bh;
 123        char *g;
 124
 125        start += block / (QNX4_BLOCK_SIZE * 8);
 126        QNX4DEBUG(("qnx4: set_bitmap requesting block [%lu], bitmap in block [%lu]\n",
 127                   (unsigned long) block, (unsigned long) start));
 128        (void) size;            /* CHECKME */
 129        bh = sb_bread(sb, start);
 130        if (bh == NULL) {
 131                return -EIO;
 132        }
 133        g = bh->b_data + (block % QNX4_BLOCK_SIZE);
 134        if (busy == 0) {
 135                (*g) &= ~(1 << (block % 8));
 136        } else {
 137                (*g) |= (1 << (block % 8));
 138        }
 139        mark_buffer_dirty(bh);
 140        brelse(bh);
 141
 142        return 0;
 143}
 144
 145static void qnx4_clear_inode(struct inode *inode)
 146{
 147        struct qnx4_inode_entry *qnx4_ino = qnx4_raw_inode(inode);
 148        /* What for? */
 149        memset(qnx4_ino->di_fname, 0, sizeof qnx4_ino->di_fname);
 150        qnx4_ino->di_size = 0;
 151        qnx4_ino->di_num_xtnts = 0;
 152        qnx4_ino->di_mode = 0;
 153        qnx4_ino->di_status = 0;
 154}
 155
 156void qnx4_free_inode(struct inode *inode)
 157{
 158        if (inode->i_ino < 1) {
 159                printk("free_inode: inode 0 or nonexistent inode\n");
 160                return;
 161        }
 162        qnx4_clear_inode(inode);
 163        clear_inode(inode);
 164}
 165
 166#endif
 167
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.