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