Whamcloud - gitweb
LU-3239 ofd: refill env in ofd_get_info
authorwang di <di.wang@intel.com>
Mon, 29 Apr 2013 09:31:59 +0000 (02:31 -0700)
committerOleg Drokin <oleg.drokin@intel.com>
Thu, 2 May 2013 05:31:47 +0000 (01:31 -0400)
Because ofd_get_info(KEY_FIEMAP) might be called from
ptlrpc_server_handle_req_in(see the stack below),
where env might not be initialized correctly(see LBUG below),
so it refill refill in ofd_get_info.

LutreError: 19182:0:(ofd_internal.h:518:ofd_info_init()) LBUG
Pid: 19182, comm: ll_ost_io00_001
Call Trace:
[<ffffffffa044e895>] libcfs_debug_dumpstack+0x55/0x80 [libcfs]
[<ffffffffa044ee97>] lbug_with_loc+0x47/0xb0 [libcfs]
[<ffffffffa0e03e62>] ofd_info_init+0x92/0x130 [ofd]
[<ffffffffa0e05835>] ofd_get_info+0x2e5/0xa90 [ofd]
[<ffffffff812805cd>] ? pointer+0x8d/0x830
[<ffffffffa029f7e5>] ? lprocfs_counter_add+0x125/0x182 [lvfs]
[<ffffffffa078528a>] nrs_orr_range_fill_physical+0x18a/0x540
[ptlrpc]
[<ffffffffa0762dd6>] ? __req_capsule_get+0x166/0x700 [ptlrpc]
[<ffffffffa073e630>] ? lustre_swab_ost_body+0x0/0x10 [ptlrpc]
[<ffffffffa07871d7>] nrs_orr_res_get+0x817/0xb80 [ptlrpc]
[<ffffffffa077d306>] nrs_resource_get+0x56/0x110 [ptlrpc]
[<ffffffffa077dccb>] nrs_resource_get_safe+0x8b/0x100 [ptlrpc]
[<ffffffffa0780248>] ptlrpc_nrs_req_initialize+0x38/0x90 [ptlrpc]
[<ffffffffa074cff0>] ptlrpc_main+0x1170/0x16f0 [ptlrpc]
[<ffffffffa074be80>] ? ptlrpc_main+0x0/0x16f0 [ptlrpc]
[<ffffffff8100c0ca>] child_rip+0xa/0x20
[<ffffffffa074be80>] ? ptlrpc_main+0x0/0x16f0 [ptlrpc]
[<ffffffffa074be80>] ? ptlrpc_main+0x0/0x16f0 [ptlrpc]
[<ffffffff8100c0c0>] ? child_rip+0x0/0x20

Signed-off-by: wang di <di.wang@intel.com>
Change-Id: Iee4b68fe331a895c61e6ccd0a14d6c60f5f9215c
Reviewed-on: http://review.whamcloud.com/6204
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Nikitas Angelinas <nikitas_angelinas@xyratex.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/ofd/ofd_obd.c
lustre/ptlrpc/service.c

index 2f082a2..059d0e2 100644 (file)
@@ -530,7 +530,7 @@ static int ofd_get_info(const struct lu_env *env, struct obd_export *exp,
                        struct lov_stripe_md *lsm)
 {
        struct ofd_device       *ofd;
                        struct lov_stripe_md *lsm)
 {
        struct ofd_device       *ofd;
-       int                      rc = 0;
+       int                     rc = 0;
 
        ENTRY;
 
 
        ENTRY;
 
@@ -539,13 +539,21 @@ static int ofd_get_info(const struct lu_env *env, struct obd_export *exp,
                RETURN(-EINVAL);
        }
 
                RETURN(-EINVAL);
        }
 
