3 --- linux-2.4.20-rh/fs/dcache.c~vfs_intent-2.4.20-rh 2003-04-11 14:04:58.000000000 +0800
4 +++ linux-2.4.20-rh-root/fs/dcache.c 2003-06-09 23:18:07.000000000 +0800
5 @@ -186,6 +186,13 @@ int d_invalidate(struct dentry * dentry)
6 spin_unlock(&dcache_lock);
10 + /* network invalidation by Lustre */
11 + if (dentry->d_flags & DCACHE_LUSTRE_INVALID) {
12 + spin_unlock(&dcache_lock);
17 * Check whether to do a partial shrink_dcache
18 * to get rid of unused child entries.
19 @@ -624,6 +631,7 @@ struct dentry * d_alloc(struct dentry *
20 dentry->d_fsdata = NULL;
21 dentry->d_extra_attributes = NULL;
22 dentry->d_mounted = 0;
23 + dentry->d_it = NULL;
24 dentry->d_cookie = NULL;
25 INIT_LIST_HEAD(&dentry->d_hash);
26 INIT_LIST_HEAD(&dentry->d_lru);
27 @@ -839,13 +847,19 @@ void d_delete(struct dentry * dentry)
28 * Adds a dentry to the hash according to its name.
31 -void d_rehash(struct dentry * entry)
32 +void __d_rehash(struct dentry * entry, int lock)
34 struct list_head *list = d_hash(entry->d_parent, entry->d_name.hash);
35 if (!list_empty(&entry->d_hash)) BUG();
36 - spin_lock(&dcache_lock);
37 + if (lock) spin_lock(&dcache_lock);
38 list_add(&entry->d_hash, list);
39 - spin_unlock(&dcache_lock);
40 + if (lock) spin_unlock(&dcache_lock);
42 +EXPORT_SYMBOL(__d_rehash);
44 +void d_rehash(struct dentry * entry)
46 + __d_rehash(entry, 1);
49 #define do_switch(x,y) do { \
50 --- linux-2.4.20-rh/fs/namei.c~vfs_intent-2.4.20-rh 2003-04-11 14:04:57.000000000 +0800
51 +++ linux-2.4.20-rh-root/fs/namei.c 2003-06-09 23:18:07.000000000 +0800
53 * XEmacs seems to be relying on it...
56 +void intent_release(struct dentry *de, struct lookup_intent *it)
58 + if (it && de->d_op && de->d_op->d_intent_release)
59 + de->d_op->d_intent_release(de, it);
63 /* In order to reduce some races, while at the same time doing additional
64 * checking and hopefully speeding things up, we copy filenames to the
65 * kernel data space before using them..
66 @@ -260,10 +267,19 @@ void path_release(struct nameidata *nd)
67 * Internal lookup() using the new generic dcache.
70 -static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
71 +static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name,
72 + int flags, struct lookup_intent *it)
74 struct dentry * dentry = d_lookup(parent, name);
76 + if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
77 + if (!dentry->d_op->d_revalidate2(dentry, flags, it) &&
78 + !d_invalidate(dentry)) {
84 if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
85 if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
87 @@ -281,11 +297,14 @@ static struct dentry * cached_lookup(str
88 * make sure that nobody added the entry to the dcache in the meantime..
91 -static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
92 +static struct dentry *real_lookup(struct dentry *parent, struct qstr *name,
93 + int flags, struct lookup_intent *it)
95 struct dentry * result;
96 struct inode *dir = parent->d_inode;
102 * First re-do the cached lookup just in case it was created
103 @@ -300,6 +319,9 @@ static struct dentry * real_lookup(struc
104 result = ERR_PTR(-ENOMEM);
107 + if (dir->i_op->lookup2)
108 + result = dir->i_op->lookup2(dir, dentry, it);
110 result = dir->i_op->lookup(dir, dentry);
113 @@ -321,6 +343,12 @@ static struct dentry * real_lookup(struc
115 result = ERR_PTR(-ENOENT);
117 + } else if (result->d_op && result->d_op->d_revalidate2) {
118 + if (!result->d_op->d_revalidate2(result, flags, it) &&
119 + !d_invalidate(result)) {
126 @@ -334,7 +362,8 @@ int max_recursive_link = 5;
127 * Without that kind of total limit, nasty chains of consecutive
128 * symlinks can cause almost arbitrarily long lookups.
130 -static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
131 +static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd,
132 + struct lookup_intent *it)
135 if (current->link_count >= max_recursive_link)
136 @@ -348,10 +377,21 @@ static inline int do_follow_link(struct
137 current->link_count++;
138 current->total_link_count++;
139 UPDATE_ATIME(dentry->d_inode);
140 - err = dentry->d_inode->i_op->follow_link(dentry, nd);
142 + if (dentry->d_inode->i_op->follow_link2)
143 + err = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
145 + err = dentry->d_inode->i_op->follow_link(dentry, nd);
146 + if (!err && it != NULL && !(it->it_int_flags & IT_FL_FOLLOWED)) {
147 + /* vfs_follow_link was never called */
148 + intent_release(dentry, it);
152 current->link_count--;
155 + intent_release(dentry, it);
159 @@ -381,15 +421,26 @@ int follow_up(struct vfsmount **mnt, str
160 return __follow_up(mnt, dentry);
163 -static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry)
164 +static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry,
165 + struct lookup_intent *it)
167 struct vfsmount *mounted;
169 spin_lock(&dcache_lock);
170 mounted = lookup_mnt(*mnt, *dentry);
172 + int opc = 0, mode = 0;
173 *mnt = mntget(mounted);
174 spin_unlock(&dcache_lock);
177 + mode = it->it_mode;
179 + intent_release(*dentry, it);
182 + it->it_mode = mode;
185 mntput(mounted->mnt_parent);
186 *dentry = dget(mounted->mnt_root);
187 @@ -401,7 +452,7 @@ static inline int __follow_down(struct v
189 int follow_down(struct vfsmount **mnt, struct dentry **dentry)
191 - return __follow_down(mnt,dentry);
192 + return __follow_down(mnt,dentry,NULL);
195 static inline void follow_dotdot(struct nameidata *nd)
196 @@ -437,7 +488,7 @@ static inline void follow_dotdot(struct
200 - while (d_mountpoint(nd->dentry) && __follow_down(&nd->mnt, &nd->dentry))
201 + while (d_mountpoint(nd->dentry) && __follow_down(&nd->mnt, &nd->dentry, NULL))
205 @@ -449,7 +500,8 @@ static inline void follow_dotdot(struct
207 * We expect 'base' to be positive and a directory.
209 -int link_path_walk(const char * name, struct nameidata *nd)
210 +int link_path_walk_it(const char *name, struct nameidata *nd,
211 + struct lookup_intent *it)
213 struct dentry *dentry;
215 @@ -526,18 +578,18 @@ int link_path_walk(const char * name, st
218 /* This does the actual lookups.. */
219 - dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
220 + dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
222 err = -EWOULDBLOCKIO;
225 - dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
226 + dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
227 err = PTR_ERR(dentry);
231 /* Check mountpoints.. */
232 - while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry))
233 + while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry, NULL))
237 @@ -548,8 +600,8 @@ int link_path_walk(const char * name, st
241 - if (inode->i_op->follow_link) {
242 - err = do_follow_link(dentry, nd);
243 + if (inode->i_op->follow_link || inode->i_op->follow_link2) {
244 + err = do_follow_link(dentry, nd, NULL);
248 @@ -565,7 +617,7 @@ int link_path_walk(const char * name, st
252 - if (!inode->i_op->lookup)
253 + if (!inode->i_op->lookup && !inode->i_op->lookup2)
256 /* here ends the main loop */
257 @@ -592,22 +644,23 @@ last_component:
261 - dentry = cached_lookup(nd->dentry, &this, 0);
262 + dentry = cached_lookup(nd->dentry, &this, 0, it);
264 err = -EWOULDBLOCKIO;
267 - dentry = real_lookup(nd->dentry, &this, 0);
268 + dentry = real_lookup(nd->dentry, &this, 0, it);
269 err = PTR_ERR(dentry);
273 - while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry))
274 + while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry, it))
276 inode = dentry->d_inode;
277 if ((lookup_flags & LOOKUP_FOLLOW)
278 - && inode && inode->i_op && inode->i_op->follow_link) {
279 - err = do_follow_link(dentry, nd);
280 + && inode && inode->i_op &&
281 + (inode->i_op->follow_link || inode->i_op->follow_link2)) {
282 + err = do_follow_link(dentry, nd, it);
286 @@ -621,7 +674,8 @@ last_component:
288 if (lookup_flags & LOOKUP_DIRECTORY) {
290 - if (!inode->i_op || !inode->i_op->lookup)
291 + if (!inode->i_op ||
292 + (!inode->i_op->lookup && !inode->i_op->lookup2))
296 @@ -645,6 +699,23 @@ return_reval:
297 * Check the cached dentry for staleness.
301 + if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
303 + if (!dentry->d_op->d_revalidate2(dentry, 0, it)) {
304 + struct dentry *new;
305 + err = permission(dentry->d_parent->d_inode,
309 + new = real_lookup(dentry->d_parent,
310 + &dentry->d_name, 0, NULL);
311 + d_invalidate(dentry);
314 + goto revalidate_again;
317 if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
319 if (!dentry->d_op->d_revalidate(dentry, 0)) {
320 @@ -658,15 +729,28 @@ out_dput:
325 + intent_release(nd->dentry, it);
331 +int link_path_walk(const char * name, struct nameidata *nd)
333 + return link_path_walk_it(name, nd, NULL);
336 +int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
338 + current->total_link_count = 0;
339 + return link_path_walk_it(name, nd, it);
342 int path_walk(const char * name, struct nameidata *nd)
344 current->total_link_count = 0;
345 - return link_path_walk(name, nd);
346 + return link_path_walk_it(name, nd, NULL);
350 @@ -751,6 +835,17 @@ walk_init_root(const char *name, struct
354 +int path_lookup_it(const char *path, unsigned flags, struct nameidata *nd,
355 + struct lookup_intent *it)
358 + if (path_init(path, flags, nd))
359 + error = path_walk_it(path, nd, it);
365 int path_lookup(const char *path, unsigned flags, struct nameidata *nd)
368 @@ -765,6 +860,7 @@ int path_init(const char *name, unsigned
370 nd->last_type = LAST_ROOT; /* if there are only slashes... */
374 return walk_init_root(name,nd);
375 read_lock(¤t->fs->lock);
376 @@ -779,7 +875,8 @@ int path_init(const char *name, unsigned
377 * needs parent already locked. Doesn't follow mounts.
380 -struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
381 +struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base,
382 + struct lookup_intent *it)
384 struct dentry * dentry;
386 @@ -802,13 +899,16 @@ struct dentry * lookup_hash(struct qstr
390 - dentry = cached_lookup(base, name, 0);
391 + dentry = cached_lookup(base, name, 0, it);
393 struct dentry *new = d_alloc(base, name);
394 dentry = ERR_PTR(-ENOMEM);
398 + if (inode->i_op->lookup2)
399 + dentry = inode->i_op->lookup2(inode, new, it);
401 dentry = inode->i_op->lookup(inode, new);
404 @@ -820,6 +920,12 @@ out:
408 +struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
410 + return lookup_hash_it(name, base, NULL);
415 struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
417 @@ -841,7 +947,7 @@ struct dentry * lookup_one_len(const cha
419 this.hash = end_name_hash(hash);
421 - return lookup_hash(&this, base);
422 + return lookup_hash_it(&this, base, NULL);
424 return ERR_PTR(-EACCES);
426 @@ -872,6 +978,23 @@ int __user_walk(const char *name, unsign
430 +int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd,
431 + struct lookup_intent *it)
436 + tmp = getname(name);
437 + err = PTR_ERR(tmp);
438 + if (!IS_ERR(tmp)) {
440 + if (path_init(tmp, flags, nd))
441 + err = path_walk_it(tmp, nd, it);
448 * It's inline, so penalty for filesystems that don't use sticky bit is
450 @@ -1010,7 +1133,8 @@ exit_lock:
451 * for symlinks (where the permissions are checked later).
454 -int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
455 +int open_namei_it(const char *pathname, int flag, int mode,
456 + struct nameidata *nd, struct lookup_intent *it)
458 int acc_mode, error = 0;
460 @@ -1024,7 +1148,7 @@ int open_namei(const char * pathname, in
461 * The simplest case - just a plain lookup.
463 if (!(flag & O_CREAT)) {
464 - error = path_lookup(pathname, lookup_flags(flag), nd);
465 + error = path_lookup_it(pathname, lookup_flags(flag), nd, it);
469 @@ -1034,6 +1158,10 @@ int open_namei(const char * pathname, in
471 * Create - we need to know the parent.
474 + it->it_mode = mode;
475 + it->it_op |= IT_CREAT;
477 error = path_lookup(pathname, LOOKUP_PARENT, nd);
480 @@ -1049,7 +1177,7 @@ int open_namei(const char * pathname, in
483 down(&dir->d_inode->i_sem);
484 - dentry = lookup_hash(&nd->last, nd->dentry);
485 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
488 error = PTR_ERR(dentry);
489 @@ -1058,6 +1186,7 @@ do_last:
493 + it->it_mode = mode;
494 /* Negative dentry, just create the file */
495 if (!dentry->d_inode) {
496 error = vfs_create(dir->d_inode, dentry,
497 @@ -1086,12 +1215,13 @@ do_last:
499 if (flag & O_NOFOLLOW)
501 - while (__follow_down(&nd->mnt,&dentry) && d_mountpoint(dentry));
502 + while (__follow_down(&nd->mnt,&dentry,it) && d_mountpoint(dentry));
505 if (!dentry->d_inode)
507 - if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link)
508 + if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link ||
509 + dentry->d_inode->i_op->follow_link2))
513 @@ -1165,7 +1295,7 @@ ok:
517 - error = do_truncate(dentry, 0);
518 + error = do_truncate(dentry, 0, 1);
520 put_write_access(inode);
522 @@ -1177,8 +1307,10 @@ ok:
526 + intent_release(dentry, it);
529 + intent_release(nd->dentry, it);
533 @@ -1197,7 +1329,19 @@ do_link:
534 * are done. Procfs-like symlinks just set LAST_BIND.
536 UPDATE_ATIME(dentry->d_inode);
537 - error = dentry->d_inode->i_op->follow_link(dentry, nd);
539 + if (dentry->d_inode->i_op->follow_link2)
540 + error = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
542 + error = dentry->d_inode->i_op->follow_link(dentry, nd);
544 + intent_release(dentry, it);
545 + } else if (it != NULL && !(it->it_int_flags & IT_FL_FOLLOWED)) {
546 + /* vfs_follow_link was never called */
547 + intent_release(dentry, it);
554 @@ -1219,13 +1363,20 @@ do_link:
557 down(&dir->d_inode->i_sem);
558 - dentry = lookup_hash(&nd->last, nd->dentry);
559 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
560 putname(nd->last.name);
564 +int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd)
566 + return open_namei_it(pathname, flag, mode, nd, NULL);
571 -static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
572 +static struct dentry *lookup_create(struct nameidata *nd, int is_dir,
573 + struct lookup_intent *it)
575 struct dentry *dentry;
577 @@ -1233,7 +1384,7 @@ static struct dentry *lookup_create(stru
578 dentry = ERR_PTR(-EEXIST);
579 if (nd->last_type != LAST_NORM)
581 - dentry = lookup_hash(&nd->last, nd->dentry);
582 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
585 if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
586 @@ -1289,7 +1440,19 @@ asmlinkage long sys_mknod(const char * f
587 error = path_lookup(tmp, LOOKUP_PARENT, &nd);
590 - dentry = lookup_create(&nd, 0);
592 + if (nd.dentry->d_inode->i_op->mknod2) {
593 + struct inode_operations *op = nd.dentry->d_inode->i_op;
594 + error = op->mknod2(nd.dentry->d_inode,
598 + /* the file system wants to use normal vfs path now */
599 + if (error != -EOPNOTSUPP)
603 + dentry = lookup_create(&nd, 0, NULL);
604 error = PTR_ERR(dentry);
606 mode &= ~current->fs->umask;
607 @@ -1310,6 +1473,7 @@ asmlinkage long sys_mknod(const char * f
610 up(&nd.dentry->d_inode->i_sem);
615 @@ -1357,7 +1521,17 @@ asmlinkage long sys_mkdir(const char * p
616 error = path_lookup(tmp, LOOKUP_PARENT, &nd);
619 - dentry = lookup_create(&nd, 1);
620 + if (nd.dentry->d_inode->i_op->mkdir2) {
621 + struct inode_operations *op = nd.dentry->d_inode->i_op;
622 + error = op->mkdir2(nd.dentry->d_inode,
626 + /* the file system wants to use normal vfs path now */
627 + if (error != -EOPNOTSUPP)
630 + dentry = lookup_create(&nd, 1, NULL);
631 error = PTR_ERR(dentry);
632 if (!IS_ERR(dentry)) {
633 error = vfs_mkdir(nd.dentry->d_inode, dentry,
634 @@ -1365,6 +1539,7 @@ asmlinkage long sys_mkdir(const char * p
637 up(&nd.dentry->d_inode->i_sem);
642 @@ -1465,8 +1640,33 @@ asmlinkage long sys_rmdir(const char * p
646 + if (nd.dentry->d_inode->i_op->rmdir2) {
647 + struct inode_operations *op = nd.dentry->d_inode->i_op;
648 + struct dentry *last;
650 + down(&nd.dentry->d_inode->i_sem);
651 + last = lookup_hash_it(&nd.last, nd.dentry, NULL);
652 + up(&nd.dentry->d_inode->i_sem);
653 + if (IS_ERR(last)) {
654 + error = PTR_ERR(last);
657 + if (d_mountpoint(last)) {
664 + error = op->rmdir2(nd.dentry->d_inode,
667 + /* the file system wants to use normal vfs path now */
668 + if (error != -EOPNOTSUPP)
671 down(&nd.dentry->d_inode->i_sem);
672 - dentry = lookup_hash(&nd.last, nd.dentry);
673 + dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
674 error = PTR_ERR(dentry);
675 if (!IS_ERR(dentry)) {
676 error = vfs_rmdir(nd.dentry->d_inode, dentry);
677 @@ -1524,8 +1724,17 @@ asmlinkage long sys_unlink(const char *
679 if (nd.last_type != LAST_NORM)
681 + if (nd.dentry->d_inode->i_op->unlink2) {
682 + struct inode_operations *op = nd.dentry->d_inode->i_op;
683 + error = op->unlink2(nd.dentry->d_inode,
686 + /* the file system wants to use normal vfs path now */
687 + if (error != -EOPNOTSUPP)
690 down(&nd.dentry->d_inode->i_sem);
691 - dentry = lookup_hash(&nd.last, nd.dentry);
692 + dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
693 error = PTR_ERR(dentry);
694 if (!IS_ERR(dentry)) {
695 /* Why not before? Because we want correct error value */
696 @@ -1592,15 +1801,26 @@ asmlinkage long sys_symlink(const char *
697 error = path_lookup(to, LOOKUP_PARENT, &nd);
700 - dentry = lookup_create(&nd, 0);
701 + if (nd.dentry->d_inode->i_op->symlink2) {
702 + struct inode_operations *op = nd.dentry->d_inode->i_op;
703 + error = op->symlink2(nd.dentry->d_inode,
707 + /* the file system wants to use normal vfs path now */
708 + if (error != -EOPNOTSUPP)
711 + dentry = lookup_create(&nd, 0, NULL);
712 error = PTR_ERR(dentry);
713 if (!IS_ERR(dentry)) {
714 error = vfs_symlink(nd.dentry->d_inode, dentry, from);
717 up(&nd.dentry->d_inode->i_sem);
725 @@ -1676,7 +1896,17 @@ asmlinkage long sys_link(const char * ol
727 if (old_nd.mnt != nd.mnt)
729 - new_dentry = lookup_create(&nd, 0);
730 + if (nd.dentry->d_inode->i_op->link2) {
731 + struct inode_operations *op = nd.dentry->d_inode->i_op;
732 + error = op->link2(old_nd.dentry->d_inode,
733 + nd.dentry->d_inode,
736 + /* the file system wants to use normal vfs path now */
737 + if (error != -EOPNOTSUPP)
740 + new_dentry = lookup_create(&nd, 0, NULL);
741 error = PTR_ERR(new_dentry);
742 if (!IS_ERR(new_dentry)) {
743 error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
744 @@ -1720,7 +1950,8 @@ exit:
747 int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
748 - struct inode *new_dir, struct dentry *new_dentry)
749 + struct inode *new_dir, struct dentry *new_dentry,
750 + struct lookup_intent *it)
753 struct inode *target;
754 @@ -1778,6 +2009,7 @@ int vfs_rename_dir(struct inode *old_dir
757 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
758 + intent_release(new_dentry, it);
761 target->i_flags |= S_DEAD;
762 @@ -1799,7 +2031,8 @@ out_unlock:
765 int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
766 - struct inode *new_dir, struct dentry *new_dentry)
767 + struct inode *new_dir, struct dentry *new_dentry,
768 + struct lookup_intent *it)
772 @@ -1830,6 +2063,7 @@ int vfs_rename_other(struct inode *old_d
775 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
776 + intent_release(new_dentry, it);
777 double_up(&old_dir->i_zombie, &new_dir->i_zombie);
780 @@ -1841,13 +2075,14 @@ int vfs_rename_other(struct inode *old_d
783 int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
784 - struct inode *new_dir, struct dentry *new_dentry)
785 + struct inode *new_dir, struct dentry *new_dentry,
786 + struct lookup_intent *it)
789 if (S_ISDIR(old_dentry->d_inode->i_mode))
790 - error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
791 + error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it);
793 - error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
794 + error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it);
796 if (old_dir == new_dir)
797 inode_dir_notify(old_dir, DN_RENAME);
798 @@ -1889,7 +2124,7 @@ static inline int do_rename(const char *
800 double_lock(new_dir, old_dir);
802 - old_dentry = lookup_hash(&oldnd.last, old_dir);
803 + old_dentry = lookup_hash_it(&oldnd.last, old_dir, NULL);
804 error = PTR_ERR(old_dentry);
805 if (IS_ERR(old_dentry))
807 @@ -1905,16 +2140,37 @@ static inline int do_rename(const char *
808 if (newnd.last.name[newnd.last.len])
811 - new_dentry = lookup_hash(&newnd.last, new_dir);
812 + new_dentry = lookup_hash_it(&newnd.last, new_dir, NULL);
813 error = PTR_ERR(new_dentry);
814 if (IS_ERR(new_dentry))
817 + if (old_dir->d_inode->i_op->rename2) {
819 + /* don't rename mount point. mds will take care of
820 + * the rest sanity checking */
821 + if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) {
826 + error = old_dir->d_inode->i_op->rename2(old_dir->d_inode,
833 + /* the file system wants to use normal vfs path now */
834 + if (error != -EOPNOTSUPP)
839 error = vfs_rename(old_dir->d_inode, old_dentry,
840 - new_dir->d_inode, new_dentry);
841 + new_dir->d_inode, new_dentry, NULL);
848 @@ -1965,20 +2221,28 @@ out:
852 -__vfs_follow_link(struct nameidata *nd, const char *link)
853 +__vfs_follow_link(struct nameidata *nd, const char *link,
854 + struct lookup_intent *it)
863 + else if (it != nd->it)
864 + printk("it != nd->it: tell phil@clusterfs.com\n");
866 + it->it_int_flags |= IT_FL_FOLLOWED;
870 if (!walk_init_root(link, nd))
871 /* weird __emul_prefix() stuff did it */
874 - res = link_path_walk(link, nd);
875 + res = link_path_walk_it(link, nd, it);
877 if (current->link_count || res || nd->last_type!=LAST_NORM)
879 @@ -2002,7 +2266,13 @@ fail:
881 int vfs_follow_link(struct nameidata *nd, const char *link)
883 - return __vfs_follow_link(nd, link);
884 + return __vfs_follow_link(nd, link, NULL);
887 +int vfs_follow_link_it(struct nameidata *nd, const char *link,
888 + struct lookup_intent *it)
890 + return __vfs_follow_link(nd, link, it);
893 /* get the link contents into pagecache */
894 @@ -2044,7 +2314,7 @@ int page_follow_link(struct dentry *dent
896 struct page *page = NULL;
897 char *s = page_getlink(dentry, &page);
898 - int res = __vfs_follow_link(nd, s);
899 + int res = __vfs_follow_link(nd, s, NULL);
902 page_cache_release(page);
903 --- linux-2.4.20-rh/fs/nfsd/vfs.c~vfs_intent-2.4.20-rh 2003-04-11 14:04:48.000000000 +0800
904 +++ linux-2.4.20-rh-root/fs/nfsd/vfs.c 2003-06-09 23:18:07.000000000 +0800
905 @@ -1293,7 +1293,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru
909 - err = vfs_rename(fdir, odentry, tdir, ndentry);
910 + err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
911 if (!err && EX_ISSYNC(tfhp->fh_export)) {
912 nfsd_sync_dir(tdentry);
913 nfsd_sync_dir(fdentry);
914 --- linux-2.4.20-rh/fs/open.c~vfs_intent-2.4.20-rh 2003-04-11 14:04:57.000000000 +0800
915 +++ linux-2.4.20-rh-root/fs/open.c 2003-06-09 23:18:07.000000000 +0800
917 #include <asm/uaccess.h>
919 #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
920 +extern int path_walk_it(const char *name, struct nameidata *nd,
921 + struct lookup_intent *it);
923 int vfs_statfs(struct super_block *sb, struct statfs *buf)
925 @@ -95,9 +97,10 @@ void fd_install(unsigned int fd, struct
926 write_unlock(&files->file_lock);
929 -int do_truncate(struct dentry *dentry, loff_t length)
930 +int do_truncate(struct dentry *dentry, loff_t length, int called_from_open)
932 struct inode *inode = dentry->d_inode;
933 + struct inode_operations *op = dentry->d_inode->i_op;
935 struct iattr newattrs;
937 @@ -108,7 +111,14 @@ int do_truncate(struct dentry *dentry, l
939 newattrs.ia_size = length;
940 newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
941 - error = notify_change(dentry, &newattrs);
942 + if (called_from_open)
943 + newattrs.ia_valid |= ATTR_FROM_OPEN;
944 + if (op->setattr_raw) {
945 + newattrs.ia_valid |= ATTR_RAW;
946 + newattrs.ia_ctime = CURRENT_TIME;
947 + error = op->setattr_raw(inode, &newattrs);
949 + error = notify_change(dentry, &newattrs);
953 @@ -118,12 +128,13 @@ static inline long do_sys_truncate(const
955 struct inode * inode;
957 + struct lookup_intent it = { .it_op = IT_GETATTR };
960 if (length < 0) /* sorry, but loff_t says... */
963 - error = user_path_walk(path, &nd);
964 + error = user_path_walk_it(path, &nd, &it);
967 inode = nd.dentry->d_inode;
968 @@ -163,11 +174,13 @@ static inline long do_sys_truncate(const
969 error = locks_verify_truncate(inode, NULL, length);
972 - error = do_truncate(nd.dentry, length);
973 + intent_release(nd.dentry, &it);
974 + error = do_truncate(nd.dentry, length, 0);
976 put_write_access(inode);
979 + intent_release(nd.dentry, &it);
983 @@ -215,7 +228,7 @@ static inline long do_sys_ftruncate(unsi
985 error = locks_verify_truncate(inode, file, length);
987 - error = do_truncate(dentry, length);
988 + error = do_truncate(dentry, length, 0);
992 @@ -260,11 +273,13 @@ asmlinkage long sys_utime(char * filenam
993 struct inode * inode;
994 struct iattr newattrs;
996 - error = user_path_walk(filename, &nd);
997 + error = user_path_walk_it(filename, &nd, NULL);
1000 inode = nd.dentry->d_inode;
1002 + /* this is safe without a Lustre lock because it only depends
1003 + on the super block */
1005 if (IS_RDONLY(inode))
1007 @@ -279,11 +294,29 @@ asmlinkage long sys_utime(char * filenam
1010 newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
1014 + if (inode->i_op->setattr_raw) {
1015 + struct inode_operations *op = nd.dentry->d_inode->i_op;
1017 + newattrs.ia_valid |= ATTR_RAW;
1018 + error = op->setattr_raw(inode, &newattrs);
1019 + /* the file system wants to use normal vfs path now */
1020 + if (error != -EOPNOTSUPP)
1021 + goto dput_and_out;
1025 + if (IS_RDONLY(inode))
1026 + goto dput_and_out;
1030 if (current->fsuid != inode->i_uid &&
1031 (error = permission(inode,MAY_WRITE)) != 0)
1035 error = notify_change(nd.dentry, &newattrs);
1038 @@ -304,12 +337,14 @@ asmlinkage long sys_utimes(char * filena
1039 struct inode * inode;
1040 struct iattr newattrs;
1042 - error = user_path_walk(filename, &nd);
1043 + error = user_path_walk_it(filename, &nd, NULL);
1047 inode = nd.dentry->d_inode;
1049 + /* this is safe without a Lustre lock because it only depends
1050 + on the super block */
1052 if (IS_RDONLY(inode))
1054 @@ -324,7 +359,20 @@ asmlinkage long sys_utimes(char * filena
1055 newattrs.ia_atime = times[0].tv_sec;
1056 newattrs.ia_mtime = times[1].tv_sec;
1057 newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
1061 + if (inode->i_op->setattr_raw) {
1062 + struct inode_operations *op = nd.dentry->d_inode->i_op;
1064 + newattrs.ia_valid |= ATTR_RAW;
1065 + error = op->setattr_raw(inode, &newattrs);
1066 + /* the file system wants to use normal vfs path now */
1067 + if (error != -EOPNOTSUPP)
1068 + goto dput_and_out;
1073 if (current->fsuid != inode->i_uid &&
1074 (error = permission(inode,MAY_WRITE)) != 0)
1076 @@ -347,6 +395,7 @@ asmlinkage long sys_access(const char *
1077 int old_fsuid, old_fsgid;
1078 kernel_cap_t old_cap;
1080 + struct lookup_intent it = { .it_op = IT_GETATTR };
1082 if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
1084 @@ -364,13 +413,14 @@ asmlinkage long sys_access(const char *
1086 current->cap_effective = current->cap_permitted;
1088 - res = user_path_walk(filename, &nd);
1089 + res = user_path_walk_it(filename, &nd, &it);
1091 res = permission(nd.dentry->d_inode, mode);
1092 /* SuS v2 requires we report a read only fs too */
1093 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
1094 && !special_file(nd.dentry->d_inode->i_mode))
1096 + intent_release(nd.dentry, &it);
1100 @@ -385,8 +435,9 @@ asmlinkage long sys_chdir(const char * f
1103 struct nameidata nd;
1104 + struct lookup_intent it = { .it_op = IT_GETATTR };
1106 - error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd);
1107 + error = __user_walk_it(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd, &it);
1111 @@ -397,6 +448,7 @@ asmlinkage long sys_chdir(const char * f
1112 set_fs_pwd(current->fs, nd.mnt, nd.dentry);
1115 + intent_release(nd.dentry, &it);
1119 @@ -436,9 +488,10 @@ asmlinkage long sys_chroot(const char *
1122 struct nameidata nd;
1123 + struct lookup_intent it = { .it_op = IT_GETATTR };
1125 - error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
1126 - LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
1127 + error = __user_walk_it(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
1128 + LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd, &it);
1132 @@ -454,6 +507,7 @@ asmlinkage long sys_chroot(const char *
1136 + intent_release(nd.dentry, &it);
1140 @@ -508,6 +562,18 @@ asmlinkage long sys_chmod(const char * f
1141 if (IS_RDONLY(inode))
1144 + if (inode->i_op->setattr_raw) {
1145 + struct inode_operations *op = nd.dentry->d_inode->i_op;
1147 + newattrs.ia_mode = mode;
1148 + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
1149 + newattrs.ia_valid |= ATTR_RAW;
1150 + error = op->setattr_raw(inode, &newattrs);
1151 + /* the file system wants to use normal vfs path now */
1152 + if (error != -EOPNOTSUPP)
1153 + goto dput_and_out;
1157 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
1159 @@ -538,6 +604,20 @@ static int chown_common(struct dentry *
1161 if (IS_RDONLY(inode))
1164 + if (inode->i_op->setattr_raw) {
1165 + struct inode_operations *op = dentry->d_inode->i_op;
1167 + newattrs.ia_uid = user;
1168 + newattrs.ia_gid = group;
1169 + newattrs.ia_valid = ATTR_UID | ATTR_GID;
1170 + newattrs.ia_valid |= ATTR_RAW;
1171 + error = op->setattr_raw(inode, &newattrs);
1172 + /* the file system wants to use normal vfs path now */
1173 + if (error != -EOPNOTSUPP)
1178 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
1180 @@ -642,6 +722,7 @@ struct file *filp_open(const char * file
1182 int namei_flags, error;
1183 struct nameidata nd;
1184 + struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = flags };
1188 @@ -651,14 +732,15 @@ struct file *filp_open(const char * file
1189 if (namei_flags & O_TRUNC)
1192 - error = open_namei(filename, namei_flags, mode, &nd);
1194 - return dentry_open(nd.dentry, nd.mnt, flags);
1195 + error = open_namei_it(filename, namei_flags, mode, &nd, &it);
1197 + return ERR_PTR(error);
1199 - return ERR_PTR(error);
1200 + return dentry_open_it(nd.dentry, nd.mnt, flags, &it);
1203 -struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1204 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1205 + int flags, struct lookup_intent *it)
1208 struct inode *inode;
1209 @@ -701,6 +783,7 @@ struct file *dentry_open(struct dentry *
1211 f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
1213 + intent_release(dentry, it);
1217 @@ -715,11 +798,17 @@ cleanup_all:
1221 + intent_release(dentry, it);
1224 return ERR_PTR(error);
1227 +struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1229 + return dentry_open_it(dentry, mnt, flags, NULL);
1233 * Find an empty file descriptor entry, and mark it busy.
1235 --- linux-2.4.20-rh/fs/stat.c~vfs_intent-2.4.20-rh 2003-04-11 14:05:08.000000000 +0800
1236 +++ linux-2.4.20-rh-root/fs/stat.c 2003-06-09 23:18:07.000000000 +0800
1237 @@ -110,11 +110,13 @@ static int do_getattr(struct vfsmount *m
1238 int vfs_stat(char *name, struct kstat *stat)
1240 struct nameidata nd;
1241 + struct lookup_intent it = { .it_op = IT_GETATTR };
1244 - error = user_path_walk(name, &nd);
1245 + error = user_path_walk_it(name, &nd, &it);
1247 error = do_getattr(nd.mnt, nd.dentry, stat);
1248 + intent_release(nd.dentry, &it);
1252 @@ -123,11 +125,13 @@ int vfs_stat(char *name, struct kstat *s
1253 int vfs_lstat(char *name, struct kstat *stat)
1255 struct nameidata nd;
1256 + struct lookup_intent it = { .it_op = IT_GETATTR };
1259 - error = user_path_walk_link(name, &nd);
1260 + error = user_path_walk_link_it(name, &nd, &it);
1262 error = do_getattr(nd.mnt, nd.dentry, stat);
1263 + intent_release(nd.dentry, &it);
1267 --- linux-2.4.20-rh/include/linux/dcache.h~vfs_intent-2.4.20-rh 2003-04-12 15:46:39.000000000 +0800
1268 +++ linux-2.4.20-rh-root/include/linux/dcache.h 2003-06-09 23:18:07.000000000 +0800
1270 #include <linux/mount.h>
1271 #include <linux/kernel.h>
1273 +#define IT_OPEN (1)
1274 +#define IT_CREAT (1<<1)
1275 +#define IT_READDIR (1<<2)
1276 +#define IT_GETATTR (1<<3)
1277 +#define IT_LOOKUP (1<<4)
1278 +#define IT_UNLINK (1<<5)
1280 +#define IT_FL_LOCKED (1)
1281 +#define IT_FL_FOLLOWED (1<<1) /* set by vfs_follow_link */
1283 +struct lookup_intent {
1287 + int it_disposition;
1290 + __u64 it_lock_handle[2];
1296 * linux/include/linux/dcache.h
1298 @@ -82,6 +104,7 @@ struct dentry {
1299 unsigned long d_time; /* used by d_revalidate */
1300 struct dentry_operations *d_op;
1301 struct super_block * d_sb; /* The root of the dentry tree */
1302 + struct lookup_intent *d_it;
1303 unsigned long d_vfs_flags;
1304 void * d_fsdata; /* fs-specific data */
1305 void * d_extra_attributes; /* TUX-specific data */
1306 @@ -96,8 +119,15 @@ struct dentry_operations {
1307 int (*d_delete)(struct dentry *);
1308 void (*d_release)(struct dentry *);
1309 void (*d_iput)(struct dentry *, struct inode *);
1310 + int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
1311 + void (*d_intent_release)(struct dentry *, struct lookup_intent *);
1314 +/* defined in fs/namei.c */
1315 +extern void intent_release(struct dentry *de, struct lookup_intent *it);
1316 +/* defined in fs/dcache.c */
1317 +extern void __d_rehash(struct dentry * entry, int lock);
1319 /* the dentry parameter passed to d_hash and d_compare is the parent
1320 * directory of the entries to be compared. It is used in case these
1321 * functions need any directory specific information for determining
1322 @@ -129,6 +159,7 @@ d_iput: no no yes
1323 * s_nfsd_free_path semaphore will be down
1325 #define DCACHE_REFERENCED 0x0008 /* Recently used, don't discard. */
1326 +#define DCACHE_LUSTRE_INVALID 0x0010 /* Lustre invalidated */
1328 extern spinlock_t dcache_lock;
1330 --- linux-2.4.20-rh/include/linux/fs.h~vfs_intent-2.4.20-rh 2003-05-30 02:07:39.000000000 +0800
1331 +++ linux-2.4.20-rh-root/include/linux/fs.h 2003-06-09 23:18:07.000000000 +0800
1332 @@ -337,6 +337,8 @@ extern void set_bh_page(struct buffer_he
1333 #define ATTR_MTIME_SET 256
1334 #define ATTR_FORCE 512 /* Not a change, but a change it */
1335 #define ATTR_ATTR_FLAG 1024
1336 +#define ATTR_RAW 2048 /* file system, not vfs will massage attrs */
1337 +#define ATTR_FROM_OPEN 4096 /* called from open path, ie O_TRUNC */
1340 * This is the Inode Attributes structure, used for notify_change(). It
1341 @@ -574,6 +576,7 @@ struct file {
1343 /* needed for tty driver, and maybe others */
1345 + struct lookup_intent *f_intent;
1347 /* preallocated helper kiobuf to speedup O_DIRECT */
1348 struct kiobuf *f_iobuf;
1349 @@ -701,6 +704,7 @@ struct nameidata {
1353 + struct lookup_intent *it;
1357 @@ -821,7 +825,9 @@ extern int vfs_symlink(struct inode *, s
1358 extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
1359 extern int vfs_rmdir(struct inode *, struct dentry *);
1360 extern int vfs_unlink(struct inode *, struct dentry *);
1361 -extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
1362 +int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1363 + struct inode *new_dir, struct dentry *new_dentry,
1364 + struct lookup_intent *it);
1368 @@ -882,20 +888,33 @@ struct file_operations {
1369 struct inode_operations {
1370 int (*create) (struct inode *,struct dentry *,int);
1371 struct dentry * (*lookup) (struct inode *,struct dentry *);
1372 + struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *);
1373 int (*link) (struct dentry *,struct inode *,struct dentry *);
1374 + int (*link2) (struct inode *,struct inode *, const char *, int);
1375 int (*unlink) (struct inode *,struct dentry *);
1376 + int (*unlink2) (struct inode *, const char *, int);
1377 int (*symlink) (struct inode *,struct dentry *,const char *);
1378 + int (*symlink2) (struct inode *, const char *, int, const char *);
1379 int (*mkdir) (struct inode *,struct dentry *,int);
1380 + int (*mkdir2) (struct inode *, const char *, int,int);
1381 int (*rmdir) (struct inode *,struct dentry *);
1382 + int (*rmdir2) (struct inode *, const char *, int);
1383 int (*mknod) (struct inode *,struct dentry *,int,int);
1384 + int (*mknod2) (struct inode *, const char *, int,int,int);
1385 int (*rename) (struct inode *, struct dentry *,
1386 struct inode *, struct dentry *);
1387 + int (*rename2) (struct inode *, struct inode *,
1388 + const char *oldname, int oldlen,
1389 + const char *newname, int newlen);
1390 int (*readlink) (struct dentry *, char *,int);
1391 int (*follow_link) (struct dentry *, struct nameidata *);
1392 + int (*follow_link2) (struct dentry *, struct nameidata *,
1393 + struct lookup_intent *it);
1394 void (*truncate) (struct inode *);
1395 int (*permission) (struct inode *, int);
1396 int (*revalidate) (struct dentry *);
1397 int (*setattr) (struct dentry *, struct iattr *);
1398 + int (*setattr_raw) (struct inode *, struct iattr *);
1399 int (*getattr) (struct dentry *, struct iattr *);
1400 int (*setxattr) (struct dentry *, const char *, void *, size_t, int);
1401 ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
1402 @@ -1091,10 +1110,14 @@ static inline int get_lease(struct inode
1404 asmlinkage long sys_open(const char *, int, int);
1405 asmlinkage long sys_close(unsigned int); /* yes, it's really unsigned */
1406 -extern int do_truncate(struct dentry *, loff_t start);
1407 +extern int do_truncate(struct dentry *, loff_t start, int called_from_open);
1409 extern struct file *filp_open(const char *, int, int);
1410 extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
1411 +extern int open_namei_it(const char *filename, int namei_flags, int mode,
1412 + struct nameidata *nd, struct lookup_intent *it);
1413 +extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1414 + int flags, struct lookup_intent *it);
1415 extern int filp_close(struct file *, fl_owner_t id);
1416 extern char * getname(const char *);
1418 @@ -1385,6 +1408,7 @@ typedef int (*read_actor_t)(read_descrip
1419 extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
1421 extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
1422 +extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
1423 extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
1424 extern int FASTCALL(path_walk(const char *, struct nameidata *));
1425 extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
1426 @@ -1396,6 +1420,8 @@ extern struct dentry * lookup_one_len(co
1427 extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
1428 #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
1429 #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
1430 +#define user_path_walk_it(name,nd,it) __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
1431 +#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
1433 extern void inode_init_once(struct inode *);
1434 extern void iput(struct inode *);
1435 @@ -1495,6 +1521,8 @@ extern struct file_operations generic_ro
1437 extern int vfs_readlink(struct dentry *, char *, int, const char *);
1438 extern int vfs_follow_link(struct nameidata *, const char *);
1439 +extern int vfs_follow_link_it(struct nameidata *, const char *,
1440 + struct lookup_intent *it);
1441 extern int page_readlink(struct dentry *, char *, int);
1442 extern int page_follow_link(struct dentry *, struct nameidata *);
1443 extern struct inode_operations page_symlink_inode_operations;
1444 --- linux-2.4.20-rh/kernel/ksyms.c~vfs_intent-2.4.20-rh 2003-05-30 02:07:42.000000000 +0800
1445 +++ linux-2.4.20-rh-root/kernel/ksyms.c 2003-06-09 23:18:07.000000000 +0800
1446 @@ -298,6 +298,7 @@ EXPORT_SYMBOL(read_cache_page);
1447 EXPORT_SYMBOL(set_page_dirty);
1448 EXPORT_SYMBOL(vfs_readlink);
1449 EXPORT_SYMBOL(vfs_follow_link);
1450 +EXPORT_SYMBOL(vfs_follow_link_it);
1451 EXPORT_SYMBOL(page_readlink);
1452 EXPORT_SYMBOL(page_follow_link);
1453 EXPORT_SYMBOL(page_symlink_inode_operations);
1454 --- linux-2.4.20-rh/fs/exec.c~vfs_intent-2.4.20-rh 2003-04-13 10:07:02.000000000 +0800
1455 +++ linux-2.4.20-rh-root/fs/exec.c 2003-06-09 23:18:07.000000000 +0800
1456 @@ -114,8 +114,9 @@ asmlinkage long sys_uselib(const char *
1458 struct nameidata nd;
1461 - error = user_path_walk(library, &nd);
1462 + struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY };
1464 + error = user_path_walk_it(library, &nd, &it);
1468 @@ -127,7 +128,8 @@ asmlinkage long sys_uselib(const char *
1472 - file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
1473 + file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &it);
1474 + intent_release(nd.dentry, &it);
1475 error = PTR_ERR(file);
1478 @@ -382,8 +384,9 @@ struct file *open_exec(const char *name)
1479 struct inode *inode;
1483 - err = path_lookup(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd);
1484 + struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY };
1486 + err = path_lookup_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd, &it);
1487 file = ERR_PTR(err);
1489 inode = nd.dentry->d_inode;
1490 @@ -395,7 +398,7 @@ struct file *open_exec(const char *name)
1492 file = ERR_PTR(err);
1494 - file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
1495 + file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &it);
1496 if (!IS_ERR(file)) {
1497 err = deny_write_access(file);
1499 @@ -404,6 +407,7 @@ struct file *open_exec(const char *name)
1503 + intent_release(nd.dentry, &it);
1507 @@ -1283,7 +1287,7 @@ int do_coredump(long signr, int exit_cod
1509 if (!file->f_op->write)
1511 - if (do_truncate(file->f_dentry, 0) != 0)
1512 + if (do_truncate(file->f_dentry, 0, 0) != 0)
1515 retval = binfmt->core_dump(signr, regs, file);
1516 --- linux-2.4.20-rh/fs/proc/base.c~vfs_intent-2.4.20-rh 2003-06-09 23:16:51.000000000 +0800
1517 +++ linux-2.4.20-rh-root/fs/proc/base.c 2003-06-09 23:18:52.000000000 +0800
1518 @@ -464,6 +464,9 @@ static int proc_pid_follow_link(struct d
1520 error = inode->u.proc_i.op.proc_get_link(inode, &nd->dentry, &nd->mnt);
1521 nd->last_type = LAST_BIND;
1523 + if (nd->it != NULL)
1524 + nd->it->it_int_flags |= IT_FL_FOLLOWED;