Whamcloud - gitweb
- pdirops patches against vanilla-2.4.20 series
[fs/lustre-release.git] / lustre / kernel_patches / patches / vfs-pdirops-2.4.20.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.20-rh/fs/namei.c
7 ===================================================================
8 --- linux-2.4.20-rh.orig/fs/namei.c     2003-09-04 20:58:33.000000000 +0800
9 +++ linux-2.4.20-rh/fs/namei.c  2003-09-04 21:21:20.000000000 +0800
10 @@ -101,6 +101,36 @@
11  
12  }
13  
14 +static 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 +
35 +static void unlock_dir(struct inode *dir, void *lock)
36 +{
37 +       if (!IS_PDIROPS(dir)) {
38 +               up(&dir->i_sem);
39 +               return;
40 +       }
41 +       dynlock_unlock(&dir->i_dcache_lock, lock);
42 +}
43 +
44  /* In order to reduce some races, while at the same time doing additional
45   * checking and hopefully speeding things up, we copy filenames to the
46   * kernel data space before using them..
47 @@ -303,10 +333,11 @@
48         struct dentry * result;
49         struct inode *dir = parent->d_inode;
50         int counter = 0;
51 +       void *lock;
52  
53  again:
54         counter++;
55 -       down(&dir->i_sem);
56 +       lock = lock_dir(dir, name);
57         /*
58          * First re-do the cached lookup just in case it was created
59          * while we waited for the directory semaphore..
60 @@ -329,7 +359,7 @@
61                         else
62                                 result = dentry;
63                 }
64 -               up(&dir->i_sem);
65 +               unlock_dir(dir, lock);
66                 return result;
67         }
68  
69 @@ -337,7 +367,7 @@
70          * Uhhuh! Nasty case: the cache was re-populated while
71          * we waited on the semaphore. Need to revalidate.
72          */
73 -       up(&dir->i_sem);
74 +       unlock_dir(dir, lock);
75         if (result->d_op && result->d_op->d_revalidate) {
76                 if (!result->d_op->d_revalidate(result, flags) && !d_invalidate(result)) {
77                         dput(result);
78 @@ -1180,13 +1210,13 @@
79                 goto exit;
80  
81         dir = nd->dentry;
82 -       down(&dir->d_inode->i_sem);
83 +       nd->lock = lock_dir(dir->d_inode, &nd->last);
84         dentry = lookup_hash_it(&nd->last, nd->dentry, it);
85  
86  do_last:
87         error = PTR_ERR(dentry);
88         if (IS_ERR(dentry)) {
89 -               up(&dir->d_inode->i_sem);
90 +               unlock_dir(dir->d_inode, nd->lock);
91                 goto exit;
92         }
93  
94 @@ -1195,7 +1225,7 @@
95         if (!dentry->d_inode) {
96                 error = vfs_create_it(dir->d_inode, dentry,
97                                    mode & ~current->fs->umask, it);
98 -               up(&dir->d_inode->i_sem);
99 +               unlock_dir(dir->d_inode, nd->lock);             
100                 dput(nd->dentry);
101                 nd->dentry = dentry;
102                 if (error)
103 @@ -1209,7 +1239,7 @@
104         /*
105          * It already exists.
106          */
107 -       up(&dir->d_inode->i_sem);
108 +       unlock_dir(dir->d_inode, nd->lock);
109  
110         error = -EEXIST;
111         if (flag & O_EXCL)
112 @@ -1362,7 +1392,7 @@
113                 goto exit;
114         }
115         dir = nd->dentry;
116 -       down(&dir->d_inode->i_sem);
117 +       nd->lock = lock_dir(dir->d_inode, &nd->last);
118         dentry = lookup_hash_it(&nd->last, nd->dentry, it);
119         putname(nd->last.name);
120         goto do_last;
121 @@ -1380,7 +1410,7 @@
122  {
123         struct dentry *dentry;
124  
125 -       down(&nd->dentry->d_inode->i_sem);
126 +       nd->lock = lock_dir(nd->dentry->d_inode, &nd->last);
127         dentry = ERR_PTR(-EEXIST);
128         if (nd->last_type != LAST_NORM)
129                 goto fail;
130 @@ -1469,7 +1499,7 @@
131                 }
132                 dput(dentry);
133         }
134 -       up(&nd.dentry->d_inode->i_sem);
135 +       unlock_dir(nd.dentry->d_inode, nd.lock);
136  out2:
137         path_release(&nd);
138  out:
139 @@ -1532,7 +1562,7 @@
140                                           mode & ~current->fs->umask);
141                         dput(dentry);
142                 }
143 -               up(&nd.dentry->d_inode->i_sem);
144 +               unlock_dir(nd.dentry->d_inode, nd.lock);
145  out2:
146                 path_release(&nd);
147  out:
148 @@ -1642,14 +1672,14 @@
149                 if (error != -EOPNOTSUPP)
150                         goto exit1;
151         }
152 -       down(&nd.dentry->d_inode->i_sem);
153 +       nd.lock = lock_dir(nd.dentry->d_inode, &nd.last);
154         dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
155         error = PTR_ERR(dentry);
156         if (!IS_ERR(dentry)) {
157                 error = vfs_rmdir(nd.dentry->d_inode, dentry);
158                 dput(dentry);
159         }
160 -       up(&nd.dentry->d_inode->i_sem);
161 +       unlock_dir(nd.dentry->d_inode, nd.lock);
162  exit1:
163         path_release(&nd);
164  exit:
165 @@ -1708,7 +1738,7 @@
166                 if (error != -EOPNOTSUPP)
167                         goto exit1;
168         }
169 -       down(&nd.dentry->d_inode->i_sem);
170 +       nd.lock = lock_dir(nd.dentry->d_inode, &nd.last);
171         dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
172         error = PTR_ERR(dentry);
173         if (!IS_ERR(dentry)) {
174 @@ -1719,7 +1749,7 @@
175         exit2:
176                 dput(dentry);
177         }
178 -       up(&nd.dentry->d_inode->i_sem);
179 +       unlock_dir(nd.dentry->d_inode, nd.lock);
180  exit1:
181         path_release(&nd);
182  exit:
183 @@ -1789,7 +1819,7 @@
184                         error = vfs_symlink(nd.dentry->d_inode, dentry, from);
185                         dput(dentry);
186                 }
187 -               up(&nd.dentry->d_inode->i_sem);
188 +               unlock_dir(nd.dentry->d_inode, nd.lock);
189         out2:
190                 path_release(&nd);
191         out:
192 @@ -1881,7 +1911,7 @@
193                         error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
194                         dput(new_dentry);
195                 }
196 -               up(&nd.dentry->d_inode->i_sem);
197 +               unlock_dir(nd.dentry->d_inode, nd.lock);
198  out_release:
199                 path_release(&nd);
200  out:
201 Index: linux-2.4.20-rh/include/linux/fs.h
202 ===================================================================
203 --- linux-2.4.20-rh.orig/include/linux/fs.h     2003-09-04 20:59:14.000000000 +0800
204 +++ linux-2.4.20-rh/include/linux/fs.h  2003-09-04 21:03:46.000000000 +0800
205 @@ -21,6 +21,7 @@
206  #include <linux/cache.h>
207  #include <linux/stddef.h>
208  #include <linux/string.h>
209 +#include <linux/dynlocks.h>
210  
211  #include <asm/atomic.h>
212  #include <asm/bitops.h>
213 @@ -136,6 +137,7 @@
214  #define S_IMMUTABLE    16      /* Immutable file */
215  #define S_DEAD         32      /* removed, but still open directory */
216  #define S_NOQUOTA      64      /* Inode is not counted to quota */
217 +#define S_PDIROPS      256     /* Parallel directory operations */
218  
219  /*
220   * Note that nosuid etc flags are inode-specific: setting some file-system
221 @@ -162,6 +164,7 @@
222  #define IS_IMMUTABLE(inode)    ((inode)->i_flags & S_IMMUTABLE)
223  #define IS_NOATIME(inode)      (__IS_FLG(inode, MS_NOATIME) || ((inode)->i_flags & S_NOATIME))
224  #define IS_NODIRATIME(inode)   __IS_FLG(inode, MS_NODIRATIME)
225 +#define IS_PDIROPS(inode)      __IS_FLG(inode, S_PDIROPS)
226  
227  #define IS_DEADDIR(inode)      ((inode)->i_flags & S_DEAD)
228  
229 @@ -489,6 +492,7 @@
230         atomic_t                i_writecount;
231         unsigned int            i_attr_flags;
232         __u32                   i_generation;
233 +       struct dynlock          i_dcache_lock;  /* for parallel directory ops */
234         union {
235                 struct minix_inode_info         minix_i;
236                 struct ext2_inode_info          ext2_i;
237 @@ -708,6 +712,7 @@
238         unsigned int flags;
239         int last_type;
240         struct lookup_intent *intent;
241 +       void *lock;
242  };
243  
244  /*
245 @@ -1621,12 +1626,6 @@
246         return dget(dentry->d_parent);
247  }
248  
249 -static inline void unlock_dir(struct dentry *dir)
250 -{
251 -       up(&dir->d_inode->i_sem);
252 -       dput(dir);
253 -}
254 -
255  /*
256   * Whee.. Deadlock country. Happily there are only two VFS
257   * operations that does this..
258 Index: linux-2.4.20-rh/fs/inode.c
259 ===================================================================
260 --- linux-2.4.20-rh.orig/fs/inode.c     2003-09-04 20:58:35.000000000 +0800
261 +++ linux-2.4.20-rh/fs/inode.c  2003-09-04 21:03:46.000000000 +0800
262 @@ -121,6 +121,7 @@
263         inode->i_data.host = inode;
264         inode->i_data.gfp_mask = GFP_HIGHUSER;
265         inode->i_mapping = &inode->i_data;
266 +       dynlock_init(&inode->i_dcache_lock);
267  }
268  
269  /**