aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/file.c16
-rw-r--r--fs/nfs/internal.h7
-rw-r--r--fs/nfs/pagelist.c4
-rw-r--r--fs/nfs/write.c7
4 files changed, 19 insertions, 15 deletions
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index a385d1c3f146..0214dd1e1060 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -208,21 +208,19 @@ EXPORT_SYMBOL_GPL(nfs_file_mmap);
* fall back to doing a synchronous write.
*/
static int
-nfs_file_fsync_commit(struct file *file, loff_t start, loff_t end, int datasync)
+nfs_file_fsync_commit(struct file *file, int datasync)
{
struct nfs_open_context *ctx = nfs_file_open_context(file);
struct inode *inode = file_inode(file);
- int have_error, do_resend, status;
+ int do_resend, status;
int ret = 0;
dprintk("NFS: fsync file(%pD2) datasync %d\n", file, datasync);
nfs_inc_stats(inode, NFSIOS_VFSFSYNC);
do_resend = test_and_clear_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags);
- have_error = test_and_clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
status = nfs_commit_inode(inode, FLUSH_SYNC);
- have_error |= test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
- if (have_error) {
+ if (test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags)) {
ret = xchg(&ctx->error, 0);
if (ret)
goto out;
@@ -247,10 +245,16 @@ nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
trace_nfs_fsync_enter(inode);
do {
+ struct nfs_open_context *ctx = nfs_file_open_context(file);
ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
+ if (test_and_clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags)) {
+ int ret2 = xchg(&ctx->error, 0);
+ if (ret2)
+ ret = ret2;
+ }
if (ret != 0)
break;
- ret = nfs_file_fsync_commit(file, start, end, datasync);
+ ret = nfs_file_fsync_commit(file, datasync);
if (!ret)
ret = pnfs_sync_inode(inode, !!datasync);
/*
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 68cc22083639..5bdf952f414b 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -768,3 +768,10 @@ static inline bool nfs_error_is_fatal(int err)
return false;
}
}
+
+static inline void nfs_context_set_write_error(struct nfs_open_context *ctx, int error)
+{
+ ctx->error = error;
+ smp_wmb();
+ set_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
+}
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index bec120ec1967..d0543e19098a 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -1170,8 +1170,8 @@ out_failed:
/* remember fatal errors */
if (nfs_error_is_fatal(desc->pg_error))
- mapping_set_error(desc->pg_inode->i_mapping,
- desc->pg_error);
+ nfs_context_set_write_error(req->wb_context,
+ desc->pg_error);
func = desc->pg_completion_ops->error_cleanup;
for (midx = 0; midx < desc->pg_mirror_count; midx++) {
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index c66206ac4ebf..babebbccae2a 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -145,13 +145,6 @@ static void nfs_io_completion_put(struct nfs_io_completion *ioc)
kref_put(&ioc->refcount, nfs_io_completion_release);
}
-static void nfs_context_set_write_error(struct nfs_open_context *ctx, int error)
-{
- ctx->error = error;
- smp_wmb();
- set_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
-}
-
static struct nfs_page *
nfs_page_private_request(struct page *page)
{