Whamcloud - gitweb
file xnu_types.h was initially added on branch b_port_step.
[fs/lustre-release.git] / lustre / kernel_patches / patches / vfs-pdirops-2.4.21-suse2.patch
1  fs/inode.c         |    1 
2  fs/namei.c         |   66 ++++++++++++++++++++++++++++++++++++++---------------
3  include/linux/fs.h |   11 ++++----
4  3 files changed, 54 insertions(+), 24 deletions(-)
5
6 Index: linux-2.4.21-suse2/fs/namei.c
7 ===================================================================
8 --- linux-2.4.21-suse2.orig/fs/namei.c  2004-08-19 13:45:04.000000000 +0400
9 +++ linux-2.4.21-suse2/fs/namei.c       2004-08-19 15:57:51.000000000 +0400
10 @@ -103,6 +103,38 @@
11  }
12  EXPORT_SYMBOL(intent_release);
13  
14 +void *lock_dir(struct inode *dir, struct qstr *name)
15 +{
16 +       unsigned long hash;
17 +       
18 +       if (!IS_PDIROPS(dir)) {
19 +               down(&dir->i_sem);
20 +               return 0;
21 +       }
22 +
23 +       /* OK. fs understands parallel directory operations.
24 +        * so, we try to acquire lock for hash of requested
25 +        * filename in order to prevent any operations with
26 +        * same name in same time -bzzz */
27 +
28 +       /* calculate name hash */
29 +       hash = full_name_hash(name->name, name->len);
30 +
31 +       /* lock this hash */
32 +       return dynlock_lock(&dir->i_dcache_lock, hash, 1, GFP_ATOMIC);
33 +}
34 +EXPORT_SYMBOL(lock_dir);
35 +
36 +void unlock_dir(struct inode *dir, void *lock)
37 +{
38 +       if (!IS_PDIROPS(dir)) {
39 +               up(&dir->i_sem);
40 +               return;
41 +       }
42 +       dynlock_unlock(&dir->i_dcache_lock, lock);
43 +}
44 +EXPORT_SYMBOL(unlock_dir);
45 +
46  /* In order to reduce some races, while at the same time doing additional
47   * checking and hopefully speeding things up, we copy filenames to the
48   * kernel data space before using them..
49 @@ -305,10 +337,11 @@
50         struct dentry * result;
51         struct inode *dir = parent->d_inode;
52         int counter = 0;
53 +       void *lock;
54  
55  again:
56         counter++;
57 -       down(&dir->i_sem);
58 +       lock = lock_dir(dir, name);
59         /*
60          * First re-do the cached lookup just in case it was created
61          * while we waited for the directory semaphore..
62 @@ -332,7 +365,7 @@
63                         else
64                                 result = dentry;
65                 }
66 -               up(&dir->i_sem);
67 +               unlock_dir(dir, lock);
68                 return result;
69         }
70  
71 @@ -340,7 +373,7 @@
72          * Uhhuh! Nasty case: the cache was re-populated while
73          * we waited on the semaphore. Need to revalidate.
74          */
75 -       up(&dir->i_sem);
76 +       unlock_dir(dir, lock);
77         if (result->d_op && result->d_op->d_revalidate) {
78                 if (!result->d_op->d_revalidate(result, flags) && !d_invalidate(result)) {
79                         dput(result);
80 @@ -1186,13 +1219,13 @@
81                 goto exit;
82  
83         dir = nd->dentry;
84 -       down(&dir->d_inode->i_sem);
85 +       nd->lock = lock_dir(dir->d_inode, &nd->last);
86         dentry = lookup_hash_it(&nd->last, nd->dentry, it);
87  
88  do_last:
89         error = PTR_ERR(dentry);
90         if (IS_ERR(dentry)) {
91 -               up(&dir->d_inode->i_sem);
92 +               unlock_dir(dir->d_inode, nd->lock);
93                 goto exit;
94         }
95  
96 @@ -1202,7 +1235,7 @@
97                 if (!IS_POSIXACL(dir->d_inode))
98                         mode &= ~current->fs->umask;
99                 error = vfs_create_it(dir->d_inode, dentry, mode, it);
100 -               up(&dir->d_inode->i_sem);
101 +               unlock_dir(dir->d_inode, nd->lock);             
102  #ifndef DENTRY_WASTE_RAM
103                 if (error)
104                         d_drop(dentry);
105 @@ -1220,7 +1253,7 @@
106         /*
107          * It already exists.
108          */
109 -       up(&dir->d_inode->i_sem);
110 +       unlock_dir(dir->d_inode, nd->lock);
111  
112         error = -EEXIST;
113         if (flag & O_EXCL)
114 @@ -1367,7 +1400,7 @@
115                 goto exit;
116         }
117         dir = nd->dentry;
118 -       down(&dir->d_inode->i_sem);
119 +       nd->lock = lock_dir(dir->d_inode, &nd->last);
120         dentry = lookup_hash_it(&nd->last, nd->dentry, it);
121         putname(nd->last.name);
122         goto do_last;
123 @@ -1385,7 +1418,7 @@
124  {
125         struct dentry *dentry;
126  
127 -       down(&nd->dentry->d_inode->i_sem);
128 +       nd->lock = lock_dir(nd->dentry->d_inode, &nd->last);
129         dentry = ERR_PTR(-EEXIST);
130         if (nd->last_type != LAST_NORM)
131                 goto fail;
132 @@ -1479,7 +1512,7 @@
133                 }
134                 dput(dentry);
135         }
136 -       up(&nd.dentry->d_inode->i_sem);
137 +       unlock_dir(nd.dentry->d_inode, nd.lock);
138  out2:
139         path_release(&nd);
140  out:
141 @@ -1547,7 +1580,7 @@
142                         error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
143                         dput(dentry);
144                 }
145 -               up(&nd.dentry->d_inode->i_sem);
146 +               unlock_dir(nd.dentry->d_inode, nd.lock);
147  out2:
148                 path_release(&nd);
149  out:
150 @@ -1657,14 +1690,14 @@
151                 if (error != -EOPNOTSUPP)
152                         goto exit1;
153         }
154 -       down(&nd.dentry->d_inode->i_sem);
155 +       nd.lock = lock_dir(nd.dentry->d_inode, &nd.last);
156         dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
157         error = PTR_ERR(dentry);
158         if (!IS_ERR(dentry)) {
159                 error = vfs_rmdir(nd.dentry->d_inode, dentry);
160                 dput(dentry);
161         }
162 -       up(&nd.dentry->d_inode->i_sem);
163 +       unlock_dir(nd.dentry->d_inode, nd.lock);
164  exit1:
165         path_release(&nd);
166  exit:
167 @@ -1723,7 +1756,7 @@
168                 if (error != -EOPNOTSUPP)
169                         goto exit1;
170         }
171 -       down(&nd.dentry->d_inode->i_sem);
172 +       nd.lock = lock_dir(nd.dentry->d_inode, &nd.last);
173         dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
174         error = PTR_ERR(dentry);
175         if (!IS_ERR(dentry)) {
176 @@ -1734,7 +1767,7 @@
177         exit2:
178                 dput(dentry);
179         }
180 -       up(&nd.dentry->d_inode->i_sem);
181 +       unlock_dir(nd.dentry->d_inode, nd.lock);
182  exit1:
183         path_release(&nd);
184  exit:
185 @@ -1808,7 +1841,7 @@
186                         error = vfs_symlink(nd.dentry->d_inode, dentry, from);
187                         dput(dentry);
188                 }
189 -               up(&nd.dentry->d_inode->i_sem);
190 +               unlock_dir(nd.dentry->d_inode, nd.lock);
191         out2:
192                 path_release(&nd);
193         out:
194 @@ -1904,7 +1937,7 @@
195                         error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
196                         dput(new_dentry);
197                 }
198 -               up(&nd.dentry->d_inode->i_sem);
199 +               unlock_dir(nd.dentry->d_inode, nd.lock);
200  out_release:
201                 path_release(&nd);
202  out:
203 Index: linux-2.4.21-suse2/fs/inode.c
204 ===================================================================
205 --- linux-2.4.21-suse2.orig/fs/inode.c  2004-08-19 13:45:04.000000000 +0400
206 +++ linux-2.4.21-suse2/fs/inode.c       2004-08-19 13:51:49.000000000 +0400
207 @@ -121,6 +121,7 @@
208                 mapping->host = inode;
209                 mapping->gfp_mask = GFP_HIGHUSER;
210                 inode->i_mapping = mapping;
211 +               dynlock_init(&inode->i_dcache_lock);
212         }
213         return inode;
214  }
215 Index: linux-2.4.21-suse2/include/linux/fs.h
216 ===================================================================
217 --- linux-2.4.21-suse2.orig/include/linux/fs.h  2004-08-19 13:45:04.000000000 +0400
218 +++ linux-2.4.21-suse2/include/linux/fs.h       2004-08-19 13:51:49.000000000 +0400
219 @@ -22,6 +22,7 @@
220  #include <linux/stddef.h>
221  #include <linux/string.h>
222  #include <linux/frlock.h>
223 +#include <linux/dynlocks.h>
224  
225  #include <asm/atomic.h>
226  #include <asm/bitops.h>
227 @@ -141,6 +142,7 @@
228  #define S_IMMUTABLE    16      /* Immutable file */
229  #define S_DEAD         32      /* removed, but still open directory */
230  #define S_NOQUOTA      64      /* Inode is not counted to quota */
231 +#define S_PDIROPS      256     /* Parallel directory operations */
232  
233  /*
234   * Note that nosuid etc flags are inode-specific: setting some file-system
235 @@ -168,6 +170,7 @@
236  #define IS_NOATIME(inode)      (__IS_FLG(inode, MS_NOATIME) || ((inode)->i_flags & S_NOATIME))
237  #define IS_NODIRATIME(inode)   __IS_FLG(inode, MS_NODIRATIME)
238  #define IS_POSIXACL(inode)     __IS_FLG(inode, MS_POSIXACL)
239 +#define IS_PDIROPS(inode)      __IS_FLG(inode, S_PDIROPS)
240  
241  #define IS_DEADDIR(inode)      ((inode)->i_flags & S_DEAD)
242  
243 @@ -525,6 +528,7 @@
244         atomic_t                i_writecount;
245         unsigned int            i_attr_flags;
246         __u32                   i_generation;
247 +       struct dynlock          i_dcache_lock;  /* for parallel directory ops */
248         union {
249                 struct minix_inode_info         minix_i;
250                 struct ext2_inode_info          ext2_i;
251 @@ -806,6 +810,7 @@
252         unsigned int flags;
253         int last_type;
254         struct lookup_intent *intent;
255 +       void *lock;
256  };
257  
258  /*
259 @@ -1793,12 +1798,6 @@
260         return dget(dentry->d_parent);
261  }
262  
263 -static inline void unlock_dir(struct dentry *dir)
264 -{
265 -       up(&dir->d_inode->i_sem);
266 -       dput(dir);
267 -}
268 -
269  /*
270   * Whee.. Deadlock country. Happily there are only two VFS
271   * operations that does this..