This source file includes following definitions.
- count_used
- minix_free_block
- minix_new_block
- minix_count_free_blocks
- minix_free_inode
- minix_new_inode
- minix_count_free_inodes
1
2
3
4
5
6
7
8
9 #include <linux/sched.h>
10 #include <linux/minix_fs.h>
11 #include <linux/kernel.h>
12 #include <linux/string.h>
13
14 #define clear_block(addr) \
15 __asm__("cld\n\t" \
16 "rep\n\t" \
17 "stosl" \
18 ::"a" (0),"c" (BLOCK_SIZE/4),"D" ((long) (addr)):"cx","di")
19
20 #define set_bit(nr,addr) ({\
21 char res; \
22 __asm__ __volatile__("btsl %1,%2\n\tsetb %0": \
23 "=q" (res):"r" (nr),"m" (*(addr))); \
24 res;})
25
26 #define clear_bit(nr,addr) ({\
27 char res; \
28 __asm__ __volatile__("btrl %1,%2\n\tsetnb %0": \
29 "=q" (res):"r" (nr),"m" (*(addr))); \
30 res;})
31
32 #define find_first_zero(addr) ({ \
33 int __res; \
34 __asm__("cld\n" \
35 "1:\tlodsl\n\t" \
36 "notl %%eax\n\t" \
37 "bsfl %%eax,%%edx\n\t" \
38 "jne 2f\n\t" \
39 "addl $32,%%ecx\n\t" \
40 "cmpl $8192,%%ecx\n\t" \
41 "jl 1b\n\t" \
42 "xorl %%edx,%%edx\n" \
43 "2:\taddl %%edx,%%ecx" \
44 :"=c" (__res):"0" (0),"S" (addr):"ax","dx","si"); \
45 __res;})
46
47 static int nibblemap[] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 };
48
49 static unsigned long count_used(struct buffer_head *map[], unsigned numblocks,
50 unsigned numbits)
51 {
52 unsigned i, j, end, sum = 0;
53 struct buffer_head *bh;
54
55 for (i=0; (i<numblocks) && numbits; i++) {
56 if (!(bh=map[i]))
57 return(0);
58 if (numbits >= (8*BLOCK_SIZE)) {
59 end = BLOCK_SIZE;
60 numbits -= 8*BLOCK_SIZE;
61 } else {
62 int tmp;
63 end = numbits >> 3;
64 numbits &= 0x7;
65 tmp = bh->b_data[end] & ((1<<numbits)-1);
66 sum += nibblemap[tmp&0xf] + nibblemap[(tmp>>4)&0xf];
67 numbits = 0;
68 }
69 for (j=0; j<end; j++)
70 sum += nibblemap[bh->b_data[j] & 0xf]
71 + nibblemap[(bh->b_data[j]>>4)&0xf];
72 }
73 return(sum);
74 }
75
76 int minix_free_block(int dev, int block)
77 {
78 struct super_block * sb;
79 struct buffer_head * bh;
80 unsigned int bit,zone;
81
82 if (!(sb = get_super(dev)))
83 panic("trying to free block on nonexistent device");
84 if (block < sb->u.minix_sb.s_firstdatazone || block >= sb->u.minix_sb.s_nzones)
85 panic("trying to free block not in datazone");
86 bh = get_hash_table(dev,block,BLOCK_SIZE);
87 if (bh) {
88 if (bh->b_count > 1) {
89 brelse(bh);
90 return 0;
91 }
92 bh->b_dirt=0;
93 bh->b_uptodate=0;
94 if (bh->b_count)
95 brelse(bh);
96 }
97 zone = block - sb->u.minix_sb.s_firstdatazone + 1;
98 bit = zone & 8191;
99 zone >>= 13;
100 bh = sb->u.minix_sb.s_zmap[zone];
101 if (clear_bit(bit,bh->b_data))
102 printk("free_block (%04x:%d): bit already cleared\n",dev,block);
103 bh->b_dirt = 1;
104 return 1;
105 }
106
107 int minix_new_block(int dev)
108 {
109 struct buffer_head * bh;
110 struct super_block * sb;
111 int i,j;
112
113 if (!(sb = get_super(dev)))
114 panic("trying to get new block from nonexistant device");
115 j = 8192;
116 for (i=0 ; i<8 ; i++)
117 if (bh=sb->u.minix_sb.s_zmap[i])
118 if ((j=find_first_zero(bh->b_data))<8192)
119 break;
120 if (i>=8 || !bh || j>=8192)
121 return 0;
122 if (set_bit(j,bh->b_data))
123 panic("new_block: bit already set");
124 bh->b_dirt = 1;
125 j += i*8192 + sb->u.minix_sb.s_firstdatazone-1;
126 if (j >= sb->u.minix_sb.s_nzones)
127 return 0;
128 if (!(bh=getblk(dev,j,BLOCK_SIZE)))
129 panic("new_block: cannot get block");
130 if (bh->b_count != 1)
131 panic("new block: count is != 1");
132 clear_block(bh->b_data);
133 bh->b_uptodate = 1;
134 bh->b_dirt = 1;
135 brelse(bh);
136 return j;
137 }
138
139 unsigned long minix_count_free_blocks(struct super_block *sb)
140 {
141 return (sb->u.minix_sb.s_nzones - count_used(sb->u.minix_sb.s_zmap,sb->u.minix_sb.s_zmap_blocks,sb->u.minix_sb.s_nzones))
142 << sb->u.minix_sb.s_log_zone_size;
143 }
144
145 void minix_free_inode(struct inode * inode)
146 {
147 struct buffer_head * bh;
148
149 if (!inode)
150 return;
151 if (!inode->i_dev) {
152 memset(inode,0,sizeof(*inode));
153 return;
154 }
155 if (inode->i_count>1) {
156 printk("free_inode: inode has count=%d\n",inode->i_count);
157 return;
158 }
159 if (inode->i_nlink) {
160 printk("free_inode: inode has nlink=%d\n",inode->i_nlink);
161 return;
162 }
163 if (!inode->i_sb) {
164 printk("free_inode: inode on nonexistent device\n");
165 return;
166 }
167 if (inode->i_ino < 1 || inode->i_ino > inode->i_sb->u.minix_sb.s_ninodes) {
168 printk("free_inode: inode 0 or nonexistent inode\n");
169 return;
170 }
171 if (!(bh=inode->i_sb->u.minix_sb.s_imap[inode->i_ino>>13])) {
172 printk("free_inode: nonexistent imap in superblock\n");
173 return;
174 }
175 if (clear_bit(inode->i_ino&8191,bh->b_data))
176 printk("free_inode: bit already cleared.\n\r");
177 bh->b_dirt = 1;
178 memset(inode,0,sizeof(*inode));
179 }
180
181 struct inode * minix_new_inode(int dev)
182 {
183 struct inode * inode;
184 struct buffer_head * bh;
185 int i,j;
186
187 if (!(inode=get_empty_inode()))
188 return NULL;
189 if (!(inode->i_sb = get_super(dev))) {
190 printk("new_inode: unknown device\n");
191 iput(inode);
192 return NULL;
193 }
194 inode->i_flags = inode->i_sb->s_flags;
195 j = 8192;
196 for (i=0 ; i<8 ; i++)
197 if (bh=inode->i_sb->u.minix_sb.s_imap[i])
198 if ((j=find_first_zero(bh->b_data))<8192)
199 break;
200 if (!bh || j >= 8192 || j+i*8192 > inode->i_sb->u.minix_sb.s_ninodes) {
201 iput(inode);
202 return NULL;
203 }
204 if (set_bit(j,bh->b_data)) {
205 printk("new_inode: bit already set");
206 iput(inode);
207 return NULL;
208 }
209 bh->b_dirt = 1;
210 inode->i_count = 1;
211 inode->i_nlink = 1;
212 inode->i_dev = dev;
213 inode->i_uid = current->euid;
214 inode->i_gid = current->egid;
215 inode->i_dirt = 1;
216 inode->i_ino = j + i*8192;
217 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
218 inode->i_op = NULL;
219 return inode;
220 }
221
222 unsigned long minix_count_free_inodes(struct super_block *sb)
223 {
224 return sb->u.minix_sb.s_ninodes - count_used(sb->u.minix_sb.s_imap,sb->u.minix_sb.s_imap_blocks,sb->u.minix_sb.s_ninodes);
225 }