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