1 /* NFSv4.1 client for Windows
2 * Copyright © 2012 The Regents of the University of Michigan
4 * Olga Kornievskaia <aglo@umich.edu>
5 * Casey Bodley <cbodley@umich.edu>
7 * This library is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation; either version 2.1 of the License, or (at
10 * your option) any later version.
12 * This library is distributed in the hope that it will be useful, but
13 * without any warranty; without even the implied warranty of merchantability
14 * or fitness for a particular purpose. See the GNU Lesser General Public
15 * License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 #include "nfs41_types.h"
29 /* preprocessor options */
32 # ifndef PNFS_DISABLE_READ
33 # define PNFS_ENABLE_READ
35 # ifndef PNFS_DISABLE_WRITE
36 # define PNFS_ENABLE_WRITE
39 # define PNFS_THREADING
41 /* XXX: the thread-by-server model breaks down when using dense layouts,
42 * because multiple stripes could be mapped to a single data server, and
43 * the per-data-server thread would have to send a COMMIT for each stripe */
44 //# define PNFS_THREAD_BY_SERVER
49 /* forward declarations from nfs41.h */
50 struct __nfs41_client
;
51 struct __nfs41_session
;
52 struct __nfs41_open_state
;
57 /* pnfs error values, in order of increasing severity */
62 PNFSERR_NOT_SUPPORTED
,
63 PNFSERR_NOT_CONNECTED
,
67 PNFSERR_INVALID_FH_LIST
,
68 PNFSERR_INVALID_DS_INDEX
,
70 PNFSERR_LAYOUT_RECALLED
,
71 PNFSERR_LAYOUT_CHANGED
,
74 enum pnfs_layout_type
{
75 PNFS_LAYOUTTYPE_FILE
= 1,
76 PNFS_LAYOUTTYPE_OBJECT
= 2,
77 PNFS_LAYOUTTYPE_BLOCK
= 3
81 PNFS_IOMODE_READ
= 0x1,
83 PNFS_IOMODE_ANY
= PNFS_IOMODE_READ
| PNFS_IOMODE_RW
86 enum pnfs_layout_status
{
87 /* a LAYOUTGET error indicated that this layout will never be granted */
88 PNFS_LAYOUT_UNAVAILABLE
= 0x10,
89 /* LAYOUTGET returned BADIOMODE, so a RW layout will never be granted */
90 PNFS_LAYOUT_NOT_RW
= 0x20,
93 enum pnfs_device_status
{
94 /* GETDEVICEINFO was successful */
95 PNFS_DEVICE_GRANTED
= 0x1,
96 /* a bulk recall or lease expiration led to device invalidation */
97 PNFS_DEVICE_REVOKED
= 0x2,
100 enum pnfs_return_type
{
101 PNFS_RETURN_FILE
= 1,
102 PNFS_RETURN_FSID
= 2,
106 #define NFL4_UFLG_MASK 0x0000003F
107 #define NFL4_UFLG_DENSE 0x00000001
108 #define NFL4_UFLG_COMMIT_THRU_MDS 0x00000002
109 #define NFL4_UFLG_STRIPE_UNIT_SIZE_MASK 0xFFFFFFC0
111 #define PNFS_DEVICEID_SIZE 16
115 typedef struct __pnfs_device
{
116 unsigned char deviceid
[PNFS_DEVICEID_SIZE
];
117 enum pnfs_layout_type type
;
118 enum pnfs_device_status status
;
119 uint32_t layout_count
; /* layouts using this device */
120 CRITICAL_SECTION lock
;
123 typedef struct __pnfs_stripe_indices
{
126 } pnfs_stripe_indices
;
128 typedef struct __pnfs_data_server
{
129 struct __nfs41_client
*client
;
134 typedef struct __pnfs_data_server_list
{
136 pnfs_data_server
*arr
;
137 } pnfs_data_server_list
;
139 typedef struct __pnfs_file_device
{
141 pnfs_stripe_indices stripes
;
142 pnfs_data_server_list servers
;
143 struct pnfs_file_device_list
*devices
; /* -> nfs41_client.devices */
144 struct list_entry entry
; /* position in devices */
149 typedef struct __pnfs_layout_state
{
152 struct list_entry entry
; /* position in nfs41_client.layouts */
153 struct list_entry layouts
; /* list of pnfs_file_layouts */
154 struct list_entry recalls
; /* list of pnfs_layouts */
155 enum pnfs_layout_status status
;
156 bool_t return_on_close
;
157 LONG open_count
; /* for return on last close */
158 uint32_t io_count
; /* number of pending io operations */
159 bool_t pending
; /* pending LAYOUTGET/LAYOUTRETURN */
161 CONDITION_VARIABLE cond
;
164 typedef struct __pnfs_layout
{
165 struct list_entry entry
;
168 enum pnfs_iomode iomode
;
169 enum pnfs_layout_type type
;
172 typedef struct __pnfs_file_layout_handles
{
175 } pnfs_file_layout_handles
;
177 typedef struct __pnfs_file_layout
{
179 pnfs_file_layout_handles filehandles
;
180 unsigned char deviceid
[PNFS_DEVICEID_SIZE
];
181 pnfs_file_device
*device
;
182 uint64_t pattern_offset
;
183 uint32_t first_index
;
189 struct pnfs_layout_list
;
190 struct cb_layoutrecall_args
;
192 enum pnfs_status
pnfs_layout_list_create(
193 OUT
struct pnfs_layout_list
**layouts_out
);
195 void pnfs_layout_list_free(
196 IN
struct pnfs_layout_list
*layouts
);
198 enum pnfs_status
pnfs_layout_state_open(
199 IN
struct __nfs41_open_state
*state
,
200 OUT pnfs_layout_state
**layout_out
);
202 /* expects caller to hold an exclusive lock on pnfs_layout_state */
203 enum pnfs_status
pnfs_layout_state_prepare(
204 IN pnfs_layout_state
*state
,
205 IN
struct __nfs41_session
*session
,
206 IN nfs41_path_fh
*meta_file
,
207 IN
struct __stateid_arg
*stateid
,
208 IN
enum pnfs_iomode iomode
,
212 void pnfs_layout_state_close(
213 IN
struct __nfs41_session
*session
,
214 IN
struct __nfs41_open_state
*state
,
217 enum pnfs_status
pnfs_file_layout_recall(
218 IN
struct __nfs41_client
*client
,
219 IN
const struct cb_layoutrecall_args
*recall
);
221 /* expects caller to hold a shared lock on pnfs_layout_state */
222 enum pnfs_status
pnfs_layout_recall_status(
223 IN
const pnfs_layout_state
*state
,
224 IN
const pnfs_layout
*layout
);
226 void pnfs_layout_recall_fenced(
227 IN pnfs_layout_state
*state
,
228 IN
const pnfs_layout
*layout
);
230 /* expects caller to hold an exclusive lock on pnfs_layout_state */
231 void pnfs_layout_io_start(
232 IN pnfs_layout_state
*state
);
234 void pnfs_layout_io_finished(
235 IN pnfs_layout_state
*state
);
239 struct pnfs_file_device_list
;
241 enum pnfs_status
pnfs_file_device_list_create(
242 OUT
struct pnfs_file_device_list
**devices_out
);
244 void pnfs_file_device_list_free(
245 IN
struct pnfs_file_device_list
*devices
);
247 void pnfs_file_device_list_invalidate(
248 IN
struct pnfs_file_device_list
*devices
);
250 enum pnfs_status
pnfs_file_device_get(
251 IN
struct __nfs41_session
*session
,
252 IN
struct pnfs_file_device_list
*devices
,
253 IN
unsigned char *deviceid
,
254 OUT pnfs_file_device
**device_out
);
256 void pnfs_file_device_put(
257 IN pnfs_file_device
*device
);
259 struct notify_deviceid4
; /* from nfs41_callback.h */
260 enum notify_deviceid_type4
;
261 enum pnfs_status
pnfs_file_device_notify(
262 IN
struct pnfs_file_device_list
*devices
,
263 IN
const struct notify_deviceid4
*change
);
265 enum pnfs_status
pnfs_data_server_client(
266 IN
struct __nfs41_root
*root
,
267 IN pnfs_data_server
*server
,
268 IN
uint32_t default_lease
,
269 OUT
struct __nfs41_client
**client_out
);
273 enum pnfs_status
pnfs_read(
274 IN
struct __nfs41_root
*root
,
275 IN
struct __nfs41_open_state
*state
,
276 IN
struct __stateid_arg
*stateid
,
277 IN pnfs_layout_state
*layout
,
280 OUT
unsigned char *buffer_out
,
283 enum pnfs_status
pnfs_write(
284 IN
struct __nfs41_root
*root
,
285 IN
struct __nfs41_open_state
*state
,
286 IN
struct __stateid_arg
*stateid
,
287 IN pnfs_layout_state
*layout
,
290 IN
unsigned char *buffer
,
292 OUT nfs41_file_info
*cinfo
);
295 /* helper functions */
297 __inline
int is_dense(
299 FORCEINLINE
int is_dense(
301 IN
const pnfs_file_layout
*layout
)
303 return (layout
->util
& NFL4_UFLG_DENSE
) != 0;
306 __inline
int should_commit_to_mds(
308 FORCEINLINE
int should_commit_to_mds(
310 IN
const pnfs_file_layout
*layout
)
312 return (layout
->util
& NFL4_UFLG_COMMIT_THRU_MDS
) != 0;
315 __inline
uint32_t layout_unit_size(
317 FORCEINLINE
uint32_t layout_unit_size(
319 IN
const pnfs_file_layout
*layout
)
321 return layout
->util
& NFL4_UFLG_STRIPE_UNIT_SIZE_MASK
;
324 __inline
uint64_t stripe_unit_number(
326 FORCEINLINE
uint64_t stripe_unit_number(
328 IN
const pnfs_file_layout
*layout
,
330 IN
uint32_t unit_size
)
332 const uint64_t relative_offset
= offset
- layout
->pattern_offset
;
333 return relative_offset
/ unit_size
;
336 __inline
uint64_t stripe_unit_offset(
338 FORCEINLINE
uint64_t stripe_unit_offset(
340 IN
const pnfs_file_layout
*layout
,
342 IN
uint32_t unit_size
)
344 return layout
->pattern_offset
+ unit_size
* sui
;
347 __inline
uint32_t stripe_index(
349 FORCEINLINE
uint32_t stripe_index(
351 IN
const pnfs_file_layout
*layout
,
353 IN
uint32_t stripe_count
)
355 return (uint32_t)((sui
+ layout
->first_index
) % stripe_count
);
358 __inline
uint32_t data_server_index(
360 FORCEINLINE
uint32_t data_server_index(
362 IN
const pnfs_file_device
*device
,
363 IN
uint32_t stripeid
)
365 return device
->stripes
.arr
[stripeid
];
368 #endif /* !__PNFS_H__ */