Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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/buffer_head.h>
 17 #include <linux/bitops.h>
 18 #include "qnx4.h"
 19 
 20 #if 0
 21 int qnx4_new_block(struct super_block *sb)
 22 {
 23         return 0;
 24 }
 25 #endif  /*  0  */
 26 
 27 static void count_bits(register const char *bmPart, register int size,
 28                        int *const tf)
 29 {
 30         char b;
 31         int tot = *tf;
 32 
 33         if (size > QNX4_BLOCK_SIZE) {
 34                 size = QNX4_BLOCK_SIZE;
 35         }
 36         do {
 37                 b = *bmPart++;
 38                 if ((b & 1) == 0)
 39                         tot++;
 40                 if ((b & 2) == 0)
 41                         tot++;
 42                 if ((b & 4) == 0)
 43                         tot++;
 44                 if ((b & 8) == 0)
 45                         tot++;
 46                 if ((b & 16) == 0)
 47                         tot++;
 48                 if ((b & 32) == 0)
 49                         tot++;
 50                 if ((b & 64) == 0)
 51                         tot++;
 52                 if ((b & 128) == 0)
 53                         tot++;
 54                 size--;
 55         } while (size != 0);
 56         *tf = tot;
 57 }
 58 
 59 unsigned long qnx4_count_free_blocks(struct super_block *sb)
 60 {
 61         int start = le32_to_cpu(qnx4_sb(sb)->BitMap->di_first_xtnt.xtnt_blk) - 1;
 62         int total = 0;
 63         int total_free = 0;
 64         int offset = 0;
 65         int size = le32_to_cpu(qnx4_sb(sb)->BitMap->di_size);
 66         struct buffer_head *bh;
 67 
 68         while (total < size) {
 69                 if ((bh = sb_bread(sb, start + offset)) == NULL) {
 70                         printk("qnx4: I/O error in counting free blocks\n");
 71                         break;
 72                 }
 73                 count_bits(bh->b_data, size - total, &total_free);
 74                 brelse(bh);
 75                 total += QNX4_BLOCK_SIZE;
 76                 offset++;
 77         }
 78 
 79         return total_free;
 80 }
 81 
 82 #ifdef CONFIG_QNX4FS_RW
 83 
 84 int qnx4_is_free(struct super_block *sb, long block)
 85 {
 86         int start = le32_to_cpu(qnx4_sb(sb)->BitMap->di_first_xtnt.xtnt_blk) - 1;
 87         int size = le32_to_cpu(qnx4_sb(sb)->BitMap->di_size);
 88         struct buffer_head *bh;
 89         const char *g;
 90         int ret = -EIO;
 91 
 92         start += block / (QNX4_BLOCK_SIZE * 8);
 93         QNX4DEBUG(("qnx4: is_free requesting block [%lu], bitmap in block [%lu]\n",
 94                    (unsigned long) block, (unsigned long) start));
 95         (void) size;            /* CHECKME */
 96         bh = sb_bread(sb, start);
 97         if (bh == NULL) {
 98                 return -EIO;
 99         }
100         g = bh->b_data + (block % QNX4_BLOCK_SIZE);
101         if (((*g) & (1 << (block % 8))) == 0) {
102                 QNX4DEBUG(("qnx4: is_free -> block is free\n"));
103                 ret = 1;
104         } else {
105                 QNX4DEBUG(("qnx4: is_free -> block is busy\n"));
106                 ret = 0;
107         }
108         brelse(bh);
109 
110         return ret;
111 }
112 
113 int qnx4_set_bitmap(struct super_block *sb, long block, int busy)
114 {
115         int start = le32_to_cpu(qnx4_sb(sb)->BitMap->di_first_xtnt.xtnt_blk) - 1;
116         int size = le32_to_cpu(qnx4_sb(sb)->BitMap->di_size);
117         struct buffer_head *bh;
118         char *g;
119 
120         start += block / (QNX4_BLOCK_SIZE * 8);
121         QNX4DEBUG(("qnx4: set_bitmap requesting block [%lu], bitmap in block [%lu]\n",
122                    (unsigned long) block, (unsigned long) start));
123         (void) size;            /* CHECKME */
124         bh = sb_bread(sb, start);
125         if (bh == NULL) {
126                 return -EIO;
127         }
128         g = bh->b_data + (block % QNX4_BLOCK_SIZE);
129         if (busy == 0) {
130                 (*g) &= ~(1 << (block % 8));
131         } else {
132                 (*g) |= (1 << (block % 8));
133         }
134         mark_buffer_dirty(bh);
135         brelse(bh);
136 
137         return 0;
138 }
139 
140 static void qnx4_clear_inode(struct inode *inode)
141 {
142         struct qnx4_inode_entry *qnx4_ino = qnx4_raw_inode(inode);
143         /* What for? */
144         memset(qnx4_ino->di_fname, 0, sizeof qnx4_ino->di_fname);
145         qnx4_ino->di_size = 0;
146         qnx4_ino->di_num_xtnts = 0;
147         qnx4_ino->di_mode = 0;
148         qnx4_ino->di_status = 0;
149 }
150 
151 void qnx4_free_inode(struct inode *inode)
152 {
153         if (inode->i_ino < 1) {
154                 printk("free_inode: inode 0 or nonexistent inode\n");
155                 return;
156         }
157         qnx4_clear_inode(inode);
158         clear_inode(inode);
159 }
160 
161 #endif
162 
  This page was automatically generated by the LXR engine.