Whamcloud - gitweb
LU-1013 obdclass: lu_object_find miss to unlink object from LRU
authorFan Yong <yong.fan@whamcloud.com>
Sat, 11 Feb 2012 01:26:29 +0000 (09:26 +0800)
committerOleg Drokin <green@whamcloud.com>
Sat, 11 Feb 2012 19:15:58 +0000 (14:15 -0500)
There is race condition between lu_object_find and lu_object_put.
For the case of two threads trying to find some object with the
same FID concurrently, and the object is not allocated in memory
yet, if the first thread adds the object into LRU list before the
second thread re-searching object hash table for inserting the
new object created by itself, then the second thread will find
the object created by the first thread. Under such case, the
second thread should unlink the object from LRU.

Signed-off-by: Fan Yong <yong.fan@whamcloud.com>
Change-Id: Iadec96c27d5285f8b859b0060a6f611e87585789
Reviewed-on: http://review.whamcloud.com/2134
Tested-by: Hudson
Reviewed-by: Bobi Jam <bobijam@whamcloud.com>
Reviewed-by: Alex Zhuravlev <bzzz@whamcloud.com>
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/obdclass/lu_object.c

index 2ad22f0..7e40191 100644 (file)
@@ -619,7 +619,7 @@ static struct lu_object *lu_object_find_try(const struct lu_env *env,
         cfs_hash_bd_lock(hs, &bd, 1);
 
         shadow = htable_lookup(s, &bd, f, waiter, &version);
-        if (likely(shadow == NULL)) {
+        if (shadow == NULL) {
                 struct lu_site_bkt_data *bkt;
 
                 bkt = cfs_hash_bd_extra_get(hs, &bd);
@@ -627,12 +627,14 @@ static struct lu_object *lu_object_find_try(const struct lu_env *env,
                 bkt->lsb_busy++;
                 cfs_hash_bd_unlock(hs, &bd, 1);
                 return o;
+        } else {
+                if (!cfs_list_empty(&shadow->lo_header->loh_lru))
+                        cfs_list_del_init(&shadow->lo_header->loh_lru);
+                lprocfs_counter_incr(s->ls_stats, LU_SS_CACHE_RACE);
+                cfs_hash_bd_unlock(hs, &bd, 1);
+                lu_object_free(env, o);
+                return shadow;
         }
-
-        lprocfs_counter_incr(s->ls_stats, LU_SS_CACHE_RACE);
-        cfs_hash_bd_unlock(hs, &bd, 1);
-        lu_object_free(env, o);
-        return shadow;
 }
 
 /**