Whamcloud - gitweb
- many fixes in GNS code after Nikita's code review. They are the following:
[fs/lustre-release.git] / lustre / kernel_patches / patches / ext3-inode-reuse-2.6.7.patch
1 Index: linux-2.6.7/fs/ext3/ialloc.c
2 ===================================================================
3 --- linux-2.6.7.orig/fs/ext3/ialloc.c   2004-10-05 21:15:58.000000000 +0400
4 +++ linux-2.6.7/fs/ext3/ialloc.c        2004-10-06 17:14:39.776562240 +0400
5 @@ -144,11 +144,16 @@
6         if (!bitmap_bh)
7                 goto error_return;
8  
9 -       BUFFER_TRACE(bitmap_bh, "get_write_access");
10 -       fatal = ext3_journal_get_write_access(handle, bitmap_bh);
11 +       BUFFER_TRACE(bitmap_bh, "get_undo_access");
12 +       fatal = ext3_journal_get_undo_access(handle, bitmap_bh, NULL);
13         if (fatal)
14                 goto error_return;
15  
16 +       /* to prevent inode reusing within single transaction -bzzz */
17 +       BUFFER_TRACE(bitmap_bh, "clear in b_committed_data");
18 +       J_ASSERT_BH(bitmap_bh, bh2jh(bitmap_bh)->b_committed_data != NULL);
19 +       ext3_set_bit(bit, bh2jh(bitmap_bh)->b_committed_data);
20 +
21         /* Ok, now we can actually update the inode bitmaps.. */
22         if (!ext3_clear_bit_atomic(sb_bgl_lock(sbi, block_group),
23                                         bit, bitmap_bh->b_data))
24 @@ -411,6 +416,16 @@
25  }
26  
27  /*
28 + * this is just to check was block freed in current transaction -bzzz
29 + */
30 +static int ext3_test_allocatable(int nr, struct buffer_head *bh)
31 +{
32 +       if (!buffer_jbd(bh) || !bh2jh(bh)->b_committed_data)
33 +               return 1;
34 +       return !ext3_test_bit(nr, bh2jh(bh)->b_committed_data);
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 @@ -426,7 +441,7 @@
42         struct super_block *sb;
43         struct buffer_head *bitmap_bh = NULL;
44         struct buffer_head *bh2;
45 -       int group;
46 +       int group, credits;
47         unsigned long ino = 0;
48         struct inode * inode;
49         struct ext3_group_desc * gdp = NULL;
50 @@ -459,16 +474,25 @@
51                 if (!bitmap_bh)
52                         goto fail;
53  
54 -               BUFFER_TRACE(bh, "get_write_access");
55 -               err = ext3_journal_get_write_access(handle, bitmap_bh);
56 +               BUFFER_TRACE(bh, "get_undo_access");
57 +               err = ext3_journal_get_undo_access(handle, bitmap_bh, &credits);
58                 if (err) goto fail;
59  
60 -               if (ext3_set_bit_atomic(sb_bgl_lock(sbi, group),
61 -                                       ino, bitmap_bh->b_data)) {
62 +               if (!ext3_test_allocatable(ino, bitmap_bh) || 
63 +                       ext3_set_bit_atomic(sb_bgl_lock(sbi, group),
64 +                                               ino, bitmap_bh->b_data)) {
65                         printk(KERN_ERR "goal inode %lu unavailable\n", goal);
66                         /* Oh well, we tried. */
67                         goto continue_allocation;
68                 }
69 +               if (!ext3_test_allocatable(ino, bitmap_bh)) {
70 +                       /* in theory it's possible another that thread has
71 +                        * allocated and freed block between test_allocatable()
72 +                        * and set_bit_atomic(). so, we we have to check
73 +                        * this -bzzz */
74 +                       journal_release_buffer(handle, bitmap_bh, credits);
75 +                       goto continue_allocation;
76 +               }
77  
78                 BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
79                 err = ext3_journal_dirty_metadata(handle, bitmap_bh);
80 @@ -511,21 +535,29 @@
81                         int credits = 0;
82  
83                         BUFFER_TRACE(bitmap_bh, "get_write_access");
84 -                       err = ext3_journal_get_write_access_credits(handle,
85 +                       err = ext3_journal_get_undo_access(handle,
86                                                         bitmap_bh, &credits);
87                         if (err)
88                                 goto fail;
89  
90 -                       if (!ext3_set_bit_atomic(sb_bgl_lock(sbi, group),
91 -                                               ino, bitmap_bh->b_data)) {
92 -                               /* we won it */
93 -                               BUFFER_TRACE(bitmap_bh,
94 -                                       "call ext3_journal_dirty_metadata");
95 -                               err = ext3_journal_dirty_metadata(handle,
96 -                                                               bitmap_bh);
97 -                               if (err)
98 -                                       goto fail;
99 -                               goto got;
100 +                       if (ext3_test_allocatable(ino, bitmap_bh) &&
101 +                               !ext3_set_bit_atomic(sb_bgl_lock(sbi, group),
102 +                                                       ino, bitmap_bh->b_data)) {
103 +                               /* in theory it's possible another that
104 +                                * thread has allocated and freed block
105 +                                * between ext3_test_allocatable() and
106 +                                * set_bit_atomic(). so, we we have to
107 +                                * check this -bzzz */
108 +                               if (ext3_test_allocatable(ino, bitmap_bh)) {
109 +                                       /* we won it */
110 +                                       BUFFER_TRACE(bitmap_bh,
111 +                                                       "call ext3_journal_dirty_metadata");
112 +                                       err = ext3_journal_dirty_metadata(handle,
113 +                                                                       bitmap_bh);
114 +                                       if (err)
115 +                                               goto fail;
116 +                                       goto got;
117 +                               }
118                         }
119                         /* we lost it */
120                         journal_release_buffer(handle, bitmap_bh, credits);