From: NeilBrown Date: Sat, 2 Oct 2010 04:31:21 +0000 (+1000) Subject: Don't use I_ICredit for UnincCredit when cleaning. X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=9f5dbbc17ecfcd2e9158b7072da42731a91a633e;p=LaFS.git Don't use I_ICredit for UnincCredit when cleaning. ICredit is only to be used when dirtying a block, so any setting of UnincCredit for cleaning must get the credit from elsewhere. If no such credit is available, fall back on dirtying the block. Signed-off-by: NeilBrown --- diff --git a/clean.c b/clean.c index f135cf5..ed37560 100644 --- a/clean.c +++ b/clean.c @@ -17,6 +17,7 @@ static int mark_cleaning(struct block *b) { int err; + int credits; if (test_bit(B_Realloc, &b->flags)) /* As cleaning is single threaded, @@ -29,13 +30,12 @@ static int mark_cleaning(struct block *b) if (err) return err; LAFS_BUG(!test_bit(B_Valid, &b->flags), b); - if (!test_bit(B_Realloc, &b->flags)) { - if (lafs_space_alloc(fs_from_inode(b->inode), 1, CleanSpace) == 1) { - if (test_and_set_bit(B_Realloc, &b->flags)) - lafs_space_return(fs_from_inode(b->inode), 1); - } else - return -EAGAIN; - } + credits = lafs_space_alloc(fs_from_inode(b->inode), 2, CleanSpace); + if (credits == 0) + return -EAGAIN; + if (!test_and_set_bit(B_Realloc, &b->flags)) + credits--; + lafs_pin_block(b); if (test_bit(B_Dirty, &b->flags)) { /* If dirty, then now that it is pinned, @@ -43,14 +43,12 @@ static int mark_cleaning(struct block *b) * Realloc */ if (test_and_clear_bit(B_Realloc, &b->flags)) - if (test_and_set_bit(B_Credit, &b->flags)) - lafs_space_return(fs_from_inode(b->inode), 1); - return 0; + credits++; } if (!test_and_set_bit(B_UnincCredit, &b->flags)) - if (!test_and_clear_bit(B_ICredit, &b->flags)) - LAFS_BUG(1, b); // ICredit should be set before we dirty a block. + credits--; + lafs_space_return(fs_from_inode(b->inode), credits); lafs_refile(b, 0); lafs_refile(&b->parent->b, 0); diff --git a/cluster.c b/cluster.c index b94387a..168426f 100644 --- a/cluster.c +++ b/cluster.c @@ -531,13 +531,13 @@ static int flush_data_to_inode(struct block *b) int credits = 1; LAFS_BUG(!test_bit(B_Valid, &lai->iblock->b.flags), &lai->iblock->b); + if (test_and_clear_bit(B_UnincCredit, &b->flags)) + credits++; if (!test_and_set_bit(B_Realloc, &lai->iblock->b.flags)) credits--; if (!test_and_set_bit(B_UnincCredit, &lai->iblock->b.flags)) - if (!test_and_clear_bit(B_ICredit, - &lai->iblock->b.flags)) - if (!test_and_clear_bit(B_UnincCredit, &b->flags)) - LAFS_BUG(1, b); /* We needed an UnincCredit */ + credits--; + LAFS_BUG(credits < 0, b); lafs_space_return(fs, credits); } else { printk("Wasn't dirty or realloc: %s\n", strblk(b)); @@ -689,17 +689,20 @@ int lafs_cluster_allocate(struct block *b, int cnum) */ LAFS_BUG(!test_bit(B_Valid, &b2->flags), b2); - if (!test_and_set_bit(B_UnincCredit, &b2->flags)) - if (!test_and_clear_bit(B_ICredit, &b2->flags)) - credits--; - if (cnum == 0) { + if (!test_and_set_bit(B_UnincCredit, &b2->flags)) + if (!test_and_clear_bit(B_ICredit, &b2->flags)) + credits--; + if (!test_bit(B_Dirty, &b2->flags)) /* need some credits... */ if (!test_and_set_bit(B_Credit, &b2->flags)) credits--; lafs_dirty_dblock(dblk(b2)); } else { + if (!test_and_set_bit(B_UnincCredit, &b2->flags)) + credits--; + if (!test_and_set_bit(B_Realloc, &b2->flags)) credits--; } diff --git a/index.c b/index.c index 5fa3037..32af941 100644 --- a/index.c +++ b/index.c @@ -2203,11 +2203,14 @@ new_parent: } else lafs_dirty_iblock(p); } - if (!test_and_set_bit(B_UnincCredit, &p->b.flags)) - if (!test_and_clear_bit(B_ICredit, &p->b.flags)) - LAFS_BUG(1, &p->b); // ICredit should be set before - //we dirty a block. - + if (!test_bit(B_UnincCredit, &p->b.flags)) { + /* Ditto for UnincCredit */ + if (lafs_space_alloc(fs, 1, CleanSpace) == 1) { + if (test_and_set_bit(B_UnincCredit, &p->b.flags)) + lafs_space_return(fs, 1); + } else + lafs_dirty_iblock(p); + } } dprintk("Uninc same phase\n");