From 4e54535c857d73f8606d2b5446bad6a6c7a6c532 Mon Sep 17 00:00:00 2001 From: Fan Yong Date: Fri, 4 Nov 2011 00:40:32 +0800 Subject: [PATCH] ORNL-26 prevent call md_set_lock_data() repeatly md_set_lock_data() is called from different functions in llite, and may be called more than once for the same pair. It is harmless for the correctness, but will affect the performance a bit, should be avoided. Drop dentry flags of "DCACHE_LUSTRE_INVALID" only when we hold the "MDS_INODELOCK_LOOKUP" lock. Signed-off-by: Fan Yong Change-Id: I4dbe206af77ba6a619f3268c238ce98ac7aef4c0 Reviewed-on: http://review.whamcloud.com/1224 Tested-by: Hudson Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/include/liblustre.h | 4 +++- lustre/include/linux/lustre_intent.h | 5 +++++ lustre/include/obd.h | 2 +- lustre/include/obd_class.h | 2 +- lustre/llite/dcache.c | 9 ++++++--- lustre/llite/file.c | 5 ++--- lustre/llite/llite_internal.h | 17 ++++++++++++++++- lustre/llite/llite_lib.c | 9 +++++---- lustre/llite/namei.c | 20 +++++++++----------- lustre/lmv/lmv_obd.c | 2 +- lustre/mdc/mdc_internal.h | 5 ++++- lustre/mdc/mdc_locks.c | 6 ++---- 12 files changed, 55 insertions(+), 31 deletions(-) diff --git a/lustre/include/liblustre.h b/lustre/include/liblustre.h index f5eb5cd..a791d35 100644 --- a/lustre/include/liblustre.h +++ b/lustre/include/liblustre.h @@ -30,6 +30,9 @@ * Use is subject to license terms. */ /* + * Copyright (c) 2011 Whamcloud, Inc. + */ +/* * This file is part of Lustre, http://www.lustre.org/ * Lustre is a trademark of Sun Microsystems, Inc. * @@ -217,7 +220,6 @@ struct lustre_intent_data { __u64 it_lock_handle; void *it_data; int it_lock_mode; - int it_int_flags; }; struct lookup_intent { int it_magic; diff --git a/lustre/include/linux/lustre_intent.h b/lustre/include/linux/lustre_intent.h index 39b5a99..6014a19 100644 --- a/lustre/include/linux/lustre_intent.h +++ b/lustre/include/linux/lustre_intent.h @@ -30,6 +30,9 @@ * Use is subject to license terms. */ /* + * Copyright (c) 2011 Whamcloud, Inc. + */ +/* * This file is part of Lustre, http://www.lustre.org/ * Lustre is a trademark of Sun Microsystems, Inc. */ @@ -44,8 +47,10 @@ struct lustre_intent_data { int it_disposition; int it_status; __u64 it_lock_handle; + __u64 it_lock_bits; void *it_data; int it_lock_mode; + int it_lock_set:1; }; struct lookup_intent { diff --git a/lustre/include/obd.h b/lustre/include/obd.h index 666c949..3662683 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -1540,7 +1540,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 *, __u32 *); + int (*m_set_lock_data)(struct obd_export *, __u64 *, void *, __u64 *); 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 7a92a42..dda23e4 100644 --- a/lustre/include/obd_class.h +++ b/lustre/include/obd_class.h @@ -2130,7 +2130,7 @@ 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, __u32 *bits) + __u64 *lockh, void *data, __u64 *bits) { ENTRY; EXP_CHECK_MD_OP(exp, set_lock_data); diff --git a/lustre/llite/dcache.c b/lustre/llite/dcache.c index e87f554..cb24e66 100644 --- a/lustre/llite/dcache.c +++ b/lustre/llite/dcache.c @@ -375,8 +375,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, NULL); + ll_set_lock_data(sbi->ll_md_exp, inode, it, NULL); } /* drop lookup or getattr locks immediately */ @@ -582,11 +581,15 @@ out: /* done in ll_unhash_aliases() dentry->d_flags |= DCACHE_LUSTRE_INVALID; */ } else { + __u64 bits = 0; + 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)); - if (de->d_flags & DCACHE_LUSTRE_INVALID) { + ll_set_lock_data(exp, de->d_inode, it, &bits); + if (de->d_flags & DCACHE_LUSTRE_INVALID && + bits & MDS_INODELOCK_LOOKUP) { lock_dentry(de); de->d_flags &= ~DCACHE_LUSTRE_INVALID; unlock_dentry(de); diff --git a/lustre/llite/file.c b/lustre/llite/file.c index cb036bf..cb55e3f 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -401,9 +401,8 @@ static int ll_intent_file_open(struct file *file, void *lmm, rc = ll_prep_inode(&file->f_dentry->d_inode, req, NULL); if (!rc && 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, NULL); + ll_set_lock_data(sbi->ll_md_exp, file->f_dentry->d_inode, + itp, NULL); out: ptlrpc_req_finished(itp->d.lustre.it_data); diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 755c708..fd2e04a 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -51,6 +51,7 @@ #include #include #include +#include #ifndef FMODE_EXEC #define FMODE_EXEC 0 @@ -135,7 +136,6 @@ struct ll_inode_info { __u64 lli_maxbytes; __u64 lli_ioepoch; unsigned long lli_flags; - cfs_time_t lli_contention_time; /* this lock protects posix_acl, pending_write_llaps, mmap_cnt */ cfs_spinlock_t lli_lock; @@ -1339,6 +1339,21 @@ static inline int ll_file_nolock(const struct file *file) (ll_i2sbi(inode)->ll_flags & LL_SBI_NOLCK)); } +static inline void ll_set_lock_data(struct obd_export *exp, struct inode *inode, + struct lookup_intent *it, __u64 *bits) +{ + if (!it->d.lustre.it_lock_set) { + CDEBUG(D_DLMTRACE, "setting l_data to inode %p (%lu/%u)\n", + inode, inode->i_ino, inode->i_generation); + md_set_lock_data(exp, &it->d.lustre.it_lock_handle, + inode, &it->d.lustre.it_lock_bits); + it->d.lustre.it_lock_set = 1; + } + + if (bits != NULL) + *bits = it->d.lustre.it_lock_bits; +} + #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2,7,50,0) /* Compatibility for old (1.8) compiled userspace quota code */ struct if_quotactl_18 { diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 2a0d78a..9fd4b1a 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -140,8 +140,8 @@ static struct ll_sb_info *ll_init_sbi(void) /* metadata statahead is enabled by default */ sbi->ll_sa_max = LL_SA_RPC_DEF; - atomic_set(&sbi->ll_sa_total, 0); - atomic_set(&sbi->ll_sa_wrong, 0); + cfs_atomic_set(&sbi->ll_sa_total, 0); + cfs_atomic_set(&sbi->ll_sa_wrong, 0); RETURN(sbi); } @@ -874,6 +874,7 @@ 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); + lli->lli_clob = NULL; cfs_sema_init(&lli->lli_readdir_sem, 1); fid_zero(&lli->lli_pfid); } @@ -1724,8 +1725,8 @@ void ll_read_inode2(struct inode *inode, void *opaque) struct ll_inode_info *lli = ll_i2info(inode); ENTRY; - CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n", - inode->i_ino, inode->i_generation, inode); + CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p)\n", + PFID(&lli->lli_fid), inode); ll_lli_init(lli); diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c index 783283c..26c5e6ee 100644 --- a/lustre/llite/namei.c +++ b/lustre/llite/namei.c @@ -132,10 +132,12 @@ struct inode *ll_iget(struct super_block *sb, ino_t hash, if (inode) { if (inode->i_state & I_NEW) { - int rc; + int rc = 0; ll_read_inode2(inode, md); - rc = cl_inode_init(inode, md); + if (S_ISREG(inode->i_mode) && + ll_i2info(inode)->lli_clob == NULL) + rc = cl_inode_init(inode, md); if (rc != 0) { md->lsm = NULL; make_bad_inode(inode); @@ -430,7 +432,6 @@ int ll_lookup_it_finish(struct ptlrpc_request *request, struct it_cb_data *icbd = data; struct dentry **de = icbd->icbd_childp; struct inode *parent = icbd->icbd_parent; - struct ll_sb_info *sbi = ll_i2sbi(parent); struct inode *inode = NULL; int rc; ENTRY; @@ -439,16 +440,13 @@ 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; + __u64 bits = 0; rc = ll_prep_inode(&inode, request, (*de)->d_sb); if (rc) RETURN(rc); - 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, &bits); + ll_set_lock_data(ll_i2sbi(parent)->ll_md_exp, inode, it, &bits); /* We used to query real size from OSTs here, but actually this is not needed. For stat() calls size would be updated @@ -468,7 +466,8 @@ int ll_lookup_it_finish(struct ptlrpc_request *request, ll_dops_init(*de, 1, 1); } /* we have lookup look - unhide dentry */ - if (bits & MDS_INODELOCK_LOOKUP) { + if ((*de)->d_flags & DCACHE_LUSTRE_INVALID && + bits & MDS_INODELOCK_LOOKUP) { lock_dentry(*de); (*de)->d_flags &= ~DCACHE_LUSTRE_INVALID; unlock_dentry(*de); @@ -748,8 +747,7 @@ static struct inode *ll_create_node(struct inode *dir, const char *name, * stuff it in the lock. */ 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, NULL); + ll_set_lock_data(sbi->ll_md_exp, inode, it, NULL); EXIT; out: ptlrpc_req_finished(request); diff --git a/lustre/lmv/lmv_obd.c b/lustre/lmv/lmv_obd.c index d2df3ca..380c6d7 100644 --- a/lustre/lmv/lmv_obd.c +++ b/lustre/lmv/lmv_obd.c @@ -2885,7 +2885,7 @@ static int lmv_cancel_unused(struct obd_export *exp, const struct lu_fid *fid, } int lmv_set_lock_data(struct obd_export *exp, __u64 *lockh, void *data, - __u32 *bits) + __u64 *bits) { struct obd_device *obd = exp->exp_obd; struct lmv_obd *lmv = &obd->u.lmv; diff --git a/lustre/mdc/mdc_internal.h b/lustre/mdc/mdc_internal.h index d2711ad..353f295 100644 --- a/lustre/mdc/mdc_internal.h +++ b/lustre/mdc/mdc_internal.h @@ -28,6 +28,9 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. + * + * Copyright (c) 2011 Whamcloud, Inc. + * */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -79,7 +82,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, __u32 *bits); + __u64 *lockh, void *data, __u64 *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 3216fb1..4d496cf 100644 --- a/lustre/mdc/mdc_locks.c +++ b/lustre/mdc/mdc_locks.c @@ -118,7 +118,7 @@ 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, - __u32 *bits) + __u64 *bits) { struct ldlm_lock *lock; ENTRY; @@ -126,10 +126,8 @@ int mdc_set_lock_data(struct obd_export *exp, __u64 *lockh, void *data, if(bits) *bits = 0; - if (!*lockh) { - EXIT; + if (!*lockh) RETURN(0); - } lock = ldlm_handle2lock((struct lustre_handle *)lockh); -- 1.8.3.1