LCOV - code coverage report
Current view: top level - fs/nfs - read.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 3 236 1.3 %
Date: 2022-03-28 15:32:58 Functions: 1 19 5.3 %
Branches: 1 122 0.8 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-only
       2                 :            : /*
       3                 :            :  * linux/fs/nfs/read.c
       4                 :            :  *
       5                 :            :  * Block I/O for NFS
       6                 :            :  *
       7                 :            :  * Partial copy of Linus' read cache modifications to fs/nfs/file.c
       8                 :            :  * modified for async RPC by okir@monad.swb.de
       9                 :            :  */
      10                 :            : 
      11                 :            : #include <linux/time.h>
      12                 :            : #include <linux/kernel.h>
      13                 :            : #include <linux/errno.h>
      14                 :            : #include <linux/fcntl.h>
      15                 :            : #include <linux/stat.h>
      16                 :            : #include <linux/mm.h>
      17                 :            : #include <linux/slab.h>
      18                 :            : #include <linux/pagemap.h>
      19                 :            : #include <linux/sunrpc/clnt.h>
      20                 :            : #include <linux/nfs_fs.h>
      21                 :            : #include <linux/nfs_page.h>
      22                 :            : #include <linux/module.h>
      23                 :            : 
      24                 :            : #include "nfs4_fs.h"
      25                 :            : #include "internal.h"
      26                 :            : #include "iostat.h"
      27                 :            : #include "fscache.h"
      28                 :            : #include "pnfs.h"
      29                 :            : #include "nfstrace.h"
      30                 :            : 
      31                 :            : #define NFSDBG_FACILITY         NFSDBG_PAGECACHE
      32                 :            : 
      33                 :            : static const struct nfs_pgio_completion_ops nfs_async_read_completion_ops;
      34                 :            : static const struct nfs_rw_ops nfs_rw_read_ops;
      35                 :            : 
      36                 :            : static struct kmem_cache *nfs_rdata_cachep;
      37                 :            : 
      38                 :          0 : static struct nfs_pgio_header *nfs_readhdr_alloc(void)
      39                 :            : {
      40                 :          0 :         struct nfs_pgio_header *p = kmem_cache_zalloc(nfs_rdata_cachep, GFP_KERNEL);
      41                 :            : 
      42         [ #  # ]:          0 :         if (p)
      43                 :          0 :                 p->rw_mode = FMODE_READ;
      44                 :          0 :         return p;
      45                 :            : }
      46                 :            : 
      47                 :          0 : static void nfs_readhdr_free(struct nfs_pgio_header *rhdr)
      48                 :            : {
      49                 :          0 :         kmem_cache_free(nfs_rdata_cachep, rhdr);
      50                 :          0 : }
      51                 :            : 
      52                 :            : static
      53                 :          0 : int nfs_return_empty_page(struct page *page)
      54                 :            : {
      55                 :          0 :         zero_user(page, 0, PAGE_SIZE);
      56                 :          0 :         SetPageUptodate(page);
      57                 :          0 :         unlock_page(page);
      58                 :          0 :         return 0;
      59                 :            : }
      60                 :            : 
      61                 :          0 : void nfs_pageio_init_read(struct nfs_pageio_descriptor *pgio,
      62                 :            :                               struct inode *inode, bool force_mds,
      63                 :            :                               const struct nfs_pgio_completion_ops *compl_ops)
      64                 :            : {
      65                 :          0 :         struct nfs_server *server = NFS_SERVER(inode);
      66                 :          0 :         const struct nfs_pageio_ops *pg_ops = &nfs_pgio_rw_ops;
      67                 :            : 
      68                 :            : #ifdef CONFIG_NFS_V4_1
      69                 :            :         if (server->pnfs_curr_ld && !force_mds)
      70                 :            :                 pg_ops = server->pnfs_curr_ld->pg_read_ops;
      71                 :            : #endif
      72                 :          0 :         nfs_pageio_init(pgio, inode, pg_ops, compl_ops, &nfs_rw_read_ops,
      73                 :          0 :                         server->rsize, 0);
      74                 :          0 : }
      75                 :            : EXPORT_SYMBOL_GPL(nfs_pageio_init_read);
      76                 :            : 
      77                 :          0 : void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio)
      78                 :            : {
      79                 :          0 :         struct nfs_pgio_mirror *mirror;
      80                 :            : 
      81   [ #  #  #  # ]:          0 :         if (pgio->pg_ops && pgio->pg_ops->pg_cleanup)
      82                 :          0 :                 pgio->pg_ops->pg_cleanup(pgio);
      83                 :            : 
      84                 :          0 :         pgio->pg_ops = &nfs_pgio_rw_ops;
      85                 :            : 
      86                 :            :         /* read path should never have more than one mirror */
      87         [ #  # ]:          0 :         WARN_ON_ONCE(pgio->pg_mirror_count != 1);
      88                 :            : 
      89                 :          0 :         mirror = &pgio->pg_mirrors[0];
      90                 :          0 :         mirror->pg_bsize = NFS_SERVER(pgio->pg_inode)->rsize;
      91                 :          0 : }
      92                 :            : EXPORT_SYMBOL_GPL(nfs_pageio_reset_read_mds);
      93                 :            : 
      94                 :          0 : static void nfs_readpage_release(struct nfs_page *req, int error)
      95                 :            : {
      96         [ #  # ]:          0 :         struct inode *inode = d_inode(nfs_req_openctx(req)->dentry);
      97                 :          0 :         struct page *page = req->wb_page;
      98                 :            : 
      99                 :          0 :         dprintk("NFS: read done (%s/%llu %d@%lld)\n", inode->i_sb->s_id,
     100                 :            :                 (unsigned long long)NFS_FILEID(inode), req->wb_bytes,
     101                 :            :                 (long long)req_offset(req));
     102                 :            : 
     103   [ #  #  #  # ]:          0 :         if (nfs_error_is_fatal_on_server(error) && error != -ETIMEDOUT)
     104         [ #  # ]:          0 :                 SetPageError(page);
     105         [ #  # ]:          0 :         if (nfs_page_group_sync_on_bit(req, PG_UNLOCKPAGE)) {
     106                 :          0 :                 struct address_space *mapping = page_file_mapping(page);
     107                 :            : 
     108         [ #  # ]:          0 :                 if (PageUptodate(page))
     109                 :            :                         nfs_readpage_to_fscache(inode, page, 0);
     110   [ #  #  #  #  :          0 :                 else if (!PageError(page) && !PagePrivate(page))
                   #  # ]
     111                 :          0 :                         generic_error_remove_page(mapping, page);
     112                 :          0 :                 unlock_page(page);
     113                 :            :         }
     114                 :          0 :         nfs_release_request(req);
     115                 :          0 : }
     116                 :            : 
     117                 :          0 : int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode,
     118                 :            :                        struct page *page)
     119                 :            : {
     120                 :          0 :         struct nfs_page *new;
     121                 :          0 :         unsigned int len;
     122                 :          0 :         struct nfs_pageio_descriptor pgio;
     123                 :          0 :         struct nfs_pgio_mirror *pgm;
     124                 :            : 
     125                 :          0 :         len = nfs_page_length(page);
     126         [ #  # ]:          0 :         if (len == 0)
     127                 :          0 :                 return nfs_return_empty_page(page);
     128                 :          0 :         new = nfs_create_request(ctx, page, 0, len);
     129         [ #  # ]:          0 :         if (IS_ERR(new)) {
     130                 :          0 :                 unlock_page(page);
     131                 :          0 :                 return PTR_ERR(new);
     132                 :            :         }
     133         [ #  # ]:          0 :         if (len < PAGE_SIZE)
     134                 :          0 :                 zero_user_segment(page, len, PAGE_SIZE);
     135                 :            : 
     136                 :          0 :         nfs_pageio_init_read(&pgio, inode, false,
     137                 :            :                              &nfs_async_read_completion_ops);
     138         [ #  # ]:          0 :         if (!nfs_pageio_add_request(&pgio, new)) {
     139         [ #  # ]:          0 :                 nfs_list_remove_request(new);
     140                 :          0 :                 nfs_readpage_release(new, pgio.pg_error);
     141                 :            :         }
     142                 :          0 :         nfs_pageio_complete(&pgio);
     143                 :            : 
     144                 :            :         /* It doesn't make sense to do mirrored reads! */
     145         [ #  # ]:          0 :         WARN_ON_ONCE(pgio.pg_mirror_count != 1);
     146                 :            : 
     147                 :          0 :         pgm = &pgio.pg_mirrors[0];
     148                 :          0 :         NFS_I(inode)->read_io += pgm->pg_bytes_written;
     149                 :            : 
     150                 :          0 :         return pgio.pg_error < 0 ? pgio.pg_error : 0;
     151                 :            : }
     152                 :            : 
     153                 :          0 : static void nfs_page_group_set_uptodate(struct nfs_page *req)
     154                 :            : {
     155         [ #  # ]:          0 :         if (nfs_page_group_sync_on_bit(req, PG_UPTODATE))
     156                 :          0 :                 SetPageUptodate(req->wb_page);
     157                 :          0 : }
     158                 :            : 
     159                 :          0 : static void nfs_read_completion(struct nfs_pgio_header *hdr)
     160                 :            : {
     161                 :          0 :         unsigned long bytes = 0;
     162                 :          0 :         int error;
     163                 :            : 
     164         [ #  # ]:          0 :         if (test_bit(NFS_IOHDR_REDO, &hdr->flags))
     165                 :          0 :                 goto out;
     166         [ #  # ]:          0 :         while (!list_empty(&hdr->pages)) {
     167                 :          0 :                 struct nfs_page *req = nfs_list_entry(hdr->pages.next);
     168                 :          0 :                 struct page *page = req->wb_page;
     169                 :          0 :                 unsigned long start = req->wb_pgbase;
     170                 :          0 :                 unsigned long end = req->wb_pgbase + req->wb_bytes;
     171                 :            : 
     172         [ #  # ]:          0 :                 if (test_bit(NFS_IOHDR_EOF, &hdr->flags)) {
     173                 :            :                         /* note: regions of the page not covered by a
     174                 :            :                          * request are zeroed in nfs_readpage_async /
     175                 :            :                          * readpage_async_filler */
     176         [ #  # ]:          0 :                         if (bytes > hdr->good_bytes) {
     177                 :            :                                 /* nothing in this request was good, so zero
     178                 :            :                                  * the full extent of the request */
     179                 :          0 :                                 zero_user_segment(page, start, end);
     180                 :            : 
     181         [ #  # ]:          0 :                         } else if (hdr->good_bytes - bytes < req->wb_bytes) {
     182                 :            :                                 /* part of this request has good bytes, but
     183                 :            :                                  * not all. zero the bad bytes */
     184                 :          0 :                                 start += hdr->good_bytes - bytes;
     185         [ #  # ]:          0 :                                 WARN_ON(start < req->wb_pgbase);
     186                 :          0 :                                 zero_user_segment(page, start, end);
     187                 :            :                         }
     188                 :            :                 }
     189                 :          0 :                 error = 0;
     190                 :          0 :                 bytes += req->wb_bytes;
     191         [ #  # ]:          0 :                 if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) {
     192         [ #  # ]:          0 :                         if (bytes <= hdr->good_bytes)
     193                 :          0 :                                 nfs_page_group_set_uptodate(req);
     194                 :            :                         else {
     195                 :          0 :                                 error = hdr->error;
     196                 :          0 :                                 xchg(&nfs_req_openctx(req)->error, error);
     197                 :            :                         }
     198                 :            :                 } else
     199                 :          0 :                         nfs_page_group_set_uptodate(req);
     200         [ #  # ]:          0 :                 nfs_list_remove_request(req);
     201                 :          0 :                 nfs_readpage_release(req, error);
     202                 :            :         }
     203                 :          0 : out:
     204                 :          0 :         hdr->release(hdr);
     205                 :          0 : }
     206                 :            : 
     207                 :          0 : static void nfs_initiate_read(struct nfs_pgio_header *hdr,
     208                 :            :                               struct rpc_message *msg,
     209                 :            :                               const struct nfs_rpc_ops *rpc_ops,
     210                 :            :                               struct rpc_task_setup *task_setup_data, int how)
     211                 :            : {
     212                 :          0 :         struct inode *inode = hdr->inode;
     213         [ #  # ]:          0 :         int swap_flags = IS_SWAPFILE(inode) ? NFS_RPC_SWAPFLAGS : 0;
     214                 :            : 
     215                 :          0 :         task_setup_data->flags |= swap_flags;
     216                 :          0 :         rpc_ops->read_setup(hdr, msg);
     217                 :          0 :         trace_nfs_initiate_read(hdr);
     218                 :          0 : }
     219                 :            : 
     220                 :            : static void
     221                 :          0 : nfs_async_read_error(struct list_head *head, int error)
     222                 :            : {
     223                 :          0 :         struct nfs_page *req;
     224                 :            : 
     225         [ #  # ]:          0 :         while (!list_empty(head)) {
     226         [ #  # ]:          0 :                 req = nfs_list_entry(head->next);
     227         [ #  # ]:          0 :                 nfs_list_remove_request(req);
     228                 :          0 :                 nfs_readpage_release(req, error);
     229                 :            :         }
     230                 :          0 : }
     231                 :            : 
     232                 :            : static const struct nfs_pgio_completion_ops nfs_async_read_completion_ops = {
     233                 :            :         .error_cleanup = nfs_async_read_error,
     234                 :            :         .completion = nfs_read_completion,
     235                 :            : };
     236                 :            : 
     237                 :            : /*
     238                 :            :  * This is the callback from RPC telling us whether a reply was
     239                 :            :  * received or some error occurred (timeout or socket shutdown).
     240                 :            :  */
     241                 :          0 : static int nfs_readpage_done(struct rpc_task *task,
     242                 :            :                              struct nfs_pgio_header *hdr,
     243                 :            :                              struct inode *inode)
     244                 :            : {
     245                 :          0 :         int status = NFS_PROTO(inode)->read_done(task, hdr);
     246         [ #  # ]:          0 :         if (status != 0)
     247                 :            :                 return status;
     248                 :            : 
     249         [ #  # ]:          0 :         nfs_add_stats(inode, NFSIOS_SERVERREADBYTES, hdr->res.count);
     250                 :          0 :         trace_nfs_readpage_done(task, hdr);
     251                 :            : 
     252         [ #  # ]:          0 :         if (task->tk_status == -ESTALE) {
     253                 :          0 :                 set_bit(NFS_INO_STALE, &NFS_I(inode)->flags);
     254                 :          0 :                 nfs_mark_for_revalidate(inode);
     255                 :            :         }
     256                 :            :         return 0;
     257                 :            : }
     258                 :            : 
     259                 :          0 : static void nfs_readpage_retry(struct rpc_task *task,
     260                 :            :                                struct nfs_pgio_header *hdr)
     261                 :            : {
     262                 :          0 :         struct nfs_pgio_args *argp = &hdr->args;
     263                 :          0 :         struct nfs_pgio_res  *resp = &hdr->res;
     264                 :            : 
     265                 :            :         /* This is a short read! */
     266                 :          0 :         nfs_inc_stats(hdr->inode, NFSIOS_SHORTREAD);
     267                 :            :         /* Has the server at least made some progress? */
     268         [ #  # ]:          0 :         if (resp->count == 0) {
     269                 :          0 :                 nfs_set_pgio_error(hdr, -EIO, argp->offset);
     270                 :          0 :                 return;
     271                 :            :         }
     272                 :            : 
     273                 :            :         /* For non rpc-based layout drivers, retry-through-MDS */
     274         [ #  # ]:          0 :         if (!task->tk_ops) {
     275                 :          0 :                 hdr->pnfs_error = -EAGAIN;
     276                 :          0 :                 return;
     277                 :            :         }
     278                 :            : 
     279                 :            :         /* Yes, so retry the read at the end of the hdr */
     280                 :          0 :         hdr->mds_offset += resp->count;
     281                 :          0 :         argp->offset += resp->count;
     282                 :          0 :         argp->pgbase += resp->count;
     283                 :          0 :         argp->count -= resp->count;
     284                 :          0 :         resp->count = 0;
     285                 :          0 :         resp->eof = 0;
     286                 :          0 :         rpc_restart_call_prepare(task);
     287                 :            : }
     288                 :            : 
     289                 :          0 : static void nfs_readpage_result(struct rpc_task *task,
     290                 :            :                                 struct nfs_pgio_header *hdr)
     291                 :            : {
     292         [ #  # ]:          0 :         if (hdr->res.eof) {
     293                 :          0 :                 loff_t pos = hdr->args.offset + hdr->res.count;
     294                 :          0 :                 unsigned int new = pos - hdr->io_start;
     295                 :            : 
     296         [ #  # ]:          0 :                 if (hdr->good_bytes > new) {
     297                 :          0 :                         hdr->good_bytes = new;
     298                 :          0 :                         set_bit(NFS_IOHDR_EOF, &hdr->flags);
     299                 :          0 :                         clear_bit(NFS_IOHDR_ERROR, &hdr->flags);
     300                 :            :                 }
     301         [ #  # ]:          0 :         } else if (hdr->res.count < hdr->args.count)
     302                 :          0 :                 nfs_readpage_retry(task, hdr);
     303                 :          0 : }
     304                 :            : 
     305                 :            : /*
     306                 :            :  * Read a page over NFS.
     307                 :            :  * We read the page synchronously in the following case:
     308                 :            :  *  -   The error flag is set for this page. This happens only when a
     309                 :            :  *      previous async read operation failed.
     310                 :            :  */
     311                 :          0 : int nfs_readpage(struct file *file, struct page *page)
     312                 :            : {
     313                 :          0 :         struct nfs_open_context *ctx;
     314                 :          0 :         struct inode *inode = page_file_mapping(page)->host;
     315                 :          0 :         int             error;
     316                 :            : 
     317                 :          0 :         dprintk("NFS: nfs_readpage (%p %ld@%lu)\n",
     318                 :            :                 page, PAGE_SIZE, page_index(page));
     319                 :          0 :         nfs_inc_stats(inode, NFSIOS_VFSREADPAGE);
     320                 :          0 :         nfs_add_stats(inode, NFSIOS_READPAGES, 1);
     321                 :            : 
     322                 :            :         /*
     323                 :            :          * Try to flush any pending writes to the file..
     324                 :            :          *
     325                 :            :          * NOTE! Because we own the page lock, there cannot
     326                 :            :          * be any new pending writes generated at this point
     327                 :            :          * for this page (other pages can be written to).
     328                 :            :          */
     329                 :          0 :         error = nfs_wb_page(inode, page);
     330         [ #  # ]:          0 :         if (error)
     331                 :          0 :                 goto out_unlock;
     332         [ #  # ]:          0 :         if (PageUptodate(page))
     333                 :          0 :                 goto out_unlock;
     334                 :            : 
     335                 :          0 :         error = -ESTALE;
     336         [ #  # ]:          0 :         if (NFS_STALE(inode))
     337                 :          0 :                 goto out_unlock;
     338                 :            : 
     339         [ #  # ]:          0 :         if (file == NULL) {
     340                 :          0 :                 error = -EBADF;
     341                 :          0 :                 ctx = nfs_find_open_context(inode, NULL, FMODE_READ);
     342         [ #  # ]:          0 :                 if (ctx == NULL)
     343                 :          0 :                         goto out_unlock;
     344                 :            :         } else
     345                 :          0 :                 ctx = get_nfs_open_context(nfs_file_open_context(file));
     346                 :            : 
     347                 :          0 :         if (!IS_SYNC(inode)) {
     348                 :            :                 error = nfs_readpage_from_fscache(ctx, inode, page);
     349                 :            :                 if (error == 0)
     350                 :            :                         goto out;
     351                 :            :         }
     352                 :            : 
     353                 :          0 :         xchg(&ctx->error, 0);
     354                 :          0 :         error = nfs_readpage_async(ctx, inode, page);
     355         [ #  # ]:          0 :         if (!error) {
     356                 :          0 :                 error = wait_on_page_locked_killable(page);
     357   [ #  #  #  # ]:          0 :                 if (!PageUptodate(page) && !error)
     358                 :          0 :                         error = xchg(&ctx->error, 0);
     359                 :            :         }
     360                 :          0 : out:
     361                 :          0 :         put_nfs_open_context(ctx);
     362                 :          0 :         return error;
     363                 :          0 : out_unlock:
     364                 :          0 :         unlock_page(page);
     365                 :          0 :         return error;
     366                 :            : }
     367                 :            : 
     368                 :            : struct nfs_readdesc {
     369                 :            :         struct nfs_pageio_descriptor *pgio;
     370                 :            :         struct nfs_open_context *ctx;
     371                 :            : };
     372                 :            : 
     373                 :            : static int
     374                 :          0 : readpage_async_filler(void *data, struct page *page)
     375                 :            : {
     376                 :          0 :         struct nfs_readdesc *desc = (struct nfs_readdesc *)data;
     377                 :          0 :         struct nfs_page *new;
     378                 :          0 :         unsigned int len;
     379                 :          0 :         int error;
     380                 :            : 
     381                 :          0 :         len = nfs_page_length(page);
     382         [ #  # ]:          0 :         if (len == 0)
     383                 :          0 :                 return nfs_return_empty_page(page);
     384                 :            : 
     385                 :          0 :         new = nfs_create_request(desc->ctx, page, 0, len);
     386         [ #  # ]:          0 :         if (IS_ERR(new))
     387                 :          0 :                 goto out_error;
     388                 :            : 
     389         [ #  # ]:          0 :         if (len < PAGE_SIZE)
     390                 :          0 :                 zero_user_segment(page, len, PAGE_SIZE);
     391         [ #  # ]:          0 :         if (!nfs_pageio_add_request(desc->pgio, new)) {
     392         [ #  # ]:          0 :                 nfs_list_remove_request(new);
     393                 :          0 :                 error = desc->pgio->pg_error;
     394                 :          0 :                 nfs_readpage_release(new, error);
     395                 :          0 :                 goto out;
     396                 :            :         }
     397                 :            :         return 0;
     398                 :            : out_error:
     399                 :          0 :         error = PTR_ERR(new);
     400                 :          0 :         unlock_page(page);
     401                 :            : out:
     402                 :            :         return error;
     403                 :            : }
     404                 :            : 
     405                 :          0 : int nfs_readpages(struct file *filp, struct address_space *mapping,
     406                 :            :                 struct list_head *pages, unsigned nr_pages)
     407                 :            : {
     408                 :          0 :         struct nfs_pageio_descriptor pgio;
     409                 :          0 :         struct nfs_pgio_mirror *pgm;
     410                 :          0 :         struct nfs_readdesc desc = {
     411                 :            :                 .pgio = &pgio,
     412                 :            :         };
     413                 :          0 :         struct inode *inode = mapping->host;
     414                 :          0 :         unsigned long npages;
     415                 :          0 :         int ret = -ESTALE;
     416                 :            : 
     417                 :          0 :         dprintk("NFS: nfs_readpages (%s/%Lu %d)\n",
     418                 :            :                         inode->i_sb->s_id,
     419                 :            :                         (unsigned long long)NFS_FILEID(inode),
     420                 :            :                         nr_pages);
     421                 :          0 :         nfs_inc_stats(inode, NFSIOS_VFSREADPAGES);
     422                 :            : 
     423         [ #  # ]:          0 :         if (NFS_STALE(inode))
     424                 :          0 :                 goto out;
     425                 :            : 
     426         [ #  # ]:          0 :         if (filp == NULL) {
     427                 :          0 :                 desc.ctx = nfs_find_open_context(inode, NULL, FMODE_READ);
     428         [ #  # ]:          0 :                 if (desc.ctx == NULL)
     429                 :            :                         return -EBADF;
     430                 :            :         } else
     431                 :          0 :                 desc.ctx = get_nfs_open_context(nfs_file_open_context(filp));
     432                 :            : 
     433                 :            :         /* attempt to read as many of the pages as possible from the cache
     434                 :            :          * - this returns -ENOBUFS immediately if the cookie is negative
     435                 :            :          */
     436                 :          0 :         ret = nfs_readpages_from_fscache(desc.ctx, inode, mapping,
     437                 :            :                                          pages, &nr_pages);
     438                 :          0 :         if (ret == 0)
     439                 :            :                 goto read_complete; /* all pages were read */
     440                 :            : 
     441                 :          0 :         nfs_pageio_init_read(&pgio, inode, false,
     442                 :            :                              &nfs_async_read_completion_ops);
     443                 :            : 
     444                 :          0 :         ret = read_cache_pages(mapping, pages, readpage_async_filler, &desc);
     445                 :          0 :         nfs_pageio_complete(&pgio);
     446                 :            : 
     447                 :            :         /* It doesn't make sense to do mirrored reads! */
     448         [ #  # ]:          0 :         WARN_ON_ONCE(pgio.pg_mirror_count != 1);
     449                 :            : 
     450                 :          0 :         pgm = &pgio.pg_mirrors[0];
     451         [ #  # ]:          0 :         NFS_I(inode)->read_io += pgm->pg_bytes_written;
     452                 :          0 :         npages = (pgm->pg_bytes_written + PAGE_SIZE - 1) >>
     453                 :            :                  PAGE_SHIFT;
     454         [ #  # ]:          0 :         nfs_add_stats(inode, NFSIOS_READPAGES, npages);
     455                 :            : read_complete:
     456                 :          0 :         put_nfs_open_context(desc.ctx);
     457                 :            : out:
     458                 :            :         return ret;
     459                 :            : }
     460                 :            : 
     461                 :         28 : int __init nfs_init_readpagecache(void)
     462                 :            : {
     463                 :         28 :         nfs_rdata_cachep = kmem_cache_create("nfs_read_data",
     464                 :            :                                              sizeof(struct nfs_pgio_header),
     465                 :            :                                              0, SLAB_HWCACHE_ALIGN,
     466                 :            :                                              NULL);
     467         [ -  + ]:         28 :         if (nfs_rdata_cachep == NULL)
     468                 :          0 :                 return -ENOMEM;
     469                 :            : 
     470                 :            :         return 0;
     471                 :            : }
     472                 :            : 
     473                 :          0 : void nfs_destroy_readpagecache(void)
     474                 :            : {
     475                 :          0 :         kmem_cache_destroy(nfs_rdata_cachep);
     476                 :          0 : }
     477                 :            : 
     478                 :            : static const struct nfs_rw_ops nfs_rw_read_ops = {
     479                 :            :         .rw_alloc_header        = nfs_readhdr_alloc,
     480                 :            :         .rw_free_header         = nfs_readhdr_free,
     481                 :            :         .rw_done                = nfs_readpage_done,
     482                 :            :         .rw_result              = nfs_readpage_result,
     483                 :            :         .rw_initiate            = nfs_initiate_read,
     484                 :            : };

Generated by: LCOV version 1.14