aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_buf_item.c12
-rw-r--r--fs/xfs/xfs_ialloc.c32
2 files changed, 33 insertions, 11 deletions
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index 61f68768ee84..bfc4e0c26fd3 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -310,13 +310,21 @@ xfs_buf_item_format(
310 310
311 /* 311 /*
312 * If it is an inode buffer, transfer the in-memory state to the 312 * If it is an inode buffer, transfer the in-memory state to the
313 * format flags and clear the in-memory state. We do not transfer 313 * format flags and clear the in-memory state.
314 *
315 * For buffer based inode allocation, we do not transfer
314 * this state if the inode buffer allocation has not yet been committed 316 * this state if the inode buffer allocation has not yet been committed
315 * to the log as setting the XFS_BLI_INODE_BUF flag will prevent 317 * to the log as setting the XFS_BLI_INODE_BUF flag will prevent
316 * correct replay of the inode allocation. 318 * correct replay of the inode allocation.
319 *
320 * For icreate item based inode allocation, the buffers aren't written
321 * to the journal during allocation, and hence we should always tag the
322 * buffer as an inode buffer so that the correct unlinked list replay
323 * occurs during recovery.
317 */ 324 */
318 if (bip->bli_flags & XFS_BLI_INODE_BUF) { 325 if (bip->bli_flags & XFS_BLI_INODE_BUF) {
319 if (!((bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF) && 326 if (xfs_sb_version_hascrc(&lip->li_mountp->m_sb) ||
327 !((bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF) &&
320 xfs_log_item_in_current_chkpt(lip))) 328 xfs_log_item_in_current_chkpt(lip)))
321 bip->__bli_format.blf_flags |= XFS_BLF_INODE_BUF; 329 bip->__bli_format.blf_flags |= XFS_BLF_INODE_BUF;
322 bip->bli_flags &= ~XFS_BLI_INODE_BUF; 330 bip->bli_flags &= ~XFS_BLI_INODE_BUF;
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index 4411565b718b..7a0c17d7ec09 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -38,6 +38,7 @@
38#include "xfs_bmap.h" 38#include "xfs_bmap.h"
39#include "xfs_cksum.h" 39#include "xfs_cksum.h"
40#include "xfs_buf_item.h" 40#include "xfs_buf_item.h"
41#include "xfs_icreate_item.h"
41 42
42 43
43/* 44/*
@@ -155,7 +156,7 @@ xfs_check_agi_freecount(
155 * than logging them (which in a transaction context puts them into the AIL 156 * than logging them (which in a transaction context puts them into the AIL
156 * for writeback rather than the xfsbufd queue). 157 * for writeback rather than the xfsbufd queue).
157 */ 158 */
158STATIC int 159int
159xfs_ialloc_inode_init( 160xfs_ialloc_inode_init(
160 struct xfs_mount *mp, 161 struct xfs_mount *mp,
161 struct xfs_trans *tp, 162 struct xfs_trans *tp,
@@ -212,6 +213,18 @@ xfs_ialloc_inode_init(
212 version = 3; 213 version = 3;
213 ino = XFS_AGINO_TO_INO(mp, agno, 214 ino = XFS_AGINO_TO_INO(mp, agno,
214 XFS_OFFBNO_TO_AGINO(mp, agbno, 0)); 215 XFS_OFFBNO_TO_AGINO(mp, agbno, 0));
216
217 /*
218 * log the initialisation that is about to take place as an
219 * logical operation. This means the transaction does not
220 * need to log the physical changes to the inode buffers as log
221 * recovery will know what initialisation is actually needed.
222 * Hence we only need to log the buffers as "ordered" buffers so
223 * they track in the AIL as if they were physically logged.
224 */
225 if (tp)
226 xfs_icreate_log(tp, agno, agbno, XFS_IALLOC_INODES(mp),
227 mp->m_sb.sb_inodesize, length, gen);
215 } else if (xfs_sb_version_hasnlink(&mp->m_sb)) 228 } else if (xfs_sb_version_hasnlink(&mp->m_sb))
216 version = 2; 229 version = 2;
217 else 230 else
@@ -227,13 +240,8 @@ xfs_ialloc_inode_init(
227 XBF_UNMAPPED); 240 XBF_UNMAPPED);
228 if (!fbuf) 241 if (!fbuf)
229 return ENOMEM; 242 return ENOMEM;
230 /* 243
231 * Initialize all inodes in this buffer and then log them. 244 /* Initialize the inode buffers and log them appropriately. */
232 *
233 * XXX: It would be much better if we had just one transaction
234 * to log a whole cluster of inodes instead of all the
235 * individual transactions causing a lot of log traffic.
236 */
237 fbuf->b_ops = &xfs_inode_buf_ops; 245 fbuf->b_ops = &xfs_inode_buf_ops;
238 xfs_buf_zero(fbuf, 0, BBTOB(fbuf->b_length)); 246 xfs_buf_zero(fbuf, 0, BBTOB(fbuf->b_length));
239 for (i = 0; i < ninodes; i++) { 247 for (i = 0; i < ninodes; i++) {
@@ -269,7 +277,13 @@ xfs_ialloc_inode_init(
269 */ 277 */
270 xfs_trans_inode_alloc_buf(tp, fbuf); 278 xfs_trans_inode_alloc_buf(tp, fbuf);
271 if (version == 3) { 279 if (version == 3) {
272 /* need to log the entire buffer */ 280 /*
281 * Mark the buffer as ordered so that they are
282 * not physically logged in the transaction but
283 * still tracked in the AIL as part of the
284 * transaction and pin the log appropriately.
285 */
286 xfs_trans_ordered_buf(tp, fbuf);
273 xfs_trans_log_buf(tp, fbuf, 0, 287 xfs_trans_log_buf(tp, fbuf, 0,
274 BBTOB(fbuf->b_length) - 1); 288 BBTOB(fbuf->b_length) - 1);
275 } 289 }