Whamcloud - gitweb
r=adilger
[fs/lustre-release.git] / lustre / kernel_patches / patches / vfs_intent-2.6-suse.patch
1 Index: linux-2.6.5-12.1/fs/exec.c
2 ===================================================================
3 --- linux-2.6.5-12.1.orig/fs/exec.c     2004-05-10 12:21:56.000000000 -0400
4 +++ linux-2.6.5-12.1/fs/exec.c  2004-06-03 18:31:28.000000000 -0400
5 @@ -125,9 +125,10 @@
6         struct nameidata nd;
7         int error;
8  
9 -       nd.intent.open.flags = FMODE_READ;
10 +       intent_init(&nd.intent, IT_OPEN);
11  
12 -       FSHOOK_BEGIN_USER_WALK(open,
13 +       nd.intent.it_flags = FMODE_READ|FMODE_EXEC;
14 +       FSHOOK_BEGIN_USER_WALK_IT(open,
15                 error,
16                 library,
17                 LOOKUP_FOLLOW|LOOKUP_OPEN,
18 @@ -144,7 +145,7 @@
19                 goto out;
20         }
21  
22 -       file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
23 +       file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &nd.intent);
24         error = PTR_ERR(file);
25         if (IS_ERR(file))
26                 goto out;
27 @@ -495,8 +496,9 @@
28  
29         FSHOOK_BEGIN(open, err, .filename = name, .flags = O_RDONLY)
30  
31 -       nd.intent.open.flags = FMODE_READ;
32 -       err = path_lookup(name, LOOKUP_FOLLOW|LOOKUP_OPEN, &nd);
33 +       intent_init(&nd.intent, IT_OPEN);
34 +       nd.intent.it_flags = FMODE_READ|FMODE_EXEC;
35 +       err = path_lookup(name, LOOKUP_FOLLOW, &nd);
36         file = ERR_PTR(err);
37  
38         if (!err) {
39 @@ -509,7 +511,7 @@
40                                 err = -EACCES;
41                         file = ERR_PTR(err);
42                         if (!err) {
43 -                               file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
44 +                               file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &nd.intent);
45                                 if (!IS_ERR(file)) {
46                                         err = deny_write_access(file);
47                                         if (err) {
48 Index: linux-2.6.5-12.1/fs/namei.c
49 ===================================================================
50 --- linux-2.6.5-12.1.orig/fs/namei.c    2004-05-10 12:21:56.000000000 -0400
51 +++ linux-2.6.5-12.1/fs/namei.c 2004-06-03 18:42:17.000000000 -0400
52 @@ -270,8 +270,19 @@
53         return 0;
54  }
55  
56 +void intent_release(struct lookup_intent *it)
57 +{
58 +       if (!it)
59 +               return;
60 +       if (it->it_magic != INTENT_MAGIC)
61 +               return;
62 +       if (it->it_op_release)
63 +               it->it_op_release(it);
64 +}
65 +
66  void path_release(struct nameidata *nd)
67  {
68 +       intent_release(&nd->intent);
69         dput(nd->dentry);
70         mntput(nd->mnt);
71  }
72 @@ -348,7 +359,10 @@
73  {
74         struct dentry * result;
75         struct inode *dir = parent->d_inode;
76 +       int counter = 0;
77  
78 +again:
79 +       counter++;
80         down(&dir->i_sem);
81         /*
82          * First re-do the cached lookup just in case it was created
83 @@ -387,7 +401,10 @@
84         if (result->d_op && result->d_op->d_revalidate) {
85                 if (!result->d_op->d_revalidate(result, nd) && !d_invalidate(result)) {
86                         dput(result);
87 -                       result = ERR_PTR(-ENOENT);
88 +                       if (counter > 10)
89 +                               result = ERR_PTR(-ESTALE);
90 +                       if (!IS_ERR(result))
91 +                               goto again;
92                 }
93         }
94         return result;
95 @@ -564,6 +581,33 @@
96         return PTR_ERR(dentry);
97  }
98  
99 +static int revalidate_special(struct nameidata *nd)
100 +{
101 +       struct dentry *dentry = nd->dentry;
102 +       int err, counter = 0;
103 +
104 + revalidate_again:
105 +       if (!dentry->d_op || !dentry->d_op->d_revalidate)
106 +               return 0;
107 +       if (!dentry->d_op->d_revalidate(dentry, nd)) {
108 +               struct dentry *new;
109 +               if ((err = permission(dentry->d_parent->d_inode, MAY_EXEC,nd)))
110 +                       return err;
111 +               new = real_lookup(dentry->d_parent, &dentry->d_name, nd);
112 +               if (IS_ERR(new))
113 +                       return PTR_ERR(new);
114 +               d_invalidate(dentry);
115 +               dput(dentry);
116 +               nd->dentry = dentry = new;
117 +               counter++;
118 +               if (counter < 10)
119 +                       goto revalidate_again;
120 +               printk("excessive revalidate_it loops\n");
121 +               return -ESTALE;
122 +       }
123 +       return 0;
124 +}
125 +
126  /*
127   * Name resolution.
128   *
129 @@ -664,7 +708,9 @@
130  
131                 if (inode->i_op->follow_link) {
132                         mntget(next.mnt);
133 +                       nd->flags |= LOOKUP_LINK_NOTLAST;
134                         err = do_follow_link(next.dentry, nd);
135 +                       nd->flags &= ~LOOKUP_LINK_NOTLAST;
136                         dput(next.dentry);
137                         mntput(next.mnt);
138                         if (err)
139 @@ -703,14 +749,34 @@
140                                 inode = nd->dentry->d_inode;
141                                 /* fallthrough */
142                         case 1:
143 +                               nd->flags |= LOOKUP_LAST;
144 +                               err = revalidate_special(nd);
145 +                               nd->flags &= ~LOOKUP_LAST;
146 +                               if (!nd->dentry->d_inode)
147 +                                       err = -ENOENT;
148 +                               if (err) {
149 +                                       path_release(nd);
150 +                                       goto return_err;
151 +                               }
152 +                               if (lookup_flags & LOOKUP_DIRECTORY) {
153 +                                       err = -ENOTDIR;
154 +                                       if(!nd->dentry->d_inode->i_op ||
155 +                                         !nd->dentry->d_inode->i_op->lookup) {
156 +                                               path_release(nd);
157 +                                               goto return_err;
158 +                                       }
159 +                               }
160                                 goto return_reval;
161                 }
162 +
163                 if (nd->dentry->d_op && nd->dentry->d_op->d_hash) {
164                         err = nd->dentry->d_op->d_hash(nd->dentry, &this);
165                         if (err < 0)
166                                 break;
167                 }
168 +               nd->flags |= LOOKUP_LAST;
169                 err = do_lookup(nd, &this, &next);
170 +               nd->flags &= ~LOOKUP_LAST;
171                 if (err)
172                         break;
173                 follow_mount(&next.mnt, &next.dentry);
174 @@ -936,7 +992,7 @@
175  }
176  
177  /* SMP-safe */
178 -struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
179 +struct dentry * lookup_one_len_it(const char * name, struct dentry * base, int len, struct nameidata *nd)
180  {
181         unsigned long hash;
182         struct qstr this;
183 @@ -956,11 +1012,16 @@
184         }
185         this.hash = end_name_hash(hash);
186  
187 -       return lookup_hash(&this, base);
188 +       return __lookup_hash(&this, base, nd);
189  access:
190         return ERR_PTR(-EACCES);
191  }
192  
193 +struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
194 +{
195 +       return lookup_one_len_it(name, base, len, NULL);
196 +}
197 +
198  /*
199   *     namei()
200   *
201 @@ -972,7 +1033,8 @@
202   * that namei follows links, while lnamei does not.
203   * SMP-safe
204   */
205 -int fastcall __user_walk(const char __user *name, unsigned flags, struct nameidata *nd, const char **pname)
206 +int fastcall __user_walk_it(const char __user *name, unsigned flags,
207 +                           struct nameidata *nd, const char **pname)
208  {
209         char *tmp = getname(name);
210         int err = PTR_ERR(tmp);
211 @@ -987,6 +1049,13 @@
212         return err;
213  }
214  
215 +int fastcall __user_walk(const char __user *name, unsigned flags,
216 +                        struct nameidata *nd, const char **pname)
217 +{
218 +       intent_init(&nd->intent, IT_LOOKUP);
219 +       return __user_walk_it(name, flags, nd, pname);
220 +}
221 +
222  /*
223   * It's inline, so penalty for filesystems that don't use sticky bit is
224   * minimal.
225 @@ -1259,8 +1328,8 @@
226                 acc_mode |= MAY_APPEND;
227  
228         /* Fill in the open() intent data */
229 -       nd->intent.open.flags = flag;
230 -       nd->intent.open.create_mode = mode;
231 +       nd->intent.it_flags = flag;
232 +       nd->intent.it_create_mode = mode;
233  
234         /*
235          * The simplest case - just a plain lookup.
236 @@ -1275,6 +1344,7 @@
237         /*
238          * Create - we need to know the parent.
239          */
240 +       nd->intent.it_op |= IT_CREAT;
241         error = path_lookup(pathname, LOOKUP_PARENT|LOOKUP_OPEN|LOOKUP_CREATE, nd);
242         if (error)
243                 return error;
244 @@ -1291,7 +1361,9 @@
245         dir = nd->dentry;
246         nd->flags &= ~LOOKUP_PARENT;
247         down(&dir->d_inode->i_sem);
248 +       nd->flags |= LOOKUP_LAST;
249         dentry = __lookup_hash(&nd->last, nd->dentry, nd);
250 +       nd->flags &= ~LOOKUP_LAST;
251  
252  do_last:
253         error = PTR_ERR(dentry);
254 @@ -1396,7 +1468,9 @@
255         }
256         dir = nd->dentry;
257         down(&dir->d_inode->i_sem);
258 +       nd->flags |= LOOKUP_LAST;
259         dentry = __lookup_hash(&nd->last, nd->dentry, nd);
260 +       nd->flags &= ~LOOKUP_LAST;
261         putname(nd->last.name);
262         goto do_last;
263  }
264 @@ -2196,7 +2270,9 @@
265  __vfs_follow_link(struct nameidata *nd, const char *link)
266  {
267         int res = 0;
268 +       struct lookup_intent it = nd->intent;
269         char *name;
270 +
271         if (IS_ERR(link))
272                 goto fail;
273  
274 @@ -2206,6 +2282,10 @@
275                         /* weird __emul_prefix() stuff did it */
276                         goto out;
277         }
278 +
279 +       intent_init(&nd->intent, it.it_op);
280 +       nd->intent.it_flags = it.it_flags;
281 +       nd->intent.it_create_mode = it.it_create_mode;
282         res = link_path_walk(link, nd);
283  out:
284         if (current->link_count || res || nd->last_type!=LAST_NORM)
285 Index: linux-2.6.5-12.1/fs/namespace.c
286 ===================================================================
287 --- linux-2.6.5-12.1.orig/fs/namespace.c        2004-05-10 12:21:56.000000000 -0400
288 +++ linux-2.6.5-12.1/fs/namespace.c     2004-06-03 18:31:28.000000000 -0400
289 @@ -108,6 +108,7 @@
290  
291  static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd)
292  {
293 +       memset(old_nd, 0, sizeof(*old_nd));
294         old_nd->dentry = mnt->mnt_mountpoint;
295         old_nd->mnt = mnt->mnt_parent;
296         mnt->mnt_parent = mnt;
297 @@ -533,6 +534,8 @@
298                 return err;
299         if (!old_name || !*old_name)
300                 return -EINVAL;
301 +
302 +       intent_init(&old_nd.intent, IT_LOOKUP);
303         err = path_lookup(old_name, LOOKUP_FOLLOW, &old_nd);
304         if (err)
305                 return err;
306 @@ -601,6 +604,7 @@
307                 return -EPERM;
308         if (!old_name || !*old_name)
309                 return -EINVAL;
310 +       intent_init(&old_nd.intent, IT_LOOKUP);
311         err = path_lookup(old_name, LOOKUP_FOLLOW, &old_nd);
312         if (err)
313                 return err;
314 @@ -750,6 +754,7 @@
315         int retval = 0;
316         int mnt_flags = 0;
317  
318 +       intent_init(&nd.intent, IT_LOOKUP);
319         /* Discard magic */
320         if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
321                 flags &= ~MS_MGC_MSK;
322 Index: linux-2.6.5-12.1/fs/open.c
323 ===================================================================
324 --- linux-2.6.5-12.1.orig/fs/open.c     2004-05-10 12:21:56.000000000 -0400
325 +++ linux-2.6.5-12.1/fs/open.c  2004-06-03 18:31:28.000000000 -0400
326 @@ -227,12 +227,12 @@
327         struct nameidata nd;
328         struct inode * inode;
329         int error;
330 -
331 +       intent_init(&nd.intent, IT_GETATTR);
332         error = -EINVAL;
333         if (length < 0) /* sorry, but loff_t says... */
334                 goto out;
335  
336 -       FSHOOK_BEGIN_USER_PATH_WALK(truncate, error, path, nd, filename, .length = length)
337 +       FSHOOK_BEGIN_USER_PATH_WALK_IT(truncate, error, path, nd, filename, .length = length)
338  
339         inode = nd.dentry->d_inode;
340  
341 @@ -466,6 +466,7 @@
342         int old_fsuid, old_fsgid;
343         kernel_cap_t old_cap;
344         int res;
345 +       intent_init(&nd.intent, IT_GETATTR);
346  
347         if (mode & ~S_IRWXO)    /* where's F_OK, X_OK, W_OK, R_OK? */
348                 return -EINVAL;
349 @@ -490,7 +491,7 @@
350         else
351                 current->cap_effective = current->cap_permitted;
352  
353 -       FSHOOK_BEGIN_USER_WALK(access,
354 +       FSHOOK_BEGIN_USER_WALK_IT(access,
355                 res,
356                 filename,
357                 LOOKUP_FOLLOW|LOOKUP_ACCESS,
358 @@ -506,6 +507,7 @@
359                 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
360                    && !special_file(nd.dentry->d_inode->i_mode))
361                         res = -EROFS;
362 +
363                 path_release(&nd);
364  
365         FSHOOK_END_USER_WALK(access, res, path)
366 @@ -545,11 +547,13 @@
367  
368  asmlinkage long sys_fchdir(unsigned int fd)
369  {
370 +       struct nameidata nd;
371         struct file *file;
372         struct dentry *dentry;
373         struct inode *inode;
374         struct vfsmount *mnt;
375         int error;
376 +       intent_init(&nd.intent, IT_GETATTR);
377  
378         FSHOOK_BEGIN(fchdir, error, .fd = fd)
379  
380 @@ -582,8 +586,9 @@
381  {
382         struct nameidata nd;
383         int error;
384 +       intent_init(&nd.intent, IT_GETATTR);
385  
386 -       FSHOOK_BEGIN_USER_WALK(chroot,
387 +       FSHOOK_BEGIN_USER_WALK_IT(chroot,
388                 error,
389                 filename,
390                 LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT,
391 @@ -670,7 +675,7 @@
392         error = -EROFS;
393         if (IS_RDONLY(inode))
394                 goto dput_and_out;
395 -
396 +       
397         error = -EPERM;
398         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
399                 goto dput_and_out;
400 @@ -804,27 +809,8 @@
401   * for the internal routines (ie open_namei()/follow_link() etc). 00 is
402   * used by symlinks.
403   */
404 -struct file *filp_open(const char * filename, int flags, int mode)
405 -{
406 -       int namei_flags, error;
407 -       struct nameidata nd;
408 -
409 -       namei_flags = flags;
410 -       if ((namei_flags+1) & O_ACCMODE)
411 -               namei_flags++;
412 -       if (namei_flags & O_TRUNC)
413 -               namei_flags |= 2;
414 -
415 -       error = open_namei(filename, namei_flags, mode, &nd);
416 -       if (!error)
417 -               return dentry_open(nd.dentry, nd.mnt, flags);
418 -
419 -       return ERR_PTR(error);
420 -}
421 -
422 -EXPORT_SYMBOL(filp_open);
423 -
424 -struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
425 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, int flags,
426 +                           struct lookup_intent *it)
427  {
428         struct file * f;
429         struct inode *inode;
430 @@ -836,6 +822,7 @@
431                 goto cleanup_dentry;
432         f->f_flags = flags;
433         f->f_mode = (flags+1) & O_ACCMODE;
434 +       f->f_it = it;
435         inode = dentry->d_inode;
436         if (f->f_mode & FMODE_WRITE) {
437                 error = get_write_access(inode);
438 @@ -855,6 +842,7 @@
439                 error = f->f_op->open(inode,f);
440                 if (error)
441                         goto cleanup_all;
442 +               intent_release(it);
443         }
444         f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
445  
446 @@ -879,6 +867,7 @@
447  cleanup_file:
448         put_filp(f);
449  cleanup_dentry:
450 +       intent_release(it);
451         dput(dentry);
452         mntput(mnt);
453         return ERR_PTR(error);
454 @@ -886,6 +875,36 @@
455  
456  EXPORT_SYMBOL(dentry_open);
457  
458 +struct file *filp_open(const char * filename, int flags, int mode)
459 +{
460 +       int namei_flags, error;
461 +       struct file * temp_filp;
462 +       struct nameidata nd;
463 +       intent_init(&nd.intent, IT_OPEN);
464 +
465 +       namei_flags = flags;
466 +       if ((namei_flags+1) & O_ACCMODE)
467 +               namei_flags++;
468 +       if (namei_flags & O_TRUNC)
469 +               namei_flags |= 2;
470 +
471 +       error = open_namei(filename, namei_flags, mode, &nd);
472 +       if (!error) {
473 +               temp_filp = dentry_open_it(nd.dentry, nd.mnt, flags, &nd.intent);
474 +               return temp_filp;
475 +       }       
476 +       return ERR_PTR(error);
477 +}
478 +
479 +
480 +struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
481 +{
482 +       struct lookup_intent it;
483 +       intent_init(&it, IT_LOOKUP);
484 +
485 +       return dentry_open_it(dentry, mnt, flags, &it);
486 +}
487 +
488  /*
489   * Find an empty file descriptor entry, and mark it busy.
490   */
491 Index: linux-2.6.5-12.1/fs/stat.c
492 ===================================================================
493 --- linux-2.6.5-12.1.orig/fs/stat.c     2004-05-10 12:21:56.000000000 -0400
494 +++ linux-2.6.5-12.1/fs/stat.c  2004-06-03 18:31:28.000000000 -0400
495 @@ -37,7 +37,7 @@
496  
497  EXPORT_SYMBOL(generic_fillattr);
498  
499 -int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
500 +int vfs_getattr_it(struct vfsmount *mnt, struct dentry *dentry, struct lookup_intent *it, struct kstat *stat)
501  {
502         struct inode *inode = dentry->d_inode;
503         int retval;
504 @@ -46,6 +46,8 @@
505         if (retval)
506                 return retval;
507  
508 +       if (inode->i_op->getattr_it)
509 +               return inode->i_op->getattr_it(mnt, dentry, it, stat);
510         if (inode->i_op->getattr)
511                 return inode->i_op->getattr(mnt, dentry, stat);
512  
513 @@ -62,14 +64,20 @@
514  
515  EXPORT_SYMBOL(vfs_getattr);
516  
517 +int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
518 +{
519 +       return vfs_getattr_it(mnt, dentry, NULL, stat);
520 +}
521 +
522  int vfs_stat(char __user *name, struct kstat *stat)
523  {
524         struct nameidata nd;
525         int error;
526 +       intent_init(&nd.intent, IT_GETATTR);
527  
528 -       FSHOOK_BEGIN_USER_PATH_WALK(stat, error, name, nd, path, .link = false)
529 +       FSHOOK_BEGIN_USER_PATH_WALK_IT(stat, error, name, nd, path, .link = false)
530  
531 -               error = vfs_getattr(nd.mnt, nd.dentry, stat);
532 +               error = vfs_getattr_it(nd.mnt, nd.dentry, &nd.intent, stat);
533                 path_release(&nd);
534  
535         FSHOOK_END_USER_WALK(stat, error, path)
536 @@ -83,10 +91,11 @@
537  {
538         struct nameidata nd;
539         int error;
540 +       intent_init(&nd.intent, IT_GETATTR);
541  
542 -       FSHOOK_BEGIN_USER_PATH_WALK_LINK(stat, error, name, nd, path, .link = true)
543 +       FSHOOK_BEGIN_USER_PATH_WALK_LINK_IT(stat, error, name, nd, path, .link = true)
544  
545 -               error = vfs_getattr(nd.mnt, nd.dentry, stat);
546 +               error = vfs_getattr_it(nd.mnt, nd.dentry, &nd.intent, stat);
547                 path_release(&nd);
548  
549         FSHOOK_END_USER_WALK(stat, error, path)
550 @@ -99,6 +108,8 @@
551  int vfs_fstat(unsigned int fd, struct kstat *stat)
552  {
553         int error;
554 +       struct nameidata nd;
555 +       intent_init(&nd.intent, IT_GETATTR);
556  
557         FSHOOK_BEGIN(fstat, error, .fd = fd)
558  
559 @@ -106,7 +117,8 @@
560  
561         error = -EBADF;
562         if (f) {
563 -               error = vfs_getattr(f->f_vfsmnt, f->f_dentry, stat);
564 +               error = vfs_getattr_it(f->f_vfsmnt, f->f_dentry, &nd.intent, stat);
565 +               intent_release(&nd.intent);
566                 fput(f);
567         }
568  
569 Index: linux-2.6.5-12.1/fs/nfs/dir.c
570 ===================================================================
571 --- linux-2.6.5-12.1.orig/fs/nfs/dir.c  2004-05-10 12:21:53.000000000 -0400
572 +++ linux-2.6.5-12.1/fs/nfs/dir.c       2004-06-03 18:31:28.000000000 -0400
573 @@ -709,7 +709,7 @@
574                 return 0;
575         if (!nd || (nd->flags & LOOKUP_CONTINUE) || !(nd->flags & LOOKUP_CREATE))
576                 return 0;
577 -       return (nd->intent.open.flags & O_EXCL) != 0;
578 +       return (nd->intent.it_flags & O_EXCL) != 0;
579  }
580  
581  static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
582 @@ -1026,7 +1026,7 @@
583         attr.ia_valid = ATTR_MODE;
584  
585         if (nd && (nd->flags & LOOKUP_CREATE))
586 -               open_flags = nd->intent.open.flags;
587 +               open_flags = nd->intent.it_flags;
588  
589         /*
590          * The 0 argument passed into the create function should one day
591 Index: linux-2.6.5-12.1/fs/inode.c
592 ===================================================================
593 --- linux-2.6.5-12.1.orig/fs/inode.c    2004-05-10 12:21:56.000000000 -0400
594 +++ linux-2.6.5-12.1/fs/inode.c 2004-06-03 18:31:28.000000000 -0400
595 @@ -221,6 +221,7 @@
596         inodes_stat.nr_unused--;
597  }
598  
599 +EXPORT_SYMBOL(__iget);
600  /**
601   * clear_inode - clear an inode
602   * @inode: inode to clear
603 Index: linux-2.6.5-12.1/fs/super.c
604 ===================================================================
605 --- linux-2.6.5-12.1.orig/fs/super.c    2004-05-10 12:21:56.000000000 -0400
606 +++ linux-2.6.5-12.1/fs/super.c 2004-06-03 18:31:28.000000000 -0400
607 @@ -789,6 +789,8 @@
608         return (struct vfsmount *)sb;
609  }
610  
611 +EXPORT_SYMBOL(do_kern_mount);
612 +
613  struct vfsmount *kern_mount(struct file_system_type *type)
614  {
615         return do_kern_mount(type->name, 0, type->name, NULL);
616 Index: linux-2.6.5-12.1/fs/block_dev.c
617 ===================================================================
618 --- linux-2.6.5-12.1.orig/fs/block_dev.c        2004-05-10 12:21:55.000000000 -0400
619 +++ linux-2.6.5-12.1/fs/block_dev.c     2004-06-03 18:31:28.000000000 -0400
620 @@ -834,6 +834,7 @@
621         if (!path || !*path)
622                 return ERR_PTR(-EINVAL);
623  
624 +       intent_init(&nd.intent, IT_LOOKUP);
625         error = path_lookup(path, LOOKUP_FOLLOW, &nd);
626         if (error)
627                 return ERR_PTR(error);
628 Index: linux-2.6.5-12.1/include/linux/dcache.h
629 ===================================================================
630 --- linux-2.6.5-12.1.orig/include/linux/dcache.h        2004-04-03 22:38:24.000000000 -0500
631 +++ linux-2.6.5-12.1/include/linux/dcache.h     2004-06-03 18:31:28.000000000 -0400
632 @@ -4,6 +4,7 @@
633  #ifdef __KERNEL__
634  
635  #include <asm/atomic.h>
636 +#include <linux/string.h>
637  #include <linux/list.h>
638  #include <linux/spinlock.h>
639  #include <linux/cache.h>
640 @@ -35,6 +36,8 @@
641         char name_str[0];
642  };
643  
644 +#include <linux/namei.h>
645 +
646  struct dentry_stat_t {
647         int nr_dentry;
648         int nr_unused;
649 Index: linux-2.6.5-12.1/include/linux/fs.h
650 ===================================================================
651 --- linux-2.6.5-12.1.orig/include/linux/fs.h    2004-05-10 12:21:56.000000000 -0400
652 +++ linux-2.6.5-12.1/include/linux/fs.h 2004-06-03 18:31:28.000000000 -0400
653 @@ -76,6 +76,7 @@
654  
655  #define FMODE_READ 1
656  #define FMODE_WRITE 2
657 +#define FMODE_EXEC 4
658  
659  #define RW_MASK                1
660  #define RWA_MASK       2
661 @@ -250,6 +250,8 @@
662  #define ATTR_ATTR_FLAG 1024
663  #define ATTR_KILL_SUID 2048
664  #define ATTR_KILL_SGID 4096
665 +#define ATTR_RAW               8192    /* file system, not vfs will massage attrs */
666 +#define ATTR_FROM_OPEN         16384    /* called from open path, ie O_TRUNC */
667  
668  /*
669   * This is the Inode Attributes structure, used for notify_change().  It
670 @@ -423,6 +425,7 @@
671         struct block_device     *i_bdev;
672         struct cdev             *i_cdev;
673         int                     i_cindex;
674 +       void                    *i_filterdata;
675  
676         unsigned long           i_dnotify_mask; /* Directory notify events */
677         struct dnotify_struct   *i_dnotify; /* for directory notifications */
678 @@ -556,6 +559,7 @@
679         spinlock_t              f_ep_lock;
680  #endif /* #ifdef CONFIG_EPOLL */
681         struct address_space    *f_mapping;
682 +       struct lookup_intent    *f_it;
683  };
684  extern spinlock_t files_lock;
685  #define file_list_lock() spin_lock(&files_lock);
686 @@ -886,7 +890,9 @@
687         void (*truncate) (struct inode *);
688         int (*permission) (struct inode *, int, struct nameidata *);
689         int (*setattr) (struct dentry *, struct iattr *);
690 +       int (*setattr_raw) (struct inode *, struct iattr *);
691         int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
692 +       int (*getattr_it) (struct vfsmount *, struct dentry *, struct lookup_intent *, struct kstat *);
693         int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
694         ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
695         ssize_t (*listxattr) (struct dentry *, char *, size_t);
696 @@ -1114,6 +1120,7 @@
697  extern int unregister_filesystem(struct file_system_type *);
698  extern struct vfsmount *kern_mount(struct file_system_type *);
699  extern int may_umount(struct vfsmount *);
700 +struct vfsmount *do_kern_mount(const char *type, int flags, const char *name, void *data);
701  extern long do_mount(char *, char *, char *, unsigned long, void *);
702  
703  extern int vfs_statfs(struct super_block *, struct kstatfs *);
704 @@ -1178,6 +1185,7 @@
705  extern int do_truncate(struct dentry *, loff_t start);
706  extern struct file *filp_open(const char *, int, int);
707  extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
708 +extern struct file * dentry_open_it(struct dentry *, struct vfsmount *, int, struct lookup_intent *);
709  extern int filp_close(struct file *, fl_owner_t id);
710  extern char * getname(const char __user *);
711  
712 Index: linux-2.6.5-12.1/include/linux/namei.h
713 ===================================================================
714 --- linux-2.6.5-12.1.orig/include/linux/namei.h 2004-05-10 12:21:56.000000000 -0400
715 +++ linux-2.6.5-12.1/include/linux/namei.h      2004-06-03 18:31:28.000000000 -0400
716 @@ -2,25 +2,55 @@
717  #define _LINUX_NAMEI_H
718  
719  #include <linux/linkage.h>
720 +#include <linux/string.h>
721  
722  struct vfsmount;
723 +struct nameidata;
724  
725 -struct open_intent {
726 -       int     flags;
727 -       int     create_mode;
728 +/* intent opcodes */
729 +#define IT_OPEN     (1)
730 +#define IT_CREAT    (1<<1)
731 +#define IT_READDIR  (1<<2)
732 +#define IT_GETATTR  (1<<3)
733 +#define IT_LOOKUP   (1<<4)
734 +#define IT_UNLINK   (1<<5)
735 +#define IT_TRUNC    (1<<6)
736 +#define IT_GETXATTR (1<<7)
737 +
738 +struct lustre_intent_data {
739 +       int       it_disposition;
740 +       int       it_status;
741 +       __u64     it_lock_handle;
742 +       void     *it_data;
743 +       int       it_lock_mode;
744  };
745  
746 +#define INTENT_MAGIC 0x19620323
747 +struct lookup_intent {
748 +       int     it_magic;
749 +       void    (*it_op_release)(struct lookup_intent *);
750 +       int     it_op;
751 +       int     it_flags;
752 +       int     it_create_mode;
753 +       union {
754 +               struct lustre_intent_data lustre;
755 +       } d;
756 +};
757 +
758 +static inline void intent_init(struct lookup_intent *it, int op)
759 +{
760 +       memset(it, 0, sizeof(*it));
761 +       it->it_magic = INTENT_MAGIC;
762 +       it->it_op = op;
763 +}
764 +
765  struct nameidata {
766         struct dentry   *dentry;
767         struct vfsmount *mnt;
768         struct qstr     last;
769         unsigned int    flags;
770         int             last_type;
771 -
772 -       /* Intent data */
773 -       union {
774 -               struct open_intent open;
775 -       } intent;
776 +       struct lookup_intent intent;
777  };
778  
779  /*
780 @@ -41,6 +71,9 @@
781  #define LOOKUP_CONTINUE                 4
782  #define LOOKUP_PARENT          16
783  #define LOOKUP_NOALT           32
784 +#define LOOKUP_LAST             (1<<6)
785 +#define LOOKUP_LINK_NOTLAST     (1<<7)
786 +
787  /*
788   * Intent data
789   */
790 @@ -49,6 +82,12 @@
791  #define LOOKUP_ACCESS          (0x0400)
792  
793  extern int FASTCALL(__user_walk(const char __user *, unsigned, struct nameidata *, const char **));
794 +extern int FASTCALL(__user_walk_it(const char __user *, unsigned, struct nameidata *, const char **));
795 +#define user_path_walk_it(name,nd) \
796 +       __user_walk_it(name, LOOKUP_FOLLOW, nd, 0)
797 +#define user_path_walk_link_it(name,nd) \
798 +       __user_walk_it(name, 0, nd, 0)
799 +extern void intent_release(struct lookup_intent *);
800  #define user_path_walk(name,nd) \
801         __user_walk(name, LOOKUP_FOLLOW, nd, 0)
802  #define user_path_walk_link(name,nd) \
803 @@ -60,7 +99,6 @@
804  
805  extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
806  extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
807 -
808  extern int follow_down(struct vfsmount **, struct dentry **);
809  extern int follow_up(struct vfsmount **, struct dentry **);
810  
811 Index: linux-2.6.5-12.1/include/linux/fshooks.h
812 ===================================================================
813 --- linux-2.6.5-12.1.orig/include/linux/fshooks.h       2004-05-10 12:21:56.000000000 -0400
814 +++ linux-2.6.5-12.1/include/linux/fshooks.h    2004-06-03 18:31:28.000000000 -0400
815 @@ -90,12 +90,18 @@
816  
817  #define FSHOOK_BEGIN_USER_WALK(type, err, path, flags, nd, field, args...) \
818                 FSHOOK_BEGIN_USER_WALK_COMMON(type, err, __user_walk(path, flags, &nd, &info.field), nd, args)
819 +#define FSHOOK_BEGIN_USER_WALK_IT(type, err, path, flags, nd, field, args...) \
820 +               FSHOOK_BEGIN_USER_WALK_COMMON(type, err, __user_walk_it(path, flags, &nd, &info.field), nd, args)
821  
822  #define FSHOOK_BEGIN_USER_PATH_WALK(type, err, path, nd, field, args...) \
823                 FSHOOK_BEGIN_USER_WALK_COMMON(type, err, __user_walk(path, LOOKUP_FOLLOW, &nd, &info.field), nd, args)
824 +#define FSHOOK_BEGIN_USER_PATH_WALK_IT(type, err, path, nd, field, args...) \
825 +               FSHOOK_BEGIN_USER_WALK_COMMON(type, err, __user_walk_it(path, LOOKUP_FOLLOW, &nd, &info.field), nd, args)
826  
827  #define FSHOOK_BEGIN_USER_PATH_WALK_LINK(type, err, path, nd, field, args...) \
828                 FSHOOK_BEGIN_USER_WALK_COMMON(type, err, __user_walk(path, 0, &nd, &info.field), nd, args)
829 +#define FSHOOK_BEGIN_USER_PATH_WALK_LINK_IT(type, err, path, nd, field, args...) \
830 +               FSHOOK_BEGIN_USER_WALK_COMMON(type, err, __user_walk_it(path, 0, &nd, &info.field), nd, args)
831  
832  #define FSHOOK_END_USER_WALK(type, err, field) \
833                                 (void)(&info != (struct fshook_##type##_info *)-1L); \
834 @@ -126,12 +132,18 @@
835  
836  #define FSHOOK_BEGIN_USER_WALK(type, err, path, flags, nd, field, args...) \
837         if (!(err = __user_walk(path, flags, &nd, 0))) {
838 +#define FSHOOK_BEGIN_USER_WALK_IT(type, err, path, flags, nd, field, args...) \
839 +       if (!(err = __user_walk_it(path, flags, &nd, 0))) {
840  
841  #define FSHOOK_BEGIN_USER_PATH_WALK(type, err, path, nd, field, args...) \
842         if (!(err = user_path_walk(path, &nd))) {
843 +#define FSHOOK_BEGIN_USER_PATH_WALK_IT(type, err, path, nd, field, args...) \
844 +       if (!(err = user_path_walk_it(path, &nd))) {
845  
846  #define FSHOOK_BEGIN_USER_PATH_WALK_LINK(type, err, path, nd, field, args...) \
847         if (!(err = user_path_walk_link(path, &nd))) {
848 +#define FSHOOK_BEGIN_USER_PATH_WALK_LINK_IT(type, err, path, nd, field, args...) \
849 +       if (!(err = user_path_walk_link_it(path, &nd))) {
850  
851  #define FSHOOK_END_USER_WALK(type, err, field) ((void)0);}
852  
853 Index: linux-2.6.5-12.1/kernel/exit.c
854 ===================================================================
855 --- linux-2.6.5-12.1.orig/kernel/exit.c 2004-05-10 12:21:56.000000000 -0400
856 +++ linux-2.6.5-12.1/kernel/exit.c      2004-06-03 18:31:28.000000000 -0400
857 @@ -260,6 +260,8 @@
858         write_unlock_irq(&tasklist_lock);
859  }
860  
861 +EXPORT_SYMBOL(reparent_to_init);
862 +
863  void __set_special_pids(pid_t session, pid_t pgrp)
864  {
865         struct task_struct *curr = current;
866 @@ -429,6 +431,8 @@
867         __exit_files(tsk);
868  }
869  
870 +EXPORT_SYMBOL(exit_files);
871 +
872  static inline void __put_fs_struct(struct fs_struct *fs)
873  {
874         /* No need to hold fs->lock if we are killing it */