Whamcloud - gitweb
b=20433 decrease the usage of memory on clients.
authorLanden <landen@sun.com>
Tue, 30 Mar 2010 22:45:10 +0000 (15:45 -0700)
committerRobert Read <rread@sun.com>
Tue, 30 Mar 2010 22:45:10 +0000 (15:45 -0700)
1. On clients, recycle dentries and inodes unused.
2. Delete the code related to ll_deathrow(att 6215 in bug 1443). It
   is useless now.

i=robert.read
i=vladimir.saveliev

18 files changed:
lustre/ChangeLog
lustre/autoconf/lustre-core.m4
lustre/include/lustre_dlm.h
lustre/include/obd.h
lustre/include/obd_class.h
lustre/ldlm/ldlm_request.c
lustre/llite/dcache.c
lustre/llite/llite_internal.h
lustre/llite/llite_lib.c
lustre/llite/namei.c
lustre/lmv/lmv_obd.c
lustre/lov/lov_obd.c
lustre/mdc/mdc_internal.h
lustre/mdc/mdc_locks.c
lustre/mdc/mdc_request.c
lustre/obdclass/lprocfs_status.c
lustre/osc/osc_request.c
lustre/tests/sanity.sh

index a8c165f..9f49d6a 100644 (file)
@@ -2424,6 +2424,13 @@ Details    : In ptlrpc_retain_replayable_request if we cannot find retained
              request with tid smaller then one currently being added, add it
             to the start, not end of the list.
 
              request with tid smaller then one currently being added, add it
             to the start, not end of the list.
 
+Severity   : normal
+Bugzilla   : 20433
+Description: decrease the usage of memory on clients.
+Details    : 1. On clients, recycle dentries and inodes unused.
+            2. Delete the code related to ll_deathrow(att 6215 in bug 1443). It
+               is useless now.
+
 --------------------------------------------------------------------------------
 
 2007-08-10         Cluster File Systems, Inc. <info@clusterfs.com>
 --------------------------------------------------------------------------------
 
 2007-08-10         Cluster File Systems, Inc. <info@clusterfs.com>
index fb5d062..337e404 100644 (file)
@@ -439,18 +439,6 @@ AC_MSG_RESULT([no])
 ])
 
 #
 ])
 
 #
-# LC_EXPORT___IGET
-# starting from 2.6.19 linux kernel exports __iget()
-#
-AC_DEFUN([LC_EXPORT___IGET],
-[LB_CHECK_SYMBOL_EXPORT([__iget],
-[fs/inode.c],[
-        AC_DEFINE(HAVE_EXPORT___IGET, 1, [kernel exports __iget])
-],[
-])
-])
-
-#
 # only for Lustre-patched kernels
 #
 AC_DEFUN([LC_LUSTRE_VERSION_H],
 # only for Lustre-patched kernels
 #
 AC_DEFUN([LC_LUSTRE_VERSION_H],
index 0b175f2..200ebb8 100644 (file)
@@ -857,7 +857,7 @@ int ldlm_namespace_foreach_res(struct ldlm_namespace *ns,
                                ldlm_res_iterator_t iter, void *closure);
 
 int ldlm_replay_locks(struct obd_import *imp);
                                ldlm_res_iterator_t iter, void *closure);
 
 int ldlm_replay_locks(struct obd_import *imp);
-void ldlm_resource_iterate(struct ldlm_namespace *, const struct ldlm_res_id *,
+int ldlm_resource_iterate(struct ldlm_namespace *, const struct ldlm_res_id *,
                            ldlm_iterator_t iter, void *data);
 
 /* ldlm_flock.c */
                            ldlm_iterator_t iter, void *data);
 
 /* ldlm_flock.c */
index 65e4706..81e86dc 100644 (file)
@@ -1365,6 +1365,8 @@ struct obd_ops {
                          struct ptlrpc_request_set *rqset);
         int (*o_change_cbdata)(struct obd_export *, struct lov_stripe_md *,
                                ldlm_iterator_t it, void *data);
                          struct ptlrpc_request_set *rqset);
         int (*o_change_cbdata)(struct obd_export *, struct lov_stripe_md *,
                                ldlm_iterator_t it, void *data);
