Whamcloud - gitweb
land b1_5 onto HEAD
[fs/lustre-release.git] / lustre / kernel_patches / patches / vfs_intent-2.6-fc5.patch
1 Index: linux-2.6.15-fc5/fs/inode.c
2 ===================================================================
3 --- linux-2.6.15-fc5.orig/fs/inode.c    2006-05-31 04:08:19.000000000 +0800
4 +++ linux-2.6.15-fc5/fs/inode.c 2006-05-31 17:24:35.000000000 +0800
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.15-fc5/fs/open.c
14 ===================================================================
15 --- linux-2.6.15-fc5.orig/fs/open.c     2006-05-31 04:08:39.000000000 +0800
16 +++ linux-2.6.15-fc5/fs/open.c  2006-05-31 17:24:35.000000000 +0800
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 @@ -488,6 +488,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 @@ -512,7 +513,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 @@ -538,8 +539,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 @@ -591,8 +593,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 @@ -815,6 +818,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 @@ -841,6 +845,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 @@ -866,6 +871,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 @@ -902,19 +908,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 @@ -931,7 +937,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.15-fc5/fs/nfsctl.c
132 ===================================================================
133 --- linux-2.6.15-fc5.orig/fs/nfsctl.c   2006-05-31 04:08:20.000000000 +0800
134 +++ linux-2.6.15-fc5/fs/nfsctl.c        2006-05-31 17:24:35.000000000 +0800
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.15-fc5/fs/namei.c
144 ===================================================================
145 --- linux-2.6.15-fc5.orig/fs/namei.c    2006-05-31 04:08:33.000000000 +0800
146 +++ linux-2.6.15-fc5/fs/namei.c 2006-05-31 17:24:35.000000000 +0800
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 -
186 +       int counter = 0;
187 +       
188         mutex_lock(&dir->i_mutex);
189 +again:
190 +       counter++;
191 +
192         /*
193          * First re-do the cached lookup just in case it was created
194          * while we waited for the directory semaphore..
195 @@ -475,13 +490,16 @@
196          * Uhhuh! Nasty case: the cache was re-populated while
197          * we waited on the semaphore. Need to revalidate.
198          */
199 -       mutex_unlock(&dir->i_mutex);
200         if (result->d_op && result->d_op->d_revalidate) {
201                 if (!result->d_op->d_revalidate(result, nd) && !d_invalidate(result)) {
202                         dput(result);
203 -                       result = ERR_PTR(-ENOENT);
204 +                       if (counter > 10)
205 +                               result = ERR_PTR(-ESTALE);
206 +                       if (!IS_ERR(result))
207 +                               goto again;
208                 }
209         }
210 +       mutex_unlock(&dir->i_mutex);
211         return result;
212  }
213  
214 @@ -509,7 +527,9 @@
215  static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *link)
216  {
217         int res = 0;
218 +       struct lookup_intent it = nd->intent;
219         char *name;
220 +
221         if (IS_ERR(link))
222                 goto fail;
223  
224 @@ -519,6 +539,10 @@
225                         /* weird __emul_prefix() stuff did it */
226                         goto out;
227         }
228 +       intent_init(&nd->intent, it.it_op);
229 +       nd->intent.it_flags = it.it_flags;
230 +       nd->intent.it_create_mode = it.it_create_mode;
231 +       nd->intent.file = it.file;
232         res = link_path_walk(link, nd);
233  out:
234         if (nd->depth || res || nd->last_type!=LAST_NORM)
235 @@ -772,6 +796,33 @@
236         return PTR_ERR(dentry);
237  }
238  
239 +static int revalidate_special(struct nameidata *nd)
240 +{
241 +       struct dentry *dentry = nd->dentry;
242 +       int err, counter = 0;
243 +
244 + revalidate_again:
245 +       if (!dentry->d_op || !dentry->d_op->d_revalidate)
246 +               return 0;
247 +       if (!dentry->d_op->d_revalidate(dentry, nd)) {
248 +               struct dentry *new;
249 +               if ((err = permission(dentry->d_parent->d_inode, MAY_EXEC, nd)))
250 +                       return err;
251 +               new = real_lookup(dentry->d_parent, &dentry->d_name, nd);
252 +               if (IS_ERR(new))
253 +                       return PTR_ERR(new);
254 +               d_invalidate(dentry);
255 +               dput(dentry);
256 +               nd->dentry = dentry = new;
257 +               counter++;
258 +               if (counter < 10)
259 +                       goto revalidate_again;
260 +               printk("excessive revalidate_it loops\n");
261 +               return -ESTALE;
262 +       }
263 +       return 0;
264 +}
265 +
266  /*
267   * Name resolution.
268   * This is the basic name resolution function, turning a pathname into
269 @@ -870,7 +921,11 @@
270                         goto out_dput;
271  
272                 if (inode->i_op->follow_link) {
273 +                       int save_flags = nd->flags;
274 +                       nd->flags |= LOOKUP_LINK_NOTLAST;
275                         err = do_follow_link(&next, nd);
276 +                       if (!(save_flags & LOOKUP_LINK_NOTLAST))
277 +                               nd->flags &= ~LOOKUP_LINK_NOTLAST;
278                         if (err)
279                                 goto return_err;
280                         err = -ENOENT;
281 @@ -905,6 +960,23 @@
282                                 inode = nd->dentry->d_inode;
283                                 /* fallthrough */
284                         case 1:
285 +                               nd->flags |= LOOKUP_LAST;
286 +                               err = revalidate_special(nd);
287 +                               nd->flags &= ~LOOKUP_LAST;
288 +                               if (!nd->dentry->d_inode)
289 +                                       err = -ENOENT;
290 +                               if (err) {
291 +                                       path_release(nd);
292 +                                       goto return_err;
293 +                               }
294 +                               if (lookup_flags & LOOKUP_DIRECTORY) {
295 +                                       err = -ENOTDIR;
296 +                                       if(!nd->dentry->d_inode->i_op ||
297 +                                         !nd->dentry->d_inode->i_op->lookup) {
298 +                                               path_release(nd);
299 +                                               goto return_err;
300 +                                       }
301 +                               }
302                                 goto return_reval;
303                 }
304                 if (nd->dentry->d_op && nd->dentry->d_op->d_hash) {
305 @@ -912,7 +984,9 @@
306                         if (err < 0)
307                                 break;
308                 }
309 +               nd->flags |= LOOKUP_LAST;
310                 err = do_lookup(nd, &this, &next, atomic);
311 +               nd->flags &= ~LOOKUP_LAST;
312                 if (err)
313                         break;
314                 inode = next.dentry->d_inode;
315 @@ -1154,13 +1228,13 @@
316  
317         if (filp == NULL)
318                 return -ENFILE;
319 -       nd->intent.open.file = filp;
320 -       nd->intent.open.flags = open_flags;
321 -       nd->intent.open.create_mode = create_mode;
322 +       nd->intent.file = filp;
323 +       nd->intent.flags = open_flags;
324 +       nd->intent.create_mode = create_mode;
325         err = do_path_lookup(dfd, name, lookup_flags|LOOKUP_OPEN, nd);
326 -       if (IS_ERR(nd->intent.open.file)) {
327 +       if (IS_ERR(nd->intent.file)) {
328                 if (err == 0) {
329 -                       err = PTR_ERR(nd->intent.open.file);
330 +                       err = PTR_ERR(nd->intent.file);
331                         path_release(nd);
332                 }
333         } else if (err != 0)
334 @@ -1263,7 +1337,7 @@
335  }
336  
337  /* SMP-safe */
338 -struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
339 +struct dentry * lookup_one_len_it(const char * name, struct dentry * base, int len, struct nameidata *nd)
340  {
341         unsigned long hash;
342         struct qstr this;
343 @@ -1283,11 +1357,17 @@
344         }
345         this.hash = end_name_hash(hash);
346  
347 -       return __lookup_hash(&this, base, NULL);
348 +       return __lookup_hash(&this, base, nd);
349  access:
350         return ERR_PTR(-EACCES);
351  }
352  
353 +struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
354 +{
355 +       return lookup_one_len_it(name, base, len, NULL);
356 +}
357 +
358 +
359  /*
360   *     namei()
361   *
362 @@ -1299,8 +1379,9 @@
363   * that namei follows links, while lnamei does not.
364   * SMP-safe
365   */
366 -int fastcall __user_walk_fd(int dfd, const char __user *name, unsigned flags,
367 -                           struct nameidata *nd)
368 +
369 +int fastcall __user_walk_fd_it(int dfd, const char __user *name, unsigned flags,
370 +                              struct nameidata *nd)
371  {
372         char *tmp = getname(name);
373         int err = PTR_ERR(tmp);
374 @@ -1312,9 +1393,22 @@
375         return err;
376  }
377  
378 +int fastcall __user_walk_fd(int dfd, const char __user *name, unsigned flags,
379 +                           struct nameidata *nd)
380 +{
381 +       intent_init(&nd->intent, IT_LOOKUP);
382 +       return __user_walk_fd_it(dfd, name, flags, nd); 
383 +}
384 +
385 +int fastcall __user_walk_it(const char __user *name, unsigned flags, struct nameidata *nd)
386 +{
387 +       return __user_walk_fd_it(AT_FDCWD, name, flags, nd);
388 +}
389 +
390  int fastcall __user_walk(const char __user *name, unsigned flags, struct nameidata *nd)
391  {
392 -       return __user_walk_fd(AT_FDCWD, name, flags, nd);
393 +       intent_init(&nd->intent, IT_LOOKUP);
394 +       return __user_walk_it(name, flags, nd);
395  }
396  
397  /*
398 @@ -1596,6 +1690,8 @@
399         if (flag & O_APPEND)
400                 acc_mode |= MAY_APPEND;
401  
402 +       nd->intent.it_flags = flag;
403 +       nd->intent.it_create_mode = mode;
404         /*
405          * The simplest case - just a plain lookup.
406          */
407 @@ -1610,6 +1706,7 @@
408         /*
409          * Create - we need to know the parent.
410          */
411 +       nd->intent.it_op |= IT_CREAT;
412         error = path_lookup_create(dfd,pathname,LOOKUP_PARENT,nd,flag,mode);
413         if (error)
414                 return error;
415 @@ -1626,7 +1723,9 @@
416         dir = nd->dentry;
417         nd->flags &= ~LOOKUP_PARENT;
418         mutex_lock(&dir->d_inode->i_mutex);
419 +       nd->flags |= LOOKUP_LAST;
420         path.dentry = lookup_hash(nd);
421 +       nd->flags &= ~LOOKUP_LAST;
422         path.mnt = nd->mnt;
423  
424  do_last:
425 @@ -1685,7 +1784,7 @@
426  exit_dput:
427         dput_path(&path, nd);
428  exit:
429 -       if (!IS_ERR(nd->intent.open.file))
430 +       if (!IS_ERR(nd->intent.file))
431                 release_open_intent(nd);
432         path_release(nd);
433         return error;
434 @@ -1728,7 +1827,9 @@
435         }
436         dir = nd->dentry;
437         mutex_lock(&dir->d_inode->i_mutex);
438 +       nd->flags |= LOOKUP_LAST;
439         path.dentry = lookup_hash(nd);
440 +       nd->flags &= ~LOOKUP_LAST;
441         path.mnt = nd->mnt;
442         __putname(nd->last.name);
443         goto do_last;
444 @@ -2240,6 +2341,8 @@
445         int error;
446         char * to;
447  
448 +       intent_init(&nd.intent, IT_LOOKUP);
449 +        intent_init(&old_nd.intent, IT_LOOKUP);
450         if (flags != 0)
451                 return -EINVAL;
452  
453 @@ -2247,7 +2350,7 @@
454         if (IS_ERR(to))
455                 return PTR_ERR(to);
456  
457 -       error = __user_walk_fd(olddfd, oldname, 0, &old_nd);
458 +       error = __user_walk_fd_it(olddfd, oldname, 0, &old_nd);
459         if (error)
460                 goto exit;
461         error = do_path_lookup(newdfd, to, LOOKUP_PARENT, &nd);
462 Index: linux-2.6.15-fc5/fs/stat.c
463 ===================================================================
464 --- linux-2.6.15-fc5.orig/fs/stat.c     2006-05-31 04:08:20.000000000 +0800
465 +++ linux-2.6.15-fc5/fs/stat.c  2006-05-31 17:24:35.000000000 +0800
466 @@ -38,7 +38,7 @@
467  
468  EXPORT_SYMBOL(generic_fillattr);
469  
470 -int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
471 +int vfs_getattr_it(struct vfsmount *mnt, struct dentry *dentry, struct lookup_intent *it, struct kstat *stat)
472  {
473         struct inode *inode = dentry->d_inode;
474         int retval;
475 @@ -47,6 +47,8 @@
476         if (retval)
477                 return retval;
478  
479 +       if (inode->i_op->getattr_it)
480 +               return inode->i_op->getattr_it(mnt, dentry, it, stat);
481         if (inode->i_op->getattr)
482                 return inode->i_op->getattr(mnt, dentry, stat);
483  
484 @@ -61,6 +63,11 @@
485         return 0;
486  }
487  
488 +int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
489 +{
490 +       return vfs_getattr_it(mnt, dentry, NULL, stat);
491 +}
492 +
493  EXPORT_SYMBOL(vfs_getattr);
494  
495  int vfs_stat_fd(int dfd, char __user *name, struct kstat *stat)
496 @@ -68,9 +75,10 @@
497         struct nameidata nd;
498         int error;
499  
500 -       error = __user_walk_fd(dfd, name, LOOKUP_FOLLOW, &nd);
501 +       intent_init(&nd.intent, IT_GETATTR);
502 +       error = __user_walk_fd_it(dfd, name, LOOKUP_FOLLOW, &nd);
503         if (!error) {
504 -               error = vfs_getattr(nd.mnt, nd.dentry, stat);
505 +               error = vfs_getattr_it(nd.mnt, nd.dentry, &nd.intent, stat);
506                 path_release(&nd);
507         }
508         return error;
509 @@ -88,9 +96,10 @@
510         struct nameidata nd;
511         int error;
512  
513 -       error = __user_walk_fd(dfd, name, 0, &nd);
514 +       intent_init(&nd.intent, IT_GETATTR);
515 +       error = __user_walk_fd_it(dfd, name, 0, &nd);
516         if (!error) {
517 -               error = vfs_getattr(nd.mnt, nd.dentry, stat);
518 +               error = vfs_getattr_it(nd.mnt, nd.dentry, &nd.intent, stat);
519                 path_release(&nd);
520         }
521         return error;
522 @@ -107,9 +116,12 @@
523  {
524         struct file *f = fget(fd);
525         int error = -EBADF;
526 +       struct nameidata nd;
527 +       intent_init(&nd.intent, IT_GETATTR);
528  
529         if (f) {
530 -               error = vfs_getattr(f->f_vfsmnt, f->f_dentry, stat);
531 +               error = vfs_getattr_it(f->f_vfsmnt, f->f_dentry, &nd.intent, stat);
532 +               intent_release(&nd.intent);
533                 fput(f);
534         }
535         return error;
536 Index: linux-2.6.15-fc5/fs/namespace.c
537 ===================================================================
538 --- linux-2.6.15-fc5.orig/fs/namespace.c        2006-05-31 04:08:33.000000000 +0800
539 +++ linux-2.6.15-fc5/fs/namespace.c     2006-05-31 17:24:35.000000000 +0800
540 @@ -74,6 +74,7 @@
541                 INIT_LIST_HEAD(&mnt->mnt_share);
542                 INIT_LIST_HEAD(&mnt->mnt_slave_list);
543                 INIT_LIST_HEAD(&mnt->mnt_slave);
544 +               INIT_LIST_HEAD(&mnt->mnt_lustre_list);  
545                 if (name) {
546                         int size = strlen(name) + 1;
547                         char *newname = kmalloc(size, GFP_KERNEL);
548 @@ -154,6 +155,7 @@
549  
550  static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd)
551  {
552 +       memset(old_nd, 0, sizeof(*old_nd));
553         old_nd->dentry = mnt->mnt_mountpoint;
554         old_nd->mnt = mnt->mnt_parent;
555         mnt->mnt_parent = mnt;
556 @@ -272,6 +274,9 @@
557  {
558         struct super_block *sb = mnt->mnt_sb;
559         dput(mnt->mnt_root);
560 +       spin_lock(&dcache_lock);
561 +       list_del(&mnt->mnt_lustre_list);
562 +       spin_unlock(&dcache_lock);
563         free_vfsmnt(mnt);
564         deactivate_super(sb);
565  }
566 @@ -538,6 +543,8 @@
567          */
568  
569         lock_kernel();
570 +       if (sb->s_op->umount_lustre)
571 +               sb->s_op->umount_lustre(sb);
572         if ((flags & MNT_FORCE) && sb->s_op->umount_begin)
573                 sb->s_op->umount_begin(sb);
574         unlock_kernel();
575 @@ -870,6 +877,7 @@
576                 return err;
577         if (!old_name || !*old_name)
578                 return -EINVAL;
579 +       intent_init(&old_nd.intent, IT_LOOKUP);
580         err = path_lookup(old_name, LOOKUP_FOLLOW, &old_nd);
581         if (err)
582                 return err;
583 @@ -955,6 +963,7 @@
584                 return -EPERM;
585         if (!old_name || !*old_name)
586                 return -EINVAL;
587 +       intent_init(&old_nd.intent, IT_LOOKUP);
588         err = path_lookup(old_name, LOOKUP_FOLLOW, &old_nd);
589         if (err)
590                 return err;
591 @@ -1270,6 +1279,7 @@
592         int retval = 0;
593         int mnt_flags = 0;
594  
595 +       intent_init(&nd.intent, IT_LOOKUP);
596         /* Discard magic */
597         if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
598                 flags &= ~MS_MGC_MSK;
599 Index: linux-2.6.15-fc5/fs/exec.c
600 ===================================================================
601 --- linux-2.6.15-fc5.orig/fs/exec.c     2006-05-31 04:08:33.000000000 +0800
602 +++ linux-2.6.15-fc5/fs/exec.c  2006-05-31 17:24:35.000000000 +0800
603 @@ -127,7 +127,9 @@
604         struct nameidata nd;
605         int error;
606  
607 -       error = __user_path_lookup_open(library, LOOKUP_FOLLOW, &nd, FMODE_READ);
608 +       intent_init(&nd.intent, IT_OPEN);
609 +       error = __user_path_lookup_open(library, LOOKUP_FOLLOW, &nd, 
610 +                                       FMODE_READ | FMODE_EXEC);
611         if (error)
612                 goto out;
613  
614 @@ -477,7 +479,9 @@
615         int err;
616         struct file *file;
617  
618 -       err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd, FMODE_READ);
619 +       intent_init(&nd.intent, IT_OPEN);
620 +       err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd, 
621 +                              FMODE_READ | FMODE_EXEC);
622         file = ERR_PTR(err);
623  
624         if (!err) {
625 Index: linux-2.6.15-fc5/include/linux/dcache.h
626 ===================================================================
627 --- linux-2.6.15-fc5.orig/include/linux/dcache.h        2006-05-31 04:08:33.000000000 +0800
628 +++ linux-2.6.15-fc5/include/linux/dcache.h     2006-05-31 17:24:41.000000000 +0800
629 @@ -4,6 +4,7 @@
630  #ifdef __KERNEL__
631  
632  #include <asm/atomic.h>
633 +#include <linux/string.h>
634  #include <linux/list.h>
635  #include <linux/spinlock.h>
636  #include <linux/cache.h>
637 @@ -36,6 +37,8 @@
638         const unsigned char *name;
639  };
640  
641 +#include <linux/namei.h>
642 +
643  struct dentry_stat_t {
644         int nr_dentry;
645         int nr_unused;
646 Index: linux-2.6.15-fc5/include/linux/fs.h
647 ===================================================================
648 --- linux-2.6.15-fc5.orig/include/linux/fs.h    2006-05-31 04:08:33.000000000 +0800
649 +++ linux-2.6.15-fc5/include/linux/fs.h 2006-05-31 17:24:35.000000000 +0800
650 @@ -59,6 +59,7 @@
651  
652  #define FMODE_READ 1
653  #define FMODE_WRITE 2
654 +#define FMODE_EXEC 4
655  
656  /* Internal kernel extensions */
657  #define FMODE_LSEEK    4
658 @@ -265,6 +266,8 @@
659  #define ATTR_KILL_SUID 2048
660  #define ATTR_KILL_SGID 4096
661  #define ATTR_FILE      8192
662 +#define ATTR_RAW               16384    /* file system, not vfs will massage attrs */
663 +#define ATTR_FROM_OPEN         32768    /* called from open path, ie O_TRUNC */
664  
665  /*
666   * This is the Inode Attributes structure, used for notify_change().  It
667 @@ -499,6 +502,7 @@
668         struct block_device     *i_bdev;
669         struct cdev             *i_cdev;
670         int                     i_cindex;
671 +       void                    *i_filterdata;
672  
673         __u32                   i_generation;
674  
675 @@ -646,6 +650,7 @@
676         spinlock_t              f_ep_lock;
677  #endif /* #ifdef CONFIG_EPOLL */
678         struct address_space    *f_mapping;
679 +       struct lookup_intent    *f_it;
680  };
681  extern spinlock_t files_lock;
682  #define file_list_lock() spin_lock(&files_lock);
683 @@ -1043,7 +1048,9 @@
684         void (*truncate) (struct inode *);
685         int (*permission) (struct inode *, int, struct nameidata *);
686         int (*setattr) (struct dentry *, struct iattr *);
687 +       int (*setattr_raw) (struct inode *, struct iattr *);
688         int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
689 +       int (*getattr_it) (struct vfsmount *, struct dentry *, struct lookup_intent *, struct kstat *);
690         int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
691         ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
692         ssize_t (*listxattr) (struct dentry *, char *, size_t);
693 @@ -1084,6 +1091,7 @@
694         int (*remount_fs) (struct super_block *, int *, char *);
695         void (*clear_inode) (struct inode *);
696         void (*umount_begin) (struct super_block *);
697 +       void (*umount_lustre) (struct super_block *);
698  
699         int (*show_options)(struct seq_file *, struct vfsmount *);
700  
701 @@ -1286,6 +1294,7 @@
702  extern int may_umount(struct vfsmount *);
703  extern void umount_tree(struct vfsmount *, int, struct list_head *);
704  extern void release_mounts(struct list_head *);
705 +struct vfsmount *do_kern_mount(const char *type, int flags, const char *name, void *data);
706  extern long do_mount(char *, char *, char *, unsigned long, void *);
707  extern struct vfsmount *copy_tree(struct vfsmount *, struct dentry *, int);
708  extern void mnt_set_mountpoint(struct vfsmount *, struct dentry *,
709 @@ -1347,6 +1356,7 @@
710                         int mode);
711  extern struct file *filp_open(const char *, int, int);
712  extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
713 +extern struct file * dentry_open_it(struct dentry *, struct vfsmount *, int, struct lookup_intent *);
714  extern int filp_close(struct file *, fl_owner_t id);
715  extern char * getname(const char __user *);
716  
717 Index: linux-2.6.15-fc5/include/linux/namei.h
718 ===================================================================
719 --- linux-2.6.15-fc5.orig/include/linux/namei.h 2006-05-31 04:08:39.000000000 +0800
720 +++ linux-2.6.15-fc5/include/linux/namei.h      2006-05-31 17:24:35.000000000 +0800
721 @@ -5,10 +5,39 @@
722  
723  struct vfsmount;
724  
725 +#define IT_OPEN                (1)
726 +#define IT_CREAT       (1<<1)
727 +#define IT_READDIR     (1<<2)
728 +#define IT_GETATTR     (1<<3)
729 +#define IT_LOOKUP      (1<<4)
730 +#define IT_UNLINK      (1<<5)
731 +#define IT_TRUNC       (1<<6)
732 +#define IT_GETXATTR    (1<<7)
733 +
734 +struct lustre_intent_data {
735 +       int     it_disposition;
736 +       int     it_status;
737 +       __u64   it_lock_handle;
738 +       void    *it_data;
739 +       int     it_lock_mode;
740 +};
741 +
742 +#define INTENT_MAGIC 0x19620323
743 +
744 +#define it_flags flags
745 +#define it_create_mode create_mode
746 +#define lookup_intent open_intent
747 +
748  struct open_intent {
749 -       int     flags;
750 -       int     create_mode;
751 -       struct file *file;
752 +               int     it_magic;
753 +               void    (*it_op_release)(struct open_intent *);
754 +               int     it_op;
755 +               int     flags;
756 +               int     create_mode;
757 +       struct  file *file;
758 +               union {
759 +                struct lustre_intent_data lustre;
760 +               } d;
761  };
762  
763  enum { MAX_NESTED_LINKS = 8 };
764 @@ -22,12 +51,16 @@
765         unsigned        depth;
766         char *saved_names[MAX_NESTED_LINKS + 1];
767  
768 -       /* Intent data */
769 -       union {
770 -               struct open_intent open;
771 -       } intent;
772 +       struct lookup_intent intent;
773  };
774  
775 +static inline void intent_init(struct lookup_intent *it, int op)
776 +{
777 +       memset(it, 0, sizeof(*it));
778 +       it->it_magic = INTENT_MAGIC;
779 +       it->it_op = op;
780 +}
781 +
782  /*
783   * Type of the last component on LOOKUP_PARENT
784   */
785 @@ -49,7 +82,8 @@
786  #define LOOKUP_NOALT           32
787  #define LOOKUP_REVAL           64
788  #define LOOKUP_ATOMIC          128
789 -
790 +#define LOOKUP_LAST            (0x1000)
791 +#define LOOKUP_LINK_NOTLAST    (0x2000)
792  /*
793   * Intent data
794   */
795 @@ -59,10 +93,19 @@
796  
797  extern int FASTCALL(__user_walk(const char __user *, unsigned, struct nameidata *));
798  extern int FASTCALL(__user_walk_fd(int dfd, const char __user *, unsigned, struct nameidata *));
799 +extern int FASTCALL(__user_walk_fd_it(int dfd, const char __user *, unsigned, struct nameidata *));
800  #define user_path_walk(name,nd) \
801         __user_walk_fd(AT_FDCWD, name, LOOKUP_FOLLOW, nd)
802  #define user_path_walk_link(name,nd) \
803         __user_walk_fd(AT_FDCWD, name, 0, nd)
804 +
805 +extern int FASTCALL(__user_walk_it(const char __user *name, unsigned flags, struct nameidata *nd));
806 +#define user_path_walk_it(name,nd) \
807 +       __user_walk_it(name, LOOKUP_FOLLOW, nd)
808 +#define user_path_walk_link_it(name,nd) \
809 +       __user_walk_it(name, 0, nd)
810 +extern void intent_release(struct lookup_intent *);
811 +
812  extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
813  extern int FASTCALL(path_walk(const char *, struct nameidata *));
814  extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
815 Index: linux-2.6.15-fc5/include/linux/mount.h
816 ===================================================================
817 --- linux-2.6.15-fc5.orig/include/linux/mount.h 2006-05-31 04:08:22.000000000 +0800
818 +++ linux-2.6.15-fc5/include/linux/mount.h      2006-05-31 17:24:35.000000000 +0800
819 @@ -46,6 +46,8 @@
820         struct list_head mnt_slave;     /* slave list entry */
821         struct vfsmount *mnt_master;    /* slave is on master->mnt_slave_list */
822         struct namespace *mnt_namespace; /* containing namespace */
823 +       struct list_head mnt_lustre_list; /* GNS mount list */
824 +       unsigned long mnt_last_used;    /* for GNS auto-umount (jiffies) */
825         int mnt_pinned;
826  };
827