1 --- lum-pristine/include/linux/dcache.h Thu Nov 22 14:46:18 2001
2 +++ lum/include/linux/dcache.h Fri Jun 14 03:03:17 2002
4 #include <asm/atomic.h>
5 #include <linux/mount.h>
8 +#define IT_CREAT (1<<1)
9 +#define IT_MKDIR (1<<2)
10 +#define IT_LINK (1<<3)
11 +#define IT_SYMLINK (1<<4)
12 +#define IT_UNLINK (1<<5)
13 +#define IT_RMDIR (1<<6)
14 +#define IT_RENAME (1<<7)
15 +#define IT_RENAME2 (1<<8)
16 +#define IT_READDIR (1<<9)
17 +#define IT_GETATTR (1<<10)
18 +#define IT_SETATTR (1<<11)
19 +#define IT_READLINK (1<<12)
20 +#define IT_MKNOD (1<<13)
22 +struct lookup_intent {
27 + struct iattr *it_iattr;
28 + __u64 it_lock_handle[2];
34 * linux/include/linux/dcache.h
37 struct dentry_operations *d_op;
38 struct super_block * d_sb; /* The root of the dentry tree */
39 unsigned long d_vfs_flags;
40 + struct lookup_intent *d_it;
41 void * d_fsdata; /* fs-specific data */
42 unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
45 struct dentry_operations {
46 int (*d_revalidate)(struct dentry *, int);
47 + int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
48 int (*d_hash) (struct dentry *, struct qstr *);
49 int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);
50 int (*d_delete)(struct dentry *);
51 void (*d_release)(struct dentry *);
52 void (*d_iput)(struct dentry *, struct inode *);
53 + void (*d_intent_release)(struct dentry *);
56 /* the dentry parameter passed to d_hash and d_compare is the parent
57 --- lum-pristine/include/linux/fs.h Fri Jun 14 13:54:00 2002
58 +++ lum/include/linux/fs.h Fri Jun 14 03:04:28 2002
61 /* needed for tty driver, and maybe others */
63 + struct lookup_intent *f_intent;
65 /* preallocated helper kiobuf to speedup O_DIRECT */
66 struct kiobuf *f_iobuf;
68 extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
69 extern int vfs_rmdir(struct inode *, struct dentry *);
70 extern int vfs_unlink(struct inode *, struct dentry *);
71 -extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
72 +int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
73 + struct inode *new_dir, struct dentry *new_dentry,
74 + struct lookup_intent *it);
79 struct inode_operations {
80 int (*create) (struct inode *,struct dentry *,int);
81 struct dentry * (*lookup) (struct inode *,struct dentry *);
82 + struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *);
83 int (*link) (struct dentry *,struct inode *,struct dentry *);
84 int (*unlink) (struct inode *,struct dentry *);
85 int (*symlink) (struct inode *,struct dentry *,const char *);
87 extern struct vfsmount *kern_mount(struct file_system_type *);
88 extern int may_umount(struct vfsmount *);
89 extern long do_mount(char *, char *, char *, unsigned long, void *);
91 +struct vfsmount *do_kern_mount(char *type, int flags, char *name, void *data);
92 #define kern_umount mntput
94 extern int vfs_statfs(struct super_block *, struct statfs *);
96 extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
98 extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
99 +extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
100 extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
101 extern int FASTCALL(path_walk(const char *, struct nameidata *));
102 extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
103 @@ -1317,6 +1322,8 @@
104 extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
105 #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
106 #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
107 +#define user_path_walk_it(name,nd,it) __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
108 +#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
110 extern void iput(struct inode *);
111 extern void force_delete(struct inode *);
112 --- lum-pristine/fs/dcache.c Mon Feb 25 14:38:08 2002
113 +++ lum/fs/dcache.c Fri Jun 14 14:03:03 2002
116 dentry->d_fsdata = NULL;
117 dentry->d_mounted = 0;
118 + dentry->d_it = NULL;
119 INIT_LIST_HEAD(&dentry->d_hash);
120 INIT_LIST_HEAD(&dentry->d_lru);
121 INIT_LIST_HEAD(&dentry->d_subdirs);
122 --- lum-pristine/fs/namei.c Mon Feb 25 14:38:09 2002
123 +++ lum/fs/namei.c Fri Jun 14 13:49:06 2002
125 * XEmacs seems to be relying on it...
128 +void intent_release(struct dentry *de)
130 + if (de->d_op && de->d_op->d_intent_release)
131 + de->d_op->d_intent_release(de);
136 /* In order to reduce some races, while at the same time doing additional
137 * checking and hopefully speeding things up, we copy filenames to the
138 * kernel data space before using them..
139 @@ -260,10 +268,18 @@
140 * Internal lookup() using the new generic dcache.
143 -static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
144 +static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags, struct lookup_intent *it)
146 struct dentry * dentry = d_lookup(parent, name);
148 + if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
149 + if (!dentry->d_op->d_revalidate2(dentry, flags, it) && !d_invalidate(dentry)) {
156 if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
157 if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
160 * make sure that nobody added the entry to the dcache in the meantime..
163 -static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
164 +static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags, struct lookup_intent *it)
166 struct dentry * result;
167 struct inode *dir = parent->d_inode;
169 result = ERR_PTR(-ENOMEM);
172 + if (dir->i_op->lookup2)
173 + result = dir->i_op->lookup2(dir, dentry, it);
175 result = dir->i_op->lookup(dir, dentry);
179 result = ERR_PTR(-ENOENT);
182 + if (result->d_op && result->d_op->d_revalidate2) {
183 + if (!result->d_op->d_revalidate2(result, flags, it) && !d_invalidate(result)) {
185 + result = ERR_PTR(-ENOENT);
193 * We expect 'base' to be positive and a directory.
195 -int link_path_walk(const char * name, struct nameidata *nd)
196 +int link_path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
198 struct dentry *dentry;
203 /* This does the actual lookups.. */
204 - dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
205 + dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
207 - dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
208 + dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
209 err = PTR_ERR(dentry);
216 - if (!inode->i_op->lookup)
217 + if (!inode->i_op->lookup && !inode->i_op->lookup2)
220 /* here ends the main loop */
225 - dentry = cached_lookup(nd->dentry, &this, 0);
226 + dentry = cached_lookup(nd->dentry, &this, 0, it);
228 - dentry = real_lookup(nd->dentry, &this, 0);
229 + dentry = real_lookup(nd->dentry, &this, 0, it);
230 err = PTR_ERR(dentry);
235 if (lookup_flags & LOOKUP_DIRECTORY) {
237 - if (!inode->i_op || !inode->i_op->lookup)
238 + if (!inode->i_op || (!inode->i_op->lookup &&
239 + !inode->i_op->lookup2))
244 else if (this.len == 2 && this.name[1] == '.')
245 nd->last_type = LAST_DOTDOT;
247 + nd->dentry->d_it = it;
251 @@ -633,15 +660,29 @@
256 + nd->dentry->d_it = it;
260 +int link_path_walk(const char * name, struct nameidata *nd)
262 + return link_path_walk_it(name, nd, NULL);
265 +int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
267 + current->total_link_count = 0;
268 + return link_path_walk_it(name, nd, it);
271 int path_walk(const char * name, struct nameidata *nd)
273 current->total_link_count = 0;
274 - return link_path_walk(name, nd);
275 + return link_path_walk_it(name, nd, NULL);
280 /* returns 1 if everything is done */
281 static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
283 * needs parent already locked. Doesn't follow mounts.
286 -struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
287 +struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base,
288 + struct lookup_intent *it)
290 struct dentry * dentry;
292 @@ -765,13 +807,16 @@
296 - dentry = cached_lookup(base, name, 0);
297 + dentry = cached_lookup(base, name, 0, it);
299 struct dentry *new = d_alloc(base, name);
300 dentry = ERR_PTR(-ENOMEM);
304 + if (inode->i_op->lookup2)
305 + dentry = inode->i_op->lookup2(inode, new, it);
307 dentry = inode->i_op->lookup(inode, new);
314 +struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
316 + return lookup_hash_it(name, base, NULL);
321 struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
325 this.hash = end_name_hash(hash);
327 - return lookup_hash(&this, base);
328 + return lookup_hash_it(&this, base, NULL);
330 return ERR_PTR(-EACCES);
336 +int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd, struct lookup_intent *it)
341 + tmp = getname(name);
342 + err = PTR_ERR(tmp);
343 + if (!IS_ERR(tmp)) {
345 + if (path_init(tmp, flags, nd))
346 + err = path_walk_it(tmp, nd, it);
353 * It's inline, so penalty for filesystems that don't use sticky bit is
356 * for symlinks (where the permissions are checked later).
359 -int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
360 +int open_namei_it(const char * pathname, int flag, int mode, struct nameidata *nd,
361 + struct lookup_intent *it)
363 int acc_mode, error = 0;
365 @@ -984,17 +1052,21 @@
366 * The simplest case - just a plain lookup.
368 if (!(flag & O_CREAT)) {
370 if (path_init(pathname, lookup_flags(flag), nd))
371 - error = path_walk(pathname, nd);
372 + error = path_walk_it(pathname, nd, it);
381 * Create - we need to know the parent.
384 + it->it_op |= IT_CREAT;
385 if (path_init(pathname, LOOKUP_PARENT, nd))
386 error = path_walk(pathname, nd);
388 @@ -1011,7 +1083,7 @@
391 down(&dir->d_inode->i_sem);
392 - dentry = lookup_hash(&nd->last, nd->dentry);
393 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
396 error = PTR_ERR(dentry);
397 @@ -1022,6 +1094,7 @@
399 /* Negative dentry, just create the file */
400 if (!dentry->d_inode) {
402 error = vfs_create(dir->d_inode, dentry,
403 mode & ~current->fs->umask);
404 up(&dir->d_inode->i_sem);
405 @@ -1136,9 +1209,11 @@
406 if (flag & FMODE_WRITE)
409 + intent_release(dentry);
413 + intent_release(dentry);
417 @@ -1181,13 +1256,20 @@
420 down(&dir->d_inode->i_sem);
421 - dentry = lookup_hash(&nd->last, nd->dentry);
422 + dentry = lookup_hash_it(&nd->last, nd->dentry, NULL);
423 putname(nd->last.name);
427 +int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
429 + return open_namei_it(pathname, flag, mode, nd, NULL);
434 -static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
435 +static struct dentry *lookup_create(struct nameidata *nd, int is_dir,
436 + struct lookup_intent *it)
438 struct dentry *dentry;
440 @@ -1195,7 +1277,7 @@
441 dentry = ERR_PTR(-EEXIST);
442 if (nd->last_type != LAST_NORM)
444 - dentry = lookup_hash(&nd->last, nd->dentry);
445 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
448 if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
449 @@ -1241,6 +1323,7 @@
451 struct dentry * dentry;
453 + struct lookup_intent it = { IT_MKNOD , mode };
457 @@ -1252,11 +1335,12 @@
458 error = path_walk(tmp, &nd);
461 - dentry = lookup_create(&nd, 0);
462 + dentry = lookup_create(&nd, 0, &it);
463 error = PTR_ERR(dentry);
465 mode &= ~current->fs->umask;
466 if (!IS_ERR(dentry)) {
467 + dentry->d_it = ⁢
468 switch (mode & S_IFMT) {
469 case 0: case S_IFREG:
470 error = vfs_create(nd.dentry->d_inode,dentry,mode);
471 @@ -1272,6 +1356,7 @@
475 + intent_release(dentry);
476 up(&nd.dentry->d_inode->i_sem);
479 @@ -1310,6 +1395,7 @@
483 + struct lookup_intent it = { IT_MKDIR, mode };
485 tmp = getname(pathname);
486 error = PTR_ERR(tmp);
487 @@ -1321,13 +1407,15 @@
488 error = path_walk(tmp, &nd);
491 - dentry = lookup_create(&nd, 1);
492 + dentry = lookup_create(&nd, 1, &it);
493 error = PTR_ERR(dentry);
494 if (!IS_ERR(dentry)) {
495 + dentry->d_it = ⁢
496 error = vfs_mkdir(nd.dentry->d_inode, dentry,
497 mode & ~current->fs->umask);
500 + intent_release(dentry);
501 up(&nd.dentry->d_inode->i_sem);
504 @@ -1407,6 +1495,7 @@
506 struct dentry *dentry;
508 + struct lookup_intent it = { IT_RMDIR, 0 };
510 name = getname(pathname);
512 @@ -1429,10 +1518,12 @@
515 down(&nd.dentry->d_inode->i_sem);
516 - dentry = lookup_hash(&nd.last, nd.dentry);
517 + dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
518 error = PTR_ERR(dentry);
519 if (!IS_ERR(dentry)) {
520 + dentry->d_it = ⁢
521 error = vfs_rmdir(nd.dentry->d_inode, dentry);
522 + intent_release(dentry);
525 up(&nd.dentry->d_inode->i_sem);
526 @@ -1476,6 +1567,7 @@
528 struct dentry *dentry;
530 + struct lookup_intent it = { IT_UNLINK, 0 };
532 name = getname(pathname);
534 @@ -1489,14 +1581,16 @@
535 if (nd.last_type != LAST_NORM)
537 down(&nd.dentry->d_inode->i_sem);
538 - dentry = lookup_hash(&nd.last, nd.dentry);
539 + dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
540 error = PTR_ERR(dentry);
541 if (!IS_ERR(dentry)) {
542 + dentry->d_it = ⁢
543 /* Why not before? Because we want correct error value */
544 if (nd.last.name[nd.last.len])
546 error = vfs_unlink(nd.dentry->d_inode, dentry);
548 + intent_release(dentry);
551 up(&nd.dentry->d_inode->i_sem);
552 @@ -1543,6 +1637,7 @@
556 + struct lookup_intent it = { IT_SYMLINK, 0 };
558 from = getname(oldname);
560 @@ -1557,12 +1652,14 @@
561 error = path_walk(to, &nd);
564 - dentry = lookup_create(&nd, 0);
565 + dentry = lookup_create(&nd, 0, &it);
566 error = PTR_ERR(dentry);
567 if (!IS_ERR(dentry)) {
568 + dentry->d_it = ⁢
569 error = vfs_symlink(nd.dentry->d_inode, dentry, from);
572 + intent_release(dentry);
573 up(&nd.dentry->d_inode->i_sem);
576 @@ -1626,6 +1723,7 @@
580 + struct lookup_intent it = { IT_LINK, 0 };
582 from = getname(oldname);
584 @@ -1648,12 +1746,14 @@
586 if (old_nd.mnt != nd.mnt)
588 - new_dentry = lookup_create(&nd, 0);
589 + new_dentry = lookup_create(&nd, 0, &it);
590 error = PTR_ERR(new_dentry);
591 if (!IS_ERR(new_dentry)) {
592 + new_dentry->d_it = ⁢
593 error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
596 + intent_release(new_dentry);
597 up(&nd.dentry->d_inode->i_sem);
600 @@ -1694,7 +1794,8 @@
603 int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
604 - struct inode *new_dir, struct dentry *new_dentry)
605 + struct inode *new_dir, struct dentry *new_dentry,
606 + struct lookup_intent *it)
609 struct inode *target;
610 @@ -1748,12 +1849,14 @@
612 double_down(&old_dir->i_zombie,
614 + new_dentry->d_it = it;
615 if (IS_DEADDIR(old_dir)||IS_DEADDIR(new_dir))
617 else if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
620 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
621 + intent_release(new_dentry);
624 target->i_flags |= S_DEAD;
625 @@ -1775,7 +1878,8 @@
628 int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
629 - struct inode *new_dir, struct dentry *new_dentry)
630 + struct inode *new_dir, struct dentry *new_dentry,
631 + struct lookup_intent *it)
635 @@ -1802,10 +1906,12 @@
638 double_down(&old_dir->i_zombie, &new_dir->i_zombie);
639 + new_dentry->d_it = it;
640 if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
643 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
644 + intent_release(new_dentry);
645 double_up(&old_dir->i_zombie, &new_dir->i_zombie);
648 @@ -1817,13 +1923,14 @@
651 int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
652 - struct inode *new_dir, struct dentry *new_dentry)
653 + struct inode *new_dir, struct dentry *new_dentry,
654 + struct lookup_intent *it)
657 if (S_ISDIR(old_dentry->d_inode->i_mode))
658 - error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
659 + error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry, it);
661 - error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
662 + error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry, it);
664 if (old_dir == new_dir)
665 inode_dir_notify(old_dir, DN_RENAME);
666 @@ -1841,6 +1948,7 @@
667 struct dentry * old_dir, * new_dir;
668 struct dentry * old_dentry, *new_dentry;
669 struct nameidata oldnd, newnd;
670 + struct lookup_intent it = {IT_RENAME, 0};
672 if (path_init(oldname, LOOKUP_PARENT, &oldnd))
673 error = path_walk(oldname, &oldnd);
674 @@ -1868,7 +1976,9 @@
676 double_lock(new_dir, old_dir);
678 - old_dentry = lookup_hash(&oldnd.last, old_dir);
679 + it.it_op = IT_RENAME;
681 + old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it);
682 error = PTR_ERR(old_dentry);
683 if (IS_ERR(old_dentry))
685 @@ -1884,14 +1994,15 @@
686 if (newnd.last.name[newnd.last.len])
689 - new_dentry = lookup_hash(&newnd.last, new_dir);
690 + it.it_op = IT_RENAME2;
691 + new_dentry = lookup_hash_it(&newnd.last, new_dir, &it);
692 error = PTR_ERR(new_dentry);
693 if (IS_ERR(new_dentry))
697 error = vfs_rename(old_dir->d_inode, old_dentry,
698 - new_dir->d_inode, new_dentry);
699 + new_dir->d_inode, new_dentry, &it);
703 --- lum-pristine/fs/open.c Fri Oct 12 16:48:42 2001
704 +++ lum/fs/open.c Thu Jun 13 20:22:44 2002
706 #include <asm/uaccess.h>
708 #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
709 +extern int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it);
710 +extern void intent_release(struct dentry *de);
712 int vfs_statfs(struct super_block *sb, struct statfs *buf)
716 struct inode * inode;
718 + struct lookup_intent it;
720 + it.it_op = IT_SETATTR;
724 if (length < 0) /* sorry, but loff_t says... */
727 - error = user_path_walk(path, &nd);
728 + error = user_path_walk_it(path, &nd, &it);
731 + nd.dentry->d_it = ⁢
732 inode = nd.dentry->d_inode;
734 /* For directories it's -EISDIR, for other non-regulars - -EINVAL */
736 put_write_access(inode);
739 + intent_release(nd.dentry);
743 @@ -235,10 +243,14 @@
745 struct inode * inode;
746 struct iattr newattrs;
747 + struct lookup_intent it;
749 + it.it_op = IT_SETATTR;
751 - error = user_path_walk(filename, &nd);
752 + error = user_path_walk_it(filename, &nd, &it);
755 + nd.dentry->d_it = ⁢
756 inode = nd.dentry->d_inode;
761 error = notify_change(nd.dentry, &newattrs);
763 + intent_release(nd.dentry);
767 @@ -279,11 +292,15 @@
769 struct inode * inode;
770 struct iattr newattrs;
771 + struct lookup_intent it;
773 + it.it_op = IT_SETATTR;
775 - error = user_path_walk(filename, &nd);
776 + error = user_path_walk_it(filename, &nd, &it);
780 + nd.dentry->d_it = ⁢
781 inode = nd.dentry->d_inode;
786 error = notify_change(nd.dentry, &newattrs);
788 + intent_release(nd.dentry);
793 int old_fsuid, old_fsgid;
794 kernel_cap_t old_cap;
796 + struct lookup_intent it;
798 + it.it_op = IT_GETATTR;
800 if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
804 current->cap_effective = current->cap_permitted;
806 - res = user_path_walk(filename, &nd);
807 + res = user_path_walk_it(filename, &nd, &it);
809 res = permission(nd.dentry->d_inode, mode);
810 /* SuS v2 requires we report a read only fs too */
815 + struct lookup_intent it;
817 + it.it_op = IT_GETATTR;
819 name = getname(filename);
820 error = PTR_ERR(name);
821 @@ -369,11 +393,12 @@
824 if (path_init(name,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd))
825 - error = path_walk(name, &nd);
826 + error = path_walk_it(name, &nd, &it);
831 + nd.dentry->d_it = ⁢
832 error = permission(nd.dentry->d_inode,MAY_EXEC);
836 set_fs_pwd(current->fs, nd.mnt, nd.dentry);
839 + intent_release(nd.dentry);
847 + struct lookup_intent it;
849 + it.it_op = IT_GETATTR;
851 name = getname(filename);
852 error = PTR_ERR(name);
853 @@ -429,11 +458,12 @@
855 path_init(name, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
856 LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
857 - error = path_walk(name, &nd);
858 + error = path_walk_it(name, &nd, &it);
863 + nd.dentry->d_it = ⁢
864 error = permission(nd.dentry->d_inode,MAY_EXEC);
871 + intent_release(nd.dentry);
875 @@ -490,12 +521,15 @@
876 struct inode * inode;
878 struct iattr newattrs;
879 + struct lookup_intent it;
881 - error = user_path_walk(filename, &nd);
882 + it.it_op = IT_SETATTR;
883 + error = user_path_walk_it(filename, &nd, &it);
886 inode = nd.dentry->d_inode;
888 + nd.dentry->d_it = ⁢
890 if (IS_RDONLY(inode))
893 error = notify_change(nd.dentry, &newattrs);
896 + intent_release(nd.dentry);
900 @@ -580,10 +615,15 @@
904 + struct lookup_intent it;
906 + it.it_op = IT_SETATTR;
908 - error = user_path_walk(filename, &nd);
909 + error = user_path_walk_it(filename, &nd, &it);
911 + nd.dentry->d_it = ⁢
912 error = chown_common(nd.dentry, user, group);
913 + intent_release(nd.dentry);
917 @@ -593,10 +633,15 @@
921 + struct lookup_intent it;
923 - error = user_path_walk_link(filename, &nd);
924 + it.it_op = IT_SETATTR;
926 + error = user_path_walk_link_it(filename, &nd, &it);
928 + nd.dentry->d_it = ⁢
929 error = chown_common(nd.dentry, user, group);
930 + intent_release(nd.dentry);
934 @@ -630,10 +675,15 @@
935 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
938 +extern int open_namei_it(const char *filename, int namei_flags, int mode,
939 + struct nameidata *nd, struct lookup_intent *it);
940 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, int flags, struct lookup_intent *it);
942 struct file *filp_open(const char * filename, int flags, int mode)
944 int namei_flags, error;
946 + struct lookup_intent it = {IT_OPEN, 0};
949 if ((namei_flags+1) & O_ACCMODE)
950 @@ -641,14 +691,14 @@
951 if (namei_flags & O_TRUNC)
954 - error = open_namei(filename, namei_flags, mode, &nd);
955 + error = open_namei_it(filename, namei_flags, mode, &nd, &it);
957 - return dentry_open(nd.dentry, nd.mnt, flags);
958 + return dentry_open_it(nd.dentry, nd.mnt, flags, &it);
960 return ERR_PTR(error);
963 -struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
964 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, int flags, struct lookup_intent *it)
968 @@ -705,11 +755,19 @@
972 + intent_release(dentry);
975 return ERR_PTR(error);
978 +struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
980 + return dentry_open_it(dentry, mnt, flags, NULL);
986 * Find an empty file descriptor entry, and mark it busy.
988 --- lum-pristine/fs/stat.c Thu Sep 13 19:04:43 2001
989 +++ lum/fs/stat.c Fri Jun 14 01:51:11 2002
992 #include <asm/uaccess.h>
994 +extern void intent_release(struct dentry *de);
997 * Revalidate the inode. This is required for proper NFS attribute caching.
999 @@ -135,13 +137,15 @@
1000 asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf)
1002 struct nameidata nd;
1003 + struct lookup_intent it = {IT_GETATTR, 0};
1006 - error = user_path_walk(filename, &nd);
1007 + error = user_path_walk_it(filename, &nd, &it);
1009 error = do_revalidate(nd.dentry);
1011 error = cp_old_stat(nd.dentry->d_inode, statbuf);
1012 + intent_release(nd.dentry);
1016 @@ -151,13 +155,15 @@
1017 asmlinkage long sys_newstat(char * filename, struct stat * statbuf)
1019 struct nameidata nd;
1020 + struct lookup_intent it = {IT_GETATTR, 0};
1023 - error = user_path_walk(filename, &nd);
1024 + error = user_path_walk_it(filename, &nd, &it);
1026 error = do_revalidate(nd.dentry);
1028 error = cp_new_stat(nd.dentry->d_inode, statbuf);
1029 + intent_release(nd.dentry);
1033 @@ -172,13 +178,15 @@
1034 asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf)
1036 struct nameidata nd;
1037 + struct lookup_intent it = {IT_GETATTR, 0};
1040 - error = user_path_walk_link(filename, &nd);
1041 + error = user_path_walk_link_it(filename, &nd, &it);
1043 error = do_revalidate(nd.dentry);
1045 error = cp_old_stat(nd.dentry->d_inode, statbuf);
1046 + intent_release(nd.dentry);
1050 @@ -189,13 +197,15 @@
1051 asmlinkage long sys_newlstat(char * filename, struct stat * statbuf)
1053 struct nameidata nd;
1054 + struct lookup_intent it = {IT_GETATTR, 0};
1057 - error = user_path_walk_link(filename, &nd);
1058 + error = user_path_walk_link_it(filename, &nd, &it);
1060 error = do_revalidate(nd.dentry);
1062 error = cp_new_stat(nd.dentry->d_inode, statbuf);
1063 + intent_release(nd.dentry);
1067 @@ -247,20 +257,22 @@
1069 struct nameidata nd;
1071 + struct lookup_intent it;
1072 + it.it_op = IT_READLINK;
1077 - error = user_path_walk_link(path, &nd);
1078 + error = user_path_walk_link_it(path, &nd, &it);
1080 struct inode * inode = nd.dentry->d_inode;
1083 if (inode->i_op && inode->i_op->readlink &&
1084 !(error = do_revalidate(nd.dentry))) {
1085 UPDATE_ATIME(inode);
1086 error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
1088 + intent_release(nd.dentry);
1092 @@ -333,12 +345,15 @@
1094 struct nameidata nd;
1096 + struct lookup_intent it;
1097 + it.it_op = IT_GETATTR;
1099 - error = user_path_walk(filename, &nd);
1100 + error = user_path_walk_it(filename, &nd, &it);
1102 error = do_revalidate(nd.dentry);
1104 error = cp_new_stat64(nd.dentry->d_inode, statbuf);
1105 + intent_release(nd.dentry);
1109 @@ -348,12 +363,15 @@
1111 struct nameidata nd;
1113 + struct lookup_intent it;
1114 + it.it_op = IT_GETATTR;
1116 - error = user_path_walk_link(filename, &nd);
1117 + error = user_path_walk_link_it(filename, &nd, &it);
1119 error = do_revalidate(nd.dentry);
1121 error = cp_new_stat64(nd.dentry->d_inode, statbuf);
1122 + intent_release(nd.dentry);
1126 @@ -363,6 +381,10 @@
1130 + struct lookup_intent it;
1132 + memset(&it, 0, sizeof(it));
1133 + it.it_op = IT_GETATTR;