Whamcloud - gitweb
b=3244
[fs/lustre-release.git] / lustre / kernel_patches / patches / ext3-nlinks-2.6.7.patch
1 Index: linux-2.6.5-7.283/fs/ext3/namei.c
2 ===================================================================
3 --- linux-2.6.5-7.283.orig/fs/ext3/namei.c
4 +++ linux-2.6.5-7.283/fs/ext3/namei.c
5 @@ -1613,11 +1613,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 @@ -1730,7 +1736,7 @@ static int ext3_mkdir(struct inode * dir
25         int retries = 0;
26         int err;
27  
28 -       if (dir->i_nlink >= EXT3_LINK_MAX)
29 +       if (EXT3_DIR_LINK_MAX(dir))
30                 return -EMLINK;
31  
32  retry:
33 @@ -1752,7 +1758,7 @@ retry:
34         inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
35         dir_block = ext3_bread (handle, inode, 0, 1, &err);
36         if (!dir_block) {
37 -               inode->i_nlink--; /* is this nlink == 0? */
38 +               ext3_dec_count(handle, inode); /* is this nlink == 0? */
39                 ext3_mark_inode_dirty(handle, inode);
40                 iput (inode);
41                 goto out_stop;
42 @@ -1784,7 +1790,7 @@ retry:
43                 iput (inode);
44                 goto out_stop;
45         }
46 -       dir->i_nlink++;
47 +       ext3_inc_count(handle, dir);
48         ext3_update_dx_flag(dir);
49         ext3_mark_inode_dirty(handle, dir);
50         d_instantiate(dentry, inode);
51 @@ -2042,16 +2048,16 @@ static int ext3_rmdir (struct inode * di
52         retval = ext3_delete_entry(handle, dir, de, bh);
53         if (retval)
54                 goto end_rmdir;
55 -       if (inode->i_nlink != 2)
56 -               ext3_warning (inode->i_sb, "ext3_rmdir",
57 -                             "empty directory has nlink!=2 (%d)",
58 -                             inode->i_nlink);
59 +       if (!EXT3_DIR_LINK_EMPTY(inode))
60 +               ext3_warning(inode->i_sb, "ext3_rmdir",
61 +                            "empty directory has too many links (%d)",
62 +                            inode->i_nlink);
63         inode->i_version++;
64         inode->i_nlink = 0;
65         ext3_orphan_add(handle, inode);
66         inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
67         ext3_mark_inode_dirty(handle, inode);
68 -       dir->i_nlink--;
69 +       ext3_dec_count(handle, dir);
70         ext3_update_dx_flag(dir);
71         ext3_mark_inode_dirty(handle, dir);
72  
73 @@ -2100,7 +2106,7 @@ static int ext3_unlink(struct inode * di
74         dir->i_ctime = dir->i_mtime = CURRENT_TIME;
75         ext3_update_dx_flag(dir);
76         ext3_mark_inode_dirty(handle, dir);
77 -       inode->i_nlink--;
78 +       ext3_dec_count(handle, inode);
79         if (!inode->i_nlink)
80                 ext3_orphan_add(handle, inode);
81         inode->i_ctime = dir->i_ctime;
82 @@ -2191,7 +2197,7 @@ static int ext3_link (struct dentry * ol
83         struct inode *inode = old_dentry->d_inode;
84         int err, retries = 0;
85  
86 -       if (inode->i_nlink >= EXT3_LINK_MAX)
87 +       if (EXT3_DIR_LINK_MAX(inode))
88                 return -EMLINK;
89  
90  retry:
91 @@ -2277,8 +2283,8 @@ static int ext3_rename (struct inode * o
92                 if (le32_to_cpu(PARENT_INO(dir_bh->b_data)) != old_dir->i_ino)
93                         goto end_rename;
94                 retval = -EMLINK;
95 -               if (!new_inode && new_dir!=old_dir &&
96 -                               new_dir->i_nlink >= EXT3_LINK_MAX)
97 +               if (!new_inode && new_dir != old_dir &&
98 +                   EXT3_DIR_LINK_MAX(new_dir))
99                         goto end_rename;
100         }
101         if (!new_bh) {
102 @@ -2335,7 +2341,7 @@ static int ext3_rename (struct inode * o
103         }
104  
105         if (new_inode) {
106 -               new_inode->i_nlink--;
107 +               ext3_dec_count(handle, new_inode);
108                 new_inode->i_ctime = CURRENT_TIME;
109         }
110         old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
111 @@ -2346,11 +2352,13 @@ static int ext3_rename (struct inode * o
112                 PARENT_INO(dir_bh->b_data) = le32_to_cpu(new_dir->i_ino);
113                 BUFFER_TRACE(dir_bh, "call ext3_journal_dirty_metadata");
114                 ext3_journal_dirty_metadata(handle, dir_bh);
115 -               old_dir->i_nlink--;
116 +               ext3_dec_count(handle, old_dir);
117                 if (new_inode) {
118 -                       new_inode->i_nlink--;
119 +                       /* checked empty_dir above, can't have another parent,
120 +                        * ext3_dec_count() won't work for many-linked dirs */
121 +                       new_inode->i_nlink = 0;
122                 } else {
123 -                       new_dir->i_nlink++;
124 +                       ext3_inc_count(handle, new_dir);
125                         ext3_update_dx_flag(new_dir);
126                         ext3_mark_inode_dirty(handle, new_dir);
127                 }
128 Index: linux-2.6.5-7.283/include/linux/ext3_fs.h
129 ===================================================================
130 --- linux-2.6.5-7.283.orig/include/linux/ext3_fs.h
131 +++ linux-2.6.5-7.283/include/linux/ext3_fs.h
132 @@ -86,7 +86,7 @@ struct statfs;
133  /*
134   * Maximal count of links to a file
135   */
136 -#define EXT3_LINK_MAX          32000
137 +#define EXT3_LINK_MAX          65000
138  
139  /*
140   * Macro-instructions used to manage several block sizes
141 @@ -538,6 +538,7 @@ static inline struct ext3_inode_info *EX
142  #define EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER    0x0001
143  #define EXT3_FEATURE_RO_COMPAT_LARGE_FILE      0x0002
144  #define EXT3_FEATURE_RO_COMPAT_BTREE_DIR       0x0004
145 +#define EXT3_FEATURE_RO_COMPAT_DIR_NLINK       0x0020
146  
147  #define EXT3_FEATURE_INCOMPAT_COMPRESSION      0x0001
148  #define EXT3_FEATURE_INCOMPAT_FILETYPE         0x0002
149 @@ -553,6 +554,7 @@ static inline struct ext3_inode_info *EX
150                                          EXT3_FEATURE_INCOMPAT_EXTENTS)
151  #define EXT3_FEATURE_RO_COMPAT_SUPP    (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \
152                                          EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \
153 +                                        EXT3_FEATURE_RO_COMPAT_DIR_NLINK| \
154                                          EXT3_FEATURE_RO_COMPAT_BTREE_DIR)
155  
156  /*