2 * linux/fs/ext/freelists.c
4 * Copyright (C) 1992 Remy Card (card@masi.ibp.fr)
8 /* freelists.c contains the code that handles the inode and block free lists */
13 The free blocks are managed by a linked list. The super block contains the
14 number of the first free block. This block contains 254 numbers of other
15 free blocks and the number of the next block in the list.
17 When an ext fs is mounted, the number of the first free block is stored
18 in s->u.ext_sb.s_firstfreeblocknumber and the block header is stored in
19 s->u.ext_sb.s_firstfreeblock. u.ext_sb.s_freeblockscount contains the count
22 The free inodes are also managed by a linked list in a similar way. The
23 super block contains the number of the first free inode. This inode contains
24 14 numbers of other free inodes and the number of the next inode in the list.
26 The number of the first free inode is stored in
27 s->u.ext_sb.s_firstfreeinodenumber and the header of the block containing
28 the inode is stored in s->u.ext_sb.s_firstfreeinodeblock.
29 u.ext_sb.s_freeinodescount contains the count of free inodes.
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>
40 #define clear_block(addr) \
45 :"a" (0),"c" (BLOCK_SIZE/4),"D" ((long) (addr)):"cx","di")
47 void ext_free_block(struct super_block
* sb
, int block
)
49 struct buffer_head
* bh
;
50 struct ext_free_block
* efb
;
53 printk("trying to free block on non-existent device\n");
57 if (block
< sb
->u
.ext_sb
.s_firstdatazone
||
58 block
>= sb
->u
.ext_sb
.s_nzones
) {
59 printk("trying to free block not in datazone\n");
62 bh
= get_hash_table(sb
->s_dev
, block
, sb
->s_blocksize
);
66 if (sb
->u
.ext_sb
.s_firstfreeblock
)
67 efb
= (struct ext_free_block
*) sb
->u
.ext_sb
.s_firstfreeblock
->b_data
;
68 if (!sb
->u
.ext_sb
.s_firstfreeblock
|| efb
->count
== 254) {
70 printk("ext_free_block: block full, skipping to %d\n", block
);
72 if (sb
->u
.ext_sb
.s_firstfreeblock
)
73 brelse (sb
->u
.ext_sb
.s_firstfreeblock
);
74 if (!(sb
->u
.ext_sb
.s_firstfreeblock
= bread (sb
->s_dev
,
75 block
, sb
->s_blocksize
)))
76 panic ("ext_free_block: unable to read block to free\n");
77 efb
= (struct ext_free_block
*) sb
->u
.ext_sb
.s_firstfreeblock
->b_data
;
78 efb
->next
= sb
->u
.ext_sb
.s_firstfreeblocknumber
;
80 sb
->u
.ext_sb
.s_firstfreeblocknumber
= block
;
82 efb
->free
[efb
->count
++] = block
;
84 sb
->u
.ext_sb
.s_freeblockscount
++;
86 sb
->u
.ext_sb
.s_firstfreeblock
->b_dirt
= 1;
91 int ext_new_block(struct super_block
* sb
)
93 struct buffer_head
* bh
;
94 struct ext_free_block
* efb
;
98 printk("trying to get new block from non-existent device\n");
101 if (!sb
->u
.ext_sb
.s_firstfreeblock
)
104 efb
= (struct ext_free_block
*) sb
->u
.ext_sb
.s_firstfreeblock
->b_data
;
106 j
= efb
->free
[--efb
->count
];
107 sb
->u
.ext_sb
.s_firstfreeblock
->b_dirt
= 1;
110 printk("ext_new_block: block empty, skipping to %d\n", efb
->next
);
112 j
= sb
->u
.ext_sb
.s_firstfreeblocknumber
;
113 sb
->u
.ext_sb
.s_firstfreeblocknumber
= efb
->next
;
114 brelse (sb
->u
.ext_sb
.s_firstfreeblock
);
115 if (!sb
->u
.ext_sb
.s_firstfreeblocknumber
) {
116 sb
->u
.ext_sb
.s_firstfreeblock
= NULL
;
118 if (!(sb
->u
.ext_sb
.s_firstfreeblock
= bread (sb
->s_dev
,
119 sb
->u
.ext_sb
.s_firstfreeblocknumber
,
121 panic ("ext_new_block: unable to read next free block\n");
124 if (j
< sb
->u
.ext_sb
.s_firstdatazone
|| j
> sb
->u
.ext_sb
.s_nzones
) {
125 printk ("ext_new_block: blk = %d\n", j
);
126 printk("allocating block not in data zone\n");
129 sb
->u
.ext_sb
.s_freeblockscount
--;
132 if (!(bh
=getblk(sb
->s_dev
, j
, sb
->s_blocksize
))) {
133 printk("new_block: cannot get block");
136 clear_block(bh
->b_data
);
141 printk("ext_new_block: allocating block %d\n", j
);
147 unsigned long ext_count_free_blocks(struct super_block
*sb
)
150 struct buffer_head
* bh
;
151 struct ext_free_block
* efb
;
152 unsigned long count
, block
;
155 if (!sb
->u
.ext_sb
.s_firstfreeblock
)
158 efb
= (struct ext_free_block
*) sb
->u
.ext_sb
.s_firstfreeblock
->b_data
;
159 count
= efb
->count
+ 1;
162 if (!(bh
= bread (sb
->s_dev
, block
, sb
->s_blocksize
))) {
163 printk ("ext_count_free: error while reading free blocks list\n");
166 efb
= (struct ext_free_block
*) bh
->b_data
;
167 count
+= efb
->count
+ 1;
173 printk("ext_count_free_blocks: stored = %d, computed = %d\n",
174 sb
->u
.ext_sb
.s_freeblockscount
, count
);
178 return sb
->u
.ext_sb
.s_freeblockscount
;
182 void ext_free_inode(struct inode
* inode
)
184 struct buffer_head
* bh
;
185 struct ext_free_inode
* efi
;
186 struct super_block
* sb
;
194 printk("free_inode: inode has no device\n");
197 if (inode
->i_count
!= 1) {
198 printk("free_inode: inode has count=%d\n",inode
->i_count
);
201 if (inode
->i_nlink
) {
202 printk("free_inode: inode has nlink=%d\n",inode
->i_nlink
);
206 printk("free_inode: inode on non-existent device\n");
214 if (ino
< 1 || ino
> sb
->u
.ext_sb
.s_ninodes
) {
215 printk("free_inode: inode 0 or non-existent inode\n");
219 if (sb
->u
.ext_sb
.s_firstfreeinodeblock
)
220 efi
= ((struct ext_free_inode
*) sb
->u
.ext_sb
.s_firstfreeinodeblock
->b_data
) +
221 (sb
->u
.ext_sb
.s_firstfreeinodenumber
-1)%EXT_INODES_PER_BLOCK
;
222 if (!sb
->u
.ext_sb
.s_firstfreeinodeblock
|| efi
->count
== 14) {
224 printk("ext_free_inode: inode full, skipping to %d\n", ino
);
226 if (sb
->u
.ext_sb
.s_firstfreeinodeblock
)
227 brelse (sb
->u
.ext_sb
.s_firstfreeinodeblock
);
228 block
= 2 + (ino
- 1) / EXT_INODES_PER_BLOCK
;
229 if (!(bh
= bread(dev
, block
, sb
->s_blocksize
)))
230 panic("ext_free_inode: unable to read inode block\n");
231 efi
= ((struct ext_free_inode
*) bh
->b_data
) +
232 (ino
- 1) % EXT_INODES_PER_BLOCK
;
233 efi
->next
= sb
->u
.ext_sb
.s_firstfreeinodenumber
;
235 sb
->u
.ext_sb
.s_firstfreeinodenumber
= ino
;
236 sb
->u
.ext_sb
.s_firstfreeinodeblock
= bh
;
238 efi
->free
[efi
->count
++] = ino
;
240 sb
->u
.ext_sb
.s_freeinodescount
++;
242 sb
->u
.ext_sb
.s_firstfreeinodeblock
->b_dirt
= 1;
246 struct inode
* ext_new_inode(const struct inode
* dir
)
248 struct super_block
* sb
;
249 struct inode
* inode
;
250 struct ext_free_inode
* efi
;
254 if (!dir
|| !(inode
=get_empty_inode()))
258 inode
->i_flags
= sb
->s_flags
;
259 if (!sb
->u
.ext_sb
.s_firstfreeinodeblock
)
262 efi
= ((struct ext_free_inode
*) sb
->u
.ext_sb
.s_firstfreeinodeblock
->b_data
) +
263 (sb
->u
.ext_sb
.s_firstfreeinodenumber
-1)%EXT_INODES_PER_BLOCK
;
265 j
= efi
->free
[--efi
->count
];
266 sb
->u
.ext_sb
.s_firstfreeinodeblock
->b_dirt
= 1;
269 printk("ext_free_inode: inode empty, skipping to %d\n", efi
->next
);
271 j
= sb
->u
.ext_sb
.s_firstfreeinodenumber
;
272 if (efi
->next
> sb
->u
.ext_sb
.s_ninodes
) {
273 printk ("efi->next = %d\n", efi
->next
);
274 panic ("ext_new_inode: bad inode number in free list\n");
276 sb
->u
.ext_sb
.s_firstfreeinodenumber
= efi
->next
;
277 block
= 2 + (((unsigned long) efi
->next
) - 1) / EXT_INODES_PER_BLOCK
;
278 brelse (sb
->u
.ext_sb
.s_firstfreeinodeblock
);
279 if (!sb
->u
.ext_sb
.s_firstfreeinodenumber
) {
280 sb
->u
.ext_sb
.s_firstfreeinodeblock
= NULL
;
282 if (!(sb
->u
.ext_sb
.s_firstfreeinodeblock
=
283 bread(sb
->s_dev
, block
, sb
->s_blocksize
)))
284 panic ("ext_new_inode: unable to read next free inode block\n");
287 sb
->u
.ext_sb
.s_freeinodescount
--;
291 inode
->i_dev
= sb
->s_dev
;
292 inode
->i_uid
= current
->euid
;
293 inode
->i_gid
= (dir
->i_mode
& S_ISGID
) ? dir
->i_gid
: current
->egid
;
296 inode
->i_mtime
= inode
->i_atime
= inode
->i_ctime
= CURRENT_TIME
;
298 inode
->i_blocks
= inode
->i_blksize
= 0;
299 insert_inode_hash(inode
);
301 printk("ext_new_inode : allocating inode %d\n", inode
->i_ino
);
307 unsigned long ext_count_free_inodes(struct super_block
*sb
)
310 struct buffer_head
* bh
;
311 struct ext_free_inode
* efi
;
312 unsigned long count
, block
, ino
;
315 if (!sb
->u
.ext_sb
.s_firstfreeinodeblock
)
318 efi
= ((struct ext_free_inode
*) sb
->u
.ext_sb
.s_firstfreeinodeblock
->b_data
) +
319 ((sb
->u
.ext_sb
.s_firstfreeinodenumber
-1)%EXT_INODES_PER_BLOCK
);
320 count
= efi
->count
+ 1;
323 if (ino
< 1 || ino
> sb
->u
.ext_sb
.s_ninodes
) {
324 printk ("u.ext_sb.s_firstfreeinodenumber = %d, ino = %d\n",
325 (int) sb
->u
.ext_sb
.s_firstfreeinodenumber
,ino
);
326 panic ("ext_count_fre_inodes: bad inode number in free list\n");
328 block
= 2 + ((ino
- 1) / EXT_INODES_PER_BLOCK
);
329 if (!(bh
= bread (sb
->s_dev
, block
, sb
->s_blocksize
))) {
330 printk ("ext_count_free_inodes: error while reading free inodes list\n");
333 efi
= ((struct ext_free_inode
*) bh
->b_data
) +
334 ((ino
- 1) % EXT_INODES_PER_BLOCK
);
335 count
+= efi
->count
+ 1;
341 printk("ext_count_free_inodes: stored = %d, computed = %d\n",
342 sb
->u
.ext_sb
.s_freeinodescount
, count
);
346 return sb
->u
.ext_sb
.s_freeinodescount
;