+        int (*o_find_cbdata)(struct obd_export *, struct lov_stripe_md *,
+                             ldlm_iterator_t it, void *data);
         int (*o_cancel)(struct obd_export *, struct lov_stripe_md *md,
                         __u32 mode, struct lustre_handle *);
         int (*o_cancel_unused)(struct obd_export *, struct lov_stripe_md *,
         int (*o_cancel)(struct obd_export *, struct lov_stripe_md *md,
                         __u32 mode, struct lustre_handle *);
         int (*o_cancel_unused)(struct obd_export *, struct lov_stripe_md *,
@@ -1464,6 +1466,8 @@ struct md_ops {
                            struct obd_capa **);
         int (*m_change_cbdata)(struct obd_export *, const struct lu_fid *,
                                ldlm_iterator_t, void *);
                            struct obd_capa **);
         int (*m_change_cbdata)(struct obd_export *, const struct lu_fid *,
                                ldlm_iterator_t, void *);
+        int (*m_find_cbdata)(struct obd_export *, const struct lu_fid *,
+                             ldlm_iterator_t, void *);
         int (*m_close)(struct obd_export *, struct md_op_data *,
                        struct md_open_data *, struct ptlrpc_request **);
         int (*m_create)(struct obd_export *, struct md_op_data *,
         int (*m_close)(struct obd_export *, struct md_op_data *,
                        struct md_open_data *, struct ptlrpc_request **);
         int (*m_create)(struct obd_export *, struct md_op_data *,
index 94b8950..7bd0b5e 100644 (file)
@@ -1422,6 +1422,20 @@ static inline int obd_change_cbdata(struct obd_export *exp,
         RETURN(rc);
 }
 
         RETURN(rc);
 }
 
+static inline int obd_find_cbdata(struct obd_export *exp,
+                                  struct lov_stripe_md *lsm,
+                                  ldlm_iterator_t it, void *data)
+{
+        int rc;
+        ENTRY;
+
+        EXP_CHECK_DT_OP(exp, find_cbdata);
+        EXP_COUNTER_INCREMENT(exp, find_cbdata);
+
+        rc = OBP(exp->exp_obd, find_cbdata)(exp, lsm, it, data);
+        RETURN(rc);
+}
+
 static inline int obd_cancel(struct obd_export *exp,
                              struct lov_stripe_md *ea, __u32 mode,
                              struct lustre_handle *lockh)
 static inline int obd_cancel(struct obd_export *exp,
                              struct lov_stripe_md *ea, __u32 mode,
                              struct lustre_handle *lockh)
@@ -1775,6 +1789,18 @@ static inline int md_change_cbdata(struct obd_export *exp,
         RETURN(rc);
 }
 
         RETURN(rc);
 }
 
+static inline int md_find_cbdata(struct obd_export *exp,
+                                 const struct lu_fid *fid,
+                                 ldlm_iterator_t it, void *data)
+{
+        int rc;
+        ENTRY;
+        EXP_CHECK_MD_OP(exp, find_cbdata);
+        EXP_MD_COUNTER_INCREMENT(exp, find_cbdata);
+        rc = MDP(exp->exp_obd, find_cbdata)(exp, fid, it, data);
+        RETURN(rc);
+}
+
 static inline int md_close(struct obd_export *exp, struct md_op_data *op_data,
                            struct md_open_data *mod,
                            struct ptlrpc_request **request)
 static inline int md_close(struct obd_export *exp, struct md_op_data *op_data,
                            struct md_open_data *mod,
                            struct ptlrpc_request **request)
index 6e70bf6..7a9e5bb 100644 (file)
@@ -1916,12 +1916,17 @@ int ldlm_namespace_foreach_res(struct ldlm_namespace *ns,
         RETURN(rc);
 }
 
         RETURN(rc);
 }
 
