|
@@ -562,9 +562,8 @@ xfs_log_mount(
|
|
}
|
|
}
|
|
|
|
|
|
mp->m_log = xlog_alloc_log(mp, log_target, blk_offset, num_bblks);
|
|
mp->m_log = xlog_alloc_log(mp, log_target, blk_offset, num_bblks);
|
|
- if (!mp->m_log) {
|
|
|
|
- cmn_err(CE_WARN, "XFS: Log allocation failed: No memory!");
|
|
|
|
- error = ENOMEM;
|
|
|
|
|
|
+ if (IS_ERR(mp->m_log)) {
|
|
|
|
+ error = -PTR_ERR(mp->m_log);
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1180,10 +1179,13 @@ xlog_alloc_log(xfs_mount_t *mp,
|
|
xfs_buf_t *bp;
|
|
xfs_buf_t *bp;
|
|
int i;
|
|
int i;
|
|
int iclogsize;
|
|
int iclogsize;
|
|
|
|
+ int error = ENOMEM;
|
|
|
|
|
|
log = kmem_zalloc(sizeof(xlog_t), KM_MAYFAIL);
|
|
log = kmem_zalloc(sizeof(xlog_t), KM_MAYFAIL);
|
|
- if (!log)
|
|
|
|
- return NULL;
|
|
|
|
|
|
+ if (!log) {
|
|
|
|
+ xlog_warn("XFS: Log allocation failed: No memory!");
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
|
|
log->l_mp = mp;
|
|
log->l_mp = mp;
|
|
log->l_targ = log_target;
|
|
log->l_targ = log_target;
|
|
@@ -1201,19 +1203,35 @@ xlog_alloc_log(xfs_mount_t *mp,
|
|
log->l_grant_reserve_cycle = 1;
|
|
log->l_grant_reserve_cycle = 1;
|
|
log->l_grant_write_cycle = 1;
|
|
log->l_grant_write_cycle = 1;
|
|
|
|
|
|
|
|
+ error = EFSCORRUPTED;
|
|
if (xfs_sb_version_hassector(&mp->m_sb)) {
|
|
if (xfs_sb_version_hassector(&mp->m_sb)) {
|
|
log->l_sectbb_log = mp->m_sb.sb_logsectlog - BBSHIFT;
|
|
log->l_sectbb_log = mp->m_sb.sb_logsectlog - BBSHIFT;
|
|
- ASSERT(log->l_sectbb_log <= mp->m_sectbb_log);
|
|
|
|
|
|
+ if (log->l_sectbb_log < 0 ||
|
|
|
|
+ log->l_sectbb_log > mp->m_sectbb_log) {
|
|
|
|
+ xlog_warn("XFS: Log sector size (0x%x) out of range.",
|
|
|
|
+ log->l_sectbb_log);
|
|
|
|
+ goto out_free_log;
|
|
|
|
+ }
|
|
|
|
+
|
|
/* for larger sector sizes, must have v2 or external log */
|
|
/* for larger sector sizes, must have v2 or external log */
|
|
- ASSERT(log->l_sectbb_log == 0 ||
|
|
|
|
- log->l_logBBstart == 0 ||
|
|
|
|
- xfs_sb_version_haslogv2(&mp->m_sb));
|
|
|
|
- ASSERT(mp->m_sb.sb_logsectlog >= BBSHIFT);
|
|
|
|
|
|
+ if (log->l_sectbb_log != 0 &&
|
|
|
|
+ (log->l_logBBstart != 0 &&
|
|
|
|
+ !xfs_sb_version_haslogv2(&mp->m_sb))) {
|
|
|
|
+ xlog_warn("XFS: log sector size (0x%x) invalid "
|
|
|
|
+ "for configuration.", log->l_sectbb_log);
|
|
|
|
+ goto out_free_log;
|
|
|
|
+ }
|
|
|
|
+ if (mp->m_sb.sb_logsectlog < BBSHIFT) {
|
|
|
|
+ xlog_warn("XFS: Log sector log (0x%x) too small.",
|
|
|
|
+ mp->m_sb.sb_logsectlog);
|
|
|
|
+ goto out_free_log;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
log->l_sectbb_mask = (1 << log->l_sectbb_log) - 1;
|
|
log->l_sectbb_mask = (1 << log->l_sectbb_log) - 1;
|
|
|
|
|
|
xlog_get_iclog_buffer_size(mp, log);
|
|
xlog_get_iclog_buffer_size(mp, log);
|
|
|
|
|
|
|
|
+ error = ENOMEM;
|
|
bp = xfs_buf_get_empty(log->l_iclog_size, mp->m_logdev_targp);
|
|
bp = xfs_buf_get_empty(log->l_iclog_size, mp->m_logdev_targp);
|
|
if (!bp)
|
|
if (!bp)
|
|
goto out_free_log;
|
|
goto out_free_log;
|
|
@@ -1313,7 +1331,8 @@ out_free_iclog:
|
|
xfs_buf_free(log->l_xbuf);
|
|
xfs_buf_free(log->l_xbuf);
|
|
out_free_log:
|
|
out_free_log:
|
|
kmem_free(log);
|
|
kmem_free(log);
|
|
- return NULL;
|
|
|
|
|
|
+out:
|
|
|
|
+ return ERR_PTR(-error);
|
|
} /* xlog_alloc_log */
|
|
} /* xlog_alloc_log */
|
|
|
|
|
|
|
|
|
|
@@ -2541,18 +2560,19 @@ redo:
|
|
xlog_ins_ticketq(&log->l_reserve_headq, tic);
|
|
xlog_ins_ticketq(&log->l_reserve_headq, tic);
|
|
xlog_trace_loggrant(log, tic,
|
|
xlog_trace_loggrant(log, tic,
|
|
"xlog_grant_log_space: sleep 2");
|
|
"xlog_grant_log_space: sleep 2");
|
|
|
|
+ spin_unlock(&log->l_grant_lock);
|
|
|
|
+ xlog_grant_push_ail(log->l_mp, need_bytes);
|
|
|
|
+ spin_lock(&log->l_grant_lock);
|
|
|
|
+
|
|
XFS_STATS_INC(xs_sleep_logspace);
|
|
XFS_STATS_INC(xs_sleep_logspace);
|
|
sv_wait(&tic->t_wait, PINOD|PLTWAIT, &log->l_grant_lock, s);
|
|
sv_wait(&tic->t_wait, PINOD|PLTWAIT, &log->l_grant_lock, s);
|
|
|
|
|
|
- if (XLOG_FORCED_SHUTDOWN(log)) {
|
|
|
|
- spin_lock(&log->l_grant_lock);
|
|
|
|
|
|
+ spin_lock(&log->l_grant_lock);
|
|
|
|
+ if (XLOG_FORCED_SHUTDOWN(log))
|
|
goto error_return;
|
|
goto error_return;
|
|
- }
|
|
|
|
|
|
|
|
xlog_trace_loggrant(log, tic,
|
|
xlog_trace_loggrant(log, tic,
|
|
"xlog_grant_log_space: wake 2");
|
|
"xlog_grant_log_space: wake 2");
|
|
- xlog_grant_push_ail(log->l_mp, need_bytes);
|
|
|
|
- spin_lock(&log->l_grant_lock);
|
|
|
|
goto redo;
|
|
goto redo;
|
|
} else if (tic->t_flags & XLOG_TIC_IN_Q)
|
|
} else if (tic->t_flags & XLOG_TIC_IN_Q)
|
|
xlog_del_ticketq(&log->l_reserve_headq, tic);
|
|
xlog_del_ticketq(&log->l_reserve_headq, tic);
|
|
@@ -2631,7 +2651,7 @@ xlog_regrant_write_log_space(xlog_t *log,
|
|
* for more free space, otherwise try to get some space for
|
|
* for more free space, otherwise try to get some space for
|
|
* this transaction.
|
|
* this transaction.
|
|
*/
|
|
*/
|
|
-
|
|
|
|
|
|
+ need_bytes = tic->t_unit_res;
|
|
if ((ntic = log->l_write_headq)) {
|
|
if ((ntic = log->l_write_headq)) {
|
|
free_bytes = xlog_space_left(log, log->l_grant_write_cycle,
|
|
free_bytes = xlog_space_left(log, log->l_grant_write_cycle,
|
|
log->l_grant_write_bytes);
|
|
log->l_grant_write_bytes);
|
|
@@ -2651,26 +2671,25 @@ xlog_regrant_write_log_space(xlog_t *log,
|
|
|
|
|
|
xlog_trace_loggrant(log, tic,
|
|
xlog_trace_loggrant(log, tic,
|
|
"xlog_regrant_write_log_space: sleep 1");
|
|
"xlog_regrant_write_log_space: sleep 1");
|
|
|
|
+ spin_unlock(&log->l_grant_lock);
|
|
|
|
+ xlog_grant_push_ail(log->l_mp, need_bytes);
|
|
|
|
+ spin_lock(&log->l_grant_lock);
|
|
|
|
+
|
|
XFS_STATS_INC(xs_sleep_logspace);
|
|
XFS_STATS_INC(xs_sleep_logspace);
|
|
sv_wait(&tic->t_wait, PINOD|PLTWAIT,
|
|
sv_wait(&tic->t_wait, PINOD|PLTWAIT,
|
|
&log->l_grant_lock, s);
|
|
&log->l_grant_lock, s);
|
|
|
|
|
|
/* If we're shutting down, this tic is already
|
|
/* If we're shutting down, this tic is already
|
|
* off the queue */
|
|
* off the queue */
|
|
- if (XLOG_FORCED_SHUTDOWN(log)) {
|
|
|
|
- spin_lock(&log->l_grant_lock);
|
|
|
|
|
|
+ spin_lock(&log->l_grant_lock);
|
|
|
|
+ if (XLOG_FORCED_SHUTDOWN(log))
|
|
goto error_return;
|
|
goto error_return;
|
|
- }
|
|
|
|
|
|
|
|
xlog_trace_loggrant(log, tic,
|
|
xlog_trace_loggrant(log, tic,
|
|
"xlog_regrant_write_log_space: wake 1");
|
|
"xlog_regrant_write_log_space: wake 1");
|
|
- xlog_grant_push_ail(log->l_mp, tic->t_unit_res);
|
|
|
|
- spin_lock(&log->l_grant_lock);
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- need_bytes = tic->t_unit_res;
|
|
|
|
-
|
|
|
|
redo:
|
|
redo:
|
|
if (XLOG_FORCED_SHUTDOWN(log))
|
|
if (XLOG_FORCED_SHUTDOWN(log))
|
|
goto error_return;
|
|
goto error_return;
|
|
@@ -2680,19 +2699,20 @@ redo:
|
|
if (free_bytes < need_bytes) {
|
|
if (free_bytes < need_bytes) {
|
|
if ((tic->t_flags & XLOG_TIC_IN_Q) == 0)
|
|
if ((tic->t_flags & XLOG_TIC_IN_Q) == 0)
|
|
xlog_ins_ticketq(&log->l_write_headq, tic);
|
|
xlog_ins_ticketq(&log->l_write_headq, tic);
|
|
|
|
+ spin_unlock(&log->l_grant_lock);
|
|
|
|
+ xlog_grant_push_ail(log->l_mp, need_bytes);
|
|
|
|
+ spin_lock(&log->l_grant_lock);
|
|
|
|
+
|
|
XFS_STATS_INC(xs_sleep_logspace);
|
|
XFS_STATS_INC(xs_sleep_logspace);
|
|
sv_wait(&tic->t_wait, PINOD|PLTWAIT, &log->l_grant_lock, s);
|
|
sv_wait(&tic->t_wait, PINOD|PLTWAIT, &log->l_grant_lock, s);
|
|
|
|
|
|
/* If we're shutting down, this tic is already off the queue */
|
|
/* If we're shutting down, this tic is already off the queue */
|
|
- if (XLOG_FORCED_SHUTDOWN(log)) {
|
|
|
|
- spin_lock(&log->l_grant_lock);
|
|
|
|
|
|
+ spin_lock(&log->l_grant_lock);
|
|
|
|
+ if (XLOG_FORCED_SHUTDOWN(log))
|
|
goto error_return;
|
|
goto error_return;
|
|
- }
|
|
|
|
|
|
|
|
xlog_trace_loggrant(log, tic,
|
|
xlog_trace_loggrant(log, tic,
|
|
"xlog_regrant_write_log_space: wake 2");
|
|
"xlog_regrant_write_log_space: wake 2");
|
|
- xlog_grant_push_ail(log->l_mp, need_bytes);
|
|
|
|
- spin_lock(&log->l_grant_lock);
|
|
|
|
goto redo;
|
|
goto redo;
|
|
} else if (tic->t_flags & XLOG_TIC_IN_Q)
|
|
} else if (tic->t_flags & XLOG_TIC_IN_Q)
|
|
xlog_del_ticketq(&log->l_write_headq, tic);
|
|
xlog_del_ticketq(&log->l_write_headq, tic);
|