@@ -226,7 +226,8 @@ struct llog_handle {
char *lgh_name;
void *private_data;
struct llog_operations *lgh_logops;
- struct kref lgh_refcount;
+ refcount_t lgh_refcount;
+ bool lgh_destroyed;
};
#define LLOG_CTXT_FLAG_UNINITIALIZED 0x00000001
@@ -65,7 +65,7 @@ static struct llog_handle *llog_alloc_handle(void)
init_rwsem(&loghandle->lgh_lock);
INIT_LIST_HEAD(&loghandle->u.phd.phd_entry);
- kref_init(&loghandle->lgh_refcount);
+ refcount_set(&loghandle->lgh_refcount, 1);
return loghandle;
}
@@ -73,11 +73,8 @@ static struct llog_handle *llog_alloc_handle(void)
/*
* Free llog handle and header data if exists. Used in llog_close() only
*/
-static void llog_free_handle(struct kref *kref)
+static void llog_free_handle(struct llog_handle *loghandle)
{
- struct llog_handle *loghandle = container_of(kref, struct llog_handle,
- lgh_refcount);
-
/* failed llog_init_handle */
if (!loghandle->lgh_hdr)
goto out;
@@ -91,15 +88,30 @@ static void llog_free_handle(struct kref *kref)
kfree(loghandle);
}
-void llog_handle_get(struct llog_handle *loghandle)
+struct llog_handle *llog_handle_get(struct llog_handle *loghandle)
{
- kref_get(&loghandle->lgh_refcount);
+ if (refcount_inc_not_zero(&loghandle->lgh_refcount))
+ return loghandle;
+ return NULL;
}
-void llog_handle_put(struct llog_handle *loghandle)
+int llog_handle_put(const struct lu_env *env, struct llog_handle *loghandle)
{
- LASSERT(kref_read(&loghandle->lgh_refcount) > 0);
- kref_put(&loghandle->lgh_refcount, llog_free_handle);
+ int rc = 0;
+
+ if (refcount_dec_and_test(&loghandle->lgh_refcount)) {
+ struct llog_operations *lop;
+
+ rc = llog_handle2ops(loghandle, &lop);
+ if (!rc) {
+ if (lop->lop_close)
+ rc = lop->lop_close(env, loghandle);
+ else
+ rc = -EOPNOTSUPP;
+ }
+ llog_free_handle(loghandle);
+ }
+ return rc;
}
static int llog_read_header(const struct lu_env *env,
@@ -541,7 +553,7 @@ int llog_open(const struct lu_env *env, struct llog_ctxt *ctxt,
revert_creds(old_cred);
if (rc) {
- llog_free_handle(&(*lgh)->lgh_refcount);
+ llog_free_handle(*lgh);
*lgh = NULL;
}
return rc;
@@ -550,19 +562,6 @@ int llog_open(const struct lu_env *env, struct llog_ctxt *ctxt,
int llog_close(const struct lu_env *env, struct llog_handle *loghandle)
{
- struct llog_operations *lop;
- int rc;
-
- rc = llog_handle2ops(loghandle, &lop);
- if (rc)
- goto out;
- if (!lop->lop_close) {
- rc = -EOPNOTSUPP;
- goto out;
- }
- rc = lop->lop_close(env, loghandle);
-out:
- llog_handle_put(loghandle);
- return rc;
+ return llog_handle_put(env, loghandle);
}
EXPORT_SYMBOL(llog_close);
@@ -85,10 +85,16 @@ static int llog_cat_id2handle(const struct lu_env *env,
cgl->lgl_ogen, logid->lgl_ogen);
continue;
}
+ *res = llog_handle_get(loghandle);
+ if (!*res) {
+ CERROR("%s: log "DFID" refcount is zero!\n",
+ loghandle->lgh_ctxt->loc_obd->obd_name,
+ PFID(&logid->lgl_oi.oi_fid));
+ continue;
+ }
loghandle->u.phd.phd_cat_handle = cathandle;
up_write(&cathandle->lgh_lock);
- rc = 0;
- goto out;
+ return rc;
}
}
up_write(&cathandle->lgh_lock);
@@ -105,10 +111,12 @@ static int llog_cat_id2handle(const struct lu_env *env,
rc = llog_init_handle(env, loghandle, fmt | LLOG_F_IS_PLAIN, NULL);
if (rc < 0) {
llog_close(env, loghandle);
- loghandle = NULL;
+ *res = NULL;
return rc;
}
+ *res = llog_handle_get(loghandle);
+ LASSERT(*res);
down_write(&cathandle->lgh_lock);
list_add_tail(&loghandle->u.phd.phd_entry, &cathandle->u.chd.chd_head);
up_write(&cathandle->lgh_lock);
@@ -117,9 +125,6 @@ static int llog_cat_id2handle(const struct lu_env *env,
loghandle->u.phd.phd_cookie.lgc_lgl = cathandle->lgh_id;
loghandle->u.phd.phd_cookie.lgc_index =
loghandle->lgh_hdr->llh_cat_idx;
-out:
- llog_handle_get(loghandle);
- *res = loghandle;
return 0;
}
@@ -204,7 +209,7 @@ static int llog_cat_process_cb(const struct lu_env *env,
}
out:
- llog_handle_put(llh);
+ llog_handle_put(env, llh);
return rc;
}
@@ -61,8 +61,8 @@ struct llog_thread_info {
int llog_info_init(void);
void llog_info_fini(void);
-void llog_handle_get(struct llog_handle *loghandle);
-void llog_handle_put(struct llog_handle *loghandle);
+struct llog_handle *llog_handle_get(struct llog_handle *loghandle);
+int llog_handle_put(const struct lu_env *env, struct llog_handle *loghandle);
int class_config_dump_handler(const struct lu_env *env,
struct llog_handle *handle,
struct llog_rec_hdr *rec, void *data);