Whamcloud - gitweb
b=6866
[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,8 +394,9 @@
50  {
51         struct dentry * result;
52         struct inode *dir = parent->d_inode;
53 +       void *lock;
54  
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 @@ -391,7 +424,7 @@
61                         else
62                                 result = dentry;
63                 }
64 -               up(&dir->i_sem);
65 +               unlock_dir(dir, lock);
66                 return result;
67         }
68  
69 @@ -399,7 +432,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, nd) && !d_invalidate(result)) {
77                         dput(result);
78 @@ -1367,7 +1400,7 @@
79  
80         dir = nd->dentry;
81         nd->flags &= ~LOOKUP_PARENT;
82 -       down(&dir->d_inode->i_sem);
83 +       nd->lock = lock_dir(dir->d_inode, &nd->last);
84         nd->flags |= LOOKUP_LAST;
85         dentry = __lookup_hash(&nd->last, nd->dentry, nd);
86         nd->flags &= ~LOOKUP_LAST;
87 @@ -1375,7 +1408,7 @@
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 @@ -1384,7 +1417,7 @@
97                 if (!IS_POSIXACL(dir->d_inode))
98                         mode &= ~current->fs->umask;
99                 error = vfs_create(dir->d_inode, dentry, mode, nd);
100 -               up(&dir->d_inode->i_sem);
101 +               unlock_dir(dir->d_inode, nd->lock);             
102                 dput(nd->dentry);
103                 nd->dentry = dentry;
104                 if (error)
105 @@ -1398,7 +1431,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 @@ -1474,7 +1507,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         nd->flags |= LOOKUP_LAST;
121         dentry = __lookup_hash(&nd->last, nd->dentry, nd);
122         nd->flags &= ~LOOKUP_LAST;
123 @@ -1494,7 +1527,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 @@ -1589,7 +1622,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 @@ -1652,7 +1685,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 @@ -1735,14 +1735,14 @@
151                         error = -EBUSY;
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(&nd.last, nd.dentry);
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 @@ -1808,7 +1808,7 @@
168         error = -EISDIR;
169         if (nd.last_type != LAST_NORM)
170                 goto exit1;
171 -       down(&nd.dentry->d_inode->i_sem);
172 +       nd.lock = lock_dir(nd.dentry->d_inode, &nd.last);
173         dentry = lookup_hash(&nd.last, nd.dentry);
174         error = PTR_ERR(dentry);
175         if (!IS_ERR(dentry)) {
176 @@ -1856,7 +1889,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 @@ -1927,7 +1960,7 @@
186                         error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
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 @@ -2021,7 +2054,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.6.7/fs/inode.c
204 ===================================================================
205 --- linux-2.6.7.orig/fs/inode.c 2004-09-06 22:53:19.000000000 +0400
206 +++ linux-2.6.7/fs/inode.c      2004-09-07 14:39:44.000000000 +0400
207 @@ -165,6 +165,7 @@
208                 }
209                 memset(&inode->u, 0, sizeof(inode->u));
210                 inode->i_mapping = mapping;
211 +               dynlock_init(&inode->i_dcache_lock);
212         }
213         return inode;
214  }
215 Index: linux-2.6.7/include/linux/fs.h
216 ===================================================================
217 --- linux-2.6.7.orig/include/linux/fs.h 2004-09-07 14:12:12.000000000 +0400
218 +++ linux-2.6.7/include/linux/fs.h      2004-09-07 14:39:44.000000000 +0400
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 @@ -141,6 +142,7 @@
228  #define S_NOQUOTA      64      /* Inode is not counted to quota */
229  #define S_DIRSYNC      128     /* Directory modifications are synchronous */
230  #define S_NOCMTIME     256     /* Do not update file c/mtime */
231 +#define S_PDIROPS      512     /* Parallel directory operations */
232  
233  /*
234   * Note that nosuid etc flags are inode-specific: setting some file-system
235 @@ -172,6 +174,7 @@
236  #define IS_NODIRATIME(inode)   __IS_FLG(inode, MS_NODIRATIME)
237  #define IS_POSIXACL(inode)     __IS_FLG(inode, MS_POSIXACL)
238  #define IS_ONE_SECOND(inode)   __IS_FLG(inode, MS_ONE_SECOND)
239 +#define IS_PDIROPS(inode)      __IS_FLG(inode, S_PDIROPS)
240  
241  #define IS_DEADDIR(inode)      ((inode)->i_flags & S_DEAD)
242  #define IS_NOCMTIME(inode)     ((inode)->i_flags & S_NOCMTIME)
243 @@ -463,6 +466,7 @@
244         atomic_t                i_writecount;
245         void                    *i_security;
246         __u32                   i_generation;
247 +       struct dynlock          i_dcache_lock;  /* for parallel directory ops */
248         union {
249                 void            *generic_ip;
250         } u;
251 Index: linux-2.6.7/include/linux/namei.h
252 ===================================================================
253 --- linux-2.6.7.orig/include/linux/namei.h      2004-09-06 22:53:19.000000000 +0400
254 +++ linux-2.6.7/include/linux/namei.h   2004-09-07 14:40:06.000000000 +0400
255 @@ -52,6 +52,7 @@
256         unsigned int    flags;
257         int             last_type;
258 +       void *lock;
259  
260         /* Intent data */
261         union {
262                 struct open_intent open;