1 Index: linux-2.4.24/fs/ext3/namei.c
2 ===================================================================
3 --- linux-2.4.24.orig/fs/ext3/namei.c 2004-03-01 19:42:04.000000000 +0300
4 +++ linux-2.4.24/fs/ext3/namei.c 2004-03-29 19:27:13.000000000 +0400
8 unsigned long ino = le32_to_cpu(de->inode);
9 + unsigned type = de->file_type;
11 + mds = (__u32 *)((char *) de + EXT3_DIR_REC_LEN(de->name_len));
12 + if ((type & 128) && EXT3_HAS_INCOMPAT_FEATURE(dir->i_sb,
13 + EXT3_FEATURE_INCOMPAT_MDSNUM) &&
14 + mds[0] != EXT3_SB(dir->i_sb)->s_mdsnum) {
15 + struct ext3_super_block *es;
16 + es = EXT3_SB(dir->i_sb)->s_es;
17 + ext3_unlock_htree(dir, lock);
19 + dentry->d_flags |= DCACHE_CROSS_REF;
20 + dentry->d_generation = mds[1];
21 + dentry->d_mdsnum = mds[0];
22 + dentry->d_inum = ino;
23 + d_add(dentry, NULL);
26 ext3_unlock_htree(dir, lock);
28 inode = iget(dir->i_sb, ino);
31 struct ext3_dir_entry_2 *de =
32 (struct ext3_dir_entry_2 *) (from + map->offs);
33 - rec_len = EXT3_DIR_REC_LEN(de->name_len);
34 + rec_len = EXT3_DIR_REC_LEN_DE(de);
35 memcpy (to, de, rec_len);
36 ((struct ext3_dir_entry_2 *) to)->rec_len = rec_len;
39 next = (struct ext3_dir_entry_2 *) ((char *) de +
40 le16_to_cpu(de->rec_len));
41 if (de->inode && de->name_len) {
42 - rec_len = EXT3_DIR_REC_LEN(de->name_len);
43 + rec_len = EXT3_DIR_REC_LEN_DE(de);
45 memmove(to, de, rec_len);
46 to->rec_len = rec_len;
48 struct buffer_head * bh)
50 struct inode *dir = dentry->d_parent->d_inode;
51 + struct super_block *sb = dir->i_sb;
52 const char *name = dentry->d_name.name;
53 int namelen = dentry->d_name.len;
54 unsigned long offset = 0;
55 @@ -1305,6 +1323,10 @@
58 reclen = EXT3_DIR_REC_LEN(namelen);
59 + if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_MDSNUM)
60 + && (dentry->d_flags & DCACHE_CROSS_REF)
61 + && (dentry->d_mdsnum != EXT3_SB(sb)->s_mdsnum))
62 + reclen += 8; /* we need space to store mds num */
64 de = (struct ext3_dir_entry_2 *)bh->b_data;
65 top = bh->b_data + dir->i_sb->s_blocksize - reclen;
70 - nlen = EXT3_DIR_REC_LEN(de->name_len);
71 + nlen = EXT3_DIR_REC_LEN_DE(de);
72 rlen = le16_to_cpu(de->rec_len);
73 if ((de->inode? rlen - nlen: rlen) >= reclen)
78 /* By now the buffer is marked for journaling */
79 - nlen = EXT3_DIR_REC_LEN(de->name_len);
80 + nlen = EXT3_DIR_REC_LEN_DE(de);
81 rlen = le16_to_cpu(de->rec_len);
83 struct ext3_dir_entry_2 *de1 =
84 @@ -1349,8 +1371,20 @@
85 de->file_type = EXT3_FT_UNKNOWN;
87 de->inode = cpu_to_le32(inode->i_ino);
88 - ext3_set_de_type(dir->i_sb, de, inode->i_mode);
90 + ext3_set_de_type(sb, de, inode->i_mode);
91 + } else if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_MDSNUM)
92 + && (dentry->d_flags & DCACHE_CROSS_REF)) {
93 + if (dentry->d_mdsnum != EXT3_SB(sb)->s_mdsnum) {
95 + mds = (__u32 *)((char *)de + EXT3_DIR_REC_LEN(namelen));
96 + mds[0] = cpu_to_le32(dentry->d_mdsnum);
97 + mds[1] = cpu_to_le32(dentry->d_generation);
98 + de->inode = cpu_to_le32(dentry->d_inum);
99 + de->file_type = 128;
101 + de->inode = cpu_to_le32(dentry->d_inum);
105 de->name_len = namelen;
106 memcpy (de->name, name, namelen);
107 @@ -2662,6 +2696,77 @@
111 + * caller has to make sure directory is protected
113 +int ext3_add_dir_entry(struct dentry *dentry)
115 + struct inode *dir = dentry->d_parent->d_inode;
119 + handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
120 + EXT3_INDEX_EXTRA_TRANS_BLOCKS);
121 + if (IS_ERR(handle)) {
122 + return PTR_ERR(handle);
126 + handle->h_sync = 1;
128 + err = ext3_add_entry(handle, dentry, NULL);
129 + ext3_journal_stop(handle, dir);
134 + * caller has to make sure directory is protected
136 +int ext3_del_dir_entry(struct dentry *dentry)
138 + struct inode * inode;
139 + struct inode * dir = dentry->d_parent->d_inode;
140 + struct buffer_head * bh;
141 + struct ext3_dir_entry_2 * de;
146 + handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
147 + if (IS_ERR(handle)) {
148 + return PTR_ERR(handle);
152 + handle->h_sync = 1;
155 + bh = ext3_find_entry (dentry, &de, 1, &lock);
159 + inode = dentry->d_inode;
163 + retval = ext3_delete_entry(handle, dir, de, bh);
164 + ext3_unlock_htree(dir, lock);
167 + dir->i_ctime = dir->i_mtime = CURRENT_TIME;
168 + ext3_update_dx_flag(dir);
169 + ext3_mark_inode_dirty(handle, dir);
171 + inode->i_ctime = dir->i_ctime;
172 + ext3_mark_inode_dirty(handle, inode);
177 + ext3_journal_stop(handle, dir);
182 * directories can handle most operations...
184 struct inode_operations ext3_dir_inode_operations = {
185 Index: linux-2.4.24/fs/ext3/dir.c
186 ===================================================================
187 --- linux-2.4.24.orig/fs/ext3/dir.c 2004-03-01 19:20:49.000000000 +0300
188 +++ linux-2.4.24/fs/ext3/dir.c 2004-03-01 19:42:15.000000000 +0300
191 static unsigned char get_dtype(struct super_block *sb, int filetype)
193 + if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_MDSNUM))
196 if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_FILETYPE) ||
197 (filetype >= EXT3_FT_MAX))
199 Index: linux-2.4.24/fs/ext3/ext3-exports.c
200 ===================================================================
201 --- linux-2.4.24.orig/fs/ext3/ext3-exports.c 2004-03-01 19:20:50.000000000 +0300
202 +++ linux-2.4.24/fs/ext3/ext3-exports.c 2004-03-11 23:40:49.000000000 +0300
204 EXPORT_SYMBOL(ext3_decode_error);
205 EXPORT_SYMBOL(__ext3_std_error);
207 +int ext3_add_dir_entry (struct dentry *dentry);
208 +EXPORT_SYMBOL(ext3_add_dir_entry);
209 +int ext3_del_dir_entry(struct dentry *dentry);
210 +EXPORT_SYMBOL(ext3_del_dir_entry);
214 Index: linux-2.4.24/include/linux/ext3_fs.h
215 ===================================================================
216 --- linux-2.4.24.orig/include/linux/ext3_fs.h 2004-03-01 19:42:04.000000000 +0300
217 +++ linux-2.4.24/include/linux/ext3_fs.h 2004-03-01 19:42:15.000000000 +0300
219 __u8 s_def_hash_version; /* Default hash version to use */
220 __u8 s_reserved_char_pad;
221 __u16 s_reserved_word_pad;
222 - __u32 s_reserved[192]; /* Padding to the end of the block */
224 + __u32 s_reserved[191]; /* Padding to the end of the block */
228 @@ -504,10 +505,12 @@
229 #define EXT3_FEATURE_INCOMPAT_FILETYPE 0x0002
230 #define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */
231 #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */
232 +#define EXT3_FEATURE_INCOMPAT_MDSNUM 0x0020 /* direntry has mdsnum */
234 #define EXT3_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR
235 #define EXT3_FEATURE_INCOMPAT_SUPP (EXT3_FEATURE_INCOMPAT_FILETYPE| \
236 - EXT3_FEATURE_INCOMPAT_RECOVER)
237 + EXT3_FEATURE_INCOMPAT_RECOVER| \
238 + EXT3_FEATURE_INCOMPAT_MDSNUM)
239 #define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \
240 EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \
241 EXT3_FEATURE_RO_COMPAT_BTREE_DIR)
243 #define EXT3_DIR_ROUND (EXT3_DIR_PAD - 1)
244 #define EXT3_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT3_DIR_ROUND) & \
246 +#define EXT3_DIR_REC_LEN_DE(de) (EXT3_DIR_REC_LEN((de)->name_len) + \
247 + (((de)->file_type & 128) ? 8 : 0))
250 * Hash Tree Directory indexing
251 * (c) Daniel Phillips, 2001
252 Index: linux-2.4.24/include/linux/ext3_fs_sb.h
253 ===================================================================
254 --- linux-2.4.24.orig/include/linux/ext3_fs_sb.h 2004-03-01 19:20:49.000000000 +0300
255 +++ linux-2.4.24/include/linux/ext3_fs_sb.h 2004-03-01 19:42:21.000000000 +0300
257 wait_queue_head_t s_delete_thread_queue;
258 wait_queue_head_t s_delete_waiter_queue;
263 #endif /* _LINUX_EXT3_FS_SB */
264 Index: linux-2.4.24/include/linux/dcache.h
265 ===================================================================
266 --- linux-2.4.24.orig/include/linux/dcache.h 2004-03-01 19:20:49.000000000 +0300
267 +++ linux-2.4.24/include/linux/dcache.h 2004-03-01 19:42:15.000000000 +0300
270 unsigned int d_flags;
271 struct inode * d_inode; /* Where the name belongs to - NULL is negative */
272 + unsigned d_inum; /* for cross-fs references (Lustre) */
273 + unsigned d_mdsnum; /* for cross-fs references (Lustre) */
274 + unsigned d_generation; /* for cross-fs references (Lustre) */
275 struct dentry * d_parent; /* parent directory */
276 struct list_head d_hash; /* lookup hash list */
277 struct list_head d_lru; /* d_count = 0 LRU list */
280 #define DCACHE_REFERENCED 0x0008 /* Recently used, don't discard. */
281 #define DCACHE_LUSTRE_INVALID 0x0010 /* Lustre invalidated */
282 +#define DCACHE_CROSS_REF 0x0020 /* entry points to inode on another MDS */
284 extern spinlock_t dcache_lock;