2 * linux/fs/minix/bitmap.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
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>
20 #include <asm/bitops.h>
22 static int nibblemap
[] = { 4,3,3,2,3,2,2,1,3,2,2,1,2,1,1,0 };
24 static unsigned long count_free(struct buffer_head
*map
[], unsigned numblocks
, __u32 numbits
)
26 unsigned i
, j
, sum
= 0;
27 struct buffer_head
*bh
;
29 for (i
=0; i
<numblocks
-1; i
++) {
32 for (j
=0; j
<BLOCK_SIZE
; j
++)
33 sum
+= nibblemap
[bh
->b_data
[j
] & 0xf]
34 + nibblemap
[(bh
->b_data
[j
]>>4) & 0xf];
37 if (numblocks
==0 || !(bh
=map
[numblocks
-1]))
39 i
= ((numbits
-(numblocks
-1)*BLOCK_SIZE
*8)/16)*2;
41 sum
+= nibblemap
[bh
->b_data
[j
] & 0xf]
42 + nibblemap
[(bh
->b_data
[j
]>>4) & 0xf];
47 i
= *(__u16
*)(&bh
->b_data
[j
]) | ~((1<<i
) - 1);
48 sum
+= nibblemap
[i
& 0xf] + nibblemap
[(i
>>4) & 0xf];
49 sum
+= nibblemap
[(i
>>8) & 0xf] + nibblemap
[(i
>>12) & 0xf];
54 void minix_free_block(struct super_block
* sb
, int block
)
56 struct buffer_head
* bh
;
57 unsigned int bit
,zone
;
60 printk("trying to free block on nonexistent device\n");
63 if (block
< sb
->u
.minix_sb
.s_firstdatazone
||
64 block
>= sb
->u
.minix_sb
.s_nzones
) {
65 printk("trying to free block not in datazone\n");
68 bh
= get_hash_table(sb
->s_dev
,block
,BLOCK_SIZE
);
70 clear_bit(BH_Dirty
, &bh
->b_state
);
72 zone
= block
- sb
->u
.minix_sb
.s_firstdatazone
+ 1;
75 if (zone
>= sb
->u
.minix_sb
.s_zmap_blocks
) {
76 printk("minix_free_block: nonexistent bitmap buffer\n");
79 bh
= sb
->u
.minix_sb
.s_zmap
[zone
];
80 if (!minix_clear_bit(bit
,bh
->b_data
))
81 printk("free_block (%s:%d): bit already cleared\n",
82 kdevname(sb
->s_dev
), block
);
83 mark_buffer_dirty(bh
, 1);
87 int minix_new_block(struct super_block
* sb
)
89 struct buffer_head
* bh
;
93 printk("trying to get new block from nonexistent device\n");
99 for (i
= 0; i
< sb
->u
.minix_sb
.s_zmap_blocks
; i
++) {
100 bh
= sb
->u
.minix_sb
.s_zmap
[i
];
101 if ((j
= minix_find_first_zero_bit(bh
->b_data
, 8192)) < 8192)
104 if (!bh
|| j
>= 8192)
106 if (minix_set_bit(j
,bh
->b_data
)) {
107 printk("new_block: bit already set");
110 mark_buffer_dirty(bh
, 1);
111 j
+= i
*8192 + sb
->u
.minix_sb
.s_firstdatazone
-1;
112 if (j
< sb
->u
.minix_sb
.s_firstdatazone
||
113 j
>= sb
->u
.minix_sb
.s_nzones
)
118 unsigned long minix_count_free_blocks(struct super_block
*sb
)
120 return (count_free(sb
->u
.minix_sb
.s_zmap
, sb
->u
.minix_sb
.s_zmap_blocks
,
121 sb
->u
.minix_sb
.s_nzones
- sb
->u
.minix_sb
.s_firstdatazone
+ 1)
122 << sb
->u
.minix_sb
.s_log_zone_size
);
125 static struct buffer_head
*V1_minix_clear_inode(struct inode
*inode
)
127 struct buffer_head
*bh
;
128 struct minix_inode
*raw_inode
;
132 if (!ino
|| ino
> inode
->i_sb
->u
.minix_sb
.s_ninodes
) {
133 printk("Bad inode number on dev %s: %d is out of range\n",
134 kdevname(inode
->i_dev
), ino
);
137 block
= (2 + inode
->i_sb
->u
.minix_sb
.s_imap_blocks
+
138 inode
->i_sb
->u
.minix_sb
.s_zmap_blocks
+
139 (ino
- 1) / MINIX_INODES_PER_BLOCK
);
140 bh
= bread(inode
->i_dev
, block
, BLOCK_SIZE
);
142 printk("unable to read i-node block\n");
145 raw_inode
= ((struct minix_inode
*)bh
->b_data
+
146 (ino
- 1) % MINIX_INODES_PER_BLOCK
);
147 raw_inode
->i_nlinks
= 0;
148 raw_inode
->i_mode
= 0;
149 mark_buffer_dirty(bh
, 1);
153 static struct buffer_head
*V2_minix_clear_inode(struct inode
*inode
)
155 struct buffer_head
*bh
;
156 struct minix2_inode
*raw_inode
;
160 if (!ino
|| ino
> inode
->i_sb
->u
.minix_sb
.s_ninodes
) {
161 printk("Bad inode number on dev %s: %d is out of range\n",
162 kdevname(inode
->i_dev
), ino
);
165 block
= (2 + inode
->i_sb
->u
.minix_sb
.s_imap_blocks
+
166 inode
->i_sb
->u
.minix_sb
.s_zmap_blocks
+
167 (ino
- 1) / MINIX2_INODES_PER_BLOCK
);
168 bh
= bread(inode
->i_dev
, block
, BLOCK_SIZE
);
170 printk("unable to read i-node block\n");
173 raw_inode
= ((struct minix2_inode
*) bh
->b_data
+
174 (ino
- 1) % MINIX2_INODES_PER_BLOCK
);
175 raw_inode
->i_nlinks
= 0;
176 raw_inode
->i_mode
= 0;
177 mark_buffer_dirty(bh
, 1);
181 /* Clear the link count and mode of a deleted inode on disk. */
183 static void minix_clear_inode(struct inode
*inode
)
185 struct buffer_head
*bh
;
186 if (INODE_VERSION(inode
) == MINIX_V1
)
187 bh
= V1_minix_clear_inode(inode
);
189 bh
= V2_minix_clear_inode(inode
);
193 void minix_free_inode(struct inode
* inode
)
195 struct buffer_head
* bh
;
201 printk("free_inode: inode has no device\n");
204 if (inode
->i_count
> 1) {
205 printk("free_inode: inode has count=%d\n",inode
->i_count
);
208 if (inode
->i_nlink
) {
209 printk("free_inode: inode has nlink=%d\n",inode
->i_nlink
);
213 printk("free_inode: inode on nonexistent device\n");
216 if (inode
->i_ino
< 1 || inode
->i_ino
> inode
->i_sb
->u
.minix_sb
.s_ninodes
) {
217 printk("free_inode: inode 0 or nonexistent inode\n");
221 if ((ino
>> 13) >= inode
->i_sb
->u
.minix_sb
.s_imap_blocks
) {
222 printk("free_inode: nonexistent imap in superblock\n");
225 bh
= inode
->i_sb
->u
.minix_sb
.s_imap
[ino
>> 13];
226 minix_clear_inode(inode
);
228 if (!minix_clear_bit(ino
& 8191, bh
->b_data
))
229 printk("free_inode: bit %lu already cleared.\n",ino
);
230 mark_buffer_dirty(bh
, 1);
233 struct inode
* minix_new_inode(const struct inode
* dir
)
235 struct super_block
* sb
;
236 struct inode
* inode
;
237 struct buffer_head
* bh
;
240 if (!dir
|| !(inode
= get_empty_inode()))
247 for (i
= 0; i
< sb
->u
.minix_sb
.s_imap_blocks
; i
++) {
248 bh
= inode
->i_sb
->u
.minix_sb
.s_imap
[i
];
249 if ((j
= minix_find_first_zero_bit(bh
->b_data
, 8192)) < 8192)
252 if (!bh
|| j
>= 8192) {
256 if (minix_set_bit(j
,bh
->b_data
)) { /* shouldn't happen */
257 printk("new_inode: bit already set");
261 mark_buffer_dirty(bh
, 1);
263 if (!j
|| j
> inode
->i_sb
->u
.minix_sb
.s_ninodes
) {
268 inode
->i_dev
= sb
->s_dev
;
269 inode
->i_uid
= current
->fsuid
;
270 inode
->i_gid
= (dir
->i_mode
& S_ISGID
) ? dir
->i_gid
: current
->fsgid
;
272 inode
->i_mtime
= inode
->i_atime
= inode
->i_ctime
= CURRENT_TIME
;
274 inode
->i_blocks
= inode
->i_blksize
= 0;
275 insert_inode_hash(inode
);
276 mark_inode_dirty(inode
);
280 unsigned long minix_count_free_inodes(struct super_block
*sb
)
282 return count_free(sb
->u
.minix_sb
.s_imap
, sb
->u
.minix_sb
.s_imap_blocks
,
283 sb
->u
.minix_sb
.s_ninodes
+ 1);