#include <linux/nfs_fs.h>
#include <linux/nfs_mount.h>
#include <linux/nfs_page.h>
#include <linux/module.h>
#include <linux/sched/mm.h>
#include <linux/sunrpc/metrics.h>
#include "flexfilelayout.h"
#include "../nfs4session.h"
#include "../nfs4idmap.h"
#include "../internal.h"
#include "../delegation.h"
#include "../nfs4trace.h"
#include "../iostat.h"
#include "../nfs.h"
#include "../nfs42.h"
#define NFSDBG_FACILITY …
#define FF_LAYOUT_POLL_RETRY_MAX …
#define FF_LAYOUTRETURN_MAXERR …
enum nfs4_ff_op_type { … };
static unsigned short io_maxretrans;
static const struct pnfs_commit_ops ff_layout_commit_ops;
static void ff_layout_read_record_layoutstats_done(struct rpc_task *task,
struct nfs_pgio_header *hdr);
static int
ff_layout_mirror_prepare_stats(struct pnfs_layout_hdr *lo,
struct nfs42_layoutstat_devinfo *devinfo,
int dev_limit, enum nfs4_ff_op_type type);
static void ff_layout_encode_ff_layoutupdate(struct xdr_stream *xdr,
const struct nfs42_layoutstat_devinfo *devinfo,
struct nfs4_ff_layout_mirror *mirror);
static struct pnfs_layout_hdr *
ff_layout_alloc_layout_hdr(struct inode *inode, gfp_t gfp_flags)
{ … }
static void
ff_layout_free_layout_hdr(struct pnfs_layout_hdr *lo)
{ … }
static int decode_pnfs_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
{ … }
static int decode_deviceid(struct xdr_stream *xdr, struct nfs4_deviceid *devid)
{ … }
static int decode_nfs_fh(struct xdr_stream *xdr, struct nfs_fh *fh)
{ … }
static int
decode_name(struct xdr_stream *xdr, u32 *id)
{ … }
static bool ff_mirror_match_fh(const struct nfs4_ff_layout_mirror *m1,
const struct nfs4_ff_layout_mirror *m2)
{ … }
static struct nfs4_ff_layout_mirror *
ff_layout_add_mirror(struct pnfs_layout_hdr *lo,
struct nfs4_ff_layout_mirror *mirror)
{ … }
static void
ff_layout_remove_mirror(struct nfs4_ff_layout_mirror *mirror)
{ … }
static struct nfs4_ff_layout_mirror *ff_layout_alloc_mirror(gfp_t gfp_flags)
{ … }
static void ff_layout_free_mirror(struct nfs4_ff_layout_mirror *mirror)
{ … }
static void ff_layout_put_mirror(struct nfs4_ff_layout_mirror *mirror)
{ … }
static void ff_layout_free_mirror_array(struct nfs4_ff_layout_segment *fls)
{ … }
static void _ff_layout_free_lseg(struct nfs4_ff_layout_segment *fls)
{ … }
static bool
ff_lseg_match_mirrors(struct pnfs_layout_segment *l1,
struct pnfs_layout_segment *l2)
{ … }
static bool
ff_lseg_range_is_after(const struct pnfs_layout_range *l1,
const struct pnfs_layout_range *l2)
{ … }
static bool
ff_lseg_merge(struct pnfs_layout_segment *new,
struct pnfs_layout_segment *old)
{ … }
static void
ff_layout_add_lseg(struct pnfs_layout_hdr *lo,
struct pnfs_layout_segment *lseg,
struct list_head *free_me)
{ … }
static void ff_layout_sort_mirrors(struct nfs4_ff_layout_segment *fls)
{ … }
static struct pnfs_layout_segment *
ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh,
struct nfs4_layoutget_res *lgr,
gfp_t gfp_flags)
{ … }
static void
ff_layout_free_lseg(struct pnfs_layout_segment *lseg)
{ … }
static void
nfs4_ff_start_busy_timer(struct nfs4_ff_busy_timer *timer, ktime_t now)
{ … }
static ktime_t
nfs4_ff_end_busy_timer(struct nfs4_ff_busy_timer *timer, ktime_t now)
{ … }
static bool
nfs4_ff_layoutstat_start_io(struct nfs4_ff_layout_mirror *mirror,
struct nfs4_ff_layoutstat *layoutstat,
ktime_t now)
{ … }
static void
nfs4_ff_layout_stat_io_update_requested(struct nfs4_ff_layoutstat *layoutstat,
__u64 requested)
{ … }
static void
nfs4_ff_layout_stat_io_update_completed(struct nfs4_ff_layoutstat *layoutstat,
__u64 requested,
__u64 completed,
ktime_t time_completed,
ktime_t time_started)
{ … }
static void
nfs4_ff_layout_stat_io_start_read(struct inode *inode,
struct nfs4_ff_layout_mirror *mirror,
__u64 requested, ktime_t now)
{ … }
static void
nfs4_ff_layout_stat_io_end_read(struct rpc_task *task,
struct nfs4_ff_layout_mirror *mirror,
__u64 requested,
__u64 completed)
{ … }
static void
nfs4_ff_layout_stat_io_start_write(struct inode *inode,
struct nfs4_ff_layout_mirror *mirror,
__u64 requested, ktime_t now)
{ … }
static void
nfs4_ff_layout_stat_io_end_write(struct rpc_task *task,
struct nfs4_ff_layout_mirror *mirror,
__u64 requested,
__u64 completed,
enum nfs3_stable_how committed)
{ … }
static void
ff_layout_mark_ds_unreachable(struct pnfs_layout_segment *lseg, u32 idx)
{ … }
static void
ff_layout_mark_ds_reachable(struct pnfs_layout_segment *lseg, u32 idx)
{ … }
static struct nfs4_pnfs_ds *
ff_layout_choose_ds_for_read(struct pnfs_layout_segment *lseg,
u32 start_idx, u32 *best_idx,
bool check_device)
{ … }
static struct nfs4_pnfs_ds *
ff_layout_choose_any_ds_for_read(struct pnfs_layout_segment *lseg,
u32 start_idx, u32 *best_idx)
{ … }
static struct nfs4_pnfs_ds *
ff_layout_choose_valid_ds_for_read(struct pnfs_layout_segment *lseg,
u32 start_idx, u32 *best_idx)
{ … }
static struct nfs4_pnfs_ds *
ff_layout_choose_best_ds_for_read(struct pnfs_layout_segment *lseg,
u32 start_idx, u32 *best_idx)
{ … }
static struct nfs4_pnfs_ds *
ff_layout_get_ds_for_read(struct nfs_pageio_descriptor *pgio,
u32 *best_idx)
{ … }
static void
ff_layout_pg_get_read(struct nfs_pageio_descriptor *pgio,
struct nfs_page *req,
bool strict_iomode)
{ … }
static void
ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio,
struct nfs_page *req)
{ … }
static void
ff_layout_pg_init_write(struct nfs_pageio_descriptor *pgio,
struct nfs_page *req)
{ … }
static unsigned int
ff_layout_pg_get_mirror_count_write(struct nfs_pageio_descriptor *pgio,
struct nfs_page *req)
{ … }
static u32
ff_layout_pg_set_mirror_write(struct nfs_pageio_descriptor *desc, u32 idx)
{ … }
static struct nfs_pgio_mirror *
ff_layout_pg_get_mirror_write(struct nfs_pageio_descriptor *desc, u32 idx)
{ … }
static const struct nfs_pageio_ops ff_layout_pg_read_ops = …;
static const struct nfs_pageio_ops ff_layout_pg_write_ops = …;
static void ff_layout_reset_write(struct nfs_pgio_header *hdr, bool retry_pnfs)
{ … }
static void ff_layout_resend_pnfs_read(struct nfs_pgio_header *hdr)
{ … }
static void ff_layout_reset_read(struct nfs_pgio_header *hdr)
{ … }
static int ff_layout_async_handle_error_v4(struct rpc_task *task,
struct nfs4_state *state,
struct nfs_client *clp,
struct pnfs_layout_segment *lseg,
u32 idx)
{ … }
static int ff_layout_async_handle_error_v3(struct rpc_task *task,
struct pnfs_layout_segment *lseg,
u32 idx)
{ … }
static int ff_layout_async_handle_error(struct rpc_task *task,
struct nfs4_state *state,
struct nfs_client *clp,
struct pnfs_layout_segment *lseg,
u32 idx)
{ … }
static void ff_layout_io_track_ds_error(struct pnfs_layout_segment *lseg,
u32 idx, u64 offset, u64 length,
u32 *op_status, int opnum, int error)
{ … }
static int ff_layout_read_done_cb(struct rpc_task *task,
struct nfs_pgio_header *hdr)
{ … }
static bool
ff_layout_need_layoutcommit(struct pnfs_layout_segment *lseg)
{ … }
static void
ff_layout_set_layoutcommit(struct inode *inode,
struct pnfs_layout_segment *lseg,
loff_t end_offset)
{ … }
static void ff_layout_read_record_layoutstats_start(struct rpc_task *task,
struct nfs_pgio_header *hdr)
{ … }
static void ff_layout_read_record_layoutstats_done(struct rpc_task *task,
struct nfs_pgio_header *hdr)
{ … }
static int ff_layout_read_prepare_common(struct rpc_task *task,
struct nfs_pgio_header *hdr)
{ … }
static void ff_layout_read_prepare_v3(struct rpc_task *task, void *data)
{ … }
static void ff_layout_read_prepare_v4(struct rpc_task *task, void *data)
{ … }
static void ff_layout_read_call_done(struct rpc_task *task, void *data)
{ … }
static void ff_layout_read_count_stats(struct rpc_task *task, void *data)
{ … }
static void ff_layout_read_release(void *data)
{ … }
static int ff_layout_write_done_cb(struct rpc_task *task,
struct nfs_pgio_header *hdr)
{ … }
static int ff_layout_commit_done_cb(struct rpc_task *task,
struct nfs_commit_data *data)
{ … }
static void ff_layout_write_record_layoutstats_start(struct rpc_task *task,
struct nfs_pgio_header *hdr)
{ … }
static void ff_layout_write_record_layoutstats_done(struct rpc_task *task,
struct nfs_pgio_header *hdr)
{ … }
static int ff_layout_write_prepare_common(struct rpc_task *task,
struct nfs_pgio_header *hdr)
{ … }
static void ff_layout_write_prepare_v3(struct rpc_task *task, void *data)
{ … }
static void ff_layout_write_prepare_v4(struct rpc_task *task, void *data)
{ … }
static void ff_layout_write_call_done(struct rpc_task *task, void *data)
{ … }
static void ff_layout_write_count_stats(struct rpc_task *task, void *data)
{ … }
static void ff_layout_write_release(void *data)
{ … }
static void ff_layout_commit_record_layoutstats_start(struct rpc_task *task,
struct nfs_commit_data *cdata)
{ … }
static void ff_layout_commit_record_layoutstats_done(struct rpc_task *task,
struct nfs_commit_data *cdata)
{ … }
static int ff_layout_commit_prepare_common(struct rpc_task *task,
struct nfs_commit_data *cdata)
{ … }
static void ff_layout_commit_prepare_v3(struct rpc_task *task, void *data)
{ … }
static void ff_layout_commit_prepare_v4(struct rpc_task *task, void *data)
{ … }
static void ff_layout_commit_done(struct rpc_task *task, void *data)
{ … }
static void ff_layout_commit_count_stats(struct rpc_task *task, void *data)
{ … }
static void ff_layout_commit_release(void *data)
{ … }
static const struct rpc_call_ops ff_layout_read_call_ops_v3 = …;
static const struct rpc_call_ops ff_layout_read_call_ops_v4 = …;
static const struct rpc_call_ops ff_layout_write_call_ops_v3 = …;
static const struct rpc_call_ops ff_layout_write_call_ops_v4 = …;
static const struct rpc_call_ops ff_layout_commit_call_ops_v3 = …;
static const struct rpc_call_ops ff_layout_commit_call_ops_v4 = …;
static enum pnfs_try_status
ff_layout_read_pagelist(struct nfs_pgio_header *hdr)
{ … }
static enum pnfs_try_status
ff_layout_write_pagelist(struct nfs_pgio_header *hdr, int sync)
{ … }
static u32 calc_ds_index_from_commit(struct pnfs_layout_segment *lseg, u32 i)
{ … }
static struct nfs_fh *
select_ds_fh_from_commit(struct pnfs_layout_segment *lseg, u32 i)
{ … }
static int ff_layout_initiate_commit(struct nfs_commit_data *data, int how)
{ … }
static int
ff_layout_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
int how, struct nfs_commit_info *cinfo)
{ … }
static bool ff_layout_match_rw(const struct rpc_task *task,
const struct nfs_pgio_header *hdr,
const struct pnfs_layout_segment *lseg)
{ … }
static bool ff_layout_match_commit(const struct rpc_task *task,
const struct nfs_commit_data *cdata,
const struct pnfs_layout_segment *lseg)
{ … }
static bool ff_layout_match_io(const struct rpc_task *task, const void *data)
{ … }
static void ff_layout_cancel_io(struct pnfs_layout_segment *lseg)
{ … }
static struct pnfs_ds_commit_info *
ff_layout_get_ds_info(struct inode *inode)
{ … }
static void
ff_layout_setup_ds_info(struct pnfs_ds_commit_info *fl_cinfo,
struct pnfs_layout_segment *lseg)
{ … }
static void
ff_layout_release_ds_info(struct pnfs_ds_commit_info *fl_cinfo,
struct inode *inode)
{ … }
static void
ff_layout_free_deviceid_node(struct nfs4_deviceid_node *d)
{ … }
static int ff_layout_encode_ioerr(struct xdr_stream *xdr,
const struct nfs4_layoutreturn_args *args,
const struct nfs4_flexfile_layoutreturn_args *ff_args)
{ … }
static void
encode_opaque_fixed(struct xdr_stream *xdr, const void *buf, size_t len)
{ … }
static void
ff_layout_encode_ff_iostat_head(struct xdr_stream *xdr,
const nfs4_stateid *stateid,
const struct nfs42_layoutstat_devinfo *devinfo)
{ … }
static void
ff_layout_encode_ff_iostat(struct xdr_stream *xdr,
const nfs4_stateid *stateid,
const struct nfs42_layoutstat_devinfo *devinfo)
{ … }
static void ff_layout_encode_iostats_array(struct xdr_stream *xdr,
const struct nfs4_layoutreturn_args *args,
struct nfs4_flexfile_layoutreturn_args *ff_args)
{ … }
static void
ff_layout_free_iostats_array(struct nfs42_layoutstat_devinfo *devinfo,
unsigned int num_entries)
{ … }
static struct nfs4_deviceid_node *
ff_layout_alloc_deviceid_node(struct nfs_server *server,
struct pnfs_device *pdev, gfp_t gfp_flags)
{ … }
static void
ff_layout_encode_layoutreturn(struct xdr_stream *xdr,
const void *voidargs,
const struct nfs4_xdr_opaque_data *ff_opaque)
{ … }
static void
ff_layout_free_layoutreturn(struct nfs4_xdr_opaque_data *args)
{ … }
static const struct nfs4_xdr_opaque_ops layoutreturn_ops = …;
static int
ff_layout_prepare_layoutreturn(struct nfs4_layoutreturn_args *args)
{ … }
#ifdef CONFIG_NFS_V4_2
void
ff_layout_send_layouterror(struct pnfs_layout_segment *lseg)
{ … }
#else
void
ff_layout_send_layouterror(struct pnfs_layout_segment *lseg)
{
}
#endif
static int
ff_layout_ntop4(const struct sockaddr *sap, char *buf, const size_t buflen)
{ … }
static size_t
ff_layout_ntop6_noscopeid(const struct sockaddr *sap, char *buf,
const int buflen)
{ … }
static void
ff_layout_encode_netaddr(struct xdr_stream *xdr, struct nfs4_pnfs_ds_addr *da)
{ … }
static void
ff_layout_encode_nfstime(struct xdr_stream *xdr,
ktime_t t)
{ … }
static void
ff_layout_encode_io_latency(struct xdr_stream *xdr,
struct nfs4_ff_io_stat *stat)
{ … }
static void
ff_layout_encode_ff_layoutupdate(struct xdr_stream *xdr,
const struct nfs42_layoutstat_devinfo *devinfo,
struct nfs4_ff_layout_mirror *mirror)
{ … }
static void
ff_layout_encode_layoutstats(struct xdr_stream *xdr, const void *args,
const struct nfs4_xdr_opaque_data *opaque)
{ … }
static void
ff_layout_free_layoutstats(struct nfs4_xdr_opaque_data *opaque)
{ … }
static const struct nfs4_xdr_opaque_ops layoutstat_ops = …;
static int
ff_layout_mirror_prepare_stats(struct pnfs_layout_hdr *lo,
struct nfs42_layoutstat_devinfo *devinfo,
int dev_limit, enum nfs4_ff_op_type type)
{ … }
static int ff_layout_prepare_layoutstats(struct nfs42_layoutstat_args *args)
{ … }
static int
ff_layout_set_layoutdriver(struct nfs_server *server,
const struct nfs_fh *dummy)
{ … }
static const struct pnfs_commit_ops ff_layout_commit_ops = …;
static struct pnfs_layoutdriver_type flexfilelayout_type = …;
static int __init nfs4flexfilelayout_init(void)
{ … }
static void __exit nfs4flexfilelayout_exit(void)
{ … }
MODULE_ALIAS(…) …;
MODULE_LICENSE(…) …;
MODULE_DESCRIPTION(…) …;
module_init(…) …;
module_exit(nfs4flexfilelayout_exit);
module_param(io_maxretrans, ushort, 0644);
MODULE_PARM_DESC(…) …;