Whamcloud - gitweb
Check "sbi->s_mb_history" before using it.
[fs/lustre-release.git] / lustre / kernel_patches / patches / vfs_intent-2.6-sles10.patch
1 Index: LINUX-SRC-TREE/fs/9p/vfs_inode.c
2 ===================================================================
3 --- LINUX-SRC-TREE.orig/fs/9p/vfs_inode.c
4 +++ LINUX-SRC-TREE/fs/9p/vfs_inode.c
5 @@ -469,7 +469,7 @@ v9fs_vfs_create(struct inode *dir, struc
6         perm = unixmode2p9mode(v9ses, mode);
7  
8         if (nd && nd->flags & LOOKUP_OPEN)
9 -               flags = nd->intent.open.flags - 1;
10 +               flags = nd->intent.flags - 1;
11         else
12                 flags = O_RDWR;
13  
14 Index: LINUX-SRC-TREE/fs/cifs/dir.c
15 ===================================================================
16 --- LINUX-SRC-TREE.orig/fs/cifs/dir.c
17 +++ LINUX-SRC-TREE/fs/cifs/dir.c
18 @@ -157,11 +157,7 @@ cifs_create(struct inode *inode, struct 
19  
20  #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)
21         if(nd && (nd->flags & LOOKUP_OPEN)) {
22 -#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,5) /* SUSE included Lustre patch */
23                 int oflags = nd->intent.it_flags;
24 -#else
25 -               int oflags = nd->intent.open.flags;
26 -#endif
27  
28                 desiredAccess = 0;
29                 if (oflags & FMODE_READ)
30 Index: LINUX-SRC-TREE/fs/exec.c
31 ===================================================================
32 --- LINUX-SRC-TREE.orig/fs/exec.c
33 +++ LINUX-SRC-TREE/fs/exec.c
34 @@ -129,7 +129,9 @@ asmlinkage long sys_uselib(const char __
35         struct nameidata nd;
36         int error;
37  
38 -       error = __user_path_lookup_open(library, LOOKUP_FOLLOW, &nd, FMODE_READ);
39 +       intent_init(&nd.intent, IT_OPEN);
40 +       error = __user_path_lookup_open(library, LOOKUP_FOLLOW, &nd,
41 +                                       FMODE_READ | FMODE_EXEC);
42         if (error)
43                 goto out;
44  
45 @@ -481,7 +483,9 @@ struct file *open_exec(const char *name)
46         int err;
47         struct file *file;
48  
49 -       err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd, FMODE_READ);
50 +       intent_init(&nd.intent, IT_OPEN);
51 +       err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd,
52 +                              FMODE_READ | FMODE_EXEC, 0);
53         file = ERR_PTR(err);
54  
55         if (!err) {
56 @@ -1543,7 +1547,7 @@ int do_coredump(long signr, int exit_cod
57                 goto close_fail;
58         if (!file->f_op->write)
59                 goto close_fail;
60 -       if (do_truncate(file->f_dentry, 0, 0, file) != 0)
61 +       if (do_truncate(file->f_dentry, 0, 0, file, 0) != 0)
62                 goto close_fail;
63  
64         retval = binfmt->core_dump(signr, regs, file);
65 Index: LINUX-SRC-TREE/fs/fuse/dir.c
66 ===================================================================
67 --- LINUX-SRC-TREE.orig/fs/fuse/dir.c
68 +++ LINUX-SRC-TREE/fs/fuse/dir.c
69 @@ -242,7 +242,7 @@ static int fuse_create_open(struct inode
70         struct fuse_entry_out outentry;
71         struct fuse_file *ff;
72         struct file *file;
73 -       int flags = nd->intent.open.flags - 1;
74 +       int flags = nd->intent.flags - 1;
75  
76         err = -ENOSYS;
77         if (fc->no_create)
78 Index: LINUX-SRC-TREE/fs/inode.c
79 ===================================================================
80 --- LINUX-SRC-TREE.orig/fs/inode.c
81 +++ LINUX-SRC-TREE/fs/inode.c
82 @@ -236,6 +236,7 @@ void __iget(struct inode * inode)
83         inodes_stat.nr_unused--;
84  }
85  
86 +EXPORT_SYMBOL(__iget);
87  /**
88   * clear_inode - clear an inode
89   * @inode: inode to clear
90 Index: LINUX-SRC-TREE/fs/namei.c
91 ===================================================================
92 --- LINUX-SRC-TREE.orig/fs/namei.c
93 +++ LINUX-SRC-TREE/fs/namei.c
94 @@ -337,8 +337,19 @@ int deny_write_access(struct file * file
95         return 0;
96  }
97  
98 +void intent_release(struct lookup_intent *it)
99 +{
100 +       if (!it)
101 +               return;
102 +       if (it->it_magic != INTENT_MAGIC)
103 +               return;
104 +       if (it->it_op_release)
105 +               it->it_op_release(it);
106 +}
107 +
108  void path_release(struct nameidata *nd)
109  {
110 +       intent_release(&nd->intent);
111         dput(nd->dentry);
112         mntput(nd->mnt);
113  }
114 @@ -359,10 +370,10 @@ void path_release_on_umount(struct namei
115   */
116  void release_open_intent(struct nameidata *nd)
117  {
118 -       if (nd->intent.open.file->f_dentry == NULL)
119 -               put_filp(nd->intent.open.file);
120 +       if (nd->intent.file->f_dentry == NULL)
121 +               put_filp(nd->intent.file);
122         else
123 -               fput(nd->intent.open.file);
124 +               fput(nd->intent.file);
125  }
126  
127  /*
128 @@ -440,8 +451,12 @@ static struct dentry * real_lookup(struc
129  {
130         struct dentry * result;
131         struct inode *dir = parent->d_inode;
132 +       int counter = 0;
133  
134         mutex_lock(&dir->i_mutex);
135 +again:
136 +       counter++;
137 +
138         /*
139          * First re-do the cached lookup just in case it was created
140          * while we waited for the directory semaphore..
141 @@ -475,13 +490,16 @@ static struct dentry * real_lookup(struc
142          * Uhhuh! Nasty case: the cache was re-populated while
143          * we waited on the semaphore. Need to revalidate.
144          */
145 -       mutex_unlock(&dir->i_mutex);
146         if (result->d_op && result->d_op->d_revalidate) {
147                 if (!result->d_op->d_revalidate(result, nd) && !d_invalidate(result)) {
148                         dput(result);
149 -                       result = ERR_PTR(-ENOENT);
150 +                       if (counter > 10)
151 +                               result = ERR_PTR(-ESTALE);
152 +                       if (!IS_ERR(result))
153 +                               goto again;
154                 }
155         }
156 +       mutex_unlock(&dir->i_mutex);
157         return result;
158  }
159  
160 @@ -510,6 +528,7 @@ static __always_inline int __vfs_follow_
161  {
162         int res = 0;
163         char *name;
164 +
165         if (IS_ERR(link))
166                 goto fail;
167  
168 @@ -519,6 +538,7 @@ static __always_inline int __vfs_follow_
169                         /* weird __emul_prefix() stuff did it */
170                         goto out;
171         }
172 +       intent_reset_fs_part(&nd->intent);
173         res = link_path_walk(link, nd);
174  out:
175         if (nd->depth || res || nd->last_type!=LAST_NORM)
176 @@ -768,6 +788,33 @@ fail:
177         return PTR_ERR(dentry);
178  }
179  
180 +static int revalidate_special(struct nameidata *nd)
181 +{
182 +       struct dentry *dentry = nd->dentry;
183 +       int err, counter = 0;
184 +
185 + revalidate_again:
186 +       if (!dentry->d_op || !dentry->d_op->d_revalidate)
187 +               return 0;
188 +       if (!dentry->d_op->d_revalidate(dentry, nd)) {
189 +               struct dentry *new;
190 +               if ((err = permission(dentry->d_parent->d_inode, MAY_EXEC, nd)))
191 +                       return err;
192 +               new = real_lookup(dentry->d_parent, &dentry->d_name, nd);
193 +               if (IS_ERR(new))
194 +                       return PTR_ERR(new);
195 +               d_invalidate(dentry);
196 +               dput(dentry);
197 +               nd->dentry = dentry = new;
198 +               counter++;
199 +               if (counter < 10)
200 +                       goto revalidate_again;
201 +               printk("excessive revalidate_it loops\n");
202 +               return -ESTALE;
203 +       }
204 +       return 0;
205 +}
206 +
207  /*
208   * Name resolution.
209   * This is the basic name resolution function, turning a pathname into
210 @@ -864,7 +911,11 @@ static fastcall int __link_path_walk(con
211                         goto out_dput;
212  
213                 if (inode->i_op->follow_link) {
214 +                       int save_flags = nd->flags;
215 +                       nd->flags |= LOOKUP_LINK_NOTLAST;
216                         err = do_follow_link(&next, nd);
217 +                       if (!(save_flags & LOOKUP_LINK_NOTLAST))
218 +                               nd->flags &= ~LOOKUP_LINK_NOTLAST;
219                         if (err)
220                                 goto return_err;
221                         err = -ENOENT;
222 @@ -899,6 +950,23 @@ last_component:
223                                 inode = nd->dentry->d_inode;
224                                 /* fallthrough */
225                         case 1:
226 +                               nd->flags |= LOOKUP_LAST;
227 +                               err = revalidate_special(nd);
228 +                               nd->flags &= ~LOOKUP_LAST;
229 +                               if (!nd->dentry->d_inode)
230 +                                       err = -ENOENT;
231 +                               if (err) {
232 +                                       path_release(nd);
233 +                                       goto return_err;
234 +                               }
235 +                               if (lookup_flags & LOOKUP_DIRECTORY) {
236 +                                       err = -ENOTDIR;
237 +                                       if(!nd->dentry->d_inode->i_op ||
238 +                                         !nd->dentry->d_inode->i_op->lookup) {
239 +                                               path_release(nd);
240 +                                               goto return_err;
241 +                                       }
242 +                               }
243                                 goto return_reval;
244                 }
245                 if (nd->dentry->d_op && nd->dentry->d_op->d_hash) {
246 @@ -906,7 +974,9 @@ last_component:
247                         if (err < 0)
248                                 break;
249                 }
250 +               nd->flags |= LOOKUP_LAST;
251                 err = do_lookup(nd, &this, &next);
252 +               nd->flags &= ~LOOKUP_LAST;
253                 if (err)
254                         break;
255                 inode = next.dentry->d_inode;
256 @@ -1066,7 +1136,7 @@ set_it:
257  }
258  
259  /* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
260 -static int fastcall do_path_lookup(int dfd, const char *name,
261 +static int fastcall do_path_lookup_it(int dfd, const char *name,
262                                 unsigned int flags, struct nameidata *nd)
263  {
264         int retval = 0;
265 @@ -1134,10 +1204,23 @@ fput_fail:
266         goto out_fail;
267  }
268  
269 -int fastcall path_lookup(const char *name, unsigned int flags,
270 +static int fastcall do_path_lookup(int dfd, const char *name,
271 +                               unsigned int flags, struct nameidata *nd)
272 +{
273 +       intent_init(&nd->intent, IT_GETATTR);
274 +       return do_path_lookup_it(dfd, name, flags, nd);
275 +}
276 +
277 +int fastcall path_lookup_it(const char *name, unsigned int flags,
278                         struct nameidata *nd)
279  {
280 -       return do_path_lookup(AT_FDCWD, name, flags, nd);
281 +       return do_path_lookup_it(AT_FDCWD, name, flags, nd);
282 +}
283 +
284 +int fastcall path_lookup(const char *name, unsigned int flags, struct nameidata *nd)
285 +{
286 +       intent_init(&nd->intent, IT_GETATTR);
287 +       return path_lookup_it(name, flags, nd);
288  }
289  
290  static int __path_lookup_intent_open(int dfd, const char *name,
291 @@ -1149,13 +1232,13 @@ static int __path_lookup_intent_open(int
292  
293         if (filp == NULL)
294                 return -ENFILE;
295 -       nd->intent.open.file = filp;
296 -       nd->intent.open.flags = open_flags;
297 -       nd->intent.open.create_mode = create_mode;
298 -       err = do_path_lookup(dfd, name, lookup_flags|LOOKUP_OPEN, nd);
299 -       if (IS_ERR(nd->intent.open.file)) {
300 +       nd->intent.file = filp;
301 +       nd->intent.flags = open_flags;
302 +       nd->intent.create_mode = create_mode;
303 +       err = do_path_lookup_it(dfd, name, lookup_flags|LOOKUP_OPEN, nd);
304 +       if (IS_ERR(nd->intent.file)) {
305                 if (err == 0) {
306 -                       err = PTR_ERR(nd->intent.open.file);
307 +                       err = PTR_ERR(nd->intent.file);
308                         path_release(nd);
309                 }
310         } else if (err != 0)
311 @@ -1172,10 +1255,10 @@ static int __path_lookup_intent_open(int
312   * @open_flags: open intent flags
313   */
314  int path_lookup_open(int dfd, const char *name, unsigned int lookup_flags,
315 -               struct nameidata *nd, int open_flags)
316 +               struct nameidata *nd, int open_flags, int create_mode)
317  {
318         return __path_lookup_intent_open(dfd, name, lookup_flags, nd,
319 -                       open_flags, 0);
320 +                       open_flags, create_mode);
321  }
322  
323  /**
324 @@ -1258,7 +1341,7 @@ struct dentry * lookup_hash(struct namei
325  }
326  
327  /* SMP-safe */
328 -struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
329 +struct dentry * lookup_one_len_it(const char * name, struct dentry * base, int len, struct nameidata *nd)
330  {
331         unsigned long hash;
332         struct qstr this;
333 @@ -1278,11 +1361,17 @@ struct dentry * lookup_one_len(const cha
334         }
335         this.hash = end_name_hash(hash);
336  
337 -       return __lookup_hash(&this, base, NULL);
338 +       return __lookup_hash(&this, base, nd);
339  access:
340         return ERR_PTR(-EACCES);
341  }
342  
343 +struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
344 +{
345 +       return lookup_one_len_it(name, base, len, NULL);
346 +}
347 +
348 +
349  /*
350   *     namei()
351   *
352 @@ -1294,22 +1383,36 @@ access:
353   * that namei follows links, while lnamei does not.
354   * SMP-safe
355   */
356 -int fastcall __user_walk_fd(int dfd, const char __user *name, unsigned flags,
357 -                           struct nameidata *nd)
358 +
359 +int fastcall __user_walk_fd_it(int dfd, const char __user *name, unsigned flags,
360 +                              struct nameidata *nd)
361  {
362         char *tmp = getname(name);
363         int err = PTR_ERR(tmp);
364  
365         if (!IS_ERR(tmp)) {
366 -               err = do_path_lookup(dfd, tmp, flags, nd);
367 +               err = do_path_lookup_it(dfd, tmp, flags, nd);
368                 putname(tmp);
369         }
370         return err;
371  }
372  
373 +int fastcall __user_walk_fd(int dfd, const char __user *name, unsigned flags,
374 +                           struct nameidata *nd)
375 +{
376 +       intent_init(&nd->intent, IT_LOOKUP);
377 +       return __user_walk_fd_it(dfd, name, flags, nd);
378 +}
379 +
380 +int fastcall __user_walk_it(const char __user *name, unsigned flags, struct nameidata *nd)
381 +{
382 +       return __user_walk_fd_it(AT_FDCWD, name, flags, nd);
383 +}
384 +
385  int fastcall __user_walk(const char __user *name, unsigned flags, struct nameidata *nd)
386  {
387 -       return __user_walk_fd(AT_FDCWD, name, flags, nd);
388 +       intent_init(&nd->intent, IT_LOOKUP);
389 +       return __user_walk_it(name, flags, nd);
390  }
391  
392  /*
393 @@ -1545,7 +1648,7 @@ int may_open(struct nameidata *nd, int a
394                 if (!error) {
395                         DQUOT_INIT(inode);
396                         
397 -                       error = do_truncate(dentry, 0, ATTR_MTIME|ATTR_CTIME, NULL);
398 +                       error = do_truncate(dentry, 0, ATTR_MTIME|ATTR_CTIME, NULL, 1);
399                 }
400                 put_write_access(inode);
401                 if (error)
402 @@ -1595,7 +1698,7 @@ int open_namei(int dfd, const char *path
403          */
404         if (!(flag & O_CREAT)) {
405                 error = path_lookup_open(dfd, pathname, lookup_flags(flag),
406 -                                        nd, flag);
407 +                                        nd, flag, mode);
408                 if (error)
409                         return error;
410                 goto ok;
411 @@ -1604,6 +1707,7 @@ int open_namei(int dfd, const char *path
412         /*
413          * Create - we need to know the parent.
414          */
415 +       nd->intent.it_op |= IT_CREAT;
416         error = path_lookup_create(dfd,pathname,LOOKUP_PARENT,nd,flag,mode);
417         if (error)
418                 return error;
419 @@ -1620,7 +1724,9 @@ int open_namei(int dfd, const char *path
420         dir = nd->dentry;
421         nd->flags &= ~LOOKUP_PARENT;
422         mutex_lock(&dir->d_inode->i_mutex);
423 +       nd->flags |= LOOKUP_LAST;
424         path.dentry = lookup_hash(nd);
425 +       nd->flags &= ~LOOKUP_LAST;
426         path.mnt = nd->mnt;
427  
428  do_last:
429 @@ -1630,9 +1736,9 @@ do_last:
430                 goto exit;
431         }
432  
433 -       if (IS_ERR(nd->intent.open.file)) {
434 +       if (IS_ERR(nd->intent.file)) {
435                 mutex_unlock(&dir->d_inode->i_mutex);
436 -               error = PTR_ERR(nd->intent.open.file);
437 +               error = PTR_ERR(nd->intent.file);
438                 goto exit_dput;
439         }
440  
441 @@ -1687,7 +1793,7 @@ ok:
442  exit_dput:
443         dput_path(&path, nd);
444  exit:
445 -       if (!IS_ERR(nd->intent.open.file))
446 +       if (!IS_ERR(nd->intent.file))
447                 release_open_intent(nd);
448         path_release(nd);
449         return error;
450 @@ -1736,7 +1842,9 @@ do_link:
451         }
452         dir = nd->dentry;
453         mutex_lock(&dir->d_inode->i_mutex);
454 +       nd->flags |= LOOKUP_LAST;
455         path.dentry = lookup_hash(nd);
456 +       nd->flags &= ~LOOKUP_LAST;
457         path.mnt = nd->mnt;
458         __putname(nd->last.name);
459         goto do_last;
460 @@ -1821,15 +1929,26 @@ asmlinkage long sys_mknodat(int dfd, con
461         struct dentry * dentry;
462         struct nameidata nd;
463  
464 +
465         if (S_ISDIR(mode))
466                 return -EPERM;
467         tmp = getname(filename);
468         if (IS_ERR(tmp))
469                 return PTR_ERR(tmp);
470  
471 -       error = do_path_lookup(dfd, tmp, LOOKUP_PARENT, &nd);
472 +       intent_init(&nd.intent, IT_LOOKUP);
473 +       error = do_path_lookup_it(dfd, tmp, LOOKUP_PARENT, &nd);
474         if (error)
475                 goto out;
476 +
477 +       if (nd.dentry->d_inode->i_op->mknod_raw) {
478 +               struct inode_operations *op = nd.dentry->d_inode->i_op;
479 +               error = op->mknod_raw(&nd, mode, dev);
480 +               /* the file system wants to use normal vfs path now */
481 +               if (error != -EOPNOTSUPP)
482 +                       goto out2;
483 +       }
484 +
485         dentry = lookup_create(&nd, 0);
486         error = PTR_ERR(dentry);
487  
488 @@ -1856,6 +1975,7 @@ asmlinkage long sys_mknodat(int dfd, con
489                 dput(dentry);
490         }
491         mutex_unlock(&nd.dentry->d_inode->i_mutex);
492 +out2:
493         path_release(&nd);
494  out:
495         putname(tmp);
496 @@ -1901,9 +2021,18 @@ asmlinkage long sys_mkdirat(int dfd, con
497                 struct dentry *dentry;
498                 struct nameidata nd;
499  
500 -               error = do_path_lookup(dfd, tmp, LOOKUP_PARENT, &nd);
501 +               intent_init(&nd.intent, IT_LOOKUP);
502 +               error = do_path_lookup_it(dfd, tmp, LOOKUP_PARENT, &nd);
503                 if (error)
504                         goto out;
505 +               if (nd.dentry->d_inode->i_op->mkdir_raw) {
506 +                       struct inode_operations *op = nd.dentry->d_inode->i_op;
507 +                       error = op->mkdir_raw(&nd, mode);
508 +                       /* the file system wants to use normal vfs path now */
509 +                       if (error != -EOPNOTSUPP)
510 +                               goto out2;
511 +               }
512 +
513                 dentry = lookup_create(&nd, 1);
514                 error = PTR_ERR(dentry);
515                 if (!IS_ERR(dentry)) {
516 @@ -1913,6 +2042,7 @@ asmlinkage long sys_mkdirat(int dfd, con
517                         dput(dentry);
518                 }
519                 mutex_unlock(&nd.dentry->d_inode->i_mutex);
520 +out2:
521                 path_release(&nd);
522  out:
523                 putname(tmp);
524 @@ -1997,8 +2127,9 @@ static long do_rmdir(int dfd, const char
525         name = getname(pathname);
526         if(IS_ERR(name))
527                 return PTR_ERR(name);
528 -
529 -       error = do_path_lookup(dfd, name, LOOKUP_PARENT, &nd);
530 +               
531 +       intent_init(&nd.intent, IT_LOOKUP);
532 +       error = do_path_lookup_it(dfd, name, LOOKUP_PARENT, &nd);
533         if (error)
534                 goto exit;
535  
536 @@ -2013,6 +2144,14 @@ static long do_rmdir(int dfd, const char
537                         error = -EBUSY;
538                         goto exit1;
539         }
540 +       if (nd.dentry->d_inode->i_op->rmdir_raw) {
541 +                struct inode_operations *op = nd.dentry->d_inode->i_op;
542 +
543 +                error = op->rmdir_raw(&nd);
544 +                /* the file system wants to use normal vfs path now */
545 +                if (error != -EOPNOTSUPP)
546 +                        goto exit1;
547 +        }
548         mutex_lock(&nd.dentry->d_inode->i_mutex);
549         dentry = lookup_hash(&nd);
550         error = PTR_ERR(dentry);
551 @@ -2081,12 +2220,20 @@ static long do_unlinkat(int dfd, const c
552         if(IS_ERR(name))
553                 return PTR_ERR(name);
554  
555 -       error = do_path_lookup(dfd, name, LOOKUP_PARENT, &nd);
556 +       intent_init(&nd.intent, IT_LOOKUP);
557 +       error = do_path_lookup_it(dfd, name, LOOKUP_PARENT, &nd);
558         if (error)
559                 goto exit;
560         error = -EISDIR;
561         if (nd.last_type != LAST_NORM)
562                 goto exit1;
563 +       if (nd.dentry->d_inode->i_op->unlink_raw) {
564 +               struct inode_operations *op = nd.dentry->d_inode->i_op;
565 +               error = op->unlink_raw(&nd);
566 +                /* the file system wants to use normal vfs path now */
567 +               if (error != -EOPNOTSUPP)
568 +                       goto exit1;
569 +        }
570         mutex_lock(&nd.dentry->d_inode->i_mutex);
571         dentry = lookup_hash(&nd);
572         error = PTR_ERR(dentry);
573 @@ -2169,9 +2316,17 @@ asmlinkage long sys_symlinkat(const char
574                 struct dentry *dentry;
575                 struct nameidata nd;
576  
577 -               error = do_path_lookup(newdfd, to, LOOKUP_PARENT, &nd);
578 +               intent_init(&nd.intent, IT_LOOKUP);
579 +               error = do_path_lookup_it(newdfd, to, LOOKUP_PARENT, &nd);
580                 if (error)
581                         goto out;
582 +               if (nd.dentry->d_inode->i_op->symlink_raw) {
583 +                       struct inode_operations *op = nd.dentry->d_inode->i_op;
584 +                       error = op->symlink_raw(&nd, from);
585 +                       /* the file system wants to use normal vfs path now */
586 +                       if (error != -EOPNOTSUPP)
587 +                               goto out2;
588 +               }
589                 dentry = lookup_create(&nd, 0);
590                 error = PTR_ERR(dentry);
591                 if (!IS_ERR(dentry)) {
592 @@ -2179,6 +2334,7 @@ asmlinkage long sys_symlinkat(const char
593                         dput(dentry);
594                 }
595                 mutex_unlock(&nd.dentry->d_inode->i_mutex);
596 +out2:
597                 path_release(&nd);
598  out:
599                 putname(to);
600 @@ -2255,15 +2411,25 @@ asmlinkage long sys_linkat(int olddfd, c
601         if (IS_ERR(to))
602                 return PTR_ERR(to);
603  
604 -       error = __user_walk_fd(olddfd, oldname, 0, &old_nd);
605 +        intent_init(&old_nd.intent, IT_LOOKUP);
606 +       error = __user_walk_fd_it(olddfd, oldname, 0, &old_nd);
607         if (error)
608                 goto exit;
609 -       error = do_path_lookup(newdfd, to, LOOKUP_PARENT, &nd);
610 +               
611 +       intent_init(&nd.intent, IT_LOOKUP);             
612 +       error = do_path_lookup_it(newdfd, to, LOOKUP_PARENT, &nd);
613         if (error)
614                 goto out;
615         error = -EXDEV;
616         if (old_nd.mnt != nd.mnt)
617                 goto out_release;
618 +       if (nd.dentry->d_inode->i_op->link_raw) {
619 +               struct inode_operations *op = nd.dentry->d_inode->i_op;
620 +               error = op->link_raw(&old_nd, &nd);
621 +               /* the file system wants to use normal vfs path now */
622 +               if (error != -EOPNOTSUPP)
623 +                       goto out_release;
624 +       }
625         new_dentry = lookup_create(&nd, 0);
626         error = PTR_ERR(new_dentry);
627         if (!IS_ERR(new_dentry)) {
628 @@ -2440,12 +2606,14 @@ static int do_rename(int olddfd, const c
629         struct dentry * old_dentry, *new_dentry;
630         struct dentry * trap;
631         struct nameidata oldnd, newnd;
632 -
633 -       error = do_path_lookup(olddfd, oldname, LOOKUP_PARENT, &oldnd);
634 +       
635 +       intent_init(&oldnd.intent, IT_LOOKUP);
636 +       error = do_path_lookup_it(olddfd, oldname, LOOKUP_PARENT, &oldnd);
637         if (error)
638                 goto exit;
639 -
640 -       error = do_path_lookup(newdfd, newname, LOOKUP_PARENT, &newnd);
641 +               
642 +       intent_init(&newnd.intent, IT_LOOKUP);
643 +       error = do_path_lookup_it(newdfd, newname, LOOKUP_PARENT, &newnd);
644         if (error)
645                 goto exit1;
646  
647 @@ -2462,6 +2630,13 @@ static int do_rename(int olddfd, const c
648         if (newnd.last_type != LAST_NORM)
649                 goto exit2;
650  
651 +       if (old_dir->d_inode->i_op->rename_raw) {
652 +               error = old_dir->d_inode->i_op->rename_raw(&oldnd, &newnd);
653 +               /* the file system wants to use normal vfs path now */
654 +               if (error != -EOPNOTSUPP)
655 +                       goto exit2;
656 +       }
657 +
658         trap = lock_rename(new_dir, old_dir);
659  
660         old_dentry = lookup_hash(&oldnd);
661 @@ -2493,8 +2668,7 @@ static int do_rename(int olddfd, const c
662         if (new_dentry == trap)
663                 goto exit5;
664  
665 -       error = vfs_rename(old_dir->d_inode, old_dentry,
666 -                                  new_dir->d_inode, new_dentry);
667 +       error = vfs_rename(old_dir->d_inode, old_dentry, new_dir->d_inode, new_dentry);
668  exit5:
669         dput(new_dentry);
670  exit4:
671 @@ -2700,6 +2874,7 @@ EXPORT_SYMBOL(__page_symlink);
672  EXPORT_SYMBOL(page_symlink);
673  EXPORT_SYMBOL(page_symlink_inode_operations);
674  EXPORT_SYMBOL(path_lookup);
675 +EXPORT_SYMBOL(path_lookup_it);
676  EXPORT_SYMBOL(path_release);
677  EXPORT_SYMBOL(path_walk);
678  EXPORT_SYMBOL(permission);
679 Index: LINUX-SRC-TREE/fs/namespace.c
680 ===================================================================
681 --- LINUX-SRC-TREE.orig/fs/namespace.c
682 +++ LINUX-SRC-TREE/fs/namespace.c
683 @@ -75,6 +75,7 @@ struct vfsmount *alloc_vfsmnt(const char
684                 INIT_LIST_HEAD(&mnt->mnt_share);
685                 INIT_LIST_HEAD(&mnt->mnt_slave_list);
686                 INIT_LIST_HEAD(&mnt->mnt_slave);
687 +               INIT_LIST_HEAD(&mnt->mnt_lustre_list);
688                 if (name) {
689                         int size = strlen(name) + 1;
690                         char *newname = kmalloc(size, GFP_KERNEL);
691 @@ -155,6 +156,7 @@ static void __touch_namespace(struct nam
692  
693  static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd)
694  {
695 +       memset(old_nd, 0, sizeof(*old_nd));
696         old_nd->dentry = mnt->mnt_mountpoint;
697         old_nd->mnt = mnt->mnt_parent;
698         mnt->mnt_parent = mnt;
699 @@ -273,6 +275,9 @@ static inline void __mntput(struct vfsmo
700  {
701         struct super_block *sb = mnt->mnt_sb;
702         dput(mnt->mnt_root);
703 +       spin_lock(&dcache_lock);
704 +       list_del(&mnt->mnt_lustre_list);
705 +       spin_unlock(&dcache_lock);
706         free_vfsmnt(mnt);
707         deactivate_super(sb);
708  }
709 @@ -539,6 +544,8 @@ static int do_umount(struct vfsmount *mn
710          */
711  
712         lock_kernel();
713 +       if (sb->s_op->umount_lustre)
714 +               sb->s_op->umount_lustre(sb);
715         if ((flags & MNT_FORCE) && sb->s_op->umount_begin)
716                 sb->s_op->umount_begin(sb);
717         unlock_kernel();
718 @@ -871,7 +878,8 @@ static int do_loopback(struct nameidata 
719                 return err;
720         if (!old_name || !*old_name)
721                 return -EINVAL;
722 -       err = path_lookup(old_name, LOOKUP_FOLLOW, &old_nd);
723 +       intent_init(&old_nd.intent, IT_LOOKUP);
724 +       err = path_lookup_it(old_name, LOOKUP_FOLLOW, &old_nd);
725         if (err)
726                 return err;
727  
728 @@ -956,7 +964,8 @@ static int do_move_mount(struct nameidat
729                 return -EPERM;
730         if (!old_name || !*old_name)
731                 return -EINVAL;
732 -       err = path_lookup(old_name, LOOKUP_FOLLOW, &old_nd);
733 +       intent_init(&old_nd.intent, IT_LOOKUP);
734 +       err = path_lookup_it(old_name, LOOKUP_FOLLOW, &old_nd);
735         if (err)
736                 return err;
737  
738 @@ -1271,6 +1280,7 @@ long do_mount(char *dev_name, char *dir_
739         int retval = 0;
740         int mnt_flags = 0;
741  
742 +
743         /* Discard magic */
744         if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
745                 flags &= ~MS_MGC_MSK;
746 @@ -1301,7 +1311,8 @@ long do_mount(char *dev_name, char *dir_
747                    MS_NOATIME | MS_NODIRATIME);
748  
749         /* ... and get the mountpoint */
750 -       retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd);
751 +       intent_init(&nd.intent, IT_LOOKUP);     
752 +       retval = path_lookup_it(dir_name, LOOKUP_FOLLOW, &nd);
753         if (retval)
754                 return retval;
755  
756 Index: LINUX-SRC-TREE/fs/nfs/dir.c
757 ===================================================================
758 --- LINUX-SRC-TREE.orig/fs/nfs/dir.c
759 +++ LINUX-SRC-TREE/fs/nfs/dir.c
760 @@ -834,7 +834,7 @@ int nfs_is_exclusive_create(struct inode
761                 return 0;
762         if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_CREATE) == 0)
763                 return 0;
764 -       return (nd->intent.open.flags & O_EXCL) != 0;
765 +       return (nd->intent.it_flags & O_EXCL) != 0;
766  }
767  
768  static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
769 @@ -911,7 +911,7 @@ static int is_atomic_open(struct inode *
770         if (nd->flags & LOOKUP_DIRECTORY)
771                 return 0;
772         /* Are we trying to write to a read only partition? */
773 -       if (IS_RDONLY(dir) && (nd->intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE)))
774 +       if (IS_RDONLY(dir) && (nd->intent.it_flags & (O_CREAT|O_TRUNC|FMODE_WRITE)))
775                 return 0;
776         return 1;
777  }
778 @@ -932,7 +932,7 @@ static struct dentry *nfs_atomic_lookup(
779         dentry->d_op = NFS_PROTO(dir)->dentry_ops;
780  
781         /* Let vfs_create() deal with O_EXCL */
782 -       if (nd->intent.open.flags & O_EXCL) {
783 +       if (nd->intent.it_flags & O_EXCL) {
784                 d_add(dentry, NULL);
785                 goto out;
786         }
787 @@ -947,7 +947,7 @@ static struct dentry *nfs_atomic_lookup(
788                 goto out;
789         }
790  
791 -       if (nd->intent.open.flags & O_CREAT) {
792 +       if (nd->intent.it_flags & O_CREAT) {
793                 nfs_begin_data_update(dir);
794                 res = nfs4_atomic_open(dir, dentry, nd);
795                 nfs_end_data_update(dir);
796 @@ -966,7 +966,7 @@ static struct dentry *nfs_atomic_lookup(
797                         case -ENOTDIR:
798                                 goto no_open;
799                         case -ELOOP:
800 -                               if (!(nd->intent.open.flags & O_NOFOLLOW))
801 +                               if (!(nd->intent.it_flags & O_NOFOLLOW))
802                                         goto no_open;
803                         /* case -EINVAL: */
804                         default:
805 @@ -1002,7 +1002,7 @@ static int nfs_open_revalidate(struct de
806         /* NFS only supports OPEN on regular files */
807         if (!S_ISREG(inode->i_mode))
808                 goto no_open;
809 -       openflags = nd->intent.open.flags;
810 +       openflags = nd->intent.it_flags;
811         /* We cannot do exclusive creation on a positive dentry */
812         if ((openflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL))
813                 goto no_open;
814 @@ -1138,7 +1138,7 @@ static int nfs_create(struct inode *dir,
815         attr.ia_valid = ATTR_MODE;
816  
817         if (nd && (nd->flags & LOOKUP_CREATE))
818 -               open_flags = nd->intent.open.flags;
819 +               open_flags = nd->intent.it_flags;
820  
821         lock_kernel();
822         nfs_begin_data_update(dir);
823 Index: LINUX-SRC-TREE/fs/nfs/nfs4proc.c
824 ===================================================================
825 --- LINUX-SRC-TREE.orig/fs/nfs/nfs4proc.c
826 +++ LINUX-SRC-TREE/fs/nfs/nfs4proc.c
827 @@ -1220,7 +1220,7 @@ static void nfs4_intent_set_file(struct 
828                 ctx = (struct nfs_open_context *)filp->private_data;
829                 ctx->state = state;
830         } else
831 -               nfs4_close_state(state, nd->intent.open.flags);
832 +               nfs4_close_state(state, nd->intent.flags);
833  }
834  
835  struct dentry *
836 @@ -1232,19 +1232,19 @@ nfs4_atomic_open(struct inode *dir, stru
837         struct dentry *res;
838  
839         if (nd->flags & LOOKUP_CREATE) {
840 -               attr.ia_mode = nd->intent.open.create_mode;
841 +               attr.ia_mode = nd->intent.create_mode;
842                 attr.ia_valid = ATTR_MODE;
843                 if (!IS_POSIXACL(dir))
844                         attr.ia_mode &= ~current->fs->umask;
845         } else {
846                 attr.ia_valid = 0;
847 -               BUG_ON(nd->intent.open.flags & O_CREAT);
848 +               BUG_ON(nd->intent.flags & O_CREAT);
849         }
850  
851         cred = rpcauth_lookupcred(NFS_SERVER(dir)->client->cl_auth, 0);
852         if (IS_ERR(cred))
853                 return (struct dentry *)cred;
854 -       state = nfs4_do_open(dir, dentry, nd->intent.open.flags, &attr, cred);
855 +       state = nfs4_do_open(dir, dentry, nd->intent.flags, &attr, cred);
856         put_rpccred(cred);
857         if (IS_ERR(state)) {
858                 if (PTR_ERR(state) == -ENOENT)
859 Index: LINUX-SRC-TREE/fs/nfsctl.c
860 ===================================================================
861 --- LINUX-SRC-TREE.orig/fs/nfsctl.c
862 +++ LINUX-SRC-TREE/fs/nfsctl.c
863 @@ -26,6 +26,7 @@ static struct file *do_open(char *name, 
864         struct nameidata nd;
865         int error;
866  
867 +       intent_init(&nd.intent, IT_OPEN);
868         nd.mnt = do_kern_mount("nfsd", 0, "nfsd", NULL);
869  
870         if (IS_ERR(nd.mnt))
871 Index: LINUX-SRC-TREE/fs/open.c
872 ===================================================================
873 --- LINUX-SRC-TREE.orig/fs/open.c
874 +++ LINUX-SRC-TREE/fs/open.c
875 @@ -198,9 +198,10 @@ out:
876  }
877  
878  int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
879 -       struct file *filp)
880 +       struct file *filp, int called_from_open)
881  {
882         int err;
883 +       struct inode_operations *op = dentry->d_inode->i_op;
884         struct iattr newattrs;
885  
886         /* Not pretty: "inode->i_size" shouldn't really be signed. But it is. */
887 @@ -215,7 +216,17 @@ int do_truncate(struct dentry *dentry, l
888         }
889  
890         mutex_lock(&dentry->d_inode->i_mutex);
891 -       err = notify_change(dentry, &newattrs);
892 +       if (called_from_open)
893 +                newattrs.ia_valid |= ATTR_FROM_OPEN;
894 +        if (op->setattr_raw) {
895 +                newattrs.ia_valid |= ATTR_RAW;
896 +                newattrs.ia_ctime = CURRENT_TIME;
897 +                down_write(&dentry->d_inode->i_alloc_sem);
898 +                err = op->setattr_raw(dentry->d_inode, &newattrs);
899 +                up_write(&dentry->d_inode->i_alloc_sem);
900 +        } else
901 +                err = notify_change(dentry, &newattrs);
902 +
903         mutex_unlock(&dentry->d_inode->i_mutex);
904         return err;
905  }
906 @@ -225,12 +236,12 @@ static long do_sys_truncate(const char _
907         struct nameidata nd;
908         struct inode * inode;
909         int error;
910 -
911 +       intent_init(&nd.intent, IT_GETATTR);
912         error = -EINVAL;
913         if (length < 0) /* sorry, but loff_t says... */
914                 goto out;
915  
916 -       error = user_path_walk(path, &nd);
917 +       error = user_path_walk_it(path, &nd);
918         if (error)
919                 goto out;
920         inode = nd.dentry->d_inode;
921 @@ -270,7 +281,7 @@ static long do_sys_truncate(const char _
922         error = locks_verify_truncate(inode, NULL, length);
923         if (!error) {
924                 DQUOT_INIT(inode);
925 -               error = do_truncate(nd.dentry, length, 0, NULL);
926 +               error = do_truncate(nd.dentry, length, 0, NULL, 0);
927         }
928         put_write_access(inode);
929  
930 @@ -322,7 +333,7 @@ static long do_sys_ftruncate(unsigned in
931  
932         error = locks_verify_truncate(inode, file, length);
933         if (!error)
934 -               error = do_truncate(dentry, length, 0, file);
935 +               error = do_truncate(dentry, length, 0, file, 0);
936  out_putf:
937         fput(file);
938  out:
939 @@ -407,9 +418,20 @@ asmlinkage long sys_utime(char __user * 
940                     (error = vfs_permission(&nd, MAY_WRITE)) != 0)
941                         goto dput_and_out;
942         }
943 -       mutex_lock(&inode->i_mutex);
944 -       error = notify_change(nd.dentry, &newattrs);
945 -       mutex_unlock(&inode->i_mutex);
946 +       if (inode->i_op->setattr_raw) {
947 +               struct inode_operations *op = nd.dentry->d_inode->i_op;
948 +
949 +               newattrs.ia_valid |= ATTR_RAW;
950 +               error = op->setattr_raw(inode, &newattrs);
951 +               /* the file system wants to use normal vfs path now */
952 +               if (error != -EOPNOTSUPP)
953 +                       goto dput_and_out;
954 +       } else {
955 +               mutex_lock(&inode->i_mutex);
956 +               error = notify_change(nd.dentry, &newattrs);
957 +               mutex_unlock(&inode->i_mutex);
958 +       }
959 +
960  dput_and_out:
961         path_release(&nd);
962  out:
963 @@ -495,6 +517,7 @@ asmlinkage long sys_faccessat(int dfd, c
964         int old_fsuid, old_fsgid;
965         kernel_cap_t old_cap;
966         int res;
967 +       intent_init(&nd.intent, IT_GETATTR);
968  
969         if (mode & ~S_IRWXO)    /* where's F_OK, X_OK, W_OK, R_OK? */
970                 return -EINVAL;
971 @@ -519,7 +542,7 @@ asmlinkage long sys_faccessat(int dfd, c
972         else
973                 current->cap_effective = current->cap_permitted;
974  
975 -       res = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd);
976 +       res = __user_walk_fd_it(dfd, filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd);
977         if (!res) {
978                 res = vfs_permission(&nd, mode);
979                 /* SuS v2 requires we report a read only fs too */
980 @@ -545,8 +568,9 @@ asmlinkage long sys_chdir(const char __u
981  {
982         struct nameidata nd;
983         int error;
984 +       intent_init(&nd.intent, IT_GETATTR);
985  
986 -       error = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &nd);
987 +       error = __user_walk_it(filename, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &nd);
988         if (error)
989                 goto out;
990  
991 @@ -596,8 +620,9 @@ asmlinkage long sys_chroot(const char __
992  {
993         struct nameidata nd;
994         int error;
995 +       intent_init(&nd.intent, IT_GETATTR);
996  
997 -       error = __user_walk(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
998 +       error = __user_walk_it(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
999         if (error)
1000                 goto out;
1001  
1002 @@ -618,38 +643,55 @@ out:
1003         return error;
1004  }
1005  
1006 -asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
1007 +int chmod_common(struct dentry *dentry, mode_t mode)
1008  {
1009 -       struct inode * inode;
1010 -       struct dentry * dentry;
1011 -       struct file * file;
1012 -       int err = -EBADF;
1013 +       struct inode * inode = dentry->d_inode;
1014         struct iattr newattrs;
1015 +       int error = -EROFS;
1016  
1017 -       file = fget(fd);
1018 -       if (!file)
1019 +       if (IS_RDONLY(inode))
1020                 goto out;
1021  
1022 -       dentry = file->f_dentry;
1023 -       inode = dentry->d_inode;
1024 +       if (inode->i_op->setattr_raw) {
1025 +               struct inode_operations *op = dentry->d_inode->i_op;
1026  
1027 -       audit_inode(NULL, inode);
1028 +               newattrs.ia_mode = mode;
1029 +               newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
1030 +               newattrs.ia_valid |= ATTR_RAW;
1031 +               error = op->setattr_raw(inode, &newattrs);
1032 +               /* the file system wants to use normal vfs path now */
1033 +               if (error != -EOPNOTSUPP)
1034 +                       goto out;
1035 +       }
1036  
1037 -       err = -EROFS;
1038 -       if (IS_RDONLY(inode))
1039 -               goto out_putf;
1040 -       err = -EPERM;
1041 +       error = -EPERM;
1042         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
1043 -               goto out_putf;
1044 +               goto out;
1045 +
1046         mutex_lock(&inode->i_mutex);
1047         if (mode == (mode_t) -1)
1048                 mode = inode->i_mode;
1049         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
1050         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
1051 -       err = notify_change(dentry, &newattrs);
1052 +       error = notify_change(dentry, &newattrs);
1053         mutex_unlock(&inode->i_mutex);
1054 +out:
1055 +       return error;
1056 +}
1057 +
1058 +asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
1059 +{
1060 +       struct file * file;
1061 +       int err = -EBADF;
1062 +
1063 +       file = fget(fd);
1064 +       if (!file)
1065 +               goto out;
1066 +
1067 +       audit_inode(NULL, file->f_dentry->d_inode);
1068 +
1069 +       err = chmod_common(file->f_dentry, mode);
1070  
1071 -out_putf:
1072         fput(file);
1073  out:
1074         return err;
1075 @@ -659,32 +701,12 @@ asmlinkage long sys_fchmodat(int dfd, co
1076                              mode_t mode)
1077  {
1078         struct nameidata nd;
1079 -       struct inode * inode;
1080         int error;
1081 -       struct iattr newattrs;
1082  
1083         error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd);
1084         if (error)
1085                 goto out;
1086 -       inode = nd.dentry->d_inode;
1087 -
1088 -       error = -EROFS;
1089 -       if (IS_RDONLY(inode))
1090 -               goto dput_and_out;
1091 -
1092 -       error = -EPERM;
1093 -       if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
1094 -               goto dput_and_out;
1095 -
1096 -       mutex_lock(&inode->i_mutex);
1097 -       if (mode == (mode_t) -1)
1098 -               mode = inode->i_mode;
1099 -       newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
1100 -       newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
1101 -       error = notify_change(nd.dentry, &newattrs);
1102 -       mutex_unlock(&inode->i_mutex);
1103 -
1104 -dput_and_out:
1105 +       error = chmod_common(nd.dentry, mode);
1106         path_release(&nd);
1107  out:
1108         return error;
1109 @@ -710,6 +732,18 @@ static int chown_common(struct dentry * 
1110         if (IS_RDONLY(inode))
1111                 goto out;
1112         error = -EPERM;
1113 +       if (inode->i_op->setattr_raw) {
1114 +               struct inode_operations *op = dentry->d_inode->i_op;
1115 +
1116 +               newattrs.ia_uid = user;
1117 +               newattrs.ia_gid = group;
1118 +               newattrs.ia_valid = ATTR_UID | ATTR_GID | ATTR_CTIME;
1119 +               newattrs.ia_valid |= ATTR_RAW;
1120 +               error = op->setattr_raw(inode, &newattrs);
1121 +               /* the file system wants to use normal vfs path now */
1122 +               if (error != -EOPNOTSUPP)
1123 +                       return error;
1124 +       }
1125         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
1126                 goto out;
1127         newattrs.ia_valid =  ATTR_CTIME;
1128 @@ -823,6 +857,7 @@ static struct file *__dentry_open(struct
1129                 error = open(inode, f);
1130                 if (error)
1131                         goto cleanup_all;
1132 +               intent_release(f->f_it);
1133         }
1134  
1135         f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
1136 @@ -849,6 +884,7 @@ cleanup_all:
1137         f->f_dentry = NULL;
1138         f->f_vfsmnt = NULL;
1139  cleanup_file:
1140 +       intent_release(f->f_it);
1141         put_filp(f);
1142         dput(dentry);
1143         mntput(mnt);
1144 @@ -874,6 +910,7 @@ static struct file *do_filp_open(int dfd
1145  {
1146         int namei_flags, error;
1147         struct nameidata nd;
1148 +       intent_init(&nd.intent, IT_OPEN);
1149  
1150         namei_flags = flags;
1151         if ((namei_flags+1) & O_ACCMODE)
1152 @@ -910,19 +947,19 @@ EXPORT_SYMBOL(filp_open);
1153  struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
1154                 int (*open)(struct inode *, struct file *))
1155  {
1156 -       if (IS_ERR(nd->intent.open.file))
1157 +       if (IS_ERR(nd->intent.file))
1158                 goto out;
1159         if (IS_ERR(dentry))
1160                 goto out_err;
1161 -       nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->mnt),
1162 -                                            nd->intent.open.flags - 1,
1163 -                                            nd->intent.open.file,
1164 +       nd->intent.file = __dentry_open(dget(dentry), mntget(nd->mnt),
1165 +                                            nd->intent.flags - 1,
1166 +                                            nd->intent.file,
1167                                              open);
1168  out:
1169 -       return nd->intent.open.file;
1170 +       return nd->intent.file;
1171  out_err:
1172         release_open_intent(nd);
1173 -       nd->intent.open.file = (struct file *)dentry;
1174 +       nd->intent.file = (struct file *)dentry;
1175         goto out;
1176  }
1177  EXPORT_SYMBOL_GPL(lookup_instantiate_filp);
1178 @@ -939,7 +976,8 @@ struct file *nameidata_to_filp(struct na
1179         struct file *filp;
1180  
1181         /* Pick up the filp from the open intent */
1182 -       filp = nd->intent.open.file;
1183 +       filp = nd->intent.file;
1184 +       filp->f_it = &nd->intent;
1185         /* Has the filesystem initialised the file for us? */
1186         if (filp->f_dentry == NULL)
1187                 filp = __dentry_open(nd->dentry, nd->mnt, flags, filp, NULL);
1188 Index: LINUX-SRC-TREE/fs/stat.c
1189 ===================================================================
1190 --- LINUX-SRC-TREE.orig/fs/stat.c
1191 +++ LINUX-SRC-TREE/fs/stat.c
1192 @@ -38,7 +38,7 @@ void generic_fillattr(struct inode *inod
1193  
1194  EXPORT_SYMBOL(generic_fillattr);
1195  
1196 -int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
1197 +int vfs_getattr_it(struct vfsmount *mnt, struct dentry *dentry, struct lookup_intent *it, struct kstat *stat)
1198  {
1199         struct inode *inode = dentry->d_inode;
1200         int retval;
1201 @@ -47,6 +47,8 @@ int vfs_getattr(struct vfsmount *mnt, st
1202         if (retval)
1203                 return retval;
1204  
1205 +       if (inode->i_op->getattr_it)
1206 +               return inode->i_op->getattr_it(mnt, dentry, it, stat);
1207         if (inode->i_op->getattr)
1208                 return inode->i_op->getattr(mnt, dentry, stat);
1209  
1210 @@ -61,6 +63,11 @@ int vfs_getattr(struct vfsmount *mnt, st
1211         return 0;
1212  }
1213  
1214 +int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
1215 +{
1216 +       return vfs_getattr_it(mnt, dentry, NULL, stat);
1217 +}
1218 +
1219  EXPORT_SYMBOL(vfs_getattr);
1220  
1221  int vfs_stat_fd(int dfd, char __user *name, struct kstat *stat)
1222 @@ -68,9 +75,10 @@ int vfs_stat_fd(int dfd, char __user *na
1223         struct nameidata nd;
1224         int error;
1225  
1226 -       error = __user_walk_fd(dfd, name, LOOKUP_FOLLOW, &nd);
1227 +       intent_init(&nd.intent, IT_GETATTR);
1228 +       error = __user_walk_fd_it(dfd, name, LOOKUP_FOLLOW, &nd);
1229         if (!error) {
1230 -               error = vfs_getattr(nd.mnt, nd.dentry, stat);
1231 +               error = vfs_getattr_it(nd.mnt, nd.dentry, &nd.intent, stat);
1232                 path_release(&nd);
1233         }
1234         return error;
1235 @@ -88,9 +96,10 @@ int vfs_lstat_fd(int dfd, char __user *n
1236         struct nameidata nd;
1237         int error;
1238  
1239 -       error = __user_walk_fd(dfd, name, 0, &nd);
1240 +       intent_init(&nd.intent, IT_GETATTR);
1241 +       error = __user_walk_fd_it(dfd, name, 0, &nd);
1242         if (!error) {
1243 -               error = vfs_getattr(nd.mnt, nd.dentry, stat);
1244 +               error = vfs_getattr_it(nd.mnt, nd.dentry, &nd.intent, stat);
1245                 path_release(&nd);
1246         }
1247         return error;
1248 @@ -107,9 +116,12 @@ int vfs_fstat(unsigned int fd, struct ks
1249  {
1250         struct file *f = fget(fd);
1251         int error = -EBADF;
1252 +       struct nameidata nd;
1253 +       intent_init(&nd.intent, IT_GETATTR);
1254  
1255         if (f) {
1256 -               error = vfs_getattr(f->f_vfsmnt, f->f_dentry, stat);
1257 +               error = vfs_getattr_it(f->f_vfsmnt, f->f_dentry, &nd.intent, stat);
1258 +               intent_release(&nd.intent);
1259                 fput(f);
1260         }
1261         return error;
1262 Index: LINUX-SRC-TREE/include/linux/dcache.h
1263 ===================================================================
1264 --- LINUX-SRC-TREE.orig/include/linux/dcache.h
1265 +++ LINUX-SRC-TREE/include/linux/dcache.h
1266 @@ -36,6 +36,9 @@ struct qstr {
1267         const unsigned char *name;
1268  };
1269  
1270 +struct inode;
1271 +#include <linux/namei.h>
1272 +
1273  struct dentry_stat_t {
1274         int nr_dentry;
1275         int nr_unused;
1276 Index: LINUX-SRC-TREE/include/linux/fs.h
1277 ===================================================================
1278 --- LINUX-SRC-TREE.orig/include/linux/fs.h
1279 +++ LINUX-SRC-TREE/include/linux/fs.h
1280 @@ -61,6 +61,7 @@ extern int dir_notify_enable;
1281  
1282  #define FMODE_READ 1
1283  #define FMODE_WRITE 2
1284 +#define FMODE_EXEC 16
1285  
1286  /* Internal kernel extensions */
1287  #define FMODE_LSEEK    4
1288 @@ -272,6 +273,8 @@ typedef void (dio_iodone_t)(struct kiocb
1289  #define ATTR_KILL_SUID 2048
1290  #define ATTR_KILL_SGID 4096
1291  #define ATTR_FILE      8192
1292 +#define ATTR_RAW               16384   /* file system, not vfs will massage attrs */
1293 +#define ATTR_FROM_OPEN         65536   /* called from open path, ie O_TRUNC */
1294  #define ATTR_NO_BLOCK  32768   /* Return EAGAIN and don't block on long truncates */
1295  
1296  /*
1297 @@ -517,6 +520,7 @@ struct inode {
1298         struct block_device     *i_bdev;
1299         struct cdev             *i_cdev;
1300         int                     i_cindex;
1301 +       void                    *i_filterdata;
1302  
1303         __u32                   i_generation;
1304  
1305 @@ -664,6 +668,7 @@ struct file {
1306         spinlock_t              f_ep_lock;
1307  #endif /* #ifdef CONFIG_EPOLL */
1308         struct address_space    *f_mapping;
1309 +       struct lookup_intent    *f_it;
1310  };
1311  extern spinlock_t files_lock;
1312  #define file_list_lock() spin_lock(&files_lock);
1313 @@ -1059,20 +1064,29 @@ struct inode_operations {
1314         int (*create) (struct inode *,struct dentry *,int, struct nameidata *);
1315         struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *);
1316         int (*link) (struct dentry *,struct inode *,struct dentry *);
1317 +       int (*link_raw) (struct nameidata *,struct nameidata *);
1318         int (*unlink) (struct inode *,struct dentry *);
1319 +       int (*unlink_raw) (struct nameidata *);
1320         int (*symlink) (struct inode *,struct dentry *,const char *);
1321 +       int (*symlink_raw) (struct nameidata *,const char *);
1322         int (*mkdir) (struct inode *,struct dentry *,int);
1323 +       int (*mkdir_raw) (struct nameidata *,int);
1324         int (*rmdir) (struct inode *,struct dentry *);
1325 +       int (*rmdir_raw) (struct nameidata *);
1326         int (*mknod) (struct inode *,struct dentry *,int,dev_t);
1327 +       int (*mknod_raw) (struct nameidata *,int,dev_t);
1328         int (*rename) (struct inode *, struct dentry *,
1329                         struct inode *, struct dentry *);
1330 +       int (*rename_raw) (struct nameidata *, struct nameidata *);
1331         int (*readlink) (struct dentry *, char __user *,int);
1332         void * (*follow_link) (struct dentry *, struct nameidata *);
1333         void (*put_link) (struct dentry *, struct nameidata *, void *);
1334         void (*truncate) (struct inode *);
1335         int (*permission) (struct inode *, int, struct nameidata *);
1336         int (*setattr) (struct dentry *, struct iattr *);
1337 +       int (*setattr_raw) (struct inode *, struct iattr *);
1338         int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
1339 +       int (*getattr_it) (struct vfsmount *, struct dentry *, struct lookup_intent *, struct kstat *);
1340         int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
1341         ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
1342         ssize_t (*listxattr) (struct dentry *, char *, size_t);
1343 @@ -1113,6 +1127,7 @@ struct super_operations {
1344         int (*remount_fs) (struct super_block *, int *, char *);
1345         void (*clear_inode) (struct inode *);
1346         void (*umount_begin) (struct super_block *);
1347 +       void (*umount_lustre) (struct super_block *);
1348  
1349         int (*show_options)(struct seq_file *, struct vfsmount *);
1350  
1351 @@ -1322,6 +1337,7 @@ extern int may_umount_tree(struct vfsmou
1352  extern int may_umount(struct vfsmount *);
1353  extern void umount_tree(struct vfsmount *, int, struct list_head *);
1354  extern void release_mounts(struct list_head *);
1355 +struct vfsmount *do_kern_mount(const char *type, int flags, const char *name, void *data);
1356  extern long do_mount(char *, char *, char *, unsigned long, void *);
1357  extern struct vfsmount *copy_tree(struct vfsmount *, struct dentry *, int);
1358  extern void mnt_set_mountpoint(struct vfsmount *, struct dentry *,
1359 @@ -1378,11 +1394,12 @@ static inline int break_lease(struct ino
1360  /* fs/open.c */
1361  
1362  extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
1363 -                      struct file *filp);
1364 +                      struct file *filp, int called_from_open);
1365  extern long do_sys_open(int fdf, const char __user *filename, int flags,
1366                         int mode);
1367  extern struct file *filp_open(const char *, int, int);
1368  extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
1369 +extern struct file * dentry_open_it(struct dentry *, struct vfsmount *, int, struct lookup_intent *);
1370  extern int filp_close(struct file *, fl_owner_t id);
1371  extern char * getname(const char __user *);
1372  
1373 Index: LINUX-SRC-TREE/include/linux/mount.h
1374 ===================================================================
1375 --- LINUX-SRC-TREE.orig/include/linux/mount.h
1376 +++ LINUX-SRC-TREE/include/linux/mount.h
1377 @@ -46,6 +46,8 @@ struct vfsmount {
1378         struct list_head mnt_slave;     /* slave list entry */
1379         struct vfsmount *mnt_master;    /* slave is on master->mnt_slave_list */
1380         struct namespace *mnt_namespace; /* containing namespace */
1381 +       struct list_head mnt_lustre_list; /* GNS mount list */
1382 +       unsigned long mnt_last_used;    /* for GNS auto-umount (jiffies) */
1383         int mnt_pinned;
1384  };
1385  
1386 Index: LINUX-SRC-TREE/include/linux/namei.h
1387 ===================================================================
1388 --- LINUX-SRC-TREE.orig/include/linux/namei.h
1389 +++ LINUX-SRC-TREE/include/linux/namei.h
1390 @@ -5,10 +5,39 @@
1391  
1392  struct vfsmount;
1393  
1394 +#define IT_OPEN                (1)
1395 +#define IT_CREAT       (1<<1)
1396 +#define IT_READDIR     (1<<2)
1397 +#define IT_GETATTR     (1<<3)
1398 +#define IT_LOOKUP      (1<<4)
1399 +#define IT_UNLINK      (1<<5)
1400 +#define IT_TRUNC       (1<<6)
1401 +#define IT_GETXATTR    (1<<7)
1402 +
1403 +struct lustre_intent_data {
1404 +       int     it_disposition;
1405 +       int     it_status;
1406 +       __u64   it_lock_handle;
1407 +       void    *it_data;
1408 +       int     it_lock_mode;
1409 +};
1410 +
1411 +#define INTENT_MAGIC 0x19620323
1412 +
1413 +#define it_flags flags
1414 +#define it_create_mode create_mode
1415 +#define lookup_intent open_intent
1416 +
1417  struct open_intent {
1418 -       int     flags;
1419 -       int     create_mode;
1420 -       struct file *file;
1421 +               int     it_magic;
1422 +               void    (*it_op_release)(struct open_intent *);
1423 +               int     it_op;
1424 +               int     flags;
1425 +               int     create_mode;
1426 +       struct  file *file;
1427 +               union {
1428 +                struct lustre_intent_data lustre;
1429 +               } d;
1430  };
1431  
1432  enum { MAX_NESTED_LINKS = 8 };
1433 @@ -22,12 +51,23 @@ struct nameidata {
1434         unsigned        depth;
1435         char *saved_names[MAX_NESTED_LINKS + 1];
1436  
1437 -       /* Intent data */
1438 -       union {
1439 -               struct open_intent open;
1440 -       } intent;
1441 +       struct lookup_intent intent;
1442  };
1443  
1444 +static inline void intent_reset_fs_part(struct lookup_intent *it)
1445 +{
1446 +        memset(&it->d, 0, sizeof(it->d));
1447 +        it->it_magic = INTENT_MAGIC;
1448 +        it->it_op_release = NULL;
1449 +}
1450 +
1451 +static inline void intent_init(struct lookup_intent *it, int op)
1452 +{
1453 +       memset(it, 0, sizeof(*it));
1454 +       it->it_magic = INTENT_MAGIC;
1455 +       it->it_op = op;
1456 +}
1457 +
1458  /*
1459   * Type of the last component on LOOKUP_PARENT
1460   */
1461 @@ -48,6 +88,8 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LA
1462  #define LOOKUP_PARENT          16
1463  #define LOOKUP_NOALT           32
1464  #define LOOKUP_REVAL           64
1465 +#define LOOKUP_LAST            (0x1000)
1466 +#define LOOKUP_LINK_NOTLAST    (0x2000)
1467  /*
1468   * Intent data
1469   */
1470 @@ -57,18 +99,29 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LA
1471  
1472  extern int FASTCALL(__user_walk(const char __user *, unsigned, struct nameidata *));
1473  extern int FASTCALL(__user_walk_fd(int dfd, const char __user *, unsigned, struct nameidata *));
1474 +extern int FASTCALL(__user_walk_fd_it(int dfd, const char __user *, unsigned, struct nameidata *));
1475  #define user_path_walk(name,nd) \
1476         __user_walk_fd(AT_FDCWD, name, LOOKUP_FOLLOW, nd)
1477  #define user_path_walk_link(name,nd) \
1478         __user_walk_fd(AT_FDCWD, name, 0, nd)
1479 +
1480 +extern int FASTCALL(__user_walk_it(const char __user *name, unsigned flags, struct nameidata *nd));
1481 +#define user_path_walk_it(name,nd) \
1482 +       __user_walk_it(name, LOOKUP_FOLLOW, nd)
1483 +#define user_path_walk_link_it(name,nd) \
1484 +       __user_walk_it(name, 0, nd)
1485 +extern void intent_release(struct lookup_intent *);
1486 +
1487  extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
1488 +extern int FASTCALL(path_lookup_it(const char *, unsigned, struct nameidata *));
1489  extern int FASTCALL(path_walk(const char *, struct nameidata *));
1490  extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
1491  extern void path_release(struct nameidata *);
1492  extern void path_release_on_umount(struct nameidata *);
1493  
1494  extern int __user_path_lookup_open(const char __user *, unsigned lookup_flags, struct nameidata *nd, int open_flags);
1495 -extern int path_lookup_open(int dfd, const char *name, unsigned lookup_flags, struct nameidata *, int open_flags);
1496 +extern int path_lookup_open(int dfd, const char *name, unsigned lookup_flags, struct nameidata *, 
1497 +                           int open_flags, int create_mode);
1498  extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
1499                 int (*open)(struct inode *, struct file *));
1500  extern struct file *nameidata_to_filp(struct nameidata *nd, int flags);