From 1738f00d4a4cee01a2c39a6313acabdcb5775269 Mon Sep 17 00:00:00 2001 From: Fan Yong Date: Wed, 11 May 2016 07:06:57 +0800 Subject: [PATCH] LU-8279 scrub: fix inode reference leak There was logic issue in osd_fid_lookup() to handle remote directory under the case of MDT file-level backup and restore: the logic wanted to trigger OI scrub when found the OI mapping for the remote directory object invalid, but forgot to assign the valid inode to the object as to such inode's reference cannot for released properly. Signed-off-by: Fan Yong Change-Id: Ib2c6dd7a3b43bd75b5e5aaadad91a1a72ef3d54e Reviewed-on: http://review.whamcloud.com/20792 Tested-by: Jenkins Reviewed-by: Andreas Dilger Reviewed-by: Alex Zhuravlev Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/osd-ldiskfs/osd_handler.c | 41 ++++++++++++++++++++++++++-------------- lustre/osd-ldiskfs/osd_scrub.c | 2 +- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index 60855df..7b549b3 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -775,10 +775,12 @@ static int osd_fid_lookup(const struct lu_env *env, struct osd_object *obj, struct osd_device *dev; struct osd_idmap_cache *oic; struct osd_inode_id *id; - struct inode *inode; + struct inode *inode = NULL; struct osd_scrub *scrub; struct scrub_file *sf; - int result; + __u32 flags = SS_CLEAR_DRYRUN | SS_CLEAR_FAILOUT | + SS_AUTO_FULL; + int result = 0; int rc1 = 0; bool cached = true; bool remote = false; @@ -869,34 +871,44 @@ trigger: if (rc1 == 0) { remote = true; cached = true; + flags |= SS_AUTO_PARTIAL; + flags &= ~SS_AUTO_FULL; goto iget; } } if (thread_is_running(&scrub->os_thread)) { - if (remote) { - osd_add_oi_cache(info, dev, id, fid); - osd_oii_insert(dev, oic, true); + if (scrub->os_partial_scan && + !scrub->os_in_join) { + goto join; } else { - result = -EINPROGRESS; + if (inode != NULL && !IS_ERR(inode)) { + LASSERT(remote); + + osd_add_oi_cache(info, dev, id, + fid); + osd_oii_insert(dev, oic, true); + } else { + result = -EINPROGRESS; + } } } else if (!dev->od_noscrub) { - __u32 flags = SS_CLEAR_DRYRUN | - SS_CLEAR_FAILOUT; - flags |= (remote ? SS_AUTO_PARTIAL : - SS_AUTO_FULL); +join: rc1 = osd_scrub_start(dev, flags); LCONSOLE_WARN("%.16s: trigger OI scrub by RPC " "for the "DFID" with flags 0x%x," " rc = %d\n", osd_name(dev), PFID(fid), flags, rc1); if (rc1 == 0 || rc1 == -EALREADY) { - result = -EINPROGRESS; - if (remote) { + if (inode != NULL && !IS_ERR(inode)) { + LASSERT(remote); + osd_add_oi_cache(info, dev, id, fid); osd_oii_insert(dev, oic, true); + } else { + result = -EINPROGRESS; } } else { result = -EREMCHG; @@ -906,9 +918,9 @@ trigger: } } - GOTO(out, result); + if (inode == NULL || IS_ERR(inode)) + GOTO(out, result); } else if (remote) { - result = 0; goto trigger; } @@ -947,6 +959,7 @@ trigger: } iput(inode); + inode = NULL; obj->oo_inode = NULL; if (result != -EREMCHG) GOTO(out, result); diff --git a/lustre/osd-ldiskfs/osd_scrub.c b/lustre/osd-ldiskfs/osd_scrub.c index 0027138..0097497 100644 --- a/lustre/osd-ldiskfs/osd_scrub.c +++ b/lustre/osd-ldiskfs/osd_scrub.c @@ -2396,7 +2396,7 @@ again: spin_unlock(&scrub->os_lock); if (!(scrub->os_file.sf_flags & SF_AUTO || scrub->os_partial_scan) || - (flags & (SS_AUTO_FULL | SS_AUTO_PARTIAL))) + (flags & SS_AUTO_PARTIAL)) RETURN(-EALREADY); osd_scrub_join(dev, flags, false); -- 1.8.3.1