Whamcloud - gitweb
973d02f4d01e21516229861edf1c433bb825fdb0
[fs/lustre-release.git] / lustre / kernel_patches / patches / ext3-mds-num-2.6.10-fc3.patch
1 Index: linux-2.6.10/fs/ext3/dir.c
2 ===================================================================
3 --- linux-2.6.10.orig/fs/ext3/dir.c     2004-12-25 05:34:57.000000000 +0800
4 +++ linux-2.6.10/fs/ext3/dir.c  2005-03-31 18:56:02.961946200 +0800
5 @@ -53,6 +53,9 @@
6  
7  static unsigned char get_dtype(struct super_block *sb, int filetype)
8  {
9 +       if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_MDSNUM))
10 +               return DT_UNKNOWN;
11 +
12         if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_FILETYPE) ||
13             (filetype >= EXT3_FT_MAX))
14                 return DT_UNKNOWN;
15 @@ -79,7 +82,8 @@
16                 error_msg = "directory entry across blocks";
17         else if (le32_to_cpu(de->inode) >
18                         le32_to_cpu(EXT3_SB(dir->i_sb)->s_es->s_inodes_count))
19 -               error_msg = "inode out of bounds";
20 +               if (de->file_type != 128)
21 +                       error_msg = "inode out of bounds";
22  
23         if (error_msg != NULL)
24                 ext3_error (dir->i_sb, function,
25 Index: linux-2.6.10/fs/ext3/namei.c
26 ===================================================================
27 --- linux-2.6.10.orig/fs/ext3/namei.c   2005-03-31 18:41:15.880803032 +0800
28 +++ linux-2.6.10/fs/ext3/namei.c        2005-03-31 18:56:02.960946352 +0800
29 @@ -24,6 +24,7 @@
30   *     Theodore Ts'o, 2002
31   */
32  
33 +#include <linux/module.h>
34  #include <linux/fs.h>
35  #include <linux/pagemap.h>
36  #include <linux/jbd.h>
37 @@ -1148,6 +1149,23 @@
38         inode = NULL;
39         if (bh) {
40                 unsigned long ino = le32_to_cpu(de->inode);
41 +               unsigned type = de->file_type;
42 +               __u32 *mds;
43 +               mds = (__u32 *)((char *) de + EXT3_DIR_REC_LEN(de->name_len));
44 +               if ((type & 128) && EXT3_HAS_INCOMPAT_FEATURE(dir->i_sb,
45 +                               EXT3_FEATURE_INCOMPAT_MDSNUM) &&
46 +                               mds[0] != EXT3_SB(dir->i_sb)->s_mdsnum) {
47 +                       struct ext3_super_block *es;
48 +                       es = EXT3_SB(dir->i_sb)->s_es;
49 +                       brelse (bh);
50 +                       dentry->d_flags |= DCACHE_CROSS_REF;
51 +                       dentry->d_generation = mds[1];
52 +                       dentry->d_mdsnum = mds[0];
53 +                       dentry->d_inum = ino;
54 +                       ext3_unlock_htree(dir, lock);
55 +                       d_add(dentry, NULL);
56 +                       return NULL;
57 +               }
58                 ext3_unlock_htree(dir, lock);
59                 brelse (bh);
60                 inode = iget(dir->i_sb, ino);
61 @@ -1221,7 +1239,7 @@
62         while (count--) {
63                 struct ext3_dir_entry_2 *de =
64                         (struct ext3_dir_entry_2 *) (from + map->offs);
65 -               rec_len = EXT3_DIR_REC_LEN(de->name_len);
66 +               rec_len = EXT3_DIR_REC_LEN_DE(de);
67                 memcpy (to, de, rec_len);
68                 ((struct ext3_dir_entry_2 *) to)->rec_len =
69                                 cpu_to_le16(rec_len);
70 @@ -1243,7 +1261,7 @@
71                 next = (struct ext3_dir_entry_2 *) ((char *) de +
72                                                     le16_to_cpu(de->rec_len));
73                 if (de->inode && de->name_len) {
74 -                       rec_len = EXT3_DIR_REC_LEN(de->name_len);
75 +                       rec_len = EXT3_DIR_REC_LEN_DE(de);
76                         if (de > to)
77                                 memmove(to, de, rec_len);
78                         to->rec_len = cpu_to_le16(rec_len);
79 @@ -1359,6 +1377,7 @@
80                              struct buffer_head * bh)
81  {
82         struct inode    *dir = dentry->d_parent->d_inode;
83 +       struct super_block *sb = dir->i_sb;
84         const char      *name = dentry->d_name.name;
85         int             namelen = dentry->d_name.len;
86         unsigned long   offset = 0;
87 @@ -1367,6 +1386,10 @@
88         char            *top;
89  
90         reclen = EXT3_DIR_REC_LEN(namelen);
91 +       if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_MDSNUM)
92 +                       && (dentry->d_flags & DCACHE_CROSS_REF)
93 +                       && (dentry->d_mdsnum != EXT3_SB(sb)->s_mdsnum))
94 +               reclen += 8; /* we need space to store mds num */
95         if (!de) {
96                 de = (struct ext3_dir_entry_2 *)bh->b_data;
97                 top = bh->b_data + dir->i_sb->s_blocksize - reclen;
98 @@ -1380,7 +1403,7 @@
99                                 brelse (bh);
100                                 return -EEXIST;
101                         }
102 -                       nlen = EXT3_DIR_REC_LEN(de->name_len);
103 +                       nlen = EXT3_DIR_REC_LEN_DE(de);
104                         rlen = le16_to_cpu(de->rec_len);
105                         if ((de->inode? rlen - nlen: rlen) >= reclen)
106                                 break;
107 @@ -1399,7 +1422,7 @@
108         }
109  
110         /* By now the buffer is marked for journaling */
111 -       nlen = EXT3_DIR_REC_LEN(de->name_len);
112 +       nlen = EXT3_DIR_REC_LEN_DE(de);
113         rlen = le16_to_cpu(de->rec_len);
114         if (de->inode) {
115                 struct ext3_dir_entry_2 *de1 =
116 @@ -1411,8 +1434,20 @@
117         de->file_type = EXT3_FT_UNKNOWN;
118         if (inode) {
119                 de->inode = cpu_to_le32(inode->i_ino);
120 -               ext3_set_de_type(dir->i_sb, de, inode->i_mode);
121 -       } else
122 +               ext3_set_de_type(sb, de, inode->i_mode);
123 +       } else if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_MDSNUM)
124 +                       && (dentry->d_flags & DCACHE_CROSS_REF)) {
125 +               if (dentry->d_mdsnum != EXT3_SB(sb)->s_mdsnum) {
126 +                       __u32 *mds;
127 +                       mds = (__u32 *)((char *)de + EXT3_DIR_REC_LEN(namelen));
128 +                       mds[0] = cpu_to_le32(dentry->d_mdsnum);
129 +                       mds[1] = cpu_to_le32(dentry->d_generation);
130 +                       de->inode = cpu_to_le32(dentry->d_inum);
131 +                       de->file_type = 128;
132 +               } else {
133 +                       de->inode = cpu_to_le32(dentry->d_inum);
134 +               }
135 +       } else 
136                 de->inode = 0;
137         de->name_len = namelen;
138         memcpy (de->name, name, namelen);
139 @@ -2737,6 +2772,81 @@
140  }
141  
142  /*
143 + * caller has to make sure directory is protected
144 + */
145 +int ext3_add_dir_entry(struct dentry *dentry)
146 +{
147 +       struct inode *dir = dentry->d_parent->d_inode;
148 +       handle_t *handle;
149 +       int err;
150 +
151 +       handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
152 +                                       EXT3_INDEX_EXTRA_TRANS_BLOCKS);
153 +       if (IS_ERR(handle)) {
154 +               return PTR_ERR(handle);
155 +       }
156 +
157 +       if (IS_SYNC(dir))
158 +               handle->h_sync = 1;
159 +
160 +       err = ext3_add_entry(handle, dentry, NULL);
161 +       ext3_journal_stop(handle);
162 +       return err;
163 +}
164 +EXPORT_SYMBOL(ext3_add_dir_entry);
165 +/*
166 + * caller has to make sure directory is protected
167 + */
168 +int ext3_del_dir_entry(struct dentry *dentry)
169 +{
170 +       struct inode * inode;
171 +       struct inode * dir = dentry->d_parent->d_inode;
172 +       struct buffer_head * bh;
173 +       struct ext3_dir_entry_2 * de;
174 +       handle_t *handle;
175 +       int retval;
176 +       void *lock = NULL;
177 +
178 +       handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
179 +       if (IS_ERR(handle)) {
180 +               return PTR_ERR(handle);
181 +       }
182 +
183 +       if (IS_SYNC(dir))
184 +               handle->h_sync = 1;
185 +
186 +       retval = -ENOENT;
187 +       bh = ext3_find_entry (dentry, &de, 1, &lock);
188 +       ext3_unlock_htree(dir, lock);
189 +       if (!bh)
190 +               goto end_unlink;
191 +
192 +       inode = dentry->d_inode;
193 +       if (inode)
194 +               DQUOT_INIT(inode);
195 +
196 +       retval = ext3_delete_entry(handle, dir, de, bh);
197 +       if (retval)
198 +               goto end_unlink;
199 +       dir->i_ctime = dir->i_mtime = CURRENT_TIME;
200 +       ext3_update_dx_flag(dir);
201 +       if (inode) {
202 +               inode->i_ctime = dir->i_ctime;
203 +               ext3_mark_inode_dirty(handle, inode);
204 +               if (S_ISDIR(inode->i_mode))
205 +                       dir->i_nlink--;
206 +       }
207 +       ext3_mark_inode_dirty(handle, dir);
208 +       retval = 0;
209 +
210 +end_unlink:
211 +       ext3_journal_stop(handle);
212 +       brelse (bh);
213 +       return retval;
214 +}
215 +
216 +EXPORT_SYMBOL(ext3_del_dir_entry);
217 +/*
218   * directories can handle most operations...
219   */
220  struct inode_operations ext3_dir_inode_operations = {
221 Index: linux-2.6.10/include/linux/ext3_fs.h
222 ===================================================================
223 --- linux-2.6.10.orig/include/linux/ext3_fs.h   2005-03-31 18:54:32.497698856 +0800
224 +++ linux-2.6.10/include/linux/ext3_fs.h        2005-03-31 18:56:41.955018352 +0800
225 @@ -483,7 +483,8 @@
226         __u16   s_reserved_word_pad;
227         __le32  s_default_mount_opts;
228         __le32  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 @@ -563,12 +564,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 @@ -643,6 +646,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 @@ -868,6 +874,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.10/include/linux/ext3_fs_sb.h
271 ===================================================================
272 --- linux-2.6.10.orig/include/linux/ext3_fs_sb.h        2005-03-31 18:44:21.076648984 +0800
273 +++ linux-2.6.10/include/linux/ext3_fs_sb.h     2005-03-31 18:56:02.964945744 +0800
274 @@ -81,6 +81,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 */