Signed-off-by: Jan Kara <jack@xxxxxxx> --- fs/block_dev.c | 36 ++++++++++++++++++++++++++++++++++++ include/linux/fs.h | 1 + 2 files changed, 37 insertions(+), 0 deletions(-) diff --git a/fs/block_dev.c b/fs/block_dev.c index b07f1da..4d6631e 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -196,6 +196,42 @@ blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, nr_segs, blkdev_get_blocks, NULL, NULL, 0); } +void iterate_bdevs(void (*func)(struct block_device *, void *), void *arg) +{ + struct inode *inode, *old_inode = NULL; + + spin_lock(&inode_sb_list_lock); + list_for_each_entry(inode, &blockdev_superblock->s_inodes, i_sb_list) { + struct address_space *mapping = inode->i_mapping; + + spin_lock(&inode->i_lock); + if (inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW) || + mapping->nrpages == 0) { + spin_unlock(&inode->i_lock); + continue; + } + __iget(inode); + spin_unlock(&inode->i_lock); + spin_unlock(&inode_sb_list_lock); + /* + * We hold a reference to 'inode' so it couldn't have been + * removed from s_inodes list while we dropped the + * inode_sb_list_lock. We cannot iput the inode now as we can + * be holding the last reference and we cannot iput it under + * inode_sb_list_lock. So we keep the reference and iput it + * later. + */ + iput(old_inode); + old_inode = inode; + + func(I_BDEV(inode), arg); + + spin_lock(&inode_sb_list_lock); + } + spin_unlock(&inode_sb_list_lock); + iput(old_inode); +} + int __sync_blockdev(struct block_device *bdev, int wait) { if (!bdev) diff --git a/include/linux/fs.h b/include/linux/fs.h index 0c4df26..0404e7c 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2089,6 +2089,7 @@ extern void bd_set_size(struct block_device *, loff_t size); extern void bd_forget(struct inode *inode); extern void bdput(struct block_device *); extern void invalidate_bdev(struct block_device *); +extern void iterate_bdevs(void (*)(struct block_device *, void *), void *); extern int sync_blockdev(struct block_device *bdev); extern struct super_block *freeze_bdev(struct block_device *); extern void emergency_thaw_all(void); -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html