From 32becabb43b6e8f21c030c23c01c3f02e351eaea Mon Sep 17 00:00:00 2001 From: shadow Date: Tue, 14 Jul 2009 06:18:38 +0000 Subject: [PATCH] Land first part of new dcache handling (bug 16654). make DCACHE_LUSTRE_INVALID always defined. Branch HEAD b=16417 i=green i=johann --- lustre/include/obd.h | 2 +- lustre/include/obd_class.h | 4 ++-- lustre/liblustre/namei.c | 2 +- lustre/llite/dcache.c | 40 +++++++++++++--------------------------- lustre/llite/dir.c | 3 ++- lustre/llite/file.c | 4 ++-- lustre/llite/llite_internal.h | 4 ++++ lustre/llite/llite_lib.c | 2 -- lustre/llite/namei.c | 25 +++++++++++++++++++------ lustre/lmv/lmv_obd.c | 6 ++++-- lustre/mdc/mdc_internal.h | 2 +- lustre/mdc/mdc_locks.c | 9 ++++++++- 12 files changed, 57 insertions(+), 46 deletions(-) diff --git a/lustre/include/obd.h b/lustre/include/obd.h index 067c58c..3848808 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -1536,7 +1536,7 @@ struct md_ops { struct ptlrpc_request *); int (*m_clear_open_replay_data)(struct obd_export *, struct obd_client_handle *); - int (*m_set_lock_data)(struct obd_export *, __u64 *, void *); + int (*m_set_lock_data)(struct obd_export *, __u64 *, void *, __u32 *); ldlm_mode_t (*m_lock_match)(struct obd_export *, int, const struct lu_fid *, ldlm_type_t, diff --git a/lustre/include/obd_class.h b/lustre/include/obd_class.h index c7ef51a..c296b1d 100644 --- a/lustre/include/obd_class.h +++ b/lustre/include/obd_class.h @@ -1953,12 +1953,12 @@ static inline int md_clear_open_replay_data(struct obd_export *exp, } static inline int md_set_lock_data(struct obd_export *exp, - __u64 *lockh, void *data) + __u64 *lockh, void *data, __u32 *bits) { ENTRY; EXP_CHECK_MD_OP(exp, set_lock_data); EXP_MD_COUNTER_INCREMENT(exp, set_lock_data); - RETURN(MDP(exp->exp_obd, set_lock_data)(exp, lockh, data)); + RETURN(MDP(exp->exp_obd, set_lock_data)(exp, lockh, data, bits)); } static inline int md_cancel_unused(struct obd_export *exp, diff --git a/lustre/liblustre/namei.c b/lustre/liblustre/namei.c index cfd7100..b748e6e 100644 --- a/lustre/liblustre/namei.c +++ b/lustre/liblustre/namei.c @@ -108,7 +108,7 @@ void llu_lookup_finish_locks(struct lookup_intent *it, struct pnode *pnode) sbi = llu_i2sbi(inode); md_set_lock_data(sbi->ll_md_exp, - &it->d.lustre.it_lock_handle, inode); + &it->d.lustre.it_lock_handle, inode, NULL); } /* drop lookup/getattr locks */ diff --git a/lustre/llite/dcache.c b/lustre/llite/dcache.c index cf1f734..2ef00a9 100644 --- a/lustre/llite/dcache.c +++ b/lustre/llite/dcache.c @@ -77,7 +77,6 @@ static void ll_release(struct dentry *de) EXIT; } -#ifdef DCACHE_LUSTRE_INVALID /* Compare if two dentries are the same. Don't match if the existing dentry * is marked DCACHE_LUSTRE_INVALID. Returns 1 if different, 0 if the same. * @@ -98,15 +97,22 @@ int ll_dcompare(struct dentry *parent, struct qstr *d_name, struct qstr *name) /* XXX: d_name must be in-dentry structure */ dchild = container_of(d_name, struct dentry, d_name); /* ugh */ - if (dchild->d_flags & DCACHE_LUSTRE_INVALID) { - CDEBUG(D_DENTRY,"INVALID dentry %p not matched, was bug 3784\n", - dchild); + + CDEBUG(D_DENTRY,"found name %.*s(%p) - flags %d/%x - refc %d\n", + name->len, name->name, dchild, + d_mountpoint(dchild), dchild->d_flags & DCACHE_LUSTRE_INVALID, + atomic_read(&dchild->d_count)); + + /* mountpoint is always valid */ + if (d_mountpoint(dchild)) + RETURN(0); + + if (dchild->d_flags & DCACHE_LUSTRE_INVALID) RETURN(1); - } + RETURN(0); } -#endif /* should NOT be called with the dcache lock, see fs/dcache.c */ static int ll_ddelete(struct dentry *de) @@ -277,17 +283,6 @@ restart: "ino=%lu\n", dentry, inode, inode->i_ino); lustre_dump_dentry(dentry, 1); libcfs_debug_dumpstack(NULL); - } else if (d_mountpoint(dentry)) { - /* For mountpoints we skip removal of the dentry - which happens solely because we have a lock on it - obtained when this dentry was not a mountpoint yet */ - CDEBUG(D_DENTRY, "Skippind mountpoint dentry removal " - "%.*s (%p) parent %p\n", - dentry->d_name.len, - dentry->d_name.name, - dentry, dentry->d_parent); - - continue; } if (ll_drop_dentry(dentry)) @@ -329,7 +324,7 @@ void ll_lookup_finish_locks(struct lookup_intent *it, struct dentry *dentry) CDEBUG(D_DLMTRACE, "setting l_data to inode %p (%lu/%u)\n", inode, inode->i_ino, inode->i_generation); md_set_lock_data(sbi->ll_md_exp, &it->d.lustre.it_lock_handle, - inode); + inode, NULL); } /* drop lookup or getattr locks immediately */ @@ -499,13 +494,6 @@ do_lock: if (rc != -ESTALE) { CDEBUG(D_INFO, "ll_intent_lock: rc %d : it->it_status " "%d\n", rc, it->d.lustre.it_status); - } else { -#ifndef HAVE_VFS_INTENT_PATCHES - if (it_disposition(it, DISP_OPEN_OPEN) && - !it_open_error(DISP_OPEN_OPEN, it)) - /* server have valid open - close file first*/ - ll_release_openhandle(de, it); -#endif } GOTO(out, rc = 0); } @@ -812,9 +800,7 @@ struct dentry_operations ll_d_ops = { .d_revalidate = ll_revalidate_nd, .d_release = ll_release, .d_delete = ll_ddelete, -#ifdef DCACHE_LUSTRE_INVALID .d_compare = ll_dcompare, -#endif #if 0 .d_pin = ll_pin, .d_unpin = ll_unpin, diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index de60208..3f393ae 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -307,7 +307,8 @@ struct page *ll_get_dir_page(struct inode *dir, __u64 hash, int exact, } else { /* for cross-ref object, l_ast_data of the lock may not be set, * we reset it here */ - md_set_lock_data(ll_i2sbi(dir)->ll_md_exp, &lockh.cookie, dir); + md_set_lock_data(ll_i2sbi(dir)->ll_md_exp, &lockh.cookie, + dir, NULL); } ldlm_lock_dump_handle(D_OTHER, &lockh); diff --git a/lustre/llite/file.c b/lustre/llite/file.c index e595d8f..48efb60 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -390,7 +390,7 @@ static int ll_intent_file_open(struct file *file, void *lmm, if (itp->d.lustre.it_lock_mode) md_set_lock_data(sbi->ll_md_exp, &itp->d.lustre.it_lock_handle, - file->f_dentry->d_inode); + file->f_dentry->d_inode, NULL); rc = ll_prep_inode(&file->f_dentry->d_inode, req, NULL); out: @@ -623,7 +623,7 @@ restart: } md_set_lock_data(ll_i2sbi(inode)->ll_md_exp, &it->d.lustre.it_lock_handle, - file->f_dentry->d_inode); + file->f_dentry->d_inode, NULL); goto restart; } OBD_ALLOC(*och_p, sizeof (struct obd_client_handle)); diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 2701b71..767b63c 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -52,6 +52,10 @@ #define FMODE_EXEC 0 #endif +#ifndef DCACHE_LUSTRE_INVALID +#define DCACHE_LUSTRE_INVALID 0x100 +#endif + #define LL_IT2STR(it) ((it) ? ldlm_it2str((it)->it_op) : "0") #define LUSTRE_FPRIVATE(file) ((file)->private_data) diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 491ae8f..91d35fa 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -154,9 +154,7 @@ void ll_free_sbi(struct super_block *sb) } static struct dentry_operations ll_d_root_ops = { -#ifdef DCACHE_LUSTRE_INVALID .d_compare = ll_dcompare, -#endif .d_revalidate = ll_revalidate_nd, }; diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c index ad0a8d6..a0befa4 100644 --- a/lustre/llite/namei.c +++ b/lustre/llite/namei.c @@ -376,9 +376,6 @@ static struct dentry *ll_find_alias(struct inode *inode, struct dentry *de) dget_locked(dentry); lock_dentry(dentry); __d_drop(dentry); -#ifdef DCACHE_LUSTRE_INVALID - dentry->d_flags &= ~DCACHE_LUSTRE_INVALID; -#endif unlock_dentry(dentry); ll_dops_init(dentry, 0); d_rehash_cond(dentry, 0); /* avoid taking dcache_lock inside */ @@ -396,6 +393,9 @@ static struct dentry *ll_find_alias(struct inode *inode, struct dentry *de) "refc %d\n", last_discon, last_discon->d_inode, atomic_read(&last_discon->d_count)); dget_locked(last_discon); + lock_dentry(last_discon); + last_discon->d_flags |= DCACHE_LUSTRE_INVALID; + unlock_dentry(last_discon); spin_unlock(&dcache_lock); spin_unlock(&ll_lookup_lock); ll_dops_init(last_discon, 1); @@ -404,7 +404,7 @@ static struct dentry *ll_find_alias(struct inode *inode, struct dentry *de) iput(inode); return last_discon; } - + de->d_flags |= DCACHE_LUSTRE_INVALID; ll_d_add(de, inode); spin_unlock(&dcache_lock); @@ -428,6 +428,7 @@ int ll_lookup_it_finish(struct ptlrpc_request *request, * 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); if (rc) @@ -436,7 +437,7 @@ int ll_lookup_it_finish(struct ptlrpc_request *request, CDEBUG(D_DLMTRACE, "setting l_data to inode %p (%lu/%u)\n", inode, inode->i_ino, inode->i_generation); md_set_lock_data(sbi->ll_md_exp, - &it->d.lustre.it_lock_handle, inode); + &it->d.lustre.it_lock_handle, inode, &bits); /* We used to query real size from OSTs here, but actually this is not needed. For stat() calls size would be updated @@ -460,6 +461,12 @@ int ll_lookup_it_finish(struct ptlrpc_request *request, lld->lld_sa_generation = 0; } } + /* 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 @@ -470,6 +477,12 @@ int ll_lookup_it_finish(struct ptlrpc_request *request, ll_d_add(*de, NULL); spin_unlock(&dcache_lock); } else { + /* negative lookup - and don't have update lock to + * parent */ + lock_dentry(*de); + (*de)->d_flags |= DCACHE_LUSTRE_INVALID; + unlock_dentry(*de); + (*de)->d_inode = NULL; /* We do not want to hash the dentry if don`t have a * lock, but if this dentry is later used in d_move, @@ -737,7 +750,7 @@ static struct inode *ll_create_node(struct inode *dir, const char *name, CDEBUG(D_DLMTRACE, "setting l_ast_data to inode %p (%lu/%u)\n", inode, inode->i_ino, inode->i_generation); md_set_lock_data(sbi->ll_md_exp, - &it->d.lustre.it_lock_handle, inode); + &it->d.lustre.it_lock_handle, inode, NULL); EXIT; out: ptlrpc_req_finished(request); diff --git a/lustre/lmv/lmv_obd.c b/lustre/lmv/lmv_obd.c index 49025ce..643f5b3 100644 --- a/lustre/lmv/lmv_obd.c +++ b/lustre/lmv/lmv_obd.c @@ -2745,13 +2745,15 @@ static int lmv_cancel_unused(struct obd_export *exp, const struct lu_fid *fid, RETURN(rc); } -int lmv_set_lock_data(struct obd_export *exp, __u64 *lockh, void *data) +int lmv_set_lock_data(struct obd_export *exp, __u64 *lockh, void *data, + __u32 *bits) { struct obd_device *obd = exp->exp_obd; struct lmv_obd *lmv = &obd->u.lmv; int rc; ENTRY; - rc = md_set_lock_data(lmv->tgts[0].ltd_exp, lockh, data); + + rc = md_set_lock_data(lmv->tgts[0].ltd_exp, lockh, data, bits); RETURN(rc); } diff --git a/lustre/mdc/mdc_internal.h b/lustre/mdc/mdc_internal.h index 85164a0..a80fa07 100644 --- a/lustre/mdc/mdc_internal.h +++ b/lustre/mdc/mdc_internal.h @@ -81,7 +81,7 @@ void mdc_exit_request(struct client_obd *cli); /* mdc/mdc_locks.c */ int mdc_set_lock_data(struct obd_export *exp, - __u64 *lockh, void *data); + __u64 *lockh, void *data, __u32 *bits); int mdc_change_cbdata(struct obd_export *exp, const struct lu_fid *fid, ldlm_iterator_t it, void *data); diff --git a/lustre/mdc/mdc_locks.c b/lustre/mdc/mdc_locks.c index cd7792e..8ab2f4b 100644 --- a/lustre/mdc/mdc_locks.c +++ b/lustre/mdc/mdc_locks.c @@ -111,11 +111,15 @@ int it_open_error(int phase, struct lookup_intent *it) EXPORT_SYMBOL(it_open_error); /* this must be called on a lockh that is known to have a referenced lock */ -int mdc_set_lock_data(struct obd_export *exp, __u64 *lockh, void *data) +int mdc_set_lock_data(struct obd_export *exp, __u64 *lockh, void *data, + __u32 *bits) { struct ldlm_lock *lock; ENTRY; + if(bits) + *bits = 0; + if (!*lockh) { EXIT; RETURN(0); @@ -138,6 +142,9 @@ int mdc_set_lock_data(struct obd_export *exp, __u64 *lockh, void *data) } #endif lock->l_ast_data = data; + if (bits) + *bits = lock->l_policy_data.l_inodebits.bits; + unlock_res_and_lock(lock); LDLM_LOCK_PUT(lock); -- 1.8.3.1