Whamcloud - gitweb
add lock in inserting extents to EA
[fs/lustre-release.git] / lustre / kernel_patches / patches / vfs-pdirops-2.4.20-rh.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: lum/fs/namei.c
7 ===================================================================
8 --- lum.orig/fs/namei.c 2004-06-07 17:19:45.000000000 -0400
9 +++ lum/fs/namei.c      2004-06-07 17:22:39.000000000 -0400
10 @@ -103,6 +103,36 @@
11  }
12  EXPORT_SYMBOL(intent_release);
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 @@ -307,10 +337,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 @@ -334,7 +365,7 @@
61                         else
62                                 result = dentry;
63                 }
64 -               up(&dir->i_sem);
65 +               unlock_dir(dir, lock);
66                 return result;
67         }
68  
69 @@ -342,7 +373,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 @@ -1169,13 +1200,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, nd, 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 @@ -1184,7 +1215,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 @@ -1198,7 +1229,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 @@ -1345,7 +1376,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, nd, it);
119         putname(nd->last.name);
120         goto do_last;
121 @@ -1363,7 +1394,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 @@ -1456,7 +1487,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 @@ -1523,7 +1554,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 @@ -1633,14 +1664,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, &nd, 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 @@ -1699,7 +1730,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, &nd, NULL);
172         error = PTR_ERR(dentry);
173         if (!IS_ERR(dentry)) {
174 @@ -1710,7 +1741,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 @@ -1784,7 +1815,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 @@ -1880,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: lum/fs/inode.c
202 ===================================================================
203 --- lum.orig/fs/inode.c 2004-06-07 17:19:45.000000000 -0400
204 +++ lum/fs/inode.c      2004-06-07 17:21:10.000000000 -0400
205 @@ -119,6 +119,7 @@
206                 mapping->host = inode;
207                 mapping->gfp_mask = GFP_HIGHUSER;
208                 inode->i_mapping = mapping;
209 +               dynlock_init(&inode->i_dcache_lock);
210         }
211         return inode;
212  }
213 Index: lum/include/linux/fs.h
214 ===================================================================
215 --- lum.orig/include/linux/fs.h 2004-06-07 17:19:45.000000000 -0400
216 +++ lum/include/linux/fs.h      2004-06-07 17:21:10.000000000 -0400
217 @@ -21,6 +21,7 @@
218  #include <linux/cache.h>
219  #include <linux/stddef.h>
220  #include <linux/string.h>
221 +#include <linux/dynlocks.h>
222  
223  #include <asm/atomic.h>
224  #include <asm/bitops.h>
225 @@ -139,6 +140,7 @@
226  #define S_IMMUTABLE    16      /* Immutable file */
227  #define S_DEAD         32      /* removed, but still open directory */
228  #define S_NOQUOTA      64      /* Inode is not counted to quota */
229 +#define S_PDIROPS      256     /* Parallel directory operations */
230  
231  /*
232   * Note that nosuid etc flags are inode-specific: setting some file-system
233 @@ -165,6 +167,7 @@
234  #define IS_IMMUTABLE(inode)    ((inode)->i_flags & S_IMMUTABLE)
235  #define IS_NOATIME(inode)      (__IS_FLG(inode, MS_NOATIME) || ((inode)->i_flags & S_NOATIME))
236  #define IS_NODIRATIME(inode)   __IS_FLG(inode, MS_NODIRATIME)
237 +#define IS_PDIROPS(inode)      __IS_FLG(inode, S_PDIROPS)
238  
239  #define IS_DEADDIR(inode)      ((inode)->i_flags & S_DEAD)
240  
241 @@ -500,6 +503,7 @@
242         atomic_t                i_writecount;
243         unsigned int            i_attr_flags;
244         __u32                   i_generation;
245 +       struct dynlock          i_dcache_lock;  /* for parallel directory ops */
246         union {
247                 struct minix_inode_info         minix_i;
248                 struct ext2_inode_info          ext2_i;
249 @@ -714,6 +718,7 @@
250         unsigned int flags;
251         int last_type;
252         struct lookup_intent *intent;
253 +       void *lock;
254  };
255  
256  /*
257 @@ -1631,12 +1636,6 @@
258         return dget(dentry->d_parent);
259  }
260  
261 -static inline void unlock_dir(struct dentry *dir)
262 -{
263 -       up(&dir->d_inode->i_sem);
264 -       dput(dir);
265 -}
266 -
267  /*
268   * Whee.. Deadlock country. Happily there are only two VFS
269   * operations that does this..