atomic_t loc_refcount;
long loc_flags; /* flags, see above defines */
struct dt_object *loc_dir;
+ struct local_oid_storage *loc_los_nameless;
+ struct local_oid_storage *loc_los_named;
};
#define LLOG_PROC_BREAK 0x0001
mdd_changelog_fini(env, m);
orph_index_fini(env, m);
mdd_dot_lustre_cleanup(env, m);
- if (m->mdd_los != NULL)
+ if (m->mdd_los != NULL) {
local_oid_storage_fini(env, m->mdd_los);
+ m->mdd_los = NULL;
+ }
lu_site_purge(env, mdd2lu_dev(m)->ld_site, ~0);
if (m->mdd_child_exp)
struct obd_llog_group *olg, int ctxt_idx,
struct obd_device *disk_obd)
{
- struct local_oid_storage *los;
struct llog_thread_info *lgi = llog_info(env);
struct llog_ctxt *ctxt;
int rc = 0;
-
ENTRY;
LASSERT(obd);
lgi->lgi_fid.f_oid = 1;
lgi->lgi_fid.f_ver = 0;
rc = local_oid_storage_init(env, disk_obd->obd_lvfs_ctxt.dt,
- &lgi->lgi_fid, &los);
- if (rc < 0)
- return rc;
+ &lgi->lgi_fid,
+ &ctxt->loc_los_nameless);
+ if (rc != 0)
+ GOTO(out, rc);
lgi->lgi_fid.f_seq = FID_SEQ_LLOG_NAME;
lgi->lgi_fid.f_oid = 1;
lgi->lgi_fid.f_ver = 0;
rc = local_oid_storage_init(env, disk_obd->obd_lvfs_ctxt.dt,
- &lgi->lgi_fid, &los);
+ &lgi->lgi_fid,
+ &ctxt->loc_los_named);
+ if (rc != 0) {
+ local_oid_storage_fini(env, ctxt->loc_los_nameless);
+ ctxt->loc_los_nameless = NULL;
+ }
+
+ GOTO(out, rc);
+
+out:
llog_ctxt_put(ctxt);
return rc;
}
static int llog_osd_cleanup(const struct lu_env *env, struct llog_ctxt *ctxt)
{
- struct dt_device *dt;
- struct ls_device *ls;
- struct local_oid_storage *los, *nlos;
-
- LASSERT(ctxt->loc_exp->exp_obd);
- dt = ctxt->loc_exp->exp_obd->obd_lvfs_ctxt.dt;
- ls = ls_device_get(dt);
- if (IS_ERR(ls))
- RETURN(PTR_ERR(ls));
-
- mutex_lock(&ls->ls_los_mutex);
- los = dt_los_find(ls, FID_SEQ_LLOG);
- nlos = dt_los_find(ls, FID_SEQ_LLOG_NAME);
- mutex_unlock(&ls->ls_los_mutex);
- if (los != NULL) {
- dt_los_put(los);
- local_oid_storage_fini(env, los);
+ if (ctxt->loc_los_nameless != NULL) {
+ local_oid_storage_fini(env, ctxt->loc_los_nameless);
+ ctxt->loc_los_nameless = NULL;
}
- if (nlos != NULL) {
- dt_los_put(nlos);
- local_oid_storage_fini(env, nlos);
+
+ if (ctxt->loc_los_named != NULL) {
+ local_oid_storage_fini(env, ctxt->loc_los_named);
+ ctxt->loc_los_named = NULL;
}
- ls_device_put(env, ls);
+
return 0;
}
rc = dt_lookup_dir(env, root, dti->dti_buf, &dti->dti_fid);
lu_object_put_nocache(env, &root->do_lu);
if (rc == -ENOENT) {
- struct lu_object_conf *conf = &dti->dti_conf;
-
/* old llog lastid accessed by FID only */
if (lastid_seq != FID_SEQ_LLOG)
return 0;
dti->dti_fid.f_seq = FID_SEQ_LLOG;
dti->dti_fid.f_oid = 1;
dti->dti_fid.f_ver = 0;
- memset(conf, 0, sizeof(*conf));
- conf->loc_flags = LOC_F_NEW;
- o = ls_locate(env, ls, &dti->dti_fid, conf);
+ o = ls_locate(env, ls, &dti->dti_fid, NULL);
if (IS_ERR(o))
return PTR_ERR(o);
dt_read_lock(env, o, 0);
rc = dt_record_read(env, o, &dti->dti_lb, &dti->dti_off);
dt_read_unlock(env, o);
- lu_object_put_nocache(env, &o->do_lu);
if (rc == 0 && le32_to_cpu(losd.lso_magic) != LOS_MAGIC) {
CERROR("%s: wrong content of seq-"LPX64"-lastid file, magic %x\n",
o->do_lu.lo_dev->ld_obd->obd_name, lastid_seq,
le32_to_cpu(losd.lso_magic));
- return -EINVAL;
+ rc = -EINVAL;
} else if (rc < 0) {
CERROR("%s: failed to read seq-"LPX64"-lastid: rc = %d\n",
o->do_lu.lo_dev->ld_obd->obd_name, lastid_seq, rc);
- return rc;
}
- *first_oid = le32_to_cpu(losd.lso_next_oid);
+ lu_object_put_nocache(env, &o->do_lu);
+ if (rc == 0)
+ *first_oid = le32_to_cpu(losd.lso_next_oid);
return rc;
}
EXPORT_SYMBOL(local_oid_storage_init);
void local_oid_storage_fini(const struct lu_env *env,
- struct local_oid_storage *los)
+ struct local_oid_storage *los)
{
struct ls_device *ls;
- if (!atomic_dec_and_test(&los->los_refcount))
- return;
-
LASSERT(env);
LASSERT(los->los_dev);
ls = dt2ls_dev(los->los_dev);
+ /* Take the mutex before decreasing the reference to avoid race
+ * conditions as described in LU-4721. */
mutex_lock(&ls->ls_los_mutex);
- if (atomic_read(&los->los_refcount) > 0) {
+ if (!atomic_dec_and_test(&los->los_refcount)) {
mutex_unlock(&ls->ls_los_mutex);
return;
}