1 --- ./fs/ext3/namei.c.orig 2004-08-19 12:53:21.000000000 +0800
2 +++ ./fs/ext3/namei.c 2004-08-19 12:44:18.000000000 +0800
3 @@ -1541,11 +1541,16 @@
4 static inline void ext3_inc_count(handle_t *handle, struct inode *inode)
7 + if (is_dx(inode) && inode->i_nlink > 1) {
8 + if (inode->i_nlink >= 65000) /* limit is 16-bit i_links_count */
13 static inline void ext3_dec_count(handle_t *handle, struct inode *inode)
16 + if (!S_ISDIR(inode->i_mode) || inode->i_nlink > 2)
20 static int ext3_add_nondir(handle_t *handle,
22 struct ext3_dir_entry_2 * de;
25 - if (dir->i_nlink >= EXT3_LINK_MAX)
26 + if (EXT3_DIR_LINK_MAXED(dir))
29 handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
31 inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
32 dir_block = ext3_bread (handle, inode, 0, 1, &err);
34 - inode->i_nlink--; /* is this nlink == 0? */
35 + ext3_dec_count(handle, inode); /* is this nlink == 0? */
36 ext3_mark_inode_dirty(handle, inode);
44 + ext3_inc_count(handle, dir);
45 ext3_update_dx_flag(dir);
46 ext3_mark_inode_dirty(handle, dir);
47 d_instantiate(dentry, inode);
48 @@ -1761,10 +1766,11 @@
50 de = (struct ext3_dir_entry_2 *) bh->b_data;
52 - if (!ext3_check_dir_entry ("empty_dir", inode, de, bh,
56 + if (!ext3_check_dir_entry("empty_dir", inode, de, bh, offset)) {
57 + /* On error skip the de and offset to the next block. */
58 + de = (void *)(bh->b_data + sb->s_blocksize);
59 + offset = (offset | (sb->s_blocksize - 1)) + 1;
62 if (le32_to_cpu(de->inode)) {
64 @@ -1957,14 +1963,14 @@
65 retval = ext3_delete_entry(handle, dir, de, bh);
68 - if (inode->i_nlink != 2)
69 - ext3_warning (inode->i_sb, "ext3_rmdir",
70 - "empty directory has nlink!=2 (%d)",
72 + if (!EXT3_DIR_LINK_EMPTY(inode))
73 + ext3_warning(inode->i_sb, __FUNCTION__,
74 + "empty directory has too many links (%d)",
76 inode->i_version = ++event;
78 ext3_orphan_add(handle, inode);
80 + ext3_dec_count(handle, dir);
81 inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
82 ext3_mark_inode_dirty(handle, inode);
83 ext3_update_dx_flag(dir);
85 dir->i_ctime = dir->i_mtime = CURRENT_TIME;
86 ext3_update_dx_flag(dir);
87 ext3_mark_inode_dirty(handle, dir);
89 + ext3_dec_count(handle, inode);
90 if (!inode->i_nlink) {
91 ext3_try_to_delay_deletion(inode);
92 ext3_orphan_add(handle, inode);
94 if (S_ISDIR(inode->i_mode))
97 - if (inode->i_nlink >= EXT3_LINK_MAX) {
98 + if (EXT3_DIR_LINK_MAXED(inode))
102 handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
103 EXT3_INDEX_EXTRA_TRANS_BLOCKS);
104 @@ -2226,8 +2231,8 @@
105 if (le32_to_cpu(PARENT_INO(dir_bh->b_data)) != old_dir->i_ino)
108 - if (!new_inode && new_dir!=old_dir &&
109 - new_dir->i_nlink >= EXT3_LINK_MAX)
110 + if (!new_inode && new_dir != old_dir &&
111 + EXT3_DIR_LINK_MAXED(new_dir))
115 @@ -2285,7 +2290,7 @@
119 - new_inode->i_nlink--;
120 + ext3_dec_count(handle, new_inode);
121 new_inode->i_ctime = CURRENT_TIME;
123 old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
124 @@ -2296,11 +2301,11 @@
125 PARENT_INO(dir_bh->b_data) = le32_to_cpu(new_dir->i_ino);
126 BUFFER_TRACE(dir_bh, "call ext3_journal_dirty_metadata");
127 ext3_journal_dirty_metadata(handle, dir_bh);
128 - old_dir->i_nlink--;
129 + ext3_dec_count(handle, old_dir);
131 - new_inode->i_nlink--;
132 + ext3_dec_count(handle, new_inode);
134 - new_dir->i_nlink++;
135 + ext3_inc_count(handle, new_dir);
136 ext3_update_dx_flag(new_dir);
137 ext3_mark_inode_dirty(handle, new_dir);
139 --- ./include/linux/ext3_fs.h.orig 2004-08-19 12:53:52.000000000 +0800
140 +++ ./include/linux/ext3_fs.h 2004-08-19 11:06:33.000000000 +0800
143 * Always enable hashed directories
145 -#define CONFIG_EXT3_INDEX
146 +#define CONFIG_EXT3_INDEX 1
150 @@ -581,14 +581,15 @@
153 #ifdef CONFIG_EXT3_INDEX
154 - #define is_dx(dir) (EXT3_HAS_COMPAT_FEATURE(dir->i_sb, \
155 - EXT3_FEATURE_COMPAT_DIR_INDEX) && \
156 +#define is_dx(dir) (EXT3_HAS_COMPAT_FEATURE(dir->i_sb, \
157 + EXT3_FEATURE_COMPAT_DIR_INDEX) && \
158 (EXT3_I(dir)->i_flags & EXT3_INDEX_FL))
159 -#define EXT3_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT3_LINK_MAX)
160 -#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1)
161 +#define EXT3_DIR_LINK_MAXED(dir) (!is_dx(dir) && (dir)->i_nlink >=EXT3_LINK_MAX)
162 +#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || \
163 + (is_dx(dir) && (dir)->i_nlink == 1))
166 -#define EXT3_DIR_LINK_MAX(dir) ((dir)->i_nlink >= EXT3_LINK_MAX)
167 +#define EXT3_DIR_LINK_MAXED(dir) ((dir)->i_nlink >= EXT3_LINK_MAX)
168 #define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2)