diff options
Diffstat (limited to 'fs/zonefs/super.c')
-rw-r--r-- | fs/zonefs/super.c | 41 |
1 files changed, 28 insertions, 13 deletions
diff --git a/fs/zonefs/super.c b/fs/zonefs/super.c index 07bc42d62673..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", @@ -607,14 +607,14 @@ static ssize_t zonefs_file_dio_append(struct kiocb *iocb, struct iov_iter *from) int nr_pages; ssize_t ret; - nr_pages = iov_iter_npages(from, BIO_MAX_PAGES); - if (!nr_pages) - return 0; - max = queue_max_zone_append_sectors(bdev_get_queue(bdev)); max = ALIGN_DOWN(max << SECTOR_SHIFT, inode->i_sb->s_blocksize); iov_iter_truncate(from, max); + nr_pages = iov_iter_npages(from, BIO_MAX_PAGES); + if (!nr_pages) + return 0; + bio = bio_alloc_bioset(GFP_NOFS, nr_pages, &fs_bio_set); if (!bio) return -ENOMEM; @@ -786,8 +786,11 @@ static ssize_t zonefs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) if (iocb->ki_pos >= ZONEFS_I(inode)->i_max_size) return -EFBIG; - if (iocb->ki_flags & IOCB_DIRECT) - return zonefs_file_dio_write(iocb, from); + if (iocb->ki_flags & IOCB_DIRECT) { + ssize_t ret = zonefs_file_dio_write(iocb, from); + if (ret != -ENOTBLK) + return ret; + } return zonefs_file_buffered_write(iocb, from); } @@ -1050,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; @@ -1119,7 +1124,7 @@ static int zonefs_create_zgroup(struct zonefs_zone_data *zd, char *file_name; struct dentry *dir; unsigned int n = 0; - int ret = -ENOMEM; + int ret; /* If the group is empty, there is nothing to do */ if (!zd->nr_zones[type]) @@ -1135,8 +1140,10 @@ static int zonefs_create_zgroup(struct zonefs_zone_data *zd, zgroup_name = "seq"; dir = zonefs_create_inode(sb->s_root, zgroup_name, NULL, type); - if (!dir) + if (!dir) { + ret = -ENOMEM; goto free; + } /* * The first zone contains the super block: skip it. @@ -1162,20 +1169,28 @@ 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; + } } /* * Use the file number within its group as file name. */ snprintf(file_name, ZONEFS_NAME_MAX - 1, "%u", n); - if (!zonefs_create_inode(dir, file_name, zone, type)) + if (!zonefs_create_inode(dir, file_name, zone, type)) { + ret = -ENOMEM; goto free; + } n++; } |