summaryrefslogtreecommitdiffstats
path: root/fs/zonefs
diff options
context:
space:
mode:
authorJohannes Thumshirn <johannes.thumshirn@wdc.com>2020-07-21 21:10:26 +0900
committerDamien Le Moal <damien.lemoal@wdc.com>2020-08-11 17:42:24 +0900
commite3c3155bc95ab6a7b21ac40418bf80bedb204949 (patch)
tree6ff49ead35604c82a93c6f70210d3990f357da5d /fs/zonefs
parent00e4db51259a5f936fec1424b884f029479d3981 (diff)
downloadlinux-e3c3155bc95ab6a7b21ac40418bf80bedb204949.tar.bz2
zonefs: add zone-capacity support
In the zoned storage model, the sectors within a zone are typically all writeable. With the introduction of the Zoned Namespace (ZNS) Command Set in the NVM Express organization, the model was extended to have a specific writeable capacity. This zone capacity can be less than the overall zone size for a NVMe ZNS device or null_blk in zoned-mode. For other ZBC/ZAC devices the zone capacity is always equal to the zone size. Use the zone capacity field instead from blk_zone for determining the maximum inode size and inode blocks in zonefs. Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
Diffstat (limited to 'fs/zonefs')
-rw-r--r--fs/zonefs/super.c16
-rw-r--r--fs/zonefs/zonefs.h3
2 files changed, 15 insertions, 4 deletions
diff --git a/fs/zonefs/super.c b/fs/zonefs/super.c
index 4a0bff65d3d6..8ec7c8f109d7 100644
--- a/fs/zonefs/super.c
+++ b/fs/zonefs/super.c
@@ -335,7 +335,7 @@ static void zonefs_io_error(struct inode *inode, bool write)
struct zonefs_sb_info *sbi = ZONEFS_SB(sb);
unsigned int noio_flag;
unsigned int nr_zones =
- zi->i_max_size >> (sbi->s_zone_sectors_shift + SECTOR_SHIFT);
+ zi->i_zone_size >> (sbi->s_zone_sectors_shift + SECTOR_SHIFT);
struct zonefs_ioerr_data err = {
.inode = inode,
.write = write,
@@ -398,7 +398,7 @@ static int zonefs_file_truncate(struct inode *inode, loff_t isize)
goto unlock;
ret = blkdev_zone_mgmt(inode->i_sb->s_bdev, op, zi->i_zsector,
- zi->i_max_size >> SECTOR_SHIFT, GFP_NOFS);
+ zi->i_zone_size >> SECTOR_SHIFT, GFP_NOFS);
if (ret) {
zonefs_err(inode->i_sb,
"Zone management operation at %llu failed %d",
@@ -1053,14 +1053,16 @@ static void zonefs_init_file_inode(struct inode *inode, struct blk_zone *zone,
zi->i_ztype = type;
zi->i_zsector = zone->start;
+ zi->i_zone_size = zone->len << SECTOR_SHIFT;
+
zi->i_max_size = min_t(loff_t, MAX_LFS_FILESIZE,
- zone->len << SECTOR_SHIFT);
+ zone->capacity << SECTOR_SHIFT);
zi->i_wpoffset = zonefs_check_zone_condition(inode, zone, true, true);
inode->i_uid = sbi->s_uid;
inode->i_gid = sbi->s_gid;
inode->i_size = zi->i_wpoffset;
- inode->i_blocks = zone->len;
+ inode->i_blocks = zi->i_max_size >> SECTOR_SHIFT;
inode->i_op = &zonefs_file_inode_operations;
inode->i_fop = &zonefs_file_operations;
@@ -1167,12 +1169,18 @@ static int zonefs_create_zgroup(struct zonefs_zone_data *zd,
if (zonefs_zone_type(next) != type)
break;
zone->len += next->len;
+ zone->capacity += next->capacity;
if (next->cond == BLK_ZONE_COND_READONLY &&
zone->cond != BLK_ZONE_COND_OFFLINE)
zone->cond = BLK_ZONE_COND_READONLY;
else if (next->cond == BLK_ZONE_COND_OFFLINE)
zone->cond = BLK_ZONE_COND_OFFLINE;
}
+ if (zone->capacity != zone->len) {
+ zonefs_err(sb, "Invalid conventional zone capacity\n");
+ ret = -EINVAL;
+ goto free;
+ }
}
/*
diff --git a/fs/zonefs/zonefs.h b/fs/zonefs/zonefs.h
index ad17fef7ce91..55b39970acb2 100644
--- a/fs/zonefs/zonefs.h
+++ b/fs/zonefs/zonefs.h
@@ -56,6 +56,9 @@ struct zonefs_inode_info {
/* File maximum size */
loff_t i_max_size;
+ /* File zone size */
+ loff_t i_zone_size;
+
/*
* To serialise fully against both syscall and mmap based IO and
* sequential file truncation, two locks are used. For serializing