xfs: block callers of xfs_flush_inodes() correctly

xfs_flush_inodes() currently uses a magic timeout to wait for
some inodes to be flushed before returning. This isn't
really reliable but used to be the best that could be done
due to deadlock potential of waiting for the entire flush.

Now the inode flush is safe to execute while we hold page
and inode locks, we can wait for all the inodes to flush
synchronously. Convert the wait mechanism to a completion
to do this efficiently. This should remove all remaining
spurious ENOSPC errors from the delayed allocation reservation
path.

This is extracted almost line for line from a larger patch
from Mikulas Patocka.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>

authored by

Dave Chinner and committed by
Christoph Hellwig
e43afd72 5825294e

+10 -3
+9 -3
fs/xfs/linux-2.6/xfs_sync.c
··· 404 xfs_syncd_queue_work( 405 struct xfs_mount *mp, 406 void *data, 407 - void (*syncer)(struct xfs_mount *, void *)) 408 { 409 struct xfs_sync_work *work; 410 ··· 414 work->w_syncer = syncer; 415 work->w_data = data; 416 work->w_mount = mp; 417 spin_lock(&mp->m_sync_lock); 418 list_add_tail(&work->w_list, &mp->m_sync_list); 419 spin_unlock(&mp->m_sync_lock); ··· 443 xfs_inode_t *ip) 444 { 445 struct inode *inode = VFS_I(ip); 446 447 igrab(inode); 448 - xfs_syncd_queue_work(ip->i_mount, inode, xfs_flush_inodes_work); 449 - delay(msecs_to_jiffies(500)); 450 xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC); 451 } 452 ··· 517 list_del(&work->w_list); 518 if (work == &mp->m_sync_work) 519 continue; 520 kmem_free(work); 521 } 522 } ··· 532 { 533 mp->m_sync_work.w_syncer = xfs_sync_worker; 534 mp->m_sync_work.w_mount = mp; 535 mp->m_sync_task = kthread_run(xfssyncd, mp, "xfssyncd"); 536 if (IS_ERR(mp->m_sync_task)) 537 return -PTR_ERR(mp->m_sync_task);
··· 404 xfs_syncd_queue_work( 405 struct xfs_mount *mp, 406 void *data, 407 + void (*syncer)(struct xfs_mount *, void *), 408 + struct completion *completion) 409 { 410 struct xfs_sync_work *work; 411 ··· 413 work->w_syncer = syncer; 414 work->w_data = data; 415 work->w_mount = mp; 416 + work->w_completion = completion; 417 spin_lock(&mp->m_sync_lock); 418 list_add_tail(&work->w_list, &mp->m_sync_list); 419 spin_unlock(&mp->m_sync_lock); ··· 441 xfs_inode_t *ip) 442 { 443 struct inode *inode = VFS_I(ip); 444 + DECLARE_COMPLETION_ONSTACK(completion); 445 446 igrab(inode); 447 + xfs_syncd_queue_work(ip->i_mount, inode, xfs_flush_inodes_work, &completion); 448 + wait_for_completion(&completion); 449 xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC); 450 } 451 ··· 514 list_del(&work->w_list); 515 if (work == &mp->m_sync_work) 516 continue; 517 + if (work->w_completion) 518 + complete(work->w_completion); 519 kmem_free(work); 520 } 521 } ··· 527 { 528 mp->m_sync_work.w_syncer = xfs_sync_worker; 529 mp->m_sync_work.w_mount = mp; 530 + mp->m_sync_work.w_completion = NULL; 531 mp->m_sync_task = kthread_run(xfssyncd, mp, "xfssyncd"); 532 if (IS_ERR(mp->m_sync_task)) 533 return -PTR_ERR(mp->m_sync_task);
+1
fs/xfs/linux-2.6/xfs_sync.h
··· 26 struct xfs_mount *w_mount; 27 void *w_data; /* syncer routine argument */ 28 void (*w_syncer)(struct xfs_mount *, void *); 29 } xfs_sync_work_t; 30 31 #define SYNC_ATTR 0x0001 /* sync attributes */
··· 26 struct xfs_mount *w_mount; 27 void *w_data; /* syncer routine argument */ 28 void (*w_syncer)(struct xfs_mount *, void *); 29 + struct completion *w_completion; 30 } xfs_sync_work_t; 31 32 #define SYNC_ATTR 0x0001 /* sync attributes */