diff --git a/lustre/kernel_patches/patches/ext3-wantedi-2.6.3.patch b/lustre/kernel_patches/patches/ext3-wantedi-2.6.3.patch new file mode 100644 index 0000000000000000000000000000000000000000..3f20da7d8676dbd97321cdedbf8a4b08b17ad7eb --- /dev/null +++ b/lustre/kernel_patches/patches/ext3-wantedi-2.6.3.patch @@ -0,0 +1,200 @@ + fs/ext3/ialloc.c | 35 ++++++++++++++++++++++++++++++++++- + fs/ext3/ioctl.c | 25 +++++++++++++++++++++++++ + fs/ext3/namei.c | 21 +++++++++++++++++---- + include/linux/dcache.h | 5 +++++ + include/linux/ext3_fs.h | 5 ++++- + 5 files changed, 85 insertions(+), 6 deletions(-) + +Index: uml-2.6.3/fs/ext3/ialloc.c +=================================================================== +--- uml-2.6.3.orig/fs/ext3/ialloc.c 2004-02-20 15:00:48.000000000 +0800 ++++ uml-2.6.3/fs/ext3/ialloc.c 2004-02-21 00:24:45.202693776 +0800 +@@ -420,7 +420,8 @@ + * For other inodes, search forward from the parent directory's block + * group to find a free inode. + */ +-struct inode *ext3_new_inode(handle_t *handle, struct inode * dir, int mode) ++struct inode *ext3_new_inode(handle_t *handle, struct inode * dir, int mode, ++ unsigned long goal) + { + struct super_block *sb; + struct buffer_head *bitmap_bh = NULL; +@@ -448,6 +449,38 @@ + + sbi = EXT3_SB(sb); + es = sbi->s_es; ++ if (goal) { ++ group = (goal - 1) / EXT3_INODES_PER_GROUP(sb); ++ ino = (goal - 1) % EXT3_INODES_PER_GROUP(sb); ++ gdp = ext3_get_group_desc(sb, group, &bh2); ++ ++ err = -EIO; ++ bitmap_bh = read_inode_bitmap (sb, group); ++ if (!bitmap_bh) ++ goto fail; ++ ++ BUFFER_TRACE(bh, "get_write_access"); ++ err = ext3_journal_get_write_access(handle, bitmap_bh); ++ if (err) goto fail; ++ ++ if (ext3_set_bit_atomic(sb_bgl_lock(sbi, group), ++ ino, bitmap_bh->b_data)) { ++ printk(KERN_ERR "goal inode %lu unavailable\n", goal); ++ /* Oh well, we tried. */ ++ goto continue_allocation; ++ } ++ ++ BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); ++ err = ext3_journal_dirty_metadata(handle, bitmap_bh); ++ if (err) goto fail; ++ ++ /* We've shortcircuited the allocation system successfully, ++ * now finish filling in the inode. ++ */ ++ goto got; ++ } ++ ++continue_allocation: + if (S_ISDIR(mode)) { + if (test_opt (sb, OLDALLOC)) + group = find_group_dir(sb, dir); +Index: uml-2.6.3/fs/ext3/ioctl.c +=================================================================== +--- uml-2.6.3.orig/fs/ext3/ioctl.c 2004-01-09 14:59:26.000000000 +0800 ++++ uml-2.6.3/fs/ext3/ioctl.c 2004-02-21 00:21:04.541239416 +0800 +@@ -24,6 +24,31 @@ + ext3_debug ("cmd = %u, arg = %lu\n", cmd, arg); + + switch (cmd) { ++ case EXT3_IOC_CREATE_INUM: { ++ char name[32]; ++ struct dentry *dchild, *dparent; ++ int rc = 0; ++ ++ dparent = list_entry(inode->i_dentry.next, struct dentry, ++ d_alias); ++ snprintf(name, sizeof name, "%lu", arg); ++ dchild = lookup_one_len(name, dparent, strlen(name)); ++ if (dchild->d_inode) { ++ printk(KERN_ERR "%*s/%lu already exists (ino %lu)\n", ++ dparent->d_name.len, dparent->d_name.name, arg, ++ dchild->d_inode->i_ino); ++ rc = -EEXIST; ++ } else { ++ dchild->d_fsdata = (void *)arg; ++ rc = vfs_create(inode, dchild, 0644, NULL); ++ if (rc) ++ printk(KERN_ERR "vfs_create: %d\n", rc); ++ else if (dchild->d_inode->i_ino != arg) ++ rc = -EEXIST; ++ } ++ dput(dchild); ++ return rc; ++ } + case EXT3_IOC_GETFLAGS: + flags = ei->i_flags & EXT3_FL_USER_VISIBLE; + return put_user(flags, (int *) arg); +Index: uml-2.6.3/fs/ext3/namei.c +=================================================================== +--- uml-2.6.3.orig/fs/ext3/namei.c 2004-02-20 15:01:27.000000000 +0800 ++++ uml-2.6.3/fs/ext3/namei.c 2004-02-21 00:21:04.611228776 +0800 +@@ -1617,6 +1617,19 @@ + return err; + } + ++static struct inode * ext3_new_inode_wantedi(handle_t *handle, struct inode *dir, ++ int mode, struct dentry *dentry) ++{ ++ unsigned long inum = 0; ++ ++ if (dentry->d_fsdata != NULL) { ++ struct dentry_params *param = ++ (struct dentry_params *) dentry->d_fsdata; ++ inum = param->p_inum; ++ } ++ return ext3_new_inode(handle, dir, mode, inum); ++} ++ + /* + * By the time this is called, we already have created + * the directory cache entry for the new file, but it +@@ -1640,7 +1653,7 @@ + if (IS_DIRSYNC(dir)) + handle->h_sync = 1; + +- inode = ext3_new_inode (handle, dir, mode); ++ inode = ext3_new_inode_wantedi (handle, dir, mode, dentry); + err = PTR_ERR(inode); + if (!IS_ERR(inode)) { + inode->i_op = &ext3_file_inode_operations; +@@ -1670,7 +1683,7 @@ + if (IS_DIRSYNC(dir)) + handle->h_sync = 1; + +- inode = ext3_new_inode (handle, dir, mode); ++ inode = ext3_new_inode_wantedi (handle, dir, mode, dentry); + err = PTR_ERR(inode); + if (!IS_ERR(inode)) { + init_special_inode(inode, inode->i_mode, rdev); +@@ -1702,7 +1715,7 @@ + if (IS_DIRSYNC(dir)) + handle->h_sync = 1; + +- inode = ext3_new_inode (handle, dir, S_IFDIR | mode); ++ inode = ext3_new_inode_wantedi (handle, dir, S_IFDIR | mode, dentry); + err = PTR_ERR(inode); + if (IS_ERR(inode)) + goto out_stop; +@@ -2094,7 +2107,7 @@ + if (IS_DIRSYNC(dir)) + handle->h_sync = 1; + +- inode = ext3_new_inode (handle, dir, S_IFLNK|S_IRWXUGO); ++ inode = ext3_new_inode_wantedi (handle, dir, S_IFLNK|S_IRWXUGO, dentry); + err = PTR_ERR(inode); + if (IS_ERR(inode)) + goto out_stop; +Index: uml-2.6.3/include/linux/dcache.h +=================================================================== +--- uml-2.6.3.orig/include/linux/dcache.h 2004-02-21 00:19:14.365988600 +0800 ++++ uml-2.6.3/include/linux/dcache.h 2004-02-21 00:21:04.612228624 +0800 +@@ -25,6 +25,11 @@ + + #define IS_ROOT(x) ((x) == (x)->d_parent) + ++struct dentry_params { ++ unsigned long p_inum; ++ void *p_ptr; ++}; ++ + /* + * "quick string" -- eases parameter passing, but more importantly + * saves "metadata" about the string (ie length and the hash). +Index: uml-2.6.3/include/linux/ext3_fs.h +=================================================================== +--- uml-2.6.3.orig/include/linux/ext3_fs.h 2004-01-09 14:59:44.000000000 +0800 ++++ uml-2.6.3/include/linux/ext3_fs.h 2004-02-21 00:21:04.613228472 +0800 +@@ -203,6 +203,7 @@ + #define EXT3_IOC_SETFLAGS _IOW('f', 2, long) + #define EXT3_IOC_GETVERSION _IOR('f', 3, long) + #define EXT3_IOC_SETVERSION _IOW('f', 4, long) ++/* EXT3_IOC_CREATE_INUM at bottom of file (visible to kernel and user). */ + #define EXT3_IOC_GETVERSION_OLD _IOR('v', 1, long) + #define EXT3_IOC_SETVERSION_OLD _IOW('v', 2, long) + #ifdef CONFIG_JBD_DEBUG +@@ -707,7 +708,8 @@ + dx_hash_info *hinfo); + + /* ialloc.c */ +-extern struct inode * ext3_new_inode (handle_t *, struct inode *, int); ++extern struct inode * ext3_new_inode (handle_t *, struct inode *, int, ++ unsigned long); + extern void ext3_free_inode (handle_t *, struct inode *); + extern struct inode * ext3_orphan_get (struct super_block *, unsigned long); + extern unsigned long ext3_count_free_inodes (struct super_block *); +@@ -792,4 +794,5 @@ + + #endif /* __KERNEL__ */ + ++#define EXT3_IOC_CREATE_INUM _IOW('f', 5, long) + #endif /* _LINUX_EXT3_FS_H */ diff --git a/lustre/kernel_patches/patches/kernel_text_address-2.6.3.patch b/lustre/kernel_patches/patches/kernel_text_address-2.6.3.patch new file mode 100644 index 0000000000000000000000000000000000000000..c60c5251ff47723c0884e3f9a36189a649aa04b8 --- /dev/null +++ b/lustre/kernel_patches/patches/kernel_text_address-2.6.3.patch @@ -0,0 +1,26 @@ +Index: linux-2.6.3/arch/i386/kernel/traps.c +=================================================================== +--- linux-2.6.3.orig/arch/i386/kernel/traps.c 2004-02-23 14:04:13.000000000 -0800 ++++ linux-2.6.3/arch/i386/kernel/traps.c 2004-02-23 14:10:07.000000000 -0800 +@@ -890,3 +890,21 @@ + + trap_init_hook(); + } ++ ++int is_kernel_text_address(unsigned long addr) ++{ ++ if (addr < (unsigned long) &_stext || ++ addr > (unsigned long) &_etext || ++ module_text_address(addr)) ++ return 0; ++ ++ return 1; ++} ++ ++int lookup_symbol(unsigned long address, char *buf, int buflen) ++{ ++ return -ENOSYS; ++} ++ ++EXPORT_SYMBOL_GPL(is_kernel_text_address); ++EXPORT_SYMBOL_GPL(lookup_symbol); diff --git a/lustre/kernel_patches/patches/vfs_intent-2.6.3.patch b/lustre/kernel_patches/patches/vfs_intent-2.6.3.patch new file mode 100644 index 0000000000000000000000000000000000000000..a801f967929cacb3198ac44d21fb2fe0b8a76e37 --- /dev/null +++ b/lustre/kernel_patches/patches/vfs_intent-2.6.3.patch @@ -0,0 +1,758 @@ + fs/exec.c | 18 +++++++--- + fs/namei.c | 86 +++++++++++++++++++++++++++++++++++++++++++++---- + fs/namespace.c | 2 + + fs/nfs/dir.c | 4 +- + fs/open.c | 62 +++++++++++++++++++++++------------ + fs/stat.c | 24 ++++++++++--- + include/linux/dcache.h | 3 + + include/linux/fs.h | 8 ++++ + include/linux/namei.h | 56 ++++++++++++++++++++++++++----- + kernel/ksyms.c | 8 ++++ + 10 files changed, 222 insertions(+), 49 deletions(-) + +Index: uml-2.6.3/fs/exec.c +=================================================================== +--- uml-2.6.3.orig/fs/exec.c 2004-02-20 15:00:48.000000000 +0800 ++++ uml-2.6.3/fs/exec.c 2004-02-21 00:15:14.154506296 +0800 +@@ -120,8 +120,11 @@ + struct file * file; + struct nameidata nd; + int error; ++ intent_init(&nd.intent, IT_OPEN); + +- nd.intent.open.flags = FMODE_READ; ++ error = user_path_walk_it(library, &nd); ++ ++ nd.intent.it_flags = O_RDONLY; + error = __user_walk(library, LOOKUP_FOLLOW|LOOKUP_OPEN, &nd); + if (error) + goto out; +@@ -134,7 +137,7 @@ + if (error) + goto exit; + +- file = dentry_open(nd.dentry, nd.mnt, O_RDONLY); ++ file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &nd.intent); + error = PTR_ERR(file); + if (IS_ERR(file)) + goto out; +@@ -474,8 +477,9 @@ + int err; + struct file *file; + +- nd.intent.open.flags = FMODE_READ; +- err = path_lookup(name, LOOKUP_FOLLOW|LOOKUP_OPEN, &nd); ++ intent_init(&nd.intent, IT_OPEN); ++ nd.intent.it_flags = O_RDONLY; ++ err = path_lookup(name, LOOKUP_FOLLOW, &nd); + file = ERR_PTR(err); + + if (!err) { +@@ -488,7 +492,7 @@ + err = -EACCES; + file = ERR_PTR(err); + if (!err) { +- file = dentry_open(nd.dentry, nd.mnt, O_RDONLY); ++ file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &nd.intent); + if (!IS_ERR(file)) { + err = deny_write_access(file); + if (err) { +Index: uml-2.6.3/fs/namei.c +=================================================================== +--- uml-2.6.3.orig/fs/namei.c 2004-02-20 15:01:27.000000000 +0800 ++++ uml-2.6.3/fs/namei.c 2004-02-20 23:59:00.678497144 +0800 +@@ -268,8 +268,19 @@ + return 0; + } + ++void intent_release(struct lookup_intent *it) ++{ ++ if (!it) ++ return; ++ if (it->it_magic != INTENT_MAGIC) ++ return; ++ if (it->it_op_release) ++ it->it_op_release(it); ++} ++ + void path_release(struct nameidata *nd) + { ++ intent_release(&nd->intent); + dput(nd->dentry); + mntput(nd->mnt); + } +@@ -346,7 +357,10 @@ + { + struct dentry * result; + struct inode *dir = parent->d_inode; ++ int counter = 0; + ++again: ++ counter++; + down(&dir->i_sem); + /* + * First re-do the cached lookup just in case it was created +@@ -385,7 +399,10 @@ + if (result->d_op && result->d_op->d_revalidate) { + if (!result->d_op->d_revalidate(result, nd) && !d_invalidate(result)) { + dput(result); +- result = ERR_PTR(-ENOENT); ++ if (counter > 10) ++ result = ERR_PTR(-ESTALE); ++ if (!IS_ERR(result)) ++ goto again; + } + } + return result; +@@ -562,6 +579,31 @@ + return PTR_ERR(dentry); + } + ++static int revalidate_special(struct nameidata *nd) ++{ ++ struct dentry *dentry = nd->dentry; ++ int err, counter = 0; ++ ++ if (!dentry->d_op || !dentry->d_op->d_revalidate) ++ return 0; ++ revalidate_again: ++ if (!dentry->d_op->d_revalidate(dentry, nd)) { ++ struct dentry *new; ++ if ((err = permission(dentry->d_parent->d_inode, MAY_EXEC,nd))) ++ return err; ++ new = real_lookup(dentry->d_parent, &dentry->d_name, nd); ++ d_invalidate(dentry); ++ dput(dentry); ++ nd->dentry = dentry = new; ++ counter++; ++ if (counter < 10) ++ goto revalidate_again; ++ printk("excessive revalidate_it loops\n"); ++ return -ESTALE; ++ } ++ return 0; ++} ++ + /* + * Name resolution. + * +@@ -662,7 +704,9 @@ + + if (inode->i_op->follow_link) { + mntget(next.mnt); ++ nd->flags |= LOOKUP_LINK_NOTLAST; + err = do_follow_link(next.dentry, nd); ++ nd->flags &= ~LOOKUP_LINK_NOTLAST; + dput(next.dentry); + mntput(next.mnt); + if (err) +@@ -701,6 +745,11 @@ + inode = nd->dentry->d_inode; + /* fallthrough */ + case 1: ++ nd->flags |= LOOKUP_LAST; ++ err = revalidate_special(nd); ++ nd->flags &= ~LOOKUP_LAST; ++ if (err) ++ break; + goto return_reval; + } + if (nd->dentry->d_op && nd->dentry->d_op->d_hash) { +@@ -708,7 +757,9 @@ + if (err < 0) + break; + } ++ nd->flags |= LOOKUP_LAST; + err = do_lookup(nd, &this, &next); ++ nd->flags &= ~LOOKUP_LAST; + if (err) + break; + follow_mount(&next.mnt, &next.dentry); +@@ -934,7 +985,7 @@ + } + + /* SMP-safe */ +-struct dentry * lookup_one_len(const char * name, struct dentry * base, int len) ++struct dentry * lookup_one_len_it(const char * name, struct dentry * base, int len, struct nameidata *nd) + { + unsigned long hash; + struct qstr this; +@@ -954,11 +1005,16 @@ + } + this.hash = end_name_hash(hash); + +- return lookup_hash(&this, base); ++ return __lookup_hash(&this, base, nd); + access: + return ERR_PTR(-EACCES); + } + ++struct dentry * lookup_one_len(const char * name, struct dentry * base, int len) ++{ ++ return lookup_one_len_it(name, base, len, NULL); ++} ++ + /* + * namei() + * +@@ -970,11 +1026,12 @@ + * that namei follows links, while lnamei does not. + * SMP-safe + */ +-int __user_walk(const char __user *name, unsigned flags, struct nameidata *nd) ++int __user_walk_it(const char __user *name, unsigned flags, struct nameidata *nd) + { + char *tmp = getname(name); + int err = PTR_ERR(tmp); + ++ + if (!IS_ERR(tmp)) { + err = path_lookup(tmp, flags, nd); + putname(tmp); +@@ -982,6 +1039,12 @@ + return err; + } + ++int __user_walk(const char __user *name, unsigned flags, struct nameidata *nd) ++{ ++ intent_init(&nd->intent, IT_LOOKUP); ++ return __user_walk_it(name, flags, nd); ++} ++ + /* + * It's inline, so penalty for filesystems that don't use sticky bit is + * minimal. +@@ -1254,8 +1317,8 @@ + acc_mode |= MAY_APPEND; + + /* Fill in the open() intent data */ +- nd->intent.open.flags = flag; +- nd->intent.open.create_mode = mode; ++ nd->intent.it_flags = flag; ++ nd->intent.it_create_mode = mode; + + /* + * The simplest case - just a plain lookup. +@@ -1270,6 +1333,7 @@ + /* + * Create - we need to know the parent. + */ ++ nd->intent.it_op |= IT_CREAT; + error = path_lookup(pathname, LOOKUP_PARENT|LOOKUP_OPEN|LOOKUP_CREATE, nd); + if (error) + return error; +@@ -1286,7 +1350,9 @@ + dir = nd->dentry; + nd->flags &= ~LOOKUP_PARENT; + down(&dir->d_inode->i_sem); ++ nd->flags |= LOOKUP_LAST; + dentry = __lookup_hash(&nd->last, nd->dentry, nd); ++ nd->flags &= ~LOOKUP_LAST; + + do_last: + error = PTR_ERR(dentry); +@@ -1391,7 +1457,9 @@ + } + dir = nd->dentry; + down(&dir->d_inode->i_sem); ++ nd->flags |= LOOKUP_LAST; + dentry = __lookup_hash(&nd->last, nd->dentry, nd); ++ nd->flags &= ~LOOKUP_LAST; + putname(nd->last.name); + goto do_last; + } +@@ -2153,7 +2221,9 @@ + __vfs_follow_link(struct nameidata *nd, const char *link) + { + int res = 0; ++ struct lookup_intent it = nd->intent; + char *name; ++ + if (IS_ERR(link)) + goto fail; + +@@ -2163,6 +2233,10 @@ + /* weird __emul_prefix() stuff did it */ + goto out; + } ++ ++ intent_init(&nd->intent, it.it_op); ++ nd->intent.it_flags = it.it_flags; ++ nd->intent.it_create_mode = it.it_create_mode; + res = link_path_walk(link, nd); + out: + if (current->link_count || res || nd->last_type!=LAST_NORM) +Index: uml-2.6.3/fs/namespace.c +=================================================================== +--- uml-2.6.3.orig/fs/namespace.c 2004-02-20 15:01:27.000000000 +0800 ++++ uml-2.6.3/fs/namespace.c 2004-02-20 23:59:00.745486960 +0800 +@@ -744,6 +744,7 @@ + int retval = 0; + int mnt_flags = 0; + ++ intent_init(&nd.intent, IT_LOOKUP); + /* Discard magic */ + if ((flags & MS_MGC_MSK) == MS_MGC_VAL) + flags &= ~MS_MGC_MSK; +Index: uml-2.6.3/fs/open.c +=================================================================== +--- uml-2.6.3.orig/fs/open.c 2004-02-20 15:00:48.000000000 +0800 ++++ uml-2.6.3/fs/open.c 2004-02-20 23:59:00.812476776 +0800 +@@ -202,7 +202,7 @@ + struct nameidata nd; + struct inode * inode; + int error; +- ++ intent_init(&nd.intent, IT_GETATTR); + error = -EINVAL; + if (length < 0) /* sorry, but loff_t says... */ + goto out; +@@ -461,6 +461,7 @@ + int old_fsuid, old_fsgid; + kernel_cap_t old_cap; + int res; ++ intent_init(&nd.intent, IT_GETATTR); + + if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ + return -EINVAL; +@@ -492,6 +493,7 @@ + if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode) + && !special_file(nd.dentry->d_inode->i_mode)) + res = -EROFS; ++ + path_release(&nd); + } + +@@ -506,6 +508,7 @@ + { + struct nameidata nd; + int error; ++ intent_init(&nd.intent, IT_GETATTR); + + error = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &nd); + if (error) +@@ -557,6 +560,7 @@ + { + struct nameidata nd; + int error; ++ intent_init(&nd.intent, IT_GETATTR); + + error = __user_walk(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd); + if (error) +@@ -629,7 +633,7 @@ + error = -EROFS; + if (IS_RDONLY(inode)) + goto dput_and_out; +- ++ + error = -EPERM; + if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) + goto dput_and_out; +@@ -737,27 +741,8 @@ + * for the internal routines (ie open_namei()/follow_link() etc). 00 is + * used by symlinks. + */ +-struct file *filp_open(const char * filename, int flags, int mode) +-{ +- int namei_flags, error; +- struct nameidata nd; +- +- namei_flags = flags; +- if ((namei_flags+1) & O_ACCMODE) +- namei_flags++; +- if (namei_flags & O_TRUNC) +- namei_flags |= 2; +- +- error = open_namei(filename, namei_flags, mode, &nd); +- if (!error) +- return dentry_open(nd.dentry, nd.mnt, flags); +- +- return ERR_PTR(error); +-} +- +-EXPORT_SYMBOL(filp_open); +- +-struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) ++struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, int flags, ++ struct lookup_intent *it) + { + struct file * f; + struct inode *inode; +@@ -769,6 +754,7 @@ + goto cleanup_dentry; + f->f_flags = flags; + f->f_mode = (flags+1) & O_ACCMODE; ++ f->f_it = it; + inode = dentry->d_inode; + if (f->f_mode & FMODE_WRITE) { + error = get_write_access(inode); +@@ -788,6 +774,7 @@ + error = f->f_op->open(inode,f); + if (error) + goto cleanup_all; ++ intent_release(it); + } + f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); + +@@ -812,6 +799,7 @@ + cleanup_file: + put_filp(f); + cleanup_dentry: ++ intent_release(it); + dput(dentry); + mntput(mnt); + return ERR_PTR(error); +@@ -819,6 +807,36 @@ + + EXPORT_SYMBOL(dentry_open); + ++struct file *filp_open(const char * filename, int flags, int mode) ++{ ++ int namei_flags, error; ++ struct file * temp_filp; ++ struct nameidata nd; ++ intent_init(&nd.intent, IT_OPEN); ++ ++ namei_flags = flags; ++ if ((namei_flags+1) & O_ACCMODE) ++ namei_flags++; ++ if (namei_flags & O_TRUNC) ++ namei_flags |= 2; ++ ++ error = open_namei(filename, namei_flags, mode, &nd); ++ if (!error) { ++ temp_filp = dentry_open_it(nd.dentry, nd.mnt, flags, &nd.intent); ++ return temp_filp; ++ } ++ return ERR_PTR(error); ++} ++ ++ ++struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) ++{ ++ struct lookup_intent it; ++ intent_init(&it, IT_LOOKUP); ++ ++ return dentry_open_it(dentry, mnt, flags, &it); ++} ++ + /* + * Find an empty file descriptor entry, and mark it busy. + */ +Index: uml-2.6.3/fs/stat.c +=================================================================== +--- uml-2.6.3.orig/fs/stat.c 2004-02-20 15:00:48.000000000 +0800 ++++ uml-2.6.3/fs/stat.c 2004-02-20 23:59:00.878466744 +0800 +@@ -36,7 +36,7 @@ + + EXPORT_SYMBOL(generic_fillattr); + +-int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) ++int vfs_getattr_it(struct vfsmount *mnt, struct dentry *dentry, struct lookup_intent *it, struct kstat *stat) + { + struct inode *inode = dentry->d_inode; + int retval; +@@ -45,6 +45,8 @@ + if (retval) + return retval; + ++ if (inode->i_op->getattr_it) ++ return inode->i_op->getattr_it(mnt, dentry, it, stat); + if (inode->i_op->getattr) + return inode->i_op->getattr(mnt, dentry, stat); + +@@ -61,14 +63,20 @@ + + EXPORT_SYMBOL(vfs_getattr); + ++int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) ++{ ++ return vfs_getattr_it(mnt, dentry, NULL, stat); ++} ++ + int vfs_stat(char __user *name, struct kstat *stat) + { + struct nameidata nd; + int error; ++ intent_init(&nd.intent, IT_GETATTR); + +- error = user_path_walk(name, &nd); ++ error = user_path_walk_it(name, &nd); + if (!error) { +- error = vfs_getattr(nd.mnt, nd.dentry, stat); ++ error = vfs_getattr_it(nd.mnt, nd.dentry, &nd.intent, stat); + path_release(&nd); + } + return error; +@@ -80,10 +88,11 @@ + { + struct nameidata nd; + int error; ++ intent_init(&nd.intent, IT_GETATTR); + +- error = user_path_walk_link(name, &nd); ++ error = user_path_walk_link_it(name, &nd); + if (!error) { +- error = vfs_getattr(nd.mnt, nd.dentry, stat); ++ error = vfs_getattr_it(nd.mnt, nd.dentry, &nd.intent, stat); + path_release(&nd); + } + return error; +@@ -95,9 +104,12 @@ + { + struct file *f = fget(fd); + int error = -EBADF; ++ struct nameidata nd; ++ intent_init(&nd.intent, IT_GETATTR); + + if (f) { +- error = vfs_getattr(f->f_vfsmnt, f->f_dentry, stat); ++ error = vfs_getattr_it(f->f_vfsmnt, f->f_dentry, &nd.intent, stat); ++ intent_release(&nd.intent); + fput(f); + } + return error; +Index: uml-2.6.3/fs/nfs/dir.c +=================================================================== +--- uml-2.6.3.orig/fs/nfs/dir.c 2004-02-20 15:01:27.000000000 +0800 ++++ uml-2.6.3/fs/nfs/dir.c 2004-02-20 23:59:00.880466440 +0800 +@@ -672,7 +672,7 @@ + return 0; + if (!nd || (nd->flags & LOOKUP_CONTINUE) || !(nd->flags & LOOKUP_CREATE)) + return 0; +- return (nd->intent.open.flags & O_EXCL) != 0; ++ return (nd->intent.it_flags & O_EXCL) != 0; + } + + static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) +@@ -960,7 +960,7 @@ + attr.ia_valid = ATTR_MODE; + + if (nd && (nd->flags & LOOKUP_CREATE)) +- open_flags = nd->intent.open.flags; ++ open_flags = nd->intent.it_flags; + + /* + * The 0 argument passed into the create function should one day +Index: uml-2.6.3/fs/inode.c +=================================================================== +--- uml-2.6.3.orig/fs/inode.c 2004-01-09 15:00:12.000000000 +0800 ++++ uml-2.6.3/fs/inode.c 2004-02-20 23:59:00.951455648 +0800 +@@ -223,6 +223,7 @@ + inodes_stat.nr_unused--; + } + ++EXPORT_SYMBOL(__iget); + /** + * clear_inode - clear an inode + * @inode: inode to clear +Index: uml-2.6.3/fs/super.c +=================================================================== +--- uml-2.6.3.orig/fs/super.c 2004-02-20 15:01:27.000000000 +0800 ++++ uml-2.6.3/fs/super.c 2004-02-20 23:59:01.024444552 +0800 +@@ -757,6 +757,8 @@ + return (struct vfsmount *)sb; + } + ++EXPORT_SYMBOL(do_kern_mount); ++ + struct vfsmount *kern_mount(struct file_system_type *type) + { + return do_kern_mount(type->name, 0, type->name, NULL); +Index: uml-2.6.3/include/linux/dcache.h +=================================================================== +--- uml-2.6.3.orig/include/linux/dcache.h 2004-02-20 15:00:57.000000000 +0800 ++++ uml-2.6.3/include/linux/dcache.h 2004-02-20 23:59:01.025444400 +0800 +@@ -4,6 +4,7 @@ + #ifdef __KERNEL__ + + #include <asm/atomic.h> ++#include <linux/string.h> + #include <linux/list.h> + #include <linux/spinlock.h> + #include <linux/cache.h> +@@ -35,6 +36,8 @@ + char name_str[0]; + }; + ++#include <linux/namei.h> ++ + struct dentry_stat_t { + int nr_dentry; + int nr_unused; +Index: uml-2.6.3/include/linux/fs.h +=================================================================== +--- uml-2.6.3.orig/include/linux/fs.h 2004-02-20 15:01:28.000000000 +0800 ++++ uml-2.6.3/include/linux/fs.h 2004-02-20 23:59:01.100433000 +0800 +@@ -243,6 +243,8 @@ + #define ATTR_ATTR_FLAG 1024 + #define ATTR_KILL_SUID 2048 + #define ATTR_KILL_SGID 4096 ++#define ATTR_RAW 8192 /* file system, not vfs will massage attrs */ ++#define ATTR_FROM_OPEN 16384 /* called from open path, ie O_TRUNC */ + + /* + * This is the Inode Attributes structure, used for notify_change(). It +@@ -408,6 +410,7 @@ + struct block_device *i_bdev; + struct cdev *i_cdev; + int i_cindex; ++ void *i_filterdata; + + unsigned long i_dnotify_mask; /* Directory notify events */ + struct dnotify_struct *i_dnotify; /* for directory notifications */ +@@ -538,6 +541,7 @@ + spinlock_t f_ep_lock; + #endif /* #ifdef CONFIG_EPOLL */ + struct address_space *f_mapping; ++ struct lookup_intent *f_it; + }; + extern spinlock_t files_lock; + #define file_list_lock() spin_lock(&files_lock); +@@ -843,7 +847,9 @@ + void (*truncate) (struct inode *); + int (*permission) (struct inode *, int, struct nameidata *); + int (*setattr) (struct dentry *, struct iattr *); ++ int (*setattr_raw) (struct inode *, struct iattr *); + int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *); ++ int (*getattr_it) (struct vfsmount *, struct dentry *, struct lookup_intent *, struct kstat *); + int (*setxattr) (struct dentry *, const char *,const void *,size_t,int); + ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t); + ssize_t (*listxattr) (struct dentry *, char *, size_t); +@@ -1056,6 +1062,7 @@ + extern int unregister_filesystem(struct file_system_type *); + extern struct vfsmount *kern_mount(struct file_system_type *); + extern int may_umount(struct vfsmount *); ++struct vfsmount *do_kern_mount(const char *type, int flags, const char *name, void *data); + extern long do_mount(char *, char *, char *, unsigned long, void *); + + extern int vfs_statfs(struct super_block *, struct kstatfs *); +@@ -1123,6 +1130,7 @@ + + extern struct file *filp_open(const char *, int, int); + extern struct file * dentry_open(struct dentry *, struct vfsmount *, int); ++extern struct file * dentry_open_it(struct dentry *, struct vfsmount *, int, struct lookup_intent *); + extern int filp_close(struct file *, fl_owner_t id); + extern char * getname(const char __user *); + +Index: uml-2.6.3/include/linux/namei.h +=================================================================== +--- uml-2.6.3.orig/include/linux/namei.h 2004-01-09 14:59:19.000000000 +0800 ++++ uml-2.6.3/include/linux/namei.h 2004-02-20 23:59:01.174421752 +0800 +@@ -2,25 +2,55 @@ + #define _LINUX_NAMEI_H + + #include <linux/linkage.h> ++#include <linux/string.h> + + struct vfsmount; ++struct nameidata; + +-struct open_intent { +- int flags; +- int create_mode; ++/* intent opcodes */ ++#define IT_OPEN (1) ++#define IT_CREAT (1<<1) ++#define IT_READDIR (1<<2) ++#define IT_GETATTR (1<<3) ++#define IT_LOOKUP (1<<4) ++#define IT_UNLINK (1<<5) ++#define IT_TRUNC (1<<6) ++#define IT_GETXATTR (1<<7) ++ ++struct lustre_intent_data { ++ int it_disposition; ++ int it_status; ++ __u64 it_lock_handle; ++ void *it_data; ++ int it_lock_mode; + }; + ++#define INTENT_MAGIC 0x19620323 ++struct lookup_intent { ++ int it_magic; ++ void (*it_op_release)(struct lookup_intent *); ++ int it_op; ++ int it_flags; ++ int it_create_mode; ++ union { ++ struct lustre_intent_data lustre; ++ } d; ++}; ++ ++static inline void intent_init(struct lookup_intent *it, int op) ++{ ++ memset(it, 0, sizeof(*it)); ++ it->it_magic = INTENT_MAGIC; ++ it->it_op = op; ++} ++ + struct nameidata { + struct dentry *dentry; + struct vfsmount *mnt; + struct qstr last; + unsigned int flags; + int last_type; +- +- /* Intent data */ +- union { +- struct open_intent open; +- } intent; ++ struct lookup_intent intent; + }; + + /* +@@ -41,6 +71,9 @@ + #define LOOKUP_CONTINUE 4 + #define LOOKUP_PARENT 16 + #define LOOKUP_NOALT 32 ++#define LOOKUP_LAST (1<<6) ++#define LOOKUP_LINK_NOTLAST (1<<7) ++ + /* + * Intent data + */ +@@ -49,6 +82,12 @@ + #define LOOKUP_ACCESS (0x0400) + + extern int FASTCALL(__user_walk(const char __user *, unsigned, struct nameidata *)); ++extern int FASTCALL(__user_walk_it(const char __user *name, unsigned flags, struct nameidata *nd)); ++#define user_path_walk_it(name,nd) \ ++ __user_walk_it(name, LOOKUP_FOLLOW, nd) ++#define user_path_walk_link_it(name,nd) \ ++ __user_walk_it(name, 0, nd) ++extern void intent_release(struct lookup_intent *); + #define user_path_walk(name,nd) \ + __user_walk(name, LOOKUP_FOLLOW, nd) + #define user_path_walk_link(name,nd) \ +@@ -60,7 +99,6 @@ + + extern struct dentry * lookup_one_len(const char *, struct dentry *, int); + extern struct dentry * lookup_hash(struct qstr *, struct dentry *); +- + extern int follow_down(struct vfsmount **, struct dentry **); + extern int follow_up(struct vfsmount **, struct dentry **); + +Index: uml-2.6.3/kernel/exit.c +=================================================================== +--- uml-2.6.3.orig/kernel/exit.c 2004-02-20 15:00:58.000000000 +0800 ++++ uml-2.6.3/kernel/exit.c 2004-02-20 23:59:01.176421448 +0800 +@@ -255,6 +255,8 @@ + write_unlock_irq(&tasklist_lock); + } + ++EXPORT_SYMBOL(reparent_to_init); ++ + void __set_special_pids(pid_t session, pid_t pgrp) + { + struct task_struct *curr = current; +@@ -422,6 +424,8 @@ + __exit_files(tsk); + } + ++EXPORT_SYMBOL(exit_files); ++ + static inline void __put_fs_struct(struct fs_struct *fs) + { + /* No need to hold fs->lock if we are killing it */