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