Whamcloud - gitweb
LU-1603 ofd: Fix null pointer dereferences in ldiskfs_statfs()
authorLi Wei <liwei@whamcloud.com>
Fri, 6 Jul 2012 13:12:38 +0000 (21:12 +0800)
committerOleg Drokin <green@whamcloud.com>
Wed, 11 Jul 2012 23:49:30 +0000 (19:49 -0400)
On an OSS running the OFD-OSD stack, unmounting all OSTs makes all OFD
and OSD keys (i.e., lu_context_key) quiescent.  Next time the OSTs are
remounted, ofd_stack_init() will try to refill the quiescent osd_key
into the context, resulting in a null pointer dereference in
ldiskfs_statfs().  Before the problem motivating LCT_QUIESCENT and
LCT_REMEMBER can be revisited, the solution is to refill contexts
after new device types have been "revived" via allocations of their
first device instances.

Change-Id: I4835afb88fae460c21501df95765afd29e570860
Signed-off-by: Li Wei <liwei@whamcloud.com>
Reviewed-on: http://review.whamcloud.com/3353
Tested-by: Hudson
Reviewed-by: Jinshan Xiong <jinshan.xiong@whamcloud.com>
Reviewed-by: Fan Yong <yong.fan@whamcloud.com>
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/ofd/ofd_dev.c

index b3c582b..ac87ce5 100644 (file)
@@ -88,12 +88,6 @@ static int ofd_stack_init(const struct lu_env *env,
                RETURN(-ENODEV);
        }
 
                RETURN(-ENODEV);
        }
 
-       rc = lu_env_refill((struct lu_env *)env);
-       if (rc != 0) {
-               CERROR("Failure to refill session: '%d'\n", rc);
-               GOTO(out_type, rc);
-       }
-
        ldt = type->typ_lu;
        if (ldt == NULL) {
                CERROR("type: '%s'\n", s2lsi(lmi->lmi_sb)->lsi_osd_type);
        ldt = type->typ_lu;
        if (ldt == NULL) {
                CERROR("type: '%s'\n", s2lsi(lmi->lmi_sb)->lsi_osd_type);
@@ -115,6 +109,13 @@ static int ofd_stack_init(const struct lu_env *env,
                 "%s-osd", lustre_cfg_string(cfg, 0));
 
        type->typ_refcnt++;
                 "%s-osd", lustre_cfg_string(cfg, 0));
 
        type->typ_refcnt++;
+
+       rc = lu_env_refill((struct lu_env *)env);
+       if (rc != 0) {
+               CERROR("Failure to refill session: '%d'\n", rc);
+               GOTO(out_free, rc);
+       }
+
        rc = ldt->ldt_ops->ldto_device_init(env, d, dev, NULL);
        if (rc) {
                CERROR("can't init device '%s', rc = %d\n",
        rc = ldt->ldt_ops->ldto_device_init(env, d, dev, NULL);
        if (rc) {
                CERROR("can't init device '%s', rc = %d\n",