public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	patches@lists.linux.dev,
	Damien Le Moal <damien.lemoal@opensource.wdc.com>,
	Johannes Thumshirn <johannes.thumshirn@wdc.com>,
	Sasha Levin <sashal@kernel.org>
Subject: [PATCH 6.1 005/181] zonefs: Reorganize code
Date: Mon,  3 Apr 2023 16:07:20 +0200	[thread overview]
Message-ID: <20230403140415.274475813@linuxfoundation.org> (raw)
In-Reply-To: <20230403140415.090615502@linuxfoundation.org>

From: Damien Le Moal <damien.lemoal@opensource.wdc.com>

[ Upstream commit 4008e2a0b01aba982356fd15b128a47bf11bd9c7 ]

Move all code related to zone file operations from super.c to the new
file.c file. Inode and zone management code remains in super.c.

Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Stable-dep-of: 88b170088ad2 ("zonefs: Fix error message in zonefs_file_dio_append()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 fs/zonefs/Makefile |   2 +-
 fs/zonefs/file.c   | 874 ++++++++++++++++++++++++++++++++++++++++
 fs/zonefs/super.c  | 973 +++------------------------------------------
 fs/zonefs/zonefs.h |  22 +
 4 files changed, 955 insertions(+), 916 deletions(-)
 create mode 100644 fs/zonefs/file.c

diff --git a/fs/zonefs/Makefile b/fs/zonefs/Makefile
index 9fe54f5319f22..645f7229de4a0 100644
--- a/fs/zonefs/Makefile
+++ b/fs/zonefs/Makefile
@@ -3,4 +3,4 @@ ccflags-y				+= -I$(src)
 
 obj-$(CONFIG_ZONEFS_FS) += zonefs.o
 
-zonefs-y	:= super.o sysfs.o
+zonefs-y	:= super.o file.o sysfs.o
diff --git a/fs/zonefs/file.c b/fs/zonefs/file.c
new file mode 100644
index 0000000000000..ece0f3959b6d1
--- /dev/null
+++ b/fs/zonefs/file.c
@@ -0,0 +1,874 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Simple file system for zoned block devices exposing zones as files.
+ *
+ * Copyright (C) 2022 Western Digital Corporation or its affiliates.
+ */
+#include <linux/module.h>
+#include <linux/pagemap.h>
+#include <linux/iomap.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/blkdev.h>
+#include <linux/statfs.h>
+#include <linux/writeback.h>
+#include <linux/quotaops.h>
+#include <linux/seq_file.h>
+#include <linux/parser.h>
+#include <linux/uio.h>
+#include <linux/mman.h>
+#include <linux/sched/mm.h>
+#include <linux/task_io_accounting_ops.h>
+
+#include "zonefs.h"
+
+#include "trace.h"
+
+static int zonefs_read_iomap_begin(struct inode *inode, loff_t offset,
+				   loff_t length, unsigned int flags,
+				   struct iomap *iomap, struct iomap *srcmap)
+{
+	struct zonefs_inode_info *zi = ZONEFS_I(inode);
+	struct super_block *sb = inode->i_sb;
+	loff_t isize;
+
+	/*
+	 * All blocks are always mapped below EOF. If reading past EOF,
+	 * act as if there is a hole up to the file maximum size.
+	 */
+	mutex_lock(&zi->i_truncate_mutex);
+	iomap->bdev = inode->i_sb->s_bdev;
+	iomap->offset = ALIGN_DOWN(offset, sb->s_blocksize);
+	isize = i_size_read(inode);
+	if (iomap->offset >= isize) {
+		iomap->type = IOMAP_HOLE;
+		iomap->addr = IOMAP_NULL_ADDR;
+		iomap->length = length;
+	} else {
+		iomap->type = IOMAP_MAPPED;
+		iomap->addr = (zi->i_zsector << SECTOR_SHIFT) + iomap->offset;
+		iomap->length = isize - iomap->offset;
+	}
+	mutex_unlock(&zi->i_truncate_mutex);
+
+	trace_zonefs_iomap_begin(inode, iomap);
+
+	return 0;
+}
+
+static const struct iomap_ops zonefs_read_iomap_ops = {
+	.iomap_begin	= zonefs_read_iomap_begin,
+};
+
+static int zonefs_write_iomap_begin(struct inode *inode, loff_t offset,
+				    loff_t length, unsigned int flags,
+				    struct iomap *iomap, struct iomap *srcmap)
+{
+	struct zonefs_inode_info *zi = ZONEFS_I(inode);
+	struct super_block *sb = inode->i_sb;
+	loff_t isize;
+
+	/* All write I/Os should always be within the file maximum size */
+	if (WARN_ON_ONCE(offset + length > zi->i_max_size))
+		return -EIO;
+
+	/*
+	 * Sequential zones can only accept direct writes. This is already
+	 * checked when writes are issued, so warn if we see a page writeback
+	 * operation.
+	 */
+	if (WARN_ON_ONCE(zi->i_ztype == ZONEFS_ZTYPE_SEQ &&
+			 !(flags & IOMAP_DIRECT)))
+		return -EIO;
+
+	/*
+	 * For conventional zones, all blocks are always mapped. For sequential
+	 * zones, all blocks after always mapped below the inode size (zone
+	 * write pointer) and unwriten beyond.
+	 */
+	mutex_lock(&zi->i_truncate_mutex);
+	iomap->bdev = inode->i_sb->s_bdev;
+	iomap->offset = ALIGN_DOWN(offset, sb->s_blocksize);
+	iomap->addr = (zi->i_zsector << SECTOR_SHIFT) + iomap->offset;
+	isize = i_size_read(inode);
+	if (iomap->offset >= isize) {
+		iomap->type = IOMAP_UNWRITTEN;
+		iomap->length = zi->i_max_size - iomap->offset;
+	} else {
+		iomap->type = IOMAP_MAPPED;
+		iomap->length = isize - iomap->offset;
+	}
+	mutex_unlock(&zi->i_truncate_mutex);
+
+	trace_zonefs_iomap_begin(inode, iomap);
+
+	return 0;
+}
+
+static const struct iomap_ops zonefs_write_iomap_ops = {
+	.iomap_begin	= zonefs_write_iomap_begin,
+};
+
+static int zonefs_read_folio(struct file *unused, struct folio *folio)
+{
+	return iomap_read_folio(folio, &zonefs_read_iomap_ops);
+}
+
+static void zonefs_readahead(struct readahead_control *rac)
+{
+	iomap_readahead(rac, &zonefs_read_iomap_ops);
+}
+
+/*
+ * Map blocks for page writeback. This is used only on conventional zone files,
+ * which implies that the page range can only be within the fixed inode size.
+ */
+static int zonefs_write_map_blocks(struct iomap_writepage_ctx *wpc,
+				   struct inode *inode, loff_t offset)
+{
+	struct zonefs_inode_info *zi = ZONEFS_I(inode);
+
+	if (WARN_ON_ONCE(zi->i_ztype != ZONEFS_ZTYPE_CNV))
+		return -EIO;
+	if (WARN_ON_ONCE(offset >= i_size_read(inode)))
+		return -EIO;
+
+	/* If the mapping is already OK, nothing needs to be done */
+	if (offset >= wpc->iomap.offset &&
+	    offset < wpc->iomap.offset + wpc->iomap.length)
+		return 0;
+
+	return zonefs_write_iomap_begin(inode, offset, zi->i_max_size - offset,
+					IOMAP_WRITE, &wpc->iomap, NULL);
+}
+
+static const struct iomap_writeback_ops zonefs_writeback_ops = {
+	.map_blocks		= zonefs_write_map_blocks,
+};
+
+static int zonefs_writepages(struct address_space *mapping,
+			     struct writeback_control *wbc)
+{
+	struct iomap_writepage_ctx wpc = { };
+
+	return iomap_writepages(mapping, wbc, &wpc, &zonefs_writeback_ops);
+}
+
+static int zonefs_swap_activate(struct swap_info_struct *sis,
+				struct file *swap_file, sector_t *span)
+{
+	struct inode *inode = file_inode(swap_file);
+	struct zonefs_inode_info *zi = ZONEFS_I(inode);
+
+	if (zi->i_ztype != ZONEFS_ZTYPE_CNV) {
+		zonefs_err(inode->i_sb,
+			   "swap file: not a conventional zone file\n");
+		return -EINVAL;
+	}
+
+	return iomap_swapfile_activate(sis, swap_file, span,
+				       &zonefs_read_iomap_ops);
+}
+
+const struct address_space_operations zonefs_file_aops = {
+	.read_folio		= zonefs_read_folio,
+	.readahead		= zonefs_readahead,
+	.writepages		= zonefs_writepages,
+	.dirty_folio		= filemap_dirty_folio,
+	.release_folio		= iomap_release_folio,
+	.invalidate_folio	= iomap_invalidate_folio,
+	.migrate_folio		= filemap_migrate_folio,
+	.is_partially_uptodate	= iomap_is_partially_uptodate,
+	.error_remove_page	= generic_error_remove_page,
+	.direct_IO		= noop_direct_IO,
+	.swap_activate		= zonefs_swap_activate,
+};
+
+int zonefs_file_truncate(struct inode *inode, loff_t isize)
+{
+	struct zonefs_inode_info *zi = ZONEFS_I(inode);
+	loff_t old_isize;
+	enum req_op op;
+	int ret = 0;
+
+	/*
+	 * Only sequential zone files can be truncated and truncation is allowed
+	 * 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.
+	 */
+	if (zi->i_ztype != ZONEFS_ZTYPE_SEQ)
+		return -EPERM;
+
+	if (!isize)
+		op = REQ_OP_ZONE_RESET;
+	else if (isize == zi->i_max_size)
+		op = REQ_OP_ZONE_FINISH;
+	else
+		return -EPERM;
+
+	inode_dio_wait(inode);
+
+	/* Serialize against page faults */
+	filemap_invalidate_lock(inode->i_mapping);
+
+	/* Serialize against zonefs_iomap_begin() */
+	mutex_lock(&zi->i_truncate_mutex);
+
+	old_isize = i_size_read(inode);
+	if (isize == old_isize)
+		goto unlock;
+
+	ret = zonefs_zone_mgmt(inode, op);
+	if (ret)
+		goto unlock;
+
+	/*
+	 * If the mount option ZONEFS_MNTOPT_EXPLICIT_OPEN is set,
+	 * take care of open zones.
+	 */
+	if (zi->i_flags & ZONEFS_ZONE_OPEN) {
+		/*
+		 * Truncating a zone to EMPTY or FULL is the equivalent of
+		 * closing the zone. For a truncation to 0, we need to
+		 * re-open the zone to ensure new writes can be processed.
+		 * For a truncation to the maximum file size, the zone is
+		 * closed and writes cannot be accepted anymore, so clear
+		 * the open flag.
+		 */
+		if (!isize)
+			ret = zonefs_zone_mgmt(inode, REQ_OP_ZONE_OPEN);
+		else
+			zi->i_flags &= ~ZONEFS_ZONE_OPEN;
+	}
+
+	zonefs_update_stats(inode, isize);
+	truncate_setsize(inode, isize);
+	zi->i_wpoffset = isize;
+	zonefs_account_active(inode);
+
+unlock:
+	mutex_unlock(&zi->i_truncate_mutex);
+	filemap_invalidate_unlock(inode->i_mapping);
+
+	return ret;
+}
+
+static int zonefs_file_fsync(struct file *file, loff_t start, loff_t end,
+			     int datasync)
+{
+	struct inode *inode = file_inode(file);
+	int ret = 0;
+
+	if (unlikely(IS_IMMUTABLE(inode)))
+		return -EPERM;
+
+	/*
+	 * Since only direct writes are allowed in sequential files, page cache
+	 * flush is needed only for conventional zone files.
+	 */
+	if (ZONEFS_I(inode)->i_ztype == ZONEFS_ZTYPE_CNV)
+		ret = file_write_and_wait_range(file, start, end);
+	if (!ret)
+		ret = blkdev_issue_flush(inode->i_sb->s_bdev);
+
+	if (ret)
+		zonefs_io_error(inode, true);
+
+	return ret;
+}
+
+static vm_fault_t zonefs_filemap_page_mkwrite(struct vm_fault *vmf)
+{
+	struct inode *inode = file_inode(vmf->vma->vm_file);
+	struct zonefs_inode_info *zi = ZONEFS_I(inode);
+	vm_fault_t ret;
+
+	if (unlikely(IS_IMMUTABLE(inode)))
+		return VM_FAULT_SIGBUS;
+
+	/*
+	 * Sanity check: only conventional zone files can have shared
+	 * writeable mappings.
+	 */
+	if (WARN_ON_ONCE(zi->i_ztype != ZONEFS_ZTYPE_CNV))
+		return VM_FAULT_NOPAGE;
+
+	sb_start_pagefault(inode->i_sb);
+	file_update_time(vmf->vma->vm_file);
+
+	/* Serialize against truncates */
+	filemap_invalidate_lock_shared(inode->i_mapping);
+	ret = iomap_page_mkwrite(vmf, &zonefs_write_iomap_ops);
+	filemap_invalidate_unlock_shared(inode->i_mapping);
+
+	sb_end_pagefault(inode->i_sb);
+	return ret;
+}
+
+static const struct vm_operations_struct zonefs_file_vm_ops = {
+	.fault		= filemap_fault,
+	.map_pages	= filemap_map_pages,
+	.page_mkwrite	= zonefs_filemap_page_mkwrite,
+};
+
+static int zonefs_file_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	/*
+	 * Conventional zones accept random writes, so their files can support
+	 * shared writable mappings. For sequential zone files, only read
+	 * mappings are possible since there are no guarantees for write
+	 * ordering between msync() and page cache writeback.
+	 */
+	if (ZONEFS_I(file_inode(file))->i_ztype == ZONEFS_ZTYPE_SEQ &&
+	    (vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE))
+		return -EINVAL;
+
+	file_accessed(file);
+	vma->vm_ops = &zonefs_file_vm_ops;
+
+	return 0;
+}
+
+static loff_t zonefs_file_llseek(struct file *file, loff_t offset, int whence)
+{
+	loff_t isize = i_size_read(file_inode(file));
+
+	/*
+	 * Seeks are limited to below the zone size for conventional zones
+	 * and below the zone write pointer for sequential zones. In both
+	 * cases, this limit is the inode size.
+	 */
+	return generic_file_llseek_size(file, offset, whence, isize, isize);
+}
+
+static int zonefs_file_write_dio_end_io(struct kiocb *iocb, ssize_t size,
+					int error, unsigned int flags)
+{
+	struct inode *inode = file_inode(iocb->ki_filp);
+	struct zonefs_inode_info *zi = ZONEFS_I(inode);
+
+	if (error) {
+		zonefs_io_error(inode, true);
+		return error;
+	}
+
+	if (size && zi->i_ztype != ZONEFS_ZTYPE_CNV) {
+		/*
+		 * Note that we may be seeing completions out of order,
+		 * but that is not a problem since a write completed
+		 * successfully necessarily means that all preceding writes
+		 * were also successful. So we can safely increase the inode
+		 * size to the write end location.
+		 */
+		mutex_lock(&zi->i_truncate_mutex);
+		if (i_size_read(inode) < iocb->ki_pos + size) {
+			zonefs_update_stats(inode, iocb->ki_pos + size);
+			zonefs_i_size_write(inode, iocb->ki_pos + size);
+		}
+		mutex_unlock(&zi->i_truncate_mutex);
+	}
+
+	return 0;
+}
+
+static const struct iomap_dio_ops zonefs_write_dio_ops = {
+	.end_io			= zonefs_file_write_dio_end_io,
+};
+
+static ssize_t zonefs_file_dio_append(struct kiocb *iocb, struct iov_iter *from)
+{
+	struct inode *inode = file_inode(iocb->ki_filp);
+	struct zonefs_inode_info *zi = ZONEFS_I(inode);
+	struct block_device *bdev = inode->i_sb->s_bdev;
+	unsigned int max = bdev_max_zone_append_sectors(bdev);
+	struct bio *bio;
+	ssize_t size;
+	int nr_pages;
+	ssize_t ret;
+
+	max = ALIGN_DOWN(max << SECTOR_SHIFT, inode->i_sb->s_blocksize);
+	iov_iter_truncate(from, max);
+
+	nr_pages = iov_iter_npages(from, BIO_MAX_VECS);
+	if (!nr_pages)
+		return 0;
+
+	bio = bio_alloc(bdev, nr_pages,
+			REQ_OP_ZONE_APPEND | REQ_SYNC | REQ_IDLE, GFP_NOFS);
+	bio->bi_iter.bi_sector = zi->i_zsector;
+	bio->bi_ioprio = iocb->ki_ioprio;
+	if (iocb_is_dsync(iocb))
+		bio->bi_opf |= REQ_FUA;
+
+	ret = bio_iov_iter_get_pages(bio, from);
+	if (unlikely(ret))
+		goto out_release;
+
+	size = bio->bi_iter.bi_size;
+	task_io_account_write(size);
+
+	if (iocb->ki_flags & IOCB_HIPRI)
+		bio_set_polled(bio, iocb);
+
+	ret = submit_bio_wait(bio);
+
+	/*
+	 * If the file zone was written underneath the file system, the zone
+	 * write pointer may not be where we expect it to be, but the zone
+	 * append write can still succeed. So check manually that we wrote where
+	 * we intended to, that is, at zi->i_wpoffset.
+	 */
+	if (!ret) {
+		sector_t wpsector =
+			zi->i_zsector + (zi->i_wpoffset >> SECTOR_SHIFT);
+
+		if (bio->bi_iter.bi_sector != wpsector) {
+			zonefs_warn(inode->i_sb,
+				"Corrupted write pointer %llu for zone at %llu\n",
+				wpsector, zi->i_zsector);
+			ret = -EIO;
+		}
+	}
+
+	zonefs_file_write_dio_end_io(iocb, size, ret, 0);
+	trace_zonefs_file_dio_append(inode, size, ret);
+
+out_release:
+	bio_release_pages(bio, false);
+	bio_put(bio);
+
+	if (ret >= 0) {
+		iocb->ki_pos += size;
+		return size;
+	}
+
+	return ret;
+}
+
+/*
+ * Do not exceed the LFS limits nor the file zone size. If pos is under the
+ * limit it becomes a short access. If it exceeds the limit, return -EFBIG.
+ */
+static loff_t zonefs_write_check_limits(struct file *file, loff_t pos,
+					loff_t count)
+{
+	struct inode *inode = file_inode(file);
+	struct zonefs_inode_info *zi = ZONEFS_I(inode);
+	loff_t limit = rlimit(RLIMIT_FSIZE);
+	loff_t max_size = zi->i_max_size;
+
+	if (limit != RLIM_INFINITY) {
+		if (pos >= limit) {
+			send_sig(SIGXFSZ, current, 0);
+			return -EFBIG;
+		}
+		count = min(count, limit - pos);
+	}
+
+	if (!(file->f_flags & O_LARGEFILE))
+		max_size = min_t(loff_t, MAX_NON_LFS, max_size);
+
+	if (unlikely(pos >= max_size))
+		return -EFBIG;
+
+	return min(count, max_size - pos);
+}
+
+static ssize_t zonefs_write_checks(struct kiocb *iocb, struct iov_iter *from)
+{
+	struct file *file = iocb->ki_filp;
+	struct inode *inode = file_inode(file);
+	struct zonefs_inode_info *zi = ZONEFS_I(inode);
+	loff_t count;
+
+	if (IS_SWAPFILE(inode))
+		return -ETXTBSY;
+
+	if (!iov_iter_count(from))
+		return 0;
+
+	if ((iocb->ki_flags & IOCB_NOWAIT) && !(iocb->ki_flags & IOCB_DIRECT))
+		return -EINVAL;
+
+	if (iocb->ki_flags & IOCB_APPEND) {
+		if (zi->i_ztype != ZONEFS_ZTYPE_SEQ)
+			return -EINVAL;
+		mutex_lock(&zi->i_truncate_mutex);
+		iocb->ki_pos = zi->i_wpoffset;
+		mutex_unlock(&zi->i_truncate_mutex);
+	}
+
+	count = zonefs_write_check_limits(file, iocb->ki_pos,
+					  iov_iter_count(from));
+	if (count < 0)
+		return count;
+
+	iov_iter_truncate(from, count);
+	return iov_iter_count(from);
+}
+
+/*
+ * Handle direct writes. For sequential zone files, this is the only possible
+ * write path. For these files, check that the user is issuing writes
+ * sequentially from the end of the file. This code assumes that the block layer
+ * delivers write requests to the device in sequential order. This is always the
+ * case if a block IO scheduler implementing the ELEVATOR_F_ZBD_SEQ_WRITE
+ * elevator feature is being used (e.g. mq-deadline). The block layer always
+ * automatically select such an elevator for zoned block devices during the
+ * device initialization.
+ */
+static ssize_t zonefs_file_dio_write(struct kiocb *iocb, struct iov_iter *from)
+{
+	struct inode *inode = file_inode(iocb->ki_filp);
+	struct zonefs_inode_info *zi = ZONEFS_I(inode);
+	struct super_block *sb = inode->i_sb;
+	bool sync = is_sync_kiocb(iocb);
+	bool append = false;
+	ssize_t ret, count;
+
+	/*
+	 * For async direct IOs to sequential zone files, refuse IOCB_NOWAIT
+	 * 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).
+	 */
+	if (zi->i_ztype == ZONEFS_ZTYPE_SEQ && !sync &&
+	    (iocb->ki_flags & IOCB_NOWAIT))
+		return -EOPNOTSUPP;
+
+	if (iocb->ki_flags & IOCB_NOWAIT) {
+		if (!inode_trylock(inode))
+			return -EAGAIN;
+	} else {
+		inode_lock(inode);
+	}
+
+	count = zonefs_write_checks(iocb, from);
+	if (count <= 0) {
+		ret = count;
+		goto inode_unlock;
+	}
+
+	if ((iocb->ki_pos | count) & (sb->s_blocksize - 1)) {
+		ret = -EINVAL;
+		goto inode_unlock;
+	}
+
+	/* Enforce sequential writes (append only) in sequential zones */
+	if (zi->i_ztype == ZONEFS_ZTYPE_SEQ) {
+		mutex_lock(&zi->i_truncate_mutex);
+		if (iocb->ki_pos != zi->i_wpoffset) {
+			mutex_unlock(&zi->i_truncate_mutex);
+			ret = -EINVAL;
+			goto inode_unlock;
+		}
+		mutex_unlock(&zi->i_truncate_mutex);
+		append = sync;
+	}
+
+	if (append)
+		ret = zonefs_file_dio_append(iocb, from);
+	else
+		ret = iomap_dio_rw(iocb, from, &zonefs_write_iomap_ops,
+				   &zonefs_write_dio_ops, 0, NULL, 0);
+	if (zi->i_ztype == ZONEFS_ZTYPE_SEQ &&
+	    (ret > 0 || ret == -EIOCBQUEUED)) {
+		if (ret > 0)
+			count = ret;
+
+		/*
+		 * Update the zone write pointer offset assuming the write
+		 * operation succeeded. If it did not, the error recovery path
+		 * will correct it. Also do active seq file accounting.
+		 */
+		mutex_lock(&zi->i_truncate_mutex);
+		zi->i_wpoffset += count;
+		zonefs_account_active(inode);
+		mutex_unlock(&zi->i_truncate_mutex);
+	}
+
+inode_unlock:
+	inode_unlock(inode);
+
+	return ret;
+}
+
+static ssize_t zonefs_file_buffered_write(struct kiocb *iocb,
+					  struct iov_iter *from)
+{
+	struct inode *inode = file_inode(iocb->ki_filp);
+	struct zonefs_inode_info *zi = ZONEFS_I(inode);
+	ssize_t ret;
+
+	/*
+	 * Direct IO writes are mandatory for sequential zone files so that the
+	 * write IO issuing order is preserved.
+	 */
+	if (zi->i_ztype != ZONEFS_ZTYPE_CNV)
+		return -EIO;
+
+	if (iocb->ki_flags & IOCB_NOWAIT) {
+		if (!inode_trylock(inode))
+			return -EAGAIN;
+	} else {
+		inode_lock(inode);
+	}
+
+	ret = zonefs_write_checks(iocb, from);
+	if (ret <= 0)
+		goto inode_unlock;
+
+	ret = iomap_file_buffered_write(iocb, from, &zonefs_write_iomap_ops);
+	if (ret > 0)
+		iocb->ki_pos += ret;
+	else if (ret == -EIO)
+		zonefs_io_error(inode, true);
+
+inode_unlock:
+	inode_unlock(inode);
+	if (ret > 0)
+		ret = generic_write_sync(iocb, ret);
+
+	return ret;
+}
+
+static ssize_t zonefs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
+{
+	struct inode *inode = file_inode(iocb->ki_filp);
+
+	if (unlikely(IS_IMMUTABLE(inode)))
+		return -EPERM;
+
+	if (sb_rdonly(inode->i_sb))
+		return -EROFS;
+
+	/* Write operations beyond the zone size are not allowed */
+	if (iocb->ki_pos >= ZONEFS_I(inode)->i_max_size)
+		return -EFBIG;
+
+	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);
+}
+
+static int zonefs_file_read_dio_end_io(struct kiocb *iocb, ssize_t size,
+				       int error, unsigned int flags)
+{
+	if (error) {
+		zonefs_io_error(file_inode(iocb->ki_filp), false);
+		return error;
+	}
+
+	return 0;
+}
+
+static const struct iomap_dio_ops zonefs_read_dio_ops = {
+	.end_io			= zonefs_file_read_dio_end_io,
+};
+
+static ssize_t zonefs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
+{
+	struct inode *inode = file_inode(iocb->ki_filp);
+	struct zonefs_inode_info *zi = ZONEFS_I(inode);
+	struct super_block *sb = inode->i_sb;
+	loff_t isize;
+	ssize_t ret;
+
+	/* Offline zones cannot be read */
+	if (unlikely(IS_IMMUTABLE(inode) && !(inode->i_mode & 0777)))
+		return -EPERM;
+
+	if (iocb->ki_pos >= zi->i_max_size)
+		return 0;
+
+	if (iocb->ki_flags & IOCB_NOWAIT) {
+		if (!inode_trylock_shared(inode))
+			return -EAGAIN;
+	} else {
+		inode_lock_shared(inode);
+	}
+
+	/* Limit read operations to written data */
+	mutex_lock(&zi->i_truncate_mutex);
+	isize = i_size_read(inode);
+	if (iocb->ki_pos >= isize) {
+		mutex_unlock(&zi->i_truncate_mutex);
+		ret = 0;
+		goto inode_unlock;
+	}
+	iov_iter_truncate(to, isize - iocb->ki_pos);
+	mutex_unlock(&zi->i_truncate_mutex);
+
+	if (iocb->ki_flags & IOCB_DIRECT) {
+		size_t count = iov_iter_count(to);
+
+		if ((iocb->ki_pos | count) & (sb->s_blocksize - 1)) {
+			ret = -EINVAL;
+			goto inode_unlock;
+		}
+		file_accessed(iocb->ki_filp);
+		ret = iomap_dio_rw(iocb, to, &zonefs_read_iomap_ops,
+				   &zonefs_read_dio_ops, 0, NULL, 0);
+	} else {
+		ret = generic_file_read_iter(iocb, to);
+		if (ret == -EIO)
+			zonefs_io_error(inode, false);
+	}
+
+inode_unlock:
+	inode_unlock_shared(inode);
+
+	return ret;
+}
+
+/*
+ * Write open accounting is done only for sequential files.
+ */
+static inline bool zonefs_seq_file_need_wro(struct inode *inode,
+					    struct file *file)
+{
+	struct zonefs_inode_info *zi = ZONEFS_I(inode);
+
+	if (zi->i_ztype != ZONEFS_ZTYPE_SEQ)
+		return false;
+
+	if (!(file->f_mode & FMODE_WRITE))
+		return false;
+
+	return true;
+}
+
+static int zonefs_seq_file_write_open(struct inode *inode)
+{
+	struct zonefs_inode_info *zi = ZONEFS_I(inode);
+	int ret = 0;
+
+	mutex_lock(&zi->i_truncate_mutex);
+
+	if (!zi->i_wr_refcnt) {
+		struct zonefs_sb_info *sbi = ZONEFS_SB(inode->i_sb);
+		unsigned int wro = atomic_inc_return(&sbi->s_wro_seq_files);
+
+		if (sbi->s_mount_opts & ZONEFS_MNTOPT_EXPLICIT_OPEN) {
+
+			if (sbi->s_max_wro_seq_files
+			    && wro > sbi->s_max_wro_seq_files) {
+				atomic_dec(&sbi->s_wro_seq_files);
+				ret = -EBUSY;
+				goto unlock;
+			}
+
+			if (i_size_read(inode) < zi->i_max_size) {
+				ret = zonefs_zone_mgmt(inode, REQ_OP_ZONE_OPEN);
+				if (ret) {
+					atomic_dec(&sbi->s_wro_seq_files);
+					goto unlock;
+				}
+				zi->i_flags |= ZONEFS_ZONE_OPEN;
+				zonefs_account_active(inode);
+			}
+		}
+	}
+
+	zi->i_wr_refcnt++;
+
+unlock:
+	mutex_unlock(&zi->i_truncate_mutex);
+
+	return ret;
+}
+
+static int zonefs_file_open(struct inode *inode, struct file *file)
+{
+	int ret;
+
+	ret = generic_file_open(inode, file);
+	if (ret)
+		return ret;
+
+	if (zonefs_seq_file_need_wro(inode, file))
+		return zonefs_seq_file_write_open(inode);
+
+	return 0;
+}
+
+static void zonefs_seq_file_write_close(struct inode *inode)
+{
+	struct zonefs_inode_info *zi = ZONEFS_I(inode);
+	struct super_block *sb = inode->i_sb;
+	struct zonefs_sb_info *sbi = ZONEFS_SB(sb);
+	int ret = 0;
+
+	mutex_lock(&zi->i_truncate_mutex);
+
+	zi->i_wr_refcnt--;
+	if (zi->i_wr_refcnt)
+		goto unlock;
+
+	/*
+	 * The file zone may not be open anymore (e.g. the file was truncated to
+	 * its maximum size or it was fully written). For this case, we only
+	 * need to decrement the write open count.
+	 */
+	if (zi->i_flags & ZONEFS_ZONE_OPEN) {
+		ret = zonefs_zone_mgmt(inode, REQ_OP_ZONE_CLOSE);
+		if (ret) {
+			__zonefs_io_error(inode, false);
+			/*
+			 * Leaving zones explicitly open may lead to a state
+			 * where most zones cannot be written (zone resources
+			 * exhausted). So take preventive action by remounting
+			 * read-only.
+			 */
+			if (zi->i_flags & ZONEFS_ZONE_OPEN &&
+			    !(sb->s_flags & SB_RDONLY)) {
+				zonefs_warn(sb,
+					"closing zone at %llu failed %d\n",
+					zi->i_zsector, ret);
+				zonefs_warn(sb,
+					"remounting filesystem read-only\n");
+				sb->s_flags |= SB_RDONLY;
+			}
+			goto unlock;
+		}
+
+		zi->i_flags &= ~ZONEFS_ZONE_OPEN;
+		zonefs_account_active(inode);
+	}
+
+	atomic_dec(&sbi->s_wro_seq_files);
+
+unlock:
+	mutex_unlock(&zi->i_truncate_mutex);
+}
+
+static int zonefs_file_release(struct inode *inode, struct file *file)
+{
+	/*
+	 * If we explicitly open a zone we must close it again as well, but the
+	 * zone management operation can fail (either due to an IO error or as
+	 * the zone has gone offline or read-only). Make sure we don't fail the
+	 * close(2) for user-space.
+	 */
+	if (zonefs_seq_file_need_wro(inode, file))
+		zonefs_seq_file_write_close(inode);
+
+	return 0;
+}
+
+const struct file_operations zonefs_file_operations = {
+	.open		= zonefs_file_open,
+	.release	= zonefs_file_release,
+	.fsync		= zonefs_file_fsync,
+	.mmap		= zonefs_file_mmap,
+	.llseek		= zonefs_file_llseek,
+	.read_iter	= zonefs_file_read_iter,
+	.write_iter	= zonefs_file_write_iter,
+	.splice_read	= generic_file_splice_read,
+	.splice_write	= iter_file_splice_write,
+	.iopoll		= iocb_bio_iopoll,
+};
diff --git a/fs/zonefs/super.c b/fs/zonefs/super.c
index a9c5c3f720adf..e808276b88018 100644
--- a/fs/zonefs/super.c
+++ b/fs/zonefs/super.c
@@ -30,7 +30,7 @@
 /*
  * Manage the active zone count. Called with zi->i_truncate_mutex held.
  */
