This source file includes following definitions.
- ext_free_block
- ext_new_block
- ext_count_free_blocks
- ext_free_inode
- ext_new_inode
- ext_count_free_inodes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 #include <linux/sched.h>
34 #include <linux/ext_fs.h>
35 #include <linux/stat.h>
36 #include <linux/kernel.h>
37 #include <linux/string.h>
38 #include <linux/locks.h>
39
40 void ext_free_block(struct super_block * sb, int block)
41 {
42 struct buffer_head * bh;
43 struct ext_free_block * efb;
44
45 if (!sb) {
46 printk("trying to free block on non-existent device\n");
47 return;
48 }
49 lock_super (sb);
50 if (block < sb->u.ext_sb.s_firstdatazone ||
51 block >= sb->u.ext_sb.s_nzones) {
52 printk("trying to free block not in datazone\n");
53 return;
54 }
55 bh = get_hash_table(sb->s_dev, block, sb->s_blocksize);
56 if (bh)
57 mark_buffer_clean(bh);
58 brelse(bh);
59 if (sb->u.ext_sb.s_firstfreeblock)
60 efb = (struct ext_free_block *) sb->u.ext_sb.s_firstfreeblock->b_data;
61 if (!sb->u.ext_sb.s_firstfreeblock || efb->count == 254) {
62 #ifdef EXTFS_DEBUG
63 printk("ext_free_block: block full, skipping to %d\n", block);
64 #endif
65 if (sb->u.ext_sb.s_firstfreeblock)
66 brelse (sb->u.ext_sb.s_firstfreeblock);
67 if (!(sb->u.ext_sb.s_firstfreeblock = bread (sb->s_dev,
68 block, sb->s_blocksize)))
69 panic ("ext_free_block: unable to read block to free\n");
70 efb = (struct ext_free_block *) sb->u.ext_sb.s_firstfreeblock->b_data;
71 efb->next = sb->u.ext_sb.s_firstfreeblocknumber;
72 efb->count = 0;
73 sb->u.ext_sb.s_firstfreeblocknumber = block;
74 } else {
75 efb->free[efb->count++] = block;
76 }
77 sb->u.ext_sb.s_freeblockscount ++;
78 sb->s_dirt = 1;
79 mark_buffer_dirty(sb->u.ext_sb.s_firstfreeblock, 1);
80 unlock_super (sb);
81 return;
82 }
83
84 int ext_new_block(struct super_block * sb)
85 {
86 struct buffer_head * bh;
87 struct ext_free_block * efb;
88 int j;
89
90 if (!sb) {
91 printk("trying to get new block from non-existent device\n");
92 return 0;
93 }
94 if (!sb->u.ext_sb.s_firstfreeblock)
95 return 0;
96 lock_super (sb);
97 efb = (struct ext_free_block *) sb->u.ext_sb.s_firstfreeblock->b_data;
98 if (efb->count) {
99 j = efb->free[--efb->count];
100 mark_buffer_dirty(sb->u.ext_sb.s_firstfreeblock, 1);
101 } else {
102 #ifdef EXTFS_DEBUG
103 printk("ext_new_block: block empty, skipping to %d\n", efb->next);
104 #endif
105 j = sb->u.ext_sb.s_firstfreeblocknumber;
106 sb->u.ext_sb.s_firstfreeblocknumber = efb->next;
107 brelse (sb->u.ext_sb.s_firstfreeblock);
108 if (!sb->u.ext_sb.s_firstfreeblocknumber) {
109 sb->u.ext_sb.s_firstfreeblock = NULL;
110 } else {
111 if (!(sb->u.ext_sb.s_firstfreeblock = bread (sb->s_dev,
112 sb->u.ext_sb.s_firstfreeblocknumber,
113 sb->s_blocksize)))
114 panic ("ext_new_block: unable to read next free block\n");
115 }
116 }
117 if (j < sb->u.ext_sb.s_firstdatazone || j > sb->u.ext_sb.s_nzones) {
118 printk ("ext_new_block: blk = %d\n", j);
119 printk("allocating block not in data zone\n");
120 return 0;
121 }
122 sb->u.ext_sb.s_freeblockscount --;
123 sb->s_dirt = 1;
124
125 if (!(bh=getblk(sb->s_dev, j, sb->s_blocksize))) {
126 printk("new_block: cannot get block");
127 return 0;
128 }
129 memset(bh->b_data, 0, BLOCK_SIZE);
130 mark_buffer_uptodate(bh, 1);
131 mark_buffer_dirty(bh, 1);
132 brelse(bh);
133 #ifdef EXTFS_DEBUG
134 printk("ext_new_block: allocating block %d\n", j);
135 #endif
136 unlock_super (sb);
137 return j;
138 }
139
140 unsigned long ext_count_free_blocks(struct super_block *sb)
141 {
142 #ifdef EXTFS_DEBUG
143 struct buffer_head * bh;
144 struct ext_free_block * efb;
145 unsigned long count, block;
146
147 lock_super (sb);
148 if (!sb->u.ext_sb.s_firstfreeblock)
149 count = 0;
150 else {
151 efb = (struct ext_free_block *) sb->u.ext_sb.s_firstfreeblock->b_data;
152 count = efb->count + 1;
153 block = efb->next;
154 while (block) {
155 if (!(bh = bread (sb->s_dev, block, sb->s_blocksize))) {
156 printk ("ext_count_free: error while reading free blocks list\n");
157 block = 0;
158 } else {
159 efb = (struct ext_free_block *) bh->b_data;
160 count += efb->count + 1;
161 block = efb->next;
162 brelse (bh);
163 }
164 }
165 }
166 printk("ext_count_free_blocks: stored = %d, computed = %d\n",
167 sb->u.ext_sb.s_freeblockscount, count);
168 unlock_super (sb);
169 return count;
170 #else
171 return sb->u.ext_sb.s_freeblockscount;
172 #endif
173 }
174
175 void ext_free_inode(struct inode * inode)
176 {
177 struct buffer_head * bh;
178 struct ext_free_inode * efi;
179 struct super_block * sb;
180 unsigned long block;
181 unsigned long ino;
182 kdev_t dev;
183
184 if (!inode)
185 return;
186 if (!inode->i_dev) {
187 printk("free_inode: inode has no device\n");
188 return;
189 }
190 if (inode->i_count != 1) {
191 printk("free_inode: inode has count=%d\n",inode->i_count);
192 return;
193 }
194 if (inode->i_nlink) {
195 printk("free_inode: inode has nlink=%d\n",inode->i_nlink);
196 return;
197 }
198 if (!inode->i_sb) {
199 printk("free_inode: inode on non-existent device\n");
200 return;
201 }
202 sb = inode->i_sb;
203 ino = inode->i_ino;
204 dev = inode->i_dev;
205 clear_inode(inode);
206 lock_super (sb);
207 if (ino < 1 || ino > sb->u.ext_sb.s_ninodes) {
208 printk("free_inode: inode 0 or non-existent inode\n");
209 unlock_super (sb);
210 return;
211 }
212 if (sb->u.ext_sb.s_firstfreeinodeblock)
213 efi = ((struct ext_free_inode *) sb->u.ext_sb.s_firstfreeinodeblock->b_data) +
214 (sb->u.ext_sb.s_firstfreeinodenumber-1)%EXT_INODES_PER_BLOCK;
215 if (!sb->u.ext_sb.s_firstfreeinodeblock || efi->count == 14) {
216 #ifdef EXTFS_DEBUG
217 printk("ext_free_inode: inode full, skipping to %d\n", ino);
218 #endif
219 if (sb->u.ext_sb.s_firstfreeinodeblock)
220 brelse (sb->u.ext_sb.s_firstfreeinodeblock);
221 block = 2 + (ino - 1) / EXT_INODES_PER_BLOCK;
222 if (!(bh = bread(dev, block, sb->s_blocksize)))
223 panic("ext_free_inode: unable to read inode block\n");
224 efi = ((struct ext_free_inode *) bh->b_data) +
225 (ino - 1) % EXT_INODES_PER_BLOCK;
226 efi->next = sb->u.ext_sb.s_firstfreeinodenumber;
227 efi->count = 0;
228 sb->u.ext_sb.s_firstfreeinodenumber = ino;
229 sb->u.ext_sb.s_firstfreeinodeblock = bh;
230 } else {
231 efi->free[efi->count++] = ino;
232 }
233 sb->u.ext_sb.s_freeinodescount ++;
234 sb->s_dirt = 1;
235 mark_buffer_dirty(sb->u.ext_sb.s_firstfreeinodeblock, 1);
236 unlock_super (sb);
237 }
238
239 struct inode * ext_new_inode(const struct inode * dir)
240 {
241 struct super_block * sb;
242 struct inode * inode;
243 struct ext_free_inode * efi;
244 unsigned long block;
245 int j;
246
247 if (!dir || !(inode=get_empty_inode()))
248 return NULL;
249 sb = dir->i_sb;
250 inode->i_sb = sb;
251 inode->i_flags = sb->s_flags;
252 if (!sb->u.ext_sb.s_firstfreeinodeblock)
253 return 0;
254 lock_super (sb);
255 efi = ((struct ext_free_inode *) sb->u.ext_sb.s_firstfreeinodeblock->b_data) +
256 (sb->u.ext_sb.s_firstfreeinodenumber-1)%EXT_INODES_PER_BLOCK;
257 if (efi->count) {
258 j = efi->free[--efi->count];
259 mark_buffer_dirty(sb->u.ext_sb.s_firstfreeinodeblock, 1);
260 } else {
261 #ifdef EXTFS_DEBUG
262 printk("ext_free_inode: inode empty, skipping to %d\n", efi->next);
263 #endif
264 j = sb->u.ext_sb.s_firstfreeinodenumber;
265 if (efi->next > sb->u.ext_sb.s_ninodes) {
266 printk ("efi->next = %ld\n", efi->next);
267 panic ("ext_new_inode: bad inode number in free list\n");
268 }
269 sb->u.ext_sb.s_firstfreeinodenumber = efi->next;
270 block = 2 + (((unsigned long) efi->next) - 1) / EXT_INODES_PER_BLOCK;
271 brelse (sb->u.ext_sb.s_firstfreeinodeblock);
272 if (!sb->u.ext_sb.s_firstfreeinodenumber) {
273 sb->u.ext_sb.s_firstfreeinodeblock = NULL;
274 } else {
275 if (!(sb->u.ext_sb.s_firstfreeinodeblock =
276 bread(sb->s_dev, block, sb->s_blocksize)))
277 panic ("ext_new_inode: unable to read next free inode block\n");
278 }
279 }
280 sb->u.ext_sb.s_freeinodescount --;
281 sb->s_dirt = 1;
282 inode->i_count = 1;
283 inode->i_nlink = 1;
284 inode->i_dev = sb->s_dev;
285 inode->i_uid = current->fsuid;
286 inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
287 inode->i_dirt = 1;
288 inode->i_ino = j;
289 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
290 inode->i_op = NULL;
291 inode->i_blocks = inode->i_blksize = 0;
292 insert_inode_hash(inode);
293 #ifdef EXTFS_DEBUG
294 printk("ext_new_inode : allocating inode %d\n", inode->i_ino);
295 #endif
296 unlock_super (sb);
297 return inode;
298 }
299
300 unsigned long ext_count_free_inodes(struct super_block *sb)
301 {
302 #ifdef EXTFS_DEBUG
303 struct buffer_head * bh;
304 struct ext_free_inode * efi;
305 unsigned long count, block, ino;
306
307 lock_super (sb);
308 if (!sb->u.ext_sb.s_firstfreeinodeblock)
309 count = 0;
310 else {
311 efi = ((struct ext_free_inode *) sb->u.ext_sb.s_firstfreeinodeblock->b_data) +
312 ((sb->u.ext_sb.s_firstfreeinodenumber-1)%EXT_INODES_PER_BLOCK);
313 count = efi->count + 1;
314 ino = efi->next;
315 while (ino) {
316 if (ino < 1 || ino > sb->u.ext_sb.s_ninodes) {
317 printk ("u.ext_sb.s_firstfreeinodenumber = %d, ino = %d\n",
318 (int) sb->u.ext_sb.s_firstfreeinodenumber,ino);
319 panic ("ext_count_fre_inodes: bad inode number in free list\n");
320 }
321 block = 2 + ((ino - 1) / EXT_INODES_PER_BLOCK);
322 if (!(bh = bread (sb->s_dev, block, sb->s_blocksize))) {
323 printk ("ext_count_free_inodes: error while reading free inodes list\n");
324 block = 0;
325 } else {
326 efi = ((struct ext_free_inode *) bh->b_data) +
327 ((ino - 1) % EXT_INODES_PER_BLOCK);
328 count += efi->count + 1;
329 ino = efi->next;
330 brelse (bh);
331 }
332 }
333 }
334 printk("ext_count_free_inodes: stored = %d, computed = %d\n",
335 sb->u.ext_sb.s_freeinodescount, count);
336 unlock_super (sb);
337 return count;
338 #else
339 return sb->u.ext_sb.s_freeinodescount;
340 #endif
341 }