if (mod == NULL)
return;
- if (mod->mod_och != NULL)
- mod->mod_och->och_mod = NULL;
+ /**
+ * No need to touch md_open_data::mod_och, it holds a reference on
+ * \var mod and will zero references to each other, \var mod will be
+ * freed after that when md_open_data::mod_och will put the reference.
+ */
- OBD_FREE(mod, sizeof(*mod));
req->rq_cb_data = NULL;
+ mod->mod_open_req = NULL;
+ obd_mod_put(mod);
}
int mdc_set_open_replay_data(struct obd_export *exp,
/* Only if the import is replayable, we set replay_open data */
if (och && imp->imp_replayable) {
- OBD_ALLOC_PTR(mod);
+ mod = obd_mod_alloc();
if (mod == NULL) {
DEBUG_REQ(D_ERROR, open_req,
"Can't allocate md_open_data");
spin_lock(&open_req->rq_lock);
och->och_mod = mod;
mod->mod_och = och;
+ obd_mod_get(mod);
mod->mod_open_req = open_req;
open_req->rq_cb_data = mod;
open_req->rq_commit_cb = mdc_commit_open;
struct md_open_data *mod = och->och_mod;
ENTRY;
- /*
- * Don't free the structure now (it happens in mdc_commit_open(), after
- * we're sure we won't need to fix up the close request in the future),
- * but make sure that replay doesn't poke at the och, which is about to
- * be freed.
- */
- LASSERT(mod != LP_POISON);
- if (mod != NULL)
- mod->mod_och = NULL;
+ LASSERT(mod != LP_POISON && mod != NULL);
+ mod->mod_och = NULL;
och->och_mod = NULL;
+ obd_mod_put(mod);
+
RETURN(0);
}
"POISONED open %p!\n", mod->mod_open_req);
mod->mod_close_req = req;
+ obd_mod_get(mod);
+
DEBUG_REQ(D_HA, mod->mod_open_req, "matched open");
/* We no longer want to preserve this open for replay even
* though the open was committed. b=3632, b=3633 */
rc = 0;
}
- if (rc != 0 && mod)
- mod->mod_close_req = NULL;
-
+ if (mod) {
+ if (rc != 0)
+ mod->mod_close_req = NULL;
+ /* Since now, mod is accessed through open_req only,
+ * thus close req does not keep a reference on mod anymore. */
+ obd_mod_put(mod);
+ }
*request = req;
RETURN(rc);
}
"POISONED setattr %p!\n", mod->mod_open_req);
mod->mod_close_req = req;
+ obd_mod_get(mod);
DEBUG_REQ(D_HA, mod->mod_open_req, "matched setattr");
/* We no longer want to preserve this setattr for replay even
* though the open was committed. b=3632, b=3633 */
rc = 0;
}
+ if (mod) {
+ if (rc != 0)
+ mod->mod_close_req = NULL;
+ /* Since now, mod is accessed through setattr req only,
+ * thus DW req does not keep a reference on mod anymore. */
+ obd_mod_put(mod);
+ }
ptlrpc_req_finished(req);
RETURN(rc);
}
handle->och_fh = body->handle;
handle->och_magic = OBD_CLIENT_HANDLE_MAGIC;
- OBD_ALLOC_PTR(handle->och_mod);
+ handle->och_mod = obd_mod_alloc();
if (handle->och_mod == NULL) {
DEBUG_REQ(D_ERROR, req, "can't allocate md_open_data");
GOTO(err_out, rc = -ENOMEM);
ptlrpc_req_finished(req);
ptlrpc_req_finished(handle->och_mod->mod_open_req);
- OBD_FREE(handle->och_mod, sizeof(*handle->och_mod));
+ obd_mod_put(handle->och_mod);
RETURN(rc);
}