|
@@ -195,6 +195,7 @@ static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait)
|
|
struct md_rdev *rdev = NULL;
|
|
struct md_rdev *rdev = NULL;
|
|
struct block_device *bdev;
|
|
struct block_device *bdev;
|
|
struct mddev *mddev = bitmap->mddev;
|
|
struct mddev *mddev = bitmap->mddev;
|
|
|
|
+ struct bitmap_storage *store = &bitmap->storage;
|
|
|
|
|
|
while ((rdev = next_active_rdev(rdev, mddev)) != NULL) {
|
|
while ((rdev = next_active_rdev(rdev, mddev)) != NULL) {
|
|
int size = PAGE_SIZE;
|
|
int size = PAGE_SIZE;
|
|
@@ -202,8 +203,8 @@ static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait)
|
|
|
|
|
|
bdev = (rdev->meta_bdev) ? rdev->meta_bdev : rdev->bdev;
|
|
bdev = (rdev->meta_bdev) ? rdev->meta_bdev : rdev->bdev;
|
|
|
|
|
|
- if (page->index == bitmap->file_pages-1)
|
|
|
|
- size = roundup(bitmap->last_page_size,
|
|
|
|
|
|
+ if (page->index == store->file_pages-1)
|
|
|
|
+ size = roundup(store->last_page_size,
|
|
bdev_logical_block_size(bdev));
|
|
bdev_logical_block_size(bdev));
|
|
/* Just make sure we aren't corrupting data or
|
|
/* Just make sure we aren't corrupting data or
|
|
* metadata
|
|
* metadata
|
|
@@ -263,7 +264,7 @@ static void write_page(struct bitmap *bitmap, struct page *page, int wait)
|
|
{
|
|
{
|
|
struct buffer_head *bh;
|
|
struct buffer_head *bh;
|
|
|
|
|
|
- if (bitmap->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;
|
|
bitmap->flags |= BITMAP_WRITE_ERROR;
|
|
@@ -408,9 +409,9 @@ void bitmap_update_sb(struct bitmap *bitmap)
|
|
return;
|
|
return;
|
|
if (bitmap->mddev->bitmap_info.external)
|
|
if (bitmap->mddev->bitmap_info.external)
|
|
return;
|
|
return;
|
|
- if (!bitmap->sb_page) /* no superblock */
|
|
|
|
|
|
+ if (!bitmap->storage.sb_page) /* no superblock */
|
|
return;
|
|
return;
|
|
- sb = kmap_atomic(bitmap->sb_page);
|
|
|
|
|
|
+ sb = kmap_atomic(bitmap->storage.sb_page);
|
|
sb->events = cpu_to_le64(bitmap->mddev->events);
|
|
sb->events = cpu_to_le64(bitmap->mddev->events);
|
|
if (bitmap->mddev->events < bitmap->events_cleared)
|
|
if (bitmap->mddev->events < bitmap->events_cleared)
|
|
/* rocking back to read-only */
|
|
/* rocking back to read-only */
|
|
@@ -421,7 +422,7 @@ void bitmap_update_sb(struct bitmap *bitmap)
|
|
sb->daemon_sleep = cpu_to_le32(bitmap->mddev->bitmap_info.daemon_sleep/HZ);
|
|
sb->daemon_sleep = cpu_to_le32(bitmap->mddev->bitmap_info.daemon_sleep/HZ);
|
|
sb->write_behind = cpu_to_le32(bitmap->mddev->bitmap_info.max_write_behind);
|
|
sb->write_behind = cpu_to_le32(bitmap->mddev->bitmap_info.max_write_behind);
|
|
kunmap_atomic(sb);
|
|
kunmap_atomic(sb);
|
|
- write_page(bitmap, bitmap->sb_page, 1);
|
|
|
|
|
|
+ write_page(bitmap, bitmap->storage.sb_page, 1);
|
|
}
|
|
}
|
|
|
|
|
|
/* print out the bitmap file superblock */
|
|
/* print out the bitmap file superblock */
|
|
@@ -429,9 +430,9 @@ void bitmap_print_sb(struct bitmap *bitmap)
|
|
{
|
|
{
|
|
bitmap_super_t *sb;
|
|
bitmap_super_t *sb;
|
|
|
|
|
|
- if (!bitmap || !bitmap->sb_page)
|
|
|
|
|
|
+ if (!bitmap || !bitmap->storage.sb_page)
|
|
return;
|
|
return;
|
|
- sb = kmap_atomic(bitmap->sb_page);
|
|
|
|
|
|
+ sb = kmap_atomic(bitmap->storage.sb_page);
|
|
printk(KERN_DEBUG "%s: bitmap file superblock:\n", bmname(bitmap));
|
|
printk(KERN_DEBUG "%s: bitmap file superblock:\n", bmname(bitmap));
|
|
printk(KERN_DEBUG " magic: %08x\n", le32_to_cpu(sb->magic));
|
|
printk(KERN_DEBUG " magic: %08x\n", le32_to_cpu(sb->magic));
|
|
printk(KERN_DEBUG " version: %d\n", le32_to_cpu(sb->version));
|
|
printk(KERN_DEBUG " version: %d\n", le32_to_cpu(sb->version));
|
|
@@ -470,15 +471,15 @@ static int bitmap_new_disk_sb(struct bitmap *bitmap)
|
|
unsigned long chunksize, daemon_sleep, write_behind;
|
|
unsigned long chunksize, daemon_sleep, write_behind;
|
|
int err = -EINVAL;
|
|
int err = -EINVAL;
|
|
|
|
|
|
- bitmap->sb_page = alloc_page(GFP_KERNEL);
|
|
|
|
- if (IS_ERR(bitmap->sb_page)) {
|
|
|
|
- err = PTR_ERR(bitmap->sb_page);
|
|
|
|
- bitmap->sb_page = NULL;
|
|
|
|
|
|
+ bitmap->storage.sb_page = alloc_page(GFP_KERNEL);
|
|
|
|
+ if (IS_ERR(bitmap->storage.sb_page)) {
|
|
|
|
+ err = PTR_ERR(bitmap->storage.sb_page);
|
|
|
|
+ bitmap->storage.sb_page = NULL;
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
- bitmap->sb_page->index = 0;
|
|
|
|
|
|
+ bitmap->storage.sb_page->index = 0;
|
|
|
|
|
|
- sb = kmap_atomic(bitmap->sb_page);
|
|
|
|
|
|
+ sb = kmap_atomic(bitmap->storage.sb_page);
|
|
|
|
|
|
sb->magic = cpu_to_le32(BITMAP_MAGIC);
|
|
sb->magic = cpu_to_le32(BITMAP_MAGIC);
|
|
sb->version = cpu_to_le32(BITMAP_MAJOR_HI);
|
|
sb->version = cpu_to_le32(BITMAP_MAJOR_HI);
|
|
@@ -536,7 +537,7 @@ static int bitmap_read_sb(struct bitmap *bitmap)
|
|
int err = -EINVAL;
|
|
int err = -EINVAL;
|
|
struct page *sb_page;
|
|
struct page *sb_page;
|
|
|
|
|
|
- if (!bitmap->file && !bitmap->mddev->bitmap_info.offset) {
|
|
|
|
|
|
+ if (!bitmap->storage.file && !bitmap->mddev->bitmap_info.offset) {
|
|
chunksize = 128 * 1024 * 1024;
|
|
chunksize = 128 * 1024 * 1024;
|
|
daemon_sleep = 5 * HZ;
|
|
daemon_sleep = 5 * HZ;
|
|
write_behind = 0;
|
|
write_behind = 0;
|
|
@@ -548,13 +549,13 @@ static int bitmap_read_sb(struct bitmap *bitmap)
|
|
sb_page = alloc_page(GFP_KERNEL);
|
|
sb_page = alloc_page(GFP_KERNEL);
|
|
if (!sb_page)
|
|
if (!sb_page)
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
- bitmap->sb_page = sb_page;
|
|
|
|
|
|
+ bitmap->storage.sb_page = sb_page;
|
|
|
|
|
|
- if (bitmap->file) {
|
|
|
|
- loff_t isize = i_size_read(bitmap->file->f_mapping->host);
|
|
|
|
|
|
+ if (bitmap->storage.file) {
|
|
|
|
+ loff_t isize = i_size_read(bitmap->storage.file->f_mapping->host);
|
|
int bytes = isize > PAGE_SIZE ? PAGE_SIZE : isize;
|
|
int bytes = isize > PAGE_SIZE ? PAGE_SIZE : isize;
|
|
|
|
|
|
- err = read_page(bitmap->file, 0,
|
|
|
|
|
|
+ err = read_page(bitmap->storage.file, 0,
|
|
bitmap, bytes, sb_page);
|
|
bitmap, bytes, sb_page);
|
|
} else {
|
|
} else {
|
|
err = read_sb_page(bitmap->mddev,
|
|
err = read_sb_page(bitmap->mddev,
|
|
@@ -647,9 +648,9 @@ static int bitmap_mask_state(struct bitmap *bitmap, enum bitmap_state bits,
|
|
bitmap_super_t *sb;
|
|
bitmap_super_t *sb;
|
|
int old;
|
|
int old;
|
|
|
|
|
|
- if (!bitmap->sb_page) /* can't set the state */
|
|
|
|
|
|
+ if (!bitmap->storage.sb_page) /* can't set the state */
|
|
return 0;
|
|
return 0;
|
|
- sb = kmap_atomic(bitmap->sb_page);
|
|
|
|
|
|
+ sb = kmap_atomic(bitmap->storage.sb_page);
|
|
old = le32_to_cpu(sb->state) & bits;
|
|
old = le32_to_cpu(sb->state) & bits;
|
|
switch (op) {
|
|
switch (op) {
|
|
case MASK_SET:
|
|
case MASK_SET:
|
|
@@ -678,17 +679,19 @@ static int bitmap_mask_state(struct bitmap *bitmap, enum bitmap_state bits,
|
|
* file a page at a time. There's a superblock at the start of the file.
|
|
* file a page at a time. There's a superblock at the start of the file.
|
|
*/
|
|
*/
|
|
/* calculate the index of the page that contains this bit */
|
|
/* calculate the index of the page that contains this bit */
|
|
-static inline unsigned long file_page_index(struct bitmap *bitmap, unsigned long chunk)
|
|
|
|
|
|
+static inline unsigned long file_page_index(struct bitmap_storage *store,
|
|
|
|
+ unsigned long chunk)
|
|
{
|
|
{
|
|
- if (!bitmap->mddev->bitmap_info.external)
|
|
|
|
|
|
+ if (store->sb_page)
|
|
chunk += sizeof(bitmap_super_t) << 3;
|
|
chunk += sizeof(bitmap_super_t) << 3;
|
|
return chunk >> PAGE_BIT_SHIFT;
|
|
return chunk >> PAGE_BIT_SHIFT;
|
|
}
|
|
}
|
|
|
|
|
|
/* calculate the (bit) offset of this bit within a page */
|
|
/* calculate the (bit) offset of this bit within a page */
|
|
-static inline unsigned long file_page_offset(struct bitmap *bitmap, unsigned long chunk)
|
|
|
|
|
|
+static inline unsigned long file_page_offset(struct bitmap_storage *store,
|
|
|
|
+ unsigned long chunk)
|
|
{
|
|
{
|
|
- if (!bitmap->mddev->bitmap_info.external)
|
|
|
|
|
|
+ if (store->sb_page)
|
|
chunk += sizeof(bitmap_super_t) << 3;
|
|
chunk += sizeof(bitmap_super_t) << 3;
|
|
return chunk & (PAGE_BITS - 1);
|
|
return chunk & (PAGE_BITS - 1);
|
|
}
|
|
}
|
|
@@ -700,13 +703,13 @@ static inline unsigned long file_page_offset(struct bitmap *bitmap, unsigned lon
|
|
* 1 page (e.g., x86) or less than 1 page -- so the bitmap might start on page
|
|
* 1 page (e.g., x86) or less than 1 page -- so the bitmap might start on page
|
|
* 0 or page 1
|
|
* 0 or page 1
|
|
*/
|
|
*/
|
|
-static inline struct page *filemap_get_page(struct bitmap *bitmap,
|
|
|
|
|
|
+static inline struct page *filemap_get_page(struct bitmap_storage *store,
|
|
unsigned long chunk)
|
|
unsigned long chunk)
|
|
{
|
|
{
|
|
- if (file_page_index(bitmap, chunk) >= bitmap->file_pages)
|
|
|
|
|
|
+ if (file_page_index(store, chunk) >= store->file_pages)
|
|
return NULL;
|
|
return NULL;
|
|
- return bitmap->filemap[file_page_index(bitmap, chunk)
|
|
|
|
- - file_page_index(bitmap, 0)];
|
|
|
|
|
|
+ return store->filemap[file_page_index(store, chunk)
|
|
|
|
+ - file_page_index(store, 0)];
|
|
}
|
|
}
|
|
|
|
|
|
static void bitmap_file_unmap(struct bitmap *bitmap)
|
|
static void bitmap_file_unmap(struct bitmap *bitmap)
|
|
@@ -715,16 +718,17 @@ static void bitmap_file_unmap(struct bitmap *bitmap)
|
|
unsigned long *attr;
|
|
unsigned long *attr;
|
|
int pages;
|
|
int pages;
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
|
|
+ struct bitmap_storage *store = &bitmap->storage;
|
|
|
|
|
|
spin_lock_irqsave(&bitmap->lock, flags);
|
|
spin_lock_irqsave(&bitmap->lock, flags);
|
|
- map = bitmap->filemap;
|
|
|
|
- bitmap->filemap = NULL;
|
|
|
|
- attr = bitmap->filemap_attr;
|
|
|
|
- bitmap->filemap_attr = NULL;
|
|
|
|
- pages = bitmap->file_pages;
|
|
|
|
- bitmap->file_pages = 0;
|
|
|
|
- sb_page = bitmap->sb_page;
|
|
|
|
- bitmap->sb_page = NULL;
|
|
|
|
|
|
+ map = store->filemap;
|
|
|
|
+ store->filemap = NULL;
|
|
|
|
+ attr = store->filemap_attr;
|
|
|
|
+ store->filemap_attr = NULL;
|
|
|
|
+ pages = store->file_pages;
|
|
|
|
+ store->file_pages = 0;
|
|
|
|
+ sb_page = store->sb_page;
|
|
|
|
+ store->sb_page = NULL;
|
|
spin_unlock_irqrestore(&bitmap->lock, flags);
|
|
spin_unlock_irqrestore(&bitmap->lock, flags);
|
|
|
|
|
|
while (pages--)
|
|
while (pages--)
|
|
@@ -743,8 +747,8 @@ static void bitmap_file_put(struct bitmap *bitmap)
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
|
|
|
|
spin_lock_irqsave(&bitmap->lock, flags);
|
|
spin_lock_irqsave(&bitmap->lock, flags);
|
|
- file = bitmap->file;
|
|
|
|
- bitmap->file = NULL;
|
|
|
|
|
|
+ file = bitmap->storage.file;
|
|
|
|
+ bitmap->storage.file = NULL;
|
|
spin_unlock_irqrestore(&bitmap->lock, flags);
|
|
spin_unlock_irqrestore(&bitmap->lock, flags);
|
|
|
|
|
|
if (file)
|
|
if (file)
|
|
@@ -771,11 +775,11 @@ static void bitmap_file_kick(struct bitmap *bitmap)
|
|
if (bitmap_mask_state(bitmap, BITMAP_STALE, MASK_SET) == 0) {
|
|
if (bitmap_mask_state(bitmap, BITMAP_STALE, MASK_SET) == 0) {
|
|
bitmap_update_sb(bitmap);
|
|
bitmap_update_sb(bitmap);
|
|
|
|
|
|
- if (bitmap->file) {
|
|
|
|
|
|
+ if (bitmap->storage.file) {
|
|
path = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
|
path = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
|
if (path)
|
|
if (path)
|
|
- ptr = d_path(&bitmap->file->f_path, path,
|
|
|
|
- PAGE_SIZE);
|
|
|
|
|
|
+ ptr = d_path(&bitmap->storage.file->f_path,
|
|
|
|
+ path, 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",
|
|
@@ -803,19 +807,19 @@ enum bitmap_page_attr {
|
|
static inline void set_page_attr(struct bitmap *bitmap, int pnum,
|
|
static inline void set_page_attr(struct bitmap *bitmap, int pnum,
|
|
enum bitmap_page_attr attr)
|
|
enum bitmap_page_attr attr)
|
|
{
|
|
{
|
|
- __set_bit((pnum<<2) + attr, bitmap->filemap_attr);
|
|
|
|
|
|
+ __set_bit((pnum<<2) + attr, bitmap->storage.filemap_attr);
|
|
}
|
|
}
|
|
|
|
|
|
static inline void clear_page_attr(struct bitmap *bitmap, int pnum,
|
|
static inline void clear_page_attr(struct bitmap *bitmap, int pnum,
|
|
enum bitmap_page_attr attr)
|
|
enum bitmap_page_attr attr)
|
|
{
|
|
{
|
|
- __clear_bit((pnum<<2) + attr, bitmap->filemap_attr);
|
|
|
|
|
|
+ __clear_bit((pnum<<2) + attr, bitmap->storage.filemap_attr);
|
|
}
|
|
}
|
|
|
|
|
|
static inline unsigned long test_page_attr(struct bitmap *bitmap, int pnum,
|
|
static inline unsigned long test_page_attr(struct bitmap *bitmap, int pnum,
|
|
enum bitmap_page_attr attr)
|
|
enum bitmap_page_attr attr)
|
|
{
|
|
{
|
|
- return test_bit((pnum<<2) + attr, bitmap->filemap_attr);
|
|
|
|
|
|
+ return test_bit((pnum<<2) + attr, bitmap->storage.filemap_attr);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -832,10 +836,10 @@ static void bitmap_file_set_bit(struct bitmap *bitmap, sector_t block)
|
|
void *kaddr;
|
|
void *kaddr;
|
|
unsigned long chunk = block >> bitmap->chunkshift;
|
|
unsigned long chunk = block >> bitmap->chunkshift;
|
|
|
|
|
|
- page = filemap_get_page(bitmap, chunk);
|
|
|
|
|
|
+ page = filemap_get_page(&bitmap->storage, chunk);
|
|
if (!page)
|
|
if (!page)
|
|
return;
|
|
return;
|
|
- bit = file_page_offset(bitmap, chunk);
|
|
|
|
|
|
+ bit = file_page_offset(&bitmap->storage, chunk);
|
|
|
|
|
|
/* set the bit */
|
|
/* set the bit */
|
|
kaddr = kmap_atomic(page);
|
|
kaddr = kmap_atomic(page);
|
|
@@ -856,10 +860,10 @@ static void bitmap_file_clear_bit(struct bitmap *bitmap, sector_t block)
|
|
void *paddr;
|
|
void *paddr;
|
|
unsigned long chunk = block >> bitmap->chunkshift;
|
|
unsigned long chunk = block >> bitmap->chunkshift;
|
|
|
|
|
|
- page = filemap_get_page(bitmap, chunk);
|
|
|
|
|
|
+ page = filemap_get_page(&bitmap->storage, chunk);
|
|
if (!page)
|
|
if (!page)
|
|
return;
|
|
return;
|
|
- bit = file_page_offset(bitmap, chunk);
|
|
|
|
|
|
+ bit = file_page_offset(&bitmap->storage, chunk);
|
|
paddr = kmap_atomic(page);
|
|
paddr = kmap_atomic(page);
|
|
if (bitmap->flags & BITMAP_HOSTENDIAN)
|
|
if (bitmap->flags & BITMAP_HOSTENDIAN)
|
|
clear_bit(bit, paddr);
|
|
clear_bit(bit, paddr);
|
|
@@ -881,14 +885,14 @@ void bitmap_unplug(struct bitmap *bitmap)
|
|
int dirty, need_write;
|
|
int dirty, need_write;
|
|
int wait = 0;
|
|
int wait = 0;
|
|
|
|
|
|
- if (!bitmap || !bitmap->filemap)
|
|
|
|
|
|
+ if (!bitmap || !bitmap->storage.filemap)
|
|
return;
|
|
return;
|
|
|
|
|
|
/* look at each page to see if there are any set bits that need to be
|
|
/* look at each page to see if there are any set bits that need to be
|
|
* flushed out to disk */
|
|
* flushed out to disk */
|
|
- for (i = 0; i < bitmap->file_pages; i++) {
|
|
|
|
|
|
+ for (i = 0; i < bitmap->storage.file_pages; i++) {
|
|
spin_lock_irqsave(&bitmap->lock, flags);
|
|
spin_lock_irqsave(&bitmap->lock, flags);
|
|
- if (!bitmap->filemap) {
|
|
|
|
|
|
+ if (!bitmap->storage.filemap) {
|
|
spin_unlock_irqrestore(&bitmap->lock, flags);
|
|
spin_unlock_irqrestore(&bitmap->lock, flags);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
@@ -903,10 +907,10 @@ void bitmap_unplug(struct bitmap *bitmap)
|
|
spin_unlock_irqrestore(&bitmap->lock, flags);
|
|
spin_unlock_irqrestore(&bitmap->lock, flags);
|
|
|
|
|
|
if (dirty || need_write)
|
|
if (dirty || need_write)
|
|
- write_page(bitmap, bitmap->filemap[i], 0);
|
|
|
|
|
|
+ write_page(bitmap, bitmap->storage.filemap[i], 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 */
|
|
- if (bitmap->file)
|
|
|
|
|
|
+ if (bitmap->storage.file)
|
|
wait_event(bitmap->write_wait,
|
|
wait_event(bitmap->write_wait,
|
|
atomic_read(&bitmap->pending_writes)==0);
|
|
atomic_read(&bitmap->pending_writes)==0);
|
|
else
|
|
else
|
|
@@ -940,14 +944,15 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
|
|
int outofdate;
|
|
int outofdate;
|
|
int ret = -ENOSPC;
|
|
int ret = -ENOSPC;
|
|
void *paddr;
|
|
void *paddr;
|
|
|
|
+ struct bitmap_storage *store = &bitmap->storage;
|
|
|
|
|
|
chunks = bitmap->chunks;
|
|
chunks = bitmap->chunks;
|
|
- file = bitmap->file;
|
|
|
|
|
|
+ file = store->file;
|
|
|
|
|
|
if (!file && !bitmap->mddev->bitmap_info.offset) {
|
|
if (!file && !bitmap->mddev->bitmap_info.offset) {
|
|
/* No permanent bitmap - fill with '1s'. */
|
|
/* No permanent bitmap - fill with '1s'. */
|
|
- bitmap->filemap = NULL;
|
|
|
|
- bitmap->file_pages = 0;
|
|
|
|
|
|
+ store->filemap = NULL;
|
|
|
|
+ store->file_pages = 0;
|
|
for (i = 0; i < chunks ; i++) {
|
|
for (i = 0; i < chunks ; i++) {
|
|
/* if the disk bit is set, set the memory bit */
|
|
/* if the disk bit is set, set the memory bit */
|
|
int needed = ((sector_t)(i+1) << (bitmap->chunkshift)
|
|
int needed = ((sector_t)(i+1) << (bitmap->chunkshift)
|
|
@@ -980,39 +985,40 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
|
|
|
|
|
|
ret = -ENOMEM;
|
|
ret = -ENOMEM;
|
|
|
|
|
|
- bitmap->filemap = kmalloc(sizeof(struct page *) * num_pages, GFP_KERNEL);
|
|
|
|
- if (!bitmap->filemap)
|
|
|
|
|
|
+ store->filemap = kmalloc(sizeof(struct page *)
|
|
|
|
+ * num_pages, GFP_KERNEL);
|
|
|
|
+ if (!store->filemap)
|
|
goto err;
|
|
goto err;
|
|
|
|
|
|
pnum = 0;
|
|
pnum = 0;
|
|
offset = 0;
|
|
offset = 0;
|
|
- if (bitmap->sb_page) {
|
|
|
|
- bitmap->filemap[0] = bitmap->sb_page;
|
|
|
|
|
|
+ if (store->sb_page) {
|
|
|
|
+ store->filemap[0] = store->sb_page;
|
|
pnum = 1;
|
|
pnum = 1;
|
|
offset = sizeof(bitmap_super_t);
|
|
offset = sizeof(bitmap_super_t);
|
|
}
|
|
}
|
|
for ( ; pnum < num_pages; pnum++) {
|
|
for ( ; pnum < num_pages; pnum++) {
|
|
- bitmap->filemap[pnum] = alloc_page(GFP_KERNEL);
|
|
|
|
- if (!bitmap->filemap[pnum]) {
|
|
|
|
- bitmap->file_pages = pnum;
|
|
|
|
|
|
+ store->filemap[pnum] = alloc_page(GFP_KERNEL);
|
|
|
|
+ if (!store->filemap[pnum]) {
|
|
|
|
+ store->file_pages = pnum;
|
|
goto err;
|
|
goto err;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- bitmap->file_pages = pnum;
|
|
|
|
|
|
+ store->file_pages = pnum;
|
|
|
|
|
|
/* 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(
|
|
|
|
|
|
+ store->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 (!store->filemap_attr)
|
|
goto err;
|
|
goto err;
|
|
|
|
|
|
oldindex = ~0L;
|
|
oldindex = ~0L;
|
|
|
|
|
|
for (i = 0; i < chunks; i++) {
|
|
for (i = 0; i < chunks; i++) {
|
|
int b;
|
|
int b;
|
|
- index = file_page_index(bitmap, i);
|
|
|
|
- bit = file_page_offset(bitmap, i);
|
|
|
|
|
|
+ index = file_page_index(&bitmap->storage, i);
|
|
|
|
+ bit = file_page_offset(&bitmap->storage, i);
|
|
if (index != oldindex) { /* this is a new page, read it in */
|
|
if (index != oldindex) { /* this is a new page, read it in */
|
|
int count;
|
|
int count;
|
|
/* unmap the old page, we're done with it */
|
|
/* unmap the old page, we're done with it */
|
|
@@ -1020,7 +1026,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
|
|
count = bytes - index * PAGE_SIZE;
|
|
count = bytes - index * PAGE_SIZE;
|
|
else
|
|
else
|
|
count = PAGE_SIZE;
|
|
count = PAGE_SIZE;
|
|
- page = bitmap->filemap[index];
|
|
|
|
|
|
+ page = store->filemap[index];
|
|
if (file)
|
|
if (file)
|
|
ret = read_page(file, index, bitmap,
|
|
ret = read_page(file, index, bitmap,
|
|
count, page);
|
|
count, page);
|
|
@@ -1036,7 +1042,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
|
|
|
|
|
|
oldindex = index;
|
|
oldindex = index;
|
|
|
|
|
|
- bitmap->last_page_size = count;
|
|
|
|
|
|
+ store->last_page_size = count;
|
|
|
|
|
|
if (outofdate) {
|
|
if (outofdate) {
|
|
/*
|
|
/*
|
|
@@ -1074,7 +1080,8 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
|
|
|
|
|
|
printk(KERN_INFO "%s: bitmap initialized from disk: "
|
|
printk(KERN_INFO "%s: bitmap initialized from disk: "
|
|
"read %lu/%lu pages, set %lu of %lu bits\n",
|
|
"read %lu/%lu pages, set %lu of %lu bits\n",
|
|
- bmname(bitmap), bitmap->file_pages, num_pages, bit_cnt, chunks);
|
|
|
|
|
|
+ bmname(bitmap), store->file_pages,
|
|
|
|
+ num_pages, bit_cnt, chunks);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
@@ -1091,14 +1098,14 @@ void bitmap_write_all(struct bitmap *bitmap)
|
|
*/
|
|
*/
|
|
int i;
|
|
int i;
|
|
|
|
|
|
- if (!bitmap || !bitmap->filemap)
|
|
|
|
|
|
+ if (!bitmap || !bitmap->storage.filemap)
|
|
return;
|
|
return;
|
|
- if (bitmap->file)
|
|
|
|
|
|
+ if (bitmap->storage.file)
|
|
/* Only one copy, so nothing needed */
|
|
/* Only one copy, so nothing needed */
|
|
return;
|
|
return;
|
|
|
|
|
|
spin_lock_irq(&bitmap->lock);
|
|
spin_lock_irq(&bitmap->lock);
|
|
- for (i = 0; i < bitmap->file_pages; i++)
|
|
|
|
|
|
+ for (i = 0; i < bitmap->storage.file_pages; i++)
|
|
set_page_attr(bitmap, i,
|
|
set_page_attr(bitmap, i,
|
|
BITMAP_PAGE_NEEDWRITE);
|
|
BITMAP_PAGE_NEEDWRITE);
|
|
bitmap->allclean = 0;
|
|
bitmap->allclean = 0;
|
|
@@ -1165,7 +1172,7 @@ void bitmap_daemon_work(struct mddev *mddev)
|
|
* we will write it.
|
|
* we will write it.
|
|
*/
|
|
*/
|
|
spin_lock_irqsave(&bitmap->lock, flags);
|
|
spin_lock_irqsave(&bitmap->lock, flags);
|
|
- for (j = 0; j < bitmap->file_pages; j++)
|
|
|
|
|
|
+ for (j = 0; j < bitmap->storage.file_pages; j++)
|
|
if (test_page_attr(bitmap, j,
|
|
if (test_page_attr(bitmap, j,
|
|
BITMAP_PAGE_PENDING)) {
|
|
BITMAP_PAGE_PENDING)) {
|
|
set_page_attr(bitmap, j,
|
|
set_page_attr(bitmap, j,
|
|
@@ -1180,8 +1187,8 @@ void bitmap_daemon_work(struct mddev *mddev)
|
|
* other changes */
|
|
* other changes */
|
|
bitmap_super_t *sb;
|
|
bitmap_super_t *sb;
|
|
bitmap->need_sync = 0;
|
|
bitmap->need_sync = 0;
|
|
- if (bitmap->filemap) {
|
|
|
|
- sb = kmap_atomic(bitmap->sb_page);
|
|
|
|
|
|
+ if (bitmap->storage.filemap) {
|
|
|
|
+ sb = kmap_atomic(bitmap->storage.sb_page);
|
|
sb->events_cleared =
|
|
sb->events_cleared =
|
|
cpu_to_le64(bitmap->events_cleared);
|
|
cpu_to_le64(bitmap->events_cleared);
|
|
kunmap_atomic(sb);
|
|
kunmap_atomic(sb);
|
|
@@ -1233,7 +1240,7 @@ void bitmap_daemon_work(struct mddev *mddev)
|
|
* the first blocking holds the superblock and it has been updated.
|
|
* the first blocking holds the superblock and it has been updated.
|
|
* We mustn't write any other blocks before the superblock.
|
|
* We mustn't write any other blocks before the superblock.
|
|
*/
|
|
*/
|
|
- for (j = 0; j < bitmap->file_pages; j++) {
|
|
|
|
|
|
+ for (j = 0; j < bitmap->storage.file_pages; j++) {
|
|
|
|
|
|
if (test_page_attr(bitmap, j,
|
|
if (test_page_attr(bitmap, j,
|
|
BITMAP_PAGE_DIRTY))
|
|
BITMAP_PAGE_DIRTY))
|
|
@@ -1244,9 +1251,9 @@ void bitmap_daemon_work(struct mddev *mddev)
|
|
clear_page_attr(bitmap, j,
|
|
clear_page_attr(bitmap, j,
|
|
BITMAP_PAGE_NEEDWRITE);
|
|
BITMAP_PAGE_NEEDWRITE);
|
|
spin_unlock_irqrestore(&bitmap->lock, flags);
|
|
spin_unlock_irqrestore(&bitmap->lock, flags);
|
|
- write_page(bitmap, bitmap->filemap[j], 0);
|
|
|
|
|
|
+ write_page(bitmap, bitmap->storage.filemap[j], 0);
|
|
spin_lock_irqsave(&bitmap->lock, flags);
|
|
spin_lock_irqsave(&bitmap->lock, flags);
|
|
- if (!bitmap->filemap)
|
|
|
|
|
|
+ if (!bitmap->storage.filemap)
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1700,7 +1707,7 @@ int bitmap_create(struct mddev *mddev)
|
|
} else
|
|
} else
|
|
bitmap->sysfs_can_clear = NULL;
|
|
bitmap->sysfs_can_clear = NULL;
|
|
|
|
|
|
- bitmap->file = file;
|
|
|
|
|
|
+ bitmap->storage.file = file;
|
|
if (file) {
|
|
if (file) {
|
|
get_file(file);
|
|
get_file(file);
|
|
/* As future accesses to this file will use bmap,
|
|
/* As future accesses to this file will use bmap,
|
|
@@ -1832,9 +1839,9 @@ void bitmap_status(struct seq_file *seq, struct bitmap *bitmap)
|
|
<< (PAGE_SHIFT - 10),
|
|
<< (PAGE_SHIFT - 10),
|
|
chunk_kb ? chunk_kb : bitmap->mddev->bitmap_info.chunksize,
|
|
chunk_kb ? chunk_kb : bitmap->mddev->bitmap_info.chunksize,
|
|
chunk_kb ? "KB" : "B");
|
|
chunk_kb ? "KB" : "B");
|
|
- if (bitmap->file) {
|
|
|
|
|
|
+ if (bitmap->storage.file) {
|
|
seq_printf(seq, ", file: ");
|
|
seq_printf(seq, ", file: ");
|
|
- seq_path(seq, &bitmap->file->f_path, " \t\n");
|
|
|
|
|
|
+ seq_path(seq, &bitmap->storage.file->f_path, " \t\n");
|
|
}
|
|
}
|
|
|
|
|
|
seq_printf(seq, "\n");
|
|
seq_printf(seq, "\n");
|
|
@@ -1958,8 +1965,9 @@ space_store(struct mddev *mddev, const char *buf, size_t len)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
|
|
|
if (mddev->bitmap &&
|
|
if (mddev->bitmap &&
|
|
- sectors < ((mddev->bitmap->file_pages - 1) * PAGE_SIZE
|
|
|
|
- + mddev->bitmap->last_page_size + 511) >> 9)
|
|
|
|
|
|
+ sectors < ((mddev->bitmap->storage.file_pages - 1)
|
|
|
|
+ * PAGE_SIZE
|
|
|
|
+ + mddev->bitmap->storage.last_page_size + 511) >> 9)
|
|
return -EFBIG; /* Bitmap is too big for this small space */
|
|
return -EFBIG; /* Bitmap is too big for this small space */
|
|
|
|
|
|
/* could make sure it isn't too big, but that isn't really
|
|
/* could make sure it isn't too big, but that isn't really
|