Exemplo n.º 1
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, attr, flags;
    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];
        attr = get_page_attr(bitmap, page);
        clear_page_attr(bitmap, page, BITMAP_PAGE_DIRTY);
        clear_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE);
        if ((attr & BITMAP_PAGE_DIRTY))
            wait = 1;
        spin_unlock_irqrestore(&bitmap->lock, flags);

        if (attr & (BITMAP_PAGE_DIRTY | BITMAP_PAGE_NEEDWRITE)) {
            err = write_page(bitmap, page, 0);
            if (err == -EAGAIN) {
                if (attr & BITMAP_PAGE_DIRTY)
                    err = write_page(bitmap, page, 1);
                else
                    err = 0;
            }
            if (err)
                return 1;
        }
    }
    if (wait) { /* if any writes were performed, we need to wait on them */
        if (bitmap->file) {
            spin_lock_irq(&bitmap->write_lock);
            wait_event_lock_irq(bitmap->write_wait,
                                list_empty(&bitmap->complete_pages), bitmap->write_lock,
                                wake_up_process(bitmap->writeback_daemon->tsk));
            spin_unlock_irq(&bitmap->write_lock);
        } else
            md_super_wait(bitmap->mddev);
    }
    return 0;
}
Exemplo n.º 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;
}