-static void zonefs_account_active(struct inode *inode)
+void zonefs_account_active(struct inode *inode)
 {
 	struct zonefs_sb_info *sbi = ZONEFS_SB(inode->i_sb);
 	struct zonefs_inode_info *zi = ZONEFS_I(inode);
@@ -68,7 +68,7 @@ static void zonefs_account_active(struct inode *inode)
 	}
 }
 
-static inline int zonefs_zone_mgmt(struct inode *inode, enum req_op op)
+int zonefs_zone_mgmt(struct inode *inode, enum req_op op)
 {
 	struct zonefs_inode_info *zi = ZONEFS_I(inode);
 	int ret;
@@ -99,7 +99,7 @@ static inline int zonefs_zone_mgmt(struct inode *inode, enum req_op op)
 	return 0;
 }
 
-static inline void zonefs_i_size_write(struct inode *inode, loff_t isize)
+void zonefs_i_size_write(struct inode *inode, loff_t isize)
 {
 	struct zonefs_inode_info *zi = ZONEFS_I(inode);
 
@@ -117,167 +117,7 @@ static inline void zonefs_i_size_write(struct inode *inode, loff_t isize)
 	}
 }
 
-static int zonefs_read_iomap_begin(struct inode *inode, loff_t offset,
-				   loff_t length, unsigned int flags,
-				   struct iomap *iomap, struct iomap *srcmap)
-{
-	struct zonefs_inode_info *zi = ZONEFS_I(inode);
-	struct super_block *sb = inode->i_sb;
-	loff_t isize;
-
-	/*
-	 * All blocks are always mapped below EOF. If reading past EOF,
-	 * act as if there is a hole up to the file maximum size.
-	 */
-	mutex_lock(&zi->i_truncate_mutex);
-	iomap->bdev = inode->i_sb->s_bdev;
-	iomap->offset = ALIGN_DOWN(offset, sb->s_blocksize);
-	isize = i_size_read(inode);
-	if (iomap->offset >= isize) {
-		iomap->type = IOMAP_HOLE;
-		iomap->addr = IOMAP_NULL_ADDR;
-		iomap->length = length;
-	} else {
-		iomap->type = IOMAP_MAPPED;
-		iomap->addr = (zi->i_zsector << SECTOR_SHIFT) + iomap->offset;
-		iomap->length = isize - iomap->offset;
-	}
-	mutex_unlock(&zi->i_truncate_mutex);
-
-	trace_zonefs_iomap_begin(inode, iomap);
-
-	return 0;
-}
-
-static const struct iomap_ops zonefs_read_iomap_ops = {
-	.iomap_begin	= zonefs_read_iomap_begin,
-};
-
-static int zonefs_write_iomap_begin(struct inode *inode, loff_t offset,
-				    loff_t length, unsigned int flags,
-				    struct iomap *iomap, struct iomap *srcmap)
-{
-	struct zonefs_inode_info *zi = ZONEFS_I(inode);
-	struct super_block *sb = inode->i_sb;
-	loff_t isize;
-
-	/* All write I/Os should always be within the file maximum size */
-	if (WARN_ON_ONCE(offset + length > zi->i_max_size))
-		return -EIO;
-
-	/*
-	 * Sequential zones can only accept direct writes. This is already
-	 * checked when writes are issued, so warn if we see a page writeback
-	 * operation.
-	 */
-	if (WARN_ON_ONCE(zi->i_ztype == ZONEFS_ZTYPE_SEQ &&
-			 !(flags & IOMAP_DIRECT)))
-		return -EIO;
-
-	/*
-	 * For conventional zones, all blocks are always mapped. For sequential
-	 * zones, all blocks after always mapped below the inode size (zone
-	 * write pointer) and unwriten beyond.
-	 */
-	mutex_lock(&zi->i_truncate_mutex);
-	iomap->bdev = inode->i_sb->s_bdev;
-	iomap->offset = ALIGN_DOWN(offset, sb->s_blocksize);
-	iomap->addr = (zi->i_zsector << SECTOR_SHIFT) + iomap->offset;
-	isize = i_size_read(inode);
-	if (iomap->offset >= isize) {
-		iomap->type = IOMAP_UNWRITTEN;
-		iomap->length = zi->i_max_size - iomap->offset;
-	} else {
-		iomap->type = IOMAP_MAPPED;
-		iomap->length = isize - iomap->offset;
-	}
-	mutex_unlock(&zi->i_truncate_mutex);
-
-	trace_zonefs_iomap_begin(inode, iomap);
-
-	return 0;
-}
-
-static const struct iomap_ops zonefs_write_iomap_ops = {
-	.iomap_begin	= zonefs_write_iomap_begin,
-};
-
-static int zonefs_read_folio(struct file *unused, struct folio *folio)
-{
-	return iomap_read_folio(folio, &zonefs_read_iomap_ops);
-}
-
-static void zonefs_readahead(struct readahead_control *rac)
-{
-	iomap_readahead(rac, &zonefs_read_iomap_ops);
-}
-
-/*
- * Map blocks for page writeback. This is used only on conventional zone files,
- * which implies that the page range can only be within the fixed inode size.
- */
-static int zonefs_write_map_blocks(struct iomap_writepage_ctx *wpc,
-				   struct inode *inode, loff_t offset)
-{
-	struct zonefs_inode_info *zi = ZONEFS_I(inode);
-
-	if (WARN_ON_ONCE(zi->i_ztype != ZONEFS_ZTYPE_CNV))
-		return -EIO;
-	if (WARN_ON_ONCE(offset >= i_size_read(inode)))
-		return -EIO;
-
-	/* If the mapping is already OK, nothing needs to be done */
-	if (offset >= wpc->iomap.offset &&
-	    offset < wpc->iomap.offset + wpc->iomap.length)
-		return 0;
-
-	return zonefs_write_iomap_begin(inode, offset, zi->i_max_size - offset,
-					IOMAP_WRITE, &wpc->iomap, NULL);
-}
-
-static const struct iomap_writeback_ops zonefs_writeback_ops = {
-	.map_blocks		= zonefs_write_map_blocks,
-};
-
-static int zonefs_writepages(struct address_space *mapping,
-			     struct writeback_control *wbc)
-{
-	struct iomap_writepage_ctx wpc = { };
-
-	return iomap_writepages(mapping, wbc, &wpc, &zonefs_writeback_ops);
-}
-
-static int zonefs_swap_activate(struct swap_info_struct *sis,
-				struct file *swap_file, sector_t *span)
-{
-	struct inode *inode = file_inode(swap_file);
-	struct zonefs_inode_info *zi = ZONEFS_I(inode);
-
-	if (zi->i_ztype != ZONEFS_ZTYPE_CNV) {
-		zonefs_err(inode->i_sb,
-			   "swap file: not a conventional zone file\n");
-		return -EINVAL;
-	}
-
-	return iomap_swapfile_activate(sis, swap_file, span,
-				       &zonefs_read_iomap_ops);
-}
-
-static const struct address_space_operations zonefs_file_aops = {
-	.read_folio		= zonefs_read_folio,
-	.readahead		= zonefs_readahead,
-	.writepages		= zonefs_writepages,
-	.dirty_folio		= filemap_dirty_folio,
-	.release_folio		= iomap_release_folio,
-	.invalidate_folio	= iomap_invalidate_folio,
-	.migrate_folio		= filemap_migrate_folio,
-	.is_partially_uptodate	= iomap_is_partially_uptodate,
-	.error_remove_page	= generic_error_remove_page,
-	.direct_IO		= noop_direct_IO,
-	.swap_activate		= zonefs_swap_activate,
-};
-
-static void zonefs_update_stats(struct inode *inode, loff_t new_isize)
+void zonefs_update_stats(struct inode *inode, loff_t new_isize)
 {
 	struct super_block *sb = inode->i_sb;
 	struct zonefs_sb_info *sbi = ZONEFS_SB(sb);
@@ -487,7 +327,7 @@ static int zonefs_io_error_cb(struct blk_zone *zone, unsigned int idx,
  * eventually correct the file size and zonefs inode write pointer offset
  * (which can be out of sync with the drive due to partial write failures).
  */
-static void __zonefs_io_error(struct inode *inode, bool write)
+void __zonefs_io_error(struct inode *inode, bool write)
 {
 	struct zonefs_inode_info *zi = ZONEFS_I(inode);
 	struct super_block *sb = inode->i_sb;
@@ -526,749 +366,6 @@ static void __zonefs_io_error(struct inode *inode, bool write)
 	memalloc_noio_restore(noio_flag);
 }
 
-static void zonefs_io_error(struct inode *inode, bool write)
-{
-	struct zonefs_inode_info *zi = ZONEFS_I(inode);
-
-	mutex_lock(&zi->i_truncate_mutex);
-	__zonefs_io_error(inode, write);
-	mutex_unlock(&zi->i_truncate_mutex);
-}
-
-static int zonefs_file_truncate(struct inode *inode, loff_t isize)
-{
-	struct zonefs_inode_info *zi = ZONEFS_I(inode);
-	loff_t old_isize;
-	enum req_op op;
-	int ret = 0;
-
-	/*
-	 * Only sequential zone files can be truncated and truncation is allowed
-	 * 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.
-	 */
-	if (zi->i_ztype != ZONEFS_ZTYPE_SEQ)
-		return -EPERM;
-
-	if (!isize)
-		op = REQ_OP_ZONE_RESET;
-	else if (isize == zi->i_max_size)
-		op = REQ_OP_ZONE_FINISH;
-	else
-		return -EPERM;
-
-	inode_dio_wait(inode);
-
-	/* Serialize against page faults */
-	filemap_invalidate_lock(inode->i_mapping);
-
-	/* Serialize against zonefs_iomap_begin() */
-	mutex_lock(&zi->i_truncate_mutex);
-
-	old_isize = i_size_read(inode);
-	if (isize == old_isize)
-		goto unlock;
-
-	ret = zonefs_zone_mgmt(inode, op);
-	if (ret)
-		goto unlock;
-
-	/*
-	 * If the mount option ZONEFS_MNTOPT_EXPLICIT_OPEN is set,
-	 * take care of open zones.
-	 */
-	if (zi->i_flags & ZONEFS_ZONE_OPEN) {
-		/*
-		 * Truncating a zone to EMPTY or FULL is the equivalent of
-		 * closing the zone. For a truncation to 0, we need to
-		 * re-open the zone to ensure new writes can be processed.
-		 * For a truncation to the maximum file size, the zone is
-		 * closed and writes cannot be accepted anymore, so clear
-		 * the open flag.
-		 */
-		if (!isize)
-			ret = zonefs_zone_mgmt(inode, REQ_OP_ZONE_OPEN);
-		else
-			zi->i_flags &= ~ZONEFS_ZONE_OPEN;
-	}
-
-	zonefs_update_stats(inode, isize);
-	truncate_setsize(inode, isize);
-	zi->i_wpoffset = isize;
-	zonefs_account_active(inode);
-
-unlock:
-	mutex_unlock(&zi->i_truncate_mutex);
-	filemap_invalidate_unlock(inode->i_mapping);
-
-	return ret;
-}
-
-static int zonefs_inode_setattr(struct user_namespace *mnt_userns,
-				struct dentry *dentry, struct iattr *iattr)
-{
-	struct inode *inode = d_inode(dentry);
-	int ret;
-
-	if (unlikely(IS_IMMUTABLE(inode)))
-		return -EPERM;
-
-	ret = setattr_prepare(&init_user_ns, dentry, iattr);
-	if (ret)
-		return ret;
-
-	/*
-	 * Since files and directories cannot be created nor deleted, do not
-	 * allow setting any write attributes on the sub-directories grouping
-	 * files by zone type.
-	 */
-	if ((iattr->ia_valid & ATTR_MODE) && S_ISDIR(inode->i_mode) &&
-	    (iattr->ia_mode & 0222))
-		return -EPERM;
-
-	if (((iattr->ia_valid & ATTR_UID) &&
-	     !uid_eq(iattr->ia_uid, inode->i_uid)) ||
-	    ((iattr->ia_valid & ATTR_GID) &&
-	     !gid_eq(iattr->ia_gid, inode->i_gid))) {
-		ret = dquot_transfer(mnt_userns, inode, iattr);
-		if (ret)
-			return ret;
-	}
-
-	if (iattr->ia_valid & ATTR_SIZE) {
-		ret = zonefs_file_truncate(inode, iattr->ia_size);
-		if (ret)
-			return ret;
-	}
-
-	setattr_copy(&init_user_ns, inode, iattr);
-
-	return 0;
-}
-
-static const struct inode_operations zonefs_file_inode_operations = {
-	.setattr	= zonefs_inode_setattr,
-};
-
-static int zonefs_file_fsync(struct file *file, loff_t start, loff_t end,
-			     int datasync)
-{
-	struct inode *inode = file_inode(file);
-	int ret = 0;
-
-	if (unlikely(IS_IMMUTABLE(inode)))
-		return -EPERM;
-
-	/*
-	 * Since only direct writes are allowed in sequential files, page cache
-	 * flush is needed only for conventional zone files.
-	 */
-	if (ZONEFS_I(inode)->i_ztype == ZONEFS_ZTYPE_CNV)
-		ret = file_write_and_wait_range(file, start, end);
-	if (!ret)
-		ret = blkdev_issue_flush(inode->i_sb->s_bdev);
-
-	if (ret)
-		zonefs_io_error(inode, true);
-
-	return ret;
-}
-
-static vm_fault_t zonefs_filemap_page_mkwrite(struct vm_fault *vmf)
-{
-	struct inode *inode = file_inode(vmf->vma->vm_file);
-	struct zonefs_inode_info *zi = ZONEFS_I(inode);
-	vm_fault_t ret;
-
-	if (unlikely(IS_IMMUTABLE(inode)))
-		return VM_FAULT_SIGBUS;
-
-	/*
-	 * Sanity check: only conventional zone files can have shared
-	 * writeable mappings.
-	 */
-	if (WARN_ON_ONCE(zi->i_ztype != ZONEFS_ZTYPE_CNV))
-		return VM_FAULT_NOPAGE;
-
-	sb_start_pagefault(inode->i_sb);
-	file_update_time(vmf->vma->vm_file);
-
-	/* Serialize against truncates */
-	filemap_invalidate_lock_shared(inode->i_mapping);
-	ret = iomap_page_mkwrite(vmf, &zonefs_write_iomap_ops);
-	filemap_invalidate_unlock_shared(inode->i_mapping);
-
-	sb_end_pagefault(inode->i_sb);
-	return ret;
-}
-
-static const struct vm_operations_struct zonefs_file_vm_ops = {
-	.fault		= filemap_fault,
-	.map_pages	= filemap_map_pages,
-	.page_mkwrite	= zonefs_filemap_page_mkwrite,
-};
-
-static int zonefs_file_mmap(struct file *file, struct vm_area_struct *vma)
-{
-	/*
-	 * Conventional zones accept random writes, so their files can support
-	 * shared writable mappings. For sequential zone files, only read
-	 * mappings are possible since there are no guarantees for write
-	 * ordering between msync() and page cache writeback.
-	 */
-	if (ZONEFS_I(file_inode(file))->i_ztype == ZONEFS_ZTYPE_SEQ &&
-	    (vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE))
-		return -EINVAL;
-
-	file_accessed(file);
-	vma->vm_ops = &zonefs_file_vm_ops;
-
-	return 0;
-}
-
-static loff_t zonefs_file_llseek(struct file *file, loff_t offset, int whence)
-{
-	loff_t isize = i_size_read(file_inode(file));
-
-	/*
-	 * Seeks are limited to below the zone size for conventional zones
-	 * and below the zone write pointer for sequential zones. In both
-	 * cases, this limit is the inode size.
-	 */
-	return generic_file_llseek_size(file, offset, whence, isize, isize);
-}
-
-static int zonefs_file_write_dio_end_io(struct kiocb *iocb, ssize_t size,
-					int error, unsigned int flags)
-{
-	struct inode *inode = file_inode(iocb->ki_filp);
-	struct zonefs_inode_info *zi = ZONEFS_I(inode);
-
-	if (error) {
-		zonefs_io_error(inode, true);
-		return error;
-	}
-
-	if (size && zi->i_ztype != ZONEFS_ZTYPE_CNV) {
-		/*
-		 * Note that we may be seeing completions out of order,
-		 * but that is not a problem since a write completed
-		 * successfully necessarily means that all preceding writes
-		 * were also successful. So we can safely increase the inode
-		 * size to the write end location.
-		 */
-		mutex_lock(&zi->i_truncate_mutex);
-		if (i_size_read(inode) < iocb->ki_pos + size) {
-			zonefs_update_stats(inode, iocb->ki_pos + size);
-			zonefs_i_size_write(inode, iocb->ki_pos + size);
-		}
-		mutex_unlock(&zi->i_truncate_mutex);
-	}
-
-	return 0;
-}
-
-static const struct iomap_dio_ops zonefs_write_dio_ops = {
-	.end_io			= zonefs_file_write_dio_end_io,
-};
-
-static ssize_t zonefs_file_dio_append(struct kiocb *iocb, struct iov_iter *from)
-{
-	struct inode *inode = file_inode(iocb->ki_filp);
-	struct zonefs_inode_info *zi = ZONEFS_I(inode);
-	struct block_device *bdev = inode->i_sb->s_bdev;
-	unsigned int max = bdev_max_zone_append_sectors(bdev);
-	struct bio *bio;
-	ssize_t size;
-	int nr_pages;
-	ssize_t ret;
-
-	max = ALIGN_DOWN(max << SECTOR_SHIFT, inode->i_sb->s_blocksize);
-	iov_iter_truncate(from, max);
-
-	nr_pages = iov_iter_npages(from, BIO_MAX_VECS);
-	if (!nr_pages)
-		return 0;
-
-	bio = bio_alloc(bdev, nr_pages,
-			REQ_OP_ZONE_APPEND | REQ_SYNC | REQ_IDLE, GFP_NOFS);
-	bio->bi_iter.bi_sector = zi->i_zsector;
-	bio->bi_ioprio = iocb->ki_ioprio;
-	if (iocb_is_dsync(iocb))
-		bio->bi_opf |= REQ_FUA;
-
-	ret = bio_iov_iter_get_pages(bio, from);
-	if (unlikely(ret))
-		goto out_release;
-
-	size = bio->bi_iter.bi_size;
-	task_io_account_write(size);
-
-	if (iocb->ki_flags & IOCB_HIPRI)
-		bio_set_polled(bio, iocb);
-
-	ret = submit_bio_wait(bio);
-
-	/*
-	 * If the file zone was written underneath the file system, the zone
-	 * write pointer may not be where we expect it to be, but the zone
-	 * append write can still succeed. So check manually that we wrote where
-	 * we intended to, that is, at zi->i_wpoffset.
-	 */
-	if (!ret) {
-		sector_t wpsector =
-			zi->i_zsector + (zi->i_wpoffset >> SECTOR_SHIFT);
-
-		if (bio->bi_iter.bi_sector != wpsector) {
-			zonefs_warn(inode->i_sb,
-				"Corrupted write pointer %llu for zone at %llu\n",
-				wpsector, zi->i_zsector);
-			ret = -EIO;
-		}
-	}
-
-	zonefs_file_write_dio_end_io(iocb, size, ret, 0);
-	trace_zonefs_file_dio_append(inode, size, ret);
-
-out_release:
-	bio_release_pages(bio, false);
-	bio_put(bio);
-
-	if (ret >= 0) {
-		iocb->ki_pos += size;
-		return size;
-	}
-
-	return ret;
-}
-
-/*
- * Do not exceed the LFS limits nor the file zone size. If pos is under the
- * limit it becomes a short access. If it exceeds the limit, return -EFBIG.
- */
-static loff_t zonefs_write_check_limits(struct file *file, loff_t pos,
-					loff_t count)
-{
-	struct inode *inode = file_inode(file);
-	struct zonefs_inode_info *zi = ZONEFS_I(inode);
-	loff_t limit = rlimit(RLIMIT_FSIZE);
-	loff_t max_size = zi->i_max_size;
-
-	if (limit != RLIM_INFINITY) {
-		if (pos >= limit) {
-			send_sig(SIGXFSZ, current, 0);
-			return -EFBIG;
-		}
-		count = min(count, limit - pos);
-	}
-
-	if (!(file->f_flags & O_LARGEFILE))
-		max_size = min_t(loff_t, MAX_NON_LFS, max_size);
-
-	if (unlikely(pos >= max_size))
-		return -EFBIG;
-
-	return min(count, max_size - pos);
-}
-
-static ssize_t zonefs_write_checks(struct kiocb *iocb, struct iov_iter *from)
-{
-	struct file *file = iocb->ki_filp;
-	struct inode *inode = file_inode(file);
-	struct zonefs_inode_info *zi = ZONEFS_I(inode);
-	loff_t count;
-
-	if (IS_SWAPFILE(inode))
-		return -ETXTBSY;
-
-	if (!iov_iter_count(from))
-		return 0;
-
-	if ((iocb->ki_flags & IOCB_NOWAIT) && !(iocb->ki_flags & IOCB_DIRECT))
-		return -EINVAL;
-
-	if (iocb->ki_flags & IOCB_APPEND) {
-		if (zi->i_ztype != ZONEFS_ZTYPE_SEQ)
-			return -EINVAL;
-		mutex_lock(&zi->i_truncate_mutex);
-		iocb->ki_pos = zi->i_wpoffset;
-		mutex_unlock(&zi->i_truncate_mutex);
-	}
-
-	count = zonefs_write_check_limits(file, iocb->ki_pos,
-					  iov_iter_count(from));
-	if (count < 0)
-		return count;
-
-	iov_iter_truncate(from, count);
-	return iov_iter_count(from);
-}
-
-/*
- * Handle direct writes. For sequential zone files, this is the only possible
- * write path. For these files, check that the user is issuing writes
- * sequentially from the end of the file. This code assumes that the block layer
- * delivers write requests to the device in sequential order. This is always the
- * case if a block IO scheduler implementing the ELEVATOR_F_ZBD_SEQ_WRITE
- * elevator feature is being used (e.g. mq-deadline). The block layer always
- * automatically select such an elevator for zoned block devices during the
- * device initialization.
- */
-static ssize_t zonefs_file_dio_write(struct kiocb *iocb, struct iov_iter *from)
-{
-	struct inode *inode = file_inode(iocb->ki_filp);
-	struct zonefs_inode_info *zi = ZONEFS_I(inode);
-	struct super_block *sb = inode->i_sb;
-	bool sync = is_sync_kiocb(iocb);
-	bool append = false;
-	ssize_t ret, count;
-
-	/*
-	 * For async direct IOs to sequential zone files, refuse IOCB_NOWAIT
-	 * 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).
-	 */
-	if (zi->i_ztype == ZONEFS_ZTYPE_SEQ && !sync &&
-	    (iocb->ki_flags & IOCB_NOWAIT))
-		return -EOPNOTSUPP;
-
-	if (iocb->ki_flags & IOCB_NOWAIT) {
-		if (!inode_trylock(inode))
-			return -EAGAIN;
-	} else {
-		inode_lock(inode);
-	}
-
-	count = zonefs_write_checks(iocb, from);
-	if (count <= 0) {
-		ret = count;
-		goto inode_unlock;
-	}
-
-	if ((iocb->ki_pos | count) & (sb->s_blocksize - 1)) {
-		ret = -EINVAL;
-		goto inode_unlock;
-	}
-
-	/* Enforce sequential writes (append only) in sequential zones */
-	if (zi->i_ztype == ZONEFS_ZTYPE_SEQ) {
-		mutex_lock(&zi->i_truncate_mutex);
-		if (iocb->ki_pos != zi->i_wpoffset) {
-			mutex_unlock(&zi->i_truncate_mutex);
-			ret = -EINVAL;
-			goto inode_unlock;
-		}
-		mutex_unlock(&zi->i_truncate_mutex);
-		append = sync;
-	}
-
-	if (append)
-		ret = zonefs_file_dio_append(iocb, from);
-	else
-		ret = iomap_dio_rw(iocb, from, &zonefs_write_iomap_ops,
-				   &zonefs_write_dio_ops, 0, NULL, 0);
-	if (zi->i_ztype == ZONEFS_ZTYPE_SEQ &&
-	    (ret > 0 || ret == -EIOCBQUEUED)) {
-		if (ret > 0)
-			count = ret;
-
-		/*
-		 * Update the zone write pointer offset assuming the write
-		 * operation succeeded. If it did not, the error recovery path
-		 * will correct it. Also do active seq file accounting.
-		 */
-		mutex_lock(&zi->i_truncate_mutex);
-		zi->i_wpoffset += count;
-		zonefs_account_active(inode);
-		mutex_unlock(&zi->i_truncate_mutex);
-	}
-
-inode_unlock:
-	inode_unlock(inode);
-
-	return ret;
-}
-
-static ssize_t zonefs_file_buffered_write(struct kiocb *iocb,
-					  struct iov_iter *from)
-{
-	struct inode *inode = file_inode(iocb->ki_filp);
-	struct zonefs_inode_info *zi = ZONEFS_I(inode);
-	ssize_t ret;
-
-	/*
-	 * Direct IO writes are mandatory for sequential zone files so that the
-	 * write IO issuing order is preserved.
-	 */
-	if (zi->i_ztype != ZONEFS_ZTYPE_CNV)
-		return -EIO;
-
-	if (iocb->ki_flags & IOCB_NOWAIT) {
-		if (!inode_trylock(inode))
-			return -EAGAIN;
-	} else {
-		inode_lock(inode);
-	}
-
-	ret = zonefs_write_checks(iocb, from);
-	if (ret <= 0)
-		goto inode_unlock;
-
-	ret = iomap_file_buffered_write(iocb, from, &zonefs_write_iomap_ops);
-	if (ret > 0)
-		iocb->ki_pos += ret;
-	else if (ret == -EIO)
-		zonefs_io_error(inode, true);
-
-inode_unlock:
-	inode_unlock(inode);
-	if (ret > 0)
-		ret = generic_write_sync(iocb, ret);
-
-	return ret;
-}
-
-static ssize_t zonefs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
-{
-	struct inode *inode = file_inode(iocb->ki_filp);
-
-	if (unlikely(IS_IMMUTABLE(inode)))
-		return -EPERM;
-
-	if (sb_rdonly(inode->i_sb))
-		return -EROFS;
-
-	/* Write operations beyond the zone size are not allowed */
-	if (iocb->ki_pos >= ZONEFS_I(inode)->i_max_size)
-		return -EFBIG;
-
-	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);
-}
-
-static int zonefs_file_read_dio_end_io(struct kiocb *iocb, ssize_t size,
-				       int error, unsigned int flags)
-{
-	if (error) {
-		zonefs_io_error(file_inode(iocb->ki_filp), false);
-		return error;
-	}
-
-	return 0;
-}
-
-static const struct iomap_dio_ops zonefs_read_dio_ops = {
-	.end_io			= zonefs_file_read_dio_end_io,
-};
-
-static ssize_t zonefs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
-{
-	struct inode *inode = file_inode(iocb->ki_filp);
-	struct zonefs_inode_info *zi = ZONEFS_I(inode);
-	struct super_block *sb = inode->i_sb;
-	loff_t isize;
-	ssize_t ret;
-
-	/* Offline zones cannot be read */
-	if (unlikely(IS_IMMUTABLE(inode) && !(inode->i_mode & 0777)))
-		return -EPERM;
-
-	if (iocb->ki_pos >= zi->i_max_size)
-		return 0;
-
-	if (iocb->ki_flags & IOCB_NOWAIT) {
-		if (!inode_trylock_shared(inode))
-			return -EAGAIN;
-	} else {
-		inode_lock_shared(inode);
-	}
-
-	/* Limit read operations to written data */
-	mutex_lock(&zi->i_truncate_mutex);
-	isize = i_size_read(inode);
-	if (iocb->ki_pos >= isize) {
-		mutex_unlock(&zi->i_truncate_mutex);
-		ret = 0;
-		goto inode_unlock;
-	}
-	iov_iter_truncate(to, isize - iocb->ki_pos);
-	mutex_unlock(&zi->i_truncate_mutex);
-
-	if (iocb->ki_flags & IOCB_DIRECT) {
-		size_t count = iov_iter_count(to);
-
-		if ((iocb->ki_pos | count) & (sb->s_blocksize - 1)) {
-			ret = -EINVAL;
-			goto inode_unlock;
-		}
-		file_accessed(iocb->ki_filp);
-		ret = iomap_dio_rw(iocb, to, &zonefs_read_iomap_ops,
-				   &zonefs_read_dio_ops, 0, NULL, 0);
-	} else {
-		ret = generic_file_read_iter(iocb, to);
-		if (ret == -EIO)
-			zonefs_io_error(inode, false);
-	}
-
-inode_unlock:
-	inode_unlock_shared(inode);
-
-	return ret;
-}
-
-/*
- * Write open accounting is done only for sequential files.
- */
-static inline bool zonefs_seq_file_need_wro(struct inode *inode,
-					    struct file *file)
-{
-	struct zonefs_inode_info *zi = ZONEFS_I(inode);
-
-	if (zi->i_ztype != ZONEFS_ZTYPE_SEQ)
-		return false;
-
-	if (!(file->f_mode & FMODE_WRITE))
-		return false;
-
-	return true;
-}
-
-static int zonefs_seq_file_write_open(struct inode *inode)
-{
-	struct zonefs_inode_info *zi = ZONEFS_I(inode);
-	int ret = 0;
-
-	mutex_lock(&zi->i_truncate_mutex);
-
-	if (!zi->i_wr_refcnt) {
-		struct zonefs_sb_info *sbi = ZONEFS_SB(inode->i_sb);
-		unsigned int wro = atomic_inc_return(&sbi->s_wro_seq_files);
-
-		if (sbi->s_mount_opts & ZONEFS_MNTOPT_EXPLICIT_OPEN) {
-
-			if (sbi->s_max_wro_seq_files
-			    && wro > sbi->s_max_wro_seq_files) {
-				atomic_dec(&sbi->s_wro_seq_files);
-				ret = -EBUSY;
-				goto unlock;
-			}
-
-			if (i_size_read(inode) < zi->i_max_size) {
-				ret = zonefs_zone_mgmt(inode, REQ_OP_ZONE_OPEN);
-				if (ret) {
-					atomic_dec(&sbi->s_wro_seq_files);
-					goto unlock;
-				}
-				zi->i_flags |= ZONEFS_ZONE_OPEN;
-				zonefs_account_active(inode);
-			}
-		}
-	}
-
-	zi->i_wr_refcnt++;
-
-unlock:
-	mutex_unlock(&zi->i_truncate_mutex);
-
-	return ret;
-}
-
-static int zonefs_file_open(struct inode *inode, struct file *file)
-{
-	int ret;
-
-	ret = generic_file_open(inode, file);
-	if (ret)
-		return ret;
-
-	if (zonefs_seq_file_need_wro(inode, file))
-		return zonefs_seq_file_write_open(inode);
-
-	return 0;
-}
-
-static void zonefs_seq_file_write_close(struct inode *inode)
-{
-	struct zonefs_inode_info *zi = ZONEFS_I(inode);
-	struct super_block *sb = inode->i_sb;
-	struct zonefs_sb_info *sbi = ZONEFS_SB(sb);
-	int ret = 0;
-
-	mutex_lock(&zi->i_truncate_mutex);
-
-	zi->i_wr_refcnt--;
-	if (zi->i_wr_refcnt)
-		goto unlock;
-
-	/*
-	 * The file zone may not be open anymore (e.g. the file was truncated to
-	 * its maximum size or it was fully written). For this case, we only
-	 * need to decrement the write open count.
-	 */
-	if (zi->i_flags & ZONEFS_ZONE_OPEN) {
-		ret = zonefs_zone_mgmt(inode, REQ_OP_ZONE_CLOSE);
-		if (ret) {
-			__zonefs_io_error(inode, false);
-			/*
-			 * Leaving zones explicitly open may lead to a state
-			 * where most zones cannot be written (zone resources
-			 * exhausted). So take preventive action by remounting
-			 * read-only.
-			 */
-			if (zi->i_flags & ZONEFS_ZONE_OPEN &&
-			    !(sb->s_flags & SB_RDONLY)) {
-				zonefs_warn(sb,
-					"closing zone at %llu failed %d\n",
-					zi->i_zsector, ret);
-				zonefs_warn(sb,
-					"remounting filesystem read-only\n");
-				sb->s_flags |= SB_RDONLY;
-			}
-			goto unlock;
-		}
-
-		zi->i_flags &= ~ZONEFS_ZONE_OPEN;
-		zonefs_account_active(inode);
-	}
-
-	atomic_dec(&sbi->s_wro_seq_files);
-
-unlock:
-	mutex_unlock(&zi->i_truncate_mutex);
-}
-
-static int zonefs_file_release(struct inode *inode, struct file *file)
-{
-	/*
-	 * If we explicitly open a zone we must close it again as well, but the
-	 * zone management operation can fail (either due to an IO error or as
-	 * the zone has gone offline or read-only). Make sure we don't fail the
-	 * close(2) for user-space.
-	 */
-	if (zonefs_seq_file_need_wro(inode, file))
-		zonefs_seq_file_write_close(inode);
-
-	return 0;
-}
-
-static const struct file_operations zonefs_file_operations = {
-	.open		= zonefs_file_open,
-	.release	= zonefs_file_release,
-	.fsync		= zonefs_file_fsync,
-	.mmap		= zonefs_file_mmap,
-	.llseek		= zonefs_file_llseek,
-	.read_iter	= zonefs_file_read_iter,
-	.write_iter	= zonefs_file_write_iter,
-	.splice_read	= generic_file_splice_read,
-	.splice_write	= iter_file_splice_write,
-	.iopoll		= iocb_bio_iopoll,
-};
-
 static struct kmem_cache *zonefs_inode_cachep;
 
 static struct inode *zonefs_alloc_inode(struct super_block *sb)
@@ -1408,13 +505,47 @@ static int zonefs_remount(struct super_block *sb, int *flags, char *data)
 	return zonefs_parse_options(sb, data);
 }
 
