Commit ac2f40be authored by NeilBrown's avatar NeilBrown

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: default avatarNeilBrown <neilb@suse.de>
parent 9f7c2220
...@@ -13,7 +13,6 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 */ /* no page was in place and we have one, so install it */
memset(mappage, 0, PAGE_SIZE); bitmap->bp[page].map = mappage;
bitmap->bp[page].map = mappage; bitmap->missing_pages--;
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) ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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, ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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) ...@@ -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 ...@@ -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) ...@@ -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 = { ...@@ -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 ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment