1 Index: linux-2.6.12/fs/ext3/namei.c
2 ===================================================================
3 --- linux-2.6.12.orig/fs/ext3/namei.c
4 +++ linux-2.6.12/fs/ext3/namei.c
9 +static inline void ext3_inc_count(handle_t * handle, struct inode *inode)
12 + if (is_dx(inode) && inode->i_nlink > 1) {
13 + /* limit is 16-bit i_links_count */
14 + if (inode->i_nlink >= EXT3_LINK_MAX || inode->i_nlink == 2)
19 +static inline void ext3_dec_count(handle_t * handle, struct inode *inode)
21 + if (!S_ISDIR(inode->i_mode) || inode->i_nlink > 2)
25 static int ext3_add_nondir(handle_t *handle,
26 struct dentry *dentry, struct inode *inode)
28 @@ -1659,7 +1659,7 @@ static int ext3_add_nondir(handle_t *han
29 d_instantiate(dentry, inode);
33 + ext3_dec_count(handle, inode);
37 @@ -1703,7 +1709,7 @@ static int ext3_mkdir(struct inode * dir
38 struct ext3_dir_entry_2 * de;
41 - if (dir->i_nlink >= EXT3_LINK_MAX)
42 + if (EXT3_DIR_LINK_MAX(dir))
46 @@ -1758,7 +1764,7 @@ retry:
51 + ext3_inc_count(handle, dir);
52 ext3_update_dx_flag(dir);
53 ext3_mark_inode_dirty(handle, dir);
54 d_instantiate(dentry, inode);
55 @@ -2023,10 +2029,10 @@ static int ext3_rmdir (struct inode * di
56 retval = ext3_delete_entry(handle, dir, de, bh);
59 - if (inode->i_nlink != 2)
60 - ext3_warning (inode->i_sb, "ext3_rmdir",
61 - "empty directory has nlink!=2 (%d)",
63 + if (!EXT3_DIR_LINK_EMPTY(inode))
64 + ext3_warning(inode->i_sb, "ext3_rmdir",
65 + "empty directory has too many links (%d)",
69 /* There's no need to set i_disksize: the fact that i_nlink is
70 @@ -2036,7 +2042,7 @@ static int ext3_rmdir (struct inode * di
71 ext3_orphan_add(handle, inode);
72 inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
73 ext3_mark_inode_dirty(handle, inode);
75 + ext3_dec_count(handle, dir);
76 ext3_update_dx_flag(dir);
77 ext3_mark_inode_dirty(handle, dir);
79 @@ -2087,7 +2093,7 @@ static int ext3_unlink(struct inode * di
80 dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
81 ext3_update_dx_flag(dir);
82 ext3_mark_inode_dirty(handle, dir);
84 + ext3_dec_count(handle, inode);
86 ext3_orphan_add(handle, inode);
87 inode->i_ctime = dir->i_ctime;
88 @@ -2160,7 +2190,7 @@ retry:
89 err = __page_symlink(inode, symname, l,
90 mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS);
93 + ext3_dec_count(handle, inode);
94 ext3_mark_inode_dirty(handle, inode);
97 @@ -2162,7 +2168,7 @@ static int ext3_link (struct dentry * ol
98 struct inode *inode = old_dentry->d_inode;
101 - if (inode->i_nlink >= EXT3_LINK_MAX)
102 + if (EXT3_DIR_LINK_MAX(inode))
106 @@ -2249,8 +2255,8 @@ static int ext3_rename (struct inode * o
107 if (le32_to_cpu(PARENT_INO(dir_bh->b_data)) != old_dir->i_ino)
110 - if (!new_inode && new_dir!=old_dir &&
111 - new_dir->i_nlink >= EXT3_LINK_MAX)
112 + if (!new_inode && new_dir != old_dir &&
113 + EXT3_DIR_LINK_MAX(new_dir))
117 @@ -2307,7 +2313,7 @@ static int ext3_rename (struct inode * o
121 - drop_nlink(new_inode);
122 + ext3_dec_count(handle, new_inode);
123 new_inode->i_ctime = CURRENT_TIME_SEC;
125 old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC;
126 @@ -2318,11 +2324,13 @@ static int ext3_rename (struct inode * o
127 PARENT_INO(dir_bh->b_data) = cpu_to_le32(new_dir->i_ino);
128 BUFFER_TRACE(dir_bh, "call ext3_journal_dirty_metadata");
129 ext3_journal_dirty_metadata(handle, dir_bh);
130 - drop_nlink(old_dir);
131 + ext3_dec_count(handle, old_dir);
133 - drop_nlink(new_inode);
134 + /* checked empty_dir above, can't have another parent,
135 + * ext3_dec_count() won't work for many-linked dirs */
136 + new_inode->i_nlink = 0;
138 - inc_nlink(new_dir);
139 + ext3_inc_count(handle, new_dir);
140 ext3_update_dx_flag(new_dir);
141 ext3_mark_inode_dirty(handle, new_dir);
143 Index: linux-2.6.12/include/linux/ext3_fs.h
144 ===================================================================
145 --- linux-2.6.12.orig/include/linux/ext3_fs.h
146 +++ linux-2.6.12/include/linux/ext3_fs.h
147 @@ -78,7 +78,7 @@ struct statfs;
149 * Maximal count of links to a file
151 -#define EXT3_LINK_MAX 32000
152 +#define EXT3_LINK_MAX 65000
155 * Macro-instructions used to manage several block sizes
156 @@ -539,6 +539,7 @@ static inline struct ext3_inode_info *EX
157 #define EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001
158 #define EXT3_FEATURE_RO_COMPAT_LARGE_FILE 0x0002
159 #define EXT3_FEATURE_RO_COMPAT_BTREE_DIR 0x0004
160 +#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020
162 #define EXT3_FEATURE_INCOMPAT_COMPRESSION 0x0001
163 #define EXT3_FEATURE_INCOMPAT_FILETYPE 0x0002
164 @@ -552,6 +553,7 @@ static inline struct ext3_inode_info *EX
165 EXT3_FEATURE_INCOMPAT_META_BG)
166 #define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \
167 EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \
168 + EXT4_FEATURE_RO_COMPAT_DIR_NLINK| \
169 EXT3_FEATURE_RO_COMPAT_BTREE_DIR)