Whamcloud - gitweb
LU-3706 scrub: fix mutex leak in osd_obj_map_recover() 34/7534/4
authorFan Yong <fan.yong@intel.com>
Sat, 10 Aug 2013 07:12:42 +0000 (15:12 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Fri, 13 Sep 2013 23:06:51 +0000 (23:06 +0000)
We forget to release inode::i_mutex on the /O/<seq>/<dx> when meet OI
mapping conflict in osd_obj_map_recover() to recover objects from the
/lost+found to their original places. Such mutex leak will cause the
OI scrub thread or other threads to be hung when access /O/<seq>/<dx>
next time.

Test-Parameters: testlist=sanity-scrub
Signed-off-by: Fan Yong <fan.yong@intel.com>
Change-Id: Idc3b99aea5591f546a6d33e5d1fe015a2aac0167
Reviewed-on: http://review.whamcloud.com/7534
Reviewed-by: Bobi Jam <bobijam@gmail.com>
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Niu Yawei <yawei.niu@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/osd-ldiskfs/osd_compat.c
lustre/osd-ldiskfs/osd_scrub.c

index f86da33..2dbd4e4 100644 (file)
@@ -1121,11 +1121,16 @@ int osd_obj_map_recover(struct osd_thread_info *info,
                 *      So keep it there before we have suitable solution. */
                brelse(bh);
 
+               mutex_unlock(&dir->i_mutex);
+               mutex_unlock(&src_parent->i_mutex);
+
+               rc = -EEXIST;
                /* If the src object has never been modified, then remove it. */
                if (inode->i_size == 0 && inode->i_mode & S_ISUID &&
                    inode->i_mode & S_ISGID)
-                       vfs_unlink(src_parent, src_child);
-               GOTO(unlock_src, rc = 0);
+                       rc = vfs_unlink(src_parent, src_child);
+               ldiskfs_journal_stop(jh);
+               RETURN(rc);
        }
 
        bh = osd_ldiskfs_find_entry(src_parent, src_child, &de, NULL);
@@ -1143,8 +1148,6 @@ int osd_obj_map_recover(struct osd_thread_info *info,
 
 unlock:
        mutex_unlock(&dir->i_mutex);
-
-unlock_src:
        mutex_unlock(&src_parent->i_mutex);
        ldiskfs_journal_stop(jh);
        return rc;
index 669cd95..06363da 100644 (file)
@@ -484,7 +484,7 @@ osd_scrub_convert_ff(struct osd_thread_info *info, struct osd_device *dev,
 
                rc1 = __osd_xattr_set(info, inode, XATTR_NAME_FID, ff, size,
                                      XATTR_CREATE);
-               if (rc1 != 0 && rc != 0)
+               if (rc1 != 0 && rc == 0)
                        rc = rc1;
        }