intelfb: add vsync interrupt support
[safe/jmp/linux-2.6] / drivers / md / bitmap.c
index b65c36d..f8ffaee 100644 (file)
@@ -89,16 +89,6 @@ int bitmap_active(struct bitmap *bitmap)
 }
 
 #define WRITE_POOL_SIZE 256
-/* mempool for queueing pending writes on the bitmap file */
-static void *write_pool_alloc(gfp_t gfp_flags, void *data)
-{
-       return kmalloc(sizeof(struct page_list), gfp_flags);
-}
-
-static void write_pool_free(void *ptr, void *data)
-{
-       kfree(ptr);
-}
 
 /*
  * just a placeholder - calls kmalloc for bitmap pages
@@ -200,7 +190,7 @@ out:
 /* if page is completely empty, put it back on the free list, or dealloc it */
 /* if page was hijacked, unmark the flag so it might get alloced next time */
 /* Note: lock should be held when calling this */
-static inline void bitmap_checkfree(struct bitmap *bitmap, unsigned long page)
+static void bitmap_checkfree(struct bitmap *bitmap, unsigned long page)
 {
        char *ptr;
 
@@ -315,6 +305,8 @@ static int write_page(struct bitmap *bitmap, struct page *page, int wait)
        if (bitmap->file == NULL)
                return write_sb_page(bitmap->mddev, bitmap->offset, page, wait);
 
+       flush_dcache_page(page); /* make sure visible to anyone reading the file */
+
        if (wait)
                lock_page(page);
        else {
@@ -341,7 +333,7 @@ static int write_page(struct bitmap *bitmap, struct page *page, int wait)
                /* add to list to be waited for by daemon */
                struct page_list *item = mempool_alloc(bitmap->write_pool, GFP_NOIO);
                item->page = page;
-               page_cache_get(page);
+               get_page(page);
                spin_lock(&bitmap->write_lock);
                list_add(&item->list, &bitmap->complete_pages);
                spin_unlock(&bitmap->write_lock);
@@ -357,10 +349,10 @@ static struct page *read_page(struct file *file, unsigned long index,
        struct inode *inode = file->f_mapping->host;
        struct page *page = NULL;
        loff_t isize = i_size_read(inode);
-       unsigned long end_index = isize >> PAGE_CACHE_SHIFT;
+       unsigned long end_index = isize >> PAGE_SHIFT;
 
-       PRINTK("read bitmap file (%dB @ %Lu)\n", (int)PAGE_CACHE_SIZE,
-                       (unsigned long long)index << PAGE_CACHE_SHIFT);
+       PRINTK("read bitmap file (%dB @ %Lu)\n", (int)PAGE_SIZE,
+                       (unsigned long long)index << PAGE_SHIFT);
 
        page = read_cache_page(inode->i_mapping, index,
                        (filler_t *)inode->i_mapping->a_ops->readpage, file);
@@ -368,7 +360,7 @@ static struct page *read_page(struct file *file, unsigned long index,
                goto out;
        wait_on_page_locked(page);
        if (!PageUptodate(page) || PageError(page)) {
-               page_cache_release(page);
+               put_page(page);
                page = ERR_PTR(-EIO);
                goto out;
        }
@@ -376,14 +368,14 @@ static struct page *read_page(struct file *file, unsigned long index,
        if (index > end_index) /* we have read beyond EOF */
                *bytes_read = 0;
        else if (index == end_index) /* possible short read */
-               *bytes_read = isize & ~PAGE_CACHE_MASK;
+               *bytes_read = isize & ~PAGE_MASK;
        else
-               *bytes_read = PAGE_CACHE_SIZE; /* got a full page */
+               *bytes_read = PAGE_SIZE; /* got a full page */
 out:
        if (IS_ERR(page))
                printk(KERN_ALERT "md: bitmap read error: (%dB @ %Lu): %ld\n",
-                       (int)PAGE_CACHE_SIZE,
-                       (unsigned long long)index << PAGE_CACHE_SHIFT,
+                       (int)PAGE_SIZE,
+                       (unsigned long long)index << PAGE_SHIFT,
                        PTR_ERR(page));
        return page;
 }
@@ -406,11 +398,11 @@ int bitmap_update_sb(struct bitmap *bitmap)
                return 0;
        }
        spin_unlock_irqrestore(&bitmap->lock, flags);
-       sb = (bitmap_super_t *)kmap(bitmap->sb_page);
+       sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0);
        sb->events = cpu_to_le64(bitmap->mddev->events);
        if (!bitmap->mddev->degraded)
                sb->events_cleared = cpu_to_le64(bitmap->mddev->events);
-       kunmap(bitmap->sb_page);
+       kunmap_atomic(sb, KM_USER0);
        return write_page(bitmap, bitmap->sb_page, 1);
 }
 
@@ -421,7 +413,7 @@ void bitmap_print_sb(struct bitmap *bitmap)
 
        if (!bitmap || !bitmap->sb_page)
                return;
-       sb = (bitmap_super_t *)kmap(bitmap->sb_page);
+       sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0);
        printk(KERN_DEBUG "%s: bitmap file superblock:\n", bmname(bitmap));
        printk(KERN_DEBUG "         magic: %08x\n", le32_to_cpu(sb->magic));
        printk(KERN_DEBUG "       version: %d\n", le32_to_cpu(sb->version));
