aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6/xfs_sync.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2008-10-30 02:14:53 -0400
committerLachlan McIlroy <lachlan@sgi.com>2008-10-30 02:14:53 -0400
commit2af75df7be7ca86965bf73766f827575d1c26fbd (patch)
tree59a7acdf30d8f6088ebe4d88ce0f8d43be966671 /fs/xfs/linux-2.6/xfs_sync.c
parent4e8938feba770b583fb13d249c17943961731a3e (diff)
[XFS] split out two helpers from xfs_syncsub
Split out two helpers from xfs_syncsub for the dummy log commit and the superblock writeout. SGI-PV: 988140 SGI-Modid: xfs-linux-melb:xfs-kern:32303a Signed-off-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: David Chinner <david@fromorbit.com> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_sync.c')
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.c162
1 files changed, 93 insertions, 69 deletions
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c
index 53d85ecb1d50..59da3327a6b5 100644
--- a/fs/xfs/linux-2.6/xfs_sync.c
+++ b/fs/xfs/linux-2.6/xfs_sync.c
@@ -315,6 +315,93 @@ xfs_sync_inodes(
315 return XFS_ERROR(last_error); 315 return XFS_ERROR(last_error);
316} 316}
317 317
318STATIC int
319xfs_commit_dummy_trans(
320 struct xfs_mount *mp,
321 uint log_flags)
322{
323 struct xfs_inode *ip = mp->m_rootip;
324 struct xfs_trans *tp;
325 int error;
326
327 /*
328 * Put a dummy transaction in the log to tell recovery
329 * that all others are OK.
330 */
331 tp = xfs_trans_alloc(mp, XFS_TRANS_DUMMY1);
332 error = xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0);
333 if (error) {
334 xfs_trans_cancel(tp, 0);
335 return error;
336 }
337
338 xfs_ilock(ip, XFS_ILOCK_EXCL);
339
340 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
341 xfs_trans_ihold(tp, ip);
342 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
343 /* XXX(hch): ignoring the error here.. */
344 error = xfs_trans_commit(tp, 0);
345
346 xfs_iunlock(ip, XFS_ILOCK_EXCL);
347
348 xfs_log_force(mp, 0, log_flags);
349 return 0;
350}
351
352STATIC int
353xfs_sync_fsdata(
354 struct xfs_mount *mp,
355 int flags)
356{
357 struct xfs_buf *bp;
358 struct xfs_buf_log_item *bip;
359 int error = 0;
360
361 /*
362 * If this is xfssyncd() then only sync the superblock if we can
363 * lock it without sleeping and it is not pinned.
364 */
365 if (flags & SYNC_BDFLUSH) {
366 ASSERT(!(flags & SYNC_WAIT));
367
368 bp = xfs_getsb(mp, XFS_BUF_TRYLOCK);
369 if (!bp)
370 goto out;
371
372 bip = XFS_BUF_FSPRIVATE(bp, struct xfs_buf_log_item *);
373 if (!bip || !xfs_buf_item_dirty(bip) || XFS_BUF_ISPINNED(bp))
374 goto out_brelse;
375 } else {
376 bp = xfs_getsb(mp, 0);
377
378 /*
379 * If the buffer is pinned then push on the log so we won't
380 * get stuck waiting in the write for someone, maybe
381 * ourselves, to flush the log.
382 *
383 * Even though we just pushed the log above, we did not have
384 * the superblock buffer locked at that point so it can
385 * become pinned in between there and here.
386 */
387 if (XFS_BUF_ISPINNED(bp))
388 xfs_log_force(mp, 0, XFS_LOG_FORCE);
389 }
390
391
392 if (flags & SYNC_WAIT)
393 XFS_BUF_UNASYNC(bp);
394 else
395 XFS_BUF_ASYNC(bp);
396
397 return xfs_bwrite(mp, bp);
398
399 out_brelse:
400 xfs_buf_relse(bp);
401 out:
402 return error;
403}
404
318/* 405/*
319 * xfs sync routine for internal use 406 * xfs sync routine for internal use
320 * 407 *
@@ -331,8 +418,6 @@ xfs_syncsub(
331 int error = 0; 418 int error = 0;
332 int last_error = 0; 419 int last_error = 0;
333 uint log_flags = XFS_LOG_FORCE; 420 uint log_flags = XFS_LOG_FORCE;
334 xfs_buf_t *bp;
335 xfs_buf_log_item_t *bip;
336 421
337 /* 422 /*
338 * Sync out the log. This ensures that the log is periodically 423 * Sync out the log. This ensures that the log is periodically
@@ -355,83 +440,22 @@ xfs_syncsub(
355 * log activity, so if this isn't vfs_sync() then flush 440 * log activity, so if this isn't vfs_sync() then flush
356 * the log again. 441 * the log again.
357 */ 442 */
358 if (flags & SYNC_DELWRI) { 443 if (flags & SYNC_DELWRI)
359 xfs_log_force(mp, (xfs_lsn_t)0, log_flags); 444 xfs_log_force(mp, 0, log_flags);
360 }
361 445
362 if (flags & SYNC_FSDATA) { 446 if (flags & SYNC_FSDATA) {
363 /* 447 error = xfs_sync_fsdata(mp, flags);
364 * If this is vfs_sync() then only sync the superblock 448 if (error)
365 * if we can lock it without sleeping and it is not pinned.
366 */
367 if (flags & SYNC_BDFLUSH) {
368 bp = xfs_getsb(mp, XFS_BUF_TRYLOCK);
369 if (bp != NULL) {
370 bip = XFS_BUF_FSPRIVATE(bp,xfs_buf_log_item_t*);
371 if ((bip != NULL) &&
372 xfs_buf_item_dirty(bip)) {
373 if (!(XFS_BUF_ISPINNED(bp))) {
374 XFS_BUF_ASYNC(bp);
375 error = xfs_bwrite(mp, bp);
376 } else {
377 xfs_buf_relse(bp);
378 }
379 } else {
380 xfs_buf_relse(bp);
381 }
382 }
383 } else {
384 bp = xfs_getsb(mp, 0);
385 /*
386 * If the buffer is pinned then push on the log so
387 * we won't get stuck waiting in the write for
388 * someone, maybe ourselves, to flush the log.
389 * Even though we just pushed the log above, we
390 * did not have the superblock buffer locked at
391 * that point so it can become pinned in between
392 * there and here.
393 */
394 if (XFS_BUF_ISPINNED(bp))
395 xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE);
396 if (flags & SYNC_WAIT)
397 XFS_BUF_UNASYNC(bp);
398 else
399 XFS_BUF_ASYNC(bp);
400 error = xfs_bwrite(mp, bp);
401 }
402 if (error) {
403 last_error = error; 449 last_error = error;
404 }
405 } 450 }
406 451
407 /* 452 /*
408 * Now check to see if the log needs a "dummy" transaction. 453 * Now check to see if the log needs a "dummy" transaction.
409 */ 454 */
410 if (!(flags & SYNC_REMOUNT) && xfs_log_need_covered(mp)) { 455 if (!(flags & SYNC_REMOUNT) && xfs_log_need_covered(mp)) {
411 xfs_trans_t *tp; 456 error = xfs_commit_dummy_trans(mp, log_flags);
412 xfs_inode_t *ip; 457 if (error)
413
414 /*
415 * Put a dummy transaction in the log to tell
416 * recovery that all others are OK.
417 */
418 tp = xfs_trans_alloc(mp, XFS_TRANS_DUMMY1);
419 if ((error = xfs_trans_reserve(tp, 0,
420 XFS_ICHANGE_LOG_RES(mp),
421 0, 0, 0))) {
422 xfs_trans_cancel(tp, 0);
423 return error; 458 return error;
424 }
425
426 ip = mp->m_rootip;
427 xfs_ilock(ip, XFS_ILOCK_EXCL);
428
429 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
430 xfs_trans_ihold(tp, ip);
431 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
432 error = xfs_trans_commit(tp, 0);
433 xfs_iunlock(ip, XFS_ILOCK_EXCL);
434 xfs_log_force(mp, (xfs_lsn_t)0, log_flags);
435 } 459 }
436 460
437 /* 461 /*