Skip to content

Commit e2cf67f

Browse files
committed
Merge tag 'zonefs-5.6-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/zonefs
Pull zonefs fix from Damien Le Moal: "A single fix from me to correctly handle the size of read-only zone files" * tag 'zonefs-5.6-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/zonefs: zonfs: Fix handling of read-only zones
2 parents 76ccd23 + ccf4ad7 commit e2cf67f

File tree

2 files changed

+34
-12
lines changed

2 files changed

+34
-12
lines changed

Documentation/filesystems/zonefs.txt

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -258,19 +258,19 @@ conditions.
258258
| option | condition | size read write read write |
259259
+--------------+-----------+-----------------------------------------+
260260
| | good | fixed yes no yes yes |
261-
| remount-ro | read-only | fixed yes no yes no |
261+
| remount-ro | read-only | as is yes no yes no |
262262
| (default) | offline | 0 no no no no |
263263
+--------------+-----------+-----------------------------------------+
264264
| | good | fixed yes no yes yes |
265-
| zone-ro | read-only | fixed yes no yes no |
265+
| zone-ro | read-only | as is yes no yes no |
266266
| | offline | 0 no no no no |
267267
+--------------+-----------+-----------------------------------------+
268268
| | good | 0 no no yes yes |
269269
| zone-offline | read-only | 0 no no yes no |
270270
| | offline | 0 no no no no |
271271
+--------------+-----------+-----------------------------------------+
272272
| | good | fixed yes yes yes yes |
273-
| repair | read-only | fixed yes no yes no |
273+
| repair | read-only | as is yes no yes no |
274274
| | offline | 0 no no no no |
275275
+--------------+-----------+-----------------------------------------+
276276

@@ -307,8 +307,16 @@ condition changes. The defined behaviors are as follow:
307307
* zone-offline
308308
* repair
309309

310-
The I/O error actions defined for each behavior are detailed in the previous
311-
section.
310+
The run-time I/O error actions defined for each behavior are detailed in the
311+
previous section. Mount time I/O errors will cause the mount operation to fail.
312+
The handling of read-only zones also differs between mount-time and run-time.
313+
If a read-only zone is found at mount time, the zone is always treated in the
314+
same manner as offline zones, that is, all accesses are disabled and the zone
315+
file size set to 0. This is necessary as the write pointer of read-only zones
316+
is defined as invalib by the ZBC and ZAC standards, making it impossible to
317+
discover the amount of data that has been written to the zone. In the case of a
318+
read-only zone discovered at run-time, as indicated in the previous section.
319+
the size of the zone file is left unchanged from its last updated value.
312320

313321
Zonefs User Space Tools
314322
=======================

fs/zonefs/super.c

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,8 @@ static void zonefs_update_stats(struct inode *inode, loff_t new_isize)
178178
* amount of readable data in the zone.
179179
*/
180180
static loff_t zonefs_check_zone_condition(struct inode *inode,
181-
struct blk_zone *zone, bool warn)
181+
struct blk_zone *zone, bool warn,
182+
bool mount)
182183
{
183184
struct zonefs_inode_info *zi = ZONEFS_I(inode);
184185

@@ -196,13 +197,26 @@ static loff_t zonefs_check_zone_condition(struct inode *inode,
196197
zone->wp = zone->start;
197198
return 0;
198199
case BLK_ZONE_COND_READONLY:
199-
/* Do not allow writes in read-only zones */
200+
/*
201+
* The write pointer of read-only zones is invalid. If such a
202+
* zone is found during mount, the file size cannot be retrieved
203+
* so we treat the zone as offline (mount == true case).
204+
* Otherwise, keep the file size as it was when last updated
205+
* so that the user can recover data. In both cases, writes are
206+
* always disabled for the zone.
207+
*/
200208
if (warn)
201209
zonefs_warn(inode->i_sb, "inode %lu: read-only zone\n",
202210
inode->i_ino);
203211
inode->i_flags |= S_IMMUTABLE;
212+
if (mount) {
213+
zone->cond = BLK_ZONE_COND_OFFLINE;
214+
inode->i_mode &= ~0777;
215+
zone->wp = zone->start;
216+
return 0;
217+
}
204218
inode->i_mode &= ~0222;
205-
/* fallthrough */
219+
return i_size_read(inode);
206220
default:
207221
if (zi->i_ztype == ZONEFS_ZTYPE_CNV)
208222
return zi->i_max_size;
@@ -231,7 +245,7 @@ static int zonefs_io_error_cb(struct blk_zone *zone, unsigned int idx,
231245
* as there is no inconsistency between the inode size and the amount of
232246
* data writen in the zone (data_size).
233247
*/
234-
data_size = zonefs_check_zone_condition(inode, zone, true);
248+
data_size = zonefs_check_zone_condition(inode, zone, true, false);
235249
isize = i_size_read(inode);
236250
if (zone->cond != BLK_ZONE_COND_OFFLINE &&
237251
zone->cond != BLK_ZONE_COND_READONLY &&
@@ -274,7 +288,7 @@ static int zonefs_io_error_cb(struct blk_zone *zone, unsigned int idx,
274288
if (zone->cond != BLK_ZONE_COND_OFFLINE) {
275289
zone->cond = BLK_ZONE_COND_OFFLINE;
276290
data_size = zonefs_check_zone_condition(inode, zone,
277-
false);
291+
false, false);
278292
}
279293
} else if (zone->cond == BLK_ZONE_COND_READONLY ||
280294
sbi->s_mount_opts & ZONEFS_MNTOPT_ERRORS_ZRO) {
@@ -283,7 +297,7 @@ static int zonefs_io_error_cb(struct blk_zone *zone, unsigned int idx,
283297
if (zone->cond != BLK_ZONE_COND_READONLY) {
284298
zone->cond = BLK_ZONE_COND_READONLY;
285299
data_size = zonefs_check_zone_condition(inode, zone,
286-
false);
300+
false, false);
287301
}
288302
}
289303

@@ -975,7 +989,7 @@ static void zonefs_init_file_inode(struct inode *inode, struct blk_zone *zone,
975989
zi->i_zsector = zone->start;
976990
zi->i_max_size = min_t(loff_t, MAX_LFS_FILESIZE,
977991
zone->len << SECTOR_SHIFT);
978-
zi->i_wpoffset = zonefs_check_zone_condition(inode, zone, true);
992+
zi->i_wpoffset = zonefs_check_zone_condition(inode, zone, true, true);
979993

980994
inode->i_uid = sbi->s_uid;
981995
inode->i_gid = sbi->s_gid;

0 commit comments

Comments
 (0)