recovery: operations take stateid_arg instead of stateid4

operations that require a stateid now take stateid_arg for recovery information.  these operations include close, setattr, lock/unlock, layoutget, and read/write (including pnfs)

nfs41_open_stateid_arg() locks nfs41_open_state and copies its stateid into a stateid_arg
nfs41_lock_stateid_arg() locks nfs41_open_state.last_lock and copies its stateid into a stateid_arg; if there is no lock state, it falls back to nfs41_open_stateid_arg()

pnfs_read/write() now take nfs41_open_state so they can generate stateid_args

Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
This commit is contained in:
Casey Bodley 2010-11-15 14:59:49 -05:00 committed by unknown
parent d59d17c3b4
commit 3ecd38e414
12 changed files with 205 additions and 227 deletions

View file

@ -31,7 +31,7 @@
#include "util.h"
stateid4 special_read_stateid = {0xffffffff,
const stateid4 special_read_stateid = {0xffffffff,
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
static int parse_rw(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
@ -62,18 +62,20 @@ out:
/* NFS41_READ */
static int read_from_mds(
IN nfs41_session *session,
IN stateid4 *stateid,
IN nfs41_path_fh *file,
IN nfs41_open_state *state,
IN uint64_t offset,
IN uint32_t length,
OUT unsigned char *buffer,
OUT ULONG *len_out)
{
stateid_arg stateid;
int status = 0;
bool_t eof;
unsigned char *p = buffer;
ULONG to_rcv = length, reloffset = 0, len = 0;
const uint32_t maxreadsize = max_read_size(session, &file->fh);
const uint32_t maxreadsize = max_read_size(session, &state->file.fh);
nfs41_lock_stateid_arg(state, &stateid);
if (to_rcv > maxreadsize)
dprintf(1, "handle_nfs41_read: reading %d in chunks of %d\n",
@ -82,10 +84,11 @@ static int read_from_mds(
while(to_rcv > 0) {
uint32_t bytes_read = 0, chunk = min(to_rcv, maxreadsize);
status = nfs41_read(session, file, stateid,
status = nfs41_read(session, &state->file, &stateid,
offset + reloffset, chunk, p, &bytes_read, &eof);
if (status == NFS4ERR_OPENMODE && !len) {
stateid = &special_read_stateid;
stateid.type = STATEID_SPECIAL;
memcpy(&stateid.stateid, &special_read_stateid, sizeof(stateid4));
continue;
} else if (status && !len) {
status = nfs_to_windows_error(status, ERROR_NET_WRITE_FAULT);
@ -114,7 +117,6 @@ out:
static int read_from_pnfs(
IN nfs41_root *root,
IN nfs41_open_state *state,
IN stateid4 *stateid,
IN uint64_t offset,
IN uint32_t length,
OUT unsigned char *buffer,
@ -131,7 +133,7 @@ static int read_from_pnfs(
goto out;
}
pnfsstat = pnfs_read(root, state->session, &state->file, stateid,
pnfsstat = pnfs_read(root, state->session, state,
layout, offset, length, buffer, len_out);
switch (pnfsstat) {
case PNFS_SUCCESS:
@ -149,18 +151,12 @@ out:
static int handle_read(nfs41_upcall *upcall)
{
stateid4 stateid, *pstateid;
readwrite_upcall_args *args = &upcall->args.rw;
nfs41_open_state *state = args->state;
ULONG pnfs_bytes_read = 0;
int status = NO_ERROR;
pstateid = nfs41_lock_stateid_copy(&state->last_lock, &stateid);
if (pstateid == NULL)
pstateid = &state->stateid;
#ifdef PNFS_ENABLE_READ
status = read_from_pnfs(args->root, state, pstateid,
status = read_from_pnfs(args->root, args->state,
args->offset, args->len, args->buffer, &args->out_len);
if (status == NO_ERROR || status == ERROR_HANDLE_EOF)
@ -176,7 +172,7 @@ static int handle_read(nfs41_upcall *upcall)
}
#endif
status = read_from_mds(state->session, pstateid, &state->file,
status = read_from_mds(args->state->session, args->state,
args->offset, args->len, args->buffer, &args->out_len);
args->out_len += pnfs_bytes_read;
@ -188,20 +184,22 @@ out:
/* NFS41_WRITE */
static int write_to_mds(
IN nfs41_session *session,
IN stateid4 *stateid,
IN nfs41_path_fh *file,
IN nfs41_open_state *state,
IN uint64_t offset,
IN uint32_t length,
IN unsigned char *buffer,
OUT ULONG *len_out)
{
stateid_arg stateid;
nfs41_write_verf verf;
enum stable_how4 stable, committed;
unsigned char *p;
const uint32_t maxwritesize = max_write_size(session, &file->fh);
const uint32_t maxwritesize = max_write_size(session, &state->file.fh);
uint32_t to_send, reloffset, len;
int status = 0;
nfs41_lock_stateid_arg(state, &stateid);
retry_write:
p = buffer;
to_send = length;
@ -217,7 +215,7 @@ retry_write:
while(to_send > 0) {
uint32_t bytes_written = 0, chunk = min(to_send, maxwritesize);
status = nfs41_write(session, file, stateid, p, chunk,
status = nfs41_write(session, &state->file, &stateid, p, chunk,
offset + reloffset, stable, &bytes_written, &verf);
if (status && !len)
goto out;
@ -234,7 +232,7 @@ retry_write:
}
if (committed == UNSTABLE4) {
dprintf(1, "sending COMMIT for offset=%d and len=%d\n", offset, len);
status = nfs41_commit(session, file, offset, len, 1);
status = nfs41_commit(session, &state->file, offset, len, 1);
}
out:
*len_out = len;
@ -244,7 +242,6 @@ out:
static int write_to_pnfs(
IN nfs41_root *root,
IN nfs41_open_state *state,
IN stateid4 *stateid,
IN uint64_t offset,
IN uint32_t length,
IN unsigned char *buffer,
@ -261,7 +258,7 @@ static int write_to_pnfs(
goto out;
}
pnfsstat = pnfs_write(root, state->session, &state->file, stateid,
pnfsstat = pnfs_write(root, state->session, state,
layout, offset, length, buffer, len_out);
if (pnfsstat) {
status = ERROR_WRITE_FAULT;
@ -273,18 +270,12 @@ out:
static int handle_write(nfs41_upcall *upcall)
{
stateid4 stateid, *pstateid = NULL;
readwrite_upcall_args *args = &upcall->args.rw;
nfs41_open_state *state = args->state;
ULONG pnfs_bytes_written = 0;
int status;
pstateid = nfs41_lock_stateid_copy(&state->last_lock, &stateid);
if (pstateid == NULL)
pstateid = &state->stateid;
#ifdef PNFS_ENABLE_WRITE
status = write_to_pnfs(args->root, args->state, pstateid,
status = write_to_pnfs(args->root, args->state,
args->offset, args->len, args->buffer, &args->out_len);
if (status == NO_ERROR)
@ -300,7 +291,7 @@ static int handle_write(nfs41_upcall *upcall)
}
#endif
status = write_to_mds(state->session, pstateid, &state->file,
status = write_to_mds(args->state->session, args->state,
args->offset, args->len, args->buffer, &args->out_len);
args->out_len += pnfs_bytes_written;