linux/fs/nfs/flexfilelayout/flexfilelayout.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   3 * NFSv4 flexfile layout driver data structures.
   4 *
   5 * Copyright (c) 2014, Primary Data, Inc. All rights reserved.
   6 *
   7 * Tao Peng <bergwolf@primarydata.com>
   8 */
   9
  10#ifndef FS_NFS_NFS4FLEXFILELAYOUT_H
  11#define FS_NFS_NFS4FLEXFILELAYOUT_H
  12
  13#define FF_FLAGS_NO_LAYOUTCOMMIT 1
  14#define FF_FLAGS_NO_IO_THRU_MDS  2
  15#define FF_FLAGS_NO_READ_IO      4
  16
  17#include <linux/refcount.h>
  18#include "../pnfs.h"
  19
  20/* XXX: Let's filter out insanely large mirror count for now to avoid oom
  21 * due to network error etc. */
  22#define NFS4_FLEXFILE_LAYOUT_MAX_MIRROR_CNT 4096
  23
  24/* LAYOUTSTATS report interval in ms */
  25#define FF_LAYOUTSTATS_REPORT_INTERVAL (60000L)
  26#define FF_LAYOUTSTATS_MAXDEV 4
  27
  28struct nfs4_ff_ds_version {
  29        u32                             version;
  30        u32                             minor_version;
  31        u32                             rsize;
  32        u32                             wsize;
  33        bool                            tightly_coupled;
  34};
  35
  36/* chained in global deviceid hlist */
  37struct nfs4_ff_layout_ds {
  38        struct nfs4_deviceid_node       id_node;
  39        u32                             ds_versions_cnt;
  40        struct nfs4_ff_ds_version       *ds_versions;
  41        struct nfs4_pnfs_ds             *ds;
  42};
  43
  44struct nfs4_ff_layout_ds_err {
  45        struct list_head                list; /* linked in mirror error_list */
  46        u64                             offset;
  47        u64                             length;
  48        int                             status;
  49        enum nfs_opnum4                 opnum;
  50        nfs4_stateid                    stateid;
  51        struct nfs4_deviceid            deviceid;
  52};
  53
  54struct nfs4_ff_io_stat {
  55        __u64                           ops_requested;
  56        __u64                           bytes_requested;
  57        __u64                           ops_completed;
  58        __u64                           bytes_completed;
  59        __u64                           bytes_not_delivered;
  60        ktime_t                         total_busy_time;
  61        ktime_t                         aggregate_completion_time;
  62};
  63
  64struct nfs4_ff_busy_timer {
  65        ktime_t start_time;
  66        atomic_t n_ops;
  67};
  68
  69struct nfs4_ff_layoutstat {
  70        struct nfs4_ff_io_stat io_stat;
  71        struct nfs4_ff_busy_timer busy_timer;
  72};
  73
  74struct nfs4_ff_layout_mirror {
  75        struct pnfs_layout_hdr          *layout;
  76        struct list_head                mirrors;
  77        u32                             ds_count;
  78        u32                             efficiency;
  79        struct nfs4_deviceid            devid;
  80        struct nfs4_ff_layout_ds        *mirror_ds;
  81        u32                             fh_versions_cnt;
  82        struct nfs_fh                   *fh_versions;
  83        nfs4_stateid                    stateid;
  84        const struct cred __rcu         *ro_cred;
  85        const struct cred __rcu         *rw_cred;
  86        refcount_t                      ref;
  87        spinlock_t                      lock;
  88        unsigned long                   flags;
  89        struct nfs4_ff_layoutstat       read_stat;
  90        struct nfs4_ff_layoutstat       write_stat;
  91        ktime_t                         start_time;
  92        u32                             report_interval;
  93};
  94
  95#define NFS4_FF_MIRROR_STAT_AVAIL       (0)
  96
  97struct nfs4_ff_layout_segment {
  98        struct pnfs_layout_segment      generic_hdr;
  99        u64                             stripe_unit;
 100        u32                             flags;
 101        u32                             mirror_array_cnt;
 102        struct nfs4_ff_layout_mirror    *mirror_array[];
 103};
 104
 105struct nfs4_flexfile_layout {
 106        struct pnfs_layout_hdr generic_hdr;
 107        struct pnfs_ds_commit_info commit_info;
 108        struct list_head        mirrors;
 109        struct list_head        error_list; /* nfs4_ff_layout_ds_err */
 110        ktime_t                 last_report_time; /* Layoutstat report times */
 111};
 112
 113struct nfs4_flexfile_layoutreturn_args {
 114        struct list_head errors;
 115        struct nfs42_layoutstat_devinfo devinfo[FF_LAYOUTSTATS_MAXDEV];
 116        unsigned int num_errors;
 117        unsigned int num_dev;
 118        struct page *pages[1];
 119};
 120
 121static inline struct nfs4_flexfile_layout *
 122FF_LAYOUT_FROM_HDR(struct pnfs_layout_hdr *lo)
 123{
 124        return container_of(lo, struct nfs4_flexfile_layout, generic_hdr);
 125}
 126
 127static inline struct nfs4_ff_layout_segment *
 128FF_LAYOUT_LSEG(struct pnfs_layout_segment *lseg)
 129{
 130        return container_of(lseg,
 131                            struct nfs4_ff_layout_segment,
 132                            generic_hdr);
 133}
 134
 135static inline struct nfs4_ff_layout_ds *
 136FF_LAYOUT_MIRROR_DS(struct nfs4_deviceid_node *node)
 137{
 138        return container_of(node, struct nfs4_ff_layout_ds, id_node);
 139}
 140
 141static inline struct nfs4_ff_layout_mirror *
 142FF_LAYOUT_COMP(struct pnfs_layout_segment *lseg, u32 idx)
 143{
 144        struct nfs4_ff_layout_segment *fls = FF_LAYOUT_LSEG(lseg);
 145
 146        if (idx < fls->mirror_array_cnt)
 147                return fls->mirror_array[idx];
 148        return NULL;
 149}
 150
 151static inline struct nfs4_deviceid_node *
 152FF_LAYOUT_DEVID_NODE(struct pnfs_layout_segment *lseg, u32 idx)
 153{
 154        struct nfs4_ff_layout_mirror *mirror = FF_LAYOUT_COMP(lseg, idx);
 155
 156        if (mirror != NULL) {
 157                struct nfs4_ff_layout_ds *mirror_ds = mirror->mirror_ds;
 158
 159                if (!IS_ERR_OR_NULL(mirror_ds))
 160                        return &mirror_ds->id_node;
 161        }
 162        return NULL;
 163}
 164
 165static inline u32
 166FF_LAYOUT_MIRROR_COUNT(struct pnfs_layout_segment *lseg)
 167{
 168        return FF_LAYOUT_LSEG(lseg)->mirror_array_cnt;
 169}
 170
 171static inline bool
 172ff_layout_no_fallback_to_mds(struct pnfs_layout_segment *lseg)
 173{
 174        return FF_LAYOUT_LSEG(lseg)->flags & FF_FLAGS_NO_IO_THRU_MDS;
 175}
 176
 177static inline bool
 178ff_layout_no_read_on_rw(struct pnfs_layout_segment *lseg)
 179{
 180        return FF_LAYOUT_LSEG(lseg)->flags & FF_FLAGS_NO_READ_IO;
 181}
 182
 183static inline int
 184nfs4_ff_layout_ds_version(const struct nfs4_ff_layout_mirror *mirror)
 185{
 186        return mirror->mirror_ds->ds_versions[0].version;
 187}
 188
 189struct nfs4_ff_layout_ds *
 190nfs4_ff_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev,
 191                            gfp_t gfp_flags);
 192void nfs4_ff_layout_put_deviceid(struct nfs4_ff_layout_ds *mirror_ds);
 193void nfs4_ff_layout_free_deviceid(struct nfs4_ff_layout_ds *mirror_ds);
 194int ff_layout_track_ds_error(struct nfs4_flexfile_layout *flo,
 195                             struct nfs4_ff_layout_mirror *mirror, u64 offset,
 196                             u64 length, int status, enum nfs_opnum4 opnum,
 197                             gfp_t gfp_flags);
 198void ff_layout_send_layouterror(struct pnfs_layout_segment *lseg);
 199int ff_layout_encode_ds_ioerr(struct xdr_stream *xdr, const struct list_head *head);
 200void ff_layout_free_ds_ioerr(struct list_head *head);
 201unsigned int ff_layout_fetch_ds_ioerr(struct pnfs_layout_hdr *lo,
 202                const struct pnfs_layout_range *range,
 203                struct list_head *head,
 204                unsigned int maxnum);
 205struct nfs_fh *
 206nfs4_ff_layout_select_ds_fh(struct nfs4_ff_layout_mirror *mirror);
 207void
 208nfs4_ff_layout_select_ds_stateid(const struct nfs4_ff_layout_mirror *mirror,
 209                nfs4_stateid *stateid);
 210
 211struct nfs4_pnfs_ds *
 212nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg,
 213                          struct nfs4_ff_layout_mirror *mirror,
 214                          bool fail_return);
 215
 216struct rpc_clnt *
 217nfs4_ff_find_or_create_ds_client(struct nfs4_ff_layout_mirror *mirror,
 218                                 struct nfs_client *ds_clp,
 219                                 struct inode *inode);
 220const struct cred *ff_layout_get_ds_cred(struct nfs4_ff_layout_mirror *mirror,
 221                                         const struct pnfs_layout_range *range,
 222                                         const struct cred *mdscred);
 223bool ff_layout_avoid_mds_available_ds(struct pnfs_layout_segment *lseg);
 224bool ff_layout_avoid_read_on_rw(struct pnfs_layout_segment *lseg);
 225
 226#endif /* FS_NFS_NFS4FLEXFILELAYOUT_H */
 227