diff options
Diffstat (limited to 'fs/fs-writeback.c')
| -rw-r--r-- | fs/fs-writeback.c | 22 | 
1 files changed, 13 insertions, 9 deletions
| diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 1a7c42c64ff4..76fc4d594acb 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
| @@ -381,10 +381,10 @@ static void queue_io(struct bdi_writeback *wb, unsigned long *older_than_this) | |||
| 381 | move_expired_inodes(&wb->b_dirty, &wb->b_io, older_than_this); | 381 | move_expired_inodes(&wb->b_dirty, &wb->b_io, older_than_this); | 
| 382 | } | 382 | } | 
| 383 | 383 | ||
| 384 | static int write_inode(struct inode *inode, int sync) | 384 | static int write_inode(struct inode *inode, struct writeback_control *wbc) | 
| 385 | { | 385 | { | 
| 386 | if (inode->i_sb->s_op->write_inode && !is_bad_inode(inode)) | 386 | if (inode->i_sb->s_op->write_inode && !is_bad_inode(inode)) | 
| 387 | return inode->i_sb->s_op->write_inode(inode, sync); | 387 | return inode->i_sb->s_op->write_inode(inode, wbc); | 
| 388 | return 0; | 388 | return 0; | 
| 389 | } | 389 | } | 
| 390 | 390 | ||
| @@ -421,7 +421,6 @@ static int | |||
| 421 | writeback_single_inode(struct inode *inode, struct writeback_control *wbc) | 421 | writeback_single_inode(struct inode *inode, struct writeback_control *wbc) | 
| 422 | { | 422 | { | 
| 423 | struct address_space *mapping = inode->i_mapping; | 423 | struct address_space *mapping = inode->i_mapping; | 
| 424 | int wait = wbc->sync_mode == WB_SYNC_ALL; | ||
| 425 | unsigned dirty; | 424 | unsigned dirty; | 
| 426 | int ret; | 425 | int ret; | 
| 427 | 426 | ||
| @@ -439,7 +438,7 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc) | |||
| 439 | * We'll have another go at writing back this inode when we | 438 | * We'll have another go at writing back this inode when we | 
| 440 | * completed a full scan of b_io. | 439 | * completed a full scan of b_io. | 
| 441 | */ | 440 | */ | 
| 442 | if (!wait) { | 441 | if (wbc->sync_mode != WB_SYNC_ALL) { | 
| 443 | requeue_io(inode); | 442 | requeue_io(inode); | 
| 444 | return 0; | 443 | return 0; | 
| 445 | } | 444 | } | 
| @@ -461,15 +460,20 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc) | |||
| 461 | 460 | ||
| 462 | ret = do_writepages(mapping, wbc); | 461 | ret = do_writepages(mapping, wbc); | 
| 463 | 462 | ||
| 464 | /* Don't write the inode if only I_DIRTY_PAGES was set */ | 463 | /* | 
| 465 | if (dirty & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) { | 464 | * Make sure to wait on the data before writing out the metadata. | 
| 466 | int err = write_inode(inode, wait); | 465 | * This is important for filesystems that modify metadata on data | 
| 466 | * I/O completion. | ||
| 467 | */ | ||
| 468 | if (wbc->sync_mode == WB_SYNC_ALL) { | ||
| 469 | int err = filemap_fdatawait(mapping); | ||
| 467 | if (ret == 0) | 470 | if (ret == 0) | 
| 468 | ret = err; | 471 | ret = err; | 
| 469 | } | 472 | } | 
| 470 | 473 | ||
| 471 | if (wait) { | 474 | /* Don't write the inode if only I_DIRTY_PAGES was set */ | 
| 472 | int err = filemap_fdatawait(mapping); | 475 | if (dirty & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) { | 
| 476 | int err = write_inode(inode, wbc); | ||
| 473 | if (ret == 0) | 477 | if (ret == 0) | 
| 474 | ret = err; | 478 | ret = err; | 
| 475 | } | 479 | } | 