@@ -440,7 +432,7 @@ void bitmap_print_sb(struct bitmap *bitmap)
        printk(KERN_DEBUG "     sync size: %llu KB\n",
                        (unsigned long long)le64_to_cpu(sb->sync_size)/2);
        printk(KERN_DEBUG "max write behind: %d\n", le32_to_cpu(sb->write_behind));
-       kunmap(bitmap->sb_page);
+       kunmap_atomic(sb, KM_USER0);
 }
 
 /* read the superblock from the bitmap file and initialize some bitmap fields */
@@ -466,7 +458,7 @@ static int bitmap_read_sb(struct bitmap *bitmap)
                return err;
        }
 
-       sb = (bitmap_super_t *)kmap(bitmap->sb_page);
+       sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0);
 
        if (bytes_read < sizeof(*sb)) { /* short read */
                printk(KERN_INFO "%s: bitmap file superblock truncated\n",
@@ -485,12 +477,12 @@ static int bitmap_read_sb(struct bitmap *bitmap)
        else if (le32_to_cpu(sb->version) < BITMAP_MAJOR_LO ||
                 le32_to_cpu(sb->version) > BITMAP_MAJOR_HI)
                reason = "unrecognized superblock version";
-       else if (chunksize < 512 || chunksize > (1024 * 1024 * 4))
-               reason = "bitmap chunksize out of range (512B - 4MB)";
+       else if (chunksize < PAGE_SIZE)
+               reason = "bitmap chunksize too small";
        else if ((1 << ffz(~chunksize)) != chunksize)
                reason = "bitmap chunksize not a power of 2";
-       else if (daemon_sleep < 1 || daemon_sleep > 15)
-               reason = "daemon sleep period out of range (1-15s)";
+       else if (daemon_sleep < 1 || daemon_sleep > MAX_SCHEDULE_TIMEOUT / HZ)
+               reason = "daemon sleep period out of range";
        else if (write_behind > COUNTER_MAX)
                reason = "write-behind limit out of range (0 - 16383)";
        if (reason) {
@@ -535,7 +527,7 @@ success:
                bitmap->events_cleared = bitmap->mddev->events;
        err = 0;
 out:
-       kunmap(bitmap->sb_page);
+       kunmap_atomic(sb, KM_USER0);
        if (err)
                bitmap_print_sb(bitmap);
        return err;
@@ -554,13 +546,13 @@ static void bitmap_mask_state(struct bitmap *bitmap, enum bitmap_state bits,
        unsigned long flags;
 
        spin_lock_irqsave(&bitmap->lock, flags);
-       if (!bitmap || !bitmap->sb_page) { /* can't set the state */
+       if (!bitmap->sb_page) { /* can't set the state */
                spin_unlock_irqrestore(&bitmap->lock, flags);
                return;
        }
-       page_cache_get(bitmap->sb_page);
+       get_page(bitmap->sb_page);
        spin_unlock_irqrestore(&bitmap->lock, flags);
-       sb = (bitmap_super_t *)kmap(bitmap->sb_page);
+       sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0);
        switch (op) {
                case MASK_SET: sb->state |= bits;
                                break;
@@ -568,8 +560,8 @@ static void bitmap_mask_state(struct bitmap *bitmap, enum bitmap_state bits,
                                break;
                default: BUG();
        }
-       kunmap(bitmap->sb_page);
-       page_cache_release(bitmap->sb_page);
+       kunmap_atomic(sb, KM_USER0);
+       put_page(bitmap->sb_page);
 }
 
 /*
@@ -622,12 +614,11 @@ static void bitmap_file_unmap(struct bitmap *bitmap)
 
        while (pages--)
                if (map[pages]->index != 0) /* 0 is sb_page, release it below */
-                       page_cache_release(map[pages]);
+                       put_page(map[pages]);
        kfree(map);
        kfree(attr);
 
-       if (sb_page)
-               page_cache_release(sb_page);
+       safe_put_page(sb_page);
 }
 
 static void bitmap_stop_daemon(struct bitmap *bitmap);
@@ -654,7 +645,7 @@ static void drain_write_queues(struct bitmap *bitmap)
 
        while ((item = dequeue_page(bitmap))) {
                /* don't bother to wait */
-               page_cache_release(item->page);
+               put_page(item->page);
                mempool_free(item, bitmap->write_pool);
        }
 
@@ -763,7 +754,7 @@ static void bitmap_file_set_bit(struct bitmap *bitmap, sector_t block)
 
        /* make sure the page stays cached until it gets written out */
        if (! (get_page_attr(bitmap, page) & BITMAP_PAGE_DIRTY))
-               page_cache_get(page);
+               get_page(page);
 
        /* set the bit */
        kaddr = kmap_atomic(page, KM_USER0);
@@ -854,6 +845,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
        unsigned long bytes, offset, dummy;
        int outofdate;
        int ret = -ENOSPC;
+       void *paddr;
 
        chunks = bitmap->chunks;
        file = bitmap->file;
@@ -887,12 +879,10 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
        if (!bitmap->filemap)
                goto out;
 
-       bitmap->filemap_attr = kmalloc(sizeof(long) * num_pages, GFP_KERNEL);
+       bitmap->filemap_attr = kzalloc(sizeof(long) * num_pages, GFP_KERNEL);
        if (!bitmap->filemap_attr)
                goto out;
 
-       memset(bitmap->filemap_attr, 0, sizeof(long) * num_pages);
-
        oldindex = ~0L;
 
        for (i = 0; i < chunks; i++) {
@@ -901,8 +891,6 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
                bit = file_page_offset(i);
                if (index != oldindex) { /* this is a new page, read it in */
                        /* unmap the old page, we're done with it */
-                       if (oldpage != NULL)
-                               kunmap(oldpage);
                        if (index == 0) {
                                /*
                                 * if we're here then the superblock page
@@ -925,30 +913,32 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
 
                        oldindex = index;
                        oldpage = page;
-                       kmap(page);
 
                        if (outofdate) {
                                /*
                                 * if bitmap is out of date, dirty the
                                 * whole page and write it out
                                 */
-                               memset(page_address(page) + offset, 0xff,
+                               paddr = kmap_atomic(page, KM_USER0);
+                               memset(paddr + offset, 0xff,
                                       PAGE_SIZE - offset);
+                               kunmap_atomic(paddr, KM_USER0);
                                ret = write_page(bitmap, page, 1);
                                if (ret) {
-                                       kunmap(page);
                                        /* release, page not in filemap yet */
-                                       page_cache_release(page);
+                                       put_page(page);
                                        goto out;
                                }
                        }
 
                        bitmap->filemap[bitmap->file_pages++] = page;
                }
+               paddr = kmap_atomic(page, KM_USER0);
                if (bitmap->flags & BITMAP_HOSTENDIAN)
-                       b = test_bit(bit, page_address(page));
+                       b = test_bit(bit, paddr);
                else
-                       b = ext2_test_bit(bit, page_address(page));
+                       b = ext2_test_bit(bit, paddr);
+               kunmap_atomic(paddr, KM_USER0);
                if (b) {
                        /* if the disk bit is set, set the memory bit */
                        bitmap_set_memory_bits(bitmap, i << CHUNK_BLOCK_SHIFT(bitmap),
@@ -963,9 +953,6 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
        ret = 0;
        bitmap_mask_state(bitmap, BITMAP_STALE, MASK_UNSET);
 
-       if (page) /* unmap the last page */
-               kunmap(page);
-
        if (bit_cnt) { /* Kick recovery if any bits were set */
                set_bit(MD_RECOVERY_NEEDED, &bitmap->mddev->recovery);
                md_wakeup_thread(bitmap->mddev->thread);
@@ -1021,6 +1008,7 @@ int bitmap_daemon_work(struct bitmap *bitmap)
        int err = 0;
        int blocks;
        int attr;
+       void *paddr;
 
        if (bitmap == NULL)
                return 0;
@@ -1043,7 +1031,7 @@ int bitmap_daemon_work(struct bitmap *bitmap)
                        /* skip this page unless it's marked as needing cleaning */
                        if (!((attr=get_page_attr(bitmap, page)) & BITMAP_PAGE_CLEAN)) {
                                if (attr & BITMAP_PAGE_NEEDWRITE) {
-                                       page_cache_get(page);
+                                       get_page(page);
                                        clear_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE);
                                }
                                spin_unlock_irqrestore(&bitmap->lock, flags);
@@ -1057,13 +1045,13 @@ int bitmap_daemon_work(struct bitmap *bitmap)
                                        default:
                                                bitmap_file_kick(bitmap);
                                        }
-                                       page_cache_release(page);
+                                       put_page(page);
                                }
                                continue;
                        }
 
                        /* grab the new page, sync and release the old */
-                       page_cache_get(page);
+                       get_page(page);
                        if (lastpage != NULL) {
                                if (get_page_attr(bitmap, lastpage) & BITMAP_PAGE_NEEDWRITE) {
                                        clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
@@ -1077,14 +1065,12 @@ int bitmap_daemon_work(struct bitmap *bitmap)
                                        set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
                                        spin_unlock_irqrestore(&bitmap->lock, flags);
                                }
-                               kunmap(lastpage);
-                               page_cache_release(lastpage);
+                               put_page(lastpage);
                                if (err)
                                        bitmap_file_kick(bitmap);
                        } else
                                spin_unlock_irqrestore(&bitmap->lock, flags);
                        lastpage = page;
-                       kmap(page);
 /*
                        printk("bitmap clean at page %lu\n", j);
 */
@@ -1107,10 +1093,12 @@ int bitmap_daemon_work(struct bitmap *bitmap)
                                                  -1);
 
                                /* clear the bit */
+                               paddr = kmap_atomic(page, KM_USER0);
                                if (bitmap->flags & BITMAP_HOSTENDIAN)
-                                       clear_bit(file_page_offset(j), page_address(page));
+                                       clear_bit(file_page_offset(j), paddr);
                                else
-                                       ext2_clear_bit(file_page_offset(j), page_address(page));
+                                       ext2_clear_bit(file_page_offset(j), paddr);
+                               kunmap_atomic(paddr, KM_USER0);
                        }
                }
                spin_unlock_irqrestore(&bitmap->lock, flags);
@@ -1118,7 +1106,6 @@ int bitmap_daemon_work(struct bitmap *bitmap)
 
        /* now sync the final page */
        if (lastpage != NULL) {
-               kunmap(lastpage);
                spin_lock_irqsave(&bitmap->lock, flags);
                if (get_page_attr(bitmap, lastpage) &BITMAP_PAGE_NEEDWRITE) {
                        clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
@@ -1133,7 +1120,7 @@ int bitmap_daemon_work(struct bitmap *bitmap)
                        spin_unlock_irqrestore(&bitmap->lock, flags);
                }
 
-               page_cache_release(lastpage);
+               put_page(lastpage);
        }
 
        return err;
@@ -1184,7 +1171,7 @@ static void bitmap_writeback_daemon(mddev_t *mddev)
                PRINTK("finished page writeback: %p\n", page);
 
                err = PageError(page);
-               page_cache_release(page);
+               put_page(page);
                if (err) {
                        printk(KERN_WARNING "%s: bitmap file writeback "
                               "failed (page %lu): %d\n",
@@ -1312,7 +1299,7 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect
                case 1:
                        *bmc = 2;
                }
-               if ((*bmc & COUNTER_MAX) == COUNTER_MAX) BUG();
+               BUG_ON((*bmc & COUNTER_MAX) == COUNTER_MAX);
                (*bmc)++;
 
                spin_unlock_irq(&bitmap->lock);
@@ -1557,20 +1544,18 @@ int bitmap_create(mddev_t *mddev)
 
        BUG_ON(file && mddev->bitmap_offset);
 
-       bitmap = kmalloc(sizeof(*bitmap), GFP_KERNEL);
+       bitmap = kzalloc(sizeof(*bitmap), GFP_KERNEL);
        if (!bitmap)
                return -ENOMEM;
 
-       memset(bitmap, 0, sizeof(*bitmap));
-
        spin_lock_init(&bitmap->lock);
        bitmap->mddev = mddev;
 
        spin_lock_init(&bitmap->write_lock);
        INIT_LIST_HEAD(&bitmap->complete_pages);
        init_waitqueue_head(&bitmap->write_wait);
-       bitmap->write_pool = mempool_create(WRITE_POOL_SIZE, write_pool_alloc,
-                               write_pool_free, NULL);
+       bitmap->write_pool = mempool_create_kmalloc_pool(WRITE_POOL_SIZE,
+                                               sizeof(struct page_list));
        err = -ENOMEM;
        if (!bitmap->write_pool)
                goto error;
@@ -1603,12 +1588,11 @@ int bitmap_create(mddev_t *mddev)
 #ifdef INJECT_FATAL_FAULT_1
        bitmap->bp = NULL;
 #else
-       bitmap->bp = kmalloc(pages * sizeof(*bitmap->bp), GFP_KERNEL);
+       bitmap->bp = kzalloc(pages * sizeof(*bitmap->bp), GFP_KERNEL);
 #endif
        err = -ENOMEM;
        if (!bitmap->bp)
                goto error;
-       memset(bitmap->bp, 0, pages * sizeof(*bitmap->bp));
 
        bitmap->flags |= BITMAP_ACTIVE;