1 Index: linux-2.4.24/fs/ext3/namei.c
2 ===================================================================
3 --- linux-2.4.24.orig/fs/ext3/namei.c 2004-06-23 08:31:23.000000000 +0400
4 +++ linux-2.4.24/fs/ext3/namei.c 2004-06-23 08:32:59.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 = cpu_to_le16(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 = cpu_to_le16(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 @@ -1283,6 +1301,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 @@ -1327,8 +1349,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,79 @@
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);
170 + inode->i_ctime = dir->i_ctime;
171 + ext3_mark_inode_dirty(handle, inode);
172 + if (S_ISDIR(inode->i_mode))
175 + ext3_mark_inode_dirty(handle, dir);
179 + ext3_journal_stop(handle, dir);
184 * directories can handle most operations...
186 struct inode_operations ext3_dir_inode_operations = {
187 Index: linux-2.4.24/fs/ext3/dir.c
188 ===================================================================
189 --- linux-2.4.24.orig/fs/ext3/dir.c 2004-06-23 08:31:21.000000000 +0400
190 +++ linux-2.4.24/fs/ext3/dir.c 2004-06-23 08:31:23.000000000 +0400
193 static unsigned char get_dtype(struct super_block *sb, int filetype)
195 + if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_MDSNUM))
198 if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_FILETYPE) ||
199 (filetype >= EXT3_FT_MAX))
201 Index: linux-2.4.24/fs/ext3/ext3-exports.c
202 ===================================================================
203 --- linux-2.4.24.orig/fs/ext3/ext3-exports.c 2004-06-23 08:31:22.000000000 +0400
204 +++ linux-2.4.24/fs/ext3/ext3-exports.c 2004-06-23 08:31:23.000000000 +0400
206 EXPORT_SYMBOL(ext3_decode_error);
207 EXPORT_SYMBOL(__ext3_std_error);
209 +int ext3_add_dir_entry (struct dentry *dentry);
210 +EXPORT_SYMBOL(ext3_add_dir_entry);
211 +int ext3_del_dir_entry(struct dentry *dentry);
212 +EXPORT_SYMBOL(ext3_del_dir_entry);
216 Index: linux-2.4.24/include/linux/ext3_fs.h
217 ===================================================================
218 --- linux-2.4.24.orig/include/linux/ext3_fs.h 2004-06-23 08:31:23.000000000 +0400
219 +++ linux-2.4.24/include/linux/ext3_fs.h 2004-06-23 08:31:23.000000000 +0400
221 __u8 s_def_hash_version; /* Default hash version to use */
222 __u8 s_reserved_char_pad;
223 __u16 s_reserved_word_pad;
224 - __u32 s_reserved[192]; /* Padding to the end of the block */
226 + __u32 s_reserved[191]; /* Padding to the end of the block */
230 @@ -518,10 +519,12 @@
231 #define EXT3_FEATURE_INCOMPAT_FILETYPE 0x0002
232 #define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */
233 #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */
234 +#define EXT3_FEATURE_INCOMPAT_MDSNUM 0x0020 /* direntry has mdsnum */
236 #define EXT3_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR
237 #define EXT3_FEATURE_INCOMPAT_SUPP (EXT3_FEATURE_INCOMPAT_FILETYPE| \
238 - EXT3_FEATURE_INCOMPAT_RECOVER)
239 + EXT3_FEATURE_INCOMPAT_RECOVER| \
240 + EXT3_FEATURE_INCOMPAT_MDSNUM)
241 #define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \
242 EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \
243 EXT3_FEATURE_RO_COMPAT_BTREE_DIR)
245 #define EXT3_DIR_ROUND (EXT3_DIR_PAD - 1)
246 #define EXT3_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT3_DIR_ROUND) & \
248 +#define EXT3_DIR_REC_LEN_DE(de) (EXT3_DIR_REC_LEN((de)->name_len) + \
249 + (((de)->file_type & 128) ? 8 : 0))
252 * Hash Tree Directory indexing
253 * (c) Daniel Phillips, 2001
254 Index: linux-2.4.24/include/linux/ext3_fs_sb.h
255 ===================================================================
256 --- linux-2.4.24.orig/include/linux/ext3_fs_sb.h 2004-06-23 08:31:21.000000000 +0400
257 +++ linux-2.4.24/include/linux/ext3_fs_sb.h 2004-06-23 08:31:23.000000000 +0400
259 wait_queue_head_t s_delete_thread_queue;
260 wait_queue_head_t s_delete_waiter_queue;
265 #endif /* _LINUX_EXT3_FS_SB */
266 Index: linux-2.4.24/include/linux/dcache.h
267 ===================================================================
268 --- linux-2.4.24.orig/include/linux/dcache.h 2004-06-23 08:31:22.000000000 +0400
269 +++ linux-2.4.24/include/linux/dcache.h 2004-06-23 08:31:23.000000000 +0400
272 unsigned int d_flags;
273 struct inode * d_inode; /* Where the name belongs to - NULL is negative */
274 + unsigned d_inum; /* for cross-fs references (Lustre) */
275 + unsigned d_mdsnum; /* for cross-fs references (Lustre) */
276 + unsigned d_generation; /* for cross-fs references (Lustre) */
277 struct dentry * d_parent; /* parent directory */
278 struct list_head d_hash; /* lookup hash list */
279 struct list_head d_lru; /* d_count = 0 LRU list */
282 #define DCACHE_REFERENCED 0x0008 /* Recently used, don't discard. */
283 #define DCACHE_LUSTRE_INVALID 0x0010 /* Lustre invalidated */
284 +#define DCACHE_CROSS_REF 0x0020 /* entry points to inode on another MDS */
286 extern spinlock_t dcache_lock;