mirror of https://gitee.com/openkylin/linux.git
md/bitmap: use set_bit, test_bit, etc for operation on bitmap->flags.
We currently use '&' and '|' which isn't the norm in the kernel and doesn't allow easy atomicity. So change to bit numbers and {set,clear,test}_bit. This allows us to remove a spinlock/unlock (which was dubious anyway) and some other simplifications. Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
84e923453e
commit
b405fe91e5
|
@ -271,7 +271,7 @@ static void write_page(struct bitmap *bitmap, struct page *page, int wait)
|
||||||
if (bitmap->storage.file == NULL) {
|
if (bitmap->storage.file == NULL) {
|
||||||
switch (write_sb_page(bitmap, page, wait)) {
|
switch (write_sb_page(bitmap, page, wait)) {
|
||||||
case -EINVAL:
|
case -EINVAL:
|
||||||
bitmap->flags |= BITMAP_WRITE_ERROR;
|
set_bit(BITMAP_WRITE_ERROR, &bitmap->flags);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
@ -289,20 +289,16 @@ static void write_page(struct bitmap *bitmap, struct page *page, int 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 (test_bit(BITMAP_WRITE_ERROR, &bitmap->flags))
|
||||||
bitmap_file_kick(bitmap);
|
bitmap_file_kick(bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void end_bitmap_write(struct buffer_head *bh, int uptodate)
|
static void end_bitmap_write(struct buffer_head *bh, int uptodate)
|
||||||
{
|
{
|
||||||
struct bitmap *bitmap = bh->b_private;
|
struct bitmap *bitmap = bh->b_private;
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (!uptodate) {
|
if (!uptodate)
|
||||||
spin_lock_irqsave(&bitmap->lock, flags);
|
set_bit(BITMAP_WRITE_ERROR, &bitmap->flags);
|
||||||
bitmap->flags |= BITMAP_WRITE_ERROR;
|
|
||||||
spin_unlock_irqrestore(&bitmap->lock, flags);
|
|
||||||
}
|
|
||||||
if (atomic_dec_and_test(&bitmap->pending_writes))
|
if (atomic_dec_and_test(&bitmap->pending_writes))
|
||||||
wake_up(&bitmap->write_wait);
|
wake_up(&bitmap->write_wait);
|
||||||
}
|
}
|
||||||
|
@ -389,7 +385,7 @@ static int read_page(struct file *file, unsigned long index,
|
||||||
|
|
||||||
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 (test_bit(BITMAP_WRITE_ERROR, &bitmap->flags))
|
||||||
ret = -EIO;
|
ret = -EIO;
|
||||||
out:
|
out:
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -521,7 +517,7 @@ static int bitmap_new_disk_sb(struct bitmap *bitmap)
|
||||||
|
|
||||||
memcpy(sb->uuid, bitmap->mddev->uuid, 16);
|
memcpy(sb->uuid, bitmap->mddev->uuid, 16);
|
||||||
|
|
||||||
bitmap->flags |= BITMAP_STALE;
|
set_bit(BITMAP_STALE, &bitmap->flags);
|
||||||
sb->state = cpu_to_le32(bitmap->flags);
|
sb->state = cpu_to_le32(bitmap->flags);
|
||||||
bitmap->events_cleared = bitmap->mddev->events;
|
bitmap->events_cleared = bitmap->mddev->events;
|
||||||
sb->events_cleared = cpu_to_le64(bitmap->mddev->events);
|
sb->events_cleared = cpu_to_le64(bitmap->mddev->events);
|
||||||
|
@ -545,7 +541,7 @@ static int bitmap_read_sb(struct bitmap *bitmap)
|
||||||
chunksize = 128 * 1024 * 1024;
|
chunksize = 128 * 1024 * 1024;
|
||||||
daemon_sleep = 5 * HZ;
|
daemon_sleep = 5 * HZ;
|
||||||
write_behind = 0;
|
write_behind = 0;
|
||||||
bitmap->flags = BITMAP_STALE;
|
set_bit(BITMAP_STALE, &bitmap->flags);
|
||||||
err = 0;
|
err = 0;
|
||||||
goto out_no_sb;
|
goto out_no_sb;
|
||||||
}
|
}
|
||||||
|
@ -617,20 +613,20 @@ static int bitmap_read_sb(struct bitmap *bitmap)
|
||||||
"-- forcing full recovery\n",
|
"-- forcing full recovery\n",
|
||||||
bmname(bitmap), events,
|
bmname(bitmap), events,
|
||||||
(unsigned long long) bitmap->mddev->events);
|
(unsigned long long) bitmap->mddev->events);
|
||||||
bitmap->flags |= BITMAP_STALE;
|
set_bit(BITMAP_STALE, &bitmap->flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* assign fields using values from superblock */
|
/* assign fields using values from superblock */
|
||||||
bitmap->flags |= le32_to_cpu(sb->state);
|
bitmap->flags |= le32_to_cpu(sb->state);
|
||||||
if (le32_to_cpu(sb->version) == BITMAP_MAJOR_HOSTENDIAN)
|
if (le32_to_cpu(sb->version) == BITMAP_MAJOR_HOSTENDIAN)
|
||||||
bitmap->flags |= BITMAP_HOSTENDIAN;
|
set_bit(BITMAP_HOSTENDIAN, &bitmap->flags);
|
||||||
bitmap->events_cleared = le64_to_cpu(sb->events_cleared);
|
bitmap->events_cleared = le64_to_cpu(sb->events_cleared);
|
||||||
err = 0;
|
err = 0;
|
||||||
out:
|
out:
|
||||||
kunmap_atomic(sb);
|
kunmap_atomic(sb);
|
||||||
out_no_sb:
|
out_no_sb:
|
||||||
if (bitmap->flags & BITMAP_STALE)
|
if (test_bit(BITMAP_STALE, &bitmap->flags))
|
||||||
bitmap->events_cleared = bitmap->mddev->events;
|
bitmap->events_cleared = bitmap->mddev->events;
|
||||||
bitmap->mddev->bitmap_info.chunksize = chunksize;
|
bitmap->mddev->bitmap_info.chunksize = chunksize;
|
||||||
bitmap->mddev->bitmap_info.daemon_sleep = daemon_sleep;
|
bitmap->mddev->bitmap_info.daemon_sleep = daemon_sleep;
|
||||||
|
@ -796,8 +792,7 @@ static void bitmap_file_kick(struct bitmap *bitmap)
|
||||||
{
|
{
|
||||||
char *path, *ptr = NULL;
|
char *path, *ptr = NULL;
|
||||||
|
|
||||||
if (!(bitmap->flags & BITMAP_STALE)) {
|
if (!test_and_set_bit(BITMAP_STALE, &bitmap->flags)) {
|
||||||
bitmap->flags |= BITMAP_STALE;
|
|
||||||
bitmap_update_sb(bitmap);
|
bitmap_update_sb(bitmap);
|
||||||
|
|
||||||
if (bitmap->storage.file) {
|
if (bitmap->storage.file) {
|
||||||
|
@ -868,7 +863,7 @@ static void bitmap_file_set_bit(struct bitmap *bitmap, sector_t block)
|
||||||
|
|
||||||
/* set the bit */
|
/* set the bit */
|
||||||
kaddr = kmap_atomic(page);
|
kaddr = kmap_atomic(page);
|
||||||
if (bitmap->flags & BITMAP_HOSTENDIAN)
|
if (test_bit(BITMAP_HOSTENDIAN, &bitmap->flags))
|
||||||
set_bit(bit, kaddr);
|
set_bit(bit, kaddr);
|
||||||
else
|
else
|
||||||
__set_bit_le(bit, kaddr);
|
__set_bit_le(bit, kaddr);
|
||||||
|
@ -890,7 +885,7 @@ static void bitmap_file_clear_bit(struct bitmap *bitmap, sector_t block)
|
||||||
return;
|
return;
|
||||||
bit = file_page_offset(&bitmap->storage, chunk);
|
bit = file_page_offset(&bitmap->storage, chunk);
|
||||||
paddr = kmap_atomic(page);
|
paddr = kmap_atomic(page);
|
||||||
if (bitmap->flags & BITMAP_HOSTENDIAN)
|
if (test_bit(BITMAP_HOSTENDIAN, &bitmap->flags))
|
||||||
clear_bit(bit, paddr);
|
clear_bit(bit, paddr);
|
||||||
else
|
else
|
||||||
__clear_bit_le(bit, paddr);
|
__clear_bit_le(bit, paddr);
|
||||||
|
@ -941,7 +936,7 @@ void bitmap_unplug(struct bitmap *bitmap)
|
||||||
else
|
else
|
||||||
md_super_wait(bitmap->mddev);
|
md_super_wait(bitmap->mddev);
|
||||||
}
|
}
|
||||||
if (bitmap->flags & BITMAP_WRITE_ERROR)
|
if (test_bit(BITMAP_WRITE_ERROR, &bitmap->flags))
|
||||||
bitmap_file_kick(bitmap);
|
bitmap_file_kick(bitmap);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(bitmap_unplug);
|
EXPORT_SYMBOL(bitmap_unplug);
|
||||||
|
@ -988,7 +983,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
outofdate = bitmap->flags & BITMAP_STALE;
|
outofdate = test_bit(BITMAP_STALE, &bitmap->flags);
|
||||||
if (outofdate)
|
if (outofdate)
|
||||||
printk(KERN_INFO "%s: bitmap file is out of date, doing full "
|
printk(KERN_INFO "%s: bitmap file is out of date, doing full "
|
||||||
"recovery\n", bmname(bitmap));
|
"recovery\n", bmname(bitmap));
|
||||||
|
@ -1045,12 +1040,13 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
|
||||||
write_page(bitmap, page, 1);
|
write_page(bitmap, page, 1);
|
||||||
|
|
||||||
ret = -EIO;
|
ret = -EIO;
|
||||||
if (bitmap->flags & BITMAP_WRITE_ERROR)
|
if (test_bit(BITMAP_WRITE_ERROR,
|
||||||
|
&bitmap->flags))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
paddr = kmap_atomic(page);
|
paddr = kmap_atomic(page);
|
||||||
if (bitmap->flags & BITMAP_HOSTENDIAN)
|
if (test_bit(BITMAP_HOSTENDIAN, &bitmap->flags))
|
||||||
b = test_bit(bit, paddr);
|
b = test_bit(bit, paddr);
|
||||||
else
|
else
|
||||||
b = test_bit_le(bit, paddr);
|
b = test_bit_le(bit, paddr);
|
||||||
|
@ -1758,7 +1754,7 @@ int bitmap_create(struct mddev *mddev)
|
||||||
mddev->bitmap = bitmap;
|
mddev->bitmap = bitmap;
|
||||||
|
|
||||||
|
|
||||||
return (bitmap->flags & BITMAP_WRITE_ERROR) ? -EIO : 0;
|
return test_bit(BITMAP_WRITE_ERROR, &bitmap->flags) ? -EIO : 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
bitmap_free(bitmap);
|
bitmap_free(bitmap);
|
||||||
|
@ -1799,7 +1795,7 @@ int bitmap_load(struct mddev *mddev)
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
bitmap->flags &= ~BITMAP_STALE;
|
clear_bit(BITMAP_STALE, &bitmap->flags);
|
||||||
|
|
||||||
/* Kick recovery in case any bits were set */
|
/* Kick recovery in case any bits were set */
|
||||||
set_bit(MD_RECOVERY_NEEDED, &bitmap->mddev->recovery);
|
set_bit(MD_RECOVERY_NEEDED, &bitmap->mddev->recovery);
|
||||||
|
@ -1809,7 +1805,7 @@ int bitmap_load(struct mddev *mddev)
|
||||||
|
|
||||||
bitmap_update_sb(bitmap);
|
bitmap_update_sb(bitmap);
|
||||||
|
|
||||||
if (bitmap->flags & BITMAP_WRITE_ERROR)
|
if (test_bit(BITMAP_WRITE_ERROR, &bitmap->flags))
|
||||||
err = -EIO;
|
err = -EIO;
|
||||||
out:
|
out:
|
||||||
return err;
|
return err;
|
||||||
|
|
|
@ -111,9 +111,9 @@ typedef __u16 bitmap_counter_t;
|
||||||
|
|
||||||
/* use these for bitmap->flags and bitmap->sb->state bit-fields */
|
/* use these for bitmap->flags and bitmap->sb->state bit-fields */
|
||||||
enum bitmap_state {
|
enum bitmap_state {
|
||||||
BITMAP_STALE = 0x002, /* the bitmap file is out of date or had -EIO */
|
BITMAP_STALE = 1, /* the bitmap file is out of date or had -EIO */
|
||||||
BITMAP_WRITE_ERROR = 0x004, /* A write error has occurred */
|
BITMAP_WRITE_ERROR = 2, /* A write error has occurred */
|
||||||
BITMAP_HOSTENDIAN = 0x8000,
|
BITMAP_HOSTENDIAN =15,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* the superblock at the front of the bitmap file -- little endian */
|
/* the superblock at the front of the bitmap file -- little endian */
|
||||||
|
|
Loading…
Reference in New Issue