aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_log.c
diff options
context:
space:
mode:
authorTim Shimmin <tes@sgi.com>2005-09-02 02:41:43 -0400
committerNathan Scott <nathans@sgi.com>2005-09-02 02:41:43 -0400
commit32fb9b57aef35b82434cfb4c9de18b484fc3ec88 (patch)
tree6905e66c1ef26d321fdf2cd1fc9421ebde67937b /fs/xfs/xfs_log.c
parentd52b44d07a43b723ac2fbf1bf4053031f723676c (diff)
[XFS] Fix up the calculation of the reservation overhead to hopefully
include all the components which make up the transaction in the ondisk log. Having this incomplete has shown up as problems on IRIX when some v2 log changes went in. The symptom was the msg of "xfs_log_write: reservation ran out. Need to up reservation" and was seen on synchronous writes on files with lots of holes (and therefore lots of extents). SGI-PV: 931457 SGI-Modid: xfs-linux:xfs-kern:23095a Signed-off-by: Tim Shimmin <tes@sgi.com> Signed-off-by: Nathan Scott <nathans@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_log.c')
-rw-r--r--fs/xfs/xfs_log.c54
1 files changed, 41 insertions, 13 deletions
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 1cd2ac163877..42975cb9e538 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -3179,29 +3179,57 @@ xlog_ticket_get(xlog_t *log,
3179 * and their unit amount is the total amount of space required. 3179 * and their unit amount is the total amount of space required.
3180 * 3180 *
3181 * The following lines of code account for non-transaction data 3181 * The following lines of code account for non-transaction data
3182 * which occupy space in the on-disk log. 3182 * which occupy space in the on-disk log.
3183 *
3184 * Normal form of a transaction is:
3185 * <oph><trans-hdr><start-oph><reg1-oph><reg1><reg2-oph>...<commit-oph>
3186 * and then there are LR hdrs, split-recs and roundoff at end of syncs.
3187 *
3188 * We need to account for all the leadup data and trailer data
3189 * around the transaction data.
3190 * And then we need to account for the worst case in terms of using
3191 * more space.
3192 * The worst case will happen if:
3193 * - the placement of the transaction happens to be such that the
3194 * roundoff is at its maximum
3195 * - the transaction data is synced before the commit record is synced
3196 * i.e. <transaction-data><roundoff> | <commit-rec><roundoff>
3197 * Therefore the commit record is in its own Log Record.
3198 * This can happen as the commit record is called with its
3199 * own region to xlog_write().
3200 * This then means that in the worst case, roundoff can happen for
3201 * the commit-rec as well.
3202 * The commit-rec is smaller than padding in this scenario and so it is
3203 * not added separately.
3183 */ 3204 */
3184 3205
3206 /* for trans header */
3207 unit_bytes += sizeof(xlog_op_header_t);
3208 unit_bytes += sizeof(xfs_trans_header_t);
3209
3185 /* for start-rec */ 3210 /* for start-rec */
3186 unit_bytes += sizeof(xlog_op_header_t); 3211 unit_bytes += sizeof(xlog_op_header_t);
3212
3213 /* for LR headers */
3214 num_headers = ((unit_bytes + log->l_iclog_size-1) >> log->l_iclog_size_log);
3215 unit_bytes += log->l_iclog_hsize * num_headers;
3187 3216
3188 /* for padding */ 3217 /* for commit-rec LR header - note: padding will subsume the ophdr */
3218 unit_bytes += log->l_iclog_hsize;
3219
3220 /* for split-recs - ophdrs added when data split over LRs */
3221 unit_bytes += sizeof(xlog_op_header_t) * num_headers;
3222
3223 /* for roundoff padding for transaction data and one for commit record */
3189 if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) && 3224 if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) &&
3190 log->l_mp->m_sb.sb_logsunit > 1) { 3225 log->l_mp->m_sb.sb_logsunit > 1) {
3191 /* log su roundoff */ 3226 /* log su roundoff */
3192 unit_bytes += log->l_mp->m_sb.sb_logsunit; 3227 unit_bytes += 2*log->l_mp->m_sb.sb_logsunit;
3193 } else { 3228 } else {
3194 /* BB roundoff */ 3229 /* BB roundoff */
3195 unit_bytes += BBSIZE; 3230 unit_bytes += 2*BBSIZE;
3196 } 3231 }
3197 3232
3198 /* for commit-rec */
3199 unit_bytes += sizeof(xlog_op_header_t);
3200
3201 /* for LR headers */
3202 num_headers = ((unit_bytes + log->l_iclog_size-1) >> log->l_iclog_size_log);
3203 unit_bytes += log->l_iclog_hsize * num_headers;
3204
3205 tic->t_unit_res = unit_bytes; 3233 tic->t_unit_res = unit_bytes;
3206 tic->t_curr_res = unit_bytes; 3234 tic->t_curr_res = unit_bytes;
3207 tic->t_cnt = cnt; 3235 tic->t_cnt = cnt;