Whamcloud - gitweb
file llobdstat.pl was initially added on branch b_devel.
[fs/lustre-release.git] / lustre / extN / ext3-2.5-noread.diff
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
4 @@ -195,6 +195,36 @@
5  }
6  
7  /*
8 + * @block_group: block group of inode
9 + * @offset: relative offset of inode within @block_group
10 + *
11 + * Check whether any of the inodes in this disk block are in use.
12 + *
13 + * Caller must be holding superblock lock (group/bitmap read lock in
14 + * future).
15 + */
16 +int ext3_itable_block_used(struct super_block *sb, unsigned int block_group,
17 +                          int offset)
18 +{
19 +       struct buffer_head *ibitmap = read_inode_bitmap(sb, block_group);
20 +       int inodes_per_block;
21 +       unsigned long inum, iend;
22 +
23 +       if (!ibitmap)
24 +               return 1;
25 +
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))
31 +                       return 1;
32 +       }
33 +
34 +       return 0;
35 +}
36 +
37 +/*
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
41 @@ -422,8 +452,9 @@
42         struct ext3_group_desc * gdp;
43         struct ext3_super_block * es;
44         struct ext3_inode_info *ei;
45 -       int err = 0;
46 +       struct ext3_iloc iloc;
47         struct inode *ret;
48 +       int err = 0;
49  
50         /* Cannot create files in a deleted directory */
51         if (!dir || !dir->i_nlink)
52 @@ -587,16 +618,23 @@
53                 goto fail2;
54         }
55         err = ext3_init_acl(handle, inode, dir);
56 +       if (err)
57 +               goto fail3;
58 +
59 +       err = ext3_get_inode_loc_new(inode, &iloc, 1);
60 +       if (err)
61 +               goto fail3;
62 +
63 +       BUFFER_TRACE(iloc->bh, "get_write_access");
64 +       err = ext3_journal_get_write_access(handle, iloc.bh);
65         if (err) {
66 -               DQUOT_FREE_INODE(inode);
67 -               goto fail2;
68 -       }
69 -       err = ext3_mark_inode_dirty(handle, inode);
70 -       if (err) {
71 -               ext3_std_error(sb, err);
72 -               DQUOT_FREE_INODE(inode);
73 -               goto fail2;
74 -       }
75 +               brelse(iloc.bh);
76 +               iloc.bh = NULL;
77 +               goto fail3;
78 +       }
79 +       err = ext3_mark_iloc_dirty(handle, inode, &iloc);
80 +       if (err)
81 +               goto fail3;
82  
83         ext3_debug("allocating inode %lu\n", inode->i_ino);
84         goto really_out;
85 @@ -610,6 +648,9 @@
86         brelse(bitmap_bh);
87         return ret;
88  
89 +fail3:
90 +       ext3_std_error(sb, err);
91 +       DQUOT_FREE_INODE(inode);
92  fail2:
93         inode->i_flags |= S_NOQUOTA;
94         inode->i_nlink = 0;
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 @@
99         unlock_kernel();
100  }
101  
102 -/* 
103 - * ext3_get_inode_loc returns with an extra refcount against the
104 - * inode's underlying buffer_head on success. 
105 - */
106 +#define NUM_INODE_PREREAD 16
107  
108 -int ext3_get_inode_loc (struct inode *inode, struct ext3_iloc *iloc)
109 +/*
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.
116 + */
117 +int ext3_get_inode_loc_new(struct inode *inode, struct ext3_iloc *iloc, int new)
118  {
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;
124         unsigned long block;
125         unsigned long block_group;
126         unsigned long group_desc;
127         unsigned long desc;
128         unsigned long offset;
129         struct ext3_group_desc * gdp;
130 -               
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);
138 +
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",
143 +                          ino);
144                 goto bad_inode;
145         }
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");
153                 goto bad_inode;
154         }
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];
158 -       if (!bh) {
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");
165                 goto bad_inode;
166         }
167  
168 -       gdp = (struct ext3_group_desc *) bh->b_data;
169 +       gdp = (struct ext3_group_desc *)(sbi->s_group_desc[group_desc]->b_data);
170         /*
171          * Figure out the offset within the block group inode table
172          */
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);
182 -               goto bad_inode;
183 +               (offset * sbi->s_inode_size >> EXT3_BLOCK_SIZE_BITS(sb));
184 +       bh[0] = sb_getblk(sb, block);
185 +       if (buffer_uptodate(bh[0]))
186 +               goto done;
187 +
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.
191 +        */
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]);
197 +       } else {
198 +               unsigned long block_end, itable_end;
199 +               int count = 1;
200 +
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;
206 +
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]);
212 +                       } else
213 +                               count++;
214 +               }
215 +
216 +               ll_rw_block(READ, count, bh);
217 +
218 +               /* Release all but the block we actually need (bh[0]) */
219 +               while (--count > 0)
220 +                       __brelse(bh[count]);
221 +
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);
228 +                       goto bad_inode;
229 +               }
230         }
231 -       offset &= (EXT3_BLOCK_SIZE(inode->i_sb) - 1);
232 +done:
233 +       offset = (offset * sbi->s_inode_size) & (EXT3_BLOCK_SIZE(sb) - 1);
234  
235 -       iloc->bh = bh;
236 -       iloc->raw_inode = (struct ext3_inode *) (bh->b_data + offset);
237 +       iloc->bh = bh[0];
238 +       iloc->raw_inode = (struct ext3_inode *)(bh[0]->b_data + offset);
239         iloc->block_group = block_group;
240 -       
241 +
242         return 0;
243 -       
244 +
245   bad_inode:
246         return -EIO;
247 +}
248 +
249 +int ext3_get_inode_loc(struct inode *inode, struct ext3_iloc *iloc)
250 +{
251 +       return ext3_get_inode_loc_new(inode, iloc, 0);
252  }
253  
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
258 @@ -719,6 +719,8 @@
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 *);
261  
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);