Whamcloud - gitweb
b=5209
[fs/lustre-release.git] / lustre / kernel_patches / patches / vfs-pdirops-2.6.7.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.6.7/fs/namei.c
7 ===================================================================
8 --- linux-2.6.7.orig/fs/namei.c 2004-09-06 22:53:19.000000000 +0400
9 +++ linux-2.6.7/fs/namei.c      2004-09-07 14:39:44.000000000 +0400
10 @@ -103,6 +103,38 @@
11   * any extra contention...
12   */
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 @@ -362,10 +394,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 @@ -391,7 +424,7 @@
63                         else
64                                 result = dentry;
65                 }
66 -               up(&dir->i_sem);
67 +               unlock_dir(dir, lock);
68                 return result;
69         }
70  
71 @@ -399,7 +432,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, nd) && !d_invalidate(result)) {
79                         dput(result);
80 @@ -1367,7 +1400,7 @@
81  
82         dir = nd->dentry;
83         nd->flags &= ~LOOKUP_PARENT;
84 -       down(&dir->d_inode->i_sem);
85 +       nd->lock = lock_dir(dir->d_inode, &nd->last);
86         nd->flags |= LOOKUP_LAST;
87         dentry = __lookup_hash(&nd->last, nd->dentry, nd);
88         nd->flags &= ~LOOKUP_LAST;
89 @@ -1375,7 +1408,7 @@
90  do_last:
91         error = PTR_ERR(dentry);
92         if (IS_ERR(dentry)) {
93 -               up(&dir->d_inode->i_sem);
94 +               unlock_dir(dir->d_inode, nd->lock);
95                 goto exit;
96         }
97  
98 @@ -1384,7 +1417,7 @@
99                 if (!IS_POSIXACL(dir->d_inode))
100                         mode &= ~current->fs->umask;
101                 error = vfs_create(dir->d_inode, dentry, mode, nd);
102 -               up(&dir->d_inode->i_sem);
103 +               unlock_dir(dir->d_inode, nd->lock);             
104                 dput(nd->dentry);
105                 nd->dentry = dentry;
106                 if (error)
107 @@ -1398,7 +1431,7 @@
108         /*
109          * It already exists.
110          */
111 -       up(&dir->d_inode->i_sem);
112 +       unlock_dir(dir->d_inode, nd->lock);
113  
114         error = -EEXIST;
115         if (flag & O_EXCL)
116 @@ -1474,7 +1507,7 @@
117                 goto exit;
118         }
119         dir = nd->dentry;
120 -       down(&dir->d_inode->i_sem);
121 +       nd->lock = lock_dir(dir->d_inode, &nd->last);
122         nd->flags |= LOOKUP_LAST;
123         dentry = __lookup_hash(&nd->last, nd->dentry, nd);
124         nd->flags &= ~LOOKUP_LAST;
125 @@ -1494,7 +1527,7 @@
126  {
127         struct dentry *dentry;
128  
129 -       down(&nd->dentry->d_inode->i_sem);
130 +       nd->lock = lock_dir(nd->dentry->d_inode, &nd->last);
131         dentry = ERR_PTR(-EEXIST);
132         if (nd->last_type != LAST_NORM)
133                 goto fail;
134 @@ -1589,7 +1622,7 @@
135                 }
136                 dput(dentry);
137         }
138 -       up(&nd.dentry->d_inode->i_sem);
139 +       unlock_dir(nd.dentry->d_inode, nd.lock);
140  out2:
141         path_release(&nd);
142  out:
143 @@ -1652,7 +1685,7 @@
144                         error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
145                         dput(dentry);
146                 }
147 -               up(&nd.dentry->d_inode->i_sem);
148 +               unlock_dir(nd.dentry->d_inode, nd.lock);
149  out2:
150                 path_release(&nd);
151  out:
152 @@ -1765,14 +1798,14 @@
153                         goto exit1;
154         }
155   
156 -       down(&nd.dentry->d_inode->i_sem);
157 +       nd.lock = lock_dir(nd.dentry->d_inode, &nd.last);
158         dentry = lookup_hash(&nd.last, nd.dentry);
159         error = PTR_ERR(dentry);
160         if (!IS_ERR(dentry)) {
161                 error = vfs_rmdir(nd.dentry->d_inode, dentry);
162                 dput(dentry);
163         }
164 -       up(&nd.dentry->d_inode->i_sem);
165 +       unlock_dir(nd.dentry->d_inode, nd.lock);
166  exit1:
167         path_release(&nd);
168  exit:
169 @@ -1842,7 +1875,7 @@
170                 if (error != -EOPNOTSUPP)
171                         goto exit1;
172         }
173 -       down(&nd.dentry->d_inode->i_sem);
174 +       nd.lock = lock_dir(nd.dentry->d_inode, &nd.last);
175         dentry = lookup_hash(&nd.last, nd.dentry);
176         error = PTR_ERR(dentry);
177         if (!IS_ERR(dentry)) {
178 @@ -1856,7 +1889,7 @@
179         exit2:
180                 dput(dentry);
181         }
182 -       up(&nd.dentry->d_inode->i_sem);
183 +       unlock_dir(nd.dentry->d_inode, nd.lock);
184  exit1:
185         path_release(&nd);
186  exit:
187 @@ -1927,7 +1960,7 @@
188                         error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
189                         dput(dentry);
190                 }
191 -               up(&nd.dentry->d_inode->i_sem);
192 +               unlock_dir(nd.dentry->d_inode, nd.lock);
193  out2:
194                 path_release(&nd);
195  out:
196 @@ -2021,7 +2054,7 @@
197                 error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
198                 dput(new_dentry);
199         }
200 -       up(&nd.dentry->d_inode->i_sem);
201 +       unlock_dir(nd.dentry->d_inode, nd.lock);
202  out_release:
203         path_release(&nd);
204  out:
205 Index: linux-2.6.7/fs/inode.c
206 ===================================================================
207 --- linux-2.6.7.orig/fs/inode.c 2004-09-06 22:53:19.000000000 +0400
208 +++ linux-2.6.7/fs/inode.c      2004-09-07 14:39:44.000000000 +0400
209 @@ -165,6 +165,7 @@
210                 }
211                 memset(&inode->u, 0, sizeof(inode->u));
212                 inode->i_mapping = mapping;
213 +               dynlock_init(&inode->i_dcache_lock);
214         }
215         return inode;
216  }
217 Index: linux-2.6.7/include/linux/fs.h
218 ===================================================================
219 --- linux-2.6.7.orig/include/linux/fs.h 2004-09-07 14:12:12.000000000 +0400
220 +++ linux-2.6.7/include/linux/fs.h      2004-09-07 14:39:44.000000000 +0400
221 @@ -19,6 +19,7 @@
222  #include <linux/prio_tree.h>
223  #include <linux/kobject.h>
224  #include <asm/atomic.h>
225 +#include <linux/dynlocks.h>
226  
227  struct iovec;
228  struct nameidata;
229 @@ -141,6 +142,7 @@
230  #define S_NOQUOTA      64      /* Inode is not counted to quota */
231  #define S_DIRSYNC      128     /* Directory modifications are synchronous */
232  #define S_NOCMTIME     256     /* Do not update file c/mtime */
233 +#define S_PDIROPS      256     /* Parallel directory operations */
234  
235  /*
236   * Note that nosuid etc flags are inode-specific: setting some file-system
237 @@ -172,6 +174,7 @@
238  #define IS_NODIRATIME(inode)   __IS_FLG(inode, MS_NODIRATIME)
239  #define IS_POSIXACL(inode)     __IS_FLG(inode, MS_POSIXACL)
240  #define IS_ONE_SECOND(inode)   __IS_FLG(inode, MS_ONE_SECOND)
241 +#define IS_PDIROPS(inode)      __IS_FLG(inode, S_PDIROPS)
242  
243  #define IS_DEADDIR(inode)      ((inode)->i_flags & S_DEAD)
244  #define IS_NOCMTIME(inode)     ((inode)->i_flags & S_NOCMTIME)
245 @@ -463,6 +466,7 @@
246         atomic_t                i_writecount;
247         void                    *i_security;
248         __u32                   i_generation;
249 +       struct dynlock          i_dcache_lock;  /* for parallel directory ops */
250         union {
251                 void            *generic_ip;
252         } u;
253 Index: linux-2.6.7/include/linux/namei.h
254 ===================================================================
255 --- linux-2.6.7.orig/include/linux/namei.h      2004-09-06 22:53:19.000000000 +0400
256 +++ linux-2.6.7/include/linux/namei.h   2004-09-07 14:40:06.000000000 +0400
257 @@ -52,6 +52,7 @@
258         unsigned int    flags;
259         int             last_type;
260         struct lookup_intent intent;
261 +       void *lock;
262  };
263  
264  /*