Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 305943
b: refs/heads/master
c: d1244cb
h: refs/heads/master
i:
  305941: 9e55631
  305939: 5d6b132
  305935: 260efb1
v: v3
  • Loading branch information
NeilBrown committed May 22, 2012
1 parent b3c000a commit 8c41db0
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 47 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9b1215c102d4b12f6c815d7fdd35d0628db35b28
refs/heads/master: d1244cb062750bdb2298ca2565239d3d8cbd91a8
113 changes: 67 additions & 46 deletions trunk/drivers/md/bitmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,58 @@ static inline struct page *filemap_get_page(struct bitmap_storage *store,
- file_page_index(store, 0)];
}

static int bitmap_storage_alloc(struct bitmap_storage *store,
unsigned long chunks, int with_super)
{
int pnum;
unsigned long num_pages;
unsigned long bytes;

bytes = DIV_ROUND_UP(chunks, 8);
if (with_super)
bytes += sizeof(bitmap_super_t);

num_pages = DIV_ROUND_UP(bytes, PAGE_SIZE);

store->filemap = kmalloc(sizeof(struct page *)
* num_pages, GFP_KERNEL);
if (!store->filemap)
return -ENOMEM;

if (with_super && !store->sb_page) {
store->sb_page = alloc_page(GFP_KERNEL);
if (store->sb_page == NULL)
return -ENOMEM;
store->sb_page->index = 0;
}
pnum = 0;
if (store->sb_page) {
store->filemap[0] = store->sb_page;
pnum = 1;
}
for ( ; pnum < num_pages; pnum++) {
store->filemap[pnum] = alloc_page(GFP_KERNEL);
if (!store->filemap[pnum]) {
store->file_pages = pnum;
return -ENOMEM;
}
store->filemap[pnum]->index = pnum;
}
store->file_pages = pnum;

/* We need 4 bits per page, rounded up to a multiple
* of sizeof(unsigned long) */
store->filemap_attr = kzalloc(
roundup(DIV_ROUND_UP(num_pages*4, 8), sizeof(unsigned long)),
GFP_KERNEL);
if (!store->filemap_attr)
return -ENOMEM;

store->bytes = bytes;

return 0;
}

static void bitmap_file_unmap(struct bitmap *bitmap)
{
struct page **map, *sb_page;
Expand Down Expand Up @@ -940,11 +992,10 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int n
static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
{
unsigned long i, chunks, index, oldindex, bit;
int pnum;
struct page *page = NULL;
unsigned long num_pages, bit_cnt = 0;
unsigned long bit_cnt = 0;
struct file *file;
unsigned long bytes, offset;
unsigned long offset;
int outofdate;
int ret = -ENOSPC;
void *paddr;
Expand Down Expand Up @@ -973,53 +1024,23 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
printk(KERN_INFO "%s: bitmap file is out of date, doing full "
"recovery\n", bmname(bitmap));

bytes = DIV_ROUND_UP(bitmap->chunks, 8);
if (!bitmap->mddev->bitmap_info.external)
bytes += sizeof(bitmap_super_t);

store->bytes = bytes;

num_pages = DIV_ROUND_UP(bytes, PAGE_SIZE);

if (file && i_size_read(file->f_mapping->host) < bytes) {
if (file && i_size_read(file->f_mapping->host) < store->bytes) {
printk(KERN_INFO "%s: bitmap file too short %lu < %lu\n",
bmname(bitmap),
(unsigned long) i_size_read(file->f_mapping->host),
bytes);
bmname(bitmap),
(unsigned long) i_size_read(file->f_mapping->host),
store->bytes);
goto err;
}

ret = -ENOMEM;

store->filemap = kmalloc(sizeof(struct page *)
* num_pages, GFP_KERNEL);
if (!store->filemap)
ret = bitmap_storage_alloc(&bitmap->storage, bitmap->chunks,
!bitmap->mddev->bitmap_info.external);
if (ret)
goto err;

pnum = 0;
oldindex = ~0L;
offset = 0;
if (store->sb_page) {
store->filemap[0] = store->sb_page;
pnum = 1;
if (!bitmap->mddev->bitmap_info.external)
offset = sizeof(bitmap_super_t);
}
for ( ; pnum < num_pages; pnum++) {
store->filemap[pnum] = alloc_page(GFP_KERNEL);
if (!store->filemap[pnum]) {
store->file_pages = pnum;
goto err;
}
}
store->file_pages = pnum;

/* We need 4 bits per page, rounded up to a multiple of sizeof(unsigned long) */
store->filemap_attr = kzalloc(
roundup(DIV_ROUND_UP(num_pages*4, 8), sizeof(unsigned long)),
GFP_KERNEL);
if (!store->filemap_attr)
goto err;

oldindex = ~0L;

for (i = 0; i < chunks; i++) {
int b;
Expand All @@ -1028,8 +1049,8 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
if (index != oldindex) { /* this is a new page, read it in */
int count;
/* unmap the old page, we're done with it */
if (index == num_pages-1)
count = bytes - index * PAGE_SIZE;
if (index == store->file_pages-1)
count = store->bytes - index * PAGE_SIZE;
else
count = PAGE_SIZE;
page = store->filemap[index];
Expand Down Expand Up @@ -1083,9 +1104,9 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
}

printk(KERN_INFO "%s: bitmap initialized from disk: "
"read %lu/%lu pages, set %lu of %lu bits\n",
"read %lu pages, set %lu of %lu bits\n",
bmname(bitmap), store->file_pages,
num_pages, bit_cnt, chunks);
bit_cnt, chunks);

return 0;

Expand Down

0 comments on commit 8c41db0

Please sign in to comment.