1 --- linux/include/linux/fs.h.lustre-orig Wed May 22 08:29:48 2002
2 +++ linux/include/linux/fs.h Tue Jun 4 09:24:48 2002
4 #include <linux/ncp_fs_i.h>
5 #include <linux/proc_fs_i.h>
6 #include <linux/usbdev_fs_i.h>
7 -#include <linux/hostfs_fs_i.h>
8 #include <linux/jffs2_fs_i.h>
9 +#include <linux/hostfs_fs_i.h>
10 #include <linux/cramfs_fs_sb.h>
14 struct proc_inode_info proc_i;
15 struct socket socket_i;
16 struct usbdev_inode_info usbdev_i;
17 - struct hostfs_inode_info hostfs_i;
18 struct jffs2_inode_info jffs2_i;
19 + struct hostfs_inode_info hostfs_i;
25 /* needed for tty driver, and maybe others */
27 + struct lookup_intent *f_intent;
29 /* preallocated helper kiobuf to speedup O_DIRECT */
30 struct kiobuf *f_iobuf;
32 extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
33 extern int vfs_rmdir(struct inode *, struct dentry *);
34 extern int vfs_unlink(struct inode *, struct dentry *);
35 -extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
36 +int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
37 + struct inode *new_dir, struct dentry *new_dentry,
38 + struct lookup_intent *it);
43 struct inode_operations {
44 int (*create) (struct inode *,struct dentry *,int);
45 struct dentry * (*lookup) (struct inode *,struct dentry *);
46 + struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *);
47 int (*link) (struct dentry *,struct inode *,struct dentry *);
48 int (*unlink) (struct inode *,struct dentry *);
49 int (*symlink) (struct inode *,struct dentry *,const char *);
51 int (*revalidate) (struct dentry *);
52 int (*setattr) (struct dentry *, struct iattr *);
53 int (*getattr) (struct dentry *, struct iattr *);
54 + int (*setxattr) (struct dentry *, const char *, void *, size_t, int);
55 + ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
56 + ssize_t (*listxattr) (struct dentry *, char *, size_t);
57 + int (*removexattr) (struct dentry *, const char *);
62 extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
64 extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
65 +extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
66 extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
67 extern int FASTCALL(path_walk(const char *, struct nameidata *));
68 extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
70 extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
71 #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
72 #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
73 +#define user_path_walk_it(name,nd,it) __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
74 +#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
76 extern void iput(struct inode *);
77 extern void force_delete(struct inode *);
78 --- linux/include/linux/dcache.h.lustre-orig Wed May 22 08:29:48 2002
79 +++ linux/include/linux/dcache.h Tue Jun 4 09:24:45 2002
81 #include <asm/atomic.h>
82 #include <linux/mount.h>
85 +#define IT_CREAT (1<<1)
86 +#define IT_MKDIR (1<<2)
87 +#define IT_LINK (1<<3)
88 +#define IT_SYMLINK (1<<4)
89 +#define IT_UNLINK (1<<5)
90 +#define IT_RMDIR (1<<6)
91 +#define IT_RENAME (1<<7)
92 +#define IT_READDIR (1<<8)
93 +#define IT_GETATTR (1<<9)
94 +#define IT_SETATTR (1<<10)
95 +#define IT_READLINK (1<<11)
97 +struct lookup_intent {
100 + int it_disposition;
102 + struct iattr *it_iattr;
107 * linux/include/linux/dcache.h
110 struct dentry_operations *d_op;
111 struct super_block * d_sb; /* The root of the dentry tree */
112 unsigned long d_vfs_flags;
113 + struct lookup_intent *d_it;
114 void * d_fsdata; /* fs-specific data */
115 unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
118 struct dentry_operations {
119 int (*d_revalidate)(struct dentry *, int);
120 + int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
121 int (*d_hash) (struct dentry *, struct qstr *);
122 int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);
123 int (*d_delete)(struct dentry *);
124 void (*d_release)(struct dentry *);
125 void (*d_iput)(struct dentry *, struct inode *);
126 + void (*d_intent_rel)(struct dentry *);
129 /* the dentry parameter passed to d_hash and d_compare is the parent
130 --- linux/fs/namei.c.lustre-orig Wed May 22 08:29:48 2002
131 +++ linux/fs/namei.c Mon Jun 3 16:14:56 2002
133 * XEmacs seems to be relying on it...
136 +void intent_release(struct dentry *de)
138 + if (de->d_op && de->d_op->d_intent_rel)
139 + de->d_op->d_intent_rel(de);
144 /* In order to reduce some races, while at the same time doing additional
145 * checking and hopefully speeding things up, we copy filenames to the
146 * kernel data space before using them..
147 @@ -260,10 +268,18 @@
148 * Internal lookup() using the new generic dcache.
151 -static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
152 +static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags, struct lookup_intent *it)
154 struct dentry * dentry = d_lookup(parent, name);
156 + if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
157 + if (!dentry->d_op->d_revalidate2(dentry, flags, it) && !d_invalidate(dentry)) {
164 if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
165 if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
168 * make sure that nobody added the entry to the dcache in the meantime..
171 -static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
172 +static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags, struct lookup_intent *it)
174 struct dentry * result;
175 struct inode *dir = parent->d_inode;
177 result = ERR_PTR(-ENOMEM);
180 + if (dir->i_op->lookup2)
181 + result = dir->i_op->lookup2(dir, dentry, it);
183 result = dir->i_op->lookup(dir, dentry);
187 result = ERR_PTR(-ENOENT);
190 + if (result->d_op && result->d_op->d_revalidate2) {
191 + if (!result->d_op->d_revalidate2(result, flags, it) && !d_invalidate(result)) {
193 + result = ERR_PTR(-ENOENT);
201 * We expect 'base' to be positive and a directory.
203 -int link_path_walk(const char * name, struct nameidata *nd)
204 +int link_path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
206 struct dentry *dentry;
211 /* This does the actual lookups.. */
212 - dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
213 + dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
215 - dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
216 + dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
217 err = PTR_ERR(dentry);
224 - if (!inode->i_op->lookup)
225 + if (!inode->i_op->lookup && !inode->i_op->lookup2)
228 /* here ends the main loop */
233 - dentry = cached_lookup(nd->dentry, &this, 0);
234 + dentry = cached_lookup(nd->dentry, &this, 0, it);
236 - dentry = real_lookup(nd->dentry, &this, 0);
237 + dentry = real_lookup(nd->dentry, &this, 0, it);
238 err = PTR_ERR(dentry);
243 if (lookup_flags & LOOKUP_DIRECTORY) {
245 - if (!inode->i_op || !inode->i_op->lookup)
246 + if (!inode->i_op || (!inode->i_op->lookup &&
247 + !inode->i_op->lookup2))
251 @@ -636,12 +662,24 @@
255 +int link_path_walk(const char * name, struct nameidata *nd)
257 + return link_path_walk_it(name, nd, NULL);
260 +int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
262 + current->total_link_count = 0;
263 + return link_path_walk_it(name, nd, it);
266 int path_walk(const char * name, struct nameidata *nd)
268 current->total_link_count = 0;
269 - return link_path_walk(name, nd);
270 + return link_path_walk_it(name, nd, NULL);
275 /* returns 1 if everything is done */
276 static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
278 * needs parent already locked. Doesn't follow mounts.
281 -struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
282 +struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base,
283 + struct lookup_intent *it)
285 struct dentry * dentry;
287 @@ -765,13 +804,16 @@
291 - dentry = cached_lookup(base, name, 0);
292 + dentry = cached_lookup(base, name, 0, it);
294 struct dentry *new = d_alloc(base, name);
295 dentry = ERR_PTR(-ENOMEM);
299 + if (inode->i_op->lookup2)
300 + dentry = inode->i_op->lookup2(inode, new, it);
302 dentry = inode->i_op->lookup(inode, new);
309 +struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
311 + return lookup_hash_it(name, base, NULL);
316 struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
320 this.hash = end_name_hash(hash);
322 - return lookup_hash(&this, base);
323 + return lookup_hash_it(&this, base, NULL);
325 return ERR_PTR(-EACCES);
331 +int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd, struct lookup_intent *it)
336 + tmp = getname(name);
337 + err = PTR_ERR(tmp);
338 + if (!IS_ERR(tmp)) {
340 + if (path_init(tmp, flags, nd))
341 + err = path_walk_it(tmp, nd, it);
348 * It's inline, so penalty for filesystems that don't use sticky bit is
351 * for symlinks (where the permissions are checked later).
354 -int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
355 +int open_namei_it(const char * pathname, int flag, int mode, struct nameidata *nd,
356 + struct lookup_intent *it)
358 int acc_mode, error = 0;
361 * The simplest case - just a plain lookup.
363 if (!(flag & O_CREAT)) {
365 if (path_init(pathname, lookup_flags(flag), nd))
366 - error = path_walk(pathname, nd);
367 + error = path_walk_it(pathname, nd, it);
373 * Create - we need to know the parent.
376 + it->it_op |= IT_CREAT;
377 if (path_init(pathname, LOOKUP_PARENT, nd))
378 error = path_walk(pathname, nd);
380 @@ -1011,7 +1079,7 @@
383 down(&dir->d_inode->i_sem);
384 - dentry = lookup_hash(&nd->last, nd->dentry);
385 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
388 error = PTR_ERR(dentry);
389 @@ -1022,6 +1090,7 @@
391 /* Negative dentry, just create the file */
392 if (!dentry->d_inode) {
394 error = vfs_create(dir->d_inode, dentry,
395 mode & ~current->fs->umask);
396 up(&dir->d_inode->i_sem);
397 @@ -1181,13 +1250,20 @@
400 down(&dir->d_inode->i_sem);
401 - dentry = lookup_hash(&nd->last, nd->dentry);
402 + dentry = lookup_hash_it(&nd->last, nd->dentry, NULL);
403 putname(nd->last.name);
407 +int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
409 + return open_namei_it(pathname, flag, mode, nd, NULL);
414 -static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
415 +static struct dentry *lookup_create(struct nameidata *nd, int is_dir,
416 + struct lookup_intent *it)
418 struct dentry *dentry;
420 @@ -1195,7 +1271,7 @@
421 dentry = ERR_PTR(-EEXIST);
422 if (nd->last_type != LAST_NORM)
424 - dentry = lookup_hash(&nd->last, nd->dentry);
425 + dentry = lookup_hash_it(&nd->last, nd->dentry, it);
428 if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
429 @@ -1241,6 +1317,7 @@
431 struct dentry * dentry;
433 + struct lookup_intent it = { IT_CREAT , mode };
437 @@ -1252,11 +1329,12 @@
438 error = path_walk(tmp, &nd);
441 - dentry = lookup_create(&nd, 0);
442 + dentry = lookup_create(&nd, 0, &it);
443 error = PTR_ERR(dentry);
445 mode &= ~current->fs->umask;
446 if (!IS_ERR(dentry)) {
447 + dentry->d_it = ⁢
448 switch (mode & S_IFMT) {
449 case 0: case S_IFREG:
450 error = vfs_create(nd.dentry->d_inode,dentry,mode);
451 @@ -1272,6 +1350,7 @@
455 + intent_release(dentry);
456 up(&nd.dentry->d_inode->i_sem);
459 @@ -1310,6 +1389,7 @@
463 + struct lookup_intent it = { IT_MKDIR, mode };
465 tmp = getname(pathname);
466 error = PTR_ERR(tmp);
467 @@ -1321,13 +1401,15 @@
468 error = path_walk(tmp, &nd);
471 - dentry = lookup_create(&nd, 1);
472 + dentry = lookup_create(&nd, 1, &it);
473 error = PTR_ERR(dentry);
474 if (!IS_ERR(dentry)) {
475 + dentry->d_it = ⁢
476 error = vfs_mkdir(nd.dentry->d_inode, dentry,
477 mode & ~current->fs->umask);
480 + intent_release(dentry);
481 up(&nd.dentry->d_inode->i_sem);
484 @@ -1407,6 +1489,7 @@
486 struct dentry *dentry;
488 + struct lookup_intent it = { IT_RMDIR, 0 };
490 name = getname(pathname);
492 @@ -1429,10 +1512,12 @@
495 down(&nd.dentry->d_inode->i_sem);
496 - dentry = lookup_hash(&nd.last, nd.dentry);
497 + dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
498 error = PTR_ERR(dentry);
499 if (!IS_ERR(dentry)) {
500 + dentry->d_it = ⁢
501 error = vfs_rmdir(nd.dentry->d_inode, dentry);
502 + intent_release(dentry);
505 up(&nd.dentry->d_inode->i_sem);
506 @@ -1476,6 +1561,7 @@
508 struct dentry *dentry;
510 + struct lookup_intent it = { IT_UNLINK, 0 };
512 name = getname(pathname);
514 @@ -1489,14 +1575,16 @@
515 if (nd.last_type != LAST_NORM)
517 down(&nd.dentry->d_inode->i_sem);
518 - dentry = lookup_hash(&nd.last, nd.dentry);
519 + dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
520 error = PTR_ERR(dentry);
521 if (!IS_ERR(dentry)) {
522 + dentry->d_it = ⁢
523 /* Why not before? Because we want correct error value */
524 if (nd.last.name[nd.last.len])
526 error = vfs_unlink(nd.dentry->d_inode, dentry);
528 + intent_release(dentry);
531 up(&nd.dentry->d_inode->i_sem);
532 @@ -1543,6 +1631,7 @@
536 + struct lookup_intent it = { IT_SYMLINK, 0 };
538 from = getname(oldname);
540 @@ -1557,12 +1646,14 @@
541 error = path_walk(to, &nd);
544 - dentry = lookup_create(&nd, 0);
545 + dentry = lookup_create(&nd, 0, &it);
546 error = PTR_ERR(dentry);
547 if (!IS_ERR(dentry)) {
548 + dentry->d_it = ⁢
549 error = vfs_symlink(nd.dentry->d_inode, dentry, from);
552 + intent_release(dentry);
553 up(&nd.dentry->d_inode->i_sem);
556 @@ -1626,6 +1717,7 @@
560 + struct lookup_intent it = { IT_LINK, 0 };
562 from = getname(oldname);
564 @@ -1648,12 +1740,14 @@
566 if (old_nd.mnt != nd.mnt)
568 - new_dentry = lookup_create(&nd, 0);
569 + new_dentry = lookup_create(&nd, 0, &it);
570 error = PTR_ERR(new_dentry);
571 if (!IS_ERR(new_dentry)) {
572 + new_dentry->d_it = ⁢
573 error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
576 + intent_release(new_dentry);
577 up(&nd.dentry->d_inode->i_sem);
580 @@ -1694,7 +1788,8 @@
583 int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
584 - struct inode *new_dir, struct dentry *new_dentry)
585 + struct inode *new_dir, struct dentry *new_dentry,
586 + struct lookup_intent *it)
589 struct inode *target;
590 @@ -1748,12 +1843,14 @@
592 double_down(&old_dir->i_zombie,
594 + new_dentry->d_it = it;
595 if (IS_DEADDIR(old_dir)||IS_DEADDIR(new_dir))
597 else if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
600 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
601 + intent_release(new_dentry);
604 target->i_flags |= S_DEAD;
605 @@ -1775,7 +1872,8 @@
608 int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
609 - struct inode *new_dir, struct dentry *new_dentry)
610 + struct inode *new_dir, struct dentry *new_dentry,
611 + struct lookup_intent *it)
615 @@ -1802,10 +1900,12 @@
618 double_down(&old_dir->i_zombie, &new_dir->i_zombie);
619 + new_dentry->d_it = it;
620 if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
623 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
624 + intent_release(new_dentry);
625 double_up(&old_dir->i_zombie, &new_dir->i_zombie);
628 @@ -1817,13 +1917,14 @@
631 int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
632 - struct inode *new_dir, struct dentry *new_dentry)
633 + struct inode *new_dir, struct dentry *new_dentry,
634 + struct lookup_intent *it)
637 if (S_ISDIR(old_dentry->d_inode->i_mode))
638 - error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
639 + error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry, it);
641 - error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
642 + error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry, it);
644 if (old_dir == new_dir)
645 inode_dir_notify(old_dir, DN_RENAME);
646 @@ -1841,6 +1942,7 @@
647 struct dentry * old_dir, * new_dir;
648 struct dentry * old_dentry, *new_dentry;
649 struct nameidata oldnd, newnd;
650 + struct lookup_intent it = {IT_RENAME, 0};
652 if (path_init(oldname, LOOKUP_PARENT, &oldnd))
653 error = path_walk(oldname, &oldnd);
654 @@ -1868,7 +1970,9 @@
656 double_lock(new_dir, old_dir);
658 - old_dentry = lookup_hash(&oldnd.last, old_dir);
659 + it.it_op = IT_RENAME;
661 + old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it);
662 error = PTR_ERR(old_dentry);
663 if (IS_ERR(old_dentry))
665 @@ -1884,14 +1988,14 @@
666 if (newnd.last.name[newnd.last.len])
669 - new_dentry = lookup_hash(&newnd.last, new_dir);
670 + new_dentry = lookup_hash_it(&newnd.last, new_dir, &it);
671 error = PTR_ERR(new_dentry);
672 if (IS_ERR(new_dentry))
676 error = vfs_rename(old_dir->d_inode, old_dentry,
677 - new_dir->d_inode, new_dentry);
678 + new_dir->d_inode, new_dentry, &it);
682 --- linux/fs/open.c.lustre-orig Wed May 22 08:29:48 2002
683 +++ linux/fs/open.c Wed May 22 08:29:48 2002
684 @@ -630,10 +630,15 @@
685 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
688 +extern int open_namei_it(const char *filename, int namei_flags, int mode,
689 + struct nameidata *nd, struct lookup_intent *it);
690 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, int flags, struct lookup_intent *it);
692 struct file *filp_open(const char * filename, int flags, int mode)
694 int namei_flags, error;
696 + struct lookup_intent it = {IT_OPEN, 0};
699 if ((namei_flags+1) & O_ACCMODE)
700 @@ -641,14 +646,14 @@
701 if (namei_flags & O_TRUNC)
704 - error = open_namei(filename, namei_flags, mode, &nd);
705 + error = open_namei_it(filename, namei_flags, mode, &nd, &it);
707 - return dentry_open(nd.dentry, nd.mnt, flags);
708 + return dentry_open_it(nd.dentry, nd.mnt, flags, &it);
710 return ERR_PTR(error);
713 -struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
714 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, int flags, struct lookup_intent *it)
721 f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
727 return ERR_PTR(error);
730 +struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
732 + return dentry_open_it(dentry, mnt, flags, NULL);
738 * Find an empty file descriptor entry, and mark it busy.