Unverified Commit 410f2933 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!10046 nfs: Ensure that the NFS client returns a correct writeback error code

Merge Pull Request from: @ci-robot 
 
PR sync from: Wang Zhaolong <wangzhaolong1@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/ANDQNI7LCLY4OHWPDICWKM6HXZW7G7OL/ 
Backport community mainline patch to make close and writeback return
correct return values:

Scott Mayhew (2):
  nfs: nfs_file_write() should check for writeback errors
  nfs: ensure correct writeback errors are returned on close()

Trond Myklebust (2):
  NFS: Use of mapping_set_error() results in spurious errors
  NFS: Don't report ENOSPC write errors twice

HULK solution to avoid residual error codes:

Wang Zhaolong (1):
  nfs: Ensure write and flush consume writeback errors


-- 
2.34.3
 
https://gitee.com/openeuler/kernel/issues/IACBGS 
 
Link:https://gitee.com/openeuler/kernel/pulls/10046

 

Reviewed-by: default avatarYang Yingliang <yangyingliang@huawei.com>
Signed-off-by: default avatarYang Yingliang <yangyingliang@huawei.com>
parents 6e1993d3 b35c34ed
Loading
Loading
Loading
Loading
+19 −20
Original line number Diff line number Diff line
@@ -148,7 +148,8 @@ nfs_file_flush(struct file *file, fl_owner_t id)
		return 0;

	/* Flush writes to the server and return any errors */
	return nfs_wb_all(inode);
	nfs_wb_all(inode);
	return file_check_and_advance_wb_err(file);
}

ssize_t
@@ -594,22 +595,13 @@ static const struct vm_operations_struct nfs_file_vm_ops = {
	.page_mkwrite = nfs_vm_page_mkwrite,
};

static int nfs_need_check_write(struct file *filp, struct inode *inode)
{
	struct nfs_open_context *ctx;

	ctx = nfs_file_open_context(filp);
	if (nfs_ctx_key_to_expire(ctx, inode))
		return 1;
	return 0;
}

ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
{
	struct file *file = iocb->ki_filp;
	struct inode *inode = file_inode(file);
	unsigned long written = 0;
	ssize_t result;
	int error;

	result = nfs_key_timeout_notify(file, inode);
	if (result)
@@ -629,7 +621,7 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
	if (iocb->ki_flags & IOCB_APPEND) {
		result = nfs_revalidate_file_size(inode, file);
		if (result)
			goto out;
			return result;
	}
	if (iocb->ki_pos > i_size_read(inode))
		nfs_revalidate_mapping(inode, file->f_mapping);
@@ -647,18 +639,25 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)

	written = result;
	iocb->ki_pos += written;
	nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, written);

	result = generic_write_sync(iocb, written);
	if (result < 0)
		goto out;

		return result;
out:
	/* Return error values */
	if (nfs_need_check_write(file, inode)) {
		int err = nfs_wb_all(inode);
		if (err < 0)
			result = err;
	error = file_check_and_advance_wb_err(file);
	switch (error) {
	default:
		break;
	case -EDQUOT:
	case -EFBIG:
	case -ENOSPC:
		nfs_wb_all(inode);
		error = file_check_and_advance_wb_err(file);
	}
	nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, written);
out:
	if (error < 0)
		result = error;
	return result;

out_swapfile:
+2 −1
Original line number Diff line number Diff line
@@ -128,7 +128,8 @@ nfs4_file_flush(struct file *file, fl_owner_t id)
		return filemap_fdatawrite(file->f_mapping);

	/* Flush writes to the server and return any errors */
	return nfs_wb_all(inode);
	nfs_wb_all(inode);
	return file_check_and_advance_wb_err(file);
}

#ifdef CONFIG_NFS_V4_2
+4 −1
Original line number Diff line number Diff line
@@ -311,7 +311,10 @@ static void nfs_mapping_set_error(struct page *page, int error)
	struct address_space *mapping = page_file_mapping(page);

	SetPageError(page);
	mapping_set_error(mapping, error);
	filemap_set_wb_err(mapping, error);
	if (mapping->host)
		errseq_set(&mapping->host->i_sb->s_wb_err,
			   error == -ENOSPC ? -ENOSPC : -EIO);
	nfs_set_pageerror(mapping);
}