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
7 static unsigned char get_dtype(struct super_block *sb, int filetype)
9 + if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_MDSNUM))
12 if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_FILETYPE) ||
13 (filetype >= EXT3_FT_MAX))
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";
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
33 +#include <linux/module.h>
35 #include <linux/pagemap.h>
36 #include <linux/jbd.h>
37 @@ -1148,6 +1149,23 @@
40 unsigned long ino = le32_to_cpu(de->inode);
41 + unsigned type = de->file_type;
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;
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);
58 ext3_unlock_htree(dir, lock);
60 inode = iget(dir->i_sb, ino);
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 =
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);
77 memmove(to, de, rec_len);
78 to->rec_len = cpu_to_le16(rec_len);
80 struct buffer_head * bh)
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 @@
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 */
96 de = (struct ext3_dir_entry_2 *)bh->b_data;
97 top = bh->b_data + dir->i_sb->s_blocksize - reclen;
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)
107 @@ -1399,7 +1422,7 @@
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);
115 struct ext3_dir_entry_2 *de1 =
116 @@ -1411,8 +1434,20 @@
117 de->file_type = EXT3_FT_UNKNOWN;
119 de->inode = cpu_to_le32(inode->i_ino);
120 - ext3_set_de_type(dir->i_sb, de, inode->i_mode);
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) {
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;
133 + de->inode = cpu_to_le32(dentry->d_inum);
137 de->name_len = namelen;
138 memcpy (de->name, name, namelen);
139 @@ -2737,6 +2772,81 @@
143 + * caller has to make sure directory is protected
145 +int ext3_add_dir_entry(struct dentry *dentry)
147 + struct inode *dir = dentry->d_parent->d_inode;
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);
158 + handle->h_sync = 1;
160 + err = ext3_add_entry(handle, dentry, NULL);
161 + ext3_journal_stop(handle);
164 +EXPORT_SYMBOL(ext3_add_dir_entry);
166 + * caller has to make sure directory is protected
168 +int ext3_del_dir_entry(struct dentry *dentry)
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;
178 + handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
179 + if (IS_ERR(handle)) {
180 + return PTR_ERR(handle);
184 + handle->h_sync = 1;
187 + bh = ext3_find_entry (dentry, &de, 1, &lock);
188 + ext3_unlock_htree(dir, lock);
192 + inode = dentry->d_inode;
196 + retval = ext3_delete_entry(handle, dir, de, bh);
199 + dir->i_ctime = dir->i_mtime = CURRENT_TIME;
200 + ext3_update_dx_flag(dir);
202 + inode->i_ctime = dir->i_ctime;
203 + ext3_mark_inode_dirty(handle, inode);
204 + if (S_ISDIR(inode->i_mode))
207 + ext3_mark_inode_dirty(handle, dir);
211 + ext3_journal_stop(handle);
216 +EXPORT_SYMBOL(ext3_del_dir_entry);
218 * directories can handle most operations...
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
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 */
231 + __u32 s_reserved[189]; /* Padding to the end of the block */
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 */
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| \
251 #define EXT3_DIR_ROUND (EXT3_DIR_PAD - 1)
252 #define EXT3_DIR_REC_LEN(name_len) (((name_len) + 8 + 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))
258 * Hash Tree Directory indexing
259 * (c) Daniel Phillips, 2001
261 extern void ext3_ext_release(struct super_block *);
262 extern void ext3_extents_initialize_blockmap(handle_t *, struct inode *);
264 +extern int ext3_add_dir_entry(struct dentry *dentry);
266 +extern int ext3_del_dir_entry(struct dentry *dentry);
267 #endif /* __KERNEL__ */
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
275 char *s_qf_names[MAXQUOTAS]; /* Names of quota files with journalled quota */
276 int s_jquota_fmt; /* Format of quota to use */
281 #endif /* _LINUX_EXT3_FS_SB */