3 fs/namei.c | 378 ++++++++++++++++++++++++++++++++++++++++++-------
5 fs/open.c | 126 ++++++++++++++--
8 include/linux/dcache.h | 31 ++++
9 include/linux/fs.h | 32 +++-
11 10 files changed, 543 insertions(+), 89 deletions(-)
13 --- linux-2.4.20-l18/fs/exec.c~vfs_intent-2.4.20-vanilla Thu Nov 28 18:53:15 2002
14 +++ linux-2.4.20-l18-phil/fs/exec.c Wed May 28 01:39:18 2003
15 @@ -107,8 +107,9 @@ asmlinkage long sys_uselib(const char *
19 + struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY };
21 - error = user_path_walk(library, &nd);
22 + error = user_path_walk_it(library, &nd, &it);
26 @@ -120,7 +121,8 @@ asmlinkage long sys_uselib(const char *
30 - file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
31 + file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &it);
32 + intent_release(nd.dentry, &it);
33 error = PTR_ERR(file);
36 @@ -363,8 +365,9 @@ struct file *open_exec(const char *name)
40 + struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY };
42 - err = path_lookup(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd);
43 + err = path_lookup_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd, &it);
46 inode = nd.dentry->d_inode;
47 @@ -376,7 +379,8 @@ struct file *open_exec(const char *name)
51 - file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
52 + file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &it);
53 + intent_release(nd.dentry, &it);
55 err = deny_write_access(file);
57 @@ -388,6 +392,7 @@ out:
61 + intent_release(nd.dentry, &it);
65 @@ -989,7 +994,7 @@ int do_coredump(long signr, struct pt_re
67 if (!file->f_op->write)
69 - if (do_truncate(file->f_dentry, 0) != 0)
70 + if (do_truncate(file->f_dentry, 0, 0) != 0)
73 retval = binfmt->core_dump(signr, regs, file);
74 --- linux-2.4.20-l18/fs/dcache.c~vfs_intent-2.4.20-vanilla Thu Nov 28 18:53:15 2002
75 +++ linux-2.4.20-l18-phil/fs/dcache.c Wed May 28 01:39:18 2003
76 @@ -181,6 +181,13 @@ int d_invalidate(struct dentry * dentry)
77 spin_unlock(&dcache_lock);
81 + /* network invalidation by Lustre */
82 + if (dentry->d_flags & DCACHE_LUSTRE_INVALID) {
83 + spin_unlock(&dcache_lock);
88 * Check whether to do a partial shrink_dcache
89 * to get rid of unused child entries.
90 @@ -616,6 +623,7 @@ struct dentry * d_alloc(struct dentry *
92 dentry->d_fsdata = NULL;
93 dentry->d_mounted = 0;
94 + dentry->d_it = NULL;
95 INIT_LIST_HEAD(&dentry->d_hash);
96 INIT_LIST_HEAD(&dentry->d_lru);
97 INIT_LIST_HEAD(&dentry->d_subdirs);
98 @@ -830,13 +838,19 @@ void d_delete(struct dentry * dentry)
99 * Adds a dentry to the hash according to its name.
102 -void d_rehash(struct dentry * entry)
103 +void __d_rehash(struct dentry * entry, int lock)
105 struct list_head *list = d_hash(entry->d_parent, entry->d_name.hash);
106 if (!list_empty(&entry->d_hash)) BUG();
107 - spin_lock(&dcache_lock);
108 + if (lock) spin_lock(&dcache_lock);
109 list_add(&entry->d_hash, list);
110 - spin_unlock(&dcache_lock);
111 + if (lock) spin_unlock(&dcache_lock);
113 +EXPORT_SYMBOL(__d_rehash);
115 +void d_rehash(struct dentry * entry)
117 + __d_rehash(entry, 1);
120 #define do_switch(x,y) do { \
121 --- linux-2.4.20-l18/fs/namei.c~vfs_intent-2.4.20-vanilla Thu Nov 28 18:53:15 2002
122 +++ linux-2.4.20-l18-phil/fs/namei.c Sun Jun 1 23:41:35 2003
124 * XEmacs seems to be relying on it...
127 +void intent_release(struct dentry *de, struct lookup_intent *it)
129 + if (it && de->d_op && de->d_op->d_intent_release)
130 + de->d_op->d_intent_release(de, it);
134 /* In order to reduce some races, while at the same time doing additional
135 * checking and hopefully speeding things up, we copy filenames to the
136 * kernel data space before using them..
137 @@ -260,10 +267,19 @@ void path_release(struct nameidata *nd)
138 * Internal lookup() using the new generic dcache.
141 -static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
142 +static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name,
143 + int flags, struct lookup_intent *it)
145 struct dentry * dentry = d_lookup(parent, name);
147 + if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
148 + if (!dentry->d_op->d_revalidate2(dentry, flags, it) &&
149 + !d_invalidate(dentry)) {
155 if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
156 if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
158 @@ -281,11 +297,14 @@ static struct dentry * cached_lookup(str
159 * make sure that nobody added the entry to the dcache in the meantime..
162 -static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
163 +static struct dentry *real_lookup(struct dentry *parent, struct qstr *name,
164 + int flags, struct lookup_intent *it)
166 struct dentry * result;
167 struct inode *dir = parent->d_inode;
173 * First re-do the cached lookup just in case it was created
174 @@ -300,6 +319,9 @@ static struct dentry * real_lookup(struc
175 result = ERR_PTR(-ENOMEM);
178 + if (dir->i_op->lookup2)
179 + result = dir->i_op->lookup2(dir, dentry, it);
181 result = dir->i_op->lookup(dir, dentry);
184 @@ -321,6 +343,12 @@ static struct dentry * real_lookup(struc
186 result = ERR_PTR(-ENOENT);
188 + } else if (result->d_op && result->d_op->d_revalidate2) {
189 + if (!result->d_op->d_revalidate2(result, flags, it) &&
190 + !d_invalidate(result)) {
197 @@ -332,7 +360,8 @@ static struct dentry * real_lookup(struc
198 * Without that kind of total limit, nasty chains of consecutive
199 * symlinks can cause almost arbitrarily long lookups.
201 -static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
202 +static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd,
203 + struct lookup_intent *it)
206 if (current->link_count >= 5)
207 @@ -346,10 +375,21 @@ static inline int do_follow_link(struct
208 current->link_count++;
209 current->total_link_count++;
210 UPDATE_ATIME(dentry->d_inode);
211 - err = dentry->d_inode->i_op->follow_link(dentry, nd);
213 + if (dentry->d_inode->i_op->follow_link2)
214 + err = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
216 + err = dentry->d_inode->i_op->follow_link(dentry, nd);
217 + if (!err && it != NULL && !(it->it_int_flags & IT_FL_FOLLOWED)) {
218 + /* vfs_follow_link was never called */
219 + intent_release(dentry, it);
223 current->link_count--;
226 + intent_release(dentry, it);
230 @@ -379,15 +419,26 @@ int follow_up(struct vfsmount **mnt, str
231 return __follow_up(mnt, dentry);
234 -static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry)
235 +static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry,
236 + struct lookup_intent *it)
238 struct vfsmount *mounted;
240 spin_lock(&dcache_lock);
241 mounted = lookup_mnt(*mnt, *dentry);
243 + int opc = 0, mode = 0;
244 *mnt = mntget(mounted);
245 spin_unlock(&dcache_lock);
248 + mode = it->it_mode;
250 + intent_release(*dentry, it);
253 + it->it_mode = mode;
256 mntput(mounted->mnt_parent);
257 *dentry = dget(mounted->mnt_root);
258 @@ -399,7 +450,7 @@ static inline int __follow_down(struct v
260 int follow_down(struct vfsmount **mnt, struct dentry **dentry)
262 - return __follow_down(mnt,dentry);
263 + return __follow_down(mnt,dentry,NULL);
266 static inline void follow_dotdot(struct nameidata *nd)
267 @@ -435,7 +486,7 @@ static inline void follow_dotdot(struct
271 - while (d_mountpoint(nd->dentry) && __follow_down(&nd->mnt, &nd->dentry))
272 + while (d_mountpoint(nd->dentry) && __follow_down(&nd->mnt, &nd->dentry, NULL))
276 @@ -447,7 +498,8 @@ static inline void follow_dotdot(struct
278 * We expect 'base' to be positive and a directory.
280 -int link_path_walk(const char * name, struct nameidata *nd)
281 +int link_path_walk_it(const char *name, struct nameidata *nd,
282 + struct lookup_intent *it)
284 struct dentry *dentry;
286 @@ -520,15 +572,15 @@ int link_path_walk(const char * name, st
289 /* This does the actual lookups.. */
290 - dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
291 + dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
293 - dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
294 + dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
295 err = PTR_ERR(dentry);
299 /* Check mountpoints.. */
300 - while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry))
301 + while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry, NULL))
305 @@ -539,8 +591,8 @@ int link_path_walk(const char * name, st
309 - if (inode->i_op->follow_link) {
310 - err = do_follow_link(dentry, nd);
311 + if (inode->i_op->follow_link || inode->i_op->follow_link2) {
312 + err = do_follow_link(dentry, nd, NULL);
316 @@ -556,7 +608,7 @@ int link_path_walk(const char * name, st
320 - if (!inode->i_op->lookup)
321 + if (!inode->i_op->lookup && !inode->i_op->lookup2)
324 /* here ends the main loop */
325 @@ -583,19 +635,20 @@ last_component:
329 - dentry = cached_lookup(nd->dentry, &this, 0);
330 + dentry = cached_lookup(nd->dentry, &this, 0, it);
332 - dentry = real_lookup(nd->dentry, &this, 0);
333 + dentry = real_lookup(nd->dentry, &this, 0, it);
334 err = PTR_ERR(dentry);
338 - while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry))
339 + while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry, it))
341 inode = dentry->d_inode;
342 if ((lookup_flags & LOOKUP_FOLLOW)
343 - && inode && inode->i_op && inode->i_op->follow_link) {
344 - err = do_follow_link(dentry, nd);
345 + && inode && inode->i_op &&
346 + (inode->i_op->follow_link || inode->i_op->follow_link2)) {
347 + err = do_follow_link(dentry, nd, it);
351 @@ -609,7 +662,8 @@ last_component:
353 if (lookup_flags & LOOKUP_DIRECTORY) {
355 - if (!inode->i_op || !inode->i_op->lookup)
356 + if (!inode->i_op ||
357 + (!inode->i_op->lookup && !inode->i_op->lookup2))
361 @@ -633,6 +687,23 @@ return_reval:
362 * Check the cached dentry for staleness.
366 + if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
368 + if (!dentry->d_op->d_revalidate2(dentry, 0, it)) {
369 + struct dentry *new;
370 + err = permission(dentry->d_parent->d_inode,
374 + new = real_lookup(dentry->d_parent,
375 + &dentry->d_name, 0, NULL);
376 + d_invalidate(dentry);
379 + goto revalidate_again;
382 if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
384 if (!dentry->d_op->d_revalidate(dentry, 0)) {
385 @@ -646,15 +717,28 @@ out_dput:
390 + intent_release(nd->dentry, it);
396 +int link_path_walk(const char * name, struct nameidata *nd)
398 + return link_path_walk_it(name, nd, NULL);
401 +int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
403 + current->total_link_count = 0;
404 + return link_path_walk_it(name, nd, it);
407 int path_walk(const char * name, struct nameidata *nd)
409 current->total_link_count = 0;
410 - return link_path_walk(name, nd);
411 + return link_path_walk_it(name, nd, NULL);
415 @@ -739,6 +823,17 @@ walk_init_root(const char *name, struct
419 +int path_lookup_it(const char *path, unsigned flags, struct nameidata *nd,
420 + struct lookup_intent *it)
423 + if (path_init(path, flags, nd))
424 + error = path_walk_it(path, nd, it);
430 int path_lookup(const char *path, unsigned flags, struct nameidata *nd)
433 @@ -753,6 +848,7 @@ int path_init(const char *name, unsigned
435 nd->last_type = LAST_ROOT; /* if there are only slashes... */
439 return walk_init_root(name,nd);
440 read_lock(¤t->fs->lock);
441 @@ -767,7 +863,8 @@ int path_init(const char *name, unsigned
442 * needs parent already locked. Doesn't follow mounts.
445 -struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
446 +struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base,
447 + struct lookup_intent *it)
449 struct dentry * dentry;
451 @@ -790,13 +887,16 @@ struct dentry * lookup_hash(struct qstr
455 - dentry = cached_lookup(base, name, 0);
456 + dentry = cached_lookup(base, name, 0, it);
458 struct dentry *new = d_alloc(base, name);
459 dentry = ERR_PTR(-ENOMEM);
463 + if (inode->i_op->lookup2)
464 + dentry = inode->i_op->lookup2(inode, new, it);
466 dentry = inode->i_op->lookup(inode, new);
469 @@ -808,6 +908,12 @@ out:
473 +struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
475 + return lookup_hash_it(name, base, NULL);
480 struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
482 @@ -829,7 +935,7 @@ struct dentry * lookup_one_len(const cha
484 this.hash = end_name_hash(hash);
486 - return lookup_hash(&this, base);
487 + return lookup_hash_it(&this, base, NULL);
489 return ERR_PTR(-EACCES);
491 @@ -860,6 +966,23 @@ int __user_walk(const char *name, unsign
495 +int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd,
496 + struct lookup_intent *it)
501 + tmp = getname(name);
502 + err = PTR_ERR(tmp);
503 + if (!IS_ERR(tmp)) {
505 + if (path_init(tmp, flags, nd))
506 + err = path_walk_it(tmp, nd, it);
513 * It's inline, so penalty for filesystems that don't use sticky bit is
515 @@ -996,7 +1119,8 @@ exit_lock:
516 * for symlinks (where the permissions are checked later).
519 -int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
520 +int open_namei_it(const char *pathname, int flag, int mode,
521 + struct nameidata *nd, struct lookup_intent *it)
523 int acc_mode, error = 0;
525 @@ -1010,7 +1134,7 @@ int open_namei(const char * pathname, in
526 * The simplest case - just a plain lookup.
528 if (!(flag & O_CREAT)) {
529 - error = path_lookup(pathname, lookup_flags(flag), nd);
530 + error = path_lookup_it(pathname, lookup_flags(flag), nd, it);
534 @@ -1020,6 +1144,10 @@ int open_namei(const char * pathname, in
536 * Create - we need to know the parent.
539 + it->it_mode = mode;
540 + it->it_op |= IT_CREAT;
542 error = path_lookup(pathname, LOOKUP_PARENT, nd);
545 @@ -1035,7 +1163,7 @@ int open_namei(const char * pathname, in
548 down(&dir->d_inode->i_sem);
549 - dentry = lookup_hash(&nd->last, nd->dentry);
550 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
553 error = PTR_ERR(dentry);
554 @@ -1044,6 +1172,7 @@ do_last:
558 + it->it_mode = mode;
559 /* Negative dentry, just create the file */
560 if (!dentry->d_inode) {
561 error = vfs_create(dir->d_inode, dentry,
562 @@ -1072,12 +1201,13 @@ do_last:
564 if (flag & O_NOFOLLOW)
566 - while (__follow_down(&nd->mnt,&dentry) && d_mountpoint(dentry));
567 + while (__follow_down(&nd->mnt,&dentry,it) && d_mountpoint(dentry));
570 if (!dentry->d_inode)
572 - if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link)
573 + if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link ||
574 + dentry->d_inode->i_op->follow_link2))
578 @@ -1151,7 +1281,7 @@ ok:
582 - error = do_truncate(dentry, 0);
583 + error = do_truncate(dentry, 0, 1);
585 put_write_access(inode);
587 @@ -1163,8 +1293,10 @@ ok:
591 + intent_release(dentry, it);
594 + intent_release(nd->dentry, it);
598 @@ -1183,7 +1315,19 @@ do_link:
599 * are done. Procfs-like symlinks just set LAST_BIND.
601 UPDATE_ATIME(dentry->d_inode);
602 - error = dentry->d_inode->i_op->follow_link(dentry, nd);
604 + if (dentry->d_inode->i_op->follow_link2)
605 + error = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
607 + error = dentry->d_inode->i_op->follow_link(dentry, nd);
609 + intent_release(dentry, it);
610 + } else if (it != NULL && !(it->it_int_flags & IT_FL_FOLLOWED)) {
611 + /* vfs_follow_link was never called */
612 + intent_release(dentry, it);
619 @@ -1205,13 +1349,20 @@ do_link:
622 down(&dir->d_inode->i_sem);
623 - dentry = lookup_hash(&nd->last, nd->dentry);
624 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
625 putname(nd->last.name);
629 +int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd)
631 + return open_namei_it(pathname, flag, mode, nd, NULL);
636 -static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
637 +static struct dentry *lookup_create(struct nameidata *nd, int is_dir,
638 + struct lookup_intent *it)
640 struct dentry *dentry;
642 @@ -1219,7 +1370,7 @@ static struct dentry *lookup_create(stru
643 dentry = ERR_PTR(-EEXIST);
644 if (nd->last_type != LAST_NORM)
646 - dentry = lookup_hash(&nd->last, nd->dentry);
647 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
650 if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
651 @@ -1275,7 +1426,19 @@ asmlinkage long sys_mknod(const char * f
652 error = path_lookup(tmp, LOOKUP_PARENT, &nd);
655 - dentry = lookup_create(&nd, 0);
657 + if (nd.dentry->d_inode->i_op->mknod2) {
658 + struct inode_operations *op = nd.dentry->d_inode->i_op;
659 + error = op->mknod2(nd.dentry->d_inode,
663 + /* the file system wants to use normal vfs path now */
664 + if (error != -EOPNOTSUPP)
668 + dentry = lookup_create(&nd, 0, NULL);
669 error = PTR_ERR(dentry);
671 mode &= ~current->fs->umask;
672 @@ -1296,6 +1459,7 @@ asmlinkage long sys_mknod(const char * f
675 up(&nd.dentry->d_inode->i_sem);
680 @@ -1343,7 +1507,17 @@ asmlinkage long sys_mkdir(const char * p
681 error = path_lookup(tmp, LOOKUP_PARENT, &nd);
684 - dentry = lookup_create(&nd, 1);
685 + if (nd.dentry->d_inode->i_op->mkdir2) {
686 + struct inode_operations *op = nd.dentry->d_inode->i_op;
687 + error = op->mkdir2(nd.dentry->d_inode,
691 + /* the file system wants to use normal vfs path now */
692 + if (error != -EOPNOTSUPP)
695 + dentry = lookup_create(&nd, 1, NULL);
696 error = PTR_ERR(dentry);
697 if (!IS_ERR(dentry)) {
698 error = vfs_mkdir(nd.dentry->d_inode, dentry,
699 @@ -1351,6 +1525,7 @@ asmlinkage long sys_mkdir(const char * p
702 up(&nd.dentry->d_inode->i_sem);
707 @@ -1451,8 +1626,33 @@ asmlinkage long sys_rmdir(const char * p
711 + if (nd.dentry->d_inode->i_op->rmdir2) {
712 + struct inode_operations *op = nd.dentry->d_inode->i_op;
713 + struct dentry *last;
715 + down(&nd.dentry->d_inode->i_sem);
716 + last = lookup_hash_it(&nd.last, nd.dentry, NULL);
717 + up(&nd.dentry->d_inode->i_sem);
718 + if (IS_ERR(last)) {
719 + error = PTR_ERR(last);
722 + if (d_mountpoint(last)) {
729 + error = op->rmdir2(nd.dentry->d_inode,
732 + /* the file system wants to use normal vfs path now */
733 + if (error != -EOPNOTSUPP)
736 down(&nd.dentry->d_inode->i_sem);
737 - dentry = lookup_hash(&nd.last, nd.dentry);
738 + dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
739 error = PTR_ERR(dentry);
740 if (!IS_ERR(dentry)) {
741 error = vfs_rmdir(nd.dentry->d_inode, dentry);
742 @@ -1510,8 +1710,17 @@ asmlinkage long sys_unlink(const char *
744 if (nd.last_type != LAST_NORM)
746 + if (nd.dentry->d_inode->i_op->unlink2) {
747 + struct inode_operations *op = nd.dentry->d_inode->i_op;
748 + error = op->unlink2(nd.dentry->d_inode,
751 + /* the file system wants to use normal vfs path now */
752 + if (error != -EOPNOTSUPP)
755 down(&nd.dentry->d_inode->i_sem);
756 - dentry = lookup_hash(&nd.last, nd.dentry);
757 + dentry = lookup_hash_it(&nd.last, nd.dentry, NULL);
758 error = PTR_ERR(dentry);
759 if (!IS_ERR(dentry)) {
760 /* Why not before? Because we want correct error value */
761 @@ -1578,15 +1787,26 @@ asmlinkage long sys_symlink(const char *
762 error = path_lookup(to, LOOKUP_PARENT, &nd);
765 - dentry = lookup_create(&nd, 0);
766 + if (nd.dentry->d_inode->i_op->symlink2) {
767 + struct inode_operations *op = nd.dentry->d_inode->i_op;
768 + error = op->symlink2(nd.dentry->d_inode,
772 + /* the file system wants to use normal vfs path now */
773 + if (error != -EOPNOTSUPP)
776 + dentry = lookup_create(&nd, 0, NULL);
777 error = PTR_ERR(dentry);
778 if (!IS_ERR(dentry)) {
779 error = vfs_symlink(nd.dentry->d_inode, dentry, from);
782 up(&nd.dentry->d_inode->i_sem);
790 @@ -1662,7 +1882,17 @@ asmlinkage long sys_link(const char * ol
792 if (old_nd.mnt != nd.mnt)
794 - new_dentry = lookup_create(&nd, 0);
795 + if (nd.dentry->d_inode->i_op->link2) {
796 + struct inode_operations *op = nd.dentry->d_inode->i_op;
797 + error = op->link2(old_nd.dentry->d_inode,
798 + nd.dentry->d_inode,
801 + /* the file system wants to use normal vfs path now */
802 + if (error != -EOPNOTSUPP)
805 + new_dentry = lookup_create(&nd, 0, NULL);
806 error = PTR_ERR(new_dentry);
807 if (!IS_ERR(new_dentry)) {
808 error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
809 @@ -1706,7 +1936,8 @@ exit:
812 int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
813 - struct inode *new_dir, struct dentry *new_dentry)
814 + struct inode *new_dir, struct dentry *new_dentry,
815 + struct lookup_intent *it)
818 struct inode *target;
819 @@ -1764,6 +1995,7 @@ int vfs_rename_dir(struct inode *old_dir
822 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
823 + intent_release(new_dentry, it);
826 target->i_flags |= S_DEAD;
827 @@ -1785,7 +2017,8 @@ out_unlock:
830 int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
831 - struct inode *new_dir, struct dentry *new_dentry)
832 + struct inode *new_dir, struct dentry *new_dentry,
833 + struct lookup_intent *it)
837 @@ -1816,6 +2049,7 @@ int vfs_rename_other(struct inode *old_d
840 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
841 + intent_release(new_dentry, it);
842 double_up(&old_dir->i_zombie, &new_dir->i_zombie);
845 @@ -1827,13 +2061,14 @@ int vfs_rename_other(struct inode *old_d
848 int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
849 - struct inode *new_dir, struct dentry *new_dentry)
850 + struct inode *new_dir, struct dentry *new_dentry,
851 + struct lookup_intent *it)
854 if (S_ISDIR(old_dentry->d_inode->i_mode))
855 - error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
856 + error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it);
858 - error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
859 + error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it);
861 if (old_dir == new_dir)
862 inode_dir_notify(old_dir, DN_RENAME);
863 @@ -1875,7 +2110,7 @@ static inline int do_rename(const char *
865 double_lock(new_dir, old_dir);
867 - old_dentry = lookup_hash(&oldnd.last, old_dir);
868 + old_dentry = lookup_hash_it(&oldnd.last, old_dir, NULL);
869 error = PTR_ERR(old_dentry);
870 if (IS_ERR(old_dentry))
872 @@ -1891,16 +2126,37 @@ static inline int do_rename(const char *
873 if (newnd.last.name[newnd.last.len])
876 - new_dentry = lookup_hash(&newnd.last, new_dir);
877 + new_dentry = lookup_hash_it(&newnd.last, new_dir, NULL);
878 error = PTR_ERR(new_dentry);
879 if (IS_ERR(new_dentry))
882 + if (old_dir->d_inode->i_op->rename2) {
884 + /* don't rename mount point. mds will take care of
885 + * the rest sanity checking */
886 + if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) {
891 + error = old_dir->d_inode->i_op->rename2(old_dir->d_inode,
898 + /* the file system wants to use normal vfs path now */
899 + if (error != -EOPNOTSUPP)
904 error = vfs_rename(old_dir->d_inode, old_dentry,
905 - new_dir->d_inode, new_dentry);
906 + new_dir->d_inode, new_dentry, NULL);
913 @@ -1951,20 +2207,28 @@ out:
917 -__vfs_follow_link(struct nameidata *nd, const char *link)
918 +__vfs_follow_link(struct nameidata *nd, const char *link,
919 + struct lookup_intent *it)
928 + else if (it != nd->it)
929 + printk("it != nd->it: tell phil@clusterfs.com\n");
931 + it->it_int_flags |= IT_FL_FOLLOWED;
935 if (!walk_init_root(link, nd))
936 /* weird __emul_prefix() stuff did it */
939 - res = link_path_walk(link, nd);
940 + res = link_path_walk_it(link, nd, it);
942 if (current->link_count || res || nd->last_type!=LAST_NORM)
944 @@ -1986,7 +2250,13 @@ fail:
946 int vfs_follow_link(struct nameidata *nd, const char *link)
948 - return __vfs_follow_link(nd, link);
949 + return __vfs_follow_link(nd, link, NULL);
952 +int vfs_follow_link_it(struct nameidata *nd, const char *link,
953 + struct lookup_intent *it)
955 + return __vfs_follow_link(nd, link, it);
958 /* get the link contents into pagecache */
959 @@ -2028,7 +2298,7 @@ int page_follow_link(struct dentry *dent
961 struct page *page = NULL;
962 char *s = page_getlink(dentry, &page);
963 - int res = __vfs_follow_link(nd, s);
964 + int res = __vfs_follow_link(nd, s, NULL);
967 page_cache_release(page);
968 --- linux-2.4.20-l18/fs/nfsd/vfs.c~vfs_intent-2.4.20-vanilla Thu Nov 28 18:53:15 2002
969 +++ linux-2.4.20-l18-phil/fs/nfsd/vfs.c Wed May 28 01:39:18 2003
970 @@ -1291,7 +1291,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru
974 - err = vfs_rename(fdir, odentry, tdir, ndentry);
975 + err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
976 if (!err && EX_ISSYNC(tfhp->fh_export)) {
977 nfsd_sync_dir(tdentry);
978 nfsd_sync_dir(fdentry);
979 --- linux-2.4.20-l18/fs/open.c~vfs_intent-2.4.20-vanilla Thu Nov 28 18:53:15 2002
980 +++ linux-2.4.20-l18-phil/fs/open.c Wed May 28 01:39:18 2003
982 #include <asm/uaccess.h>
984 #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
985 +extern int path_walk_it(const char *name, struct nameidata *nd,
986 + struct lookup_intent *it);
988 int vfs_statfs(struct super_block *sb, struct statfs *buf)
990 @@ -95,9 +97,10 @@ void fd_install(unsigned int fd, struct
991 write_unlock(&files->file_lock);
994 -int do_truncate(struct dentry *dentry, loff_t length)
995 +int do_truncate(struct dentry *dentry, loff_t length, int called_from_open)
997 struct inode *inode = dentry->d_inode;
998 + struct inode_operations *op = dentry->d_inode->i_op;
1000 struct iattr newattrs;
1002 @@ -108,7 +111,14 @@ int do_truncate(struct dentry *dentry, l
1003 down(&inode->i_sem);
1004 newattrs.ia_size = length;
1005 newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
1006 - error = notify_change(dentry, &newattrs);
1007 + if (called_from_open)
1008 + newattrs.ia_valid |= ATTR_FROM_OPEN;
1009 + if (op->setattr_raw) {
1010 + newattrs.ia_valid |= ATTR_RAW;
1011 + newattrs.ia_ctime = CURRENT_TIME;
1012 + error = op->setattr_raw(inode, &newattrs);
1014 + error = notify_change(dentry, &newattrs);
1018 @@ -118,12 +128,13 @@ static inline long do_sys_truncate(const
1019 struct nameidata nd;
1020 struct inode * inode;
1022 + struct lookup_intent it = { .it_op = IT_GETATTR };
1025 if (length < 0) /* sorry, but loff_t says... */
1028 - error = user_path_walk(path, &nd);
1029 + error = user_path_walk_it(path, &nd, &it);
1032 inode = nd.dentry->d_inode;
1033 @@ -163,11 +174,13 @@ static inline long do_sys_truncate(const
1034 error = locks_verify_truncate(inode, NULL, length);
1037 - error = do_truncate(nd.dentry, length);
1038 + intent_release(nd.dentry, &it);
1039 + error = do_truncate(nd.dentry, length, 0);
1041 put_write_access(inode);
1044 + intent_release(nd.dentry, &it);
1048 @@ -215,7 +228,7 @@ static inline long do_sys_ftruncate(unsi
1050 error = locks_verify_truncate(inode, file, length);
1052 - error = do_truncate(dentry, length);
1053 + error = do_truncate(dentry, length, 0);
1057 @@ -260,11 +273,13 @@ asmlinkage long sys_utime(char * filenam
1058 struct inode * inode;
1059 struct iattr newattrs;
1061 - error = user_path_walk(filename, &nd);
1062 + error = user_path_walk_it(filename, &nd, NULL);
1065 inode = nd.dentry->d_inode;
1067 + /* this is safe without a Lustre lock because it only depends
1068 + on the super block */
1070 if (IS_RDONLY(inode))
1072 @@ -279,11 +294,29 @@ asmlinkage long sys_utime(char * filenam
1075 newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
1079 + if (inode->i_op->setattr_raw) {
1080 + struct inode_operations *op = nd.dentry->d_inode->i_op;
1082 + newattrs.ia_valid |= ATTR_RAW;
1083 + error = op->setattr_raw(inode, &newattrs);
1084 + /* the file system wants to use normal vfs path now */
1085 + if (error != -EOPNOTSUPP)
1086 + goto dput_and_out;
1090 + if (IS_RDONLY(inode))
1091 + goto dput_and_out;
1095 if (current->fsuid != inode->i_uid &&
1096 (error = permission(inode,MAY_WRITE)) != 0)
1100 error = notify_change(nd.dentry, &newattrs);
1103 @@ -304,12 +337,14 @@ asmlinkage long sys_utimes(char * filena
1104 struct inode * inode;
1105 struct iattr newattrs;
1107 - error = user_path_walk(filename, &nd);
1108 + error = user_path_walk_it(filename, &nd, NULL);
1112 inode = nd.dentry->d_inode;
1114 + /* this is safe without a Lustre lock because it only depends
1115 + on the super block */
1117 if (IS_RDONLY(inode))
1119 @@ -324,7 +359,20 @@ asmlinkage long sys_utimes(char * filena
1120 newattrs.ia_atime = times[0].tv_sec;
1121 newattrs.ia_mtime = times[1].tv_sec;
1122 newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
1126 + if (inode->i_op->setattr_raw) {
1127 + struct inode_operations *op = nd.dentry->d_inode->i_op;
1129 + newattrs.ia_valid |= ATTR_RAW;
1130 + error = op->setattr_raw(inode, &newattrs);
1131 + /* the file system wants to use normal vfs path now */
1132 + if (error != -EOPNOTSUPP)
1133 + goto dput_and_out;
1138 if (current->fsuid != inode->i_uid &&
1139 (error = permission(inode,MAY_WRITE)) != 0)
1141 @@ -347,6 +395,7 @@ asmlinkage long sys_access(const char *
1142 int old_fsuid, old_fsgid;
1143 kernel_cap_t old_cap;
1145 + struct lookup_intent it = { .it_op = IT_GETATTR };
1147 if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
1149 @@ -364,13 +413,14 @@ asmlinkage long sys_access(const char *
1151 current->cap_effective = current->cap_permitted;
1153 - res = user_path_walk(filename, &nd);
1154 + res = user_path_walk_it(filename, &nd, &it);
1156 res = permission(nd.dentry->d_inode, mode);
1157 /* SuS v2 requires we report a read only fs too */
1158 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
1159 && !special_file(nd.dentry->d_inode->i_mode))
1161 + intent_release(nd.dentry, &it);
1165 @@ -385,8 +435,9 @@ asmlinkage long sys_chdir(const char * f
1168 struct nameidata nd;
1169 + struct lookup_intent it = { .it_op = IT_GETATTR };
1171 - error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd);
1172 + error = __user_walk_it(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd, &it);
1176 @@ -397,6 +448,7 @@ asmlinkage long sys_chdir(const char * f
1177 set_fs_pwd(current->fs, nd.mnt, nd.dentry);
1180 + intent_release(nd.dentry, &it);
1184 @@ -436,9 +488,10 @@ asmlinkage long sys_chroot(const char *
1187 struct nameidata nd;
1188 + struct lookup_intent it = { .it_op = IT_GETATTR };
1190 - error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
1191 - LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
1192 + error = __user_walk_it(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
1193 + LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd, &it);
1197 @@ -454,6 +507,7 @@ asmlinkage long sys_chroot(const char *
1201 + intent_release(nd.dentry, &it);
1205 @@ -508,6 +562,18 @@ asmlinkage long sys_chmod(const char * f
1206 if (IS_RDONLY(inode))
1209 + if (inode->i_op->setattr_raw) {
1210 + struct inode_operations *op = nd.dentry->d_inode->i_op;
1212 + newattrs.ia_mode = mode;
1213 + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
1214 + newattrs.ia_valid |= ATTR_RAW;
1215 + error = op->setattr_raw(inode, &newattrs);
1216 + /* the file system wants to use normal vfs path now */
1217 + if (error != -EOPNOTSUPP)
1218 + goto dput_and_out;
1222 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
1224 @@ -538,6 +604,20 @@ static int chown_common(struct dentry *
1226 if (IS_RDONLY(inode))
1229 + if (inode->i_op->setattr_raw) {
1230 + struct inode_operations *op = dentry->d_inode->i_op;
1232 + newattrs.ia_uid = user;
1233 + newattrs.ia_gid = group;
1234 + newattrs.ia_valid = ATTR_UID | ATTR_GID;
1235 + newattrs.ia_valid |= ATTR_RAW;
1236 + error = op->setattr_raw(inode, &newattrs);
1237 + /* the file system wants to use normal vfs path now */
1238 + if (error != -EOPNOTSUPP)
1243 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
1245 @@ -638,10 +718,12 @@ asmlinkage long sys_fchown(unsigned int
1246 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
1250 struct file *filp_open(const char * filename, int flags, int mode)
1252 int namei_flags, error;
1253 struct nameidata nd;
1254 + struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = flags };
1256 namei_flags = flags;
1257 if ((namei_flags+1) & O_ACCMODE)
1258 @@ -649,14 +731,15 @@ struct file *filp_open(const char * file
1259 if (namei_flags & O_TRUNC)
1262 - error = open_namei(filename, namei_flags, mode, &nd);
1264 - return dentry_open(nd.dentry, nd.mnt, flags);
1265 + error = open_namei_it(filename, namei_flags, mode, &nd, &it);
1267 + return ERR_PTR(error);
1269 - return ERR_PTR(error);
1270 + return dentry_open_it(nd.dentry, nd.mnt, flags, &it);
1273 -struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1274 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1275 + int flags, struct lookup_intent *it)
1278 struct inode *inode;
1279 @@ -699,6 +782,7 @@ struct file *dentry_open(struct dentry *
1281 f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
1283 + intent_release(dentry, it);
1287 @@ -713,11 +797,17 @@ cleanup_all:
1291 + intent_release(dentry, it);
1294 return ERR_PTR(error);
1297 +struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1299 + return dentry_open_it(dentry, mnt, flags, NULL);
1303 * Find an empty file descriptor entry, and mark it busy.
1305 --- linux-2.4.20-l18/fs/stat.c~vfs_intent-2.4.20-vanilla Thu Sep 13 19:04:43 2001
1306 +++ linux-2.4.20-l18-phil/fs/stat.c Wed May 28 01:39:18 2003
1307 @@ -135,13 +135,15 @@ static int cp_new_stat(struct inode * in
1308 asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf)
1310 struct nameidata nd;
1311 + struct lookup_intent it = { .it_op = IT_GETATTR };
1314 - error = user_path_walk(filename, &nd);
1315 + error = user_path_walk_it(filename, &nd, &it);
1317 error = do_revalidate(nd.dentry);
1319 error = cp_old_stat(nd.dentry->d_inode, statbuf);
1320 + intent_release(nd.dentry, &it);
1324 @@ -151,13 +153,15 @@ asmlinkage long sys_stat(char * filename
1325 asmlinkage long sys_newstat(char * filename, struct stat * statbuf)
1327 struct nameidata nd;
1328 + struct lookup_intent it = { .it_op = IT_GETATTR };
1331 - error = user_path_walk(filename, &nd);
1332 + error = user_path_walk_it(filename, &nd, &it);
1334 error = do_revalidate(nd.dentry);
1336 error = cp_new_stat(nd.dentry->d_inode, statbuf);
1337 + intent_release(nd.dentry, &it);
1341 @@ -172,13 +176,15 @@ asmlinkage long sys_newstat(char * filen
1342 asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf)
1344 struct nameidata nd;
1345 + struct lookup_intent it = { .it_op = IT_GETATTR };
1348 - error = user_path_walk_link(filename, &nd);
1349 + error = user_path_walk_link_it(filename, &nd, &it);
1351 error = do_revalidate(nd.dentry);
1353 error = cp_old_stat(nd.dentry->d_inode, statbuf);
1354 + intent_release(nd.dentry, &it);
1358 @@ -189,13 +195,15 @@ asmlinkage long sys_lstat(char * filenam
1359 asmlinkage long sys_newlstat(char * filename, struct stat * statbuf)
1361 struct nameidata nd;
1362 + struct lookup_intent it = { .it_op = IT_GETATTR };
1365 - error = user_path_walk_link(filename, &nd);
1366 + error = user_path_walk_link_it(filename, &nd, &it);
1368 error = do_revalidate(nd.dentry);
1370 error = cp_new_stat(nd.dentry->d_inode, statbuf);
1371 + intent_release(nd.dentry, &it);
1375 @@ -333,12 +341,14 @@ asmlinkage long sys_stat64(char * filena
1377 struct nameidata nd;
1379 + struct lookup_intent it = { .it_op = IT_GETATTR };
1381 - error = user_path_walk(filename, &nd);
1382 + error = user_path_walk_it(filename, &nd, &it);
1384 error = do_revalidate(nd.dentry);
1386 error = cp_new_stat64(nd.dentry->d_inode, statbuf);
1387 + intent_release(nd.dentry, &it);
1391 @@ -348,12 +358,14 @@ asmlinkage long sys_lstat64(char * filen
1393 struct nameidata nd;
1395 + struct lookup_intent it = { .it_op = IT_GETATTR };
1397 - error = user_path_walk_link(filename, &nd);
1398 + error = user_path_walk_link_it(filename, &nd, &it);
1400 error = do_revalidate(nd.dentry);
1402 error = cp_new_stat64(nd.dentry->d_inode, statbuf);
1403 + intent_release(nd.dentry, &it);
1407 --- linux-2.4.20-l18/fs/proc/base.c~vfs_intent-2.4.20-vanilla Wed Jun 4 22:53:14 2003
1408 +++ linux-2.4.20-l18-phil/fs/proc/base.c Wed Jun 4 22:50:35 2003
1409 @@ -464,6 +464,9 @@ static int proc_pid_follow_link(struct d
1411 error = inode->u.proc_i.op.proc_get_link(inode, &nd->dentry, &nd->mnt);
1412 nd->last_type = LAST_BIND;
1414 + if (nd->it != NULL)
1415 + nd->it->it_int_flags |= IT_FL_FOLLOWED;
1419 --- linux-2.4.20-l18/include/linux/dcache.h~vfs_intent-2.4.20-vanilla Thu Nov 28 18:53:15 2002
1420 +++ linux-2.4.20-l18-phil/include/linux/dcache.h Sun Jun 1 22:35:10 2003
1422 #include <linux/mount.h>
1423 #include <linux/kernel.h>
1425 +#define IT_OPEN (1)
1426 +#define IT_CREAT (1<<1)
1427 +#define IT_READDIR (1<<2)
1428 +#define IT_GETATTR (1<<3)
1429 +#define IT_LOOKUP (1<<4)
1430 +#define IT_UNLINK (1<<5)
1432 +#define IT_FL_LOCKED (1)
1433 +#define IT_FL_FOLLOWED (1<<1) /* set by vfs_follow_link */
1435 +struct lookup_intent {
1439 + int it_disposition;
1442 + __u64 it_lock_handle[2];
1448 * linux/include/linux/dcache.h
1450 @@ -79,6 +101,7 @@ struct dentry {
1451 unsigned long d_time; /* used by d_revalidate */
1452 struct dentry_operations *d_op;
1453 struct super_block * d_sb; /* The root of the dentry tree */
1454 + struct lookup_intent *d_it;
1455 unsigned long d_vfs_flags;
1456 void * d_fsdata; /* fs-specific data */
1457 unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
1458 @@ -91,8 +114,15 @@ struct dentry_operations {
1459 int (*d_delete)(struct dentry *);
1460 void (*d_release)(struct dentry *);
1461 void (*d_iput)(struct dentry *, struct inode *);
1462 + int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
1463 + void (*d_intent_release)(struct dentry *, struct lookup_intent *);
1466 +/* defined in fs/namei.c */
1467 +extern void intent_release(struct dentry *de, struct lookup_intent *it);
1468 +/* defined in fs/dcache.c */
1469 +extern void __d_rehash(struct dentry * entry, int lock);
1471 /* the dentry parameter passed to d_hash and d_compare is the parent
1472 * directory of the entries to be compared. It is used in case these
1473 * functions need any directory specific information for determining
1474 @@ -124,6 +154,7 @@ d_iput: no no yes
1475 * s_nfsd_free_path semaphore will be down
1477 #define DCACHE_REFERENCED 0x0008 /* Recently used, don't discard. */
1478 +#define DCACHE_LUSTRE_INVALID 0x0010 /* Lustre invalidated */
1480 extern spinlock_t dcache_lock;
1482 --- linux-2.4.20-l18/include/linux/fs.h~vfs_intent-2.4.20-vanilla Wed May 28 01:39:17 2003
1483 +++ linux-2.4.20-l18-phil/include/linux/fs.h Sun Jun 1 22:07:11 2003
1484 @@ -338,6 +338,8 @@ extern void set_bh_page(struct buffer_he
1485 #define ATTR_MTIME_SET 256
1486 #define ATTR_FORCE 512 /* Not a change, but a change it */
1487 #define ATTR_ATTR_FLAG 1024
1488 +#define ATTR_RAW 2048 /* file system, not vfs will massage attrs */
1489 +#define ATTR_FROM_OPEN 4096 /* called from open path, ie O_TRUNC */
1492 * This is the Inode Attributes structure, used for notify_change(). It
1493 @@ -542,6 +544,7 @@ struct file {
1495 /* needed for tty driver, and maybe others */
1497 + struct lookup_intent *f_intent;
1499 /* preallocated helper kiobuf to speedup O_DIRECT */
1500 struct kiobuf *f_iobuf;
1501 @@ -661,6 +664,7 @@ struct nameidata {
1505 + struct lookup_intent *it;
1508 #define DQUOT_USR_ENABLED 0x01 /* User diskquotas enabled */
1509 @@ -794,7 +798,9 @@ extern int vfs_symlink(struct inode *, s
1510 extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
1511 extern int vfs_rmdir(struct inode *, struct dentry *);
1512 extern int vfs_unlink(struct inode *, struct dentry *);
1513 -extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
1514 +int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1515 + struct inode *new_dir, struct dentry *new_dentry,
1516 + struct lookup_intent *it);
1520 @@ -855,20 +861,33 @@ struct file_operations {
1521 struct inode_operations {
1522 int (*create) (struct inode *,struct dentry *,int);
1523 struct dentry * (*lookup) (struct inode *,struct dentry *);
1524 + struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *);
1525 int (*link) (struct dentry *,struct inode *,struct dentry *);
1526 + int (*link2) (struct inode *,struct inode *, const char *, int);
1527 int (*unlink) (struct inode *,struct dentry *);
1528 + int (*unlink2) (struct inode *, const char *, int);
1529 int (*symlink) (struct inode *,struct dentry *,const char *);
1530 + int (*symlink2) (struct inode *, const char *, int, const char *);
1531 int (*mkdir) (struct inode *,struct dentry *,int);
1532 + int (*mkdir2) (struct inode *, const char *, int,int);
1533 int (*rmdir) (struct inode *,struct dentry *);
1534 + int (*rmdir2) (struct inode *, const char *, int);
1535 int (*mknod) (struct inode *,struct dentry *,int,int);
1536 + int (*mknod2) (struct inode *, const char *, int,int,int);
1537 int (*rename) (struct inode *, struct dentry *,
1538 struct inode *, struct dentry *);
1539 + int (*rename2) (struct inode *, struct inode *,
1540 + const char *oldname, int oldlen,
1541 + const char *newname, int newlen);
1542 int (*readlink) (struct dentry *, char *,int);
1543 int (*follow_link) (struct dentry *, struct nameidata *);
1544 + int (*follow_link2) (struct dentry *, struct nameidata *,
1545 + struct lookup_intent *it);
1546 void (*truncate) (struct inode *);
1547 int (*permission) (struct inode *, int);
1548 int (*revalidate) (struct dentry *);
1549 int (*setattr) (struct dentry *, struct iattr *);
1550 + int (*setattr_raw) (struct inode *, struct iattr *);
1551 int (*getattr) (struct dentry *, struct iattr *);
1552 int (*setxattr) (struct dentry *, const char *, void *, size_t, int);
1553 ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
1554 @@ -1070,10 +1089,14 @@ static inline int get_lease(struct inode
1556 asmlinkage long sys_open(const char *, int, int);
1557 asmlinkage long sys_close(unsigned int); /* yes, it's really unsigned */
1558 -extern int do_truncate(struct dentry *, loff_t start);
1559 +extern int do_truncate(struct dentry *, loff_t start, int called_from_open);
1561 extern struct file *filp_open(const char *, int, int);
1562 extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
1563 +extern int open_namei_it(const char *filename, int namei_flags, int mode,
1564 + struct nameidata *nd, struct lookup_intent *it);
1565 +extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1566 + int flags, struct lookup_intent *it);
1567 extern int filp_close(struct file *, fl_owner_t id);
1568 extern char * getname(const char *);
1570 @@ -1335,6 +1358,7 @@ typedef int (*read_actor_t)(read_descrip
1571 extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
1573 extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
1574 +extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
1575 extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
1576 extern int FASTCALL(path_walk(const char *, struct nameidata *));
1577 extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
1578 @@ -1346,6 +1370,8 @@ extern struct dentry * lookup_one_len(co
1579 extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
1580 #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
1581 #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
1582 +#define user_path_walk_it(name,nd,it) __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
1583 +#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
1585 extern void iput(struct inode *);
1586 extern void force_delete(struct inode *);
1587 @@ -1455,6 +1481,8 @@ extern struct file_operations generic_ro
1589 extern int vfs_readlink(struct dentry *, char *, int, const char *);
1590 extern int vfs_follow_link(struct nameidata *, const char *);
1591 +extern int vfs_follow_link_it(struct nameidata *, const char *,
1592 + struct lookup_intent *it);
1593 extern int page_readlink(struct dentry *, char *, int);
1594 extern int page_follow_link(struct dentry *, struct nameidata *);
1595 extern struct inode_operations page_symlink_inode_operations;
1596 --- linux-2.4.20-l18/kernel/ksyms.c~vfs_intent-2.4.20-vanilla Wed May 28 01:39:18 2003
1597 +++ linux-2.4.20-l18-phil/kernel/ksyms.c Wed May 28 01:39:18 2003
1598 @@ -269,6 +269,7 @@ EXPORT_SYMBOL(read_cache_page);
1599 EXPORT_SYMBOL(set_page_dirty);
1600 EXPORT_SYMBOL(vfs_readlink);
1601 EXPORT_SYMBOL(vfs_follow_link);
1602 +EXPORT_SYMBOL(vfs_follow_link_it);
1603 EXPORT_SYMBOL(page_readlink);
1604 EXPORT_SYMBOL(page_follow_link);
1605 EXPORT_SYMBOL(page_symlink_inode_operations);