NFS: Convert buffered read paths to use netfs when fscache is enabled
[linux-block.git] / fs / nfs / read.c
index 8cb9e8d3c51dcb214fc15177d1280c5004de10f9..f71eeee67e201de2285d5998f92390359d542d7a 100644 (file)
@@ -31,7 +31,7 @@
 
 #define NFSDBG_FACILITY                NFSDBG_PAGECACHE
 
-static const struct nfs_pgio_completion_ops nfs_async_read_completion_ops;
+const struct nfs_pgio_completion_ops nfs_async_read_completion_ops;
 static const struct nfs_rw_ops nfs_rw_read_ops;
 
 static struct kmem_cache *nfs_rdata_cachep;
@@ -74,7 +74,7 @@ void nfs_pageio_init_read(struct nfs_pageio_descriptor *pgio,
 }
 EXPORT_SYMBOL_GPL(nfs_pageio_init_read);
 
-static void nfs_pageio_complete_read(struct nfs_pageio_descriptor *pgio)
+void nfs_pageio_complete_read(struct nfs_pageio_descriptor *pgio)
 {
        struct nfs_pgio_mirror *pgm;
        unsigned long npages;
@@ -110,20 +110,14 @@ EXPORT_SYMBOL_GPL(nfs_pageio_reset_read_mds);
 
 static void nfs_readpage_release(struct nfs_page *req, int error)
 {
-       struct inode *inode = d_inode(nfs_req_openctx(req)->dentry);
        struct folio *folio = nfs_page_to_folio(req);
 
-       dprintk("NFS: read done (%s/%llu %d@%lld)\n", inode->i_sb->s_id,
-               (unsigned long long)NFS_FILEID(inode), req->wb_bytes,
-               (long long)req_offset(req));
-
        if (nfs_error_is_fatal_on_server(error) && error != -ETIMEDOUT)
                folio_set_error(folio);
-       if (nfs_page_group_sync_on_bit(req, PG_UNLOCKPAGE)) {
-               if (folio_test_uptodate(folio))
-                       nfs_fscache_write_page(inode, &folio->page);
-               folio_unlock(folio);
-       }
+       if (nfs_page_group_sync_on_bit(req, PG_UNLOCKPAGE))
+               if (nfs_netfs_folio_unlock(folio))
+                       folio_unlock(folio);
+
        nfs_release_request(req);
 }
 
@@ -177,6 +171,8 @@ static void nfs_read_completion(struct nfs_pgio_header *hdr)
                nfs_list_remove_request(req);
                nfs_readpage_release(req, error);
        }
+       nfs_netfs_read_completion(hdr);
+
 out:
        hdr->release(hdr);
 }
@@ -187,6 +183,7 @@ static void nfs_initiate_read(struct nfs_pgio_header *hdr,
                              struct rpc_task_setup *task_setup_data, int how)
 {
        rpc_ops->read_setup(hdr, msg);
+       nfs_netfs_initiate_read(hdr);
        trace_nfs_initiate_read(hdr);
 }
 
@@ -202,7 +199,7 @@ nfs_async_read_error(struct list_head *head, int error)
        }
 }
 
-static const struct nfs_pgio_completion_ops nfs_async_read_completion_ops = {
+const struct nfs_pgio_completion_ops nfs_async_read_completion_ops = {
        .error_cleanup = nfs_async_read_error,
        .completion = nfs_read_completion,
 };
@@ -277,9 +274,9 @@ static void nfs_readpage_result(struct rpc_task *task,
                nfs_readpage_retry(task, hdr);
 }
 
-static int nfs_read_add_folio(struct nfs_pageio_descriptor *pgio,
-                             struct nfs_open_context *ctx,
-                             struct folio *folio)
+int nfs_read_add_folio(struct nfs_pageio_descriptor *pgio,
+                      struct nfs_open_context *ctx,
+                      struct folio *folio)
 {
        struct inode *inode = folio_file_mapping(folio)->host;
        struct nfs_server *server = NFS_SERVER(inode);
@@ -295,15 +292,11 @@ static int nfs_read_add_folio(struct nfs_pageio_descriptor *pgio,
 
        aligned_len = min_t(unsigned int, ALIGN(len, rsize), fsize);
 
-       if (!IS_SYNC(inode)) {
-               error = nfs_fscache_read_page(inode, &folio->page);
-               if (error == 0)
-                       goto out_unlock;
-       }
-
        new = nfs_page_create_from_folio(ctx, folio, 0, aligned_len);
-       if (IS_ERR(new))
-               goto out_error;
+       if (IS_ERR(new)) {
+               error = PTR_ERR(new);
+               goto out;
+       }
 
        if (len < fsize)
                folio_zero_segment(folio, len, fsize);
@@ -314,10 +307,6 @@ static int nfs_read_add_folio(struct nfs_pageio_descriptor *pgio,
                goto out;
        }
        return 0;
-out_error:
-       error = PTR_ERR(new);
-out_unlock:
-       folio_unlock(folio);
 out:
        return error;
 }
@@ -356,6 +345,10 @@ int nfs_read_folio(struct file *file, struct folio *folio)
        if (NFS_STALE(inode))
                goto out_unlock;
 
+       ret = nfs_netfs_read_folio(file, folio);
+       if (!ret)
+               goto out;
+
        ctx = get_nfs_open_context(nfs_file_open_context(file));
 
        xchg(&ctx->error, 0);
@@ -364,7 +357,7 @@ int nfs_read_folio(struct file *file, struct folio *folio)
 
        ret = nfs_read_add_folio(&pgio, ctx, folio);
        if (ret)
-               goto out;
+               goto out_put;
 
        nfs_pageio_complete_read(&pgio);
        ret = pgio.pg_error < 0 ? pgio.pg_error : 0;
@@ -373,14 +366,14 @@ int nfs_read_folio(struct file *file, struct folio *folio)
                if (!folio_test_uptodate(folio) && !ret)
                        ret = xchg(&ctx->error, 0);
        }
-out:
+out_put:
        put_nfs_open_context(ctx);
+out:
        trace_nfs_aop_readpage_done(inode, folio, ret);
        return ret;
 out_unlock:
        folio_unlock(folio);
-       trace_nfs_aop_readpage_done(inode, folio, ret);
-       return ret;
+       goto out;
 }
 
 void nfs_readahead(struct readahead_control *ractl)
@@ -401,6 +394,10 @@ void nfs_readahead(struct readahead_control *ractl)
        if (NFS_STALE(inode))
                goto out;
 
+       ret = nfs_netfs_readahead(ractl);
+       if (!ret)
+               goto out;
+
        if (file == NULL) {
                ret = -EBADF;
                ctx = nfs_find_open_context(inode, NULL, FMODE_READ);