Commit 8d0304e6 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'md/3.16' of git://neil.brown.name/md

Pull md updates from Neil Brown:
 "Assorted md fixes for 3.16

  Mostly performance improvements with a few corner-case bug fixes"

* tag 'md/3.16' of git://neil.brown.name/md:
  raid5: speedup sync_request processing
  md/raid5: deadlock between retry_aligned_read with barrier io
  raid5: add an option to avoid copy data from bio to stripe cache
  md/bitmap: remove confusing code from filemap_get_page.
  raid5: avoid release list until last reference of the stripe
  md: md_clear_badblocks should return an error code on failure.
  md/raid56: Don't perform reads to support writes until stripe is ready.
  md: refuse to change shape of array if it is active but read-only
parents dfb94547 053f5b65
...@@ -669,17 +669,13 @@ static inline unsigned long file_page_offset(struct bitmap_storage *store, ...@@ -669,17 +669,13 @@ static inline unsigned long file_page_offset(struct bitmap_storage *store,
/* /*
* return a pointer to the page in the filemap that contains the given bit * return a pointer to the page in the filemap that contains the given bit
* *
* this lookup is complicated by the fact that the bitmap sb might be exactly
* 1 page (e.g., x86) or less than 1 page -- so the bitmap might start on page
* 0 or page 1
*/ */
static inline struct page *filemap_get_page(struct bitmap_storage *store, static inline struct page *filemap_get_page(struct bitmap_storage *store,
unsigned long chunk) unsigned long chunk)
{ {
if (file_page_index(store, chunk) >= store->file_pages) if (file_page_index(store, chunk) >= store->file_pages)
return NULL; return NULL;
return store->filemap[file_page_index(store, chunk) return store->filemap[file_page_index(store, chunk)];
- file_page_index(store, 0)];
} }
static int bitmap_storage_alloc(struct bitmap_storage *store, static int bitmap_storage_alloc(struct bitmap_storage *store,
......
...@@ -3448,6 +3448,8 @@ level_store(struct mddev *mddev, const char *buf, size_t len) ...@@ -3448,6 +3448,8 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
mddev->level = LEVEL_NONE; mddev->level = LEVEL_NONE;
return rv; return rv;
} }
if (mddev->ro)
return -EROFS;
/* request to change the personality. Need to ensure: /* request to change the personality. Need to ensure:
* - array is not engaged in resync/recovery/reshape * - array is not engaged in resync/recovery/reshape
...@@ -3634,6 +3636,8 @@ layout_store(struct mddev *mddev, const char *buf, size_t len) ...@@ -3634,6 +3636,8 @@ layout_store(struct mddev *mddev, const char *buf, size_t len)
int err; int err;
if (mddev->pers->check_reshape == NULL) if (mddev->pers->check_reshape == NULL)
return -EBUSY; return -EBUSY;
if (mddev->ro)
return -EROFS;
mddev->new_layout = n; mddev->new_layout = n;
err = mddev->pers->check_reshape(mddev); err = mddev->pers->check_reshape(mddev);
if (err) { if (err) {
...@@ -3723,6 +3727,8 @@ chunk_size_store(struct mddev *mddev, const char *buf, size_t len) ...@@ -3723,6 +3727,8 @@ chunk_size_store(struct mddev *mddev, const char *buf, size_t len)
int err; int err;
if (mddev->pers->check_reshape == NULL) if (mddev->pers->check_reshape == NULL)
return -EBUSY; return -EBUSY;
if (mddev->ro)
return -EROFS;
mddev->new_chunk_sectors = n >> 9; mddev->new_chunk_sectors = n >> 9;
err = mddev->pers->check_reshape(mddev); err = mddev->pers->check_reshape(mddev);
if (err) { if (err) {
...@@ -6135,6 +6141,8 @@ static int update_size(struct mddev *mddev, sector_t num_sectors) ...@@ -6135,6 +6141,8 @@ static int update_size(struct mddev *mddev, sector_t num_sectors)
*/ */
if (mddev->sync_thread) if (mddev->sync_thread)
return -EBUSY; return -EBUSY;
if (mddev->ro)
return -EROFS;
rdev_for_each(rdev, mddev) { rdev_for_each(rdev, mddev) {
sector_t avail = rdev->sectors; sector_t avail = rdev->sectors;
...@@ -6157,6 +6165,8 @@ static int update_raid_disks(struct mddev *mddev, int raid_disks) ...@@ -6157,6 +6165,8 @@ static int update_raid_disks(struct mddev *mddev, int raid_disks)
/* change the number of raid disks */ /* change the number of raid disks */
if (mddev->pers->check_reshape == NULL) if (mddev->pers->check_reshape == NULL)
return -EINVAL; return -EINVAL;
if (mddev->ro)
return -EROFS;
if (raid_disks <= 0 || if (raid_disks <= 0 ||
(mddev->max_disks && raid_disks >= mddev->max_disks)) (mddev->max_disks && raid_disks >= mddev->max_disks))
return -EINVAL; return -EINVAL;
...@@ -8333,7 +8343,7 @@ static int md_clear_badblocks(struct badblocks *bb, sector_t s, int sectors) ...@@ -8333,7 +8343,7 @@ static int md_clear_badblocks(struct badblocks *bb, sector_t s, int sectors)
if (a < s) { if (a < s) {
/* we need to split this range */ /* we need to split this range */
if (bb->count >= MD_MAX_BADBLOCKS) { if (bb->count >= MD_MAX_BADBLOCKS) {
rv = 0; rv = -ENOSPC;
goto out; goto out;
} }
memmove(p+lo+1, p+lo, (bb->count - lo) * 8); memmove(p+lo+1, p+lo, (bb->count - lo) * 8);
......
This diff is collapsed.
...@@ -232,7 +232,7 @@ struct stripe_head { ...@@ -232,7 +232,7 @@ struct stripe_head {
*/ */
struct bio req, rreq; struct bio req, rreq;
struct bio_vec vec, rvec; struct bio_vec vec, rvec;
struct page *page; struct page *page, *orig_page;
struct bio *toread, *read, *towrite, *written; struct bio *toread, *read, *towrite, *written;
sector_t sector; /* sector of this page */ sector_t sector; /* sector of this page */
unsigned long flags; unsigned long flags;
...@@ -299,6 +299,7 @@ enum r5dev_flags { ...@@ -299,6 +299,7 @@ enum r5dev_flags {
* data in, and now is a good time to write it out. * data in, and now is a good time to write it out.
*/ */
R5_Discard, /* Discard the stripe */ R5_Discard, /* Discard the stripe */
R5_SkipCopy, /* Don't copy data from bio to stripe cache */
}; };
/* /*
...@@ -436,6 +437,7 @@ struct r5conf { ...@@ -436,6 +437,7 @@ struct r5conf {
atomic_t pending_full_writes; /* full write backlog */ atomic_t pending_full_writes; /* full write backlog */
int bypass_count; /* bypassed prereads */ int bypass_count; /* bypassed prereads */
int bypass_threshold; /* preread nice */ int bypass_threshold; /* preread nice */
int skip_copy; /* Don't copy data from bio to stripe cache */
struct list_head *last_hold; /* detect hold_list promotions */ struct list_head *last_hold; /* detect hold_list promotions */
atomic_t reshape_stripes; /* stripes with pending writes for reshape */ atomic_t reshape_stripes; /* stripes with pending writes for reshape */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment