1 Index: linux-2.4.24/fs/ext3/namei.c
2 ===================================================================
3 --- linux-2.4.24.orig/fs/ext3/namei.c 2004-07-19 11:11:29.000000000 +0400
4 +++ linux-2.4.24/fs/ext3/namei.c 2004-07-19 11:11:29.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-07-19 11:11:16.000000000 +0400
190 +++ linux-2.4.24/fs/ext3/dir.c 2004-07-30 23:56:03.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))
202 else if (((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize)
203 error_msg = "directory entry across blocks";
204 else if (le32_to_cpu(de->inode) >
205 - le32_to_cpu(dir->i_sb->u.ext3_sb.s_es->s_inodes_count))
206 - error_msg = "inode out of bounds";
207 + le32_to_cpu(dir->i_sb->u.ext3_sb.s_es->s_inodes_count)) {
208 + if (de->file_type != 128)
209 + error_msg = "inode out of bounds";
212 if (error_msg != NULL)
213 ext3_error (dir->i_sb, function,
214 Index: linux-2.4.24/fs/ext3/ext3-exports.c
215 ===================================================================
216 --- linux-2.4.24.orig/fs/ext3/ext3-exports.c 2004-07-19 11:11:16.000000000 +0400
217 +++ linux-2.4.24/fs/ext3/ext3-exports.c 2004-07-19 11:11:29.000000000 +0400
219 EXPORT_SYMBOL(ext3_decode_error);
220 EXPORT_SYMBOL(__ext3_std_error);
222 +int ext3_add_dir_entry (struct dentry *dentry);
223 +EXPORT_SYMBOL(ext3_add_dir_entry);
224 +int ext3_del_dir_entry(struct dentry *dentry);
225 +EXPORT_SYMBOL(ext3_del_dir_entry);
229 Index: linux-2.4.24/include/linux/ext3_fs.h
230 ===================================================================
231 --- linux-2.4.24.orig/include/linux/ext3_fs.h 2004-07-19 11:11:29.000000000 +0400
232 +++ linux-2.4.24/include/linux/ext3_fs.h 2004-07-19 11:13:53.000000000 +0400
234 __u8 s_def_hash_version; /* Default hash version to use */
235 __u8 s_reserved_char_pad;
236 __u16 s_reserved_word_pad;
237 - __u32 s_reserved[192]; /* Padding to the end of the block */
239 + __u32 s_reserved[191]; /* Padding to the end of the block */
243 @@ -519,10 +520,12 @@
244 #define EXT3_FEATURE_INCOMPAT_FILETYPE 0x0002
245 #define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */
246 #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */
247 +#define EXT3_FEATURE_INCOMPAT_MDSNUM 0x0020 /* direntry has mdsnum */
249 #define EXT3_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR
250 #define EXT3_FEATURE_INCOMPAT_SUPP (EXT3_FEATURE_INCOMPAT_FILETYPE| \
251 - EXT3_FEATURE_INCOMPAT_RECOVER)
252 + EXT3_FEATURE_INCOMPAT_RECOVER| \
253 + EXT3_FEATURE_INCOMPAT_MDSNUM)
254 #define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \
255 EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \
256 EXT3_FEATURE_RO_COMPAT_BTREE_DIR)
258 #define EXT3_DIR_ROUND (EXT3_DIR_PAD - 1)
259 #define EXT3_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT3_DIR_ROUND) & \
261 +#define EXT3_DIR_REC_LEN_DE(de) (EXT3_DIR_REC_LEN((de)->name_len) + \
262 + (((de)->file_type & 128) ? 8 : 0))
265 * Hash Tree Directory indexing
266 * (c) Daniel Phillips, 2001
267 Index: linux-2.4.24/include/linux/ext3_fs_sb.h
268 ===================================================================
269 --- linux-2.4.24.orig/include/linux/ext3_fs_sb.h 2004-07-19 11:11:16.000000000 +0400
270 +++ linux-2.4.24/include/linux/ext3_fs_sb.h 2004-07-19 11:12:54.000000000 +0400
272 wait_queue_head_t s_delete_thread_queue;
273 wait_queue_head_t s_delete_waiter_queue;
278 #endif /* _LINUX_EXT3_FS_SB */
279 Index: linux-2.4.24/include/linux/dcache.h
280 ===================================================================
281 --- linux-2.4.24.orig/include/linux/dcache.h 2004-07-19 11:11:16.000000000 +0400
282 +++ linux-2.4.24/include/linux/dcache.h 2004-07-19 11:12:53.000000000 +0400
285 unsigned int d_flags;
286 struct inode * d_inode; /* Where the name belongs to - NULL is negative */
287 + unsigned d_inum; /* for cross-fs references (Lustre) */
288 + unsigned d_mdsnum; /* for cross-fs references (Lustre) */
289 + unsigned d_generation; /* for cross-fs references (Lustre) */
290 struct dentry * d_parent; /* parent directory */
291 struct list_head d_hash; /* lookup hash list */
292 struct list_head d_lru; /* d_count = 0 LRU list */
295 #define DCACHE_REFERENCED 0x0008 /* Recently used, don't discard. */
296 #define DCACHE_LUSTRE_INVALID 0x0010 /* Lustre invalidated */
297 +#define DCACHE_CROSS_REF 0x0020 /* entry points to inode on another MDS */
299 extern spinlock_t dcache_lock;