Whamcloud - gitweb
78fa7db20dccdbebed71040ab4baf00bf170e4fa
[fs/lustre-release.git] / lustre / patches / patch-2.4.18-14
1 --- lum/fs/namei.c~lustre       2002-12-04 01:39:11.000000000 -0700
2 +++ lum-root/fs/namei.c 2002-12-04 01:39:12.000000000 -0700
3 @@ -1,3 +1,6 @@
4 +
5 +
6 +
7  /*
8   *  linux/fs/namei.c
9   *
10 @@ -94,6 +97,14 @@
11   * XEmacs seems to be relying on it...
12   */
13  
14 +void intent_release(struct dentry *de, struct lookup_intent *it)
15 +{
16 +       if (it && de->d_op && de->d_op->d_intent_release)
17 +               de->d_op->d_intent_release(de, it);
18 +
19 +}
20 +
21 +
22  /* In order to reduce some races, while at the same time doing additional
23   * checking and hopefully speeding things up, we copy filenames to the
24   * kernel data space before using them..
25 @@ -260,10 +271,19 @@ void path_release(struct nameidata *nd)
26   * Internal lookup() using the new generic dcache.
27   * SMP-safe
28   */
29 -static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
30 +static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name,
31 +                                   int flags, struct lookup_intent *it)
32  {
33         struct dentry * dentry = d_lookup(parent, name);
34  
35 +       if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
36 +               if (!dentry->d_op->d_revalidate2(dentry, flags, it) &&
37 +                   !d_invalidate(dentry)) {
38 +                       dput(dentry);
39 +                       dentry = NULL;
40 +               }
41 +               return dentry;
42 +       } else
43         if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
44                 if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
45                         dput(dentry);
46 @@ -281,7 +301,8 @@ static struct dentry * cached_lookup(str
47   * make sure that nobody added the entry to the dcache in the meantime..
48   * SMP-safe
49   */
50 -static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
51 +static struct dentry *real_lookup(struct dentry *parent, struct qstr *name,
52 +                                 int flags, struct lookup_intent *it)
53  {
54         struct dentry * result;
55         struct inode *dir = parent->d_inode;
56 @@ -300,6 +321,9 @@ static struct dentry * real_lookup(struc
57                 result = ERR_PTR(-ENOMEM);
58                 if (dentry) {
59                         lock_kernel();
60 +                       if (dir->i_op->lookup2)
61 +                               result = dir->i_op->lookup2(dir, dentry, it);
62 +                       else
63                         result = dir->i_op->lookup(dir, dentry);
64                         unlock_kernel();
65                         if (result)
66 @@ -321,6 +345,12 @@ static struct dentry * real_lookup(struc
67                         dput(result);
68                         result = ERR_PTR(-ENOENT);
69                 }
70 +       } else if (result->d_op && result->d_op->d_revalidate2) {
71 +               if (!result->d_op->d_revalidate2(result, flags, it) &&
72 +                   !d_invalidate(result)) {
73 +                       dput(result);
74 +                       result = ERR_PTR(-ENOENT);
75 +               }
76         }
77         return result;
78  }
79 @@ -334,7 +364,8 @@ int max_recursive_link = 5;
80   * Without that kind of total limit, nasty chains of consecutive
81   * symlinks can cause almost arbitrarily long lookups. 
82   */
83 -static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
84 +static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd, 
85 +                                 struct lookup_intent *it)
86  {
87         int err;
88         if (current->link_count >= max_recursive_link)
89 @@ -348,10 +379,14 @@ static inline int do_follow_link(struct 
90         current->link_count++;
91         current->total_link_count++;
92         UPDATE_ATIME(dentry->d_inode);
93 -       err = dentry->d_inode->i_op->follow_link(dentry, nd);
94 +        if (dentry->d_inode->i_op->follow_link2)
95 +                err = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
96 +        else 
97 +                err = dentry->d_inode->i_op->follow_link(dentry, nd);
98         current->link_count--;
99         return err;
100  loop:
101 +        intent_release(dentry, it);
102         path_release(nd);
103         return -ELOOP;
104  }
105 @@ -449,7 +484,8 @@ static inline void follow_dotdot(struct 
106   *
107   * We expect 'base' to be positive and a directory.
108   */
109 -int link_path_walk(const char * name, struct nameidata *nd)
110 +int link_path_walk_it(const char *name, struct nameidata *nd,
111 +                     struct lookup_intent *it)
112  {
113         struct dentry *dentry;
114         struct inode *inode;
115 @@ -526,12 +562,12 @@ int link_path_walk(const char * name, st
116                                 break;
117                 }
118                 /* This does the actual lookups.. */
119 -               dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
120 +               dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
121                 if (!dentry) {
122                         err = -EWOULDBLOCKIO;
123                         if (atomic)
124                                 break;
125 -                       dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
126 +                       dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
127                         err = PTR_ERR(dentry);
128                         if (IS_ERR(dentry))
129                                 break;
130 @@ -548,8 +584,8 @@ int link_path_walk(const char * name, st
131                 if (!inode->i_op)
132                         goto out_dput;
133  
134 -               if (inode->i_op->follow_link) {
135 -                       err = do_follow_link(dentry, nd);
136 +               if (inode->i_op->follow_link || inode->i_op->follow_link2) {
137 +                       err = do_follow_link(dentry, nd, it);
138                         dput(dentry);
139                         if (err)
140                                 goto return_err;
141 @@ -565,7 +601,7 @@ int link_path_walk(const char * name, st
142                         nd->dentry = dentry;
143                 }
144                 err = -ENOTDIR; 
145 -               if (!inode->i_op->lookup)
146 +               if (!inode->i_op->lookup && !inode->i_op->lookup2)
147                         break;
148                 continue;
149                 /* here ends the main loop */
150 @@ -592,12 +628,12 @@ last_component:
151                         if (err < 0)
152                                 break;
153                 }
154 -               dentry = cached_lookup(nd->dentry, &this, 0);
155 +               dentry = cached_lookup(nd->dentry, &this, 0, it);
156                 if (!dentry) {
157                         err = -EWOULDBLOCKIO;
158                         if (atomic)
159                                 break;
160 -                       dentry = real_lookup(nd->dentry, &this, 0);
161 +                       dentry = real_lookup(nd->dentry, &this, 0, it);
162                         err = PTR_ERR(dentry);
163                         if (IS_ERR(dentry))
164                                 break;
165 @@ -606,8 +642,10 @@ last_component:
166                         ;
167                 inode = dentry->d_inode;
168                 if ((lookup_flags & LOOKUP_FOLLOW)
169 -                   && inode && inode->i_op && inode->i_op->follow_link) {
170 -                       err = do_follow_link(dentry, nd);
171 +                   && inode && inode->i_op && 
172 +                    (inode->i_op->follow_link || 
173 +                     inode->i_op->follow_link2)) {
174 +                       err = do_follow_link(dentry, nd, it);
175                         dput(dentry);
176                         if (err)
177                                 goto return_err;
178 @@ -621,7 +659,8 @@ last_component:
179                         goto no_inode;
180                 if (lookup_flags & LOOKUP_DIRECTORY) {
181                         err = -ENOTDIR; 
182 -                       if (!inode->i_op || !inode->i_op->lookup)
183 +                       if (!inode->i_op || (!inode->i_op->lookup &&
184 +                                            !inode->i_op->lookup2))
185                                 break;
186                 }
187                 goto return_base;
188 @@ -663,10 +702,21 @@ return_err:
189         return err;
190  }
191  
192 +int link_path_walk(const char * name, struct nameidata *nd)
193 +{
194 +       return link_path_walk_it(name, nd, NULL);
195 +}
196 +
197 +int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
198 +{
199 +       current->total_link_count = 0;
200 +       return link_path_walk_it(name, nd, it);
201 +}
202 +
203  int path_walk(const char * name, struct nameidata *nd)
204  {
205         current->total_link_count = 0;
206 -       return link_path_walk(name, nd);
207 +       return link_path_walk_it(name, nd, NULL);
208  }
209  
210  /* SMP-safe */
211 @@ -751,6 +801,17 @@ walk_init_root(const char *name, struct 
212  }
213  
214  /* SMP-safe */
215 +int path_lookup_it(const char *path, unsigned flags, struct nameidata *nd,
216 +                  struct lookup_intent *it)
217 +{
218 +       int error = 0;
219 +       if (path_init(path, flags, nd))
220 +               error = path_walk_it(path, nd, it);
221 +       return error;
222 +}
223 +
224 +
225 +/* SMP-safe */
226  int path_lookup(const char *path, unsigned flags, struct nameidata *nd)
227  {
228         int error = 0;
229 @@ -779,7 +840,8 @@ int path_init(const char *name, unsigned
230   * needs parent already locked. Doesn't follow mounts.
231   * SMP-safe.
232   */
233 -struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
234 +struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base,
235 +                              struct lookup_intent *it)
236  {
237         struct dentry * dentry;
238         struct inode *inode;
239 @@ -802,13 +864,16 @@ struct dentry * lookup_hash(struct qstr 
240                         goto out;
241         }
242  
243 -       dentry = cached_lookup(base, name, 0);
244 +       dentry = cached_lookup(base, name, 0, it);
245         if (!dentry) {
246                 struct dentry *new = d_alloc(base, name);
247                 dentry = ERR_PTR(-ENOMEM);
248                 if (!new)
249                         goto out;
250                 lock_kernel();
251 +               if (inode->i_op->lookup2)
252 +                       dentry = inode->i_op->lookup2(inode, new, it);
253 +               else
254                 dentry = inode->i_op->lookup(inode, new);
255                 unlock_kernel();
256                 if (!dentry)
257 @@ -820,6 +885,12 @@ out:
258         return dentry;
259  }
260  
261 +struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
262 +{
263 +       return lookup_hash_it(name, base, NULL);
264 +}
265 +
266 +
267  /* SMP-safe */
268  struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
269  {
270 @@ -841,7 +912,7 @@ struct dentry * lookup_one_len(const cha
271         }
272         this.hash = end_name_hash(hash);
273  
274 -       return lookup_hash(&this, base);
275 +       return lookup_hash_it(&this, base, NULL);
276  access:
277         return ERR_PTR(-EACCES);
278  }
279 @@ -872,6 +943,23 @@ int __user_walk(const char *name, unsign
280         return err;
281  }
282  
283 +int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd,
284 +                  struct lookup_intent *it)
285 +{
286 +       char *tmp;
287 +       int err;
288 +
289 +       tmp = getname(name);
290 +       err = PTR_ERR(tmp);
291 +       if (!IS_ERR(tmp)) {
292 +               err = 0;
293 +               if (path_init(tmp, flags, nd))
294 +                       err = path_walk_it(tmp, nd, it);
295 +               putname(tmp);
296 +       }
297 +       return err;
298 +}
299 +
300  /*
301   * It's inline, so penalty for filesystems that don't use sticky bit is
302   * minimal.
303 @@ -1010,7 +1098,8 @@ exit_lock:
304   * for symlinks (where the permissions are checked later).
305   * SMP-safe
306   */
307 -int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
308 +int open_namei_it(const char *pathname, int flag, int mode,
309 +                 struct nameidata *nd, struct lookup_intent *it)
310  {
311         int acc_mode, error = 0;
312         struct inode *inode;
313 @@ -1024,7 +1113,7 @@ int open_namei(const char * pathname, in
314          * The simplest case - just a plain lookup.
315          */
316         if (!(flag & O_CREAT)) {
317 -               error = path_lookup(pathname, lookup_flags(flag), nd);
318 +               error = path_lookup_it(pathname, lookup_flags(flag), nd, it);
319                 if (error)
320                         return error;
321                 dentry = nd->dentry;
322 @@ -1034,6 +1123,10 @@ int open_namei(const char * pathname, in
323         /*
324          * Create - we need to know the parent.
325          */
326 +       if (it) {
327 +               it->it_mode = mode;
328 +               it->it_op |= IT_CREAT;
329 +       }
330         error = path_lookup(pathname, LOOKUP_PARENT, nd);
331         if (error)
332                 return error;
333 @@ -1049,7 +1142,7 @@ int open_namei(const char * pathname, in
334  
335         dir = nd->dentry;
336         down(&dir->d_inode->i_sem);
337 -       dentry = lookup_hash(&nd->last, nd->dentry);
338 +       dentry = lookup_hash_it(&nd->last, nd->dentry, it);
339  
340  do_last:
341         error = PTR_ERR(dentry);
342 @@ -1058,6 +1151,7 @@ do_last:
343                 goto exit;
344         }
345  
346 +       it->it_mode = mode;
347         /* Negative dentry, just create the file */
348         if (!dentry->d_inode) {
349                 error = vfs_create(dir->d_inode, dentry,
350 @@ -1091,7 +1185,8 @@ do_last:
351         error = -ENOENT;
352         if (!dentry->d_inode)
353                 goto exit_dput;
354 -       if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link)
355 +       if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link || 
356 +                                      dentry->d_inode->i_op->follow_link2))
357                 goto do_link;
358  
359         dput(nd->dentry);
360 @@ -1177,8 +1272,10 @@ ok:
361         return 0;
362  
363  exit_dput:
364 +       intent_release(dentry, it);
365         dput(dentry);
366  exit:
367 +       intent_release(nd->dentry, it);
368         path_release(nd);
369         return error;
370  
371 @@ -1197,7 +1294,12 @@ do_link:
372          * are done. Procfs-like symlinks just set LAST_BIND.
373          */
374         UPDATE_ATIME(dentry->d_inode);
375 -       error = dentry->d_inode->i_op->follow_link(dentry, nd);
376 +        if (dentry->d_inode->i_op->follow_link2) 
377 +                error = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
378 +        else 
379 +                error = dentry->d_inode->i_op->follow_link(dentry, nd);
380 +       if (error)
381 +               intent_release(dentry, it);
382         dput(dentry);
383         if (error)
384                 return error;
385 @@ -1219,13 +1321,20 @@ do_link:
386         }
387         dir = nd->dentry;
388         down(&dir->d_inode->i_sem);
389 -       dentry = lookup_hash(&nd->last, nd->dentry);
390 +       dentry = lookup_hash_it(&nd->last, nd->dentry, it);
391         putname(nd->last.name);
392         goto do_last;
393  }
394  
395 +int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd)
396 +{
397 +       return open_namei_it(pathname, flag, mode, nd, NULL);
398 +}
399 +
400 +
401  /* SMP-safe */
402 -static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
403 +static struct dentry *lookup_create(struct nameidata *nd, int is_dir,
404 +                                   struct lookup_intent *it)
405  {
406         struct dentry *dentry;
407  
408 @@ -1233,7 +1342,7 @@ static struct dentry *lookup_create(stru
409         dentry = ERR_PTR(-EEXIST);
410         if (nd->last_type != LAST_NORM)
411                 goto fail;
412 -       dentry = lookup_hash(&nd->last, nd->dentry);
413 +       dentry = lookup_hash_it(&nd->last, nd->dentry, it);
414         if (IS_ERR(dentry))
415                 goto fail;
416         if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
417 @@ -1279,6 +1388,7 @@ asmlinkage long sys_mknod(const char * f
418         char * tmp;
419         struct dentry * dentry;
420         struct nameidata nd;
421 +       struct lookup_intent it = { .it_op = IT_MKNOD, .it_mode = mode };
422  
423         if (S_ISDIR(mode))
424                 return -EPERM;
425 @@ -1289,7 +1399,7 @@ asmlinkage long sys_mknod(const char * f
426         error = path_lookup(tmp, LOOKUP_PARENT, &nd);
427         if (error)
428                 goto out;
429 -       dentry = lookup_create(&nd, 0);
430 +       dentry = lookup_create(&nd, 0, &it);
431         error = PTR_ERR(dentry);
432  
433         mode &= ~current->fs->umask;
434 @@ -1307,6 +1417,7 @@ asmlinkage long sys_mknod(const char * f
435                 default:
436                         error = -EINVAL;
437                 }
438 +               intent_release(dentry, &it);
439                 dput(dentry);
440         }
441         up(&nd.dentry->d_inode->i_sem);
442 @@ -1347,6 +1458,7 @@ asmlinkage long sys_mkdir(const char * p
443  {
444         int error = 0;
445         char * tmp;
446 +       struct lookup_intent it = { .it_op = IT_MKDIR, .it_mode = mode };
447  
448         tmp = getname(pathname);
449         error = PTR_ERR(tmp);
450 @@ -1357,11 +1469,12 @@ asmlinkage long sys_mkdir(const char * p
451                 error = path_lookup(tmp, LOOKUP_PARENT, &nd);
452                 if (error)
453                         goto out;
454 -               dentry = lookup_create(&nd, 1);
455 +               dentry = lookup_create(&nd, 1, &it);
456                 error = PTR_ERR(dentry);
457                 if (!IS_ERR(dentry)) {
458                         error = vfs_mkdir(nd.dentry->d_inode, dentry,
459                                           mode & ~current->fs->umask);
460 +                       intent_release(dentry, &it);
461                         dput(dentry);
462                 }
463                 up(&nd.dentry->d_inode->i_sem);
464 @@ -1445,6 +1558,7 @@ asmlinkage long sys_rmdir(const char * p
465         char * name;
466         struct dentry *dentry;
467         struct nameidata nd;
468 +       struct lookup_intent it = { .it_op = IT_RMDIR };
469  
470         name = getname(pathname);
471         if(IS_ERR(name))
472 @@ -1466,10 +1580,11 @@ asmlinkage long sys_rmdir(const char * p
473                         goto exit1;
474         }
475         down(&nd.dentry->d_inode->i_sem);
476 -       dentry = lookup_hash(&nd.last, nd.dentry);
477 +       dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
478         error = PTR_ERR(dentry);
479         if (!IS_ERR(dentry)) {
480                 error = vfs_rmdir(nd.dentry->d_inode, dentry);
481 +               intent_release(dentry, &it);
482                 dput(dentry);
483         }
484         up(&nd.dentry->d_inode->i_sem);
485 @@ -1513,6 +1628,7 @@ asmlinkage long sys_unlink(const char * 
486         char * name;
487         struct dentry *dentry;
488         struct nameidata nd;
489 +       struct lookup_intent it = { .it_op = IT_UNLINK };
490  
491         name = getname(pathname);
492         if(IS_ERR(name))
493 @@ -1525,7 +1641,7 @@ asmlinkage long sys_unlink(const char * 
494         if (nd.last_type != LAST_NORM)
495                 goto exit1;
496         down(&nd.dentry->d_inode->i_sem);
497 -       dentry = lookup_hash(&nd.last, nd.dentry);
498 +       dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
499         error = PTR_ERR(dentry);
500         if (!IS_ERR(dentry)) {
501                 /* Why not before? Because we want correct error value */
502 @@ -1533,6 +1649,7 @@ asmlinkage long sys_unlink(const char * 
503                         goto slashes;
504                 error = vfs_unlink(nd.dentry->d_inode, dentry);
505         exit2:
506 +               intent_release(dentry, &it);
507                 dput(dentry);
508         }
509         up(&nd.dentry->d_inode->i_sem);
510 @@ -1579,6 +1696,7 @@ asmlinkage long sys_symlink(const char *
511         int error = 0;
512         char * from;
513         char * to;
514 +       struct lookup_intent it = { .it_op = IT_SYMLINK };
515  
516         from = getname(oldname);
517         if(IS_ERR(from))
518 @@ -1592,10 +1710,12 @@ asmlinkage long sys_symlink(const char *
519                 error = path_lookup(to, LOOKUP_PARENT, &nd);
520                 if (error)
521                         goto out;
522 -               dentry = lookup_create(&nd, 0);
523 +               it.it_data = from;
524 +               dentry = lookup_create(&nd, 0, &it);
525                 error = PTR_ERR(dentry);
526                 if (!IS_ERR(dentry)) {
527                         error = vfs_symlink(nd.dentry->d_inode, dentry, from);
528 +                       intent_release(dentry, &it);
529                         dput(dentry);
530                 }
531                 up(&nd.dentry->d_inode->i_sem);
532 @@ -1660,6 +1780,7 @@ asmlinkage long sys_link(const char * ol
533  {
534         int error;
535         char * to;
536 +       struct lookup_intent it = { .it_op = IT_LINK };
537  
538         to = getname(newname);
539         error = PTR_ERR(to);
540 @@ -1667,7 +1788,7 @@ asmlinkage long sys_link(const char * ol
541                 struct dentry *new_dentry;
542                 struct nameidata nd, old_nd;
543  
544 -               error = __user_walk(oldname, LOOKUP_POSITIVE, &old_nd);
545 +               error = __user_walk_it(oldname, LOOKUP_POSITIVE, &old_nd, &it);
546                 if (error)
547                         goto exit;
548                 error = path_lookup(to, LOOKUP_PARENT, &nd);
549 @@ -1676,10 +1797,12 @@ asmlinkage long sys_link(const char * ol
550                 error = -EXDEV;
551                 if (old_nd.mnt != nd.mnt)
552                         goto out_release;
553 -               new_dentry = lookup_create(&nd, 0);
554 +               it.it_op = IT_LINK2;
555 +               new_dentry = lookup_create(&nd, 0, &it);
556                 error = PTR_ERR(new_dentry);
557                 if (!IS_ERR(new_dentry)) {
558                         error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
559 +                       intent_release(new_dentry, &it);
560                         dput(new_dentry);
561                 }
562                 up(&nd.dentry->d_inode->i_sem);
563 @@ -1720,7 +1843,8 @@ exit:
564   *        locking].
565   */
566  int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
567 -              struct inode *new_dir, struct dentry *new_dentry)
568 +                  struct inode *new_dir, struct dentry *new_dentry,
569 +                  struct lookup_intent *it)
570  {
571         int error;
572         struct inode *target;
573 @@ -1778,6 +1902,7 @@ int vfs_rename_dir(struct inode *old_dir
574                 error = -EBUSY;
575         else 
576                 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
577 +       intent_release(new_dentry, it);
578         if (target) {
579                 if (!error)
580                         target->i_flags |= S_DEAD;
581 @@ -1799,7 +1924,8 @@ out_unlock:
582  }
583  
584  int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
585 -              struct inode *new_dir, struct dentry *new_dentry)
586 +                    struct inode *new_dir, struct dentry *new_dentry,
587 +                    struct lookup_intent *it)
588  {
589         int error;
590  
591 @@ -1830,6 +1956,7 @@ int vfs_rename_other(struct inode *old_d
592                 error = -EBUSY;
593         else
594                 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
595 +       intent_release(new_dentry, it);
596         double_up(&old_dir->i_zombie, &new_dir->i_zombie);
597         if (error)
598                 return error;
599 @@ -1841,13 +1968,14 @@ int vfs_rename_other(struct inode *old_d
600  }
601  
602  int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
603 -              struct inode *new_dir, struct dentry *new_dentry)
604 +              struct inode *new_dir, struct dentry *new_dentry,
605 +              struct lookup_intent *it)
606  {
607         int error;
608         if (S_ISDIR(old_dentry->d_inode->i_mode))
609 -               error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
610 +               error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it);
611         else
612 -               error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
613 +               error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it);
614         if (!error) {
615                 if (old_dir == new_dir)
616                         inode_dir_notify(old_dir, DN_RENAME);
617 @@ -1864,6 +1992,7 @@ static inline int do_rename(const char *
618         int error = 0;
619         struct dentry * old_dir, * new_dir;
620         struct dentry * old_dentry, *new_dentry;
621 +       struct lookup_intent it = { .it_op = IT_RENAME };
622         struct nameidata oldnd, newnd;
623  
624         error = path_lookup(oldname, LOOKUP_PARENT, &oldnd);
625 @@ -1889,7 +2018,7 @@ static inline int do_rename(const char *
626  
627         double_lock(new_dir, old_dir);
628  
629 -       old_dentry = lookup_hash(&oldnd.last, old_dir);
630 +       old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it);
631         error = PTR_ERR(old_dentry);
632         if (IS_ERR(old_dentry))
633                 goto exit3;
634 @@ -1905,18 +2034,21 @@ static inline int do_rename(const char *
635                 if (newnd.last.name[newnd.last.len])
636                         goto exit4;
637         }
638 -       new_dentry = lookup_hash(&newnd.last, new_dir);
639 +       it.it_op = IT_RENAME2;
640 +       new_dentry = lookup_hash_it(&newnd.last, new_dir, &it);
641         error = PTR_ERR(new_dentry);
642         if (IS_ERR(new_dentry))
643                 goto exit4;
644  
645         lock_kernel();
646         error = vfs_rename(old_dir->d_inode, old_dentry,
647 -                                  new_dir->d_inode, new_dentry);
648 +                                  new_dir->d_inode, new_dentry, &it);
649         unlock_kernel();
650  
651 +       intent_release(new_dentry, &it);
652         dput(new_dentry);
653  exit4:
654 +       intent_release(old_dentry, &it);
655         dput(old_dentry);
656  exit3:
657         double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem);
658 @@ -1965,7 +2097,8 @@ out:
659  }
660  
661  static inline int
662 -__vfs_follow_link(struct nameidata *nd, const char *link)
663 +__vfs_follow_link(struct nameidata *nd, const char *link, 
664 +                     struct lookup_intent *it)
665  {
666         int res = 0;
667         char *name;
668 @@ -1978,7 +2111,7 @@ __vfs_follow_link(struct nameidata *nd, 
669                         /* weird __emul_prefix() stuff did it */
670                         goto out;
671         }
672 -       res = link_path_walk(link, nd);
673 +       res = link_path_walk_it(link, nd, it);
674  out:
675         if (current->link_count || res || nd->last_type!=LAST_NORM)
676                 return res;
677 @@ -2000,7 +2133,13 @@ fail:
678  
679  int vfs_follow_link(struct nameidata *nd, const char *link)
680  {
681 -       return __vfs_follow_link(nd, link);
682 +       return __vfs_follow_link(nd, link, NULL);
683 +}
684 +
685 +int vfs_follow_link_it(struct nameidata *nd, const char *link, 
686 +                       struct lookup_intent *it)
687 +{
688 +       return __vfs_follow_link(nd, link, it);
689  }
690  
691  /* get the link contents into pagecache */
692 @@ -2042,7 +2181,7 @@ int page_follow_link(struct dentry *dent
693  {
694         struct page *page = NULL;
695         char *s = page_getlink(dentry, &page);
696 -       int res = __vfs_follow_link(nd, s);
697 +       int res = __vfs_follow_link(nd, s, NULL);
698         if (page) {
699                 kunmap(page);
700                 page_cache_release(page);
701 --- /dev/null   2002-08-30 17:31:37.000000000 -0600
702 +++ lum-root/include/linux/lustre_version.h     2002-12-04 01:39:12.000000000 -0700
703 @@ -0,0 +1 @@
704 +#define LUSTRE_KERNEL_VERSION 4
705 --- lum/arch/ia64/mm/init.c~lustre      2002-12-04 01:39:11.000000000 -0700
706 +++ lum-root/arch/ia64/mm/init.c        2002-12-04 01:39:12.000000000 -0700
707 @@ -37,6 +37,12 @@ unsigned long MAX_DMA_ADDRESS = PAGE_OFF
708  
709  static unsigned long totalram_pages;
710  
711 +struct page *check_get_page(unsigned long kaddr)
712 +{
713 +#warning FIXME: Lustre team, is this solid?
714 +       return virt_to_page(kaddr);
715 +}
716 +
717  int
718  do_check_pgt_cache (int low, int high)
719  {
720 --- lum/arch/i386/mm/init.c~lustre      2002-12-04 01:39:11.000000000 -0700
721 +++ lum-root/arch/i386/mm/init.c        2002-12-04 01:39:12.000000000 -0700
722 @@ -43,6 +43,12 @@ unsigned long highstart_pfn, highend_pfn
723  static unsigned long totalram_pages;
724  static unsigned long totalhigh_pages;
725  
726 +struct page *check_get_page(unsigned long kaddr)
727 +{
728 +#warning FIXME: Lustre team, is this solid?
729 +       return virt_to_page(kaddr);
730 +}
731 +
732  int do_check_pgt_cache(int low, int high)
733  {
734         int freed = 0;
735 --- lum/drivers/block/blkpg.c~lustre    2002-12-04 01:39:11.000000000 -0700
736 +++ lum-root/drivers/block/blkpg.c      2002-12-04 01:39:12.000000000 -0700
737 @@ -297,3 +297,38 @@ int blk_ioctl(kdev_t dev, unsigned int c
738  }
739  
740  EXPORT_SYMBOL(blk_ioctl);
741 +
742 +#define NUM_DEV_NO_WRITE 16
743 +static int dev_no_write[NUM_DEV_NO_WRITE];
744 +
745 +/*
746 + * Debug code for turning block devices "read-only" (will discard writes
747 + * silently).  This is for filesystem crash/recovery testing.
748 + */
749 +void dev_set_rdonly(kdev_t dev, int no_write)
750 +{
751 +       if (dev) {
752 +               printk(KERN_WARNING "Turning device %s read-only\n",
753 +                      bdevname(dev));
754 +               dev_no_write[no_write] = 0xdead0000 + dev;
755 +       }
756 +}
757 +
758 +int dev_check_rdonly(kdev_t dev) {
759 +       int i;
760 +
761 +       for (i = 0; i < NUM_DEV_NO_WRITE; i++) {
762 +               if ((dev_no_write[i] & 0xffff0000) == 0xdead0000 &&
763 +                   dev == (dev_no_write[i] & 0xffff))
764 +                       return 1;
765 +       }
766 +       return 0;
767 +}
768 +
769 +void dev_clear_rdonly(int no_write) {
770 +       dev_no_write[no_write] = 0;
771 +}
772 +
773 +EXPORT_SYMBOL(dev_set_rdonly);
774 +EXPORT_SYMBOL(dev_check_rdonly);
775 +EXPORT_SYMBOL(dev_clear_rdonly);
776 --- lum/drivers/block/loop.c~lustre     2002-12-04 01:39:12.000000000 -0700
777 +++ lum-root/drivers/block/loop.c       2002-12-04 01:39:12.000000000 -0700
778 @@ -491,6 +491,11 @@ static int loop_make_request(request_que
779         spin_unlock_irq(&lo->lo_lock);
780  
781         if (rw == WRITE) {
782 +#ifdef CONFIG_DEV_RDONLY
783 +               if (dev_check_rdonly(rbh->b_rdev))
784 +                       goto err;
785 +#endif
786 +
787                 if (lo->lo_flags & LO_FLAGS_READ_ONLY)
788                         goto err;
789         } else if (rw == READA) {
790 --- lum/drivers/ide/ide-disk.c~lustre   2002-12-04 01:39:12.000000000 -0700
791 +++ lum-root/drivers/ide/ide-disk.c     2002-12-04 01:39:12.000000000 -0700
792 @@ -557,6 +557,12 @@ static ide_startstop_t lba_48_rw_disk (i
793   */
794  static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
795  {
796 +#ifdef CONFIG_DEV_RDONLY
797 +       if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) {
798 +               ide_end_request(1, HWGROUP(drive));
799 +               return ide_stopped;
800 +       }
801 +#endif
802         if (IDE_CONTROL_REG)
803                 OUT_BYTE(drive->ctl,IDE_CONTROL_REG);
804  
805 --- lum/fs/ext3/Makefile~lustre 2002-12-04 01:39:12.000000000 -0700
806 +++ lum-root/fs/ext3/Makefile   2002-12-04 01:39:12.000000000 -0700
807 @@ -9,6 +9,8 @@
808  
809  O_TARGET := ext3.o
810  
811 +export-objs := super.o
812 +
813  obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
814                 ioctl.o namei.o super.o symlink.o
815  obj-m    := $(O_TARGET)
816 --- lum/fs/ext3/super.c~lustre  2002-12-04 01:39:12.000000000 -0700
817 +++ lum-root/fs/ext3/super.c    2002-12-04 01:39:12.000000000 -0700
818 @@ -1746,7 +1746,7 @@ static void __exit exit_ext3_fs(void)
819         unregister_filesystem(&ext3_fs_type);
820  }
821  
822 -EXPORT_NO_SYMBOLS;
823 +EXPORT_SYMBOL(ext3_bread);
824  
825  MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
826  MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");
827 --- lum/include/linux/slab.h~lustre     2002-12-04 01:39:12.000000000 -0700
828 +++ lum-root/include/linux/slab.h       2002-12-04 01:39:12.000000000 -0700
829 @@ -57,6 +57,7 @@ extern int kmem_cache_destroy(kmem_cache
830  extern int kmem_cache_shrink(kmem_cache_t *);
831  extern void *kmem_cache_alloc(kmem_cache_t *, int);
832  extern void kmem_cache_free(kmem_cache_t *, void *);
833 +extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp);
834  
835  extern void *kmalloc(size_t, int);
836  extern void kfree(const void *);
837 --- lum/kernel/ksyms.c~lustre   2002-12-04 01:39:12.000000000 -0700
838 +++ lum-root/kernel/ksyms.c     2002-12-04 01:39:12.000000000 -0700
839 @@ -292,6 +292,7 @@ EXPORT_SYMBOL(read_cache_page);
840  EXPORT_SYMBOL(set_page_dirty);
841  EXPORT_SYMBOL(vfs_readlink);
842  EXPORT_SYMBOL(vfs_follow_link);
843 +EXPORT_SYMBOL(vfs_follow_link_it);
844  EXPORT_SYMBOL(page_readlink);
845  EXPORT_SYMBOL(page_follow_link);
846  EXPORT_SYMBOL(page_symlink_inode_operations);
847 @@ -306,6 +307,12 @@ EXPORT_SYMBOL_GPL(buffermem_pages);
848  EXPORT_SYMBOL_GPL(nr_free_pages);
849  EXPORT_SYMBOL_GPL(page_cache_size);
850  
851 +/* lustre */
852 +EXPORT_SYMBOL(panic_notifier_list);
853 +EXPORT_SYMBOL(pagecache_lock_cacheline);
854 +EXPORT_SYMBOL(do_kern_mount);
855 +EXPORT_SYMBOL(kmem_cache_validate);
856 +
857  /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
858  EXPORT_SYMBOL(default_llseek);
859  EXPORT_SYMBOL(dentry_open);
860 --- lum/include/linux/dcache.h~lustre   2002-12-04 01:39:12.000000000 -0700
861 +++ lum-root/include/linux/dcache.h     2002-12-04 01:39:12.000000000 -0700
862 @@ -6,6 +6,34 @@
863  #include <asm/atomic.h>
864  #include <linux/mount.h>
865  
866 +#define IT_OPEN  (1)
867 +#define IT_CREAT  (1<<1)
868 +#define IT_MKDIR  (1<<2)
869 +#define IT_LINK  (1<<3)
870 +#define IT_LINK2  (1<<4)
871 +#define IT_SYMLINK  (1<<5)
872 +#define IT_UNLINK  (1<<6)
873 +#define IT_RMDIR  (1<<7)
874 +#define IT_RENAME  (1<<8)
875 +#define IT_RENAME2  (1<<9)
876 +#define IT_READDIR  (1<<10)
877 +#define IT_GETATTR  (1<<11)
878 +#define IT_SETATTR  (1<<12)
879 +#define IT_READLINK  (1<<13)
880 +#define IT_MKNOD  (1<<14)
881 +#define IT_LOOKUP  (1<<15)
882 +
883 +struct lookup_intent {
884 +       int it_op;
885 +       int it_mode;
886 +       int it_disposition;
887 +       int it_status;
888 +       struct iattr *it_iattr;
889 +       __u64 it_lock_handle[2];
890 +       int it_lock_mode;
891 +       void *it_data;
892 +};
893 +
894  /*
895   * linux/include/linux/dcache.h
896   *
897 @@ -78,6 +106,7 @@ struct dentry {
898         unsigned long d_time;           /* used by d_revalidate */
899         struct dentry_operations  *d_op;
900         struct super_block * d_sb;      /* The root of the dentry tree */
901 +       struct lookup_intent *d_it;
902         unsigned long d_vfs_flags;
903         void * d_fsdata;                /* fs-specific data */
904         void * d_extra_attributes;      /* TUX-specific data */
905 @@ -91,6 +120,8 @@ struct dentry_operations {
906         int (*d_delete)(struct dentry *);
907         void (*d_release)(struct dentry *);
908         void (*d_iput)(struct dentry *, struct inode *);
909 +       int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
910 +       void (*d_intent_release)(struct dentry *, struct lookup_intent *);
911  };
912  
913  /* the dentry parameter passed to d_hash and d_compare is the parent
914 --- lum/include/linux/fs.h~lustre       2002-12-04 01:39:12.000000000 -0700
915 +++ lum-root/include/linux/fs.h 2002-12-04 01:39:12.000000000 -0700
916 @@ -576,6 +576,7 @@ struct file {
917  
918         /* needed for tty driver, and maybe others */
919         void                    *private_data;
920 +       struct lookup_intent    *f_intent;
921  
922         /* preallocated helper kiobuf to speedup O_DIRECT */
923         struct kiobuf           *f_iobuf;
924 @@ -836,7 +837,9 @@ extern int vfs_symlink(struct inode *, s
925  extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
926  extern int vfs_rmdir(struct inode *, struct dentry *);
927  extern int vfs_unlink(struct inode *, struct dentry *);
928 -extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
929 +int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
930 +               struct inode *new_dir, struct dentry *new_dentry,
931 +               struct lookup_intent *it);
932  
933  /*
934   * File types
935 @@ -897,6 +900,7 @@ struct file_operations {
936  struct inode_operations {
937         int (*create) (struct inode *,struct dentry *,int);
938         struct dentry * (*lookup) (struct inode *,struct dentry *);
939 +       struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *);
940         int (*link) (struct dentry *,struct inode *,struct dentry *);
941         int (*unlink) (struct inode *,struct dentry *);
942         int (*symlink) (struct inode *,struct dentry *,const char *);
943 @@ -907,6 +911,8 @@ struct inode_operations {
944                         struct inode *, struct dentry *);
945         int (*readlink) (struct dentry *, char *,int);
946         int (*follow_link) (struct dentry *, struct nameidata *);
947 +       int (*follow_link2) (struct dentry *, struct nameidata *, 
948 +                            struct lookup_intent *it);
949         void (*truncate) (struct inode *);
950         int (*permission) (struct inode *, int);
951         int (*revalidate) (struct dentry *);
952 @@ -1046,6 +1052,7 @@ extern int unregister_filesystem(struct 
953  extern struct vfsmount *kern_mount(struct file_system_type *);
954  extern int may_umount(struct vfsmount *);
955  extern long do_mount(char *, char *, char *, unsigned long, void *);
956 +struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data);
957  extern void umount_tree(struct vfsmount *);
958  
959  #define kern_umount mntput
960 @@ -1380,6 +1387,7 @@ typedef int (*read_actor_t)(read_descrip
961  extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
962  
963  extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
964 +extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
965  extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
966  extern int FASTCALL(path_walk(const char *, struct nameidata *));
967  extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
968 @@ -1391,6 +1399,8 @@ extern struct dentry * lookup_one_len(co
969  extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
970  #define user_path_walk(name,nd)         __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
971  #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
972 +#define user_path_walk_it(name,nd,it)  __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
973 +#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
974  
975  extern void inode_init_once(struct inode *);
976  extern void iput(struct inode *);
977 @@ -1491,6 +1501,8 @@ extern struct file_operations generic_ro
978  
979  extern int vfs_readlink(struct dentry *, char *, int, const char *);
980  extern int vfs_follow_link(struct nameidata *, const char *);
981 +extern int vfs_follow_link_it(struct nameidata *, const char *, 
982 +                              struct lookup_intent *it);
983  extern int page_readlink(struct dentry *, char *, int);
984  extern int page_follow_link(struct dentry *, struct nameidata *);
985  extern struct inode_operations page_symlink_inode_operations;
986 --- lum/fs/dcache.c~lustre      2002-12-04 01:39:12.000000000 -0700
987 +++ lum-root/fs/dcache.c        2002-12-04 01:39:12.000000000 -0700
988 @@ -150,6 +150,8 @@ repeat:
989  unhash_it:
990         list_del_init(&dentry->d_hash);
991  
992 +
993 +
994  kill_it: {
995                 struct dentry *parent;
996                 list_del(&dentry->d_child);
997 @@ -645,6 +647,7 @@ struct dentry * d_alloc(struct dentry * 
998         dentry->d_fsdata = NULL;
999         dentry->d_extra_attributes = NULL;
1000         dentry->d_mounted = 0;
1001 +       dentry->d_it = NULL;
1002         INIT_LIST_HEAD(&dentry->d_hash);
1003         INIT_LIST_HEAD(&dentry->d_lru);
1004         INIT_LIST_HEAD(&dentry->d_subdirs);
1005 --- lum/fs/nfsd/vfs.c~lustre    2002-12-04 01:39:12.000000000 -0700
1006 +++ lum-root/fs/nfsd/vfs.c      2002-12-04 01:39:12.000000000 -0700
1007 @@ -1298,7 +1298,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru
1008                         err = nfserr_perm;
1009         } else
1010  #endif
1011 -       err = vfs_rename(fdir, odentry, tdir, ndentry);
1012 +       err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
1013         unlock_kernel();
1014         if (!err && EX_ISSYNC(tfhp->fh_export)) {
1015                 nfsd_sync_dir(tdentry);
1016 --- lum/fs/open.c~lustre        2002-12-04 01:39:12.000000000 -0700
1017 +++ lum-root/fs/open.c  2002-12-04 01:39:12.000000000 -0700
1018 @@ -19,6 +19,9 @@
1019  #include <asm/uaccess.h>
1020  
1021  #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
1022 +extern int path_walk_it(const char *name, struct nameidata *nd,
1023 +                       struct lookup_intent *it);
1024 +extern void intent_release(struct dentry *de, struct lookup_intent *it);
1025  
1026  int vfs_statfs(struct super_block *sb, struct statfs *buf)
1027  {
1028 @@ -118,12 +121,13 @@ static inline long do_sys_truncate(const
1029         struct nameidata nd;
1030         struct inode * inode;
1031         int error;
1032 +       struct lookup_intent it = { .it_op = IT_SETATTR };
1033  
1034         error = -EINVAL;
1035         if (length < 0) /* sorry, but loff_t says... */
1036                 goto out;
1037  
1038 -       error = user_path_walk(path, &nd);
1039 +       error = user_path_walk_it(path, &nd, &it);
1040         if (error)
1041                 goto out;
1042         inode = nd.dentry->d_inode;
1043 @@ -168,6 +172,7 @@ static inline long do_sys_truncate(const
1044         put_write_access(inode);
1045  
1046  dput_and_out:
1047 +       intent_release(nd.dentry, &it);
1048         path_release(&nd);
1049  out:
1050         return error;
1051 @@ -259,8 +264,9 @@ asmlinkage long sys_utime(char * filenam
1052         struct nameidata nd;
1053         struct inode * inode;
1054         struct iattr newattrs;
1055 +       struct lookup_intent it = { .it_op = IT_SETATTR };
1056  
1057 -       error = user_path_walk(filename, &nd);
1058 +       error = user_path_walk_it(filename, &nd, &it);
1059         if (error)
1060                 goto out;
1061         inode = nd.dentry->d_inode;
1062 @@ -286,6 +292,7 @@ asmlinkage long sys_utime(char * filenam
1063         }
1064         error = notify_change(nd.dentry, &newattrs);
1065  dput_and_out:
1066 +       intent_release(nd.dentry, &it);
1067         path_release(&nd);
1068  out:
1069         return error;
1070 @@ -303,8 +310,9 @@ asmlinkage long sys_utimes(char * filena
1071         struct nameidata nd;
1072         struct inode * inode;
1073         struct iattr newattrs;
1074 +       struct lookup_intent it = { .it_op = IT_SETATTR };
1075  
1076 -       error = user_path_walk(filename, &nd);
1077 +       error = user_path_walk_it(filename, &nd, &it);
1078  
1079         if (error)
1080                 goto out;
1081 @@ -331,6 +339,7 @@ asmlinkage long sys_utimes(char * filena
1082         }
1083         error = notify_change(nd.dentry, &newattrs);
1084  dput_and_out:
1085 +       intent_release(nd.dentry, &it);
1086         path_release(&nd);
1087  out:
1088         return error;
1089 @@ -347,6 +356,7 @@ asmlinkage long sys_access(const char * 
1090         int old_fsuid, old_fsgid;
1091         kernel_cap_t old_cap;
1092         int res;
1093 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1094  
1095         if (mode & ~S_IRWXO)    /* where's F_OK, X_OK, W_OK, R_OK? */
1096                 return -EINVAL;
1097 @@ -364,13 +374,14 @@ asmlinkage long sys_access(const char * 
1098         else
1099                 current->cap_effective = current->cap_permitted;
1100  
1101 -       res = user_path_walk(filename, &nd);
1102 +       res = user_path_walk_it(filename, &nd, &it);
1103         if (!res) {
1104                 res = permission(nd.dentry->d_inode, mode);
1105                 /* SuS v2 requires we report a read only fs too */
1106                 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
1107                    && !special_file(nd.dentry->d_inode->i_mode))
1108                         res = -EROFS;
1109 +               intent_release(nd.dentry, &it);
1110                 path_release(&nd);
1111         }
1112  
1113 @@ -385,8 +396,11 @@ asmlinkage long sys_chdir(const char * f
1114  {
1115         int error;
1116         struct nameidata nd;
1117 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1118  
1119 -       error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd);
1120 +       error = __user_walk_it(filename,
1121 +                              LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,
1122 +                              &nd, &it);
1123         if (error)
1124                 goto out;
1125  
1126 @@ -397,6 +411,7 @@ asmlinkage long sys_chdir(const char * f
1127         set_fs_pwd(current->fs, nd.mnt, nd.dentry);
1128  
1129  dput_and_out:
1130 +       intent_release(nd.dentry, &it);
1131         path_release(&nd);
1132  out:
1133         return error;
1134 @@ -436,9 +451,10 @@ asmlinkage long sys_chroot(const char * 
1135  {
1136         int error;
1137         struct nameidata nd;
1138 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1139  
1140 -       error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
1141 -                     LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
1142 +       error = __user_walk_it(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
1143 +                              LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd, &it);
1144         if (error)
1145                 goto out;
1146  
1147 @@ -454,6 +470,7 @@ asmlinkage long sys_chroot(const char * 
1148         set_fs_altroot();
1149         error = 0;
1150  dput_and_out:
1151 +       intent_release(nd.dentry, &it);
1152         path_release(&nd);
1153  out:
1154         return error;
1155 @@ -498,8 +515,9 @@ asmlinkage long sys_chmod(const char * f
1156         struct inode * inode;
1157         int error;
1158         struct iattr newattrs;
1159 +       struct lookup_intent it = { .it_op = IT_SETATTR };
1160  
1161 -       error = user_path_walk(filename, &nd);
1162 +       error = user_path_walk_it(filename, &nd, &it);
1163         if (error)
1164                 goto out;
1165         inode = nd.dentry->d_inode;
1166 @@ -519,6 +537,7 @@ asmlinkage long sys_chmod(const char * f
1167         error = notify_change(nd.dentry, &newattrs);
1168  
1169  dput_and_out:
1170 +       intent_release(nd.dentry, &it);
1171         path_release(&nd);
1172  out:
1173         return error;
1174 @@ -588,10 +607,12 @@ asmlinkage long sys_chown(const char * f
1175  {
1176         struct nameidata nd;
1177         int error;
1178 +       struct lookup_intent it = { .it_op = IT_SETATTR };
1179  
1180 -       error = user_path_walk(filename, &nd);
1181 +       error = user_path_walk_it(filename, &nd, &it);
1182         if (!error) {
1183                 error = chown_common(nd.dentry, user, group);
1184 +               intent_release(nd.dentry, &it);
1185                 path_release(&nd);
1186         }
1187         return error;
1188 @@ -601,10 +622,12 @@ asmlinkage long sys_lchown(const char * 
1189  {
1190         struct nameidata nd;
1191         int error;
1192 +       struct lookup_intent it = { .it_op = IT_SETATTR };
1193  
1194 -       error = user_path_walk_link(filename, &nd);
1195 +       error = user_path_walk_link_it(filename, &nd, &it);
1196         if (!error) {
1197                 error = chown_common(nd.dentry, user, group);
1198 +               intent_release(nd.dentry, &it);
1199                 path_release(&nd);
1200         }
1201         return error;
1202 @@ -638,10 +661,16 @@ asmlinkage long sys_fchown(unsigned int 
1203   * for the internal routines (ie open_namei()/follow_link() etc). 00 is
1204   * used by symlinks.
1205   */
1206 +extern int open_namei_it(const char *filename, int namei_flags, int mode,
1207 +                        struct nameidata *nd, struct lookup_intent *it);
1208 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1209 +                           int flags, struct lookup_intent *it);
1210 +
1211  struct file *filp_open(const char * filename, int flags, int mode)
1212  {
1213         int namei_flags, error;
1214         struct nameidata nd;
1215 +       struct lookup_intent it = { .it_op = IT_OPEN };
1216  
1217         namei_flags = flags;
1218         if ((namei_flags+1) & O_ACCMODE)
1219 @@ -649,18 +678,19 @@ struct file *filp_open(const char * file
1220         if (namei_flags & O_TRUNC)
1221                 namei_flags |= 2;
1222  
1223 -       error = open_namei(filename, namei_flags, mode, &nd);
1224 -       if (!error)
1225 -               return dentry_open(nd.dentry, nd.mnt, flags);
1226 +       error = open_namei_it(filename, namei_flags, mode, &nd, &it);
1227 +       if (error)
1228 +               return ERR_PTR(error);
1229  
1230 -       return ERR_PTR(error);
1231 +       return dentry_open_it(nd.dentry, nd.mnt, flags, &it);
1232  }
1233  
1234  extern ssize_t do_readahead(struct file *file, unsigned long index, unsigned long nr);
1235  /* for files over a certains size it doesn't pay to do readahead on open */
1236  #define READAHEAD_CUTOFF 48000
1237  
1238 -struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1239 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1240 +                           int flags, struct lookup_intent *it)
1241  {
1242         struct file * f;
1243         struct inode *inode;
1244 @@ -711,6 +741,7 @@ struct file *dentry_open(struct dentry *
1245                 do_readahead(f, 0, (48 * 1024) >> PAGE_SHIFT);
1246         
1247  
1248 +       intent_release(dentry, it);
1249         return f;
1250  
1251  cleanup_all:
1252 @@ -725,11 +756,17 @@ cleanup_all:
1253  cleanup_file:
1254         put_filp(f);
1255  cleanup_dentry:
1256 +       intent_release(dentry, it);
1257         dput(dentry);
1258         mntput(mnt);
1259         return ERR_PTR(error);
1260  }
1261  
1262 +struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1263 +{
1264 +       return dentry_open_it(dentry, mnt, flags, NULL);
1265 +}
1266 +
1267  /*
1268   * Find an empty file descriptor entry, and mark it busy.
1269   */
1270 --- lum/fs/stat.c~lustre        2002-12-04 01:39:12.000000000 -0700
1271 +++ lum-root/fs/stat.c  2002-12-04 01:39:12.000000000 -0700
1272 @@ -13,6 +13,7 @@
1273  
1274  #include <asm/uaccess.h>
1275  
1276 +extern void intent_release(struct dentry *de, struct lookup_intent *it);
1277  /*
1278   * Revalidate the inode. This is required for proper NFS attribute caching.
1279   */
1280 @@ -104,10 +105,12 @@ int vfs_stat(char *name, struct kstat *s
1281  {
1282         struct nameidata nd;
1283         int error;
1284 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1285  
1286 -       error = user_path_walk(name, &nd);
1287 +       error = user_path_walk_it(name, &nd, &it);
1288         if (!error) {
1289                 error = do_getattr(nd.mnt, nd.dentry, stat);
1290 +               intent_release(nd.dentry, &it);
1291                 path_release(&nd);
1292         }
1293         return error;
1294 @@ -117,10 +120,12 @@ int vfs_lstat(char *name, struct kstat *
1295  {
1296         struct nameidata nd;
1297         int error;
1298 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1299  
1300 -       error = user_path_walk_link(name, &nd);
1301 +       error = user_path_walk_link_it(name, &nd, &it);
1302         if (!error) {
1303                 error = do_getattr(nd.mnt, nd.dentry, stat);
1304 +               intent_release(nd.dentry, &it);
1305                 path_release(&nd);
1306         }
1307         return error;
1308 --- lum/mm/slab.c~lustre        2002-12-04 01:39:12.000000000 -0700
1309 +++ lum-root/mm/slab.c  2002-12-04 01:39:12.000000000 -0700
1310 @@ -1208,6 +1208,59 @@ failed:
1311   * Called with the cache-lock held.
1312   */
1313  
1314 +extern struct page *check_get_page(unsigned long kaddr);
1315 +struct page *page_mem_map(struct page *page);
1316 +static int kmem_check_cache_obj (kmem_cache_t * cachep,
1317 +                                slab_t *slabp, void * objp)
1318 +{
1319 +       int i;
1320 +       unsigned int objnr;
1321 +
1322 +#if DEBUG
1323 +       if (cachep->flags & SLAB_RED_ZONE) {
1324 +               objp -= BYTES_PER_WORD;
1325 +               if ( *(unsigned long *)objp != RED_MAGIC2)
1326 +                       /* Either write before start, or a double free. */
1327 +                       return 0;
1328 +               if (*(unsigned long *)(objp+cachep->objsize -
1329 +                               BYTES_PER_WORD) != RED_MAGIC2)
1330 +                       /* Either write past end, or a double free. */
1331 +                       return 0;
1332 +       }
1333 +#endif
1334 +
1335 +       objnr = (objp-slabp->s_mem)/cachep->objsize;
1336 +       if (objnr >= cachep->num)
1337 +               return 0;
1338 +       if (objp != slabp->s_mem + objnr*cachep->objsize)
1339 +               return 0;
1340 +
1341 +       /* Check slab's freelist to see if this obj is there. */
1342 +       for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) {
1343 +               if (i == objnr)
1344 +                       return 0;
1345 +       }
1346 +       return 1;
1347 +}
1348 +
1349 +
1350 +int kmem_cache_validate(kmem_cache_t *cachep, void *objp)
1351 +{
1352 +       struct page *page = check_get_page((unsigned long)objp);
1353 +
1354 +       if (!VALID_PAGE(page))
1355 +               return 0;
1356 +
1357 +       if (!PageSlab(page))
1358 +               return 0;
1359 +
1360 +       /* XXX check for freed slab objects ? */
1361 +       if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp))
1362 +               return 0;
1363 +
1364 +       return (cachep == GET_PAGE_CACHE(page));
1365 +}
1366 +
1367  #if DEBUG
1368  static int kmem_extra_free_checks (kmem_cache_t * cachep,
1369                         slab_t *slabp, void * objp)
1370
1371 _