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