Exemple #1
0
/*
 * write out a page to a file
 */
static void write_page(struct bitmap *bitmap, struct page *page, int wait)
{
    struct buffer_head *bh;

    if (bitmap->file == NULL) {
        switch (write_sb_page(bitmap, page, wait)) {
        case -EINVAL:
            bitmap->flags |= BITMAP_WRITE_ERROR;
        }
    } else {

        bh = page_buffers(page);

        while (bh && bh->b_blocknr) {
            atomic_inc(&bitmap->pending_writes);
            set_buffer_locked(bh);
            set_buffer_mapped(bh);
            submit_bh(WRITE, bh);
            bh = bh->b_this_page;
        }

        if (wait) {
            wait_event(bitmap->write_wait,
                       atomic_read(&bitmap->pending_writes)==0);
        }
    }
    if (bitmap->flags & BITMAP_WRITE_ERROR)
        bitmap_file_kick(bitmap);
}
Exemple #2
0
/* this gets called when the md device is ready to unplug its underlying
 * (slave) device queues -- before we let any writes go down, we need to
 * sync the dirty pages of the bitmap file to disk */
int bitmap_unplug(struct bitmap *bitmap)
{
	unsigned long i, flags;
	int dirty, need_write;
	struct page *page;
	int wait = 0;
	int err;

	if (!bitmap)
		return 0;

	/* look at each page to see if there are any set bits that need to be
	 * flushed out to disk */
	for (i = 0; i < bitmap->file_pages; i++) {
		spin_lock_irqsave(&bitmap->lock, flags);
		if (!bitmap->filemap) {
			spin_unlock_irqrestore(&bitmap->lock, flags);
			return 0;
		}
		page = bitmap->filemap[i];
		dirty = test_page_attr(bitmap, page, BITMAP_PAGE_DIRTY);
		need_write = test_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE);
		clear_page_attr(bitmap, page, BITMAP_PAGE_DIRTY);
		clear_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE);
		if (dirty)
			wait = 1;
		spin_unlock_irqrestore(&bitmap->lock, flags);

		if (dirty | need_write)
			err = write_page(bitmap, page, 0);
	}
	if (wait) { /* if any writes were performed, we need to wait on them */
		if (bitmap->file)
			wait_event(bitmap->write_wait,
				   atomic_read(&bitmap->pending_writes)==0);
		else
			md_super_wait(bitmap->mddev);
	}
	if (bitmap->flags & BITMAP_WRITE_ERROR)
		bitmap_file_kick(bitmap);
	return 0;
}