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