]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
NFS: Replace custom error reporting mechanism with generic one
authorTrond Myklebust <trondmy@gmail.com>
Sun, 7 Apr 2019 17:59:05 +0000 (13:59 -0400)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Thu, 25 Apr 2019 18:18:14 +0000 (14:18 -0400)
Replace the NFS custom error reporting mechanism with the generic
mapping_set_error().

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
fs/nfs/file.c
fs/nfs/internal.h
fs/nfs/write.c
include/linux/nfs_fs.h

index f807e8643ae6b03b352997faca0137b912d97518..144e183250c3e100a1f6d930b16c6b5268117939 100644 (file)
@@ -199,13 +199,6 @@ EXPORT_SYMBOL_GPL(nfs_file_mmap);
  * Flush any dirty pages for this process, and check for write errors.
  * The return status from this call provides a reliable indication of
  * whether any write errors occurred for this process.
- *
- * Notice that it clears the NFS_CONTEXT_ERROR_WRITE before synching to
- * disk, but it retrieves and clears ctx->error after synching, despite
- * the two being set at the same time in nfs_context_set_write_error().
- * This is because the former is used to notify the _next_ call to
- * nfs_file_write() that a write error occurred, and hence cause it to
- * fall back to doing a synchronous write.
  */
 static int
 nfs_file_fsync_commit(struct file *file, int datasync)
@@ -220,11 +213,8 @@ nfs_file_fsync_commit(struct file *file, int datasync)
        nfs_inc_stats(inode, NFSIOS_VFSFSYNC);
        do_resend = test_and_clear_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags);
        status = nfs_commit_inode(inode, FLUSH_SYNC);
-       if (test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags)) {
-               ret = xchg(&ctx->error, 0);
-               if (ret)
-                       goto out;
-       }
+       if (status == 0)
+               status = file_check_and_advance_wb_err(file);
        if (status < 0) {
                ret = status;
                goto out;
@@ -245,13 +235,7 @@ 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;
-               }
+               ret = file_write_and_wait_range(file, start, end);
                if (ret != 0)
                        break;
                ret = nfs_file_fsync_commit(file, datasync);
@@ -600,8 +584,7 @@ static int nfs_need_check_write(struct file *filp, struct inode *inode)
        struct nfs_open_context *ctx;
 
        ctx = nfs_file_open_context(filp);
-       if (test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags) ||
-           nfs_ctx_key_to_expire(ctx, inode))
+       if (nfs_ctx_key_to_expire(ctx, inode))
                return 1;
        return 0;
 }
index 3cefd0ed01be3c7dcd1677b3578284eafeb0f6e2..196534634c3a1d8686c75ad756db0f84f5895233 100644 (file)
@@ -773,9 +773,3 @@ static inline bool nfs_error_is_fatal(int err)
        }
 }
 
-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);
-}
index 64cf6a340ba6e3afc08e65bf5255248952fb387b..03cde38ecd310146d18c8ab4f522ff080a7a4292 100644 (file)
@@ -244,6 +244,12 @@ static void nfs_set_pageerror(struct address_space *mapping)
        nfs_zap_mapping(mapping->host, mapping);
 }
 
+static void nfs_mapping_set_error(struct page *page, int error)
+{
+       SetPageError(page);
+       mapping_set_error(page_file_mapping(page), error);
+}
+
 /*
  * nfs_page_group_search_locked
  * @head - head request of page group
@@ -582,9 +588,9 @@ nfs_lock_and_join_requests(struct page *page)
        return ERR_PTR(ret);
 }
 
-static void nfs_write_error_remove_page(struct nfs_page *req)
+static void nfs_write_error(struct nfs_page *req, int error)
 {
-       SetPageError(req->wb_page);
+       nfs_mapping_set_error(req->wb_page, error);
        nfs_end_page_writeback(req);
        nfs_release_request(req);
 }
@@ -608,6 +614,7 @@ nfs_error_is_fatal_on_server(int err)
 static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
                                struct page *page)
 {
+       struct address_space *mapping;
        struct nfs_page *req;
        int ret = 0;
 
@@ -621,19 +628,19 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
        nfs_set_page_writeback(page);
        WARN_ON_ONCE(test_bit(PG_CLEAN, &req->wb_flags));
 
-       ret = req->wb_context->error;
        /* If there is a fatal error that covers this write, just exit */
-       if (nfs_error_is_fatal_on_server(ret))
+       ret = 0;
+       mapping = page_file_mapping(page);
+       if (test_bit(AS_ENOSPC, &mapping->flags) ||
+           test_bit(AS_EIO, &mapping->flags))
                goto out_launder;
 
-       ret = 0;
        if (!nfs_pageio_add_request(pgio, req)) {
                ret = pgio->pg_error;
                /*
                 * Remove the problematic req upon fatal errors on the server
                 */
                if (nfs_error_is_fatal(ret)) {
-                       nfs_context_set_write_error(req->wb_context, ret);
                        if (nfs_error_is_fatal_on_server(ret))
                                goto out_launder;
                } else
@@ -645,7 +652,7 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
 out:
        return ret;
 out_launder:
-       nfs_write_error_remove_page(req);
+       nfs_write_error(req, ret);
        return 0;
 }
 
@@ -998,7 +1005,7 @@ static void nfs_write_completion(struct nfs_pgio_header *hdr)
                if (test_bit(NFS_IOHDR_ERROR, &hdr->flags) &&
                    (hdr->good_bytes < bytes)) {
                        nfs_set_pageerror(page_file_mapping(req->wb_page));
-                       nfs_context_set_write_error(req->wb_context, hdr->error);
+                       nfs_mapping_set_error(req->wb_page, hdr->error);
                        goto remove_req;
                }
                if (nfs_write_need_commit(hdr)) {
@@ -1422,14 +1429,10 @@ static void nfs_async_write_error(struct list_head *head, int error)
        while (!list_empty(head)) {
                req = nfs_list_entry(head->next);
                nfs_list_remove_request(req);
-               if (nfs_error_is_fatal(error)) {
-                       nfs_context_set_write_error(req->wb_context, error);
-                       if (nfs_error_is_fatal_on_server(error)) {
-                               nfs_write_error_remove_page(req);
-                               continue;
-                       }
-               }
-               nfs_redirty_request(req);
+               if (nfs_error_is_fatal(error))
+                       nfs_write_error(req, error);
+               else
+                       nfs_redirty_request(req);
        }
 }
 
@@ -1843,9 +1846,10 @@ static void nfs_commit_release_pages(struct nfs_commit_data *data)
                        req->wb_bytes,
                        (long long)req_offset(req));
                if (status < 0) {
-                       nfs_context_set_write_error(req->wb_context, status);
-                       if (req->wb_page)
+                       if (req->wb_page) {
+                               nfs_mapping_set_error(req->wb_page, status);
                                nfs_inode_remove_request(req);
+                       }
                        dprintk_cont(", error = %d\n", status);
                        goto next;
                }
index 40e30376130bbbd49292ae51a3daca8e0bbd4f47..d363d5765cdf70f850fc28bfb359f82d6f44a9f1 100644 (file)
@@ -76,7 +76,6 @@ struct nfs_open_context {
        fmode_t mode;
 
        unsigned long flags;
-#define NFS_CONTEXT_ERROR_WRITE                (0)
 #define NFS_CONTEXT_RESEND_WRITES      (1)
 #define NFS_CONTEXT_BAD                        (2)
 #define NFS_CONTEXT_UNLOCK     (3)