Commit 34422914 authored by Damien Le Moal's avatar Damien Le Moal

zonefs: Reduce struct zonefs_inode_info size

Instead of using the i_ztype field in struct zonefs_inode_info to
indicate the zone type of an inode, introduce the new inode flag
ZONEFS_ZONE_CNV to be set in the i_flags field of struct
zonefs_inode_info to identify conventional zones. If this flag is not
set, the zone of an inode is considered to be a sequential zone.

The helpers zonefs_zone_is_cnv(), zonefs_zone_is_seq(),
zonefs_inode_is_cnv() and zonefs_inode_is_seq() are introduced to
simplify testing the zone type of a struct zonefs_inode_info and of a
struct inode.
Signed-off-by: default avatarDamien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: default avatarJohannes Thumshirn <johannes.thumshirn@wdc.com>
parent 46a9c526
...@@ -77,8 +77,7 @@ static int zonefs_write_iomap_begin(struct inode *inode, loff_t offset, ...@@ -77,8 +77,7 @@ static int zonefs_write_iomap_begin(struct inode *inode, loff_t offset,
* checked when writes are issued, so warn if we see a page writeback * checked when writes are issued, so warn if we see a page writeback
* operation. * operation.
*/ */
if (WARN_ON_ONCE(zi->i_ztype == ZONEFS_ZTYPE_SEQ && if (WARN_ON_ONCE(zonefs_zone_is_seq(zi) && !(flags & IOMAP_DIRECT)))
!(flags & IOMAP_DIRECT)))
return -EIO; return -EIO;
/* /*
...@@ -128,7 +127,7 @@ static int zonefs_write_map_blocks(struct iomap_writepage_ctx *wpc, ...@@ -128,7 +127,7 @@ static int zonefs_write_map_blocks(struct iomap_writepage_ctx *wpc,
{ {
struct zonefs_inode_info *zi = ZONEFS_I(inode); struct zonefs_inode_info *zi = ZONEFS_I(inode);
if (WARN_ON_ONCE(zi->i_ztype != ZONEFS_ZTYPE_CNV)) if (WARN_ON_ONCE(zonefs_zone_is_seq(zi)))
return -EIO; return -EIO;
if (WARN_ON_ONCE(offset >= i_size_read(inode))) if (WARN_ON_ONCE(offset >= i_size_read(inode)))
return -EIO; return -EIO;
...@@ -158,9 +157,8 @@ static int zonefs_swap_activate(struct swap_info_struct *sis, ...@@ -158,9 +157,8 @@ static int zonefs_swap_activate(struct swap_info_struct *sis,
struct file *swap_file, sector_t *span) struct file *swap_file, sector_t *span)
{ {
struct inode *inode = file_inode(swap_file); struct inode *inode = file_inode(swap_file);
struct zonefs_inode_info *zi = ZONEFS_I(inode);
if (zi->i_ztype != ZONEFS_ZTYPE_CNV) { if (zonefs_inode_is_seq(inode)) {
zonefs_err(inode->i_sb, zonefs_err(inode->i_sb,
"swap file: not a conventional zone file\n"); "swap file: not a conventional zone file\n");
return -EINVAL; return -EINVAL;
...@@ -196,7 +194,7 @@ int zonefs_file_truncate(struct inode *inode, loff_t isize) ...@@ -196,7 +194,7 @@ int zonefs_file_truncate(struct inode *inode, loff_t isize)
* only down to a 0 size, which is equivalent to a zone reset, and to * only down to a 0 size, which is equivalent to a zone reset, and to
* the maximum file size, which is equivalent to a zone finish. * the maximum file size, which is equivalent to a zone finish.
*/ */
if (zi->i_ztype != ZONEFS_ZTYPE_SEQ) if (!zonefs_zone_is_seq(zi))
return -EPERM; return -EPERM;
if (!isize) if (!isize)
...@@ -266,7 +264,7 @@ static int zonefs_file_fsync(struct file *file, loff_t start, loff_t end, ...@@ -266,7 +264,7 @@ static int zonefs_file_fsync(struct file *file, loff_t start, loff_t end,
* Since only direct writes are allowed in sequential files, page cache * Since only direct writes are allowed in sequential files, page cache
* flush is needed only for conventional zone files. * flush is needed only for conventional zone files.
*/ */
if (ZONEFS_I(inode)->i_ztype == ZONEFS_ZTYPE_CNV) if (zonefs_inode_is_cnv(inode))
ret = file_write_and_wait_range(file, start, end); ret = file_write_and_wait_range(file, start, end);
if (!ret) if (!ret)
ret = blkdev_issue_flush(inode->i_sb->s_bdev); ret = blkdev_issue_flush(inode->i_sb->s_bdev);
...@@ -280,7 +278,6 @@ static int zonefs_file_fsync(struct file *file, loff_t start, loff_t end, ...@@ -280,7 +278,6 @@ static int zonefs_file_fsync(struct file *file, loff_t start, loff_t end,
static vm_fault_t zonefs_filemap_page_mkwrite(struct vm_fault *vmf) static vm_fault_t zonefs_filemap_page_mkwrite(struct vm_fault *vmf)
{ {
struct inode *inode = file_inode(vmf->vma->vm_file); struct inode *inode = file_inode(vmf->vma->vm_file);
struct zonefs_inode_info *zi = ZONEFS_I(inode);
vm_fault_t ret; vm_fault_t ret;
if (unlikely(IS_IMMUTABLE(inode))) if (unlikely(IS_IMMUTABLE(inode)))
...@@ -290,7 +287,7 @@ static vm_fault_t zonefs_filemap_page_mkwrite(struct vm_fault *vmf) ...@@ -290,7 +287,7 @@ static vm_fault_t zonefs_filemap_page_mkwrite(struct vm_fault *vmf)
* Sanity check: only conventional zone files can have shared * Sanity check: only conventional zone files can have shared
* writeable mappings. * writeable mappings.
*/ */
if (WARN_ON_ONCE(zi->i_ztype != ZONEFS_ZTYPE_CNV)) if (zonefs_inode_is_seq(inode))
return VM_FAULT_NOPAGE; return VM_FAULT_NOPAGE;
sb_start_pagefault(inode->i_sb); sb_start_pagefault(inode->i_sb);
...@@ -319,7 +316,7 @@ static int zonefs_file_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -319,7 +316,7 @@ static int zonefs_file_mmap(struct file *file, struct vm_area_struct *vma)
* mappings are possible since there are no guarantees for write * mappings are possible since there are no guarantees for write
* ordering between msync() and page cache writeback. * ordering between msync() and page cache writeback.
*/ */
if (ZONEFS_I(file_inode(file))->i_ztype == ZONEFS_ZTYPE_SEQ && if (zonefs_inode_is_seq(file_inode(file)) &&
(vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE)) (vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE))
return -EINVAL; return -EINVAL;
...@@ -352,7 +349,7 @@ static int zonefs_file_write_dio_end_io(struct kiocb *iocb, ssize_t size, ...@@ -352,7 +349,7 @@ static int zonefs_file_write_dio_end_io(struct kiocb *iocb, ssize_t size,
return error; return error;
} }
if (size && zi->i_ztype != ZONEFS_ZTYPE_CNV) { if (size && zonefs_zone_is_seq(zi)) {
/* /*
* Note that we may be seeing completions out of order, * Note that we may be seeing completions out of order,
* but that is not a problem since a write completed * but that is not a problem since a write completed
...@@ -491,7 +488,7 @@ static ssize_t zonefs_write_checks(struct kiocb *iocb, struct iov_iter *from) ...@@ -491,7 +488,7 @@ static ssize_t zonefs_write_checks(struct kiocb *iocb, struct iov_iter *from)
return -EINVAL; return -EINVAL;
if (iocb->ki_flags & IOCB_APPEND) { if (iocb->ki_flags & IOCB_APPEND) {
if (zi->i_ztype != ZONEFS_ZTYPE_SEQ) if (zonefs_zone_is_cnv(zi))
return -EINVAL; return -EINVAL;
mutex_lock(&zi->i_truncate_mutex); mutex_lock(&zi->i_truncate_mutex);
iocb->ki_pos = zi->i_wpoffset; iocb->ki_pos = zi->i_wpoffset;
...@@ -531,8 +528,7 @@ static ssize_t zonefs_file_dio_write(struct kiocb *iocb, struct iov_iter *from) ...@@ -531,8 +528,7 @@ static ssize_t zonefs_file_dio_write(struct kiocb *iocb, struct iov_iter *from)
* as this can cause write reordering (e.g. the first aio gets EAGAIN * as this can cause write reordering (e.g. the first aio gets EAGAIN
* on the inode lock but the second goes through but is now unaligned). * on the inode lock but the second goes through but is now unaligned).
*/ */
if (zi->i_ztype == ZONEFS_ZTYPE_SEQ && !sync && if (zonefs_zone_is_seq(zi) && !sync && (iocb->ki_flags & IOCB_NOWAIT))
(iocb->ki_flags & IOCB_NOWAIT))
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (iocb->ki_flags & IOCB_NOWAIT) { if (iocb->ki_flags & IOCB_NOWAIT) {
...@@ -554,7 +550,7 @@ static ssize_t zonefs_file_dio_write(struct kiocb *iocb, struct iov_iter *from) ...@@ -554,7 +550,7 @@ static ssize_t zonefs_file_dio_write(struct kiocb *iocb, struct iov_iter *from)
} }
/* Enforce sequential writes (append only) in sequential zones */ /* Enforce sequential writes (append only) in sequential zones */
if (zi->i_ztype == ZONEFS_ZTYPE_SEQ) { if (zonefs_zone_is_seq(zi)) {
mutex_lock(&zi->i_truncate_mutex); mutex_lock(&zi->i_truncate_mutex);
if (iocb->ki_pos != zi->i_wpoffset) { if (iocb->ki_pos != zi->i_wpoffset) {
mutex_unlock(&zi->i_truncate_mutex); mutex_unlock(&zi->i_truncate_mutex);
...@@ -570,7 +566,7 @@ static ssize_t zonefs_file_dio_write(struct kiocb *iocb, struct iov_iter *from) ...@@ -570,7 +566,7 @@ static ssize_t zonefs_file_dio_write(struct kiocb *iocb, struct iov_iter *from)
else else
ret = iomap_dio_rw(iocb, from, &zonefs_write_iomap_ops, ret = iomap_dio_rw(iocb, from, &zonefs_write_iomap_ops,
&zonefs_write_dio_ops, 0, NULL, 0); &zonefs_write_dio_ops, 0, NULL, 0);
if (zi->i_ztype == ZONEFS_ZTYPE_SEQ && if (zonefs_zone_is_seq(zi) &&
(ret > 0 || ret == -EIOCBQUEUED)) { (ret > 0 || ret == -EIOCBQUEUED)) {
if (ret > 0) if (ret > 0)
count = ret; count = ret;
...@@ -596,14 +592,13 @@ static ssize_t zonefs_file_buffered_write(struct kiocb *iocb, ...@@ -596,14 +592,13 @@ static ssize_t zonefs_file_buffered_write(struct kiocb *iocb,
struct iov_iter *from) struct iov_iter *from)
{ {
struct inode *inode = file_inode(iocb->ki_filp); struct inode *inode = file_inode(iocb->ki_filp);
struct zonefs_inode_info *zi = ZONEFS_I(inode);
ssize_t ret; ssize_t ret;
/* /*
* Direct IO writes are mandatory for sequential zone files so that the * Direct IO writes are mandatory for sequential zone files so that the
* write IO issuing order is preserved. * write IO issuing order is preserved.
*/ */
if (zi->i_ztype != ZONEFS_ZTYPE_CNV) if (zonefs_inode_is_seq(inode))
return -EIO; return -EIO;
if (iocb->ki_flags & IOCB_NOWAIT) { if (iocb->ki_flags & IOCB_NOWAIT) {
...@@ -731,9 +726,7 @@ static ssize_t zonefs_file_read_iter(struct kiocb *iocb, struct iov_iter *to) ...@@ -731,9 +726,7 @@ static ssize_t zonefs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
static inline bool zonefs_seq_file_need_wro(struct inode *inode, static inline bool zonefs_seq_file_need_wro(struct inode *inode,
struct file *file) struct file *file)
{ {
struct zonefs_inode_info *zi = ZONEFS_I(inode); if (zonefs_inode_is_cnv(inode))
if (zi->i_ztype != ZONEFS_ZTYPE_SEQ)
return false; return false;
if (!(file->f_mode & FMODE_WRITE)) if (!(file->f_mode & FMODE_WRITE))
......
...@@ -37,7 +37,7 @@ void zonefs_account_active(struct inode *inode) ...@@ -37,7 +37,7 @@ void zonefs_account_active(struct inode *inode)
lockdep_assert_held(&zi->i_truncate_mutex); lockdep_assert_held(&zi->i_truncate_mutex);
if (zi->i_ztype != ZONEFS_ZTYPE_SEQ) if (zonefs_zone_is_cnv(zi))
return; return;
/* /*
...@@ -177,14 +177,14 @@ static loff_t zonefs_check_zone_condition(struct inode *inode, ...@@ -177,14 +177,14 @@ static loff_t zonefs_check_zone_condition(struct inode *inode,
zonefs_warn(inode->i_sb, "inode %lu: read-only zone\n", zonefs_warn(inode->i_sb, "inode %lu: read-only zone\n",
inode->i_ino); inode->i_ino);
zi->i_flags |= ZONEFS_ZONE_READONLY; zi->i_flags |= ZONEFS_ZONE_READONLY;
if (zi->i_ztype == ZONEFS_ZTYPE_CNV) if (zonefs_zone_is_cnv(zi))
return zi->i_max_size; return zi->i_max_size;
return zi->i_wpoffset; return zi->i_wpoffset;
case BLK_ZONE_COND_FULL: case BLK_ZONE_COND_FULL:
/* The write pointer of full zones is invalid. */ /* The write pointer of full zones is invalid. */
return zi->i_max_size; return zi->i_max_size;
default: default:
if (zi->i_ztype == ZONEFS_ZTYPE_CNV) if (zonefs_zone_is_cnv(zi))
return zi->i_max_size; return zi->i_max_size;
return (zone->wp - zone->start) << SECTOR_SHIFT; return (zone->wp - zone->start) << SECTOR_SHIFT;
} }
...@@ -260,7 +260,7 @@ static int zonefs_io_error_cb(struct blk_zone *zone, unsigned int idx, ...@@ -260,7 +260,7 @@ static int zonefs_io_error_cb(struct blk_zone *zone, unsigned int idx,
* In all cases, warn about inode size inconsistency and handle the * In all cases, warn about inode size inconsistency and handle the
* IO error according to the zone condition and to the mount options. * IO error according to the zone condition and to the mount options.
*/ */
if (zi->i_ztype == ZONEFS_ZTYPE_SEQ && isize != data_size) if (zonefs_zone_is_seq(zi) && isize != data_size)
zonefs_warn(sb, "inode %lu: invalid size %lld (should be %lld)\n", zonefs_warn(sb, "inode %lu: invalid size %lld (should be %lld)\n",
inode->i_ino, isize, data_size); inode->i_ino, isize, data_size);
...@@ -584,7 +584,9 @@ static int zonefs_init_file_inode(struct inode *inode, struct blk_zone *zone, ...@@ -584,7 +584,9 @@ static int zonefs_init_file_inode(struct inode *inode, struct blk_zone *zone,
inode->i_ino = zone->start >> sbi->s_zone_sectors_shift; inode->i_ino = zone->start >> sbi->s_zone_sectors_shift;
inode->i_mode = S_IFREG | sbi->s_perm; inode->i_mode = S_IFREG | sbi->s_perm;
zi->i_ztype = type; if (type == ZONEFS_ZTYPE_CNV)
zi->i_flags |= ZONEFS_ZONE_CNV;
zi->i_zsector = zone->start; zi->i_zsector = zone->start;
zi->i_zone_size = zone->len << SECTOR_SHIFT; zi->i_zone_size = zone->len << SECTOR_SHIFT;
if (zi->i_zone_size > bdev_zone_sectors(sb->s_bdev) << SECTOR_SHIFT && if (zi->i_zone_size > bdev_zone_sectors(sb->s_bdev) << SECTOR_SHIFT &&
......
...@@ -44,6 +44,7 @@ static inline enum zonefs_ztype zonefs_zone_type(struct blk_zone *zone) ...@@ -44,6 +44,7 @@ static inline enum zonefs_ztype zonefs_zone_type(struct blk_zone *zone)
#define ZONEFS_ZONE_ACTIVE (1U << 2) #define ZONEFS_ZONE_ACTIVE (1U << 2)
#define ZONEFS_ZONE_OFFLINE (1U << 3) #define ZONEFS_ZONE_OFFLINE (1U << 3)
#define ZONEFS_ZONE_READONLY (1U << 4) #define ZONEFS_ZONE_READONLY (1U << 4)
#define ZONEFS_ZONE_CNV (1U << 31)
/* /*
* In-memory inode data. * In-memory inode data.
...@@ -51,9 +52,6 @@ static inline enum zonefs_ztype zonefs_zone_type(struct blk_zone *zone) ...@@ -51,9 +52,6 @@ static inline enum zonefs_ztype zonefs_zone_type(struct blk_zone *zone)
struct zonefs_inode_info { struct zonefs_inode_info {
struct inode i_vnode; struct inode i_vnode;
/* File zone type */
enum zonefs_ztype i_ztype;
/* File zone start sector (512B unit) */ /* File zone start sector (512B unit) */
sector_t i_zsector; sector_t i_zsector;
...@@ -91,6 +89,26 @@ static inline struct zonefs_inode_info *ZONEFS_I(struct inode *inode) ...@@ -91,6 +89,26 @@ static inline struct zonefs_inode_info *ZONEFS_I(struct inode *inode)
return container_of(inode, struct zonefs_inode_info, i_vnode); return container_of(inode, struct zonefs_inode_info, i_vnode);
} }
static inline bool zonefs_zone_is_cnv(struct zonefs_inode_info *zi)
{
return zi->i_flags & ZONEFS_ZONE_CNV;
}
static inline bool zonefs_zone_is_seq(struct zonefs_inode_info *zi)
{
return !zonefs_zone_is_cnv(zi);
}
static inline bool zonefs_inode_is_cnv(struct inode *inode)
{
return zonefs_zone_is_cnv(ZONEFS_I(inode));
}
static inline bool zonefs_inode_is_seq(struct inode *inode)
{
return zonefs_zone_is_seq(ZONEFS_I(inode));
}
/* /*
* On-disk super block (block 0). * On-disk super block (block 0).
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment