From: NeilBrown Date: Fri, 9 Jul 2010 10:49:54 +0000 (+1000) Subject: Make sure we don't wait forever on writeback X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=c921b7192b592faf80fa50cfce3237c9930c2897;p=LaFS.git Make sure we don't wait forever on writeback If we ever wait on writeback on a block, we need to cluster_flush quite promptly or we could wait forever. Signed-off-by: NeilBrown --- diff --git a/clean.c b/clean.c index 54405d4..709dc92 100644 --- a/clean.c +++ b/clean.c @@ -92,6 +92,9 @@ static int cleaner(void *data) timeout); clear_bit(CleanerNeeded, &fs->fsstate); + if (test_and_clear_bit(FlushNeeded, &fs->fsstate)) + lafs_cluster_flush(fs, 0); + timeout = MAX_SCHEDULE_TIMEOUT; to = lafs_do_checkpoint(fs); if (to < timeout) @@ -139,6 +142,15 @@ void lafs_wake_cleaner(struct fs *fs) wake_up(&fs->async_complete); } +void lafs_trigger_flush(struct block *b) +{ + struct fs *fs = fs_from_inode(b->inode); + + if (test_bit(B_Writeback, &b->flags) && + !test_and_set_bit(FlushNeeded, &fs->fsstate)) + lafs_wake_cleaner(fs); +} + static int mark_cleaning(struct block *b) { int err; diff --git a/io.c b/io.c index 7d35a45..82d92a6 100644 --- a/io.c +++ b/io.c @@ -373,6 +373,7 @@ static void wait_writeback(struct block *b) { if (test_bit(B_Writeback, &b->flags)) { DEFINE_WAIT(wq); + lafs_trigger_flush(b); for (;;) { prepare_to_wait(&block_wait, &wq, TASK_UNINTERRUPTIBLE); if (test_bit(B_Writeback, &b->flags)) @@ -404,6 +405,7 @@ int _lafs_iolock_written_async(struct block *b) /* Writeback was set by a racing thread.. */ lafs_iounlock_block(b); } + lafs_trigger_flush(b); if (test_and_set_bit(B_Async, &b->flags)) return 0; diff --git a/lafs.h b/lafs.h index 1024a87..4043e9b 100644 --- a/lafs.h +++ b/lafs.h @@ -641,6 +641,7 @@ int lafs_start_cleaner(struct fs *fs); void lafs_stop_cleaner(struct fs *fs); void lafs_wake_cleaner(struct fs *fs); void lafs_unclean(struct datablock *db); +void lafs_trigger_flush(struct block *b); /* cluster.c */ int lafs_cluster_allocate(struct block *b, int cnum); diff --git a/state.h b/state.h index b9d462f..95b96c5 100644 --- a/state.h +++ b/state.h @@ -99,6 +99,9 @@ struct fs { * be full and new allocation requests get * -ENOSPC */ +#define FlushNeeded 8 /* Need to flush the current cluster because + * someone is waiting on writeback + */ struct work_struct done_work; /* used for handling * refile after write completes */