Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lustre / kernel_patches / patches / vfs_intent-2.6-sles10.patch
1 ---
2  fs/9p/vfs_inode.c      |    2 
3  fs/exec.c              |    8 ++
4  fs/fuse/dir.c          |    2 
5  fs/inode.c             |    1 
6  fs/namei.c             |  137 ++++++++++++++++++++++++++++++++++++++++++-------
7  fs/namespace.c         |   10 +++
8  fs/nfsctl.c            |    1 
9  fs/open.c              |   31 ++++++-----
10  fs/stat.c              |   24 ++++++--
11  include/linux/dcache.h |    3 +
12  include/linux/fs.h     |   10 +++
13  include/linux/mount.h  |    2 
14  include/linux/namei.h  |   65 ++++++++++++++++++++---
15  13 files changed, 248 insertions(+), 48 deletions(-)
16
17 --- linux-2.6.16.21-0.8.orig/fs/inode.c
18 +++ linux-2.6.16.21-0.8/fs/inode.c
19 @@ -236,6 +236,7 @@ void __iget(struct inode * inode)
20         inodes_stat.nr_unused--;
21  }
22  
23 +EXPORT_SYMBOL(__iget);
24  /**
25   * clear_inode - clear an inode
26   * @inode: inode to clear
27 --- linux-2.6.16.21-0.8.orig/fs/open.c
28 +++ linux-2.6.16.21-0.8/fs/open.c
29 @@ -224,12 +224,12 @@ static long do_sys_truncate(const char _
30         struct nameidata nd;
31         struct inode * inode;
32         int error;
33 -
34 +       intent_init(&nd.intent, IT_GETATTR);
35         error = -EINVAL;
36         if (length < 0) /* sorry, but loff_t says... */
37                 goto out;
38  
39 -       error = user_path_walk(path, &nd);
40 +       error = user_path_walk_it(path, &nd);
41         if (error)
42                 goto out;
43         inode = nd.dentry->d_inode;
44 @@ -494,6 +494,7 @@ asmlinkage long sys_faccessat(int dfd, c
45         int old_fsuid, old_fsgid;
46         kernel_cap_t old_cap;
47         int res;
48 +       intent_init(&nd.intent, IT_GETATTR);
49  
50         if (mode & ~S_IRWXO)    /* where's F_OK, X_OK, W_OK, R_OK? */
51                 return -EINVAL;
52 @@ -518,7 +519,7 @@ asmlinkage long sys_faccessat(int dfd, c
53         else
54                 current->cap_effective = current->cap_permitted;
55  
56 -       res = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd);
57 +       res = __user_walk_fd_it(dfd, filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd);
58         if (!res) {
59                 res = vfs_permission(&nd, mode);
60                 /* SuS v2 requires we report a read only fs too */
61 @@ -544,8 +545,9 @@ asmlinkage long sys_chdir(const char __u
62  {
63         struct nameidata nd;
64         int error;
65 +       intent_init(&nd.intent, IT_GETATTR);
66  
67 -       error = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &nd);
68 +       error = __user_walk_it(filename, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &nd);
69         if (error)
70                 goto out;
71  
72 @@ -595,8 +597,9 @@ asmlinkage long sys_chroot(const char __
73  {
74         struct nameidata nd;
75         int error;
76 +       intent_init(&nd.intent, IT_GETATTR);
77  
78 -       error = __user_walk(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
79 +       error = __user_walk_it(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
80         if (error)
81                 goto out;
82  
83 @@ -817,6 +820,7 @@ static struct file *__dentry_open(struct
84                 error = open(inode, f);
85                 if (error)
86                         goto cleanup_all;
87 +               intent_release(f->f_it);
88         }
89  
90         f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
91 @@ -843,6 +847,7 @@ cleanup_all:
92         f->f_dentry = NULL;
93         f->f_vfsmnt = NULL;
94  cleanup_file:
95 +       intent_release(f->f_it);
96         put_filp(f);
97         dput(dentry);
98         mntput(mnt);
99 @@ -868,6 +873,7 @@ static struct file *do_filp_open(int dfd
100  {
101         int namei_flags, error;
102         struct nameidata nd;
103 +       intent_init(&nd.intent, IT_OPEN);
104  
105         namei_flags = flags;
106         if ((namei_flags+1) & O_ACCMODE)
107 @@ -904,19 +910,19 @@ EXPORT_SYMBOL(filp_open);
108  struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
109                 int (*open)(struct inode *, struct file *))
110  {
111 -       if (IS_ERR(nd->intent.open.file))
112 +       if (IS_ERR(nd->intent.file))
113                 goto out;
114         if (IS_ERR(dentry))
115                 goto out_err;
116 -       nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->mnt),
117 -                                            nd->intent.open.flags - 1,
118 -                                            nd->intent.open.file,
119 +       nd->intent.file = __dentry_open(dget(dentry), mntget(nd->mnt),
120 +                                            nd->intent.flags - 1,
121 +                                            nd->intent.file,
122                                              open);
123  out:
124 -       return nd->intent.open.file;
125 +       return nd->intent.file;
126  out_err:
127         release_open_intent(nd);
128 -       nd->intent.open.file = (struct file *)dentry;
129 +       nd->intent.file = (struct file *)dentry;
130         goto out;
131  }
132  EXPORT_SYMBOL_GPL(lookup_instantiate_filp);
133 @@ -933,7 +939,8 @@ struct file *nameidata_to_filp(struct na
134         struct file *filp;
135  
136         /* Pick up the filp from the open intent */
137 -       filp = nd->intent.open.file;
138 +       filp = nd->intent.file;
139 +       filp->f_it = &nd->intent;
140         /* Has the filesystem initialised the file for us? */
141         if (filp->f_dentry == NULL)
142                 filp = __dentry_open(nd->dentry, nd->mnt, flags, filp, NULL);
143 --- linux-2.6.16.21-0.8.orig/fs/nfsctl.c
144 +++ linux-2.6.16.21-0.8/fs/nfsctl.c
145 @@ -26,6 +26,7 @@ static struct file *do_open(char *name, 
146         struct nameidata nd;
147         int error;
148  
149 +       intent_init(&nd.intent, IT_OPEN);
150         nd.mnt = do_kern_mount("nfsd", 0, "nfsd", NULL);
151  
152         if (IS_ERR(nd.mnt))
153 --- linux-2.6.16.21-0.8.orig/fs/namei.c
154 +++ linux-2.6.16.21-0.8/fs/namei.c
155 @@ -337,8 +337,19 @@ int deny_write_access(struct file * file
156         return 0;
157  }
158  
159 +void intent_release(struct lookup_intent *it)
160 +{
161 +       if (!it)
162 +               return;
163 +       if (it->it_magic != INTENT_MAGIC)
164 +               return;
165 +       if (it->it_op_release)
166 +               it->it_op_release(it);
167 +}
168 +
169  void path_release(struct nameidata *nd)
170  {
171 +       intent_release(&nd->intent);
172         dput(nd->dentry);
173         mntput(nd->mnt);
174  }
175 @@ -359,10 +370,10 @@ void path_release_on_umount(struct namei
176   */
177  void release_open_intent(struct nameidata *nd)
178  {
179 -       if (nd->intent.open.file->f_dentry == NULL)
180 -               put_filp(nd->intent.open.file);
181 +       if (nd->intent.file->f_dentry == NULL)
182 +               put_filp(nd->intent.file);
183         else
184 -               fput(nd->intent.open.file);
185 +               fput(nd->intent.file);
186  }
187  
188  /*
189 @@ -440,8 +451,12 @@ static struct dentry * real_lookup(struc
190  {
191         struct dentry * result;
192         struct inode *dir = parent->d_inode;
193 +       int counter = 0;
194  
195         mutex_lock(&dir->i_mutex);
196 +again:
197 +       counter++;
198 +
199         /*
200          * First re-do the cached lookup just in case it was created
201          * while we waited for the directory semaphore..
202 @@ -475,13 +490,16 @@ static struct dentry * real_lookup(struc
203          * Uhhuh! Nasty case: the cache was re-populated while
204          * we waited on the semaphore. Need to revalidate.
205          */
206 -       mutex_unlock(&dir->i_mutex);
207         if (result->d_op && result->d_op->d_revalidate) {
208                 if (!result->d_op->d_revalidate(result, nd) && !d_invalidate(result)) {
209                         dput(result);
210 -                       result = ERR_PTR(-ENOENT);
211 +                       if (counter > 10)
212 +                               result = ERR_PTR(-ESTALE);
213 +                       if (!IS_ERR(result))
214 +                               goto again;
215                 }
216         }
217 +       mutex_unlock(&dir->i_mutex);
218         return result;
219  }
220  
221 @@ -510,6 +528,7 @@ static __always_inline int __vfs_follow_
222  {
223         int res = 0;
224         char *name;
225 +
226         if (IS_ERR(link))
227                 goto fail;
228  
229 @@ -519,6 +538,7 @@ static __always_inline int __vfs_follow_
230                         /* weird __emul_prefix() stuff did it */
231                         goto out;
232         }
233 +       intent_reset_fs_part(&nd->intent);
234         res = link_path_walk(link, nd);
235  out:
236         if (nd->depth || res || nd->last_type!=LAST_NORM)
237 @@ -768,6 +788,33 @@ fail:
238         return PTR_ERR(dentry);
239  }
240  
241 +static int revalidate_special(struct nameidata *nd)
242 +{
243 +       struct dentry *dentry = nd->dentry;
244 +       int err, counter = 0;
245 +
246 + revalidate_again:
247 +       if (!dentry->d_op || !dentry->d_op->d_revalidate)
248 +               return 0;
249 +       if (!dentry->d_op->d_revalidate(dentry, nd)) {
250 +               struct dentry *new;
251 +               if ((err = permission(dentry->d_parent->d_inode, MAY_EXEC, nd)))
252 +                       return err;
253 +               new = real_lookup(dentry->d_parent, &dentry->d_name, nd);
254 +               if (IS_ERR(new))
255 +                       return PTR_ERR(new);
256 +               d_invalidate(dentry);
257 +               dput(dentry);
258 +               nd->dentry = dentry = new;
259 +               counter++;
260 +               if (counter < 10)
261 +                       goto revalidate_again;
262 +               printk("excessive revalidate_it loops\n");
263 +               return -ESTALE;
264 +       }
265 +       return 0;
266 +}
267 +
268  /*
269   * Name resolution.
270   * This is the basic name resolution function, turning a pathname into
271 @@ -864,7 +911,11 @@ static fastcall int __link_path_walk(con
272                         goto out_dput;
273  
274                 if (inode->i_op->follow_link) {
275 +                       int save_flags = nd->flags;
276 +                       nd->flags |= LOOKUP_LINK_NOTLAST;
277                         err = do_follow_link(&next, nd);
278 +                       if (!(save_flags & LOOKUP_LINK_NOTLAST))
279 +                               nd->flags &= ~LOOKUP_LINK_NOTLAST;
280                         if (err)
281                                 goto return_err;
282                         err = -ENOENT;
283 @@ -899,6 +950,23 @@ last_component:
284                                 inode = nd->dentry->d_inode;
285                                 /* fallthrough */
286                         case 1:
287 +                               nd->flags |= LOOKUP_LAST;
288 +                               err = revalidate_special(nd);
289 +                               nd->flags &= ~LOOKUP_LAST;
290 +                               if (!nd->dentry->d_inode)
291 +                                       err = -ENOENT;
292 +                               if (err) {
293 +                                       path_release(nd);
294 +                                       goto return_err;
295 +                               }
296 +                               if (lookup_flags & LOOKUP_DIRECTORY) {
297 +                                       err = -ENOTDIR;
298 +                                       if(!nd->dentry->d_inode->i_op ||
299 +                                         !nd->dentry->d_inode->i_op->lookup) {
300 +                                               path_release(nd);
301 +                                               goto return_err;
302 +                                       }
303 +                               }
304                                 goto return_reval;
305                 }
306                 if (nd->dentry->d_op && nd->dentry->d_op->d_hash) {
307 @@ -906,7 +974,9 @@ last_component:
308                         if (err < 0)
309                                 break;
310                 }
311 +               nd->flags |= LOOKUP_LAST;
312                 err = do_lookup(nd, &this, &next);
313 +               nd->flags &= ~LOOKUP_LAST;
314                 if (err)
315                         break;
316                 inode = next.dentry->d_inode;
317 @@ -1148,13 +1218,13 @@ static int __path_lookup_intent_open(int
318  
319         if (filp == NULL)
320                 return -ENFILE;
321 -       nd->intent.open.file = filp;
322 -       nd->intent.open.flags = open_flags;
323 -       nd->intent.open.create_mode = create_mode;
324 +       nd->intent.file = filp;
325 +       nd->intent.flags = open_flags;
326 +       nd->intent.create_mode = create_mode;
327         err = do_path_lookup(dfd, name, lookup_flags|LOOKUP_OPEN, nd);
328 -       if (IS_ERR(nd->intent.open.file)) {
329 +       if (IS_ERR(nd->intent.file)) {
330                 if (err == 0) {
331 -                       err = PTR_ERR(nd->intent.open.file);
332 +                       err = PTR_ERR(nd->intent.file);
333                         path_release(nd);
334                 }
335         } else if (err != 0)
336 @@ -1257,7 +1327,7 @@ struct dentry * lookup_hash(struct namei
337  }
338  
339  /* SMP-safe */
340 -struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
341 +struct dentry * lookup_one_len_it(const char * name, struct dentry * base, int len, struct nameidata *nd)
342  {
343         unsigned long hash;
344         struct qstr this;
345 @@ -1277,11 +1347,17 @@ struct dentry * lookup_one_len(const cha
346         }
347         this.hash = end_name_hash(hash);
348  
349 -       return __lookup_hash(&this, base, NULL);
350 +       return __lookup_hash(&this, base, nd);
351  access:
352         return ERR_PTR(-EACCES);
353  }
354  
355 +struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
356 +{
357 +       return lookup_one_len_it(name, base, len, NULL);
358 +}
359 +
360 +
361  /*
362   *     namei()
363   *
364 @@ -1293,8 +1369,9 @@ access:
365   * that namei follows links, while lnamei does not.
366   * SMP-safe
367   */
368 -int fastcall __user_walk_fd(int dfd, const char __user *name, unsigned flags,
369 -                           struct nameidata *nd)
370 +
371 +int fastcall __user_walk_fd_it(int dfd, const char __user *name, unsigned flags,
372 +                              struct nameidata *nd)
373  {
374         char *tmp = getname(name);
375         int err = PTR_ERR(tmp);
376 @@ -1306,9 +1383,22 @@ int fastcall __user_walk_fd(int dfd, con
377         return err;
378  }
379  
380 +int fastcall __user_walk_fd(int dfd, const char __user *name, unsigned flags,
381 +                           struct nameidata *nd)
382 +{
383 +       intent_init(&nd->intent, IT_LOOKUP);
384 +       return __user_walk_fd_it(dfd, name, flags, nd);
385 +}
386 +
387 +int fastcall __user_walk_it(const char __user *name, unsigned flags, struct nameidata *nd)
388 +{
389 +       return __user_walk_fd_it(AT_FDCWD, name, flags, nd);
390 +}
391 +
392  int fastcall __user_walk(const char __user *name, unsigned flags, struct nameidata *nd)
393  {
394 -       return __user_walk_fd(AT_FDCWD, name, flags, nd);
395 +       intent_init(&nd->intent, IT_LOOKUP);
396 +       return __user_walk_it(name, flags, nd);
397  }
398  
399  /*
400 @@ -1588,6 +1678,8 @@ int open_namei(int dfd, const char *path
401         if (flag & O_APPEND)
402                 acc_mode |= MAY_APPEND;
403  
404 +       nd->intent.it_flags = flag;
405 +       nd->intent.it_create_mode = mode;
406         /*
407          * The simplest case - just a plain lookup.
408          */
409 @@ -1602,6 +1694,7 @@ int open_namei(int dfd, const char *path
410         /*
411          * Create - we need to know the parent.
412          */
413 +       nd->intent.it_op |= IT_CREAT;
414         error = path_lookup_create(dfd,pathname,LOOKUP_PARENT,nd,flag,mode);
415         if (error)
416                 return error;
417 @@ -1618,7 +1711,9 @@ int open_namei(int dfd, const char *path
418         dir = nd->dentry;
419         nd->flags &= ~LOOKUP_PARENT;
420         mutex_lock(&dir->d_inode->i_mutex);
421 +       nd->flags |= LOOKUP_LAST;
422         path.dentry = lookup_hash(nd);
423 +       nd->flags &= ~LOOKUP_LAST;
424         path.mnt = nd->mnt;
425  
426  do_last:
427 @@ -1628,9 +1723,9 @@ do_last:
428                 goto exit;
429         }
430  
431 -       if (IS_ERR(nd->intent.open.file)) {
432 +       if (IS_ERR(nd->intent.file)) {
433                 mutex_unlock(&dir->d_inode->i_mutex);
434 -               error = PTR_ERR(nd->intent.open.file);
435 +               error = PTR_ERR(nd->intent.file);
436                 goto exit_dput;
437         }
438  
439 @@ -1683,7 +1778,7 @@ ok:
440  exit_dput:
441         dput_path(&path, nd);
442  exit:
443 -       if (!IS_ERR(nd->intent.open.file))
444 +       if (!IS_ERR(nd->intent.file))
445                 release_open_intent(nd);
446         path_release(nd);
447         return error;
448 @@ -1726,7 +1821,9 @@ do_link:
449         }
450         dir = nd->dentry;
451         mutex_lock(&dir->d_inode->i_mutex);
452 +       nd->flags |= LOOKUP_LAST;
453         path.dentry = lookup_hash(nd);
454 +       nd->flags &= ~LOOKUP_LAST;
455         path.mnt = nd->mnt;
456         __putname(nd->last.name);
457         goto do_last;
458 @@ -2238,6 +2335,8 @@ asmlinkage long sys_linkat(int olddfd, c
459         int error;
460         char * to;
461  
462 +       intent_init(&nd.intent, IT_LOOKUP);
463 +        intent_init(&old_nd.intent, IT_LOOKUP);
464         if (flags != 0)
465                 return -EINVAL;
466  
467 @@ -2245,7 +2344,7 @@ asmlinkage long sys_linkat(int olddfd, c
468         if (IS_ERR(to))
469                 return PTR_ERR(to);
470  
471 -       error = __user_walk_fd(olddfd, oldname, 0, &old_nd);
472 +       error = __user_walk_fd_it(olddfd, oldname, 0, &old_nd);
473         if (error)
474                 goto exit;
475         error = do_path_lookup(newdfd, to, LOOKUP_PARENT, &nd);
476 --- linux-2.6.16.21-0.8.orig/fs/stat.c
477 +++ linux-2.6.16.21-0.8/fs/stat.c
478 @@ -38,7 +38,7 @@ void generic_fillattr(struct inode *inod
479  
480  EXPORT_SYMBOL(generic_fillattr);
481  
482 -int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
483 +int vfs_getattr_it(struct vfsmount *mnt, struct dentry *dentry, struct lookup_intent *it, struct kstat *stat)
484  {
485         struct inode *inode = dentry->d_inode;
486         int retval;
487 @@ -47,6 +47,8 @@ int vfs_getattr(struct vfsmount *mnt, st
488         if (retval)
489                 return retval;
490  
491 +       if (inode->i_op->getattr_it)
492 +               return inode->i_op->getattr_it(mnt, dentry, it, stat);
493         if (inode->i_op->getattr)
494                 return inode->i_op->getattr(mnt, dentry, stat);
495  
496 @@ -61,6 +63,11 @@ int vfs_getattr(struct vfsmount *mnt, st
497         return 0;
498  }
499  
500 +int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
501 +{
502 +       return vfs_getattr_it(mnt, dentry, NULL, stat);
503 +}
504 +
505  EXPORT_SYMBOL(vfs_getattr);
506  
507  int vfs_stat_fd(int dfd, char __user *name, struct kstat *stat)
508 @@ -68,9 +75,10 @@ int vfs_stat_fd(int dfd, char __user *na
509         struct nameidata nd;
510         int error;
511  
512 -       error = __user_walk_fd(dfd, name, LOOKUP_FOLLOW, &nd);
513 +       intent_init(&nd.intent, IT_GETATTR);
514 +       error = __user_walk_fd_it(dfd, name, LOOKUP_FOLLOW, &nd);
515         if (!error) {
516 -               error = vfs_getattr(nd.mnt, nd.dentry, stat);
517 +               error = vfs_getattr_it(nd.mnt, nd.dentry, &nd.intent, stat);
518                 path_release(&nd);
519         }
520         return error;
521 @@ -88,9 +96,10 @@ int vfs_lstat_fd(int dfd, char __user *n
522         struct nameidata nd;
523         int error;
524  
525 -       error = __user_walk_fd(dfd, name, 0, &nd);
526 +       intent_init(&nd.intent, IT_GETATTR);
527 +       error = __user_walk_fd_it(dfd, name, 0, &nd);
528         if (!error) {
529 -               error = vfs_getattr(nd.mnt, nd.dentry, stat);
530 +               error = vfs_getattr_it(nd.mnt, nd.dentry, &nd.intent, stat);
531                 path_release(&nd);
532         }
533         return error;
534 @@ -107,9 +116,12 @@ int vfs_fstat(unsigned int fd, struct ks
535  {
536         struct file *f = fget(fd);
537         int error = -EBADF;
538 +       struct nameidata nd;
539 +       intent_init(&nd.intent, IT_GETATTR);
540  
541         if (f) {
542 -               error = vfs_getattr(f->f_vfsmnt, f->f_dentry, stat);
543 +               error = vfs_getattr_it(f->f_vfsmnt, f->f_dentry, &nd.intent, stat);
544 +               intent_release(&nd.intent);
545                 fput(f);
546         }
547         return error;
548 --- linux-2.6.16.21-0.8.orig/fs/namespace.c
549 +++ linux-2.6.16.21-0.8/fs/namespace.c
550 @@ -75,6 +75,7 @@ struct vfsmount *alloc_vfsmnt(const char
551                 INIT_LIST_HEAD(&mnt->mnt_share);
552                 INIT_LIST_HEAD(&mnt->mnt_slave_list);
553                 INIT_LIST_HEAD(&mnt->mnt_slave);
554 +               INIT_LIST_HEAD(&mnt->mnt_lustre_list);
555                 if (name) {
556                         int size = strlen(name) + 1;
557                         char *newname = kmalloc(size, GFP_KERNEL);
558 @@ -155,6 +156,7 @@ static void __touch_namespace(struct nam
559  
560  static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd)
561  {
562 +       memset(old_nd, 0, sizeof(*old_nd));
563         old_nd->dentry = mnt->mnt_mountpoint;
564         old_nd->mnt = mnt->mnt_parent;
565         mnt->mnt_parent = mnt;
566 @@ -273,6 +275,9 @@ static inline void __mntput(struct vfsmo
567  {
568         struct super_block *sb = mnt->mnt_sb;
569         dput(mnt->mnt_root);
570 +       spin_lock(&dcache_lock);
571 +       list_del(&mnt->mnt_lustre_list);
572 +       spin_unlock(&dcache_lock);
573         free_vfsmnt(mnt);
574         deactivate_super(sb);
575  }
576 @@ -539,6 +544,8 @@ static int do_umount(struct vfsmount *mn
577          */
578  
579         lock_kernel();
580 +       if (sb->s_op->umount_lustre)
581 +               sb->s_op->umount_lustre(sb);
582         if ((flags & MNT_FORCE) && sb->s_op->umount_begin)
583                 sb->s_op->umount_begin(sb);
584         unlock_kernel();
585 @@ -871,6 +878,7 @@ static int do_loopback(struct nameidata 
586                 return err;
587         if (!old_name || !*old_name)
588                 return -EINVAL;
589 +       intent_init(&old_nd.intent, IT_LOOKUP);
590         err = path_lookup(old_name, LOOKUP_FOLLOW, &old_nd);
591         if (err)
592                 return err;
593 @@ -956,6 +964,7 @@ static int do_move_mount(struct nameidat
594                 return -EPERM;
595         if (!old_name || !*old_name)
596                 return -EINVAL;
597 +       intent_init(&old_nd.intent, IT_LOOKUP);
598         err = path_lookup(old_name, LOOKUP_FOLLOW, &old_nd);
599         if (err)
600                 return err;
601 @@ -1271,6 +1280,7 @@ long do_mount(char *dev_name, char *dir_
602         int retval = 0;
603         int mnt_flags = 0;
604  
605 +       intent_init(&nd.intent, IT_LOOKUP);
606         /* Discard magic */
607         if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
608                 flags &= ~MS_MGC_MSK;
609 --- linux-2.6.16.21-0.8.orig/fs/exec.c
610 +++ linux-2.6.16.21-0.8/fs/exec.c
611 @@ -128,7 +128,9 @@ asmlinkage long sys_uselib(const char __
612         struct nameidata nd;
613         int error;
614  
615 -       error = __user_path_lookup_open(library, LOOKUP_FOLLOW, &nd, FMODE_READ);
616 +       intent_init(&nd.intent, IT_OPEN);
617 +       error = __user_path_lookup_open(library, LOOKUP_FOLLOW, &nd,
618 +                                       FMODE_READ | FMODE_EXEC);
619         if (error)
620                 goto out;
621  
622 @@ -478,7 +480,9 @@ struct file *open_exec(const char *name)
623         int err;
624         struct file *file;
625  
626 -       err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd, FMODE_READ);
627 +       intent_init(&nd.intent, IT_OPEN);
628 +       err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd,
629 +                              FMODE_READ | FMODE_EXEC);
630         file = ERR_PTR(err);
631  
632         if (!err) {
633 --- linux-2.6.16.21-0.8.orig/include/linux/dcache.h
634 +++ linux-2.6.16.21-0.8/include/linux/dcache.h
635 @@ -36,6 +36,9 @@ struct qstr {
636         const unsigned char *name;
637  };
638  
639 +struct inode;
640 +#include <linux/namei.h>
641 +
642  struct dentry_stat_t {
643         int nr_dentry;
644         int nr_unused;
645 --- linux-2.6.16.21-0.8.orig/include/linux/fs.h
646 +++ linux-2.6.16.21-0.8/include/linux/fs.h
647 @@ -59,6 +59,7 @@ extern int dir_notify_enable;
648  
649  #define FMODE_READ 1
650  #define FMODE_WRITE 2
651 +#define FMODE_EXEC 16
652  
653  /* Internal kernel extensions */
654  #define FMODE_LSEEK    4
655 @@ -265,6 +266,8 @@ typedef void (dio_iodone_t)(struct kiocb
656  #define ATTR_KILL_SUID 2048
657  #define ATTR_KILL_SGID 4096
658  #define ATTR_FILE      8192
659 +#define ATTR_RAW               16384   /* file system, not vfs will massage attrs */
660 +#define ATTR_FROM_OPEN         65536   /* called from open path, ie O_TRUNC */
661  #define ATTR_NO_BLOCK  32768   /* Return EAGAIN and don't block on long truncates */
662  
663  /*
664 @@ -500,6 +503,7 @@ struct inode {
665         struct block_device     *i_bdev;
666         struct cdev             *i_cdev;
667         int                     i_cindex;
668 +       void                    *i_filterdata;
669  
670         __u32                   i_generation;
671  
672 @@ -647,6 +651,7 @@ struct file {
673         spinlock_t              f_ep_lock;
674  #endif /* #ifdef CONFIG_EPOLL */
675         struct address_space    *f_mapping;
676 +       struct lookup_intent    *f_it;
677  };
678  extern spinlock_t files_lock;
679  #define file_list_lock() spin_lock(&files_lock);
680 @@ -1049,7 +1054,9 @@ struct inode_operations {
681         void (*truncate) (struct inode *);
682         int (*permission) (struct inode *, int, struct nameidata *);
683         int (*setattr) (struct dentry *, struct iattr *);
684 +       int (*setattr_raw) (struct inode *, struct iattr *);
685         int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
686 +       int (*getattr_it) (struct vfsmount *, struct dentry *, struct lookup_intent *, struct kstat *);
687         int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
688         ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
689         ssize_t (*listxattr) (struct dentry *, char *, size_t);
690 @@ -1090,6 +1097,7 @@ struct super_operations {
691         int (*remount_fs) (struct super_block *, int *, char *);
692         void (*clear_inode) (struct inode *);
693         void (*umount_begin) (struct super_block *);
694 +       void (*umount_lustre) (struct super_block *);
695  
696         int (*show_options)(struct seq_file *, struct vfsmount *);
697  
698 @@ -1292,6 +1300,7 @@ extern int may_umount_tree(struct vfsmou
699  extern int may_umount(struct vfsmount *);
700  extern void umount_tree(struct vfsmount *, int, struct list_head *);
701  extern void release_mounts(struct list_head *);
702 +struct vfsmount *do_kern_mount(const char *type, int flags, const char *name, void *data);
703  extern long do_mount(char *, char *, char *, unsigned long, void *);
704  extern struct vfsmount *copy_tree(struct vfsmount *, struct dentry *, int);
705  extern void mnt_set_mountpoint(struct vfsmount *, struct dentry *,
706 @@ -1353,6 +1362,7 @@ extern long do_sys_open(int fdf, const c
707                         int mode);
708  extern struct file *filp_open(const char *, int, int);
709  extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
710 +extern struct file * dentry_open_it(struct dentry *, struct vfsmount *, int, struct lookup_intent *);
711  extern int filp_close(struct file *, fl_owner_t id);
712  extern char * getname(const char __user *);
713  
714 --- linux-2.6.16.21-0.8.orig/include/linux/namei.h
715 +++ linux-2.6.16.21-0.8/include/linux/namei.h
716 @@ -5,10 +5,39 @@
717  
718  struct vfsmount;
719  
720 +#define IT_OPEN                (1)
721 +#define IT_CREAT       (1<<1)
722 +#define IT_READDIR     (1<<2)
723 +#define IT_GETATTR     (1<<3)
724 +#define IT_LOOKUP      (1<<4)
725 +#define IT_UNLINK      (1<<5)
726 +#define IT_TRUNC       (1<<6)
727 +#define IT_GETXATTR    (1<<7)
728 +
729 +struct lustre_intent_data {
730 +       int     it_disposition;
731 +       int     it_status;
732 +       __u64   it_lock_handle;
733 +       void    *it_data;
734 +       int     it_lock_mode;
735 +};
736 +
737 +#define INTENT_MAGIC 0x19620323
738 +
739 +#define it_flags flags
740 +#define it_create_mode create_mode
741 +#define lookup_intent open_intent
742 +
743  struct open_intent {
744 -       int     flags;
745 -       int     create_mode;
746 -       struct file *file;
747 +               int     it_magic;
748 +               void    (*it_op_release)(struct open_intent *);
749 +               int     it_op;
750 +               int     flags;
751 +               int     create_mode;
752 +       struct  file *file;
753 +               union {
754 +                struct lustre_intent_data lustre;
755 +               } d;
756  };
757  
758  enum { MAX_NESTED_LINKS = 8 };
759 @@ -22,12 +51,23 @@ struct nameidata {
760         unsigned        depth;
761         char *saved_names[MAX_NESTED_LINKS + 1];
762  
763 -       /* Intent data */
764 -       union {
765 -               struct open_intent open;
766 -       } intent;
767 +       struct lookup_intent intent;
768  };
769  
770 +static inline void intent_reset_fs_part(struct lookup_intent *it)
771 +{
772 +        memset(&it->d, 0, sizeof(it->d));
773 +        it->it_magic = INTENT_MAGIC;
774 +        it->it_op_release = NULL;
775 +}
776 +
777 +static inline void intent_init(struct lookup_intent *it, int op)
778 +{
779 +       memset(it, 0, sizeof(*it));
780 +       it->it_magic = INTENT_MAGIC;
781 +       it->it_op = op;
782 +}
783 +
784  /*
785   * Type of the last component on LOOKUP_PARENT
786   */
787 @@ -48,6 +88,8 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LA
788  #define LOOKUP_PARENT          16
789  #define LOOKUP_NOALT           32
790  #define LOOKUP_REVAL           64
791 +#define LOOKUP_LAST            (0x1000)
792 +#define LOOKUP_LINK_NOTLAST    (0x2000)
793  /*
794   * Intent data
795   */
796 @@ -57,10 +99,19 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LA
797  
798  extern int FASTCALL(__user_walk(const char __user *, unsigned, struct nameidata *));
799  extern int FASTCALL(__user_walk_fd(int dfd, const char __user *, unsigned, struct nameidata *));
800 +extern int FASTCALL(__user_walk_fd_it(int dfd, const char __user *, unsigned, struct nameidata *));
801  #define user_path_walk(name,nd) \
802         __user_walk_fd(AT_FDCWD, name, LOOKUP_FOLLOW, nd)
803  #define user_path_walk_link(name,nd) \
804         __user_walk_fd(AT_FDCWD, name, 0, nd)
805 +
806 +extern int FASTCALL(__user_walk_it(const char __user *name, unsigned flags, struct nameidata *nd));
807 +#define user_path_walk_it(name,nd) \
808 +       __user_walk_it(name, LOOKUP_FOLLOW, nd)
809 +#define user_path_walk_link_it(name,nd) \
810 +       __user_walk_it(name, 0, nd)
811 +extern void intent_release(struct lookup_intent *);
812 +
813  extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
814  extern int FASTCALL(path_walk(const char *, struct nameidata *));
815  extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
816 --- linux-2.6.16.21-0.8.orig/include/linux/mount.h
817 +++ linux-2.6.16.21-0.8/include/linux/mount.h
818 @@ -46,6 +46,8 @@ struct vfsmount {
819         struct list_head mnt_slave;     /* slave list entry */
820         struct vfsmount *mnt_master;    /* slave is on master->mnt_slave_list */
821         struct namespace *mnt_namespace; /* containing namespace */
822 +       struct list_head mnt_lustre_list; /* GNS mount list */
823 +       unsigned long mnt_last_used;    /* for GNS auto-umount (jiffies) */
824         int mnt_pinned;
825  };
826  
827 --- linux-2.6.16.21-0.8.orig/fs/9p/vfs_inode.c
828 +++ linux-2.6.16.21-0.8/fs/9p/vfs_inode.c
829 @@ -469,7 +469,7 @@ v9fs_vfs_create(struct inode *dir, struc
830         perm = unixmode2p9mode(v9ses, mode);
831  
832         if (nd && nd->flags & LOOKUP_OPEN)
833 -               flags = nd->intent.open.flags - 1;
834 +               flags = nd->intent.flags - 1;
835         else
836                 flags = O_RDWR;
837  
838 --- linux-2.6.16.21-0.8.orig/fs/fuse/dir.c
839 +++ linux-2.6.16.21-0.8/fs/fuse/dir.c
840 @@ -242,7 +242,7 @@ static int fuse_create_open(struct inode
841         struct fuse_entry_out outentry;
842         struct fuse_file *ff;
843         struct file *file;
844 -       int flags = nd->intent.open.flags - 1;
845 +       int flags = nd->intent.flags - 1;
846  
847         err = -ENOSYS;
848         if (fc->no_create)