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.
                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;
                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:
                /*
                        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:
 
        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.