Whamcloud - gitweb
land lustre part of b_hd_sec on HEAD.
[fs/lustre-release.git] / lustre / kernel_patches / patches / ext3-mds-num-2.6.7.patch
1 Index: linux-2.6.7/fs/ext3/namei.c
2 ===================================================================
3 --- linux-2.6.7.orig/fs/ext3/namei.c    2004-09-12 18:53:33.000000000 +0400
4 +++ linux-2.6.7/fs/ext3/namei.c 2004-09-12 19:14:37.000000000 +0400
5 @@ -24,6 +24,7 @@
6   *     Theodore Ts'o, 2002
7   */
8  
9 +#include <linux/module.h>
10  #include <linux/fs.h>
11  #include <linux/pagemap.h>
12  #include <linux/jbd.h>
13 @@ -1150,6 +1151,23 @@
14         inode = NULL;
15         if (bh) {
16                 unsigned long ino = le32_to_cpu(de->inode);
17 +               unsigned type = de->file_type;
18 +               __u32 *mds;
19 +               mds = (__u32 *)((char *) de + EXT3_DIR_REC_LEN(de->name_len));
20 +               if ((type & 128) && EXT3_HAS_INCOMPAT_FEATURE(dir->i_sb,
21 +                               EXT3_FEATURE_INCOMPAT_MDSNUM) &&
22 +                               mds[0] != EXT3_SB(dir->i_sb)->s_mdsnum) {
23 +                       struct ext3_super_block *es;
24 +                       es = EXT3_SB(dir->i_sb)->s_es;
25 +                       brelse (bh);
26 +                       dentry->d_flags |= DCACHE_CROSS_REF;
27 +                       dentry->d_generation = mds[1];
28 +                       dentry->d_mdsnum = mds[0];
29 +                       dentry->d_inum = ino;
30 +                       ext3_unlock_htree(dir, lock);
31 +                       d_add(dentry, NULL);
32 +                       return NULL;
33 +               }
34                 ext3_unlock_htree(dir, lock);
35                 brelse (bh);
36                 inode = iget(dir->i_sb, ino);
37 @@ -1223,7 +1241,7 @@
38         while (count--) {
39                 struct ext3_dir_entry_2 *de =
40                         (struct ext3_dir_entry_2 *) (from + map->offs);
41 -               rec_len = EXT3_DIR_REC_LEN(de->name_len);
42 +               rec_len = EXT3_DIR_REC_LEN_DE(de);
43                 memcpy (to, de, rec_len);
44                 ((struct ext3_dir_entry_2 *) to)->rec_len =
45                                 cpu_to_le16(rec_len);
46 @@ -1245,7 +1263,7 @@
47                 next = (struct ext3_dir_entry_2 *) ((char *) de +
48                                                     le16_to_cpu(de->rec_len));
49                 if (de->inode && de->name_len) {
50 -                       rec_len = EXT3_DIR_REC_LEN(de->name_len);
51 +                       rec_len = EXT3_DIR_REC_LEN_DE(de);
52                         if (de > to)
53                                 memmove(to, de, rec_len);
54                         to->rec_len = cpu_to_le16(rec_len);
55 @@ -1361,6 +1379,7 @@
56                              struct buffer_head * bh)
57  {
58         struct inode    *dir = dentry->d_parent->d_inode;
59 +       struct super_block *sb = dir->i_sb;
60         const char      *name = dentry->d_name.name;
61         int             namelen = dentry->d_name.len;
62         unsigned long   offset = 0;
63 @@ -1369,6 +1388,10 @@
64         char            *top;
65  
66         reclen = EXT3_DIR_REC_LEN(namelen);
67 +       if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_MDSNUM)
68 +                       && (dentry->d_flags & DCACHE_CROSS_REF)
69 +                       && (dentry->d_mdsnum != EXT3_SB(sb)->s_mdsnum))
70 +               reclen += 8; /* we need space to store mds num */
71         if (!de) {
72                 de = (struct ext3_dir_entry_2 *)bh->b_data;
73                 top = bh->b_data + dir->i_sb->s_blocksize - reclen;
74 @@ -1382,7 +1405,7 @@
75                                 brelse (bh);
76                                 return -EEXIST;
77                         }
78 -                       nlen = EXT3_DIR_REC_LEN(de->name_len);
79 +                       nlen = EXT3_DIR_REC_LEN_DE(de);
80                         rlen = le16_to_cpu(de->rec_len);
81                         if ((de->inode? rlen - nlen: rlen) >= reclen)
82                                 break;
83 @@ -1401,7 +1424,7 @@
84         }
85  
86         /* By now the buffer is marked for journaling */
87 -       nlen = EXT3_DIR_REC_LEN(de->name_len);
88 +       nlen = EXT3_DIR_REC_LEN_DE(de);
89         rlen = le16_to_cpu(de->rec_len);
90         if (de->inode) {
91                 struct ext3_dir_entry_2 *de1 =
92 @@ -1413,8 +1436,20 @@
93         de->file_type = EXT3_FT_UNKNOWN;
94         if (inode) {
95                 de->inode = cpu_to_le32(inode->i_ino);
96 -               ext3_set_de_type(dir->i_sb, de, inode->i_mode);
97 -       } else
98 +               ext3_set_de_type(sb, de, inode->i_mode);
99 +       } else if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_MDSNUM)
100 +                       && (dentry->d_flags & DCACHE_CROSS_REF)) {
101 +               if (dentry->d_mdsnum != EXT3_SB(sb)->s_mdsnum) {
102 +                       __u32 *mds;
103 +                       mds = (__u32 *)((char *)de + EXT3_DIR_REC_LEN(namelen));
104 +                       mds[0] = cpu_to_le32(dentry->d_mdsnum);
105 +                       mds[1] = cpu_to_le32(dentry->d_generation);
106 +                       de->inode = cpu_to_le32(dentry->d_inum);
107 +                       de->file_type = 128;
108 +               } else {
109 +                       de->inode = cpu_to_le32(dentry->d_inum);
110 +               }
111 +       } else 
112                 de->inode = 0;
113         de->name_len = namelen;
114         memcpy (de->name, name, namelen);
115 @@ -2721,6 +2756,81 @@
116  }
117  
118  /*
119 + * caller has to make sure directory is protected
120 + */
121 +int ext3_add_dir_entry(struct dentry *dentry)
122 +{
123 +       struct inode *dir = dentry->d_parent->d_inode;
124 +       handle_t *handle;
125 +       int err;
126 +
127 +       handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
128 +                                       EXT3_INDEX_EXTRA_TRANS_BLOCKS);
129 +       if (IS_ERR(handle)) {
130 +               return PTR_ERR(handle);
131 +       }
132 +
133 +       if (IS_SYNC(dir))
134 +               handle->h_sync = 1;
135 +
136 +       err = ext3_add_entry(handle, dentry, NULL);
137 +       ext3_journal_stop(handle);
138 +       return err;
139 +}
140 +EXPORT_SYMBOL(ext3_add_dir_entry);
141 +/*
142 + * caller has to make sure directory is protected
143 + */
144 +int ext3_del_dir_entry(struct dentry *dentry)
145 +{
146 +       struct inode * inode;
147 +       struct inode * dir = dentry->d_parent->d_inode;
148 +       struct buffer_head * bh;
149 +       struct ext3_dir_entry_2 * de;
150 +       handle_t *handle;
151 +       int retval;
152 +       void *lock = NULL;
153 +
154 +       handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
155 +       if (IS_ERR(handle)) {
156 +               return PTR_ERR(handle);
157 +       }
158 +
159 +       if (IS_SYNC(dir))
160 +               handle->h_sync = 1;
161 +
162 +       retval = -ENOENT;
163 +       bh = ext3_find_entry (dentry, &de, 1, &lock);
164 +       ext3_unlock_htree(dir, lock);
165 +       if (!bh)
166 +               goto end_unlink;
167 +
168 +       inode = dentry->d_inode;
169 +       if (inode)
170 +               DQUOT_INIT(inode);
171 +
172 +       retval = ext3_delete_entry(handle, dir, de, bh);
173 +       if (retval)
174 +               goto end_unlink;
175 +       dir->i_ctime = dir->i_mtime = CURRENT_TIME;
176 +       ext3_update_dx_flag(dir);
177 +       if (inode) {
178 +               inode->i_ctime = dir->i_ctime;
179 +               ext3_mark_inode_dirty(handle, inode);
180 +               if (S_ISDIR(inode->i_mode))
181 +                       dir->i_nlink--;
182 +       }
183 +       ext3_mark_inode_dirty(handle, dir);
184 +       retval = 0;
185 +
186 +end_unlink:
187 +       ext3_journal_stop(handle);
188 +       brelse (bh);
189 +       return retval;
190 +}
191 +
192 +EXPORT_SYMBOL(ext3_del_dir_entry);
193 +/*
194   * directories can handle most operations...
195   */
196  struct inode_operations ext3_dir_inode_operations = {
197 Index: linux-2.6.7/fs/ext3/dir.c
198 ===================================================================
199 --- linux-2.6.7.orig/fs/ext3/dir.c      2004-08-26 17:11:31.000000000 +0400
200 +++ linux-2.6.7/fs/ext3/dir.c   2004-09-12 19:14:37.000000000 +0400
201 @@ -53,6 +53,9 @@
202  
203  static unsigned char get_dtype(struct super_block *sb, int filetype)
204  {
205 +       if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_MDSNUM))
206 +               return DT_UNKNOWN;
207 +
208         if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_FILETYPE) ||
209             (filetype >= EXT3_FT_MAX))
210                 return DT_UNKNOWN;
211 @@ -79,7 +82,8 @@
212                 error_msg = "directory entry across blocks";
213         else if (le32_to_cpu(de->inode) >
214                         le32_to_cpu(EXT3_SB(dir->i_sb)->s_es->s_inodes_count))
215 -               error_msg = "inode out of bounds";
216 +               if (de->file_type != 128)
217 +                       error_msg = "inode out of bounds";
218  
219         if (error_msg != NULL)
220                 ext3_error (dir->i_sb, function,
221 Index: linux-2.6.7/include/linux/ext3_fs.h
222 ===================================================================
223 --- linux-2.6.7.orig/include/linux/ext3_fs.h    2004-09-12 19:14:24.000000000 +0400
224 +++ linux-2.6.7/include/linux/ext3_fs.h 2004-09-12 19:15:12.000000000 +0400
225 @@ -452,7 +452,8 @@
226         __u16   s_reserved_word_pad;
227         __u32   s_default_mount_opts;
228         __u32   s_first_meta_bg;        /* First metablock block group */
229 -       __u32   s_reserved[190];        /* Padding to the end of the block */
230 +       __u32   s_mdsnum;
231 +       __u32   s_reserved[189];        /* Padding to the end of the block */
232  };
233  
234  #ifdef __KERNEL__
235 @@ -532,12 +533,14 @@
236  #define EXT3_FEATURE_INCOMPAT_RECOVER          0x0004 /* Needs recovery */
237  #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV      0x0008 /* Journal device */
238  #define EXT3_FEATURE_INCOMPAT_META_BG          0x0010
239 +#define EXT3_FEATURE_INCOMPAT_MDSNUM           0x0020 /* direntry has mdsnum */
240  #define EXT3_FEATURE_INCOMPAT_EXTENTS          0x0040 /* extents support */
241  
242  #define EXT3_FEATURE_COMPAT_SUPP       EXT2_FEATURE_COMPAT_EXT_ATTR
243  #define EXT3_FEATURE_INCOMPAT_SUPP     (EXT3_FEATURE_INCOMPAT_FILETYPE| \
244                                          EXT3_FEATURE_INCOMPAT_RECOVER| \
245                                          EXT3_FEATURE_INCOMPAT_META_BG| \
246 +                                        EXT3_FEATURE_INCOMPAT_MDSNUM| \
247                                          EXT3_FEATURE_INCOMPAT_EXTENTS)
248  #define EXT3_FEATURE_RO_COMPAT_SUPP    (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \
249                                          EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \
250 @@ -612,6 +615,9 @@
251  #define EXT3_DIR_ROUND                 (EXT3_DIR_PAD - 1)
252  #define EXT3_DIR_REC_LEN(name_len)     (((name_len) + 8 + EXT3_DIR_ROUND) & \
253                                          ~EXT3_DIR_ROUND)
254 +#define EXT3_DIR_REC_LEN_DE(de)        (EXT3_DIR_REC_LEN((de)->name_len) + \
255 +                                       (((de)->file_type & 128) ? 8 : 0))
256 +
257  /*
258   * Hash Tree Directory indexing
259   * (c) Daniel Phillips, 2001
260 @@ -827,6 +833,9 @@
261  extern void ext3_ext_release(struct super_block *);
262  extern void ext3_extents_initialize_blockmap(handle_t *, struct inode *);
263  
264 +extern int ext3_add_dir_entry(struct dentry *dentry);
265 +
266 +extern int ext3_del_dir_entry(struct dentry *dentry);
267  #endif /* __KERNEL__ */
268  
269  #define EXT3_IOC_CREATE_INUM                   _IOW('f', 5, long)
270 Index: linux-2.6.7/include/linux/ext3_fs_sb.h
271 ===================================================================
272 --- linux-2.6.7.orig/include/linux/ext3_fs_sb.h 2004-09-12 18:53:33.000000000 +0400
273 +++ linux-2.6.7/include/linux/ext3_fs_sb.h      2004-09-12 19:14:37.000000000 +0400
274 @@ -76,6 +76,7 @@
275         char *s_qf_names[MAXQUOTAS];            /* Names of quota files with journalled quota */
276         int s_jquota_fmt;                       /* Format of quota to use */
277  #endif
278 +       u32 s_mdsnum;
279  };
280  
281  #endif /* _LINUX_EXT3_FS_SB */