1 ===== fs/ext3/ialloc.c 1.26 vs edited =====
2 --- 1.26/fs/ext3/ialloc.c Fri Feb 14 19:24:09 2003
3 +++ edited/fs/ext3/ialloc.c Sat Mar 8 01:20:55 2003
8 + * @block_group: block group of inode
9 + * @offset: relative offset of inode within @block_group
11 + * Check whether any of the inodes in this disk block are in use.
13 + * Caller must be holding superblock lock (group/bitmap read lock in
16 +int ext3_itable_block_used(struct super_block *sb, unsigned int block_group,
19 + struct buffer_head *ibitmap = read_inode_bitmap(sb, block_group);
20 + int inodes_per_block;
21 + unsigned long inum, iend;
26 + inodes_per_block = sb->s_blocksize / EXT3_SB(sb)->s_inode_size;
27 + inum = offset & ~(inodes_per_block - 1);
28 + iend = inum + inodes_per_block;
29 + for (; inum < iend; inum++) {
30 + if (inum != offset && ext3_test_bit(inum, ibitmap->b_data))
38 * There are two policies for allocating an inode. If the new inode is
39 * a directory, then a forward search is made for a block group with both
40 * free space and a low directory-to-inode ratio; if that fails, then of
42 struct ext3_group_desc * gdp;
43 struct ext3_super_block * es;
44 struct ext3_inode_info *ei;
46 + struct ext3_iloc iloc;
50 /* Cannot create files in a deleted directory */
51 if (!dir || !dir->i_nlink)
55 err = ext3_init_acl(handle, inode, dir);
59 + err = ext3_get_inode_loc_new(inode, &iloc, 1);
63 + BUFFER_TRACE(iloc->bh, "get_write_access");
64 + err = ext3_journal_get_write_access(handle, iloc.bh);
66 - DQUOT_FREE_INODE(inode);
69 - err = ext3_mark_inode_dirty(handle, inode);
71 - ext3_std_error(sb, err);
72 - DQUOT_FREE_INODE(inode);
79 + err = ext3_mark_iloc_dirty(handle, inode, &iloc);
83 ext3_debug("allocating inode %lu\n", inode->i_ino);
90 + ext3_std_error(sb, err);
91 + DQUOT_FREE_INODE(inode);
93 inode->i_flags |= S_NOQUOTA;
95 ===== fs/ext3/inode.c 1.62 vs edited =====
96 --- 1.62/fs/ext3/inode.c Fri Feb 14 19:24:09 2003
97 +++ edited/fs/ext3/inode.c Sat Mar 8 02:10:39 2003
98 @@ -2144,69 +2144,118 @@
103 - * ext3_get_inode_loc returns with an extra refcount against the
104 - * inode's underlying buffer_head on success.
106 +#define NUM_INODE_PREREAD 16
108 -int ext3_get_inode_loc (struct inode *inode, struct ext3_iloc *iloc)
110 + * ext3_get_inode_loc returns with an extra refcount against the inode's
111 + * underlying buffer_head on success. If this is for a new inode allocation
112 + * (new is non-zero) then we may be able to optimize away the read if there
113 + * are no other in-use inodes in this inode table block. If we need to do
114 + * a read, then read in a whole chunk of blocks to avoid blocking again soon
115 + * if we are doing lots of creates/updates.
117 +int ext3_get_inode_loc_new(struct inode *inode, struct ext3_iloc *iloc, int new)
119 - struct buffer_head *bh = 0;
120 + struct buffer_head *bh[NUM_INODE_PREREAD];
121 + struct super_block *sb = inode->i_sb;
122 + struct ext3_sb_info *sbi = EXT3_SB(sb);
123 + unsigned long ino = inode->i_ino;
125 unsigned long block_group;
126 unsigned long group_desc;
128 unsigned long offset;
129 struct ext3_group_desc * gdp;
131 - if ((inode->i_ino != EXT3_ROOT_INO &&
132 - inode->i_ino != EXT3_JOURNAL_INO &&
133 - inode->i_ino < EXT3_FIRST_INO(inode->i_sb)) ||
134 - inode->i_ino > le32_to_cpu(
135 - EXT3_SB(inode->i_sb)->s_es->s_inodes_count)) {
136 - ext3_error (inode->i_sb, "ext3_get_inode_loc",
137 - "bad inode number: %lu", inode->i_ino);
139 + if ((ino != EXT3_ROOT_INO && ino != EXT3_JOURNAL_INO &&
140 + ino < EXT3_FIRST_INO(sb)) ||
141 + ino > le32_to_cpu(sbi->s_es->s_inodes_count)) {
142 + ext3_error(sb, "ext3_get_inode_loc", "bad inode number: %lu",
146 - block_group = (inode->i_ino - 1) / EXT3_INODES_PER_GROUP(inode->i_sb);
147 - if (block_group >= EXT3_SB(inode->i_sb)->s_groups_count) {
148 - ext3_error (inode->i_sb, "ext3_get_inode_loc",
149 - "group >= groups count");
150 + block_group = (ino - 1) / EXT3_INODES_PER_GROUP(sb);
151 + if (block_group >= EXT3_SB(sb)->s_groups_count) {
152 + ext3_error(sb, "ext3_get_inode_loc", "group >= groups count");
155 - group_desc = block_group >> EXT3_DESC_PER_BLOCK_BITS(inode->i_sb);
156 - desc = block_group & (EXT3_DESC_PER_BLOCK(inode->i_sb) - 1);
157 - bh = EXT3_SB(inode->i_sb)->s_group_desc[group_desc];
159 - ext3_error (inode->i_sb, "ext3_get_inode_loc",
160 - "Descriptor not loaded");
161 + group_desc = block_group >> EXT3_DESC_PER_BLOCK_BITS(sb);
162 + desc = block_group & (EXT3_DESC_PER_BLOCK(sb) - 1);
163 + if (!sbi->s_group_desc[group_desc]) {
164 + ext3_error(sb, "ext3_get_inode_loc", "Descriptor not loaded");
168 - gdp = (struct ext3_group_desc *) bh->b_data;
169 + gdp = (struct ext3_group_desc *)(sbi->s_group_desc[group_desc]->b_data);
171 * Figure out the offset within the block group inode table
173 - offset = ((inode->i_ino - 1) % EXT3_INODES_PER_GROUP(inode->i_sb)) *
174 - EXT3_INODE_SIZE(inode->i_sb);
175 + offset = ((ino - 1) % EXT3_INODES_PER_GROUP(sb));
176 block = le32_to_cpu(gdp[desc].bg_inode_table) +
177 - (offset >> EXT3_BLOCK_SIZE_BITS(inode->i_sb));
178 - if (!(bh = sb_bread(inode->i_sb, block))) {
179 - ext3_error (inode->i_sb, "ext3_get_inode_loc",
180 - "unable to read inode block - "
181 - "inode=%lu, block=%lu", inode->i_ino, block);
183 + (offset * sbi->s_inode_size >> EXT3_BLOCK_SIZE_BITS(sb));
184 + bh[0] = sb_getblk(sb, block);
185 + if (buffer_uptodate(bh[0]))
188 + /* If we don't really need to read this block, and it isn't already
189 + * in memory, then we just zero it out. Otherwise, we keep the
190 + * current block contents (deleted inode data) for posterity.
192 + if (new && !ext3_itable_block_used(sb, block_group, offset)) {
193 + lock_buffer(bh[0]);
194 + memset(bh[0]->b_data, 0, bh[0]->b_size);
195 + set_buffer_uptodate(bh[0]);
196 + unlock_buffer(bh[0]);
198 + unsigned long block_end, itable_end;
201 + itable_end = le32_to_cpu(gdp[desc].bg_inode_table) +
202 + sbi->s_itb_per_group;
203 + block_end = block + NUM_INODE_PREREAD;
204 + if (block_end > itable_end)
205 + block_end = itable_end;
207 + for (; block < block_end; block++) {
208 + bh[count] = sb_getblk(sb, block);
209 + if (count && (buffer_uptodate(bh[count]) ||
210 + buffer_locked(bh[count]))) {
211 + __brelse(bh[count]);
216 + ll_rw_block(READ, count, bh);
218 + /* Release all but the block we actually need (bh[0]) */
219 + while (--count > 0)
220 + __brelse(bh[count]);
222 + wait_on_buffer(bh[0]);
223 + if (!buffer_uptodate(bh[0])) {
224 + ext3_error(sb, __FUNCTION__,
225 + "unable to read inode block - "
226 + "inode=%lu, block=%llu", ino,
227 + (unsigned long long)bh[0]->b_blocknr);
231 - offset &= (EXT3_BLOCK_SIZE(inode->i_sb) - 1);
233 + offset = (offset * sbi->s_inode_size) & (EXT3_BLOCK_SIZE(sb) - 1);
236 - iloc->raw_inode = (struct ext3_inode *) (bh->b_data + offset);
238 + iloc->raw_inode = (struct ext3_inode *)(bh[0]->b_data + offset);
239 iloc->block_group = block_group;
249 +int ext3_get_inode_loc(struct inode *inode, struct ext3_iloc *iloc)
251 + return ext3_get_inode_loc_new(inode, iloc, 0);
254 void ext3_read_inode(struct inode * inode)
255 ===== include/linux/ext3_fs.h 1.22 vs edited =====
256 --- 1.22/include/linux/ext3_fs.h Tue Jan 14 00:56:29 2003
257 +++ edited/include/linux/ext3_fs.h Sat Mar 8 01:56:28 2003
259 extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *);
260 extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *);
262 +extern int ext3_itable_block_used(struct super_block *, unsigned int, int);
263 +extern int ext3_get_inode_loc_new(struct inode *, struct ext3_iloc *, int);
264 extern int ext3_get_inode_loc (struct inode *, struct ext3_iloc *);
265 extern void ext3_read_inode (struct inode *);
266 extern void ext3_write_inode (struct inode *, int);