From c1a4879c4c9c886fdaba3e6d97dd787b2c11f182 Mon Sep 17 00:00:00 2001 From: shaver Date: Wed, 26 Mar 2003 07:09:48 +0000 Subject: [PATCH] Merge from b_devel. --- lustre/extN/extN-delete_thread.diff | 15 +- .../kernel_patches/patches/export-truncate.patch | 29 ++ lustre/kernel_patches/patches/lustre-2.5.63.patch | 451 +++++++++++++++++---- lustre/kernel_patches/pc/export-truncate.pc | 2 + .../kernel_patches/pc/iod-stock-24-exports_hp.pc | 3 + lustre/tests/opendevunlink.c | 111 +++++ lustre/tests/opendirunlink.c | 122 ++++++ lustre/tests/openfile.c | 172 ++++++++ lustre/tests/unlinkmany.c | 74 ++++ 9 files changed, 907 insertions(+), 72 deletions(-) create mode 100644 lustre/kernel_patches/patches/export-truncate.patch create mode 100644 lustre/kernel_patches/pc/export-truncate.pc create mode 100644 lustre/kernel_patches/pc/iod-stock-24-exports_hp.pc create mode 100644 lustre/tests/opendevunlink.c create mode 100644 lustre/tests/opendirunlink.c create mode 100644 lustre/tests/openfile.c create mode 100644 lustre/tests/unlinkmany.c diff --git a/lustre/extN/extN-delete_thread.diff b/lustre/extN/extN-delete_thread.diff index acb25e4..6e278c8 100644 --- a/lustre/extN/extN-delete_thread.diff +++ b/lustre/extN/extN-delete_thread.diff @@ -36,7 +36,7 @@ #endif /* _LINUX_EXTN_FS_SB */ --- linux/fs/extN/super.c.orig Wed Mar 12 14:05:30 2003 +++ linux/fs/extN/super.c Thu Mar 13 19:05:26 2003 -@@ -396,6 +396,200 @@ +@@ -396,6 +396,207 @@ } } @@ -98,7 +98,7 @@ + + list_del_init(&inode->i_dentry); + spin_unlock(&sbi->s_delete_lock); -+ extN_debug("%s deleting inode %lu, %lu blocks\n", ++ printk(KERN_DEBUG "%s delete ino %lu blk %lu\n", + tsk->comm, inode->i_ino, blocks); + + iput(inode); @@ -212,8 +212,14 @@ + } + J_ASSERT(new_inode != old_inode); + -+ list_del(&EXTN_I(old_inode)->i_orphan); -+ list_add(&EXTN_I(new_inode)->i_orphan, &sbi->s_orphan); ++ J_ASSERT(!list_empty(&EXTN_I(old_inode)->i_orphan)); ++ /* Ugh. We need to insert new_inode into the same spot on the list ++ * as old_inode was, to ensure the in-memory orphan list is still ++ * the same as the on-disk orphan list. ++ */ ++ EXTN_I(new_inode)->i_orphan = EXTN_I(old_inode)->i_orphan; ++ EXTN_I(new_inode)->i_orphan.next->prev = &EXTN_I(new_inode)->i_orphan; ++ EXTN_I(new_inode)->i_orphan.prev->next = &EXTN_I(new_inode)->i_orphan; + EXTN_I(new_inode)->i_state |= EXTN_STATE_DELETE; + up(&sbi->s_orphan_lock); + @@ -222,6 +228,7 @@ + printk(KERN_DEBUG "delete inode %lu (%lu blocks) by thread\n", + new_inode->i_ino, blocks); + spin_lock(&sbi->s_delete_lock); ++ J_ASSERT(list_empty(&new_inode->i_dentry)); + list_add_tail(&new_inode->i_dentry, &sbi->s_delete_list); + sbi->s_delete_blocks += blocks; + sbi->s_delete_inodes++; diff --git a/lustre/kernel_patches/patches/export-truncate.patch b/lustre/kernel_patches/patches/export-truncate.patch new file mode 100644 index 0000000..12e6f440b --- /dev/null +++ b/lustre/kernel_patches/patches/export-truncate.patch @@ -0,0 +1,29 @@ +--- linux/include/linux/mm.h.truncexport 2003-03-21 20:03:18.000000000 -0500 ++++ linux/include/linux/mm.h 2003-03-21 20:05:04.000000000 -0500 +@@ -650,6 +650,7 @@ + /* filemap.c */ + extern void remove_inode_page(struct page *); + extern unsigned long page_unuse(struct page *); ++extern void truncate_complete_page(struct page *); + extern void truncate_inode_pages(struct address_space *, loff_t); + + /* generic vm_area_ops exported for stackable file systems */ +--- linux/mm/filemap.c.truncexport 2003-03-21 20:01:19.000000000 -0500 ++++ linux/mm/filemap.c 2003-03-21 20:01:41.000000000 -0500 +@@ -245,7 +245,7 @@ + do_flushpage(page, partial); + } + +-static void truncate_complete_page(struct page *page) ++void truncate_complete_page(struct page *page) + { + /* + * Leave it on the LRU if it gets converted into anonymous buffers +@@ -266,6 +266,7 @@ + remove_inode_page(page); + page_cache_release(page); + } ++EXPORT_SYMBOL_GPL(truncate_complete_page); + + static int FASTCALL(truncate_list_pages(struct list_head *, unsigned long, unsigned *)); + static int truncate_list_pages(struct list_head *head, unsigned long start, unsigned *partial) diff --git a/lustre/kernel_patches/patches/lustre-2.5.63.patch b/lustre/kernel_patches/patches/lustre-2.5.63.patch index c857ca4..40e6a90 100644 --- a/lustre/kernel_patches/patches/lustre-2.5.63.patch +++ b/lustre/kernel_patches/patches/lustre-2.5.63.patch @@ -1,20 +1,22 @@ - arch/um/kernel/mem.c | 18 +++++++++++- - fs/dcache.c | 12 ++++++-- - fs/namei.c | 71 +++++++++++++++++++++++++++++++++++-------------- + arch/um/kernel/mem.c | 18 ++++++ + fs/dcache.c | 12 +++- + fs/namei.c | 132 ++++++++++++++++++++++++++++++++++++++----------- fs/namespace.c | 1 - fs/nfsd/vfs.c | 2 - - fs/sysfs/inode.c | 2 - - include/linux/dcache.h | 28 +++++++++++++++++++ - include/linux/fs.h | 20 +++++++++++++ - include/linux/namei.h | 3 +- + fs/nfsd/vfs.c | 2 + fs/open.c | 39 ++++++++++++-- + fs/stat.c | 2 + fs/sysfs/inode.c | 2 + include/linux/dcache.h | 28 ++++++++++ + include/linux/fs.h | 20 +++++++ + include/linux/namei.h | 3 - include/linux/slab.h | 1 - kernel/ksyms.c | 7 ++++ - mm/slab.c | 5 +++ - net/unix/af_unix.c | 2 - - 13 files changed, 143 insertions(+), 29 deletions(-) + kernel/ksyms.c | 7 ++ + mm/slab.c | 5 + + net/unix/af_unix.c | 2 + 15 files changed, 231 insertions(+), 43 deletions(-) ---- linux-2.5.63/arch/um/kernel/mem.c~lustre-2.5.63 Thu Mar 13 20:57:08 2003 -+++ linux-2.5.63-kedar/arch/um/kernel/mem.c Thu Mar 13 20:57:08 2003 +--- linux-2.5.63-nointent/arch/um/kernel/mem.c~lustre-2.5.63 Tue Mar 18 15:02:10 2003 ++++ linux-2.5.63-nointent-root/arch/um/kernel/mem.c Tue Mar 18 15:02:10 2003 @@ -660,6 +660,22 @@ struct page *pte_mem_map(pte_t pte) return(phys_mem_map(pte_val(pte))); } @@ -47,19 +49,24 @@ return(0); } ---- linux-2.5.63/fs/namei.c~lustre-2.5.63 Thu Mar 13 20:57:08 2003 -+++ linux-2.5.63-kedar/fs/namei.c Thu Mar 13 20:57:08 2003 -@@ -265,6 +265,9 @@ int deny_write_access(struct file * file +--- linux-2.5.63-nointent/fs/namei.c~lustre-2.5.63 Tue Mar 18 15:02:10 2003 ++++ linux-2.5.63-nointent-root/fs/namei.c Mon Mar 24 17:08:18 2003 +@@ -101,6 +101,14 @@ + * any extra contention... + */ - void path_release(struct nameidata *nd) - { -+ if (nd->dentry && nd->dentry->d_op && -+ nd->dentry->d_op->d_intent_release) -+ nd->dentry->d_op->d_intent_release(nd->dentry, &nd->it); - dput(nd->dentry); - mntput(nd->mnt); - } -@@ -273,10 +276,18 @@ void path_release(struct nameidata *nd) ++void intent_release(struct dentry *de, struct lookup_intent *it) ++{ ++ if (it && de->d_op && de->d_op->d_intent_release) ++ de->d_op->d_intent_release(de, it); ++ ++} ++ ++ + /* In order to reduce some races, while at the same time doing additional + * checking and hopefully speeding things up, we copy filenames to the + * kernel data space before using them.. +@@ -273,10 +281,18 @@ void path_release(struct nameidata *nd) * Internal lookup() using the new generic dcache. * SMP-safe */ @@ -79,7 +86,7 @@ if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) { dput(dentry); -@@ -330,7 +341,7 @@ ok: +@@ -330,7 +346,7 @@ ok: * make sure that nobody added the entry to the dcache in the meantime.. * SMP-safe */ @@ -88,7 +95,7 @@ { struct dentry * result; struct inode *dir = parent->d_inode; -@@ -348,7 +359,10 @@ static struct dentry * real_lookup(struc +@@ -348,7 +364,10 @@ static struct dentry * real_lookup(struc struct dentry * dentry = d_alloc(parent, name); result = ERR_PTR(-ENOMEM); if (dentry) { @@ -100,7 +107,7 @@ if (result) dput(dentry); else { -@@ -370,6 +384,12 @@ static struct dentry * real_lookup(struc +@@ -370,6 +389,12 @@ static struct dentry * real_lookup(struc dput(result); result = ERR_PTR(-ENOENT); } @@ -113,7 +120,52 @@ } return result; } -@@ -531,7 +551,7 @@ done: +@@ -402,6 +427,7 @@ static inline int do_follow_link(struct + current->link_count--; + return err; + loop: ++ intent_release(dentry, &nd->it); + path_release(nd); + return err; + } +@@ -447,15 +473,26 @@ static int follow_mount(struct vfsmount + return res; + } + +-static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry) ++static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry, ++ struct lookup_intent *it) + { + struct vfsmount *mounted; + + spin_lock(&dcache_lock); + mounted = lookup_mnt(*mnt, *dentry); + if (mounted) { ++ int opc = 0, mode = 0; + *mnt = mntget(mounted); + spin_unlock(&dcache_lock); ++ if (it) { ++ opc = it->it_op; ++ mode = it->it_mode; ++ } ++ intent_release(*dentry, it); ++ if (it) { ++ it->it_op = opc; ++ it->it_mode = mode; ++ } + dput(*dentry); + mntput(mounted->mnt_parent); + *dentry = dget(mounted->mnt_root); +@@ -467,7 +504,7 @@ static inline int __follow_down(struct v + + int follow_down(struct vfsmount **mnt, struct dentry **dentry) + { +- return __follow_down(mnt,dentry); ++ return __follow_down(mnt,dentry,NULL); + } + + static inline void follow_dotdot(struct vfsmount **mnt, struct dentry **dentry) +@@ -531,7 +568,7 @@ done: return 0; need_lookup: @@ -122,7 +174,7 @@ if (IS_ERR(dentry)) goto fail; goto done; -@@ -665,7 +685,7 @@ int link_path_walk(const char * name, st +@@ -665,7 +702,7 @@ int link_path_walk(const char * name, st nd->dentry = next.dentry; } err = -ENOTDIR; @@ -131,7 +183,7 @@ break; continue; /* here ends the main loop */ -@@ -716,7 +736,8 @@ last_component: +@@ -716,7 +753,8 @@ last_component: break; if (lookup_flags & LOOKUP_DIRECTORY) { err = -ENOTDIR; @@ -141,7 +193,15 @@ break; } goto return_base; -@@ -857,7 +878,8 @@ int path_lookup(const char *name, unsign +@@ -735,6 +773,7 @@ out_dput: + dput(next.dentry); + break; + } ++ intent_release(nd->dentry, &nd->it); + path_release(nd); + return_err: + return err; +@@ -857,7 +896,8 @@ int path_lookup(const char *name, unsign * needs parent already locked. Doesn't follow mounts. * SMP-safe. */ @@ -151,7 +211,7 @@ { struct dentry * dentry; struct inode *inode; -@@ -880,13 +902,16 @@ struct dentry * lookup_hash(struct qstr +@@ -880,13 +920,16 @@ struct dentry * lookup_hash(struct qstr goto out; } @@ -170,7 +230,7 @@ if (!dentry) { dentry = new; security_inode_post_lookup(inode, dentry); -@@ -898,7 +923,7 @@ out: +@@ -898,7 +941,7 @@ out: } /* SMP-safe */ @@ -179,7 +239,7 @@ { unsigned long hash; struct qstr this; -@@ -918,11 +943,16 @@ struct dentry * lookup_one_len(const cha +@@ -918,11 +961,16 @@ struct dentry * lookup_one_len(const cha } this.hash = end_name_hash(hash); @@ -197,7 +257,17 @@ /* * namei() * -@@ -1239,7 +1269,7 @@ int open_namei(const char * pathname, in +@@ -1224,6 +1272,9 @@ int open_namei(const char * pathname, in + /* + * Create - we need to know the parent. + */ ++ nd->it.it_mode = mode; ++ nd->it.it_op |= IT_CREAT; ++ + error = path_lookup(pathname, LOOKUP_PARENT, nd); + if (error) + return error; +@@ -1239,7 +1290,7 @@ int open_namei(const char * pathname, in dir = nd->dentry; down(&dir->d_inode->i_sem); @@ -206,7 +276,51 @@ do_last: error = PTR_ERR(dentry); -@@ -1342,7 +1372,7 @@ do_link: +@@ -1247,7 +1298,8 @@ do_last: + up(&dir->d_inode->i_sem); + goto exit; + } +- ++ ++ nd->it.it_mode = mode; + /* Negative dentry, just create the file */ + if (!dentry->d_inode) { + if (!IS_POSIXACL(dir->d_inode)) +@@ -1277,7 +1329,7 @@ do_last: + error = -ELOOP; + if (flag & O_NOFOLLOW) + goto exit_dput; +- while (__follow_down(&nd->mnt,&dentry) && d_mountpoint(dentry)); ++ while (__follow_down(&nd->mnt,&dentry,&nd->it) && d_mountpoint(dentry)); + } + error = -ENOENT; + if (!dentry->d_inode) +@@ -1297,8 +1349,10 @@ ok: + return 0; + + exit_dput: ++ intent_release(dentry, &nd->it); + dput(dentry); + exit: ++ intent_release(nd->dentry, &nd->it); + path_release(nd); + return error; + +@@ -1320,7 +1374,12 @@ do_link: + if (error) + goto exit_dput; + UPDATE_ATIME(dentry->d_inode); +- error = dentry->d_inode->i_op->follow_link(dentry, nd); ++ if (dentry->d_inode->i_op->follow_link2) ++ error = dentry->d_inode->i_op->follow_link2(dentry, nd, &nd->it); ++ else ++ error = dentry->d_inode->i_op->follow_link(dentry, nd); ++ if (error) ++ intent_release(dentry, &nd->it); + dput(dentry); + if (error) + return error; +@@ -1342,7 +1401,7 @@ do_link: } dir = nd->dentry; down(&dir->d_inode->i_sem); @@ -215,7 +329,7 @@ putname(nd->last.name); goto do_last; } -@@ -1356,7 +1386,7 @@ static struct dentry *lookup_create(stru +@@ -1356,7 +1415,7 @@ static struct dentry *lookup_create(stru dentry = ERR_PTR(-EEXIST); if (nd->last_type != LAST_NORM) goto fail; @@ -224,7 +338,7 @@ if (IS_ERR(dentry)) goto fail; if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode) -@@ -1588,7 +1618,7 @@ asmlinkage long sys_rmdir(const char * p +@@ -1588,7 +1647,7 @@ asmlinkage long sys_rmdir(const char * p goto exit1; } down(&nd.dentry->d_inode->i_sem); @@ -233,16 +347,63 @@ error = PTR_ERR(dentry); if (!IS_ERR(dentry)) { error = vfs_rmdir(nd.dentry->d_inode, dentry); -@@ -1655,7 +1685,7 @@ asmlinkage long sys_unlink(const char * +@@ -1654,8 +1713,18 @@ asmlinkage long sys_unlink(const char * + error = -EISDIR; if (nd.last_type != LAST_NORM) goto exit1; ++ if (nd.dentry->d_inode->i_op->unlink2) { ++ struct inode_operations *op = nd.dentry->d_inode->i_op; ++ error = op->unlink2(nd.dentry->d_inode, ++ nd.last.name, ++ nd.last.len); ++ /* the file system wants to use normal vfs path now */ ++ if (error != -EOPNOTSUPP) ++ goto exit1; ++ } down(&nd.dentry->d_inode->i_sem); - dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash(&nd.last, nd.dentry, &nd.it); ++// dentry = lookup_hash(&nd.last, nd.dentry, &nd.it); ++ dentry = lookup_hash(&nd.last, nd.dentry, NULL); error = PTR_ERR(dentry); if (!IS_ERR(dentry)) { /* Why not before? Because we want correct error value */ -@@ -1934,7 +1964,8 @@ int vfs_rename_other(struct inode *old_d +@@ -1859,7 +1928,8 @@ exit: + * locking]. + */ + int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, +- struct inode *new_dir, struct dentry *new_dentry) ++ struct inode *new_dir, struct dentry *new_dentry, ++ struct lookup_intent *it) + { + int error = 0; + struct inode *target; +@@ -1887,6 +1957,7 @@ int vfs_rename_dir(struct inode *old_dir + error = -EBUSY; + else + error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); ++ intent_release(new_dentry, it); + if (target) { + if (!error) + target->i_flags |= S_DEAD; +@@ -1904,7 +1975,8 @@ int vfs_rename_dir(struct inode *old_dir + } + + int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, +- struct inode *new_dir, struct dentry *new_dentry) ++ struct inode *new_dir, struct dentry *new_dentry, ++ struct lookup_intent *it) + { + struct inode *target; + int error; +@@ -1921,6 +1993,7 @@ int vfs_rename_other(struct inode *old_d + error = -EBUSY; + else + error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); ++ intent_release(new_dentry, it); + if (!error) { + /* The following d_move() should become unconditional */ + if (!(old_dir->i_sb->s_type->fs_flags & FS_ODD_RENAME)) +@@ -1934,7 +2007,8 @@ int vfs_rename_other(struct inode *old_d } int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, @@ -252,7 +413,19 @@ { int error; int is_dir = S_ISDIR(old_dentry->d_inode->i_mode); -@@ -2005,7 +2036,7 @@ static inline int do_rename(const char * +@@ -1960,9 +2034,9 @@ int vfs_rename(struct inode *old_dir, st + DQUOT_INIT(new_dir); + + if (is_dir) +- error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry); ++ error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry, it); + else +- error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry); ++ error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry, it); + if (!error) { + if (old_dir == new_dir) + inode_dir_notify(old_dir, DN_RENAME); +@@ -2005,7 +2079,7 @@ static inline int do_rename(const char * trap = lock_rename(new_dir, old_dir); @@ -261,7 +434,7 @@ error = PTR_ERR(old_dentry); if (IS_ERR(old_dentry)) goto exit3; -@@ -2025,7 +2056,7 @@ static inline int do_rename(const char * +@@ -2025,7 +2099,7 @@ static inline int do_rename(const char * error = -EINVAL; if (old_dentry == trap) goto exit4; @@ -270,7 +443,7 @@ error = PTR_ERR(new_dentry); if (IS_ERR(new_dentry)) goto exit4; -@@ -2035,7 +2066,7 @@ static inline int do_rename(const char * +@@ -2035,7 +2109,7 @@ static inline int do_rename(const char * goto exit5; error = vfs_rename(old_dir->d_inode, old_dentry, @@ -279,8 +452,8 @@ exit5: dput(new_dentry); exit4: ---- linux-2.5.63/fs/nfsd/vfs.c~lustre-2.5.63 Thu Mar 13 20:57:08 2003 -+++ linux-2.5.63-kedar/fs/nfsd/vfs.c Thu Mar 13 20:57:08 2003 +--- linux-2.5.63-nointent/fs/nfsd/vfs.c~lustre-2.5.63 Tue Mar 18 15:02:10 2003 ++++ linux-2.5.63-nointent-root/fs/nfsd/vfs.c Tue Mar 18 15:02:10 2003 @@ -1337,7 +1337,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru err = nfserr_perm; } else @@ -290,8 +463,8 @@ if (!err && EX_ISSYNC(tfhp->fh_export)) { nfsd_sync_dir(tdentry); nfsd_sync_dir(fdentry); ---- linux-2.5.63/fs/sysfs/inode.c~lustre-2.5.63 Thu Mar 13 20:57:08 2003 -+++ linux-2.5.63-kedar/fs/sysfs/inode.c Thu Mar 13 20:57:08 2003 +--- linux-2.5.63-nointent/fs/sysfs/inode.c~lustre-2.5.63 Tue Mar 18 15:02:10 2003 ++++ linux-2.5.63-nointent-root/fs/sysfs/inode.c Tue Mar 18 15:02:10 2003 @@ -540,7 +540,7 @@ static struct dentry * get_dentry(struct qstr.name = name; qstr.len = strlen(name); @@ -301,8 +474,8 @@ } ---- linux-2.5.63/include/linux/dcache.h~lustre-2.5.63 Thu Mar 13 20:57:08 2003 -+++ linux-2.5.63-kedar/include/linux/dcache.h Thu Mar 13 20:57:08 2003 +--- linux-2.5.63-nointent/include/linux/dcache.h~lustre-2.5.63 Tue Mar 18 15:02:10 2003 ++++ linux-2.5.63-nointent-root/include/linux/dcache.h Tue Mar 18 15:02:10 2003 @@ -12,6 +12,27 @@ struct vfsmount; @@ -366,8 +539,8 @@ extern spinlock_t dcache_lock; extern rwlock_t dparent_lock; ---- linux-2.5.63/include/linux/fs.h~lustre-2.5.63 Thu Mar 13 20:57:08 2003 -+++ linux-2.5.63-kedar/include/linux/fs.h Thu Mar 13 20:57:08 2003 +--- linux-2.5.63-nointent/include/linux/fs.h~lustre-2.5.63 Tue Mar 18 15:02:10 2003 ++++ linux-2.5.63-nointent-root/include/linux/fs.h Tue Mar 18 15:02:10 2003 @@ -234,6 +234,9 @@ typedef int (get_blocks_t)(struct inode #define ATTR_ATTR_FLAG 1024 #define ATTR_KILL_SUID 2048 @@ -429,8 +602,8 @@ extern long do_mount(char *, char *, char *, unsigned long, void *); extern int vfs_statfs(struct super_block *, struct statfs *); ---- linux-2.5.63/include/linux/namei.h~lustre-2.5.63 Thu Mar 13 20:57:08 2003 -+++ linux-2.5.63-kedar/include/linux/namei.h Thu Mar 13 20:57:08 2003 +--- linux-2.5.63-nointent/include/linux/namei.h~lustre-2.5.63 Tue Mar 18 15:02:10 2003 ++++ linux-2.5.63-nointent-root/include/linux/namei.h Tue Mar 18 15:02:10 2003 @@ -11,6 +11,7 @@ struct nameidata { struct qstr last; unsigned int flags; @@ -448,8 +621,8 @@ extern int follow_down(struct vfsmount **, struct dentry **); extern int follow_up(struct vfsmount **, struct dentry **); ---- linux-2.5.63/include/linux/slab.h~lustre-2.5.63 Thu Mar 13 20:57:08 2003 -+++ linux-2.5.63-kedar/include/linux/slab.h Thu Mar 13 20:57:08 2003 +--- linux-2.5.63-nointent/include/linux/slab.h~lustre-2.5.63 Tue Mar 18 15:02:10 2003 ++++ linux-2.5.63-nointent-root/include/linux/slab.h Tue Mar 18 15:02:10 2003 @@ -55,6 +55,7 @@ extern int kmem_cache_destroy(kmem_cache extern int kmem_cache_shrink(kmem_cache_t *); extern void *kmem_cache_alloc(kmem_cache_t *, int); @@ -458,8 +631,8 @@ extern unsigned int kmem_cache_size(kmem_cache_t *); extern void *kmalloc(size_t, int); ---- linux-2.5.63/kernel/ksyms.c~lustre-2.5.63 Thu Mar 13 20:57:08 2003 -+++ linux-2.5.63-kedar/kernel/ksyms.c Thu Mar 13 20:57:08 2003 +--- linux-2.5.63-nointent/kernel/ksyms.c~lustre-2.5.63 Tue Mar 18 15:02:10 2003 ++++ linux-2.5.63-nointent-root/kernel/ksyms.c Tue Mar 18 15:02:10 2003 @@ -377,6 +377,7 @@ EXPORT_SYMBOL(unregister_filesystem); EXPORT_SYMBOL(kern_mount); EXPORT_SYMBOL(__mntput); @@ -481,8 +654,8 @@ /* waitqueue handling */ EXPORT_SYMBOL(add_wait_queue); EXPORT_SYMBOL(add_wait_queue_exclusive); ---- linux-2.5.63/mm/slab.c~lustre-2.5.63 Thu Mar 13 20:57:08 2003 -+++ linux-2.5.63-kedar/mm/slab.c Thu Mar 13 20:57:08 2003 +--- linux-2.5.63-nointent/mm/slab.c~lustre-2.5.63 Tue Mar 18 15:02:10 2003 ++++ linux-2.5.63-nointent-root/mm/slab.c Tue Mar 18 15:02:10 2003 @@ -1792,6 +1792,11 @@ static inline void __cache_free (kmem_ca } } @@ -495,8 +668,8 @@ /** * kmem_cache_alloc - Allocate an object * @cachep: The cache to allocate from. ---- linux-2.5.63/net/unix/af_unix.c~lustre-2.5.63 Thu Mar 13 20:57:08 2003 -+++ linux-2.5.63-kedar/net/unix/af_unix.c Thu Mar 13 20:57:08 2003 +--- linux-2.5.63-nointent/net/unix/af_unix.c~lustre-2.5.63 Tue Mar 18 15:02:10 2003 ++++ linux-2.5.63-nointent-root/net/unix/af_unix.c Tue Mar 18 15:02:10 2003 @@ -720,7 +720,7 @@ static int unix_bind(struct socket *sock /* * Do the final lookup. @@ -506,8 +679,8 @@ err = PTR_ERR(dentry); if (IS_ERR(dentry)) goto out_mknod_unlock; ---- linux-2.5.63/fs/dcache.c~lustre-2.5.63 Thu Mar 13 20:57:08 2003 -+++ linux-2.5.63-kedar/fs/dcache.c Thu Mar 13 20:57:08 2003 +--- linux-2.5.63-nointent/fs/dcache.c~lustre-2.5.63 Tue Mar 18 15:02:10 2003 ++++ linux-2.5.63-nointent-root/fs/dcache.c Tue Mar 18 15:02:10 2003 @@ -1111,15 +1111,21 @@ void d_delete(struct dentry * dentry) * Adds a dentry to the hash according to its name. */ @@ -533,8 +706,8 @@ } #define do_switch(x,y) do { \ ---- linux-2.5.63/fs/namespace.c~lustre-2.5.63 Thu Mar 13 20:58:54 2003 -+++ linux-2.5.63-kedar/fs/namespace.c Thu Mar 13 20:59:22 2003 +--- linux-2.5.63-nointent/fs/namespace.c~lustre-2.5.63 Tue Mar 18 15:02:10 2003 ++++ linux-2.5.63-nointent-root/fs/namespace.c Tue Mar 18 15:02:10 2003 @@ -925,6 +925,7 @@ void set_fs_pwd(struct fs_struct *fs, st mntput(old_pwdmnt); } @@ -543,5 +716,147 @@ static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd) { +--- linux-2.5.63-nointent/fs/open.c~lustre-2.5.63 Thu Mar 20 12:43:39 2003 ++++ linux-2.5.63-nointent-root/fs/open.c Mon Mar 24 16:25:47 2003 +@@ -97,7 +97,8 @@ static inline long do_sys_truncate(const + struct nameidata nd; + struct inode * inode; + int error; +- ++ struct lookup_intent it = { .it_op = IT_GETATTR }; ++ nd.it=it; + error = -EINVAL; + if (length < 0) /* sorry, but loff_t says... */ + goto out; +@@ -142,11 +143,13 @@ static inline long do_sys_truncate(const + error = locks_verify_truncate(inode, NULL, length); + if (!error) { + DQUOT_INIT(inode); ++ intent_release(nd.dentry, &nd.it); + error = do_truncate(nd.dentry, length); + } + put_write_access(inode); + + dput_and_out: ++ intent_release(nd.dentry, &nd.it); + path_release(&nd); + out: + return error; +@@ -340,6 +343,8 @@ asmlinkage long sys_access(const char * + int old_fsuid, old_fsgid; + kernel_cap_t old_cap; + int res; ++ struct lookup_intent it = { .it_op = IT_GETATTR }; ++ nd.it=it; + + if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ + return -EINVAL; +@@ -371,6 +376,8 @@ asmlinkage long sys_access(const char * + if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode) + && !special_file(nd.dentry->d_inode->i_mode)) + res = -EROFS; ++ ++ intent_release(nd.dentry, &nd.it); + path_release(&nd); + } + +@@ -385,6 +392,8 @@ asmlinkage long sys_chdir(const char * f + { + struct nameidata nd; + int error; ++ struct lookup_intent it = { .it_op = IT_GETATTR }; ++ nd.it=it; + + error = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &nd); + if (error) +@@ -397,6 +406,7 @@ asmlinkage long sys_chdir(const char * f + set_fs_pwd(current->fs, nd.mnt, nd.dentry); + + dput_and_out: ++ intent_release(nd.dentry, &nd.it); + path_release(&nd); + out: + return error; +@@ -436,6 +446,8 @@ asmlinkage long sys_chroot(const char * + { + struct nameidata nd; + int error; ++ struct lookup_intent it = { .it_op = IT_GETATTR }; ++ nd.it=it; + + error = __user_walk(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd); + if (error) +@@ -508,6 +520,18 @@ asmlinkage long sys_chmod(const char * f + error = -EROFS; + if (IS_RDONLY(inode)) + goto dput_and_out; ++ ++ if (inode->i_op->setattr_raw) { ++ struct inode_operations *op = nd.dentry->d_inode->i_op; ++ ++ newattrs.ia_mode = mode; ++ newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; ++ newattrs.ia_valid |= ATTR_RAW; ++ error = op->setattr_raw(inode, &newattrs); ++ /* the file system wants to use normal vfs path now */ ++ if (error != -EOPNOTSUPP) ++ goto dput_and_out; ++ } + + error = -EPERM; + if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) +@@ -619,7 +643,10 @@ asmlinkage long sys_fchown(unsigned int + struct file *filp_open(const char * filename, int flags, int mode) + { + int namei_flags, error; ++ struct file * temp_filp; + struct nameidata nd; ++ struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = flags }; ++ nd.it=it; + + namei_flags = flags; + if ((namei_flags+1) & O_ACCMODE) +@@ -628,9 +655,11 @@ struct file *filp_open(const char * file + namei_flags |= 2; + + error = open_namei(filename, namei_flags, mode, &nd); +- if (!error) +- return dentry_open(nd.dentry, nd.mnt, flags); +- ++ if (!error) { ++ temp_filp = dentry_open(nd.dentry, nd.mnt, flags); ++ intent_release(nd.dentry,&nd.it); ++ return temp_filp; ++ } + return ERR_PTR(error); + } + +@@ -675,7 +704,7 @@ struct file *dentry_open(struct dentry * + goto cleanup_all; + } + } +- ++ + return f; + + cleanup_all: +--- linux-2.5.63-nointent/fs/stat.c~lustre-2.5.63 Fri Mar 21 21:15:40 2003 ++++ linux-2.5.63-nointent-root/fs/stat.c Fri Mar 21 21:16:53 2003 +@@ -65,6 +65,7 @@ int vfs_stat(char *name, struct kstat *s + error = user_path_walk(name, &nd); + if (!error) { + error = vfs_getattr(nd.mnt, nd.dentry, stat); ++ intent_release(nd.dentry, &nd.it); + path_release(&nd); + } + return error; +@@ -80,6 +81,7 @@ int vfs_lstat(char *name, struct kstat * + error = user_path_walk_link(name, &nd); + if (!error) { + error = vfs_getattr(nd.mnt, nd.dentry, stat); ++ intent_release(nd.dentry, &nd.it); + path_release(&nd); + } + return error; _ diff --git a/lustre/kernel_patches/pc/export-truncate.pc b/lustre/kernel_patches/pc/export-truncate.pc new file mode 100644 index 0000000..bd58c82 --- /dev/null +++ b/lustre/kernel_patches/pc/export-truncate.pc @@ -0,0 +1,2 @@ +include/linux/mm.h +mm/filemap.c diff --git a/lustre/kernel_patches/pc/iod-stock-24-exports_hp.pc b/lustre/kernel_patches/pc/iod-stock-24-exports_hp.pc new file mode 100644 index 0000000..e4eceee --- /dev/null +++ b/lustre/kernel_patches/pc/iod-stock-24-exports_hp.pc @@ -0,0 +1,3 @@ +fs/inode.c +fs/Makefile +mm/page_alloc.c diff --git a/lustre/tests/opendevunlink.c b/lustre/tests/opendevunlink.c new file mode 100644 index 0000000..fde7d36 --- /dev/null +++ b/lustre/tests/opendevunlink.c @@ -0,0 +1,111 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + char *dname1, *dname2; + int fddev1, fddev2, rc; + //DIR *dp; + struct stat st1, st2; + + if (argc < 2 || argc > 3) { + fprintf(stderr, "usage: %s filename1 [filename2]\n", argv[0]); + exit(1); + } + + dname1 = argv[1]; + if (argc == 3) + dname2 = argv[2]; + else + dname2 = argv[1]; + + //create the special file (right now only test on pipe) + fprintf(stderr, "creating special file %s\n", dname1); + rc = mknod(dname1, 0777|S_IFIFO, 0); + if (rc == -1) { + fprintf(stderr, "creating %s fails: %s\n", + dname1, strerror(errno)); + exit(1); + } + + // open the special file again + fprintf(stderr, "opening file\n"); + fddev1 = open(dname1, O_RDONLY | O_NONBLOCK); + if (fddev1 == -1) { + fprintf(stderr, "open %s fails: %s\n", + dname1, strerror(errno)); + exit(1); + } + + // doesn't matter if the two dirs are the same?? + fddev2 = open(dname2, O_RDONLY | O_NONBLOCK); + if (fddev2 == -1) { + fprintf(stderr, "open %s fails: %s\n", + dname2, strerror(errno)); + exit(1); + } + + // delete the special file + fprintf (stderr, "unlinking %s\n", dname1); + rc = unlink(dname1); + if (rc) { + fprintf(stderr, "unlink %s error: %s\n", + dname1, strerror(errno)); + exit(1); + } + + if (access(dname2, F_OK) == 0){ + fprintf(stderr, "%s still exists\n", dname2); + exit(1); + } + + if (access(dname1, F_OK) == 0){ + fprintf(stderr, "%s still exists\n", dname1); + exit(1); + } + + // fchmod one special file + rc = fchmod (fddev1, 0777); + if(rc == -1) + { + fprintf(stderr, "fchmod unlinked special file %s fails: %s\n", + dname1, strerror(errno)); + exit(1); + } + + // fstat two files to check if they are the same + rc = fstat(fddev1, &st1); + if(rc == -1) + { + fprintf(stderr, "fstat unlinked special file %s fails: %s\n", + dname1, strerror(errno)); + exit(1); + } + + rc = fstat(fddev2, &st2); + if (rc == -1) { + fprintf(stderr, "fstat file %s fails: %s\n", + dname2, strerror(errno)); + exit(1); + } + + if (st1.st_mode != st2.st_mode) { // can we do this? + fprintf(stderr, "fstat different value on %s and %s\n", dname1, dname2); + exit(1); + } + + fprintf(stderr, "Ok, everything goes well.\n"); + return 0; +} + diff --git a/lustre/tests/opendirunlink.c b/lustre/tests/opendirunlink.c new file mode 100644 index 0000000..2664618 --- /dev/null +++ b/lustre/tests/opendirunlink.c @@ -0,0 +1,122 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + char *dname1, *dname2; + int fddir1, fddir2, rc; + //DIR *dp; + struct stat st1, st2; + + if (argc < 2 || argc > 3) { + fprintf(stderr, "usage: %s dirname1 [dirname2]\n", argv[0]); + exit(1); + } + + dname1 = argv[1]; + if (argc == 3) + dname2 = argv[2]; + else + dname2 = argv[1]; + + //create the directory + fprintf(stderr, "creating directory %s\n", dname1); + rc = mkdir(dname1, 0744); + if (rc == -1) { + fprintf(stderr, "creating %s fails: %s\n", + dname1, strerror(errno)); + exit(1); + } + + // open the dir again + fprintf(stderr, "opening directory\n"); + fddir1 = open(dname1, O_RDONLY | O_DIRECTORY); + if (fddir1 == -1) { + fprintf(stderr, "open %s fails: %s\n", + dname1, strerror(errno)); + exit(1); + } + + // doesn't matter if the two dirs are the same?? + fddir2 = open(dname2, O_RDONLY | O_DIRECTORY); + if (fddir2 == -1) { + fprintf(stderr, "open %s fails: %s\n", + dname2, strerror(errno)); + exit(1); + } + + // another method +/* + if ( (dp = opendir(dname2)) == NULL) { + fprintf(stderr, "opendir() %s\n", strerror(errno)); + exit(1); + } + fddir = dirfd(dp); +*/ + + // delete the dir + fprintf (stderr, "unlinking %s\n", dname1); + rc = rmdir(dname1); + if (rc) { + fprintf(stderr, "unlink %s error: %s\n", + dname1, strerror(errno)); + exit(1); + } + + if (access(dname2, F_OK) == 0){ + fprintf(stderr, "%s still exists\n", dname2); + exit(1); + } + + if (access(dname1, F_OK) == 0){ + fprintf(stderr, "%s still exists\n", dname1); + exit(1); + } + + // fchmod the dir + rc = fchmod (fddir1, 0777); + if(rc == -1) + { + fprintf(stderr, "fchmod unlinked dir fails %s\n", + strerror(errno)); + exit(1); + } + + // fstat two dirs to check if they are the same + rc = fstat(fddir1, &st1); + if(rc == -1) + { + fprintf(stderr, "fstat unlinked dir %s fails %s\n", + dname1, strerror(errno)); + exit(1); + } + + rc = fstat(fddir2, &st2); + if (rc == -1) { + fprintf(stderr, "fstat dir %s fails %s\n", + dname2, strerror(errno)); + exit(1); + } + + if (st1.st_mode != st2.st_mode) { // can we do this? + fprintf(stderr, "fstat different value on %s and %s\n", dname1, dname2); + exit(1); + } + + fprintf(stderr, "Ok, everything goes well.\n"); + return 0; +} + diff --git a/lustre/tests/openfile.c b/lustre/tests/openfile.c new file mode 100644 index 0000000..5fc7a26 --- /dev/null +++ b/lustre/tests/openfile.c @@ -0,0 +1,172 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + */ + +#if 0 +#define DEBUG +#endif + + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct flag_mapping { + char string[20]; + int flag; +}FLAG_MAPPING; + +FLAG_MAPPING flag_table[] = { + {"O_RDONLY", O_RDONLY}, + {"O_WRONLY", O_WRONLY}, + {"O_RDWR", O_RDWR}, + {"O_CREAT", O_CREAT}, + {"O_EXCL", O_EXCL}, + {"O_NOCTTY", O_NOCTTY}, + {"O_TRUNC", O_TRUNC}, + {"O_APPEND", O_APPEND}, + {"O_NONBLOCK", O_NONBLOCK}, + {"O_NDELAY", O_NDELAY}, + {"O_SYNC", O_SYNC}, + {"O_NOFOLLOW", O_NOFOLLOW}, + {"O_DIRECTORY", O_DIRECTORY}, + {"O_LARGEFILE", O_LARGEFILE}, + {"", -1} +}; + +void +Usage_and_abort() +{ + fprintf(stderr, "Usage: openfile -f flags [ -m mode ] filename \n"); + fprintf(stderr, "e.g. " \ + "openfile -f O_RDWR:O_CREAT -m 0755 /etc/passwd\n"); + exit(-1); + +} + +main(int argc, char** argv) +{ + int i; + int flags=0; + mode_t mode=0; + char* fname=NULL; + int mode_set=0; + int flag_set=0; + int file_set=0; + char c; + char* cloned_flags; + + if(argc == 1) { + Usage_and_abort(); + } + + while ((c = getopt (argc, argv, "f:m:")) != -1) { + switch (c) { + case 'f': + { + char *tmp ; + + cloned_flags = (char*)malloc(strlen(optarg)); + if (cloned_flags==NULL) { + fprintf(stderr, "Insufficient memory.\n"); + exit(-1); + } + + strncpy(cloned_flags, optarg, strlen(optarg)); + tmp = strtok(optarg, ":"); + while (tmp) + { + int i=0; +#ifdef DEBUG +printf("flags = %s\n",tmp); +#endif + flag_set = 1; + while (flag_table[i].flag != -1) + { + int r; + r = strncasecmp (tmp, (flag_table[i].string), + strlen((flag_table[i].string)) ); + + if (r == 0) + break; + i++; + } + + if(flag_table[i].flag != -1) + flags |= flag_table[i].flag; + else { + fprintf(stderr, "No such flag: %s\n", + tmp); + exit(-1); + } + + tmp = strtok(NULL, ":"); + + } +#ifdef DEBUG +printf("flags = %x\n", flags); +#endif + } + break; + case 'm': +#ifdef DEBUG +printf("mode = %s\n", optarg); +#endif + mode = strtol (optarg, NULL, 8); + mode_set = 1; +#ifdef DEBUG +printf("mode = %o\n", mode); +#endif + break; + default: + fprintf(stderr, "Bad parameters.\n"); + Usage_and_abort(); + } + } + + if(optind == argc) { + fprintf(stderr, "Bad parameters.\n"); + Usage_and_abort(); + } + + fname = argv[optind]; + file_set = 1; + + if( !flag_set || !file_set) { + + fprintf(stderr, "Missing flag or file-name\n"); + exit(-1); + } + + + if ( mode_set ) + i = open(fname, flags, mode); + else + i = open(fname, flags); + + + if (i!=-1) { + fprintf(stderr, "Succeed in opening file \"%s\"(flags=%s", + fname, cloned_flags ); + + if (mode_set) + fprintf(stderr, ", mode=%o", mode); + fprintf(stderr, ")\n", mode); + close (i); + }else { + fprintf(stderr, "Error in opening file \"%s\"(flags=%s", + fname, cloned_flags); + if (mode_set) + fprintf(stderr, ", mode=%o", mode); + fprintf(stderr, ") %s\n", strerror(errno)); + } + return(i); +} + diff --git a/lustre/tests/unlinkmany.c b/lustre/tests/unlinkmany.c new file mode 100644 index 0000000..ba1bee7 --- /dev/null +++ b/lustre/tests/unlinkmany.c @@ -0,0 +1,74 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void usage(char *prog) +{ + printf("usage: %s filenamefmt count\n", prog); + printf(" %s filenamefmt start count\n", prog); +} + +int main(int argc, char ** argv) +{ + int i, rc = 0; + char format[4096], *fmt; + char filename[4096]; + long start, last; + long begin = 0, count; + + if (argc < 3 || argc > 4) { + usage(argv[0]); + return 1; + } + + if (strlen(argv[1]) > 4080) { + printf("name too long\n"); + return 1; + } + + start = last = time(0); + + if (argc == 3) { + count = strtol(argv[2], NULL, 0); + if (count < 1) { + printf("count must be at least one\n"); + return 1; + } + } else { + begin = strtol(argv[2], NULL, 0); + count = strtol(argv[3], NULL, 0); + } + + if (strchr(argv[1], '%')) { + fmt = argv[1]; + } else { + sprintf(format, "%s%%d", argv[1]); + fmt = format; + } + for (i = 0; i < count; i++, begin++) { + sprintf(filename, fmt, begin); + rc = unlink(filename); + if (rc) { + printf("unlink(%s) error: %s\n", + filename, strerror(errno)); + rc = errno; + break; + } + if ((i % 10000) == 0) { + printf(" - unlinked %d (time %ld ; total %ld ; last " + "%ld)\n", i, time(0), time(0) - start, + time(0) - last); + last = time(0); + } + } + printf("total: %d unlinks in %ld seconds: %f unlinks/second\n", i, + time(0) - start, ((float)i / (time(0) - start))); + + return rc; +} -- 1.8.3.1