ReactOS 0.4.15-dev-5893-g1bb4167
readwrite.c File Reference
#include <windows.h>
#include <stdio.h>
#include "nfs41_ops.h"
#include "name_cache.h"
#include "upcall.h"
#include "daemon_debug.h"
#include "util.h"
Include dependency graph for readwrite.c:

Go to the source code of this file.

Macros

#define MAX_WRITE_RETRIES   6
 

Functions

static int parse_rw (unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
 
static int read_from_mds (IN nfs41_upcall *upcall, IN stateid_arg *stateid)
 
static int read_from_pnfs (IN nfs41_upcall *upcall, IN stateid_arg *stateid)
 
static int handle_read (nfs41_upcall *upcall)
 
static int write_to_mds (IN nfs41_upcall *upcall, IN stateid_arg *stateid)
 
static int write_to_pnfs (IN nfs41_upcall *upcall, IN stateid_arg *stateid)
 
static int handle_write (nfs41_upcall *upcall)
 
static int marshall_rw (unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
 

Variables

const stateid4 special_read_stateid
 
const nfs41_upcall_op nfs41_op_read
 
const nfs41_upcall_op nfs41_op_write
 

Macro Definition Documentation

◆ MAX_WRITE_RETRIES

#define MAX_WRITE_RETRIES   6

Definition at line 33 of file readwrite.c.

Function Documentation

◆ handle_read()

static int handle_read ( nfs41_upcall upcall)
static

Definition at line 138 of file readwrite.c.

139{
140 readwrite_upcall_args *args = &upcall->args.rw;
141 stateid_arg stateid;
142 ULONG pnfs_bytes_read = 0;
143 int status = NO_ERROR;
144
145 nfs41_open_stateid_arg(upcall->state_ref, &stateid);
146
147#ifdef PNFS_ENABLE_READ
148 status = read_from_pnfs(upcall, &stateid);
149
151 goto out;
152
153 if (args->out_len) {
154 pnfs_bytes_read = args->out_len;
155 args->out_len = 0;
156
157 args->offset += pnfs_bytes_read;
158 args->buffer += pnfs_bytes_read;
159 args->len -= pnfs_bytes_read;
160 }
161#endif
162
163 status = read_from_mds(upcall, &stateid);
164
165 args->out_len += pnfs_bytes_read;
166out:
167 return status;
168}
static int read_from_pnfs(IN nfs41_upcall *upcall, IN stateid_arg *stateid)
Definition: readwrite.c:108
static int read_from_mds(IN nfs41_upcall *upcall, IN stateid_arg *stateid)
Definition: readwrite.c:58
#define NO_ERROR
Definition: dderror.h:5
void nfs41_open_stateid_arg(IN nfs41_open_state *state, OUT struct __stateid_arg *arg)
nfs41_updowncall_list upcall
Definition: nfs41_driver.c:273
static FILE * out
Definition: regtests2xml.c:44
Definition: match.c:390
Definition: ps.c:97
uint32_t ULONG
Definition: typedefs.h:59
#define ERROR_HANDLE_EOF
Definition: winerror.h:140

◆ handle_write()

static int handle_write ( nfs41_upcall upcall)
static

Definition at line 274 of file readwrite.c.

275{
276 readwrite_upcall_args *args = &upcall->args.rw;
277 stateid_arg stateid;
278 uint32_t pnfs_bytes_written = 0;
279 int status;
280
281 nfs41_open_stateid_arg(upcall->state_ref, &stateid);
282
283#ifdef PNFS_ENABLE_WRITE
284 status = write_to_pnfs(upcall, &stateid);
285 if (args->out_len) {
286 pnfs_bytes_written = args->out_len;
287 args->out_len = 0;
288
289 args->offset += pnfs_bytes_written;
290 args->buffer += pnfs_bytes_written;
291 args->len -= pnfs_bytes_written;
292
293 if (args->len == 0)
294 goto out;
295 }
296#endif
297
298 status = write_to_mds(upcall, &stateid);
299out:
300 args->out_len += pnfs_bytes_written;
301 return status;
302}
static int write_to_mds(IN nfs41_upcall *upcall, IN stateid_arg *stateid)
Definition: readwrite.c:172
static int write_to_pnfs(IN nfs41_upcall *upcall, IN stateid_arg *stateid)
Definition: readwrite.c:250
UINT32 uint32_t
Definition: types.h:75

◆ marshall_rw()

static int marshall_rw ( unsigned char buffer,
uint32_t length,
nfs41_upcall upcall 
)
static

Definition at line 304 of file readwrite.c.

305{
306 readwrite_upcall_args *args = &upcall->args.rw;
307 int status;
308 status = safe_write(&buffer, length, &args->out_len, sizeof(args->out_len));
309 if (status) goto out;
310 status = safe_write(&buffer, length, &args->ctime, sizeof(args->ctime));
311out:
312 return status;
313}
int safe_write(unsigned char **pos, uint32_t *remaining, void *src, uint32_t src_len)
Definition: util.c:44
GLuint buffer
Definition: glext.h:5915
GLuint GLsizei GLsizei * length
Definition: glext.h:6040

◆ parse_rw()

static int parse_rw ( unsigned char buffer,
uint32_t  length,
nfs41_upcall upcall 
)
static

Definition at line 39 of file readwrite.c.

40{
41 int status;
43
44 status = safe_read(&buffer, &length, &args->len, sizeof(args->len));
45 if (status) goto out;
46 status = safe_read(&buffer, &length, &args->offset, sizeof(args->offset));
47 if (status) goto out;
48 status = safe_read(&buffer, &length, &args->buffer, sizeof(args->buffer));
49 if (status) goto out;
50
51 dprintf(1, "parsing %s len=%lu offset=%llu buf=%p\n",
52 opcode2string(upcall->opcode), args->len, args->offset, args->buffer);
53out:
54 return status;
55}
int safe_read(unsigned char **pos, uint32_t *remaining, void *dest, uint32_t dest_len)
Definition: util.c:33
const char * opcode2string(DWORD opcode)
Definition: daemon_debug.c:280
#define dprintf
Definition: regdump.c:33

◆ read_from_mds()

static int read_from_mds ( IN nfs41_upcall upcall,
IN stateid_arg stateid 
)
static

Definition at line 58 of file readwrite.c.

61{
62 nfs41_session *session = upcall->state_ref->session;
63 nfs41_path_fh *file = &upcall->state_ref->file;
65 int status = 0;
66 bool_t eof;
67 unsigned char *p = args->buffer;
68 ULONG to_rcv = args->len, reloffset = 0, len = 0;
69 const uint32_t maxreadsize = max_read_size(session, &file->fh);
70
71 if (to_rcv > maxreadsize)
72 dprintf(1, "handle_nfs41_read: reading %d in chunks of %d\n",
73 to_rcv, maxreadsize);
74
75 while(to_rcv > 0) {
76 uint32_t bytes_read = 0, chunk = min(to_rcv, maxreadsize);
77
78 status = nfs41_read(session, file, stateid, args->offset + reloffset, chunk,
79 p, &bytes_read, &eof);
80 if (status == NFS4ERR_OPENMODE && !len) {
81 stateid->type = STATEID_SPECIAL;
82 memcpy(&stateid->stateid, &special_read_stateid, sizeof(stateid4));
83 continue;
84 } else if (status && !len) {
86 goto out;
87 }
88
89 p += bytes_read;
90 to_rcv -= bytes_read;
91 len += bytes_read;
92 args->offset += bytes_read;
93 if (status) {
95 break;
96 }
97 if (eof) {
98 if (!len)
100 break;
101 }
102 }
103out:
104 args->out_len = len;
105 return status;
106}
const stateid4 special_read_stateid
Definition: readwrite.c:36
int nfs_to_windows_error(int status, int default_error)
Definition: util.c:235
uint32_t max_read_size(IN const nfs41_session *session, IN const nfs41_fh *fh)
Definition: util.c:84
int32_t bool_t
Definition: types.h:101
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define min(a, b)
Definition: monoChain.cc:55
@ NFS4ERR_OPENMODE
Definition: nfs41_const.h:145
int nfs41_read(IN nfs41_session *session, IN nfs41_path_fh *file, IN stateid_arg *stateid, IN uint64_t offset, IN uint32_t count, OUT unsigned char *data_out, OUT uint32_t *data_len_out, OUT bool_t *eof_out)
Definition: nfs41_ops.c:774
@ STATEID_SPECIAL
Definition: nfs41_ops.h:281
_Check_return_ _CRTIMP int __cdecl __cdecl eof(_In_ int _FileHandle)
Definition: fci.c:127
#define ERROR_NET_WRITE_FAULT
Definition: winerror.h:172

Referenced by handle_read().

◆ read_from_pnfs()

static int read_from_pnfs ( IN nfs41_upcall upcall,
IN stateid_arg stateid 
)
static

Definition at line 108 of file readwrite.c.

111{
112 readwrite_upcall_args *args = &upcall->args.rw;
114 enum pnfs_status pnfsstat;
115 int status = NO_ERROR;
116
117 if (pnfs_layout_state_open(upcall->state_ref, &layout)) {
119 goto out;
120 }
121
122 pnfsstat = pnfs_read(upcall->root_ref, upcall->state_ref, stateid, layout,
123 args->offset, args->len, args->buffer, &args->out_len);
124 switch (pnfsstat) {
125 case PNFS_SUCCESS:
126 break;
127 case PNFS_READ_EOF:
129 break;
130 default:
132 break;
133 }
134out:
135 return status;
136}
#define ERROR_NOT_SUPPORTED
Definition: compat.h:100
static DWORD layout
Definition: bitmap.c:46
pnfs_status
Definition: pnfs.h:58
@ PNFS_READ_EOF
Definition: pnfs.h:61
@ PNFS_SUCCESS
Definition: pnfs.h:59
enum pnfs_status pnfs_layout_state_open(IN struct __nfs41_open_state *state, OUT pnfs_layout_state **layout_out)
enum pnfs_status pnfs_read(IN struct __nfs41_root *root, IN struct __nfs41_open_state *state, IN struct __stateid_arg *stateid, IN pnfs_layout_state *layout, IN uint64_t offset, IN uint64_t length, OUT unsigned char *buffer_out, OUT ULONG *len_out)
#define ERROR_READ_FAULT
Definition: winerror.h:133

Referenced by handle_read().

◆ write_to_mds()

static int write_to_mds ( IN nfs41_upcall upcall,
IN stateid_arg stateid 
)
static

Definition at line 172 of file readwrite.c.

175{
176 nfs41_session *session = upcall->state_ref->session;
177 nfs41_path_fh *file = &upcall->state_ref->file;
178 readwrite_upcall_args *args = &upcall->args.rw;
179 nfs41_write_verf verf;
180 enum stable_how4 stable, committed;
181 unsigned char *p;
182 const uint32_t maxwritesize = max_write_size(session, &file->fh);
183 uint32_t to_send, reloffset, len;
184 int status = 0;
185 /* on write verifier mismatch, retry N times before failing */
186 uint32_t retries = MAX_WRITE_RETRIES;
187 nfs41_file_info info = { 0 };
188
189retry_write:
190 p = args->buffer;
191 to_send = args->len;
192 reloffset = 0;
193 len = 0;
194 stable = to_send <= maxwritesize ? FILE_SYNC4 : UNSTABLE4;
195 committed = FILE_SYNC4;
196
197 if (to_send > maxwritesize)
198 dprintf(1, "handle_nfs41_write: writing %d in chunks of %d\n",
199 to_send, maxwritesize);
200
201 while(to_send > 0) {
202 uint32_t bytes_written = 0, chunk = min(to_send, maxwritesize);
203
204 status = nfs41_write(session, file, stateid, p, chunk,
205 args->offset + reloffset, stable, &bytes_written, &verf, &info);
206 if (status && !len)
207 goto out;
208 p += bytes_written;
209 to_send -= bytes_written;
210 len += bytes_written;
211 reloffset += bytes_written;
212 if (status) {
213 status = 0;
214 break;
215 }
216 if (!verify_write(&verf, &committed)) {
217 if (retries--) goto retry_write;
218 goto out_verify_failed;
219 }
220 }
221 if (committed != FILE_SYNC4) {
222 dprintf(1, "sending COMMIT for offset=%d and len=%d\n", args->offset, len);
223 status = nfs41_commit(session, file, args->offset, len, 1, &verf, &info);
224 if (status)
225 goto out;
226
227 if (!verify_commit(&verf)) {
228 if (retries--) goto retry_write;
229 goto out_verify_failed;
230 }
231 } else if (stable == UNSTABLE4) {
233 bitmap4 attr_request;
234 nfs41_superblock_getattr_mask(file->fh.superblock, &attr_request);
235 status = nfs41_getattr(session, file, &attr_request, &info);
236 if (status)
237 goto out;
238 }
239 args->ctime = info.change;
240out:
241 args->out_len = len;
243
244out_verify_failed:
245 len = 0;
247 goto out;
248}
#define MAX_WRITE_RETRIES
Definition: readwrite.c:33
bool_t verify_write(IN nfs41_write_verf *verf, IN OUT enum stable_how4 *stable)
Definition: util.c:100
bool_t verify_commit(IN nfs41_write_verf *verf)
Definition: util.c:126
uint32_t max_write_size(IN const nfs41_session *session, IN const nfs41_fh *fh)
Definition: util.c:92
static __inline void nfs41_superblock_getattr_mask(IN const nfs41_superblock *superblock, OUT bitmap4 *attrs)
Definition: nfs41.h:448
@ NFS4ERR_IO
Definition: nfs41_const.h:90
int nfs41_getattr(IN nfs41_session *session, IN OPTIONAL nfs41_path_fh *file, IN bitmap4 *attr_request, OUT nfs41_file_info *info)
Definition: nfs41_ops.c:1063
int nfs41_write(IN nfs41_session *session, IN nfs41_path_fh *file, IN stateid_arg *stateid, IN unsigned char *data, IN uint32_t data_len, IN uint64_t offset, IN enum stable_how4 stable, OUT uint32_t *bytes_written, OUT nfs41_write_verf *verf, OUT nfs41_file_info *cinfo)
Definition: nfs41_ops.c:685
int nfs41_commit(IN nfs41_session *session, IN nfs41_path_fh *file, IN uint64_t offset, IN uint32_t count, IN bool_t do_getattr, OUT nfs41_write_verf *verf, OUT nfs41_file_info *cinfo)
Definition: nfs41_ops.c:833
stable_how4
Definition: nfs41_ops.h:835
@ FILE_SYNC4
Definition: nfs41_ops.h:838
@ UNSTABLE4
Definition: nfs41_ops.h:836

Referenced by handle_write().

◆ write_to_pnfs()

static int write_to_pnfs ( IN nfs41_upcall upcall,
IN stateid_arg stateid 
)
static

Definition at line 250 of file readwrite.c.

253{
254 readwrite_upcall_args *args = &upcall->args.rw;
256 int status = NO_ERROR;
257 nfs41_file_info info = { 0 };
258
259 if (pnfs_layout_state_open(upcall->state_ref, &layout)) {
261 goto out;
262 }
263
264 if (pnfs_write(upcall->root_ref, upcall->state_ref, stateid, layout,
265 args->offset, args->len, args->buffer, &args->out_len, &info)) {
267 goto out;
268 }
269 args->ctime = info.change;
270out:
271 return status;
272}
enum pnfs_status pnfs_write(IN struct __nfs41_root *root, IN struct __nfs41_open_state *state, IN struct __stateid_arg *stateid, IN pnfs_layout_state *layout, IN uint64_t offset, IN uint64_t length, IN unsigned char *buffer, OUT ULONG *len_out, OUT nfs41_file_info *cinfo)
#define ERROR_WRITE_FAULT
Definition: winerror.h:132

Referenced by handle_write().

Variable Documentation

◆ nfs41_op_read

const nfs41_upcall_op nfs41_op_read
Initial value:
= {
}
static int marshall_rw(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
Definition: readwrite.c:304
static int handle_read(nfs41_upcall *upcall)
Definition: readwrite.c:138
static int parse_rw(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
Definition: readwrite.c:39

Definition at line 316 of file readwrite.c.

◆ nfs41_op_write

const nfs41_upcall_op nfs41_op_write
Initial value:
= {
}
static int handle_write(nfs41_upcall *upcall)
Definition: readwrite.c:274

Definition at line 321 of file readwrite.c.

◆ special_read_stateid

const stateid4 special_read_stateid
Initial value:
= {0xffffffff,
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}

Definition at line 36 of file readwrite.c.

Referenced by read_from_mds().