|    option    | condition | size     read    write    read    write |
     +--------------+-----------+-----------------------------------------+
     |              | good      | fixed    yes     no       yes     yes   |
-    | remount-ro   | read-only | fixed    yes     no       yes     no    |
+    | remount-ro   | read-only | as is    yes     no       yes     no    |
     | (default)    | offline   |   0      no      no       no      no    |
     +--------------+-----------+-----------------------------------------+
     |              | good      | fixed    yes     no       yes     yes   |
-    | zone-ro      | read-only | fixed    yes     no       yes     no    |
+    | zone-ro      | read-only | as is    yes     no       yes     no    |
     |              | offline   |   0      no      no       no      no    |
     +--------------+-----------+-----------------------------------------+
     |              | good      |   0      no      no       yes     yes   |
     |              | offline   |   0      no      no       no      no    |
     +--------------+-----------+-----------------------------------------+
     |              | good      | fixed    yes     yes      yes     yes   |
-    | repair       | read-only | fixed    yes     no       yes     no    |
+    | repair       | read-only | as is    yes     no       yes     no    |
     |              | offline   |   0      no      no       no      no    |
     +--------------+-----------+-----------------------------------------+
 
 * zone-offline
 * repair
 
-The I/O error actions defined for each behavior are detailed in the previous
-section.
+The run-time I/O error actions defined for each behavior are detailed in the
+previous section. Mount time I/O errors will cause the mount operation to fail.
+The handling of read-only zones also differs between mount-time and run-time.
+If a read-only zone is found at mount time, the zone is always treated in the
+same manner as offline zones, that is, all accesses are disabled and the zone
+file size set to 0. This is necessary as the write pointer of read-only zones
+is defined as invalib by the ZBC and ZAC standards, making it impossible to
+discover the amount of data that has been written to the zone. In the case of a
+read-only zone discovered at run-time, as indicated in the previous section.
+the size of the zone file is left unchanged from its last updated value.
 
 Zonefs User Space Tools
 =======================
 
  * amount of readable data in the zone.
  */
 static loff_t zonefs_check_zone_condition(struct inode *inode,
-                                         struct blk_zone *zone, bool warn)
+                                         struct blk_zone *zone, bool warn,
+                                         bool mount)
 {
        struct zonefs_inode_info *zi = ZONEFS_I(inode);
 
                zone->wp = zone->start;
                return 0;
        case BLK_ZONE_COND_READONLY:
-               /* Do not allow writes in read-only zones */
+               /*
+                * The write pointer of read-only zones is invalid. If such a
+                * zone is found during mount, the file size cannot be retrieved
+                * so we treat the zone as offline (mount == true case).
+                * Otherwise, keep the file size as it was when last updated
+                * so that the user can recover data. In both cases, writes are
+                * always disabled for the zone.
+                */
                if (warn)
                        zonefs_warn(inode->i_sb, "inode %lu: read-only zone\n",
                                    inode->i_ino);
                inode->i_flags |= S_IMMUTABLE;
+               if (mount) {
+                       zone->cond = BLK_ZONE_COND_OFFLINE;
+                       inode->i_mode &= ~0777;
+                       zone->wp = zone->start;
+                       return 0;
+               }
                inode->i_mode &= ~0222;
-               /* fallthrough */
+               return i_size_read(inode);
        default:
                if (zi->i_ztype == ZONEFS_ZTYPE_CNV)
                        return zi->i_max_size;
         * as there is no inconsistency between the inode size and the amount of
         * data writen in the zone (data_size).
         */
-       data_size = zonefs_check_zone_condition(inode, zone, true);
+       data_size = zonefs_check_zone_condition(inode, zone, true, false);
        isize = i_size_read(inode);
        if (zone->cond != BLK_ZONE_COND_OFFLINE &&
            zone->cond != BLK_ZONE_COND_READONLY &&
                if (zone->cond != BLK_ZONE_COND_OFFLINE) {
                        zone->cond = BLK_ZONE_COND_OFFLINE;
                        data_size = zonefs_check_zone_condition(inode, zone,
-                                                               false);
+                                                               false, false);
                }
        } else if (zone->cond == BLK_ZONE_COND_READONLY ||
                   sbi->s_mount_opts & ZONEFS_MNTOPT_ERRORS_ZRO) {
                if (zone->cond != BLK_ZONE_COND_READONLY) {
                        zone->cond = BLK_ZONE_COND_READONLY;
                        data_size = zonefs_check_zone_condition(inode, zone,
-                                                               false);
+                                                               false, false);
                }
        }
 
        zi->i_zsector = zone->start;
        zi->i_max_size = min_t(loff_t, MAX_LFS_FILESIZE,
                               zone->len << SECTOR_SHIFT);
-       zi->i_wpoffset = zonefs_check_zone_condition(inode, zone, true);
+       zi->i_wpoffset = zonefs_check_zone_condition(inode, zone, true, true);
 
        inode->i_uid = sbi->s_uid;
        inode->i_gid = sbi->s_gid;