summaryrefslogtreecommitdiff
path: root/fs/zonefs/file.c
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2024-02-21 03:52:26 +0300
committerMark Brown <broonie@kernel.org>2024-02-21 03:52:26 +0300
commitb96ccdcf9d58ed49a576ee9ad10e94e98b9bbb2e (patch)
tree414c4252cdb2412fca74353af423b818c67c0800 /fs/zonefs/file.c
parent3b4ec34602c562fa8fa59dd8545ac7f3cdfc235e (diff)
parent5b417fe0cded0b5917683398e6519aae8045cd40 (diff)
downloadlinux-b96ccdcf9d58ed49a576ee9ad10e94e98b9bbb2e.tar.xz
ASoC: Intel: avs: Fixes and new platforms support
Merge series from Cezary Rojewski <cezary.rojewski@intel.com>: The avs-driver continues to be utilized on more recent Intel machines. As TGL-based (cAVS 2.5) e.g.: RPL, inherit most of the functionality from previous platforms: SKL <- APL <- CNL <- ICL <- TGL rather than putting everything into a single file, the platform-specific bits are split into cnl/icl/tgl.c files instead. Makes the division clear and code easier to maintain. Layout of the patchset: First are two changes combined together address the sound-clipping problem, present when only one stream is running - specifically one CAPTURE stream. Follow up is naming-scheme adjustment for some of the existing functions what improves code incohesiveness. As existing IPC/IRQ code operates solely on cAVS 1.5 architecture, it needs no abstraction. The situation changes when newer platforms come into the picture. Thus the next two patches abstract the existing IPC/IRQ handlers so that majority of the common code can be re-used. The ICCMAX change stands out a bit - the AudioDSP firmware loading procedure differs on ICL-based platforms (and onwards) and having a separate commit makes the situation clear to the developers who are going to support the solution from LTS perspective. For that reason I decided not to merge it into the commit introducing the icl.c file.
Diffstat (limited to 'fs/zonefs/file.c')
-rw-r--r--fs/zonefs/file.c42
1 files changed, 27 insertions, 15 deletions
diff --git a/fs/zonefs/file.c b/fs/zonefs/file.c
index 6ab2318a9c8e..dba5dcb62bef 100644
--- a/fs/zonefs/file.c
+++ b/fs/zonefs/file.c
@@ -348,7 +348,12 @@ static int zonefs_file_write_dio_end_io(struct kiocb *iocb, ssize_t size,
struct zonefs_inode_info *zi = ZONEFS_I(inode);
if (error) {
- zonefs_io_error(inode, true);
+ /*
+ * For Sync IOs, error recovery is called from
+ * zonefs_file_dio_write().
+ */
+ if (!is_sync_kiocb(iocb))
+ zonefs_io_error(inode, true);
return error;
}
@@ -491,6 +496,14 @@ static ssize_t zonefs_file_dio_write(struct kiocb *iocb, struct iov_iter *from)
ret = -EINVAL;
goto inode_unlock;
}
+ /*
+ * Advance the zone write pointer offset. This assumes that the
+ * IO will succeed, which is OK to do because we do not allow
+ * partial writes (IOMAP_DIO_PARTIAL is not set) and if the IO
+ * fails, the error path will correct the write pointer offset.
+ */
+ z->z_wpoffset += count;
+ zonefs_inode_account_active(inode);
mutex_unlock(&zi->i_truncate_mutex);
}
@@ -504,20 +517,19 @@ static ssize_t zonefs_file_dio_write(struct kiocb *iocb, struct iov_iter *from)
if (ret == -ENOTBLK)
ret = -EBUSY;
- if (zonefs_zone_is_seq(z) &&
- (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);
- z->z_wpoffset += count;
- zonefs_inode_account_active(inode);
- mutex_unlock(&zi->i_truncate_mutex);
+ /*
+ * For a failed IO or partial completion, trigger error recovery
+ * to update the zone write pointer offset to a correct value.
+ * For asynchronous IOs, zonefs_file_write_dio_end_io() may already
+ * have executed error recovery if the IO already completed when we
+ * reach here. However, we cannot know that and execute error recovery
+ * again (that will not change anything).
+ */
+ if (zonefs_zone_is_seq(z)) {
+ if (ret > 0 && ret != count)
+ ret = -EIO;
+ if (ret < 0 && ret != -EIOCBQUEUED)
+ zonefs_io_error(inode, true);
}
inode_unlock: