summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2016-07-19 13:16:52 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2016-07-19 13:16:52 -0400
commita4a4f9439c73b921ef246368fc6f2d7c0281e99d (patch)
tree7ed28dab1f5a5b9769a919dbeb523ebd1e87a8e6
parentb223f4e215b32849b841e750e83a915b670070f5 (diff)
downloadlinux-a4a4f9439c73b921ef246368fc6f2d7c0281e99d.tar.bz2
bdev: get rid of ->bd_inodes
Since 2006 we have ->i_bdev pinning bdev in question, so there's no way to get to bdev ->evict_inode() while there's an aliasing inode anywhere. In other words, the only place walking the list of aliases is guaranteed to do it only when the list is empty... Remove the detritus; it should've been done in "[PATCH] Fix a race condition between ->i_mapping and iput()", but nobody had noticed it back then. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/block_dev.c16
-rw-r--r--include/linux/fs.h1
2 files changed, 2 insertions, 15 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 71ccab1d22c6..73130dad30e4 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -614,7 +614,6 @@ static void init_once(void *foo)
memset(bdev, 0, sizeof(*bdev));
mutex_init(&bdev->bd_mutex);
- INIT_LIST_HEAD(&bdev->bd_inodes);
INIT_LIST_HEAD(&bdev->bd_list);
#ifdef CONFIG_SYSFS
INIT_LIST_HEAD(&bdev->bd_holder_disks);
@@ -624,24 +623,13 @@ static void init_once(void *foo)
mutex_init(&bdev->bd_fsfreeze_mutex);
}
-static inline void __bd_forget(struct inode *inode)
-{
- list_del_init(&inode->i_devices);
- inode->i_bdev = NULL;
- inode->i_mapping = &inode->i_data;
-}
-
static void bdev_evict_inode(struct inode *inode)
{
struct block_device *bdev = &BDEV_I(inode)->bdev;
- struct list_head *p;
truncate_inode_pages_final(&inode->i_data);
invalidate_inode_buffers(inode); /* is it needed here? */
clear_inode(inode);
spin_lock(&bdev_lock);
- while ( (p = bdev->bd_inodes.next) != &bdev->bd_inodes ) {
- __bd_forget(list_entry(p, struct inode, i_devices));
- }
list_del_init(&bdev->bd_list);
spin_unlock(&bdev_lock);
}
@@ -805,7 +793,6 @@ static struct block_device *bd_acquire(struct inode *inode)
bdgrab(bdev);
inode->i_bdev = bdev;
inode->i_mapping = bdev->bd_inode->i_mapping;
- list_add(&inode->i_devices, &bdev->bd_inodes);
}
spin_unlock(&bdev_lock);
}
@@ -821,7 +808,8 @@ void bd_forget(struct inode *inode)
spin_lock(&bdev_lock);
if (!sb_is_blkdev_sb(inode->i_sb))
bdev = inode->i_bdev;
- __bd_forget(inode);
+ inode->i_bdev = NULL;
+ inode->i_mapping = &inode->i_data;
spin_unlock(&bdev_lock);
if (bdev)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index bacc0733663c..1878c8461622 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -459,7 +459,6 @@ struct block_device {
struct inode * bd_inode; /* will die */
struct super_block * bd_super;
struct mutex bd_mutex; /* open/close mutex */
- struct list_head bd_inodes;
void * bd_claiming;
void * bd_holder;
int bd_holders;