|
@@ -100,12 +100,11 @@ STATIC void xlog_ungrant_log_space(xlog_t *log,
|
|
|
|
|
|
|
|
|
|
/* local ticket functions */
|
|
/* local ticket functions */
|
|
-STATIC xlog_ticket_t *xlog_ticket_get(xlog_t *log,
|
|
|
|
|
|
+STATIC xlog_ticket_t *xlog_ticket_alloc(xlog_t *log,
|
|
int unit_bytes,
|
|
int unit_bytes,
|
|
int count,
|
|
int count,
|
|
char clientid,
|
|
char clientid,
|
|
uint flags);
|
|
uint flags);
|
|
-STATIC void xlog_ticket_put(xlog_t *log, xlog_ticket_t *ticket);
|
|
|
|
|
|
|
|
#if defined(DEBUG)
|
|
#if defined(DEBUG)
|
|
STATIC void xlog_verify_dest_ptr(xlog_t *log, __psint_t ptr);
|
|
STATIC void xlog_verify_dest_ptr(xlog_t *log, __psint_t ptr);
|
|
@@ -360,7 +359,7 @@ xfs_log_done(xfs_mount_t *mp,
|
|
*/
|
|
*/
|
|
xlog_trace_loggrant(log, ticket, "xfs_log_done: (non-permanent)");
|
|
xlog_trace_loggrant(log, ticket, "xfs_log_done: (non-permanent)");
|
|
xlog_ungrant_log_space(log, ticket);
|
|
xlog_ungrant_log_space(log, ticket);
|
|
- xlog_ticket_put(log, ticket);
|
|
|
|
|
|
+ xfs_log_ticket_put(ticket);
|
|
} else {
|
|
} else {
|
|
xlog_trace_loggrant(log, ticket, "xfs_log_done: (permanent)");
|
|
xlog_trace_loggrant(log, ticket, "xfs_log_done: (permanent)");
|
|
xlog_regrant_reserve_log_space(log, ticket);
|
|
xlog_regrant_reserve_log_space(log, ticket);
|
|
@@ -514,7 +513,7 @@ xfs_log_reserve(xfs_mount_t *mp,
|
|
retval = xlog_regrant_write_log_space(log, internal_ticket);
|
|
retval = xlog_regrant_write_log_space(log, internal_ticket);
|
|
} else {
|
|
} else {
|
|
/* may sleep if need to allocate more tickets */
|
|
/* may sleep if need to allocate more tickets */
|
|
- internal_ticket = xlog_ticket_get(log, unit_bytes, cnt,
|
|
|
|
|
|
+ internal_ticket = xlog_ticket_alloc(log, unit_bytes, cnt,
|
|
client, flags);
|
|
client, flags);
|
|
if (!internal_ticket)
|
|
if (!internal_ticket)
|
|
return XFS_ERROR(ENOMEM);
|
|
return XFS_ERROR(ENOMEM);
|
|
@@ -749,7 +748,7 @@ xfs_log_unmount_write(xfs_mount_t *mp)
|
|
if (tic) {
|
|
if (tic) {
|
|
xlog_trace_loggrant(log, tic, "unmount rec");
|
|
xlog_trace_loggrant(log, tic, "unmount rec");
|
|
xlog_ungrant_log_space(log, tic);
|
|
xlog_ungrant_log_space(log, tic);
|
|
- xlog_ticket_put(log, tic);
|
|
|
|
|
|
+ xfs_log_ticket_put(tic);
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
/*
|
|
/*
|
|
@@ -3222,22 +3221,33 @@ xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog)
|
|
*/
|
|
*/
|
|
|
|
|
|
/*
|
|
/*
|
|
- * Free a used ticket.
|
|
|
|
|
|
+ * Free a used ticket when it's refcount falls to zero.
|
|
*/
|
|
*/
|
|
-STATIC void
|
|
|
|
-xlog_ticket_put(xlog_t *log,
|
|
|
|
- xlog_ticket_t *ticket)
|
|
|
|
|
|
+void
|
|
|
|
+xfs_log_ticket_put(
|
|
|
|
+ xlog_ticket_t *ticket)
|
|
{
|
|
{
|
|
- sv_destroy(&ticket->t_wait);
|
|
|
|
- kmem_zone_free(xfs_log_ticket_zone, ticket);
|
|
|
|
-} /* xlog_ticket_put */
|
|
|
|
|
|
+ ASSERT(atomic_read(&ticket->t_ref) > 0);
|
|
|
|
+ if (atomic_dec_and_test(&ticket->t_ref)) {
|
|
|
|
+ sv_destroy(&ticket->t_wait);
|
|
|
|
+ kmem_zone_free(xfs_log_ticket_zone, ticket);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
|
|
|
|
+xlog_ticket_t *
|
|
|
|
+xfs_log_ticket_get(
|
|
|
|
+ xlog_ticket_t *ticket)
|
|
|
|
+{
|
|
|
|
+ ASSERT(atomic_read(&ticket->t_ref) > 0);
|
|
|
|
+ atomic_inc(&ticket->t_ref);
|
|
|
|
+ return ticket;
|
|
|
|
+}
|
|
|
|
|
|
/*
|
|
/*
|
|
* Allocate and initialise a new log ticket.
|
|
* Allocate and initialise a new log ticket.
|
|
*/
|
|
*/
|
|
STATIC xlog_ticket_t *
|
|
STATIC xlog_ticket_t *
|
|
-xlog_ticket_get(xlog_t *log,
|
|
|
|
|
|
+xlog_ticket_alloc(xlog_t *log,
|
|
int unit_bytes,
|
|
int unit_bytes,
|
|
int cnt,
|
|
int cnt,
|
|
char client,
|
|
char client,
|
|
@@ -3308,6 +3318,7 @@ xlog_ticket_get(xlog_t *log,
|
|
unit_bytes += 2*BBSIZE;
|
|
unit_bytes += 2*BBSIZE;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ atomic_set(&tic->t_ref, 1);
|
|
tic->t_unit_res = unit_bytes;
|
|
tic->t_unit_res = unit_bytes;
|
|
tic->t_curr_res = unit_bytes;
|
|
tic->t_curr_res = unit_bytes;
|
|
tic->t_cnt = cnt;
|
|
tic->t_cnt = cnt;
|
|
@@ -3323,7 +3334,7 @@ xlog_ticket_get(xlog_t *log,
|
|
xlog_tic_reset_res(tic);
|
|
xlog_tic_reset_res(tic);
|
|
|
|
|
|
return tic;
|
|
return tic;
|
|
-} /* xlog_ticket_get */
|
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
/******************************************************************************
|