1 fs/ext3/ialloc.c | 47 +++++++++++++++++++++-
2 fs/ext3/inode.c | 99 ++++++++++++++++++++++++++++++++++++------------
3 include/linux/ext3_fs.h | 2
4 3 files changed, 122 insertions(+), 26 deletions(-)
6 --- linux-2.4.18-chaos52/fs/ext3/ialloc.c~extN-noread 2003-05-16 12:26:29.000000000 +0800
7 +++ linux-2.4.18-chaos52-root/fs/ext3/ialloc.c 2003-05-16 12:26:31.000000000 +0800
8 @@ -289,6 +289,37 @@ error_return:
12 + * @block_group: block group of inode
13 + * @offset: relative offset of inode within @block_group
15 + * Check whether any of the inodes in this disk block are in use.
17 + * Caller must be holding superblock lock (group/bitmap read lock in future).
19 +int ext3_itable_block_used(struct super_block *sb, unsigned int block_group,
22 + int bitmap_nr = load_inode_bitmap(sb, block_group);
23 + int inodes_per_block;
24 + unsigned long inum, iend;
25 + struct buffer_head *ibitmap;
30 + inodes_per_block = sb->s_blocksize / EXT3_SB(sb)->s_inode_size;
31 + inum = offset & ~(inodes_per_block - 1);
32 + iend = inum + inodes_per_block;
33 + ibitmap = EXT3_SB(sb)->s_inode_bitmap[bitmap_nr];
34 + for (; inum < iend; inum++) {
35 + if (inum != offset && ext3_test_bit(inum, ibitmap->b_data))
43 * There are two policies for allocating an inode. If the new inode is
44 * a directory, then a forward search is made for a block group with both
45 * free space and a low directory-to-inode ratio; if that fails, then of
46 @@ -312,6 +343,7 @@ struct inode * ext3_new_inode (handle_t
47 struct ext3_group_desc * gdp;
48 struct ext3_group_desc * tmp;
49 struct ext3_super_block * es;
50 + struct ext3_iloc iloc;
53 /* Cannot create files in a deleted directory */
54 @@ -505,7 +537,7 @@ repeat:
55 ei->i_prealloc_count = 0;
57 ei->i_block_group = i;
60 if (ei->i_flags & EXT3_SYNC_FL)
61 inode->i_flags |= S_SYNC;
63 @@ -514,9 +546,18 @@ repeat:
64 inode->i_generation = sbi->s_next_generation++;
66 ei->i_state = EXT3_STATE_NEW;
67 - err = ext3_mark_inode_dirty(handle, inode);
68 + err = ext3_get_inode_loc_new(inode, &iloc, 1);
71 + BUFFER_TRACE(iloc->bh, "get_write_access");
72 + err = ext3_journal_get_write_access(handle, iloc.bh);
78 + err = ext3_mark_iloc_dirty(handle, inode, &iloc);
82 if(DQUOT_ALLOC_INODE(inode)) {
84 --- linux-2.4.18-chaos52/fs/ext3/inode.c~extN-noread 2003-05-16 12:26:29.000000000 +0800
85 +++ linux-2.4.18-chaos52-root/fs/ext3/inode.c 2003-05-16 12:27:06.000000000 +0800
86 @@ -2013,21 +2013,26 @@ out_stop:
89 - * ext3_get_inode_loc returns with an extra refcount against the
90 - * inode's underlying buffer_head on success.
92 +#define NUM_INODE_PREREAD 16
94 -int ext3_get_inode_loc (struct inode *inode, struct ext3_iloc *iloc)
96 + * ext3_get_inode_loc returns with an extra refcount against the inode's
97 + * underlying buffer_head on success. If this is for a new inode allocation
98 + * (new is non-zero) then we may be able to optimize away the read if there
99 + * are no other in-use inodes in this inode table block. If we need to do
100 + * a read, then read in a whole chunk of blocks to avoid blocking again soon
101 + * if we are doing lots of creates/updates.
103 +int ext3_get_inode_loc_new(struct inode *inode, struct ext3_iloc *iloc, int new)
105 struct super_block *sb = inode->i_sb;
106 struct ext3_sb_info *sbi = EXT3_SB(sb);
107 - struct buffer_head *bh = 0;
108 + struct buffer_head *bh[NUM_INODE_PREREAD];
110 unsigned long block_group;
111 unsigned long group_desc;
113 unsigned long offset;
114 struct ext3_group_desc * gdp;
117 if ((inode->i_ino != EXT3_ROOT_INO &&
118 inode->i_ino != EXT3_JOURNAL_INO &&
119 inode->i_ino < EXT3_FIRST_INO(sb)) ||
120 @@ -2042,38 +2047,86 @@ int ext3_get_inode_loc (struct inode *in
122 group_desc = block_group >> sbi->s_desc_per_block_bits;
123 desc = block_group & (sbi->s_desc_per_block - 1);
124 - bh = sbi->s_group_desc[group_desc];
126 + if (!sbi->s_group_desc[group_desc]) {
127 ext3_error(sb, __FUNCTION__, "Descriptor not loaded");
131 - gdp = (struct ext3_group_desc *) bh->b_data;
132 + gdp = (struct ext3_group_desc *)(sbi->s_group_desc[group_desc]->b_data);
135 * Figure out the offset within the block group inode table
137 - offset = ((inode->i_ino - 1) % sbi->s_inodes_per_group) *
139 + offset = ((inode->i_ino - 1) % sbi->s_inodes_per_group);
141 block = le32_to_cpu(gdp[desc].bg_inode_table) +
142 - (offset >> EXT3_BLOCK_SIZE_BITS(sb));
143 - if (!(bh = sb_bread(sb, block))) {
144 - ext3_error (sb, __FUNCTION__,
145 - "unable to read inode block - "
146 - "inode=%lu, block=%lu", inode->i_ino, block);
148 + (offset * sbi->s_inode_size >> EXT3_BLOCK_SIZE_BITS(sb));
150 + bh[0] = sb_getblk(sb, block);
151 + if (buffer_uptodate(bh[0]))
154 + /* If we don't really need to read this block, and it isn't already
155 + * in memory, then we just zero it out. Otherwise, we keep the
156 + * current block contents (deleted inode data) for posterity.
158 + if (new && !ext3_itable_block_used(sb, block_group, offset)) {
159 + lock_buffer(bh[0]);
160 + memset(bh[0]->b_data, 0, bh[0]->b_size);
161 + mark_buffer_uptodate(bh[0], 1);
162 + unlock_buffer(bh[0]);
164 + unsigned long block_end, itable_end;
167 + itable_end = le32_to_cpu(gdp[desc].bg_inode_table) +
168 + sbi->s_itb_per_group;
169 + block_end = block + NUM_INODE_PREREAD;
170 + if (block_end > itable_end)
171 + block_end = itable_end;
173 + for (++block; block < block_end; block++) {
174 + bh[count] = sb_getblk(sb, block);
175 + if (count && (buffer_uptodate(bh[count]) ||
176 + buffer_locked(bh[count]))) {
177 + __brelse(bh[count]);
182 + ll_rw_block(READ, count, bh);
184 + /* Release all but the block we actually need (bh[0]) */
185 + while (--count > 0)
186 + __brelse(bh[count]);
188 + wait_on_buffer(bh[0]);
189 + if (!buffer_uptodate(bh[0])) {
190 + ext3_error(sb, __FUNCTION__,
191 + "unable to read inode block - "
192 + "inode=%lu, block=%lu", inode->i_ino,
197 - offset &= (EXT3_BLOCK_SIZE(sb) - 1);
199 + offset = (offset * sbi->s_inode_size) & (EXT3_BLOCK_SIZE(sb) - 1);
202 - iloc->raw_inode = (struct ext3_inode *) (bh->b_data + offset);
204 + iloc->raw_inode = (struct ext3_inode *)(bh[0]->b_data + offset);
205 iloc->block_group = block_group;
215 +int ext3_get_inode_loc(struct inode *inode, struct ext3_iloc *iloc)
217 + return ext3_get_inode_loc_new(inode, iloc, 0);
220 void ext3_read_inode(struct inode * inode)
222 struct ext3_iloc iloc;
223 --- linux-2.4.18-chaos52/include/linux/ext3_fs.h~extN-noread 2003-05-16 12:26:29.000000000 +0800
224 +++ linux-2.4.18-chaos52-root/include/linux/ext3_fs.h 2003-05-16 12:26:31.000000000 +0800
225 @@ -640,6 +640,8 @@ extern int ext3_forget(handle_t *, int,
226 extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *);
227 extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *);
229 +extern int ext3_itable_block_used(struct super_block *sb, unsigned int, int);
230 +extern int ext3_get_inode_loc_new(struct inode *, struct ext3_iloc *, int);
231 extern int ext3_get_inode_loc (struct inode *, struct ext3_iloc *);
232 extern void ext3_read_inode (struct inode *);
233 extern void ext3_write_inode (struct inode *, int);