if (bitmap->file == NULL)
return write_sb_page(bitmap->mddev, bitmap->offset, page, wait);
- lock_page(page);
+ if (wait)
+ lock_page(page);
+ else {
+ if (TestSetPageLocked(page))
+ return -EAGAIN; /* already locked */
+ if (PageWriteback(page)) {
+ unlock_page(page);
+ return -EAGAIN;
+ }
+ }
ret = page->mapping->a_ops->prepare_write(NULL, page, 0, PAGE_SIZE);
if (!ret)
if (!bitmap->mddev->degraded)
sb->events_cleared = cpu_to_le64(bitmap->mddev->events);
kunmap(bitmap->sb_page);
- return write_page(bitmap, bitmap->sb_page, 0);
+ return write_page(bitmap, bitmap->sb_page, 1);
}
/* print out the bitmap file superblock */
unsigned long i, attr, flags;
struct page *page;
int wait = 0;
+ int err;
if (!bitmap)
return 0;
wait = 1;
spin_unlock_irqrestore(&bitmap->lock, flags);
- if (attr & (BITMAP_PAGE_DIRTY | BITMAP_PAGE_NEEDWRITE))
- if (write_page(bitmap, page, 0))
+ 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_unlock_irqrestore(&bitmap->lock, flags);
if (attr & BITMAP_PAGE_NEEDWRITE) {
- if (write_page(bitmap, page, 0))
+ switch (write_page(bitmap, page, 0)) {
+ case -EAGAIN:
+ set_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE);
+ break;
+ case 0:
+ break;
+ default:
bitmap_file_kick(bitmap);
+ }
page_cache_release(page);
}
continue;
clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
spin_unlock_irqrestore(&bitmap->lock, flags);
err = write_page(bitmap, lastpage, 0);
+ if (err == -EAGAIN) {
+ err = 0;
+ set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
+ }
} else {
set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
spin_unlock_irqrestore(&bitmap->lock, flags);
clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
spin_unlock_irqrestore(&bitmap->lock, flags);
err = write_page(bitmap, lastpage, 0);
+ if (err == -EAGAIN) {
+ set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
+ err = 0;
+ }
} else {
set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
spin_unlock_irqrestore(&bitmap->lock, flags);
}
}
-/* dirty the entire bitmap */
-int bitmap_setallbits(struct bitmap *bitmap)
-{
- unsigned long flags;
- unsigned long j;
-
- /* dirty the in-memory bitmap */
- bitmap_set_memory_bits(bitmap, 0, bitmap->chunks << CHUNK_BLOCK_SHIFT(bitmap), 1);
-
- /* dirty the bitmap file */
- for (j = 0; j < bitmap->file_pages; j++) {
- struct page *page = bitmap->filemap[j];
-
- spin_lock_irqsave(&bitmap->lock, flags);
- page_cache_get(page);
- spin_unlock_irqrestore(&bitmap->lock, flags);
- memset(kmap(page), 0xff, PAGE_SIZE);
- kunmap(page);
- if (write_page(bitmap, page, 0))
- return 1;
- }
-
- return 0;
-}
-
/*
* free memory that was allocated
*/