From b796ee0611c1cc3da25ee0710838bcf429103c2e Mon Sep 17 00:00:00 2001 From: LiuYing Date: Tue, 2 Nov 2010 09:18:04 +0800 Subject: [PATCH] b=23399 Deadlock probably due to statahead partly revoke patch (id=28310) o=fanyong i=tappro i=wangdi --- lustre/include/obd.h | 2 +- lustre/include/obd_class.h | 4 +- lustre/llite/dcache.c | 58 ++++++---- lustre/llite/llite_internal.h | 32 +----- lustre/llite/llite_lib.c | 1 - lustre/llite/namei.c | 67 +++-------- lustre/llite/statahead.c | 253 ++++-------------------------------------- lustre/lmv/lmv_obd.c | 4 +- lustre/mdc/mdc_internal.h | 2 +- lustre/mdc/mdc_locks.c | 19 +--- 10 files changed, 85 insertions(+), 357 deletions(-) diff --git a/lustre/include/obd.h b/lustre/include/obd.h index 4a341d0..f55aa5b 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -1543,7 +1543,7 @@ struct md_ops { struct ldlm_enqueue_info *); int (*m_revalidate_lock)(struct obd_export *, struct lookup_intent *, - struct lu_fid *, __u32 *); + struct lu_fid *); /* * NOTE: If adding ops, add another LPROCFS_MD_OP_INIT() line to diff --git a/lustre/include/obd_class.h b/lustre/include/obd_class.h index f96fb6e..c9585b0 100644 --- a/lustre/include/obd_class.h +++ b/lustre/include/obd_class.h @@ -2165,13 +2165,13 @@ static inline int md_intent_getattr_async(struct obd_export *exp, static inline int md_revalidate_lock(struct obd_export *exp, struct lookup_intent *it, - struct lu_fid *fid, __u32 *bits) + struct lu_fid *fid) { int rc; ENTRY; EXP_CHECK_MD_OP(exp, revalidate_lock); EXP_MD_COUNTER_INCREMENT(exp, revalidate_lock); - rc = MDP(exp->exp_obd, revalidate_lock)(exp, it, fid, bits); + rc = MDP(exp->exp_obd, revalidate_lock)(exp, it, fid); RETURN(rc); } diff --git a/lustre/llite/dcache.c b/lustre/llite/dcache.c index 02a2f1f..4f359b0 100644 --- a/lustre/llite/dcache.c +++ b/lustre/llite/dcache.c @@ -110,7 +110,6 @@ int ll_dcompare(struct dentry *parent, struct qstr *d_name, struct qstr *name) if (dchild->d_flags & DCACHE_LUSTRE_INVALID) RETURN(1); - RETURN(0); } @@ -169,7 +168,7 @@ static int ll_ddelete(struct dentry *de) RETURN(0); } -int ll_set_dd(struct dentry *de) +static int ll_set_dd(struct dentry *de) { ENTRY; LASSERT(de != NULL); @@ -183,7 +182,6 @@ int ll_set_dd(struct dentry *de) OBD_ALLOC_PTR(lld); if (likely(lld != NULL)) { - CFS_INIT_LIST_HEAD(&lld->lld_sa_alias); lock_dentry(de); if (likely(de->d_fsdata == NULL)) de->d_fsdata = lld; @@ -198,6 +196,26 @@ int ll_set_dd(struct dentry *de) RETURN(0); } +int ll_dops_init(struct dentry *de, int block) +{ + struct ll_dentry_data *lld = ll_d2d(de); + int rc = 0; + + if (lld == NULL && block != 0) { + rc = ll_set_dd(de); + if (rc) + return rc; + + lld = ll_d2d(de); + } + + if (lld != NULL) + lld->lld_sa_generation = 0; + + de->d_op = &ll_d_ops; + return rc; +} + void ll_intent_drop_lock(struct lookup_intent *it) { struct lustre_handle *handle; @@ -492,14 +510,8 @@ int ll_revalidate_it(struct dentry *de, int lookup_flags, } } - if (it->it_op == IT_GETATTR) { + if (it->it_op == IT_GETATTR) first = ll_statahead_enter(parent, &de, 0); - if (first == 1) { - ll_statahead_exit(parent, de, 1); - ll_finish_md_op_data(op_data); - GOTO(out, rc = 1); - } - } do_lock: it->it_create_mode &= ~current->fs->umask; @@ -575,14 +587,12 @@ out: "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)); - if (first != 1) { - if (de->d_flags & DCACHE_LUSTRE_INVALID) { - lock_dentry(de); - de->d_flags &= ~DCACHE_LUSTRE_INVALID; - unlock_dentry(de); - } - ll_lookup_finish_locks(it, de); + if (de->d_flags & DCACHE_LUSTRE_INVALID) { + lock_dentry(de); + de->d_flags &= ~DCACHE_LUSTRE_INVALID; + unlock_dentry(de); } + ll_lookup_finish_locks(it, de); } RETURN(rc); @@ -763,15 +773,17 @@ int ll_revalidate_nd(struct dentry *dentry, struct nameidata *nd) if (nd && !(nd->flags & (LOOKUP_CONTINUE|LOOKUP_PARENT))) { struct lookup_intent *it; + it = ll_convert_intent(&nd->intent.open, nd->flags); if (IS_ERR(it)) RETURN(0); - if (it->it_op == (IT_OPEN|IT_CREAT)) - if (nd->intent.open.flags & O_EXCL) { - CDEBUG(D_VFSTRACE, "create O_EXCL, returning 0\n"); - rc = 0; - goto out_it; - } + + if (it->it_op == (IT_OPEN|IT_CREAT) && + nd->intent.open.flags & O_EXCL) { + CDEBUG(D_VFSTRACE, "create O_EXCL, returning 0\n"); + rc = 0; + goto out_it; + } rc = ll_revalidate_it(dentry, nd->flags, it); diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 03436ec..9ca31dc 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -75,7 +75,6 @@ struct ll_dentry_data { struct lookup_intent *lld_it; #endif unsigned int lld_sa_generation; - cfs_list_t lld_sa_alias; }; #define ll_d2d(de) ((struct ll_dentry_data*)((de)->d_fsdata)) @@ -177,7 +176,7 @@ struct ll_inode_info { /* metadata statahead */ /* protect statahead stuff: lli_opendir_pid, lli_opendir_key, lli_sai, - * lli_sa_dentry, and so on. */ + * and so on. */ cfs_spinlock_t lli_sa_lock; /* * "opendir_pid" is the token when lookup/revalid -- I am the owner of @@ -190,7 +189,6 @@ struct ll_inode_info { * before child -- it is me should cleanup the dir readahead. */ void *lli_opendir_key; struct ll_statahead_info *lli_sai; - cfs_list_t lli_sa_dentry; struct cl_object *lli_clob; /* the most recent timestamps obtained from mds */ struct ost_lvb lli_lvb; @@ -531,8 +529,6 @@ struct it_cb_data { struct inode *icbd_parent; struct dentry **icbd_childp; obd_id hash; - struct inode **icbd_alias; - __u32 *bits; }; __u32 ll_i2suppgid(struct inode *i); @@ -599,7 +595,6 @@ int ll_md_blocking_ast(struct ldlm_lock *, struct ldlm_lock_desc *, struct lookup_intent *ll_convert_intent(struct open_intent *oit, int lookup_flags); #endif -void ll_lookup_it_alias(struct dentry **de, struct inode *inode, __u32 bits); int ll_lookup_it_finish(struct ptlrpc_request *request, struct lookup_intent *it, void *data); @@ -686,12 +681,12 @@ int ll_fid2path(struct obd_export *exp, void *arg); /** * protect race ll_find_aliases vs ll_revalidate_it vs ll_unhash_aliases */ +int ll_dops_init(struct dentry *de, int block); extern cfs_spinlock_t ll_lookup_lock; extern struct dentry_operations ll_d_ops; void ll_intent_drop_lock(struct lookup_intent *); void ll_intent_release(struct lookup_intent *); int ll_drop_dentry(struct dentry *dentry); -extern int ll_set_dd(struct dentry *de); int ll_drop_dentry(struct dentry *dentry); void ll_unhash_aliases(struct inode *); void ll_frob_intent(struct lookup_intent **itp, struct lookup_intent *deft); @@ -1129,7 +1124,6 @@ struct ll_statahead_info { unsigned int sai_skip_hidden;/* skipped hidden dentry count */ unsigned int sai_ls_all:1; /* "ls -al", do stat-ahead for * hidden entries */ - unsigned int sai_nolock; /* without lookup lock case */ cfs_waitq_t sai_waitq; /* stat-ahead wait queue */ struct ptlrpc_thread sai_thread; /* stat-ahead thread */ cfs_list_t sai_entries_sent; /* entries sent out */ @@ -1139,7 +1133,7 @@ struct ll_statahead_info { int do_statahead_enter(struct inode *dir, struct dentry **dentry, int lookup); void ll_statahead_exit(struct inode *dir, struct dentry *dentry, int result); -void ll_stop_statahead(struct inode *inode, void *key); +void ll_stop_statahead(struct inode *dir, void *key); static inline void ll_statahead_mark(struct inode *dir, struct dentry *dentry) @@ -1201,26 +1195,6 @@ int ll_statahead_enter(struct inode *dir, struct dentry **dentryp, int lookup) return do_statahead_enter(dir, dentryp, lookup); } -static int inline ll_dops_init(struct dentry *de, int block) -{ - struct ll_dentry_data *lld = ll_d2d(de); - int rc = 0; - - if (lld == NULL && block != 0) { - rc = ll_set_dd(de); - if (rc) - return rc; - - lld = ll_d2d(de); - } - - if (lld != NULL) - lld->lld_sa_generation = 0; - - de->d_op = &ll_d_ops; - return rc; -} - /* llite ioctl register support rountine */ #ifdef __KERNEL__ enum llioc_iter { diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index d1593d2..5c98d39 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -815,7 +815,6 @@ void ll_lli_init(struct ll_inode_info *lli) cfs_sema_init(&lli->lli_rmtperm_sem, 1); CFS_INIT_LIST_HEAD(&lli->lli_oss_capas); cfs_spin_lock_init(&lli->lli_sa_lock); - CFS_INIT_LIST_HEAD(&lli->lli_sa_dentry); } int ll_fill_super(struct super_block *sb) diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c index 04e7b37..19ba2a7 100644 --- a/lustre/llite/namei.c +++ b/lustre/llite/namei.c @@ -258,18 +258,6 @@ int ll_md_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, ll_drop_negative_dentry(inode); } - if ((bits & MDS_INODELOCK_LOOKUP) && - !cfs_list_empty(&lli->lli_sa_dentry)) { - struct ll_dentry_data *lld, *next; - - cfs_spin_lock(&lli->lli_sa_lock); - cfs_list_for_each_entry_safe(lld, next, - &lli->lli_sa_dentry, - lld_sa_alias) - cfs_list_del_init(&lld->lld_sa_alias); - cfs_spin_unlock(&lli->lli_sa_lock); - } - if (inode->i_sb->s_root && inode != inode->i_sb->s_root->d_inode && (bits & MDS_INODELOCK_LOOKUP)) @@ -438,29 +426,6 @@ static struct dentry *ll_find_alias(struct inode *inode, struct dentry *de) return de; } -void ll_lookup_it_alias(struct dentry **de, struct inode *inode, __u32 bits) -{ - struct dentry *save = *de; - ENTRY; - - ll_dops_init(*de, 1); - *de = ll_find_alias(inode, *de); - if (*de != save) { - struct ll_dentry_data *lld = ll_d2d(*de); - - /* just make sure the ll_dentry_data is ready */ - if (unlikely(lld == NULL)) - ll_dops_init(*de, 1); - } - /* we have lookup look - unhide dentry */ - if (bits & MDS_INODELOCK_LOOKUP) { - lock_dentry(*de); - (*de)->d_flags &= ~DCACHE_LUSTRE_INVALID; - unlock_dentry(*de); - } - EXIT; -} - int ll_lookup_it_finish(struct ptlrpc_request *request, struct lookup_intent *it, void *data) { @@ -475,6 +440,7 @@ int ll_lookup_it_finish(struct ptlrpc_request *request, /* NB 1 request reference will be taken away by ll_intent_lock() * when I return */ if (!it_disposition(it, DISP_LOOKUP_NEG)) { + struct dentry *save = *de; __u32 bits; rc = ll_prep_inode(&inode, request, (*de)->d_sb); @@ -486,13 +452,6 @@ int ll_lookup_it_finish(struct ptlrpc_request *request, md_set_lock_data(sbi->ll_md_exp, &it->d.lustre.it_lock_handle, inode, &bits); - if (icbd->bits != NULL) - *icbd->bits = bits; - if (icbd->icbd_alias != NULL) { - *icbd->icbd_alias = inode; - RETURN(0); - } - /* We used to query real size from OSTs here, but actually this is not needed. For stat() calls size would be updated from subsequent do_revalidate()->ll_inode_revalidate_it() in @@ -501,7 +460,21 @@ int ll_lookup_it_finish(struct ptlrpc_request *request, Everybody else who needs correct file size would call cl_glimpse_size or some equivalent themselves anyway. Also see bug 7198. */ - ll_lookup_it_alias(de, inode, bits); + ll_dops_init(*de, 1); + *de = ll_find_alias(inode, *de); + if (*de != save) { + struct ll_dentry_data *lld = ll_d2d(*de); + + /* just make sure the ll_dentry_data is ready */ + if (unlikely(lld == NULL)) + ll_dops_init(*de, 1); + } + /* we have lookup look - unhide dentry */ + if (bits & MDS_INODELOCK_LOOKUP) { + lock_dentry(*de); + (*de)->d_flags &= ~DCACHE_LUSTRE_INVALID; + unlock_dentry(*de); + } } else { ll_dops_init(*de, 1); /* Check that parent has UPDATE lock. If there is none, we @@ -576,8 +549,6 @@ static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry, icbd.icbd_childp = &dentry; icbd.icbd_parent = parent; - icbd.icbd_alias = NULL; - icbd.bits = NULL; if (it->it_op & IT_CREAT || (it->it_op & IT_OPEN && it->it_create_mode & O_CREAT)) @@ -686,7 +657,6 @@ static struct dentry *ll_lookup_nd(struct inode *parent, struct dentry *dentry, if (IS_ERR(nd->intent.open.file)) RETURN((struct dentry *)nd->intent.open.file); #endif - if (ll_d2d(dentry) && ll_d2d(dentry)->lld_it) { it = ll_d2d(dentry)->lld_it; ll_d2d(dentry)->lld_it = NULL; @@ -831,9 +801,8 @@ static int ll_create_it(struct inode *dir, struct dentry *dentry, int mode, inode = ll_create_node(dir, dentry->d_name.name, dentry->d_name.len, NULL, 0, mode, 0, it); - if (IS_ERR(inode)) { + if (IS_ERR(inode)) RETURN(PTR_ERR(inode)); - } d_instantiate(dentry, inode); /* Negative dentry may be unhashed if parent does not have UPDATE lock, @@ -900,8 +869,8 @@ static int ll_new_node(struct inode *dir, struct qstr *name, d_drop(dchild); d_instantiate(dchild, inode); - EXIT; } + EXIT; err_exit: ptlrpc_req_finished(request); diff --git a/lustre/llite/statahead.c b/lustre/llite/statahead.c index 4c3f0e0..006f7f5 100644 --- a/lustre/llite/statahead.c +++ b/lustre/llite/statahead.c @@ -55,8 +55,6 @@ struct ll_sai_entry { int se_stat; struct ptlrpc_request *se_req; struct md_enqueue_info *se_minfo; - struct dentry *se_dentry; - struct inode *se_inode; }; enum { @@ -123,38 +121,6 @@ static inline int sa_low_hit(struct ll_statahead_info *sai) (sai->sai_consecutive_miss > 8)); } -static inline int sa_skip_nolock(struct ll_statahead_info *sai) -{ - return (sai->sai_nolock >= 3); -} - -static void ll_sai_entry_free(struct ll_sai_entry *entry) -{ - struct dentry *dentry = entry->se_dentry; - struct inode *inode = entry->se_inode; - - if (dentry) { - struct ll_dentry_data *lld = ll_d2d(dentry); - struct ll_inode_info *lli; - - entry->se_dentry = NULL; - LASSERT(inode != NULL); - lli = ll_i2info(inode); - if (!cfs_list_empty(&lli->lli_sa_dentry)) { - cfs_spin_lock(&lli->lli_sa_lock); - cfs_list_del_init(&lld->lld_sa_alias); - cfs_spin_unlock(&lli->lli_sa_lock); - } - dput(dentry); - } - if (inode) { - entry->se_inode = NULL; - iput(inode); - } - LASSERT(cfs_list_empty(&entry->se_list)); - OBD_FREE_PTR(entry); -} - /** * process the deleted entry's member and free the entry. * (1) release intent @@ -179,8 +145,10 @@ static void ll_sai_entry_cleanup(struct ll_sai_entry *entry, int free) entry->se_req = NULL; ptlrpc_req_finished(req); } - if (free) - ll_sai_entry_free(entry); + if (free) { + LASSERT(cfs_list_empty(&entry->se_list)); + OBD_FREE_PTR(entry); + } EXIT; } @@ -319,7 +287,7 @@ static int ll_sai_entry_fini(struct ll_statahead_info *sai) if (entry->se_index < sai->sai_index_next) { cfs_list_del_init(&entry->se_list); rc = entry->se_stat; - ll_sai_entry_free(entry); + OBD_FREE_PTR(entry); } } else { LASSERT(sa_is_stopped(sai)); @@ -390,7 +358,7 @@ ll_sai_entry_to_stated(struct ll_statahead_info *sai, struct ll_sai_entry *entry /* stale entry */ if (unlikely(entry->se_index < sai->sai_index_next)) { cfs_spin_unlock(&lli->lli_sa_lock); - ll_sai_entry_free(entry); + OBD_FREE_PTR(entry); RETURN(0); } @@ -456,12 +424,9 @@ static int do_statahead_interpret(struct ll_statahead_info *sai) * lookup. */ struct dentry *save = dentry; - __u32 bits = 0; struct it_cb_data icbd = { .icbd_parent = minfo->mi_dir, - .icbd_childp = &dentry, - .icbd_alias = &entry->se_inode, - .bits = &bits + .icbd_childp = &dentry }; LASSERT(fid_is_zero(&minfo->mi_data.op_fid2)); @@ -473,45 +438,14 @@ static int do_statahead_interpret(struct ll_statahead_info *sai) /* Here dentry->d_inode might be NULL, because the entry may * have been removed before we start doing stat ahead. */ - - /* BUG 15962, 21739: since statahead thread does not hold - * parent's i_mutex, it can not alias the dentry to inode. - * Here we just create/update inode in memory, and let the - * main "ls -l" thread to alias such dentry to the inode with - * parent's i_mutex held. - * On the other hand, we hold ldlm ibits lock for the inode - * yet, to allow other operations to cancel such lock in time, - * we should drop the ldlm lock reference count, then the main - * "ls -l" thread should check/get such ldlm ibits lock before - * aliasing such dentry to the inode later. If we don't do such - * drop here, it maybe cause deadlock with i_muext held by - * others, just like bug 21739. */ rc = ll_lookup_it_finish(req, it, &icbd); - if (entry->se_inode != NULL) { - struct ll_dentry_data *lld = ll_d2d(dentry); - struct ll_inode_info *sei = ll_i2info(entry->se_inode); - - /* For statahead lookup case, both MDS_INODELOCK_LOOKUP - * and MDS_INODELOCK_UPDATE should be granted */ - if (likely(bits & MDS_INODELOCK_LOOKUP && - bits & MDS_INODELOCK_UPDATE)) { - /* the first dentry ref_count will be dropped by - * ll_sai_entry_to_stated(), so hold another ref - * in advance */ - entry->se_dentry = dget(dentry); - cfs_spin_lock(&sei->lli_sa_lock); - cfs_list_add(&lld->lld_sa_alias, - &sei->lli_sa_dentry); - cfs_spin_unlock(&sei->lli_sa_lock); - sai->sai_nolock = 0; - } else { - iput(entry->se_inode); - entry->se_inode = NULL; - sai->sai_nolock++; - } + if (!rc) + ll_lookup_finish_locks(it, dentry); + + if (dentry != save) { + minfo->mi_dentry = dentry; + dput(save); } - LASSERT(dentry == save); - ll_intent_drop_lock(it); } else { /* * revalidate. @@ -722,8 +656,7 @@ static int do_sa_revalidate(struct inode *dir, struct dentry *dentry) if (unlikely(dentry == dentry->d_sb->s_root)) RETURN(1); - rc = md_revalidate_lock(ll_i2mdexp(dir), &it, ll_inode2fid(inode), - NULL); + rc = md_revalidate_lock(ll_i2mdexp(dir), &it, ll_inode2fid(inode)); if (rc == 1) { ll_intent_release(&it); RETURN(1); @@ -777,18 +710,9 @@ static int ll_statahead_one(struct dentry *parent, const char* entry_name, ll_name2qstr(&name, entry_name, entry_name_len); dentry = d_lookup(parent, &name); if (!dentry) { - if (unlikely(sa_skip_nolock(sai))) { - CWARN("can not obtain lookup lock, skip the succeedent " - "lookup cases, will cause statahead miss, and " - "statahead maybe exit for that.\n"); - GOTO(out, rc = -EAGAIN); - } - dentry = d_alloc(parent, &name); if (dentry) { - rc = ll_dops_init(dentry, 1); - if (!rc) - rc = do_sa_lookup(dir, dentry); + rc = do_sa_lookup(dir, dentry); if (rc) dput(dentry); } else { @@ -977,9 +901,9 @@ out: /** * called in ll_file_release(). */ -void ll_stop_statahead(struct inode *inode, void *key) +void ll_stop_statahead(struct inode *dir, void *key) { - struct ll_inode_info *lli = ll_i2info(inode); + struct ll_inode_info *lli = ll_i2info(dir); if (unlikely(key == NULL)) return; @@ -1138,48 +1062,11 @@ out: return rc; } -/* - * tgt: the dentry to be revalidate or lookup - * new: the dentry created by statahead - */ -static int is_same_dentry(struct dentry *tgt, struct dentry *new, int lookup) -{ - if (tgt == new) { - LASSERT(lookup == 0); - return 1; - } - if (tgt->d_parent != new->d_parent) - return 0; - if (tgt->d_name.hash != new->d_name.hash) - return 0; - if (tgt->d_name.len != new->d_name.len) - return 0; - if (memcmp(tgt->d_name.name, new->d_name.name, tgt->d_name.len) != 0) - return 0; - if (tgt->d_inode == NULL && lookup) - return 1; - if (tgt->d_inode) - LASSERTF(tgt->d_flags & DCACHE_LUSTRE_INVALID, - "[%.*s/%.*s] [%x %p "DFID"] [%x %p "DFID"]\n", - tgt->d_parent->d_name.len, tgt->d_parent->d_name.name, - tgt->d_name.len, tgt->d_name.name, - tgt->d_flags, tgt, PFID(ll_inode2fid(tgt->d_inode)), - new->d_flags, new, PFID(ll_inode2fid(new->d_inode))); - else - LASSERTF(tgt->d_flags & DCACHE_LUSTRE_INVALID, - "[%.*s/%.*s] [%x %p 0] [%x %p "DFID"]\n", - tgt->d_parent->d_name.len, tgt->d_parent->d_name.name, - tgt->d_name.len, tgt->d_name.name, - tgt->d_flags, tgt, - new->d_flags, new, PFID(ll_inode2fid(new->d_inode))); - return 0; -} - /** * Start statahead thread if this is the first dir entry. * Otherwise if a thread is started already, wait it until it is ahead of me. - * \retval 0 -- stat ahead thread process such dentry, miss for lookup - * \retval 1 -- stat ahead thread process such dentry, hit for any case + * \retval 0 -- stat ahead thread process such dentry, for lookup, it miss + * \retval 1 -- stat ahead thread process such dentry, for lookup, it hit * \retval -EEXIST -- stat ahead thread started, and this is the first dentry * \retval -EBADFD -- statahead thread exit and not dentry available * \retval -EAGAIN -- try to stat by caller @@ -1244,108 +1131,6 @@ int do_statahead_enter(struct inode *dir, struct dentry **dentryp, int lookup) RETURN(rc); } - if (ll_sai_entry_stated(sai)) { - struct ll_sai_entry *entry; - - entry = cfs_list_entry(sai->sai_entries_stated.next, - struct ll_sai_entry, se_list); - /* This is for statahead lookup */ - if (entry->se_inode != NULL) { - struct lookup_intent it = {.it_op = IT_LOOKUP}; - struct dentry *dchild = entry->se_dentry; - struct inode *ichild = entry->se_inode; - struct ll_dentry_data *lld = ll_d2d(dchild); - struct ll_inode_info *sei = ll_i2info(ichild); - struct dentry *save = dchild; - int invalid = 0; - __u32 bits = MDS_INODELOCK_LOOKUP | - MDS_INODELOCK_UPDATE; - int found = 0; - - LASSERT(dchild != *dentryp); - - if (!lookup) - mutex_lock(&dir->i_mutex); - - /* - * Make sure dentry is still valid. - * For statahead lookup case, we need both - * LOOKUP lock and UPDATE lock which obtained - * by statahead thread originally. - * - * Consider following racer case: - * 1. statahead thread on client1 get lock with - * both LOOKUK and UPDATE bits for "aaa" - * 2. rename thread on client2 cancel such lock - * from client1, then rename "aaa" to "bbb" - * 3. ls thread on client1 obtain LOOKUP lock - * for "bbb" again - * 4. here the dentry "aaa" created by statahead - * thread should be invalid even related - * LOOKUP lock valid for the same inode - */ - rc = md_revalidate_lock(ll_i2mdexp(dir), &it, - ll_inode2fid(ichild), - &bits); - cfs_spin_lock(&sei->lli_sa_lock); - if (!cfs_list_empty(&lld->lld_sa_alias)) - cfs_list_del_init(&lld->lld_sa_alias); - else - invalid = 1; - cfs_spin_unlock(&sei->lli_sa_lock); - if (rc != 1) - /* Someone has cancelled the original - * lock before the real "revalidate" - * using it. Drop it. */ - goto out_mutex; - - if (invalid) { - /* Someone has cancelled the original - * lock, and reobtained it, the dentry - * maybe invalid anymore, Drop it. */ - ll_intent_drop_lock(&it); - goto out_mutex; - } - - ll_lookup_it_alias(&dchild, ichild, bits); - found = is_same_dentry(*dentryp, dchild, lookup); - ll_lookup_finish_locks(&it, dchild); - if (dchild != save) - dput(save); - ichild = NULL; - -out_mutex: - if (!lookup) - mutex_unlock(&dir->i_mutex); - /* Drop the inode reference count held by - * interpreter. */ - if (ichild != NULL) - iput(ichild); - - entry->se_dentry = NULL; - entry->se_inode = NULL; - if (found) { - if (lookup) { - LASSERT(*dentryp != dchild); - /* VFS will drop the reference - * count for dchild and *dentryp - * by itself. */ - *dentryp = dchild; - } else { - LASSERT(*dentryp == dchild); - /* Drop the dentry reference - * count held by statahead. */ - dput(dchild); - } - RETURN(1); - } else { - /* Drop the dentry reference count held - * by statahead. */ - dput(dchild); - } - } - } - if (lookup) { struct dentry *result; diff --git a/lustre/lmv/lmv_obd.c b/lustre/lmv/lmv_obd.c index d9b2c8c..e5ec165 100644 --- a/lustre/lmv/lmv_obd.c +++ b/lustre/lmv/lmv_obd.c @@ -3013,7 +3013,7 @@ int lmv_intent_getattr_async(struct obd_export *exp, } int lmv_revalidate_lock(struct obd_export *exp, struct lookup_intent *it, - struct lu_fid *fid, __u32 *bits) + struct lu_fid *fid) { struct obd_device *obd = exp->exp_obd; struct lmv_obd *lmv = &obd->u.lmv; @@ -3029,7 +3029,7 @@ int lmv_revalidate_lock(struct obd_export *exp, struct lookup_intent *it, if (IS_ERR(tgt)) RETURN(PTR_ERR(tgt)); - rc = md_revalidate_lock(tgt->ltd_exp, it, fid, bits); + rc = md_revalidate_lock(tgt->ltd_exp, it, fid); RETURN(rc); } diff --git a/lustre/mdc/mdc_internal.h b/lustre/mdc/mdc_internal.h index 56985d9..44e0e20 100644 --- a/lustre/mdc/mdc_internal.h +++ b/lustre/mdc/mdc_internal.h @@ -156,7 +156,7 @@ static inline void mdc_set_capa_size(struct ptlrpc_request *req, } int mdc_revalidate_lock(struct obd_export *exp, struct lookup_intent *it, - struct lu_fid *fid, __u32 *bits); + struct lu_fid *fid); int mdc_intent_getattr_async(struct obd_export *exp, struct md_enqueue_info *minfo, diff --git a/lustre/mdc/mdc_locks.c b/lustre/mdc/mdc_locks.c index b70e974..7bf1abe 100644 --- a/lustre/mdc/mdc_locks.c +++ b/lustre/mdc/mdc_locks.c @@ -834,7 +834,7 @@ static int mdc_finish_intent_lock(struct obd_export *exp, } int mdc_revalidate_lock(struct obd_export *exp, struct lookup_intent *it, - struct lu_fid *fid, __u32 *bits) + struct lu_fid *fid) { /* We could just return 1 immediately, but since we should only * be called in revalidate_it if we already have a lock, let's @@ -846,12 +846,8 @@ int mdc_revalidate_lock(struct obd_export *exp, struct lookup_intent *it, ENTRY; fid_build_reg_res_name(fid, &res_id); - /* Firstly consider the bits */ - if (bits && *bits) - policy.l_inodebits.bits = *bits; - else - policy.l_inodebits.bits = (it->it_op == IT_GETATTR) ? - MDS_INODELOCK_UPDATE : MDS_INODELOCK_LOOKUP; + policy.l_inodebits.bits = (it->it_op == IT_GETATTR) ? + MDS_INODELOCK_UPDATE : MDS_INODELOCK_LOOKUP; mode = ldlm_lock_match(exp->exp_obd->obd_namespace, LDLM_FL_BLOCK_GRANTED, &res_id, LDLM_IBITS, @@ -859,13 +855,6 @@ int mdc_revalidate_lock(struct obd_export *exp, struct lookup_intent *it, if (mode) { it->d.lustre.it_lock_handle = lockh.cookie; it->d.lustre.it_lock_mode = mode; - if (bits) { - struct ldlm_lock *lock = ldlm_handle2lock(&lockh); - - LASSERT(lock != NULL); - *bits = lock->l_policy_data.l_inodebits.bits; - LDLM_LOCK_PUT(lock); - } } RETURN(!!mode); @@ -921,7 +910,7 @@ int mdc_intent_lock(struct obd_export *exp, struct md_op_data *op_data, /* We could just return 1 immediately, but since we should only * be called in revalidate_it if we already have a lock, let's * verify that. */ - rc = mdc_revalidate_lock(exp, it, &op_data->op_fid2, NULL); + rc = mdc_revalidate_lock(exp, it, &op_data->op_fid2); /* Only return failure if it was not GETATTR by cfid (from inode_revalidate) */ if (rc || op_data->op_namelen != 0) -- 1.8.3.1