aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6/xfs_sync.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_sync.c')
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.c78
1 files changed, 33 insertions, 45 deletions
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c
index a608e72fa405..f7ba76633c29 100644
--- a/fs/xfs/linux-2.6/xfs_sync.c
+++ b/fs/xfs/linux-2.6/xfs_sync.c
@@ -62,12 +62,6 @@ xfs_sync_inodes_ag(
62 uint32_t first_index = 0; 62 uint32_t first_index = 0;
63 int error = 0; 63 int error = 0;
64 int last_error = 0; 64 int last_error = 0;
65 int fflag = XFS_B_ASYNC;
66
67 if (flags & SYNC_DELWRI)
68 fflag = XFS_B_DELWRI;
69 if (flags & SYNC_WAIT)
70 fflag = 0; /* synchronous overrides all */
71 65
72 do { 66 do {
73 struct inode *inode; 67 struct inode *inode;
@@ -128,11 +122,23 @@ xfs_sync_inodes_ag(
128 * If we have to flush data or wait for I/O completion 122 * If we have to flush data or wait for I/O completion
129 * we need to hold the iolock. 123 * we need to hold the iolock.
130 */ 124 */
131 if ((flags & SYNC_DELWRI) && VN_DIRTY(inode)) { 125 if (flags & SYNC_DELWRI) {
132 xfs_ilock(ip, XFS_IOLOCK_SHARED); 126 if (VN_DIRTY(inode)) {
133 lock_flags |= XFS_IOLOCK_SHARED; 127 if (flags & SYNC_TRYLOCK) {
134 error = xfs_flush_pages(ip, 0, -1, fflag, FI_NONE); 128 if (xfs_ilock_nowait(ip, XFS_IOLOCK_SHARED))
135 if (flags & SYNC_IOWAIT) 129 lock_flags |= XFS_IOLOCK_SHARED;
130 } else {
131 xfs_ilock(ip, XFS_IOLOCK_SHARED);
132 lock_flags |= XFS_IOLOCK_SHARED;
133 }
134 if (lock_flags & XFS_IOLOCK_SHARED) {
135 error = xfs_flush_pages(ip, 0, -1,
136 (flags & SYNC_WAIT) ? 0
137 : XFS_B_ASYNC,
138 FI_NONE);
139 }
140 }
141 if (VN_CACHED(inode) && (flags & SYNC_IOWAIT))
136 xfs_ioend_wait(ip); 142 xfs_ioend_wait(ip);
137 } 143 }
138 xfs_ilock(ip, XFS_ILOCK_SHARED); 144 xfs_ilock(ip, XFS_ILOCK_SHARED);
@@ -398,15 +404,17 @@ STATIC void
398xfs_syncd_queue_work( 404xfs_syncd_queue_work(
399 struct xfs_mount *mp, 405 struct xfs_mount *mp,
400 void *data, 406 void *data,
401 void (*syncer)(struct xfs_mount *, void *)) 407 void (*syncer)(struct xfs_mount *, void *),
408 struct completion *completion)
402{ 409{
403 struct bhv_vfs_sync_work *work; 410 struct xfs_sync_work *work;
404 411
405 work = kmem_alloc(sizeof(struct bhv_vfs_sync_work), KM_SLEEP); 412 work = kmem_alloc(sizeof(struct xfs_sync_work), KM_SLEEP);
406 INIT_LIST_HEAD(&work->w_list); 413 INIT_LIST_HEAD(&work->w_list);
407 work->w_syncer = syncer; 414 work->w_syncer = syncer;
408 work->w_data = data; 415 work->w_data = data;
409 work->w_mount = mp; 416 work->w_mount = mp;
417 work->w_completion = completion;
410 spin_lock(&mp->m_sync_lock); 418 spin_lock(&mp->m_sync_lock);
411 list_add_tail(&work->w_list, &mp->m_sync_list); 419 list_add_tail(&work->w_list, &mp->m_sync_list);
412 spin_unlock(&mp->m_sync_lock); 420 spin_unlock(&mp->m_sync_lock);
@@ -420,49 +428,26 @@ xfs_syncd_queue_work(
420 * heads, looking about for more room... 428 * heads, looking about for more room...
421 */ 429 */
422STATIC void 430STATIC void
423xfs_flush_inode_work( 431xfs_flush_inodes_work(
424 struct xfs_mount *mp,
425 void *arg)
426{
427 struct inode *inode = arg;
428 filemap_flush(inode->i_mapping);
429 iput(inode);
430}
431
432void
433xfs_flush_inode(
434 xfs_inode_t *ip)
435{
436 struct inode *inode = VFS_I(ip);
437
438 igrab(inode);
439 xfs_syncd_queue_work(ip->i_mount, inode, xfs_flush_inode_work);
440 delay(msecs_to_jiffies(500));
441}
442
443/*
444 * This is the "bigger hammer" version of xfs_flush_inode_work...
445 * (IOW, "If at first you don't succeed, use a Bigger Hammer").
446 */
447STATIC void
448xfs_flush_device_work(
449 struct xfs_mount *mp, 432 struct xfs_mount *mp,
450 void *arg) 433 void *arg)
451{ 434{
452 struct inode *inode = arg; 435 struct inode *inode = arg;
453 sync_blockdev(mp->m_super->s_bdev); 436 xfs_sync_inodes(mp, SYNC_DELWRI | SYNC_TRYLOCK);
437 xfs_sync_inodes(mp, SYNC_DELWRI | SYNC_TRYLOCK | SYNC_IOWAIT);
454 iput(inode); 438 iput(inode);
455} 439}
456 440
457void 441void
458xfs_flush_device( 442xfs_flush_inodes(
459 xfs_inode_t *ip) 443 xfs_inode_t *ip)
460{ 444{
461 struct inode *inode = VFS_I(ip); 445 struct inode *inode = VFS_I(ip);
446 DECLARE_COMPLETION_ONSTACK(completion);
462 447
463 igrab(inode); 448 igrab(inode);
464 xfs_syncd_queue_work(ip->i_mount, inode, xfs_flush_device_work); 449 xfs_syncd_queue_work(ip->i_mount, inode, xfs_flush_inodes_work, &completion);
465 delay(msecs_to_jiffies(500)); 450 wait_for_completion(&completion);
466 xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC); 451 xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC);
467} 452}
468 453
@@ -497,7 +482,7 @@ xfssyncd(
497{ 482{
498 struct xfs_mount *mp = arg; 483 struct xfs_mount *mp = arg;
499 long timeleft; 484 long timeleft;
500 bhv_vfs_sync_work_t *work, *n; 485 xfs_sync_work_t *work, *n;
501 LIST_HEAD (tmp); 486 LIST_HEAD (tmp);
502 487
503 set_freezable(); 488 set_freezable();
@@ -532,6 +517,8 @@ xfssyncd(
532 list_del(&work->w_list); 517 list_del(&work->w_list);
533 if (work == &mp->m_sync_work) 518 if (work == &mp->m_sync_work)
534 continue; 519 continue;
520 if (work->w_completion)
521 complete(work->w_completion);
535 kmem_free(work); 522 kmem_free(work);
536 } 523 }
537 } 524 }
@@ -545,6 +532,7 @@ xfs_syncd_init(
545{ 532{
546 mp->m_sync_work.w_syncer = xfs_sync_worker; 533 mp->m_sync_work.w_syncer = xfs_sync_worker;
547 mp->m_sync_work.w_mount = mp; 534 mp->m_sync_work.w_mount = mp;
535 mp->m_sync_work.w_completion = NULL;
548 mp->m_sync_task = kthread_run(xfssyncd, mp, "xfssyncd"); 536 mp->m_sync_task = kthread_run(xfssyncd, mp, "xfssyncd");
549 if (IS_ERR(mp->m_sync_task)) 537 if (IS_ERR(mp->m_sync_task))
550 return -PTR_ERR(mp->m_sync_task); 538 return -PTR_ERR(mp->m_sync_task);