History

md: resolve external metadata handling deadlock in md_allow_write

md_allow_write() marks the metadata dirty while holding mddev->lock and then waits for the write to complete. For externally managed metadata this causes a deadlock as userspace needs to take the lock to communicate that the metadata update has completed. Change md_allow_write() in the 'external' case to start the 'mark active' operation and then return -EAGAIN. The expected side effects while waiting for userspace to write 'active' to 'array_state' are holding off reshape (code currently handles -ENOMEM), cause some 'stripe_cache_size' change requests to fail, cause some GET_BITMAP_FILE ioctl requests to fall back to GFP_NOIO, and cause updates to 'raid_disks' to fail. Except for 'stripe_cache_size' changes these failures can be mitigated by coordinating with mdmon. md_write_start() still prevents writes from occurring until the metadata handler has had a chance to take action as it unconditionally waits for MD_CHANGE_CLEAN to be cleared. [neilb@suse.de: return -EAGAIN, try GFP_NOIO] Signed-off-by: Dan Williams <dan.j.williams@intel.com>

Dan Williams committed 18 years ago

Commit b5470dc1 parent 1fe797e4 files · +30 −17Browse files

Showing the changes to include/linux/raid (1 of 4 files). Show all

Unified · Split

include/linux/raid/md.h+1−1
@@ -95,7 +95,7 @@ extern int sync_page_io(struct block_device *bdev, sector_t sector, int size, · 94 unmodified lines
9595 struct page *page, int rw);
9696 extern void md_do_sync(mddev_t *mddev);
9797 extern void md_new_event(mddev_t *mddev);
98−extern void md_allow_write(mddev_t *mddev);
98+extern int md_allow_write(mddev_t *mddev);
9999 extern void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev);
100100
101101 #endif /* CONFIG_MD */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t