From 51c90a076884a8cda2bcc655058be43c2c0dced2 Mon Sep 17 00:00:00 2001 From: Sergey Cheremencev Date: Wed, 27 May 2015 11:13:20 -0700 Subject: [PATCH] LU-6207 osd: add dput in osd_ost_init In case of error(from osd_ea_fid_set) in osd_ost_init missed dput causes kernel panic with message: BUG: Dentry ffff880038452f00{i=280,n=O} still in use Change-Id: I8fee0b99f5784b644a4d8773e8e358a2a4b5187d Signed-off-by: Sergey Cheremencev Xyratex-bug-id: MRP-2059 Reviewed-on: http://es-gerrit.xyus.xyratex.com:8080/3787 Reviewed-by: Elena Gryaznova Tested-by: Elena Gryaznova Tested-by: Jenkins Reviewed-by: Rahul Deshmukh Reviewed-by: Alexander Zarochentsev Reviewed-by: Vitaly Fertman Reviewed-on: http://review.whamcloud.com/13648 Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Alex Zhuravlev --- lustre/include/obd_support.h | 1 + lustre/osd-ldiskfs/osd_compat.c | 27 ++++++++++++++------------- lustre/osd-ldiskfs/osd_handler.c | 3 +++ lustre/tests/conf-sanity.sh | 10 ++++++++++ 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/lustre/include/obd_support.h b/lustre/include/obd_support.h index f4eee4b..621d263 100644 --- a/lustre/include/obd_support.h +++ b/lustre/include/obd_support.h @@ -271,6 +271,7 @@ int obd_alloc_fail(const void *ptr, const char *name, const char *type, #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194 #define OBD_FAIL_OSD_COMPAT_INVALID_ENTRY 0x195 #define OBD_FAIL_OSD_COMPAT_NO_ENTRY 0x196 +#define OBD_FAIL_OSD_OST_EA_FID_SET 0x197 #define OBD_FAIL_OST 0x200 #define OBD_FAIL_OST_CONNECT_NET 0x201 diff --git a/lustre/osd-ldiskfs/osd_compat.c b/lustre/osd-ldiskfs/osd_compat.c index 235fb0e..da016a3 100644 --- a/lustre/osd-ldiskfs/osd_compat.c +++ b/lustre/osd-ldiskfs/osd_compat.c @@ -369,10 +369,8 @@ static int osd_ost_init(const struct lu_env *env, struct osd_device *dev) /* to get subdir count from last_rcvd */ rc = osd_last_rcvd_subdir_count(dev); - if (rc < 0) { - OBD_FREE_PTR(dev->od_ost_map); - RETURN(rc); - } + if (rc < 0) + GOTO(cleanup_alloc, rc); dev->od_ost_map->om_subdir_count = rc; rc = 0; @@ -385,7 +383,7 @@ static int osd_ost_init(const struct lu_env *env, struct osd_device *dev) d = ll_lookup_one_len("O", rootd, strlen("O")); if (IS_ERR(d)) - GOTO(cleanup, rc = PTR_ERR(d)); + GOTO(cleanup_ctxt, rc = PTR_ERR(d)); if (d->d_inode == NULL) { dput(d); /* The lookup() may be called again inside simple_mkdir(). @@ -393,7 +391,7 @@ static int osd_ost_init(const struct lu_env *env, struct osd_device *dev) * mount time, it will not affect the whole performance. */ d = simple_mkdir(rootd, dev->od_mnt, "O", 0755, 1); if (IS_ERR(d)) - GOTO(cleanup, rc = PTR_ERR(d)); + GOTO(cleanup_ctxt, rc = PTR_ERR(d)); /* It is quite probably that the device is new formatted. */ dev->od_maybe_new = 1; @@ -406,16 +404,19 @@ static int osd_ost_init(const struct lu_env *env, struct osd_device *dev) * has no OI mapping, and only is visible inside the OSD.*/ lu_igif_build(fid, inode->i_ino, inode->i_generation); rc = osd_ea_fid_set(info, inode, fid, - LMAC_NOT_IN_OI | LMAC_FID_ON_OST, 0); + LMAC_NOT_IN_OI | LMAC_FID_ON_OST, 0); + if (rc) + GOTO(cleanup_dentry, rc); - GOTO(cleanup, rc); + pop_ctxt(&save, &new); + RETURN(0); -cleanup: +cleanup_dentry: + dput(d); +cleanup_ctxt: pop_ctxt(&save, &new); - if (IS_ERR(d)) { - OBD_FREE_PTR(dev->od_ost_map); - RETURN(PTR_ERR(d)); - } +cleanup_alloc: + OBD_FREE_PTR(dev->od_ost_map); return rc; } diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index 669033f..508ec87 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -2366,6 +2366,9 @@ int osd_ea_fid_set(struct osd_thread_info *info, struct inode *inode, if (OBD_FAIL_CHECK(OBD_FAIL_FID_INLMA)) RETURN(0); + if (OBD_FAIL_CHECK(OBD_FAIL_OSD_OST_EA_FID_SET)) + rc = -ENOMEM; + lustre_lma_init(lma, fid, compat, incompat); lustre_lma_swab(lma); diff --git a/lustre/tests/conf-sanity.sh b/lustre/tests/conf-sanity.sh index 3c453f1..d33ea40 100644 --- a/lustre/tests/conf-sanity.sh +++ b/lustre/tests/conf-sanity.sh @@ -5397,6 +5397,16 @@ test_84() { } run_test 84 "check recovery_hard_time" +test_85() { + [[ $(lustre_version_code ost1) -ge $(version_code 2.7.55) ]] || + { skip "Need OST version at least 2.7.55" && return 0; } +##define OBD_FAIL_OSD_OST_EA_FID_SET 0x197 + do_facet ost1 "lctl set_param fail_loc=0x197" + start_ost + stop_ost +} +run_test 85 "osd_ost init: fail ea_fid_set" + if ! combined_mgs_mds ; then stop mgs fi -- 1.8.3.1