From cf6b8f530fdd9a494207f59dc8d08c345d1a7570 Mon Sep 17 00:00:00 2001
From: Bobi Jam <bobijam.xu@intel.com>
Date: Mon, 12 Feb 2018 13:44:48 +0800
Subject: [PATCH] LU-10551 lod: obd_fid_alloc() could start a nested trans

* obd_fid_alloc() could possibly start a nested transaction, which
  would reset the OI cache. So we add a
  osd_thread_info::oti_ins_cache_depth to prevent clearing OI cache
  in the nested trnasaction.

* Add more debug mesages in osd_idc_find_or_init()/
  osd_idc_find_and_init()

Test-Parameters: alwaysuploadlogs envdefinitions=PTLDEBUG=-1 testlist=sanity-pfl ostfilesystemtype=zfs mdtfilesystemtype=zfs mdscount=2 mdtcount=4
Signed-off-by: Bobi Jam <bobijam.xu@intel.com>
Change-Id: Id75fd1787ffc0f47bbf110d460f23db6c34670da
Reviewed-on: https://review.whamcloud.com/31268
Reviewed-by: Fan Yong <fan.yong@intel.com>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
---
 lustre/osd-ldiskfs/osd_handler.c  | 61 ++++++++++++++++++++-----------
 lustre/osd-ldiskfs/osd_internal.h |  2 +
 lustre/osd-zfs/osd_handler.c      |  8 +++-
 lustre/osd-zfs/osd_internal.h     |  2 +
 lustre/osd-zfs/osd_oi.c           | 16 +++++++-
 5 files changed, 64 insertions(+), 25 deletions(-)

diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c
index 9519356659..13d8b51169 100644
--- a/lustre/osd-ldiskfs/osd_handler.c
+++ b/lustre/osd-ldiskfs/osd_handler.c
@@ -251,10 +251,16 @@ osd_idc_find_or_init(const struct lu_env *env, struct osd_device *osd,
 	if (idc != NULL)
 		return idc;
 
+	CDEBUG(D_INODE, "%s: FID "DFID" not in the id map cache\n",
+	       osd->od_svname, PFID(fid));
+
 	/* new mapping is needed */
 	idc = osd_idc_add(env, osd, fid);
-	if (IS_ERR(idc))
+	if (IS_ERR(idc)) {
+		CERROR("%s: FID "DFID" add id map cache failed: %ld\n",
+		       osd->od_svname, PFID(fid), PTR_ERR(idc));
 		return idc;
+	}
 
 	/* initialize it */
 	rc = osd_remote_fid(env, osd, fid);
@@ -302,10 +308,16 @@ static int osd_idc_find_and_init(const struct lu_env *env,
 		return 0;
 	}
 
+	CDEBUG(D_INODE, "%s: FID "DFID" not in the id map cache\n",
+	       osd->od_svname, PFID(fid));
+
 	/* new mapping is needed */
 	idc = osd_idc_add(env, osd, fid);
-	if (IS_ERR(idc))
+	if (IS_ERR(idc)) {
+		CERROR("%s: FID "DFID" add id map cache failed: %ld\n",
+		       osd->od_svname, PFID(fid), PTR_ERR(idc));
 		return PTR_ERR(idc);
+	}
 
 	if (obj->oo_inode != NULL) {
 		idc->oic_lid.oii_ino = obj->oo_inode->i_ino;
@@ -1685,27 +1697,30 @@ static struct thandle *osd_trans_create(const struct lu_env *env,
 	sb_start_write(osd_sb(osd_dt_dev(d)));
 
 	OBD_ALLOC_GFP(oh, sizeof *oh, GFP_NOFS);
-	if (oh != NULL) {
-		oh->ot_quota_trans = &oti->oti_quota_trans;
-		memset(oh->ot_quota_trans, 0, sizeof(*oh->ot_quota_trans));
-		th = &oh->ot_super;
-		th->th_dev = d;
-		th->th_result = 0;
-		oh->ot_credits = 0;
-		INIT_LIST_HEAD(&oh->ot_commit_dcb_list);
-		INIT_LIST_HEAD(&oh->ot_stop_dcb_list);
-		osd_th_alloced(oh);
-
-		memset(oti->oti_declare_ops, 0,
-		       sizeof(oti->oti_declare_ops));
-		memset(oti->oti_declare_ops_cred, 0,
-		       sizeof(oti->oti_declare_ops_cred));
-		memset(oti->oti_declare_ops_used, 0,
-		       sizeof(oti->oti_declare_ops_used));
-	} else {
+	if (!oh) {
 		sb_end_write(osd_sb(osd_dt_dev(d)));
-		th = ERR_PTR(-ENOMEM);
+		RETURN(ERR_PTR(-ENOMEM));
 	}
+
+	oh->ot_quota_trans = &oti->oti_quota_trans;
+	memset(oh->ot_quota_trans, 0, sizeof(*oh->ot_quota_trans));
+	th = &oh->ot_super;
+	th->th_dev = d;
+	th->th_result = 0;
+	oh->ot_credits = 0;
+	INIT_LIST_HEAD(&oh->ot_commit_dcb_list);
+	INIT_LIST_HEAD(&oh->ot_stop_dcb_list);
+	osd_th_alloced(oh);
+
+	memset(oti->oti_declare_ops, 0,
+	       sizeof(oti->oti_declare_ops));
+	memset(oti->oti_declare_ops_cred, 0,
+	       sizeof(oti->oti_declare_ops_cred));
+	memset(oti->oti_declare_ops_used, 0,
+	       sizeof(oti->oti_declare_ops_used));
+
+	oti->oti_ins_cache_depth++;
+
 	RETURN(th);
 }
 
@@ -1954,8 +1969,10 @@ static int osd_trans_stop(const struct lu_env *env, struct dt_device *dt,
 	if (unlikely(remove_agents != 0))
 		osd_process_scheduled_agent_removals(env, osd);
 
+	oti->oti_ins_cache_depth--;
 	/* reset OI cache for safety */
-	oti->oti_ins_cache_used = 0;
+	if (oti->oti_ins_cache_depth == 0)
+		oti->oti_ins_cache_used = 0;
 
 	sb_end_write(osd_sb(osd));
 
diff --git a/lustre/osd-ldiskfs/osd_internal.h b/lustre/osd-ldiskfs/osd_internal.h
index 3d25d78c1c..5a1aa8658f 100644
--- a/lustre/osd-ldiskfs/osd_internal.h
+++ b/lustre/osd-ldiskfs/osd_internal.h
@@ -587,6 +587,8 @@ struct osd_thread_info {
 	struct osd_idmap_cache *oti_ins_cache;
 	int		       oti_ins_cache_size;
 	int		       oti_ins_cache_used;
+	/* inc by osd_trans_create and dec by osd_trans_stop */
+	int		       oti_ins_cache_depth;
 
         int                    oti_r_locks;
         int                    oti_w_locks;
diff --git a/lustre/osd-zfs/osd_handler.c b/lustre/osd-zfs/osd_handler.c
index 1dd49c0421..d2bb0c7ba9 100644
--- a/lustre/osd-zfs/osd_handler.c
+++ b/lustre/osd-zfs/osd_handler.c
@@ -284,8 +284,11 @@ static int osd_trans_stop(const struct lu_env *env, struct dt_device *dt,
 	oh = container_of0(th, struct osd_thandle, ot_super);
 	INIT_LIST_HEAD(&unlinked);
 	list_splice_init(&oh->ot_unlinked_list, &unlinked);
+
+	osd_oti_get(env)->oti_ins_cache_depth--;
 	/* reset OI cache for safety */
-	osd_oti_get(env)->oti_ins_cache_used = 0;
+	if (osd_oti_get(env)->oti_ins_cache_depth == 0)
+		osd_oti_get(env)->oti_ins_cache_used = 0;
 
 	if (oh->ot_assigned == 0) {
 		LASSERT(oh->ot_tx);
@@ -364,6 +367,9 @@ static struct thandle *osd_trans_create(const struct lu_env *env,
 	th = &oh->ot_super;
 	th->th_dev = dt;
 	th->th_result = 0;
+
+	osd_oti_get(env)->oti_ins_cache_depth++;
+
 	RETURN(th);
 }
 
diff --git a/lustre/osd-zfs/osd_internal.h b/lustre/osd-zfs/osd_internal.h
index d21c0d0995..5c72d58591 100644
--- a/lustre/osd-zfs/osd_internal.h
+++ b/lustre/osd-zfs/osd_internal.h
@@ -255,6 +255,8 @@ struct osd_thread_info {
 	struct osd_idmap_cache *oti_ins_cache;
 	int		       oti_ins_cache_size;
 	int		       oti_ins_cache_used;
+	/* inc by osd_trans_create and dec by osd_trans_stop */
+	int		       oti_ins_cache_depth;
 	struct lu_buf	       oti_xattr_lbuf;
 	zap_cursor_t	       oti_zc;
 	zap_cursor_t	       oti_zc2;
diff --git a/lustre/osd-zfs/osd_oi.c b/lustre/osd-zfs/osd_oi.c
index f042dda133..a2532c4dd5 100644
--- a/lustre/osd-zfs/osd_oi.c
+++ b/lustre/osd-zfs/osd_oi.c
@@ -1059,10 +1059,16 @@ struct osd_idmap_cache *osd_idc_find_or_init(const struct lu_env *env,
 	if (idc != NULL)
 		return idc;
 
+	CDEBUG(D_INODE, "%s: FID "DFID" not in the id map cache\n",
+	       osd->od_svname, PFID(fid));
+
 	/* new mapping is needed */
 	idc = osd_idc_add(env, osd, fid);
-	if (IS_ERR(idc))
+	if (IS_ERR(idc)) {
+		CERROR("%s: FID "DFID" add id map cache failed: %ld\n",
+		       osd->od_svname, PFID(fid), PTR_ERR(idc));
 		return idc;
+	}
 
 	/* initialize it */
 	rc = osd_remote_fid(env, osd, fid);
@@ -1107,10 +1113,16 @@ int osd_idc_find_and_init(const struct lu_env *env, struct osd_device *osd,
 		return 0;
 	}
 
+	CDEBUG(D_INODE, "%s: FID "DFID" not in the id map cache\n",
+	       osd->od_svname, PFID(fid));
+
 	/* new mapping is needed */
 	idc = osd_idc_add(env, osd, fid);
-	if (IS_ERR(idc))
+	if (IS_ERR(idc)) {
+		CERROR("%s: FID "DFID" add id map cache failed: %ld\n",
+		       osd->od_svname, PFID(fid), PTR_ERR(idc));
 		return PTR_ERR(idc);
+	}
 
 	if (obj->oo_dn)
 		idc->oic_dnode = obj->oo_dn->dn_object;
-- 
GitLab