-/* non-blocking function to manipulate a lock whose cb_data is being put away.*/
-void ldlm_resource_iterate(struct ldlm_namespace *ns,
-                           const struct ldlm_res_id *res_id,
-                           ldlm_iterator_t iter, void *data)
+/* non-blocking function to manipulate a lock whose cb_data is being put away.
+ * return  0:  find no resource
+ *       > 0:  must be LDLM_ITER_STOP/LDLM_ITER_CONTINUE.
+ *       < 0:  errors
+ */
+int ldlm_resource_iterate(struct ldlm_namespace *ns,
+                          const struct ldlm_res_id *res_id,
+                          ldlm_iterator_t iter, void *data)
 {
         struct ldlm_resource *res;
 {
         struct ldlm_resource *res;
+        int rc;
         ENTRY;
 
         if (ns == NULL) {
         ENTRY;
 
         if (ns == NULL) {
@@ -1930,16 +1935,14 @@ void ldlm_resource_iterate(struct ldlm_namespace *ns,
         }
 
         res = ldlm_resource_get(ns, NULL, res_id, 0, 0);
         }
 
         res = ldlm_resource_get(ns, NULL, res_id, 0, 0);
-        if (res == NULL) {
-                EXIT;
-                return;
-        }
+        if (res == NULL)
+                RETURN(0);
 
         LDLM_RESOURCE_ADDREF(res);
 
         LDLM_RESOURCE_ADDREF(res);
-        ldlm_resource_foreach(res, iter, data);
+        rc = ldlm_resource_foreach(res, iter, data);
         LDLM_RESOURCE_DELREF(res);
         ldlm_resource_putref(res);
         LDLM_RESOURCE_DELREF(res);
         ldlm_resource_putref(res);
-        EXIT;
+        RETURN(rc);
 }
 
 /* Lock replay */
 }
 
 /* Lock replay */
index f503b01..de07cca 100644 (file)
@@ -114,6 +114,35 @@ int ll_dcompare(struct dentry *parent, struct qstr *d_name, struct qstr *name)
         RETURN(0);
 }
 
         RETURN(0);
 }
 
+static inline int return_if_equal(struct ldlm_lock *lock, void *data)
+{
+        return LDLM_ITER_STOP;
+}
+
+/* find any ldlm lock of the inode in mdc and lov
+ * return 0    not find
+ *        1    find one
+ *      < 0    error */
+static int find_cbdata(struct inode *inode)
+{
+        struct ll_inode_info *lli = ll_i2info(inode);
+        struct ll_sb_info *sbi = ll_i2sbi(inode);
+        int rc = 0;
+        ENTRY;
+
+        LASSERT(inode);
+        rc = md_find_cbdata(sbi->ll_md_exp, ll_inode2fid(inode),
+                            return_if_equal, NULL);
+        if (rc != 0)
+                 RETURN(rc);
+
+        if (lli->lli_smd)
+                rc = obd_find_cbdata(sbi->ll_dt_exp, lli->lli_smd,
+                                     return_if_equal, NULL);
+
+        RETURN(rc);
+}
+
 /* should NOT be called with the dcache lock, see fs/dcache.c */
 static int ll_ddelete(struct dentry *de)
 {
 /* should NOT be called with the dcache lock, see fs/dcache.c */
 static int ll_ddelete(struct dentry *de)
 {
@@ -126,6 +155,15 @@ static int ll_ddelete(struct dentry *de)
                d_unhashed(de) ? "" : "hashed,",
                list_empty(&de->d_subdirs) ? "" : "subdirs");
 
                d_unhashed(de) ? "" : "hashed,",
                list_empty(&de->d_subdirs) ? "" : "subdirs");
 
+        /* if not ldlm lock for this inode, set i_nlink to 0 so that
+         * this inode can be recycled later b=20433 */
+        LASSERT(atomic_read(&de->d_count) == 0);
+        if (de->d_inode && !find_cbdata(de->d_inode))
+                de->d_inode->i_nlink = 0;
+
+        if (de->d_flags & DCACHE_LUSTRE_INVALID)
+                RETURN(1);
+
         RETURN(0);
 }
 
         RETURN(0);
 }
 
@@ -787,10 +825,19 @@ out_it:
 }
 #endif
 
 }
 #endif
 
