Linux 2.4.0-test10pre1
[davej-history.git] / fs / minix / bitmap.c
blobdce2687ee1021af81f7b4fd7b2bd3407206e77c5
1 /*
2 * linux/fs/minix/bitmap.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */
7 /*
8 * Modified for 680x0 by Hamish Macdonald
9 * Fixed for 680x0 by Andreas Schwab
12 /* bitmap.c contains the code that handles the inode and block bitmaps */
14 #include <linux/sched.h>
15 #include <linux/minix_fs.h>
16 #include <linux/stat.h>
17 #include <linux/kernel.h>
18 #include <linux/string.h>
19 #include <linux/locks.h>
20 #include <linux/quotaops.h>
22 #include <asm/bitops.h>
24 static int nibblemap[] = { 4,3,3,2,3,2,2,1,3,2,2,1,2,1,1,0 };
26 static unsigned long count_free(struct buffer_head *map[], unsigned numblocks, __u32 numbits)
28 unsigned i, j, sum = 0;
29 struct buffer_head *bh;
31 for (i=0; i<numblocks-1; i++) {
32 if (!(bh=map[i]))
33 return(0);
34 for (j=0; j<BLOCK_SIZE; j++)
35 sum += nibblemap[bh->b_data[j] & 0xf]
36 + nibblemap[(bh->b_data[j]>>4) & 0xf];
39 if (numblocks==0 || !(bh=map[numblocks-1]))
40 return(0);
41 i = ((numbits-(numblocks-1)*BLOCK_SIZE*8)/16)*2;
42 for (j=0; j<i; j++) {
43 sum += nibblemap[bh->b_data[j] & 0xf]
44 + nibblemap[(bh->b_data[j]>>4) & 0xf];
47 i = numbits%16;
48 if (i!=0) {
49 i = *(__u16 *)(&bh->b_data[j]) | ~((1<<i) - 1);
50 sum += nibblemap[i & 0xf] + nibblemap[(i>>4) & 0xf];
51 sum += nibblemap[(i>>8) & 0xf] + nibblemap[(i>>12) & 0xf];
53 return(sum);
56 void minix_free_block(struct inode * inode, int block)
58 struct super_block * sb = inode->i_sb;
59 struct buffer_head * bh;
60 unsigned int bit,zone;
62 if (!sb) {
63 printk("trying to free block on nonexistent device\n");
64 return;
66 if (block < sb->u.minix_sb.s_firstdatazone ||
67 block >= sb->u.minix_sb.s_nzones) {
68 printk("trying to free block not in datazone\n");
69 return;
71 bh = get_hash_table(sb->s_dev,block,BLOCK_SIZE);
72 if (bh)
73 clear_bit(BH_Dirty, &bh->b_state);
74 brelse(bh);
75 zone = block - sb->u.minix_sb.s_firstdatazone + 1;
76 bit = zone & 8191;
77 zone >>= 13;
78 if (zone >= sb->u.minix_sb.s_zmap_blocks) {
79 printk("minix_free_block: nonexistent bitmap buffer\n");
80 return;
82 bh = sb->u.minix_sb.s_zmap[zone];
83 if (!minix_test_and_clear_bit(bit,bh->b_data))
84 printk("free_block (%s:%d): bit already cleared\n",
85 kdevname(sb->s_dev), block);
86 mark_buffer_dirty(bh);
87 return;
90 int minix_new_block(struct inode * inode)
92 struct super_block * sb = inode->i_sb;
93 struct buffer_head * bh;
94 int i,j;
96 if (!sb) {
97 printk("trying to get new block from nonexistent device\n");
98 return 0;
100 repeat:
101 j = 8192;
102 bh = NULL;
103 for (i = 0; i < sb->u.minix_sb.s_zmap_blocks; i++) {
104 bh = sb->u.minix_sb.s_zmap[i];
105 if ((j = minix_find_first_zero_bit(bh->b_data, 8192)) < 8192)
106 break;
108 if (!bh || j >= 8192)
109 return 0;
110 if (minix_test_and_set_bit(j,bh->b_data)) {
111 printk("new_block: bit already set");
112 goto repeat;
114 mark_buffer_dirty(bh);
115 j += i*8192 + sb->u.minix_sb.s_firstdatazone-1;
116 if (j < sb->u.minix_sb.s_firstdatazone ||
117 j >= sb->u.minix_sb.s_nzones)
118 return 0;
119 return j;
122 unsigned long minix_count_free_blocks(struct super_block *sb)
124 return (count_free(sb->u.minix_sb.s_zmap, sb->u.minix_sb.s_zmap_blocks,
125 sb->u.minix_sb.s_nzones - sb->u.minix_sb.s_firstdatazone + 1)
126 << sb->u.minix_sb.s_log_zone_size);
129 static struct buffer_head *V1_minix_clear_inode(struct inode *inode)
131 struct buffer_head *bh;
132 struct minix_inode *raw_inode;
133 int ino, block;
135 ino = inode->i_ino;
136 if (!ino || ino > inode->i_sb->u.minix_sb.s_ninodes) {
137 printk("Bad inode number on dev %s: %d is out of range\n",
138 kdevname(inode->i_dev), ino);
139 return NULL;
141 block = (2 + inode->i_sb->u.minix_sb.s_imap_blocks +
142 inode->i_sb->u.minix_sb.s_zmap_blocks +
143 (ino - 1) / MINIX_INODES_PER_BLOCK);
144 bh = bread(inode->i_dev, block, BLOCK_SIZE);
145 if (!bh) {
146 printk("unable to read i-node block\n");
147 return NULL;
149 raw_inode = ((struct minix_inode *)bh->b_data +
150 (ino - 1) % MINIX_INODES_PER_BLOCK);
151 raw_inode->i_nlinks = 0;
152 raw_inode->i_mode = 0;
153 mark_buffer_dirty(bh);
154 return bh;
157 static struct buffer_head *V2_minix_clear_inode(struct inode *inode)
159 struct buffer_head *bh;
160 struct minix2_inode *raw_inode;
161 int ino, block;
163 ino = inode->i_ino;
164 if (!ino || ino > inode->i_sb->u.minix_sb.s_ninodes) {
165 printk("Bad inode number on dev %s: %d is out of range\n",
166 kdevname(inode->i_dev), ino);
167 return NULL;
169 block = (2 + inode->i_sb->u.minix_sb.s_imap_blocks +
170 inode->i_sb->u.minix_sb.s_zmap_blocks +
171 (ino - 1) / MINIX2_INODES_PER_BLOCK);
172 bh = bread(inode->i_dev, block, BLOCK_SIZE);
173 if (!bh) {
174 printk("unable to read i-node block\n");
175 return NULL;
177 raw_inode = ((struct minix2_inode *) bh->b_data +
178 (ino - 1) % MINIX2_INODES_PER_BLOCK);
179 raw_inode->i_nlinks = 0;
180 raw_inode->i_mode = 0;
181 mark_buffer_dirty(bh);
182 return bh;
185 /* Clear the link count and mode of a deleted inode on disk. */
187 static void minix_clear_inode(struct inode *inode)
189 struct buffer_head *bh;
190 if (INODE_VERSION(inode) == MINIX_V1)
191 bh = V1_minix_clear_inode(inode);
192 else
193 bh = V2_minix_clear_inode(inode);
194 brelse (bh);
197 void minix_free_inode(struct inode * inode)
199 struct buffer_head * bh;
200 unsigned long ino;
202 if (inode->i_ino < 1 || inode->i_ino > inode->i_sb->u.minix_sb.s_ninodes) {
203 printk("free_inode: inode 0 or nonexistent inode\n");
204 return;
206 ino = inode->i_ino;
207 if ((ino >> 13) >= inode->i_sb->u.minix_sb.s_imap_blocks) {
208 printk("free_inode: nonexistent imap in superblock\n");
209 return;
212 bh = inode->i_sb->u.minix_sb.s_imap[ino >> 13];
213 minix_clear_inode(inode);
214 clear_inode(inode);
215 if (!minix_test_and_clear_bit(ino & 8191, bh->b_data))
216 printk("free_inode: bit %lu already cleared.\n",ino);
217 mark_buffer_dirty(bh);
220 struct inode * minix_new_inode(const struct inode * dir, int * error)
222 struct super_block * sb;
223 struct inode * inode;
224 struct buffer_head * bh;
225 int i,j;
227 inode = get_empty_inode();
228 if (!inode) {
229 *error = -ENOMEM;
230 return NULL;
232 sb = dir->i_sb;
233 inode->i_sb = sb;
234 inode->i_flags = 0;
235 j = 8192;
236 bh = NULL;
237 *error = -ENOSPC;
238 lock_super(sb);
239 for (i = 0; i < sb->u.minix_sb.s_imap_blocks; i++) {
240 bh = inode->i_sb->u.minix_sb.s_imap[i];
241 if ((j = minix_find_first_zero_bit(bh->b_data, 8192)) < 8192)
242 break;
244 if (!bh || j >= 8192) {
245 iput(inode);
246 unlock_super(sb);
247 return NULL;
249 if (minix_test_and_set_bit(j,bh->b_data)) { /* shouldn't happen */
250 printk("new_inode: bit already set");
251 iput(inode);
252 unlock_super(sb);
253 return NULL;
255 mark_buffer_dirty(bh);
256 j += i*8192;
257 if (!j || j > inode->i_sb->u.minix_sb.s_ninodes) {
258 iput(inode);
259 unlock_super(sb);
260 return NULL;
262 inode->i_nlink = 1;
263 inode->i_dev = sb->s_dev;
264 inode->i_uid = current->fsuid;
265 inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
266 inode->i_ino = j;
267 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
268 inode->i_blocks = inode->i_blksize = 0;
269 insert_inode_hash(inode);
270 mark_inode_dirty(inode);
272 unlock_super(sb);
273 *error = 0;
274 return inode;
277 unsigned long minix_count_free_inodes(struct super_block *sb)
279 return count_free(sb->u.minix_sb.s_imap, sb->u.minix_sb.s_imap_blocks,
280 sb->u.minix_sb.s_ninodes + 1);