LCOV - code coverage report
Current view: top level - fs/nfs - file.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 311 0.0 %
Date: 2022-03-28 15:32:58 Functions: 0 23 0.0 %
Branches: 0 142 0.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-only
       2                 :            : /*
       3                 :            :  *  linux/fs/nfs/file.c
       4                 :            :  *
       5                 :            :  *  Copyright (C) 1992  Rick Sladkey
       6                 :            :  *
       7                 :            :  *  Changes Copyright (C) 1994 by Florian La Roche
       8                 :            :  *   - Do not copy data too often around in the kernel.
       9                 :            :  *   - In nfs_file_read the return value of kmalloc wasn't checked.
      10                 :            :  *   - Put in a better version of read look-ahead buffering. Original idea
      11                 :            :  *     and implementation by Wai S Kok elekokws@ee.nus.sg.
      12                 :            :  *
      13                 :            :  *  Expire cache on write to a file by Wai S Kok (Oct 1994).
      14                 :            :  *
      15                 :            :  *  Total rewrite of read side for new NFS buffer cache.. Linus.
      16                 :            :  *
      17                 :            :  *  nfs regular file handling functions
      18                 :            :  */
      19                 :            : 
      20                 :            : #include <linux/module.h>
      21                 :            : #include <linux/time.h>
      22                 :            : #include <linux/kernel.h>
      23                 :            : #include <linux/errno.h>
      24                 :            : #include <linux/fcntl.h>
      25                 :            : #include <linux/stat.h>
      26                 :            : #include <linux/nfs_fs.h>
      27                 :            : #include <linux/nfs_mount.h>
      28                 :            : #include <linux/mm.h>
      29                 :            : #include <linux/pagemap.h>
      30                 :            : #include <linux/gfp.h>
      31                 :            : #include <linux/swap.h>
      32                 :            : 
      33                 :            : #include <linux/uaccess.h>
      34                 :            : 
      35                 :            : #include "delegation.h"
      36                 :            : #include "internal.h"
      37                 :            : #include "iostat.h"
      38                 :            : #include "fscache.h"
      39                 :            : #include "pnfs.h"
      40                 :            : 
      41                 :            : #include "nfstrace.h"
      42                 :            : 
      43                 :            : #define NFSDBG_FACILITY         NFSDBG_FILE
      44                 :            : 
      45                 :            : static const struct vm_operations_struct nfs_file_vm_ops;
      46                 :            : 
      47                 :            : /* Hack for future NFS swap support */
      48                 :            : #ifndef IS_SWAPFILE
      49                 :            : # define IS_SWAPFILE(inode)     (0)
      50                 :            : #endif
      51                 :            : 
      52                 :          0 : int nfs_check_flags(int flags)
      53                 :            : {
      54         [ #  # ]:          0 :         if ((flags & (O_APPEND | O_DIRECT)) == (O_APPEND | O_DIRECT))
      55                 :          0 :                 return -EINVAL;
      56                 :            : 
      57                 :            :         return 0;
      58                 :            : }
      59                 :            : EXPORT_SYMBOL_GPL(nfs_check_flags);
      60                 :            : 
      61                 :            : /*
      62                 :            :  * Open file
      63                 :            :  */
      64                 :            : static int
      65                 :          0 : nfs_file_open(struct inode *inode, struct file *filp)
      66                 :            : {
      67                 :          0 :         int res;
      68                 :            : 
      69                 :          0 :         dprintk("NFS: open file(%pD2)\n", filp);
      70                 :            : 
      71                 :          0 :         nfs_inc_stats(inode, NFSIOS_VFSOPEN);
      72         [ #  # ]:          0 :         res = nfs_check_flags(filp->f_flags);
      73                 :          0 :         if (res)
      74                 :            :                 return res;
      75                 :            : 
      76                 :          0 :         res = nfs_open(inode, filp);
      77                 :          0 :         return res;
      78                 :            : }
      79                 :            : 
      80                 :            : int
      81                 :          0 : nfs_file_release(struct inode *inode, struct file *filp)
      82                 :            : {
      83                 :          0 :         dprintk("NFS: release(%pD2)\n", filp);
      84                 :            : 
      85                 :          0 :         nfs_inc_stats(inode, NFSIOS_VFSRELEASE);
      86                 :          0 :         nfs_file_clear_open_context(filp);
      87                 :          0 :         return 0;
      88                 :            : }
      89                 :            : EXPORT_SYMBOL_GPL(nfs_file_release);
      90                 :            : 
      91                 :            : /**
      92                 :            :  * nfs_revalidate_size - Revalidate the file size
      93                 :            :  * @inode: pointer to inode struct
      94                 :            :  * @filp: pointer to struct file
      95                 :            :  *
      96                 :            :  * Revalidates the file length. This is basically a wrapper around
      97                 :            :  * nfs_revalidate_inode() that takes into account the fact that we may
      98                 :            :  * have cached writes (in which case we don't care about the server's
      99                 :            :  * idea of what the file length is), or O_DIRECT (in which case we
     100                 :            :  * shouldn't trust the cache).
     101                 :            :  */
     102                 :            : static int nfs_revalidate_file_size(struct inode *inode, struct file *filp)
     103                 :            : {
     104                 :            :         struct nfs_server *server = NFS_SERVER(inode);
     105                 :            : 
     106                 :            :         if (filp->f_flags & O_DIRECT)
     107                 :            :                 goto force_reval;
     108                 :            :         if (nfs_check_cache_invalid(inode, NFS_INO_REVAL_PAGECACHE))
     109                 :            :                 goto force_reval;
     110                 :            :         return 0;
     111                 :            : force_reval:
     112                 :            :         return __nfs_revalidate_inode(server, inode);
     113                 :            : }
     114                 :            : 
     115                 :          0 : loff_t nfs_file_llseek(struct file *filp, loff_t offset, int whence)
     116                 :            : {
     117                 :          0 :         dprintk("NFS: llseek file(%pD2, %lld, %d)\n",
     118                 :            :                         filp, offset, whence);
     119                 :            : 
     120                 :            :         /*
     121                 :            :          * whence == SEEK_END || SEEK_DATA || SEEK_HOLE => we must revalidate
     122                 :            :          * the cached file length
     123                 :            :          */
     124         [ #  # ]:          0 :         if (whence != SEEK_SET && whence != SEEK_CUR) {
     125                 :          0 :                 struct inode *inode = filp->f_mapping->host;
     126                 :            : 
     127                 :          0 :                 int retval = nfs_revalidate_file_size(inode, filp);
     128         [ #  # ]:          0 :                 if (retval < 0)
     129                 :          0 :                         return (loff_t)retval;
     130                 :            :         }
     131                 :            : 
     132                 :          0 :         return generic_file_llseek(filp, offset, whence);
     133                 :            : }
     134                 :            : EXPORT_SYMBOL_GPL(nfs_file_llseek);
     135                 :            : 
     136                 :            : /*
     137                 :            :  * Flush all dirty pages, and check for write errors.
     138                 :            :  */
     139                 :            : static int
     140                 :          0 : nfs_file_flush(struct file *file, fl_owner_t id)
     141                 :            : {
     142                 :          0 :         struct inode    *inode = file_inode(file);
     143                 :            : 
     144                 :          0 :         dprintk("NFS: flush(%pD2)\n", file);
     145                 :            : 
     146                 :          0 :         nfs_inc_stats(inode, NFSIOS_VFSFLUSH);
     147         [ #  # ]:          0 :         if ((file->f_mode & FMODE_WRITE) == 0)
     148                 :            :                 return 0;
     149                 :            : 
     150                 :            :         /* Flush writes to the server and return any errors */
     151                 :          0 :         return nfs_wb_all(inode);
     152                 :            : }
     153                 :            : 
     154                 :            : ssize_t
     155                 :          0 : nfs_file_read(struct kiocb *iocb, struct iov_iter *to)
     156                 :            : {
     157         [ #  # ]:          0 :         struct inode *inode = file_inode(iocb->ki_filp);
     158                 :          0 :         ssize_t result;
     159                 :            : 
     160         [ #  # ]:          0 :         if (iocb->ki_flags & IOCB_DIRECT)
     161                 :          0 :                 return nfs_file_direct_read(iocb, to);
     162                 :            : 
     163                 :          0 :         dprintk("NFS: read(%pD2, %zu@%lu)\n",
     164                 :            :                 iocb->ki_filp,
     165                 :            :                 iov_iter_count(to), (unsigned long) iocb->ki_pos);
     166                 :            : 
     167                 :          0 :         nfs_start_io_read(inode);
     168                 :          0 :         result = nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping);
     169         [ #  # ]:          0 :         if (!result) {
     170                 :          0 :                 result = generic_file_read_iter(iocb, to);
     171         [ #  # ]:          0 :                 if (result > 0)
     172         [ #  # ]:          0 :                         nfs_add_stats(inode, NFSIOS_NORMALREADBYTES, result);
     173                 :            :         }
     174                 :          0 :         nfs_end_io_read(inode);
     175                 :          0 :         return result;
     176                 :            : }
     177                 :            : EXPORT_SYMBOL_GPL(nfs_file_read);
     178                 :            : 
     179                 :            : int
     180                 :          0 : nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
     181                 :            : {
     182                 :          0 :         struct inode *inode = file_inode(file);
     183                 :          0 :         int     status;
     184                 :            : 
     185                 :          0 :         dprintk("NFS: mmap(%pD2)\n", file);
     186                 :            : 
     187                 :            :         /* Note: generic_file_mmap() returns ENOSYS on nommu systems
     188                 :            :          *       so we call that before revalidating the mapping
     189                 :            :          */
     190                 :          0 :         status = generic_file_mmap(file, vma);
     191         [ #  # ]:          0 :         if (!status) {
     192                 :          0 :                 vma->vm_ops = &nfs_file_vm_ops;
     193                 :          0 :                 status = nfs_revalidate_mapping(inode, file->f_mapping);
     194                 :            :         }
     195                 :          0 :         return status;
     196                 :            : }
     197                 :            : EXPORT_SYMBOL_GPL(nfs_file_mmap);
     198                 :            : 
     199                 :            : /*
     200                 :            :  * Flush any dirty pages for this process, and check for write errors.
     201                 :            :  * The return status from this call provides a reliable indication of
     202                 :            :  * whether any write errors occurred for this process.
     203                 :            :  */
     204                 :            : static int
     205                 :            : nfs_file_fsync_commit(struct file *file, int datasync)
     206                 :            : {
     207                 :            :         struct inode *inode = file_inode(file);
     208                 :            :         int ret;
     209                 :            : 
     210                 :            :         dprintk("NFS: fsync file(%pD2) datasync %d\n", file, datasync);
     211                 :            : 
     212                 :            :         nfs_inc_stats(inode, NFSIOS_VFSFSYNC);
     213                 :            :         ret = nfs_commit_inode(inode, FLUSH_SYNC);
     214                 :            :         if (ret < 0)
     215                 :            :                 return ret;
     216                 :            :         return file_check_and_advance_wb_err(file);
     217                 :            : }
     218                 :            : 
     219                 :            : int
     220                 :          0 : nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
     221                 :            : {
     222                 :          0 :         struct nfs_open_context *ctx = nfs_file_open_context(file);
     223                 :          0 :         struct inode *inode = file_inode(file);
     224                 :          0 :         int ret;
     225                 :            : 
     226                 :          0 :         trace_nfs_fsync_enter(inode);
     227                 :            : 
     228                 :          0 :         for (;;) {
     229                 :          0 :                 ret = file_write_and_wait_range(file, start, end);
     230         [ #  # ]:          0 :                 if (ret != 0)
     231                 :            :                         break;
     232                 :          0 :                 ret = nfs_file_fsync_commit(file, datasync);
     233         [ #  # ]:          0 :                 if (ret != 0)
     234                 :            :                         break;
     235                 :          0 :                 ret = pnfs_sync_inode(inode, !!datasync);
     236                 :          0 :                 if (ret != 0)
     237                 :            :                         break;
     238         [ #  # ]:          0 :                 if (!test_and_clear_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags))
     239                 :            :                         break;
     240                 :            :                 /*
     241                 :            :                  * If nfs_file_fsync_commit detected a server reboot, then
     242                 :            :                  * resend all dirty pages that might have been covered by
     243                 :            :                  * the NFS_CONTEXT_RESEND_WRITES flag
     244                 :            :                  */
     245                 :            :                 start = 0;
     246                 :            :                 end = LLONG_MAX;
     247                 :            :         }
     248                 :            : 
     249                 :          0 :         trace_nfs_fsync_exit(inode, ret);
     250                 :          0 :         return ret;
     251                 :            : }
     252                 :            : EXPORT_SYMBOL_GPL(nfs_file_fsync);
     253                 :            : 
     254                 :            : /*
     255                 :            :  * Decide whether a read/modify/write cycle may be more efficient
     256                 :            :  * then a modify/write/read cycle when writing to a page in the
     257                 :            :  * page cache.
     258                 :            :  *
     259                 :            :  * Some pNFS layout drivers can only read/write at a certain block
     260                 :            :  * granularity like all block devices and therefore we must perform
     261                 :            :  * read/modify/write whenever a page hasn't read yet and the data
     262                 :            :  * to be written there is not aligned to a block boundary and/or
     263                 :            :  * smaller than the block size.
     264                 :            :  *
     265                 :            :  * The modify/write/read cycle may occur if a page is read before
     266                 :            :  * being completely filled by the writer.  In this situation, the
     267                 :            :  * page must be completely written to stable storage on the server
     268                 :            :  * before it can be refilled by reading in the page from the server.
     269                 :            :  * This can lead to expensive, small, FILE_SYNC mode writes being
     270                 :            :  * done.
     271                 :            :  *
     272                 :            :  * It may be more efficient to read the page first if the file is
     273                 :            :  * open for reading in addition to writing, the page is not marked
     274                 :            :  * as Uptodate, it is not dirty or waiting to be committed,
     275                 :            :  * indicating that it was previously allocated and then modified,
     276                 :            :  * that there were valid bytes of data in that range of the file,
     277                 :            :  * and that the new data won't completely replace the old data in
     278                 :            :  * that range of the file.
     279                 :            :  */
     280                 :            : static bool nfs_full_page_write(struct page *page, loff_t pos, unsigned int len)
     281                 :            : {
     282                 :            :         unsigned int pglen = nfs_page_length(page);
     283                 :            :         unsigned int offset = pos & (PAGE_SIZE - 1);
     284                 :            :         unsigned int end = offset + len;
     285                 :            : 
     286                 :            :         return !pglen || (end >= pglen && !offset);
     287                 :            : }
     288                 :            : 
     289                 :            : static bool nfs_want_read_modify_write(struct file *file, struct page *page,
     290                 :            :                         loff_t pos, unsigned int len)
     291                 :            : {
     292                 :            :         /*
     293                 :            :          * Up-to-date pages, those with ongoing or full-page write
     294                 :            :          * don't need read/modify/write
     295                 :            :          */
     296                 :            :         if (PageUptodate(page) || PagePrivate(page) ||
     297                 :            :             nfs_full_page_write(page, pos, len))
     298                 :            :                 return false;
     299                 :            : 
     300                 :            :         if (pnfs_ld_read_whole_page(file->f_mapping->host))
     301                 :            :                 return true;
     302                 :            :         /* Open for reading too? */
     303                 :            :         if (file->f_mode & FMODE_READ)
     304                 :            :                 return true;
     305                 :            :         return false;
     306                 :            : }
     307                 :            : 
     308                 :            : /*
     309                 :            :  * This does the "real" work of the write. We must allocate and lock the
     310                 :            :  * page to be sent back to the generic routine, which then copies the
     311                 :            :  * data from user space.
     312                 :            :  *
     313                 :            :  * If the writer ends up delaying the write, the writer needs to
     314                 :            :  * increment the page use counts until he is done with the page.
     315                 :            :  */
     316                 :          0 : static int nfs_write_begin(struct file *file, struct address_space *mapping,
     317                 :            :                         loff_t pos, unsigned len, unsigned flags,
     318                 :            :                         struct page **pagep, void **fsdata)
     319                 :            : {
     320                 :          0 :         int ret;
     321                 :          0 :         pgoff_t index = pos >> PAGE_SHIFT;
     322                 :          0 :         struct page *page;
     323                 :          0 :         int once_thru = 0;
     324                 :            : 
     325                 :          0 :         dfprintk(PAGECACHE, "NFS: write_begin(%pD2(%lu), %u@%lld)\n",
     326                 :            :                 file, mapping->host->i_ino, len, (long long) pos);
     327                 :            : 
     328                 :          0 : start:
     329                 :          0 :         page = grab_cache_page_write_begin(mapping, index, flags);
     330         [ #  # ]:          0 :         if (!page)
     331                 :            :                 return -ENOMEM;
     332                 :          0 :         *pagep = page;
     333                 :            : 
     334                 :          0 :         ret = nfs_flush_incompatible(file, page);
     335         [ #  # ]:          0 :         if (ret) {
     336                 :          0 :                 unlock_page(page);
     337                 :          0 :                 put_page(page);
     338   [ #  #  #  # ]:          0 :         } else if (!once_thru &&
     339                 :          0 :                    nfs_want_read_modify_write(file, page, pos, len)) {
     340                 :          0 :                 once_thru = 1;
     341                 :          0 :                 ret = nfs_readpage(file, page);
     342                 :          0 :                 put_page(page);
     343         [ #  # ]:          0 :                 if (!ret)
     344                 :          0 :                         goto start;
     345                 :            :         }
     346                 :            :         return ret;
     347                 :            : }
     348                 :            : 
     349                 :          0 : static int nfs_write_end(struct file *file, struct address_space *mapping,
     350                 :            :                         loff_t pos, unsigned len, unsigned copied,
     351                 :            :                         struct page *page, void *fsdata)
     352                 :            : {
     353                 :          0 :         unsigned offset = pos & (PAGE_SIZE - 1);
     354                 :          0 :         struct nfs_open_context *ctx = nfs_file_open_context(file);
     355                 :          0 :         int status;
     356                 :            : 
     357                 :          0 :         dfprintk(PAGECACHE, "NFS: write_end(%pD2(%lu), %u@%lld)\n",
     358                 :            :                 file, mapping->host->i_ino, len, (long long) pos);
     359                 :            : 
     360                 :            :         /*
     361                 :            :          * Zero any uninitialised parts of the page, and then mark the page
     362                 :            :          * as up to date if it turns out that we're extending the file.
     363                 :            :          */
     364         [ #  # ]:          0 :         if (!PageUptodate(page)) {
     365                 :          0 :                 unsigned pglen = nfs_page_length(page);
     366                 :          0 :                 unsigned end = offset + copied;
     367                 :            : 
     368         [ #  # ]:          0 :                 if (pglen == 0) {
     369                 :          0 :                         zero_user_segments(page, 0, offset,
     370                 :            :                                         end, PAGE_SIZE);
     371                 :          0 :                         SetPageUptodate(page);
     372         [ #  # ]:          0 :                 } else if (end >= pglen) {
     373                 :          0 :                         zero_user_segment(page, end, PAGE_SIZE);
     374         [ #  # ]:          0 :                         if (offset == 0)
     375                 :          0 :                                 SetPageUptodate(page);
     376                 :            :                 } else
     377                 :          0 :                         zero_user_segment(page, pglen, PAGE_SIZE);
     378                 :            :         }
     379                 :            : 
     380                 :          0 :         status = nfs_updatepage(file, page, offset, copied);
     381                 :            : 
     382                 :          0 :         unlock_page(page);
     383                 :          0 :         put_page(page);
     384                 :            : 
     385         [ #  # ]:          0 :         if (status < 0)
     386                 :            :                 return status;
     387                 :          0 :         NFS_I(mapping->host)->write_io += copied;
     388                 :            : 
     389         [ #  # ]:          0 :         if (nfs_ctx_key_to_expire(ctx, mapping->host)) {
     390                 :          0 :                 status = nfs_wb_all(mapping->host);
     391         [ #  # ]:          0 :                 if (status < 0)
     392                 :            :                         return status;
     393                 :            :         }
     394                 :            : 
     395                 :          0 :         return copied;
     396                 :            : }
     397                 :            : 
     398                 :            : /*
     399                 :            :  * Partially or wholly invalidate a page
     400                 :            :  * - Release the private state associated with a page if undergoing complete
     401                 :            :  *   page invalidation
     402                 :            :  * - Called if either PG_private or PG_fscache is set on the page
     403                 :            :  * - Caller holds page lock
     404                 :            :  */
     405                 :          0 : static void nfs_invalidate_page(struct page *page, unsigned int offset,
     406                 :            :                                 unsigned int length)
     407                 :            : {
     408                 :          0 :         dfprintk(PAGECACHE, "NFS: invalidate_page(%p, %u, %u)\n",
     409                 :            :                  page, offset, length);
     410                 :            : 
     411         [ #  # ]:          0 :         if (offset != 0 || length < PAGE_SIZE)
     412                 :            :                 return;
     413                 :            :         /* Cancel any unstarted writes on this page */
     414                 :          0 :         nfs_wb_page_cancel(page_file_mapping(page)->host, page);
     415                 :            : 
     416                 :          0 :         nfs_fscache_invalidate_page(page, page->mapping->host);
     417                 :            : }
     418                 :            : 
     419                 :            : /*
     420                 :            :  * Attempt to release the private state associated with a page
     421                 :            :  * - Called if either PG_private or PG_fscache is set on the page
     422                 :            :  * - Caller holds page lock
     423                 :            :  * - Return true (may release page) or false (may not)
     424                 :            :  */
     425                 :          0 : static int nfs_release_page(struct page *page, gfp_t gfp)
     426                 :            : {
     427                 :          0 :         dfprintk(PAGECACHE, "NFS: release_page(%p)\n", page);
     428                 :            : 
     429                 :            :         /* If PagePrivate() is set, then the page is not freeable */
     430         [ #  # ]:          0 :         if (PagePrivate(page))
     431                 :          0 :                 return 0;
     432                 :            :         return nfs_fscache_release_page(page, gfp);
     433                 :            : }
     434                 :            : 
     435                 :          0 : static void nfs_check_dirty_writeback(struct page *page,
     436                 :            :                                 bool *dirty, bool *writeback)
     437                 :            : {
     438                 :          0 :         struct nfs_inode *nfsi;
     439                 :          0 :         struct address_space *mapping = page_file_mapping(page);
     440                 :            : 
     441         [ #  # ]:          0 :         if (!mapping || PageSwapCache(page))
     442                 :          0 :                 return;
     443                 :            : 
     444                 :            :         /*
     445                 :            :          * Check if an unstable page is currently being committed and
     446                 :            :          * if so, have the VM treat it as if the page is under writeback
     447                 :            :          * so it will not block due to pages that will shortly be freeable.
     448                 :            :          */
     449                 :          0 :         nfsi = NFS_I(mapping->host);
     450         [ #  # ]:          0 :         if (atomic_read(&nfsi->commit_info.rpcs_out)) {
     451                 :          0 :                 *writeback = true;
     452                 :          0 :                 return;
     453                 :            :         }
     454                 :            : 
     455                 :            :         /*
     456                 :            :          * If PagePrivate() is set, then the page is not freeable and as the
     457                 :            :          * inode is not being committed, it's not going to be cleaned in the
     458                 :            :          * near future so treat it as dirty
     459                 :            :          */
     460         [ #  # ]:          0 :         if (PagePrivate(page))
     461                 :          0 :                 *dirty = true;
     462                 :            : }
     463                 :            : 
     464                 :            : /*
     465                 :            :  * Attempt to clear the private state associated with a page when an error
     466                 :            :  * occurs that requires the cached contents of an inode to be written back or
     467                 :            :  * destroyed
     468                 :            :  * - Called if either PG_private or fscache is set on the page
     469                 :            :  * - Caller holds page lock
     470                 :            :  * - Return 0 if successful, -error otherwise
     471                 :            :  */
     472                 :          0 : static int nfs_launder_page(struct page *page)
     473                 :            : {
     474                 :          0 :         struct inode *inode = page_file_mapping(page)->host;
     475                 :          0 :         struct nfs_inode *nfsi = NFS_I(inode);
     476                 :            : 
     477                 :          0 :         dfprintk(PAGECACHE, "NFS: launder_page(%ld, %llu)\n",
     478                 :            :                 inode->i_ino, (long long)page_offset(page));
     479                 :            : 
     480                 :          0 :         nfs_fscache_wait_on_page_write(nfsi, page);
     481                 :          0 :         return nfs_wb_page(inode, page);
     482                 :            : }
     483                 :            : 
     484                 :          0 : static int nfs_swap_activate(struct swap_info_struct *sis, struct file *file,
     485                 :            :                                                 sector_t *span)
     486                 :            : {
     487                 :          0 :         unsigned long blocks;
     488                 :          0 :         long long isize;
     489                 :          0 :         struct rpc_clnt *clnt = NFS_CLIENT(file->f_mapping->host);
     490                 :          0 :         struct inode *inode = file->f_mapping->host;
     491                 :            : 
     492                 :          0 :         spin_lock(&inode->i_lock);
     493                 :          0 :         blocks = inode->i_blocks;
     494                 :          0 :         isize = inode->i_size;
     495                 :          0 :         spin_unlock(&inode->i_lock);
     496         [ #  # ]:          0 :         if (blocks*512 < isize) {
     497                 :          0 :                 pr_warn("swap activate: swapfile has holes\n");
     498                 :          0 :                 return -EINVAL;
     499                 :            :         }
     500                 :            : 
     501                 :          0 :         *span = sis->pages;
     502                 :            : 
     503                 :          0 :         return rpc_clnt_swap_activate(clnt);
     504                 :            : }
     505                 :            : 
     506                 :          0 : static void nfs_swap_deactivate(struct file *file)
     507                 :            : {
     508                 :          0 :         struct rpc_clnt *clnt = NFS_CLIENT(file->f_mapping->host);
     509                 :            : 
     510                 :          0 :         rpc_clnt_swap_deactivate(clnt);
     511                 :          0 : }
     512                 :            : 
     513                 :            : const struct address_space_operations nfs_file_aops = {
     514                 :            :         .readpage = nfs_readpage,
     515                 :            :         .readpages = nfs_readpages,
     516                 :            :         .set_page_dirty = __set_page_dirty_nobuffers,
     517                 :            :         .writepage = nfs_writepage,
     518                 :            :         .writepages = nfs_writepages,
     519                 :            :         .write_begin = nfs_write_begin,
     520                 :            :         .write_end = nfs_write_end,
     521                 :            :         .invalidatepage = nfs_invalidate_page,
     522                 :            :         .releasepage = nfs_release_page,
     523                 :            :         .direct_IO = nfs_direct_IO,
     524                 :            : #ifdef CONFIG_MIGRATION
     525                 :            :         .migratepage = nfs_migrate_page,
     526                 :            : #endif
     527                 :            :         .launder_page = nfs_launder_page,
     528                 :            :         .is_dirty_writeback = nfs_check_dirty_writeback,
     529                 :            :         .error_remove_page = generic_error_remove_page,
     530                 :            :         .swap_activate = nfs_swap_activate,
     531                 :            :         .swap_deactivate = nfs_swap_deactivate,
     532                 :            : };
     533                 :            : 
     534                 :            : /*
     535                 :            :  * Notification that a PTE pointing to an NFS page is about to be made
     536                 :            :  * writable, implying that someone is about to modify the page through a
     537                 :            :  * shared-writable mapping
     538                 :            :  */
     539                 :          0 : static vm_fault_t nfs_vm_page_mkwrite(struct vm_fault *vmf)
     540                 :            : {
     541                 :          0 :         struct page *page = vmf->page;
     542                 :          0 :         struct file *filp = vmf->vma->vm_file;
     543                 :          0 :         struct inode *inode = file_inode(filp);
     544                 :          0 :         unsigned pagelen;
     545                 :          0 :         vm_fault_t ret = VM_FAULT_NOPAGE;
     546                 :          0 :         struct address_space *mapping;
     547                 :            : 
     548                 :          0 :         dfprintk(PAGECACHE, "NFS: vm_page_mkwrite(%pD2(%lu), offset %lld)\n",
     549                 :            :                 filp, filp->f_mapping->host->i_ino,
     550                 :            :                 (long long)page_offset(page));
     551                 :            : 
     552                 :          0 :         sb_start_pagefault(inode->i_sb);
     553                 :            : 
     554                 :            :         /* make sure the cache has finished storing the page */
     555                 :          0 :         nfs_fscache_wait_on_page_write(NFS_I(inode), page);
     556                 :            : 
     557                 :          0 :         wait_on_bit_action(&NFS_I(inode)->flags, NFS_INO_INVALIDATING,
     558                 :            :                         nfs_wait_bit_killable, TASK_KILLABLE);
     559                 :            : 
     560                 :          0 :         lock_page(page);
     561                 :          0 :         mapping = page_file_mapping(page);
     562         [ #  # ]:          0 :         if (mapping != inode->i_mapping)
     563                 :          0 :                 goto out_unlock;
     564                 :            : 
     565                 :          0 :         wait_on_page_writeback(page);
     566                 :            : 
     567                 :          0 :         pagelen = nfs_page_length(page);
     568         [ #  # ]:          0 :         if (pagelen == 0)
     569                 :          0 :                 goto out_unlock;
     570                 :            : 
     571                 :          0 :         ret = VM_FAULT_LOCKED;
     572   [ #  #  #  # ]:          0 :         if (nfs_flush_incompatible(filp, page) == 0 &&
     573                 :          0 :             nfs_updatepage(filp, page, 0, pagelen) == 0)
     574                 :          0 :                 goto out;
     575                 :            : 
     576                 :            :         ret = VM_FAULT_SIGBUS;
     577                 :          0 : out_unlock:
     578                 :          0 :         unlock_page(page);
     579                 :          0 : out:
     580                 :          0 :         sb_end_pagefault(inode->i_sb);
     581                 :          0 :         return ret;
     582                 :            : }
     583                 :            : 
     584                 :            : static const struct vm_operations_struct nfs_file_vm_ops = {
     585                 :            :         .fault = filemap_fault,
     586                 :            :         .map_pages = filemap_map_pages,
     587                 :            :         .page_mkwrite = nfs_vm_page_mkwrite,
     588                 :            : };
     589                 :            : 
     590                 :          0 : static int nfs_need_check_write(struct file *filp, struct inode *inode)
     591                 :            : {
     592                 :          0 :         struct nfs_open_context *ctx;
     593                 :            : 
     594                 :          0 :         ctx = nfs_file_open_context(filp);
     595         [ #  # ]:          0 :         if (nfs_ctx_key_to_expire(ctx, inode))
     596                 :          0 :                 return 1;
     597                 :            :         return 0;
     598                 :            : }
     599                 :            : 
     600                 :          0 : ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
     601                 :            : {
     602                 :          0 :         struct file *file = iocb->ki_filp;
     603                 :          0 :         struct inode *inode = file_inode(file);
     604                 :          0 :         unsigned long written = 0;
     605                 :          0 :         ssize_t result;
     606                 :            : 
     607                 :          0 :         result = nfs_key_timeout_notify(file, inode);
     608         [ #  # ]:          0 :         if (result)
     609                 :            :                 return result;
     610                 :            : 
     611         [ #  # ]:          0 :         if (iocb->ki_flags & IOCB_DIRECT)
     612                 :          0 :                 return nfs_file_direct_write(iocb, from);
     613                 :            : 
     614                 :          0 :         dprintk("NFS: write(%pD2, %zu@%Ld)\n",
     615                 :            :                 file, iov_iter_count(from), (long long) iocb->ki_pos);
     616                 :            : 
     617         [ #  # ]:          0 :         if (IS_SWAPFILE(inode))
     618                 :          0 :                 goto out_swapfile;
     619                 :            :         /*
     620                 :            :          * O_APPEND implies that we must revalidate the file length.
     621                 :            :          */
     622         [ #  # ]:          0 :         if (iocb->ki_flags & IOCB_APPEND) {
     623                 :          0 :                 result = nfs_revalidate_file_size(inode, file);
     624         [ #  # ]:          0 :                 if (result)
     625                 :          0 :                         goto out;
     626                 :            :         }
     627         [ #  # ]:          0 :         if (iocb->ki_pos > i_size_read(inode))
     628                 :          0 :                 nfs_revalidate_mapping(inode, file->f_mapping);
     629                 :            : 
     630                 :          0 :         nfs_start_io_write(inode);
     631                 :          0 :         result = generic_write_checks(iocb, from);
     632         [ #  # ]:          0 :         if (result > 0) {
     633                 :          0 :                 current->backing_dev_info = inode_to_bdi(inode);
     634                 :          0 :                 result = generic_perform_write(file, from, iocb->ki_pos);
     635                 :          0 :                 current->backing_dev_info = NULL;
     636                 :            :         }
     637                 :          0 :         nfs_end_io_write(inode);
     638         [ #  # ]:          0 :         if (result <= 0)
     639                 :          0 :                 goto out;
     640                 :            : 
     641                 :          0 :         written = result;
     642                 :          0 :         iocb->ki_pos += written;
     643                 :          0 :         result = generic_write_sync(iocb, written);
     644         [ #  # ]:          0 :         if (result < 0)
     645                 :          0 :                 goto out;
     646                 :            : 
     647                 :            :         /* Return error values */
     648                 :          0 :         if (nfs_need_check_write(file, inode)) {
     649                 :          0 :                 int err = nfs_wb_all(inode);
     650         [ #  # ]:          0 :                 if (err < 0)
     651                 :          0 :                         result = err;
     652                 :            :         }
     653         [ #  # ]:          0 :         nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, written);
     654                 :            : out:
     655                 :            :         return result;
     656                 :            : 
     657                 :            : out_swapfile:
     658                 :          0 :         printk(KERN_INFO "NFS: attempt to write to active swap file!\n");
     659                 :          0 :         return -ETXTBSY;
     660                 :            : }
     661                 :            : EXPORT_SYMBOL_GPL(nfs_file_write);
     662                 :            : 
     663                 :            : static int
     664                 :          0 : do_getlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
     665                 :            : {
     666                 :          0 :         struct inode *inode = filp->f_mapping->host;
     667                 :          0 :         int status = 0;
     668                 :          0 :         unsigned int saved_type = fl->fl_type;
     669                 :            : 
     670                 :            :         /* Try local locking first */
     671                 :          0 :         posix_test_lock(filp, fl);
     672         [ #  # ]:          0 :         if (fl->fl_type != F_UNLCK) {
     673                 :            :                 /* found a conflict */
     674                 :          0 :                 goto out;
     675                 :            :         }
     676                 :          0 :         fl->fl_type = saved_type;
     677                 :            : 
     678         [ #  # ]:          0 :         if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ))
     679                 :          0 :                 goto out_noconflict;
     680                 :            : 
     681         [ #  # ]:          0 :         if (is_local)
     682                 :          0 :                 goto out_noconflict;
     683                 :            : 
     684                 :          0 :         status = NFS_PROTO(inode)->lock(filp, cmd, fl);
     685                 :          0 : out:
     686                 :          0 :         return status;
     687                 :          0 : out_noconflict:
     688                 :          0 :         fl->fl_type = F_UNLCK;
     689                 :          0 :         goto out;
     690                 :            : }
     691                 :            : 
     692                 :            : static int
     693                 :          0 : do_unlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
     694                 :            : {
     695                 :          0 :         struct inode *inode = filp->f_mapping->host;
     696                 :          0 :         struct nfs_lock_context *l_ctx;
     697                 :          0 :         int status;
     698                 :            : 
     699                 :            :         /*
     700                 :            :          * Flush all pending writes before doing anything
     701                 :            :          * with locks..
     702                 :            :          */
     703                 :          0 :         nfs_wb_all(inode);
     704                 :            : 
     705                 :          0 :         l_ctx = nfs_get_lock_context(nfs_file_open_context(filp));
     706         [ #  # ]:          0 :         if (!IS_ERR(l_ctx)) {
     707                 :          0 :                 status = nfs_iocounter_wait(l_ctx);
     708                 :          0 :                 nfs_put_lock_context(l_ctx);
     709                 :            :                 /*  NOTE: special case
     710                 :            :                  *      If we're signalled while cleaning up locks on process exit, we
     711                 :            :                  *      still need to complete the unlock.
     712                 :            :                  */
     713   [ #  #  #  # ]:          0 :                 if (status < 0 && !(fl->fl_flags & FL_CLOSE))
     714                 :            :                         return status;
     715                 :            :         }
     716                 :            : 
     717                 :            :         /*
     718                 :            :          * Use local locking if mounted with "-onolock" or with appropriate
     719                 :            :          * "-olocal_lock="
     720                 :            :          */
     721         [ #  # ]:          0 :         if (!is_local)
     722                 :          0 :                 status = NFS_PROTO(inode)->lock(filp, cmd, fl);
     723                 :            :         else
     724                 :          0 :                 status = locks_lock_file_wait(filp, fl);
     725                 :            :         return status;
     726                 :            : }
     727                 :            : 
     728                 :            : static int
     729                 :          0 : do_setlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
     730                 :            : {
     731                 :          0 :         struct inode *inode = filp->f_mapping->host;
     732                 :          0 :         int status;
     733                 :            : 
     734                 :            :         /*
     735                 :            :          * Flush all pending writes before doing anything
     736                 :            :          * with locks..
     737                 :            :          */
     738                 :          0 :         status = nfs_sync_mapping(filp->f_mapping);
     739         [ #  # ]:          0 :         if (status != 0)
     740                 :          0 :                 goto out;
     741                 :            : 
     742                 :            :         /*
     743                 :            :          * Use local locking if mounted with "-onolock" or with appropriate
     744                 :            :          * "-olocal_lock="
     745                 :            :          */
     746         [ #  # ]:          0 :         if (!is_local)
     747                 :          0 :                 status = NFS_PROTO(inode)->lock(filp, cmd, fl);
     748                 :            :         else
     749                 :          0 :                 status = locks_lock_file_wait(filp, fl);
     750         [ #  # ]:          0 :         if (status < 0)
     751                 :          0 :                 goto out;
     752                 :            : 
     753                 :            :         /*
     754                 :            :          * Invalidate cache to prevent missing any changes.  If
     755                 :            :          * the file is mapped, clear the page cache as well so
     756                 :            :          * those mappings will be loaded.
     757                 :            :          *
     758                 :            :          * This makes locking act as a cache coherency point.
     759                 :            :          */
     760                 :          0 :         nfs_sync_mapping(filp->f_mapping);
     761         [ #  # ]:          0 :         if (!NFS_PROTO(inode)->have_delegation(inode, FMODE_READ)) {
     762                 :          0 :                 nfs_zap_caches(inode);
     763         [ #  # ]:          0 :                 if (mapping_mapped(filp->f_mapping))
     764                 :          0 :                         nfs_revalidate_mapping(inode, filp->f_mapping);
     765                 :            :         }
     766                 :          0 : out:
     767                 :          0 :         return status;
     768                 :            : }
     769                 :            : 
     770                 :            : /*
     771                 :            :  * Lock a (portion of) a file
     772                 :            :  */
     773                 :          0 : int nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
     774                 :            : {
     775                 :          0 :         struct inode *inode = filp->f_mapping->host;
     776                 :          0 :         int ret = -ENOLCK;
     777                 :          0 :         int is_local = 0;
     778                 :            : 
     779                 :          0 :         dprintk("NFS: lock(%pD2, t=%x, fl=%x, r=%lld:%lld)\n",
     780                 :            :                         filp, fl->fl_type, fl->fl_flags,
     781                 :            :                         (long long)fl->fl_start, (long long)fl->fl_end);
     782                 :            : 
     783                 :          0 :         nfs_inc_stats(inode, NFSIOS_VFSLOCK);
     784                 :            : 
     785                 :            :         /* No mandatory locks over NFS */
     786   [ #  #  #  # ]:          0 :         if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK)
     787                 :          0 :                 goto out_err;
     788                 :            : 
     789         [ #  # ]:          0 :         if (NFS_SERVER(inode)->flags & NFS_MOUNT_LOCAL_FCNTL)
     790                 :          0 :                 is_local = 1;
     791                 :            : 
     792         [ #  # ]:          0 :         if (NFS_PROTO(inode)->lock_check_bounds != NULL) {
     793                 :          0 :                 ret = NFS_PROTO(inode)->lock_check_bounds(fl);
     794         [ #  # ]:          0 :                 if (ret < 0)
     795                 :          0 :                         goto out_err;
     796                 :            :         }
     797                 :            : 
     798         [ #  # ]:          0 :         if (IS_GETLK(cmd))
     799                 :          0 :                 ret = do_getlk(filp, cmd, fl, is_local);
     800         [ #  # ]:          0 :         else if (fl->fl_type == F_UNLCK)
     801                 :          0 :                 ret = do_unlk(filp, cmd, fl, is_local);
     802                 :            :         else
     803                 :          0 :                 ret = do_setlk(filp, cmd, fl, is_local);
     804                 :          0 : out_err:
     805                 :          0 :         return ret;
     806                 :            : }
     807                 :            : EXPORT_SYMBOL_GPL(nfs_lock);
     808                 :            : 
     809                 :            : /*
     810                 :            :  * Lock a (portion of) a file
     811                 :            :  */
     812                 :          0 : int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
     813                 :            : {
     814                 :          0 :         struct inode *inode = filp->f_mapping->host;
     815                 :          0 :         int is_local = 0;
     816                 :            : 
     817                 :          0 :         dprintk("NFS: flock(%pD2, t=%x, fl=%x)\n",
     818                 :            :                         filp, fl->fl_type, fl->fl_flags);
     819                 :            : 
     820         [ #  # ]:          0 :         if (!(fl->fl_flags & FL_FLOCK))
     821                 :            :                 return -ENOLCK;
     822                 :            : 
     823                 :            :         /*
     824                 :            :          * The NFSv4 protocol doesn't support LOCK_MAND, which is not part of
     825                 :            :          * any standard. In principle we might be able to support LOCK_MAND
     826                 :            :          * on NFSv2/3 since NLMv3/4 support DOS share modes, but for now the
     827                 :            :          * NFS code is not set up for it.
     828                 :            :          */
     829         [ #  # ]:          0 :         if (fl->fl_type & LOCK_MAND)
     830                 :            :                 return -EINVAL;
     831                 :            : 
     832         [ #  # ]:          0 :         if (NFS_SERVER(inode)->flags & NFS_MOUNT_LOCAL_FLOCK)
     833                 :          0 :                 is_local = 1;
     834                 :            : 
     835                 :            :         /* We're simulating flock() locks using posix locks on the server */
     836         [ #  # ]:          0 :         if (fl->fl_type == F_UNLCK)
     837                 :          0 :                 return do_unlk(filp, cmd, fl, is_local);
     838                 :          0 :         return do_setlk(filp, cmd, fl, is_local);
     839                 :            : }
     840                 :            : EXPORT_SYMBOL_GPL(nfs_flock);
     841                 :            : 
     842                 :            : const struct file_operations nfs_file_operations = {
     843                 :            :         .llseek         = nfs_file_llseek,
     844                 :            :         .read_iter      = nfs_file_read,
     845                 :            :         .write_iter     = nfs_file_write,
     846                 :            :         .mmap           = nfs_file_mmap,
     847                 :            :         .open           = nfs_file_open,
     848                 :            :         .flush          = nfs_file_flush,
     849                 :            :         .release        = nfs_file_release,
     850                 :            :         .fsync          = nfs_file_fsync,
     851                 :            :         .lock           = nfs_lock,
     852                 :            :         .flock          = nfs_flock,
     853                 :            :         .splice_read    = generic_file_splice_read,
     854                 :            :         .splice_write   = iter_file_splice_write,
     855                 :            :         .check_flags    = nfs_check_flags,
     856                 :            :         .setlease       = simple_nosetlease,
     857                 :            : };
     858                 :            : EXPORT_SYMBOL_GPL(nfs_file_operations);

Generated by: LCOV version 1.14