+void ll_d_iput(struct dentry *de, struct inode *inode)
+{
+        LASSERT(inode);
+        if (!find_cbdata(inode))
+                inode->i_nlink = 0;
+        iput(inode);
+}
+
 struct dentry_operations ll_d_ops = {
         .d_revalidate = ll_revalidate_nd,
         .d_release = ll_release,
 struct dentry_operations ll_d_ops = {
         .d_revalidate = ll_revalidate_nd,
         .d_release = ll_release,
-        .d_delete = ll_ddelete,
+        .d_delete  = ll_ddelete,
+        .d_iput    = ll_d_iput,
         .d_compare = ll_dcompare,
 #if 0
         .d_pin = ll_pin,
         .d_compare = ll_dcompare,
 #if 0
         .d_pin = ll_pin,
index 9741c44..1d59daf 100644 (file)
@@ -368,10 +368,6 @@ struct ll_sb_info {
         unsigned int              ll_namelen;
         struct file_operations   *ll_fop;
 
         unsigned int              ll_namelen;
         struct file_operations   *ll_fop;
 
-#ifdef HAVE_EXPORT___IGET
-        cfs_list_t                ll_deathrow;/*inodes to be destroyed (b1443)*/
-        cfs_spinlock_t            ll_deathrow_lock;
-#endif
         /* =0 - hold lock over whole read/write
          * >0 - max. chunk to be read/written w/o lock re-acquiring */
         unsigned long             ll_max_rw_chunk;
         /* =0 - hold lock over whole read/write
          * >0 - max. chunk to be read/written w/o lock re-acquiring */
         unsigned long             ll_max_rw_chunk;
index 59a1ce5..4658c10 100644 (file)
@@ -124,10 +124,6 @@ static struct ll_sb_info *ll_init_sbi(void)
         sbi->ll_flags |= LL_SBI_LRU_RESIZE;
 #endif
 
         sbi->ll_flags |= LL_SBI_LRU_RESIZE;
 #endif
 
-#ifdef HAVE_EXPORT___IGET
-        CFS_INIT_LIST_HEAD(&sbi->ll_deathrow);
-        cfs_spin_lock_init(&sbi->ll_deathrow_lock);
-#endif
         for (i = 0; i <= LL_PROCESS_HIST_MAX; i++) {
                 cfs_spin_lock_init(&sbi->ll_rw_extents_info.pp_extents[i]. \
                                    pp_r_hist.oh_lock);
         for (i = 0; i <= LL_PROCESS_HIST_MAX; i++) {
                 cfs_spin_lock_init(&sbi->ll_rw_extents_info.pp_extents[i]. \
                                    pp_r_hist.oh_lock);
@@ -581,104 +577,6 @@ void lustre_dump_dentry(struct dentry *dentry, int recur)
         }
 }
 
         }
 }
 
-#ifdef HAVE_EXPORT___IGET
-static void prune_dir_dentries(struct inode *inode)
-{
-        struct dentry *dentry, *prev = NULL;
-
-        /* due to lustre specific logic, a directory
-         * can have few dentries - a bug from VFS POV */
-restart:
-        spin_lock(&dcache_lock);
-        if (!list_empty(&inode->i_dentry)) {
-                dentry = list_entry(inode->i_dentry.prev,
-                                    struct dentry, d_alias);
-                /* in order to prevent infinite loops we
-                 * break if previous dentry is busy */
-                if (dentry != prev) {
-                        prev = dentry;
-                        dget_locked(dentry);
-                        spin_unlock(&dcache_lock);
-
-                        /* try to kill all child dentries */
-                        lock_dentry(dentry);
-                        shrink_dcache_parent(dentry);
-                        unlock_dentry(dentry);
-                        dput(dentry);
-
-                        /* now try to get rid of current dentry */
-                        d_prune_aliases(inode);
-                        goto restart;
-                }
-        }
-        spin_unlock(&dcache_lock);
-}
-
-static void prune_deathrow_one(struct ll_inode_info *lli)
-{
-        struct inode *inode = ll_info2i(lli);
-
-        /* first, try to drop any dentries - they hold a ref on the inode */
-        if (S_ISDIR(inode->i_mode))
-                prune_dir_dentries(inode);
-        else
-                d_prune_aliases(inode);
-
-
-        /* if somebody still uses it, leave it */
-        LASSERT(atomic_read(&inode->i_count) > 0);
-        if (atomic_read(&inode->i_count) > 1)
-                goto out;
-
-        CDEBUG(D_INODE, "inode %lu/%u(%d) looks a good candidate for prune\n",
-               inode->i_ino,inode->i_generation,
-               atomic_read(&inode->i_count));
-
-        /* seems nobody uses it anymore */
-        inode->i_nlink = 0;
-
-out:
-        iput(inode);
-        return;
-}
-
-static void prune_deathrow(struct ll_sb_info *sbi, int try)
-{
-        struct ll_inode_info *lli;
-        int empty;
-
-        do {
-                if (need_resched() && try)
-                        break;
-
-                if (try) {
-                        if (!cfs_spin_trylock(&sbi->ll_deathrow_lock))
-                                break;
-                } else {
-                        cfs_spin_lock(&sbi->ll_deathrow_lock);
-                }
-
-                empty = 1;
-                lli = NULL;
-                if (!cfs_list_empty(&sbi->ll_deathrow)) {
-                        lli = cfs_list_entry(sbi->ll_deathrow.next,
-                                             struct ll_inode_info,
-                                             lli_dead_list);
-                        cfs_list_del_init(&lli->lli_dead_list);
-                        if (!cfs_list_empty(&sbi->ll_deathrow))
-                                empty = 0;
-                }
-                cfs_spin_unlock(&sbi->ll_deathrow_lock);
-
-                if (lli)
-                        prune_deathrow_one(lli);
-
-        } while (empty == 0);
-}
-#else /* !HAVE_EXPORT___IGET */
-#define prune_deathrow(sbi, try) do {} while (0)
-#endif /* HAVE_EXPORT___IGET */
-
 void client_common_put_super(struct super_block *sb)
 {
         struct ll_sb_info *sbi = ll_s2sbi(sb);
 void client_common_put_super(struct super_block *sb)
 {
         struct ll_sb_info *sbi = ll_s2sbi(sb);
@@ -697,9 +595,6 @@ void client_common_put_super(struct super_block *sb)
 
         cl_sb_fini(sb);
 
 
         cl_sb_fini(sb);
 
-        /* destroy inodes in deathrow */
-        prune_deathrow(sbi, 0);
-
         cfs_list_del(&sbi->ll_conn_chain);
 
         obd_fid_fini(sbi->ll_dt_exp);
         cfs_list_del(&sbi->ll_conn_chain);
 
         obd_fid_fini(sbi->ll_dt_exp);
@@ -1128,11 +1023,6 @@ void ll_clear_inode(struct inode *inode)
 #endif
         lli->lli_inode_magic = LLI_INODE_DEAD;
 
 #endif
         lli->lli_inode_magic = LLI_INODE_DEAD;
 
-#ifdef HAVE_EXPORT___IGET
-        cfs_spin_lock(&sbi->ll_deathrow_lock);
-        cfs_list_del_init(&lli->lli_dead_list);
-        cfs_spin_unlock(&sbi->ll_deathrow_lock);
-#endif
         ll_clear_inode_capas(inode);
         /*
          * XXX This has to be done before lsm is freed below, because
         ll_clear_inode_capas(inode);
         /*
          * XXX This has to be done before lsm is freed below, because
@@ -2002,7 +1892,6 @@ int ll_prep_inode(struct inode **inode,
 
         LASSERT(*inode || sb);
         sbi = sb ? ll_s2sbi(sb) : ll_i2sbi(*inode);
 
         LASSERT(*inode || sb);
         sbi = sb ? ll_s2sbi(sb) : ll_i2sbi(*inode);
-        prune_deathrow(sbi, 1);
         memset(&md, 0, sizeof(struct lustre_md));
 
         rc = md_get_lustre_md(sbi->ll_md_exp, req, sbi->ll_dt_exp,
         memset(&md, 0, sizeof(struct lustre_md));
 
         rc = md_get_lustre_md(sbi->ll_md_exp, req, sbi->ll_dt_exp,
index 9eecc1f..27d194b 100644 (file)
@@ -1161,6 +1161,10 @@ int ll_objects_destroy(struct ptlrpc_request *request, struct inode *dir)
         return rc;
 }
 
         return rc;
 }
 
+/* ll_unlink_generic() doesn't update the inode with the new link count.
+ * Instead, ll_ddelete() and ll_d_iput() will update it based upon if there
+ * is any lock existing. They will recycle dentries and inodes based upon locks
+ * too. b=20433 */
 static int ll_unlink_generic(struct inode *dir, struct dentry *dparent,
                              struct dentry *dchild, struct qstr *name)
 {
 static int ll_unlink_generic(struct inode *dir, struct dentry *dparent,
                              struct dentry *dchild, struct qstr *name)
 {
index e4af062..9ab8bc9 100644 (file)
@@ -1368,6 +1368,36 @@ static int lmv_change_cbdata(struct obd_export *exp, const struct lu_fid *fid,
         RETURN(0);
 }
 
         RETURN(0);
 }
 
+static int lmv_find_cbdata(struct obd_export *exp, const struct lu_fid *fid,
+                           ldlm_iterator_t it, void *data)
+{
+        struct obd_device   *obd = exp->exp_obd;
+        struct lmv_obd      *lmv = &obd->u.lmv;
+        int                  i;
+        int                  rc;
+        ENTRY;
+
+        rc = lmv_check_connect(obd);
+        if (rc)
+                RETURN(rc);
+
+        CDEBUG(D_INODE, "CBDATA for "DFID"\n", PFID(fid));
+
+        /*
+         * With CMD every object can have two locks in different namespaces:
+         * lookup lock in space of mds storing direntry and update/open lock in
+         * space of mds storing inode.
+         */
+        for (i = 0; i < lmv->desc.ld_tgt_count; i++) {
+                rc = md_find_cbdata(lmv->tgts[i].ltd_exp, fid, it, data);
+                if (rc)
+                        RETURN(rc);
+        }
+
+        RETURN(rc);
+}
+
+
 static int lmv_close(struct obd_export *exp, struct md_op_data *op_data,
                      struct md_open_data *mod, struct ptlrpc_request **request)
 {
 static int lmv_close(struct obd_export *exp, struct md_op_data *op_data,
                      struct md_open_data *mod, struct ptlrpc_request **request)
 {
@@ -3012,6 +3042,7 @@ struct obd_ops lmv_obd_ops = {
 struct md_ops lmv_md_ops = {
         .m_getstatus            = lmv_getstatus,
         .m_change_cbdata        = lmv_change_cbdata,
 struct md_ops lmv_md_ops = {
         .m_getstatus            = lmv_getstatus,
         .m_change_cbdata        = lmv_change_cbdata,
+        .m_find_cbdata          = lmv_find_cbdata,
         .m_close                = lmv_close,
         .m_create               = lmv_create,
         .m_done_writing         = lmv_done_writing,
         .m_close                = lmv_close,
         .m_create               = lmv_create,
         .m_done_writing         = lmv_done_writing,
index 0d096fd..c1f91bc 100644 (file)
@@ -1747,6 +1747,46 @@ static int lov_change_cbdata(struct obd_export *exp,
         RETURN(rc);
 }
 
         RETURN(rc);
 }
 
+/* find any ldlm lock of the inode in lov
+ * return 0    not find
+ *        1    find one
+ *      < 0    error */
+static int lov_find_cbdata(struct obd_export *exp,
+                           struct lov_stripe_md *lsm, ldlm_iterator_t it,
+                           void *data)
+{
+        struct lov_obd *lov;
+        int rc = 0, i;
+        ENTRY;
+
+        ASSERT_LSM_MAGIC(lsm);
+
+        if (!exp || !exp->exp_obd)
+                RETURN(-ENODEV);
+
+        LASSERT_MDS_GROUP(lsm->lsm_object_gr);
+
+        lov = &exp->exp_obd->u.lov;
+        for (i = 0; i < lsm->lsm_stripe_count; i++) {
+                struct lov_stripe_md submd;
+                struct lov_oinfo *loi = lsm->lsm_oinfo[i];
+
+                if (!lov->lov_tgts[loi->loi_ost_idx]) {
+                        CDEBUG(D_HA, "lov idx %d NULL \n", loi->loi_ost_idx);
+                        continue;
+                }
+
+                submd.lsm_object_id = loi->loi_id;
+                submd.lsm_object_gr = loi->loi_gr;
+                submd.lsm_stripe_count = 0;
+                rc = obd_find_cbdata(lov->lov_tgts[loi->loi_ost_idx]->ltd_exp,
+                                     &submd, it, data);
+                if (rc != 0)
+                        RETURN(rc);
+        }
+        RETURN(rc);
+}
+
 static int lov_cancel(struct obd_export *exp, struct lov_stripe_md *lsm,
                       __u32 mode, struct lustre_handle *lockh)
 {
 static int lov_cancel(struct obd_export *exp, struct lov_stripe_md *lsm,
                       __u32 mode, struct lustre_handle *lockh)
 {
@@ -2739,6 +2779,7 @@ struct obd_ops lov_obd_ops = {
         .o_sync                = lov_sync,
         .o_enqueue             = lov_enqueue,
         .o_change_cbdata       = lov_change_cbdata,
         .o_sync                = lov_sync,
         .o_enqueue             = lov_enqueue,
         .o_change_cbdata       = lov_change_cbdata,
+        .o_find_cbdata         = lov_find_cbdata,
         .o_cancel              = lov_cancel,
         .o_cancel_unused       = lov_cancel_unused,
         .o_iocontrol           = lov_iocontrol,
         .o_cancel              = lov_cancel,
         .o_cancel_unused       = lov_cancel_unused,
         .o_iocontrol           = lov_iocontrol,
index 2918f54..5e38c50 100644 (file)
@@ -84,6 +84,9 @@ int mdc_set_lock_data(struct obd_export *exp,
 int mdc_change_cbdata(struct obd_export *exp, const struct lu_fid *fid,
                       ldlm_iterator_t it, void *data);
 
 int mdc_change_cbdata(struct obd_export *exp, const struct lu_fid *fid,
                       ldlm_iterator_t it, void *data);
 
+int mdc_find_cbdata(struct obd_export *exp, const struct lu_fid *fid,
+                    ldlm_iterator_t it, void *data);
+
 int mdc_intent_lock(struct obd_export *exp,
                     struct md_op_data *,
                     void *lmm, int lmmsize,
 int mdc_intent_lock(struct obd_export *exp,
                     struct md_op_data *,
                     void *lmm, int lmmsize,
index a206d15..f2f23d1 100644 (file)
@@ -198,6 +198,28 @@ int mdc_change_cbdata(struct obd_export *exp,
         return 0;
 }
 
         return 0;
 }
 
+/* find any ldlm lock of the inode in mdc
+ * return 0    not find
+ *        1    find one
+ *      < 0    error */
+int mdc_find_cbdata(struct obd_export *exp,
+                    const struct lu_fid *fid,
+                    ldlm_iterator_t it, void *data)
+{
+        struct ldlm_res_id res_id;
+        int rc = 0;
+        ENTRY;
+
+        fid_build_reg_res_name((struct lu_fid*)fid, &res_id);
+        rc = ldlm_resource_iterate(class_exp2obd(exp)->obd_namespace, &res_id,
+                                   it, data);
+        if (rc == LDLM_ITER_STOP)
+                RETURN(1);
+        else if (rc == LDLM_ITER_CONTINUE)
+                RETURN(0);
+        RETURN(rc);
+}
+
 static inline void mdc_clear_replay_flag(struct ptlrpc_request *req, int rc)
 {
         /* Don't hold error requests for replay. */
 static inline void mdc_clear_replay_flag(struct ptlrpc_request *req, int rc)
 {
         /* Don't hold error requests for replay. */
index f84d849..d2fda85 100644 (file)
@@ -2241,6 +2241,7 @@ struct obd_ops mdc_obd_ops = {
 struct md_ops mdc_md_ops = {
         .m_getstatus        = mdc_getstatus,
         .m_change_cbdata    = mdc_change_cbdata,
 struct md_ops mdc_md_ops = {
         .m_getstatus        = mdc_getstatus,
         .m_change_cbdata    = mdc_change_cbdata,
+        .m_find_cbdata      = mdc_find_cbdata,
         .m_close            = mdc_close,
         .m_create           = mdc_create,
         .m_done_writing     = mdc_done_writing,
         .m_close            = mdc_close,
         .m_create           = mdc_create,
         .m_done_writing     = mdc_done_writing,
index 9978fe8..00ae233 100644 (file)
@@ -1415,6 +1415,7 @@ void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats)
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, commitrw);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, enqueue);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, change_cbdata);
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, find_cbdata);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel_unused);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, cancel_unused);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, init_export);
@@ -1511,6 +1512,7 @@ int lprocfs_alloc_md_stats(struct obd_device *obd,
 
         LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
         LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata);
 
         LPROCFS_MD_OP_INIT(num_private_stats, stats, getstatus);
         LPROCFS_MD_OP_INIT(num_private_stats, stats, change_cbdata);
+        LPROCFS_MD_OP_INIT(num_private_stats, stats, find_cbdata);
         LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
         LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
         LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
         LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
         LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
         LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
index 074308e..ad20ebe 100644 (file)
@@ -3115,6 +3115,26 @@ static int osc_change_cbdata(struct obd_export *exp, struct lov_stripe_md *lsm,
         return 0;
 }
 
         return 0;
 }
 
+/* find any ldlm lock of the inode in osc
+ * return 0    not find
+ *        1    find one
+ *      < 0    error */
+static int osc_find_cbdata(struct obd_export *exp, struct lov_stripe_md *lsm,
+                           ldlm_iterator_t replace, void *data)
+{
+        struct ldlm_res_id res_id;
+        struct obd_device *obd = class_exp2obd(exp);
+        int rc = 0;
+
+        osc_build_res_name(lsm->lsm_object_id, lsm->lsm_object_gr, &res_id);
+        rc = ldlm_resource_iterate(obd->obd_namespace, &res_id, replace, data);
+        if (rc == LDLM_ITER_STOP)
+                return(1);
+        if (rc == LDLM_ITER_CONTINUE)
+                return(0);
+        return(rc);
+}
+
 static int osc_enqueue_fini(struct ptlrpc_request *req, struct ost_lvb *lvb,
                             obd_enqueue_update_f upcall, void *cookie,
                             int *flags, int rc)
 static int osc_enqueue_fini(struct ptlrpc_request *req, struct ost_lvb *lvb,
                             obd_enqueue_update_f upcall, void *cookie,
                             int *flags, int rc)
@@ -4468,6 +4488,7 @@ struct obd_ops osc_obd_ops = {
         .o_sync                 = osc_sync,
         .o_enqueue              = osc_enqueue,
         .o_change_cbdata        = osc_change_cbdata,
         .o_sync                 = osc_sync,
         .o_enqueue              = osc_enqueue,
         .o_change_cbdata        = osc_change_cbdata,
+        .o_find_cbdata          = osc_find_cbdata,
         .o_cancel               = osc_cancel,
         .o_cancel_unused        = osc_cancel_unused,
         .o_iocontrol            = osc_iocontrol,
         .o_cancel               = osc_cancel,
         .o_cancel_unused        = osc_cancel_unused,
         .o_iocontrol            = osc_iocontrol,
index 0752702..1f22dc0 100644 (file)
@@ -20,9 +20,6 @@ CPU=`awk '/model/ {print $4}' /proc/cpuinfo`
 #                                    buffer i/o errs             sock spc runas
 [ "$CPU" = "UML" ] && EXCEPT="$EXCEPT 27m 27n 27o 27p 27q 27r 31d 54a  64b 99a 99b 99c 99d 99e 99f 101"
 
 #                                    buffer i/o errs             sock spc runas
 [ "$CPU" = "UML" ] && EXCEPT="$EXCEPT 27m 27n 27o 27p 27q 27r 31d 54a  64b 99a 99b 99c 99d 99e 99f 101"
 
-# test76 is not valid with FIDs because inode numbers are not reused
-ALWAYS_EXCEPT="$ALWAYS_EXCEPT 76"
-
 case `uname -r` in
 2.4*) FSTYPE=${FSTYPE:-ext3} ;;
 2.6*) FSTYPE=${FSTYPE:-ldiskfs} ;;
 case `uname -r` in
 2.4*) FSTYPE=${FSTYPE:-ext3} ;;
 2.6*) FSTYPE=${FSTYPE:-ldiskfs} ;;
@@ -3536,10 +3533,9 @@ num_inodes() {
        awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
 }
 
        awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
 }
 
-test_76() { # bug 1443
-       DETH=$(grep deathrow /proc/kallsyms /proc/ksyms 2> /dev/null | wc -l)
-       [ $DETH -eq 0 ] && skip "No _iget." && return 0
-        BEFORE_INODES=`num_inodes`
+test_76() { # Now for bug 20433, added originally in bug 1443
+       cancel_lru_locks osc
+       BEFORE_INODES=`num_inodes`
        echo "before inodes: $BEFORE_INODES"
        local COUNT=1000
        [ "$SLOW" = "no" ] && COUNT=100
        echo "before inodes: $BEFORE_INODES"
        local COUNT=1000
        [ "$SLOW" = "no" ] && COUNT=100
@@ -3547,13 +3543,22 @@ test_76() { # bug 1443
                touch $DIR/$tfile
                rm -f $DIR/$tfile
        done
                touch $DIR/$tfile
                rm -f $DIR/$tfile
        done
+       cancel_lru_locks osc
        AFTER_INODES=`num_inodes`
        echo "after inodes: $AFTER_INODES"
        AFTER_INODES=`num_inodes`
        echo "after inodes: $AFTER_INODES"
-       [ $AFTER_INODES -gt $((BEFORE_INODES + 32)) ] && \
-               error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
-       true
+       local wait=0
+       while [ $AFTER_INODES -gt $BEFORE_INODES ]; do
+               sleep 2
+               AFTER_INODES=`num_inodes`
+               wait=$((wait+2))
+               echo "wait $wait seconds inodes: $AFTER_INODES"
+               if [ $wait -gt 30 ]; then
+                       error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
+               fi
+       done
 }
 }
-run_test 76 "destroy duplicate inodes in client inode cache ===="
+run_test 76 "confirm clients recycle inodes properly ===="
+
 
 export ORIG_CSUM=""
 set_checksums()
 
 export ORIG_CSUM=""
 set_checksums()