1 Index: linux-2.4.22-ac1/fs/ext3/ialloc.c
2 ===================================================================
3 --- linux-2.4.22-ac1.orig/fs/ext3/ialloc.c 2003-10-22 14:20:03.000000000 +0400
4 +++ linux-2.4.22-ac1/fs/ext3/ialloc.c 2003-10-29 22:32:28.000000000 +0300
7 bh = sb->u.ext3_sb.s_inode_bitmap[bitmap_nr];
9 - BUFFER_TRACE(bh, "get_write_access");
10 - fatal = ext3_journal_get_write_access(handle, bh);
11 + BUFFER_TRACE(bh, "get_undo_access");
12 + fatal = ext3_journal_get_undo_access(handle, bh);
16 + /* to prevent inode reusing within single transaction -bzzz */
17 + BUFFER_TRACE(bh, "clear in b_committed_data");
18 + J_ASSERT_BH(bh, bh2jh(bh)->b_committed_data != NULL);
19 + ext3_set_bit(bit, bh2jh(bh)->b_committed_data);
21 /* Ok, now we can actually update the inode bitmaps.. */
22 if (!ext3_clear_bit (bit, bh->b_data))
23 ext3_error (sb, "ext3_free_inode",
28 +static int ext3_test_allocatable(int nr, struct buffer_head *bh)
30 + if (ext3_test_bit(nr, bh->b_data))
32 + if (!buffer_jbd(bh) || !bh2jh(bh)->b_committed_data)
35 + if (!ext3_test_bit(nr, bh2jh(bh)->b_committed_data))
36 + printk("EXT3-fs: inode %d was used\n", nr);
38 + return !ext3_test_bit(nr, bh2jh(bh)->b_committed_data);
41 +static int ext3_find_usable_inode(struct super_block *sb,
42 + struct buffer_head *bh)
44 + int here, maxinodes, next;
46 + maxinodes = EXT3_INODES_PER_GROUP(sb);
49 + while (here < maxinodes) {
50 + next = ext3_find_next_zero_bit((unsigned long *) bh->b_data,
52 + if (next >= maxinodes)
54 + if (ext3_test_allocatable(next, bh))
57 + J_ASSERT_BH(bh, bh2jh(bh)->b_committed_data);
58 + here = ext3_find_next_zero_bit
59 + ((unsigned long *) bh2jh(bh)->b_committed_data,
66 * There are two policies for allocating an inode. If the new inode is
67 * a directory, then a forward search is made for a block group with both
69 struct super_block * sb;
70 struct buffer_head * bh;
71 struct buffer_head * bh2;
78 err = ext3_journal_get_write_access(handle, bh);
81 - if (ext3_set_bit(ino, bh->b_data)) {
82 + if (!ext3_test_allocatable(ino, bh) ||
83 + ext3_set_bit(ino, bh->b_data)) {
84 printk(KERN_ERR "goal inode %lu unavailable\n", goal);
85 /* Oh well, we tried. */
88 group = find_group_other(sb, dir);
96 - bitmap_nr = load_inode_bitmap (sb, group);
97 + bitmap_nr = load_inode_bitmap(sb, group);
101 bh = sb->u.ext3_sb.s_inode_bitmap[bitmap_nr];
102 - gdp = ext3_get_group_desc (sb, group, &bh2);
104 - if ((ino = ext3_find_first_zero_bit ((unsigned long *) bh->b_data,
105 - EXT3_INODES_PER_GROUP(sb))) <
106 - EXT3_INODES_PER_GROUP(sb)) {
107 - BUFFER_TRACE(bh, "get_write_access");
108 - err = ext3_journal_get_write_access(handle, bh);
109 - if (err) goto fail;
111 - if (ext3_set_bit (ino, bh->b_data)) {
112 - ext3_error (sb, "ext3_new_inode",
113 - "bit already set for inode %lu", ino);
116 - BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
117 - err = ext3_journal_dirty_metadata(handle, bh);
118 - if (err) goto fail;
120 - if (le16_to_cpu(gdp->bg_free_inodes_count) != 0) {
121 - ext3_error (sb, "ext3_new_inode",
122 - "Free inodes count corrupted in group %d",
124 - /* Is it really ENOSPC? */
126 - if (sb->s_flags & MS_RDONLY)
129 - BUFFER_TRACE(bh2, "get_write_access");
130 - err = ext3_journal_get_write_access(handle, bh2);
131 - if (err) goto fail;
132 - gdp->bg_free_inodes_count = 0;
133 - BUFFER_TRACE(bh2, "call ext3_journal_dirty_metadata");
134 - err = ext3_journal_dirty_metadata(handle, bh2);
135 - if (err) goto fail;
136 + /* try to allocate in selected group */
137 + if ((ino = ext3_find_usable_inode(sb, bh)) >= 0)
140 + /* can't allocate: try to allocate in ANY another groups */
144 + for (group = group + 1; group != k; group++) {
145 + struct ext3_group_desc *tmp;
147 + if (group >= sb->u.ext3_sb.s_groups_count)
149 + tmp = ext3_get_group_desc(sb, group, &bh2);
150 + if (le16_to_cpu(tmp->bg_free_inodes_count) == 0)
153 + bitmap_nr = load_inode_bitmap(sb, group);
156 + bh = sb->u.ext3_sb.s_inode_bitmap[bitmap_nr];
158 + /* try to allocate in selected group */
159 + if ((ino = ext3_find_usable_inode(sb, bh)) >= 0) {
170 + BUFFER_TRACE(bh, "get_undo_access");
171 + err = ext3_journal_get_undo_access(handle, bh);
175 + if (ext3_set_bit(ino, bh->b_data)) {
176 + ext3_error (sb, "ext3_new_inode",
177 + "bit already set for inode %lu",
178 + (unsigned long) ino);
181 + BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
182 + err = ext3_journal_dirty_metadata(handle, bh);
187 ino += group * EXT3_INODES_PER_GROUP(sb) + 1;