Whamcloud - gitweb
file llobdstat.pl was initially added on branch b_devel.
[fs/lustre-release.git] / lustre / kernel_patches / patches / vfs_intent_hp.patch
1  fs/dcache.c            |    8 
2  fs/namei.c             |  335 +++++++++++++++++----
3  fs/nfsd/vfs.c          |    2 
4  fs/open.c              |  142 +++++++-
5  fs/stat.c              |   24 +
6  include/linux/dcache.h |   26 +
7  include/linux/fs.h     |   27 +
8  kernel/ksyms.c         |    1 
9  fs/exec.c                   |   18 -
10  9 files changed, 487 insertions(+), 96 deletions(-)
11  
12 --- linux-2.4.19-hp2_pnnl4/fs/dcache.c~vfs_intent_hp    Sun Jan 19 19:04:47 2003
13 +++ linux-2.4.19-hp2_pnnl4-root/fs/dcache.c     Sun Jan 19 19:04:47 2003
14 @@ -186,6 +188,13 @@ int d_invalidate(struct dentry * dentry)
15                 spin_unlock(&dcache_lock);
16                 return 0;
17         }
18 +
19 +       /* network invalidation by Lustre */
20 +       if (dentry->d_flags & DCACHE_LUSTRE_INVALID) {
21 +               spin_unlock(&dcache_lock);
22 +               return 0;
23 +       }
24 +
25         /*
26          * Check whether to do a partial shrink_dcache
27          * to get rid of unused child entries.
28 @@ -616,6 +618,7 @@ struct dentry * d_alloc(struct dentry * 
29         dentry->d_op = NULL;
30         dentry->d_fsdata = NULL;
31         dentry->d_mounted = 0;
32 +       dentry->d_it = NULL;
33         INIT_LIST_HEAD(&dentry->d_hash);
34         INIT_LIST_HEAD(&dentry->d_lru);
35         INIT_LIST_HEAD(&dentry->d_subdirs);
36 @@ -859,13 +867,19 @@ void d_delete(struct dentry * dentry)
37   * Adds a dentry to the hash according to its name.
38   */
39   
40 -void d_rehash(struct dentry * entry)
41 +void __d_rehash(struct dentry * entry, int lock)
42  {
43         struct list_head *list = d_hash(entry->d_parent, entry->d_name.hash);
44         if (!list_empty(&entry->d_hash)) BUG();
45 -       spin_lock(&dcache_lock);
46 +       if (lock) spin_lock(&dcache_lock);
47         list_add(&entry->d_hash, list);
48 -       spin_unlock(&dcache_lock);
49 +       if (lock) spin_unlock(&dcache_lock);
50 +}
51 +EXPORT_SYMBOL(__d_rehash);
52 +
53 +void d_rehash(struct dentry * entry)
54 +{
55 +       __d_rehash(entry, 1);
56  }
57  
58  #define do_switch(x,y) do { \
59 --- linux-2.4.19-hp2_pnnl4/fs/namei.c~vfs_intent_hp     Sun Jan 19 19:04:47 2003
60 +++ linux-2.4.19-hp2_pnnl4-root/fs/namei.c      Sun Jan 19 19:35:55 2003
61 @@ -94,6 +97,13 @@
62   * XEmacs seems to be relying on it...
63   */
64  
65 +void intent_release(struct dentry *de, struct lookup_intent *it)
66 +{
67 +       if (it && de->d_op && de->d_op->d_intent_release)
68 +               de->d_op->d_intent_release(de, it);
69 +
70 +}
71 +
72  /* In order to reduce some races, while at the same time doing additional
73   * checking and hopefully speeding things up, we copy filenames to the
74   * kernel data space before using them..
75 @@ -260,10 +271,19 @@ void path_release(struct nameidata *nd)
76   * Internal lookup() using the new generic dcache.
77   * SMP-safe
78   */
79 -static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
80 +static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name,
81 +                                   int flags, struct lookup_intent *it)
82  {
83         struct dentry * dentry = d_lookup(parent, name);
84  
85 +       if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
86 +               if (!dentry->d_op->d_revalidate2(dentry, flags, it) &&
87 +                   !d_invalidate(dentry)) {
88 +                       dput(dentry);
89 +                       dentry = NULL;
90 +               }
91 +               return dentry;
92 +       } else
93         if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
94                 if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
95                         dput(dentry);
96 @@ -281,11 +301,14 @@ static struct dentry * cached_lookup(str
97   * make sure that nobody added the entry to the dcache in the meantime..
98   * SMP-safe
99   */
100 -static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
101 +static struct dentry *real_lookup(struct dentry *parent, struct qstr *name,
102 +                                 int flags, struct lookup_intent *it)
103  {
104         struct dentry * result;
105         struct inode *dir = parent->d_inode;
106  
107 +again:
108 +
109         down(&dir->i_sem);
110         /*
111          * First re-do the cached lookup just in case it was created
112 @@ -300,6 +321,9 @@ static struct dentry * real_lookup(struc
113                 result = ERR_PTR(-ENOMEM);
114                 if (dentry) {
115                         lock_kernel();
116 +                       if (dir->i_op->lookup2)
117 +                               result = dir->i_op->lookup2(dir, dentry, it);
118 +                       else
119                         result = dir->i_op->lookup(dir, dentry);
120                         unlock_kernel();
121                         if (result)
122 @@ -321,6 +345,12 @@ static struct dentry * real_lookup(struc
123                         dput(result);
124                         result = ERR_PTR(-ENOENT);
125                 }
126 +       } else if (result->d_op && result->d_op->d_revalidate2) {
127 +               if (!result->d_op->d_revalidate2(result, flags, it) &&
128 +                   !d_invalidate(result)) {
129 +                       dput(result);
130 +                       goto again;
131 +               }
132         }
133         return result;
134  }
135 @@ -332,7 +362,8 @@ static struct dentry * real_lookup(struc
136   * Without that kind of total limit, nasty chains of consecutive
137   * symlinks can cause almost arbitrarily long lookups. 
138   */
139 -static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
140 +static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd,
141 +                                struct lookup_intent *it)
142  {
143         int err;
144         if (current->link_count >= 5)
145 @@ -346,10 +377,14 @@ static inline int do_follow_link(struct 
146         current->link_count++;
147         current->total_link_count++;
148         UPDATE_ATIME(dentry->d_inode);
149 -       err = dentry->d_inode->i_op->follow_link(dentry, nd);
150 +       if (dentry->d_inode->i_op->follow_link2)
151 +               err = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
152 +       else
153 +               err = dentry->d_inode->i_op->follow_link(dentry, nd);
154         current->link_count--;
155         return err;
156  loop:
157 +       intent_release(dentry, it);
158         path_release(nd);
159         return -ELOOP;
160  }
161 @@ -381,15 +416,26 @@ int follow_up(struct vfsmount **mnt, str
162         return __follow_up(mnt, dentry);
163  }
164  
165 -static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry)
166 +static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry,
167 +                               struct lookup_intent *it)
168  {
169         struct vfsmount *mounted;
170  
171         spin_lock(&dcache_lock);
172         mounted = lookup_mnt(*mnt, *dentry);
173         if (mounted) {
174 +               int opc = 0, mode = 0;
175                 *mnt = mntget(mounted);
176                 spin_unlock(&dcache_lock);
177 +               if (it) {
178 +                       opc = it->it_op;
179 +                       mode = it->it_mode;
180 +               }
181 +               intent_release(*dentry, it);
182 +               if (it) {
183 +                       it->it_op = opc;
184 +                       it->it_mode = mode;
185 +               }
186                 dput(*dentry);
187                 mntput(mounted->mnt_parent);
188                 *dentry = dget(mounted->mnt_root);
189 @@ -401,7 +447,7 @@ static inline int __follow_down(struct v
190  
191  int follow_down(struct vfsmount **mnt, struct dentry **dentry)
192  {
193 -       return __follow_down(mnt,dentry);
194 +       return __follow_down(mnt,dentry,NULL);
195  }
196   
197  static inline void follow_dotdot(struct nameidata *nd)
198 @@ -437,7 +483,7 @@ static inline void follow_dotdot(struct 
199                 mntput(nd->mnt);
200                 nd->mnt = parent;
201         }
202 -       while (d_mountpoint(nd->dentry) && __follow_down(&nd->mnt, &nd->dentry))
203 +       while (d_mountpoint(nd->dentry) && __follow_down(&nd->mnt, &nd->dentry, NULL))
204                 ;
205  }
206  
207 @@ -447,7 +482,8 @@ static inline void follow_dotdot(struct 
208   *
209   * We expect 'base' to be positive and a directory.
210   */
211 -int link_path_walk(const char * name, struct nameidata *nd)
212 +int link_path_walk_it(const char *name, struct nameidata *nd,
213 +                     struct lookup_intent *it)
214  {
215         struct dentry *dentry;
216         struct inode *inode;
217 @@ -520,15 +556,15 @@ int link_path_walk(const char * name, st
218                                 break;
219                 }
220                 /* This does the actual lookups.. */
221 -               dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
222 +               dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
223                 if (!dentry) {
224 -                       dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
225 +                       dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
226                         err = PTR_ERR(dentry);
227                         if (IS_ERR(dentry))
228                                 break;
229                 }
230                 /* Check mountpoints.. */
231 -               while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry))
232 +               while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry, NULL))
233                         ;
234  
235                 err = -ENOENT;
236 @@ -539,8 +575,8 @@ int link_path_walk(const char * name, st
237                 if (!inode->i_op)
238                         goto out_dput;
239  
240 -               if (inode->i_op->follow_link) {
241 -                       err = do_follow_link(dentry, nd);
242 +               if (inode->i_op->follow_link || inode->i_op->follow_link2) {
243 +                       err = do_follow_link(dentry, nd, NULL);
244                         dput(dentry);
245                         if (err)
246                                 goto return_err;
247 @@ -556,7 +592,7 @@ int link_path_walk(const char * name, st
248                         nd->dentry = dentry;
249                 }
250                 err = -ENOTDIR; 
251 -               if (!inode->i_op->lookup)
252 +               if (!inode->i_op->lookup && !inode->i_op->lookup2)
253                         break;
254                 continue;
255                 /* here ends the main loop */
256 @@ -583,19 +619,20 @@ last_component:
257                         if (err < 0)
258                                 break;
259                 }
260 -               dentry = cached_lookup(nd->dentry, &this, 0);
261 +               dentry = cached_lookup(nd->dentry, &this, 0, it);
262                 if (!dentry) {
263 -                       dentry = real_lookup(nd->dentry, &this, 0);
264 +                       dentry = real_lookup(nd->dentry, &this, 0, it);
265                         err = PTR_ERR(dentry);
266                         if (IS_ERR(dentry))
267                                 break;
268                 }
269 -               while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry))
270 +               while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry, it))
271                         ;
272                 inode = dentry->d_inode;
273                 if ((lookup_flags & LOOKUP_FOLLOW)
274 -                   && inode && inode->i_op && inode->i_op->follow_link) {
275 -                       err = do_follow_link(dentry, nd);
276 +                   && inode && inode->i_op &&
277 +                   (inode->i_op->follow_link || inode->i_op->follow_link2)) {
278 +                       err = do_follow_link(dentry, nd, it);
279                         dput(dentry);
280                         if (err)
281                                 goto return_err;
282 @@ -609,7 +647,8 @@ last_component:
283                         goto no_inode;
284                 if (lookup_flags & LOOKUP_DIRECTORY) {
285                         err = -ENOTDIR; 
286 -                       if (!inode->i_op || !inode->i_op->lookup)
287 +                       if (!inode->i_op ||
288 +                           (!inode->i_op->lookup && !inode->i_op->lookup2))
289                                 break;
290                 }
291                 goto return_base;
292 @@ -646,15 +685,28 @@ out_dput:
293                 dput(dentry);
294                 break;
295         }
296 +       if (err)
297 +               intent_release(nd->dentry, it);
298         path_release(nd);
299  return_err:
300         return err;
301  }
302  
303 +int link_path_walk(const char * name, struct nameidata *nd)
304 +{
305 +       return link_path_walk_it(name, nd, NULL);
306 +}
307 +
308 +int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
309 +{
310 +       current->total_link_count = 0;
311 +       return link_path_walk_it(name, nd, it);
312 +}
313 +
314  int path_walk(const char * name, struct nameidata *nd)
315  {
316         current->total_link_count = 0;
317 -       return link_path_walk(name, nd);
318 +       return link_path_walk_it(name, nd, NULL);
319  }
320  
321  /* SMP-safe */
322 @@ -757,7 +809,8 @@ int path_init(const char *name, unsigned
323   * needs parent already locked. Doesn't follow mounts.
324   * SMP-safe.
325   */
326 -struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
327 +struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base,
328 +                              struct lookup_intent *it)
329  {
330         struct dentry * dentry;
331         struct inode *inode;
332 @@ -780,13 +833,16 @@ struct dentry * lookup_hash(struct qstr 
333                         goto out;
334         }
335  
336 -       dentry = cached_lookup(base, name, 0);
337 +       dentry = cached_lookup(base, name, 0, it);
338         if (!dentry) {
339                 struct dentry *new = d_alloc(base, name);
340                 dentry = ERR_PTR(-ENOMEM);
341                 if (!new)
342                         goto out;
343                 lock_kernel();
344 +               if (inode->i_op->lookup2)
345 +                       dentry = inode->i_op->lookup2(inode, new, it);
346 +               else
347                 dentry = inode->i_op->lookup(inode, new);
348                 unlock_kernel();
349                 if (!dentry)
350 @@ -798,6 +854,12 @@ out:
351         return dentry;
352  }
353  
354 +struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
355 +{
356 +       return lookup_hash_it(name, base, NULL);
357 +}
358 +
359 +
360  /* SMP-safe */
361  struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
362  {
363 @@ -819,7 +881,7 @@ struct dentry * lookup_one_len(const cha
364         }
365         this.hash = end_name_hash(hash);
366  
367 -       return lookup_hash(&this, base);
368 +       return lookup_hash_it(&this, base, NULL);
369  access:
370         return ERR_PTR(-EACCES);
371  }
372 @@ -851,6 +913,23 @@ int __user_walk(const char *name, unsign
373         return err;
374  }
375  
376 +int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd,
377 +                  struct lookup_intent *it)
378 +{
379 +       char *tmp;
380 +       int err;
381 +
382 +       tmp = getname(name);
383 +       err = PTR_ERR(tmp);
384 +       if (!IS_ERR(tmp)) {
385 +               err = 0;
386 +               if (path_init(tmp, flags, nd))
387 +                       err = path_walk_it(tmp, nd, it);
388 +               putname(tmp);
389 +       }
390 +       return err;
391 +}
392 +
393  /*
394   * It's inline, so penalty for filesystems that don't use sticky bit is
395   * minimal.
396 @@ -987,7 +1066,8 @@ exit_lock:
397   * for symlinks (where the permissions are checked later).
398   * SMP-safe
399   */
400 -int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
401 +int open_namei_it(const char *pathname, int flag, int mode,
402 +                 struct nameidata *nd, struct lookup_intent *it)
403  {
404         int acc_mode, error = 0;
405         struct inode *inode;
406 @@ -1002,7 +1082,7 @@ int open_namei(const char * pathname, in
407          */
408         if (!(flag & O_CREAT)) {
409                 if (path_init(pathname, lookup_flags(flag), nd))
410 -                       error = path_walk(pathname, nd);
411 +                       error = path_walk_it(pathname, nd, it);
412                 if (error)
413                         return error;
414                 dentry = nd->dentry;
415 @@ -1012,6 +1092,10 @@ int open_namei(const char * pathname, in
416         /*
417          * Create - we need to know the parent.
418          */
419 +       if (it) {
420 +               it->it_mode = mode;
421 +               it->it_op |= IT_CREAT;
422 +       }
423         if (path_init(pathname, LOOKUP_PARENT, nd))
424                 error = path_walk(pathname, nd);
425         if (error)
426 @@ -1028,7 +1112,7 @@ int open_namei(const char * pathname, in
427  
428         dir = nd->dentry;
429         down(&dir->d_inode->i_sem);
430 -       dentry = lookup_hash(&nd->last, nd->dentry);
431 +       dentry = lookup_hash_it(&nd->last, nd->dentry, it);
432  
433  do_last:
434         error = PTR_ERR(dentry);
435 @@ -1037,6 +1121,7 @@ do_last:
436                 goto exit;
437         }
438  
439 +       it->it_mode = mode;
440         /* Negative dentry, just create the file */
441         if (!dentry->d_inode) {
442                 if (!IS_POSIXACL(dir->d_inode))
443 @@ -1066,12 +1151,13 @@ do_last:
444                 error = -ELOOP;
445                 if (flag & O_NOFOLLOW)
446                         goto exit_dput;
447 -               while (__follow_down(&nd->mnt,&dentry) && d_mountpoint(dentry));
448 +               while (__follow_down(&nd->mnt,&dentry,it) && d_mountpoint(dentry));
449         }
450         error = -ENOENT;
451         if (!dentry->d_inode)
452                 goto exit_dput;
453 -       if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link)
454 +       if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link ||
455 +                                     dentry->d_inode->i_op->follow_link2))
456                 goto do_link;
457  
458         dput(nd->dentry);
459 @@ -1145,7 +1231,7 @@ do_last:
460                 if (!error) {
461                         DQUOT_INIT(inode);
462                         
463 -                       error = do_truncate(dentry, 0);
464 +                       error = do_truncate(dentry, 0, 1);
465                 }
466                 put_write_access(inode);
467                 if (error)
468 @@ -1157,8 +1243,10 @@ ok:
469         return 0;
470  
471  exit_dput:
472 +       intent_release(dentry, it);
473         dput(dentry);
474  exit:
475 +       intent_release(nd->dentry, it);
476         path_release(nd);
477         return error;
478  
479 @@ -1177,7 +1265,12 @@ do_link:
480          * are done. Procfs-like symlinks just set LAST_BIND.
481          */
482         UPDATE_ATIME(dentry->d_inode);
483 -       error = dentry->d_inode->i_op->follow_link(dentry, nd);
484 +       if (dentry->d_inode->i_op->follow_link2)
485 +               error = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
486 +       else
487 +               error = dentry->d_inode->i_op->follow_link(dentry, nd);
488 +       if (error)
489 +               intent_release(dentry, it);
490         dput(dentry);
491         if (error)
492                 return error;
493 @@ -1199,13 +1292,20 @@ do_link:
494         }
495         dir = nd->dentry;
496         down(&dir->d_inode->i_sem);
497 -       dentry = lookup_hash(&nd->last, nd->dentry);
498 +       dentry = lookup_hash_it(&nd->last, nd->dentry, it);
499         putname(nd->last.name);
500         goto do_last;
501  }
502  
503 +int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd)
504 +{
505 +       return open_namei_it(pathname, flag, mode, nd, NULL);
506 +}
507 +
508 +
509  /* SMP-safe */
510 -static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
511 +static struct dentry *lookup_create(struct nameidata *nd, int is_dir,
512 +                                   struct lookup_intent *it)
513  {
514         struct dentry *dentry;
515  
516 @@ -1213,7 +1313,7 @@ static struct dentry *lookup_create(stru
517         dentry = ERR_PTR(-EEXIST);
518         if (nd->last_type != LAST_NORM)
519                 goto fail;
520 -       dentry = lookup_hash(&nd->last, nd->dentry);
521 +       dentry = lookup_hash_it(&nd->last, nd->dentry, it);
522         if (IS_ERR(dentry))
523                 goto fail;
524         if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
525 @@ -1270,7 +1371,19 @@ asmlinkage long sys_mknod(const char * f
526                 error = path_walk(tmp, &nd);
527         if (error)
528                 goto out;
529 -       dentry = lookup_create(&nd, 0);
530 +
531 +       if (nd.dentry->d_inode->i_op->mknod2) {
532 +               struct inode_operations *op = nd.dentry->d_inode->i_op;
533 +               error = op->mknod2(nd.dentry->d_inode,
534 +                                  nd.last.name,
535 +                                  nd.last.len,
536 +                                  mode, dev);
537 +               /* the file system wants to use normal vfs path now */
538 +               if (error != -EOPNOTSUPP)
539 +                       goto out2;
540 +       }
541 +
542 +       dentry = lookup_create(&nd, 0, NULL);
543         error = PTR_ERR(dentry);
544  
545         if (!IS_POSIXACL(nd.dentry->d_inode))
546 @@ -1289,6 +1402,7 @@ asmlinkage long sys_mknod(const char * f
547                 dput(dentry);
548         }
549         up(&nd.dentry->d_inode->i_sem);
550 +out2:
551         path_release(&nd);
552  out:
553         putname(tmp);
554 @@ -1340,15 +1456,25 @@ asmlinkage long sys_mkdir(const char * p
555                         error = path_walk(tmp, &nd);
556                 if (error)
557                         goto out;
558 -               dentry = lookup_create(&nd, 1);
559 +               if (nd.dentry->d_inode->i_op->mkdir2) {
560 +                       struct inode_operations *op = nd.dentry->d_inode->i_op;
561 +                       error = op->mkdir2(nd.dentry->d_inode,
562 +                                          nd.last.name,
563 +                                          nd.last.len,
564 +                                          mode);
565 +                       /* the file system wants to use normal vfs path now */
566 +                       if (error != -EOPNOTSUPP)
567 +                               goto out2;
568 +               }
569 +               dentry = lookup_create(&nd, 1, NULL);
570                 error = PTR_ERR(dentry);
571                 if (!IS_ERR(dentry)) {
572 -                       if (!IS_POSIXACL(nd.dentry->d_inode))
573 -                               mode &= ~current->fs->umask;
574 -                       error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
575 +                       error = vfs_mkdir(nd.dentry->d_inode, dentry,
576 +                                         mode & ~current->fs->umask);
577                         dput(dentry);
578                 }
579                 up(&nd.dentry->d_inode->i_sem);
580 +out2:
581                 path_release(&nd);
582  out:
583                 putname(tmp);
584 @@ -1450,8 +1578,33 @@ asmlinkage long sys_rmdir(const char * p
585                         error = -EBUSY;
586                         goto exit1;
587         }
588 +       if (nd.dentry->d_inode->i_op->rmdir2) {
589 +               struct inode_operations *op = nd.dentry->d_inode->i_op;
590 +               struct dentry *last;
591 +
592 +               down(&nd.dentry->d_inode->i_sem);
593 +               last = lookup_hash_it(&nd.last, nd.dentry, NULL);
594 +               up(&nd.dentry->d_inode->i_sem);
595 +               if (IS_ERR(last)) {
596 +                       error = PTR_ERR(last);
597 +                       goto exit1;
598 +               }
599 +               if (d_mountpoint(last)) {
600 +                       dput(last);
601 +                       error = -EBUSY;
602 +                       goto exit1;
603 +               }
604 +               dput(last);
605 +
606 +               error = op->rmdir2(nd.dentry->d_inode,
607 +                                  nd.last.name,
608 +                                  nd.last.len);
609 +               /* the file system wants to use normal vfs path now */
610 +               if (error != -EOPNOTSUPP)
611 +                       goto exit1;
612 +       }
613         down(&nd.dentry->d_inode->i_sem);
614 -       dentry = lookup_hash(&nd.last, nd.dentry);
615 +       dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
616         error = PTR_ERR(dentry);
617         if (!IS_ERR(dentry)) {
618                 error = vfs_rmdir(nd.dentry->d_inode, dentry);
619 @@ -1510,8 +1649,17 @@ asmlinkage long sys_unlink(const char * 
620         error = -EISDIR;
621         if (nd.last_type != LAST_NORM)
622                 goto exit1;
623 +       if (nd.dentry->d_inode->i_op->unlink2) {
624 +               struct inode_operations *op = nd.dentry->d_inode->i_op;
625 +               error = op->unlink2(nd.dentry->d_inode,
626 +                                   nd.last.name,
627 +                                   nd.last.len);
628 +               /* the file system wants to use normal vfs path now */
629 +               if (error != -EOPNOTSUPP)
630 +                       goto exit1;
631 +       }
632         down(&nd.dentry->d_inode->i_sem);
633 -       dentry = lookup_hash(&nd.last, nd.dentry);
634 +       dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
635         error = PTR_ERR(dentry);
636         if (!IS_ERR(dentry)) {
637                 /* Why not before? Because we want correct error value */
638 @@ -1579,15 +1729,26 @@ asmlinkage long sys_symlink(const char *
639                         error = path_walk(to, &nd);
640                 if (error)
641                         goto out;
642 -               dentry = lookup_create(&nd, 0);
643 +               if (nd.dentry->d_inode->i_op->symlink2) {
644 +                       struct inode_operations *op = nd.dentry->d_inode->i_op;
645 +                       error = op->symlink2(nd.dentry->d_inode,
646 +                                            nd.last.name,
647 +                                            nd.last.len,
648 +                                            from);
649 +                       /* the file system wants to use normal vfs path now */
650 +                       if (error != -EOPNOTSUPP)
651 +                               goto out2;
652 +               }
653 +               dentry = lookup_create(&nd, 0, NULL);
654                 error = PTR_ERR(dentry);
655                 if (!IS_ERR(dentry)) {
656                         error = vfs_symlink(nd.dentry->d_inode, dentry, from);
657                         dput(dentry);
658                 }
659                 up(&nd.dentry->d_inode->i_sem);
660 +       out2:
661                 path_release(&nd);
662 -out:
663 +       out:
664                 putname(to);
665         }
666         putname(from);
667 @@ -1660,7 +1824,7 @@ asmlinkage long sys_link(const char * ol
668  
669                 error = 0;
670                 if (path_init(from, LOOKUP_POSITIVE, &old_nd))
671 -                       error = path_walk(from, &old_nd);
672 +                       error = path_walk_it(from, &old_nd, NULL);
673                 if (error)
674                         goto exit;
675                 if (path_init(to, LOOKUP_PARENT, &nd))
676 @@ -1670,7 +1834,17 @@ asmlinkage long sys_link(const char * ol
677                 error = -EXDEV;
678                 if (old_nd.mnt != nd.mnt)
679                         goto out_release;
680 -               new_dentry = lookup_create(&nd, 0);
681 +               if (nd.dentry->d_inode->i_op->link2) {
682 +                       struct inode_operations *op = nd.dentry->d_inode->i_op;
683 +                       error = op->link2(old_nd.dentry->d_inode,
684 +                                         nd.dentry->d_inode,
685 +                                         nd.last.name,
686 +                                         nd.last.len);
687 +                       /* the file system wants to use normal vfs path now */
688 +                       if (error != -EOPNOTSUPP)
689 +                               goto out_release;
690 +               }
691 +               new_dentry = lookup_create(&nd, 0, NULL);
692                 error = PTR_ERR(new_dentry);
693                 if (!IS_ERR(new_dentry)) {
694                         error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
695 @@ -1716,7 +1892,8 @@ exit:
696   *        locking].
697   */
698  int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
699 -              struct inode *new_dir, struct dentry *new_dentry)
700 +                  struct inode *new_dir, struct dentry *new_dentry,
701 +                  struct lookup_intent *it)
702  {
703         int error;
704         struct inode *target;
705 @@ -1753,6 +1923,7 @@ int vfs_rename_dir(struct inode *old_dir
706                 error = -EBUSY;
707         else 
708                 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
709 +       intent_release(new_dentry, it);
710         if (target) {
711                 if (!error)
712                         target->i_flags |= S_DEAD;
713 @@ -1795,7 +1973,8 @@ out_unlock:
714  }
715  
716  int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
717 -              struct inode *new_dir, struct dentry *new_dentry)
718 +                    struct inode *new_dir, struct dentry *new_dentry,
719 +                    struct lookup_intent *it)
720  {
721         int error;
722  
723 @@ -1826,6 +2005,7 @@ int vfs_rename_other(struct inode *old_d
724                 error = -EBUSY;
725         else
726                 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
727 +       intent_release(new_dentry, it);
728         double_up(&old_dir->i_zombie, &new_dir->i_zombie);
729         if (error)
730                 return error;
731 @@ -1837,13 +2017,14 @@ int vfs_rename_other(struct inode *old_d
732  }
733  
734  int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
735 -              struct inode *new_dir, struct dentry *new_dentry)
736 +              struct inode *new_dir, struct dentry *new_dentry,
737 +              struct lookup_intent *it)
738  {
739         int error;
740         if (S_ISDIR(old_dentry->d_inode->i_mode))
741 -               error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
742 +               error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it);
743         else
744 -               error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
745 +               error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it);
746         if (!error) {
747                 if (old_dir == new_dir)
748                         inode_dir_notify(old_dir, DN_RENAME);
749 @@ -1888,7 +2070,7 @@ static inline int do_rename(const char *
750  
751         double_lock(new_dir, old_dir);
752  
753 -       old_dentry = lookup_hash(&oldnd.last, old_dir);
754 +       old_dentry = lookup_hash_it(&oldnd.last, old_dir, NULL);
755         error = PTR_ERR(old_dentry);
756         if (IS_ERR(old_dentry))
757                 goto exit3;
758 @@ -1904,16 +2086,37 @@ static inline int do_rename(const char *
759                 if (newnd.last.name[newnd.last.len])
760                         goto exit4;
761         }
762 -       new_dentry = lookup_hash(&newnd.last, new_dir);
763 +       new_dentry = lookup_hash_it(&newnd.last, new_dir, NULL);
764         error = PTR_ERR(new_dentry);
765         if (IS_ERR(new_dentry))
766                 goto exit4;
767  
768 +       if (old_dir->d_inode->i_op->rename2) {
769 +               lock_kernel();
770 +               /* don't rename mount point. mds will take care of
771 +                * the rest sanity checking */
772 +               if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) {
773 +                       error = -EBUSY;
774 +                       goto exit5;
775 +               }
776 +
777 +               error = old_dir->d_inode->i_op->rename2(old_dir->d_inode,
778 +                                                       new_dir->d_inode,
779 +                                                       oldnd.last.name,
780 +                                                       oldnd.last.len,
781 +                                                       newnd.last.name,
782 +                                                       newnd.last.len);
783 +               unlock_kernel();
784 +               /* the file system wants to use normal vfs path now */
785 +               if (error != -EOPNOTSUPP)
786 +                       goto exit5;
787 +       }
788 +
789         lock_kernel();
790         error = vfs_rename(old_dir->d_inode, old_dentry,
791 -                                  new_dir->d_inode, new_dentry);
792 +                                  new_dir->d_inode, new_dentry, NULL);
793         unlock_kernel();
794 -
795 +exit5:
796         dput(new_dentry);
797  exit4:
798         dput(old_dentry);
799 @@ -1964,7 +2163,8 @@ out:
800  }
801  
802  static inline int
803 -__vfs_follow_link(struct nameidata *nd, const char *link)
804 +__vfs_follow_link(struct nameidata *nd, const char *link,
805 +                 struct lookup_intent *it)
806  {
807         int res = 0;
808         char *name;
809 @@ -1977,7 +2177,7 @@ __vfs_follow_link(struct nameidata *nd, 
810                         /* weird __emul_prefix() stuff did it */
811                         goto out;
812         }
813 -       res = link_path_walk(link, nd);
814 +       res = link_path_walk_it(link, nd, it);
815  out:
816         if (current->link_count || res || nd->last_type!=LAST_NORM)
817                 return res;
818 @@ -1999,7 +2199,13 @@ fail:
819  
820  int vfs_follow_link(struct nameidata *nd, const char *link)
821  {
822 -       return __vfs_follow_link(nd, link);
823 +       return __vfs_follow_link(nd, link, NULL);
824 +}
825 +
826 +int vfs_follow_link_it(struct nameidata *nd, const char *link,
827 +                      struct lookup_intent *it)
828 +{
829 +       return __vfs_follow_link(nd, link, it);
830  }
831  
832  /* get the link contents into pagecache */
833 @@ -2041,7 +2247,7 @@ int page_follow_link(struct dentry *dent
834  {
835         struct page *page = NULL;
836         char *s = page_getlink(dentry, &page);
837 -       int res = __vfs_follow_link(nd, s);
838 +       int res = __vfs_follow_link(nd, s, NULL);
839         if (page) {
840                 kunmap(page);
841                 page_cache_release(page);
842 --- linux-2.4.19-hp2_pnnl4/fs/nfsd/vfs.c~vfs_intent_hp  Sun Jan 19 19:04:47 2003
843 +++ linux-2.4.19-hp2_pnnl4-root/fs/nfsd/vfs.c   Sun Jan 19 19:37:57 2003
844 @@ -1295,7 +1295,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru
845                         err = nfserr_perm;
846         } else
847  #endif
848 -       err = vfs_rename(fdir, odentry, tdir, ndentry);
849 +       err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
850         if (!err && EX_ISSYNC(tfhp->fh_export)) {
851                 nfsd_sync_dir(tdentry);
852                 nfsd_sync_dir(fdentry);
853 --- linux-2.4.19-hp2_pnnl4/fs/open.c~vfs_intent_hp      Sun Jan 19 19:04:47 2003
854 +++ linux-2.4.19-hp2_pnnl4-root/fs/open.c       Sun Jan 19 19:41:00 2003
855 @@ -19,6 +19,8 @@
856  #include <asm/uaccess.h>
857  
858  #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
859 +extern int path_walk_it(const char *name, struct nameidata *nd,
860 +                       struct lookup_intent *it);
861  
862  int vfs_statfs(struct super_block *sb, struct statfs *buf)
863  {
864 @@ -95,9 +97,10 @@ void fd_install(unsigned int fd, struct 
865         write_unlock(&files->file_lock);
866  }
867  
868 -int do_truncate(struct dentry *dentry, loff_t length)
869 +int do_truncate(struct dentry *dentry, loff_t length, int called_from_open)
870  {
871         struct inode *inode = dentry->d_inode;
872 +       struct inode_operations *op = dentry->d_inode->i_op;
873         int error;
874         struct iattr newattrs;
875  
876 @@ -108,7 +111,14 @@ int do_truncate(struct dentry *dentry, l
877         down(&inode->i_sem);
878         newattrs.ia_size = length;
879         newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
880 -       error = notify_change(dentry, &newattrs);
881 +       if (called_from_open)
882 +               newattrs.ia_valid |= ATTR_FROM_OPEN;
883 +       if (op->setattr_raw) {
884 +               newattrs.ia_valid |= ATTR_RAW;
885 +               newattrs.ia_ctime = CURRENT_TIME;
886 +               error = op->setattr_raw(inode, &newattrs);
887 +       } else 
888 +               error = notify_change(dentry, &newattrs);
889         up(&inode->i_sem);
890         return error;
891  }
892 @@ -118,12 +121,13 @@ static inline long do_sys_truncate(const
893         struct nameidata nd;
894         struct inode * inode;
895         int error;
896 +       struct lookup_intent it = { .it_op = IT_GETATTR };
897  
898         error = -EINVAL;
899         if (length < 0) /* sorry, but loff_t says... */
900                 goto out;
901  
902 -       error = user_path_walk(path, &nd);
903 +       error = user_path_walk_it(path, &nd, &it);
904         if (error)
905                 goto out;
906         inode = nd.dentry->d_inode;
907 @@ -163,11 +167,13 @@ static inline long do_sys_truncate(const
908         error = locks_verify_truncate(inode, NULL, length);
909         if (!error) {
910                 DQUOT_INIT(inode);
911 -               error = do_truncate(nd.dentry, length);
912 +               intent_release(nd.dentry, &it);
913 +               error = do_truncate(nd.dentry, length, 0);
914         }
915         put_write_access(inode);
916  
917  dput_and_out:
918 +       intent_release(nd.dentry, &it);
919         path_release(&nd);
920  out:
921         return error;
922 @@ -215,7 +228,7 @@ static inline long do_sys_ftruncate(unsi
923  
924         error = locks_verify_truncate(inode, file, length);
925         if (!error)
926 -               error = do_truncate(dentry, length);
927 +               error = do_truncate(dentry, length, 0);
928  out_putf:
929         fput(file);
930  out:
931 @@ -260,11 +273,13 @@ asmlinkage long sys_utime(char * filenam
932         struct inode * inode;
933         struct iattr newattrs;
934  
935 -       error = user_path_walk(filename, &nd);
936 +       error = user_path_walk_it(filename, &nd, NULL);
937         if (error)
938                 goto out;
939         inode = nd.dentry->d_inode;
940  
941 +       /* this is safe without a Lustre lock because it only depends
942 +          on the super block */
943         error = -EROFS;
944         if (IS_RDONLY(inode))
945                 goto dput_and_out;
946 @@ -279,11 +294,29 @@ asmlinkage long sys_utime(char * filenam
947                         goto dput_and_out;
948  
949                 newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
950 -       } else {
951 +       }
952 +
953 +       if (inode->i_op->setattr_raw) {
954 +               struct inode_operations *op = nd.dentry->d_inode->i_op;
955 +
956 +               newattrs.ia_valid |= ATTR_RAW;
957 +               error = op->setattr_raw(inode, &newattrs);
958 +               /* the file system wants to use normal vfs path now */
959 +               if (error != -EOPNOTSUPP)
960 +                       goto dput_and_out;
961 +       }
962 +
963 +       error = -EROFS;
964 +       if (IS_RDONLY(inode))
965 +               goto dput_and_out;
966 +
967 +       error = -EPERM;
968 +       if (!times) {
969                 if (current->fsuid != inode->i_uid &&
970                     (error = permission(inode,MAY_WRITE)) != 0)
971                         goto dput_and_out;
972         }
973 +
974         error = notify_change(nd.dentry, &newattrs);
975  dput_and_out:
976         path_release(&nd);
977 @@ -304,12 +337,14 @@ asmlinkage long sys_utimes(char * filena
978         struct inode * inode;
979         struct iattr newattrs;
980  
981 -       error = user_path_walk(filename, &nd);
982 +       error = user_path_walk_it(filename, &nd, NULL);
983  
984         if (error)
985                 goto out;
986         inode = nd.dentry->d_inode;
987  
988 +       /* this is safe without a Lustre lock because it only depends
989 +          on the super block */
990         error = -EROFS;
991         if (IS_RDONLY(inode))
992                 goto dput_and_out;
993 @@ -324,7 +359,20 @@ asmlinkage long sys_utimes(char * filena
994                 newattrs.ia_atime = times[0].tv_sec;
995                 newattrs.ia_mtime = times[1].tv_sec;
996                 newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
997 -       } else {
998 +       }
999 +
1000 +       if (inode->i_op->setattr_raw) {
1001 +               struct inode_operations *op = nd.dentry->d_inode->i_op;
1002 +
1003 +               newattrs.ia_valid |= ATTR_RAW;
1004 +               error = op->setattr_raw(inode, &newattrs);
1005 +               /* the file system wants to use normal vfs path now */
1006 +               if (error != -EOPNOTSUPP)
1007 +                       goto dput_and_out;
1008 +       }
1009 +
1010 +       error = -EPERM;
1011 +       if (!utimes) {
1012                 if (current->fsuid != inode->i_uid &&
1013                     (error = permission(inode,MAY_WRITE)) != 0)
1014                         goto dput_and_out;
1015 @@ -347,6 +356,7 @@ asmlinkage long sys_access(const char * 
1016         int old_fsuid, old_fsgid;
1017         kernel_cap_t old_cap;
1018         int res;
1019 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1020  
1021         if (mode & ~S_IRWXO)    /* where's F_OK, X_OK, W_OK, R_OK? */
1022                 return -EINVAL;
1023 @@ -364,13 +374,14 @@ asmlinkage long sys_access(const char * 
1024         else
1025                 current->cap_effective = current->cap_permitted;
1026  
1027 -       res = user_path_walk(filename, &nd);
1028 +       res = user_path_walk_it(filename, &nd, &it);
1029         if (!res) {
1030                 res = permission(nd.dentry->d_inode, mode);
1031                 /* SuS v2 requires we report a read only fs too */
1032                 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
1033                    && !special_file(nd.dentry->d_inode->i_mode))
1034                         res = -EROFS;
1035 +               intent_release(nd.dentry, &it);
1036                 path_release(&nd);
1037         }
1038  
1039 @@ -386,6 +397,7 @@ asmlinkage long sys_chdir(const char * f
1040         int error;
1041         struct nameidata nd;
1042         char *name;
1043 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1044  
1045         name = getname(filename);
1046         error = PTR_ERR(name);
1047 @@ -394,7 +406,7 @@ asmlinkage long sys_chdir(const char * f
1048  
1049         error = 0;
1050         if (path_init(name,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd))
1051 -               error = path_walk(name, &nd);
1052 +               error = path_walk_it(name, &nd, &it);
1053         putname(name);
1054         if (error)
1055                 goto out;
1056 @@ -406,6 +418,7 @@ asmlinkage long sys_chdir(const char * f
1057         set_fs_pwd(current->fs, nd.mnt, nd.dentry);
1058  
1059  dput_and_out:
1060 +       intent_release(nd.dentry, &it);
1061         path_release(&nd);
1062  out:
1063         return error;
1064 @@ -446,6 +459,7 @@ asmlinkage long sys_chroot(const char * 
1065         int error;
1066         struct nameidata nd;
1067         char *name;
1068 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1069  
1070         name = getname(filename);
1071         error = PTR_ERR(name);
1072 @@ -454,7 +468,7 @@ asmlinkage long sys_chroot(const char * 
1073  
1074         path_init(name, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
1075                       LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
1076 -       error = path_walk(name, &nd);   
1077 +       error = path_walk_it(name, &nd, &it);
1078         putname(name);
1079         if (error)
1080                 goto out;
1081 @@ -471,6 +485,7 @@ asmlinkage long sys_chroot(const char * 
1082         set_fs_altroot();
1083         error = 0;
1084  dput_and_out:
1085 +       intent_release(nd.dentry, &it);
1086         path_release(&nd);
1087  out:
1088         return error;
1089 @@ -508,6 +564,18 @@ asmlinkage long sys_chmod(const char * f
1090         if (IS_RDONLY(inode))
1091                 goto dput_and_out;
1092  
1093 +       if (inode->i_op->setattr_raw) {
1094 +               struct inode_operations *op = nd.dentry->d_inode->i_op;
1095 +
1096 +               newattrs.ia_mode = mode;
1097 +               newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
1098 +               newattrs.ia_valid |= ATTR_RAW;
1099 +               error = op->setattr_raw(inode, &newattrs);
1100 +               /* the file system wants to use normal vfs path now */
1101 +               if (error != -EOPNOTSUPP)
1102 +                       goto dput_and_out;
1103 +       }
1104 +
1105         error = -EPERM;
1106         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
1107                 goto dput_and_out;
1108 @@ -538,6 +606,20 @@ static int chown_common(struct dentry * 
1109         error = -EROFS;
1110         if (IS_RDONLY(inode))
1111                 goto out;
1112 +
1113 +       if (inode->i_op->setattr_raw) {
1114 +               struct inode_operations *op = dentry->d_inode->i_op;
1115 +
1116 +               newattrs.ia_uid = user;
1117 +               newattrs.ia_gid = group;
1118 +               newattrs.ia_valid = ATTR_UID | ATTR_GID;
1119 +               newattrs.ia_valid |= ATTR_RAW;
1120 +               error = op->setattr_raw(inode, &newattrs);
1121 +               /* the file system wants to use normal vfs path now */
1122 +               if (error != -EOPNOTSUPP)
1123 +                       return error;
1124 +       }
1125 +
1126         error = -EPERM;
1127         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
1128                 goto out;
1129 @@ -655,10 +676,16 @@ asmlinkage long sys_fchown(unsigned int 
1130   * for the internal routines (ie open_namei()/follow_link() etc). 00 is
1131   * used by symlinks.
1132   */
1133 +extern int open_namei_it(const char *filename, int namei_flags, int mode,
1134 +                        struct nameidata *nd, struct lookup_intent *it);
1135 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1136 +                           int flags, struct lookup_intent *it);
1137 +
1138  struct file *filp_open(const char * filename, int flags, int mode)
1139  {
1140         int namei_flags, error;
1141         struct nameidata nd;
1142 +       struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = flags };
1143  
1144         namei_flags = flags;
1145         if ((namei_flags+1) & O_ACCMODE)
1146 @@ -666,14 +693,15 @@ struct file *filp_open(const char * file
1147         if (namei_flags & O_TRUNC)
1148                 namei_flags |= 2;
1149  
1150 -       error = open_namei(filename, namei_flags, mode, &nd);
1151 -       if (!error)
1152 -               return dentry_open(nd.dentry, nd.mnt, flags);
1153 +       error = open_namei_it(filename, namei_flags, mode, &nd, &it);
1154 +       if (error)
1155 +               return ERR_PTR(error);
1156  
1157 -       return ERR_PTR(error);
1158 +       return dentry_open_it(nd.dentry, nd.mnt, flags, &it);
1159  }
1160  
1161 -struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1162 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1163 +                           int flags, struct lookup_intent *it)
1164  {
1165         struct file * f;
1166         struct inode *inode;
1167 @@ -716,6 +744,7 @@ struct file *dentry_open(struct dentry *
1168         }
1169         f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
1170  
1171 +       intent_release(dentry, it);
1172         return f;
1173  
1174  cleanup_all:
1175 @@ -730,11 +759,17 @@ cleanup_all:
1176  cleanup_file:
1177         put_filp(f);
1178  cleanup_dentry:
1179 +       intent_release(dentry, it);
1180         dput(dentry);
1181         mntput(mnt);
1182         return ERR_PTR(error);
1183  }
1184  
1185 +struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1186 +{
1187 +       return dentry_open_it(dentry, mnt, flags, NULL);
1188 +}
1189 +
1190  /*
1191   * Find an empty file descriptor entry, and mark it busy.
1192   */
1193 --- linux-2.4.19-hp2_pnnl4/fs/stat.c~vfs_intent_hp      Sun Jan 19 19:04:47 2003
1194 +++ linux-2.4.19-hp2_pnnl4-root/fs/stat.c       Sun Jan 19 19:44:51 2003
1195 @@ -135,13 +136,15 @@ static int cp_new_stat(struct inode * in
1196  asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf)
1197  {
1198         struct nameidata nd;
1199 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1200         int error;
1201  
1202 -       error = user_path_walk(filename, &nd);
1203 +       error = user_path_walk_it(filename, &nd, &it);
1204         if (!error) {
1205                 error = do_revalidate(nd.dentry);
1206                 if (!error)
1207                         error = cp_old_stat(nd.dentry->d_inode, statbuf);
1208 +               intent_release(nd.dentry, &it);
1209                 path_release(&nd);
1210         }
1211         return error;
1212 @@ -151,13 +154,15 @@ asmlinkage long sys_stat(char * filename
1213  asmlinkage long sys_newstat(char * filename, struct stat * statbuf)
1214  {
1215         struct nameidata nd;
1216 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1217         int error;
1218  
1219 -       error = user_path_walk(filename, &nd);
1220 +       error = user_path_walk_it(filename, &nd, &it);
1221         if (!error) {
1222                 error = do_revalidate(nd.dentry);
1223                 if (!error)
1224                         error = cp_new_stat(nd.dentry->d_inode, statbuf);
1225 +               intent_release(nd.dentry, &it);
1226                 path_release(&nd);
1227         }
1228         return error;
1229 @@ -172,13 +177,15 @@ asmlinkage long sys_newstat(char * filen
1230  asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf)
1231  {
1232         struct nameidata nd;
1233 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1234         int error;
1235  
1236 -       error = user_path_walk_link(filename, &nd);
1237 +       error = user_path_walk_link_it(filename, &nd, &it);
1238         if (!error) {
1239                 error = do_revalidate(nd.dentry);
1240                 if (!error)
1241                         error = cp_old_stat(nd.dentry->d_inode, statbuf);
1242 +               intent_release(nd.dentry, &it);
1243                 path_release(&nd);
1244         }
1245         return error;
1246 @@ -189,13 +196,15 @@ asmlinkage long sys_lstat(char * filenam
1247  asmlinkage long sys_newlstat(char * filename, struct stat * statbuf)
1248  {
1249         struct nameidata nd;
1250 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1251         int error;
1252  
1253 -       error = user_path_walk_link(filename, &nd);
1254 +       error = user_path_walk_link_it(filename, &nd, &it);
1255         if (!error) {
1256                 error = do_revalidate(nd.dentry);
1257                 if (!error)
1258                         error = cp_new_stat(nd.dentry->d_inode, statbuf);
1259 +               intent_release(nd.dentry, &it);
1260                 path_release(&nd);
1261         }
1262         return error;
1263 @@ -333,12 +344,14 @@ asmlinkage long sys_stat64(char * filena
1264  {
1265         struct nameidata nd;
1266         int error;
1267 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1268  
1269 -       error = user_path_walk(filename, &nd);
1270 +       error = user_path_walk_it(filename, &nd, &it);
1271         if (!error) {
1272                 error = do_revalidate(nd.dentry);
1273                 if (!error)
1274                         error = cp_new_stat64(nd.dentry->d_inode, statbuf);
1275 +               intent_release(nd.dentry, &it);
1276                 path_release(&nd);
1277         }
1278         return error;
1279 @@ -348,12 +361,14 @@ asmlinkage long sys_lstat64(char * filen
1280  {
1281         struct nameidata nd;
1282         int error;
1283 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1284  
1285 -       error = user_path_walk_link(filename, &nd);
1286 +       error = user_path_walk_link_it(filename, &nd, &it);
1287         if (!error) {
1288                 error = do_revalidate(nd.dentry);
1289                 if (!error)
1290                         error = cp_new_stat64(nd.dentry->d_inode, statbuf);
1291 +               intent_release(nd.dentry, &it);
1292                 path_release(&nd);
1293         }
1294         return error;
1295 --- linux-2.4.19-hp2_pnnl4/fs/exec.c~vfs_intent_hp      Sun Feb  9 01:14:52 2003
1296 +++ linux-2.4.19-hp2_pnnl4-root/fs/exec.c       Sun Feb  9 01:29:49 2003
1297 @@ -103,13 +104,18 @@ static inline void put_binfmt(struct lin
1298   *
1299   * Also note that we take the address to load from from the file itself.
1300   */
1301 +extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1302 +                           int flags, struct lookup_intent *it);
1303 +int path_lookup_it(const char *path, unsigned flags, struct nameidata *nd,
1304 +                  struct lookup_intent *it);
1305  asmlinkage long sys_uselib(const char * library)
1306  {
1307         struct file * file;
1308         struct nameidata nd;
1309         int error;
1310 +       struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY };
1311  
1312 -       error = user_path_walk(library, &nd);
1313 +       error = user_path_walk_it(library, &nd, &it);
1314         if (error)
1315                 goto out;
1316  
1317 @@ -121,7 +127,8 @@ asmlinkage long sys_uselib(const char * 
1318         if (error)
1319                 goto exit;
1320  
1321 -       file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
1322 +       file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &it);
1323 +       intent_release(nd.dentry, &it);
1324         error = PTR_ERR(file);
1325         if (IS_ERR(file))
1326                 goto out;
1327 @@ -350,9 +350,10 @@ struct file *open_exec(const char *name)
1328         struct inode *inode;
1329         struct file *file;
1330         int err = 0;
1331 +       struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY };
1332  
1333         if (path_init(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd))
1334 -               err = path_walk(name, &nd);
1335 +               err = path_walk_it(name, &nd, &it);
1336         file = ERR_PTR(err);
1337         if (!err) {
1338                 inode = nd.dentry->d_inode;
1339 @@ -363,7 +369,8 @@ struct file *open_exec(const char *name)
1340                                 err = -EACCES;
1341                         file = ERR_PTR(err);
1342                         if (!err) {
1343 -                               file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
1344 +                               file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &it);
1345 +                               intent_release(nd.dentry, &it);
1346                                 if (!IS_ERR(file)) {
1347                                         err = deny_write_access(file);
1348                                         if (err) {
1349 @@ -976,7 +986,7 @@ int do_coredump(long signr, struct pt_re
1350                 goto close_fail;
1351         if (!file->f_op->write)
1352                 goto close_fail;
1353 -       if (do_truncate(file->f_dentry, 0) != 0)
1354 +       if (do_truncate(file->f_dentry, 0, 0) != 0)
1355                 goto close_fail;
1356  
1357         retval = binfmt->core_dump(signr, regs, file);
1358 --- linux-2.4.19-hp2_pnnl4/include/linux/dcache.h~vfs_intent_hp Sun Jan 19 19:04:47 2003
1359 +++ linux-2.4.19-hp2_pnnl4-root/include/linux/dcache.h  Sun Jan 19 19:04:48 2003
1360 @@ -6,6 +6,25 @@
1361  #include <asm/atomic.h>
1362  #include <linux/mount.h>
1363  
1364 +#define IT_OPEN     (1)
1365 +#define IT_CREAT    (1<<1)
1366 +#define IT_READDIR  (1<<2)
1367 +#define IT_GETATTR  (1<<3)
1368 +#define IT_LOOKUP   (1<<4)
1369 +#define IT_UNLINK   (1<<5)
1370 +
1371 +struct lookup_intent {
1372 +       int it_op;
1373 +       int it_mode;
1374 +       int it_flags;
1375 +       int it_disposition;
1376 +       int it_status;
1377 +       struct iattr *it_iattr;
1378 +       __u64 it_lock_handle[2];
1379 +       int it_lock_mode;
1380 +       void *it_data;
1381 +};
1382 +
1383  /*
1384   * linux/include/linux/dcache.h
1385   *
1386 @@ -78,6 +106,7 @@ struct dentry {
1387         unsigned long d_time;           /* used by d_revalidate */
1388         struct dentry_operations  *d_op;
1389         struct super_block * d_sb;      /* The root of the dentry tree */
1390 +       struct lookup_intent *d_it;
1391         unsigned long d_vfs_flags;
1392         void * d_fsdata;                /* fs-specific data */
1393         unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
1394 @@ -90,8 +119,15 @@ struct dentry_operations {
1395         int (*d_delete)(struct dentry *);
1396         void (*d_release)(struct dentry *);
1397         void (*d_iput)(struct dentry *, struct inode *);
1398 +       int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
1399 +       void (*d_intent_release)(struct dentry *, struct lookup_intent *);
1400  };
1401  
1402 +/* defined in fs/namei.c */
1403 +extern void intent_release(struct dentry *de, struct lookup_intent *it);
1404 +/* defined in fs/dcache.c */
1405 +extern void __d_rehash(struct dentry * entry, int lock);
1406 +
1407  /* the dentry parameter passed to d_hash and d_compare is the parent
1408   * directory of the entries to be compared. It is used in case these
1409   * functions need any directory specific information for determining
1410 @@ -124,6 +149,7 @@ d_iput:             no              no              yes
1411                                          * s_nfsd_free_path semaphore will be down
1412                                          */
1413  #define DCACHE_REFERENCED      0x0008  /* Recently used, don't discard. */
1414 +#define DCACHE_LUSTRE_INVALID  0x0010  /* Lustre invalidated */
1415  
1416  extern spinlock_t dcache_lock;
1417  
1418 --- linux-2.4.19-hp2_pnnl4/include/linux/fs.h~vfs_intent_hp     Sun Jan 19 19:04:47 2003
1419 +++ linux-2.4.19-hp2_pnnl4-root/include/linux/fs.h      Sun Jan 19 19:04:48 2003
1420 @@ -338,6 +338,8 @@ extern void set_bh_page(struct buffer_he
1421  #define ATTR_MTIME_SET 256
1422  #define ATTR_FORCE     512     /* Not a change, but a change it */
1423  #define ATTR_ATTR_FLAG 1024
1424 +#define ATTR_RAW       2048    /* file system, not vfs will massage attrs */
1425 +#define ATTR_FROM_OPEN 4096    /* called from open path, ie O_TRUNC */
1426  
1427  /*
1428   * This is the Inode Attributes structure, used for notify_change().  It
1429 @@ -575,6 +575,7 @@ struct file {
1430  
1431         /* needed for tty driver, and maybe others */
1432         void                    *private_data;
1433 +       struct lookup_intent    *f_intent;
1434  
1435         /* preallocated helper kiobuf to speedup O_DIRECT */
1436         struct kiobuf           *f_iobuf;
1437 @@ -815,7 +816,9 @@ extern int vfs_symlink(struct inode *, s
1438  extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
1439  extern int vfs_rmdir(struct inode *, struct dentry *);
1440  extern int vfs_unlink(struct inode *, struct dentry *);
1441 -extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
1442 +int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1443 +               struct inode *new_dir, struct dentry *new_dentry,
1444 +               struct lookup_intent *it);
1445  
1446  /*
1447   * File types
1448 @@ -876,20 +879,33 @@ struct file_operations {
1449  struct inode_operations {
1450         int (*create) (struct inode *,struct dentry *,int);
1451         struct dentry * (*lookup) (struct inode *,struct dentry *);
1452 +       struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *);
1453         int (*link) (struct dentry *,struct inode *,struct dentry *);
1454 +       int (*link2) (struct inode *,struct inode *, const char *, int);
1455         int (*unlink) (struct inode *,struct dentry *);
1456 +       int (*unlink2) (struct inode *, const char *, int);
1457         int (*symlink) (struct inode *,struct dentry *,const char *);
1458 +       int (*symlink2) (struct inode *, const char *, int, const char *);
1459         int (*mkdir) (struct inode *,struct dentry *,int);
1460 +       int (*mkdir2) (struct inode *, const char *, int,int);
1461         int (*rmdir) (struct inode *,struct dentry *);
1462 +       int (*rmdir2) (struct inode *, const char *, int);
1463         int (*mknod) (struct inode *,struct dentry *,int,int);
1464 +       int (*mknod2) (struct inode *, const char *, int,int,int);
1465         int (*rename) (struct inode *, struct dentry *,
1466                         struct inode *, struct dentry *);
1467 +       int (*rename2) (struct inode *, struct inode *,
1468 +                       const char *oldname, int oldlen,
1469 +                       const char *newname, int newlen);
1470         int (*readlink) (struct dentry *, char *,int);
1471         int (*follow_link) (struct dentry *, struct nameidata *);
1472 +       int (*follow_link2) (struct dentry *, struct nameidata *,
1473 +                            struct lookup_intent *it);
1474         void (*truncate) (struct inode *);
1475         int (*permission) (struct inode *, int);
1476         int (*revalidate) (struct dentry *);
1477         int (*setattr) (struct dentry *, struct iattr *);
1478 +       int (*setattr_raw) (struct inode *, struct iattr *);
1479         int (*getattr) (struct dentry *, struct iattr *);
1480         int (*setxattr) (struct dentry *, const char *, void *, size_t, int);
1481         ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
1482 @@ -1112,7 +1130,7 @@ static inline int get_lease(struct inode
1483  
1484  asmlinkage long sys_open(const char *, int, int);
1485  asmlinkage long sys_close(unsigned int);       /* yes, it's really unsigned */
1486 -extern int do_truncate(struct dentry *, loff_t start);
1487 +extern int do_truncate(struct dentry *, loff_t start, int called_from_open);
1488  
1489  extern struct file *filp_open(const char *, int, int);
1490  extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
1491 @@ -1354,6 +1369,7 @@ typedef int (*read_actor_t)(read_descrip
1492  extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
1493  
1494  extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
1495 +extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
1496  extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
1497  extern int FASTCALL(path_walk(const char *, struct nameidata *));
1498  extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
1499 @@ -1364,6 +1380,8 @@ extern struct dentry * lookup_one_len(co
1500  extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
1501  #define user_path_walk(name,nd)         __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
1502  #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
1503 +#define user_path_walk_it(name,nd,it)  __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
1504 +#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
1505  
1506  extern void inode_init_once(struct inode *);
1507  extern void iput(struct inode *);
1508 @@ -1499,6 +1517,8 @@ extern struct file_operations generic_ro
1509  
1510  extern int vfs_readlink(struct dentry *, char *, int, const char *);
1511  extern int vfs_follow_link(struct nameidata *, const char *);
1512 +extern int vfs_follow_link_it(struct nameidata *, const char *,
1513 +                             struct lookup_intent *it);
1514  extern int page_readlink(struct dentry *, char *, int);
1515  extern int page_follow_link(struct dentry *, struct nameidata *);
1516  extern struct inode_operations page_symlink_inode_operations;
1517 --- linux-2.4.19-hp2_pnnl4/kernel/ksyms.c~vfs_intent_hp Sun Jan 19 19:04:47 2003
1518 +++ linux-2.4.19-hp2_pnnl4-root/kernel/ksyms.c  Sun Jan 19 19:04:48 2003
1519 @@ -293,6 +293,7 @@ EXPORT_SYMBOL(read_cache_page);
1520  EXPORT_SYMBOL(set_page_dirty);
1521  EXPORT_SYMBOL(vfs_readlink);
1522  EXPORT_SYMBOL(vfs_follow_link);
1523 +EXPORT_SYMBOL(vfs_follow_link_it);
1524  EXPORT_SYMBOL(page_readlink);
1525  EXPORT_SYMBOL(page_follow_link);
1526  EXPORT_SYMBOL(page_symlink_inode_operations);