1 /* SPDX-License-Identifier: GPL-2.0 */
3 * NFSv4 flexfile layout driver data structures.
5 * Copyright (c) 2014, Primary Data, Inc. All rights reserved.
7 * Tao Peng <bergwolf@primarydata.com>
10 #ifndef FS_NFS_NFS4FLEXFILELAYOUT_H
11 #define FS_NFS_NFS4FLEXFILELAYOUT_H
13 #define FF_FLAGS_NO_LAYOUTCOMMIT 1
14 #define FF_FLAGS_NO_IO_THRU_MDS 2
15 #define FF_FLAGS_NO_READ_IO 4
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
23 /* LAYOUTSTATS report interval in ms */
24 #define FF_LAYOUTSTATS_REPORT_INTERVAL (60000L)
25 #define FF_LAYOUTSTATS_MAXDEV 4
27 struct nfs4_ff_ds_version
{
35 /* chained in global deviceid hlist */
36 struct nfs4_ff_layout_ds
{
37 struct nfs4_deviceid_node id_node
;
39 struct nfs4_ff_ds_version
*ds_versions
;
40 struct nfs4_pnfs_ds
*ds
;
43 struct nfs4_ff_layout_ds_err
{
44 struct list_head list
; /* linked in mirror error_list */
48 enum nfs_opnum4 opnum
;
50 struct nfs4_deviceid deviceid
;
53 struct nfs4_ff_io_stat
{
55 __u64 bytes_requested
;
57 __u64 bytes_completed
;
58 __u64 bytes_not_delivered
;
59 ktime_t total_busy_time
;
60 ktime_t aggregate_completion_time
;
63 struct nfs4_ff_busy_timer
{
68 struct nfs4_ff_layoutstat
{
69 struct nfs4_ff_io_stat io_stat
;
70 struct nfs4_ff_busy_timer busy_timer
;
73 struct nfs4_ff_layout_mirror
{
74 struct pnfs_layout_hdr
*layout
;
75 struct list_head mirrors
;
78 struct nfs4_deviceid devid
;
79 struct nfs4_ff_layout_ds
*mirror_ds
;
81 struct nfs_fh
*fh_versions
;
83 struct rpc_cred __rcu
*ro_cred
;
84 struct rpc_cred __rcu
*rw_cred
;
88 struct nfs4_ff_layoutstat read_stat
;
89 struct nfs4_ff_layoutstat write_stat
;
94 #define NFS4_FF_MIRROR_STAT_AVAIL (0)
96 struct nfs4_ff_layout_segment
{
97 struct pnfs_layout_segment generic_hdr
;
100 u32 mirror_array_cnt
;
101 struct nfs4_ff_layout_mirror
**mirror_array
;
104 struct 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 */
112 struct 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];
120 static inline struct nfs4_flexfile_layout
*
121 FF_LAYOUT_FROM_HDR(struct pnfs_layout_hdr
*lo
)
123 return container_of(lo
, struct nfs4_flexfile_layout
, generic_hdr
);
126 static inline struct nfs4_ff_layout_segment
*
127 FF_LAYOUT_LSEG(struct pnfs_layout_segment
*lseg
)
129 return container_of(lseg
,
130 struct nfs4_ff_layout_segment
,
134 static inline struct nfs4_deviceid_node
*
135 FF_LAYOUT_DEVID_NODE(struct pnfs_layout_segment
*lseg
, u32 idx
)
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
)
141 return &FF_LAYOUT_LSEG(lseg
)->mirror_array
[idx
]->mirror_ds
->id_node
;
144 static inline struct nfs4_ff_layout_ds
*
145 FF_LAYOUT_MIRROR_DS(struct nfs4_deviceid_node
*node
)
147 return container_of(node
, struct nfs4_ff_layout_ds
, id_node
);
150 static inline struct nfs4_ff_layout_mirror
*
151 FF_LAYOUT_COMP(struct pnfs_layout_segment
*lseg
, u32 idx
)
153 if (idx
>= FF_LAYOUT_LSEG(lseg
)->mirror_array_cnt
)
155 return FF_LAYOUT_LSEG(lseg
)->mirror_array
[idx
];
159 FF_LAYOUT_MIRROR_COUNT(struct pnfs_layout_segment
*lseg
)
161 return FF_LAYOUT_LSEG(lseg
)->mirror_array_cnt
;
165 ff_layout_no_fallback_to_mds(struct pnfs_layout_segment
*lseg
)
167 return FF_LAYOUT_LSEG(lseg
)->flags
& FF_FLAGS_NO_IO_THRU_MDS
;
171 ff_layout_no_read_on_rw(struct pnfs_layout_segment
*lseg
)
173 return FF_LAYOUT_LSEG(lseg
)->flags
& FF_FLAGS_NO_READ_IO
;
177 ff_layout_test_devid_unavailable(struct nfs4_deviceid_node
*node
)
180 * Flexfiles should never mark a DS unavailable, but if it does
181 * print a (ratelimited) warning as this can affect performance.
183 if (nfs4_test_deviceid_unavailable(node
)) {
184 u32
*p
= (u32
*)node
->deviceid
.data
;
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]);
195 nfs4_ff_layout_ds_version(struct pnfs_layout_segment
*lseg
, u32 ds_idx
)
197 return FF_LAYOUT_COMP(lseg
, ds_idx
)->mirror_ds
->ds_versions
[0].version
;
200 struct nfs4_ff_layout_ds
*
201 nfs4_ff_alloc_deviceid_node(struct nfs_server
*server
, struct pnfs_device
*pdev
,
203 void nfs4_ff_layout_put_deviceid(struct nfs4_ff_layout_ds
*mirror_ds
);
204 void nfs4_ff_layout_free_deviceid(struct nfs4_ff_layout_ds
*mirror_ds
);
205 int 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
,
209 int ff_layout_encode_ds_ioerr(struct xdr_stream
*xdr
, const struct list_head
*head
);
210 void ff_layout_free_ds_ioerr(struct list_head
*head
);
211 unsigned 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
);
216 nfs4_ff_layout_select_ds_fh(struct pnfs_layout_segment
*lseg
, u32 mirror_idx
);
218 struct nfs4_pnfs_ds
*
219 nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment
*lseg
, u32 ds_idx
,
223 nfs4_ff_find_or_create_ds_client(struct pnfs_layout_segment
*lseg
,
225 struct nfs_client
*ds_clp
,
226 struct inode
*inode
);
227 struct rpc_cred
*ff_layout_get_ds_cred(struct pnfs_layout_segment
*lseg
,
228 u32 ds_idx
, struct rpc_cred
*mdscred
);
229 bool ff_layout_avoid_mds_available_ds(struct pnfs_layout_segment
*lseg
);
230 bool ff_layout_avoid_read_on_rw(struct pnfs_layout_segment
*lseg
);
232 #endif /* FS_NFS_NFS4FLEXFILELAYOUT_H */