-static const struct super_operations zonefs_sops = {
-	.alloc_inode	= zonefs_alloc_inode,
-	.free_inode	= zonefs_free_inode,
-	.statfs		= zonefs_statfs,
-	.remount_fs	= zonefs_remount,
-	.show_options	= zonefs_show_options,
-};
+static int zonefs_inode_setattr(struct user_namespace *mnt_userns,
+				struct dentry *dentry, struct iattr *iattr)
+{
+	struct inode *inode = d_inode(dentry);
+	int ret;
+
+	if (unlikely(IS_IMMUTABLE(inode)))
+		return -EPERM;
+
+	ret = setattr_prepare(&init_user_ns, dentry, iattr);
+	if (ret)
+		return ret;
+
+	/*
+	 * Since files and directories cannot be created nor deleted, do not
+	 * allow setting any write attributes on the sub-directories grouping
+	 * files by zone type.
+	 */
+	if ((iattr->ia_valid & ATTR_MODE) && S_ISDIR(inode->i_mode) &&
+	    (iattr->ia_mode & 0222))
+		return -EPERM;
+
+	if (((iattr->ia_valid & ATTR_UID) &&
+	     !uid_eq(iattr->ia_uid, inode->i_uid)) ||
+	    ((iattr->ia_valid & ATTR_GID) &&
+	     !gid_eq(iattr->ia_gid, inode->i_gid))) {
+		ret = dquot_transfer(mnt_userns, inode, iattr);
+		if (ret)
+			return ret;
+	}
+
+	if (iattr->ia_valid & ATTR_SIZE) {
+		ret = zonefs_file_truncate(inode, iattr->ia_size);
+		if (ret)
+			return ret;
+	}
+
+	setattr_copy(&init_user_ns, inode, iattr);
+
+	return 0;
+}
 
 static const struct inode_operations zonefs_dir_inode_operations = {
 	.lookup		= simple_lookup,
@@ -1434,6 +565,10 @@ static void zonefs_init_dir_inode(struct inode *parent, struct inode *inode,
 	inc_nlink(parent);
 }
 
+static const struct inode_operations zonefs_file_inode_operations = {
+	.setattr	= zonefs_inode_setattr,
+};
+
 static int zonefs_init_file_inode(struct inode *inode, struct blk_zone *zone,
 				  enum zonefs_ztype type)
 {
@@ -1785,6 +920,14 @@ static int zonefs_read_super(struct super_block *sb)
 	return ret;
 }
 
+static const struct super_operations zonefs_sops = {
+	.alloc_inode	= zonefs_alloc_inode,
+	.free_inode	= zonefs_free_inode,
+	.statfs		= zonefs_statfs,
+	.remount_fs	= zonefs_remount,
+	.show_options	= zonefs_show_options,
+};
+
 /*
  * Check that the device is zoned. If it is, get the list of zones and create
  * sub-directories and files according to the device zone configuration and
diff --git a/fs/zonefs/zonefs.h b/fs/zonefs/zonefs.h
index 1dbe78119ff16..839ebe9afb6c1 100644
--- a/fs/zonefs/zonefs.h
+++ b/fs/zonefs/zonefs.h
@@ -209,6 +209,28 @@ static inline struct zonefs_sb_info *ZONEFS_SB(struct super_block *sb)
 #define zonefs_warn(sb, format, args...)	\
 	pr_warn("zonefs (%s) WARNING: " format, sb->s_id, ## args)
 
+/* In super.c */
+void zonefs_account_active(struct inode *inode);
+int zonefs_zone_mgmt(struct inode *inode, enum req_op op);
+void zonefs_i_size_write(struct inode *inode, loff_t isize);
+void zonefs_update_stats(struct inode *inode, loff_t new_isize);
+void __zonefs_io_error(struct inode *inode, bool write);
+
+static inline void zonefs_io_error(struct inode *inode, bool write)
+{
+	struct zonefs_inode_info *zi = ZONEFS_I(inode);
+
+	mutex_lock(&zi->i_truncate_mutex);
+	__zonefs_io_error(inode, write);
+	mutex_unlock(&zi->i_truncate_mutex);
+}
+
+/* In file.c */
+extern const struct address_space_operations zonefs_file_aops;
+extern const struct file_operations zonefs_file_operations;
+int zonefs_file_truncate(struct inode *inode, loff_t isize);
+
+/* In sysfs.c */
 int zonefs_sysfs_register(struct super_block *sb);
 void zonefs_sysfs_unregister(struct super_block *sb);
 int zonefs_sysfs_init(void);
-- 
2.39.2




  parent reply	other threads:[~2023-04-03 14:35 UTC|newest]

Thread overview: 202+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-03 14:07 [PATCH 6.1 000/181] 6.1.23-rc1 review Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 001/181] thunderbolt: Limit USB3 bandwidth of certain Intel USB4 host routers Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 002/181] cifs: update ip_addr for ses only for primary chan setup Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 003/181] cifs: prevent data race in cifs_reconnect_tcon() Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 004/181] cifs: avoid race conditions with parallel reconnects Greg Kroah-Hartman
2023-04-03 14:07 ` Greg Kroah-Hartman [this message]
2023-04-03 14:07 ` [PATCH 6.1 006/181] zonefs: Simplify IO error handling Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 007/181] zonefs: Reduce struct zonefs_inode_info size Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 008/181] zonefs: Separate zone information from inode information Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 009/181] zonefs: Fix error message in zonefs_file_dio_append() Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 010/181] fsverity: dont drop pagecache at end of FS_IOC_ENABLE_VERITY Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 011/181] kernel: kcsan: kcsan_test: build without structleak plugin Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 012/181] kcsan: avoid passing -g for test Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 013/181] btrfs: rename BTRFS_FS_NO_OVERCOMMIT to BTRFS_FS_ACTIVE_ZONE_TRACKING Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 014/181] btrfs: zoned: count fresh BG region as zone unusable Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 015/181] net: ethernet: ti: am65-cpsw/cpts: Fix CPTS release action Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 016/181] riscv: ftrace: Fixup panic by disabling preemption Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 017/181] ARM: dts: aspeed: p10bmc: Update battery node name Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 018/181] drm/msm/dpu: Refactor sc7280_pp location Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 019/181] drm/msm/dpu: correct sm8250 and sm8350 scaler Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 020/181] drm/msm/disp/dpu: fix sc7280_pp base offset Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 021/181] blk-mq: move the srcu_struct used for quiescing to the tagset Greg Kroah-Hartman
2023-04-03 21:06   ` Pascal Ernster
2023-04-04  1:17     ` Ming Lei
2023-04-04  5:56       ` Pascal Ernster
2023-04-04 15:19         ` Sasha Levin
2023-04-04 18:28           ` Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 022/181] blk-mq: fix "bad unlock balance detected" on q->srcu in __blk_mq_run_dispatch_ops Greg Kroah-Hartman
2023-04-03 20:47   ` Pascal Ernster
2023-04-03 14:07 ` [PATCH 6.1 023/181] tty: serial: fsl_lpuart: switch to new dmaengine_terminate_* API Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 024/181] tty: serial: fsl_lpuart: fix race on RX DMA shutdown Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 025/181] tracing: Add .percent suffix option to histogram values Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 026/181] tracing: Add .graph suffix option to histogram value Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 027/181] tracing: Do not let histogram values have some modifiers Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 028/181] net: mscc: ocelot: fix stats region batching Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 029/181] arm64: efi: Set NX compat flag in PE/COFF header Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 030/181] cifs: fix missing unload_nls() in smb2_reconnect() Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 031/181] xfrm: Zero padding when dumping algos and encap Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 032/181] ASoC: codecs: tx-macro: Fix for KASAN: slab-out-of-bounds Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 033/181] ASoC: Intel: avs: max98357a: Explicitly define codec format Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 034/181] ASoC: Intel: avs: da7219: " Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 035/181] ASoC: Intel: avs: ssm4567: Remove nau8825 bits Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 036/181] ASoC: Intel: avs: nau8825: Adjust clock control Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 037/181] zstd: Fix definition of assert() Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 038/181] ACPI: video: Add backlight=native DMI quirk for Dell Vostro 15 3535 Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 039/181] ASoC: SOF: ipc3: Check for upper size limit for the received message Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 040/181] ASoC: SOF: ipc4-topology: Fix incorrect sample rate print unit Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 041/181] ASoC: SOF: Intel: pci-tng: revert invalid bar size setting Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 042/181] ASoC: SOF: IPC4: update gain ipc msg definition to align with fw Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 043/181] md: avoid signed overflow in slot_store() Greg Kroah-Hartman
2023-04-03 14:07 ` [PATCH 6.1 044/181] x86/PVH: obtain VGA console info in Dom0 Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 045/181] drm/amdkfd: Fix BO offset for multi-VMA page migration Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 046/181] drm/amdkfd: fix a potential double free in pqm_create_queue Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 047/181] drm/amdkfd: fix potential kgd_mem UAFs Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 048/181] net: hsr: Dont log netdev_err message on unknown prp dst node Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 049/181] ALSA: asihpi: check pao in control_message() Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 050/181] ALSA: hda/ca0132: fixup buffer overrun at tuning_ctl_set() Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 051/181] fbdev: tgafb: Fix potential divide by zero Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 052/181] ACPI: tools: pfrut: Check if the input of level and type is in the right numeric range Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 053/181] sched_getaffinity: dont assume cpumask_size() is fully initialized Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 054/181] nvme-pci: add NVME_QUIRK_BOGUS_NID for Lexar NM620 Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 055/181] drm/amdkfd: Fixed kfd_process cleanup on module exit Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 056/181] net/mlx5e: Lower maximum allowed MTU in XSK to match XDP prerequisites Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 057/181] fbdev: nvidia: Fix potential divide by zero Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 058/181] fbdev: intelfb: " Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 059/181] fbdev: lxfb: " Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 060/181] fbdev: au1200fb: " Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 061/181] tools/power turbostat: Fix /dev/cpu_dma_latency warnings Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 062/181] tools/power turbostat: fix decoding of HWP_STATUS Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 063/181] tracing: Fix wrong return in kprobe_event_gen_test.c Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 064/181] btrfs: fix uninitialized variable warning in btrfs_update_block_group Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 065/181] btrfs: use temporary variable for space_info " Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 066/181] mtd: rawnand: meson: initialize struct with zeroes Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 067/181] mtd: nand: mxic-ecc: Fix mxic_ecc_data_xfer_wait_for_completion() when irq is used Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 068/181] swiotlb: fix the deadlock in swiotlb_do_find_slots Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 069/181] ca8210: Fix unsigned mac_len comparison with zero in ca8210_skb_tx() Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 070/181] riscv/kvm: Fix VM hang in case of timer delta being zero Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 071/181] mips: bmips: BCM6358: disable RAC flush for TP1 Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 072/181] ALSA: usb-audio: Fix recursive locking at XRUN during syncing Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 073/181] PCI: dwc: Fix PORT_LINK_CONTROL update when CDM check enabled Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 074/181] swiotlb: fix slot alignment checks Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 075/181] platform/x86: think-lmi: add missing type attribute Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 076/181] platform/x86: think-lmi: use correct possible_values delimiters Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 077/181] platform/x86: think-lmi: only display possible_values if available Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 078/181] platform/x86: think-lmi: Add possible_values for ThinkStation Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 079/181] platform/surface: aggregator: Add missing fwnode_handle_put() Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 080/181] mtd: rawnand: meson: invalidate cache on polling ECC bit Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 081/181] SUNRPC: fix shutdown of NFS TCP client socket Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 082/181] sfc: ef10: dont overwrite offload features at NIC reset Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 083/181] scsi: megaraid_sas: Fix crash after a double completion Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 084/181] scsi: mpt3sas: Dont print sense pool info twice Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 085/181] net: dsa: realtek: fix out-of-bounds access Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 086/181] ptp_qoriq: fix memory leak in probe() Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 087/181] net: dsa: microchip: ksz8: fix ksz8_fdb_dump() Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 088/181] net: dsa: microchip: ksz8: fix ksz8_fdb_dump() to extract all 1024 entries Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 089/181] net: dsa: microchip: ksz8: fix offset for the timestamp filed Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 090/181] net: dsa: microchip: ksz8: ksz8_fdb_dump: avoid extracting ghost entry from empty dynamic MAC table Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 091/181] net: dsa: microchip: ksz8863_smi: fix bulk access Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 092/181] net: dsa: microchip: ksz8: fix MDB configuration with non-zero VID Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 093/181] r8169: fix RTL8168H and RTL8107E rx crc error Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 094/181] regulator: Handle deferred clk Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 095/181] net/net_failover: fix txq exceeding warning Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 096/181] net: stmmac: dont reject VLANs when IFF_PROMISC is set Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 097/181] drm/i915/tc: Fix the ICL PHY ownership check in TC-cold state Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 098/181] platform/x86/intel/pmc: Alder Lake PCH slp_s0_residency fix Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 099/181] can: bcm: bcm_tx_setup(): fix KMSAN uninit-value in vfs_write Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 100/181] s390/vfio-ap: fix memory leak in vfio_ap device driver Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 101/181] ACPI: bus: Rework system-level device notification handling Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 102/181] loop: LOOP_CONFIGURE: send uevents for partitions Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 103/181] net: mvpp2: classifier flow fix fragmentation flags Greg Kroah-Hartman
2023-04-03 14:08 ` [PATCH 6.1 104/181] net: mvpp2: parser fix QinQ Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 105/181] net: mvpp2: parser fix PPPoE Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 106/181] smsc911x: avoid PHY being resumed when interface is not up Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 107/181] ice: Fix ice_cfg_rdma_fltr() to only update relevant fields Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 108/181] ice: add profile conflict check for AVF FDIR Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 109/181] ice: fix invalid check for empty list in ice_sched_assoc_vsi_to_agg() Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 110/181] ALSA: ymfpci: Create card with device-managed snd_devm_card_new() Greg Kroah-Hartman
2023-08-23 13:58   ` Takashi Yano
2023-08-23 14:15     ` Takashi Iwai
2023-08-23 15:45       ` Takashi Yano
2023-08-23 16:13         ` Takashi Iwai
2023-04-03 14:09 ` [PATCH 6.1 111/181] ALSA: ymfpci: Fix BUG_ON in probe function Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 112/181] net: ipa: compute DMA pool size properly Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 113/181] i40e: fix registers dump after run ethtool adapter self test Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 114/181] bnxt_en: Fix reporting of test result in ethtool selftest Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 115/181] bnxt_en: Fix typo in PCI id to device description string mapping Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 116/181] bnxt_en: Add missing 200G link speed reporting Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 117/181] net: dsa: mv88e6xxx: Enable IGMP snooping on user ports only Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 118/181] net: ethernet: mtk_eth_soc: fix flow block refcounting logic Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 119/181] net: ethernet: mtk_eth_soc: add missing ppe cache flush when deleting a flow Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 120/181] pinctrl: ocelot: Fix alt mode for ocelot Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 121/181] Input: xpad - fix incorrectly applied patch for MAP_PROFILE_BUTTON Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 122/181] iommu/vt-d: Allow zero SAGAW if second-stage not supported Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 123/181] Input: i8042 - add TUXEDO devices to i8042 quirk tables for partial fix Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 124/181] Input: alps - fix compatibility with -funsigned-char Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 125/181] Input: focaltech - use explicitly signed char type Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 126/181] cifs: prevent infinite recursion in CIFSGetDFSRefer() Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 127/181] cifs: fix DFS traversal oops without CONFIG_CIFS_DFS_UPCALL Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 128/181] Input: i8042 - add quirk for Fujitsu Lifebook A574/H Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 129/181] Input: goodix - add Lenovo Yoga Book X90F to nine_bytes_report DMI table Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 130/181] btrfs: fix deadlock when aborting transaction during relocation with scrub Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 131/181] btrfs: fix race between quota disable and quota assign ioctls Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 132/181] btrfs: scan device in non-exclusive mode Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 133/181] zonefs: Do not propagate iomap_dio_rw() ENOTBLK error to user space Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 134/181] block/io_uring: pass in issue_flags for uring_cmd task_work handling Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 135/181] io_uring/poll: clear single/double poll flags on poll arming Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 136/181] io_uring/rsrc: fix rogue rsrc node grabbing Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 137/181] io_uring: fix poll/netmsg alloc caches Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 138/181] vmxnet3: use gro callback when UPT is enabled Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 139/181] zonefs: Always invalidate last cached page on append write Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 140/181] dm: fix __send_duplicate_bios() to always allow for splitting IO Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 141/181] can: j1939: prevent deadlock by moving j1939_sk_errqueue() Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 142/181] xen/netback: dont do grant copy across page boundary Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 143/181] net: phy: dp83869: fix default value for tx-/rx-internal-delay Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 144/181] modpost: Fix processing of CRCs on 32-bit build machines Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 145/181] pinctrl: amd: Disable and mask interrupts on resume Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 146/181] pinctrl: at91-pio4: fix domain name assignment Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 147/181] platform/x86: ideapad-laptop: Stop sending KEY_TOUCHPAD_TOGGLE Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 148/181] powerpc: Dont try to copy PPR for task with NULL pt_regs Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 149/181] powerpc/pseries/vas: Ignore VAS update for DLPAR if copy/paste is not enabled Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 150/181] powerpc/64s: Fix __pte_needs_flush() false positive warning Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 151/181] NFSv4: Fix hangs when recovering open state after a server reboot Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 152/181] ALSA: hda/conexant: Partial revert of a quirk for Lenovo Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 153/181] ALSA: usb-audio: Fix regression on detection of Roland VS-100 Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 154/181] ALSA: hda/realtek: Add quirks for some Clevo laptops Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 155/181] ALSA: hda/realtek: Add quirk for Lenovo ZhaoYang CF4620Z Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 156/181] xtensa: fix KASAN report for show_stack Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 157/181] rcu: Fix rcu_torture_read ftrace event Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 158/181] dt-bindings: mtd: jedec,spi-nor: Document CPOL/CPHA support Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 159/181] s390/uaccess: add missing earlyclobber annotations to __clear_user() Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 160/181] s390: reintroduce expoline dependence to scripts Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 161/181] drm/etnaviv: fix reference leak when mmaping imported buffer Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 162/181] drm/amdgpu: allow more APUs to do mode2 reset when go to S4 Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 163/181] drm/amd/display: Add DSC Support for Synaptics Cascaded MST Hub Greg Kroah-Hartman
2023-04-03 14:09 ` [PATCH 6.1 164/181] drm/amd/display: Take FEC Overhead into Timeslot Calculation Greg Kroah-Hartman
2023-04-03 14:10 ` [PATCH 6.1 165/181] drm/i915/gem: Flush lmem contents after construction Greg Kroah-Hartman
2023-04-03 14:10 ` [PATCH 6.1 166/181] drm/i915/dpt: Treat the DPT BO as a framebuffer Greg Kroah-Hartman
2023-04-03 14:10 ` [PATCH 6.1 167/181] drm/i915: Disable DC states for all commits Greg Kroah-Hartman
2023-04-03 14:10 ` [PATCH 6.1 168/181] drm/i915: Move CSC load back into .color_commit_arm() when PSR is enabled on skl/glk Greg Kroah-Hartman
2023-04-03 14:10 ` [PATCH 6.1 169/181] KVM: arm64: PMU: Fix GET_ONE_REG for vPMC regs to return the current value Greg Kroah-Hartman
2023-04-03 14:10 ` [PATCH 6.1 170/181] KVM: arm64: Disable interrupts while walking userspace PTs Greg Kroah-Hartman
2023-04-03 14:10 ` [PATCH 6.1 171/181] net: dsa: mv88e6xxx: read FID when handling ATU violations Greg Kroah-Hartman
2023-04-03 14:10 ` [PATCH 6.1 172/181] net: dsa: mv88e6xxx: replace ATU violation prints with trace points Greg Kroah-Hartman
2023-04-03 14:10 ` [PATCH 6.1 173/181] net: dsa: mv88e6xxx: replace VTU " Greg Kroah-Hartman
2023-04-03 14:10 ` [PATCH 6.1 174/181] selftests/bpf: Test btf dump for struct with padding only fields Greg Kroah-Hartman
2023-04-03 14:10 ` [PATCH 6.1 175/181] libbpf: Fix BTF-to-C converters padding logic Greg Kroah-Hartman
2023-04-03 14:10 ` [PATCH 6.1 176/181] selftests/bpf: Add few corner cases to test padding handling of btf_dump Greg Kroah-Hartman
2023-04-03 14:10 ` [PATCH 6.1 177/181] libbpf: Fix btf_dumps packed struct determination Greg Kroah-Hartman
2023-04-03 14:10 ` [PATCH 6.1 178/181] usb: ucsi: Fix ucsi->connector race Greg Kroah-Hartman
2023-04-03 14:10 ` [PATCH 6.1 179/181] drm/amdkfd: Get prange->offset after svm_range_vram_node_new Greg Kroah-Hartman
2023-04-03 14:10 ` [PATCH 6.1 180/181] hsr: ratelimit only when errors are printed Greg Kroah-Hartman
2023-04-03 14:10 ` [PATCH 6.1 181/181] x86/PVH: avoid 32-bit build warning when obtaining VGA console info Greg Kroah-Hartman
2023-04-03 19:28 ` [PATCH 6.1 000/181] 6.1.23-rc1 review Markus Reichelt
2023-04-03 22:54 ` Shuah Khan
2023-04-03 23:21 ` ogasawara takeshi
2023-04-04  0:12 ` Wang Yugui
2023-04-04  2:06 ` Florian Fainelli
2023-04-04  2:40 ` Bagas Sanjaya
2023-04-04 10:46 ` Chris Paterson
2023-04-04 10:51 ` Conor Dooley
2023-04-04 13:01 ` Naresh Kamboju
2023-04-04 21:23 ` Guenter Roeck

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230403140415.274475813@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=damien.lemoal@opensource.wdc.com \
    --cc=johannes.thumshirn@wdc.com \
    --cc=patches@lists.linux.dev \
    --cc=sashal@kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox