Whamcloud - gitweb
761c72c25e15a2a7890f66c24610515f363405b2
[fs/lustre-release.git] / ldiskfs / kernel_patches / patches / ext3-nlinks-2.6.22-vanilla.patch
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
5 @@ -1600,6 +1600,22 @@
6         return -ENOENT;
7  }
8  
9 +static inline void ext3_inc_count(handle_t * handle, struct inode *inode)
10 +{
11 +       inc_nlink(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)
15 +                       inode->i_nlink = 1;
16 +       }
17 +}
18 +
19 +static inline void ext3_dec_count(handle_t * handle, struct inode *inode)
20 +{
21 +       if (!S_ISDIR(inode->i_mode) || inode->i_nlink > 2)
22 +               drop_nlink(inode);
23 +}
24 +
25  static int ext3_add_nondir(handle_t *handle,
26                 struct dentry *dentry, struct inode *inode)
27  {
28 @@ -1659,7 +1659,7 @@ static int ext3_add_nondir(handle_t *han
29                 d_instantiate(dentry, inode);
30                 return 0;
31         }
32 -       drop_nlink(inode);
33 +       ext3_dec_count(handle, inode);
34         iput(inode);
35         return err;
36  }
37 @@ -1703,7 +1709,7 @@ static int ext3_mkdir(struct inode * dir
38         struct ext3_dir_entry_2 * de;
39         int err, retries = 0;
40  
41 -       if (dir->i_nlink >= EXT3_LINK_MAX)
42 +       if (EXT3_DIR_LINK_MAX(dir))
43                 return -EMLINK;
44  
45  retry:
46 @@ -1726,7 +1732,7 @@ retry:
47         inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
48         dir_block = ext3_bread (handle, inode, 0, 1, &err);
49         if (!dir_block) {
50 -               drop_nlink(inode); /* is this nlink == 0? */
51 +               ext3_dec_count(handle, inode); /* is this nlink == 0? */
52                 ext3_mark_inode_dirty(handle, inode);
53                 iput (inode);
54                 goto out_stop;
55 @@ -1758,7 +1764,7 @@ retry:
56                 iput (inode);
57                 goto out_stop;
58         }
59 -       inc_nlink(dir);
60 +       ext3_inc_count(handle, dir);
61         ext3_update_dx_flag(dir);
62         ext3_mark_inode_dirty(handle, dir);
63         d_instantiate(dentry, inode);
64 @@ -2023,10 +2029,10 @@ static int ext3_rmdir (struct inode * di
65         retval = ext3_delete_entry(handle, dir, de, bh);
66         if (retval)
67                 goto end_rmdir;
68 -       if (inode->i_nlink != 2)
69 -               ext3_warning (inode->i_sb, "ext3_rmdir",
70 -                             "empty directory has nlink!=2 (%d)",
71 -                             inode->i_nlink);
72 +       if (!EXT3_DIR_LINK_EMPTY(inode))
73 +               ext3_warning(inode->i_sb, "ext3_rmdir",
74 +                            "empty directory has too many links (%d)",
75 +                            inode->i_nlink);
76         inode->i_version++;
77         inode->i_nlink = 0;
78         /* There's no need to set i_disksize: the fact that i_nlink is
79 @@ -2036,7 +2042,7 @@ static int ext3_rmdir (struct inode * di
80         ext3_orphan_add(handle, inode);
81         inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
82         ext3_mark_inode_dirty(handle, inode);
83 -       drop_nlink(dir);
84 +       ext3_dec_count(handle, dir);
85         ext3_update_dx_flag(dir);
86         ext3_mark_inode_dirty(handle, dir);
87  
88 @@ -2087,7 +2093,7 @@ static int ext3_unlink(struct inode * di
89         dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
90         ext3_update_dx_flag(dir);
91         ext3_mark_inode_dirty(handle, dir);
92 -       drop_nlink(inode);
93 +       ext3_dec_count(handle, inode);
94         if (!inode->i_nlink)
95                 ext3_orphan_add(handle, inode);
96         inode->i_ctime = dir->i_ctime;
97 @@ -2160,7 +2190,7 @@ retry:
98                 err = __page_symlink(inode, symname, l,
99                                 mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS);
100                 if (err) {
101 -                       drop_nlink(inode);
102 +                       ext3_dec_count(handle, inode);
103                         ext3_mark_inode_dirty(handle, inode);
104                         iput (inode);
105                         goto out_stop;
106 @@ -2162,7 +2168,7 @@ static int ext3_link (struct dentry * ol
107         struct inode *inode = old_dentry->d_inode;
108         int err, retries = 0;
109  
110 -       if (inode->i_nlink >= EXT3_LINK_MAX)
111 +       if (EXT3_DIR_LINK_MAX(inode))
112                 return -EMLINK;
113  
114  retry:
115 @@ -2249,8 +2255,8 @@ static int ext3_rename (struct inode * o
116                 if (le32_to_cpu(PARENT_INO(dir_bh->b_data)) != old_dir->i_ino)
117                         goto end_rename;
118                 retval = -EMLINK;
119 -               if (!new_inode && new_dir!=old_dir &&
120 -                               new_dir->i_nlink >= EXT3_LINK_MAX)
121 +               if (!new_inode && new_dir != old_dir &&
122 +                   EXT3_DIR_LINK_MAX(new_dir))
123                         goto end_rename;
124         }
125         if (!new_bh) {
126 @@ -2307,7 +2313,7 @@ static int ext3_rename (struct inode * o
127         }
128  
129         if (new_inode) {
130 -               drop_nlink(new_inode);
131 +               ext3_dec_count(handle, new_inode);
132                 new_inode->i_ctime = CURRENT_TIME_SEC;
133         }
134         old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC;
135 @@ -2318,11 +2324,13 @@ static int ext3_rename (struct inode * o
136                 PARENT_INO(dir_bh->b_data) = cpu_to_le32(new_dir->i_ino);
137                 BUFFER_TRACE(dir_bh, "call ext3_journal_dirty_metadata");
138                 ext3_journal_dirty_metadata(handle, dir_bh);
139 -               drop_nlink(old_dir);
140 +               ext3_dec_count(handle, old_dir);
141                 if (new_inode) {
142 -                       drop_nlink(new_inode);
143 +                       /* checked empty_dir above, can't have another parent,
144 +                        * ext3_dec_count() won't work for many-linked dirs */
145 +                       new_inode->i_nlink = 0;
146                 } else {
147 -                       inc_nlink(new_dir);
148 +                       ext3_inc_count(handle, new_dir);
149                         ext3_update_dx_flag(new_dir);
150                         ext3_mark_inode_dirty(handle, new_dir);
151                 }
152 Index: linux-2.6.12/include/linux/ext3_fs.h
153 ===================================================================
154 --- linux-2.6.12.orig/include/linux/ext3_fs.h
155 +++ linux-2.6.12/include/linux/ext3_fs.h
156 @@ -78,7 +78,7 @@ struct statfs;
157  /*
158   * Maximal count of links to a file
159   */
160 -#define EXT3_LINK_MAX          32000
161 +#define EXT3_LINK_MAX          65000
162  
163  /*
164   * Macro-instructions used to manage several block sizes
165 @@ -539,6 +539,7 @@ static inline struct ext3_inode_info *EX
166  #define EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER    0x0001
167  #define EXT3_FEATURE_RO_COMPAT_LARGE_FILE      0x0002
168  #define EXT3_FEATURE_RO_COMPAT_BTREE_DIR       0x0004
169 +#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK       0x0020
170  
171  #define EXT3_FEATURE_INCOMPAT_COMPRESSION      0x0001
172  #define EXT3_FEATURE_INCOMPAT_FILETYPE         0x0002
173 @@ -552,6 +553,7 @@ static inline struct ext3_inode_info *EX
174                                          EXT3_FEATURE_INCOMPAT_META_BG)
175  #define EXT3_FEATURE_RO_COMPAT_SUPP    (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \
176                                          EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \
177 +                                        EXT4_FEATURE_RO_COMPAT_DIR_NLINK| \
178                                          EXT3_FEATURE_RO_COMPAT_BTREE_DIR)
179  
180  /*