From c9bcd77485535586b544db6251faff8827c2e457 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sat, 3 Jul 2010 11:24:17 +1000 Subject: [PATCH] Add iolock_written_async There are a couple of places where this open coded. Do it properly and use B_Async to keep the block around. Also wake the cleaner thread when a B_Async block finished writeback. Signed-off-by: NeilBrown --- inode.c | 20 ++++++-------------- io.c | 37 ++++++++++++++++++++++++++++++++++--- lafs.h | 6 +++--- 3 files changed, 43 insertions(+), 20 deletions(-) diff --git a/inode.c b/inode.c index 20d8235..8eb00f9 100644 --- a/inode.c +++ b/inode.c @@ -704,13 +704,7 @@ restart: LAFS_BUG(1, &ib2->b); } - /* lafs_iolock_written(&ib2->b); - without blocking */ - if (!lafs_iolock_block_async(&ib2->b)) { - putiref(ib2, MKREF(inode_handle_orphan2)); - goto out2; - } - if (test_bit(B_Writeback, &ib2->b.flags)) { - lafs_iounlock_block(&ib2->b); + if (!lafs_iolock_written_async(&ib2->b)) { putiref(ib2, MKREF(inode_handle_orphan2)); do_restart = 0; goto out2; @@ -731,13 +725,11 @@ restart: BUG(); } putiref(ib2, MKREF(inode_handle_orphan2)); - if (ib->uninc) { - if (lafs_iolock_block_async(&ib->b)) { - if (!test_bit(B_Writeback, &ib->b.flags)) - while (ib->uninc) - lafs_incorporate(fs, ib); - lafs_iounlock_block(&ib->b); - } + if (ib->uninc && + lafs_iolock_written_async(&ib->b)) { + while (ib->uninc) + lafs_incorporate(fs, ib); + lafs_iounlock_block(&ib->b); } out2: putiref(ib, MKREF(inode_handle_orphan)); diff --git a/io.c b/io.c index b6837f5..aa78a37 100644 --- a/io.c +++ b/io.c @@ -212,6 +212,18 @@ void _lafs_iolock_block(struct block *b) } } +int _lafs_iolock_block_async(struct block *b) { + if (test_bit(B_IOLock, &b->flags)) + if (!test_and_set_bit(B_Async, &b->flags)) + getref(b, MKREF(async)); + if (test_and_set_bit(B_IOLock, &b->flags)) + return 0; + + if (test_and_clear_bit(B_Async, &b->flags)) + putref(b, MKREF(async)); + return 1; +} + void lafs_iounlock_block(struct block *b) { @@ -226,8 +238,7 @@ lafs_iounlock_block(struct block *b) lafs_iocheck_block(dblk(b), 1); lafs_io_wake(b); - if (test_bit(B_Async, &b->flags) || - test_bit(B_Orphan, &b->flags)) + if (test_bit(B_Async, &b->flags)) lafs_wake_cleaner(fs_from_inode(b->inode)); } @@ -240,6 +251,8 @@ void lafs_writeback_done(struct block *b) if (test_bit(B_Index, &b->flags)) { clear_bit(B_Writeback, &b->flags); lafs_io_wake(b); + if (test_bit(B_Async, &b->flags)) + lafs_wake_cleaner(fs_from_inode(b->inode)); } else lafs_iocheck_writeback(dblk(b), 1); } @@ -307,8 +320,11 @@ void lafs_iocheck_writeback(struct datablock *db, int unlock) if (havewrite) end_page_writeback(page); - if (unlock) + if (unlock) { lafs_io_wake(&db->b); + if (test_bit(B_Async, &db->b.flags)) + lafs_wake_cleaner(fs_from_inode(db->b.inode)); + } } int __must_check @@ -370,6 +386,21 @@ void _lafs_iolock_written(struct block *b) wait_writeback(b); } +int _lafs_iolock_written_async(struct block *b) +{ + if (!_lafs_iolock_block_async(b)) + return 0; + if (test_bit(B_Writeback, &b->flags)) + if (!test_and_set_bit(B_Async, &b->flags)) + getref(b, MKREF(async)); + if (test_bit(B_Writeback, &b->flags)) + return 0; + + if (test_and_clear_bit(B_Async, &b->flags)) + putref(b, MKREF(async)); + return 1; +} + static void block_loaded(struct bio *bio, int error) { diff --git a/lafs.h b/lafs.h index 606d3b7..1024a87 100644 --- a/lafs.h +++ b/lafs.h @@ -118,13 +118,13 @@ int lafs_index_empty(struct indexblock *ib); #define lafs_iolock_block(b) do { _lafs_iolock_block(b); set_iolock_info(b); } while(0) #define lafs_iolock_block_async(b) ( _lafs_iolock_block_async(b) ? ( set_iolock_info(b), 1) : 0) #define lafs_iolock_written(b) do { _lafs_iolock_written(b); set_iolock_info(b); } while(0) +#define lafs_iolock_written_async(b) ( _lafs_iolock_written_async(b) ? ( set_iolock_info(b), 1) : 0) void lafs_io_wake(struct block *b); void _lafs_iolock_block(struct block *b); void _lafs_iolock_written(struct block *b); -static inline int _lafs_iolock_block_async(struct block *b) { - return !test_and_set_bit(B_IOLock, &b->flags); -} +int _lafs_iolock_block_async(struct block *b); +int _lafs_iolock_written_async(struct block *b); void lafs_iounlock_block(struct block *b); void lafs_iocheck_block(struct datablock *db, int unlock); -- 2.39.5