Whamcloud - gitweb
file llobdstat.pl was initially added on branch b_devel.
[fs/lustre-release.git] / lustre / kernel_patches / patches / vfs_intent.patch
1  fs/dcache.c            |    8 +
2  fs/namei.c             |  287 ++++++++++++++++++++++++++++++++++++++++---------
3  fs/nfsd/vfs.c          |    2 
4  fs/open.c              |   53 +++++++--
5  fs/stat.c              |    9 +
6  include/linux/dcache.h |   25 ++++
7  include/linux/fs.h     |   22 +++
8  kernel/ksyms.c         |    1 
9  8 files changed, 344 insertions(+), 63 deletions(-)
10
11 --- linux-2.4.18-18.8.0-l7/fs/dcache.c~vfs_intent-2.4.18-18     Mon Jan 20 08:28:00 2003
12 +++ linux-2.4.18-18.8.0-l7-root/fs/dcache.c     Mon Jan 20 08:54:54 2003
13 @@ -186,6 +188,13 @@ int d_invalidate(struct dentry * dentry)
14                 spin_unlock(&dcache_lock);
15                 return 0;
16         }
17 +
18 +       /* network invalidation by Lustre */
19 +       if (dentry->d_flags & DCACHE_LUSTRE_INVALID) { 
20 +               spin_unlock(&dcache_lock);
21 +               return 0;
22 +       }
23 +
24         /*
25          * Check whether to do a partial shrink_dcache
26          * to get rid of unused child entries.
27 @@ -645,6 +654,7 @@ struct dentry * d_alloc(struct dentry * 
28         dentry->d_fsdata = NULL;
29         dentry->d_extra_attributes = NULL;
30         dentry->d_mounted = 0;
31 +       dentry->d_it = NULL;
32         INIT_LIST_HEAD(&dentry->d_hash);
33         INIT_LIST_HEAD(&dentry->d_lru);
34         INIT_LIST_HEAD(&dentry->d_subdirs);
35 --- linux-2.4.18-18.8.0-l7/fs/namei.c~vfs_intent-2.4.18-18      Mon Jan 20 12:25:10 2003
36 +++ linux-2.4.18-18.8.0-l7-root/fs/namei.c      Wed Jan 22 22:53:28 2003
37 @@ -94,6 +97,13 @@
38   * XEmacs seems to be relying on it...
39   */
40  
41 +void intent_release(struct dentry *de, struct lookup_intent *it)
42 +{
43 +       if (it && de->d_op && de->d_op->d_intent_release)
44 +               de->d_op->d_intent_release(de, it);
45 +
46 +}
47 +
48  /* In order to reduce some races, while at the same time doing additional
49   * checking and hopefully speeding things up, we copy filenames to the
50   * kernel data space before using them..
51 @@ -260,10 +271,19 @@ void path_release(struct nameidata *nd)
52   * Internal lookup() using the new generic dcache.
53   * SMP-safe
54   */
55 -static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
56 +static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name,
57 +                                   int flags, struct lookup_intent *it)
58  {
59         struct dentry * dentry = d_lookup(parent, name);
60  
61 +       if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
62 +               if (!dentry->d_op->d_revalidate2(dentry, flags, it) &&
63 +                   !d_invalidate(dentry)) {
64 +                       dput(dentry);
65 +                       dentry = NULL;
66 +               }
67 +               return dentry;
68 +       } else
69         if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
70                 if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
71                         dput(dentry);
72 @@ -281,7 +301,8 @@ static struct dentry * cached_lookup(str
73   * make sure that nobody added the entry to the dcache in the meantime..
74   * SMP-safe
75   */
76 -static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
77 +static struct dentry *real_lookup(struct dentry *parent, struct qstr *name,
78 +                                 int flags, struct lookup_intent *it)
79  {
80         struct dentry * result;
81         struct inode *dir = parent->d_inode;
82 @@ -300,6 +321,9 @@ static struct dentry * real_lookup(struc
83                 result = ERR_PTR(-ENOMEM);
84                 if (dentry) {
85                         lock_kernel();
86 +                       if (dir->i_op->lookup2)
87 +                               result = dir->i_op->lookup2(dir, dentry, it);
88 +                       else
89                         result = dir->i_op->lookup(dir, dentry);
90                         unlock_kernel();
91                         if (result)
92 @@ -321,6 +345,12 @@ static struct dentry * real_lookup(struc
93                         dput(result);
94                         result = ERR_PTR(-ENOENT);
95                 }
96 +       } else if (result->d_op && result->d_op->d_revalidate2) {
97 +               if (!result->d_op->d_revalidate2(result, flags, it) &&
98 +                   !d_invalidate(result)) {
99 +                       dput(result);
100 +                       result = ERR_PTR(-ENOENT);
101 +               }
102         }
103         return result;
104  }
105 @@ -334,7 +364,8 @@ int max_recursive_link = 5;
106   * Without that kind of total limit, nasty chains of consecutive
107   * symlinks can cause almost arbitrarily long lookups. 
108   */
109 -static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
110 +static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd, 
111 +                                struct lookup_intent *it)
112  {
113         int err;
114         if (current->link_count >= max_recursive_link)
115 @@ -348,10 +379,14 @@ static inline int do_follow_link(struct 
116         current->link_count++;
117         current->total_link_count++;
118         UPDATE_ATIME(dentry->d_inode);
119 -       err = dentry->d_inode->i_op->follow_link(dentry, nd);
120 +       if (dentry->d_inode->i_op->follow_link2)
121 +               err = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
122 +       else 
123 +               err = dentry->d_inode->i_op->follow_link(dentry, nd);
124         current->link_count--;
125         return err;
126  loop:
127 +       intent_release(dentry, it);
128         path_release(nd);
129         return -ELOOP;
130  }
131 @@ -449,7 +484,8 @@ static inline void follow_dotdot(struct 
132   *
133   * We expect 'base' to be positive and a directory.
134   */
135 -int link_path_walk(const char * name, struct nameidata *nd)
136 +int link_path_walk_it(const char *name, struct nameidata *nd,
137 +                     struct lookup_intent *it)
138  {
139         struct dentry *dentry;
140         struct inode *inode;
141 @@ -526,12 +562,12 @@ int link_path_walk(const char * name, st
142                                 break;
143                 }
144                 /* This does the actual lookups.. */
145 -               dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
146 +               dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
147                 if (!dentry) {
148                         err = -EWOULDBLOCKIO;
149                         if (atomic)
150                                 break;
151 -                       dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
152 +                       dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
153                         err = PTR_ERR(dentry);
154                         if (IS_ERR(dentry))
155                                 break;
156 @@ -548,8 +584,8 @@ int link_path_walk(const char * name, st
157                 if (!inode->i_op)
158                         goto out_dput;
159  
160 -               if (inode->i_op->follow_link) {
161 -                       err = do_follow_link(dentry, nd);
162 +               if (inode->i_op->follow_link || inode->i_op->follow_link2) {
163 +                       err = do_follow_link(dentry, nd, NULL);
164                         dput(dentry);
165                         if (err)
166                                 goto return_err;
167 @@ -565,7 +601,7 @@ int link_path_walk(const char * name, st
168                         nd->dentry = dentry;
169                 }
170                 err = -ENOTDIR; 
171 -               if (!inode->i_op->lookup)
172 +               if (!inode->i_op->lookup && !inode->i_op->lookup2)
173                         break;
174                 continue;
175                 /* here ends the main loop */
176 @@ -592,12 +628,12 @@ last_component:
177                         if (err < 0)
178                                 break;
179                 }
180 -               dentry = cached_lookup(nd->dentry, &this, 0);
181 +               dentry = cached_lookup(nd->dentry, &this, 0, it);
182                 if (!dentry) {
183                         err = -EWOULDBLOCKIO;
184                         if (atomic)
185                                 break;
186 -                       dentry = real_lookup(nd->dentry, &this, 0);
187 +                       dentry = real_lookup(nd->dentry, &this, 0, it);
188                         err = PTR_ERR(dentry);
189                         if (IS_ERR(dentry))
190                                 break;
191 @@ -606,8 +642,9 @@ last_component:
192                         ;
193                 inode = dentry->d_inode;
194                 if ((lookup_flags & LOOKUP_FOLLOW)
195 -                   && inode && inode->i_op && inode->i_op->follow_link) {
196 -                       err = do_follow_link(dentry, nd);
197 +                   && inode && inode->i_op && 
198 +                   (inode->i_op->follow_link || inode->i_op->follow_link2)) {
199 +                       err = do_follow_link(dentry, nd, it);
200                         dput(dentry);
201                         if (err)
202                                 goto return_err;
203 @@ -621,7 +659,8 @@ last_component:
204                         goto no_inode;
205                 if (lookup_flags & LOOKUP_DIRECTORY) {
206                         err = -ENOTDIR; 
207 -                       if (!inode->i_op || !inode->i_op->lookup)
208 +                       if (!inode->i_op || (!inode->i_op->lookup &&
209 +                                            !inode->i_op->lookup2))
210                                 break;
211                 }
212                 goto return_base;
213 @@ -658,15 +697,28 @@ out_dput:
214                 dput(dentry);
215                 break;
216         }
217 +       if (err)
218 +               intent_release(nd->dentry, it);
219         path_release(nd);
220  return_err:
221         return err;
222  }
223  
224 +int link_path_walk(const char * name, struct nameidata *nd)
225 +{
226 +       return link_path_walk_it(name, nd, NULL);
227 +}
228 +
229 +int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
230 +{
231 +       current->total_link_count = 0;
232 +       return link_path_walk_it(name, nd, it);
233 +}
234 +
235  int path_walk(const char * name, struct nameidata *nd)
236  {
237         current->total_link_count = 0;
238 -       return link_path_walk(name, nd);
239 +       return link_path_walk_it(name, nd, NULL);
240  }
241  
242  /* SMP-safe */
243 @@ -751,6 +803,17 @@ walk_init_root(const char *name, struct 
244  }
245  
246  /* SMP-safe */
247 +int path_lookup_it(const char *path, unsigned flags, struct nameidata *nd,
248 +                  struct lookup_intent *it)
249 +{
250 +       int error = 0;
251 +       if (path_init(path, flags, nd))
252 +               error = path_walk_it(path, nd, it);
253 +       return error;
254 +}
255 +
256 +
257 +/* SMP-safe */
258  int path_lookup(const char *path, unsigned flags, struct nameidata *nd)
259  {
260         int error = 0;
261 @@ -779,7 +842,8 @@ int path_init(const char *name, unsigned
262   * needs parent already locked. Doesn't follow mounts.
263   * SMP-safe.
264   */
265 -struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
266 +struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base,
267 +                              struct lookup_intent *it)
268  {
269         struct dentry * dentry;
270         struct inode *inode;
271 @@ -802,13 +866,16 @@ struct dentry * lookup_hash(struct qstr 
272                         goto out;
273         }
274  
275 -       dentry = cached_lookup(base, name, 0);
276 +       dentry = cached_lookup(base, name, 0, it);
277         if (!dentry) {
278                 struct dentry *new = d_alloc(base, name);
279                 dentry = ERR_PTR(-ENOMEM);
280                 if (!new)
281                         goto out;
282                 lock_kernel();
283 +               if (inode->i_op->lookup2)
284 +                       dentry = inode->i_op->lookup2(inode, new, it);
285 +               else
286                 dentry = inode->i_op->lookup(inode, new);
287                 unlock_kernel();
288                 if (!dentry)
289 @@ -820,6 +887,12 @@ out:
290         return dentry;
291  }
292  
293 +struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
294 +{
295 +       return lookup_hash_it(name, base, NULL);
296 +}
297 +
298 +
299  /* SMP-safe */
300  struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
301  {
302 @@ -841,7 +914,7 @@ struct dentry * lookup_one_len(const cha
303         }
304         this.hash = end_name_hash(hash);
305  
306 -       return lookup_hash(&this, base);
307 +       return lookup_hash_it(&this, base, NULL);
308  access:
309         return ERR_PTR(-EACCES);
310  }
311 @@ -872,6 +945,23 @@ int __user_walk(const char *name, unsign
312         return err;
313  }
314  
315 +int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd,
316 +                  struct lookup_intent *it)
317 +{
318 +       char *tmp;
319 +       int err;
320 +
321 +       tmp = getname(name);
322 +       err = PTR_ERR(tmp);
323 +       if (!IS_ERR(tmp)) {
324 +               err = 0;
325 +               if (path_init(tmp, flags, nd))
326 +                       err = path_walk_it(tmp, nd, it);
327 +               putname(tmp);
328 +       }
329 +       return err;
330 +}
331 +
332  /*
333   * It's inline, so penalty for filesystems that don't use sticky bit is
334   * minimal.
335 @@ -1045,14 +1135,17 @@ int may_open(struct nameidata *nd, int a
336          return get_lease(inode, flag);
337  }
338  
339 +extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
340 +                           int flags, struct lookup_intent *it);
341 +
342  struct file *filp_open(const char * pathname, int open_flags, int mode)
343  {
344         int acc_mode, error = 0;
345 -       struct inode *inode;
346         struct dentry *dentry;
347         struct dentry *dir;
348         int flag = open_flags;
349         struct nameidata nd;
350 +       struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = open_flags };
351         int count = 0;
352  
353         if ((flag+1) & O_ACCMODE)
354 @@ -1066,7 +1159,7 @@ struct file *filp_open(const char * path
355          * The simplest case - just a plain lookup.
356          */
357         if (!(flag & O_CREAT)) {
358 -               error = path_lookup(pathname, lookup_flags(flag), &nd);
359 +               error = path_lookup_it(pathname, lookup_flags(flag), &nd, &it);
360                 if (error)
361                         return ERR_PTR(error);
362                 dentry = nd.dentry;
363 @@ -1076,6 +1169,8 @@ struct file *filp_open(const char * path
364         /*
365          * Create - we need to know the parent.
366          */
367 +       it.it_mode = mode;
368 +       it.it_op |= IT_CREAT;
369         error = path_lookup(pathname, LOOKUP_PARENT, &nd);
370         if (error)
371                 return ERR_PTR(error);
372 @@ -1091,7 +1186,7 @@ struct file *filp_open(const char * path
373  
374         dir = nd.dentry;
375         down(&dir->d_inode->i_sem);
376 -       dentry = lookup_hash(&nd.last, nd.dentry);
377 +       dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
378  
379  do_last:
380         error = PTR_ERR(dentry);
381 @@ -1100,6 +1195,7 @@ do_last:
382                 goto exit;
383         }
384  
385 +       it.it_mode = mode;
386         /* Negative dentry, just create the file */
387         if (!dentry->d_inode) {
388                 error = vfs_create(dir->d_inode, dentry,
389 @@ -1134,7 +1230,8 @@ do_last:
390         error = -ENOENT;
391         if (!dentry->d_inode)
392                 goto exit_dput;
393 -       if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link)
394 +       if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link || 
395 +                                     dentry->d_inode->i_op->follow_link2))
396                 goto do_link;
397  
398         dput(nd.dentry);
399 @@ -1149,11 +1246,13 @@ ok:
400         if (!S_ISREG(nd.dentry->d_inode->i_mode))
401                 open_flags &= ~O_TRUNC;
402  
403 -        return dentry_open(nd.dentry, nd.mnt, open_flags);
404 +       return dentry_open_it(nd.dentry, nd.mnt, open_flags, &it);
405  
406  exit_dput:
407 +       intent_release(dentry, &it);
408         dput(dentry);
409  exit:
410 +       intent_release(nd.dentry, &it);
411         path_release(&nd);
412         return ERR_PTR(error);
413  
414 @@ -1172,7 +1271,12 @@ do_link:
415          * are done. Procfs-like symlinks just set LAST_BIND.
416          */
417         UPDATE_ATIME(dentry->d_inode);
418 -       error = dentry->d_inode->i_op->follow_link(dentry, &nd);
419 +       if (dentry->d_inode->i_op->follow_link2) 
420 +               error = dentry->d_inode->i_op->follow_link2(dentry, &nd, &it);
421 +       else 
422 +               error = dentry->d_inode->i_op->follow_link(dentry, &nd);
423 +       if (error)
424 +               intent_release(dentry, &it);
425         dput(dentry);
426         if (error)
427                 return error;
428 @@ -1194,13 +1298,15 @@ do_link:
429         }
430         dir = nd.dentry;
431         down(&dir->d_inode->i_sem);
432 -       dentry = lookup_hash(&nd.last, nd.dentry);
433 +       dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
434         putname(nd.last.name);
435         goto do_last;
436  }
437  
438 +
439  /* SMP-safe */
440 -static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
441 +static struct dentry *lookup_create(struct nameidata *nd, int is_dir,
442 +                                   struct lookup_intent *it)
443  {
444         struct dentry *dentry;
445  
446 @@ -1208,7 +1314,7 @@ static struct dentry *lookup_create(stru
447         dentry = ERR_PTR(-EEXIST);
448         if (nd->last_type != LAST_NORM)
449                 goto fail;
450 -       dentry = lookup_hash(&nd->last, nd->dentry);
451 +       dentry = lookup_hash_it(&nd->last, nd->dentry, it);
452         if (IS_ERR(dentry))
453                 goto fail;
454         if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
455 @@ -1264,7 +1370,19 @@ asmlinkage long sys_mknod(const char * f
456         error = path_lookup(tmp, LOOKUP_PARENT, &nd);
457         if (error)
458                 goto out;
459 -       dentry = lookup_create(&nd, 0);
460 +
461 +       if (nd.dentry->d_inode->i_op->mknod2) {
462 +               struct inode_operations *op = nd.dentry->d_inode->i_op;
463 +               error = op->mknod2(nd.dentry->d_inode, 
464 +                                  nd.last.name, 
465 +                                  nd.last.len,
466 +                                  mode, dev);
467 +               /* the file system want to use normal vfs path now */
468 +               if (error != -EOPNOTSUPP)
469 +                       goto out2;
470 +       }
471 +
472 +       dentry = lookup_create(&nd, 0, NULL);
473         error = PTR_ERR(dentry);
474  
475         mode &= ~current->fs->umask;
476 @@ -1285,6 +1403,7 @@ asmlinkage long sys_mknod(const char * f
477                 dput(dentry);
478         }
479         up(&nd.dentry->d_inode->i_sem);
480 + out2:
481         path_release(&nd);
482  out:
483         putname(tmp);
484 @@ -1332,7 +1451,17 @@ asmlinkage long sys_mkdir(const char * p
485                 error = path_lookup(tmp, LOOKUP_PARENT, &nd);
486                 if (error)
487                         goto out;
488 -               dentry = lookup_create(&nd, 1);
489 +               if (nd.dentry->d_inode->i_op->mkdir2) {
490 +                       struct inode_operations *op = nd.dentry->d_inode->i_op;
491 +                       error = op->mkdir2(nd.dentry->d_inode, 
492 +                                          nd.last.name, 
493 +                                          nd.last.len,
494 +                                          mode);
495 +                       /* the file system want to use normal vfs path now */
496 +                       if (error != -EOPNOTSUPP)
497 +                               goto out2;
498 +               }
499 +               dentry = lookup_create(&nd, 1, NULL);
500                 error = PTR_ERR(dentry);
501                 if (!IS_ERR(dentry)) {
502                         error = vfs_mkdir(nd.dentry->d_inode, dentry,
503 @@ -1340,6 +1469,7 @@ asmlinkage long sys_mkdir(const char * p
504                         dput(dentry);
505                 }
506                 up(&nd.dentry->d_inode->i_sem);
507 +out2:
508                 path_release(&nd);
509  out:
510                 putname(tmp);
511 @@ -1440,8 +1570,17 @@ asmlinkage long sys_rmdir(const char * p
512                         error = -EBUSY;
513                         goto exit1;
514         }
515 +       if (nd.dentry->d_inode->i_op->rmdir2) {
516 +               struct inode_operations *op = nd.dentry->d_inode->i_op;
517 +               error = op->rmdir2(nd.dentry->d_inode, 
518 +                                  nd.last.name, 
519 +                                  nd.last.len);
520 +               /* the file system want to use normal vfs path now */
521 +               if (error != -EOPNOTSUPP)
522 +                       goto exit1;
523 +       }
524         down(&nd.dentry->d_inode->i_sem);
525 -       dentry = lookup_hash(&nd.last, nd.dentry);
526 +       dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
527         error = PTR_ERR(dentry);
528         if (!IS_ERR(dentry)) {
529                 error = vfs_rmdir(nd.dentry->d_inode, dentry);
530 @@ -1499,8 +1638,17 @@ asmlinkage long sys_unlink(const char * 
531         error = -EISDIR;
532         if (nd.last_type != LAST_NORM)
533                 goto exit1;
534 +       if (nd.dentry->d_inode->i_op->unlink2) {
535 +               struct inode_operations *op = nd.dentry->d_inode->i_op;
536 +               error = op->unlink2(nd.dentry->d_inode, 
537 +                                   nd.last.name, 
538 +                                   nd.last.len);
539 +               /* the file system want to use normal vfs path now */
540 +               if (error != -EOPNOTSUPP)
541 +                       goto exit1;
542 +       }
543         down(&nd.dentry->d_inode->i_sem);
544 -       dentry = lookup_hash(&nd.last, nd.dentry);
545 +       dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
546         error = PTR_ERR(dentry);
547         if (!IS_ERR(dentry)) {
548                 /* Why not before? Because we want correct error value */
549 @@ -1567,15 +1715,26 @@ asmlinkage long sys_symlink(const char *
550                 error = path_lookup(to, LOOKUP_PARENT, &nd);
551                 if (error)
552                         goto out;
553 -               dentry = lookup_create(&nd, 0);
554 +               if (nd.dentry->d_inode->i_op->symlink2) {
555 +                       struct inode_operations *op = nd.dentry->d_inode->i_op;
556 +                       error = op->symlink2(nd.dentry->d_inode, 
557 +                                            nd.last.name, 
558 +                                            nd.last.len,
559 +                                            from);
560 +                       /* the file system want to use normal vfs path now */
561 +                       if (error != -EOPNOTSUPP)
562 +                               goto out2;
563 +               }
564 +               dentry = lookup_create(&nd, 0, NULL);
565                 error = PTR_ERR(dentry);
566                 if (!IS_ERR(dentry)) {
567                         error = vfs_symlink(nd.dentry->d_inode, dentry, from);
568                         dput(dentry);
569                 }
570                 up(&nd.dentry->d_inode->i_sem);
571 +       out2:
572                 path_release(&nd);
573 -out:
574 +       out:
575                 putname(to);
576         }
577         putname(from);
578 @@ -1642,7 +1801,7 @@ asmlinkage long sys_link(const char * ol
579                 struct dentry *new_dentry;
580                 struct nameidata nd, old_nd;
581  
582 -               error = __user_walk(oldname, LOOKUP_POSITIVE, &old_nd);
583 +               error = __user_walk_it(oldname, LOOKUP_POSITIVE, &old_nd, NULL);
584                 if (error)
585                         goto exit;
586                 error = path_lookup(to, LOOKUP_PARENT, &nd);
587 @@ -1651,7 +1810,17 @@ asmlinkage long sys_link(const char * ol
588                 error = -EXDEV;
589                 if (old_nd.mnt != nd.mnt)
590                         goto out_release;
591 -               new_dentry = lookup_create(&nd, 0);
592 +               if (nd.dentry->d_inode->i_op->link2) {
593 +                       struct inode_operations *op = nd.dentry->d_inode->i_op;
594 +                       error = op->link2(old_nd.dentry->d_inode, 
595 +                                         nd.dentry->d_inode, 
596 +                                         nd.last.name, 
597 +                                         nd.last.len);
598 +                       /* the file system want to use normal vfs path now */
599 +                       if (error != -EOPNOTSUPP)
600 +                               goto out_release;
601 +               }
602 +               new_dentry = lookup_create(&nd, 0, NULL);
603                 error = PTR_ERR(new_dentry);
604                 if (!IS_ERR(new_dentry)) {
605                         error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
606 @@ -1695,7 +1864,8 @@ exit:
607   *        locking].
608   */
609  int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
610 -              struct inode *new_dir, struct dentry *new_dentry)
611 +                  struct inode *new_dir, struct dentry *new_dentry,
612 +                  struct lookup_intent *it)
613  {
614         int error;
615         struct inode *target;
616 @@ -1753,6 +1923,7 @@ int vfs_rename_dir(struct inode *old_dir
617                 error = -EBUSY;
618         else 
619                 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
620 +       intent_release(new_dentry, it);
621         if (target) {
622                 if (!error)
623                         target->i_flags |= S_DEAD;
624 @@ -1774,7 +1945,8 @@ out_unlock:
625  }
626  
627  int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
628 -              struct inode *new_dir, struct dentry *new_dentry)
629 +                    struct inode *new_dir, struct dentry *new_dentry,
630 +                    struct lookup_intent *it)
631  {
632         int error;
633  
634 @@ -1805,6 +1977,7 @@ int vfs_rename_other(struct inode *old_d
635                 error = -EBUSY;
636         else
637                 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
638 +       intent_release(new_dentry, it);
639         double_up(&old_dir->i_zombie, &new_dir->i_zombie);
640         if (error)
641                 return error;
642 @@ -1816,13 +1989,14 @@ int vfs_rename_other(struct inode *old_d
643  }
644  
645  int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
646 -              struct inode *new_dir, struct dentry *new_dentry)
647 +              struct inode *new_dir, struct dentry *new_dentry,
648 +              struct lookup_intent *it)
649  {
650         int error;
651         if (S_ISDIR(old_dentry->d_inode->i_mode))
652 -               error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
653 +               error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it);
654         else
655 -               error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
656 +               error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it);
657         if (!error) {
658                 if (old_dir == new_dir)
659                         inode_dir_notify(old_dir, DN_RENAME);
660 @@ -1862,9 +2036,23 @@ static inline int do_rename(const char *
661         if (newnd.last_type != LAST_NORM)
662                 goto exit2;
663  
664 +       if (old_dir->d_inode->i_op->rename2) {
665 +               lock_kernel();
666 +               error = old_dir->d_inode->i_op->rename2(old_dir->d_inode, 
667 +                                                       new_dir->d_inode,
668 +                                                       oldnd.last.name, 
669 +                                                       oldnd.last.len,
670 +                                                       newnd.last.name,
671 +                                                       newnd.last.len);
672 +               unlock_kernel();
673 +               /* the file system want to use normal vfs path now */
674 +               if (error != -EOPNOTSUPP)
675 +                       goto exit2;
676 +       }
677 +
678         double_lock(new_dir, old_dir);
679  
680 -       old_dentry = lookup_hash(&oldnd.last, old_dir);
681 +       old_dentry = lookup_hash_it(&oldnd.last, old_dir, NULL);
682         error = PTR_ERR(old_dentry);
683         if (IS_ERR(old_dentry))
684                 goto exit3;
685 @@ -1880,14 +2068,14 @@ static inline int do_rename(const char *
686                 if (newnd.last.name[newnd.last.len])
687                         goto exit4;
688         }
689 -       new_dentry = lookup_hash(&newnd.last, new_dir);
690 +       new_dentry = lookup_hash_it(&newnd.last, new_dir, NULL);
691         error = PTR_ERR(new_dentry);
692         if (IS_ERR(new_dentry))
693                 goto exit4;
694  
695         lock_kernel();
696         error = vfs_rename(old_dir->d_inode, old_dentry,
697 -                                  new_dir->d_inode, new_dentry);
698 +                                  new_dir->d_inode, new_dentry, NULL);
699         unlock_kernel();
700  
701         dput(new_dentry);
702 @@ -1940,7 +2127,8 @@ out:
703  }
704  
705  static inline int
706 -__vfs_follow_link(struct nameidata *nd, const char *link)
707 +__vfs_follow_link(struct nameidata *nd, const char *link, 
708 +                 struct lookup_intent *it)
709  {
710         int res = 0;
711         char *name;
712 @@ -1953,7 +2141,7 @@ __vfs_follow_link(struct nameidata *nd, 
713                         /* weird __emul_prefix() stuff did it */
714                         goto out;
715         }
716 -       res = link_path_walk(link, nd);
717 +       res = link_path_walk_it(link, nd, it);
718  out:
719         if (current->link_count || res || nd->last_type!=LAST_NORM)
720                 return res;
721 @@ -1975,7 +2163,13 @@ fail:
722  
723  int vfs_follow_link(struct nameidata *nd, const char *link)
724  {
725 -       return __vfs_follow_link(nd, link);
726 +       return __vfs_follow_link(nd, link, NULL);
727 +}
728 +
729 +int vfs_follow_link_it(struct nameidata *nd, const char *link, 
730 +                      struct lookup_intent *it)
731 +{
732 +       return __vfs_follow_link(nd, link, it);
733  }
734  
735  /* get the link contents into pagecache */
736 @@ -2017,7 +2211,7 @@ int page_follow_link(struct dentry *dent
737  {
738         struct page *page = NULL;
739         char *s = page_getlink(dentry, &page);
740 -       int res = __vfs_follow_link(nd, s);
741 +       int res = __vfs_follow_link(nd, s, NULL);
742         if (page) {
743                 kunmap(page);
744                 page_cache_release(page);
745 --- linux-2.4.18-18.8.0-l7/fs/nfsd/vfs.c~vfs_intent-2.4.18-18   Mon Jan 20 12:25:10 2003
746 +++ linux-2.4.18-18.8.0-l7-root/fs/nfsd/vfs.c   Mon Jan 20 12:25:10 2003
747 @@ -1298,7 +1298,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru
748                         err = nfserr_perm;
749         } else
750  #endif
751 -       err = vfs_rename(fdir, odentry, tdir, ndentry);
752 +       err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
753         unlock_kernel();
754         if (!err && EX_ISSYNC(tfhp->fh_export)) {
755                 nfsd_sync_dir(tdentry);
756 --- linux-2.4.18-18.8.0-l7/fs/open.c~vfs_intent-2.4.18-18       Mon Jan 20 12:25:10 2003
757 +++ linux-2.4.18-18.8.0-l7-root/fs/open.c       Wed Jan 22 10:39:31 2003
758 @@ -19,6 +19,9 @@
759  #include <asm/uaccess.h>
760  
761  #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
762 +extern int path_walk_it(const char *name, struct nameidata *nd,
763 +                       struct lookup_intent *it);
764 +extern void intent_release(struct dentry *de, struct lookup_intent *it);
765  
766  int vfs_statfs(struct super_block *sb, struct statfs *buf)
767  {
768 @@ -118,12 +121,13 @@ static inline long do_sys_truncate(const
769         struct nameidata nd;
770         struct inode * inode;
771         int error;
772 +       struct lookup_intent it = { .it_op = IT_TRUNC };
773  
774         error = -EINVAL;
775         if (length < 0) /* sorry, but loff_t says... */
776                 goto out;
777  
778 -       error = user_path_walk(path, &nd);
779 +       error = user_path_walk_it(path, &nd, &it);
780         if (error)
781                 goto out;
782         inode = nd.dentry->d_inode;
783 @@ -168,6 +172,7 @@ static inline long do_sys_truncate(const
784         put_write_access(inode);
785  
786  dput_and_out:
787 +       intent_release(nd.dentry, &it);
788         path_release(&nd);
789  out:
790         return error;
791 @@ -259,8 +264,9 @@ asmlinkage long sys_utime(char * filenam
792         struct nameidata nd;
793         struct inode * inode;
794         struct iattr newattrs;
795 +       struct lookup_intent it = { .it_op = IT_SETATTR };
796  
797 -       error = user_path_walk(filename, &nd);
798 +       error = user_path_walk_it(filename, &nd, &it);
799         if (error)
800                 goto out;
801         inode = nd.dentry->d_inode;
802 @@ -286,6 +292,7 @@ asmlinkage long sys_utime(char * filenam
803         }
804         error = notify_change(nd.dentry, &newattrs);
805  dput_and_out:
806 +       intent_release(nd.dentry, &it);
807         path_release(&nd);
808  out:
809         return error;
810 @@ -303,8 +310,9 @@ asmlinkage long sys_utimes(char * filena
811         struct nameidata nd;
812         struct inode * inode;
813         struct iattr newattrs;
814 +       struct lookup_intent it = { .it_op = IT_SETATTR };
815  
816 -       error = user_path_walk(filename, &nd);
817 +       error = user_path_walk_it(filename, &nd, &it);
818  
819         if (error)
820                 goto out;
821 @@ -331,6 +339,7 @@ asmlinkage long sys_utimes(char * filena
822         }
823         error = notify_change(nd.dentry, &newattrs);
824  dput_and_out:
825 +       intent_release(nd.dentry, &it);
826         path_release(&nd);
827  out:
828         return error;
829 @@ -347,6 +356,7 @@ asmlinkage long sys_access(const char * 
830         int old_fsuid, old_fsgid;
831         kernel_cap_t old_cap;
832         int res;
833 +       struct lookup_intent it = { .it_op = IT_GETATTR };
834  
835         if (mode & ~S_IRWXO)    /* where's F_OK, X_OK, W_OK, R_OK? */
836                 return -EINVAL;
837 @@ -364,13 +374,14 @@ asmlinkage long sys_access(const char * 
838         else
839                 current->cap_effective = current->cap_permitted;
840  
841 -       res = user_path_walk(filename, &nd);
842 +       res = user_path_walk_it(filename, &nd, &it);
843         if (!res) {
844                 res = permission(nd.dentry->d_inode, mode);
845                 /* SuS v2 requires we report a read only fs too */
846                 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
847                    && !special_file(nd.dentry->d_inode->i_mode))
848                         res = -EROFS;
849 +               intent_release(nd.dentry, &it);
850                 path_release(&nd);
851         }
852  
853 @@ -385,8 +396,11 @@ asmlinkage long sys_chdir(const char * f
854  {
855         int error;
856         struct nameidata nd;
857 +       struct lookup_intent it = { .it_op = IT_GETATTR };
858  
859 -       error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd);
860 +       error = __user_walk_it(filename,
861 +                              LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,
862 +                              &nd, &it);
863         if (error)
864                 goto out;
865  
866 @@ -397,6 +411,7 @@ asmlinkage long sys_chdir(const char * f
867         set_fs_pwd(current->fs, nd.mnt, nd.dentry);
868  
869  dput_and_out:
870 +       intent_release(nd.dentry, &it);
871         path_release(&nd);
872  out:
873         return error;
874 @@ -436,9 +451,10 @@ asmlinkage long sys_chroot(const char * 
875  {
876         int error;
877         struct nameidata nd;
878 +       struct lookup_intent it = { .it_op = IT_GETATTR };
879  
880 -       error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
881 -                     LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
882 +       error = __user_walk_it(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
883 +                              LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd, &it);
884         if (error)
885                 goto out;
886  
887 @@ -454,6 +470,7 @@ asmlinkage long sys_chroot(const char * 
888         set_fs_altroot();
889         error = 0;
890  dput_and_out:
891 +       intent_release(nd.dentry, &it);
892         path_release(&nd);
893  out:
894         return error;
895 @@ -498,8 +515,9 @@ asmlinkage long sys_chmod(const char * f
896         struct inode * inode;
897         int error;
898         struct iattr newattrs;
899 +       struct lookup_intent it = { .it_op = IT_SETATTR };
900  
901 -       error = user_path_walk(filename, &nd);
902 +       error = user_path_walk_it(filename, &nd, &it);
903         if (error)
904                 goto out;
905         inode = nd.dentry->d_inode;
906 @@ -519,6 +537,7 @@ asmlinkage long sys_chmod(const char * f
907         error = notify_change(nd.dentry, &newattrs);
908  
909  dput_and_out:
910 +       intent_release(nd.dentry, &it);
911         path_release(&nd);
912  out:
913         return error;
914 @@ -588,10 +607,12 @@ asmlinkage long sys_chown(const char * f
915  {
916         struct nameidata nd;
917         int error;
918 +       struct lookup_intent it = { .it_op = IT_SETATTR };
919  
920 -       error = user_path_walk(filename, &nd);
921 +       error = user_path_walk_it(filename, &nd, &it);
922         if (!error) {
923                 error = chown_common(nd.dentry, user, group);
924 +               intent_release(nd.dentry, &it);
925                 path_release(&nd);
926         }
927         return error;
928 @@ -601,10 +622,12 @@ asmlinkage long sys_lchown(const char * 
929  {
930         struct nameidata nd;
931         int error;
932 +       struct lookup_intent it = { .it_op = IT_SETATTR };
933  
934 -       error = user_path_walk_link(filename, &nd);
935 +       error = user_path_walk_link_it(filename, &nd, &it);
936         if (!error) {
937                 error = chown_common(nd.dentry, user, group);
938 +               intent_release(nd.dentry, &it);
939                 path_release(&nd);
940         }
941         return error;
942 @@ -628,7 +651,8 @@ extern ssize_t do_readahead(struct file 
943  /* for files over a certains size it doesn't pay to do readahead on open */
944  #define READAHEAD_CUTOFF 48000
945  
946 -struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
947 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
948 +                           int flags, struct lookup_intent *it)
949  {
950         struct file * f;
951         struct inode *inode;
952 @@ -693,6 +717,7 @@ struct file *dentry_open(struct dentry *
953                 do_readahead(f, 0, (48 * 1024) >> PAGE_SHIFT);
954         
955  
956 +       intent_release(dentry, it);
957         return f;
958  
959  cleanup_all:
960 @@ -707,11 +732,17 @@ cleanup_all:
961  cleanup_file:
962         put_filp(f);
963  cleanup_dentry:
964 +       intent_release(dentry, it);
965         dput(dentry);
966         mntput(mnt);
967         return ERR_PTR(error);
968  }
969  
970 +struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
971 +{
972 +       return dentry_open_it(dentry, mnt, flags, NULL);
973 +}
974 +
975  /*
976   * Find an empty file descriptor entry, and mark it busy.
977   */
978 --- linux-2.4.18-18.8.0-l7/fs/stat.c~vfs_intent-2.4.18-18       Mon Jan 20 12:25:10 2003
979 +++ linux-2.4.18-18.8.0-l7-root/fs/stat.c       Mon Jan 20 12:25:10 2003
980 @@ -13,6 +13,7 @@
981  
982  #include <asm/uaccess.h>
983  
984 +extern void intent_release(struct dentry *de, struct lookup_intent *it);
985  /*
986   * Revalidate the inode. This is required for proper NFS attribute caching.
987   */
988 @@ -104,10 +105,12 @@ int vfs_stat(char *name, struct kstat *s
989  {
990         struct nameidata nd;
991         int error;
992 +       struct lookup_intent it = { .it_op = IT_GETATTR };
993  
994 -       error = user_path_walk(name, &nd);
995 +       error = user_path_walk_it(name, &nd, &it);
996         if (!error) {
997                 error = do_getattr(nd.mnt, nd.dentry, stat);
998 +               intent_release(nd.dentry, &it);
999                 path_release(&nd);
1000         }
1001         return error;
1002 @@ -117,10 +120,12 @@ int vfs_lstat(char *name, struct kstat *
1003  {
1004         struct nameidata nd;
1005         int error;
1006 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1007  
1008 -       error = user_path_walk_link(name, &nd);
1009 +       error = user_path_walk_link_it(name, &nd, &it);
1010         if (!error) {
1011                 error = do_getattr(nd.mnt, nd.dentry, stat);
1012 +               intent_release(nd.dentry, &it);
1013                 path_release(&nd);
1014         }
1015         return error;
1016 --- linux-2.4.18-18.8.0-l7/include/linux/dcache.h~vfs_intent-2.4.18-18  Mon Jan 20 12:25:10 2003
1017 +++ linux-2.4.18-18.8.0-l7-root/include/linux/dcache.h  Wed Jan 22 19:38:12 2003
1018 @@ -6,6 +6,27 @@
1019  #include <asm/atomic.h>
1020  #include <linux/mount.h>
1021  
1022 +#define IT_OPEN     (1)
1023 +#define IT_CREAT    (1<<1)
1024 +#define IT_READDIR  (1<<2)
1025 +#define IT_GETATTR  (1<<3)
1026 +#define IT_SETATTR  (1<<4)
1027 +#define IT_TRUNC    (1<<5)
1028 +#define IT_READLINK (1<<6)
1029 +#define IT_LOOKUP   (1<<7)
1030 +
1031 +struct lookup_intent {
1032 +       int it_op;
1033 +       int it_mode;
1034 +       int it_flags;
1035 +       int it_disposition;
1036 +       int it_status;
1037 +       struct iattr *it_iattr;
1038 +       __u64 it_lock_handle[2];
1039 +       int it_lock_mode;
1040 +       void *it_data;
1041 +};
1042 +
1043  /*
1044   * linux/include/linux/dcache.h
1045   *
1046 @@ -78,6 +99,7 @@ struct dentry {
1047         unsigned long d_time;           /* used by d_revalidate */
1048         struct dentry_operations  *d_op;
1049         struct super_block * d_sb;      /* The root of the dentry tree */
1050 +       struct lookup_intent *d_it;
1051         unsigned long d_vfs_flags;
1052         void * d_fsdata;                /* fs-specific data */
1053         void * d_extra_attributes;      /* TUX-specific data */
1054 @@ -91,6 +113,8 @@ struct dentry_operations {
1055         int (*d_delete)(struct dentry *);
1056         void (*d_release)(struct dentry *);
1057         void (*d_iput)(struct dentry *, struct inode *);
1058 +       int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
1059 +       void (*d_intent_release)(struct dentry *, struct lookup_intent *);
1060  };
1061  
1062  /* the dentry parameter passed to d_hash and d_compare is the parent
1063 @@ -124,6 +148,7 @@ d_iput:             no              no              yes
1064                                          * s_nfsd_free_path semaphore will be down
1065                                          */
1066  #define DCACHE_REFERENCED      0x0008  /* Recently used, don't discard. */
1067 +#define DCACHE_LUSTRE_INVALID  0x0010  /* Lustre invalidated */
1068  
1069  extern spinlock_t dcache_lock;
1070  
1071 --- linux-2.4.18-18.8.0-l7/include/linux/fs.h~vfs_intent-2.4.18-18      Mon Jan 20 12:25:10 2003
1072 +++ linux-2.4.18-18.8.0-l7-root/include/linux/fs.h      Wed Jan 22 22:46:13 2003
1073 @@ -576,6 +576,7 @@ struct file {
1074  
1075         /* needed for tty driver, and maybe others */
1076         void                    *private_data;
1077 +       struct lookup_intent    *f_intent;
1078  
1079         /* preallocated helper kiobuf to speedup O_DIRECT */
1080         struct kiobuf           *f_iobuf;
1081 @@ -836,7 +837,9 @@ extern int vfs_symlink(struct inode *, s
1082  extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
1083  extern int vfs_rmdir(struct inode *, struct dentry *);
1084  extern int vfs_unlink(struct inode *, struct dentry *);
1085 -extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
1086 +int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1087 +               struct inode *new_dir, struct dentry *new_dentry,
1088 +               struct lookup_intent *it);
1089  
1090  /*
1091   * File types
1092 @@ -897,16 +900,28 @@ struct file_operations {
1093  struct inode_operations {
1094         int (*create) (struct inode *,struct dentry *,int);
1095         struct dentry * (*lookup) (struct inode *,struct dentry *);
1096 +       struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *);
1097         int (*link) (struct dentry *,struct inode *,struct dentry *);
1098 +       int (*link2) (struct inode *,struct inode *, const char *, int);
1099         int (*unlink) (struct inode *,struct dentry *);
1100 +       int (*unlink2) (struct inode *, const char *, int);
1101         int (*symlink) (struct inode *,struct dentry *,const char *);
1102 +       int (*symlink2) (struct inode *, const char *, int, const char *);
1103         int (*mkdir) (struct inode *,struct dentry *,int);
1104 +       int (*mkdir2) (struct inode *, const char *, int,int);
1105         int (*rmdir) (struct inode *,struct dentry *);
1106 +       int (*rmdir2) (struct inode *, const char *, int);
1107         int (*mknod) (struct inode *,struct dentry *,int,int);
1108 +       int (*mknod2) (struct inode *, const char *, int,int,int);
1109         int (*rename) (struct inode *, struct dentry *,
1110                         struct inode *, struct dentry *);
1111 +       int (*rename2) (struct inode *, struct inode *, 
1112 +                       const char *oldname, int oldlen, 
1113 +                       const char *newname, int newlen);
1114         int (*readlink) (struct dentry *, char *,int);
1115         int (*follow_link) (struct dentry *, struct nameidata *);
1116 +       int (*follow_link2) (struct dentry *, struct nameidata *, 
1117 +                            struct lookup_intent *it);
1118         void (*truncate) (struct inode *);
1119         int (*permission) (struct inode *, int);
1120         int (*revalidate) (struct dentry *);
1121 @@ -1381,6 +1396,7 @@ typedef int (*read_actor_t)(read_descrip
1122  extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
1123  
1124  extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
1125 +extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
1126  extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
1127  extern int FASTCALL(path_walk(const char *, struct nameidata *));
1128  extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
1129 @@ -1392,6 +1408,8 @@ extern struct dentry * lookup_one_len(co
1130  extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
1131  #define user_path_walk(name,nd)         __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
1132  #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
1133 +#define user_path_walk_it(name,nd,it)  __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
1134 +#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
1135  
1136  extern void inode_init_once(struct inode *);
1137  extern void iput(struct inode *);
1138 @@ -1492,6 +1510,8 @@ extern struct file_operations generic_ro
1139  
1140  extern int vfs_readlink(struct dentry *, char *, int, const char *);
1141  extern int vfs_follow_link(struct nameidata *, const char *);
1142 +extern int vfs_follow_link_it(struct nameidata *, const char *, 
1143 +                             struct lookup_intent *it);
1144  extern int page_readlink(struct dentry *, char *, int);
1145  extern int page_follow_link(struct dentry *, struct nameidata *);
1146  extern struct inode_operations page_symlink_inode_operations;
1147 --- linux-2.4.18-18.8.0-l7/kernel/ksyms.c~vfs_intent-2.4.18-18  Mon Jan 20 12:25:10 2003
1148 +++ linux-2.4.18-18.8.0-l7-root/kernel/ksyms.c  Mon Jan 20 12:25:10 2003
1149 @@ -293,6 +293,7 @@ EXPORT_SYMBOL(read_cache_page);
1150  EXPORT_SYMBOL(set_page_dirty);
1151  EXPORT_SYMBOL(vfs_readlink);
1152  EXPORT_SYMBOL(vfs_follow_link);
1153 +EXPORT_SYMBOL(vfs_follow_link_it);
1154  EXPORT_SYMBOL(page_readlink);
1155  EXPORT_SYMBOL(page_follow_link);
1156  EXPORT_SYMBOL(page_symlink_inode_operations);
1157
1158 _