+       /* Because ofd_get_info might be called from
+        * handle_request_in as well(see LU-3239), where env might
+        * not be initilaized correctly, and le_ses might be in
+        * an un-initialized state, so only refill le_ctx here */
+       rc = lu_env_refill((struct lu_env *)env);
+       if (rc != 0)
+               RETURN(rc);
+
        ofd = ofd_exp(exp);
 
        if (KEY_IS(KEY_BLOCKSIZE)) {
                __u32 *blocksize = val;
                if (blocksize) {
                        if (*vallen < sizeof(*blocksize))
        ofd = ofd_exp(exp);
 
        if (KEY_IS(KEY_BLOCKSIZE)) {
                __u32 *blocksize = val;
                if (blocksize) {
                        if (*vallen < sizeof(*blocksize))
-                               RETURN(-EOVERFLOW);
+                               GOTO(out, rc = -EOVERFLOW);
                        *blocksize = 1 << ofd->ofd_dt_conf.ddp_block_shift;
                }
                *vallen = sizeof(*blocksize);
                        *blocksize = 1 << ofd->ofd_dt_conf.ddp_block_shift;
                }
                *vallen = sizeof(*blocksize);
@@ -553,7 +561,7 @@ static int ofd_get_info(const struct lu_env *env, struct obd_export *exp,
                __u32 *blocksize_bits = val;
                if (blocksize_bits) {
                        if (*vallen < sizeof(*blocksize_bits))
                __u32 *blocksize_bits = val;
                if (blocksize_bits) {
                        if (*vallen < sizeof(*blocksize_bits))
-                               RETURN(-EOVERFLOW);
+                               GOTO(out, rc = -EOVERFLOW);
                        *blocksize_bits = ofd->ofd_dt_conf.ddp_block_shift;
                }
                *vallen = sizeof(*blocksize_bits);
                        *blocksize_bits = ofd->ofd_dt_conf.ddp_block_shift;
                }
                *vallen = sizeof(*blocksize_bits);
@@ -563,7 +571,7 @@ static int ofd_get_info(const struct lu_env *env, struct obd_export *exp,
 
                if (val == NULL) {
                        *vallen = sizeof(obd_id);
 
                if (val == NULL) {
                        *vallen = sizeof(obd_id);
-                       RETURN(0);
+                       GOTO(out, rc = 0);
                }
                ofd_info_init(env, exp);
                oseq = ofd_seq_load(env, ofd,
                }
                ofd_info_init(env, exp);
                oseq = ofd_seq_load(env, ofd,
@@ -572,7 +580,7 @@ static int ofd_get_info(const struct lu_env *env, struct obd_export *exp,
                if (last_id) {
                        if (*vallen < sizeof(*last_id)) {
                                ofd_seq_put(env, oseq);
                if (last_id) {
                        if (*vallen < sizeof(*last_id)) {
                                ofd_seq_put(env, oseq);
-                               RETURN(-EOVERFLOW);
+                               GOTO(out, rc = -EOVERFLOW);
                        }
                        *last_id = ofd_seq_last_oid(oseq);
                }
                        }
                        *last_id = ofd_seq_last_oid(oseq);
                }
@@ -587,13 +595,13 @@ static int ofd_get_info(const struct lu_env *env, struct obd_export *exp,
                if (val == NULL) {
                        *vallen = fiemap_count_to_size(
                                               fm_key->fiemap.fm_extent_count);
                if (val == NULL) {
                        *vallen = fiemap_count_to_size(
                                               fm_key->fiemap.fm_extent_count);
-                       RETURN(0);
+                       GOTO(out, rc = 0);
                }
 
                info = ofd_info_init(env, exp);
                rc = ostid_to_fid(&info->fti_fid, &fm_key->oa.o_oi, 0);
                if (rc != 0)
                }
 
                info = ofd_info_init(env, exp);
                rc = ostid_to_fid(&info->fti_fid, &fm_key->oa.o_oi, 0);
                if (rc != 0)
-                       RETURN(rc);
+                       GOTO(out, rc);
                CDEBUG(D_INODE, "get FIEMAP of object "DFID"\n",
                       PFID(&info->fti_fid));
 
                CDEBUG(D_INODE, "get FIEMAP of object "DFID"\n",
                       PFID(&info->fti_fid));
 
@@ -621,7 +629,6 @@ static int ofd_get_info(const struct lu_env *env, struct obd_export *exp,
                *((__u32 *) val) = ofd->ofd_sync_lock_cancel;
                *vallen = sizeof(__u32);
        } else if (KEY_IS(KEY_LAST_FID)) {
                *((__u32 *) val) = ofd->ofd_sync_lock_cancel;
                *vallen = sizeof(__u32);
        } else if (KEY_IS(KEY_LAST_FID)) {
-               struct lu_env           env;
                struct ofd_device       *ofd = ofd_exp(exp);
                struct ofd_seq          *oseq;
                struct lu_fid           *fid = val;
                struct ofd_device       *ofd = ofd_exp(exp);
                struct ofd_seq          *oseq;
                struct lu_fid           *fid = val;
@@ -629,22 +636,20 @@ static int ofd_get_info(const struct lu_env *env, struct obd_export *exp,
 
                if (fid == NULL) {
                        *vallen = sizeof(struct lu_fid);
 
                if (fid == NULL) {
                        *vallen = sizeof(struct lu_fid);
-                       RETURN(0);
+                       GOTO(out, rc = 0);
                }
 
                if (*vallen < sizeof(*fid))
                }
 
                if (*vallen < sizeof(*fid))
-                       RETURN(-EOVERFLOW);
+                       GOTO(out, rc = -EOVERFLOW);
 
 
-               rc = lu_env_init(&env, LCT_DT_THREAD);
-               if (rc != 0)
-                       RETURN(rc);
-               ofd_info_init(&env, exp);
+               ofd_info_init(env, exp);
 
                fid_le_to_cpu(fid, fid);
 
 
                fid_le_to_cpu(fid, fid);
 
-               oseq = ofd_seq_load(&env, ofd, ostid_seq((struct ost_id *)fid));
+               oseq = ofd_seq_load(env, ofd,
+                                   ostid_seq((struct ost_id *)fid));
                if (IS_ERR(oseq))
                if (IS_ERR(oseq))
-                       GOTO(out_fini, rc = PTR_ERR(oseq));
+                       GOTO(out, rc = PTR_ERR(oseq));
 
                rc = ostid_to_fid(fid, &oseq->os_oi,
                             ofd->ofd_lut.lut_lsd.lsd_osd_index);
 
                rc = ostid_to_fid(fid, &oseq->os_oi,
                             ofd->ofd_lut.lut_lsd.lsd_osd_index);
@@ -655,14 +660,12 @@ static int ofd_get_info(const struct lu_env *env, struct obd_export *exp,
                       PFID(fid));
                *vallen = sizeof(*fid);
 out_put:
                       PFID(fid));
                *vallen = sizeof(*fid);
 out_put:
-               ofd_seq_put(&env, oseq);
-out_fini:
-               lu_env_fini(&env);
+               ofd_seq_put(env, oseq);
        } else {
                CERROR("Not supported key %s\n", (char*)key);
                rc = -EOPNOTSUPP;
        }
        } else {
                CERROR("Not supported key %s\n", (char*)key);
                rc = -EOPNOTSUPP;
        }
-
+out:
        RETURN(rc);
 }
 
        RETURN(rc);
 }
 
index 31204b8..7e176c0 100644 (file)
@@ -2505,6 +2505,7 @@ static int ptlrpc_main(void *arg)
                /* Process all incoming reqs before handling any */
                if (ptlrpc_server_request_incoming(svcpt)) {
                        lu_context_enter(&env->le_ctx);
                /* Process all incoming reqs before handling any */
                if (ptlrpc_server_request_incoming(svcpt)) {
                        lu_context_enter(&env->le_ctx);
+                       env->le_ses = NULL;
                        ptlrpc_server_handle_req_in(svcpt, thread);
                        lu_context_exit(&env->le_ctx);
 
                        ptlrpc_server_handle_req_in(svcpt, thread);
                        lu_context_exit(&env->le_ctx);