#include <linux/types.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <linux/file.h>
#include <linux/writeback.h>
#include <linux/swap.h>
#include <linux/migrate.h>
#include <linux/sunrpc/clnt.h>
#include <linux/nfs_fs.h>
#include <linux/nfs_mount.h>
#include <linux/nfs_page.h>
#include <linux/backing-dev.h>
#include <linux/export.h>
#include <linux/freezer.h>
#include <linux/wait.h>
#include <linux/iversion.h>
#include <linux/filelock.h>
#include <linux/uaccess.h>
#include <linux/sched/mm.h>
#include "delegation.h"
#include "internal.h"
#include "iostat.h"
#include "nfs4_fs.h"
#include "fscache.h"
#include "pnfs.h"
#include "nfstrace.h"
#define NFSDBG_FACILITY …
#define MIN_POOL_WRITE …
#define MIN_POOL_COMMIT …
struct nfs_io_completion { … };
static void nfs_redirty_request(struct nfs_page *req);
static const struct rpc_call_ops nfs_commit_ops;
static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops;
static const struct nfs_commit_completion_ops nfs_commit_completion_ops;
static const struct nfs_rw_ops nfs_rw_write_ops;
static void nfs_inode_remove_request(struct nfs_page *req);
static void nfs_clear_request_commit(struct nfs_commit_info *cinfo,
struct nfs_page *req);
static void nfs_init_cinfo_from_inode(struct nfs_commit_info *cinfo,
struct inode *inode);
static struct kmem_cache *nfs_wdata_cachep;
static mempool_t *nfs_wdata_mempool;
static struct kmem_cache *nfs_cdata_cachep;
static mempool_t *nfs_commit_mempool;
struct nfs_commit_data *nfs_commitdata_alloc(void)
{ … }
EXPORT_SYMBOL_GPL(…);
void nfs_commit_free(struct nfs_commit_data *p)
{ … }
EXPORT_SYMBOL_GPL(…);
static struct nfs_pgio_header *nfs_writehdr_alloc(void)
{ … }
static void nfs_writehdr_free(struct nfs_pgio_header *hdr)
{ … }
static struct nfs_io_completion *nfs_io_completion_alloc(gfp_t gfp_flags)
{ … }
static void nfs_io_completion_init(struct nfs_io_completion *ioc,
void (*complete)(void *), void *data)
{ … }
static void nfs_io_completion_release(struct kref *kref)
{ … }
static void nfs_io_completion_get(struct nfs_io_completion *ioc)
{ … }
static void nfs_io_completion_put(struct nfs_io_completion *ioc)
{ … }
static struct nfs_page *nfs_folio_find_head_request(struct folio *folio)
{ … }
static void nfs_grow_file(struct folio *folio, unsigned int offset,
unsigned int count)
{ … }
static void nfs_set_pageerror(struct address_space *mapping)
{ … }
static void nfs_mapping_set_error(struct folio *folio, int error)
{ … }
static struct nfs_page *
nfs_page_group_search_locked(struct nfs_page *head, unsigned int page_offset)
{ … }
static bool nfs_page_group_covers_page(struct nfs_page *req)
{ … }
static void nfs_mark_uptodate(struct nfs_page *req)
{ … }
static int wb_priority(struct writeback_control *wbc)
{ … }
int nfs_congestion_kb;
#define NFS_CONGESTION_ON_THRESH …
#define NFS_CONGESTION_OFF_THRESH …
static void nfs_folio_set_writeback(struct folio *folio)
{ … }
static void nfs_folio_end_writeback(struct folio *folio)
{ … }
static void nfs_page_end_writeback(struct nfs_page *req)
{ … }
static void
nfs_destroy_unlinked_subrequests(struct nfs_page *destroy_list,
struct nfs_page *old_head,
struct inode *inode)
{ … }
void nfs_join_page_group(struct nfs_page *head, struct nfs_commit_info *cinfo,
struct inode *inode)
{ … }
static int nfs_wait_on_request(struct nfs_page *req)
{ … }
static void
nfs_unroll_locks(struct nfs_page *head, struct nfs_page *req)
{ … }
static int
nfs_page_group_lock_subreq(struct nfs_page *head, struct nfs_page *subreq)
{ … }
static struct nfs_page *nfs_lock_and_join_requests(struct folio *folio)
{ … }
static void nfs_write_error(struct nfs_page *req, int error)
{ … }
static int nfs_page_async_flush(struct folio *folio,
struct writeback_control *wbc,
struct nfs_pageio_descriptor *pgio)
{ … }
static int nfs_do_writepage(struct folio *folio, struct writeback_control *wbc,
struct nfs_pageio_descriptor *pgio)
{ … }
static int nfs_writepage_locked(struct folio *folio,
struct writeback_control *wbc)
{ … }
static int nfs_writepages_callback(struct folio *folio,
struct writeback_control *wbc, void *data)
{ … }
static void nfs_io_completion_commit(void *inode)
{ … }
int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
{ … }
static void nfs_inode_add_request(struct nfs_page *req)
{ … }
static void nfs_inode_remove_request(struct nfs_page *req)
{ … }
static void nfs_mark_request_dirty(struct nfs_page *req)
{ … }
void
nfs_request_add_commit_list_locked(struct nfs_page *req, struct list_head *dst,
struct nfs_commit_info *cinfo)
{ … }
EXPORT_SYMBOL_GPL(…);
void
nfs_request_add_commit_list(struct nfs_page *req, struct nfs_commit_info *cinfo)
{ … }
EXPORT_SYMBOL_GPL(…);
void
nfs_request_remove_commit_list(struct nfs_page *req,
struct nfs_commit_info *cinfo)
{ … }
EXPORT_SYMBOL_GPL(…);
static void nfs_init_cinfo_from_inode(struct nfs_commit_info *cinfo,
struct inode *inode)
{ … }
void nfs_init_cinfo(struct nfs_commit_info *cinfo,
struct inode *inode,
struct nfs_direct_req *dreq)
{ … }
EXPORT_SYMBOL_GPL(…);
void
nfs_mark_request_commit(struct nfs_page *req, struct pnfs_layout_segment *lseg,
struct nfs_commit_info *cinfo, u32 ds_commit_idx)
{ … }
static void nfs_folio_clear_commit(struct folio *folio)
{ … }
static void nfs_clear_request_commit(struct nfs_commit_info *cinfo,
struct nfs_page *req)
{ … }
int nfs_write_need_commit(struct nfs_pgio_header *hdr)
{ … }
static void nfs_async_write_init(struct nfs_pgio_header *hdr)
{ … }
static void nfs_write_completion(struct nfs_pgio_header *hdr)
{ … }
unsigned long
nfs_reqs_to_commit(struct nfs_commit_info *cinfo)
{ … }
int
nfs_scan_commit_list(struct list_head *src, struct list_head *dst,
struct nfs_commit_info *cinfo, int max)
{ … }
EXPORT_SYMBOL_GPL(…);
int
nfs_scan_commit(struct inode *inode, struct list_head *dst,
struct nfs_commit_info *cinfo)
{ … }
static struct nfs_page *nfs_try_to_update_request(struct folio *folio,
unsigned int offset,
unsigned int bytes)
{ … }
static struct nfs_page *nfs_setup_write_request(struct nfs_open_context *ctx,
struct folio *folio,
unsigned int offset,
unsigned int bytes)
{ … }
static int nfs_writepage_setup(struct nfs_open_context *ctx,
struct folio *folio, unsigned int offset,
unsigned int count)
{ … }
int nfs_flush_incompatible(struct file *file, struct folio *folio)
{ … }
int
nfs_key_timeout_notify(struct file *filp, struct inode *inode)
{ … }
bool nfs_ctx_key_to_expire(struct nfs_open_context *ctx, struct inode *inode)
{ … }
static bool nfs_folio_write_uptodate(struct folio *folio, unsigned int pagelen)
{ … }
static bool
is_whole_file_wrlock(struct file_lock *fl)
{ … }
static int nfs_can_extend_write(struct file *file, struct folio *folio,
unsigned int pagelen)
{ … }
int nfs_update_folio(struct file *file, struct folio *folio,
unsigned int offset, unsigned int count)
{ … }
static int flush_task_priority(int how)
{ … }
static void nfs_initiate_write(struct nfs_pgio_header *hdr,
struct rpc_message *msg,
const struct nfs_rpc_ops *rpc_ops,
struct rpc_task_setup *task_setup_data, int how)
{ … }
static void nfs_redirty_request(struct nfs_page *req)
{ … }
static void nfs_async_write_error(struct list_head *head, int error)
{ … }
static void nfs_async_write_reschedule_io(struct nfs_pgio_header *hdr)
{ … }
static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops = …;
void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,
struct inode *inode, int ioflags, bool force_mds,
const struct nfs_pgio_completion_ops *compl_ops)
{ … }
EXPORT_SYMBOL_GPL(…);
void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio)
{ … }
EXPORT_SYMBOL_GPL(…);
void nfs_commit_prepare(struct rpc_task *task, void *calldata)
{ … }
static void nfs_writeback_check_extend(struct nfs_pgio_header *hdr,
struct nfs_fattr *fattr)
{ … }
void nfs_writeback_update_inode(struct nfs_pgio_header *hdr)
{ … }
EXPORT_SYMBOL_GPL(…);
static int nfs_writeback_done(struct rpc_task *task,
struct nfs_pgio_header *hdr,
struct inode *inode)
{ … }
static void nfs_writeback_result(struct rpc_task *task,
struct nfs_pgio_header *hdr)
{ … }
static int wait_on_commit(struct nfs_mds_commit_info *cinfo)
{ … }
void nfs_commit_begin(struct nfs_mds_commit_info *cinfo)
{ … }
bool nfs_commit_end(struct nfs_mds_commit_info *cinfo)
{ … }
void nfs_commitdata_release(struct nfs_commit_data *data)
{ … }
EXPORT_SYMBOL_GPL(…);
int nfs_initiate_commit(struct rpc_clnt *clnt, struct nfs_commit_data *data,
const struct nfs_rpc_ops *nfs_ops,
const struct rpc_call_ops *call_ops,
int how, int flags)
{ … }
EXPORT_SYMBOL_GPL(…);
static loff_t nfs_get_lwb(struct list_head *head)
{ … }
void nfs_init_commit(struct nfs_commit_data *data,
struct list_head *head,
struct pnfs_layout_segment *lseg,
struct nfs_commit_info *cinfo)
{ … }
EXPORT_SYMBOL_GPL(…);
void nfs_retry_commit(struct list_head *page_list,
struct pnfs_layout_segment *lseg,
struct nfs_commit_info *cinfo,
u32 ds_commit_idx)
{ … }
EXPORT_SYMBOL_GPL(…);
static void nfs_commit_resched_write(struct nfs_commit_info *cinfo,
struct nfs_page *req)
{ … }
static int
nfs_commit_list(struct inode *inode, struct list_head *head, int how,
struct nfs_commit_info *cinfo)
{ … }
static void nfs_commit_done(struct rpc_task *task, void *calldata)
{ … }
static void nfs_commit_release_pages(struct nfs_commit_data *data)
{ … }
static void nfs_commit_release(void *calldata)
{ … }
static const struct rpc_call_ops nfs_commit_ops = …;
static const struct nfs_commit_completion_ops nfs_commit_completion_ops = …;
int nfs_generic_commit_list(struct inode *inode, struct list_head *head,
int how, struct nfs_commit_info *cinfo)
{ … }
static int __nfs_commit_inode(struct inode *inode, int how,
struct writeback_control *wbc)
{ … }
int nfs_commit_inode(struct inode *inode, int how)
{ … }
EXPORT_SYMBOL_GPL(…);
int nfs_write_inode(struct inode *inode, struct writeback_control *wbc)
{ … }
EXPORT_SYMBOL_GPL(…);
int nfs_filemap_write_and_wait_range(struct address_space *mapping,
loff_t lstart, loff_t lend)
{ … }
EXPORT_SYMBOL_GPL(…);
int nfs_wb_all(struct inode *inode)
{ … }
EXPORT_SYMBOL_GPL(…);
int nfs_wb_folio_cancel(struct inode *inode, struct folio *folio)
{ … }
int nfs_wb_folio(struct inode *inode, struct folio *folio)
{ … }
#ifdef CONFIG_MIGRATION
int nfs_migrate_folio(struct address_space *mapping, struct folio *dst,
struct folio *src, enum migrate_mode mode)
{ … }
#endif
int __init nfs_init_writepagecache(void)
{ … }
void nfs_destroy_writepagecache(void)
{ … }
static const struct nfs_rw_ops nfs_rw_write_ops = …;