Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lustre / kernel_patches / patches / vfs_intent-2.6-fc3.patch
1 --- linux-2.6.10.orig/fs/exec.c
2 +++ linux-2.6.10/fs/exec.c
3 @@ -124,9 +124,10 @@
4         struct file * file;
5         struct nameidata nd;
6         int error;
7 +       intent_init(&nd.intent, IT_OPEN);
8  
9 -       nd.intent.open.flags = FMODE_READ;
10 -       error = __user_walk(library, LOOKUP_FOLLOW|LOOKUP_OPEN, &nd);
11 +       nd.intent.it_flags = FMODE_READ|FMODE_EXEC;
12 +       error = __user_walk_it(library, LOOKUP_FOLLOW|LOOKUP_OPEN, &nd);
13         if (error)
14                 goto out;
15  
16 @@ -138,7 +139,7 @@
17         if (error)
18                 goto exit;
19  
20 -       file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
21 +       file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &nd.intent);
22         error = PTR_ERR(file);
23         if (IS_ERR(file))
24                 goto out;
25 @@ -485,8 +486,9 @@
26         int err;
27         struct file *file;
28  
29 -       nd.intent.open.flags = FMODE_READ;
30 -       err = path_lookup(name, LOOKUP_FOLLOW|LOOKUP_OPEN, &nd);
31 +       intent_init(&nd.intent, IT_OPEN);
32 +       nd.intent.it_flags = FMODE_READ|FMODE_EXEC;
33 +       err = path_lookup(name, LOOKUP_FOLLOW, &nd);
34         file = ERR_PTR(err);
35  
36         if (!err) {
37 @@ -499,7 +501,7 @@
38                                 err = -EACCES;
39                         file = ERR_PTR(err);
40                         if (!err) {
41 -                               file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
42 +                               file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &nd.intent);
43                                 if (!IS_ERR(file)) {
44                                         err = deny_write_access(file);
45                                         if (err) {
46 --- linux-2.6.10.orig/fs/inode.c
47 +++ linux-2.6.10/fs/inode.c
48 @@ -233,6 +233,7 @@
49         inodes_stat.nr_unused--;
50  }
51  
52 +EXPORT_SYMBOL(__iget);
53  /**
54   * clear_inode - clear an inode
55   * @inode: inode to clear
56 --- linux-2.6.10.orig/fs/namei.c
57 +++ linux-2.6.10/fs/namei.c
58 @@ -288,8 +288,19 @@
59         return 0;
60  }
61  
62 +void intent_release(struct lookup_intent *it)
63 +{
64 +       if (!it)
65 +               return;
66 +       if (it->it_magic != INTENT_MAGIC)
67 +               return;
68 +       if (it->it_op_release)
69 +               it->it_op_release(it);
70 +}
71 +
72  void path_release(struct nameidata *nd)
73  {
74 +       intent_release(&nd->intent);
75         dput(nd->dentry);
76         mntput(nd->mnt);
77  }
78 @@ -379,7 +390,10 @@
79  {
80         struct dentry * result;
81         struct inode *dir = parent->d_inode;
82 +       int counter = 0;
83  
84 +again:
85 +       counter++;
86         down(&dir->i_sem);
87         /*
88          * First re-do the cached lookup just in case it was created
89 @@ -418,7 +432,10 @@
90         if (result->d_op && result->d_op->d_revalidate) {
91                 if (!result->d_op->d_revalidate(result, nd) && !d_invalidate(result)) {
92                         dput(result);
93 -                       result = ERR_PTR(-ENOENT);
94 +                       if (counter > 10)
95 +                               result = ERR_PTR(-ESTALE);
96 +                       if (!IS_ERR(result))
97 +                               goto again;
98                 }
99         }
100         return result;
101 @@ -449,6 +466,7 @@
102  {
103         int res = 0;
104         char *name;
105 +
106         if (IS_ERR(link))
107                 goto fail;
108  
109 @@ -458,6 +476,7 @@
110                         /* weird __emul_prefix() stuff did it */
111                         goto out;
112         }
113 +       intent_reset_fs_part(&nd->intent);
114         res = link_path_walk(link, nd);
115  out:
116         if (nd->depth || res || nd->last_type!=LAST_NORM)
117 @@ -666,6 +685,33 @@
118         return PTR_ERR(dentry);
119  }
120  
121 +static int revalidate_special(struct nameidata *nd)
122 +{
123 +       struct dentry *dentry = nd->dentry;
124 +       int err, counter = 0;
125 +
126 + revalidate_again:
127 +       if (!dentry->d_op || !dentry->d_op->d_revalidate)
128 +               return 0;
129 +       if (!dentry->d_op->d_revalidate(dentry, nd)) {
130 +               struct dentry *new;
131 +               if ((err = permission(dentry->d_parent->d_inode, MAY_EXEC, nd)))
132 +                       return err;
133 +               new = real_lookup(dentry->d_parent, &dentry->d_name, nd);
134 +               if (IS_ERR(new))
135 +                       return PTR_ERR(new);
136 +               d_invalidate(dentry);
137 +               dput(dentry);
138 +               nd->dentry = dentry = new;
139 +               counter++;
140 +               if (counter < 10)
141 +                       goto revalidate_again;
142 +               printk("excessive revalidate_it loops\n");
143 +               return -ESTALE;
144 +       }
145 +       return 0;
146 +}
147 +
148  /*
149   * Name resolution.
150   *
151 @@ -767,8 +813,12 @@
152                         goto out_dput;
153  
154                 if (inode->i_op->follow_link) {
155 +                       int save_flags = nd->flags;
156                         mntget(next.mnt);
157 +                       nd->flags |= LOOKUP_LINK_NOTLAST;
158                         err = do_follow_link(next.dentry, nd);
159 +                       if (!(save_flags & LOOKUP_LINK_NOTLAST))
160 +                               nd->flags &= ~LOOKUP_LINK_NOTLAST;
161                         dput(next.dentry);
162                         mntput(next.mnt);
163                         if (err)
164 @@ -807,14 +857,34 @@
165                                 inode = nd->dentry->d_inode;
166                                 /* fallthrough */
167                         case 1:
168 +                               nd->flags |= LOOKUP_LAST;
169 +                               err = revalidate_special(nd);
170 +                               nd->flags &= ~LOOKUP_LAST;
171 +                               if (!nd->dentry->d_inode)
172 +                                       err = -ENOENT;
173 +                               if (err) {
174 +                                       path_release(nd);
175 +                                       goto return_err;
176 +                               }
177 +                               if (lookup_flags & LOOKUP_DIRECTORY) {
178 +                                       err = -ENOTDIR;
179 +                                       if (!nd->dentry->d_inode->i_op ||
180 +                                           !nd->dentry->d_inode->i_op->lookup){
181 +                                               path_release(nd);
182 +                                               goto return_err;
183 +                                       }
184 +                               }
185                                 goto return_reval;
186                 }
187 +
188                 if (nd->dentry->d_op && nd->dentry->d_op->d_hash) {
189                         err = nd->dentry->d_op->d_hash(nd->dentry, &this);
190                         if (err < 0)
191                                 break;
192                 }
193 +               nd->flags |= LOOKUP_LAST;
194                 err = do_lookup(nd, &this, &next, atomic);
195 +               nd->flags &= ~LOOKUP_LAST;
196                 if (err)
197                         break;
198                 follow_mount(&next.mnt, &next.dentry);
199 @@ -1032,7 +1102,7 @@
200  }
201  
202  /* SMP-safe */
203 -struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
204 +struct dentry * lookup_one_len_it(const char * name, struct dentry * base, int len, struct nameidata *nd)
205  {
206         unsigned long hash;
207         struct qstr this;
208 @@ -1052,11 +1122,16 @@
209         }
210         this.hash = end_name_hash(hash);
211  
212 -       return lookup_hash(&this, base);
213 +       return __lookup_hash(&this, base, nd);
214  access:
215         return ERR_PTR(-EACCES);
216  }
217  
218 +struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
219 +{
220 +       return lookup_one_len_it(name, base, len, NULL);
221 +}
222 +
223  /*
224   *     namei()
225   *
226 @@ -1068,7 +1143,7 @@
227   * that namei follows links, while lnamei does not.
228   * SMP-safe
229   */
230 -int fastcall __user_walk(const char __user *name, unsigned flags, struct nameidata *nd)
231 +int fastcall __user_walk_it(const char __user *name, unsigned flags, struct nameidata *nd)
232  {
233         char *tmp = getname(name);
234         int err = PTR_ERR(tmp);
235 @@ -1080,6 +1155,12 @@
236         return err;
237  }
238  
239 +int fastcall __user_walk(const char __user *name, unsigned flags, struct nameidata *nd)
240 +{
241 +       intent_init(&nd->intent, IT_LOOKUP);
242 +       return __user_walk_it(name, flags, nd);
243 +}
244 +
245  /*
246   * It's inline, so penalty for filesystems that don't use sticky bit is
247   * minimal.
248 @@ -1363,8 +1444,8 @@
249                 acc_mode |= MAY_APPEND;
250  
251         /* Fill in the open() intent data */
252 -       nd->intent.open.flags = flag;
253 -       nd->intent.open.create_mode = mode;
254 +       nd->intent.it_flags = flag;
255 +       nd->intent.it_create_mode = mode;
256  
257         /*
258          * The simplest case - just a plain lookup.
259 @@ -1379,6 +1460,7 @@
260         /*
261          * Create - we need to know the parent.
262          */
263 +       nd->intent.it_op |= IT_CREAT;
264         error = path_lookup(pathname, LOOKUP_PARENT|LOOKUP_OPEN|LOOKUP_CREATE, nd);
265         if (error)
266                 return error;
267 @@ -1395,7 +1477,9 @@
268         dir = nd->dentry;
269         nd->flags &= ~LOOKUP_PARENT;
270         down(&dir->d_inode->i_sem);
271 +       nd->flags |= LOOKUP_LAST;
272         dentry = __lookup_hash(&nd->last, nd->dentry, nd);
273 +       nd->flags &= ~LOOKUP_LAST;
274  
275  do_last:
276         error = PTR_ERR(dentry);
277 @@ -1508,7 +1592,9 @@
278         }
279         dir = nd->dentry;
280         down(&dir->d_inode->i_sem);
281 +       nd->flags |= LOOKUP_LAST;
282         dentry = __lookup_hash(&nd->last, nd->dentry, nd);
283 +       nd->flags &= ~LOOKUP_LAST;
284         putname(nd->last.name);
285         goto do_last;
286  }
287 --- linux-2.6.10.orig/fs/namespace.c
288 +++ linux-2.6.10/fs/namespace.c
289 @@ -62,6 +62,7 @@
290                 INIT_LIST_HEAD(&mnt->mnt_mounts);
291                 INIT_LIST_HEAD(&mnt->mnt_list);
292                 INIT_LIST_HEAD(&mnt->mnt_fslink);
293 +               INIT_LIST_HEAD(&mnt->mnt_lustre_list);
294                 if (name) {
295                         int size = strlen(name)+1;
296                         char *newname = kmalloc(size, GFP_KERNEL);
297 @@ -113,6 +114,7 @@
298  
299  static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd)
300  {
301 +       memset(old_nd, 0, sizeof(*old_nd));
302         old_nd->dentry = mnt->mnt_mountpoint;
303         old_nd->mnt = mnt->mnt_parent;
304         mnt->mnt_parent = mnt;
305 @@ -176,6 +178,9 @@
306  {
307         struct super_block *sb = mnt->mnt_sb;
308         dput(mnt->mnt_root);
309 +       spin_lock(&dcache_lock);
310 +       list_del(&mnt->mnt_lustre_list);
311 +       spin_unlock(&dcache_lock);
312         free_vfsmnt(mnt);
313         deactivate_super(sb);
314  }
315 @@ -402,6 +407,8 @@
316          */
317  
318         lock_kernel();
319 +       if (sb->s_op->umount_lustre)
320 +               sb->s_op->umount_lustre(sb);
321         if( (flags&MNT_FORCE) && sb->s_op->umount_begin)
322                 sb->s_op->umount_begin(sb);
323         unlock_kernel();
324 @@ -627,6 +634,7 @@
325                 return err;
326         if (!old_name || !*old_name)
327                 return -EINVAL;
328 +       intent_init(&old_nd.intent, IT_LOOKUP);
329         err = path_lookup(old_name, LOOKUP_FOLLOW, &old_nd);
330         if (err)
331                 return err;
332 @@ -701,6 +709,7 @@
333                 return -EPERM;
334         if (!old_name || !*old_name)
335                 return -EINVAL;
336 +       intent_init(&old_nd.intent, IT_LOOKUP);
337         err = path_lookup(old_name, LOOKUP_FOLLOW, &old_nd);
338         if (err)
339                 return err;
340 @@ -1012,6 +1021,7 @@
341         int retval = 0;
342         int mnt_flags = 0;
343  
344 +       intent_init(&nd.intent, IT_LOOKUP);
345         /* Discard magic */
346         if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
347                 flags &= ~MS_MGC_MSK;
348 --- linux-2.6.10.orig/fs/open.c
349 +++ linux-2.6.10/fs/open.c
350 @@ -216,12 +216,12 @@
351         struct nameidata nd;
352         struct inode * inode;
353         int error;
354 -
355 +       intent_init(&nd.intent, IT_GETATTR);
356         error = -EINVAL;
357         if (length < 0) /* sorry, but loff_t says... */
358                 goto out;
359  
360 -       error = user_path_walk(path, &nd);
361 +       error = user_path_walk_it(path, &nd);
362         if (error)
363                 goto out;
364         inode = nd.dentry->d_inode;
365 @@ -475,6 +475,7 @@
366         int old_fsuid, old_fsgid;
367         kernel_cap_t old_cap;
368         int res;
369 +       intent_init(&nd.intent, IT_GETATTR);
370  
371         if (mode & ~S_IRWXO)    /* where's F_OK, X_OK, W_OK, R_OK? */
372                 return -EINVAL;
373 @@ -499,13 +500,14 @@
374         else
375                 current->cap_effective = current->cap_permitted;
376  
377 -       res = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd);
378 +       res = __user_walk_it(filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd);
379         if (!res) {
380                 res = permission(nd.dentry->d_inode, mode, &nd);
381                 /* SuS v2 requires we report a read only fs too */
382                 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
383                    && !special_file(nd.dentry->d_inode->i_mode))
384                         res = -EROFS;
385 +
386                 path_release(&nd);
387         }
388  
389 @@ -520,8 +522,9 @@
390  {
391         struct nameidata nd;
392         int error;
393 +       intent_init(&nd.intent, IT_GETATTR);
394  
395 -       error = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &nd);
396 +       error = __user_walk_it(filename, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &nd);
397         if (error)
398                 goto out;
399  
400 @@ -573,8 +576,9 @@
401  {
402         struct nameidata nd;
403         int error;
404 +       intent_init(&nd.intent, IT_GETATTR);
405  
406 -       error = __user_walk(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
407 +       error = __user_walk_it(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
408         if (error)
409                 goto out;
410  
411 @@ -758,8 +762,10 @@
412  struct file *filp_open(const char * filename, int flags, int mode)
413  {
414         int namei_flags, error;
415 +       struct file * temp_filp;
416         struct nameidata nd;
417  
418 +       intent_init(&nd.intent, IT_OPEN);
419         namei_flags = flags;
420         if ((namei_flags+1) & O_ACCMODE)
421                 namei_flags++;
422 @@ -767,15 +773,26 @@
423                 namei_flags |= 2;
424  
425         error = open_namei(filename, namei_flags, mode, &nd);
426 -       if (!error)
427 -               return dentry_open(nd.dentry, nd.mnt, flags);
428 -
429 +       if (!error) {
430 +               temp_filp = dentry_open_it(nd.dentry, nd.mnt, flags, &nd.intent);
431 +               return temp_filp;
432 +       }
433         return ERR_PTR(error);
434  }
435  
436 -EXPORT_SYMBOL(filp_open);
437  
438  struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
439 + {
440 +
441 +       struct lookup_intent it;
442 +       intent_init(&it, IT_LOOKUP);
443 +
444 +       return dentry_open_it(dentry, mnt, flags, &it);
445 +}
446 +
447 +EXPORT_SYMBOL(dentry_open);
448 +
449 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, int flags,struct lookup_intent *it)
450  {
451         struct file * f;
452         struct inode *inode;
453 @@ -787,6 +804,7 @@
454                 goto cleanup_dentry;
455         f->f_flags = flags;
456         f->f_mode = ((flags+1) & O_ACCMODE) | FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE;
457 +       f->f_it = it;
458         inode = dentry->d_inode;
459         if (f->f_mode & FMODE_WRITE) {
460                 error = get_write_access(inode);
461 @@ -805,6 +823,7 @@
462                 error = f->f_op->open(inode,f);
463                 if (error)
464                         goto cleanup_all;
465 +               intent_release(it);
466         }
467         f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
468  
469 @@ -830,13 +849,12 @@
470  cleanup_file:
471         put_filp(f);
472  cleanup_dentry:
473 +       intent_release(it);
474         dput(dentry);
475         mntput(mnt);
476         return ERR_PTR(error);
477  }
478  
479 -EXPORT_SYMBOL(dentry_open);
480 -
481  /*
482   * Find an empty file descriptor entry, and mark it busy.
483   */
484 --- linux-2.6.10.orig/fs/stat.c
485 +++ linux-2.6.10/fs/stat.c
486 @@ -38,7 +38,7 @@
487  
488  EXPORT_SYMBOL(generic_fillattr);
489  
490 -int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
491 +int vfs_getattr_it(struct vfsmount *mnt, struct dentry *dentry, struct lookup_intent *it, struct kstat *stat)
492  {
493         struct inode *inode = dentry->d_inode;
494         int retval;
495 @@ -47,6 +47,8 @@
496         if (retval)
497                 return retval;
498  
499 +       if (inode->i_op->getattr_it)
500 +               return inode->i_op->getattr_it(mnt, dentry, it, stat);
501         if (inode->i_op->getattr)
502                 return inode->i_op->getattr(mnt, dentry, stat);
503  
504 @@ -63,14 +65,20 @@
505  
506  EXPORT_SYMBOL(vfs_getattr);
507  
508 +int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
509 +{
510 +       return vfs_getattr_it(mnt, dentry, NULL, stat);
511 +}
512 +
513  int vfs_stat(char __user *name, struct kstat *stat)
514  {
515         struct nameidata nd;
516         int error;
517 +       intent_init(&nd.intent, IT_GETATTR);
518  
519 -       error = user_path_walk(name, &nd);
520 +       error = user_path_walk_it(name, &nd);
521         if (!error) {
522 -               error = vfs_getattr(nd.mnt, nd.dentry, stat);
523 +               error = vfs_getattr_it(nd.mnt, nd.dentry, &nd.intent, stat);
524                 path_release(&nd);
525         }
526         return error;
527 @@ -82,10 +90,11 @@
528  {
529         struct nameidata nd;
530         int error;
531 +       intent_init(&nd.intent, IT_GETATTR);
532  
533 -       error = user_path_walk_link(name, &nd);
534 +       error = user_path_walk_link_it(name, &nd);
535         if (!error) {
536 -               error = vfs_getattr(nd.mnt, nd.dentry, stat);
537 +               error = vfs_getattr_it(nd.mnt, nd.dentry, &nd.intent, stat);
538                 path_release(&nd);
539         }
540         return error;
541 @@ -97,9 +106,12 @@
542  {
543         struct file *f = fget(fd);
544         int error = -EBADF;
545 +       struct nameidata nd;
546 +       intent_init(&nd.intent, IT_GETATTR);
547  
548         if (f) {
549 -               error = vfs_getattr(f->f_vfsmnt, f->f_dentry, stat);
550 +               error = vfs_getattr_it(f->f_vfsmnt, f->f_dentry, &nd.intent, stat);
551 +               intent_release(&nd.intent);
552                 fput(f);
553         }
554         return error;
555 --- linux-2.6.10.orig/include/linux/dcache.h
556 +++ linux-2.6.10/include/linux/dcache.h
557 @@ -4,6 +4,7 @@
558  #ifdef __KERNEL__
559  
560  #include <asm/atomic.h>
561 +#include <linux/string.h>
562  #include <linux/list.h>
563  #include <linux/spinlock.h>
564  #include <linux/cache.h>
565 @@ -37,6 +38,8 @@
566         const unsigned char *name;
567  };
568  
569 +#include <linux/namei.h>
570 +
571  struct dentry_stat_t {
572         int nr_dentry;
573         int nr_unused;
574 --- linux-2.6.10.orig/include/linux/fs.h
575 +++ linux-2.6.10/include/linux/fs.h
576 @@ -78,6 +78,7 @@
577  
578  #define FMODE_READ 1
579  #define FMODE_WRITE 2
580 +#define FMODE_EXEC 4
581  
582  /* Internal kernel extensions */
583  #define FMODE_LSEEK    4
584 @@ -262,6 +263,8 @@
585  #define ATTR_ATTR_FLAG 1024
586  #define ATTR_KILL_SUID 2048
587  #define ATTR_KILL_SGID 4096
588 +#define ATTR_RAW               8192    /* file system, not vfs will massage attrs */
589 +#define ATTR_FROM_OPEN         16384    /* called from open path, ie O_TRUNC */
590  
591  /*
592   * This is the Inode Attributes structure, used for notify_change().  It
593 @@ -465,6 +468,7 @@
594         struct block_device     *i_bdev;
595         struct cdev             *i_cdev;
596         int                     i_cindex;
597 +       void                    *i_filterdata;
598  
599         __u32                   i_generation;
600  
601 @@ -600,6 +604,7 @@
602         spinlock_t              f_ep_lock;
603  #endif /* #ifdef CONFIG_EPOLL */
604         struct address_space    *f_mapping;
605 +       struct lookup_intent    *f_it;
606  };
607  extern spinlock_t files_lock;
608  #define file_list_lock() spin_lock(&files_lock);
609 @@ -950,7 +955,9 @@
610         void (*truncate) (struct inode *);
611         int (*permission) (struct inode *, int, struct nameidata *);
612         int (*setattr) (struct dentry *, struct iattr *);
613 +       int (*setattr_raw) (struct inode *, struct iattr *);
614         int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
615 +       int (*getattr_it) (struct vfsmount *, struct dentry *, struct lookup_intent *, struct kstat *);
616         int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
617         ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
618         ssize_t (*listxattr) (struct dentry *, char *, size_t);
619 @@ -990,6 +997,7 @@
620         int (*remount_fs) (struct super_block *, int *, char *);
621         void (*clear_inode) (struct inode *);
622         void (*umount_begin) (struct super_block *);
623 +       void (*umount_lustre) (struct super_block *);
624  
625         int (*show_options)(struct seq_file *, struct vfsmount *);
626  };
627 @@ -1181,6 +1189,7 @@
628  extern struct vfsmount *kern_mount(struct file_system_type *);
629  extern int may_umount_tree(struct vfsmount *);
630  extern int may_umount(struct vfsmount *);
631 +struct vfsmount *do_kern_mount(const char *type, int flags, const char *name, void *data);
632  extern long do_mount(char *, char *, char *, unsigned long, void *);
633  
634  extern int vfs_statfs(struct super_block *, struct kstatfs *);
635 @@ -1245,6 +1254,7 @@
636  extern int do_truncate(struct dentry *, loff_t start);
637  extern struct file *filp_open(const char *, int, int);
638  extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
639 +extern struct file * dentry_open_it(struct dentry *, struct vfsmount *, int, struct lookup_intent *);
640  extern int filp_close(struct file *, fl_owner_t id);
641  extern char * getname(const char __user *);
642  
643 --- linux-2.6.10.orig/include/linux/mount.h
644 +++ linux-2.6.10/include/linux/mount.h
645 @@ -36,6 +36,8 @@
646         struct list_head mnt_list;
647         struct list_head mnt_fslink;    /* link in fs-specific expiry list */
648         struct namespace *mnt_namespace; /* containing namespace */
649 +       struct list_head mnt_lustre_list; /* GNS mount list */
650 +       unsigned long mnt_last_used;    /* for GNS auto-umount (jiffies) */
651  };
652  
653  static inline struct vfsmount *mntget(struct vfsmount *mnt)
654 --- linux-2.6.10.orig/include/linux/namei.h
655 +++ linux-2.6.10/include/linux/namei.h
656 @@ -2,14 +2,55 @@
657  #define _LINUX_NAMEI_H
658  
659  #include <linux/linkage.h>
660 +#include <linux/string.h>
661  
662  struct vfsmount;
663 +struct nameidata;
664  
665 -struct open_intent {
666 -       int     flags;
667 -       int     create_mode;
668 +/* intent opcodes */
669 +#define IT_OPEN                (1)
670 +#define IT_CREAT       (1<<1)
671 +#define IT_READDIR     (1<<2)
672 +#define IT_GETATTR     (1<<3)
673 +#define IT_LOOKUP      (1<<4)
674 +#define IT_UNLINK      (1<<5)
675 +#define IT_TRUNC       (1<<6)
676 +#define IT_GETXATTR    (1<<7)
677 +
678 +struct lustre_intent_data {
679 +       int     it_disposition;
680 +       int     it_status;
681 +       __u64   it_lock_handle;
682 +       void    *it_data;
683 +       int     it_lock_mode;
684  };
685  
686 +#define INTENT_MAGIC 0x19620323
687 +struct lookup_intent {
688 +       int     it_magic;
689 +       void    (*it_op_release)(struct lookup_intent *);
690 +       int     it_op;
691 +       int     it_flags;
692 +       int     it_create_mode;
693 +       union {
694 +               struct lustre_intent_data lustre;
695 +       } d;
696 +};
697 +
698 +static inline void intent_reset_fs_part(struct lookup_intent *it)
699 +{
700 +        memset(&it->d, 0, sizeof(it->d));
701 +        it->it_magic = INTENT_MAGIC;
702 +        it->it_op_release = NULL;
703 +}
704 +
705 +static inline void intent_init(struct lookup_intent *it, int op)
706 +{
707 +       memset(it, 0, sizeof(*it));
708 +       it->it_magic = INTENT_MAGIC;
709 +       it->it_op = op;
710 +}
711 +
712  enum { MAX_NESTED_LINKS = 8 };
713  
714  struct nameidata {
715 @@ -21,10 +62,7 @@
716         unsigned        depth;
717         char *saved_names[MAX_NESTED_LINKS + 1];
718  
719 -       /* Intent data */
720 -       union {
721 -               struct open_intent open;
722 -       } intent;
723 +       struct lookup_intent intent;
724  };
725  
726  /*
727 @@ -47,6 +85,8 @@
728  #define LOOKUP_NOALT           32
729  #define LOOKUP_ATOMIC          64
730  #define LOOKUP_REVAL           128
731 +#define LOOKUP_LAST            (0x1000)
732 +#define LOOKUP_LINK_NOTLAST    (0x2000)
733  
734  /*
735   * Intent data
736 @@ -56,6 +96,12 @@
737  #define LOOKUP_ACCESS          (0x0400)
738  
739  extern int FASTCALL(__user_walk(const char __user *, unsigned, struct nameidata *));
740 +extern int FASTCALL(__user_walk_it(const char __user *name, unsigned flags, struct nameidata *nd));
741 +#define user_path_walk_it(name,nd) \
742 +       __user_walk_it(name, LOOKUP_FOLLOW, nd)
743 +#define user_path_walk_link_it(name,nd) \
744 +       __user_walk_it(name, 0, nd)
745 +extern void intent_release(struct lookup_intent *);
746  #define user_path_walk(name,nd) \
747         __user_walk(name, LOOKUP_FOLLOW, nd)
748  #define user_path_walk_link(name,nd) \
749 @@ -68,7 +114,6 @@
750  
751  extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
752  extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
753 -
754  extern int follow_down(struct vfsmount **, struct dentry **);
755  extern int follow_up(struct vfsmount **, struct dentry **);
756