Whamcloud - gitweb
file llobdstat.pl was initially added on branch b_devel.
[fs/lustre-release.git] / lustre / kernel_patches / patches / ext3-2.4.18-fixes.patch
1 diff -ru lum-2.4.18-um30/fs/ext3/balloc.c uml-2.4.18-12.5/fs/ext3/balloc.c
2 --- lum-2.4.18-um30/fs/ext3/balloc.c    Mon Feb 25 12:38:08 2002
3 +++ uml-2.4.18-12.5/fs/ext3/balloc.c    Thu Sep 19 13:40:11 2002
4 @@ -276,7 +276,8 @@
5         }
6         lock_super (sb);
7         es = sb->u.ext3_sb.s_es;
8 -       if (block < le32_to_cpu(es->s_first_data_block) || 
9 +       if (block < le32_to_cpu(es->s_first_data_block) ||
10 +           block + count < block ||
11             (block + count) > le32_to_cpu(es->s_blocks_count)) {
12                 ext3_error (sb, "ext3_free_blocks",
13                             "Freeing blocks not in datazone - "
14 @@ -309,17 +310,6 @@
15         if (!gdp)
16                 goto error_return;
17  
18 -       if (in_range (le32_to_cpu(gdp->bg_block_bitmap), block, count) ||
19 -           in_range (le32_to_cpu(gdp->bg_inode_bitmap), block, count) ||
20 -           in_range (block, le32_to_cpu(gdp->bg_inode_table),
21 -                     sb->u.ext3_sb.s_itb_per_group) ||
22 -           in_range (block + count - 1, le32_to_cpu(gdp->bg_inode_table),
23 -                     sb->u.ext3_sb.s_itb_per_group))
24 -               ext3_error (sb, "ext3_free_blocks",
25 -                           "Freeing blocks in system zones - "
26 -                           "Block = %lu, count = %lu",
27 -                           block, count);
28 -
29         /*
30          * We are about to start releasing blocks in the bitmap,
31          * so we need undo access.
32 @@ -345,14 +335,24 @@
33         if (err)
34                 goto error_return;
35  
36 -       for (i = 0; i < count; i++) {
37 +       for (i = 0; i < count; i++, block++) {
38 +               if (block == le32_to_cpu(gdp->bg_block_bitmap) ||
39 +                   block == le32_to_cpu(gdp->bg_inode_bitmap) ||
40 +                   in_range(block, le32_to_cpu(gdp->bg_inode_table),
41 +                            sb->u.ext2_sb.s_itb_per_group)) {
42 +                       ext3_error(sb, __FUNCTION__,
43 +                                  "Freeing block in system zone - block = %lu",
44 +                                  block);
45 +                       continue;
46 +               }
47 +
48                 /*
49                  * An HJ special.  This is expensive...
50                  */
51  #ifdef CONFIG_JBD_DEBUG
52                 {
53                         struct buffer_head *debug_bh;
54 -                       debug_bh = sb_get_hash_table(sb, block + i);
55 +                       debug_bh = sb_get_hash_table(sb, block);
56                         if (debug_bh) {
57                                 BUFFER_TRACE(debug_bh, "Deleted!");
58                                 if (!bh2jh(bitmap_bh)->b_committed_data)
59 @@ -365,9 +365,8 @@
60  #endif
61                 BUFFER_TRACE(bitmap_bh, "clear bit");
62                 if (!ext3_clear_bit (bit + i, bitmap_bh->b_data)) {
63 -                       ext3_error (sb, __FUNCTION__,
64 -                                     "bit already cleared for block %lu", 
65 -                                     block + i);
66 +                       ext3_error(sb, __FUNCTION__,
67 +                                  "bit already cleared for block %lu", block);
68                         BUFFER_TRACE(bitmap_bh, "bit already cleared");
69                 } else {
70                         dquot_freed_blocks++;
71 @@ -415,7 +417,6 @@
72         if (!err) err = ret;
73  
74         if (overflow && !err) {
75 -               block += count;
76                 count = overflow;
77                 goto do_more;
78         }
79 @@ -542,6 +543,7 @@
80         int i, j, k, tmp, alloctmp;
81         int bitmap_nr;
82         int fatal = 0, err;
83 +       int performed_allocation = 0;
84         struct super_block * sb;
85         struct ext3_group_desc * gdp;
86         struct ext3_super_block * es;
87 @@ -575,6 +577,7 @@
88  
89         ext3_debug ("goal=%lu.\n", goal);
90  
91 +repeat:
92         /*
93          * First, test whether the goal block is free.
94          */
95 @@ -644,8 +647,7 @@
96         }
97  
98         /* No space left on the device */
99 -       unlock_super (sb);
100 -       return 0;
101 +       goto out;
102  
103  search_back:
104         /* 
105 @@ -684,16 +686,28 @@
106         if (tmp == le32_to_cpu(gdp->bg_block_bitmap) ||
107             tmp == le32_to_cpu(gdp->bg_inode_bitmap) ||
108             in_range (tmp, le32_to_cpu(gdp->bg_inode_table),
109 -                     sb->u.ext3_sb.s_itb_per_group))
110 -               ext3_error (sb, "ext3_new_block",
111 -                           "Allocating block in system zone - "
112 -                           "block = %u", tmp);
113 +                     EXT3_SB(sb)->s_itb_per_group)) {
114 +               ext3_error(sb, __FUNCTION__,
115 +                          "Allocating block in system zone - block = %u", tmp);
116 +
117 +               /* Note: This will potentially use up one of the handle's
118 +                * buffer credits.  Normally we have way too many credits,
119 +                * so that is OK.  In _very_ rare cases it might not be OK.
120 +                * We will trigger an assertion if we run out of credits,
121 +                * and we will have to do a full fsck of the filesystem -
122 +                * better than randomly corrupting filesystem metadata.
123 +                */
124 +               ext3_set_bit(j, bh->b_data);
125 +               goto repeat;
126 +       }
127 +
128  
129         /* The superblock lock should guard against anybody else beating
130          * us to this point! */
131         J_ASSERT_BH(bh, !ext3_test_bit(j, bh->b_data));
132         BUFFER_TRACE(bh, "setting bitmap bit");
133         ext3_set_bit(j, bh->b_data);
134 +       performed_allocation = 1;
135  
136  #ifdef CONFIG_JBD_DEBUG
137         {
138 @@ -815,6 +829,11 @@
139                 ext3_std_error(sb, fatal);
140         }
141         unlock_super (sb);
142 +       /*
143 +        * Undo the block allocation
144 +        */
145 +       if (!performed_allocation)
146 +               DQUOT_FREE_BLOCK(inode, 1);
147         return 0;
148         
149  }
150 diff -ru lum-2.4.18-um30/fs/ext3/file.c uml-2.4.18-12.5/fs/ext3/file.c
151 --- lum-2.4.18-um30/fs/ext3/file.c      Thu Nov 15 14:37:55 2001
152 +++ uml-2.4.18-12.5/fs/ext3/file.c      Thu Sep 19 13:40:11 2002
153 @@ -61,19 +61,52 @@
154  static ssize_t
155  ext3_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
156  {
157 +       int ret, err;
158         struct inode *inode = file->f_dentry->d_inode;
159  
160 -       /*
161 -        * Nasty: if the file is subject to synchronous writes then we need
162 -        * to force generic_osync_inode() to call ext3_write_inode().
163 -        * We do that by marking the inode dirty.  This adds much more
164 -        * computational expense than we need, but we're going to sync
165 -        * anyway.
166 -        */
167 -       if (IS_SYNC(inode) || (file->f_flags & O_SYNC))
168 -               mark_inode_dirty(inode);
169 +       ret = generic_file_write(file, buf, count, ppos);
170  
171 -       return generic_file_write(file, buf, count, ppos);
172 +       /* Skip file flushing code if there was an error, or if nothing
173 +          was written. */
174 +       if (ret <= 0)
175 +               return ret;
176 +       
177 +       /* If the inode is IS_SYNC, or is O_SYNC and we are doing
178 +           data-journaling, then we need to make sure that we force the
179 +           transaction to disk to keep all metadata uptodate
180 +           synchronously. */
181 +
182 +       if (file->f_flags & O_SYNC) {
183 +               /* If we are non-data-journaled, then the dirty data has
184 +                   already been flushed to backing store by
185 +                   generic_osync_inode, and the inode has been flushed
186 +                   too if there have been any modifications other than
187 +                   mere timestamp updates.
188 +                  
189 +                  Open question --- do we care about flushing
190 +                  timestamps too if the inode is IS_SYNC? */
191 +               if (!ext3_should_journal_data(inode))
192 +                       return ret;
193 +
194 +               goto force_commit;
195 +       }
196 +
197 +       /* So we know that there has been no forced data flush.  If the
198 +           inode is marked IS_SYNC, we need to force one ourselves. */
199 +       if (!IS_SYNC(inode))
200 +               return ret;
201 +       
202 +       /* Open question #2 --- should we force data to disk here too?
203 +           If we don't, the only impact is that data=writeback
204 +           filesystems won't flush data to disk automatically on
205 +           IS_SYNC, only metadata (but historically, that is what ext2
206 +           has done.) */
207 +       
208 +force_commit:
209 +       err = ext3_force_commit(inode->i_sb);
210 +       if (err) 
211 +               return err;
212 +       return ret;
213  }
214  
215  struct file_operations ext3_file_operations = {
216 diff -ru lum-2.4.18-um30/fs/ext3/fsync.c uml-2.4.18-12.5/fs/ext3/fsync.c
217 --- lum-2.4.18-um30/fs/ext3/fsync.c     Tue Nov 20 22:34:13 2001
218 +++ uml-2.4.18-12.5/fs/ext3/fsync.c     Thu Sep 19 13:40:11 2002
219 @@ -62,7 +62,12 @@
220          * we'll end up waiting on them in commit.
221          */
222         ret = fsync_inode_buffers(inode);
223 -       ret |= fsync_inode_data_buffers(inode);
224 +
225 +       /* In writeback mode, we need to force out data buffers too.  In
226 +        * the other modes, ext3_force_commit takes care of forcing out
227 +        * just the right data blocks. */
228 +       if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA)
229 +               ret |= fsync_inode_data_buffers(inode);
230  
231         ext3_force_commit(inode->i_sb);
232  
233 diff -ru lum-2.4.18-um30/fs/ext3/ialloc.c uml-2.4.18-12.5/fs/ext3/ialloc.c
234 --- lum-2.4.18-um30/fs/ext3/ialloc.c    Mon Feb 25 12:38:08 2002
235 +++ uml-2.4.18-12.5/fs/ext3/ialloc.c    Thu Sep 19 13:40:11 2002
236 @@ -392,7 +392,7 @@
237  
238         err = -ENOSPC;
239         if (!gdp)
240 -               goto fail;
241 +               goto out;
242  
243         err = -EIO;
244         bitmap_nr = load_inode_bitmap (sb, i);
245 @@ -523,9 +523,10 @@
246         return inode;
247  
248  fail:
249 +       ext3_std_error(sb, err);
250 +out:
251         unlock_super(sb);
252         iput(inode);
253 -       ext3_std_error(sb, err);
254         return ERR_PTR(err);
255  }
256  
257 diff -ru lum-2.4.18-um30/fs/ext3/inode.c uml-2.4.18-12.5/fs/ext3/inode.c
258 --- lum-2.4.18-um30/fs/ext3/inode.c     Mon Feb 25 12:38:08 2002
259 +++ uml-2.4.18-12.5/fs/ext3/inode.c     Thu Sep 19 13:40:11 2002
260 @@ -412,6 +412,7 @@
261         return NULL;
262  
263  changed:
264 +       brelse(bh);
265         *err = -EAGAIN;
266         goto no_block;
267  failure:
268 @@ -581,8 +582,6 @@
269                         
270                         parent = nr;
271                 }
272 -               if (IS_SYNC(inode))
273 -                       handle->h_sync = 1;
274         }
275         if (n == num)
276                 return 0;
277 @@ -1015,8 +1018,8 @@
278                               unsigned from, unsigned to)
279  {
280         struct inode *inode = page->mapping->host;
281 -       handle_t *handle = ext3_journal_current_handle();
282         int ret, needed_blocks = ext3_writepage_trans_blocks(inode);
283 +       handle_t *handle;
284  
285         lock_kernel();
286         handle = ext3_journal_start(inode, needed_blocks);
287 diff -ru lum-2.4.18-um30/fs/ext3/namei.c uml-2.4.18-12.5/fs/ext3/namei.c
288 --- lum-2.4.18-um30/fs/ext3/namei.c     Fri Nov  9 15:25:04 2001
289 +++ uml-2.4.18-12.5/fs/ext3/namei.c     Thu Sep 19 13:40:11 2002
290 @@ -354,8 +355,8 @@
291                          */
292                         dir->i_mtime = dir->i_ctime = CURRENT_TIME;
293                         dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
294 -                       ext3_mark_inode_dirty(handle, dir);
295                         dir->i_version = ++event;
296 +                       ext3_mark_inode_dirty(handle, dir);
297                         BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
298                         ext3_journal_dirty_metadata(handle, bh);
299                         brelse(bh);
300 @@ -464,8 +465,8 @@
301                 inode->i_op = &ext3_file_inode_operations;
302                 inode->i_fop = &ext3_file_operations;
303                 inode->i_mapping->a_ops = &ext3_aops;
304 -               ext3_mark_inode_dirty(handle, inode);
305                 err = ext3_add_nondir(handle, dentry, inode);
306 +               ext3_mark_inode_dirty(handle, inode);
307         }
308         ext3_journal_stop(handle, dir);
309         return err;
310 @@ -489,8 +490,8 @@
311         err = PTR_ERR(inode);
312         if (!IS_ERR(inode)) {
313                 init_special_inode(inode, mode, rdev);
314 -               ext3_mark_inode_dirty(handle, inode);
315                 err = ext3_add_nondir(handle, dentry, inode);
316 +               ext3_mark_inode_dirty(handle, inode);
317         }
318         ext3_journal_stop(handle, dir);
319         return err;
320 @@ -933,8 +934,8 @@
321                 inode->i_size = l-1;
322         }
323         inode->u.ext3_i.i_disksize = inode->i_size;
324 -       ext3_mark_inode_dirty(handle, inode);
325         err = ext3_add_nondir(handle, dentry, inode);
326 +       ext3_mark_inode_dirty(handle, inode);
327  out_stop:
328         ext3_journal_stop(handle, dir);
329         return err;
330 @@ -970,8 +971,8 @@
331         ext3_inc_count(handle, inode);
332         atomic_inc(&inode->i_count);
333  
334 -       ext3_mark_inode_dirty(handle, inode);
335         err = ext3_add_nondir(handle, dentry, inode);
336 +       ext3_mark_inode_dirty(handle, inode);
337         ext3_journal_stop(handle, dir);
338         return err;
339  }
340 diff -ru lum-2.4.18-um30/fs/ext3/super.c uml-2.4.18-12.5/fs/ext3/super.c
341 --- lum-2.4.18-um30/fs/ext3/super.c     Fri Jul 12 17:59:37 2002
342 +++ uml-2.4.18-12.5/fs/ext3/super.c     Thu Sep 19 13:40:11 2002
343 @@ -1589,8 +1589,10 @@
344                 journal_t *journal = EXT3_SB(sb)->s_journal;
345  
346                 /* Now we set up the journal barrier. */
347 +               unlock_super(sb);
348                 journal_lock_updates(journal);
349                 journal_flush(journal);
350 +               lock_super(sb);
351  
352                 /* Journal blocked and flushed, clear needs_recovery flag. */
353                 EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);