Subject: Re: linux-next: manual merge of the efi tree with the efi-fixes tree

From: Stephen Rothwell <[email-masked]>
Date: Mon, 11 Dec 2023 15:39:05 +1100

Hi all,

On Mon, 11 Dec 2023 15:13:03 +1100 Stephen Rothwell <[email-masked]> wrote:
> 
> Today's linux-next merge of the efi tree got a conflict in:
> 
>   fs/efivarfs/super.c
> 
> between commits:
> 
>   0b6d38bdd6f8 ("efivarfs: Free s_fs_info on unmount")
>   ab5c4251a009 ("efivarfs: Move efivarfs list into superblock s_fs_info")
> 
> from the efi-fixes tree and commit:
> 
>   b501d5b36f58 ("efivarfs: automatically update super block flag")
> 
> from the efi tree.
> 
> I fixed it up (see below) and can carry the fix as necessary. This
> is now fixed as far as linux-next is concerned, but any non trivial
> conflicts should be mentioned to your upstream maintainer when your tree
> is submitted for merging.  You may also want to consider cooperating
> with the maintainer of the conflicting tree to minimise any particularly
> complex conflicts.

Actually the below is needed. ("info" is not a great name for, even a
static, global variable.  And maybe what I have called "einfo" could be
"sfi" like in efivarfs_kill_sb() ...)
-- 
Cheers,
Stephen Rothwell

diff --cc fs/efivarfs/super.c
index d7d9a3e189a0,42eff5ac7ab4..d209475a8a49
--- a/fs/efivarfs/super.c
+++ b/fs/efivarfs/super.c
@@@ -18,6 -20,32 +20,30 @@@
  
  #include "internal.h"
  
 -LIST_HEAD(efivarfs_list);
 -
+ struct efivarfs_info {
+ 	struct super_block *sb;
+ 	struct notifier_block nb;
+ };
+ 
+ static struct efivarfs_info info;
+ 
+ static int efivarfs_ops_notifier(struct notifier_block *nb, unsigned long event,
+ 				 void *data)
+ {
+ 	switch (event) {
+ 	case EFIVAR_OPS_RDONLY:
+ 		info.sb->s_flags |= SB_RDONLY;
+ 		break;
+ 	case EFIVAR_OPS_RDWR:
+ 		info.sb->s_flags &= ~SB_RDONLY;
+ 		break;
+ 	default:
+ 		return NOTIFY_DONE;
+ 	}
+ 
+ 	return NOTIFY_OK;
+ }
+ 
  static void efivarfs_evict_inode(struct inode *inode)
  {
  	clear_inode(inode);
@@@ -290,7 -317,6 +316,7 @@@ static int efivarfs_parse_param(struct 
  
  static int efivarfs_fill_super(struct super_block *sb, struct fs_context *fc)
  {
- 	struct efivarfs_fs_info *info = sb->s_fs_info;
++	struct efivarfs_fs_info *einfo = sb->s_fs_info;
  	struct inode *inode = NULL;
  	struct dentry *root;
  	int err;
@@@ -316,10 -345,17 +342,16 @@@
  	if (!root)
  		return -ENOMEM;
  
+ 	info.sb = sb;
+ 	info.nb.notifier_call = efivarfs_ops_notifier;
+ 	err = blocking_notifier_chain_register(&efivar_ops_nh, &info.nb);
+ 	if (err)
+ 		return err;
+ 
 -	INIT_LIST_HEAD(&efivarfs_list);
 -
 -	err = efivar_init(efivarfs_callback, (void *)sb, true, &efivarfs_list);
 +	err = efivar_init(efivarfs_callback, (void *)sb, true,
- 			  &info->efivarfs_list);
++			  &einfo->efivarfs_list);
  	if (err)
- 		efivar_entry_iter(efivarfs_destroy, &info->efivarfs_list, NULL);
 -		efivar_entry_iter(efivarfs_destroy, &efivarfs_list, NULL);
++		efivar_entry_iter(efivarfs_destroy, &einfo->efivarfs_list, NULL);
  
  	return err;
  }
@@@ -357,13 -399,15 +400,15 @@@ static int efivarfs_init_fs_context(str
  
  static void efivarfs_kill_sb(struct super_block *sb)
  {
 +	struct efivarfs_fs_info *sfi = sb->s_fs_info;
 +
+ 	blocking_notifier_chain_unregister(&efivar_ops_nh, &info.nb);
+ 	info.sb = NULL;
  	kill_litter_super(sb);
  
 -	if (!efivar_is_available())
 -		return;
 -
  	/* Remove all entries and destroy */
 -	efivar_entry_iter(efivarfs_destroy, &efivarfs_list, NULL);
 +	efivar_entry_iter(efivarfs_destroy, &sfi->efivarfs_list, NULL);
 +	kfree(sfi);
  }
  
  static struct file_system_type efivarfs_type = {