Commit 3e0d88f9 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents f10b4396 db58653c
Loading
Loading
Loading
Loading
+17 −6
Original line number Diff line number Diff line
@@ -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");
+4 −2
Original line number Diff line number Diff line
@@ -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.