/* 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; }
/* 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; }