diff options
-rw-r--r-- | fs/nfs/file.c | 16 | ||||
-rw-r--r-- | fs/nfs/internal.h | 7 | ||||
-rw-r--r-- | fs/nfs/pagelist.c | 4 | ||||
-rw-r--r-- | fs/nfs/write.c | 7 |
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); | |||
208 | * fall back to doing a synchronous write. | 208 | * fall back to doing a synchronous write. |
209 | */ | 209 | */ |
210 | static int | 210 | static int |
211 | nfs_file_fsync_commit(struct file *file, loff_t start, loff_t end, int datasync) | 211 | nfs_file_fsync_commit(struct file *file, int datasync) |
212 | { | 212 | { |
213 | struct nfs_open_context *ctx = nfs_file_open_context(file); | 213 | struct nfs_open_context *ctx = nfs_file_open_context(file); |
214 | struct inode *inode = file_inode(file); | 214 | struct inode *inode = file_inode(file); |
215 | int have_error, do_resend, status; | 215 | int do_resend, status; |
216 | int ret = 0; | 216 | int ret = 0; |
217 | 217 | ||
218 | dprintk("NFS: fsync file(%pD2) datasync %d\n", file, datasync); | 218 | dprintk("NFS: fsync file(%pD2) datasync %d\n", file, datasync); |
219 | 219 | ||
220 | nfs_inc_stats(inode, NFSIOS_VFSFSYNC); | 220 | nfs_inc_stats(inode, NFSIOS_VFSFSYNC); |
221 | do_resend = test_and_clear_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags); | 221 | do_resend = test_and_clear_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags); |
222 | have_error = test_and_clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags); | ||
223 | status = nfs_commit_inode(inode, FLUSH_SYNC); | 222 | status = nfs_commit_inode(inode, FLUSH_SYNC); |
224 | have_error |= test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags); | 223 | if (test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags)) { |
225 | if (have_error) { | ||
226 | ret = xchg(&ctx->error, 0); | 224 | ret = xchg(&ctx->error, 0); |
227 | if (ret) | 225 | if (ret) |
228 | goto out; | 226 | goto out; |
@@ -247,10 +245,16 @@ nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync) | |||
247 | trace_nfs_fsync_enter(inode); | 245 | trace_nfs_fsync_enter(inode); |
248 | 246 | ||
249 | do { | 247 | do { |
248 | struct nfs_open_context *ctx = nfs_file_open_context(file); | ||
250 | ret = filemap_write_and_wait_range(inode->i_mapping, start, end); | 249 | ret = filemap_write_and_wait_range(inode->i_mapping, start, end); |
250 | if (test_and_clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags)) { | ||
251 | int ret2 = xchg(&ctx->error, 0); | ||
252 | if (ret2) | ||
253 | ret = ret2; | ||
254 | } | ||
251 | if (ret != 0) | 255 | if (ret != 0) |
252 | break; | 256 | break; |
253 | ret = nfs_file_fsync_commit(file, start, end, datasync); | 257 | ret = nfs_file_fsync_commit(file, datasync); |
254 | if (!ret) | 258 | if (!ret) |
255 | ret = pnfs_sync_inode(inode, !!datasync); | 259 | ret = pnfs_sync_inode(inode, !!datasync); |
256 | /* | 260 | /* |
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) | |||
768 | return false; | 768 | return false; |
769 | } | 769 | } |
770 | } | 770 | } |
771 | |||
772 | static inline void nfs_context_set_write_error(struct nfs_open_context *ctx, int error) | ||
773 | { | ||
774 | ctx->error = error; | ||
775 | smp_wmb(); | ||
776 | set_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags); | ||
777 | } | ||
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: | |||
1170 | 1170 | ||
1171 | /* remember fatal errors */ | 1171 | /* remember fatal errors */ |
1172 | if (nfs_error_is_fatal(desc->pg_error)) | 1172 | if (nfs_error_is_fatal(desc->pg_error)) |
1173 | mapping_set_error(desc->pg_inode->i_mapping, | 1173 | nfs_context_set_write_error(req->wb_context, |
1174 | desc->pg_error); | 1174 | desc->pg_error); |
1175 | 1175 | ||
1176 | func = desc->pg_completion_ops->error_cleanup; | 1176 | func = desc->pg_completion_ops->error_cleanup; |
1177 | for (midx = 0; midx < desc->pg_mirror_count; midx++) { | 1177 | 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) | |||
145 | kref_put(&ioc->refcount, nfs_io_completion_release); | 145 | kref_put(&ioc->refcount, nfs_io_completion_release); |
146 | } | 146 | } |
147 | 147 | ||
148 | static void nfs_context_set_write_error(struct nfs_open_context *ctx, int error) | ||
149 | { | ||
150 | ctx->error = error; | ||
151 | smp_wmb(); | ||
152 | set_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags); | ||
153 | } | ||
154 | |||
155 | static struct nfs_page * | 148 | static struct nfs_page * |
156 | nfs_page_private_request(struct page *page) | 149 | nfs_page_private_request(struct page *page) |
157 | { | 150 | { |