diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2017-02-17 07:33:04 -0800 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-02-17 07:33:04 -0800 |
| commit | 7fa84a1a0636e31ba9dde0c87e673c3b1722c9e7 (patch) | |
| tree | dc61e35ebc34a094af21519fd4cfa0bc4a6e4cce | |
| parent | c82e967d8a4e2fd0cd9676a4190a3bf6f05a32f2 (diff) | |
| parent | 1e64d58846cf1fda68b858567167e8323bac413a (diff) | |
Merge "block: protect iterate_bdevs() against concurrent close"
| -rw-r--r-- | fs/block_dev.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c index 44d4a1e9244e..ac9b7553c02a 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -1806,6 +1806,7 @@ void iterate_bdevs(void (*func)(struct block_device *, void *), void *arg) spin_lock(&blockdev_superblock->s_inode_list_lock); list_for_each_entry(inode, &blockdev_superblock->s_inodes, i_sb_list) { struct address_space *mapping = inode->i_mapping; + struct block_device *bdev; spin_lock(&inode->i_lock); if (inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW) || @@ -1826,8 +1827,12 @@ void iterate_bdevs(void (*func)(struct block_device *, void *), void *arg) */ iput(old_inode); old_inode = inode; + bdev = I_BDEV(inode); - func(I_BDEV(inode), arg); + mutex_lock(&bdev->bd_mutex); + if (bdev->bd_openers) + func(bdev, arg); + mutex_unlock(&bdev->bd_mutex); spin_lock(&blockdev_superblock->s_inode_list_lock); } |
