Struct inode has an i_devices list head which is used when inode represents a block device or a character device for tracking all inodes referencing that device. The only use of that tracking is to remove references to the device from inodes when the device is released. However both block device and character device code take reference to the device together with referencing it from an inode (block device code takes inode reference, character device code kobj reference) thus device cannot be released while there are any inodes referencing it. Remove the useless code and i_devices from struct inode. Signed-off-by: Jan Kara <jack@xxxxxxx> --- fs/block_dev.c | 17 +++-------------- fs/char_dev.c | 19 ------------------- fs/inode.c | 1 - include/linux/cdev.h | 1 - include/linux/fs.h | 2 -- 5 files changed, 3 insertions(+), 37 deletions(-) diff --git a/fs/block_dev.c b/fs/block_dev.c index 1e86823a9cbd..01fc44cd9e7d 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -398,7 +398,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); @@ -408,24 +407,14 @@ 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(&inode->i_data, 0); 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); } @@ -585,7 +574,6 @@ static struct block_device *bd_acquire(struct inode *inode) ihold(bdev->bd_inode); inode->i_bdev = bdev; inode->i_mapping = bdev->bd_inode->i_mapping; - list_add(&inode->i_devices, &bdev->bd_inodes); } spin_unlock(&bdev_lock); } @@ -606,7 +594,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/fs/char_dev.c b/fs/char_dev.c index f77f7702fabe..883208f2f211 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c @@ -389,7 +389,6 @@ static int chrdev_open(struct inode *inode, struct file *filp) p = inode->i_cdev; if (!p) { inode->i_cdev = p = new; - list_add(&inode->i_devices, &p->list); new = NULL; } else if (!cdev_get(p)) ret = -ENXIO; @@ -422,23 +421,10 @@ static int chrdev_open(struct inode *inode, struct file *filp) void cd_forget(struct inode *inode) { spin_lock(&cdev_lock); - list_del_init(&inode->i_devices); inode->i_cdev = NULL; spin_unlock(&cdev_lock); } -static void cdev_purge(struct cdev *cdev) -{ - spin_lock(&cdev_lock); - while (!list_empty(&cdev->list)) { - struct inode *inode; - inode = container_of(cdev->list.next, struct inode, i_devices); - list_del_init(&inode->i_devices); - inode->i_cdev = NULL; - } - spin_unlock(&cdev_lock); -} - /* * Dummy default file-operations: the only thing this does * is contain the open that then fills in the correct operations @@ -509,10 +495,8 @@ void cdev_del(struct cdev *p) static void cdev_default_release(struct kobject *kobj) { - struct cdev *p = container_of(kobj, struct cdev, kobj); struct kobject *parent = kobj->parent; - cdev_purge(p); kobject_put(parent); } @@ -521,7 +505,6 @@ static void cdev_dynamic_release(struct kobject *kobj) struct cdev *p = container_of(kobj, struct cdev, kobj); struct kobject *parent = kobj->parent; - cdev_purge(p); kfree(p); kobject_put(parent); } @@ -543,7 +526,6 @@ struct cdev *cdev_alloc(void) { struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL); if (p) { - INIT_LIST_HEAD(&p->list); kobject_init(&p->kobj, &ktype_cdev_dynamic); } return p; @@ -560,7 +542,6 @@ struct cdev *cdev_alloc(void) void cdev_init(struct cdev *cdev, const struct file_operations *fops) { memset(cdev, 0, sizeof *cdev); - INIT_LIST_HEAD(&cdev->list); kobject_init(&cdev->kobj, &ktype_cdev_default); cdev->ops = fops; } diff --git a/fs/inode.c b/fs/inode.c index 4bcdad3c9361..e89be4c4c9f4 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -365,7 +365,6 @@ void inode_init_once(struct inode *inode) { memset(inode, 0, sizeof(*inode)); INIT_HLIST_NODE(&inode->i_hash); - INIT_LIST_HEAD(&inode->i_devices); INIT_LIST_HEAD(&inode->i_wb_list); INIT_LIST_HEAD(&inode->i_lru); address_space_init_once(&inode->i_data); diff --git a/include/linux/cdev.h b/include/linux/cdev.h index fb4591977b03..fe00138b5106 100644 --- a/include/linux/cdev.h +++ b/include/linux/cdev.h @@ -13,7 +13,6 @@ struct cdev { struct kobject kobj; struct module *owner; const struct file_operations *ops; - struct list_head list; dev_t dev; unsigned int count; }; diff --git a/include/linux/fs.h b/include/linux/fs.h index 23b2a35d712e..ac6e06a09980 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -440,7 +440,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; @@ -595,7 +594,6 @@ struct inode { #ifdef CONFIG_QUOTA struct dquot *i_dquot[MAXQUOTAS]; #endif - struct list_head i_devices; union { struct pipe_inode_info *i_pipe; struct block_device *i_bdev; -- 1.8.1.4 -- 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