Commit 5702e977 authored by Zhang Yi's avatar Zhang Yi Committed by Long Li
Browse files

iomap: pass blocksize to iomap_truncate_page()

maillist inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I9VTE3
CVE: NA

Reference: https://lore.kernel.org/linux-fsdevel/20240529095206.2568162-1-yi.zhang@huaweicloud.com/



--------------------------------

iomap_truncate_page() always assumes the block size of the truncating
inode is i_blocksize(), this is not always true for some filesystems,
e.g. XFS does extent size alignment for realtime inodes. Drop this
assumption and pass the block size for zeroing into
iomap_truncate_page(), allow filesystems to indicate the correct block
size.

Fixes: fabcdd2d ("fs: xfs: Introduce FORCEALIGN inode flag")
Suggested-by: default avatarDave Chinner <david@fromorbit.com>
Signed-off-by: default avatarZhang Yi <yi.zhang@huawei.com>
Signed-off-by: default avatarLong Li <leo.lilong@huawei.com>
parent e058a3ad
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/bio.h>
#include <linux/sched/signal.h>
#include <linux/migrate.h>
#include <linux/math64.h>
#include "trace.h"

#include "../internal.h"
@@ -1044,11 +1045,10 @@ iomap_zero_range(struct inode *inode, loff_t pos, loff_t len, bool *did_zero,
EXPORT_SYMBOL_GPL(iomap_zero_range);

int
iomap_truncate_page(struct inode *inode, loff_t pos, bool *did_zero,
		const struct iomap_ops *ops)
iomap_truncate_page(struct inode *inode, loff_t pos, unsigned int blocksize,
		bool *did_zero, const struct iomap_ops *ops)
{
	unsigned int blocksize = i_blocksize(inode);
	unsigned int off = pos & (blocksize - 1);
	unsigned int off = rem_u64(pos, blocksize);

	/* Block boundary? Nothing to do */
	if (!off)
+3 −2
Original line number Diff line number Diff line
@@ -769,6 +769,7 @@ xfs_setattr_size(
	int			error;
	uint			lock_flags = 0;
	bool			did_zeroing = false;
	unsigned int            blocksize = i_blocksize(inode);

	ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL));
	ASSERT(xfs_isilocked(ip, XFS_MMAPLOCK_EXCL));
@@ -830,8 +831,8 @@ xfs_setattr_size(
						     newsize);
		if (error)
			return error;
		error = iomap_truncate_page(inode, newsize, &did_zeroing,
				&xfs_buffered_write_iomap_ops);
		error = iomap_truncate_page(inode, newsize, blocksize,
				&did_zeroing, &xfs_buffered_write_iomap_ops);
	}

	if (error)
+2 −2
Original line number Diff line number Diff line
@@ -207,8 +207,8 @@ int iomap_file_unshare(struct inode *inode, loff_t pos, loff_t len,
		const struct iomap_ops *ops);
int iomap_zero_range(struct inode *inode, loff_t pos, loff_t len,
		bool *did_zero, const struct iomap_ops *ops);
int iomap_truncate_page(struct inode *inode, loff_t pos, bool *did_zero,
		const struct iomap_ops *ops);
int iomap_truncate_page(struct inode *inode, loff_t pos, unsigned int blocksize,
		bool *did_zero, const struct iomap_ops *ops);
vm_fault_t iomap_page_mkwrite(struct vm_fault *vmf,
			const struct iomap_ops *ops);
int iomap_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,