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