Whamcloud - gitweb
- make HEAD from b_post_cmd3
[fs/lustre-release.git] / lustre / kernel_patches / patches / vfs_intent-2.6.18-vanilla.patch
1 Index: linux-2.6/fs/inode.c
2 ===================================================================
3 --- linux-2.6.orig/fs/inode.c   2006-08-31 11:17:39.000000000 +0800
4 +++ linux-2.6/fs/inode.c        2006-08-31 11:23:48.000000000 +0800
5 @@ -234,6 +234,7 @@ void __iget(struct inode * inode)
6         inodes_stat.nr_unused--;
7  }
8  
9 +EXPORT_SYMBOL(__iget);
10  /**
11   * clear_inode - clear an inode
12   * @inode: inode to clear
13 Index: linux-2.6/fs/open.c
14 ===================================================================
15 --- linux-2.6.orig/fs/open.c    2006-08-31 11:17:39.000000000 +0800
16 +++ linux-2.6/fs/open.c 2006-08-31 11:59:09.000000000 +0800
17 @@ -226,11 +226,12 @@ static long do_sys_truncate(const char _
18         struct inode * inode;
19         int error;
20  
21 +       intent_init(&nd.intent.open, IT_GETATTR);
22         error = -EINVAL;
23         if (length < 0) /* sorry, but loff_t says... */
24                 goto out;
25  
26 -       error = user_path_walk(path, &nd);
27 +       error = user_path_walk_it(path, &nd);
28         if (error)
29                 goto out;
30         inode = nd.dentry->d_inode;
31 @@ -495,6 +496,7 @@ asmlinkage long sys_faccessat(int dfd, c
32         int old_fsuid, old_fsgid;
33         kernel_cap_t old_cap;
34         int res;
35 +       intent_init(&nd.intent.open, IT_GETATTR);
36  
37         if (mode & ~S_IRWXO)    /* where's F_OK, X_OK, W_OK, R_OK? */
38                 return -EINVAL;
39 @@ -519,7 +521,7 @@ asmlinkage long sys_faccessat(int dfd, c
40         else
41                 current->cap_effective = current->cap_permitted;
42  
43 -       res = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd);
44 +       res = __user_walk_fd_it(dfd, filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd);
45         if (!res) {
46                 res = vfs_permission(&nd, mode);
47                 /* SuS v2 requires we report a read only fs too */
48 @@ -545,8 +547,9 @@ asmlinkage long sys_chdir(const char __u
49  {
50         struct nameidata nd;
51         int error;
52 +       intent_init(&nd.intent.open, IT_GETATTR);
53  
54 -       error = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &nd);
55 +       error = __user_walk_it(filename, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &nd);
56         if (error)
57                 goto out;
58  
59 @@ -596,8 +599,9 @@ asmlinkage long sys_chroot(const char __
60  {
61         struct nameidata nd;
62         int error;
63 +       intent_init(&nd.intent.open, IT_GETATTR);
64  
65 -       error = __user_walk(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
66 +       error = __user_walk_it(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
67         if (error)
68                 goto out;
69  
70 @@ -823,6 +827,7 @@ static struct file *__dentry_open(struct
71                 error = open(inode, f);
72                 if (error)
73                         goto cleanup_all;
74 +               intent_release(f->f_it);
75         }
76  
77         f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
78 @@ -849,6 +854,7 @@ cleanup_all:
79         f->f_dentry = NULL;
80         f->f_vfsmnt = NULL;
81  cleanup_file:
82 +       intent_release(f->f_it);
83         put_filp(f);
84         dput(dentry);
85         mntput(mnt);
86 @@ -874,6 +880,7 @@ static struct file *do_filp_open(int dfd
87  {
88         int namei_flags, error;
89         struct nameidata nd;
90 +       intent_init(&nd.intent.open, IT_OPEN);
91  
92         namei_flags = flags;
93         if ((namei_flags+1) & O_ACCMODE)
94 @@ -944,6 +951,7 @@ struct file *nameidata_to_filp(struct na
95  
96         /* Pick up the filp from the open intent */
97         filp = nd->intent.open.file;
98 +       filp->f_it = &nd->intent.open;
99         /* Has the filesystem initialised the file for us? */
100         if (filp->f_dentry == NULL)
101                 filp = __dentry_open(nd->dentry, nd->mnt, flags, filp, NULL);
102 Index: linux-2.6/fs/nfsctl.c
103 ===================================================================
104 --- linux-2.6.orig/fs/nfsctl.c  2006-08-31 11:17:39.000000000 +0800
105 +++ linux-2.6/fs/nfsctl.c       2006-08-31 11:23:48.000000000 +0800
106 @@ -25,6 +25,7 @@ static struct file *do_open(char *name, 
107         struct nameidata nd;
108         int error;
109  
110 +       intent_init(&nd.intent.open, IT_OPEN);
111         nd.mnt = do_kern_mount("nfsd", 0, "nfsd", NULL);
112  
113         if (IS_ERR(nd.mnt))
114 Index: linux-2.6/fs/namei.c
115 ===================================================================
116 --- linux-2.6.orig/fs/namei.c   2006-08-31 11:17:39.000000000 +0800
117 +++ linux-2.6/fs/namei.c        2006-08-31 11:59:09.000000000 +0800
118 @@ -344,8 +344,19 @@ int deny_write_access(struct file * file
119         return 0;
120  }
121  
122 +void intent_release(struct lookup_intent *it)
123 +{
124 +       if (!it)
125 +               return;
126 +       if (it->it_magic != INTENT_MAGIC)
127 +               return;
128 +       if (it->it_op_release)
129 +               it->it_op_release(it);
130 +}
131 +
132  void path_release(struct nameidata *nd)
133  {
134 +       intent_release(&nd->intent);
135         dput(nd->dentry);
136         mntput(nd->mnt);
137  }
138 @@ -447,8 +458,12 @@ static struct dentry * real_lookup(struc
139  {
140         struct dentry * result;
141         struct inode *dir = parent->d_inode;
142 +       int counter = 0;
143  
144         mutex_lock(&dir->i_mutex);
145 +again:
146 +       counter++;
147 +
148         /*
149          * First re-do the cached lookup just in case it was created
150          * while we waited for the directory semaphore..
151 @@ -482,13 +497,16 @@ static struct dentry * real_lookup(struc
152          * Uhhuh! Nasty case: the cache was re-populated while
153          * we waited on the semaphore. Need to revalidate.
154          */
155 -       mutex_unlock(&dir->i_mutex);
156         if (result->d_op && result->d_op->d_revalidate) {
157                 if (!result->d_op->d_revalidate(result, nd) && !d_invalidate(result)) {
158                         dput(result);
159 -                       result = ERR_PTR(-ENOENT);
160 +                       if (counter > 10)
161 +                               result = ERR_PTR(-ESTALE);
162 +                       if (!IS_ERR(result))
163 +                               goto again;
164                 }
165         }
166 +       mutex_unlock(&dir->i_mutex);
167         return result;
168  }
169  
170 @@ -516,7 +534,9 @@ walk_init_root(const char *name, struct 
171  static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *link)
172  {
173         int res = 0;
174 +       struct lookup_intent it = nd->intent.open;
175         char *name;
176 +
177         if (IS_ERR(link))
178                 goto fail;
179  
180 @@ -526,6 +546,10 @@ static __always_inline int __vfs_follow_
181                         /* weird __emul_prefix() stuff did it */
182                         goto out;
183         }
184 +       intent_init(&nd->intent.open, it.it_op);
185 +       nd->intent.open.it_flags = it.it_flags;
186 +       nd->intent.open.it_create_mode = it.it_create_mode;
187 +       nd->intent.open.file = it.file;
188         res = link_path_walk(link, nd);
189  out:
190         if (nd->depth || res || nd->last_type!=LAST_NORM)
191 @@ -778,6 +802,33 @@ fail:
192         return PTR_ERR(dentry);
193  }
194  
195 +static int revalidate_special(struct nameidata *nd)
196 +{
197 +       struct dentry *dentry = nd->dentry;
198 +       int err, counter = 0;
199 +
200 + revalidate_again:
201 +       if (!dentry->d_op || !dentry->d_op->d_revalidate)
202 +               return 0;
203 +       if (!dentry->d_op->d_revalidate(dentry, nd)) {
204 +               struct dentry *new;
205 +               if ((err = permission(dentry->d_parent->d_inode, MAY_EXEC, nd)))
206 +                       return err;
207 +               new = real_lookup(dentry->d_parent, &dentry->d_name, nd);
208 +               if (IS_ERR(new))
209 +                       return PTR_ERR(new);
210 +               d_invalidate(dentry);
211 +               dput(dentry);
212 +               nd->dentry = dentry = new;
213 +               counter++;
214 +               if (counter < 10)
215 +                       goto revalidate_again;
216 +               printk("excessive revalidate_it loops\n");
217 +               return -ESTALE;
218 +       }
219 +       return 0;
220 +}
221 +
222  /*
223   * Name resolution.
224   * This is the basic name resolution function, turning a pathname into
225 @@ -874,7 +925,11 @@ static fastcall int __link_path_walk(con
226                         goto out_dput;
227  
228                 if (inode->i_op->follow_link) {
229 +                       int save_flags = nd->flags;
230 +                       nd->flags |= LOOKUP_LINK_NOTLAST;
231                         err = do_follow_link(&next, nd);
232 +                       if (!(save_flags & LOOKUP_LINK_NOTLAST))
233 +                               nd->flags &= ~LOOKUP_LINK_NOTLAST;
234                         if (err)
235                                 goto return_err;
236                         err = -ENOENT;
237 @@ -909,6 +964,23 @@ last_component:
238                                 inode = nd->dentry->d_inode;
239                                 /* fallthrough */
240                         case 1:
241 +                               nd->flags |= LOOKUP_LAST;
242 +                               err = revalidate_special(nd);
243 +                               nd->flags &= ~LOOKUP_LAST;
244 +                               if (!nd->dentry->d_inode)
245 +                                       err = -ENOENT;
246 +                               if (err) {
247 +                                       path_release(nd);
248 +                                       goto return_err;
249 +                               }
250 +                               if (lookup_flags & LOOKUP_DIRECTORY) {
251 +                                       err = -ENOTDIR;
252 +                                       if(!nd->dentry->d_inode->i_op ||
253 +                                         !nd->dentry->d_inode->i_op->lookup) {
254 +                                               path_release(nd);
255 +                                               goto return_err;
256 +                                       }
257 +                               }
258                                 goto return_reval;
259                 }
260                 if (nd->dentry->d_op && nd->dentry->d_op->d_hash) {
261 @@ -916,7 +988,9 @@ last_component:
262                         if (err < 0)
263                                 break;
264                 }
265 +               nd->flags |= LOOKUP_LAST;
266                 err = do_lookup(nd, &this, &next);
267 +               nd->flags &= ~LOOKUP_LAST;
268                 if (err)
269                         break;
270                 inode = next.dentry->d_inode;
271 @@ -1268,7 +1342,7 @@ static struct dentry *lookup_hash(struct
272  }
273  
274  /* SMP-safe */
275 -struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
276 +struct dentry * lookup_one_len_it(const char * name, struct dentry * base, int len, struct nameidata *nd)
277  {
278         unsigned long hash;
279         struct qstr this;
280 @@ -1288,11 +1362,17 @@ struct dentry * lookup_one_len(const cha
281         }
282         this.hash = end_name_hash(hash);
283  
284 -       return __lookup_hash(&this, base, NULL);
285 +       return __lookup_hash(&this, base, nd);
286  access:
287         return ERR_PTR(-EACCES);
288  }
289  
290 +struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
291 +{
292 +       return lookup_one_len_it(name, base, len, NULL);
293 +}
294 +
295 +
296  /*
297   *     namei()
298   *
299 @@ -1304,8 +1384,9 @@ access:
300   * that namei follows links, while lnamei does not.
301   * SMP-safe
302   */
303 -int fastcall __user_walk_fd(int dfd, const char __user *name, unsigned flags,
304 -                           struct nameidata *nd)
305 +
306 +int fastcall __user_walk_fd_it(int dfd, const char __user *name, unsigned flags,
307 +                              struct nameidata *nd)
308  {
309         char *tmp = getname(name);
310         int err = PTR_ERR(tmp);
311 @@ -1317,9 +1398,22 @@ int fastcall __user_walk_fd(int dfd, con
312         return err;
313  }
314  
315 +int fastcall __user_walk_fd(int dfd, const char __user *name, unsigned flags,
316 +                           struct nameidata *nd)
317 +{
318 +       intent_init(&nd->intent.open, IT_LOOKUP);
319 +       return __user_walk_fd_it(dfd, name, flags, nd);
320 +}
321 +
322 +int fastcall __user_walk_it(const char __user *name, unsigned flags, struct nameidata *nd)
323 +{
324 +       return __user_walk_fd_it(AT_FDCWD, name, flags, nd);
325 +}
326 +
327  int fastcall __user_walk(const char __user *name, unsigned flags, struct nameidata *nd)
328  {
329 -       return __user_walk_fd(AT_FDCWD, name, flags, nd);
330 +       intent_init(&nd->intent.open, IT_LOOKUP);
331 +       return __user_walk_it(name, flags, nd);
332  }
333  
334  /*
335 @@ -1600,6 +1694,8 @@ int open_namei(int dfd, const char *path
336         if (flag & O_APPEND)
337                 acc_mode |= MAY_APPEND;
338  
339 +       nd->intent.open.it_flags = flag;
340 +       nd->intent.open.it_create_mode = mode;
341         /*
342          * The simplest case - just a plain lookup.
343          */
344 @@ -1614,6 +1710,7 @@ int open_namei(int dfd, const char *path
345         /*
346          * Create - we need to know the parent.
347          */
348 +       nd->intent.open.it_op |= IT_CREAT;
349         error = path_lookup_create(dfd,pathname,LOOKUP_PARENT,nd,flag,mode);
350         if (error)
351                 return error;
352 @@ -1630,7 +1727,9 @@ int open_namei(int dfd, const char *path
353         dir = nd->dentry;
354         nd->flags &= ~LOOKUP_PARENT;
355         mutex_lock(&dir->d_inode->i_mutex);
356 +       nd->flags |= LOOKUP_LAST;
357         path.dentry = lookup_hash(nd);
358 +       nd->flags &= ~LOOKUP_LAST;
359         path.mnt = nd->mnt;
360  
361  do_last:
362 @@ -1746,7 +1845,9 @@ do_link:
363         }
364         dir = nd->dentry;
365         mutex_lock(&dir->d_inode->i_mutex);
366 +       nd->flags |= LOOKUP_LAST;
367         path.dentry = lookup_hash(nd);
368 +       nd->flags &= ~LOOKUP_LAST;
369         path.mnt = nd->mnt;
370         __putname(nd->last.name);
371         goto do_last;
372 @@ -2260,6 +2361,9 @@ asmlinkage long sys_linkat(int olddfd, c
373         int error;
374         char * to;
375  
376 +       intent_init(&nd.intent.open, IT_LOOKUP);
377 +       intent_init(&old_nd.intent.open, IT_LOOKUP);
378 +
379         if ((flags & ~AT_SYMLINK_FOLLOW) != 0)
380                 return -EINVAL;
381  
382 @@ -2267,7 +2371,7 @@ asmlinkage long sys_linkat(int olddfd, c
383         if (IS_ERR(to))
384                 return PTR_ERR(to);
385  
386 -       error = __user_walk_fd(olddfd, oldname,
387 +       error = __user_walk_fd_it(olddfd, oldname,
388                                flags & AT_SYMLINK_FOLLOW ? LOOKUP_FOLLOW : 0,
389                                &old_nd);
390         if (error)
391 Index: linux-2.6/fs/stat.c
392 ===================================================================
393 --- linux-2.6.orig/fs/stat.c    2006-08-31 11:17:39.000000000 +0800
394 +++ linux-2.6/fs/stat.c 2006-08-31 11:23:48.000000000 +0800
395 @@ -37,7 +37,7 @@ void generic_fillattr(struct inode *inod
396  
397  EXPORT_SYMBOL(generic_fillattr);
398  
399 -int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
400 +int vfs_getattr_it(struct vfsmount *mnt, struct dentry *dentry, struct lookup_intent *it, struct kstat *stat)
401  {
402         struct inode *inode = dentry->d_inode;
403         int retval;
404 @@ -46,6 +46,8 @@ int vfs_getattr(struct vfsmount *mnt, st
405         if (retval)
406                 return retval;
407  
408 +       if (inode->i_op->getattr_it)
409 +               return inode->i_op->getattr_it(mnt, dentry, it, stat);
410         if (inode->i_op->getattr)
411                 return inode->i_op->getattr(mnt, dentry, stat);
412  
413 @@ -60,6 +62,11 @@ int vfs_getattr(struct vfsmount *mnt, st
414         return 0;
415  }
416  
417 +int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
418 +{
419 +       return vfs_getattr_it(mnt, dentry, NULL, stat);
420 +}
421 +
422  EXPORT_SYMBOL(vfs_getattr);
423  
424  int vfs_stat_fd(int dfd, char __user *name, struct kstat *stat)
425 @@ -67,9 +74,10 @@ int vfs_stat_fd(int dfd, char __user *na
426         struct nameidata nd;
427         int error;
428  
429 -       error = __user_walk_fd(dfd, name, LOOKUP_FOLLOW, &nd);
430 +       intent_init(&nd.intent.open, IT_GETATTR);
431 +       error = __user_walk_fd_it(dfd, name, LOOKUP_FOLLOW, &nd);
432         if (!error) {
433 -               error = vfs_getattr(nd.mnt, nd.dentry, stat);
434 +               error = vfs_getattr_it(nd.mnt, nd.dentry, &nd.intent.open, stat);
435                 path_release(&nd);
436         }
437         return error;
438 @@ -87,9 +95,10 @@ int vfs_lstat_fd(int dfd, char __user *n
439         struct nameidata nd;
440         int error;
441  
442 -       error = __user_walk_fd(dfd, name, 0, &nd);
443 +       intent_init(&nd.intent.open, IT_GETATTR);
444 +       error = __user_walk_fd_it(dfd, name, 0, &nd);
445         if (!error) {
446 -               error = vfs_getattr(nd.mnt, nd.dentry, stat);
447 +               error = vfs_getattr_it(nd.mnt, nd.dentry, &nd.intent.open, stat);
448                 path_release(&nd);
449         }
450         return error;
451 @@ -106,9 +115,12 @@ int vfs_fstat(unsigned int fd, struct ks
452  {
453         struct file *f = fget(fd);
454         int error = -EBADF;
455 +       struct nameidata nd;
456 +       intent_init(&nd.intent.open, IT_GETATTR);
457  
458         if (f) {
459 -               error = vfs_getattr(f->f_vfsmnt, f->f_dentry, stat);
460 +               error = vfs_getattr_it(f->f_vfsmnt, f->f_dentry, &nd.intent.open, stat);
461 +               intent_release(&nd.intent.open);
462                 fput(f);
463         }
464         return error;
465 Index: linux-2.6/fs/namespace.c
466 ===================================================================
467 --- linux-2.6.orig/fs/namespace.c       2006-08-31 11:17:39.000000000 +0800
468 +++ linux-2.6/fs/namespace.c    2006-08-31 11:59:07.000000000 +0800
469 @@ -73,6 +73,7 @@ struct vfsmount *alloc_vfsmnt(const char
470                 INIT_LIST_HEAD(&mnt->mnt_share);
471                 INIT_LIST_HEAD(&mnt->mnt_slave_list);
472                 INIT_LIST_HEAD(&mnt->mnt_slave);
473 +               INIT_LIST_HEAD(&mnt->mnt_lustre_list);
474                 if (name) {
475                         int size = strlen(name) + 1;
476                         char *newname = kmalloc(size, GFP_KERNEL);
477 @@ -162,6 +163,7 @@ static void __touch_namespace(struct nam
478  
479  static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd)
480  {
481 +       memset(old_nd, 0, sizeof(*old_nd));
482         old_nd->dentry = mnt->mnt_mountpoint;
483         old_nd->mnt = mnt->mnt_parent;
484         mnt->mnt_parent = mnt;
485 @@ -280,6 +282,9 @@ static inline void __mntput(struct vfsmo
486  {
487         struct super_block *sb = mnt->mnt_sb;
488         dput(mnt->mnt_root);
489 +       spin_lock(&dcache_lock);
490 +       list_del(&mnt->mnt_lustre_list);
491 +       spin_unlock(&dcache_lock);
492         free_vfsmnt(mnt);
493         deactivate_super(sb);
494  }
495 @@ -582,6 +587,8 @@ static int do_umount(struct vfsmount *mn
496          */
497  
498         lock_kernel();
499 +       if (sb->s_op->umount_lustre)
500 +               sb->s_op->umount_lustre(sb);
501         if (sb->s_op->umount_begin)
502                 sb->s_op->umount_begin(mnt, flags);
503         unlock_kernel();
504 @@ -914,6 +921,7 @@ static int do_loopback(struct nameidata 
505                 return err;
506         if (!old_name || !*old_name)
507                 return -EINVAL;
508 +       intent_init(&old_nd.intent.open, IT_LOOKUP);
509         err = path_lookup(old_name, LOOKUP_FOLLOW, &old_nd);
510         if (err)
511                 return err;
512 @@ -999,6 +1007,7 @@ static int do_move_mount(struct nameidat
513                 return -EPERM;
514         if (!old_name || !*old_name)
515                 return -EINVAL;
516 +       intent_init(&old_nd.intent.open, IT_LOOKUP);
517         err = path_lookup(old_name, LOOKUP_FOLLOW, &old_nd);
518         if (err)
519                 return err;
520 @@ -1388,6 +1397,7 @@ long do_mount(char *dev_name, char *dir_
521         int retval = 0;
522         int mnt_flags = 0;
523  
524 +       intent_init(&nd.intent.open, IT_LOOKUP);
525         /* Discard magic */
526         if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
527                 flags &= ~MS_MGC_MSK;
528 Index: linux-2.6/fs/exec.c
529 ===================================================================
530 --- linux-2.6.orig/fs/exec.c    2006-08-31 11:17:39.000000000 +0800
531 +++ linux-2.6/fs/exec.c 2006-08-31 11:59:09.000000000 +0800
532 @@ -127,6 +127,7 @@ asmlinkage long sys_uselib(const char __
533         struct nameidata nd;
534         int error;
535  
536 +       intent_init(&nd.intent.open, IT_OPEN);
537         error = __user_path_lookup_open(library, LOOKUP_FOLLOW, &nd, FMODE_READ|FMODE_EXEC);
538         if (error)
539                 goto out;
540 @@ -477,6 +478,7 @@ struct file *open_exec(const char *name)
541         int err;
542         struct file *file;
543  
544 +       intent_init(&nd.intent.open, IT_OPEN);
545         err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd, FMODE_READ|FMODE_EXEC);
546         file = ERR_PTR(err);
547  
548 Index: linux-2.6/include/linux/dcache.h
549 ===================================================================
550 --- linux-2.6.orig/include/linux/dcache.h       2006-08-31 11:17:39.000000000 +0800
551 +++ linux-2.6/include/linux/dcache.h    2006-08-31 12:00:07.000000000 +0800
552 @@ -36,6 +36,9 @@ struct qstr {
553         const unsigned char *name;
554  };
555  
556 +struct inode;
557 +#include <linux/namei.h>
558 +
559  struct dentry_stat_t {
560         int nr_dentry;
561         int nr_unused;
562 Index: linux-2.6/include/linux/fs.h
563 ===================================================================
564 --- linux-2.6.orig/include/linux/fs.h   2006-08-31 11:17:39.000000000 +0800
565 +++ linux-2.6/include/linux/fs.h        2006-08-31 11:59:09.000000000 +0800
566 @@ -280,6 +280,8 @@ typedef void (dio_iodone_t)(struct kiocb
567  #define ATTR_KILL_SUID 2048
568  #define ATTR_KILL_SGID 4096
569  #define ATTR_FILE      8192
570 +#define ATTR_RAW               16384    /* file system, not vfs will massage attrs */
571 +#define ATTR_FROM_OPEN         32768    /* called from open path, ie O_TRUNC */
572  
573  /*
574   * This is the Inode Attributes structure, used for notify_change().  It
575 @@ -533,6 +535,7 @@ struct inode {
576         struct block_device     *i_bdev;
577         struct cdev             *i_cdev;
578         int                     i_cindex;
579 +       void                    *i_filterdata;
580  
581         __u32                   i_generation;
582  
583 @@ -700,6 +703,7 @@ struct file {
584         spinlock_t              f_ep_lock;
585  #endif /* #ifdef CONFIG_EPOLL */
586         struct address_space    *f_mapping;
587 +       struct lookup_intent    *f_it;
588  };
589  extern spinlock_t files_lock;
590  #define file_list_lock() spin_lock(&files_lock);
591 @@ -1100,7 +1104,9 @@ struct inode_operations {
592         void (*truncate) (struct inode *);
593         int (*permission) (struct inode *, int, struct nameidata *);
594         int (*setattr) (struct dentry *, struct iattr *);
595 +       int (*setattr_raw) (struct inode *, struct iattr *);
596         int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
597 +       int (*getattr_it) (struct vfsmount *, struct dentry *, struct lookup_intent *, struct kstat *);
598         int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
599         ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
600         ssize_t (*listxattr) (struct dentry *, char *, size_t);
601 @@ -1141,6 +1147,7 @@ struct super_operations {
602         int (*remount_fs) (struct super_block *, int *, char *);
603         void (*clear_inode) (struct inode *);
604         void (*umount_begin) (struct vfsmount *, int);
605 +       void (*umount_lustre) (struct super_block *);
606  
607         int (*show_options)(struct seq_file *, struct vfsmount *);
608         int (*show_stats)(struct seq_file *, struct vfsmount *);
609 @@ -1363,6 +1370,7 @@ extern int may_umount_tree(struct vfsmou
610  extern int may_umount(struct vfsmount *);
611  extern void umount_tree(struct vfsmount *, int, struct list_head *);
612  extern void release_mounts(struct list_head *);
613 +struct vfsmount *do_kern_mount(const char *type, int flags, const char *name, void *data);
614  extern long do_mount(char *, char *, char *, unsigned long, void *);
615  extern struct vfsmount *copy_tree(struct vfsmount *, struct dentry *, int);
616  extern void mnt_set_mountpoint(struct vfsmount *, struct dentry *,
617 @@ -1424,6 +1432,7 @@ extern long do_sys_open(int fdf, const c
618                         int mode);
619  extern struct file *filp_open(const char *, int, int);
620  extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
621 +extern struct file * dentry_open_it(struct dentry *, struct vfsmount *, int, struct lookup_intent *);
622  extern int filp_close(struct file *, fl_owner_t id);
623  extern char * getname(const char __user *);
624  
625 Index: linux-2.6/include/linux/namei.h
626 ===================================================================
627 --- linux-2.6.orig/include/linux/namei.h        2006-08-31 11:17:39.000000000 +0800
628 +++ linux-2.6/include/linux/namei.h     2006-08-31 11:23:48.000000000 +0800
629 @@ -5,10 +5,39 @@
630  
631  struct vfsmount;
632  
633 +#define IT_OPEN                (1)
634 +#define IT_CREAT       (1<<1)
635 +#define IT_READDIR     (1<<2)
636 +#define IT_GETATTR     (1<<3)
637 +#define IT_LOOKUP      (1<<4)
638 +#define IT_UNLINK      (1<<5)
639 +#define IT_TRUNC       (1<<6)
640 +#define IT_GETXATTR    (1<<7)
641 +
642 +struct lustre_intent_data {
643 +       int     it_disposition;
644 +       int     it_status;
645 +       __u64   it_lock_handle;
646 +       void    *it_data;
647 +       int     it_lock_mode;
648 +};
649 +
650 +#define INTENT_MAGIC 0x19620323
651 +
652 +#define it_flags flags
653 +#define it_create_mode create_mode
654 +#define lookup_intent open_intent
655 +
656  struct open_intent {
657 -       int     flags;
658 -       int     create_mode;
659 -       struct file *file;
660 +               int     it_magic;
661 +               void    (*it_op_release)(struct open_intent *);
662 +               int     it_op;
663 +               int     flags;
664 +               int     create_mode;
665 +       struct  file *file;
666 +               union {
667 +                struct lustre_intent_data lustre;
668 +               } d;
669  };
670  
671  enum { MAX_NESTED_LINKS = 8 };
672 @@ -28,6 +57,13 @@ struct nameidata {
673         } intent;
674  };
675  
676 +static inline void intent_init(struct lookup_intent *it, int op)
677 +{
678 +       memset(it, 0, sizeof(*it));
679 +       it->it_magic = INTENT_MAGIC;
680 +       it->it_op = op;
681 +}
682 +
683  /*
684   * Type of the last component on LOOKUP_PARENT
685   */
686 @@ -48,6 +84,8 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LA
687  #define LOOKUP_PARENT          16
688  #define LOOKUP_NOALT           32
689  #define LOOKUP_REVAL           64
690 +#define LOOKUP_LAST            (0x1000)
691 +#define LOOKUP_LINK_NOTLAST    (0x2000)
692  /*
693   * Intent data
694   */
695 @@ -57,10 +95,19 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LA
696  
697  extern int FASTCALL(__user_walk(const char __user *, unsigned, struct nameidata *));
698  extern int FASTCALL(__user_walk_fd(int dfd, const char __user *, unsigned, struct nameidata *));
699 +extern int FASTCALL(__user_walk_fd_it(int dfd, const char __user *, unsigned, struct nameidata *));
700  #define user_path_walk(name,nd) \
701         __user_walk_fd(AT_FDCWD, name, LOOKUP_FOLLOW, nd)
702  #define user_path_walk_link(name,nd) \
703         __user_walk_fd(AT_FDCWD, name, 0, nd)
704 +
705 +extern int FASTCALL(__user_walk_it(const char __user *name, unsigned flags, struct nameidata *nd));
706 +#define user_path_walk_it(name,nd) \
707 +       __user_walk_it(name, LOOKUP_FOLLOW, nd)
708 +#define user_path_walk_link_it(name,nd) \
709 +       __user_walk_it(name, 0, nd)
710 +extern void intent_release(struct lookup_intent *);
711 +
712  extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
713  extern int FASTCALL(path_walk(const char *, struct nameidata *));
714  extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
715 Index: linux-2.6/include/linux/mount.h
716 ===================================================================
717 --- linux-2.6.orig/include/linux/mount.h        2006-08-31 11:17:40.000000000 +0800
718 +++ linux-2.6/include/linux/mount.h     2006-08-31 11:23:48.000000000 +0800
719 @@ -53,6 +53,8 @@ struct vfsmount {
720         struct list_head mnt_slave;     /* slave list entry */
721         struct vfsmount *mnt_master;    /* slave is on master->mnt_slave_list */
722         struct namespace *mnt_namespace; /* containing namespace */
723 +       struct list_head mnt_lustre_list; /* GNS mount list */
724 +       unsigned long mnt_last_used;    /* for GNS auto-umount (jiffies) */
725         int mnt_pinned;
726  };
727