diff options
author | Jan Kara <jack@suse.cz> | 2012-05-03 08:47:56 -0400 |
---|---|---|
committer | Fengguang Wu <fengguang.wu@intel.com> | 2012-05-06 01:43:38 -0400 |
commit | cc1676d917f32504dbadc858fa790bc524c9f0da (patch) | |
tree | d665d5ad0a844a6b1aff74deb4c8aa01c7596135 | |
parent | 365b94ae67d2915d412b593d47449a6bffed9d37 (diff) |
writeback: Move requeueing when I_SYNC set to writeback_sb_inodes()
When writeback_single_inode() is called on inode which has I_SYNC already
set while doing WB_SYNC_NONE, inode is moved to b_more_io list. However
this makes sense only if the caller is flusher thread. For other callers of
writeback_single_inode() it doesn't really make sense and may be even wrong
- flusher thread may be doing WB_SYNC_ALL writeback in parallel.
So we move requeueing from writeback_single_inode() to writeback_sb_inodes().
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
-rw-r--r-- | fs/fs-writeback.c | 30 | ||||
-rw-r--r-- | include/trace/events/writeback.h | 36 |
2 files changed, 45 insertions, 21 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index dd41437b7a1f..65cd14769226 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -373,21 +373,8 @@ writeback_single_inode(struct inode *inode, struct bdi_writeback *wb, | |||
373 | WARN_ON(inode->i_state & I_WILL_FREE); | 373 | WARN_ON(inode->i_state & I_WILL_FREE); |
374 | 374 | ||
375 | if (inode->i_state & I_SYNC) { | 375 | if (inode->i_state & I_SYNC) { |
376 | /* | 376 | if (wbc->sync_mode != WB_SYNC_ALL) |
377 | * If this inode is locked for writeback and we are not doing | ||
378 | * writeback-for-data-integrity, move it to b_more_io so that | ||
379 | * writeback can proceed with the other inodes on s_io. | ||
380 | * | ||
381 | * We'll have another go at writing back this inode when we | ||
382 | * completed a full scan of b_io. | ||
383 | */ | ||
384 | if (wbc->sync_mode != WB_SYNC_ALL) { | ||
385 | requeue_io(inode, wb); | ||
386 | trace_writeback_single_inode_requeue(inode, wbc, | ||
387 | nr_to_write); | ||
388 | return 0; | 377 | return 0; |
389 | } | ||
390 | |||
391 | /* | 378 | /* |
392 | * It's a data-integrity sync. We must wait. | 379 | * It's a data-integrity sync. We must wait. |
393 | */ | 380 | */ |
@@ -576,6 +563,21 @@ static long writeback_sb_inodes(struct super_block *sb, | |||
576 | redirty_tail(inode, wb); | 563 | redirty_tail(inode, wb); |
577 | continue; | 564 | continue; |
578 | } | 565 | } |
566 | if ((inode->i_state & I_SYNC) && wbc.sync_mode != WB_SYNC_ALL) { | ||
567 | /* | ||
568 | * If this inode is locked for writeback and we are not | ||
569 | * doing writeback-for-data-integrity, move it to | ||
570 | * b_more_io so that writeback can proceed with the | ||
571 | * other inodes on s_io. | ||
572 | * | ||
573 | * We'll have another go at writing back this inode | ||
574 | * when we completed a full scan of b_io. | ||
575 | */ | ||
576 | spin_unlock(&inode->i_lock); | ||
577 | requeue_io(inode, wb); | ||
578 | trace_writeback_sb_inodes_requeue(inode); | ||
579 | continue; | ||
580 | } | ||
579 | __iget(inode); | 581 | __iget(inode); |
580 | write_chunk = writeback_chunk_size(wb->bdi, work); | 582 | write_chunk = writeback_chunk_size(wb->bdi, work); |
581 | wbc.nr_to_write = write_chunk; | 583 | wbc.nr_to_write = write_chunk; |
diff --git a/include/trace/events/writeback.h b/include/trace/events/writeback.h index 7b81887b023f..b453d92c2253 100644 --- a/include/trace/events/writeback.h +++ b/include/trace/events/writeback.h | |||
@@ -372,6 +372,35 @@ TRACE_EVENT(balance_dirty_pages, | |||
372 | ) | 372 | ) |
373 | ); | 373 | ); |
374 | 374 | ||
375 | TRACE_EVENT(writeback_sb_inodes_requeue, | ||
376 | |||
377 | TP_PROTO(struct inode *inode), | ||
378 | TP_ARGS(inode), | ||
379 | |||
380 | TP_STRUCT__entry( | ||
381 | __array(char, name, 32) | ||
382 | __field(unsigned long, ino) | ||
383 | __field(unsigned long, state) | ||
384 | __field(unsigned long, dirtied_when) | ||
385 | ), | ||
386 | |||
387 | TP_fast_assign( | ||
388 | strncpy(__entry->name, | ||
389 | dev_name(inode_to_bdi(inode)->dev), 32); | ||
390 | __entry->ino = inode->i_ino; | ||
391 | __entry->state = inode->i_state; | ||
392 | __entry->dirtied_when = inode->dirtied_when; | ||
393 | ), | ||
394 | |||
395 | TP_printk("bdi %s: ino=%lu state=%s dirtied_when=%lu age=%lu", | ||
396 | __entry->name, | ||
397 | __entry->ino, | ||
398 | show_inode_state(__entry->state), | ||
399 | __entry->dirtied_when, | ||
400 | (jiffies - __entry->dirtied_when) / HZ | ||
401 | ) | ||
402 | ); | ||
403 | |||
375 | DECLARE_EVENT_CLASS(writeback_congest_waited_template, | 404 | DECLARE_EVENT_CLASS(writeback_congest_waited_template, |
376 | 405 | ||
377 | TP_PROTO(unsigned int usec_timeout, unsigned int usec_delayed), | 406 | TP_PROTO(unsigned int usec_timeout, unsigned int usec_delayed), |
@@ -450,13 +479,6 @@ DECLARE_EVENT_CLASS(writeback_single_inode_template, | |||
450 | ) | 479 | ) |
451 | ); | 480 | ); |
452 | 481 | ||
453 | DEFINE_EVENT(writeback_single_inode_template, writeback_single_inode_requeue, | ||
454 | TP_PROTO(struct inode *inode, | ||
455 | struct writeback_control *wbc, | ||
456 | unsigned long nr_to_write), | ||
457 | TP_ARGS(inode, wbc, nr_to_write) | ||
458 | ); | ||
459 | |||
460 | DEFINE_EVENT(writeback_single_inode_template, writeback_single_inode, | 482 | DEFINE_EVENT(writeback_single_inode_template, writeback_single_inode, |
461 | TP_PROTO(struct inode *inode, | 483 | TP_PROTO(struct inode *inode, |
462 | struct writeback_control *wbc, | 484 | struct writeback_control *wbc, |