diff options
Diffstat (limited to 'block/bdev.c')
-rw-r--r-- | block/bdev.c | 32 |
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); } |