2 fs/namei.c | 287 ++++++++++++++++++++++++++++++++++++++++---------
4 fs/open.c | 53 +++++++--
6 include/linux/dcache.h | 25 ++++
7 include/linux/fs.h | 22 +++
9 8 files changed, 344 insertions(+), 63 deletions(-)
11 --- linux-2.4.18-18.8.0-l7/fs/dcache.c~vfs_intent-2.4.18-18 Mon Jan 20 08:28:00 2003
12 +++ linux-2.4.18-18.8.0-l7-root/fs/dcache.c Mon Jan 20 08:54:54 2003
13 @@ -186,6 +188,13 @@ int d_invalidate(struct dentry * dentry)
14 spin_unlock(&dcache_lock);
18 + /* network invalidation by Lustre */
19 + if (dentry->d_flags & DCACHE_LUSTRE_INVALID) {
20 + spin_unlock(&dcache_lock);
25 * Check whether to do a partial shrink_dcache
26 * to get rid of unused child entries.
27 @@ -645,6 +654,7 @@ struct dentry * d_alloc(struct dentry *
28 dentry->d_fsdata = NULL;
29 dentry->d_extra_attributes = NULL;
30 dentry->d_mounted = 0;
31 + dentry->d_it = NULL;
32 INIT_LIST_HEAD(&dentry->d_hash);
33 INIT_LIST_HEAD(&dentry->d_lru);
34 INIT_LIST_HEAD(&dentry->d_subdirs);
35 --- linux-2.4.18-18.8.0-l7/fs/namei.c~vfs_intent-2.4.18-18 Mon Jan 20 12:25:10 2003
36 +++ linux-2.4.18-18.8.0-l7-root/fs/namei.c Wed Jan 22 22:53:28 2003
38 * XEmacs seems to be relying on it...
41 +void intent_release(struct dentry *de, struct lookup_intent *it)
43 + if (it && de->d_op && de->d_op->d_intent_release)
44 + de->d_op->d_intent_release(de, it);
48 /* In order to reduce some races, while at the same time doing additional
49 * checking and hopefully speeding things up, we copy filenames to the
50 * kernel data space before using them..
51 @@ -260,10 +271,19 @@ void path_release(struct nameidata *nd)
52 * Internal lookup() using the new generic dcache.
55 -static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
56 +static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name,
57 + int flags, struct lookup_intent *it)
59 struct dentry * dentry = d_lookup(parent, name);
61 + if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
62 + if (!dentry->d_op->d_revalidate2(dentry, flags, it) &&
63 + !d_invalidate(dentry)) {
69 if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
70 if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
72 @@ -281,7 +301,8 @@ static struct dentry * cached_lookup(str
73 * make sure that nobody added the entry to the dcache in the meantime..
76 -static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
77 +static struct dentry *real_lookup(struct dentry *parent, struct qstr *name,
78 + int flags, struct lookup_intent *it)
80 struct dentry * result;
81 struct inode *dir = parent->d_inode;
82 @@ -300,6 +321,9 @@ static struct dentry * real_lookup(struc
83 result = ERR_PTR(-ENOMEM);
86 + if (dir->i_op->lookup2)
87 + result = dir->i_op->lookup2(dir, dentry, it);
89 result = dir->i_op->lookup(dir, dentry);
92 @@ -321,6 +345,12 @@ static struct dentry * real_lookup(struc
94 result = ERR_PTR(-ENOENT);
96 + } else if (result->d_op && result->d_op->d_revalidate2) {
97 + if (!result->d_op->d_revalidate2(result, flags, it) &&
98 + !d_invalidate(result)) {
100 + result = ERR_PTR(-ENOENT);
105 @@ -334,7 +364,8 @@ int max_recursive_link = 5;
106 * Without that kind of total limit, nasty chains of consecutive
107 * symlinks can cause almost arbitrarily long lookups.
109 -static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
110 +static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd,
111 + struct lookup_intent *it)
114 if (current->link_count >= max_recursive_link)
115 @@ -348,10 +379,14 @@ static inline int do_follow_link(struct
116 current->link_count++;
117 current->total_link_count++;
118 UPDATE_ATIME(dentry->d_inode);
119 - err = dentry->d_inode->i_op->follow_link(dentry, nd);
120 + if (dentry->d_inode->i_op->follow_link2)
121 + err = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
123 + err = dentry->d_inode->i_op->follow_link(dentry, nd);
124 current->link_count--;
127 + intent_release(dentry, it);
131 @@ -449,7 +484,8 @@ static inline void follow_dotdot(struct
133 * We expect 'base' to be positive and a directory.
135 -int link_path_walk(const char * name, struct nameidata *nd)
136 +int link_path_walk_it(const char *name, struct nameidata *nd,
137 + struct lookup_intent *it)
139 struct dentry *dentry;
141 @@ -526,12 +562,12 @@ int link_path_walk(const char * name, st
144 /* This does the actual lookups.. */
145 - dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
146 + dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
148 err = -EWOULDBLOCKIO;
151 - dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
152 + dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
153 err = PTR_ERR(dentry);
156 @@ -548,8 +584,8 @@ int link_path_walk(const char * name, st
160 - if (inode->i_op->follow_link) {
161 - err = do_follow_link(dentry, nd);
162 + if (inode->i_op->follow_link || inode->i_op->follow_link2) {
163 + err = do_follow_link(dentry, nd, NULL);
167 @@ -565,7 +601,7 @@ int link_path_walk(const char * name, st
171 - if (!inode->i_op->lookup)
172 + if (!inode->i_op->lookup && !inode->i_op->lookup2)
175 /* here ends the main loop */
176 @@ -592,12 +628,12 @@ last_component:
180 - dentry = cached_lookup(nd->dentry, &this, 0);
181 + dentry = cached_lookup(nd->dentry, &this, 0, it);
183 err = -EWOULDBLOCKIO;
186 - dentry = real_lookup(nd->dentry, &this, 0);
187 + dentry = real_lookup(nd->dentry, &this, 0, it);
188 err = PTR_ERR(dentry);
191 @@ -606,8 +642,9 @@ last_component:
193 inode = dentry->d_inode;
194 if ((lookup_flags & LOOKUP_FOLLOW)
195 - && inode && inode->i_op && inode->i_op->follow_link) {
196 - err = do_follow_link(dentry, nd);
197 + && inode && inode->i_op &&
198 + (inode->i_op->follow_link || inode->i_op->follow_link2)) {
199 + err = do_follow_link(dentry, nd, it);
203 @@ -621,7 +659,8 @@ last_component:
205 if (lookup_flags & LOOKUP_DIRECTORY) {
207 - if (!inode->i_op || !inode->i_op->lookup)
208 + if (!inode->i_op || (!inode->i_op->lookup &&
209 + !inode->i_op->lookup2))
213 @@ -658,15 +697,28 @@ out_dput:
218 + intent_release(nd->dentry, it);
224 +int link_path_walk(const char * name, struct nameidata *nd)
226 + return link_path_walk_it(name, nd, NULL);
229 +int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
231 + current->total_link_count = 0;
232 + return link_path_walk_it(name, nd, it);
235 int path_walk(const char * name, struct nameidata *nd)
237 current->total_link_count = 0;
238 - return link_path_walk(name, nd);
239 + return link_path_walk_it(name, nd, NULL);
243 @@ -751,6 +803,17 @@ walk_init_root(const char *name, struct
247 +int path_lookup_it(const char *path, unsigned flags, struct nameidata *nd,
248 + struct lookup_intent *it)
251 + if (path_init(path, flags, nd))
252 + error = path_walk_it(path, nd, it);
258 int path_lookup(const char *path, unsigned flags, struct nameidata *nd)
261 @@ -779,7 +842,8 @@ int path_init(const char *name, unsigned
262 * needs parent already locked. Doesn't follow mounts.
265 -struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
266 +struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base,
267 + struct lookup_intent *it)
269 struct dentry * dentry;
271 @@ -802,13 +866,16 @@ struct dentry * lookup_hash(struct qstr
275 - dentry = cached_lookup(base, name, 0);
276 + dentry = cached_lookup(base, name, 0, it);
278 struct dentry *new = d_alloc(base, name);
279 dentry = ERR_PTR(-ENOMEM);
283 + if (inode->i_op->lookup2)
284 + dentry = inode->i_op->lookup2(inode, new, it);
286 dentry = inode->i_op->lookup(inode, new);
289 @@ -820,6 +887,12 @@ out:
293 +struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
295 + return lookup_hash_it(name, base, NULL);
300 struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
302 @@ -841,7 +914,7 @@ struct dentry * lookup_one_len(const cha
304 this.hash = end_name_hash(hash);
306 - return lookup_hash(&this, base);
307 + return lookup_hash_it(&this, base, NULL);
309 return ERR_PTR(-EACCES);
311 @@ -872,6 +945,23 @@ int __user_walk(const char *name, unsign
315 +int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd,
316 + struct lookup_intent *it)
321 + tmp = getname(name);
322 + err = PTR_ERR(tmp);
323 + if (!IS_ERR(tmp)) {
325 + if (path_init(tmp, flags, nd))
326 + err = path_walk_it(tmp, nd, it);
333 * It's inline, so penalty for filesystems that don't use sticky bit is
335 @@ -1045,14 +1135,17 @@ int may_open(struct nameidata *nd, int a
336 return get_lease(inode, flag);
339 +extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
340 + int flags, struct lookup_intent *it);
342 struct file *filp_open(const char * pathname, int open_flags, int mode)
344 int acc_mode, error = 0;
345 - struct inode *inode;
346 struct dentry *dentry;
348 int flag = open_flags;
350 + struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = open_flags };
353 if ((flag+1) & O_ACCMODE)
354 @@ -1066,7 +1159,7 @@ struct file *filp_open(const char * path
355 * The simplest case - just a plain lookup.
357 if (!(flag & O_CREAT)) {
358 - error = path_lookup(pathname, lookup_flags(flag), &nd);
359 + error = path_lookup_it(pathname, lookup_flags(flag), &nd, &it);
361 return ERR_PTR(error);
363 @@ -1076,6 +1169,8 @@ struct file *filp_open(const char * path
365 * Create - we need to know the parent.
368 + it.it_op |= IT_CREAT;
369 error = path_lookup(pathname, LOOKUP_PARENT, &nd);
371 return ERR_PTR(error);
372 @@ -1091,7 +1186,7 @@ struct file *filp_open(const char * path
375 down(&dir->d_inode->i_sem);
376 - dentry = lookup_hash(&nd.last, nd.dentry);
377 + dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
380 error = PTR_ERR(dentry);
381 @@ -1100,6 +1195,7 @@ do_last:
386 /* Negative dentry, just create the file */
387 if (!dentry->d_inode) {
388 error = vfs_create(dir->d_inode, dentry,
389 @@ -1134,7 +1230,8 @@ do_last:
391 if (!dentry->d_inode)
393 - if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link)
394 + if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link ||
395 + dentry->d_inode->i_op->follow_link2))
399 @@ -1149,11 +1246,13 @@ ok:
400 if (!S_ISREG(nd.dentry->d_inode->i_mode))
401 open_flags &= ~O_TRUNC;
403 - return dentry_open(nd.dentry, nd.mnt, open_flags);
404 + return dentry_open_it(nd.dentry, nd.mnt, open_flags, &it);
407 + intent_release(dentry, &it);
410 + intent_release(nd.dentry, &it);
412 return ERR_PTR(error);
414 @@ -1172,7 +1271,12 @@ do_link:
415 * are done. Procfs-like symlinks just set LAST_BIND.
417 UPDATE_ATIME(dentry->d_inode);
418 - error = dentry->d_inode->i_op->follow_link(dentry, &nd);
419 + if (dentry->d_inode->i_op->follow_link2)
420 + error = dentry->d_inode->i_op->follow_link2(dentry, &nd, &it);
422 + error = dentry->d_inode->i_op->follow_link(dentry, &nd);
424 + intent_release(dentry, &it);
428 @@ -1194,13 +1298,15 @@ do_link:
431 down(&dir->d_inode->i_sem);
432 - dentry = lookup_hash(&nd.last, nd.dentry);
433 + dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
434 putname(nd.last.name);
440 -static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
441 +static struct dentry *lookup_create(struct nameidata *nd, int is_dir,
442 + struct lookup_intent *it)
444 struct dentry *dentry;
446 @@ -1208,7 +1314,7 @@ static struct dentry *lookup_create(stru
447 dentry = ERR_PTR(-EEXIST);
448 if (nd->last_type != LAST_NORM)
450 - dentry = lookup_hash(&nd->last, nd->dentry);
451 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
454 if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
455 @@ -1264,7 +1370,19 @@ asmlinkage long sys_mknod(const char * f
456 error = path_lookup(tmp, LOOKUP_PARENT, &nd);
459 - dentry = lookup_create(&nd, 0);
461 + if (nd.dentry->d_inode->i_op->mknod2) {
462 + struct inode_operations *op = nd.dentry->d_inode->i_op;
463 + error = op->mknod2(nd.dentry->d_inode,
467 + /* the file system want to use normal vfs path now */
468 + if (error != -EOPNOTSUPP)
472 + dentry = lookup_create(&nd, 0, NULL);
473 error = PTR_ERR(dentry);
475 mode &= ~current->fs->umask;
476 @@ -1285,6 +1403,7 @@ asmlinkage long sys_mknod(const char * f
479 up(&nd.dentry->d_inode->i_sem);
484 @@ -1332,7 +1451,17 @@ asmlinkage long sys_mkdir(const char * p
485 error = path_lookup(tmp, LOOKUP_PARENT, &nd);
488 - dentry = lookup_create(&nd, 1);
489 + if (nd.dentry->d_inode->i_op->mkdir2) {
490 + struct inode_operations *op = nd.dentry->d_inode->i_op;
491 + error = op->mkdir2(nd.dentry->d_inode,
495 + /* the file system want to use normal vfs path now */
496 + if (error != -EOPNOTSUPP)
499 + dentry = lookup_create(&nd, 1, NULL);
500 error = PTR_ERR(dentry);
501 if (!IS_ERR(dentry)) {
502 error = vfs_mkdir(nd.dentry->d_inode, dentry,
503 @@ -1340,6 +1469,7 @@ asmlinkage long sys_mkdir(const char * p
506 up(&nd.dentry->d_inode->i_sem);
511 @@ -1440,8 +1570,17 @@ asmlinkage long sys_rmdir(const char * p
515 + if (nd.dentry->d_inode->i_op->rmdir2) {
516 + struct inode_operations *op = nd.dentry->d_inode->i_op;
517 + error = op->rmdir2(nd.dentry->d_inode,
520 + /* the file system want to use normal vfs path now */
521 + if (error != -EOPNOTSUPP)
524 down(&nd.dentry->d_inode->i_sem);
525 - dentry = lookup_hash(&nd.last, nd.dentry);
526 + dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
527 error = PTR_ERR(dentry);
528 if (!IS_ERR(dentry)) {
529 error = vfs_rmdir(nd.dentry->d_inode, dentry);
530 @@ -1499,8 +1638,17 @@ asmlinkage long sys_unlink(const char *
532 if (nd.last_type != LAST_NORM)
534 + if (nd.dentry->d_inode->i_op->unlink2) {
535 + struct inode_operations *op = nd.dentry->d_inode->i_op;
536 + error = op->unlink2(nd.dentry->d_inode,
539 + /* the file system want to use normal vfs path now */
540 + if (error != -EOPNOTSUPP)
543 down(&nd.dentry->d_inode->i_sem);
544 - dentry = lookup_hash(&nd.last, nd.dentry);
545 + dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
546 error = PTR_ERR(dentry);
547 if (!IS_ERR(dentry)) {
548 /* Why not before? Because we want correct error value */
549 @@ -1567,15 +1715,26 @@ asmlinkage long sys_symlink(const char *
550 error = path_lookup(to, LOOKUP_PARENT, &nd);
553 - dentry = lookup_create(&nd, 0);
554 + if (nd.dentry->d_inode->i_op->symlink2) {
555 + struct inode_operations *op = nd.dentry->d_inode->i_op;
556 + error = op->symlink2(nd.dentry->d_inode,
560 + /* the file system want to use normal vfs path now */
561 + if (error != -EOPNOTSUPP)
564 + dentry = lookup_create(&nd, 0, NULL);
565 error = PTR_ERR(dentry);
566 if (!IS_ERR(dentry)) {
567 error = vfs_symlink(nd.dentry->d_inode, dentry, from);
570 up(&nd.dentry->d_inode->i_sem);
578 @@ -1642,7 +1801,7 @@ asmlinkage long sys_link(const char * ol
579 struct dentry *new_dentry;
580 struct nameidata nd, old_nd;
582 - error = __user_walk(oldname, LOOKUP_POSITIVE, &old_nd);
583 + error = __user_walk_it(oldname, LOOKUP_POSITIVE, &old_nd, NULL);
586 error = path_lookup(to, LOOKUP_PARENT, &nd);
587 @@ -1651,7 +1810,17 @@ asmlinkage long sys_link(const char * ol
589 if (old_nd.mnt != nd.mnt)
591 - new_dentry = lookup_create(&nd, 0);
592 + if (nd.dentry->d_inode->i_op->link2) {
593 + struct inode_operations *op = nd.dentry->d_inode->i_op;
594 + error = op->link2(old_nd.dentry->d_inode,
595 + nd.dentry->d_inode,
598 + /* the file system want to use normal vfs path now */
599 + if (error != -EOPNOTSUPP)
602 + new_dentry = lookup_create(&nd, 0, NULL);
603 error = PTR_ERR(new_dentry);
604 if (!IS_ERR(new_dentry)) {
605 error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
606 @@ -1695,7 +1864,8 @@ exit:
609 int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
610 - struct inode *new_dir, struct dentry *new_dentry)
611 + struct inode *new_dir, struct dentry *new_dentry,
612 + struct lookup_intent *it)
615 struct inode *target;
616 @@ -1753,6 +1923,7 @@ int vfs_rename_dir(struct inode *old_dir
619 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
620 + intent_release(new_dentry, it);
623 target->i_flags |= S_DEAD;
624 @@ -1774,7 +1945,8 @@ out_unlock:
627 int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
628 - struct inode *new_dir, struct dentry *new_dentry)
629 + struct inode *new_dir, struct dentry *new_dentry,
630 + struct lookup_intent *it)
634 @@ -1805,6 +1977,7 @@ int vfs_rename_other(struct inode *old_d
637 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
638 + intent_release(new_dentry, it);
639 double_up(&old_dir->i_zombie, &new_dir->i_zombie);
642 @@ -1816,13 +1989,14 @@ int vfs_rename_other(struct inode *old_d
645 int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
646 - struct inode *new_dir, struct dentry *new_dentry)
647 + struct inode *new_dir, struct dentry *new_dentry,
648 + struct lookup_intent *it)
651 if (S_ISDIR(old_dentry->d_inode->i_mode))
652 - error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
653 + error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it);
655 - error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
656 + error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it);
658 if (old_dir == new_dir)
659 inode_dir_notify(old_dir, DN_RENAME);
660 @@ -1862,9 +2036,23 @@ static inline int do_rename(const char *
661 if (newnd.last_type != LAST_NORM)
664 + if (old_dir->d_inode->i_op->rename2) {
666 + error = old_dir->d_inode->i_op->rename2(old_dir->d_inode,
673 + /* the file system want to use normal vfs path now */
674 + if (error != -EOPNOTSUPP)
678 double_lock(new_dir, old_dir);
680 - old_dentry = lookup_hash(&oldnd.last, old_dir);
681 + old_dentry = lookup_hash_it(&oldnd.last, old_dir, NULL);
682 error = PTR_ERR(old_dentry);
683 if (IS_ERR(old_dentry))
685 @@ -1880,14 +2068,14 @@ static inline int do_rename(const char *
686 if (newnd.last.name[newnd.last.len])
689 - new_dentry = lookup_hash(&newnd.last, new_dir);
690 + new_dentry = lookup_hash_it(&newnd.last, new_dir, NULL);
691 error = PTR_ERR(new_dentry);
692 if (IS_ERR(new_dentry))
696 error = vfs_rename(old_dir->d_inode, old_dentry,
697 - new_dir->d_inode, new_dentry);
698 + new_dir->d_inode, new_dentry, NULL);
702 @@ -1940,7 +2127,8 @@ out:
706 -__vfs_follow_link(struct nameidata *nd, const char *link)
707 +__vfs_follow_link(struct nameidata *nd, const char *link,
708 + struct lookup_intent *it)
712 @@ -1953,7 +2141,7 @@ __vfs_follow_link(struct nameidata *nd,
713 /* weird __emul_prefix() stuff did it */
716 - res = link_path_walk(link, nd);
717 + res = link_path_walk_it(link, nd, it);
719 if (current->link_count || res || nd->last_type!=LAST_NORM)
721 @@ -1975,7 +2163,13 @@ fail:
723 int vfs_follow_link(struct nameidata *nd, const char *link)
725 - return __vfs_follow_link(nd, link);
726 + return __vfs_follow_link(nd, link, NULL);
729 +int vfs_follow_link_it(struct nameidata *nd, const char *link,
730 + struct lookup_intent *it)
732 + return __vfs_follow_link(nd, link, it);
735 /* get the link contents into pagecache */
736 @@ -2017,7 +2211,7 @@ int page_follow_link(struct dentry *dent
738 struct page *page = NULL;
739 char *s = page_getlink(dentry, &page);
740 - int res = __vfs_follow_link(nd, s);
741 + int res = __vfs_follow_link(nd, s, NULL);
744 page_cache_release(page);
745 --- linux-2.4.18-18.8.0-l7/fs/nfsd/vfs.c~vfs_intent-2.4.18-18 Mon Jan 20 12:25:10 2003
746 +++ linux-2.4.18-18.8.0-l7-root/fs/nfsd/vfs.c Mon Jan 20 12:25:10 2003
747 @@ -1298,7 +1298,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru
751 - err = vfs_rename(fdir, odentry, tdir, ndentry);
752 + err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
754 if (!err && EX_ISSYNC(tfhp->fh_export)) {
755 nfsd_sync_dir(tdentry);
756 --- linux-2.4.18-18.8.0-l7/fs/open.c~vfs_intent-2.4.18-18 Mon Jan 20 12:25:10 2003
757 +++ linux-2.4.18-18.8.0-l7-root/fs/open.c Wed Jan 22 10:39:31 2003
759 #include <asm/uaccess.h>
761 #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
762 +extern int path_walk_it(const char *name, struct nameidata *nd,
763 + struct lookup_intent *it);
764 +extern void intent_release(struct dentry *de, struct lookup_intent *it);
766 int vfs_statfs(struct super_block *sb, struct statfs *buf)
768 @@ -118,12 +121,13 @@ static inline long do_sys_truncate(const
770 struct inode * inode;
772 + struct lookup_intent it = { .it_op = IT_TRUNC };
775 if (length < 0) /* sorry, but loff_t says... */
778 - error = user_path_walk(path, &nd);
779 + error = user_path_walk_it(path, &nd, &it);
782 inode = nd.dentry->d_inode;
783 @@ -168,6 +172,7 @@ static inline long do_sys_truncate(const
784 put_write_access(inode);
787 + intent_release(nd.dentry, &it);
791 @@ -259,8 +264,9 @@ asmlinkage long sys_utime(char * filenam
793 struct inode * inode;
794 struct iattr newattrs;
795 + struct lookup_intent it = { .it_op = IT_SETATTR };
797 - error = user_path_walk(filename, &nd);
798 + error = user_path_walk_it(filename, &nd, &it);
801 inode = nd.dentry->d_inode;
802 @@ -286,6 +292,7 @@ asmlinkage long sys_utime(char * filenam
804 error = notify_change(nd.dentry, &newattrs);
806 + intent_release(nd.dentry, &it);
810 @@ -303,8 +310,9 @@ asmlinkage long sys_utimes(char * filena
812 struct inode * inode;
813 struct iattr newattrs;
814 + struct lookup_intent it = { .it_op = IT_SETATTR };
816 - error = user_path_walk(filename, &nd);
817 + error = user_path_walk_it(filename, &nd, &it);
821 @@ -331,6 +339,7 @@ asmlinkage long sys_utimes(char * filena
823 error = notify_change(nd.dentry, &newattrs);
825 + intent_release(nd.dentry, &it);
829 @@ -347,6 +356,7 @@ asmlinkage long sys_access(const char *
830 int old_fsuid, old_fsgid;
831 kernel_cap_t old_cap;
833 + struct lookup_intent it = { .it_op = IT_GETATTR };
835 if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
837 @@ -364,13 +374,14 @@ asmlinkage long sys_access(const char *
839 current->cap_effective = current->cap_permitted;
841 - res = user_path_walk(filename, &nd);
842 + res = user_path_walk_it(filename, &nd, &it);
844 res = permission(nd.dentry->d_inode, mode);
845 /* SuS v2 requires we report a read only fs too */
846 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
847 && !special_file(nd.dentry->d_inode->i_mode))
849 + intent_release(nd.dentry, &it);
853 @@ -385,8 +396,11 @@ asmlinkage long sys_chdir(const char * f
857 + struct lookup_intent it = { .it_op = IT_GETATTR };
859 - error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd);
860 + error = __user_walk_it(filename,
861 + LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,
866 @@ -397,6 +411,7 @@ asmlinkage long sys_chdir(const char * f
867 set_fs_pwd(current->fs, nd.mnt, nd.dentry);
870 + intent_release(nd.dentry, &it);
874 @@ -436,9 +451,10 @@ asmlinkage long sys_chroot(const char *
878 + struct lookup_intent it = { .it_op = IT_GETATTR };
880 - error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
881 - LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
882 + error = __user_walk_it(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
883 + LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd, &it);
887 @@ -454,6 +470,7 @@ asmlinkage long sys_chroot(const char *
891 + intent_release(nd.dentry, &it);
895 @@ -498,8 +515,9 @@ asmlinkage long sys_chmod(const char * f
896 struct inode * inode;
898 struct iattr newattrs;
899 + struct lookup_intent it = { .it_op = IT_SETATTR };
901 - error = user_path_walk(filename, &nd);
902 + error = user_path_walk_it(filename, &nd, &it);
905 inode = nd.dentry->d_inode;
906 @@ -519,6 +537,7 @@ asmlinkage long sys_chmod(const char * f
907 error = notify_change(nd.dentry, &newattrs);
910 + intent_release(nd.dentry, &it);
914 @@ -588,10 +607,12 @@ asmlinkage long sys_chown(const char * f
918 + struct lookup_intent it = { .it_op = IT_SETATTR };
920 - error = user_path_walk(filename, &nd);
921 + error = user_path_walk_it(filename, &nd, &it);
923 error = chown_common(nd.dentry, user, group);
924 + intent_release(nd.dentry, &it);
928 @@ -601,10 +622,12 @@ asmlinkage long sys_lchown(const char *
932 + struct lookup_intent it = { .it_op = IT_SETATTR };
934 - error = user_path_walk_link(filename, &nd);
935 + error = user_path_walk_link_it(filename, &nd, &it);
937 error = chown_common(nd.dentry, user, group);
938 + intent_release(nd.dentry, &it);
942 @@ -628,7 +651,8 @@ extern ssize_t do_readahead(struct file
943 /* for files over a certains size it doesn't pay to do readahead on open */
944 #define READAHEAD_CUTOFF 48000
946 -struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
947 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
948 + int flags, struct lookup_intent *it)
952 @@ -693,6 +717,7 @@ struct file *dentry_open(struct dentry *
953 do_readahead(f, 0, (48 * 1024) >> PAGE_SHIFT);
956 + intent_release(dentry, it);
960 @@ -707,11 +732,17 @@ cleanup_all:
964 + intent_release(dentry, it);
967 return ERR_PTR(error);
970 +struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
972 + return dentry_open_it(dentry, mnt, flags, NULL);
976 * Find an empty file descriptor entry, and mark it busy.
978 --- linux-2.4.18-18.8.0-l7/fs/stat.c~vfs_intent-2.4.18-18 Mon Jan 20 12:25:10 2003
979 +++ linux-2.4.18-18.8.0-l7-root/fs/stat.c Mon Jan 20 12:25:10 2003
982 #include <asm/uaccess.h>
984 +extern void intent_release(struct dentry *de, struct lookup_intent *it);
986 * Revalidate the inode. This is required for proper NFS attribute caching.
988 @@ -104,10 +105,12 @@ int vfs_stat(char *name, struct kstat *s
992 + struct lookup_intent it = { .it_op = IT_GETATTR };
994 - error = user_path_walk(name, &nd);
995 + error = user_path_walk_it(name, &nd, &it);
997 error = do_getattr(nd.mnt, nd.dentry, stat);
998 + intent_release(nd.dentry, &it);
1002 @@ -117,10 +120,12 @@ int vfs_lstat(char *name, struct kstat *
1004 struct nameidata nd;
1006 + struct lookup_intent it = { .it_op = IT_GETATTR };
1008 - error = user_path_walk_link(name, &nd);
1009 + error = user_path_walk_link_it(name, &nd, &it);
1011 error = do_getattr(nd.mnt, nd.dentry, stat);
1012 + intent_release(nd.dentry, &it);
1016 --- linux-2.4.18-18.8.0-l7/include/linux/dcache.h~vfs_intent-2.4.18-18 Mon Jan 20 12:25:10 2003
1017 +++ linux-2.4.18-18.8.0-l7-root/include/linux/dcache.h Wed Jan 22 19:38:12 2003
1019 #include <asm/atomic.h>
1020 #include <linux/mount.h>
1022 +#define IT_OPEN (1)
1023 +#define IT_CREAT (1<<1)
1024 +#define IT_READDIR (1<<2)
1025 +#define IT_GETATTR (1<<3)
1026 +#define IT_SETATTR (1<<4)
1027 +#define IT_TRUNC (1<<5)
1028 +#define IT_READLINK (1<<6)
1029 +#define IT_LOOKUP (1<<7)
1031 +struct lookup_intent {
1035 + int it_disposition;
1037 + struct iattr *it_iattr;
1038 + __u64 it_lock_handle[2];
1044 * linux/include/linux/dcache.h
1046 @@ -78,6 +99,7 @@ struct dentry {
1047 unsigned long d_time; /* used by d_revalidate */
1048 struct dentry_operations *d_op;
1049 struct super_block * d_sb; /* The root of the dentry tree */
1050 + struct lookup_intent *d_it;
1051 unsigned long d_vfs_flags;
1052 void * d_fsdata; /* fs-specific data */
1053 void * d_extra_attributes; /* TUX-specific data */
1054 @@ -91,6 +113,8 @@ struct dentry_operations {
1055 int (*d_delete)(struct dentry *);
1056 void (*d_release)(struct dentry *);
1057 void (*d_iput)(struct dentry *, struct inode *);
1058 + int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
1059 + void (*d_intent_release)(struct dentry *, struct lookup_intent *);
1062 /* the dentry parameter passed to d_hash and d_compare is the parent
1063 @@ -124,6 +148,7 @@ d_iput: no no yes
1064 * s_nfsd_free_path semaphore will be down
1066 #define DCACHE_REFERENCED 0x0008 /* Recently used, don't discard. */
1067 +#define DCACHE_LUSTRE_INVALID 0x0010 /* Lustre invalidated */
1069 extern spinlock_t dcache_lock;
1071 --- linux-2.4.18-18.8.0-l7/include/linux/fs.h~vfs_intent-2.4.18-18 Mon Jan 20 12:25:10 2003
1072 +++ linux-2.4.18-18.8.0-l7-root/include/linux/fs.h Wed Jan 22 22:46:13 2003
1073 @@ -576,6 +576,7 @@ struct file {
1075 /* needed for tty driver, and maybe others */
1077 + struct lookup_intent *f_intent;
1079 /* preallocated helper kiobuf to speedup O_DIRECT */
1080 struct kiobuf *f_iobuf;
1081 @@ -836,7 +837,9 @@ extern int vfs_symlink(struct inode *, s
1082 extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
1083 extern int vfs_rmdir(struct inode *, struct dentry *);
1084 extern int vfs_unlink(struct inode *, struct dentry *);
1085 -extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
1086 +int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1087 + struct inode *new_dir, struct dentry *new_dentry,
1088 + struct lookup_intent *it);
1092 @@ -897,16 +900,28 @@ struct file_operations {
1093 struct inode_operations {
1094 int (*create) (struct inode *,struct dentry *,int);
1095 struct dentry * (*lookup) (struct inode *,struct dentry *);
1096 + struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *);
1097 int (*link) (struct dentry *,struct inode *,struct dentry *);
1098 + int (*link2) (struct inode *,struct inode *, const char *, int);
1099 int (*unlink) (struct inode *,struct dentry *);
1100 + int (*unlink2) (struct inode *, const char *, int);
1101 int (*symlink) (struct inode *,struct dentry *,const char *);
1102 + int (*symlink2) (struct inode *, const char *, int, const char *);
1103 int (*mkdir) (struct inode *,struct dentry *,int);
1104 + int (*mkdir2) (struct inode *, const char *, int,int);
1105 int (*rmdir) (struct inode *,struct dentry *);
1106 + int (*rmdir2) (struct inode *, const char *, int);
1107 int (*mknod) (struct inode *,struct dentry *,int,int);
1108 + int (*mknod2) (struct inode *, const char *, int,int,int);
1109 int (*rename) (struct inode *, struct dentry *,
1110 struct inode *, struct dentry *);
1111 + int (*rename2) (struct inode *, struct inode *,
1112 + const char *oldname, int oldlen,
1113 + const char *newname, int newlen);
1114 int (*readlink) (struct dentry *, char *,int);
1115 int (*follow_link) (struct dentry *, struct nameidata *);
1116 + int (*follow_link2) (struct dentry *, struct nameidata *,
1117 + struct lookup_intent *it);
1118 void (*truncate) (struct inode *);
1119 int (*permission) (struct inode *, int);
1120 int (*revalidate) (struct dentry *);
1121 @@ -1381,6 +1396,7 @@ typedef int (*read_actor_t)(read_descrip
1122 extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
1124 extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
1125 +extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
1126 extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
1127 extern int FASTCALL(path_walk(const char *, struct nameidata *));
1128 extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
1129 @@ -1392,6 +1408,8 @@ extern struct dentry * lookup_one_len(co
1130 extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
1131 #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
1132 #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
1133 +#define user_path_walk_it(name,nd,it) __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
1134 +#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
1136 extern void inode_init_once(struct inode *);
1137 extern void iput(struct inode *);
1138 @@ -1492,6 +1510,8 @@ extern struct file_operations generic_ro
1140 extern int vfs_readlink(struct dentry *, char *, int, const char *);
1141 extern int vfs_follow_link(struct nameidata *, const char *);
1142 +extern int vfs_follow_link_it(struct nameidata *, const char *,
1143 + struct lookup_intent *it);
1144 extern int page_readlink(struct dentry *, char *, int);
1145 extern int page_follow_link(struct dentry *, struct nameidata *);
1146 extern struct inode_operations page_symlink_inode_operations;
1147 --- linux-2.4.18-18.8.0-l7/kernel/ksyms.c~vfs_intent-2.4.18-18 Mon Jan 20 12:25:10 2003
1148 +++ linux-2.4.18-18.8.0-l7-root/kernel/ksyms.c Mon Jan 20 12:25:10 2003
1149 @@ -293,6 +293,7 @@ EXPORT_SYMBOL(read_cache_page);
1150 EXPORT_SYMBOL(set_page_dirty);
1151 EXPORT_SYMBOL(vfs_readlink);
1152 EXPORT_SYMBOL(vfs_follow_link);
1153 +EXPORT_SYMBOL(vfs_follow_link_it);
1154 EXPORT_SYMBOL(page_readlink);
1155 EXPORT_SYMBOL(page_follow_link);
1156 EXPORT_SYMBOL(page_symlink_inode_operations);