Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lustre / kernel_patches / patches / ext3-nlinks-2.4.24.patch
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,17 @@
4  static inline void ext3_inc_count(handle_t *handle, struct inode *inode)
5  {
6         inode->i_nlink++;
7 +       if (is_dx(inode) && inode->i_nlink > 1) {
8 +               /* limit is 16-bit i_links_count */
9 +               if (inode->i_nlink >= EXT3_LINK_MAX || inode->i_nlink == 2)
10 +                       inode->i_nlink = 1;
11 +       }
12  }
13  
14  static inline void ext3_dec_count(handle_t *handle, struct inode *inode)
15  {
16 -       inode->i_nlink--;
17 +       if (!S_ISDIR(inode->i_mode) || inode->i_nlink > 2)
18 +               inode->i_nlink--;
19  }
20  
21  static int ext3_add_nondir(handle_t *handle,
22 @@ -1646,7 +1651,7 @@
23         struct ext3_dir_entry_2 * de;
24         int err;
25  
26 -       if (dir->i_nlink >= EXT3_LINK_MAX)
27 +       if (EXT3_DIR_LINK_MAX(dir))
28                 return -EMLINK;
29  
30         handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
31 @@ -1668,7 +1673,7 @@
32         inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
33         dir_block = ext3_bread (handle, inode, 0, 1, &err);
34         if (!dir_block) {
35 -               inode->i_nlink--; /* is this nlink == 0? */
36 +               ext3_dec_count(handle, inode); /* is this nlink == 0? */
37                 ext3_mark_inode_dirty(handle, inode);
38                 iput (inode);
39                 goto out_stop;
40 @@ -1700,7 +1705,7 @@
41                 iput (inode);
42                 goto out_stop;
43         }
44 -       dir->i_nlink++;
45 +       ext3_inc_count(handle, dir);
46         ext3_update_dx_flag(dir);
47         ext3_mark_inode_dirty(handle, dir);
48         d_instantiate(dentry, inode);
49 @@ -1761,10 +1766,11 @@
50                         }
51                         de = (struct ext3_dir_entry_2 *) bh->b_data;
52                 }
53 -               if (!ext3_check_dir_entry ("empty_dir", inode, de, bh,
54 -                                          offset)) {
55 -                       brelse (bh);
56 -                       return 1;
57 +               if (!ext3_check_dir_entry("empty_dir", inode, de, bh, offset)) {
58 +                       /* On error skip the de and offset to the next block. */
59 +                       de = (void *)(bh->b_data + sb->s_blocksize);
60 +                       offset = (offset | (sb->s_blocksize - 1)) + 1;
61 +                       continue;
62                 }
63                 if (le32_to_cpu(de->inode)) {
64                         brelse (bh);
65 @@ -1957,14 +1963,14 @@
66         retval = ext3_delete_entry(handle, dir, de, bh);
67         if (retval)
68                 goto end_rmdir;
69 -       if (inode->i_nlink != 2)
70 -               ext3_warning (inode->i_sb, "ext3_rmdir",
71 -                             "empty directory has nlink!=2 (%d)",
72 -                             inode->i_nlink);
73 +       if (!EXT3_DIR_LINK_EMPTY(inode))
74 +               ext3_warning(inode->i_sb, __FUNCTION__,
75 +                            "empty directory has too many links (%d)",
76 +                            inode->i_nlink);
77         inode->i_version = ++event;
78         inode->i_nlink = 0;
79         ext3_orphan_add(handle, inode);
80 -       dir->i_nlink--;
81 +       ext3_dec_count(handle, dir);
82         inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
83         ext3_mark_inode_dirty(handle, inode);
84         ext3_update_dx_flag(dir);
85 @@ -2046,7 +2052,7 @@
86         dir->i_ctime = dir->i_mtime = CURRENT_TIME;
87         ext3_update_dx_flag(dir);
88         ext3_mark_inode_dirty(handle, dir);
89 -       inode->i_nlink--;
90 +       ext3_dec_count(handle, inode);
91         if (!inode->i_nlink) {
92                 ext3_try_to_delay_deletion(inode);
93                 ext3_orphan_add(handle, inode);
94 @@ -2140,9 +2146,8 @@
95         if (S_ISDIR(inode->i_mode))
96                 return -EPERM;
97  
98 -       if (inode->i_nlink >= EXT3_LINK_MAX) {
99 +       if (EXT3_DIR_LINK_MAX(inode))
100                 return -EMLINK;
101 -       }
102  
103         handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
104                                         EXT3_INDEX_EXTRA_TRANS_BLOCKS);
105 @@ -2226,8 +2231,8 @@
106                 if (le32_to_cpu(PARENT_INO(dir_bh->b_data)) != old_dir->i_ino)
107                         goto end_rename;
108                 retval = -EMLINK;
109 -               if (!new_inode && new_dir!=old_dir &&
110 -                               new_dir->i_nlink >= EXT3_LINK_MAX)
111 +               if (!new_inode && new_dir != old_dir &&
112 +                   EXT3_DIR_LINK_MAX(new_dir))
113                         goto end_rename;
114         }
115         if (!new_bh) {
116 @@ -2285,7 +2290,7 @@
117         }
118  
119         if (new_inode) {
120 -               new_inode->i_nlink--;
121 +               ext3_dec_count(handle, new_inode);
122                 new_inode->i_ctime = CURRENT_TIME;
123         }
124         old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
125 @@ -2296,11 +2301,13 @@
126                 PARENT_INO(dir_bh->b_data) = le32_to_cpu(new_dir->i_ino);
127                 BUFFER_TRACE(dir_bh, "call ext3_journal_dirty_metadata");
128                 ext3_journal_dirty_metadata(handle, dir_bh);
129 -               old_dir->i_nlink--;
130 +               ext3_dec_count(handle, old_dir);
131                 if (new_inode) {
132 -                       new_inode->i_nlink--;
133 +                       /* checked empty_dir above, can't have another parent,
134 +                        * ext3_dec_count() won't work for many-linked dirs */
135 +                       new_inode->i_nlink = 0;
136                 } else {
137 -                       new_dir->i_nlink++;
138 +                       ext3_inc_count(handle, new_dir);
139                         ext3_update_dx_flag(new_dir);
140                         ext3_mark_inode_dirty(handle, new_dir);
141                 }
142 --- ./include/linux/ext3_fs.h.orig      2004-08-19 12:53:52.000000000 +0800
143 +++ ./include/linux/ext3_fs.h   2004-08-19 11:06:33.000000000 +0800
144 @@ -79,7 +81,7 @@
145  /*
146   * Maximal count of links to a file
147   */
148 -#define EXT3_LINK_MAX          32000
149 +#define EXT3_LINK_MAX          65000
150  
151  /*
152   * Macro-instructions used to manage several block sizes