diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index c97f10b48b5b..86be578787a7 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c @@ -48,7 +48,7 @@ enum {Enabled, Magic}; #define MISC_FMT_OPEN_FILE (1UL << 28) typedef struct { - struct list_head list; + struct hlist_node node; unsigned long flags; /* type, status, etc. */ int offset; /* offset of magic */ int size; /* size of magic/mask */ @@ -95,7 +95,7 @@ static Node *search_binfmt_handler(struct binfmt_misc *misc, Node *e; /* Walk all the registered handlers. */ - list_for_each_entry(e, &misc->entries, list) { + hlist_for_each_entry(e, &misc->entries, node) { char *s; int j; @@ -665,8 +665,8 @@ static struct binfmt_misc *i_binfmt_misc(struct inode *inode) * * If the ->evict call was not caused by a super block shutdown but by a write * to remove the entry or all entries via bm_{entry,status}_write() the entry - * will have already been removed from the list. We keep the list_empty() check - * to make that explicit. + * will have already been removed from the list. We keep the hlist_unhashed() + * check to make that explicit. */ static void bm_evict_inode(struct inode *inode) { @@ -679,8 +679,8 @@ static void bm_evict_inode(struct inode *inode) misc = i_binfmt_misc(inode); write_lock(&misc->entries_lock); - if (!list_empty(&e->list)) - list_del_init(&e->list); + if (!hlist_unhashed(&e->node)) + hlist_del_init(&e->node); write_unlock(&misc->entries_lock); put_binfmt_handler(e); } @@ -701,7 +701,7 @@ static void bm_evict_inode(struct inode *inode) static void remove_binfmt_handler(struct binfmt_misc *misc, Node *e) { write_lock(&misc->entries_lock); - list_del_init(&e->list); + hlist_del_init(&e->node); write_unlock(&misc->entries_lock); locked_recursive_removal(e->dentry, NULL); } @@ -757,7 +757,7 @@ static ssize_t bm_entry_write(struct file *file, const char __user *buffer, * read-only. So we only need to take the write lock when we * actually remove the entry from the list. */ - if (!list_empty(&e->list)) + if (!hlist_unhashed(&e->node)) remove_binfmt_handler(i_binfmt_misc(inode), e); inode_unlock(inode); @@ -801,7 +801,7 @@ static int add_entry(Node *e, struct super_block *sb) d_make_persistent(dentry, inode); misc = i_binfmt_misc(inode); write_lock(&misc->entries_lock); - list_add(&e->list, &misc->entries); + hlist_add_head(&e->node, &misc->entries); write_unlock(&misc->entries_lock); simple_done_creating(dentry); return 0; @@ -874,8 +874,9 @@ static ssize_t bm_status_write(struct file *file, const char __user *buffer, { struct binfmt_misc *misc; int res = parse_command(buffer, count); - Node *e, *next; + struct hlist_node *next; struct inode *inode; + Node *e; misc = i_binfmt_misc(file_inode(file)); switch (res) { @@ -901,7 +902,7 @@ static ssize_t bm_status_write(struct file *file, const char __user *buffer, * read-only. So we only need to take the write lock when we * actually remove the entry from the list. */ - list_for_each_entry_safe(e, next, &misc->entries, list) + hlist_for_each_entry_safe(e, next, &misc->entries, node) remove_binfmt_handler(misc, e); inode_unlock(inode); @@ -971,7 +972,7 @@ static int bm_fill_super(struct super_block *sb, struct fs_context *fc) if (!misc) return -ENOMEM; - INIT_LIST_HEAD(&misc->entries); + INIT_HLIST_HEAD(&misc->entries); rwlock_init(&misc->entries_lock); /* Pairs with smp_load_acquire() in load_binfmt_misc(). */ diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index 2c77e383e737..071da63f2b48 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h @@ -101,7 +101,7 @@ struct linux_binfmt { #if IS_ENABLED(CONFIG_BINFMT_MISC) struct binfmt_misc { - struct list_head entries; + struct hlist_head entries; rwlock_t entries_lock; bool enabled; } __randomize_layout; diff --git a/kernel/user.c b/kernel/user.c index 7aef4e679a6a..c6a2bfb4d918 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -23,7 +23,7 @@ #if IS_ENABLED(CONFIG_BINFMT_MISC) struct binfmt_misc init_binfmt_misc = { - .entries = LIST_HEAD_INIT(init_binfmt_misc.entries), + .entries = HLIST_HEAD_INIT, .enabled = true, .entries_lock = __RW_LOCK_UNLOCKED(init_binfmt_misc.entries_lock), };