zonefs fixes for 6.1-rc7

- Fix a race between zonefs module initialization of sysfs attribute
    directory and mounting a drive (from Xiaoxu).
 
  - Fix active zone accounting in the rare case of an IO error due to a
    zone transition to offline or read-only state (from me).
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQSRPv8tYSvhwAzJdzjdoc3SxdoYdgUCY4FHbQAKCRDdoc3SxdoY
 dtVJAQDQPKQW7GlxgmfsxNZz4bR9CT2DHqoprN1g1bbKM9hYKwEApq0xtpBjyqX2
 EaePIFvlYa67f5kWnW4XEd5vetbh0AI=
 =imdG
 -----END PGP SIGNATURE-----

Merge tag 'zonefs-6.1-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/zonefs

Pull zonefs fixes from Damien Le Moal:

 - Fix a race between zonefs module initialization of sysfs attribute
   directory and mounting a drive (from Xiaoxu).

 - Fix active zone accounting in the rare case of an IO error due to a
   zone transition to offline or read-only state (from me).

* tag 'zonefs-6.1-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/zonefs:
  zonefs: Fix active zone accounting
  zonefs: Fix race between modprobe and mount
This commit is contained in:
Linus Torvalds 2022-11-25 16:34:39 -08:00
commit 3e0d88f911
2 changed files with 21 additions and 8 deletions

View file

@ -40,6 +40,13 @@ static void zonefs_account_active(struct inode *inode)
if (zi->i_ztype != ZONEFS_ZTYPE_SEQ)
return;
/*
* For zones that transitioned to the offline or readonly condition,
* we only need to clear the active state.
*/
if (zi->i_flags & (ZONEFS_ZONE_OFFLINE | ZONEFS_ZONE_READONLY))
goto out;
/*
* If the zone is active, that is, if it is explicitly open or
* partially written, check if it was already accounted as active.
@ -53,6 +60,7 @@ static void zonefs_account_active(struct inode *inode)
return;
}
out:
/* The zone is not active. If it was, update the active count */
if (zi->i_flags & ZONEFS_ZONE_ACTIVE) {
zi->i_flags &= ~ZONEFS_ZONE_ACTIVE;
@ -324,6 +332,7 @@ static loff_t zonefs_check_zone_condition(struct inode *inode,
inode->i_flags |= S_IMMUTABLE;
inode->i_mode &= ~0777;
zone->wp = zone->start;
zi->i_flags |= ZONEFS_ZONE_OFFLINE;
return 0;
case BLK_ZONE_COND_READONLY:
/*
@ -342,8 +351,10 @@ static loff_t zonefs_check_zone_condition(struct inode *inode,
zone->cond = BLK_ZONE_COND_OFFLINE;
inode->i_mode &= ~0777;
zone->wp = zone->start;
zi->i_flags |= ZONEFS_ZONE_OFFLINE;
return 0;
}
zi->i_flags |= ZONEFS_ZONE_READONLY;
inode->i_mode &= ~0222;
return i_size_read(inode);
case BLK_ZONE_COND_FULL:
@ -1922,18 +1933,18 @@ static int __init zonefs_init(void)
if (ret)
return ret;
ret = register_filesystem(&zonefs_type);
ret = zonefs_sysfs_init();
if (ret)
goto destroy_inodecache;
ret = zonefs_sysfs_init();
ret = register_filesystem(&zonefs_type);
if (ret)
goto unregister_fs;
goto sysfs_exit;
return 0;
unregister_fs:
unregister_filesystem(&zonefs_type);
sysfs_exit:
zonefs_sysfs_exit();
destroy_inodecache:
zonefs_destroy_inodecache();
@ -1942,9 +1953,9 @@ static int __init zonefs_init(void)
static void __exit zonefs_exit(void)
{
unregister_filesystem(&zonefs_type);
zonefs_sysfs_exit();
zonefs_destroy_inodecache();
unregister_filesystem(&zonefs_type);
}
MODULE_AUTHOR("Damien Le Moal");

View file

@ -39,8 +39,10 @@ static inline enum zonefs_ztype zonefs_zone_type(struct blk_zone *zone)
return ZONEFS_ZTYPE_SEQ;
}
#define ZONEFS_ZONE_OPEN (1 << 0)
#define ZONEFS_ZONE_ACTIVE (1 << 1)
#define ZONEFS_ZONE_OPEN (1U << 0)
#define ZONEFS_ZONE_ACTIVE (1U << 1)
#define ZONEFS_ZONE_OFFLINE (1U << 2)
#define ZONEFS_ZONE_READONLY (1U << 3)
/*
* In-memory inode data.