Whamcloud - gitweb
LU-2790 ldlm: handle lvbo_init failure in ldlm_resource_get
authorFan Yong <yong.fan@whamcloud.com>
Tue, 19 Feb 2013 00:42:58 +0000 (08:42 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Sun, 31 Mar 2013 21:04:27 +0000 (17:04 -0400)
Under some special cases, such as RAM pressure, lvbo_init()
may be failed, then the caller - ldlm_resource_get() should
handle the failure to prevent subsequent operations to use
non-exist resource.

Signed-off-by: Fan Yong <fan.yong@intel.com>
Change-Id: I0eabbf5daaaba9aa163a45f24b6b621477ec4d32
Reviewed-on: http://review.whamcloud.com/5699
Tested-by: Hudson
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Bobi Jam <bobijam@gmail.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/include/lustre_dlm.h
lustre/ldlm/ldlm_resource.c

index df5014a..ea27fcc 100644 (file)
@@ -1137,7 +1137,7 @@ struct ldlm_resource {
         * To serialize lvbo_init.
         */
        struct mutex            lr_lvb_mutex;
-       __u32                   lr_lvb_len;
+       int                     lr_lvb_len;
        /** protected by lr_lock */
        void                    *lr_lvb_data;
 
index e48124b..47b2901 100644 (file)
@@ -1104,6 +1104,11 @@ ldlm_resource_get(struct ldlm_namespace *ns, struct ldlm_resource *parent,
                        mutex_lock(&res->lr_lvb_mutex);
                        mutex_unlock(&res->lr_lvb_mutex);
                 }
+
+               if (unlikely(res->lr_lvb_len < 0)) {
+                       ldlm_resource_putref(res);
+                       res = NULL;
+               }
                 return res;
         }
 
@@ -1143,6 +1148,11 @@ ldlm_resource_get(struct ldlm_namespace *ns, struct ldlm_resource *parent,
                        mutex_lock(&res->lr_lvb_mutex);
                        mutex_unlock(&res->lr_lvb_mutex);
                }
+
+               if (unlikely(res->lr_lvb_len < 0)) {
+                       ldlm_resource_putref(res);
+                       res = NULL;
+               }
                return res;
        }
        /* We won! Let's add the resource. */
@@ -1156,9 +1166,18 @@ ldlm_resource_get(struct ldlm_namespace *ns, struct ldlm_resource *parent,
 
                 OBD_FAIL_TIMEOUT(OBD_FAIL_LDLM_CREATE_RESOURCE, 2);
                 rc = ns->ns_lvbo->lvbo_init(res);
-                if (rc)
-                        CERROR("lvbo_init failed for resource "
-                               LPU64": rc %d\n", name->name[0], rc);
+               if (rc < 0) {
+                       CERROR("lvbo_init failed for resource "
+                              LPU64": rc %d\n", name->name[0], rc);
+                       if (res->lr_lvb_data) {
+                               OBD_FREE(res->lr_lvb_data, res->lr_lvb_len);
+                               res->lr_lvb_data = NULL;
+                       }
+                       res->lr_lvb_len = rc;
+                       mutex_unlock(&res->lr_lvb_mutex);
+                       ldlm_resource_putref(res);
+                       return NULL;
+               }
        }
 
        /* We create resource with locked lr_lvb_mutex. */