Whamcloud - gitweb
b=7049
[fs/lustre-release.git] / lustre / kernel_patches / patches / vfs-pdirops-2.6.10-fc3.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.10/fs/inode.c
7 ===================================================================
8 --- linux-2.6.10.orig/fs/inode.c        2004-12-25 05:35:40.000000000 +0800
9 +++ linux-2.6.10/fs/inode.c     2005-03-31 18:03:53.551688872 +0800
10 @@ -166,6 +166,7 @@
11                 }
12                 memset(&inode->u, 0, sizeof(inode->u));
13                 inode->i_mapping = mapping;
14 +               dynlock_init(&inode->i_dcache_lock);
15         }
16         return inode;
17  }
18 Index: linux-2.6.10/fs/namei.c
19 ===================================================================
20 --- linux-2.6.10.orig/fs/namei.c        2005-03-31 17:57:10.767921312 +0800
21 +++ linux-2.6.10/fs/namei.c     2005-03-31 18:05:52.839554360 +0800
22 @@ -104,6 +104,38 @@
23   * any extra contention...
24   */
25  
26 +void *lock_dir(struct inode *dir, struct qstr *name)
27 +{
28 +       unsigned long hash;
29 +       
30 +       if (!IS_PDIROPS(dir)) {
31 +               down(&dir->i_sem);
32 +               return 0;
33 +       }
34 +
35 +       /* OK. fs understands parallel directory operations.
36 +        * so, we try to acquire lock for hash of requested
37 +        * filename in order to prevent any operations with
38 +        * same name in same time -bzzz */
39 +
40 +       /* calculate name hash */
41 +       hash = full_name_hash(name->name, name->len);
42 +
43 +       /* lock this hash */
44 +       return dynlock_lock(&dir->i_dcache_lock, hash, 1, GFP_ATOMIC);
45 +}
46 +EXPORT_SYMBOL(lock_dir);
47 +
48 +void unlock_dir(struct inode *dir, void *lock)
49 +{
50 +       if (!IS_PDIROPS(dir)) {
51 +               up(&dir->i_sem);
52 +               return;
53 +       }
54 +       dynlock_unlock(&dir->i_dcache_lock, lock);
55 +}
56 +EXPORT_SYMBOL(unlock_dir);
57 +
58  /* In order to reduce some races, while at the same time doing additional
59   * checking and hopefully speeding things up, we copy filenames to the
60   * kernel data space before using them..
61 @@ -390,8 +422,9 @@
62  {
63         struct dentry * result;
64         struct inode *dir = parent->d_inode;
65 +       void *lock;
66  
67 -       down(&dir->i_sem);
68 +       lock = lock_dir(dir, name);
69         /*
70          * First re-do the cached lookup just in case it was created
71          * while we waited for the directory semaphore..
72 @@ -417,7 +450,7 @@
73                         else
74                                 result = dentry;
75                 }
76 -               up(&dir->i_sem);
77 +               unlock_dir(dir, lock);
78                 return result;
79         }
80  
81 @@ -425,7 +458,7 @@
82          * Uhhuh! Nasty case: the cache was re-populated while
83          * we waited on the semaphore. Need to revalidate.
84          */
85 -       up(&dir->i_sem);
86 +       unlock_dir(dir, lock);
87         if (result->d_op && result->d_op->d_revalidate) {
88                 if (!result->d_op->d_revalidate(result, nd) && !d_invalidate(result)) {
89                         dput(result);
90 @@ -1461,7 +1494,7 @@
91  
92         dir = nd->dentry;
93         nd->flags &= ~LOOKUP_PARENT;
94 -       down(&dir->d_inode->i_sem);
95 +       nd->lock = lock_dir(dir->d_inode, &nd->last);
96         nd->flags |= LOOKUP_LAST;
97         dentry = __lookup_hash(&nd->last, nd->dentry, nd);
98         nd->flags &= ~LOOKUP_LAST;
99 @@ -1469,7 +1502,7 @@
100  do_last:
101         error = PTR_ERR(dentry);
102         if (IS_ERR(dentry)) {
103 -               up(&dir->d_inode->i_sem);
104 +               unlock_dir(dir->d_inode, nd->lock);
105                 goto exit;
106         }
107  
108 @@ -1478,7 +1511,7 @@
109                 if (!IS_POSIXACL(dir->d_inode))
110                         mode &= ~current->fs->umask;
111                 error = vfs_create(dir->d_inode, dentry, mode, nd);
112 -               up(&dir->d_inode->i_sem);
113 +               unlock_dir(dir->d_inode, nd->lock);             
114                 dput(nd->dentry);
115                 nd->dentry = dentry;
116                 if (error)
117 @@ -1492,7 +1525,7 @@
118         /*
119          * It already exists.
120          */
121 -       up(&dir->d_inode->i_sem);
122 +       unlock_dir(dir->d_inode, nd->lock);
123  
124         error = -EEXIST;
125         if (flag & O_EXCL)
126 @@ -1576,7 +1609,7 @@
127                 goto exit;
128         }
129         dir = nd->dentry;
130 -       down(&dir->d_inode->i_sem);
131 +       nd->lock = lock_dir(dir->d_inode, &nd->last);
132         nd->flags |= LOOKUP_LAST;
133         dentry = __lookup_hash(&nd->last, nd->dentry, nd);
134         nd->flags &= ~LOOKUP_LAST;
135 @@ -1596,7 +1629,7 @@
136  {
137         struct dentry *dentry;
138  
139 -       down(&nd->dentry->d_inode->i_sem);
140 +       nd->lock = lock_dir(nd->dentry->d_inode, &nd->last);
141         dentry = ERR_PTR(-EEXIST);
142         if (nd->last_type != LAST_NORM)
143                 goto fail;
144 @@ -1688,7 +1721,7 @@
145                 }
146                 dput(dentry);
147         }
148 -       up(&nd.dentry->d_inode->i_sem);
149 +       unlock_dir(nd.dentry->d_inode, nd.lock);
150  out2:
151         path_release(&nd);
152  out:
153 @@ -1747,7 +1780,7 @@
154                         error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
155                         dput(dentry);
156                 }
157 -               up(&nd.dentry->d_inode->i_sem);
158 +               unlock_dir(nd.dentry->d_inode, nd.lock);
159  out2:
160                 path_release(&nd);
161  out:
162 @@ -1852,14 +1885,14 @@
163                         error = -EBUSY;
164                         goto exit1;
165         }
166 -       down(&nd.dentry->d_inode->i_sem);
167 +       nd.lock = lock_dir(nd.dentry->d_inode, &nd.last);
168         dentry = lookup_hash(&nd.last, nd.dentry);
169         error = PTR_ERR(dentry);
170         if (!IS_ERR(dentry)) {
171                 error = vfs_rmdir(nd.dentry->d_inode, dentry);
172                 dput(dentry);
173         }
174 -       up(&nd.dentry->d_inode->i_sem);
175 +       unlock_dir(nd.dentry->d_inode, nd.lock);
176  exit1:
177         path_release(&nd);
178  exit:
179 @@ -1925,7 +1958,7 @@
180         error = -EISDIR;
181         if (nd.last_type != LAST_NORM)
182                 goto exit1;
183 -       down(&nd.dentry->d_inode->i_sem);
184 +       nd.lock = lock_dir(nd.dentry->d_inode, &nd.last);
185         dentry = lookup_hash(&nd.last, nd.dentry);
186         error = PTR_ERR(dentry);
187         if (!IS_ERR(dentry)) {
188 @@ -1939,7 +1972,7 @@
189         exit2:
190                 dput(dentry);
191         }
192 -       up(&nd.dentry->d_inode->i_sem);
193 +       unlock_dir(nd.dentry->d_inode, nd.lock);
194         if (inode)
195                 iput(inode);    /* truncate the inode here */
196  exit1:
197 @@ -2005,7 +2038,7 @@
198                         error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
199                         dput(dentry);
200                 }
201 -               up(&nd.dentry->d_inode->i_sem);
202 +               unlock_dir(nd.dentry->d_inode, nd.lock);
203  out2:
204                 path_release(&nd);
205  out:
206 @@ -2094,7 +2127,7 @@
207                 error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
208                 dput(new_dentry);
209         }
210 -       up(&nd.dentry->d_inode->i_sem);
211 +       unlock_dir(nd.dentry->d_inode, nd.lock);
212  out_release:
213         path_release(&nd);
214  out:
215 Index: linux-2.6.10/include/linux/fs.h
216 ===================================================================
217 --- linux-2.6.10.orig/include/linux/fs.h        2005-03-31 17:57:13.330531736 +0800
218 +++ linux-2.6.10/include/linux/fs.h     2005-03-31 18:08:59.645155592 +0800
219 @@ -19,6 +19,7 @@
220  #include <linux/prio_tree.h>
221  #include <linux/kobject.h>
222  #include <asm/atomic.h>
223 +#include <linux/dynlocks.h>
224  
225  struct iovec;
226  struct nameidata;
227 @@ -151,7 +152,7 @@
228  #define S_DIRSYNC      64      /* Directory modifications are synchronous */
229  #define S_NOCMTIME     128     /* Do not update file c/mtime */
230  #define S_SWAPFILE     256     /* Do not truncate: swapon got its bmaps */
231 -
232 +#define S_PDIROPS      512     /* Parallel directory operations */
233  /*
234   * Note that nosuid etc flags are inode-specific: setting some file-system
235   * flags just means all the inodes inherit those flags by default. It might be
236 @@ -181,6 +182,7 @@
237  #define IS_NODIRATIME(inode)   __IS_FLG(inode, MS_NODIRATIME)
238  #define IS_POSIXACL(inode)     __IS_FLG(inode, MS_POSIXACL)
239  #define IS_ONE_SECOND(inode)   __IS_FLG(inode, MS_ONE_SECOND)
240 +#define IS_PDIROPS(inode)      __IS_FLG(inode, S_PDIROPS)
241  
242  #define IS_DEADDIR(inode)      ((inode)->i_flags & S_DEAD)
243  #define IS_NOCMTIME(inode)     ((inode)->i_flags & S_NOCMTIME)
244 @@ -482,6 +484,7 @@
245  
246         atomic_t                i_writecount;
247         void                    *i_security;
248 +       struct dynlock          i_dcache_lock;  /* for parallel directory ops */
249         union {
250                 void            *generic_ip;
251         } u;
252 Index: linux-2.6.10/include/linux/namei.h
253 ===================================================================
254 --- linux-2.6.10.orig/include/linux/namei.h     2005-03-31 17:50:12.533502608 +0800
255 +++ linux-2.6.10/include/linux/namei.h  2005-03-31 18:10:30.237383480 +0800
256 @@ -63,7 +63,8 @@
257         int             last_type;
258         unsigned        depth;
259         char *saved_names[MAX_NESTED_LINKS + 1];
260 -
261 +       
262 +       void *lock;
263         /* Intent data */
264         union {
265                 struct open_intent open;
266 @@ -91,7 +92,7 @@
267  #define LOOKUP_ATOMIC          64
268  #define LOOKUP_LAST            128     
269  #define LOOKUP_LINK_NOTLAST    256     
270 -+ 
271
272  /*
273   * Intent data
274   */