From d506a00e0f6c1932555cf1c93cc5da80b172f9bd Mon Sep 17 00:00:00 2001 From: adilger Date: Thu, 13 May 2004 09:09:27 +0000 Subject: [PATCH] Land b1_2_smallfix onto b1_2 (20040512_1444) b=2350, b=3313, b=3265, b=3315, b=3301, b=3325, b=3329, b=3125, b=3098 --- .../kernel_patches/patches/iopen-2.6-suse.patch | 258 ++++++++++++++------- lnet/klnds/qswlnd/qswlnd.c | 5 +- lnet/klnds/qswlnd/qswlnd.h | 8 +- lnet/klnds/qswlnd/qswlnd_cb.c | 2 +- lustre/ChangeLog | 9 + lustre/configure.in | 2 +- lustre/include/linux/lustre_idl.h | 20 -- lustre/include/linux/obd.h | 3 + lustre/include/lustre/liblustreapi.h | 15 +- lustre/include/lustre/lustre_user.h | 30 ++- .../kernel_patches/patches/add_page_private.patch | 4 +- .../ext3-extents-2.4.18-chaos-pdirops.patch | 2 +- .../patches/ext3-extents-2.4.18-chaos.patch | 2 +- lustre/kernel_patches/patches/iopen-2.4.18-2.patch | 189 +++++++++------ lustre/kernel_patches/patches/iopen-2.4.18.patch | 189 +++++++++------ lustre/kernel_patches/patches/iopen-2.6-suse.patch | 258 ++++++++++++++------- .../patches/iopen-misc-2.6-suse.patch | 59 ++++- lustre/kernel_patches/patches/lustre_version.patch | 7 +- .../patches/vfs_intent-2.4.18-18-chaos65.patch | 4 +- .../patches/vfs_intent-2.4.19-pre1.patch | 4 +- .../patches/vfs_intent-2.4.19-suse.patch | 4 +- .../patches/vfs_intent-2.4.20-hp.patch | 4 +- .../patches/vfs_intent-2.4.20-rh.patch | 4 +- .../patches/vfs_intent-2.4.20-vanilla.patch | 4 +- .../patches/vfs_intent-2.4.21-chaos.patch | 4 +- .../patches/vfs_intent-2.4.21-suse-171.patch | 4 +- .../patches/vfs_intent-2.4.21-suse2.patch | 4 +- .../patches/vfs_intent-2.4.22-rh.patch | 4 +- .../patches/vfs_intent-2.6-suse.patch | 4 +- lustre/ldlm/ldlm_lib.c | 4 +- lustre/ldlm/ldlm_lockd.c | 9 +- lustre/ldlm/ldlm_resource.c | 9 +- lustre/liblustre/file.c | 17 +- lustre/liblustre/llite_lib.h | 7 +- lustre/llite/dcache.c | 47 +++- lustre/llite/dir.c | 6 +- lustre/llite/file.c | 16 +- lustre/llite/llite_lib.c | 2 + lustre/llite/lproc_llite.c | 8 - lustre/llite/namei.c | 7 + lustre/mdc/mdc_internal.h | 2 + lustre/mdc/mdc_lib.c | 34 +++ lustre/mdc/mdc_locks.c | 2 +- lustre/mdc/mdc_request.c | 18 +- lustre/mds/handler.c | 24 ++ lustre/mds/mds_internal.h | 2 + lustre/mds/mds_open.c | 99 +++++--- lustre/obdclass/class_obd.c | 4 +- lustre/obdfilter/filter.c | 47 +++- lustre/osc/lproc_osc.c | 7 +- lustre/osc/osc_create.c | 15 +- lustre/portals/knals/qswnal/qswnal.c | 5 +- lustre/portals/knals/qswnal/qswnal.h | 8 +- lustre/portals/knals/qswnal/qswnal_cb.c | 2 +- lustre/tests/fsx.c | 38 ++- lustre/tests/insanity.sh | 4 +- lustre/tests/replay-single.sh | 12 + lustre/tests/sanity.sh | 95 +++++++- lustre/tests/sanityN.sh | 4 +- lustre/utils/Lustre/lustredb.py | 4 + lustre/utils/lconf | 47 ++-- lustre/utils/lfs.c | 45 ++-- lustre/utils/liblustreapi.c | 182 +++++++-------- lustre/utils/obd.c | 13 +- 64 files changed, 1281 insertions(+), 670 deletions(-) diff --git a/ldiskfs/kernel_patches/patches/iopen-2.6-suse.patch b/ldiskfs/kernel_patches/patches/iopen-2.6-suse.patch index ef5a253..2133355 100644 --- a/ldiskfs/kernel_patches/patches/iopen-2.6-suse.patch +++ b/ldiskfs/kernel_patches/patches/iopen-2.6-suse.patch @@ -1,4 +1,3 @@ - Documentation/filesystems/ext2.txt | 16 ++ fs/ext3/inode.c | 3 fs/ext3/iopen.c | 239 +++++++++++++++++++++++++++++++++++++ fs/ext3/iopen.h | 15 ++ @@ -7,10 +6,23 @@ include/linux/ext3_fs.h | 2 7 files changed, 304 insertions(+), 1 deletion(-) -Index: linux-2.6.4-51.1/fs/ext3/inode.c +Index: linux-stage/fs/ext3/Makefile =================================================================== ---- linux-2.6.4-51.1.orig/fs/ext3/inode.c 2004-04-06 00:31:14.000000000 -0400 -+++ linux-2.6.4-51.1/fs/ext3/inode.c 2004-04-06 00:31:24.000000000 -0400 +--- linux-stage.orig/fs/ext3/Makefile 2004-05-07 16:00:16.000000000 -0400 ++++ linux-stage/fs/ext3/Makefile 2004-05-07 16:00:17.000000000 -0400 +@@ -4,7 +4,7 @@ + + obj-$(CONFIG_EXT3_FS) += ext3.o + +-ext3-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ ++ext3-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \ + ioctl.o namei.o super.o symlink.o hash.o + + ext3-$(CONFIG_EXT3_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o +Index: linux-stage/fs/ext3/inode.c +=================================================================== +--- linux-stage.orig/fs/ext3/inode.c 2004-05-07 16:00:16.000000000 -0400 ++++ linux-stage/fs/ext3/inode.c 2004-05-07 17:21:59.000000000 -0400 @@ -37,6 +37,7 @@ #include #include @@ -19,22 +31,21 @@ Index: linux-2.6.4-51.1/fs/ext3/inode.c #include "acl.h" /* -@@ -2472,6 +2473,8 @@ +@@ -2472,6 +2473,9 @@ ei->i_acl = EXT3_ACL_NOT_CACHED; ei->i_default_acl = EXT3_ACL_NOT_CACHED; #endif + if (ext3_iopen_get_inode(inode)) + return; ++ if (ext3_get_inode_loc(inode, &iloc, 0)) goto bad_inode; bh = iloc.bh; -Index: linux-2.6.4-51.1/fs/ext3/iopen.c +Index: linux-stage/fs/ext3/iopen.c =================================================================== ---- linux-2.6.4-51.1.orig/fs/ext3/iopen.c 2004-04-06 00:31:24.000000000 -0400 -+++ linux-2.6.4-51.1/fs/ext3/iopen.c 2004-04-06 00:31:24.000000000 -0400 -@@ -0,0 +1,223 @@ -+ -+ +--- linux-stage.orig/fs/ext3/iopen.c 2004-05-07 16:00:17.000000000 -0400 ++++ linux-stage/fs/ext3/iopen.c 2004-05-07 17:22:37.000000000 -0400 +@@ -0,0 +1,272 @@ +/* + * linux/fs/ext3/iopen.c + * @@ -44,6 +55,25 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c + * + * This file may be redistributed under the terms of the GNU General + * Public License. ++ * ++ * ++ * Invariants: ++ * - there is only ever a single DCACHE_NFSD_DISCONNECTED dentry alias ++ * for an inode at one time. ++ * - there are never both connected and DCACHE_NFSD_DISCONNECTED dentry ++ * aliases on an inode at the same time. ++ * ++ * If we have any connected dentry aliases for an inode, use one of those ++ * in iopen_lookup(). Otherwise, we instantiate a single NFSD_DISCONNECTED ++ * dentry for this inode, which thereafter will be found by the dcache ++ * when looking up this inode number in __iopen__, so we don't return here ++ * until it is gone. ++ * ++ * If we get an inode via a regular name lookup, then we "rename" the ++ * NFSD_DISCONNECTED dentry to the proper name and parent. This ensures ++ * existing users of the disconnected dentry will continue to use the same ++ * dentry as the connected users, and there will never be both kinds of ++ * dentry aliases at one time. + */ + +#include @@ -52,6 +82,8 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c +#include +#include +#include ++#include ++#include +#include "iopen.h" + +#ifndef assert @@ -63,14 +95,15 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c +/* + * This implements looking up an inode by number. + */ -+static struct dentry *iopen_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd) ++static struct dentry *iopen_lookup(struct inode * dir, struct dentry *dentry, ++ struct nameidata *nd) +{ -+ struct inode * inode; ++ struct inode *inode; + unsigned long ino; + struct list_head *lp; + struct dentry *alternate; + char buf[IOPEN_NAME_LEN]; -+ ++ + if (dentry->d_name.len >= IOPEN_NAME_LEN) + return ERR_PTR(-ENAMETOOLONG); + @@ -99,6 +132,9 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c + return ERR_PTR(-ENOENT); + } + ++ assert(list_empty(&dentry->d_alias)); /* d_instantiate */ ++ assert(d_unhashed(dentry)); /* d_rehash */ ++ + /* preferrably return a connected dentry */ + spin_lock(&dcache_lock); + list_for_each(lp, &inode->i_dentry) { @@ -116,9 +152,14 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c + return alternate; + } + dentry->d_flags |= DCACHE_DISCONNECTED; ++ ++ /* d_add(), but don't drop dcache_lock before adding dentry to inode */ ++ list_add(&dentry->d_alias, &inode->i_dentry); /* d_instantiate */ ++ dentry->d_inode = inode; ++ ++ __d_rehash(dentry, 0); /* d_rehash */ + spin_unlock(&dcache_lock); + -+ d_add(dentry, inode); + return NULL; +} + @@ -126,7 +167,7 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c + __typeof__ (x) __tmp = x; \ + x = y; y = __tmp; } while (0) + -+static inline void switch_names(struct dentry * dentry, struct dentry * target) ++static inline void switch_names(struct dentry *dentry, struct dentry *target) +{ + const unsigned char *old_name, *new_name; + @@ -141,20 +182,27 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c + dentry->d_name.name = old_name; +} + -+ -+struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode) ++/* This function is spliced into ext3_lookup and does the move of a ++ * disconnected dentry (if it exists) to a connected dentry. ++ */ ++struct dentry *iopen_connect_dentry(struct dentry *dentry, struct inode *inode, ++ int rehash) +{ + struct dentry *tmp, *goal = NULL; + struct list_head *lp; + -+ /* preferrably return a connected dentry */ -+ spin_lock(&dcache_lock); + /* verify this dentry is really new */ -+ assert(!de->d_inode); -+ assert(list_empty(&de->d_subdirs)); -+ assert(list_empty(&de->d_alias)); ++ assert(dentry->d_inode == NULL); ++ assert(list_empty(&dentry->d_alias)); /* d_instantiate */ ++ if (rehash) ++ assert(d_unhashed(dentry)); /* d_rehash */ ++ assert(list_empty(&dentry->d_subdirs)); + ++ spin_lock(&dcache_lock); ++ if (!inode) ++ goto do_rehash; + ++ /* preferrably return a connected dentry */ + list_for_each(lp, &inode->i_dentry) { + tmp = list_entry(lp, struct dentry, d_alias); + if (tmp->d_flags & DCACHE_DISCONNECTED) { @@ -165,16 +213,30 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c + break; + } + } -+ spin_unlock(&dcache_lock); + + if (!goal) -+ return NULL; ++ goto do_instantiate; + -+ goal->d_flags &= ~DCACHE_DISCONNECTED; -+ d_rehash(de); -+ d_move(goal, de); ++ /* Move the goal to the de hash queue */ ++ goal->d_flags &= ~ DCACHE_DISCONNECTED; ++ security_d_instantiate(goal, inode); ++ __d_rehash(dentry, 0); ++ __d_move(goal, dentry); ++ spin_unlock(&dcache_lock); ++ iput(inode); + + return goal; ++ ++ /* d_add(), but don't drop dcache_lock before adding dentry to inode */ ++do_instantiate: ++ list_add(&dentry->d_alias, &inode->i_dentry); /* d_instantiate */ ++ dentry->d_inode = inode; ++do_rehash: ++ if (rehash) ++ __d_rehash(dentry, 0); /* d_rehash */ ++ spin_unlock(&dcache_lock); ++ ++ return NULL; +} + +/* @@ -205,9 +267,9 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c + * This function is spliced into ext3_lookup and returns 1 the file + * name is __iopen__ and dentry has been filled in appropriately. + */ -+int ext3_check_for_iopen(struct inode * dir, struct dentry *dentry) ++int ext3_check_for_iopen(struct inode *dir, struct dentry *dentry) +{ -+ struct inode * inode; ++ struct inode *inode; + + if (dir->i_ino != EXT3_ROOT_INO || + !test_opt(dir->i_sb, IOPEN) || @@ -227,7 +289,7 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c + * number is the one for /__iopen__, in which case the inode is filled + * in appropriately. Otherwise, this fuction returns 0. + */ -+int ext3_iopen_get_inode(struct inode * inode) ++int ext3_iopen_get_inode(struct inode *inode) +{ + if (inode->i_ino != EXT3_BAD_INO) + return 0; @@ -256,10 +318,10 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c + + return 1; +} -Index: linux-2.6.4-51.1/fs/ext3/iopen.h +Index: linux-stage/fs/ext3/iopen.h =================================================================== ---- linux-2.6.4-51.1.orig/fs/ext3/iopen.h 2004-04-06 00:31:24.000000000 -0400 -+++ linux-2.6.4-51.1/fs/ext3/iopen.h 2004-04-06 00:31:24.000000000 -0400 +--- linux-stage.orig/fs/ext3/iopen.h 2004-05-07 16:00:17.000000000 -0400 ++++ linux-stage/fs/ext3/iopen.h 2004-05-07 16:00:17.000000000 -0400 @@ -0,0 +1,15 @@ +/* + * iopen.h @@ -272,14 +334,14 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.h + * Public License. + */ + -+extern int ext3_check_for_iopen(struct inode * dir, struct dentry *dentry); -+extern int ext3_iopen_get_inode(struct inode * inode); -+ -+ -Index: linux-2.6.4-51.1/fs/ext3/namei.c ++extern int ext3_check_for_iopen(struct inode *dir, struct dentry *dentry); ++extern int ext3_iopen_get_inode(struct inode *inode); ++extern struct dentry *iopen_connect_dentry(struct dentry *dentry, ++ struct inode *inode, int rehash); +Index: linux-stage/fs/ext3/namei.c =================================================================== ---- linux-2.6.4-51.1.orig/fs/ext3/namei.c 2004-04-06 00:31:11.000000000 -0400 -+++ linux-2.6.4-51.1/fs/ext3/namei.c 2004-04-06 00:31:24.000000000 -0400 +--- linux-stage.orig/fs/ext3/namei.c 2004-05-07 16:00:16.000000000 -0400 ++++ linux-stage/fs/ext3/namei.c 2004-05-07 16:00:17.000000000 -0400 @@ -37,6 +37,7 @@ #include #include @@ -288,47 +350,78 @@ Index: linux-2.6.4-51.1/fs/ext3/namei.c #include "acl.h" /* -@@ -970,15 +971,21 @@ - } - #endif - -+struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode); -+ - static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd) - { - struct inode * inode; - struct ext3_dir_entry_2 * de; - struct buffer_head * bh; -+ struct dentry *alternate = NULL; - +@@ -979,6 +980,9 @@ if (dentry->d_name.len > EXT3_NAME_LEN) return ERR_PTR(-ENAMETOOLONG); -+ if (ext3_check_for_iopen(dir, dentry)) -+ return NULL; ++ if (ext3_check_for_iopen(dir, dentry)) ++ return NULL; + bh = ext3_find_entry(dentry, &de); inode = NULL; if (bh) { -@@ -989,8 +996,14 @@ +@@ -989,10 +993,8 @@ if (!inode) return ERR_PTR(-EACCES); } -+ if (inode && (alternate = iopen_connect_dentry(dentry, inode))) { -+ iput(inode); -+ return alternate; -+ } +- if (inode) +- return d_splice_alias(inode, dentry); +- d_add(dentry, inode); +- return NULL; + - if (inode) - return d_splice_alias(inode, dentry); ++ return iopen_connect_dentry(dentry, inode, 1); + } + + +@@ -2019,10 +2021,6 @@ + inode->i_nlink); + inode->i_version++; + inode->i_nlink = 0; +- /* There's no need to set i_disksize: the fact that i_nlink is +- * zero will ensure that the right thing happens during any +- * recovery. */ +- inode->i_size = 0; + ext3_orphan_add(handle, inode); + inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; + ext3_mark_inode_dirty(handle, inode); +@@ -2139,6 +2137,23 @@ + return err; + } + ++/* Like ext3_add_nondir() except for call to iopen_connect_dentry */ ++static int ext3_add_link(handle_t *handle, struct dentry *dentry, ++ struct inode *inode) ++{ ++ int err = ext3_add_entry(handle, dentry, inode); ++ if (!err) { ++ err = ext3_mark_inode_dirty(handle, inode); ++ if (err == 0) { ++ (void)iopen_connect_dentry(dentry, inode, 0); ++ return 0; ++ } ++ } ++ ext3_dec_count(handle, inode); ++ iput(inode); ++ return err; ++} + - d_add(dentry, inode); - return NULL; + static int ext3_link (struct dentry * old_dentry, + struct inode * dir, struct dentry *dentry) + { +@@ -2161,7 +2176,8 @@ + ext3_inc_count(handle, inode); + atomic_inc(&inode->i_count); + +- err = ext3_add_nondir(handle, dentry, inode); ++ err = ext3_add_link(handle, dentry, inode); ++ ext3_orphan_del(handle,inode); + ext3_journal_stop(handle); + return err; } -Index: linux-2.6.4-51.1/fs/ext3/super.c +Index: linux-stage/fs/ext3/super.c =================================================================== ---- linux-2.6.4-51.1.orig/fs/ext3/super.c 2004-04-06 00:31:14.000000000 -0400 -+++ linux-2.6.4-51.1/fs/ext3/super.c 2004-04-06 00:31:24.000000000 -0400 +--- linux-stage.orig/fs/ext3/super.c 2004-05-07 16:00:16.000000000 -0400 ++++ linux-stage/fs/ext3/super.c 2004-05-07 17:21:59.000000000 -0400 @@ -536,7 +536,7 @@ Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, Opt_noload, Opt_commit, Opt_journal_update, Opt_journal_inum, @@ -353,24 +446,24 @@ Index: linux-2.6.4-51.1/fs/ext3/super.c set_opt(sbi->s_mount_opt, ABORT); break; + case Opt_iopen: -+ set_opt (sbi->s_mount_opt, IOPEN); -+ clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV); ++ set_opt (sbi->s_mount_opt, IOPEN); ++ clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV); + break; + case Opt_noiopen: + clear_opt (sbi->s_mount_opt, IOPEN); -+ clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV); ++ clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV); + break; + case Opt_iopen_nopriv: -+ set_opt (sbi->s_mount_opt, IOPEN); -+ set_opt (sbi->s_mount_opt, IOPEN_NOPRIV); ++ set_opt (sbi->s_mount_opt, IOPEN); ++ set_opt (sbi->s_mount_opt, IOPEN_NOPRIV); + break; case Opt_ignore: break; default: -Index: linux-2.6.4-51.1/include/linux/ext3_fs.h +Index: linux-stage/include/linux/ext3_fs.h =================================================================== ---- linux-2.6.4-51.1.orig/include/linux/ext3_fs.h 2004-04-06 00:31:11.000000000 -0400 -+++ linux-2.6.4-51.1/include/linux/ext3_fs.h 2004-04-06 00:31:24.000000000 -0400 +--- linux-stage.orig/include/linux/ext3_fs.h 2004-05-07 16:00:16.000000000 -0400 ++++ linux-stage/include/linux/ext3_fs.h 2004-05-07 16:00:17.000000000 -0400 @@ -325,6 +325,8 @@ #define EXT3_MOUNT_NO_UID32 0x2000 /* Disable 32-bit UIDs */ #define EXT3_MOUNT_XATTR_USER 0x4000 /* Extended user attributes */ @@ -380,16 +473,3 @@ Index: linux-2.6.4-51.1/include/linux/ext3_fs.h /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ #ifndef _LINUX_EXT2_FS_H -Index: linux-2.6.4-51.1/fs/ext3/Makefile -=================================================================== ---- linux-2.6.4-51.1.orig/fs/ext3/Makefile 2004-04-06 00:27:21.000000000 -0400 -+++ linux-2.6.4-51.1/fs/ext3/Makefile 2004-04-06 00:31:42.000000000 -0400 -@@ -5,7 +5,7 @@ - obj-$(CONFIG_EXT3_FS) += ext3.o - - ext3-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ -- ioctl.o namei.o super.o symlink.o hash.o -+ ioctl.o namei.o super.o symlink.o hash.o iopen.o - - ext3-$(CONFIG_EXT3_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o - ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o diff --git a/lnet/klnds/qswlnd/qswlnd.c b/lnet/klnds/qswlnd/qswlnd.c index 3b3b5d4..9fbc0c3 100644 --- a/lnet/klnds/qswlnd/qswlnd.c +++ b/lnet/klnds/qswlnd/qswlnd.c @@ -114,7 +114,7 @@ kqswnal_yield( nal_t *nal ) { CDEBUG (D_NET, "yield\n"); - if (current->need_resched) + if (need_resched()) schedule(); return; } @@ -793,8 +793,7 @@ kqswnal_initialise (void) /**********************************************************************/ /* Spawn scheduling threads */ - for (i = 0; i < smp_num_cpus; i++) - { + for (i = 0; i < num_online_cpus(); i++) { rc = kqswnal_thread_start (kqswnal_scheduler, NULL); if (rc != 0) { diff --git a/lnet/klnds/qswlnd/qswlnd.h b/lnet/klnds/qswlnd/qswlnd.h index bedc6e0..2849a29 100644 --- a/lnet/klnds/qswlnd/qswlnd.h +++ b/lnet/klnds/qswlnd/qswlnd.h @@ -18,7 +18,7 @@ * along with Lustre; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * Basic library routines. + * Basic library routines. * */ @@ -53,7 +53,11 @@ #include #include #include -#include +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +#include /* wait_on_buffer */ +#else +#include /* wait_on_buffer */ +#endif #include #include #include diff --git a/lnet/klnds/qswlnd/qswlnd_cb.c b/lnet/klnds/qswlnd/qswlnd_cb.c index 731357e..6bff730 100644 --- a/lnet/klnds/qswlnd/qswlnd_cb.c +++ b/lnet/klnds/qswlnd/qswlnd_cb.c @@ -1821,7 +1821,7 @@ kqswnal_scheduler (void *arg) !list_empty(&kqswnal_data.kqn_delayedtxds) || !list_empty(&kqswnal_data.kqn_delayedfwds)); LASSERT (rc == 0); - } else if (current->need_resched) + } else if (need_resched()) schedule (); spin_lock_irqsave (&kqswnal_data.kqn_sched_lock, flags); diff --git a/lustre/ChangeLog b/lustre/ChangeLog index 1ad8661..afe8799 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -26,9 +26,18 @@ tbd Cluster File Systems, Inc. - don't crash in mdc_close for bad permissions on open (3285) - zero i_rdev for non-device files (3147) - clear page->private before handing to FS, better assertion (3119) + - fix incorrect decref of invalidated dentry (2350) + - don't hold journal transaction open across create RPC (3313) + - update atime on MDS at close time (3265) + - close LDAP connection when recovering to avoid server load (3315) + - update iopen-2.6 patch with fixes from 2399,2517,2904 (3301) + - don't leak open file on MDS after open resend (3325) + - serialize filter_precreate and filter_destroy_precreated (3329) * miscellania - allow default OST striping configuration per directory (1414) + - fix compilation for qswnal for 2.6 kernels (3125) - increase maximum number of MDS request buffers for large systems + - change liblustreapi to be useful for external progs like lfsck (3098) 2004-03-22 Cluster File Systems, Inc. * version 1.2.1 diff --git a/lustre/configure.in b/lustre/configure.in index 97157f9..5de965c 100644 --- a/lustre/configure.in +++ b/lustre/configure.in @@ -5,7 +5,7 @@ AC_INIT AC_CANONICAL_SYSTEM -AM_INIT_AUTOMAKE(lustre, 1.2.1.10) +AM_INIT_AUTOMAKE(lustre, 1.2.1.12) # AM_MAINTAINER_MODE # Four main targets: lustre kernel modules, utilities, tests, and liblustre diff --git a/lustre/include/linux/lustre_idl.h b/lustre/include/linux/lustre_idl.h index 85dc751..ef7b3af 100644 --- a/lustre/include/linux/lustre_idl.h +++ b/lustre/include/linux/lustre_idl.h @@ -80,21 +80,6 @@ /* * GENERAL STUFF */ -struct obd_uuid { - __u8 uuid[40]; -}; - -static inline int obd_uuid_equals(struct obd_uuid *u1, struct obd_uuid *u2) -{ - return strcmp(u1->uuid, u2->uuid) == 0; -} - -static inline void obd_str2uuid(struct obd_uuid *uuid, char *tmp) -{ - strncpy(uuid->uuid, tmp, sizeof(*uuid)); - uuid->uuid[sizeof(*uuid) - 1] = '\0'; -} - /* FOO_REQUEST_PORTAL is for incoming requests on the FOO * FOO_REPLY_PORTAL is for incoming replies on the FOO * FOO_BULK_PORTAL is for incoming bulk on the FOO @@ -516,11 +501,6 @@ struct ll_fid { __u32 f_type; }; -struct ll_recreate_obj { - __u64 lrc_id; - __u32 lrc_ost_idx; -}; - extern void lustre_swab_ll_fid (struct ll_fid *fid); #define MDS_STATUS_CONN 1 diff --git a/lustre/include/linux/obd.h b/lustre/include/linux/obd.h index 7e4150d..f9a0bab 100644 --- a/lustre/include/linux/obd.h +++ b/lustre/include/linux/obd.h @@ -173,6 +173,9 @@ struct filter_obd { unsigned long *fo_last_rcvd_slots; __u64 fo_mount_count; + unsigned int fo_destroy_in_progress:1; + struct semaphore fo_create_lock; + struct file_operations *fo_fop; struct inode_operations *fo_iop; struct address_space_operations *fo_aops; diff --git a/lustre/include/lustre/liblustreapi.h b/lustre/include/lustre/liblustreapi.h index 5aa2de2..350bd09 100644 --- a/lustre/include/lustre/liblustreapi.h +++ b/lustre/include/lustre/liblustreapi.h @@ -29,13 +29,14 @@ #include /* liblustreapi.c */ -extern int op_create_file(char *name, long stripe_size, int stripe_offset, - int stripe_count); -extern int op_find(char *path, struct obd_uuid *obduuid, int recursive, - int verbose, int quiet); -extern int op_check(int type_num, char **obd_type_p, char *dir); -extern int op_catinfo(char *dir, char *keyword, char *node_name); -extern int get_file_stripe(char *path, struct lov_user_md *lum); +extern int llapi_file_create(char *name, long stripe_size, int stripe_offset, + int stripe_count, int stripe_pattern); +extern int llapi_file_get_stripe(char *path, struct lov_user_md *lum); +extern int llapi_find(char *path, struct obd_uuid *obduuid, int recursive, + int verbose, int quiet); +extern int llapi_target_check(int num_types, char **obd_types, char *dir); +extern int llapi_catinfo(char *dir, char *keyword, char *node_name); +extern int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, int *ost_count); extern int llapi_is_lustre_mnttype(char *type); #endif diff --git a/lustre/include/lustre/lustre_user.h b/lustre/include/lustre/lustre_user.h index e98b204..f0a839a 100644 --- a/lustre/include/lustre/lustre_user.h +++ b/lustre/include/lustre/lustre_user.h @@ -24,6 +24,11 @@ #ifndef _LUSTRE_USER_H #define _LUSTRE_USER_H #include +#ifdef __KERNEL__ +#include +#else +#include +#endif #define LL_IOC_GETFLAGS _IOR ('f', 151, long) #define LL_IOC_SETFLAGS _IOW ('f', 152, long) @@ -54,9 +59,8 @@ struct lov_user_ost_data_v1 { /* per-stripe data structure */ __u64 l_object_id; /* OST object ID */ __u64 l_object_gr; /* OST object group (creating MDS number) */ - __u32 l_ost_generation; /* generation of this OST index */ - __u16 l_ost_idx; /* OST index in LOV */ - __u16 l_reserved2; + __u32 l_ost_gen; /* generation of this OST index */ + __u32 l_ost_idx; /* OST index in LOV */ } __attribute__((packed)); #define lov_user_md lov_user_md_v1 @@ -71,4 +75,24 @@ struct lov_user_md_v1 { /* LOV EA user data (host-endian) */ struct lov_user_ost_data_v1 lmm_objects[0]; /* per-stripe data */ } __attribute__((packed)); +struct ll_recreate_obj { + __u64 lrc_id; + __u32 lrc_ost_idx; +}; + +struct obd_uuid { + __u8 uuid[40]; +}; + +static inline int obd_uuid_equals(struct obd_uuid *u1, struct obd_uuid *u2) +{ + return strcmp(u1->uuid, u2->uuid) == 0; +} + +static inline void obd_str2uuid(struct obd_uuid *uuid, char *tmp) +{ + strncpy(uuid->uuid, tmp, sizeof(*uuid)); + uuid->uuid[sizeof(*uuid) - 1] = '\0'; +} + #endif /* _LUSTRE_USER_H */ diff --git a/lustre/kernel_patches/patches/add_page_private.patch b/lustre/kernel_patches/patches/add_page_private.patch index f7cc567..93005b66 100644 --- a/lustre/kernel_patches/patches/add_page_private.patch +++ b/lustre/kernel_patches/patches/add_page_private.patch @@ -13,8 +13,8 @@ Index: linux-ia64/include/linux/mm.h _ Index: linux-ia64/mm/filemap.c =================================================================== ---- linux-ia64.orig/mm/filemap.c 2004-04-27 12:35:18.000000000 -0700 -+++ linux-ia64/mm/filemap.c 2004-04-27 12:42:47.000000000 -0700 +--- linux-ia64.orig/mm/filemap.c 2004-04-27 12:35:18.000000000 -0700 ++++ linux-ia64/mm/filemap.c 2004-04-27 12:42:47.000000000 -0700 @@ -676,6 +676,7 @@ static inline void __add_to_page_cache(s page_cache_get(page); page->index = offset; diff --git a/lustre/kernel_patches/patches/ext3-extents-2.4.18-chaos-pdirops.patch b/lustre/kernel_patches/patches/ext3-extents-2.4.18-chaos-pdirops.patch index c931e8d..592af93 100644 --- a/lustre/kernel_patches/patches/ext3-extents-2.4.18-chaos-pdirops.patch +++ b/lustre/kernel_patches/patches/ext3-extents-2.4.18-chaos-pdirops.patch @@ -1762,7 +1762,7 @@ @@ -12,7 +12,8 @@ O_TARGET := ext3.o export-objs := ext3-exports.o - obj-y := balloc.o iopen.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ + obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \ - ioctl.o namei.o super.o symlink.o xattr.o hash.o ext3-exports.o + ioctl.o namei.o super.o symlink.o xattr.o hash.o ext3-exports.o \ + extents.o diff --git a/lustre/kernel_patches/patches/ext3-extents-2.4.18-chaos.patch b/lustre/kernel_patches/patches/ext3-extents-2.4.18-chaos.patch index a88b30d..a0b4230 100644 --- a/lustre/kernel_patches/patches/ext3-extents-2.4.18-chaos.patch +++ b/lustre/kernel_patches/patches/ext3-extents-2.4.18-chaos.patch @@ -1760,7 +1760,7 @@ Index: linux-2.4.18-chaos/fs/ext3/Makefile @@ -12,7 +12,8 @@ export-objs := ext3-exports.o - obj-y := balloc.o iopen.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ + obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \ - ioctl.o namei.o super.o symlink.o xattr.o ext3-exports.o + ioctl.o namei.o super.o symlink.o xattr.o ext3-exports.o \ + extents.o diff --git a/lustre/kernel_patches/patches/iopen-2.4.18-2.patch b/lustre/kernel_patches/patches/iopen-2.4.18-2.patch index 8215730..4af67bc 100644 --- a/lustre/kernel_patches/patches/iopen-2.4.18-2.patch +++ b/lustre/kernel_patches/patches/iopen-2.4.18-2.patch @@ -8,9 +8,11 @@ include/linux/ext3_fs.h | 2 8 files changed, 318 insertions(+), 1 deletion(-) ---- linux-2.4.18-p4smp/Documentation/filesystems/ext2.txt~iopen-2.4.18 2003-07-09 12:17:30.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/Documentation/filesystems/ext2.txt 2003-07-09 17:13:02.000000000 -0600 -@@ -35,6 +35,22 @@ resgid=n The group ID which may use th +Index: linux-aed/Documentation/filesystems/ext2.txt +=================================================================== +--- linux-aed.orig/Documentation/filesystems/ext2.txt Tue May 4 13:14:35 2004 ++++ linux-aed/Documentation/filesystems/ext2.txt Tue May 4 19:17:12 2004 +@@ -35,6 +35,22 @@ sb=n Use alternate superblock at this location. @@ -33,19 +35,23 @@ grpquota,noquota,quota,usrquota Quota options are silently ignored by ext2. ---- linux-2.4.18-p4smp/fs/ext3/Makefile~iopen-2.4.18 2003-07-09 17:12:12.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/fs/ext3/Makefile 2003-07-09 17:13:15.000000000 -0600 -@@ -11,7 +11,7 @@ O_TARGET := ext3.o +Index: linux-aed/fs/ext3/Makefile +=================================================================== +--- linux-aed.orig/fs/ext3/Makefile Tue May 4 19:16:51 2004 ++++ linux-aed/fs/ext3/Makefile Tue May 4 19:17:12 2004 +@@ -11,7 +11,7 @@ - export-objs := super.o inode.o xattr.o ext3-exports.o + export-objs := ext3-exports.o -obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ -+obj-y := balloc.o iopen.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ ++obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \ ioctl.o namei.o super.o symlink.o xattr.o hash.o ext3-exports.o obj-m := $(O_TARGET) ---- linux-2.4.18-p4smp/fs/ext3/inode.c~iopen-2.4.18 2003-07-09 17:11:19.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/fs/ext3/inode.c 2003-07-09 17:13:02.000000000 -0600 +Index: linux-aed/fs/ext3/inode.c +=================================================================== +--- linux-aed.orig/fs/ext3/inode.c Tue May 4 19:17:09 2004 ++++ linux-aed/fs/ext3/inode.c Tue May 4 19:17:12 2004 @@ -31,6 +31,7 @@ #include #include @@ -54,7 +60,7 @@ /* * SEARCH_FROM_ZERO forces each block allocation to search from the start -@@ -2165,6 +2166,9 @@ void ext3_read_inode(struct inode * inod +@@ -2277,6 +2278,9 @@ struct buffer_head *bh; int block; @@ -64,9 +70,11 @@ if(ext3_get_inode_loc(inode, &iloc)) goto bad_inode; bh = iloc.bh; ---- /dev/null 2003-01-30 03:24:37.000000000 -0700 -+++ linux-2.4.18-p4smp-braam/fs/ext3/iopen.c 2003-07-09 17:13:02.000000000 -0600 -@@ -0,0 +1,258 @@ +Index: linux-aed/fs/ext3/iopen.c +=================================================================== +--- linux-aed.orig/fs/ext3/iopen.c Tue May 4 13:14:35 2004 ++++ linux-aed/fs/ext3/iopen.c Tue May 4 19:17:12 2004 +@@ -0,0 +1,282 @@ +/* + * linux/fs/ext3/iopen.c + * @@ -203,13 +211,24 @@ + +/* This function is spliced into ext3_lookup and does the move of a + * disconnected dentry (if it exists) to a connected dentry. -+ * Caller must hold dcache_lock. + */ -+struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode) ++struct dentry *iopen_connect_dentry(struct dentry *dentry, struct inode *inode, ++ int rehash) +{ + struct dentry *tmp, *goal = NULL; + struct list_head *lp; + ++ /* verify this dentry is really new */ ++ assert(dentry->d_inode == NULL); ++ assert(list_empty(&dentry->d_alias)); /* d_instantiate */ ++ if (rehash) ++ assert(list_empty(&dentry->d_hash)); /* d_rehash */ ++ assert(list_empty(&dentry->d_subdirs)); ++ ++ spin_lock(&dcache_lock); ++ if (!inode) ++ goto do_rehash; ++ + /* preferrably return a connected dentry */ + list_for_each(lp, &inode->i_dentry) { + tmp = list_entry(lp, struct dentry, d_alias); @@ -223,27 +242,40 @@ + } + + if (!goal) -+ return NULL; ++ goto do_instantiate; + + /* Move the goal to the de hash queue - like d_move() */ + goal->d_flags &= ~DCACHE_NFSD_DISCONNECTED; + list_del_init(&goal->d_hash); + + list_del(&goal->d_child); -+ list_del(&de->d_child); ++ list_del(&dentry->d_child); + + /* Switch the parents and the names.. */ -+ switch_names(goal, de); -+ do_switch(goal->d_parent, de->d_parent); -+ do_switch(goal->d_name.len, de->d_name.len); -+ do_switch(goal->d_name.hash, de->d_name.hash); ++ switch_names(goal, dentry); ++ do_switch(goal->d_parent, dentry->d_parent); ++ do_switch(goal->d_name.len, dentry->d_name.len); ++ do_switch(goal->d_name.hash, dentry->d_name.hash); + + /* And add them back to the (new) parent lists */ + list_add(&goal->d_child, &goal->d_parent->d_subdirs); -+ list_add(&de->d_child, &de->d_parent->d_subdirs); ++ list_add(&dentry->d_child, &dentry->d_parent->d_subdirs); + __d_rehash(goal, 0); ++ spin_unlock(&dcache_lock); ++ iput(inode); + + return goal; ++ ++ /* d_add(), but don't drop dcache_lock before adding dentry to inode */ ++do_instantiate: ++ list_add(&dentry->d_alias, &inode->i_dentry); /* d_instantiate */ ++ dentry->d_inode = inode; ++do_rehash: ++ if (rehash) ++ __d_rehash(dentry, 0); /* d_rehash */ ++ spin_unlock(&dcache_lock); ++ ++ return NULL; +} + +/* @@ -325,8 +357,10 @@ + + return 1; +} ---- /dev/null 2003-01-30 03:24:37.000000000 -0700 -+++ linux-2.4.18-p4smp-braam/fs/ext3/iopen.h 2003-07-09 17:13:02.000000000 -0600 +Index: linux-aed/fs/ext3/iopen.h +=================================================================== +--- linux-aed.orig/fs/ext3/iopen.h Tue May 4 13:14:35 2004 ++++ linux-aed/fs/ext3/iopen.h Tue May 4 19:17:12 2004 @@ -0,0 +1,15 @@ +/* + * iopen.h @@ -341,10 +375,12 @@ + +extern int ext3_check_for_iopen(struct inode *dir, struct dentry *dentry); +extern int ext3_iopen_get_inode(struct inode *inode); -+extern struct dentry *iopen_connect_dentry(struct dentry *de, -+ struct inode *inode); ---- linux-2.4.18-p4smp/fs/ext3/namei.c~iopen-2.4.18 2003-07-09 13:32:38.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/fs/ext3/namei.c 2003-07-09 17:13:02.000000000 -0600 ++extern struct dentry *iopen_connect_dentry(struct dentry *dentry, ++ struct inode *inode, int rehash); +Index: linux-aed/fs/ext3/namei.c +=================================================================== +--- linux-aed.orig/fs/ext3/namei.c Tue May 4 19:17:05 2004 ++++ linux-aed/fs/ext3/namei.c Tue May 4 19:17:12 2004 @@ -34,6 +34,7 @@ #include #include @@ -353,12 +389,7 @@ /* * define how far ahead to read directories while searching them. -@@ -709,10 +710,14 @@ cleanup_and_exit: - struct inode * inode; - struct ext3_dir_entry_2 * de; - struct buffer_head * bh; -+ struct dentry *alternate = NULL; - +@@ -713,6 +714,9 @@ if (dentry->d_name.len > EXT3_NAME_LEN) return ERR_PTR(-ENAMETOOLONG); @@ -368,39 +399,67 @@ bh = ext3_find_entry(dentry, &de); inode = NULL; if (bh) { -@@ -723,7 +729,28 @@ static struct dentry *ext3_lookup(struct +@@ -723,8 +727,8 @@ if (!inode) return ERR_PTR(-EACCES); } - d_add(dentry, inode); +- return NULL; + -+ /* verify this dentry is really new */ -+ assert(!dentry->d_inode); -+ assert(list_empty(&dentry->d_alias)); /* d_instantiate */ -+ assert(list_empty(&dentry->d_hash)); /* d_rehash */ -+ assert(list_empty(&dentry->d_subdirs)); -+ -+ spin_lock(&dcache_lock); -+ if (inode && (alternate = iopen_connect_dentry(dentry, inode))) { -+ spin_unlock(&dcache_lock); -+ iput(inode); -+ return alternate; ++ return iopen_connect_dentry(dentry, inode, 1); + } + + #define S_SHIFT 12 +@@ -1588,10 +1592,6 @@ + inode->i_nlink); + inode->i_version = ++event; + inode->i_nlink = 0; +- /* There's no need to set i_disksize: the fact that i_nlink is +- * zero will ensure that the right thing happens during any +- * recovery. */ +- inode->i_size = 0; + ext3_orphan_add(handle, inode); + ext3_mark_inode_dirty(handle, inode); + dir->i_nlink--; +@@ -1711,6 +1711,23 @@ + goto out_stop; + } + ++/* Like ext3_add_nondir() except for call to iopen_connect_dentry */ ++static int ext3_add_link(handle_t *handle, struct dentry *dentry, ++ struct inode *inode) ++{ ++ int err = ext3_add_entry(handle, dentry, inode); ++ if (!err) { ++ err = ext3_mark_inode_dirty(handle, inode); ++ if (err == 0) { ++ (void)iopen_connect_dentry(dentry, inode, 0); ++ return 0; ++ } + } ++ ext3_dec_count(handle, inode); ++ iput(inode); ++ return err; ++} + -+ /* d_add(), but don't drop dcache_lock before adding dentry to inode */ -+ if (inode) /* d_instantiate */ -+ list_add(&dentry->d_alias, &inode->i_dentry); -+ dentry->d_inode = inode; -+ -+ __d_rehash(dentry, 0); /* d_rehash */ -+ spin_unlock(&dcache_lock); -+ - return NULL; - } + static int ext3_link (struct dentry * old_dentry, + struct inode * dir, struct dentry *dentry) + { +@@ -1736,7 +1753,8 @@ + ext3_inc_count(handle, inode); + atomic_inc(&inode->i_count); ---- linux-2.4.18-p4smp/fs/ext3/super.c~iopen-2.4.18 2003-07-09 13:32:38.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/fs/ext3/super.c 2003-07-09 17:13:02.000000000 -0600 -@@ -831,6 +831,18 @@ static int parse_options (char * options +- err = ext3_add_nondir(handle, dentry, inode); ++ err = ext3_add_link(handle, dentry, inode); ++ ext3_orphan_del(handle, inode); + ext3_mark_inode_dirty(handle, inode); + ext3_journal_stop(handle, dir); + return err; +Index: linux-aed/fs/ext3/super.c +=================================================================== +--- linux-aed.orig/fs/ext3/super.c Tue May 4 19:17:01 2004 ++++ linux-aed/fs/ext3/super.c Tue May 4 19:17:12 2004 +@@ -834,6 +834,18 @@ || !strcmp (this_char, "quota") || !strcmp (this_char, "usrquota")) /* Don't do anything ;-) */ ; @@ -419,9 +478,11 @@ else if (!strcmp (this_char, "journal")) { /* @@@ FIXME */ /* Eventually we will want to be able to create ---- linux-2.4.18-p4smp/include/linux/ext3_fs.h~iopen-2.4.18 2003-07-09 13:32:38.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/include/linux/ext3_fs.h 2003-07-09 17:13:02.000000000 -0600 -@@ -321,6 +321,8 @@ struct ext3_inode { +Index: linux-aed/include/linux/ext3_fs.h +=================================================================== +--- linux-aed.orig/include/linux/ext3_fs.h Tue May 4 19:17:08 2004 ++++ linux-aed/include/linux/ext3_fs.h Tue May 4 19:17:12 2004 +@@ -321,6 +321,8 @@ #define EXT3_MOUNT_WRITEBACK_DATA 0x0C00 /* No data ordering */ #define EXT3_MOUNT_UPDATE_JOURNAL 0x1000 /* Update the journal format */ #define EXT3_MOUNT_NO_UID32 0x2000 /* Disable 32-bit UIDs */ @@ -430,5 +491,3 @@ #define EXT3_MOUNT_ASYNCDEL 0x20000 /* Delayed deletion */ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ - -_ diff --git a/lustre/kernel_patches/patches/iopen-2.4.18.patch b/lustre/kernel_patches/patches/iopen-2.4.18.patch index 202ebc6..7c56b03 100644 --- a/lustre/kernel_patches/patches/iopen-2.4.18.patch +++ b/lustre/kernel_patches/patches/iopen-2.4.18.patch @@ -8,9 +8,11 @@ include/linux/ext3_fs.h | 2 8 files changed, 318 insertions(+), 1 deletion(-) ---- linux-2.4.18-p4smp/Documentation/filesystems/ext2.txt~iopen-2.4.18 2003-07-09 12:17:30.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/Documentation/filesystems/ext2.txt 2003-07-09 17:13:02.000000000 -0600 -@@ -35,6 +35,22 @@ resgid=n The group ID which may use th +Index: linux-aed/Documentation/filesystems/ext2.txt +=================================================================== +--- linux-aed.orig/Documentation/filesystems/ext2.txt Tue May 4 13:14:35 2004 ++++ linux-aed/Documentation/filesystems/ext2.txt Tue May 4 19:17:12 2004 +@@ -35,6 +35,22 @@ sb=n Use alternate superblock at this location. @@ -33,19 +35,23 @@ grpquota,noquota,quota,usrquota Quota options are silently ignored by ext2. ---- linux-2.4.18-p4smp/fs/ext3/Makefile~iopen-2.4.18 2003-07-09 17:12:12.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/fs/ext3/Makefile 2003-07-09 17:13:15.000000000 -0600 -@@ -11,7 +11,7 @@ O_TARGET := ext3.o +Index: linux-aed/fs/ext3/Makefile +=================================================================== +--- linux-aed.orig/fs/ext3/Makefile Tue May 4 19:16:51 2004 ++++ linux-aed/fs/ext3/Makefile Tue May 4 19:17:12 2004 +@@ -11,7 +11,7 @@ - export-objs := super.o inode.o xattr.o ext3-exports.o + export-objs := ext3-exports.o -obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ -+obj-y := balloc.o iopen.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ ++obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \ ioctl.o namei.o super.o symlink.o xattr.o ext3-exports.o obj-m := $(O_TARGET) ---- linux-2.4.18-p4smp/fs/ext3/inode.c~iopen-2.4.18 2003-07-09 17:11:19.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/fs/ext3/inode.c 2003-07-09 17:13:02.000000000 -0600 +Index: linux-aed/fs/ext3/inode.c +=================================================================== +--- linux-aed.orig/fs/ext3/inode.c Tue May 4 19:17:09 2004 ++++ linux-aed/fs/ext3/inode.c Tue May 4 19:17:12 2004 @@ -31,6 +31,7 @@ #include #include @@ -54,7 +60,7 @@ /* * SEARCH_FROM_ZERO forces each block allocation to search from the start -@@ -2165,6 +2166,9 @@ void ext3_read_inode(struct inode * inod +@@ -2277,6 +2278,9 @@ struct buffer_head *bh; int block; @@ -64,9 +70,11 @@ if(ext3_get_inode_loc(inode, &iloc)) goto bad_inode; bh = iloc.bh; ---- /dev/null 2003-01-30 03:24:37.000000000 -0700 -+++ linux-2.4.18-p4smp-braam/fs/ext3/iopen.c 2003-07-09 17:13:02.000000000 -0600 -@@ -0,0 +1,258 @@ +Index: linux-aed/fs/ext3/iopen.c +=================================================================== +--- linux-aed.orig/fs/ext3/iopen.c Tue May 4 13:14:35 2004 ++++ linux-aed/fs/ext3/iopen.c Tue May 4 19:17:12 2004 +@@ -0,0 +1,282 @@ +/* + * linux/fs/ext3/iopen.c + * @@ -203,13 +211,24 @@ + +/* This function is spliced into ext3_lookup and does the move of a + * disconnected dentry (if it exists) to a connected dentry. -+ * Caller must hold dcache_lock. + */ -+struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode) ++struct dentry *iopen_connect_dentry(struct dentry *dentry, struct inode *inode, ++ int rehash) +{ + struct dentry *tmp, *goal = NULL; + struct list_head *lp; + ++ /* verify this dentry is really new */ ++ assert(dentry->d_inode == NULL); ++ assert(list_empty(&dentry->d_alias)); /* d_instantiate */ ++ if (rehash) ++ assert(list_empty(&dentry->d_hash)); /* d_rehash */ ++ assert(list_empty(&dentry->d_subdirs)); ++ ++ spin_lock(&dcache_lock); ++ if (!inode) ++ goto do_rehash; ++ + /* preferrably return a connected dentry */ + list_for_each(lp, &inode->i_dentry) { + tmp = list_entry(lp, struct dentry, d_alias); @@ -223,27 +242,40 @@ + } + + if (!goal) -+ return NULL; ++ goto do_instantiate; + + /* Move the goal to the de hash queue - like d_move() */ + goal->d_flags &= ~DCACHE_NFSD_DISCONNECTED; + list_del_init(&goal->d_hash); + + list_del(&goal->d_child); -+ list_del(&de->d_child); ++ list_del(&dentry->d_child); + + /* Switch the parents and the names.. */ -+ switch_names(goal, de); -+ do_switch(goal->d_parent, de->d_parent); -+ do_switch(goal->d_name.len, de->d_name.len); -+ do_switch(goal->d_name.hash, de->d_name.hash); ++ switch_names(goal, dentry); ++ do_switch(goal->d_parent, dentry->d_parent); ++ do_switch(goal->d_name.len, dentry->d_name.len); ++ do_switch(goal->d_name.hash, dentry->d_name.hash); + + /* And add them back to the (new) parent lists */ + list_add(&goal->d_child, &goal->d_parent->d_subdirs); -+ list_add(&de->d_child, &de->d_parent->d_subdirs); ++ list_add(&dentry->d_child, &dentry->d_parent->d_subdirs); + __d_rehash(goal, 0); ++ spin_unlock(&dcache_lock); ++ iput(inode); + + return goal; ++ ++ /* d_add(), but don't drop dcache_lock before adding dentry to inode */ ++do_instantiate: ++ list_add(&dentry->d_alias, &inode->i_dentry); /* d_instantiate */ ++ dentry->d_inode = inode; ++do_rehash: ++ if (rehash) ++ __d_rehash(dentry, 0); /* d_rehash */ ++ spin_unlock(&dcache_lock); ++ ++ return NULL; +} + +/* @@ -325,8 +357,10 @@ + + return 1; +} ---- /dev/null 2003-01-30 03:24:37.000000000 -0700 -+++ linux-2.4.18-p4smp-braam/fs/ext3/iopen.h 2003-07-09 17:13:02.000000000 -0600 +Index: linux-aed/fs/ext3/iopen.h +=================================================================== +--- linux-aed.orig/fs/ext3/iopen.h Tue May 4 13:14:35 2004 ++++ linux-aed/fs/ext3/iopen.h Tue May 4 19:17:12 2004 @@ -0,0 +1,15 @@ +/* + * iopen.h @@ -341,10 +375,12 @@ + +extern int ext3_check_for_iopen(struct inode *dir, struct dentry *dentry); +extern int ext3_iopen_get_inode(struct inode *inode); -+extern struct dentry *iopen_connect_dentry(struct dentry *de, -+ struct inode *inode); ---- linux-2.4.18-p4smp/fs/ext3/namei.c~iopen-2.4.18 2003-07-09 13:32:38.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/fs/ext3/namei.c 2003-07-09 17:13:02.000000000 -0600 ++extern struct dentry *iopen_connect_dentry(struct dentry *dentry, ++ struct inode *inode, int rehash); +Index: linux-aed/fs/ext3/namei.c +=================================================================== +--- linux-aed.orig/fs/ext3/namei.c Tue May 4 19:17:05 2004 ++++ linux-aed/fs/ext3/namei.c Tue May 4 19:17:12 2004 @@ -34,6 +34,7 @@ #include #include @@ -353,12 +389,7 @@ /* * define how far ahead to read directories while searching them. -@@ -703,10 +704,14 @@ cleanup_and_exit: - struct inode * inode; - struct ext3_dir_entry_2 * de; - struct buffer_head * bh; -+ struct dentry *alternate = NULL; - +@@ -713,6 +714,9 @@ if (dentry->d_name.len > EXT3_NAME_LEN) return ERR_PTR(-ENAMETOOLONG); @@ -368,39 +399,67 @@ bh = ext3_find_entry(dentry, &de); inode = NULL; if (bh) { -@@ -723,7 +729,28 @@ static struct dentry *ext3_lookup(struct +@@ -723,8 +727,8 @@ if (!inode) return ERR_PTR(-EACCES); } - d_add(dentry, inode); +- return NULL; + -+ /* verify this dentry is really new */ -+ assert(!dentry->d_inode); -+ assert(list_empty(&dentry->d_alias)); /* d_instantiate */ -+ assert(list_empty(&dentry->d_hash)); /* d_rehash */ -+ assert(list_empty(&dentry->d_subdirs)); -+ -+ spin_lock(&dcache_lock); -+ if (inode && (alternate = iopen_connect_dentry(dentry, inode))) { -+ spin_unlock(&dcache_lock); -+ iput(inode); -+ return alternate; ++ return iopen_connect_dentry(dentry, inode, 1); + } + + #define S_SHIFT 12 +@@ -1588,10 +1592,6 @@ + inode->i_nlink); + inode->i_version = ++event; + inode->i_nlink = 0; +- /* There's no need to set i_disksize: the fact that i_nlink is +- * zero will ensure that the right thing happens during any +- * recovery. */ +- inode->i_size = 0; + ext3_orphan_add(handle, inode); + ext3_mark_inode_dirty(handle, inode); + dir->i_nlink--; +@@ -1711,6 +1711,23 @@ + goto out_stop; + } + ++/* Like ext3_add_nondir() except for call to iopen_connect_dentry */ ++static int ext3_add_link(handle_t *handle, struct dentry *dentry, ++ struct inode *inode) ++{ ++ int err = ext3_add_entry(handle, dentry, inode); ++ if (!err) { ++ err = ext3_mark_inode_dirty(handle, inode); ++ if (err == 0) { ++ (void)iopen_connect_dentry(dentry, inode, 0); ++ return 0; ++ } + } ++ ext3_dec_count(handle, inode); ++ iput(inode); ++ return err; ++} + -+ /* d_add(), but don't drop dcache_lock before adding dentry to inode */ -+ if (inode) /* d_instantiate */ -+ list_add(&dentry->d_alias, &inode->i_dentry); -+ dentry->d_inode = inode; -+ -+ __d_rehash(dentry, 0); /* d_rehash */ -+ spin_unlock(&dcache_lock); -+ - return NULL; - } + static int ext3_link (struct dentry * old_dentry, + struct inode * dir, struct dentry *dentry) + { +@@ -1736,7 +1753,8 @@ + ext3_inc_count(handle, inode); + atomic_inc(&inode->i_count); ---- linux-2.4.18-p4smp/fs/ext3/super.c~iopen-2.4.18 2003-07-09 13:32:38.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/fs/ext3/super.c 2003-07-09 17:13:02.000000000 -0600 -@@ -831,6 +831,18 @@ static int parse_options (char * options +- err = ext3_add_nondir(handle, dentry, inode); ++ err = ext3_add_link(handle, dentry, inode); ++ ext3_orphan_del(handle, inode); + ext3_mark_inode_dirty(handle, inode); + ext3_journal_stop(handle, dir); + return err; +Index: linux-aed/fs/ext3/super.c +=================================================================== +--- linux-aed.orig/fs/ext3/super.c Tue May 4 19:17:01 2004 ++++ linux-aed/fs/ext3/super.c Tue May 4 19:17:12 2004 +@@ -834,6 +834,18 @@ || !strcmp (this_char, "quota") || !strcmp (this_char, "usrquota")) /* Don't do anything ;-) */ ; @@ -419,9 +478,11 @@ else if (!strcmp (this_char, "journal")) { /* @@@ FIXME */ /* Eventually we will want to be able to create ---- linux-2.4.18-p4smp/include/linux/ext3_fs.h~iopen-2.4.18 2003-07-09 13:32:38.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/include/linux/ext3_fs.h 2003-07-09 17:13:02.000000000 -0600 -@@ -321,6 +321,8 @@ struct ext3_inode { +Index: linux-aed/include/linux/ext3_fs.h +=================================================================== +--- linux-aed.orig/include/linux/ext3_fs.h Tue May 4 19:17:08 2004 ++++ linux-aed/include/linux/ext3_fs.h Tue May 4 19:17:12 2004 +@@ -321,6 +321,8 @@ #define EXT3_MOUNT_UPDATE_JOURNAL 0x1000 /* Update the journal format */ #define EXT3_MOUNT_NO_UID32 0x2000 /* Disable 32-bit UIDs */ #define EXT3_MOUNT_INDEX 0x4000 /* Enable directory index */ @@ -430,5 +491,3 @@ #define EXT3_MOUNT_ASYNCDEL 0x20000 /* Delayed deletion */ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ - -_ diff --git a/lustre/kernel_patches/patches/iopen-2.6-suse.patch b/lustre/kernel_patches/patches/iopen-2.6-suse.patch index ef5a253..2133355 100644 --- a/lustre/kernel_patches/patches/iopen-2.6-suse.patch +++ b/lustre/kernel_patches/patches/iopen-2.6-suse.patch @@ -1,4 +1,3 @@ - Documentation/filesystems/ext2.txt | 16 ++ fs/ext3/inode.c | 3 fs/ext3/iopen.c | 239 +++++++++++++++++++++++++++++++++++++ fs/ext3/iopen.h | 15 ++ @@ -7,10 +6,23 @@ include/linux/ext3_fs.h | 2 7 files changed, 304 insertions(+), 1 deletion(-) -Index: linux-2.6.4-51.1/fs/ext3/inode.c +Index: linux-stage/fs/ext3/Makefile =================================================================== ---- linux-2.6.4-51.1.orig/fs/ext3/inode.c 2004-04-06 00:31:14.000000000 -0400 -+++ linux-2.6.4-51.1/fs/ext3/inode.c 2004-04-06 00:31:24.000000000 -0400 +--- linux-stage.orig/fs/ext3/Makefile 2004-05-07 16:00:16.000000000 -0400 ++++ linux-stage/fs/ext3/Makefile 2004-05-07 16:00:17.000000000 -0400 +@@ -4,7 +4,7 @@ + + obj-$(CONFIG_EXT3_FS) += ext3.o + +-ext3-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ ++ext3-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \ + ioctl.o namei.o super.o symlink.o hash.o + + ext3-$(CONFIG_EXT3_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o +Index: linux-stage/fs/ext3/inode.c +=================================================================== +--- linux-stage.orig/fs/ext3/inode.c 2004-05-07 16:00:16.000000000 -0400 ++++ linux-stage/fs/ext3/inode.c 2004-05-07 17:21:59.000000000 -0400 @@ -37,6 +37,7 @@ #include #include @@ -19,22 +31,21 @@ Index: linux-2.6.4-51.1/fs/ext3/inode.c #include "acl.h" /* -@@ -2472,6 +2473,8 @@ +@@ -2472,6 +2473,9 @@ ei->i_acl = EXT3_ACL_NOT_CACHED; ei->i_default_acl = EXT3_ACL_NOT_CACHED; #endif + if (ext3_iopen_get_inode(inode)) + return; ++ if (ext3_get_inode_loc(inode, &iloc, 0)) goto bad_inode; bh = iloc.bh; -Index: linux-2.6.4-51.1/fs/ext3/iopen.c +Index: linux-stage/fs/ext3/iopen.c =================================================================== ---- linux-2.6.4-51.1.orig/fs/ext3/iopen.c 2004-04-06 00:31:24.000000000 -0400 -+++ linux-2.6.4-51.1/fs/ext3/iopen.c 2004-04-06 00:31:24.000000000 -0400 -@@ -0,0 +1,223 @@ -+ -+ +--- linux-stage.orig/fs/ext3/iopen.c 2004-05-07 16:00:17.000000000 -0400 ++++ linux-stage/fs/ext3/iopen.c 2004-05-07 17:22:37.000000000 -0400 +@@ -0,0 +1,272 @@ +/* + * linux/fs/ext3/iopen.c + * @@ -44,6 +55,25 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c + * + * This file may be redistributed under the terms of the GNU General + * Public License. ++ * ++ * ++ * Invariants: ++ * - there is only ever a single DCACHE_NFSD_DISCONNECTED dentry alias ++ * for an inode at one time. ++ * - there are never both connected and DCACHE_NFSD_DISCONNECTED dentry ++ * aliases on an inode at the same time. ++ * ++ * If we have any connected dentry aliases for an inode, use one of those ++ * in iopen_lookup(). Otherwise, we instantiate a single NFSD_DISCONNECTED ++ * dentry for this inode, which thereafter will be found by the dcache ++ * when looking up this inode number in __iopen__, so we don't return here ++ * until it is gone. ++ * ++ * If we get an inode via a regular name lookup, then we "rename" the ++ * NFSD_DISCONNECTED dentry to the proper name and parent. This ensures ++ * existing users of the disconnected dentry will continue to use the same ++ * dentry as the connected users, and there will never be both kinds of ++ * dentry aliases at one time. + */ + +#include @@ -52,6 +82,8 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c +#include +#include +#include ++#include ++#include +#include "iopen.h" + +#ifndef assert @@ -63,14 +95,15 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c +/* + * This implements looking up an inode by number. + */ -+static struct dentry *iopen_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd) ++static struct dentry *iopen_lookup(struct inode * dir, struct dentry *dentry, ++ struct nameidata *nd) +{ -+ struct inode * inode; ++ struct inode *inode; + unsigned long ino; + struct list_head *lp; + struct dentry *alternate; + char buf[IOPEN_NAME_LEN]; -+ ++ + if (dentry->d_name.len >= IOPEN_NAME_LEN) + return ERR_PTR(-ENAMETOOLONG); + @@ -99,6 +132,9 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c + return ERR_PTR(-ENOENT); + } + ++ assert(list_empty(&dentry->d_alias)); /* d_instantiate */ ++ assert(d_unhashed(dentry)); /* d_rehash */ ++ + /* preferrably return a connected dentry */ + spin_lock(&dcache_lock); + list_for_each(lp, &inode->i_dentry) { @@ -116,9 +152,14 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c + return alternate; + } + dentry->d_flags |= DCACHE_DISCONNECTED; ++ ++ /* d_add(), but don't drop dcache_lock before adding dentry to inode */ ++ list_add(&dentry->d_alias, &inode->i_dentry); /* d_instantiate */ ++ dentry->d_inode = inode; ++ ++ __d_rehash(dentry, 0); /* d_rehash */ + spin_unlock(&dcache_lock); + -+ d_add(dentry, inode); + return NULL; +} + @@ -126,7 +167,7 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c + __typeof__ (x) __tmp = x; \ + x = y; y = __tmp; } while (0) + -+static inline void switch_names(struct dentry * dentry, struct dentry * target) ++static inline void switch_names(struct dentry *dentry, struct dentry *target) +{ + const unsigned char *old_name, *new_name; + @@ -141,20 +182,27 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c + dentry->d_name.name = old_name; +} + -+ -+struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode) ++/* This function is spliced into ext3_lookup and does the move of a ++ * disconnected dentry (if it exists) to a connected dentry. ++ */ ++struct dentry *iopen_connect_dentry(struct dentry *dentry, struct inode *inode, ++ int rehash) +{ + struct dentry *tmp, *goal = NULL; + struct list_head *lp; + -+ /* preferrably return a connected dentry */ -+ spin_lock(&dcache_lock); + /* verify this dentry is really new */ -+ assert(!de->d_inode); -+ assert(list_empty(&de->d_subdirs)); -+ assert(list_empty(&de->d_alias)); ++ assert(dentry->d_inode == NULL); ++ assert(list_empty(&dentry->d_alias)); /* d_instantiate */ ++ if (rehash) ++ assert(d_unhashed(dentry)); /* d_rehash */ ++ assert(list_empty(&dentry->d_subdirs)); + ++ spin_lock(&dcache_lock); ++ if (!inode) ++ goto do_rehash; + ++ /* preferrably return a connected dentry */ + list_for_each(lp, &inode->i_dentry) { + tmp = list_entry(lp, struct dentry, d_alias); + if (tmp->d_flags & DCACHE_DISCONNECTED) { @@ -165,16 +213,30 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c + break; + } + } -+ spin_unlock(&dcache_lock); + + if (!goal) -+ return NULL; ++ goto do_instantiate; + -+ goal->d_flags &= ~DCACHE_DISCONNECTED; -+ d_rehash(de); -+ d_move(goal, de); ++ /* Move the goal to the de hash queue */ ++ goal->d_flags &= ~ DCACHE_DISCONNECTED; ++ security_d_instantiate(goal, inode); ++ __d_rehash(dentry, 0); ++ __d_move(goal, dentry); ++ spin_unlock(&dcache_lock); ++ iput(inode); + + return goal; ++ ++ /* d_add(), but don't drop dcache_lock before adding dentry to inode */ ++do_instantiate: ++ list_add(&dentry->d_alias, &inode->i_dentry); /* d_instantiate */ ++ dentry->d_inode = inode; ++do_rehash: ++ if (rehash) ++ __d_rehash(dentry, 0); /* d_rehash */ ++ spin_unlock(&dcache_lock); ++ ++ return NULL; +} + +/* @@ -205,9 +267,9 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c + * This function is spliced into ext3_lookup and returns 1 the file + * name is __iopen__ and dentry has been filled in appropriately. + */ -+int ext3_check_for_iopen(struct inode * dir, struct dentry *dentry) ++int ext3_check_for_iopen(struct inode *dir, struct dentry *dentry) +{ -+ struct inode * inode; ++ struct inode *inode; + + if (dir->i_ino != EXT3_ROOT_INO || + !test_opt(dir->i_sb, IOPEN) || @@ -227,7 +289,7 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c + * number is the one for /__iopen__, in which case the inode is filled + * in appropriately. Otherwise, this fuction returns 0. + */ -+int ext3_iopen_get_inode(struct inode * inode) ++int ext3_iopen_get_inode(struct inode *inode) +{ + if (inode->i_ino != EXT3_BAD_INO) + return 0; @@ -256,10 +318,10 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.c + + return 1; +} -Index: linux-2.6.4-51.1/fs/ext3/iopen.h +Index: linux-stage/fs/ext3/iopen.h =================================================================== ---- linux-2.6.4-51.1.orig/fs/ext3/iopen.h 2004-04-06 00:31:24.000000000 -0400 -+++ linux-2.6.4-51.1/fs/ext3/iopen.h 2004-04-06 00:31:24.000000000 -0400 +--- linux-stage.orig/fs/ext3/iopen.h 2004-05-07 16:00:17.000000000 -0400 ++++ linux-stage/fs/ext3/iopen.h 2004-05-07 16:00:17.000000000 -0400 @@ -0,0 +1,15 @@ +/* + * iopen.h @@ -272,14 +334,14 @@ Index: linux-2.6.4-51.1/fs/ext3/iopen.h + * Public License. + */ + -+extern int ext3_check_for_iopen(struct inode * dir, struct dentry *dentry); -+extern int ext3_iopen_get_inode(struct inode * inode); -+ -+ -Index: linux-2.6.4-51.1/fs/ext3/namei.c ++extern int ext3_check_for_iopen(struct inode *dir, struct dentry *dentry); ++extern int ext3_iopen_get_inode(struct inode *inode); ++extern struct dentry *iopen_connect_dentry(struct dentry *dentry, ++ struct inode *inode, int rehash); +Index: linux-stage/fs/ext3/namei.c =================================================================== ---- linux-2.6.4-51.1.orig/fs/ext3/namei.c 2004-04-06 00:31:11.000000000 -0400 -+++ linux-2.6.4-51.1/fs/ext3/namei.c 2004-04-06 00:31:24.000000000 -0400 +--- linux-stage.orig/fs/ext3/namei.c 2004-05-07 16:00:16.000000000 -0400 ++++ linux-stage/fs/ext3/namei.c 2004-05-07 16:00:17.000000000 -0400 @@ -37,6 +37,7 @@ #include #include @@ -288,47 +350,78 @@ Index: linux-2.6.4-51.1/fs/ext3/namei.c #include "acl.h" /* -@@ -970,15 +971,21 @@ - } - #endif - -+struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode); -+ - static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd) - { - struct inode * inode; - struct ext3_dir_entry_2 * de; - struct buffer_head * bh; -+ struct dentry *alternate = NULL; - +@@ -979,6 +980,9 @@ if (dentry->d_name.len > EXT3_NAME_LEN) return ERR_PTR(-ENAMETOOLONG); -+ if (ext3_check_for_iopen(dir, dentry)) -+ return NULL; ++ if (ext3_check_for_iopen(dir, dentry)) ++ return NULL; + bh = ext3_find_entry(dentry, &de); inode = NULL; if (bh) { -@@ -989,8 +996,14 @@ +@@ -989,10 +993,8 @@ if (!inode) return ERR_PTR(-EACCES); } -+ if (inode && (alternate = iopen_connect_dentry(dentry, inode))) { -+ iput(inode); -+ return alternate; -+ } +- if (inode) +- return d_splice_alias(inode, dentry); +- d_add(dentry, inode); +- return NULL; + - if (inode) - return d_splice_alias(inode, dentry); ++ return iopen_connect_dentry(dentry, inode, 1); + } + + +@@ -2019,10 +2021,6 @@ + inode->i_nlink); + inode->i_version++; + inode->i_nlink = 0; +- /* There's no need to set i_disksize: the fact that i_nlink is +- * zero will ensure that the right thing happens during any +- * recovery. */ +- inode->i_size = 0; + ext3_orphan_add(handle, inode); + inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; + ext3_mark_inode_dirty(handle, inode); +@@ -2139,6 +2137,23 @@ + return err; + } + ++/* Like ext3_add_nondir() except for call to iopen_connect_dentry */ ++static int ext3_add_link(handle_t *handle, struct dentry *dentry, ++ struct inode *inode) ++{ ++ int err = ext3_add_entry(handle, dentry, inode); ++ if (!err) { ++ err = ext3_mark_inode_dirty(handle, inode); ++ if (err == 0) { ++ (void)iopen_connect_dentry(dentry, inode, 0); ++ return 0; ++ } ++ } ++ ext3_dec_count(handle, inode); ++ iput(inode); ++ return err; ++} + - d_add(dentry, inode); - return NULL; + static int ext3_link (struct dentry * old_dentry, + struct inode * dir, struct dentry *dentry) + { +@@ -2161,7 +2176,8 @@ + ext3_inc_count(handle, inode); + atomic_inc(&inode->i_count); + +- err = ext3_add_nondir(handle, dentry, inode); ++ err = ext3_add_link(handle, dentry, inode); ++ ext3_orphan_del(handle,inode); + ext3_journal_stop(handle); + return err; } -Index: linux-2.6.4-51.1/fs/ext3/super.c +Index: linux-stage/fs/ext3/super.c =================================================================== ---- linux-2.6.4-51.1.orig/fs/ext3/super.c 2004-04-06 00:31:14.000000000 -0400 -+++ linux-2.6.4-51.1/fs/ext3/super.c 2004-04-06 00:31:24.000000000 -0400 +--- linux-stage.orig/fs/ext3/super.c 2004-05-07 16:00:16.000000000 -0400 ++++ linux-stage/fs/ext3/super.c 2004-05-07 17:21:59.000000000 -0400 @@ -536,7 +536,7 @@ Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, Opt_noload, Opt_commit, Opt_journal_update, Opt_journal_inum, @@ -353,24 +446,24 @@ Index: linux-2.6.4-51.1/fs/ext3/super.c set_opt(sbi->s_mount_opt, ABORT); break; + case Opt_iopen: -+ set_opt (sbi->s_mount_opt, IOPEN); -+ clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV); ++ set_opt (sbi->s_mount_opt, IOPEN); ++ clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV); + break; + case Opt_noiopen: + clear_opt (sbi->s_mount_opt, IOPEN); -+ clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV); ++ clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV); + break; + case Opt_iopen_nopriv: -+ set_opt (sbi->s_mount_opt, IOPEN); -+ set_opt (sbi->s_mount_opt, IOPEN_NOPRIV); ++ set_opt (sbi->s_mount_opt, IOPEN); ++ set_opt (sbi->s_mount_opt, IOPEN_NOPRIV); + break; case Opt_ignore: break; default: -Index: linux-2.6.4-51.1/include/linux/ext3_fs.h +Index: linux-stage/include/linux/ext3_fs.h =================================================================== ---- linux-2.6.4-51.1.orig/include/linux/ext3_fs.h 2004-04-06 00:31:11.000000000 -0400 -+++ linux-2.6.4-51.1/include/linux/ext3_fs.h 2004-04-06 00:31:24.000000000 -0400 +--- linux-stage.orig/include/linux/ext3_fs.h 2004-05-07 16:00:16.000000000 -0400 ++++ linux-stage/include/linux/ext3_fs.h 2004-05-07 16:00:17.000000000 -0400 @@ -325,6 +325,8 @@ #define EXT3_MOUNT_NO_UID32 0x2000 /* Disable 32-bit UIDs */ #define EXT3_MOUNT_XATTR_USER 0x4000 /* Extended user attributes */ @@ -380,16 +473,3 @@ Index: linux-2.6.4-51.1/include/linux/ext3_fs.h /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ #ifndef _LINUX_EXT2_FS_H -Index: linux-2.6.4-51.1/fs/ext3/Makefile -=================================================================== ---- linux-2.6.4-51.1.orig/fs/ext3/Makefile 2004-04-06 00:27:21.000000000 -0400 -+++ linux-2.6.4-51.1/fs/ext3/Makefile 2004-04-06 00:31:42.000000000 -0400 -@@ -5,7 +5,7 @@ - obj-$(CONFIG_EXT3_FS) += ext3.o - - ext3-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ -- ioctl.o namei.o super.o symlink.o hash.o -+ ioctl.o namei.o super.o symlink.o hash.o iopen.o - - ext3-$(CONFIG_EXT3_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o - ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o diff --git a/lustre/kernel_patches/patches/iopen-misc-2.6-suse.patch b/lustre/kernel_patches/patches/iopen-misc-2.6-suse.patch index a84120a..2d70c7b 100644 --- a/lustre/kernel_patches/patches/iopen-misc-2.6-suse.patch +++ b/lustre/kernel_patches/patches/iopen-misc-2.6-suse.patch @@ -1,7 +1,7 @@ -Index: linux-2.6.0/Documentation/filesystems/ext2.txt +Index: linux-2.6.4-51.0/Documentation/filesystems/ext2.txt =================================================================== ---- linux-2.6.0.orig/Documentation/filesystems/ext2.txt 2002-11-11 06:28:06.000000000 +0300 -+++ linux-2.6.0/Documentation/filesystems/ext2.txt 2004-01-07 17:12:07.000000000 +0300 +--- linux-2.6.4-51.0.orig/Documentation/filesystems/ext2.txt 2004-05-06 22:21:26.000000000 -0400 ++++ linux-2.6.4-51.0/Documentation/filesystems/ext2.txt 2004-05-06 22:24:42.000000000 -0400 @@ -35,6 +35,22 @@ sb=n Use alternate superblock at this location. @@ -25,3 +25,56 @@ Index: linux-2.6.0/Documentation/filesystems/ext2.txt grpquota,noquota,quota,usrquota Quota options are silently ignored by ext2. +Index: linux-2.6.4-51.0/fs/dcache.c +=================================================================== +--- linux-2.6.4-51.0.orig/fs/dcache.c 2004-05-06 22:24:42.000000000 -0400 ++++ linux-2.6.4-51.0/fs/dcache.c 2004-05-06 22:58:37.000000000 -0400 +@@ -1195,12 +1195,11 @@ + * dcache entries should not be moved in this way. + */ + +-void d_move(struct dentry * dentry, struct dentry * target) ++void __d_move(struct dentry * dentry, struct dentry * target) + { + if (!dentry->d_inode) + printk(KERN_WARNING "VFS: moving negative dcache entry\n"); + +- spin_lock(&dcache_lock); + write_seqlock(&rename_lock); + /* + * XXXX: do we really need to take target->d_lock? +@@ -1253,6 +1252,14 @@ + spin_unlock(&target->d_lock); + spin_unlock(&dentry->d_lock); + write_sequnlock(&rename_lock); ++} ++ ++EXPORT_SYMBOL(__d_move); ++ ++void d_move(struct dentry *dentry, struct dentry *target) ++{ ++ spin_lock(&dcache_lock); ++ __d_move(dentry, target); + spin_unlock(&dcache_lock); + } + +Index: linux-2.6.4-51.0/include/linux/dcache.h +=================================================================== +--- linux-2.6.4-51.0.orig/include/linux/dcache.h 2004-05-06 22:24:42.000000000 -0400 ++++ linux-2.6.4-51.0/include/linux/dcache.h 2004-05-06 23:03:43.000000000 -0400 +@@ -234,6 +234,7 @@ + * This adds the entry to the hash queues. + */ + extern void d_rehash(struct dentry *); ++extern void __d_rehash(struct dentry *, int lock); + + /** + * d_add - add dentry to hash queues +@@ -252,6 +253,7 @@ + + /* used for rename() and baskets */ + extern void d_move(struct dentry *, struct dentry *); ++extern void __d_move(struct dentry *, struct dentry *); + + /* appendix may either be NULL or be used for transname suffixes */ + extern struct dentry * d_lookup(struct dentry *, struct qstr *); diff --git a/lustre/kernel_patches/patches/lustre_version.patch b/lustre/kernel_patches/patches/lustre_version.patch index 77c5531..6f32e7d 100644 --- a/lustre/kernel_patches/patches/lustre_version.patch +++ b/lustre/kernel_patches/patches/lustre_version.patch @@ -1,5 +1,6 @@ - - +Version 36: don't dput dentry in link_path_walk_it after lookup error (b=2350) +Version 35: pass intent to real_lookup after revalidate failure (b=3285) +Version 34: fix ext3 iopen assertion failure (b=2517, b=2399) include/linux/lustre_version.h | 1 + 1 files changed, 1 insertion(+) @@ -7,6 +8,6 @@ --- /dev/null Fri Aug 30 17:31:37 2002 +++ linux-2.4.18-18.8.0-l12-braam/include/linux/lustre_version.h Thu Feb 13 07:58:33 2003 @@ -0,0 +1 @@ -+#define LUSTRE_KERNEL_VERSION 35 ++#define LUSTRE_KERNEL_VERSION 36 _ diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.18-18-chaos65.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.18-18-chaos65.patch index a4381f5..4ddd53d 100644 --- a/lustre/kernel_patches/patches/vfs_intent-2.4.18-18-chaos65.patch +++ b/lustre/kernel_patches/patches/vfs_intent-2.4.18-18-chaos65.patch @@ -472,12 +472,12 @@ Index: linux-2.4.18-p4smp/fs/namei.c + break; + new = real_lookup(dentry->d_parent, + &dentry->d_name, 0, it); -+ d_invalidate(dentry); -+ dput(dentry); + if (IS_ERR(new)) { + err = PTR_ERR(new); + break; + } ++ d_invalidate(dentry); ++ dput(dentry); + nd->dentry = new; + } + if (!nd->dentry->d_inode) diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.19-pre1.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.19-pre1.patch index fb75b0a..404e78a 100644 --- a/lustre/kernel_patches/patches/vfs_intent-2.4.19-pre1.patch +++ b/lustre/kernel_patches/patches/vfs_intent-2.4.19-pre1.patch @@ -451,12 +451,12 @@ Index: linux-2.4.19-pre1/fs/namei.c + break; + new = real_lookup(dentry->d_parent, + &dentry->d_name, 0, it); -+ d_invalidate(dentry); -+ dput(dentry); + if (IS_ERR(new)) { + err = PTR_ERR(new); + break; + } ++ d_invalidate(dentry); ++ dput(dentry); + nd->dentry = new; + } + } else diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.19-suse.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.19-suse.patch index 8dafec7..9fc54e5 100644 --- a/lustre/kernel_patches/patches/vfs_intent-2.4.19-suse.patch +++ b/lustre/kernel_patches/patches/vfs_intent-2.4.19-suse.patch @@ -434,12 +434,12 @@ Index: linux-2.4.19.SuSE/fs/namei.c + break; + new = real_lookup(dentry->d_parent, + &dentry->d_name, 0, it); -+ d_invalidate(dentry); -+ dput(dentry); + if (IS_ERR(new)) { + err = PTR_ERR(new); + break; + } ++ d_invalidate(dentry); ++ dput(dentry); + nd->dentry = new; + } + } else diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.20-hp.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.20-hp.patch index 9cc6f7e..1bb500f 100644 --- a/lustre/kernel_patches/patches/vfs_intent-2.4.20-hp.patch +++ b/lustre/kernel_patches/patches/vfs_intent-2.4.20-hp.patch @@ -488,12 +488,12 @@ Index: linux/fs/namei.c + break; + new = real_lookup(dentry->d_parent, + &dentry->d_name, 0, it); -+ d_invalidate(dentry); -+ dput(dentry); + if (IS_ERR(new)) { + err = PTR_ERR(new); + break; + } ++ d_invalidate(dentry); ++ dput(dentry); + nd->dentry = new; + } + if (!nd->dentry->d_inode) diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.20-rh.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.20-rh.patch index 2179450..501e139 100644 --- a/lustre/kernel_patches/patches/vfs_intent-2.4.20-rh.patch +++ b/lustre/kernel_patches/patches/vfs_intent-2.4.20-rh.patch @@ -378,12 +378,12 @@ Index: linux-2.4.20/fs/namei.c + break; + new = real_lookup(dentry->d_parent, + &dentry->d_name, 0, it); -+ d_invalidate(dentry); -+ dput(dentry); + if (IS_ERR(new)) { + err = PTR_ERR(new); + break; + } ++ d_invalidate(dentry); ++ dput(dentry); + nd->dentry = new; + } + if (!nd->dentry->d_inode) diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.20-vanilla.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.20-vanilla.patch index 9e786b2..cf51f54 100644 --- a/lustre/kernel_patches/patches/vfs_intent-2.4.20-vanilla.patch +++ b/lustre/kernel_patches/patches/vfs_intent-2.4.20-vanilla.patch @@ -425,12 +425,12 @@ Index: linux-2.4.24/fs/namei.c + break; + new = real_lookup(dentry->d_parent, + &dentry->d_name, 0, it); -+ d_invalidate(dentry); -+ dput(dentry); + if (IS_ERR(new)) { + err = PTR_ERR(new); + break; + } ++ d_invalidate(dentry); ++ dput(dentry); + nd->dentry = new; + } + if (!nd->dentry->d_inode) diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.21-chaos.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.21-chaos.patch index c6e2ce6..0e12d54 100644 --- a/lustre/kernel_patches/patches/vfs_intent-2.4.21-chaos.patch +++ b/lustre/kernel_patches/patches/vfs_intent-2.4.21-chaos.patch @@ -314,12 +314,12 @@ Index: linux-ia64/fs/namei.c + break; + new = real_lookup(dentry->d_parent, + &dentry->d_name, 0, it); -+ d_invalidate(dentry); -+ dput(dentry); + if (IS_ERR(new)) { + err = PTR_ERR(new); + break; + } ++ d_invalidate(dentry); ++ dput(dentry); + nd->dentry = new; + } + if (!nd->dentry->d_inode) diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.21-suse-171.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.21-suse-171.patch index 6f79f6d..a3d6de3 100644 --- a/lustre/kernel_patches/patches/vfs_intent-2.4.21-suse-171.patch +++ b/lustre/kernel_patches/patches/vfs_intent-2.4.21-suse-171.patch @@ -314,12 +314,12 @@ Index: linux-2.4.21-171/fs/namei.c + break; + new = real_lookup(dentry->d_parent, + &dentry->d_name, 0, it); -+ d_invalidate(dentry); -+ dput(dentry); + if (IS_ERR(new)) { + err = PTR_ERR(new); + break; + } ++ d_invalidate(dentry); ++ dput(dentry); + nd->dentry = new; + } + } else diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.21-suse2.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.21-suse2.patch index 0342e3f..15af47e 100644 --- a/lustre/kernel_patches/patches/vfs_intent-2.4.21-suse2.patch +++ b/lustre/kernel_patches/patches/vfs_intent-2.4.21-suse2.patch @@ -314,12 +314,12 @@ Index: linux-2.4.21-x86_64/fs/namei.c + break; + new = real_lookup(dentry->d_parent, + &dentry->d_name, 0, it); -+ d_invalidate(dentry); -+ dput(dentry); + if (IS_ERR(new)) { + err = PTR_ERR(new); + break; + } ++ d_invalidate(dentry); ++ dput(dentry); + nd->dentry = new; + } + if (!nd->dentry->d_inode) diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.22-rh.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.22-rh.patch index 6f44b00..06d5082 100644 --- a/lustre/kernel_patches/patches/vfs_intent-2.4.22-rh.patch +++ b/lustre/kernel_patches/patches/vfs_intent-2.4.22-rh.patch @@ -302,12 +302,12 @@ + break; + new = real_lookup(dentry->d_parent, + &dentry->d_name, 0, it); -+ d_invalidate(dentry); -+ dput(dentry); + if (IS_ERR(new)) { + err = PTR_ERR(new); + break; + } ++ d_invalidate(dentry); ++ dput(dentry); + nd->dentry = new; + } + } else diff --git a/lustre/kernel_patches/patches/vfs_intent-2.6-suse.patch b/lustre/kernel_patches/patches/vfs_intent-2.6-suse.patch index ecc93fd..761d823 100644 --- a/lustre/kernel_patches/patches/vfs_intent-2.6-suse.patch +++ b/lustre/kernel_patches/patches/vfs_intent-2.6-suse.patch @@ -92,7 +92,7 @@ Index: linux-2.6.4-51.0/fs/namei.c } } return result; -@@ -563,6 +580,31 @@ +@@ -563,6 +580,33 @@ return PTR_ERR(dentry); } @@ -109,6 +109,8 @@ Index: linux-2.6.4-51.0/fs/namei.c + if ((err = permission(dentry->d_parent->d_inode, MAY_EXEC, nd))) + return err; + new = real_lookup(dentry->d_parent, &dentry->d_name, nd); ++ if (IS_ERR(new)) ++ return PTR_ERR(new); + d_invalidate(dentry); + dput(dentry); + nd->dentry = dentry = new; diff --git a/lustre/ldlm/ldlm_lib.c b/lustre/ldlm/ldlm_lib.c index 64cf6e44..8165ce0 100644 --- a/lustre/ldlm/ldlm_lib.c +++ b/lustre/ldlm/ldlm_lib.c @@ -46,7 +46,7 @@ int client_obd_setup(struct obd_device *obddev, obd_count len, void *buf) int rq_portal, rp_portal, connect_op; char *name = obddev->obd_type->typ_name; char *mgmt_name = NULL; - int rc = 0; + int rc; struct obd_device *mgmt_obd; mgmtcli_register_for_events_t register_f; ENTRY; @@ -111,7 +111,7 @@ int client_obd_setup(struct obd_device *obddev, obd_count len, void *buf) cli->cl_max_pages_per_rpc = PTLRPC_MAX_BRW_PAGES; cli->cl_max_rpcs_in_flight = OSC_MAX_RIF_DEFAULT; - ldlm_get_ref(); + rc = ldlm_get_ref(); if (rc) { CERROR("ldlm_get_ref failed: %d\n", rc); GOTO(err, rc); diff --git a/lustre/ldlm/ldlm_lockd.c b/lustre/ldlm/ldlm_lockd.c index ecb4c21..9f25d99 100644 --- a/lustre/ldlm/ldlm_lockd.c +++ b/lustre/ldlm/ldlm_lockd.c @@ -1292,7 +1292,6 @@ static int ldlm_setup(void) rc = kernel_thread(ldlm_bl_thread_main, &bltd, 0); if (rc < 0) { CERROR("cannot start LDLM thread #%d: rc %d\n", i, rc); - LBUG(); GOTO(out_thread, rc); } wait_for_completion(&blp->blp_comp); @@ -1300,17 +1299,13 @@ static int ldlm_setup(void) rc = ptlrpc_start_n_threads(NULL, ldlm_state->ldlm_cancel_service, LDLM_NUM_THREADS, "ldlm_cn"); - if (rc) { - LBUG(); + if (rc) GOTO(out_thread, rc); - } rc = ptlrpc_start_n_threads(NULL, ldlm_state->ldlm_cb_service, LDLM_NUM_THREADS, "ldlm_cb"); - if (rc) { - LBUG(); + if (rc) GOTO(out_thread, rc); - } INIT_LIST_HEAD(&expired_lock_thread.elt_expired_locks); spin_lock_init(&expired_lock_thread.elt_lock); diff --git a/lustre/ldlm/ldlm_resource.c b/lustre/ldlm/ldlm_resource.c index 2b88d3c..53b9d46 100644 --- a/lustre/ldlm/ldlm_resource.c +++ b/lustre/ldlm/ldlm_resource.c @@ -136,7 +136,7 @@ static int lprocfs_write_lru_size(struct file *file, const char *buffer, unsigned long count, void *data) { struct ldlm_namespace *ns = data; - char dummy[MAX_STRING_SIZE + 1]; + char dummy[MAX_STRING_SIZE + 1], *end; unsigned long tmp; dummy[MAX_STRING_SIZE] = '\0'; @@ -153,7 +153,12 @@ static int lprocfs_write_lru_size(struct file *file, const char *buffer, return count; } - tmp = simple_strtoul(dummy, NULL, 0); + tmp = simple_strtoul(dummy, &end, 0); + if (tmp == 0 && *end) { + CERROR("invalid value written\n"); + return -EINVAL; + } + CDEBUG(D_DLMTRACE, "changing namespace %s max_unused from %u to %u\n", ns->ns_name, ns->ns_max_unused, (unsigned int)tmp); ns->ns_max_unused = (unsigned int)tmp; diff --git a/lustre/liblustre/file.c b/lustre/liblustre/file.c index 03538bf..0aa6687 100644 --- a/lustre/liblustre/file.c +++ b/lustre/liblustre/file.c @@ -258,20 +258,19 @@ int llu_mdc_close(struct obd_export *mdc_exp, struct inode *inode) int rc, valid; ENTRY; - valid = OBD_MD_FLID; + obdo.o_id = lli->lli_st_ino; + obdo.o_valid = OBD_MD_FLID; + valid = OBD_MD_FLTYPE | OBD_MD_FLMODE | OBD_MD_FLSIZE |OBD_MD_FLBLOCKS | + OBD_MD_FLATIME | OBD_MD_FLMTIME | OBD_MD_FLCTIME; if (test_bit(LLI_F_HAVE_OST_SIZE_LOCK, &lli->lli_flags)) valid |= OBD_MD_FLSIZE | OBD_MD_FLBLOCKS; - memset(&obdo, 0, sizeof(obdo)); - obdo.o_id = lli->lli_st_ino; - obdo.o_mode = lli->lli_st_mode; - obdo.o_size = lli->lli_st_size; - obdo.o_blocks = lli->lli_st_blocks; + obdo_from_inode(&obdo, inode, valid); + if (0 /* ll_is_inode_dirty(inode) */) { obdo.o_flags = MDS_BFLAG_UNCOMMITTED_WRITES; - valid |= OBD_MD_FLFLAGS; + obdo.o_valid |= OBD_MD_FLFLAGS; } - obdo.o_valid = valid; rc = mdc_close(mdc_exp, &obdo, och, &req); if (rc == EAGAIN) { /* We are the last writer, so the MDS has instructed us to get @@ -279,7 +278,7 @@ int llu_mdc_close(struct obd_export *mdc_exp, struct inode *inode) //ll_queue_done_writing(inode); rc = 0; } else if (rc) { - CERROR("inode %lu close failed: rc = %d\n", lli->lli_st_ino, rc); + CERROR("inode %lu close failed: rc %d\n", lli->lli_st_ino, rc); } else { rc = llu_objects_destroy(req, inode); if (rc) diff --git a/lustre/liblustre/llite_lib.h b/lustre/liblustre/llite_lib.h index ac9ad91..4217f84 100644 --- a/lustre/liblustre/llite_lib.h +++ b/lustre/liblustre/llite_lib.h @@ -216,13 +216,14 @@ static inline void ll_i2uctxt(struct ll_uctxt *ctxt, struct inode *i1, ctxt->gid1 = -1; if (i2) { - lli2 = llu_i2info(i2); + lli2 = llu_i2info(i2); if (in_group_p(lli2->lli_st_gid)) ctxt->gid2 = lli2->lli_st_gid; else ctxt->gid2 = -1; - } else - ctxt->gid2 = 0; + } else { + ctxt->gid2 = -1; + } } diff --git a/lustre/llite/dcache.c b/lustre/llite/dcache.c index 01a9c8a..910abfe 100644 --- a/lustre/llite/dcache.c +++ b/lustre/llite/dcache.c @@ -49,11 +49,28 @@ static void ll_release(struct dentry *de) EXIT; } +/* should NOT be called with the dcache lock, see fs/dcache.c */ +static int ll_ddelete(struct dentry *de) +{ + ENTRY; + LASSERT(de); + CDEBUG(D_DENTRY, "%s dentry %*s (%p, parent %p, inode %p) %s%s\n", + (de->d_flags & DCACHE_LUSTRE_INVALID ? "keeping" : "deleting"), + de->d_name.len, de->d_name.name, de, de->d_parent, de->d_inode, + d_unhashed(de) ? "" : "hashed,", + list_empty(&de->d_subdirs) ? "" : "subdirs"); + //RETURN(de->d_flags & DCACHE_LUSTRE_INVALID); + RETURN(0); +} + void ll_set_dd(struct dentry *de) { ENTRY; LASSERT(de != NULL); + CDEBUG(D_DENTRY, "ldd on dentry %*s (%p) parent %p inode %p refc %d\n", + de->d_name.len, de->d_name.name, de, de->d_parent, de->d_inode, + atomic_read(&de->d_count)); lock_kernel(); if (de->d_fsdata == NULL) { OBD_ALLOC(de->d_fsdata, sizeof(struct ll_dentry_data)); @@ -97,28 +114,36 @@ void ll_unhash_aliases(struct inode *inode) struct ll_sb_info *sbi; ENTRY; - sbi = ll_i2sbi(inode); - - CDEBUG(D_INODE, "marking dentries for ino %lu/%u(%p) invalid\n", - inode->i_ino, inode->i_generation, inode); - if (inode == NULL) { CERROR("unexpected NULL inode, tell phil\n"); return; } + + CDEBUG(D_INODE, "marking dentries for ino %lu/%u(%p) invalid\n", + inode->i_ino, inode->i_generation, inode); + + sbi = ll_i2sbi(inode); head = &inode->i_dentry; restart: spin_lock(&dcache_lock); tmp = head; while ((tmp = tmp->next) != head) { struct dentry *dentry = list_entry(tmp, struct dentry, d_alias); - if (!atomic_read(&dentry->d_count)) { + if (atomic_read(&dentry->d_count) == 0) { + CDEBUG(D_DENTRY, "deleting dentry %*s (%p) parent %p " + "inode %p\n", dentry->d_name.len, + dentry->d_name.name, dentry, dentry->d_parent, + dentry->d_inode); dget_locked(dentry); __d_drop(dentry); spin_unlock(&dcache_lock); dput(dentry); goto restart; - } else { + } else if (!(dentry->d_flags & DCACHE_LUSTRE_INVALID)) { + CDEBUG(D_DENTRY, "unhashing dentry %*s (%p) parent %p " + "inode %p refc %d\n", dentry->d_name.len, + dentry->d_name.name, dentry, dentry->d_parent, + dentry->d_inode, atomic_read(&dentry->d_count)); hlist_del_init(&dentry->d_hash); dentry->d_flags |= DCACHE_LUSTRE_INVALID; hlist_add_head(&dentry->d_hash, @@ -263,8 +288,13 @@ int ll_revalidate_it(struct dentry *de, int flags, struct lookup_intent *it) ptlrpc_req_finished(req); if (rc == 0) { ll_unhash_aliases(de->d_inode); - de->d_flags |= DCACHE_LUSTRE_INVALID; + /* done in ll_unhash_aliases() + dentry->d_flags |= DCACHE_LUSTRE_INVALID; */ } else { + CDEBUG(D_DENTRY, "revalidated dentry %*s (%p) parent %p " + "inode %p refc %d\n", de->d_name.len, + de->d_name.name, de, de->d_parent, de->d_inode, + atomic_read(&de->d_count)); ll_lookup_finish_locks(it, de); de->d_flags &= ~DCACHE_LUSTRE_INVALID; } @@ -377,6 +407,7 @@ struct dentry_operations ll_d_ops = { .d_revalidate_it = ll_revalidate_it, #endif .d_release = ll_release, + .d_delete = ll_ddelete, #if 0 .d_pin = ll_pin, .d_unpin = ll_unpin, diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index 34516ca..7b9eef7 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -635,12 +635,14 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file, int ll_dir_open(struct inode *inode, struct file *file) { - return ll_file_open(inode, file); + ENTRY; + RETURN(ll_file_open(inode, file)); } int ll_dir_release(struct inode *inode, struct file *file) { - return ll_file_release(inode, file); + ENTRY; + RETURN(ll_file_release(inode, file)); } struct file_operations ll_dir_operations = { diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 0d316f0..b311349 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -39,21 +39,19 @@ int ll_mdc_close(struct obd_export *mdc_exp, struct inode *inode, struct ptlrpc_request *req = NULL; struct obd_client_handle *och = &fd->fd_mds_och; struct obdo obdo; - int rc, valid; + int rc; ENTRY; - valid = OBD_MD_FLID; - - memset(&obdo, 0, sizeof(obdo)); obdo.o_id = inode->i_ino; - obdo.o_mode = inode->i_mode; - obdo.o_size = inode->i_size; - obdo.o_blocks = inode->i_blocks; + obdo.o_valid = OBD_MD_FLID; + obdo_from_inode(&obdo, inode, OBD_MD_FLTYPE | OBD_MD_FLMODE | + OBD_MD_FLSIZE | OBD_MD_FLBLOCKS | + OBD_MD_FLATIME | OBD_MD_FLMTIME | + OBD_MD_FLCTIME); if (0 /* ll_is_inode_dirty(inode) */) { obdo.o_flags = MDS_BFLAG_UNCOMMITTED_WRITES; - valid |= OBD_MD_FLFLAGS; + obdo.o_valid |= OBD_MD_FLFLAGS; } - obdo.o_valid = valid; rc = mdc_close(mdc_exp, &obdo, och, &req); if (rc == EAGAIN) { /* We are the last writer, so the MDS has instructed us to get diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 43dded3..13a2f9b 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -238,6 +238,8 @@ void lustre_common_put_super(struct super_block *sb) spin_lock(&dcache_lock); hlist_for_each_safe(tmp, next, &sbi->ll_orphan_dentry_list) { struct dentry *dentry = hlist_entry(tmp, struct dentry, d_hash); + CWARN("orphan dentry %*s (%p) at unmount\n", + dentry->d_name.len, dentry->d_name.name, dentry); shrink_dcache_parent(dentry); } spin_unlock(&dcache_lock); diff --git a/lustre/llite/lproc_llite.c b/lustre/llite/lproc_llite.c index 9f1987c..e9a3e39 100644 --- a/lustre/llite/lproc_llite.c +++ b/lustre/llite/lproc_llite.c @@ -161,14 +161,6 @@ static int ll_rd_filesfree(char *page, char **start, off_t off, int count, } -#if 0 -static int ll_rd_path(char *page, char **start, off_t off, int count, int *eof, - void *data) -{ - return 0; -} -#endif - static int ll_rd_fstype(char *page, char **start, off_t off, int count, int *eof, void *data) { diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c index 771a854..932e258 100644 --- a/lustre/llite/namei.c +++ b/lustre/llite/namei.c @@ -76,6 +76,10 @@ static int ll_test_inode(struct inode *inode, void *opaque) md->body->ino, md->body->generation); } +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + if (inode->i_ino != md->body->ino) + return 0; +#endif if (inode->i_generation != md->body->generation) return 0; @@ -253,6 +257,9 @@ struct dentry *ll_find_alias(struct inode *inode, struct dentry *de) atomic_inc(&dentry->d_count); iput(inode); dentry->d_flags &= ~DCACHE_LUSTRE_INVALID; + CDEBUG(D_DENTRY, "alias dentry %*s (%p) parent %p inode %p " + "refc %d\n", de->d_name.len, de->d_name.name, de, + de->d_parent, de->d_inode, atomic_read(&de->d_count)); return dentry; } diff --git a/lustre/mdc/mdc_internal.h b/lustre/mdc/mdc_internal.h index 2b459b4..568df2c 100644 --- a/lustre/mdc/mdc_internal.h +++ b/lustre/mdc/mdc_internal.h @@ -21,6 +21,8 @@ void mdc_link_pack(struct ptlrpc_request *req, int offset, void mdc_rename_pack(struct ptlrpc_request *req, int offset, struct mdc_op_data *data, const char *old, int oldlen, const char *new, int newlen); +void mdc_close_pack(struct ptlrpc_request *req, int offset, struct obdo *oa, + int valid, struct obd_client_handle *och); struct mdc_open_data { struct obd_client_handle *mod_och; diff --git a/lustre/mdc/mdc_lib.c b/lustre/mdc/mdc_lib.c index 794bcf9..e2dc251 100644 --- a/lustre/mdc/mdc_lib.c +++ b/lustre/mdc/mdc_lib.c @@ -292,3 +292,37 @@ void mdc_getattr_pack(struct ptlrpc_request *req, int valid, int offset, } } +void mdc_close_pack(struct ptlrpc_request *req, int offset, struct obdo *oa, + int valid, struct obd_client_handle *och) +{ + struct mds_body *body; + + body = lustre_msg_buf(req->rq_reqmsg, 0, sizeof(*body)); + + mdc_pack_fid(&body->fid1, oa->o_id, 0, oa->o_mode); + memcpy(&body->handle, &och->och_fh, sizeof(body->handle)); + if (oa->o_valid & OBD_MD_FLATIME) { + body->atime = oa->o_atime; + body->valid |= OBD_MD_FLATIME; + } + if (oa->o_valid & OBD_MD_FLMTIME) { + body->mtime = oa->o_mtime; + body->valid |= OBD_MD_FLMTIME; + } + if (oa->o_valid & OBD_MD_FLCTIME) { + body->ctime = oa->o_ctime; + body->valid |= OBD_MD_FLCTIME; + } + if (oa->o_valid & OBD_MD_FLSIZE) { + body->size = oa->o_size; + body->valid |= OBD_MD_FLSIZE; + } + if (oa->o_valid & OBD_MD_FLBLOCKS) { + body->blocks = oa->o_blocks; + body->valid |= OBD_MD_FLBLOCKS; + } + if (oa->o_valid & OBD_MD_FLFLAGS) { + body->flags = oa->o_flags; + body->valid |= OBD_MD_FLFLAGS; + } +} diff --git a/lustre/mdc/mdc_locks.c b/lustre/mdc/mdc_locks.c index 0fd4b37..25bb4bf 100644 --- a/lustre/mdc/mdc_locks.c +++ b/lustre/mdc/mdc_locks.c @@ -424,7 +424,7 @@ int mdc_intent_lock(struct obd_export *exp, struct ll_uctxt *uctxt, ENTRY; LASSERT(it); - CDEBUG(D_DLMTRACE, "name: %*s in %ld, intent: %s\n", len, name, + CDEBUG(D_DLMTRACE, "name: %*s in inode %ld, intent: %s\n", len, name, (unsigned long)pfid->id, ldlm_it2str(it->it_op)); if (cfid && (it->it_op == IT_LOOKUP || it->it_op == IT_GETATTR)) { diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index 2898a2f..52aa135 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -441,13 +441,12 @@ static int go_back_to_sleep(void *unused) return 0; } -int mdc_close(struct obd_export *exp, struct obdo *obdo, +int mdc_close(struct obd_export *exp, struct obdo *oa, struct obd_client_handle *och, struct ptlrpc_request **request) { - struct mds_body *body; struct obd_device *obd = class_exp2obd(exp); - int reqsize = sizeof(*body); - int rc, repsize[3] = {sizeof(*body), + int reqsize = sizeof(struct mds_body); + int rc, repsize[3] = {sizeof(struct mds_body), obd->u.cli.cl_max_mds_easize, obd->u.cli.cl_max_mds_cookiesize}; struct ptlrpc_request *req; @@ -471,13 +470,7 @@ int mdc_close(struct obd_export *exp, struct obdo *obdo, CDEBUG(D_HA, "couldn't find open req; expecting close error\n"); } - body = lustre_msg_buf(req->rq_reqmsg, 0, sizeof(*body)); - mdc_pack_fid(&body->fid1, obdo->o_id, 0, obdo->o_mode); - memcpy(&body->handle, &och->och_fh, sizeof(body->handle)); - body->size = obdo->o_size; - body->blocks = obdo->o_blocks; - body->flags = obdo->o_flags; - body->valid = obdo->o_valid; + mdc_close_pack(req, 0, oa, oa->o_valid, och); req->rq_replen = lustre_msg_size(3, repsize); req->rq_commit_cb = mdc_commit_close; @@ -499,7 +492,8 @@ int mdc_close(struct obd_export *exp, struct obdo *obdo, if (req->rq_repmsg == NULL) { CDEBUG(D_HA, "request failed to send: %p, %d\n", req, req->rq_status); - rc = req->rq_status ? req->rq_status : -EIO; + if (rc == 0) + rc = req->rq_status ? req->rq_status : -EIO; } else if (rc == 0) { rc = req->rq_repmsg->status; if (req->rq_repmsg->type == PTL_RPC_MSG_ERR) { diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index 3d9da59..4405c08 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -339,6 +339,8 @@ static int mds_destroy_export(struct obd_export *export) list_del(&mfd->mfd_list); spin_unlock(&med->med_open_lock); + /* If you change this message, be sure to update + * replay_single:test_46 */ CERROR("force closing client file handle for %*s (%s:%lu)\n", dentry->d_name.len, dentry->d_name.name, ll_bdevname(dentry->d_inode->i_sb, btmp), @@ -1082,6 +1084,22 @@ int mds_handle(struct ptlrpc_request *req) obd = req->rq_export->exp_obd; mds = &obd->u.mds; + + /* sanity check: if the xid matches, the request must + * be marked as a resent or replayed */ + if (req->rq_xid == med->med_mcd->mcd_last_xid) + LASSERTF(lustre_msg_get_flags(req->rq_reqmsg) & + (MSG_RESENT | MSG_REPLAY), + "rq_xid "LPU64" matches last_xid, " + "expected RESENT flag\n", + req->rq_xid); + /* else: note the opposite is not always true; a + * RESENT req after a failover will usually not match + * the last_xid, since it was likely never + * committed. A REPLAYed request will almost never + * match the last xid, however it could for a + * committed, but still retained, open. */ + /* Check for aborted recovery. */ spin_lock_bh(&obd->obd_processing_task_lock); abort_recovery = obd->obd_abort_recovery; @@ -1646,6 +1664,12 @@ static void fixup_handle_for_resent_req(struct ptlrpc_request *req, } l_unlock(&obd->obd_namespace->ns_lock); + /* If the xid matches, then we know this is a resent request, + * and allow it. (It's probably an OPEN, for which we don't + * send a lock */ + if (req->rq_xid == exp->exp_mds_data.med_mcd->mcd_last_xid) + return; + /* This remote handle isn't enqueued, so we never received or * processed this request. Clear MSG_RESENT, because it can * be handled like any normal request now. */ diff --git a/lustre/mds/mds_internal.h b/lustre/mds/mds_internal.h index ec3f063..9c5ae2e 100644 --- a/lustre/mds/mds_internal.h +++ b/lustre/mds/mds_internal.h @@ -7,6 +7,8 @@ #include +#define MAX_ATIME_DIFF 60 + struct mds_filter_data { __u64 io_epoch; }; diff --git a/lustre/mds/mds_open.c b/lustre/mds/mds_open.c index d8e940a..ca0fd3b 100644 --- a/lustre/mds/mds_open.c +++ b/lustre/mds/mds_open.c @@ -333,14 +333,6 @@ static int mds_create_objects(struct ptlrpc_request *req, int offset, RETURN(-ENOMEM); oti.oti_objid = *ids; - if (*handle == NULL) - *handle = fsfilt_start(obd, inode, FSFILT_OP_CREATE, NULL); - if (IS_ERR(*handle)) { - rc = PTR_ERR(*handle); - *handle = NULL; - GOTO(out_ids, rc); - } - /* replay case */ if(lustre_msg_get_flags(req->rq_reqmsg) & MSG_REPLAY) { LASSERT (rec->ur_fid2->id); @@ -349,6 +341,14 @@ static int mds_create_objects(struct ptlrpc_request *req, int offset, lmm = rec->ur_eadata; LASSERT(lmm); + if (*handle == NULL) + *handle = fsfilt_start(obd,inode,FSFILT_OP_CREATE,NULL); + if (IS_ERR(*handle)) { + rc = PTR_ERR(*handle); + *handle = NULL; + GOTO(out_ids, rc); + } + mds_objids_from_lmm(*ids, lmm, &mds->mds_lov_desc); lmm_buf = lustre_msg_buf(req->rq_repmsg, offset, 0); @@ -398,7 +398,7 @@ static int mds_create_objects(struct ptlrpc_request *req, int offset, lmm, &lmm_size, 1); if (rc > 0) rc = obd_iocontrol(OBD_IOC_LOV_SETSTRIPE, - mds->mds_osc_exp, + mds->mds_osc_exp, 0, &lsm, lmm); OBD_FREE(lmm, mds->mds_max_mdsize); if (rc) @@ -454,6 +454,15 @@ static int mds_create_objects(struct ptlrpc_request *req, int offset, LASSERT(rc >= 0); lmm_size = rc; body->eadatasize = rc; + + if (*handle == NULL) + *handle = fsfilt_start(obd, inode, FSFILT_OP_CREATE, NULL); + if (IS_ERR(*handle)) { + rc = PTR_ERR(*handle); + *handle = NULL; + GOTO(out_ids, rc); + } + rc = fsfilt_set_md(obd, inode, *handle, lmm, lmm_size); lmm_buf = lustre_msg_buf(req->rq_repmsg, offset, 0); lmm_bufsize = req->rq_repmsg->buflens[offset]; @@ -588,6 +597,10 @@ static void reconstruct_open(struct mds_update_record *rec, int offset, GOTO(out_dput, req->rq_status = -ENOMEM); } put_child = 0; + } else { + body->handle.cookie = mfd->mfd_handle.h_cookie; + CDEBUG(D_INODE, "resend mfd %p, cookie "LPX64"\n", mfd, + mfd->mfd_handle.h_cookie); } out_dput: @@ -928,7 +941,10 @@ int mds_open(struct mds_update_record *rec, int offset, if (rc) CERROR("error on parent setattr: rc = %d\n", rc); - acc_mode = 0; /* Don't check for permissions */ + rc = mds_finish_transno(mds, dchild->d_inode, handle, req, 0, + rep ? rep->lock_policy_res1 : 0); + handle = NULL; + acc_mode = 0; /* Don't check for permissions */ } LASSERT(!mds_inode_is_orphan(dchild->d_inode)); @@ -1039,14 +1055,15 @@ int mds_mfd_close(struct ptlrpc_request *req, struct obd_device *obd, void *handle = NULL; struct mds_body *request_body = NULL, *reply_body = NULL; struct dentry_params dp; + struct iattr iattr = { 0 }; ENTRY; - if (req != NULL) { + if (req && req->rq_reqmsg != NULL) request_body = lustre_msg_buf(req->rq_reqmsg, 0, sizeof(*request_body)); + if (req && req->rq_repmsg != NULL) reply_body = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*reply_body)); - } fidlen = ll_fid2str(fidname, inode->i_ino, inode->i_generation); @@ -1081,7 +1098,7 @@ int mds_mfd_close(struct ptlrpc_request *req, struct obd_device *obd, LASSERT(pending_child->d_inode != NULL); cleanup_phase = 2; /* dput(pending_child) when finished */ - if (req != NULL) { + if (req != NULL && req->rq_repmsg != NULL) { lmm = lustre_msg_buf(req->rq_repmsg, 1, 0); stripe_count = le32_to_cpu(lmm->lmm_stripe_count); } @@ -1094,7 +1111,8 @@ int mds_mfd_close(struct ptlrpc_request *req, struct obd_device *obd, GOTO(cleanup, rc); } - if (req != NULL && (reply_body->valid & OBD_MD_FLEASIZE) && + if (req != NULL && req->rq_repmsg != NULL && + (reply_body->valid & OBD_MD_FLEASIZE) && mds_log_op_unlink(obd, pending_child->d_inode, lmm, req->rq_repmsg->buflens[1], lustre_msg_buf(req->rq_repmsg, 2, 0), @@ -1111,32 +1129,60 @@ int mds_mfd_close(struct ptlrpc_request *req, struct obd_device *obd, rc = vfs_unlink(pending_dir, pending_child); if (rc) CERROR("error unlinking orphan %s: rc %d\n",fidname,rc); - } else if (mfd->mfd_mode & FMODE_WRITE && rc == 0) { + + goto out; /* Don't bother updating attrs on unlinked inode */ + } + + if (request_body != NULL && mfd->mfd_mode & FMODE_WRITE && rc == 0) { /* Update the on-disk attributes if this was the last write * close, and all information was provided (i.e., rc == 0) * * XXX this should probably be abstracted with mds_reint_setattr */ + #if 0 - struct iattr iattr; + if (request_body->valid & OBD_MD_FLMTIME && + LTIME_S(iattr.ia_mtime) > LTIME_S(inode->i_mtime)) { + LTIME_S(iattr.ia_mtime) = request_body->mtime; + iattr.ia_valid |= ATTR_MTIME; + } + if (request_body->valid & OBD_MD_FLCTIME && + LTIME_S(iattr.ia_ctime) > LTIME_S(inode->i_ctime)) { + LTIME_S(iattr.ia_ctime) = request_body->ctime; + iattr.ia_valid |= ATTR_CTIME; + } /* XXX can't set block count with fsfilt_setattr (!) */ - iattr.ia_valid = ATTR_CTIME | ATTR_ATIME | - ATTR_MTIME | ATTR_SIZE; - iattr.ia_atime = request_body->atime; - iattr.ia_ctime = request_body->ctime; - iattr.ia_mtime = request_body->mtime; - iattr.ia_size = request_body->size; + if (request_body->valid & OBD_MD_FLSIZE) { + iattr.ia_valid |= ATTR_SIZE; + iattr.ia_size = request_body->size; + } /* iattr.ia_blocks = request_body->blocks */ +#endif + } + if (request_body != NULL && request_body->valid & OBD_MD_FLATIME) { + /* Only start a transaction to write out only the atime if + * it is more out-of-date than the specified limit. If we + * are already going to write out the atime then do it anyway. + * */ + LTIME_S(iattr.ia_atime) = request_body->atime; + if ((LTIME_S(iattr.ia_atime) > + LTIME_S(inode->i_atime) + MAX_ATIME_DIFF) || + (iattr.ia_valid != 0 && + LTIME_S(iattr.ia_atime) > LTIME_S(inode->i_atime))) + iattr.ia_valid |= ATTR_ATIME; + } + + if (iattr.ia_valid != 0) { handle = fsfilt_start(obd, inode, FSFILT_OP_SETATTR, NULL); if (IS_ERR(handle)) GOTO(cleanup, rc = PTR_ERR(handle)); rc = fsfilt_setattr(obd, mfd->mfd_dentry, handle, &iattr, 0); if (rc) CERROR("error in setattr(%s): rc %d\n", fidname, rc); -#endif } +out: /* If other clients have this file open for write, rc will be > 0 */ if (rc > 0) rc = 0; @@ -1145,7 +1191,7 @@ int mds_mfd_close(struct ptlrpc_request *req, struct obd_device *obd, cleanup: atomic_dec(&mds->mds_open_count); - if (req) { + if (req != NULL && reply_body != NULL) { rc = mds_finish_transno(mds, pending_dir, handle, req, rc, 0); } else if (handle) { int err = fsfilt_commit(obd, pending_dir, handle, 0); @@ -1218,17 +1264,16 @@ int mds_close(struct ptlrpc_request *req) spin_unlock(&med->med_open_lock); push_ctxt(&saved, &obd->obd_ctxt, NULL); - req->rq_status = mds_mfd_close(rc ? NULL : req, obd, mfd, 1); + req->rq_status = mds_mfd_close(req, obd, mfd, 1); pop_ctxt(&saved, &obd->obd_ctxt, NULL); + mds_mfd_put(mfd); if (OBD_FAIL_CHECK(OBD_FAIL_MDS_CLOSE_PACK)) { CERROR("test case OBD_FAIL_MDS_CLOSE_PACK\n"); req->rq_status = -ENOMEM; - mds_mfd_put(mfd); RETURN(-ENOMEM); } - mds_mfd_put(mfd); RETURN(0); } diff --git a/lustre/obdclass/class_obd.c b/lustre/obdclass/class_obd.c index 0c4ab42..03b1024 100644 --- a/lustre/obdclass/class_obd.c +++ b/lustre/obdclass/class_obd.c @@ -645,8 +645,8 @@ static void cleanup_obdclass(void) /* Check that we're building against the appropriate version of the Lustre * kernel patch */ #include -#define LUSTRE_MIN_VERSION 28 -#define LUSTRE_MAX_VERSION 35 +#define LUSTRE_MIN_VERSION 32 +#define LUSTRE_MAX_VERSION 36 #if (LUSTRE_KERNEL_VERSION < LUSTRE_MIN_VERSION) # error Cannot continue: Your Lustre kernel patch is older than the sources #elif (LUSTRE_KERNEL_VERSION > LUSTRE_MAX_VERSION) diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c index 2ab2652..acd507e 100644 --- a/lustre/obdfilter/filter.c +++ b/lustre/obdfilter/filter.c @@ -1204,6 +1204,10 @@ int filter_common_setup(struct obd_device *obd, obd_count len, void *buf, if (rc) GOTO(err_mntput, rc); + + filter->fo_destroy_in_progress = 0; + sema_init(&filter->fo_create_lock, 1); + spin_lock_init(&filter->fo_translock); spin_lock_init(&filter->fo_objidlock); INIT_LIST_HEAD(&filter->fo_export_list); @@ -1574,7 +1578,8 @@ struct dentry *__filter_oa2dentry(struct obd_device *obd, } if (dchild->d_inode == NULL) { - CERROR("%s on non-existent object: "LPU64"\n", what, oa->o_id); + CERROR("%s: %s on non-existent object: "LPU64"\n", + obd->obd_name, what, oa->o_id); f_dput(dchild); RETURN(ERR_PTR(-ENOENT)); } @@ -1754,6 +1759,16 @@ static void filter_destroy_precreated(struct obd_export *exp, struct obdo *oa, } doa.o_mode = S_IFREG; + filter->fo_destroy_in_progress = 1; + down(&filter->fo_create_lock); + if (!filter->fo_destroy_in_progress) { + CERROR("%s: destroy_in_progress already cleared\n", + exp->exp_obd->obd_name); + up(&filter->fo_create_lock); + EXIT; + return; + } + last = filter_last_id(filter, &doa); CWARN("%s: deleting orphan objects from "LPU64" to "LPU64"\n", exp->exp_obd->obd_name, oa->o_id + 1, last); @@ -1768,6 +1783,10 @@ static void filter_destroy_precreated(struct obd_export *exp, struct obdo *oa, spin_lock(&filter->fo_objidlock); filter->fo_last_objids[doa.o_gr] = oa->o_id; spin_unlock(&filter->fo_objidlock); + + filter->fo_destroy_in_progress = 0; + up(&filter->fo_create_lock); + EXIT; } @@ -1824,12 +1843,10 @@ static int filter_should_precreate(struct obd_export *exp, struct obdo *oa, static int filter_precreate(struct obd_device *obd, struct obdo *oa, obd_gr group, int *num) { - struct dentry *dchild = NULL; + struct dentry *dchild = NULL, *dparent = NULL; struct filter_obd *filter; - struct dentry *dparent; - int err = 0, rc = 0, i; + int err = 0, rc = 0, recreate_obj = 0, i; __u64 next_id; - int recreate_obj = 0; void *handle = NULL; ENTRY; @@ -1840,11 +1857,19 @@ static int filter_precreate(struct obd_device *obd, struct obdo *oa, recreate_obj = 1; } - CDEBUG(D_HA, "%s: precreating %d objects\n", obd->obd_name, *num); + CDEBUG(D_HA, "%s: precreating %d objects\n", obd->obd_name, *num); + + down(&filter->fo_create_lock); for (i = 0; i < *num && err == 0; i++) { int cleanup_phase = 0; + if (filter->fo_destroy_in_progress) { + CWARN("%s: precreate aborted by destroy\n", + obd->obd_name); + break; + } + if (recreate_obj) { __u64 last_id; next_id = oa->o_id; @@ -1853,7 +1878,7 @@ static int filter_precreate(struct obd_device *obd, struct obdo *oa, CERROR("Error: Trying to recreate obj greater" "than last id "LPD64" > "LPD64"\n", next_id, last_id); - RETURN(-EINVAL); + GOTO(cleanup, rc = -EINVAL); } } else next_id = filter_last_id(filter, oa) + 1; @@ -1878,13 +1903,13 @@ static int filter_precreate(struct obd_device *obd, struct obdo *oa, if (recreate_obj) { CERROR("%s: Serious error: recreating obj %*s " "but obj already exists \n", - obd->obd_name, dchild->d_name.len, + obd->obd_name, dchild->d_name.len, dchild->d_name.name); LBUG(); } else { CERROR("%s: Serious error: objid %*s already " "exists; is this filesystem corrupt?\n", - obd->obd_name, dchild->d_name.len, + obd->obd_name, dchild->d_name.len, dchild->d_name.name); LBUG(); } @@ -1933,10 +1958,12 @@ static int filter_precreate(struct obd_device *obd, struct obdo *oa, } *num = i; + up(&filter->fo_create_lock); + CDEBUG(D_HA, "%s: server last_objid for group "LPU64": "LPU64"\n", obd->obd_name, group, filter->fo_last_objids[group]); - CDEBUG(D_HA, "%s: filter_precreate() created %d objects\n", + CDEBUG(D_HA, "%s: filter_precreate() created %d objects\n", obd->obd_name, i); RETURN(rc); } diff --git a/lustre/osc/lproc_osc.c b/lustre/osc/lproc_osc.c index 88b4d2a..078d0d1 100644 --- a/lustre/osc/lproc_osc.c +++ b/lustre/osc/lproc_osc.c @@ -108,14 +108,13 @@ int osc_rd_max_dirty_mb(char *page, char **start, off_t off, int count, { struct obd_device *dev = data; struct client_obd *cli = &dev->u.cli; - int val; - int rc; + unsigned val; spin_lock(&cli->cl_loi_list_lock); val = cli->cl_dirty_max >> 20; - rc = snprintf(page, count, "%d\n", val); spin_unlock(&cli->cl_loi_list_lock); - return rc; + + return snprintf(page, count, "%u\n", val); } int osc_wr_max_dirty_mb(struct file *file, const char *buffer, diff --git a/lustre/osc/osc_create.c b/lustre/osc/osc_create.c index 033b490..407b0bf 100644 --- a/lustre/osc/osc_create.c +++ b/lustre/osc/osc_create.c @@ -164,7 +164,7 @@ static int oscc_wait_for_objects(struct osc_creator *oscc, int count) spin_unlock(&oscc->oscc_lock); osc_invalid = oscc->oscc_obd->u.cli.cl_import->imp_invalid; - + return have_objs || ost_full || osc_invalid; } @@ -260,24 +260,23 @@ int osc_create(struct obd_export *exp, struct obdo *oa, it is finished before we can continue with create. */ if (oscc_recovering(oscc)) { struct l_wait_info lwi; - + CDEBUG(D_HA,"%p: oscc recovery in progress, waiting\n", oscc); - - lwi = LWI_TIMEOUT(MAX(obd_timeout * HZ, 1), NULL, NULL); - rc = l_wait_event(oscc->oscc_waitq, + + lwi = LWI_TIMEOUT(MAX(obd_timeout*HZ/4, 1), NULL, NULL); + rc = l_wait_event(oscc->oscc_waitq, !oscc_recovering(oscc), &lwi); LASSERT(rc == 0 || rc == -ETIMEDOUT); if (rc == -ETIMEDOUT) { - CDEBUG(D_HA, "%p: timed out waiting for " - "recovery\n", + CDEBUG(D_HA,"%p: timeout waiting on recovery\n", oscc); RETURN(rc); } CDEBUG(D_HA, "%p: oscc recovery over, waking up\n", oscc); } - + spin_lock(&oscc->oscc_lock); if (oscc->oscc_last_id >= oscc->oscc_next_id) { memcpy(oa, &oscc->oscc_oa, sizeof(*oa)); diff --git a/lustre/portals/knals/qswnal/qswnal.c b/lustre/portals/knals/qswnal/qswnal.c index 3b3b5d4..9fbc0c3 100644 --- a/lustre/portals/knals/qswnal/qswnal.c +++ b/lustre/portals/knals/qswnal/qswnal.c @@ -114,7 +114,7 @@ kqswnal_yield( nal_t *nal ) { CDEBUG (D_NET, "yield\n"); - if (current->need_resched) + if (need_resched()) schedule(); return; } @@ -793,8 +793,7 @@ kqswnal_initialise (void) /**********************************************************************/ /* Spawn scheduling threads */ - for (i = 0; i < smp_num_cpus; i++) - { + for (i = 0; i < num_online_cpus(); i++) { rc = kqswnal_thread_start (kqswnal_scheduler, NULL); if (rc != 0) { diff --git a/lustre/portals/knals/qswnal/qswnal.h b/lustre/portals/knals/qswnal/qswnal.h index bedc6e0..2849a29 100644 --- a/lustre/portals/knals/qswnal/qswnal.h +++ b/lustre/portals/knals/qswnal/qswnal.h @@ -18,7 +18,7 @@ * along with Lustre; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * Basic library routines. + * Basic library routines. * */ @@ -53,7 +53,11 @@ #include #include #include -#include +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +#include /* wait_on_buffer */ +#else +#include /* wait_on_buffer */ +#endif #include #include #include diff --git a/lustre/portals/knals/qswnal/qswnal_cb.c b/lustre/portals/knals/qswnal/qswnal_cb.c index 731357e..6bff730 100644 --- a/lustre/portals/knals/qswnal/qswnal_cb.c +++ b/lustre/portals/knals/qswnal/qswnal_cb.c @@ -1821,7 +1821,7 @@ kqswnal_scheduler (void *arg) !list_empty(&kqswnal_data.kqn_delayedtxds) || !list_empty(&kqswnal_data.kqn_delayedfwds)); LASSERT (rc == 0); - } else if (current->need_resched) + } else if (need_resched()) schedule (); spin_lock_irqsave (&kqswnal_data.kqn_sched_lock, flags); diff --git a/lustre/tests/fsx.c b/lustre/tests/fsx.c index c87cd6a..ead1c85 100644 --- a/lustre/tests/fsx.c +++ b/lustre/tests/fsx.c @@ -154,15 +154,20 @@ warn(const char * fmt, ...) void +__attribute__((format(printf, 1, 2))) prt(char *fmt, ...) { va_list args; va_start(args, fmt); vfprintf(stdout, fmt, args); - if (fsxlogf) - vfprintf(fsxlogf, fmt, args); va_end(args); + + if (fsxlogf) { + va_start(args, fmt); + vfprintf(fsxlogf, fmt, args); + va_end(args); + } } void @@ -545,31 +550,41 @@ alloc_tf_buf(void) int len; len = snprintf(&dummy, 0, "%u ", highest); - if (len < 0) { + if (len < 1) { prterr("finding max tf_buf"); exit(1); } - tf_buf = malloc(len + 1); + len++; + tf_buf = malloc(len); if (tf_buf == NULL) { prterr("allocating tf_buf"); exit(1); } - max_tf_len = sprintf(tf_buf, "%u ", highest); + max_tf_len = snprintf(tf_buf, len, "%u ", highest); + if (max_tf_len < 1) { + prterr("fiding max_tv_len\n"); + exit(1); + } + if (max_tf_len != len - 1) { + warn("snprintf() gave %d instead of %d?\n", + max_tf_len, len - 1); + exit(1); + } } -char * +char * fill_tf_buf(struct test_file *tf) { if (tf_buf == NULL) alloc_tf_buf(); - sprintf(tf_buf,"%u ", (int)(tf - test_files)); + sprintf(tf_buf,"%lu ", (unsigned long)(tf - test_files)); return tf_buf; } void -output_line(struct test_file *tf, int op, unsigned long offset, - unsigned long size, struct timeval *tv) +output_line(struct test_file *tf, int op, unsigned offset, + unsigned size, struct timeval *tv) { char *tf_num = ""; @@ -953,8 +968,9 @@ writefileimage() if (iret == -1) prterr("writefileimage: write"); else - prt("short write: 0x%x bytes instead of 0x%llx\n", - iret, (unsigned long long)file_size); + prt("short write: 0x%lx bytes instead of 0x%llx\n", + (unsigned long)iret, + (unsigned long long)file_size); report_failure(172); } if (lite ? 0 : ftruncate(fd, file_size) == -1) { diff --git a/lustre/tests/insanity.sh b/lustre/tests/insanity.sh index 93a6e56..6200733 100755 --- a/lustre/tests/insanity.sh +++ b/lustre/tests/insanity.sh @@ -10,7 +10,7 @@ init_test_env $@ . ${CONFIG:=$LUSTRE/tests/cfg/insanity-local.sh} -ALWAYS_EXCEPT="10" +ALWAYS_EXCEPT="0 10" build_test_filter @@ -137,7 +137,7 @@ setup() { wait_for mds start mds $MDSLCONFARGS ${REFORMAT} while ! do_node $CLIENTS "ls -d $LUSTRE" > /dev/null; do sleep 5; done - zconf_mount $CLIENTS $MOUNT + grep " $MOUNT " /proc/mounts || zconf_mount $CLIENTS $MOUNT } diff --git a/lustre/tests/replay-single.sh b/lustre/tests/replay-single.sh index 9a29ec7..5786fde 100755 --- a/lustre/tests/replay-single.sh +++ b/lustre/tests/replay-single.sh @@ -889,6 +889,7 @@ test_45() { multiop $DIR/$tfile O_c & pid=$! + sleep 1 # allow the open to complete usleep 500 @@ -908,6 +909,17 @@ test_45() { } run_test 45 "Handle failed close" +test_46() { + dmesg -c >/dev/null + drop_reply "touch $DIR/$tfile" + fail mds + # ironically, the previous test, 45, will cause a real forced close, + # so just look for one for this test + dmesg | grep -i "force closing client file handle for $tfile" && return 1 + return 0 +} +run_test 46 "Don't leak file handle after open resend (3325)" + equals_msg test complete, cleaning up $CLEANUP diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 60f4805..818b49b 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -7,11 +7,11 @@ set -e ONLY=${ONLY:-"$*"} -# bug number for skipped test: -ALWAYS_EXCEPT=${ALWAYS_EXCEPT:-""} +# bug number for skipped test: 2108 +ALWAYS_EXCEPT=${ALWAYS_EXCEPT:-"42a"} # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT! case `uname -r` in -2.6.*) ALWAYS_EXCEPT="$ALWAYS_EXCEPT 54c" # bug 3117 +2.6.*) ALWAYS_EXCEPT="$ALWAYS_EXCEPT 54c 55" # bug 3117 esac [ "$ALWAYS_EXCEPT$EXCEPT" ] && echo "Skipping tests: $ALWAYS_EXCEPT $EXCEPT" @@ -71,6 +71,25 @@ log() { lctl mark "$*" 2> /dev/null || true } +trace() { + log "STARTING: $*" + strace -o $TMP/$1.strace -ttt $* + RC=$? + log "FINISHED: $*: rc $RC" + return 1 +} +TRACE=${TRACE:-""} + +check_kernel_version() { + VERSION_FILE=/proc/fs/lustre/kernel_version + WANT_VER=$1 + [ ! -f $VERSION_FILE ] && echo "can't find kernel version" && return 1 + GOT_VER=`cat $VERSION_FILE` + [ $GOT_VER -ge $WANT_VER ] && return 0 + log "test needs at least kernel version $WANT_VER, running $GOT_VER" + return 1 +} + run_one() { if ! mount | grep -q $DIR; then $START @@ -1190,7 +1209,7 @@ test_36d() { run_test 36d "non-root OST utime check (open, utime) ===========" test_36e() { - [ $RUNAS_ID -eq $UID ] && return + [ $RUNAS_ID -eq $UID ] && echo "skipping test 36e" && return [ ! -d $DIR/d36 ] && mkdir $DIR/d36 touch $DIR/d36/f36e $RUNAS utime $DIR/d36/f36e && error "utime worked, want failure" || true @@ -1513,7 +1532,8 @@ test_47() { run_test 47 "Device nodes check ================================" test_48a() { # bug 2399 - mkdir $DIR/d48a + check_kernel_version 34 || return 0 + mkdir -p $DIR/d48a cd $DIR/d48a mv $DIR/d48a $DIR/d48.new || error "move directory failed" mkdir $DIR/d48a || error "recreate directory failed" @@ -1525,24 +1545,65 @@ test_48a() { # bug 2399 mkdir . && error "'mkdir .' worked after recreating cwd" rmdir . && error "'rmdir .' worked after recreating cwd" ln -s . baz || error "'ln -s .' failed after recreating cwd" + cd .. || error "'cd ..' failed after recreating cwd" } run_test 48a "Access renamed working dir (should return errors)=" test_48b() { # bug 2399 - mkdir $DIR/d48b + check_kernel_version 34 || return 0 + mkdir -p $DIR/d48b cd $DIR/d48b rmdir $DIR/d48b || error "remove cwd $DIR/d48b failed" touch foo && error "'touch foo' worked after removing cwd" mkdir foo && error "'mkdir foo' worked after removing cwd" ls . && error "'ls .' worked after removing cwd" ls .. || error "'ls ..' failed after removing cwd" - cd . && error "'cd .' worked after recreate cwd" + cd . && error "'cd .' worked after removing cwd" mkdir . && error "'mkdir .' worked after removing cwd" rmdir . && error "'rmdir .' worked after removing cwd" ln -s . foo && error "'ln -s .' worked after removing cwd" || true + cd .. || error "'cd ..' failed after removing cwd" } run_test 48b "Access removed working dir (should return errors)=" +test_48c() { # bug 2350 + check_kernel_version 36 || return 0 + #sysctl -w portals.debug=-1 + #set -vx + mkdir -p $DIR/d48c/dir + cd $DIR/d48c/dir + rmdir $DIR/d48c/dir || error "remove cwd $DIR/d48c/dir failed" + $TRACE touch foo && error "'touch foo' worked after removing cwd" + $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd" + $TRACE ls . && error "'ls .' worked after removing cwd" + $TRACE ls .. || error "'ls ..' failed after removing cwd" + $TRACE cd . && error "'cd .' worked after removing cwd" + $TRACE mkdir . && error "'mkdir .' worked after removing cwd" + $TRACE rmdir . && error "'rmdir .' worked after removing cwd" + $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd" ||true + $TRACE cd .. || error "'cd ..' failed after removing cwd" +} +run_test 48c "Access removed working subdir (should return errors)" + +test_48d() { # bug 2350 + check_kernel_version 36 || return 0 + #sysctl -w portals.debug=-1 + #set -vx + mkdir -p $DIR/d48d/dir + cd $DIR/d48d/dir + rm -r $DIR/d48d || error "remove cwd and parent $DIR/d48d failed" + $TRACE touch foo && error "'touch foo' worked after removing cwd" + $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd" + $TRACE ls . && error "'ls .' worked after removing cwd" + $TRACE ls .. && error "'ls ..' worked after removing cwd" + $TRACE cd . && error "'cd .' worked after recreate cwd" + $TRACE mkdir . && error "'mkdir .' worked after removing cwd" + $TRACE rmdir . && error "'rmdir .' worked after removing cwd" + $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd" ||true + $TRACE cd .. && error "'cd ..' worked after recreate cwd" || true +} +run_test 48d "Access removed parent subdir (should return errors)" + test_50() { # bug 1485 mkdir $DIR/d50 @@ -1670,13 +1731,13 @@ run_test 54d "fifo device works in lustre ======================" test_55() { rm -rf $DIR/d55 mkdir $DIR/d55 - mount -t ext3 -o loop,iopen $EXT3_DEV $DIR/d55 || error + mount -t ext3 -o loop,iopen $EXT3_DEV $DIR/d55 || error "mounting" touch $DIR/d55/foo - $IOPENTEST1 $DIR/d55/foo $DIR/d55 || error - $IOPENTEST2 $DIR/d55 || error + $IOPENTEST1 $DIR/d55/foo $DIR/d55 || error "running $IOPENTEST1" + $IOPENTEST2 $DIR/d55 || error "running $IOPENTEST2" echo "check for $EXT3_DEV. Please wait..." rm -rf $DIR/d55/* - umount $DIR/d55 || error + umount $DIR/d55 || error "unmounting" } run_test 55 "check iopen_connect_dentry() ======================" @@ -1830,7 +1891,7 @@ run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)" # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq. test_63() { - MAX_DIRTY_MB=`cat /proc/fs/lustre/osc/*/max_dirty_mb | head -1` + MAX_DIRTY_MB=`cat /proc/fs/lustre/osc/*/max_dirty_mb | head -n 1` for i in /proc/fs/lustre/osc/*/max_dirty_mb ; do echo 0 > $i done @@ -1921,6 +1982,16 @@ test_66() { } run_test 66 "update inode blocks count on client ===============" +test_67() { # bug 3285 - supplementary group fails on MDS, passes on client + [ "$RUNAS_ID" = "$UID" ] && echo "skipping test 67" && return + check_kernel_version 35 || return 0 + mkdir $DIR/d67 + chmod 771 $DIR/d67 + chgrp $RUNAS_ID $DIR/d67 + $RUNAS -g $((RUNAS_ID + 1)) -G1,2,$RUNAS_ID ls $DIR/d67 && error || true +} +run_test 67 "supplementary group failure (should return error) =" + # on the LLNL clusters, runas will still pick up root's $TMP settings, # which will not be writable for the runas user, and then you get a CVS # error message with a corrupt path string (CVS bug) and panic. diff --git a/lustre/tests/sanityN.sh b/lustre/tests/sanityN.sh index e884b73..972d548 100644 --- a/lustre/tests/sanityN.sh +++ b/lustre/tests/sanityN.sh @@ -3,8 +3,8 @@ set -e ONLY=${ONLY:-"$*"} -# bug number for skipped test: 1768 1557 -ALWAYS_EXCEPT=${ALWAYS_EXCEPT:-"4 8 14b"} +# bug number for skipped test: 1768 +ALWAYS_EXCEPT=${ALWAYS_EXCEPT:-"4 14b"} # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT! [ "$ALWAYS_EXCEPT$EXCEPT" ] && echo "Skipping tests: $ALWAYS_EXCEPT $EXCEPT" diff --git a/lustre/utils/Lustre/lustredb.py b/lustre/utils/Lustre/lustredb.py index 4ba04db..eda5779 100644 --- a/lustre/utils/Lustre/lustredb.py +++ b/lustre/utils/Lustre/lustredb.py @@ -129,6 +129,10 @@ class LustreDB_XML(LustreDB): self.dom_node = dom self.root_node = root_node + def close(self): + # do nothing + return None + def xmltext(self, dom_node, tag): list = dom_node.getElementsByTagName(tag) if len(list) > 0: diff --git a/lustre/utils/lconf b/lustre/utils/lconf index 8c2658d..7fd6c6b 100755 --- a/lustre/utils/lconf +++ b/lustre/utils/lconf @@ -537,7 +537,7 @@ class LCTLInterface: quit""" % (type, name, uuid) self.run(cmds) - def setup(self, name, setup = ""): + def setup(self, name, setup = ""): cmds = """ cfg_device %s setup %s @@ -921,15 +921,6 @@ def sys_get_local_address(net_type, wildcard, cluster_id): log(e) elif net_type == 'gm': fixme("automatic local address for GM") - elif net_type == 'scimac': - scinode="/opt/scali/sbin/scinode" - if os.path.exists(scinode): - (rc,local) = run(scinode) - else: - panic (scinode, " not found on node with scimac networking") - if rc: - panic (scinode, " failed") - local=string.rstrip(local[0]) return local @@ -1125,8 +1116,6 @@ class Network(Module): self.add_portals_module("knals/qswnal", 'kqswnal') if self.net_type == 'gm': self.add_portals_module("knals/gmnal", 'kgmnal') - if self.net_type == 'scimac': - self.add_portals_module("knals/scimacnal", 'kscimacnal') def nid_to_uuid(self, nid): return "NID_%s_UUID" %(nid,) @@ -1288,7 +1277,7 @@ class LOV(Module): self.name = "lov_%s" % name_override self.add_lustre_module('lov', 'lov') self.mds_uuid = self.db.get_first_ref('mds') - self.stripe_sz = self.db.get_val_int('stripesize', 65536) + self.stripe_sz = self.db.get_val_int('stripesize', 1048576) self.stripe_off = self.db.get_val_int('stripeoffset', 0) self.pattern = self.db.get_val_int('stripepattern', 0) self.devlist = self.db.get_refs('obd') @@ -1413,7 +1402,8 @@ class MDSDEV(Module): self.target_dev_uuid = self.uuid self.uuid = target_uuid - # modules + + # loading modules self.add_lustre_module('mdc', 'mdc') self.add_lustre_module('osc', 'osc') self.add_lustre_module('lov', 'lov') @@ -1678,9 +1668,9 @@ class OSD(Module): def mgmt_uuid_for_fs(mtpt_name): if not mtpt_name: return '' - mtpt_db = toplevel.lookup_name(mtpt_name) + mtpt_db = toplustreDB.lookup_name(mtpt_name) fs_uuid = mtpt_db.get_first_ref('filesystem') - fs = toplevel.lookup(fs_uuid) + fs = toplustreDB.lookup(fs_uuid) if not fs: return '' return fs.get_first_ref('mgmt') @@ -2265,6 +2255,7 @@ def doHost(lustreDB, hosts): prof_list = node_db.get_refs('profile') if config.write_conf: + lustreDB.close() for_each_profile(node_db, prof_list, doModules) sys_make_devices() for_each_profile(node_db, prof_list, doWriteconf) @@ -2293,6 +2284,7 @@ def doHost(lustreDB, hosts): for_each_profile(node_db, prof_list, doCleanup) for_each_profile(node_db, prof_list, doUnloadModules) + lustreDB.close() else: # ugly hack, only need to run lctl commands for --dump @@ -2323,22 +2315,24 @@ def doHost(lustreDB, hosts): sys_set_portals_upcall(portals_upcall) for_each_profile(node_db, prof_list, doSetup) + lustreDB.close() -def doRecovery(db, lctl, tgt_uuid, client_uuid, nid_uuid): - tgt = db.lookup(tgt_uuid) +def doRecovery(lustreDB, lctl, tgt_uuid, client_uuid, nid_uuid): + tgt = lustreDB.lookup(tgt_uuid) if not tgt: raise Lustre.LconfError("doRecovery: "+ tgt_uuid +" not found.") new_uuid = get_active_target(tgt) if not new_uuid: raise Lustre.LconfError("doRecovery: no active target found for: " + tgt_uuid) - net = choose_local_server(get_ost_net(db, new_uuid)) + net = choose_local_server(get_ost_net(lustreDB, new_uuid)) if not net: raise Lustre.LconfError("Unable to find a connection to:" + new_uuid) log("Reconnecting", tgt_uuid, " to ", net.nid_uuid); try: - oldnet = get_server_by_nid_uuid(db, nid_uuid) + oldnet = get_server_by_nid_uuid(lustreDB, nid_uuid) + lustreDB.close() if oldnet: lctl.disconnect(oldnet) except CommandError, e: @@ -2585,7 +2579,7 @@ lconf_options = [ ] def main(): - global lctl, config, toplevel, CONFIG_FILE + global lctl, config, toplustreDB, CONFIG_FILE # in the upcall this is set to SIG_IGN signal.signal(signal.SIGCHLD, signal.SIG_DFL) @@ -2637,8 +2631,9 @@ def main(): except Exception: panic("%s does not appear to be a config file." % (args[0])) sys.exit(1) # make sure to die here, even in debug mode. + config_file.close() CONFIG_FILE = args[0] - db = Lustre.LustreDB_XML(dom.documentElement, dom.documentElement) + lustreDB = Lustre.LustreDB_XML(dom.documentElement, dom.documentElement) if not config.config: config.config = os.path.basename(args[0])# use full path? if config.config[-4:] == '.xml': @@ -2647,7 +2642,7 @@ def main(): if not config.config: panic("--ldapurl requires --config name") dn = "config=%s,fs=lustre" % (config.config) - db = Lustre.LustreDB_LDAP('', {}, base=dn, url = config.ldapurl) + lustreDB = Lustre.LustreDB_LDAP('', {}, base=dn, url = config.ldapurl) elif config.ptldebug or config.subsystem: sys_set_ptldebug(None) sys_set_subsystem(None) @@ -2657,9 +2652,9 @@ def main(): print 'see lconf --help for command summary' sys.exit(1) - toplevel = db + toplustreDB = lustreDB - ver = db.get_version() + ver = lustreDB.get_version() if not ver: panic("No version found in config data, please recreate.") if ver != Lustre.CONFIG_VERSION: @@ -2691,7 +2686,7 @@ def main(): lctl.clear_log(config.record_device, config.record_log) lctl.record(config.record_device, config.record_log) - doHost(db, node_list) + doHost(lustreDB, node_list) if config.record: lctl.end_record() diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index 658a921..91fd24e 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -113,7 +113,7 @@ static int lfs_setstripe(int argc, char **argv) return CMD_HELP; } - result = op_create_file(argv[1], st_size, st_offset, st_count); + result = llapi_file_create(argv[1], st_size, st_offset, st_count, 0); if (result) fprintf(stderr, "error: %s: create stripe file failed\n", argv[0]); @@ -174,7 +174,7 @@ static int lfs_find(int argc, char **argv) return CMD_HELP; do { - rc = op_find(argv[optind], obduuid, recursive, verbose, quiet); + rc = llapi_find(argv[optind], obduuid, recursive,verbose,quiet); } while (++optind < argc && !rc); if (rc) @@ -193,7 +193,7 @@ static int lfs_getstripe(int argc, char **argv) optind = 1; do { - rc = op_find(argv[optind], obduuid, 0, 0, 0); + rc = llapi_find(argv[optind], obduuid, 0, 0, 0); } while (++optind < argc && !rc); if (rc) @@ -222,10 +222,11 @@ static int lfs_osts(int argc, char **argv) mnt = getmntent(fp); while (feof(fp) == 0 && ferror(fp) ==0) { if (llapi_is_lustre_mnttype(mnt->mnt_type)) { - rc = op_find(mnt->mnt_dir, obduuid, 0, 0, 0); + rc = llapi_find(mnt->mnt_dir, obduuid, 0, 0, 0); if (rc) - fprintf(stderr, "error: lfs osts failed for %s\n", - mnt->mnt_dir); + fprintf(stderr, + "error: lfs osts failed on %s\n", + mnt->mnt_dir); } mnt = getmntent(fp); } @@ -240,25 +241,25 @@ static int lfs_check(int argc, char **argv) int rc; FILE *fp; struct mntent *mnt = NULL; - int type_num = 1; - char *obd_type_p[2]; + int num_types = 1; + char *obd_types[2]; char obd_type1[4]; char obd_type2[4]; if (argc != 2) return CMD_HELP; - obd_type_p[1]=obd_type1; - obd_type_p[2]=obd_type2; - - if (strcmp(argv[1],"osts")==0) { - strcpy(obd_type_p[0],"osc"); - } else if (strcmp(argv[1],"mds")==0) { - strcpy(obd_type_p[0],"mdc"); - } else if (strcmp(argv[1],"servers")==0) { - type_num=2; - strcpy(obd_type_p[0],"osc"); - strcpy(obd_type_p[1],"mdc"); + obd_types[1] = obd_type1; + obd_types[2] = obd_type2; + + if (strcmp(argv[1], "osts") == 0) { + strcpy(obd_types[0], "osc"); + } else if (strcmp(argv[1], "mds") == 0) { + strcpy(obd_types[0], "mdc"); + } else if (strcmp(argv[1], "servers") == 0) { + num_types = 2; + strcpy(obd_types[0], "osc"); + strcpy(obd_types[1], "mdc"); } else { fprintf(stderr, "error: %s: option '%s' unrecognized\n", argv[0], argv[1]); @@ -279,7 +280,7 @@ static int lfs_check(int argc, char **argv) endmntent(fp); } - rc = op_check(type_num,obd_type_p,mnt->mnt_dir); + rc = llapi_target_check(num_types, obd_types, mnt->mnt_dir); if (rc) fprintf(stderr, "error: %s: %s status failed\n", @@ -317,9 +318,9 @@ static int lfs_catinfo(int argc, char **argv) if (mnt) { if (argc == 3) - rc = op_catinfo(mnt->mnt_dir, argv[1], argv[2]); + rc = llapi_catinfo(mnt->mnt_dir, argv[1], argv[2]); else - rc = op_catinfo(mnt->mnt_dir, argv[1], NULL); + rc = llapi_catinfo(mnt->mnt_dir, argv[1], NULL); } else { fprintf(stderr, "no lustre_lite mounted.\n"); rc = -1; diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index 254d7a0..ca1a490 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -61,17 +61,18 @@ static void err_msg(char *fmt, ...) fprintf(stderr, ": %s (%d)\n", strerror(tmp_errno), tmp_errno); } -int op_create_file(char *name, long stripe_size, int stripe_offset, - int stripe_count) +int llapi_file_create(char *name, long stripe_size, int stripe_offset, + int stripe_count, int stripe_pattern) { struct lov_user_md lum = { 0 }; int fd, rc = 0; /* Initialize IOCTL striping pattern structure */ lum.lmm_magic = LOV_USER_MAGIC; + lum.lmm_pattern = stripe_pattern; lum.lmm_stripe_size = stripe_size; - lum.lmm_stripe_offset = stripe_offset; lum.lmm_stripe_count = stripe_count; + lum.lmm_stripe_offset = stripe_offset; fd = open(name, O_CREAT | O_RDWR | O_LOV_DELAY_CREATE, 0644); if (errno == EISDIR) @@ -100,21 +101,23 @@ int op_create_file(char *name, long stripe_size, int stripe_offset, return rc; } +/* short term backwards compat only */ +int op_create_file(char *name, long stripe_size, int stripe_offset, + int stripe_count) +{ + return llapi_file_create(name, stripe_size, stripe_offset, + stripe_count, 0); +} + struct find_param { int recursive; int verbose; int quiet; struct obd_uuid *obduuid; - struct obd_ioctl_data data; - struct lov_desc desc; - int uuidslen; - char *buf; - int buflen; - struct obd_uuid *uuids; + int lumlen; struct lov_user_md *lum; int got_uuids; int obdindex; - int max_ost_count; }; /* XXX Max obds per lov currently hardcoded to 1000 in lov/lov_obd.c */ @@ -123,49 +126,15 @@ struct find_param { static int prepare_find(struct find_param *param) { - int datalen, desclen; - int cfglen, lumlen; - int max_ost_count = MAX_LOV_UUID_COUNT; - - datalen = size_round(sizeof(param->data)); - desclen = size_round(sizeof(param->desc)); - param->uuidslen = size_round(max_ost_count * sizeof(*param->uuids)); - cfglen = datalen + desclen + param->uuidslen; - lumlen = lov_mds_md_size(max_ost_count); - if (cfglen > lumlen) - param->buflen = cfglen; - else - param->buflen = lumlen; - - /* XXX max ioctl buffer size currently hardcoded to 8192 */ - if (param->buflen > 8192) { - int nuuids, remaining; - - param->buflen = 8192; - nuuids = (param->buflen - datalen - desclen) / - sizeof(*param->uuids); - param->uuidslen = size_round(nuuids * sizeof(*param->uuids)); - remaining = nuuids * sizeof(*param->uuids); - if (param->uuidslen > remaining) - nuuids--; - max_ost_count = nuuids; - while ((lumlen=lov_mds_md_size(max_ost_count)) > param->buflen) - --max_ost_count; - - cfglen = datalen + desclen + param->uuidslen; - } - - if ((param->buf = malloc(param->buflen)) == NULL) { - err_msg("unable to allocate %d bytes of memory for ioctl's", - param->buflen); + param->lumlen = lov_mds_md_size(MAX_LOV_UUID_COUNT); + if ((param->lum = malloc(param->lumlen)) == NULL) { + err_msg("unable to allocate %d bytes of memory for ioctl", + param->lumlen); return ENOMEM; } - param->lum = (struct lov_user_md *)param->buf; - param->uuids = (struct obd_uuid *)param->buf; param->got_uuids = 0; param->obdindex = OBD_NOT_FOUND; - param->max_ost_count = max_ost_count; return 0; } @@ -174,48 +143,72 @@ static void cleanup_find(struct find_param *param) { if (param->obduuid) free(param->obduuid); - if (param->buf) - free(param->buf); + if (param->lum) + free(param->lum); } -static int get_obd_uuids(DIR *dir, char *dname, struct find_param *param) +int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, int *ost_count) { - int obdcount; - struct obd_uuid *uuidp; - int rc, i; - - param->got_uuids = 1; - memset(¶m->data, 0, sizeof(param->data)); - param->data.ioc_inllen1 = sizeof(struct lov_desc); - param->data.ioc_inlbuf1 = (char *)¶m->desc; - param->data.ioc_inllen2 = param->uuidslen; - param->data.ioc_inlbuf2 = (char *)param->uuids; - - memset(¶m->desc, 0, sizeof(struct lov_desc)); - param->desc.ld_tgt_count = param->max_ost_count; - - if (obd_ioctl_pack(¶m->data, ¶m->buf, param->buflen)) { - fprintf(stderr, "internal buffer error from %s\n", dname); - return (param->obduuid ? EINVAL : 0); + struct obd_ioctl_data data = { 0, }; + struct lov_desc desc = { 0, }; + char *buf = NULL; + int max_ost_count, rc; + + max_ost_count = (OBD_MAX_IOCTL_BUFFER - size_round(sizeof(data)) - + size_round(sizeof(desc))) / sizeof(*uuidp); + if (max_ost_count > *ost_count) + max_ost_count = *ost_count; + + data.ioc_inllen1 = sizeof(desc); + data.ioc_inlbuf1 = (char *)&desc; + data.ioc_inllen2 = size_round(max_ost_count * sizeof(*uuidp)); + data.ioc_inlbuf2 = (char *)uuidp; + + desc.ld_tgt_count = max_ost_count; + + if (obd_ioctl_pack(&data, &buf, OBD_MAX_IOCTL_BUFFER)) { + fprintf(stderr, "internal buffer error packing\n"); + rc = EINVAL; + goto out; } - rc = ioctl(dirfd(dir), OBD_IOC_LOV_GET_CONFIG, param->buf); + rc = ioctl(fd, OBD_IOC_LOV_GET_CONFIG, buf); if (rc) { - err_msg("error getting LOV config from %s", dname); - return (param->obduuid ? errno : 0); + err_msg("error getting LOV config"); + rc = errno; + goto out; } - if (obd_ioctl_unpack(¶m->data, param->buf, param->buflen)) { - err_msg("invalid reply from ioctl from %s", dname); - return (param->obduuid ? EINVAL : 0); + if (obd_ioctl_unpack(&data, buf, OBD_MAX_IOCTL_BUFFER)) { + fprintf(stderr, "invalid reply from ioctl"); + rc = EINVAL; + goto out; } - obdcount = param->desc.ld_tgt_count; + *ost_count = desc.ld_tgt_count; +out: + free(buf); + + return 0; +} + +static int setup_obd_uuids(DIR *dir, char *dname, struct find_param *param) +{ + struct obd_uuid uuids[1024], *uuidp; + int obdcount = 1024; + int rc, i; + + param->got_uuids = 1; + + rc = llapi_lov_get_uuids(dirfd(dir), uuids, &obdcount); + if (rc != 0) + return (param->obduuid ? rc : 0); + if (obdcount == 0) return 0; if (param->obduuid) { - for (i = 0, uuidp = param->uuids; i < obdcount; i++, uuidp++) { + for (i = 0, uuidp = uuids; i < obdcount; i++, uuidp++) { if (strncmp(param->obduuid->uuid, uuidp->uuid, sizeof(*uuidp)) == 0) { param->obdindex = i; @@ -228,7 +221,7 @@ static int get_obd_uuids(DIR *dir, char *dname, struct find_param *param) } } else if (!param->quiet) { printf("OBDS:\n"); - for (i = 0, uuidp = param->uuids; i < obdcount; i++, uuidp++) + for (i = 0, uuidp = uuids; i < obdcount; i++, uuidp++) printf("%4d: %s\n", i, uuidp->uuid); } @@ -289,7 +282,7 @@ void lov_dump_user_lmm_v1(struct lov_user_md_v1 *lum, char *dname, char *fname, } } -void lov_dump_user_lmm(struct find_param *param, char *dname, char *fname) +void llapi_lov_dump_user_lmm(struct find_param *param, char *dname, char *fname) { switch(*(__u32 *)param->lum) { /* lum->lmm_magic */ case LOV_USER_MAGIC_V1: @@ -303,7 +296,7 @@ void lov_dump_user_lmm(struct find_param *param, char *dname, char *fname) } } -int get_file_stripe(char *path, struct lov_user_md *lum) +int llapi_file_get_stripe(char *path, struct lov_user_md *lum) { char *dname, *fname; int fd, rc = 0; @@ -346,12 +339,18 @@ int get_file_stripe(char *path, struct lov_user_md *lum) return rc; } +/* short term backwards compat only */ +int op_get_file_stripe(char *path, struct lov_user_md *lum) +{ + return llapi_file_get_stripe(path, lum); +} + static int process_file(DIR *dir, char *dname, char *fname, struct find_param *param) { int rc; - strncpy((char *)param->lum, fname, param->buflen); + strncpy((char *)param->lum, fname, param->lumlen); rc = ioctl(dirfd(dir), IOC_MDC_GETSTRIPE, (void *)param->lum); if (rc) { @@ -373,7 +372,7 @@ static int process_file(DIR *dir, char *dname, char *fname, return rc; } - lov_dump_user_lmm(param, dname, fname); + llapi_lov_dump_user_lmm(param, dname, fname); return 0; } @@ -407,13 +406,13 @@ static int process_dir(DIR *dir, char *dname, struct find_param *param) int rc; if (!param->got_uuids) { - rc = get_obd_uuids(dir, dname, param); + rc = setup_obd_uuids(dir, dname, param); if (rc) return rc; } /* retrieve dir's stripe info */ - strncpy((char *)param->lum, dname, param->buflen); + strncpy((char *)param->lum, dname, param->lumlen); rc = ioctl(dirfd(dir), LL_IOC_LOV_GETSTRIPE, (void *)param->lum); if (rc) { if (errno == ENODATA) { @@ -425,7 +424,7 @@ static int process_dir(DIR *dir, char *dname, struct find_param *param) return errno; } } else { - lov_dump_user_lmm(param, dname, ""); + llapi_lov_dump_user_lmm(param, dname, ""); } /* Handle the contents of the directory */ @@ -513,7 +512,7 @@ static int process_path(char *path, struct find_param *param) rc = errno; } else { if (!param->got_uuids) - rc = get_obd_uuids(dir, dname, param); + rc = setup_obd_uuids(dir, dname, param); if (rc == 0) rc = process_file(dir, dname, fname, param); closedir(dir); @@ -523,9 +522,8 @@ static int process_path(char *path, struct find_param *param) return rc; } - -int op_find(char *path, struct obd_uuid *obduuid, int recursive, - int verbose, int quiet) +int llapi_find(char *path, struct obd_uuid *obduuid, int recursive, + int verbose, int quiet) { struct find_param param; int ret = 0; @@ -556,7 +554,7 @@ out: #define MAX_STRING_SIZE 128 #define DEVICES_LIST "/proc/fs/lustre/devices" -int op_check(int type_num, char **obd_type, char *dir) +int llapi_target_check(int type_num, char **obd_type, char *dir) { char buf[MAX_STRING_SIZE]; FILE *fp = fopen(DEVICES_LIST, "r"); @@ -564,8 +562,8 @@ int op_check(int type_num, char **obd_type, char *dir) int i; if (fp == NULL) { - fprintf(stderr, "error: %s could not open file " - DEVICES_LIST " .\n", strerror(rc = errno)); + fprintf(stderr, "error: %s opening "DEVICES_LIST"\n", + strerror(rc = errno)); return rc; } @@ -618,7 +616,7 @@ int op_check(int type_num, char **obd_type, char *dir) #undef MAX_STRING_SIZE -int op_catinfo(char *dir, char *keyword, char *node_name) +int llapi_catinfo(char *dir, char *keyword, char *node_name) { char raw[OBD_MAX_IOCTL_BUFFER]; char out[LLOG_CHUNK_SIZE]; diff --git a/lustre/utils/obd.c b/lustre/utils/obd.c index 3a4089a..95b9917 100644 --- a/lustre/utils/obd.c +++ b/lustre/utils/obd.c @@ -779,22 +779,21 @@ int jt_obd_list(int argc, char **argv) int rc; char buf[MAX_STRING_SIZE]; FILE *fp = fopen(DEVICES_LIST, "r"); - + if (fp == NULL) { - fprintf(stderr, "error: %s: %s could not open file " - DEVICES_LIST " .\n", + fprintf(stderr, "error: %s: %s opening "DEVICES_LIST"\n", jt_cmdname(argv[0]), strerror(rc = errno)); return rc; } - + if (argc != 1) return CMD_HELP; - + while (fgets(buf, sizeof(buf), fp) != NULL) printf("%s", buf); - + fclose(fp); - + return 0; } -- 1.8.3.1