Whamcloud - gitweb
ORNL-26 prevent call md_set_lock_data() repeatly
authorFan Yong <yong.fan@whamcloud.com>
Thu, 3 Nov 2011 16:40:32 +0000 (00:40 +0800)
committerOleg Drokin <green@whamcloud.com>
Fri, 4 Nov 2011 01:34:59 +0000 (21:34 -0400)
md_set_lock_data() is called from different functions in llite, and
may be called more than once for the same <inode lock> 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 <yong.fan@whamcloud.com>
Change-Id: I4dbe206af77ba6a619f3268c238ce98ac7aef4c0
Reviewed-on: http://review.whamcloud.com/1224
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
12 files changed:
lustre/include/liblustre.h
lustre/include/linux/lustre_intent.h
lustre/include/obd.h
lustre/include/obd_class.h
lustre/llite/dcache.c
lustre/llite/file.c
lustre/llite/llite_internal.h
lustre/llite/llite_lib.c
lustre/llite/namei.c
lustre/lmv/lmv_obd.c
lustre/mdc/mdc_internal.h
lustre/mdc/mdc_locks.c

index f5eb5cd..a791d35 100644 (file)
@@ -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;
index 39b5a99..6014a19 100644 (file)
@@ -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 {
index 666c949..3662683 100644 (file)
@@ -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,
index 7a92a42..dda23e4 100644 (file)
@@ -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);
index e87f554..cb24e66 100644 (file)
@@ -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);
index cb036bf..cb55e3f 100644 (file)
@@ -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);
index 755c708..fd2e04a 100644 (file)
@@ -51,6 +51,7 @@
 #include <cl_object.h>
 #include <lclient.h>
 #include <lustre_mdc.h>
+#include <linux/lustre_intent.h>
 
 #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 {
index 2a0d78a..9fd4b1a 100644 (file)
@@ -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);
 
index 783283c..26c5e6e 100644 (file)
@@ -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);
index d2df3ca..380c6d7 100644 (file)
@@ -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;
index d2711ad..353f295 100644 (file)
@@ -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);
index 3216fb1..4d496cf 100644 (file)
@@ -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);