aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2012-05-21 23:55:07 -0400
committerNeilBrown <neilb@suse.de>2012-05-21 23:55:07 -0400
commit6409bb05a9831f6af36a20b97cda13059c2ef1b6 (patch)
treec997526bd60d3fb5cafea604e5b240c2479e20d9
parentbf07bb7d5be813630d3530be274b3324f85e310c (diff)
md/bitmap: add new 'space' attribute for bitmaps.
If we are to allow bitmaps to be resized when the array is resized, we need to know how much space there is. So create an attribute to store this information and set appropriate defaults. It can be set more precisely via sysfs, or future metadata extensions may allow it to be recorded. Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r--drivers/md/bitmap.c39
-rw-r--r--drivers/md/md.c33
-rw-r--r--drivers/md/md.h3
3 files changed, 73 insertions, 2 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index c7784a985676..ac688fb54e1d 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -1934,6 +1934,44 @@ location_store(struct mddev *mddev, const char *buf, size_t len)
1934static struct md_sysfs_entry bitmap_location = 1934static struct md_sysfs_entry bitmap_location =
1935__ATTR(location, S_IRUGO|S_IWUSR, location_show, location_store); 1935__ATTR(location, S_IRUGO|S_IWUSR, location_show, location_store);
1936 1936
1937/* 'bitmap/space' is the space available at 'location' for the
1938 * bitmap. This allows the kernel to know when it is safe to
1939 * resize the bitmap to match a resized array.
1940 */
1941static ssize_t
1942space_show(struct mddev *mddev, char *page)
1943{
1944 return sprintf(page, "%lu\n", mddev->bitmap_info.space);
1945}
1946
1947static ssize_t
1948space_store(struct mddev *mddev, const char *buf, size_t len)
1949{
1950 unsigned long sectors;
1951 int rv;
1952
1953 rv = kstrtoul(buf, 10, &sectors);
1954 if (rv)
1955 return rv;
1956
1957 if (sectors == 0)
1958 return -EINVAL;
1959
1960 if (mddev->bitmap &&
1961 sectors < ((mddev->bitmap->file_pages - 1) * PAGE_SIZE
1962 + mddev->bitmap->last_page_size + 511) >> 9)
1963 return -EFBIG; /* Bitmap is too big for this small space */
1964
1965 /* could make sure it isn't too big, but that isn't really
1966 * needed - user-space should be careful.
1967 */
1968 mddev->bitmap_info.space = sectors;
1969 return len;
1970}
1971
1972static struct md_sysfs_entry bitmap_space =
1973__ATTR(space, S_IRUGO|S_IWUSR, space_show, space_store);
1974
1937static ssize_t 1975static ssize_t
1938timeout_show(struct mddev *mddev, char *page) 1976timeout_show(struct mddev *mddev, char *page)
1939{ 1977{
@@ -2109,6 +2147,7 @@ __ATTR(max_backlog_used, S_IRUGO | S_IWUSR,
2109 2147
2110static struct attribute *md_bitmap_attrs[] = { 2148static struct attribute *md_bitmap_attrs[] = {
2111 &bitmap_location.attr, 2149 &bitmap_location.attr,
2150 &bitmap_space.attr,
2112 &bitmap_timeout.attr, 2151 &bitmap_timeout.attr,
2113 &bitmap_backlog.attr, 2152 &bitmap_backlog.attr,
2114 &bitmap_chunksize.attr, 2153 &bitmap_chunksize.attr,
diff --git a/drivers/md/md.c b/drivers/md/md.c
index ac99616f48d4..9a677f2078a7 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1197,7 +1197,10 @@ static int super_90_validate(struct mddev *mddev, struct md_rdev *rdev)
1197 mddev->dev_sectors = ((sector_t)sb->size) * 2; 1197 mddev->dev_sectors = ((sector_t)sb->size) * 2;
1198 mddev->events = ev1; 1198 mddev->events = ev1;
1199 mddev->bitmap_info.offset = 0; 1199 mddev->bitmap_info.offset = 0;
1200 mddev->bitmap_info.space = 0;
1201 /* bitmap can use 60 K after the 4K superblocks */
1200 mddev->bitmap_info.default_offset = MD_SB_BYTES >> 9; 1202 mddev->bitmap_info.default_offset = MD_SB_BYTES >> 9;
1203 mddev->bitmap_info.default_space = 64*2 - (MD_SB_BYTES >> 9);
1201 mddev->reshape_backwards = 0; 1204 mddev->reshape_backwards = 0;
1202 1205
1203 if (mddev->minor_version >= 91) { 1206 if (mddev->minor_version >= 91) {
@@ -1234,9 +1237,12 @@ static int super_90_validate(struct mddev *mddev, struct md_rdev *rdev)
1234 mddev->max_disks = MD_SB_DISKS; 1237 mddev->max_disks = MD_SB_DISKS;
1235 1238
1236 if (sb->state & (1<<MD_SB_BITMAP_PRESENT) && 1239 if (sb->state & (1<<MD_SB_BITMAP_PRESENT) &&
1237 mddev->bitmap_info.file == NULL) 1240 mddev->bitmap_info.file == NULL) {
1238 mddev->bitmap_info.offset = 1241 mddev->bitmap_info.offset =
1239 mddev->bitmap_info.default_offset; 1242 mddev->bitmap_info.default_offset;
1243 mddev->bitmap_info.space =
1244 mddev->bitmap_info.space;
1245 }
1240 1246
1241 } else if (mddev->pers == NULL) { 1247 } else if (mddev->pers == NULL) {
1242 /* Insist on good event counter while assembling, except 1248 /* Insist on good event counter while assembling, except
@@ -1677,7 +1683,12 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev)
1677 mddev->dev_sectors = le64_to_cpu(sb->size); 1683 mddev->dev_sectors = le64_to_cpu(sb->size);
1678 mddev->events = ev1; 1684 mddev->events = ev1;
1679 mddev->bitmap_info.offset = 0; 1685 mddev->bitmap_info.offset = 0;
1686 mddev->bitmap_info.space = 0;
1687 /* Default location for bitmap is 1K after superblock
1688 * using 3K - total of 4K
1689 */
1680 mddev->bitmap_info.default_offset = 1024 >> 9; 1690 mddev->bitmap_info.default_offset = 1024 >> 9;
1691 mddev->bitmap_info.default_space = (4096-1024) >> 9;
1681 mddev->reshape_backwards = 0; 1692 mddev->reshape_backwards = 0;
1682 1693
1683 mddev->recovery_cp = le64_to_cpu(sb->resync_offset); 1694 mddev->recovery_cp = le64_to_cpu(sb->resync_offset);
@@ -1686,9 +1697,23 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev)
1686 mddev->max_disks = (4096-256)/2; 1697 mddev->max_disks = (4096-256)/2;
1687 1698
1688 if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET) && 1699 if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET) &&
1689 mddev->bitmap_info.file == NULL ) 1700 mddev->bitmap_info.file == NULL) {
1690 mddev->bitmap_info.offset = 1701 mddev->bitmap_info.offset =
1691 (__s32)le32_to_cpu(sb->bitmap_offset); 1702 (__s32)le32_to_cpu(sb->bitmap_offset);
1703 /* Metadata doesn't record how much space is available.
1704 * For 1.0, we assume we can use up to the superblock
1705 * if before, else to 4K beyond superblock.
1706 * For others, assume no change is possible.
1707 */
1708 if (mddev->minor_version > 0)
1709 mddev->bitmap_info.space = 0;
1710 else if (mddev->bitmap_info.offset > 0)
1711 mddev->bitmap_info.space =
1712 8 - mddev->bitmap_info.offset;
1713 else
1714 mddev->bitmap_info.space =
1715 -mddev->bitmap_info.offset;
1716 }
1692 1717
1693 if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_RESHAPE_ACTIVE)) { 1718 if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_RESHAPE_ACTIVE)) {
1694 mddev->reshape_position = le64_to_cpu(sb->reshape_position); 1719 mddev->reshape_position = le64_to_cpu(sb->reshape_position);
@@ -5280,6 +5305,7 @@ static void md_clean(struct mddev *mddev)
5280 mddev->merge_check_needed = 0; 5305 mddev->merge_check_needed = 0;
5281 mddev->bitmap_info.offset = 0; 5306 mddev->bitmap_info.offset = 0;
5282 mddev->bitmap_info.default_offset = 0; 5307 mddev->bitmap_info.default_offset = 0;
5308 mddev->bitmap_info.default_space = 0;
5283 mddev->bitmap_info.chunksize = 0; 5309 mddev->bitmap_info.chunksize = 0;
5284 mddev->bitmap_info.daemon_sleep = 0; 5310 mddev->bitmap_info.daemon_sleep = 0;
5285 mddev->bitmap_info.max_write_behind = 0; 5311 mddev->bitmap_info.max_write_behind = 0;
@@ -6076,6 +6102,7 @@ static int set_array_info(struct mddev * mddev, mdu_array_info_t *info)
6076 set_bit(MD_CHANGE_DEVS, &mddev->flags); 6102 set_bit(MD_CHANGE_DEVS, &mddev->flags);
6077 6103
6078 mddev->bitmap_info.default_offset = MD_SB_BYTES >> 9; 6104 mddev->bitmap_info.default_offset = MD_SB_BYTES >> 9;
6105 mddev->bitmap_info.default_space = 64*2 - (MD_SB_BYTES >> 9);
6079 mddev->bitmap_info.offset = 0; 6106 mddev->bitmap_info.offset = 0;
6080 6107
6081 mddev->reshape_position = MaxSector; 6108 mddev->reshape_position = MaxSector;
@@ -6258,6 +6285,8 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info)
6258 return -EINVAL; 6285 return -EINVAL;
6259 mddev->bitmap_info.offset = 6286 mddev->bitmap_info.offset =
6260 mddev->bitmap_info.default_offset; 6287 mddev->bitmap_info.default_offset;
6288 mddev->bitmap_info.space =
6289 mddev->bitmap_info.default_space;
6261 mddev->pers->quiesce(mddev, 1); 6290 mddev->pers->quiesce(mddev, 1);
6262 rv = bitmap_create(mddev); 6291 rv = bitmap_create(mddev);
6263 if (!rv) 6292 if (!rv)
diff --git a/drivers/md/md.h b/drivers/md/md.h
index 360937389e64..7b4a3c318cae 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -393,10 +393,13 @@ struct mddev {
393 * For external metadata, offset 393 * For external metadata, offset
394 * from start of device. 394 * from start of device.
395 */ 395 */
396 unsigned long space; /* space available at this offset */
396 loff_t default_offset; /* this is the offset to use when 397 loff_t default_offset; /* this is the offset to use when
397 * hot-adding a bitmap. It should 398 * hot-adding a bitmap. It should
398 * eventually be settable by sysfs. 399 * eventually be settable by sysfs.
399 */ 400 */
401 unsigned long default_space; /* space available at
402 * default offset */
400 struct mutex mutex; 403 struct mutex mutex;
401 unsigned long chunksize; 404 unsigned long chunksize;
402 unsigned long daemon_sleep; /* how many jiffies between updates? */ 405 unsigned long daemon_sleep; /* how many jiffies between updates? */