diff options
author | Jan Kara <jack@suse.cz> | 2012-07-03 10:45:31 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-07-22 15:58:45 -0400 |
commit | 5c0d6b60a0ba46d45020547eacf7199171920935 (patch) | |
tree | 7d9f99cc40981dc0872e1ac33317f48b9e1f2bfb | |
parent | b3de653105180b57af90ef2f5b8441f085f4ff56 (diff) |
vfs: Create function for iterating over block devices
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/block_dev.c | 36 | ||||
-rw-r--r-- | include/linux/fs.h | 5 |
2 files changed, 41 insertions, 0 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c index c2bbe1fb1326..1e519195d45b 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -1710,3 +1710,39 @@ int __invalidate_device(struct block_device *bdev, bool kill_dirty) | |||
1710 | return res; | 1710 | return res; |
1711 | } | 1711 | } |
1712 | EXPORT_SYMBOL(__invalidate_device); | 1712 | EXPORT_SYMBOL(__invalidate_device); |
1713 | |||
1714 | void iterate_bdevs(void (*func)(struct block_device *, void *), void *arg) | ||
1715 | { | ||
1716 | struct inode *inode, *old_inode = NULL; | ||
1717 | |||
1718 | spin_lock(&inode_sb_list_lock); | ||
1719 | list_for_each_entry(inode, &blockdev_superblock->s_inodes, i_sb_list) { | ||
1720 | struct address_space *mapping = inode->i_mapping; | ||
1721 | |||
1722 | spin_lock(&inode->i_lock); | ||
1723 | if (inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW) || | ||
1724 | mapping->nrpages == 0) { | ||
1725 | spin_unlock(&inode->i_lock); | ||
1726 | continue; | ||
1727 | } | ||
1728 | __iget(inode); | ||
1729 | spin_unlock(&inode->i_lock); | ||
1730 | spin_unlock(&inode_sb_list_lock); | ||
1731 | /* | ||
1732 | * We hold a reference to 'inode' so it couldn't have been | ||
1733 | * removed from s_inodes list while we dropped the | ||
1734 | * inode_sb_list_lock. We cannot iput the inode now as we can | ||
1735 | * be holding the last reference and we cannot iput it under | ||
1736 | * inode_sb_list_lock. So we keep the reference and iput it | ||
1737 | * later. | ||
1738 | */ | ||
1739 | iput(old_inode); | ||
1740 | old_inode = inode; | ||
1741 | |||
1742 | func(I_BDEV(inode), arg); | ||
1743 | |||
1744 | spin_lock(&inode_sb_list_lock); | ||
1745 | } | ||
1746 | spin_unlock(&inode_sb_list_lock); | ||
1747 | iput(old_inode); | ||
1748 | } | ||
diff --git a/include/linux/fs.h b/include/linux/fs.h index 48548bdd7722..6a6ca85bee23 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -2102,6 +2102,7 @@ extern sector_t blkdev_max_block(struct block_device *bdev); | |||
2102 | extern void bd_forget(struct inode *inode); | 2102 | extern void bd_forget(struct inode *inode); |
2103 | extern void bdput(struct block_device *); | 2103 | extern void bdput(struct block_device *); |
2104 | extern void invalidate_bdev(struct block_device *); | 2104 | extern void invalidate_bdev(struct block_device *); |
2105 | extern void iterate_bdevs(void (*)(struct block_device *, void *), void *); | ||
2105 | extern int sync_blockdev(struct block_device *bdev); | 2106 | extern int sync_blockdev(struct block_device *bdev); |
2106 | extern void kill_bdev(struct block_device *); | 2107 | extern void kill_bdev(struct block_device *); |
2107 | extern struct super_block *freeze_bdev(struct block_device *); | 2108 | extern struct super_block *freeze_bdev(struct block_device *); |
@@ -2123,6 +2124,10 @@ static inline int thaw_bdev(struct block_device *bdev, struct super_block *sb) | |||
2123 | { | 2124 | { |
2124 | return 0; | 2125 | return 0; |
2125 | } | 2126 | } |
2127 | |||
2128 | static inline void iterate_bdevs(void (*f)(struct block_device *, void *), void *arg) | ||
2129 | { | ||
2130 | } | ||
2126 | #endif | 2131 | #endif |
2127 | extern int sync_filesystem(struct super_block *); | 2132 | extern int sync_filesystem(struct super_block *); |
2128 | extern const struct file_operations def_blk_fops; | 2133 | extern const struct file_operations def_blk_fops; |