From 7273261abac8f0ac48ebbff00a5d3171e6028f0c Mon Sep 17 00:00:00 2001 From: pravins Date: Thu, 16 Jul 2009 12:48:50 +0000 Subject: [PATCH] b=18857 i=green i=tappro fix new inode check on client. --- lustre/llite/llite_internal.h | 2 +- lustre/llite/llite_lib.c | 18 ++++++++++++++---- lustre/llite/namei.c | 42 +++++++++++++++++++++++++++++++++++++++++- lustre/tests/replay-single.sh | 2 +- 4 files changed, 57 insertions(+), 7 deletions(-) diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 767b63c..6476098 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -707,7 +707,7 @@ int ll_revalidate_it_finish(struct ptlrpc_request *request, /* llite/llite_lib.c */ extern struct super_operations lustre_super_operations; - +void ll_dump_inode(struct inode *inode); char *ll_read_opt(const char *opt, char *data); void ll_lli_init(struct ll_inode_info *lli); int ll_fill_super(struct super_block *sb); diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 91d35fa..e8fef82 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -530,16 +530,26 @@ int ll_get_max_mdsize(struct ll_sb_info *sbi, int *lmmsize) void ll_dump_inode(struct inode *inode) { struct list_head *tmp; + struct dentry *dentry; int dentry_count = 0; LASSERT(inode != NULL); + CERROR("inode %p dump: dev=%s ino=%lu mode=%o count=%u state %lx\n", + inode, ll_i2mdexp(inode)->exp_obd->obd_name, inode->i_ino, + inode->i_mode, atomic_read(&inode->i_count), inode->i_state); + + list_for_each(tmp, &inode->i_dentry) { + dentry = list_entry(tmp, struct dentry, d_alias); + CERROR("Alias[%d] dentry %p dump: name=%.*s parent=%.*s (%p), inode=%p, count=%u, " + "flags=0x%x, fsdata=%p\n", dentry_count, dentry, + dentry->d_name.len, dentry->d_name.name, + dentry->d_parent->d_name.len, dentry->d_parent->d_name.name, + dentry->d_parent, dentry->d_inode, atomic_read(&dentry->d_count), + dentry->d_flags, dentry->d_fsdata); - list_for_each(tmp, &inode->i_dentry) dentry_count++; + } - CERROR("inode %p dump: dev=%s ino=%lu mode=%o count=%u, %d dentries\n", - inode, ll_i2mdexp(inode)->exp_obd->obd_name, inode->i_ino, - inode->i_mode, atomic_read(&inode->i_count), dentry_count); } void lustre_dump_dentry(struct dentry *dentry, int recur) diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c index a0befa4..c921b28 100644 --- a/lustre/llite/namei.c +++ b/lustre/llite/namei.c @@ -41,6 +41,8 @@ #include #include #include +#include +#include #define DEBUG_SUBSYSTEM S_LLITE @@ -721,6 +723,42 @@ static struct dentry *ll_lookup_nd(struct inode *parent, struct dentry *dentry, } #endif +/** + * check new allocated inode, new inode shld not have any valid alias + */ +static void ll_validate_new_inode(struct inode *new) +{ + struct list_head *lp; + struct dentry * dentry; + int need_inval = 0; + int in_recheck = 0; + + if (list_empty(&new->i_dentry)) + return; +recheck: + spin_lock(&dcache_lock); + list_for_each(lp, &new->i_dentry) { + dentry = list_entry(lp, struct dentry, d_alias); + if (!d_unhashed(dentry) && !(dentry->d_flags & DCACHE_LUSTRE_INVALID)){ + ll_dump_inode(new); + if (in_recheck) + LBUG(); + } + need_inval = 1; + } + spin_unlock(&dcache_lock); + + if (need_inval && !in_recheck) { + /* kill all old inode's data pages */ + truncate_inode_pages(new->i_mapping, 0); + + /* invalidate all dirent and recheck inode */ + ll_unhash_aliases(new); + in_recheck = 1; + goto recheck; + } +} + /* We depend on "mode" being set with the proper file type/umask by now */ static struct inode *ll_create_node(struct inode *dir, const char *name, int namelen, const void *data, int datalen, @@ -742,7 +780,7 @@ static struct inode *ll_create_node(struct inode *dir, const char *name, if (rc) GOTO(out, inode = ERR_PTR(rc)); - LASSERT(list_empty(&inode->i_dentry)); + ll_validate_new_inode(inode); /* We asked for a lock on the directory, but were granted a * lock on the inode. Since we finally have an inode pointer, @@ -792,6 +830,8 @@ static int ll_create_it(struct inode *dir, struct dentry *dentry, int mode, RETURN(PTR_ERR(inode)); } + /* it might been set during parent dir revalidation */ + dentry->d_flags &= ~DCACHE_LUSTRE_INVALID; d_instantiate(dentry, inode); /* Negative dentry may be unhashed if parent does not have UPDATE lock, * but some callers, e.g. do_coredump, expect dentry to be hashed after diff --git a/lustre/tests/replay-single.sh b/lustre/tests/replay-single.sh index badd1a0..eb5f614 100755 --- a/lustre/tests/replay-single.sh +++ b/lustre/tests/replay-single.sh @@ -20,7 +20,7 @@ remote_mds_nodsh && log "SKIP: remote MDS with nodsh" && exit 0 # Skip these tests # bug number: 17466 15962 -ALWAYS_EXCEPT="61d 33b $REPLAY_SINGLE_EXCEPT" +ALWAYS_EXCEPT="61d $REPLAY_SINGLE_EXCEPT" if [ "$FAILURE_MODE" = "HARD" ] && mixed_ost_devs; then CONFIG_EXCEPTIONS="0b 42 47 61a 61c" -- 1.8.3.1