Whamcloud - gitweb
b=22771 Patch to disable mbcache
[fs/lustre-release.git] / ldiskfs / kernel_patches / patches / ext3-kill-dx_root.patch
1 Index: b/fs/ext3/namei.c
2 ===================================================================
3 --- a/fs/ext3/namei.c
4 +++ b/fs/ext3/namei.c
5 @@ -115,22 +115,13 @@ struct dx_entry
6   * hash version mod 4 should never be 0.  Sincerely, the paranoia department.
7   */
8  
9 -struct dx_root
10 +struct dx_root_info
11  {
12 -       struct fake_dirent dot;
13 -       char dot_name[4];
14 -       struct fake_dirent dotdot;
15 -       char dotdot_name[4];
16 -       struct dx_root_info
17 -       {
18 -               __le32 reserved_zero;
19 -               u8 hash_version;
20 -               u8 info_length; /* 8 */
21 -               u8 indirect_levels;
22 -               u8 unused_flags;
23 -       }
24 -       info;
25 -       struct dx_entry entries[0];
26 +       __le32 reserved_zero;
27 +       u8 hash_version;
28 +       u8 info_length; /* 8 */
29 +       u8 indirect_levels;
30 +       u8 unused_flags;
31  };
32  
33  struct dx_node
34 @@ -174,6 +165,7 @@ typedef enum {
35  #define LDP_FLAGS_RANGE 0x07
36  
37  #ifdef CONFIG_EXT3_INDEX
38 +struct dx_root_info * dx_get_dx_info(struct ext3_dir_entry_2 *de);
39  static inline unsigned dx_get_block (struct dx_entry *entry);
40  static void dx_set_block (struct dx_entry *entry, unsigned value);
41  static inline unsigned dx_get_hash (struct dx_entry *entry);
42 @@ -210,6 +202,16 @@ static int ext3_dx_add_entry(handle_t *h
43   * Future: use high four bits of block for coalesce-on-delete flags
44   * Mask them off for now.
45   */
46 +struct dx_root_info * dx_get_dx_info(struct ext3_dir_entry_2 *de)
47 +{
48 +       /* get dotdot first */
49 +       de = (struct ext3_dir_entry_2 *)((char *)de + le16_to_cpu(de->rec_len));
50 +
51 +       /* dx root info is after dotdot entry */
52 +       de = (struct ext3_dir_entry_2 *)((char *)de + EXT3_DIR_REC_LEN(2));
53 +
54 +       return (struct dx_root_info *) de;
55 +}
56  
57  static inline unsigned dx_get_block (struct dx_entry *entry)
58  {
59 @@ -362,7 +364,7 @@ dx_probe(struct dentry *dentry, struct i
60  {
61         unsigned count, indirect;
62         struct dx_entry *at, *entries, *p, *q, *m;
63 -       struct dx_root *root;
64 +       struct dx_root_info * info;
65         struct buffer_head *bh;
66         struct dx_frame *frame = frame_in;
67         u32 hash;
68 @@ -372,46 +374,45 @@ dx_probe(struct dentry *dentry, struct i
69                 dir = dentry->d_parent->d_inode;
70         if (!(bh = ext3_bread (NULL,dir, 0, 0, err)))
71                 goto fail;
72 -       root = (struct dx_root *) bh->b_data;
73 -       if (root->info.hash_version != DX_HASH_TEA &&
74 -           root->info.hash_version != DX_HASH_HALF_MD4 &&
75 -           root->info.hash_version != DX_HASH_LEGACY) {
76 +
77 +       info = dx_get_dx_info((struct ext3_dir_entry_2*)bh->b_data);
78 +       if (info->hash_version != DX_HASH_TEA &&
79 +           info->hash_version != DX_HASH_HALF_MD4 &&
80 +           info->hash_version != DX_HASH_LEGACY) {
81                 ext3_warning(dir->i_sb, __FUNCTION__,
82                              "Unrecognised inode hash code %d for directory "
83 -                            "#%lu", root->info.hash_version, dir->i_ino);
84 +                            "#%lu", info->hash_version, dir->i_ino);
85                 brelse(bh);
86                 *err = ERR_BAD_DX_DIR;
87                 goto fail;
88         }
89 -       hinfo->hash_version = root->info.hash_version;
90 +       hinfo->hash_version = info->hash_version;
91         hinfo->seed = EXT3_SB(dir->i_sb)->s_hash_seed;
92         if (dentry)
93                 ext3fs_dirhash(dentry->d_name.name, dentry->d_name.len, hinfo);
94         hash = hinfo->hash;
95  
96 -       if (root->info.unused_flags & 1) {
97 +       if (info->unused_flags & 1) {
98                 ext3_warning(dir->i_sb, __FUNCTION__,
99                              "Unimplemented inode hash flags: %#06x",
100 -                            root->info.unused_flags);
101 +                            info->unused_flags);
102                 brelse(bh);
103                 *err = ERR_BAD_DX_DIR;
104                 goto fail;
105         }
106  
107 -       if ((indirect = root->info.indirect_levels) > 1) {
108 +       if ((indirect = info->indirect_levels) > 1) {
109                 ext3_warning(dir->i_sb, __FUNCTION__,
110                              "Unimplemented inode hash depth: %#06x",
111 -                            root->info.indirect_levels);
112 +                            info->indirect_levels);
113                 brelse(bh);
114                 *err = ERR_BAD_DX_DIR;
115                 goto fail;
116         }
117  
118 -       entries = (struct dx_entry *) (((char *)&root->info) +
119 -                                      root->info.info_length);
120 +       entries = (struct dx_entry *) (((char *)info) + info->info_length);
121  
122 -       if (dx_get_limit(entries) != dx_root_limit(dir,
123 -                                                  root->info.info_length)) {
124 +       if (dx_get_limit(entries) != dx_root_limit(dir, info->info_length)) {
125                 ext3_warning(dir->i_sb, __FUNCTION__,
126                              "dx entry: limit != root limit");
127                 brelse(bh);
128 @@ -467,10 +469,12 @@ fail:
129  
130  static void dx_release (struct dx_frame *frames)
131  {
132 +       struct dx_root_info *info;
133 +
134         if (frames[0].bh == NULL)
135                 return;
136 -
137 -       if (((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels)
138 +       info = dx_get_dx_info((struct ext3_dir_entry_2*)frames[0].bh->b_data);
139 +       if (info->indirect_levels)
140                 brelse(frames[1].bh);
141         brelse(frames[0].bh);
142  }
143 @@ -1419,17 +1423,16 @@ static int make_indexed_dir(handle_t *ha
144         const char      *name = dentry->d_name.name;
145         int             namelen = dentry->d_name.len;
146         struct buffer_head *bh2;
147 -       struct dx_root  *root;
148         struct dx_frame frames[2], *frame;
149         struct dx_entry *entries;
150 -       struct ext3_dir_entry_2 *de, *de2;
151 +       struct ext3_dir_entry_2 *de, *de2, *dot_de, *dotdot_de;
152         char            *data1, *top;
153         unsigned        len;
154         int             retval;
155         unsigned        blocksize;
156         struct dx_hash_info hinfo;
157         u32             block;
158 -       struct fake_dirent *fde;
159 +       struct dx_root_info *dx_info;
160  
161         blocksize =  dir->i_sb->s_blocksize;
162         dxtrace(printk("Creating index\n"));
163 @@ -1439,7 +1442,7 @@ static int make_indexed_dir(handle_t *ha
164                 brelse(bh);
165                 return retval;
166         }
167 -       root = (struct dx_root *) bh->b_data;
168 +       dot_de = (struct ext3_dir_entry_2 *) bh->b_data;
169  
170         bh2 = ext3_append (handle, dir, &block, &retval);
171         if (!(bh2)) {
172 @@ -1450,9 +1453,9 @@ static int make_indexed_dir(handle_t *ha
173         data1 = bh2->b_data;
174  
175         /* The 0th block becomes the root, move the dirents out */
176 -       fde = &root->dotdot;
177 -       de = (struct ext3_dir_entry_2 *)((char *)fde + le16_to_cpu(fde->rec_len));
178 -       len = ((char *) root) + blocksize - (char *) de;
179 +       dotdot_de = (struct ext3_dir_entry_2 *)((char *)dot_de + le16_to_cpu(dot_de->rec_len));
180 +       de = (struct ext3_dir_entry_2 *)((char *)dotdot_de + le16_to_cpu(dotdot_de->rec_len));
181 +       len = ((char *) dot_de) + blocksize - (char *) de;
182         memcpy (data1, de, len);
183         de = (struct ext3_dir_entry_2 *) data1;
184         top = data1 + len;
185 @@ -1460,18 +1463,21 @@ static int make_indexed_dir(handle_t *ha
186                 de = de2;
187         de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de);
188         /* Initialize the root; the dot dirents already exist */
189 -       de = (struct ext3_dir_entry_2 *) (&root->dotdot);
190 -       de->rec_len = cpu_to_le16(blocksize - EXT3_DIR_REC_LEN(2));
191 -       memset (&root->info, 0, sizeof(root->info));
192 -       root->info.info_length = sizeof(root->info);
193 -       root->info.hash_version = EXT3_SB(dir->i_sb)->s_def_hash_version;
194 -       entries = root->entries;
195 +       dotdot_de->rec_len = cpu_to_le16(blocksize - le16_to_cpu(dot_de->rec_len));
196 +
197 +       /* initialize hashing info */
198 +       dx_info = dx_get_dx_info(dot_de);
199 +       memset (dx_info, 0, sizeof(*dx_info));
200 +       dx_info->info_length = sizeof(*dx_info);
201 +       dx_info->hash_version = EXT3_SB(dir->i_sb)->s_def_hash_version;
202 +
203 +       entries = (void *)dx_info + sizeof(*dx_info);
204         dx_set_block (entries, 1);
205         dx_set_count (entries, 1);
206 -       dx_set_limit (entries, dx_root_limit(dir, sizeof(root->info)));
207 +       dx_set_limit (entries, dx_root_limit(dir, sizeof(*dx_info)));
208  
209         /* Initialize as for dx_probe */
210 -       hinfo.hash_version = root->info.hash_version;
211 +       hinfo.hash_version = dx_info->hash_version;
212         hinfo.seed = EXT3_SB(dir->i_sb)->s_hash_seed;
213         ext3fs_dirhash(name, namelen, &hinfo);
214         frame = frames;
215 @@ -1720,6 +1726,7 @@ static int ext3_dx_add_entry(handle_t *h
216                                 goto journal_error;
217                         brelse (bh2);
218                 } else {
219 +                       struct dx_root_info *info;
220                         dxtrace(printk("Creating second level index...\n"));
221                         memcpy((char *) entries2, (char *) entries,
222                                icount * sizeof(struct dx_entry));
223 @@ -1728,7 +1735,8 @@ static int ext3_dx_add_entry(handle_t *h
224                         /* Set up root */
225                         dx_set_count(entries, 1);
226                         dx_set_block(entries + 0, newblock);
227 -                       ((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels = 1;
228 +                       info = dx_get_dx_info((struct ext3_dir_entry_2*)frames[0].bh->b_data);
229 +                       info->indirect_levels = 1;
230  
231                         /* Add new access path frame */
232                         frame = frames + 1;