+static int
+flush_cmp(const void *X, const void *Y)
+{
+ struct page *x = *((struct page **)X);
+ struct page *y = *((struct page **)Y);
+
+ if (x->fd < y->fd)
+ return -1;
+ if (x->fd > y->fd)
+ return 1;
+ if (x->pos < y->pos)
+ return -1;
+ if (x->pos > y->pos)
+ return 1;
+ return 0;
+}
+
+static void
+flush_pages(struct page_cache *c, uns force)
+{
+ uns cnt = 0;
+ uns max = force ? ~0U : c->free_count / 2;
+ uns i;
+ struct page *p, *q, **req, **rr;
+
+ WALK_LIST(p, c->dirty_pages)
+ {
+ cnt++;
+ if (cnt >= max)
+ break;
+ }
+ req = rr = alloca(cnt * sizeof(struct page *));
+ i = cnt;
+ p = HEAD(c->dirty_pages);
+ while ((q = (struct page *) p->n.next) && i--)
+ {
+ rem_node(&p->n);
+ add_tail(&c->free_pages, &p->n);
+ *rr++ = p;
+ p = q;
+ }
+ qsort(req, cnt, sizeof(struct page *), flush_cmp);
+ for(i=0; i<cnt; i++)
+ flush_page(c, req[i]);
+}
+