diff -urN 2.3.41/fs/buffer.c buf-flush/fs/buffer.c --- 2.3.41/fs/buffer.c Sun Jan 9 20:45:31 2000 +++ buf-flush/fs/buffer.c Wed Feb 2 16:47:07 2000 @@ -820,8 +820,10 @@ dirty = size_buffers_type[BUF_DIRTY] >> PAGE_SHIFT; tot = nr_free_buffer_pages(); - hard_dirty_limit = tot * bdf_prm.b_un.nfract / 100; - soft_dirty_limit = hard_dirty_limit >> 1; + + dirty *= 200; + soft_dirty_limit = tot * bdf_prm.b_un.nfract; + hard_dirty_limit = soft_dirty_limit * 2; if (dirty > soft_dirty_limit) { @@ -2000,7 +2002,7 @@ */ int try_to_free_buffers(struct page * page) { - struct buffer_head * tmp, * bh = page->buffers; + struct buffer_head * tmp, * p, * bh = page->buffers; int index = BUFSIZE_INDEX(bh->b_size); int ret; @@ -2009,7 +2011,7 @@ spin_lock(&free_list[index].lock); tmp = bh; do { - struct buffer_head * p = tmp; + p = tmp; tmp = tmp->b_this_page; if (buffer_busy(p)) @@ -2051,7 +2053,8 @@ busy_buffer_page: /* Uhhuh, start writeback so that we don't end up with all dirty pages */ - wakeup_bdflush(0); + if (buffer_dirty(p)) + wakeup_bdflush(0); ret = 0; goto out; } @@ -2210,7 +2213,7 @@ as all dirty buffers lives _only_ in the DIRTY lru list. As we never browse the LOCKED and CLEAN lru lists they are infact completly useless. */ -static void flush_dirty_buffers(int check_flushtime) +static int flush_dirty_buffers(int check_flushtime) { struct buffer_head * bh, *next; int flushed = 0, i; @@ -2259,6 +2262,8 @@ } out_unlock: spin_unlock(&lru_list_lock); + + return flushed; } /* @@ -2342,6 +2347,7 @@ */ int bdflush(void * unused) { + int flushed; /* * We have a bare-bones task_struct, and really should fill * in a few more things so "top" and /proc/2/{exe,root,cwd} @@ -2363,7 +2369,7 @@ for (;;) { CHECK_EMERGENCY_SYNC - flush_dirty_buffers(0); + flushed = flush_dirty_buffers(0); /* If wakeup_bdflush will wakeup us after our bdflush_done wakeup, then @@ -2378,10 +2384,10 @@ /* * If there are still a lot of dirty buffers around, * skip the sleep and flush some more. Otherwise, we - * sleep for a while. + * go to sleep waiting a wakeup. */ - if (balance_dirty_state(NODEV) < 0) - schedule_timeout(5*HZ); + if (!flushed || balance_dirty_state(NODEV) < 0) + schedule(); /* Remember to mark us as running otherwise the next schedule will block. */ __set_current_state(TASK_RUNNING);