Пример #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;
}
Пример #2
0
static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait)
{
    mdk_rdev_t *rdev;
    struct list_head *tmp;
    mddev_t *mddev = bitmap->mddev;

    ITERATE_RDEV(mddev, rdev, tmp)
    if (test_bit(In_sync, &rdev->flags)
            && !test_bit(Faulty, &rdev->flags)) {
        int size = PAGE_SIZE;
        if (page->index == bitmap->file_pages-1)
            size = roundup(bitmap->last_page_size,
                           bdev_hardsect_size(rdev->bdev));
        /* Just make sure we aren't corrupting data or
         * metadata
         */
        if (bitmap->offset < 0) {
            /* DATA  BITMAP METADATA  */
            if (bitmap->offset
                    + page->index * (PAGE_SIZE/512)
                    + size/512 > 0)
                /* bitmap runs in to metadata */
                return -EINVAL;
            if (rdev->data_offset + mddev->size*2
                    > rdev->sb_offset*2 + bitmap->offset)
                /* data runs in to bitmap */
                return -EINVAL;
        } else if (rdev->sb_offset*2 < rdev->data_offset) {
            /* METADATA BITMAP DATA */
            if (rdev->sb_offset*2
                    + bitmap->offset
                    + page->index*(PAGE_SIZE/512) + size/512
                    > rdev->data_offset)
                /* bitmap runs in to data */
                return -EINVAL;
        } else {
            /* DATA METADATA BITMAP - no problems */
        }
        md_super_write(mddev, rdev,
                       (rdev->sb_offset<<1) + bitmap->offset
                       + page->index * (PAGE_SIZE/512),
                       size,
                       page);
    }

    if (wait)
        md_super_wait(mddev);
    return 0;
}
Пример #3
0
static int write_sb_page(mddev_t *mddev, long offset, struct page *page, int wait)
{
    mdk_rdev_t *rdev;
    struct list_head *tmp;

    ITERATE_RDEV(mddev, rdev, tmp)
    if (test_bit(In_sync, &rdev->flags)
            && !test_bit(Faulty, &rdev->flags))
        md_super_write(mddev, rdev,
                       (rdev->sb_offset<<1) + offset
                       + page->index * (PAGE_SIZE/512),
                       PAGE_SIZE,
                       page);

    if (wait)
        md_super_wait(mddev);
    return 0;
}
Пример #4
0
static int write_sb_page(mddev_t *mddev, long offset, struct page *page, int wait)
{
	mdk_rdev_t *rdev;

	rcu_read_lock();
	rdev_for_each_rcu(rdev, mddev)
		if (test_bit(In_sync, &rdev->flags)
		    && !test_bit(Faulty, &rdev->flags))
			md_super_write(mddev, rdev,
				       (rdev->sb_offset<<1) + offset
				       + page->index * (PAGE_SIZE/512),
				       PAGE_SIZE,
				       page);
	rcu_read_unlock();

	if (wait)
		md_super_wait(mddev);
	return 0;
}
Пример #5
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;
}
Пример #6
0
static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait)
{
	mdk_rdev_t *rdev;
	struct list_head *tmp;
	mddev_t *mddev = bitmap->mddev;

	ITERATE_RDEV(mddev, rdev, tmp)
		if (test_bit(In_sync, &rdev->flags)
		    && !test_bit(Faulty, &rdev->flags)) {
			int size = PAGE_SIZE;
			if (page->index == bitmap->file_pages-1)
				size = roundup(bitmap->last_page_size,
					       bdev_hardsect_size(rdev->bdev));
			md_super_write(mddev, rdev,
				       (rdev->sb_offset<<1) + bitmap->offset
				       + page->index * (PAGE_SIZE/512),
				       size,
				       page);
		}

	if (wait)
		md_super_wait(mddev);
	return 0;
}