aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/bitmap.c199
-rw-r--r--drivers/md/bitmap.h3
2 files changed, 172 insertions, 30 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index bc552bbad83e..a35561f8f57d 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -698,7 +698,7 @@ static int bitmap_storage_alloc(struct bitmap_storage *store,
698 return -ENOMEM; 698 return -ENOMEM;
699 699
700 if (with_super && !store->sb_page) { 700 if (with_super && !store->sb_page) {
701 store->sb_page = alloc_page(GFP_KERNEL); 701 store->sb_page = alloc_page(GFP_KERNEL|__GFP_ZERO);
702 if (store->sb_page == NULL) 702 if (store->sb_page == NULL)
703 return -ENOMEM; 703 return -ENOMEM;
704 store->sb_page->index = 0; 704 store->sb_page->index = 0;
@@ -709,7 +709,7 @@ static int bitmap_storage_alloc(struct bitmap_storage *store,
709 pnum = 1; 709 pnum = 1;
710 } 710 }
711 for ( ; pnum < num_pages; pnum++) { 711 for ( ; pnum < num_pages; pnum++) {
712 store->filemap[pnum] = alloc_page(GFP_KERNEL); 712 store->filemap[pnum] = alloc_page(GFP_KERNEL|__GFP_ZERO);
713 if (!store->filemap[pnum]) { 713 if (!store->filemap[pnum]) {
714 store->file_pages = pnum; 714 store->file_pages = pnum;
715 return -ENOMEM; 715 return -ENOMEM;
@@ -1630,8 +1630,6 @@ int bitmap_create(struct mddev *mddev)
1630{ 1630{
1631 struct bitmap *bitmap; 1631 struct bitmap *bitmap;
1632 sector_t blocks = mddev->resync_max_sectors; 1632 sector_t blocks = mddev->resync_max_sectors;
1633 unsigned long chunks;
1634 unsigned long pages;
1635 struct file *file = mddev->bitmap_info.file; 1633 struct file *file = mddev->bitmap_info.file;
1636 int err; 1634 int err;
1637 struct sysfs_dirent *bm = NULL; 1635 struct sysfs_dirent *bm = NULL;
@@ -1691,37 +1689,14 @@ int bitmap_create(struct mddev *mddev)
1691 goto error; 1689 goto error;
1692 1690
1693 bitmap->daemon_lastrun = jiffies; 1691 bitmap->daemon_lastrun = jiffies;
1694 bitmap->counts.chunkshift = (ffz(~mddev->bitmap_info.chunksize) 1692 err = bitmap_resize(bitmap, blocks, mddev->bitmap_info.chunksize, 1);
1695 - BITMAP_BLOCK_SHIFT); 1693 if (err)
1696
1697 chunks = DIV_ROUND_UP_SECTOR_T(blocks, 1 << bitmap->counts.chunkshift);
1698 pages = DIV_ROUND_UP(chunks, PAGE_COUNTER_RATIO);
1699
1700 BUG_ON(!pages);
1701
1702 bitmap->counts.chunks = chunks;
1703 bitmap->counts.pages = pages;
1704 bitmap->counts.missing_pages = pages;
1705
1706 bitmap->counts.bp = kzalloc(pages * sizeof(*bitmap->counts.bp),
1707 GFP_KERNEL);
1708
1709 err = -ENOMEM;
1710 if (!bitmap->counts.bp)
1711 goto error; 1694 goto error;
1712 1695
1713 if (file || mddev->bitmap_info.offset) {
1714 err = bitmap_storage_alloc(&bitmap->storage, bitmap->counts.chunks,
1715 !mddev->bitmap_info.external);
1716 if (err)
1717 goto error;
1718 }
1719 printk(KERN_INFO "created bitmap (%lu pages) for device %s\n", 1696 printk(KERN_INFO "created bitmap (%lu pages) for device %s\n",
1720 pages, bmname(bitmap)); 1697 bitmap->counts.pages, bmname(bitmap));
1721 1698
1722 mddev->bitmap = bitmap; 1699 mddev->bitmap = bitmap;
1723
1724
1725 return test_bit(BITMAP_WRITE_ERROR, &bitmap->flags) ? -EIO : 0; 1700 return test_bit(BITMAP_WRITE_ERROR, &bitmap->flags) ? -EIO : 0;
1726 1701
1727 error: 1702 error:
@@ -1807,6 +1782,170 @@ void bitmap_status(struct seq_file *seq, struct bitmap *bitmap)
1807 seq_printf(seq, "\n"); 1782 seq_printf(seq, "\n");
1808} 1783}
1809 1784
1785int bitmap_resize(struct bitmap *bitmap, sector_t blocks,
1786 int chunksize, int init)
1787{
1788 /* If chunk_size is 0, choose an appropriate chunk size.
1789 * Then possibly allocate new storage space.
1790 * Then quiesce, copy bits, replace bitmap, and re-start
1791 *
1792 * This function is called both to set up the initial bitmap
1793 * and to resize the bitmap while the array is active.
1794 * If this happens as a result of the array being resized,
1795 * chunksize will be zero, and we need to choose a suitable
1796 * chunksize, otherwise we use what we are given.
1797 */
1798 struct bitmap_storage store;
1799 struct bitmap_counts old_counts;
1800 unsigned long chunks;
1801 sector_t block;
1802 sector_t old_blocks, new_blocks;
1803 int chunkshift;
1804 int ret = 0;
1805 long pages;
1806 struct bitmap_page *new_bp;
1807
1808 if (chunksize == 0) {
1809 /* If there is enough space, leave the chunk size unchanged,
1810 * else increase by factor of two until there is enough space.
1811 */
1812 long bytes;
1813 long space = bitmap->mddev->bitmap_info.space;
1814
1815 if (space == 0) {
1816 /* We don't know how much space there is, so limit
1817 * to current size - in sectors.
1818 */
1819 bytes = DIV_ROUND_UP(bitmap->counts.chunks, 8);
1820 if (!bitmap->mddev->bitmap_info.external)
1821 bytes += sizeof(bitmap_super_t);
1822 space = DIV_ROUND_UP(bytes, 512);
1823 bitmap->mddev->bitmap_info.space = space;
1824 }
1825 chunkshift = bitmap->counts.chunkshift;
1826 chunkshift--;
1827 do {
1828 /* 'chunkshift' is shift from block size to chunk size */
1829 chunkshift++;
1830 chunks = DIV_ROUND_UP_SECTOR_T(blocks, 1 << chunkshift);
1831 bytes = DIV_ROUND_UP(chunks, 8);
1832 if (!bitmap->mddev->bitmap_info.external)
1833 bytes += sizeof(bitmap_super_t);
1834 } while (bytes > (space << 9));
1835 } else
1836 chunkshift = ffz(~chunksize) - BITMAP_BLOCK_SHIFT;
1837
1838 chunks = DIV_ROUND_UP_SECTOR_T(blocks, 1 << chunkshift);
1839 memset(&store, 0, sizeof(store));
1840 if (bitmap->mddev->bitmap_info.offset || bitmap->mddev->bitmap_info.file)
1841 ret = bitmap_storage_alloc(&store, chunks,
1842 !bitmap->mddev->bitmap_info.external);
1843 if (ret)
1844 goto err;
1845
1846 pages = DIV_ROUND_UP(chunks, PAGE_COUNTER_RATIO);
1847
1848 new_bp = kzalloc(pages * sizeof(*new_bp), GFP_KERNEL);
1849 ret = -ENOMEM;
1850 if (!new_bp) {
1851 bitmap_file_unmap(&store);
1852 goto err;
1853 }
1854
1855 if (!init)
1856 bitmap->mddev->pers->quiesce(bitmap->mddev, 1);
1857
1858 store.file = bitmap->storage.file;
1859 bitmap->storage.file = NULL;
1860
1861 if (store.sb_page && bitmap->storage.sb_page)
1862 memcpy(page_address(store.sb_page),
1863 page_address(bitmap->storage.sb_page),
1864 sizeof(bitmap_super_t));
1865 bitmap_file_unmap(&bitmap->storage);
1866 bitmap->storage = store;
1867
1868 old_counts = bitmap->counts;
1869 bitmap->counts.bp = new_bp;
1870 bitmap->counts.pages = pages;
1871 bitmap->counts.missing_pages = pages;
1872 bitmap->counts.chunkshift = chunkshift;
1873 bitmap->counts.chunks = chunks;
1874 bitmap->mddev->bitmap_info.chunksize = 1 << (chunkshift +
1875 BITMAP_BLOCK_SHIFT);
1876
1877 blocks = min(old_counts.chunks << old_counts.chunkshift,
1878 chunks << chunkshift);
1879
1880 spin_lock_irq(&bitmap->counts.lock);
1881 for (block = 0; block < blocks; ) {
1882 bitmap_counter_t *bmc_old, *bmc_new;
1883 int set;
1884
1885 bmc_old = bitmap_get_counter(&old_counts, block,
1886 &old_blocks, 0);
1887 set = bmc_old && NEEDED(*bmc_old);
1888
1889 if (set) {
1890 bmc_new = bitmap_get_counter(&bitmap->counts, block,
1891 &new_blocks, 1);
1892 if (*bmc_new == 0) {
1893 /* need to set on-disk bits too. */
1894 sector_t end = block + new_blocks;
1895 sector_t start = block >> chunkshift;
1896 start <<= chunkshift;
1897 while (start < end) {
1898 bitmap_file_set_bit(bitmap, block);
1899 start += 1 << chunkshift;
1900 }
1901 *bmc_new = 2;
1902 bitmap_count_page(&bitmap->counts,
1903 block, 1);
1904 bitmap_set_pending(&bitmap->counts,
1905 block);
1906 }
1907 *bmc_new |= NEEDED_MASK;
1908 if (new_blocks < old_blocks)
1909 old_blocks = new_blocks;
1910 }
1911 block += old_blocks;
1912 }
1913
1914 if (!init) {
1915 int i;
1916 while (block < (chunks << chunkshift)) {
1917 bitmap_counter_t *bmc;
1918 bmc = bitmap_get_counter(&bitmap->counts, block,
1919 &new_blocks, 1);
1920 if (bmc) {
1921 /* new space. It needs to be resynced, so
1922 * we set NEEDED_MASK.
1923 */
1924 if (*bmc == 0) {
1925 *bmc = NEEDED_MASK | 2;
1926 bitmap_count_page(&bitmap->counts,
1927 block, 1);
1928 bitmap_set_pending(&bitmap->counts,
1929 block);
1930 }
1931 }
1932 block += new_blocks;
1933 }
1934 for (i = 0; i < bitmap->storage.file_pages; i++)
1935 set_page_attr(bitmap, i, BITMAP_PAGE_DIRTY);
1936 }
1937 spin_unlock_irq(&bitmap->counts.lock);
1938
1939 if (!init) {
1940 bitmap_unplug(bitmap);
1941 bitmap->mddev->pers->quiesce(bitmap->mddev, 0);
1942 }
1943 ret = 0;
1944err:
1945 return ret;
1946}
1947EXPORT_SYMBOL_GPL(bitmap_resize);
1948
1810static ssize_t 1949static ssize_t
1811location_show(struct mddev *mddev, char *page) 1950location_show(struct mddev *mddev, char *page)
1812{ 1951{
diff --git a/drivers/md/bitmap.h b/drivers/md/bitmap.h
index 6bde180e987b..04dcde3871be 100644
--- a/drivers/md/bitmap.h
+++ b/drivers/md/bitmap.h
@@ -255,6 +255,9 @@ void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector);
255 255
256void bitmap_unplug(struct bitmap *bitmap); 256void bitmap_unplug(struct bitmap *bitmap);
257void bitmap_daemon_work(struct mddev *mddev); 257void bitmap_daemon_work(struct mddev *mddev);
258
259int bitmap_resize(struct bitmap *bitmap, sector_t blocks,
260 int chunksize, int init);
258#endif 261#endif
259 262
260#endif 263#endif