summaryrefslogtreecommitdiff
path: root/block/bdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/bdev.c')
-rw-r--r--block/bdev.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/block/bdev.c b/block/bdev.c
index 738e3c8457e7..210ad4aee905 100644
--- a/block/bdev.c
+++ b/block/bdev.c
@@ -474,13 +474,19 @@ void bdev_drop(struct block_device *bdev)
long nr_blockdev_pages(void)
{
- struct inode *inode;
+ struct genradix_iter iter;
+ void **i;
long ret = 0;
- spin_lock(&blockdev_superblock->s_inode_list_lock);
- list_for_each_entry(inode, &blockdev_superblock->s_inodes, i_sb_list)
+ rcu_read_lock();
+ genradix_for_each(&blockdev_superblock->s_inodes.items, iter, i) {
+ struct inode *inode = *((struct inode **) i);
+ if (!inode)
+ continue;
+
ret += inode->i_mapping->nrpages;
- spin_unlock(&blockdev_superblock->s_inode_list_lock);
+ }
+ rcu_read_unlock();
return ret;
}
@@ -1216,10 +1222,16 @@ EXPORT_SYMBOL_GPL(bdev_mark_dead);
void sync_bdevs(bool wait)
{
- struct inode *inode, *old_inode = NULL;
+ struct genradix_iter iter;
+ void **i;
+ struct inode *old_inode = NULL;
+
+ rcu_read_lock();
+ genradix_for_each(&blockdev_superblock->s_inodes.items, iter, i) {
+ struct inode *inode = *((struct inode **) i);
+ if (!inode)
+ continue;
- 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;
@@ -1231,7 +1243,7 @@ void sync_bdevs(bool wait)
}
__iget(inode);
spin_unlock(&inode->i_lock);
- spin_unlock(&blockdev_superblock->s_inode_list_lock);
+ rcu_read_unlock();
/*
* We hold a reference to 'inode' so it couldn't have been
* removed from s_inodes list while we dropped the
@@ -1260,9 +1272,9 @@ void sync_bdevs(bool wait)
}
mutex_unlock(&bdev->bd_disk->open_mutex);
- spin_lock(&blockdev_superblock->s_inode_list_lock);
+ rcu_read_lock();
}
- spin_unlock(&blockdev_superblock->s_inode_list_lock);
+ rcu_read_unlock();
iput(old_inode);
}