md/bitmap: white space clean up and similar.
Fixes some whitespace problems Fixed some checkpatch.pl complaints. Replaced kmalloc ... memset(0), with kzalloc Fixed an unlikely memory leak on an error path. Reformatted a number of 'if/else' sets, sometimes replacing goto with an else clause. Removed some old comments and commented-out code. Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
9f7c222001
commit
ac2f40be46
@ -13,7 +13,6 @@
|
|||||||
* Still to do:
|
* Still to do:
|
||||||
*
|
*
|
||||||
* flush after percent set rather than just time based. (maybe both).
|
* flush after percent set rather than just time based. (maybe both).
|
||||||
* wait if count gets too high, wake when it drops to half.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
@ -51,9 +50,6 @@
|
|||||||
#define INJECT_FATAL_FAULT_3 0 /* undef */
|
#define INJECT_FATAL_FAULT_3 0 /* undef */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//#define DPRINTK PRINTK /* set this NULL to avoid verbose debug output */
|
|
||||||
#define DPRINTK(x...) do { } while(0)
|
|
||||||
|
|
||||||
#ifndef PRINTK
|
#ifndef PRINTK
|
||||||
# if DEBUG > 0
|
# if DEBUG > 0
|
||||||
# define PRINTK(x...) printk(KERN_DEBUG x)
|
# define PRINTK(x...) printk(KERN_DEBUG x)
|
||||||
@ -62,12 +58,11 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline char * bmname(struct bitmap *bitmap)
|
static inline char *bmname(struct bitmap *bitmap)
|
||||||
{
|
{
|
||||||
return bitmap->mddev ? mdname(bitmap->mddev) : "mdX";
|
return bitmap->mddev ? mdname(bitmap->mddev) : "mdX";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* just a placeholder - calls kmalloc for bitmap pages
|
* just a placeholder - calls kmalloc for bitmap pages
|
||||||
*/
|
*/
|
||||||
@ -78,7 +73,7 @@ static unsigned char *bitmap_alloc_page(struct bitmap *bitmap)
|
|||||||
#ifdef INJECT_FAULTS_1
|
#ifdef INJECT_FAULTS_1
|
||||||
page = NULL;
|
page = NULL;
|
||||||
#else
|
#else
|
||||||
page = kmalloc(PAGE_SIZE, GFP_NOIO);
|
page = kzalloc(PAGE_SIZE, GFP_NOIO);
|
||||||
#endif
|
#endif
|
||||||
if (!page)
|
if (!page)
|
||||||
printk("%s: bitmap_alloc_page FAILED\n", bmname(bitmap));
|
printk("%s: bitmap_alloc_page FAILED\n", bmname(bitmap));
|
||||||
@ -107,7 +102,8 @@ static void bitmap_free_page(struct bitmap *bitmap, unsigned char *page)
|
|||||||
* if we find our page, we increment the page's refcount so that it stays
|
* if we find our page, we increment the page's refcount so that it stays
|
||||||
* allocated while we're using it
|
* allocated while we're using it
|
||||||
*/
|
*/
|
||||||
static int bitmap_checkpage(struct bitmap *bitmap, unsigned long page, int create)
|
static int bitmap_checkpage(struct bitmap *bitmap,
|
||||||
|
unsigned long page, int create)
|
||||||
__releases(bitmap->lock)
|
__releases(bitmap->lock)
|
||||||
__acquires(bitmap->lock)
|
__acquires(bitmap->lock)
|
||||||
{
|
{
|
||||||
@ -121,7 +117,6 @@ __acquires(bitmap->lock)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (bitmap->bp[page].hijacked) /* it's hijacked, don't try to alloc */
|
if (bitmap->bp[page].hijacked) /* it's hijacked, don't try to alloc */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -131,43 +126,34 @@ __acquires(bitmap->lock)
|
|||||||
if (!create)
|
if (!create)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
spin_unlock_irq(&bitmap->lock);
|
|
||||||
|
|
||||||
/* this page has not been allocated yet */
|
/* this page has not been allocated yet */
|
||||||
|
|
||||||
if ((mappage = bitmap_alloc_page(bitmap)) == NULL) {
|
spin_unlock_irq(&bitmap->lock);
|
||||||
|
mappage = bitmap_alloc_page(bitmap);
|
||||||
|
spin_lock_irq(&bitmap->lock);
|
||||||
|
|
||||||
|
if (mappage == NULL) {
|
||||||
PRINTK("%s: bitmap map page allocation failed, hijacking\n",
|
PRINTK("%s: bitmap map page allocation failed, hijacking\n",
|
||||||
bmname(bitmap));
|
bmname(bitmap));
|
||||||
/* failed - set the hijacked flag so that we can use the
|
/* failed - set the hijacked flag so that we can use the
|
||||||
* pointer as a counter */
|
* pointer as a counter */
|
||||||
spin_lock_irq(&bitmap->lock);
|
|
||||||
if (!bitmap->bp[page].map)
|
if (!bitmap->bp[page].map)
|
||||||
bitmap->bp[page].hijacked = 1;
|
bitmap->bp[page].hijacked = 1;
|
||||||
goto out;
|
} else if (bitmap->bp[page].map ||
|
||||||
}
|
bitmap->bp[page].hijacked) {
|
||||||
|
|
||||||
/* got a page */
|
|
||||||
|
|
||||||
spin_lock_irq(&bitmap->lock);
|
|
||||||
|
|
||||||
/* recheck the page */
|
|
||||||
|
|
||||||
if (bitmap->bp[page].map || bitmap->bp[page].hijacked) {
|
|
||||||
/* somebody beat us to getting the page */
|
/* somebody beat us to getting the page */
|
||||||
bitmap_free_page(bitmap, mappage);
|
bitmap_free_page(bitmap, mappage);
|
||||||
return 0;
|
return 0;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/* no page was in place and we have one, so install it */
|
||||||
|
|
||||||
|
bitmap->bp[page].map = mappage;
|
||||||
|
bitmap->missing_pages--;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* no page was in place and we have one, so install it */
|
|
||||||
|
|
||||||
memset(mappage, 0, PAGE_SIZE);
|
|
||||||
bitmap->bp[page].map = mappage;
|
|
||||||
bitmap->missing_pages--;
|
|
||||||
out:
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* if page is completely empty, put it back on the free list, or dealloc it */
|
/* 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 */
|
/* if page was hijacked, unmark the flag so it might get alloced next time */
|
||||||
/* Note: lock should be held when calling this */
|
/* Note: lock should be held when calling this */
|
||||||
@ -183,26 +169,15 @@ static void bitmap_checkfree(struct bitmap *bitmap, unsigned long page)
|
|||||||
if (bitmap->bp[page].hijacked) { /* page was hijacked, undo this now */
|
if (bitmap->bp[page].hijacked) { /* page was hijacked, undo this now */
|
||||||
bitmap->bp[page].hijacked = 0;
|
bitmap->bp[page].hijacked = 0;
|
||||||
bitmap->bp[page].map = NULL;
|
bitmap->bp[page].map = NULL;
|
||||||
return;
|
} else {
|
||||||
|
/* normal case, free the page */
|
||||||
|
ptr = bitmap->bp[page].map;
|
||||||
|
bitmap->bp[page].map = NULL;
|
||||||
|
bitmap->missing_pages++;
|
||||||
|
bitmap_free_page(bitmap, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* normal case, free the page */
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* actually ... let's not. We will probably need the page again exactly when
|
|
||||||
* memory is tight and we are flusing to disk
|
|
||||||
*/
|
|
||||||
return;
|
|
||||||
#else
|
|
||||||
ptr = bitmap->bp[page].map;
|
|
||||||
bitmap->bp[page].map = NULL;
|
|
||||||
bitmap->missing_pages++;
|
|
||||||
bitmap_free_page(bitmap, ptr);
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bitmap file handling - read and write the bitmap file and its superblock
|
* bitmap file handling - read and write the bitmap file and its superblock
|
||||||
*/
|
*/
|
||||||
@ -220,11 +195,14 @@ static struct page *read_sb_page(mddev_t *mddev, loff_t offset,
|
|||||||
|
|
||||||
mdk_rdev_t *rdev;
|
mdk_rdev_t *rdev;
|
||||||
sector_t target;
|
sector_t target;
|
||||||
|
int did_alloc = 0;
|
||||||
|
|
||||||
if (!page)
|
if (!page) {
|
||||||
page = alloc_page(GFP_KERNEL);
|
page = alloc_page(GFP_KERNEL);
|
||||||
if (!page)
|
if (!page)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
did_alloc = 1;
|
||||||
|
}
|
||||||
|
|
||||||
list_for_each_entry(rdev, &mddev->disks, same_set) {
|
list_for_each_entry(rdev, &mddev->disks, same_set) {
|
||||||
if (! test_bit(In_sync, &rdev->flags)
|
if (! test_bit(In_sync, &rdev->flags)
|
||||||
@ -242,6 +220,8 @@ static struct page *read_sb_page(mddev_t *mddev, loff_t offset,
|
|||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (did_alloc)
|
||||||
|
put_page(page);
|
||||||
return ERR_PTR(-EIO);
|
return ERR_PTR(-EIO);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -286,49 +266,51 @@ static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait)
|
|||||||
mddev_t *mddev = bitmap->mddev;
|
mddev_t *mddev = bitmap->mddev;
|
||||||
|
|
||||||
while ((rdev = next_active_rdev(rdev, mddev)) != NULL) {
|
while ((rdev = next_active_rdev(rdev, mddev)) != NULL) {
|
||||||
int size = PAGE_SIZE;
|
int size = PAGE_SIZE;
|
||||||
loff_t offset = mddev->bitmap_info.offset;
|
loff_t offset = mddev->bitmap_info.offset;
|
||||||
if (page->index == bitmap->file_pages-1)
|
if (page->index == bitmap->file_pages-1)
|
||||||
size = roundup(bitmap->last_page_size,
|
size = roundup(bitmap->last_page_size,
|
||||||
bdev_logical_block_size(rdev->bdev));
|
bdev_logical_block_size(rdev->bdev));
|
||||||
/* Just make sure we aren't corrupting data or
|
/* Just make sure we aren't corrupting data or
|
||||||
* metadata
|
* metadata
|
||||||
*/
|
*/
|
||||||
if (mddev->external) {
|
if (mddev->external) {
|
||||||
/* Bitmap could be anywhere. */
|
/* Bitmap could be anywhere. */
|
||||||
if (rdev->sb_start + offset + (page->index *(PAGE_SIZE/512)) >
|
if (rdev->sb_start + offset + (page->index
|
||||||
rdev->data_offset &&
|
* (PAGE_SIZE/512))
|
||||||
rdev->sb_start + offset <
|
> rdev->data_offset
|
||||||
rdev->data_offset + mddev->dev_sectors +
|
&&
|
||||||
(PAGE_SIZE/512))
|
rdev->sb_start + offset
|
||||||
goto bad_alignment;
|
< (rdev->data_offset + mddev->dev_sectors
|
||||||
} else if (offset < 0) {
|
+ (PAGE_SIZE/512)))
|
||||||
/* DATA BITMAP METADATA */
|
goto bad_alignment;
|
||||||
if (offset
|
} else if (offset < 0) {
|
||||||
+ (long)(page->index * (PAGE_SIZE/512))
|
/* DATA BITMAP METADATA */
|
||||||
+ size/512 > 0)
|
if (offset
|
||||||
/* bitmap runs in to metadata */
|
+ (long)(page->index * (PAGE_SIZE/512))
|
||||||
goto bad_alignment;
|
+ size/512 > 0)
|
||||||
if (rdev->data_offset + mddev->dev_sectors
|
/* bitmap runs in to metadata */
|
||||||
> rdev->sb_start + offset)
|
goto bad_alignment;
|
||||||
/* data runs in to bitmap */
|
if (rdev->data_offset + mddev->dev_sectors
|
||||||
goto bad_alignment;
|
> rdev->sb_start + offset)
|
||||||
} else if (rdev->sb_start < rdev->data_offset) {
|
/* data runs in to bitmap */
|
||||||
/* METADATA BITMAP DATA */
|
goto bad_alignment;
|
||||||
if (rdev->sb_start
|
} else if (rdev->sb_start < rdev->data_offset) {
|
||||||
+ offset
|
/* METADATA BITMAP DATA */
|
||||||
+ page->index*(PAGE_SIZE/512) + size/512
|
if (rdev->sb_start
|
||||||
> rdev->data_offset)
|
+ offset
|
||||||
/* bitmap runs in to data */
|
+ page->index*(PAGE_SIZE/512) + size/512
|
||||||
goto bad_alignment;
|
> rdev->data_offset)
|
||||||
} else {
|
/* bitmap runs in to data */
|
||||||
/* DATA METADATA BITMAP - no problems */
|
goto bad_alignment;
|
||||||
}
|
} else {
|
||||||
md_super_write(mddev, rdev,
|
/* DATA METADATA BITMAP - no problems */
|
||||||
rdev->sb_start + offset
|
}
|
||||||
+ page->index * (PAGE_SIZE/512),
|
md_super_write(mddev, rdev,
|
||||||
size,
|
rdev->sb_start + offset
|
||||||
page);
|
+ page->index * (PAGE_SIZE/512),
|
||||||
|
size,
|
||||||
|
page);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wait)
|
if (wait)
|
||||||
@ -364,10 +346,9 @@ static void write_page(struct bitmap *bitmap, struct page *page, int wait)
|
|||||||
bh = bh->b_this_page;
|
bh = bh->b_this_page;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wait) {
|
if (wait)
|
||||||
wait_event(bitmap->write_wait,
|
wait_event(bitmap->write_wait,
|
||||||
atomic_read(&bitmap->pending_writes)==0);
|
atomic_read(&bitmap->pending_writes)==0);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (bitmap->flags & BITMAP_WRITE_ERROR)
|
if (bitmap->flags & BITMAP_WRITE_ERROR)
|
||||||
bitmap_file_kick(bitmap);
|
bitmap_file_kick(bitmap);
|
||||||
@ -424,7 +405,7 @@ static struct page *read_page(struct file *file, unsigned long index,
|
|||||||
struct buffer_head *bh;
|
struct buffer_head *bh;
|
||||||
sector_t block;
|
sector_t block;
|
||||||
|
|
||||||
PRINTK("read bitmap file (%dB @ %Lu)\n", (int)PAGE_SIZE,
|
PRINTK("read bitmap file (%dB @ %llu)\n", (int)PAGE_SIZE,
|
||||||
(unsigned long long)index << PAGE_SHIFT);
|
(unsigned long long)index << PAGE_SHIFT);
|
||||||
|
|
||||||
page = alloc_page(GFP_KERNEL);
|
page = alloc_page(GFP_KERNEL);
|
||||||
@ -478,7 +459,7 @@ static struct page *read_page(struct file *file, unsigned long index,
|
|||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
if (IS_ERR(page))
|
if (IS_ERR(page))
|
||||||
printk(KERN_ALERT "md: bitmap read error: (%dB @ %Lu): %ld\n",
|
printk(KERN_ALERT "md: bitmap read error: (%dB @ %llu): %ld\n",
|
||||||
(int)PAGE_SIZE,
|
(int)PAGE_SIZE,
|
||||||
(unsigned long long)index << PAGE_SHIFT,
|
(unsigned long long)index << PAGE_SHIFT,
|
||||||
PTR_ERR(page));
|
PTR_ERR(page));
|
||||||
@ -664,11 +645,14 @@ static int bitmap_mask_state(struct bitmap *bitmap, enum bitmap_state bits,
|
|||||||
sb = kmap_atomic(bitmap->sb_page, KM_USER0);
|
sb = kmap_atomic(bitmap->sb_page, KM_USER0);
|
||||||
old = le32_to_cpu(sb->state) & bits;
|
old = le32_to_cpu(sb->state) & bits;
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case MASK_SET: sb->state |= cpu_to_le32(bits);
|
case MASK_SET:
|
||||||
break;
|
sb->state |= cpu_to_le32(bits);
|
||||||
case MASK_UNSET: sb->state &= cpu_to_le32(~bits);
|
break;
|
||||||
break;
|
case MASK_UNSET:
|
||||||
default: BUG();
|
sb->state &= cpu_to_le32(~bits);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BUG();
|
||||||
}
|
}
|
||||||
kunmap_atomic(sb, KM_USER0);
|
kunmap_atomic(sb, KM_USER0);
|
||||||
return old;
|
return old;
|
||||||
@ -710,12 +694,12 @@ static inline unsigned long file_page_offset(struct bitmap *bitmap, unsigned lon
|
|||||||
static inline struct page *filemap_get_page(struct bitmap *bitmap,
|
static inline struct page *filemap_get_page(struct bitmap *bitmap,
|
||||||
unsigned long chunk)
|
unsigned long chunk)
|
||||||
{
|
{
|
||||||
if (file_page_index(bitmap, chunk) >= bitmap->file_pages) return NULL;
|
if (file_page_index(bitmap, chunk) >= bitmap->file_pages)
|
||||||
|
return NULL;
|
||||||
return bitmap->filemap[file_page_index(bitmap, chunk)
|
return bitmap->filemap[file_page_index(bitmap, chunk)
|
||||||
- file_page_index(bitmap, 0)];
|
- file_page_index(bitmap, 0)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void bitmap_file_unmap(struct bitmap *bitmap)
|
static void bitmap_file_unmap(struct bitmap *bitmap)
|
||||||
{
|
{
|
||||||
struct page **map, *sb_page;
|
struct page **map, *sb_page;
|
||||||
@ -766,7 +750,6 @@ static void bitmap_file_put(struct bitmap *bitmap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bitmap_file_kick - if an error occurs while manipulating the bitmap file
|
* bitmap_file_kick - if an error occurs while manipulating the bitmap file
|
||||||
* then it is no longer reliable, so we stop using it and we mark the file
|
* then it is no longer reliable, so we stop using it and we mark the file
|
||||||
@ -785,7 +768,6 @@ static void bitmap_file_kick(struct bitmap *bitmap)
|
|||||||
ptr = d_path(&bitmap->file->f_path, path,
|
ptr = d_path(&bitmap->file->f_path, path,
|
||||||
PAGE_SIZE);
|
PAGE_SIZE);
|
||||||
|
|
||||||
|
|
||||||
printk(KERN_ALERT
|
printk(KERN_ALERT
|
||||||
"%s: kicking failed bitmap file %s from array!\n",
|
"%s: kicking failed bitmap file %s from array!\n",
|
||||||
bmname(bitmap), IS_ERR(ptr) ? "" : ptr);
|
bmname(bitmap), IS_ERR(ptr) ? "" : ptr);
|
||||||
@ -803,9 +785,9 @@ static void bitmap_file_kick(struct bitmap *bitmap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum bitmap_page_attr {
|
enum bitmap_page_attr {
|
||||||
BITMAP_PAGE_DIRTY = 0, // there are set bits that need to be synced
|
BITMAP_PAGE_DIRTY = 0, /* there are set bits that need to be synced */
|
||||||
BITMAP_PAGE_CLEAN = 1, // there are bits that might need to be cleared
|
BITMAP_PAGE_CLEAN = 1, /* there are bits that might need to be cleared */
|
||||||
BITMAP_PAGE_NEEDWRITE=2, // there are cleared bits that need to be synced
|
BITMAP_PAGE_NEEDWRITE = 2, /* there are cleared bits that need to be synced */
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void set_page_attr(struct bitmap *bitmap, struct page *page,
|
static inline void set_page_attr(struct bitmap *bitmap, struct page *page,
|
||||||
@ -840,15 +822,15 @@ static void bitmap_file_set_bit(struct bitmap *bitmap, sector_t block)
|
|||||||
void *kaddr;
|
void *kaddr;
|
||||||
unsigned long chunk = block >> CHUNK_BLOCK_SHIFT(bitmap);
|
unsigned long chunk = block >> CHUNK_BLOCK_SHIFT(bitmap);
|
||||||
|
|
||||||
if (!bitmap->filemap) {
|
if (!bitmap->filemap)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
page = filemap_get_page(bitmap, chunk);
|
page = filemap_get_page(bitmap, chunk);
|
||||||
if (!page) return;
|
if (!page)
|
||||||
|
return;
|
||||||
bit = file_page_offset(bitmap, chunk);
|
bit = file_page_offset(bitmap, chunk);
|
||||||
|
|
||||||
/* set the bit */
|
/* set the bit */
|
||||||
kaddr = kmap_atomic(page, KM_USER0);
|
kaddr = kmap_atomic(page, KM_USER0);
|
||||||
if (bitmap->flags & BITMAP_HOSTENDIAN)
|
if (bitmap->flags & BITMAP_HOSTENDIAN)
|
||||||
set_bit(bit, kaddr);
|
set_bit(bit, kaddr);
|
||||||
@ -859,7 +841,6 @@ static void bitmap_file_set_bit(struct bitmap *bitmap, sector_t block)
|
|||||||
|
|
||||||
/* record page number so it gets flushed to disk when unplug occurs */
|
/* record page number so it gets flushed to disk when unplug occurs */
|
||||||
set_page_attr(bitmap, page, BITMAP_PAGE_DIRTY);
|
set_page_attr(bitmap, page, BITMAP_PAGE_DIRTY);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this gets called when the md device is ready to unplug its underlying
|
/* this gets called when the md device is ready to unplug its underlying
|
||||||
@ -892,7 +873,7 @@ void bitmap_unplug(struct bitmap *bitmap)
|
|||||||
wait = 1;
|
wait = 1;
|
||||||
spin_unlock_irqrestore(&bitmap->lock, flags);
|
spin_unlock_irqrestore(&bitmap->lock, flags);
|
||||||
|
|
||||||
if (dirty | need_write)
|
if (dirty || need_write)
|
||||||
write_page(bitmap, page, 0);
|
write_page(bitmap, page, 0);
|
||||||
}
|
}
|
||||||
if (wait) { /* if any writes were performed, we need to wait on them */
|
if (wait) { /* if any writes were performed, we need to wait on them */
|
||||||
@ -905,6 +886,7 @@ void bitmap_unplug(struct bitmap *bitmap)
|
|||||||
if (bitmap->flags & BITMAP_WRITE_ERROR)
|
if (bitmap->flags & BITMAP_WRITE_ERROR)
|
||||||
bitmap_file_kick(bitmap);
|
bitmap_file_kick(bitmap);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(bitmap_unplug);
|
||||||
|
|
||||||
static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed);
|
static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed);
|
||||||
/* * bitmap_init_from_disk -- called at bitmap_create time to initialize
|
/* * bitmap_init_from_disk -- called at bitmap_create time to initialize
|
||||||
@ -947,7 +929,6 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
|
|||||||
if (!bitmap->mddev->bitmap_info.external)
|
if (!bitmap->mddev->bitmap_info.external)
|
||||||
bytes += sizeof(bitmap_super_t);
|
bytes += sizeof(bitmap_super_t);
|
||||||
|
|
||||||
|
|
||||||
num_pages = (bytes + PAGE_SIZE - 1) / PAGE_SIZE;
|
num_pages = (bytes + PAGE_SIZE - 1) / PAGE_SIZE;
|
||||||
|
|
||||||
if (file && i_size_read(file->f_mapping->host) < bytes) {
|
if (file && i_size_read(file->f_mapping->host) < bytes) {
|
||||||
@ -966,7 +947,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
|
|||||||
|
|
||||||
/* We need 4 bits per page, rounded up to a multiple of sizeof(unsigned long) */
|
/* We need 4 bits per page, rounded up to a multiple of sizeof(unsigned long) */
|
||||||
bitmap->filemap_attr = kzalloc(
|
bitmap->filemap_attr = kzalloc(
|
||||||
roundup( DIV_ROUND_UP(num_pages*4, 8), sizeof(unsigned long)),
|
roundup(DIV_ROUND_UP(num_pages*4, 8), sizeof(unsigned long)),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!bitmap->filemap_attr)
|
if (!bitmap->filemap_attr)
|
||||||
goto err;
|
goto err;
|
||||||
@ -1021,7 +1002,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
|
|||||||
if (outofdate) {
|
if (outofdate) {
|
||||||
/*
|
/*
|
||||||
* if bitmap is out of date, dirty the
|
* if bitmap is out of date, dirty the
|
||||||
* whole page and write it out
|
* whole page and write it out
|
||||||
*/
|
*/
|
||||||
paddr = kmap_atomic(page, KM_USER0);
|
paddr = kmap_atomic(page, KM_USER0);
|
||||||
memset(paddr + offset, 0xff,
|
memset(paddr + offset, 0xff,
|
||||||
@ -1052,7 +1033,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* everything went OK */
|
/* everything went OK */
|
||||||
ret = 0;
|
ret = 0;
|
||||||
bitmap_mask_state(bitmap, BITMAP_STALE, MASK_UNSET);
|
bitmap_mask_state(bitmap, BITMAP_STALE, MASK_UNSET);
|
||||||
|
|
||||||
@ -1080,21 +1061,16 @@ void bitmap_write_all(struct bitmap *bitmap)
|
|||||||
*/
|
*/
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0; i < bitmap->file_pages; i++)
|
for (i = 0; i < bitmap->file_pages; i++)
|
||||||
set_page_attr(bitmap, bitmap->filemap[i],
|
set_page_attr(bitmap, bitmap->filemap[i],
|
||||||
BITMAP_PAGE_NEEDWRITE);
|
BITMAP_PAGE_NEEDWRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void bitmap_count_page(struct bitmap *bitmap, sector_t offset, int inc)
|
static void bitmap_count_page(struct bitmap *bitmap, sector_t offset, int inc)
|
||||||
{
|
{
|
||||||
sector_t chunk = offset >> CHUNK_BLOCK_SHIFT(bitmap);
|
sector_t chunk = offset >> CHUNK_BLOCK_SHIFT(bitmap);
|
||||||
unsigned long page = chunk >> PAGE_COUNTER_SHIFT;
|
unsigned long page = chunk >> PAGE_COUNTER_SHIFT;
|
||||||
bitmap->bp[page].count += inc;
|
bitmap->bp[page].count += inc;
|
||||||
/*
|
|
||||||
if (page == 0) printk("count page 0, offset %llu: %d gives %d\n",
|
|
||||||
(unsigned long long)offset, inc, bitmap->bp[page].count);
|
|
||||||
*/
|
|
||||||
bitmap_checkfree(bitmap, page);
|
bitmap_checkfree(bitmap, page);
|
||||||
}
|
}
|
||||||
static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap,
|
static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap,
|
||||||
@ -1197,14 +1173,11 @@ void bitmap_daemon_work(mddev_t *mddev)
|
|||||||
(sector_t)j << CHUNK_BLOCK_SHIFT(bitmap),
|
(sector_t)j << CHUNK_BLOCK_SHIFT(bitmap),
|
||||||
&blocks, 0);
|
&blocks, 0);
|
||||||
if (bmc) {
|
if (bmc) {
|
||||||
/*
|
|
||||||
if (j < 100) printk("bitmap: j=%lu, *bmc = 0x%x\n", j, *bmc);
|
|
||||||
*/
|
|
||||||
if (*bmc)
|
if (*bmc)
|
||||||
bitmap->allclean = 0;
|
bitmap->allclean = 0;
|
||||||
|
|
||||||
if (*bmc == 2) {
|
if (*bmc == 2) {
|
||||||
*bmc=1; /* maybe clear the bit next time */
|
*bmc = 1; /* maybe clear the bit next time */
|
||||||
set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
|
set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
|
||||||
} else if (*bmc == 1 && !bitmap->need_sync) {
|
} else if (*bmc == 1 && !bitmap->need_sync) {
|
||||||
/* we can clear the bit */
|
/* we can clear the bit */
|
||||||
@ -1243,7 +1216,7 @@ void bitmap_daemon_work(mddev_t *mddev)
|
|||||||
|
|
||||||
done:
|
done:
|
||||||
if (bitmap->allclean == 0)
|
if (bitmap->allclean == 0)
|
||||||
bitmap->mddev->thread->timeout =
|
bitmap->mddev->thread->timeout =
|
||||||
bitmap->mddev->bitmap_info.daemon_sleep;
|
bitmap->mddev->bitmap_info.daemon_sleep;
|
||||||
mutex_unlock(&mddev->bitmap_info.mutex);
|
mutex_unlock(&mddev->bitmap_info.mutex);
|
||||||
}
|
}
|
||||||
@ -1265,7 +1238,7 @@ __acquires(bitmap->lock)
|
|||||||
|
|
||||||
if (bitmap_checkpage(bitmap, page, create) < 0) {
|
if (bitmap_checkpage(bitmap, page, create) < 0) {
|
||||||
csize = ((sector_t)1) << (CHUNK_BLOCK_SHIFT(bitmap));
|
csize = ((sector_t)1) << (CHUNK_BLOCK_SHIFT(bitmap));
|
||||||
*blocks = csize - (offset & (csize- 1));
|
*blocks = csize - (offset & (csize - 1));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* now locked ... */
|
/* now locked ... */
|
||||||
@ -1276,12 +1249,12 @@ __acquires(bitmap->lock)
|
|||||||
int hi = (pageoff > PAGE_COUNTER_MASK);
|
int hi = (pageoff > PAGE_COUNTER_MASK);
|
||||||
csize = ((sector_t)1) << (CHUNK_BLOCK_SHIFT(bitmap) +
|
csize = ((sector_t)1) << (CHUNK_BLOCK_SHIFT(bitmap) +
|
||||||
PAGE_COUNTER_SHIFT - 1);
|
PAGE_COUNTER_SHIFT - 1);
|
||||||
*blocks = csize - (offset & (csize- 1));
|
*blocks = csize - (offset & (csize - 1));
|
||||||
return &((bitmap_counter_t *)
|
return &((bitmap_counter_t *)
|
||||||
&bitmap->bp[page].map)[hi];
|
&bitmap->bp[page].map)[hi];
|
||||||
} else { /* page is allocated */
|
} else { /* page is allocated */
|
||||||
csize = ((sector_t)1) << (CHUNK_BLOCK_SHIFT(bitmap));
|
csize = ((sector_t)1) << (CHUNK_BLOCK_SHIFT(bitmap));
|
||||||
*blocks = csize - (offset & (csize- 1));
|
*blocks = csize - (offset & (csize - 1));
|
||||||
return (bitmap_counter_t *)
|
return (bitmap_counter_t *)
|
||||||
&(bitmap->bp[page].map[pageoff]);
|
&(bitmap->bp[page].map[pageoff]);
|
||||||
}
|
}
|
||||||
@ -1289,7 +1262,8 @@ __acquires(bitmap->lock)
|
|||||||
|
|
||||||
int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors, int behind)
|
int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors, int behind)
|
||||||
{
|
{
|
||||||
if (!bitmap) return 0;
|
if (!bitmap)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (behind) {
|
if (behind) {
|
||||||
int bw;
|
int bw;
|
||||||
@ -1328,10 +1302,10 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(*bmc) {
|
switch (*bmc) {
|
||||||
case 0:
|
case 0:
|
||||||
bitmap_file_set_bit(bitmap, offset);
|
bitmap_file_set_bit(bitmap, offset);
|
||||||
bitmap_count_page(bitmap,offset, 1);
|
bitmap_count_page(bitmap, offset, 1);
|
||||||
blk_plug_device_unlocked(bitmap->mddev->queue);
|
blk_plug_device_unlocked(bitmap->mddev->queue);
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case 1:
|
case 1:
|
||||||
@ -1345,16 +1319,19 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect
|
|||||||
offset += blocks;
|
offset += blocks;
|
||||||
if (sectors > blocks)
|
if (sectors > blocks)
|
||||||
sectors -= blocks;
|
sectors -= blocks;
|
||||||
else sectors = 0;
|
else
|
||||||
|
sectors = 0;
|
||||||
}
|
}
|
||||||
bitmap->allclean = 0;
|
bitmap->allclean = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(bitmap_startwrite);
|
||||||
|
|
||||||
void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors,
|
void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors,
|
||||||
int success, int behind)
|
int success, int behind)
|
||||||
{
|
{
|
||||||
if (!bitmap) return;
|
if (!bitmap)
|
||||||
|
return;
|
||||||
if (behind) {
|
if (behind) {
|
||||||
if (atomic_dec_and_test(&bitmap->behind_writes))
|
if (atomic_dec_and_test(&bitmap->behind_writes))
|
||||||
wake_up(&bitmap->behind_wait);
|
wake_up(&bitmap->behind_wait);
|
||||||
@ -1391,18 +1368,20 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto
|
|||||||
wake_up(&bitmap->overflow_wait);
|
wake_up(&bitmap->overflow_wait);
|
||||||
|
|
||||||
(*bmc)--;
|
(*bmc)--;
|
||||||
if (*bmc <= 2) {
|
if (*bmc <= 2)
|
||||||
set_page_attr(bitmap,
|
set_page_attr(bitmap,
|
||||||
filemap_get_page(bitmap, offset >> CHUNK_BLOCK_SHIFT(bitmap)),
|
filemap_get_page(bitmap, offset >> CHUNK_BLOCK_SHIFT(bitmap)),
|
||||||
BITMAP_PAGE_CLEAN);
|
BITMAP_PAGE_CLEAN);
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&bitmap->lock, flags);
|
spin_unlock_irqrestore(&bitmap->lock, flags);
|
||||||
offset += blocks;
|
offset += blocks;
|
||||||
if (sectors > blocks)
|
if (sectors > blocks)
|
||||||
sectors -= blocks;
|
sectors -= blocks;
|
||||||
else sectors = 0;
|
else
|
||||||
|
sectors = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(bitmap_endwrite);
|
||||||
|
|
||||||
static int __bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
|
static int __bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
|
||||||
int degraded)
|
int degraded)
|
||||||
@ -1455,14 +1434,14 @@ int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
|
|||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(bitmap_start_sync);
|
||||||
|
|
||||||
void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted)
|
void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted)
|
||||||
{
|
{
|
||||||
bitmap_counter_t *bmc;
|
bitmap_counter_t *bmc;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
/*
|
|
||||||
if (offset == 0) printk("bitmap_end_sync 0 (%d)\n", aborted);
|
if (bitmap == NULL) {
|
||||||
*/ if (bitmap == NULL) {
|
|
||||||
*blocks = 1024;
|
*blocks = 1024;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1471,26 +1450,23 @@ void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int ab
|
|||||||
if (bmc == NULL)
|
if (bmc == NULL)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
/* locked */
|
/* locked */
|
||||||
/*
|
|
||||||
if (offset == 0) printk("bitmap_end sync found 0x%x, blocks %d\n", *bmc, *blocks);
|
|
||||||
*/
|
|
||||||
if (RESYNC(*bmc)) {
|
if (RESYNC(*bmc)) {
|
||||||
*bmc &= ~RESYNC_MASK;
|
*bmc &= ~RESYNC_MASK;
|
||||||
|
|
||||||
if (!NEEDED(*bmc) && aborted)
|
if (!NEEDED(*bmc) && aborted)
|
||||||
*bmc |= NEEDED_MASK;
|
*bmc |= NEEDED_MASK;
|
||||||
else {
|
else {
|
||||||
if (*bmc <= 2) {
|
if (*bmc <= 2)
|
||||||
set_page_attr(bitmap,
|
set_page_attr(bitmap,
|
||||||
filemap_get_page(bitmap, offset >> CHUNK_BLOCK_SHIFT(bitmap)),
|
filemap_get_page(bitmap, offset >> CHUNK_BLOCK_SHIFT(bitmap)),
|
||||||
BITMAP_PAGE_CLEAN);
|
BITMAP_PAGE_CLEAN);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unlock:
|
unlock:
|
||||||
spin_unlock_irqrestore(&bitmap->lock, flags);
|
spin_unlock_irqrestore(&bitmap->lock, flags);
|
||||||
bitmap->allclean = 0;
|
bitmap->allclean = 0;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(bitmap_end_sync);
|
||||||
|
|
||||||
void bitmap_close_sync(struct bitmap *bitmap)
|
void bitmap_close_sync(struct bitmap *bitmap)
|
||||||
{
|
{
|
||||||
@ -1507,6 +1483,7 @@ void bitmap_close_sync(struct bitmap *bitmap)
|
|||||||
sector += blocks;
|
sector += blocks;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(bitmap_close_sync);
|
||||||
|
|
||||||
void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector)
|
void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector)
|
||||||
{
|
{
|
||||||
@ -1537,6 +1514,7 @@ void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector)
|
|||||||
bitmap->last_end_sync = jiffies;
|
bitmap->last_end_sync = jiffies;
|
||||||
sysfs_notify(&bitmap->mddev->kobj, NULL, "sync_completed");
|
sysfs_notify(&bitmap->mddev->kobj, NULL, "sync_completed");
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(bitmap_cond_end_sync);
|
||||||
|
|
||||||
static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed)
|
static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed)
|
||||||
{
|
{
|
||||||
@ -1553,9 +1531,9 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int n
|
|||||||
spin_unlock_irq(&bitmap->lock);
|
spin_unlock_irq(&bitmap->lock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (! *bmc) {
|
if (!*bmc) {
|
||||||
struct page *page;
|
struct page *page;
|
||||||
*bmc = 1 | (needed?NEEDED_MASK:0);
|
*bmc = 1 | (needed ? NEEDED_MASK : 0);
|
||||||
bitmap_count_page(bitmap, offset, 1);
|
bitmap_count_page(bitmap, offset, 1);
|
||||||
page = filemap_get_page(bitmap, offset >> CHUNK_BLOCK_SHIFT(bitmap));
|
page = filemap_get_page(bitmap, offset >> CHUNK_BLOCK_SHIFT(bitmap));
|
||||||
set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
|
set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
|
||||||
@ -1720,9 +1698,9 @@ int bitmap_create(mddev_t *mddev)
|
|||||||
bitmap->chunkshift = ffz(~mddev->bitmap_info.chunksize);
|
bitmap->chunkshift = ffz(~mddev->bitmap_info.chunksize);
|
||||||
|
|
||||||
/* now that chunksize and chunkshift are set, we can use these macros */
|
/* now that chunksize and chunkshift are set, we can use these macros */
|
||||||
chunks = (blocks + CHUNK_BLOCK_RATIO(bitmap) - 1) >>
|
chunks = (blocks + CHUNK_BLOCK_RATIO(bitmap) - 1) >>
|
||||||
CHUNK_BLOCK_SHIFT(bitmap);
|
CHUNK_BLOCK_SHIFT(bitmap);
|
||||||
pages = (chunks + PAGE_COUNTER_RATIO - 1) / PAGE_COUNTER_RATIO;
|
pages = (chunks + PAGE_COUNTER_RATIO - 1) / PAGE_COUNTER_RATIO;
|
||||||
|
|
||||||
BUG_ON(!pages);
|
BUG_ON(!pages);
|
||||||
|
|
||||||
@ -1775,11 +1753,11 @@ static ssize_t
|
|||||||
location_show(mddev_t *mddev, char *page)
|
location_show(mddev_t *mddev, char *page)
|
||||||
{
|
{
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
if (mddev->bitmap_info.file) {
|
if (mddev->bitmap_info.file)
|
||||||
len = sprintf(page, "file");
|
len = sprintf(page, "file");
|
||||||
} else if (mddev->bitmap_info.offset) {
|
else if (mddev->bitmap_info.offset)
|
||||||
len = sprintf(page, "%+lld", (long long)mddev->bitmap_info.offset);
|
len = sprintf(page, "%+lld", (long long)mddev->bitmap_info.offset);
|
||||||
} else
|
else
|
||||||
len = sprintf(page, "none");
|
len = sprintf(page, "none");
|
||||||
len += sprintf(page+len, "\n");
|
len += sprintf(page+len, "\n");
|
||||||
return len;
|
return len;
|
||||||
@ -1868,7 +1846,7 @@ timeout_show(mddev_t *mddev, char *page)
|
|||||||
ssize_t len;
|
ssize_t len;
|
||||||
unsigned long secs = mddev->bitmap_info.daemon_sleep / HZ;
|
unsigned long secs = mddev->bitmap_info.daemon_sleep / HZ;
|
||||||
unsigned long jifs = mddev->bitmap_info.daemon_sleep % HZ;
|
unsigned long jifs = mddev->bitmap_info.daemon_sleep % HZ;
|
||||||
|
|
||||||
len = sprintf(page, "%lu", secs);
|
len = sprintf(page, "%lu", secs);
|
||||||
if (jifs)
|
if (jifs)
|
||||||
len += sprintf(page+len, ".%03u", jiffies_to_msecs(jifs));
|
len += sprintf(page+len, ".%03u", jiffies_to_msecs(jifs));
|
||||||
@ -2050,12 +2028,3 @@ struct attribute_group md_bitmap_group = {
|
|||||||
.attrs = md_bitmap_attrs,
|
.attrs = md_bitmap_attrs,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* the bitmap API -- for raid personalities */
|
|
||||||
EXPORT_SYMBOL(bitmap_startwrite);
|
|
||||||
EXPORT_SYMBOL(bitmap_endwrite);
|
|
||||||
EXPORT_SYMBOL(bitmap_start_sync);
|
|
||||||
EXPORT_SYMBOL(bitmap_end_sync);
|
|
||||||
EXPORT_SYMBOL(bitmap_unplug);
|
|
||||||
EXPORT_SYMBOL(bitmap_close_sync);
|
|
||||||
EXPORT_SYMBOL(bitmap_cond_end_sync);
|
|
||||||
|
@ -319,7 +319,7 @@ struct mddev_s
|
|||||||
*/
|
*/
|
||||||
struct mutex mutex;
|
struct mutex mutex;
|
||||||
unsigned long chunksize;
|
unsigned long chunksize;
|
||||||
unsigned long daemon_sleep; /* how many seconds between updates? */
|
unsigned long daemon_sleep; /* how many jiffies between updates? */
|
||||||
unsigned long max_write_behind; /* write-behind mode */
|
unsigned long max_write_behind; /* write-behind mode */
|
||||||
int external;
|
int external;
|
||||||
} bitmap_info;
|
} bitmap_info;
|
||||||
|
Loading…
Reference in New Issue
Block a user