md: don't return -EAGAIN in md_allow_write for external metadata arrays
This essentially reverts commit b5470dc5fc18 ("md: resolve external metadata handling deadlock in md_allow_write") with some adjustments. Since commit 6791875e2e53 ("md: make reconfig_mutex optional for writes to md sysfs files.") changing array_state to 'active' does not use mddev_lock() and will not cause a deadlock with md_allow_write(). This revert simplifies userspace tools that write to sysfs attributes like "stripe_cache_size" or "consistency_policy" because it removes the need for special handling for external metadata arrays, checking for EAGAIN and retrying the write. Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com> Signed-off-by: Shaohua Li <shli@fb.com>
This commit is contained in:
parent
3d05f3aed5
commit
2214c260c7
@ -8022,18 +8022,15 @@ EXPORT_SYMBOL(md_write_end);
|
|||||||
* may proceed without blocking. It is important to call this before
|
* may proceed without blocking. It is important to call this before
|
||||||
* attempting a GFP_KERNEL allocation while holding the mddev lock.
|
* attempting a GFP_KERNEL allocation while holding the mddev lock.
|
||||||
* Must be called with mddev_lock held.
|
* Must be called with mddev_lock held.
|
||||||
*
|
|
||||||
* In the ->external case MD_SB_CHANGE_PENDING can not be cleared until mddev->lock
|
|
||||||
* is dropped, so return -EAGAIN after notifying userspace.
|
|
||||||
*/
|
*/
|
||||||
int md_allow_write(struct mddev *mddev)
|
void md_allow_write(struct mddev *mddev)
|
||||||
{
|
{
|
||||||
if (!mddev->pers)
|
if (!mddev->pers)
|
||||||
return 0;
|
return;
|
||||||
if (mddev->ro)
|
if (mddev->ro)
|
||||||
return 0;
|
return;
|
||||||
if (!mddev->pers->sync_request)
|
if (!mddev->pers->sync_request)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
spin_lock(&mddev->lock);
|
spin_lock(&mddev->lock);
|
||||||
if (mddev->in_sync) {
|
if (mddev->in_sync) {
|
||||||
@ -8046,13 +8043,12 @@ int md_allow_write(struct mddev *mddev)
|
|||||||
spin_unlock(&mddev->lock);
|
spin_unlock(&mddev->lock);
|
||||||
md_update_sb(mddev, 0);
|
md_update_sb(mddev, 0);
|
||||||
sysfs_notify_dirent_safe(mddev->sysfs_state);
|
sysfs_notify_dirent_safe(mddev->sysfs_state);
|
||||||
|
/* wait for the dirty state to be recorded in the metadata */
|
||||||
|
wait_event(mddev->sb_wait,
|
||||||
|
!test_bit(MD_SB_CHANGE_CLEAN, &mddev->sb_flags) &&
|
||||||
|
!test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags));
|
||||||
} else
|
} else
|
||||||
spin_unlock(&mddev->lock);
|
spin_unlock(&mddev->lock);
|
||||||
|
|
||||||
if (test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags))
|
|
||||||
return -EAGAIN;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(md_allow_write);
|
EXPORT_SYMBOL_GPL(md_allow_write);
|
||||||
|
|
||||||
|
@ -665,7 +665,7 @@ extern int sync_page_io(struct md_rdev *rdev, sector_t sector, int size,
|
|||||||
bool metadata_op);
|
bool metadata_op);
|
||||||
extern void md_do_sync(struct md_thread *thread);
|
extern void md_do_sync(struct md_thread *thread);
|
||||||
extern void md_new_event(struct mddev *mddev);
|
extern void md_new_event(struct mddev *mddev);
|
||||||
extern int md_allow_write(struct mddev *mddev);
|
extern void md_allow_write(struct mddev *mddev);
|
||||||
extern void md_wait_for_blocked_rdev(struct md_rdev *rdev, struct mddev *mddev);
|
extern void md_wait_for_blocked_rdev(struct md_rdev *rdev, struct mddev *mddev);
|
||||||
extern void md_set_array_sectors(struct mddev *mddev, sector_t array_sectors);
|
extern void md_set_array_sectors(struct mddev *mddev, sector_t array_sectors);
|
||||||
extern int md_check_no_bitmap(struct mddev *mddev);
|
extern int md_check_no_bitmap(struct mddev *mddev);
|
||||||
|
@ -3197,7 +3197,7 @@ static int raid1_reshape(struct mddev *mddev)
|
|||||||
struct r1conf *conf = mddev->private;
|
struct r1conf *conf = mddev->private;
|
||||||
int cnt, raid_disks;
|
int cnt, raid_disks;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int d, d2, err;
|
int d, d2;
|
||||||
|
|
||||||
/* Cannot change chunk_size, layout, or level */
|
/* Cannot change chunk_size, layout, or level */
|
||||||
if (mddev->chunk_sectors != mddev->new_chunk_sectors ||
|
if (mddev->chunk_sectors != mddev->new_chunk_sectors ||
|
||||||
@ -3209,11 +3209,8 @@ static int raid1_reshape(struct mddev *mddev)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mddev_is_clustered(mddev)) {
|
if (!mddev_is_clustered(mddev))
|
||||||
err = md_allow_write(mddev);
|
md_allow_write(mddev);
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
raid_disks = mddev->raid_disks + mddev->delta_disks;
|
raid_disks = mddev->raid_disks + mddev->delta_disks;
|
||||||
|
|
||||||
|
@ -2309,14 +2309,12 @@ static int resize_stripes(struct r5conf *conf, int newsize)
|
|||||||
struct stripe_head *osh, *nsh;
|
struct stripe_head *osh, *nsh;
|
||||||
LIST_HEAD(newstripes);
|
LIST_HEAD(newstripes);
|
||||||
struct disk_info *ndisks;
|
struct disk_info *ndisks;
|
||||||
int err;
|
int err = 0;
|
||||||
struct kmem_cache *sc;
|
struct kmem_cache *sc;
|
||||||
int i;
|
int i;
|
||||||
int hash, cnt;
|
int hash, cnt;
|
||||||
|
|
||||||
err = md_allow_write(conf->mddev);
|
md_allow_write(conf->mddev);
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
/* Step 1 */
|
/* Step 1 */
|
||||||
sc = kmem_cache_create(conf->cache_name[1-conf->active_name],
|
sc = kmem_cache_create(conf->cache_name[1-conf->active_name],
|
||||||
@ -6310,7 +6308,6 @@ int
|
|||||||
raid5_set_cache_size(struct mddev *mddev, int size)
|
raid5_set_cache_size(struct mddev *mddev, int size)
|
||||||
{
|
{
|
||||||
struct r5conf *conf = mddev->private;
|
struct r5conf *conf = mddev->private;
|
||||||
int err;
|
|
||||||
|
|
||||||
if (size <= 16 || size > 32768)
|
if (size <= 16 || size > 32768)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -6322,10 +6319,7 @@ raid5_set_cache_size(struct mddev *mddev, int size)
|
|||||||
;
|
;
|
||||||
mutex_unlock(&conf->cache_size_mutex);
|
mutex_unlock(&conf->cache_size_mutex);
|
||||||
|
|
||||||
|
md_allow_write(mddev);
|
||||||
err = md_allow_write(mddev);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
mutex_lock(&conf->cache_size_mutex);
|
mutex_lock(&conf->cache_size_mutex);
|
||||||
while (size > conf->max_nr_stripes)
|
while (size > conf->max_nr_stripes)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user