Whamcloud - gitweb
LU-8279 scrub: fix inode reference leak 92/20792/3
authorFan Yong <fan.yong@intel.com>
Tue, 10 May 2016 23:06:57 +0000 (07:06 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Thu, 16 Jun 2016 20:20:55 +0000 (20:20 +0000)
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 <fan.yong@intel.com>
Change-Id: Ib2c6dd7a3b43bd75b5e5aaadad91a1a72ef3d54e
Reviewed-on: http://review.whamcloud.com/20792
Tested-by: Jenkins
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/osd-ldiskfs/osd_handler.c
lustre/osd-ldiskfs/osd_scrub.c

index 60855df..7b549b3 100644 (file)
@@ -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);
index 0027138..0097497 100644 (file)
@@ -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);