1 |
/* Inode allocation routines. |
/* Inode allocation routines. |
2 |
|
|
3 |
Copyright (C) 1995,96,99,2000,02 Free Software Foundation, Inc. |
Copyright (C) 1995,96,99,2000,02,05 Free Software Foundation, Inc. |
4 |
|
|
5 |
Converted to work under the hurd by Miles Bader <miles@gnu.org> |
Converted to work under the hurd by Miles Bader <miles@gnu.org> |
6 |
|
|
60 |
|
|
61 |
assert (!diskfs_readonly); |
assert (!diskfs_readonly); |
62 |
|
|
63 |
ext2_debug ("freeing inode %u", inum); |
ext2_debug ("freeing inode %Lu", inum); |
64 |
|
|
65 |
spin_lock (&global_lock); |
spin_lock (&global_lock); |
66 |
|
|
75 |
bit = (inum - 1) % sblock->s_inodes_per_group; |
bit = (inum - 1) % sblock->s_inodes_per_group; |
76 |
|
|
77 |
gdp = group_desc (block_group); |
gdp = group_desc (block_group); |
78 |
bh = bptr (gdp->bg_inode_bitmap); |
bh = buffer_lookup (gdp->bg_inode_bitmap); |
79 |
|
|
80 |
if (!clear_bit (bit, bh)) |
if (!clear_bit (bit, bh)) |
81 |
ext2_warning ("bit already cleared for inode %Ld", inum); |
ext2_warning ("bit already cleared for inode %Ld", inum); |
82 |
else |
else |
83 |
{ |
{ |
84 |
|
buffer_ref (bh); |
85 |
record_global_poke (bh); |
record_global_poke (bh); |
86 |
|
|
87 |
gdp->bg_free_inodes_count++; |
gdp->bg_free_inodes_count++; |
88 |
if (S_ISDIR (old_mode)) |
if (S_ISDIR (old_mode)) |
89 |
gdp->bg_used_dirs_count--; |
gdp->bg_used_dirs_count--; |
90 |
|
buffer_ref (gdp); |
91 |
record_global_poke (gdp); |
record_global_poke (gdp); |
92 |
|
|
93 |
sblock->s_free_inodes_count++; |
sblock->s_free_inodes_count++; |
94 |
} |
} |
95 |
|
|
96 |
|
buffer_put (bh); |
97 |
sblock_dirty = 1; |
sblock_dirty = 1; |
98 |
spin_unlock (&global_lock); |
spin_unlock (&global_lock); |
99 |
alloc_sync(0); |
alloc_sync(0); |
114 |
ino_t |
ino_t |
115 |
ext2_alloc_inode (ino_t dir_inum, mode_t mode) |
ext2_alloc_inode (ino_t dir_inum, mode_t mode) |
116 |
{ |
{ |
117 |
char *bh; |
char *bh = 0; |
118 |
int i, j, inum, avefreei; |
int i, j, inum, avefreei; |
119 |
struct ext2_group_desc *gdp; |
struct ext2_group_desc *gdp; |
120 |
struct ext2_group_desc *tmp; |
struct ext2_group_desc *tmp; |
121 |
|
|
122 |
spin_lock (&global_lock); |
spin_lock (&global_lock); |
123 |
|
|
124 |
repeat: |
repeat: |
125 |
|
assert (! bh); |
126 |
gdp = NULL; |
gdp = NULL; |
127 |
i = 0; |
i = 0; |
128 |
|
|
217 |
return 0; |
return 0; |
218 |
} |
} |
219 |
|
|
220 |
bh = bptr (gdp->bg_inode_bitmap); |
bh = buffer_lookup (gdp->bg_inode_bitmap); |
221 |
if ((inum = |
if ((inum = |
222 |
find_first_zero_bit ((unsigned long *) bh, sblock->s_inodes_per_group)) |
find_first_zero_bit ((unsigned long *) bh, sblock->s_inodes_per_group)) |
223 |
< sblock->s_inodes_per_group) |
< sblock->s_inodes_per_group) |
225 |
if (set_bit (inum, bh)) |
if (set_bit (inum, bh)) |
226 |
{ |
{ |
227 |
ext2_warning ("bit already set for inode %d", inum); |
ext2_warning ("bit already set for inode %d", inum); |
228 |
|
buffer_put (bh); |
229 |
|
bh = 0; |
230 |
goto repeat; |
goto repeat; |
231 |
} |
} |
232 |
record_global_poke (bh); |
record_global_poke (bh); |
233 |
|
bh = 0; |
234 |
} |
} |
235 |
else |
else |
236 |
{ |
{ |
237 |
|
buffer_put (bh); |
238 |
|
bh = 0; |
239 |
if (gdp->bg_free_inodes_count != 0) |
if (gdp->bg_free_inodes_count != 0) |
240 |
{ |
{ |
241 |
ext2_error ("free inodes count corrupted in group %d", i); |
ext2_error ("free inodes count corrupted in group %d", i); |
257 |
gdp->bg_free_inodes_count--; |
gdp->bg_free_inodes_count--; |
258 |
if (S_ISDIR (mode)) |
if (S_ISDIR (mode)) |
259 |
gdp->bg_used_dirs_count++; |
gdp->bg_used_dirs_count++; |
260 |
|
buffer_ref (gdp); |
261 |
record_global_poke (gdp); |
record_global_poke (gdp); |
262 |
|
|
263 |
sblock->s_free_inodes_count--; |
sblock->s_free_inodes_count--; |
264 |
sblock_dirty = 1; |
sblock_dirty = 1; |
265 |
|
|
266 |
sync_out: |
sync_out: |
267 |
|
assert (! bh); |
268 |
spin_unlock (&global_lock); |
spin_unlock (&global_lock); |
269 |
alloc_sync (0); |
alloc_sync (0); |
270 |
|
|
271 |
|
/* Make sure the coming read_node won't complain about bad |
272 |
|
fields. */ |
273 |
|
{ |
274 |
|
struct ext2_inode *di = dino_lookup (inum); |
275 |
|
memset (di, 0, sizeof *di); |
276 |
|
dino_put (di); |
277 |
|
} |
278 |
|
|
279 |
return inum; |
return inum; |
280 |
} |
} |
281 |
|
|
373 |
gdp = NULL; |
gdp = NULL; |
374 |
for (i = 0; i < groups_count; i++) |
for (i = 0; i < groups_count; i++) |
375 |
{ |
{ |
376 |
|
void *bh; |
377 |
gdp = group_desc (i); |
gdp = group_desc (i); |
378 |
desc_count += gdp->bg_free_inodes_count; |
desc_count += gdp->bg_free_inodes_count; |
379 |
x = count_free (bptr (gdp->bg_inode_bitmap), |
bh = buffer_lookup (gdp->bg_inode_bitmap); |
380 |
sblock->s_inodes_per_group / 8); |
x = count_free (bh, sblock->s_inodes_per_group / 8); |
381 |
|
buffer_put (bh); |
382 |
ext2_debug ("group %d: stored = %d, counted = %lu", |
ext2_debug ("group %d: stored = %d, counted = %lu", |
383 |
i, gdp->bg_free_inodes_count, x); |
i, gdp->bg_free_inodes_count, x); |
384 |
bitmap_count += x; |
bitmap_count += x; |
408 |
gdp = NULL; |
gdp = NULL; |
409 |
for (i = 0; i < groups_count; i++) |
for (i = 0; i < groups_count; i++) |
410 |
{ |
{ |
411 |
|
void *bh; |
412 |
gdp = group_desc (i); |
gdp = group_desc (i); |
413 |
desc_count += gdp->bg_free_inodes_count; |
desc_count += gdp->bg_free_inodes_count; |
414 |
x = count_free (bptr (gdp->bg_inode_bitmap), |
bh = buffer_lookup (gdp->bg_inode_bitmap); |
415 |
sblock->s_inodes_per_group / 8); |
x = count_free (bh, sblock->s_inodes_per_group / 8); |
416 |
|
buffer_put (bh); |
417 |
if (gdp->bg_free_inodes_count != x) |
if (gdp->bg_free_inodes_count != x) |
418 |
ext2_error ("wrong free inodes count in group %d, " |
ext2_error ("wrong free inodes count in group %d, " |
419 |
"stored = %d, counted = %lu", |
"stored = %d, counted = %lu", |