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

@ -33,23 +33,22 @@
#define LKLVL 2 /* dprintf level for lock logging */ #define LKLVL 2 /* dprintf level for lock logging */
stateid4* nfs41_lock_stateid_copy( void nfs41_lock_stateid_arg(
IN nfs41_lock_state *lock_state, IN nfs41_open_state *state,
IN OUT stateid4 *dest) OUT stateid_arg *arg)
{ {
stateid4 *result; AcquireSRWLockShared(&state->last_lock.lock);
AcquireSRWLockShared(&lock_state->lock); if (state->last_lock.initialized) {
if (lock_state->initialized) { /* use lock stateid where available */
memcpy(dest, &lock_state->stateid, sizeof(stateid4)); memcpy(&arg->stateid, &state->last_lock.stateid, sizeof(stateid4));
result = dest; arg->type = STATEID_LOCK;
dprintf(LKLVL, "nfs41_lock_stateid_copy: copying existing stateid " ReleaseSRWLockShared(&state->last_lock.lock);
"with seqid=%u\n", result->seqid);
} else { } else {
result = NULL; ReleaseSRWLockShared(&state->last_lock.lock);
dprintf(LKLVL, "nfs41_lock_stateid_copy: no existing lock state\n");
/* fall back on open stateid */
nfs41_open_stateid_arg(state, arg);
} }
ReleaseSRWLockShared(&lock_state->lock);
return result;
} }
static void update_last_lock_state( static void update_last_lock_state(
@ -124,15 +123,15 @@ static __inline uint32_t get_lock_type(BOOLEAN exclusive, BOOLEAN blocking)
static int handle_lock(nfs41_upcall *upcall) static int handle_lock(nfs41_upcall *upcall)
{ {
int status; stateid_arg stateid;
lock_upcall_args *args = &upcall->args.lock; lock_upcall_args *args = &upcall->args.lock;
nfs41_open_state *state = args->state; nfs41_open_state *state = args->state;
const uint32_t type = get_lock_type(args->exclusive, args->blocking); const uint32_t type = get_lock_type(args->exclusive, args->blocking);
stateid4 stateid, *prev_stateid; int status;
prev_stateid = nfs41_lock_stateid_copy(&state->last_lock, &stateid); nfs41_lock_stateid_arg(state, &stateid);
status = nfs41_lock(state->session, state, prev_stateid, status = nfs41_lock(state->session, &state->file, &state->owner,
type, args->offset, args->length, &stateid); type, args->offset, args->length, &stateid);
if (status) { if (status) {
dprintf(LKLVL, "nfs41_lock failed with %s\n", dprintf(LKLVL, "nfs41_lock failed with %s\n",
@ -141,27 +140,27 @@ static int handle_lock(nfs41_upcall *upcall)
goto out; goto out;
} }
update_last_lock_state(&state->last_lock, &stateid); update_last_lock_state(&state->last_lock, &stateid.stateid);
out: out:
return status; return status;
} }
static void cancel_lock(IN nfs41_upcall *upcall) static void cancel_lock(IN nfs41_upcall *upcall)
{ {
int status = NO_ERROR; stateid_arg stateid;
lock_upcall_args *args = &upcall->args.lock; lock_upcall_args *args = &upcall->args.lock;
nfs41_open_state *state = args->state; nfs41_open_state *state = args->state;
stateid4 stateid, *prev_stateid; int status = NO_ERROR;
dprintf(1, "--> cancel_lock()\n"); dprintf(1, "--> cancel_lock()\n");
if (upcall->status) if (upcall->status)
goto out; goto out;
prev_stateid = nfs41_lock_stateid_copy(&state->last_lock, &stateid); nfs41_lock_stateid_arg(state, &stateid);
status = nfs41_unlock(state->session, state, status = nfs41_unlock(state->session, &state->file,
prev_stateid, args->offset, args->length); args->offset, args->length, &stateid);
if (status) { if (status) {
dprintf(LKLVL, "cancel_lock: nfs41_unlock() failed with %s\n", dprintf(LKLVL, "cancel_lock: nfs41_unlock() failed with %s\n",
nfs_error_string(status)); nfs_error_string(status));
@ -169,7 +168,7 @@ static void cancel_lock(IN nfs41_upcall *upcall)
goto out; goto out;
} }
update_last_lock_state(&state->last_lock, &stateid); update_last_lock_state(&state->last_lock, &stateid.stateid);
out: out:
dprintf(1, "<-- cancel_lock() returning %d\n", status); dprintf(1, "<-- cancel_lock() returning %d\n", status);
} }
@ -201,17 +200,18 @@ out:
static int handle_unlock(nfs41_upcall *upcall) static int handle_unlock(nfs41_upcall *upcall)
{ {
int status; stateid_arg stateid;
unlock_upcall_args *args = &upcall->args.unlock; unlock_upcall_args *args = &upcall->args.unlock;
nfs41_open_state *state = args->state; nfs41_open_state *state = args->state;
stateid4 stateid;
uint32_t i, nsuccess = 0; uint32_t i, nsuccess = 0;
unsigned char *buf = args->buf; unsigned char *buf = args->buf;
uint32_t buf_len = args->buf_len; uint32_t buf_len = args->buf_len;
uint64_t offset; uint64_t offset;
uint64_t length; uint64_t length;
int status;
if (nfs41_lock_stateid_copy(&state->last_lock, &stateid) == NULL) { nfs41_lock_stateid_arg(state, &stateid);
if (stateid.type != STATEID_LOCK) {
eprintf("attempt to unlock a file with no lock state\n"); eprintf("attempt to unlock a file with no lock state\n");
status = ERROR_NOT_LOCKED; status = ERROR_NOT_LOCKED;
goto out; goto out;
@ -222,7 +222,8 @@ static int handle_unlock(nfs41_upcall *upcall)
if (safe_read(&buf, &buf_len, &offset, sizeof(LONGLONG))) break; if (safe_read(&buf, &buf_len, &offset, sizeof(LONGLONG))) break;
if (safe_read(&buf, &buf_len, &length, sizeof(LONGLONG))) break; if (safe_read(&buf, &buf_len, &length, sizeof(LONGLONG))) break;
status = nfs41_unlock(state->session, state, &stateid, offset, length); status = nfs41_unlock(state->session,
&state->file, offset, length, &stateid);
if (status == NFS4_OK) { if (status == NFS4_OK) {
nsuccess++; nsuccess++;
} else { } else {
@ -233,7 +234,7 @@ static int handle_unlock(nfs41_upcall *upcall)
} }
if (nsuccess) { if (nsuccess) {
update_last_lock_state(&state->last_lock, &stateid); update_last_lock_state(&state->last_lock, &stateid.stateid);
status = NO_ERROR; status = NO_ERROR;
} }
out: out:

View file

@ -400,4 +400,14 @@ void nfs41_open_state_ref(
void nfs41_open_state_deref( void nfs41_open_state_deref(
IN nfs41_open_state *state); IN nfs41_open_state *state);
struct __stateid_arg;
void nfs41_open_stateid_arg(
IN nfs41_open_state *state,
OUT struct __stateid_arg *arg);
/* lock.c */
void nfs41_lock_stateid_arg(
IN nfs41_open_state *state,
OUT struct __stateid_arg *arg);
#endif /* __NFS41__ */ #endif /* __NFS41__ */

View file

@ -590,7 +590,8 @@ out:
int nfs41_close( int nfs41_close(
IN nfs41_session *session, IN nfs41_session *session,
IN nfs41_open_state *state) IN nfs41_path_fh *file,
IN stateid_arg *stateid)
{ {
int status; int status;
nfs41_compound compound; nfs41_compound compound;
@ -617,11 +618,11 @@ int nfs41_close(
goto out; goto out;
compound_add_op(&compound, OP_PUTFH, &putfh_args, &putfh_res); compound_add_op(&compound, OP_PUTFH, &putfh_args, &putfh_res);
putfh_args.file = &state->file; putfh_args.file = file;
putfh_args.in_recovery = 0; putfh_args.in_recovery = 0;
compound_add_op(&compound, OP_CLOSE, &close_args, &close_res); compound_add_op(&compound, OP_CLOSE, &close_args, &close_res);
close_args.open_stateid = &state->stateid; close_args.stateid = stateid;
compound_add_op(&compound, OP_GETATTR, &getattr_args, &getattr_res); compound_add_op(&compound, OP_GETATTR, &getattr_args, &getattr_res);
getattr_args.attr_request = &attr_request; getattr_args.attr_request = &attr_request;
@ -639,7 +640,7 @@ int nfs41_close(
memcpy(&info.attrmask, &getattr_res.obj_attributes.attrmask, memcpy(&info.attrmask, &getattr_res.obj_attributes.attrmask,
sizeof(bitmap4)); sizeof(bitmap4));
nfs41_attr_cache_update(session_name_cache(session), nfs41_attr_cache_update(session_name_cache(session),
state->file.fh.fileid, &info); file->fh.fileid, &info);
out: out:
return status; return status;
@ -648,7 +649,7 @@ out:
int nfs41_write( int nfs41_write(
IN nfs41_session *session, IN nfs41_session *session,
IN nfs41_path_fh *file, IN nfs41_path_fh *file,
IN stateid4 *stateid, IN stateid_arg *stateid,
IN unsigned char *data, IN unsigned char *data,
IN uint32_t data_len, IN uint32_t data_len,
IN uint64_t offset, IN uint64_t offset,
@ -732,7 +733,7 @@ out:
int nfs41_read( int nfs41_read(
IN nfs41_session *session, IN nfs41_session *session,
IN nfs41_path_fh *file, IN nfs41_path_fh *file,
IN stateid4 *stateid, IN stateid_arg *stateid,
IN uint64_t offset, IN uint64_t offset,
IN uint32_t count, IN uint32_t count,
OUT unsigned char *data_out, OUT unsigned char *data_out,
@ -857,12 +858,12 @@ out:
int nfs41_lock( int nfs41_lock(
IN nfs41_session *session, IN nfs41_session *session,
IN nfs41_open_state *open_state, IN nfs41_path_fh *file,
IN stateid4 *lock_state OPTIONAL, IN state_owner4 *owner,
IN uint32_t type, IN uint32_t type,
IN uint64_t offset, IN uint64_t offset,
IN uint64_t length, IN uint64_t length,
OUT stateid4 *stateid_out) IN OUT stateid_arg *stateid)
{ {
int status; int status;
nfs41_compound compound; nfs41_compound compound;
@ -883,7 +884,7 @@ int nfs41_lock(
goto out; goto out;
compound_add_op(&compound, OP_PUTFH, &putfh_args, &putfh_res); compound_add_op(&compound, OP_PUTFH, &putfh_args, &putfh_res);
putfh_args.file = &open_state->file; putfh_args.file = file;
putfh_args.in_recovery = 0; putfh_args.in_recovery = 0;
compound_add_op(&compound, OP_LOCK, &lock_args, &lock_res); compound_add_op(&compound, OP_LOCK, &lock_args, &lock_res);
@ -891,18 +892,18 @@ int nfs41_lock(
lock_args.reclaim = 0; lock_args.reclaim = 0;
lock_args.offset = offset; lock_args.offset = offset;
lock_args.length = length; lock_args.length = length;
if (lock_state) { if (stateid->type == STATEID_LOCK) {
lock_args.locker.new_lock_owner = 0; lock_args.locker.new_lock_owner = 0;
lock_args.locker.u.lock_owner.lock_stateid = lock_state; lock_args.locker.u.lock_owner.lock_stateid = stateid;
lock_args.locker.u.lock_owner.lock_seqid = 0; /* ignored */ lock_args.locker.u.lock_owner.lock_seqid = 0; /* ignored */
} else { } else {
lock_args.locker.new_lock_owner = 1; lock_args.locker.new_lock_owner = 1;
lock_args.locker.u.open_owner.open_seqid = 0; /* ignored */ lock_args.locker.u.open_owner.open_seqid = 0; /* ignored */
lock_args.locker.u.open_owner.open_stateid = &open_state->stateid; lock_args.locker.u.open_owner.open_stateid = stateid;
lock_args.locker.u.open_owner.lock_seqid = 0; /* ignored */ lock_args.locker.u.open_owner.lock_seqid = 0; /* ignored */
lock_args.locker.u.open_owner.lock_owner = &open_state->owner; lock_args.locker.u.open_owner.lock_owner = owner;
} }
lock_res.u.resok4.lock_stateid = stateid_out; lock_res.u.resok4.lock_stateid = &stateid->stateid;
lock_res.u.denied.owner.owner_len = NFS4_OPAQUE_LIMIT; lock_res.u.denied.owner.owner_len = NFS4_OPAQUE_LIMIT;
status = compound_encode_send_decode(session, &compound, 0, 0); status = compound_encode_send_decode(session, &compound, 0, 0);
@ -914,57 +915,12 @@ out:
return status; return status;
} }
int nfs41_test_lock(
IN nfs41_session *session,
IN nfs41_open_state *state,
IN uint32_t type,
IN uint64_t offset,
IN uint64_t length)
{
int status;
nfs41_compound compound;
nfs_argop4 argops[3];
nfs_resop4 resops[3];
nfs41_sequence_args sequence_args;
nfs41_sequence_res sequence_res;
nfs41_putfh_args putfh_args;
nfs41_putfh_res putfh_res;
nfs41_lockt_args lockt_args;
nfs41_lockt_res lockt_res;
compound_init(&compound, argops, resops, "test_lock");
compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
status = nfs41_session_sequence(&sequence_args, session, 0);
if (status)
goto out;
compound_add_op(&compound, OP_PUTFH, &putfh_args, &putfh_res);
putfh_args.file = &state->file;
putfh_args.in_recovery = 0;
compound_add_op(&compound, OP_LOCKT, &lockt_args, &lockt_res);
lockt_args.locktype = type;
lockt_args.offset = offset;
lockt_args.length = length;
lockt_args.owner = &state->owner;
lockt_res.denied.owner.owner_len = NFS4_OPAQUE_LIMIT;
status = compound_encode_send_decode(session, &compound, 0, 0);
if (status)
goto out;
compound_error(status = compound.res.status);
out:
return status;
}
int nfs41_unlock( int nfs41_unlock(
IN nfs41_session *session, IN nfs41_session *session,
IN nfs41_open_state *open_state, IN nfs41_path_fh *file,
IN OUT stateid4 *lock_state,
IN uint64_t offset, IN uint64_t offset,
IN uint64_t length) IN uint64_t length,
IN OUT stateid_arg *stateid)
{ {
int status; int status;
nfs41_compound compound; nfs41_compound compound;
@ -985,7 +941,7 @@ int nfs41_unlock(
goto out; goto out;
compound_add_op(&compound, OP_PUTFH, &putfh_args, &putfh_res); compound_add_op(&compound, OP_PUTFH, &putfh_args, &putfh_res);
putfh_args.file = &open_state->file; putfh_args.file = file;
putfh_args.in_recovery = 0; putfh_args.in_recovery = 0;
compound_add_op(&compound, OP_LOCKU, &locku_args, &locku_res); compound_add_op(&compound, OP_LOCKU, &locku_args, &locku_res);
@ -993,8 +949,8 @@ int nfs41_unlock(
locku_args.locktype = READ_LT; locku_args.locktype = READ_LT;
locku_args.offset = offset; locku_args.offset = offset;
locku_args.length = length; locku_args.length = length;
locku_args.lock_stateid = lock_state; locku_args.lock_stateid = stateid;
locku_res.lock_stateid = lock_state; locku_res.lock_stateid = &stateid->stateid;
status = compound_encode_send_decode(session, &compound, 0, 0); status = compound_encode_send_decode(session, &compound, 0, 0);
if (status) if (status)
@ -1299,7 +1255,7 @@ out:
int nfs41_setattr( int nfs41_setattr(
IN nfs41_session *session, IN nfs41_session *session,
IN nfs41_path_fh *file, IN nfs41_path_fh *file,
IN stateid4 *stateid, IN stateid_arg *stateid,
IN nfs41_file_info *info) IN nfs41_file_info *info)
{ {
int status; int status;
@ -1662,7 +1618,7 @@ out:
enum nfsstat4 pnfs_rpc_layoutget( enum nfsstat4 pnfs_rpc_layoutget(
IN nfs41_session *session, IN nfs41_session *session,
IN nfs41_path_fh *file, IN nfs41_path_fh *file,
IN stateid4 *state, IN stateid_arg *stateid,
IN enum pnfs_iomode iomode, IN enum pnfs_iomode iomode,
IN uint64_t offset, IN uint64_t offset,
IN uint64_t length, IN uint64_t length,
@ -1697,7 +1653,7 @@ enum nfsstat4 pnfs_rpc_layoutget(
layoutget_args.iomode = iomode; layoutget_args.iomode = iomode;
layoutget_args.offset = offset; layoutget_args.offset = offset;
layoutget_args.minlength = layoutget_args.length = length; layoutget_args.minlength = layoutget_args.length = length;
layoutget_args.stateid = state; layoutget_args.stateid = stateid;
layoutget_args.maxcount = session->fore_chan_attrs.ca_maxresponsesize - READ_OVERHEAD; layoutget_args.maxcount = session->fore_chan_attrs.ca_maxresponsesize - READ_OVERHEAD;
layoutget_res.u.res_ok.layout = layout; layoutget_res.u.res_ok.layout = layout;

View file

@ -244,6 +244,22 @@ typedef struct __nfs41_reclaim_complete_res {
} nfs41_reclaim_complete_res; } nfs41_reclaim_complete_res;
/* recoverable stateid argument */
enum stateid_type {
STATEID_OPEN,
STATEID_LOCK,
STATEID_DELEG_FILE,
STATEID_DELEG_DIR,
STATEID_LAYOUT,
STATEID_SPECIAL
};
typedef struct __stateid_arg {
stateid4 stateid;
enum stateid_type type;
nfs41_open_state *open;
} stateid_arg;
/* OP_ACCESS */ /* OP_ACCESS */
enum { enum {
ACCESS4_READ = 0x00000001, ACCESS4_READ = 0x00000001,
@ -269,13 +285,11 @@ typedef struct __nfs41_access_res {
/* OP_CLOSE */ /* OP_CLOSE */
typedef struct __nfs41_op_close_args { typedef struct __nfs41_op_close_args {
// uint32_t seqid; // not used, always 0 // uint32_t seqid; // not used, always 0
stateid4 *open_stateid; /* -> nfs41_op_open_res_ok.stateid */ stateid_arg *stateid;
} nfs41_op_close_args; } nfs41_op_close_args;
typedef struct __nfs41_op_close_res { typedef struct __nfs41_op_close_res {
uint32_t status; uint32_t status;
/* case NFS4_OK: */
stateid4 open_stateid;
} nfs41_op_close_res; } nfs41_op_close_res;
@ -360,13 +374,13 @@ enum {
typedef struct __open_to_lock_owner4 { typedef struct __open_to_lock_owner4 {
uint32_t open_seqid; uint32_t open_seqid;
stateid4 *open_stateid; stateid_arg *open_stateid;
uint32_t lock_seqid; uint32_t lock_seqid;
state_owner4 *lock_owner; state_owner4 *lock_owner;
} open_to_lock_owner4; } open_to_lock_owner4;
typedef struct __exist_lock_owner4 { typedef struct __exist_lock_owner4 {
stateid4 *lock_stateid; stateid_arg *lock_stateid;
uint32_t lock_seqid; uint32_t lock_seqid;
} exist_lock_owner4; } exist_lock_owner4;
@ -431,7 +445,7 @@ typedef struct __nfs41_lockt_res {
typedef struct __nfs41_locku_args { typedef struct __nfs41_locku_args {
uint32_t locktype; uint32_t locktype;
uint32_t seqid; uint32_t seqid;
stateid4 *lock_stateid; stateid_arg *lock_stateid;
uint64_t offset; uint64_t offset;
uint64_t length; uint64_t length;
} nfs41_locku_args; } nfs41_locku_args;
@ -628,7 +642,7 @@ typedef struct __nfs41_op_open_res {
/* OP_READ */ /* OP_READ */
typedef struct __nfs41_read_args { typedef struct __nfs41_read_args {
stateid4 *stateid; /* -> nfs41_op_open_res_ok.stateid */ stateid_arg *stateid; /* -> nfs41_op_open_res_ok.stateid */
uint64_t offset; uint64_t offset;
uint32_t count; uint32_t count;
} nfs41_read_args; } nfs41_read_args;
@ -726,7 +740,7 @@ enum time_how4 {
}; };
typedef struct __nfs41_setattr_args { typedef struct __nfs41_setattr_args {
stateid4 *stateid; stateid_arg *stateid;
nfs41_file_info *info; nfs41_file_info *info;
} nfs41_setattr_args; } nfs41_setattr_args;
@ -750,7 +764,7 @@ typedef struct __nfs41_write_verf {
} nfs41_write_verf; } nfs41_write_verf;
typedef struct __nfs41_write_args { typedef struct __nfs41_write_args {
stateid4 *stateid; /* -> nfs41_op_open_res_ok.stateid */ stateid_arg *stateid; /* -> nfs41_op_open_res_ok.stateid */
uint64_t offset; uint64_t offset;
uint32_t stable; /* stable_how4 */ uint32_t stable; /* stable_how4 */
uint32_t data_len; uint32_t data_len;
@ -777,7 +791,7 @@ typedef struct __pnfs_layoutget_args {
uint64_t offset; uint64_t offset;
uint64_t length; uint64_t length;
uint64_t minlength; uint64_t minlength;
stateid4 *stateid; stateid_arg *stateid;
uint32_t maxcount; uint32_t maxcount;
} pnfs_layoutget_args; } pnfs_layoutget_args;
@ -923,12 +937,13 @@ int nfs41_create(
int nfs41_close( int nfs41_close(
IN nfs41_session *session, IN nfs41_session *session,
IN nfs41_open_state *state); IN nfs41_path_fh *file,
IN stateid_arg *stateid);
int nfs41_write( int nfs41_write(
IN nfs41_session *session, IN nfs41_session *session,
IN nfs41_path_fh *file, IN nfs41_path_fh *file,
IN stateid4 *stateid, IN stateid_arg *stateid,
IN unsigned char *data, IN unsigned char *data,
IN uint32_t data_len, IN uint32_t data_len,
IN uint64_t offset, IN uint64_t offset,
@ -939,7 +954,7 @@ int nfs41_write(
int nfs41_read( int nfs41_read(
IN nfs41_session *session, IN nfs41_session *session,
IN nfs41_path_fh *file, IN nfs41_path_fh *file,
IN stateid4 *stateid, IN stateid_arg *stateid,
IN uint64_t offset, IN uint64_t offset,
IN uint32_t count, IN uint32_t count,
OUT unsigned char *data_out, OUT unsigned char *data_out,
@ -955,26 +970,19 @@ int nfs41_commit(
int nfs41_lock( int nfs41_lock(
IN nfs41_session *session, IN nfs41_session *session,
IN nfs41_open_state *open_state, IN nfs41_path_fh *file,
IN stateid4 *lock_state OPTIONAL, IN state_owner4 *owner,
IN uint32_t type, IN uint32_t type,
IN uint64_t offset, IN uint64_t offset,
IN uint64_t length, IN uint64_t length,
OUT stateid4 *stateid_out); IN OUT stateid_arg *stateid);
int nfs41_test_lock(
IN nfs41_session *session,
IN nfs41_open_state *state,
IN uint32_t type,
IN uint64_t offset,
IN uint64_t length);
int nfs41_unlock( int nfs41_unlock(
IN nfs41_session *session, IN nfs41_session *session,
IN nfs41_open_state *open_state, IN nfs41_path_fh *file,
IN OUT stateid4 *lock_state,
IN uint64_t offset, IN uint64_t offset,
IN uint64_t length); IN uint64_t length,
IN OUT stateid_arg *stateid);
stateid4* nfs41_lock_stateid_copy( stateid4* nfs41_lock_stateid_copy(
IN nfs41_lock_state *lock_state, IN nfs41_lock_state *lock_state,
@ -1019,7 +1027,7 @@ int nfs41_rename(
int nfs41_setattr( int nfs41_setattr(
IN nfs41_session *session, IN nfs41_session *session,
IN nfs41_path_fh *file, IN nfs41_path_fh *file,
IN stateid4 *stateid, IN stateid_arg *stateid,
IN nfs41_file_info *info); IN nfs41_file_info *info);
int nfs41_link( int nfs41_link(
@ -1070,7 +1078,7 @@ enum nfsstat4 nfs41_fs_locations(
enum nfsstat4 pnfs_rpc_layoutget( enum nfsstat4 pnfs_rpc_layoutget(
IN nfs41_session *session, IN nfs41_session *session,
IN nfs41_path_fh *file, IN nfs41_path_fh *file,
IN stateid4 *state, IN stateid_arg *stateid,
IN enum pnfs_iomode iomode, IN enum pnfs_iomode iomode,
IN uint64_t offset, IN uint64_t offset,
IN uint64_t length, IN uint64_t length,

View file

@ -1101,13 +1101,14 @@ static bool_t encode_op_close(
if (!xdr_u_int32_t(xdr, &zero)) // This should be ignored by server if (!xdr_u_int32_t(xdr, &zero)) // This should be ignored by server
return FALSE; return FALSE;
return xdr_stateid4(xdr, args->open_stateid); return xdr_stateid4(xdr, &args->stateid->stateid);
} }
static bool_t decode_op_close( static bool_t decode_op_close(
XDR *xdr, XDR *xdr,
nfs_resop4 *resop) nfs_resop4 *resop)
{ {
stateid4 ignored;
nfs41_op_close_res *res = (nfs41_op_close_res*)resop->res; nfs41_op_close_res *res = (nfs41_op_close_res*)resop->res;
if (unexpected_op(resop->op, OP_CLOSE)) if (unexpected_op(resop->op, OP_CLOSE))
@ -1117,7 +1118,7 @@ static bool_t decode_op_close(
return FALSE; return FALSE;
if (res->status == NFS4_OK) if (res->status == NFS4_OK)
return xdr_stateid4(xdr, &res->open_stateid); return xdr_stateid4(xdr, &ignored);
return TRUE; return TRUE;
} }
@ -1315,7 +1316,7 @@ static bool_t xdr_locker4(
if (!xdr_u_int32_t(xdr, &locker->u.open_owner.open_seqid)) if (!xdr_u_int32_t(xdr, &locker->u.open_owner.open_seqid))
return FALSE; return FALSE;
if (!xdr_stateid4(xdr, locker->u.open_owner.open_stateid)) if (!xdr_stateid4(xdr, &locker->u.open_owner.open_stateid->stateid))
return FALSE; return FALSE;
if (!xdr_u_int32_t(xdr, &locker->u.open_owner.lock_seqid)) if (!xdr_u_int32_t(xdr, &locker->u.open_owner.lock_seqid))
@ -1324,7 +1325,7 @@ static bool_t xdr_locker4(
return xdr_state_owner4(xdr, locker->u.open_owner.lock_owner); return xdr_state_owner4(xdr, locker->u.open_owner.lock_owner);
} else { } else {
/* exist_lock_owner4 lock_owner */ /* exist_lock_owner4 lock_owner */
if (!xdr_stateid4(xdr, locker->u.lock_owner.lock_stateid)) if (!xdr_stateid4(xdr, &locker->u.lock_owner.lock_stateid->stateid))
return FALSE; return FALSE;
return xdr_u_int32_t(xdr, &locker->u.lock_owner.lock_seqid); return xdr_u_int32_t(xdr, &locker->u.lock_owner.lock_seqid);
@ -1459,7 +1460,7 @@ static bool_t encode_op_locku(
if (!xdr_u_int32_t(xdr, &args->seqid)) if (!xdr_u_int32_t(xdr, &args->seqid))
return FALSE; return FALSE;
if (!xdr_stateid4(xdr, args->lock_stateid)) if (!xdr_stateid4(xdr, &args->lock_stateid->stateid))
return FALSE; return FALSE;
if (!xdr_u_hyper(xdr, &args->offset)) if (!xdr_u_hyper(xdr, &args->offset))
@ -1974,7 +1975,7 @@ static bool_t encode_op_read(
if (unexpected_op(argop->op, OP_READ)) if (unexpected_op(argop->op, OP_READ))
return FALSE; return FALSE;
if (!xdr_stateid4(xdr, args->stateid)) if (!xdr_stateid4(xdr, &args->stateid->stateid))
return FALSE; return FALSE;
if (!xdr_u_hyper(xdr, &args->offset)) if (!xdr_u_hyper(xdr, &args->offset))
@ -2409,7 +2410,7 @@ static bool_t encode_op_setattr(
if (unexpected_op(argop->op, OP_SETATTR)) if (unexpected_op(argop->op, OP_SETATTR))
return FALSE; return FALSE;
if (!xdr_stateid4(xdr, args->stateid)) if (!xdr_stateid4(xdr, &args->stateid->stateid))
return FALSE; return FALSE;
/* encode attribute values from args->info into attrs.attr_vals */ /* encode attribute values from args->info into attrs.attr_vals */
@ -2452,7 +2453,7 @@ static bool_t encode_op_write(
if (unexpected_op(argop->op, OP_WRITE)) if (unexpected_op(argop->op, OP_WRITE))
return FALSE; return FALSE;
if (!xdr_stateid4(xdr, args->stateid)) if (!xdr_stateid4(xdr, &args->stateid->stateid))
return FALSE; return FALSE;
if (!xdr_u_hyper(xdr, &args->offset)) if (!xdr_u_hyper(xdr, &args->offset))
@ -2811,7 +2812,7 @@ static bool_t encode_op_layoutget(
if (!xdr_u_hyper(xdr, &args->minlength)) if (!xdr_u_hyper(xdr, &args->minlength))
return FALSE; return FALSE;
if (!xdr_stateid4(xdr, args->stateid)) if (!xdr_stateid4(xdr, &args->stateid->stateid))
return FALSE; return FALSE;
return xdr_u_int32_t(xdr, &args->maxcount); return xdr_u_int32_t(xdr, &args->maxcount);

View file

@ -94,6 +94,17 @@ void nfs41_open_state_deref(
free(state); free(state);
} }
void nfs41_open_stateid_arg(
IN nfs41_open_state *state,
OUT stateid_arg *arg)
{
AcquireSRWLockShared(&state->lock);
memcpy(&arg->stateid, &state->stateid, sizeof(stateid4));
ReleaseSRWLockShared(&state->lock);
arg->type = STATEID_OPEN;
arg->open = state;
}
/* client list of associated open state */ /* client list of associated open state */
static void client_state_add( static void client_state_add(
@ -491,7 +502,10 @@ static void cancel_open(IN nfs41_upcall *upcall)
goto out; /* if handle_open() failed, the state was already freed */ goto out; /* if handle_open() failed, the state was already freed */
if (state->do_close) { if (state->do_close) {
status = nfs41_close(state->session, state); stateid_arg stateid;
nfs41_open_stateid_arg(state, &stateid);
status = nfs41_close(state->session, &state->file, &stateid);
if (status) if (status)
dprintf(1, "cancel_open: nfs41_close() failed with %s\n", dprintf(1, "cancel_open: nfs41_close() failed with %s\n",
nfs_error_string(status)); nfs_error_string(status));
@ -569,7 +583,10 @@ static int handle_close(nfs41_upcall *upcall)
} }
if (state->do_close) { if (state->do_close) {
status = nfs41_close(state->session, state); stateid_arg stateid;
nfs41_open_stateid_arg(state, &stateid);
status = nfs41_close(state->session, &state->file, &stateid);
if (status) { if (status) {
dprintf(1, "nfs41_close() failed with error %s.\n", dprintf(1, "nfs41_close() failed with error %s.\n",
nfs_error_string(status)); nfs_error_string(status));

View file

@ -194,8 +194,7 @@ typedef struct __pnfs_layout_recall {
typedef struct __pnfs_io_pattern { typedef struct __pnfs_io_pattern {
struct __pnfs_io_thread *threads; struct __pnfs_io_thread *threads;
struct __nfs41_root *root; struct __nfs41_root *root;
nfs41_path_fh *meta_file; struct __nfs41_open_state *state;
stateid4 stateid;
pnfs_file_layout *layout; pnfs_file_layout *layout;
unsigned char *buffer; unsigned char *buffer;
uint64_t offset_start; uint64_t offset_start;
@ -330,8 +329,7 @@ __inline uint32_t data_server_index(
enum pnfs_status pnfs_read( enum pnfs_status pnfs_read(
IN struct __nfs41_root *root, IN struct __nfs41_root *root,
IN struct __nfs41_session *session, IN struct __nfs41_session *session,
IN nfs41_path_fh *file, IN struct __nfs41_open_state *state,
IN stateid4 *stateid,
IN pnfs_file_layout *layout, IN pnfs_file_layout *layout,
IN uint64_t offset, IN uint64_t offset,
IN uint64_t length, IN uint64_t length,
@ -341,8 +339,7 @@ enum pnfs_status pnfs_read(
enum pnfs_status pnfs_write( enum pnfs_status pnfs_write(
IN struct __nfs41_root *root, IN struct __nfs41_root *root,
IN struct __nfs41_session *session, IN struct __nfs41_session *session,
IN nfs41_path_fh *file, IN struct __nfs41_open_state *state,
IN stateid4 *stateid,
IN pnfs_file_layout *layout, IN pnfs_file_layout *layout,
IN uint64_t offset, IN uint64_t offset,
IN uint64_t length, IN uint64_t length,

View file

@ -281,7 +281,7 @@ static enum pnfs_status get_sparse_fh(
} else if (filehandle_count == 1) { } else if (filehandle_count == 1) {
*file_out = &layout->filehandles.arr[0]; *file_out = &layout->filehandles.arr[0];
} else if (filehandle_count == 0) { } else if (filehandle_count == 0) {
*file_out = pattern->meta_file; *file_out = &pattern->state->file;
} else { } else {
eprintf("invalid sparse layout! has %u file handles " eprintf("invalid sparse layout! has %u file handles "
"and %u servers\n", filehandle_count, server_count); "and %u servers\n", filehandle_count, server_count);

View file

@ -43,8 +43,7 @@ static uint32_t io_unit_count(
static enum pnfs_status pattern_init( static enum pnfs_status pattern_init(
IN pnfs_io_pattern *pattern, IN pnfs_io_pattern *pattern,
IN nfs41_root *root, IN nfs41_root *root,
IN nfs41_path_fh *meta_file, IN nfs41_open_state *state,
IN stateid4 *stateid,
IN pnfs_file_layout *layout, IN pnfs_file_layout *layout,
IN unsigned char *buffer, IN unsigned char *buffer,
IN uint64_t offset, IN uint64_t offset,
@ -76,12 +75,7 @@ static enum pnfs_status pattern_init(
} }
pattern->root = root; pattern->root = root;
pattern->meta_file = meta_file; pattern->state = state;
/* 13.9.1. Global Stateid Requirements
* "The stateid sent to the data server MUST be sent
* with the seqid set to zero" */
memcpy(&pattern->stateid, stateid, sizeof(stateid4));
pattern->stateid.seqid = 0;
pattern->layout = layout; pattern->layout = layout;
pattern->buffer = buffer; pattern->buffer = buffer;
pattern->offset_start = offset; pattern->offset_start = offset;
@ -301,9 +295,9 @@ static enum pnfs_status map_ds_error(
static uint32_t WINAPI file_layout_read_thread(void *args) static uint32_t WINAPI file_layout_read_thread(void *args)
{ {
pnfs_io_unit io; pnfs_io_unit io;
stateid_arg stateid;
pnfs_io_thread *thread = (pnfs_io_thread*)args; pnfs_io_thread *thread = (pnfs_io_thread*)args;
pnfs_io_pattern *pattern = thread->pattern; pnfs_io_pattern *pattern = thread->pattern;
stateid4 *state = &pattern->stateid;
pnfs_data_server *server; pnfs_data_server *server;
nfs41_client *client; nfs41_client *client;
uint32_t maxreadsize, bytes_read, total_read; uint32_t maxreadsize, bytes_read, total_read;
@ -329,13 +323,16 @@ static uint32_t WINAPI file_layout_read_thread(void *args)
goto out; goto out;
} }
nfs41_lock_stateid_arg(pattern->state, &stateid);
stateid.stateid.seqid = 0;
total_read = 0; total_read = 0;
while ((status = thread_next_unit(thread, &io)) == PNFS_PENDING) { while ((status = thread_next_unit(thread, &io)) == PNFS_PENDING) {
maxreadsize = max_read_size(client->session, &io.file->fh); maxreadsize = max_read_size(client->session, &io.file->fh);
if (io.length > maxreadsize) if (io.length > maxreadsize)
io.length = maxreadsize; io.length = maxreadsize;
nfsstat = nfs41_read(client->session, io.file, state, io.offset, nfsstat = nfs41_read(client->session, io.file, &stateid, io.offset,
(uint32_t)io.length, io.buffer, &bytes_read, &eof); (uint32_t)io.length, io.buffer, &bytes_read, &eof);
if (nfsstat) { if (nfsstat) {
eprintf("nfs41_read() failed with %s\n", eprintf("nfs41_read() failed with %s\n",
@ -363,10 +360,10 @@ out:
static uint32_t WINAPI file_layout_write_thread(void *args) static uint32_t WINAPI file_layout_write_thread(void *args)
{ {
pnfs_io_unit io; pnfs_io_unit io;
stateid_arg stateid;
nfs41_write_verf verf; nfs41_write_verf verf;
pnfs_io_thread *thread = (pnfs_io_thread*)args; pnfs_io_thread *thread = (pnfs_io_thread*)args;
pnfs_io_pattern *pattern = thread->pattern; pnfs_io_pattern *pattern = thread->pattern;
stateid4 *state = &pattern->stateid;
pnfs_data_server *server; pnfs_data_server *server;
pnfs_file_layout *layout = pattern->layout; pnfs_file_layout *layout = pattern->layout;
nfs41_client *client; nfs41_client *client;
@ -395,6 +392,9 @@ static uint32_t WINAPI file_layout_write_thread(void *args)
goto out; goto out;
} }
nfs41_lock_stateid_arg(pattern->state, &stateid);
stateid.stateid.seqid = 0;
retry_write: retry_write:
thread->offset = offset_start; thread->offset = offset_start;
thread->stable = DATA_SYNC4; thread->stable = DATA_SYNC4;
@ -406,7 +406,7 @@ retry_write:
if (io.length > maxwritesize) if (io.length > maxwritesize)
io.length = maxwritesize; io.length = maxwritesize;
nfsstat = nfs41_write(client->session, io.file, state, io.buffer, nfsstat = nfs41_write(client->session, io.file, &stateid, io.buffer,
(uint32_t)io.length, io.offset, UNSTABLE4, &bytes_written, &verf); (uint32_t)io.length, io.offset, UNSTABLE4, &bytes_written, &verf);
if (nfsstat) { if (nfsstat) {
eprintf("nfs41_write() failed with %s\n", eprintf("nfs41_write() failed with %s\n",
@ -460,8 +460,7 @@ out:
enum pnfs_status pnfs_read( enum pnfs_status pnfs_read(
IN nfs41_root *root, IN nfs41_root *root,
IN nfs41_session *session, IN nfs41_session *session,
IN nfs41_path_fh *file, IN nfs41_open_state *state,
IN stateid4 *stateid,
IN pnfs_file_layout *layout, IN pnfs_file_layout *layout,
IN uint64_t offset, IN uint64_t offset,
IN uint64_t length, IN uint64_t length,
@ -475,8 +474,8 @@ enum pnfs_status pnfs_read(
*len_out = 0; *len_out = 0;
status = pattern_init(&pattern, root, file, stateid, status = pattern_init(&pattern, root, state, layout,
layout, buffer_out, offset, length, session->lease_time); buffer_out, offset, length, session->lease_time);
if (status) { if (status) {
eprintf("pattern_init() failed with %s\n", eprintf("pattern_init() failed with %s\n",
pnfs_error_string(status)); pnfs_error_string(status));
@ -500,8 +499,7 @@ out:
enum pnfs_status pnfs_write( enum pnfs_status pnfs_write(
IN nfs41_root *root, IN nfs41_root *root,
IN nfs41_session *session, IN nfs41_session *session,
IN nfs41_path_fh *file, IN nfs41_open_state *state,
IN stateid4 *stateid,
IN pnfs_file_layout *layout, IN pnfs_file_layout *layout,
IN uint64_t offset, IN uint64_t offset,
IN uint64_t length, IN uint64_t length,
@ -518,8 +516,8 @@ enum pnfs_status pnfs_write(
*len_out = 0; *len_out = 0;
status = pattern_init(&pattern, root, file, stateid, status = pattern_init(&pattern, root, state, layout,
layout, buffer, offset, length, session->lease_time); buffer, offset, length, session->lease_time);
if (status) { if (status) {
eprintf("pattern_init() failed with %s\n", eprintf("pattern_init() failed with %s\n",
pnfs_error_string(status)); pnfs_error_string(status));
@ -541,7 +539,7 @@ enum pnfs_status pnfs_write(
* after LAYOUTCOMMIT */ * after LAYOUTCOMMIT */
dprintf(1, "sending COMMIT to meta server for offset=%d and len=%d\n", dprintf(1, "sending COMMIT to meta server for offset=%d and len=%d\n",
offset, *len_out); offset, *len_out);
nfsstat = nfs41_commit(session, pattern.meta_file, offset, *len_out, 0); nfsstat = nfs41_commit(session, &state->file, offset, *len_out, 0);
if (nfsstat) { if (nfsstat) {
dprintf(IOLVL, "nfs41_commit() failed with %s\n", dprintf(IOLVL, "nfs41_commit() failed with %s\n",
nfs_error_string(nfsstat)); nfs_error_string(nfsstat));
@ -553,7 +551,7 @@ enum pnfs_status pnfs_write(
/* send LAYOUTCOMMIT */ /* send LAYOUTCOMMIT */
new_last_offset = offset + *len_out - 1; new_last_offset = offset + *len_out - 1;
nfsstat = pnfs_rpc_layoutcommit(session, pattern.meta_file, nfsstat = pnfs_rpc_layoutcommit(session, &state->file,
&pattern.layout->layout.state, offset, *len_out, &pattern.layout->layout.state, offset, *len_out,
&new_last_offset, NULL); &new_last_offset, NULL);
if (nfsstat) { if (nfsstat) {

View file

@ -192,7 +192,7 @@ static enum pnfs_status file_layout_fetch(
IN OUT pnfs_file_layout *layout, IN OUT pnfs_file_layout *layout,
IN nfs41_session *session, IN nfs41_session *session,
IN nfs41_path_fh *meta_file, IN nfs41_path_fh *meta_file,
IN stateid4 *state, IN stateid_arg *stateid,
IN enum pnfs_iomode iomode, IN enum pnfs_iomode iomode,
IN uint64_t offset, IN uint64_t offset,
IN uint64_t length) IN uint64_t length)
@ -204,7 +204,7 @@ static enum pnfs_status file_layout_fetch(
pnfs_iomode_string(iomode), layout->layout.state.seqid); pnfs_iomode_string(iomode), layout->layout.state.seqid);
nfsstat = pnfs_rpc_layoutget(session, meta_file, nfsstat = pnfs_rpc_layoutget(session, meta_file,
state, iomode, offset, length, layout); stateid, iomode, offset, length, layout);
if (nfsstat) { if (nfsstat) {
dprintf(FLLVL, "pnfs_rpc_layoutget() failed with %s\n", dprintf(FLLVL, "pnfs_rpc_layoutget() failed with %s\n",
nfs_error_string(nfsstat)); nfs_error_string(nfsstat));
@ -264,7 +264,7 @@ static enum pnfs_status file_layout_cache(
IN OUT pnfs_file_layout *layout, IN OUT pnfs_file_layout *layout,
IN nfs41_session *session, IN nfs41_session *session,
IN nfs41_path_fh *meta_file, IN nfs41_path_fh *meta_file,
IN stateid4 *state, IN stateid_arg *stateid,
IN enum pnfs_iomode iomode, IN enum pnfs_iomode iomode,
IN uint64_t offset, IN uint64_t offset,
IN uint64_t length) IN uint64_t length)
@ -283,19 +283,22 @@ static enum pnfs_status file_layout_cache(
status = layout_grant_status(&layout->layout, iomode); status = layout_grant_status(&layout->layout, iomode);
if (status == PNFS_PENDING) { if (status == PNFS_PENDING) {
/* if there's an existing layout stateid, use it */ /* if there's an existing layout stateid, use it */
if (layout->layout.state.seqid) if (layout->layout.state.seqid) {
state = &layout->layout.state; memcpy(&stateid->stateid, &layout->layout.state,
sizeof(stateid4));
stateid->type = STATEID_LAYOUT;
}
if ((layout->layout.status & PNFS_LAYOUT_NOT_RW) == 0) { if ((layout->layout.status & PNFS_LAYOUT_NOT_RW) == 0) {
/* try to get a RW layout first */ /* try to get a RW layout first */
status = file_layout_fetch(layout, session, status = file_layout_fetch(layout, session,
meta_file, state, PNFS_IOMODE_RW, offset, length); meta_file, stateid, PNFS_IOMODE_RW, offset, length);
} }
if (status && iomode == PNFS_IOMODE_READ) { if (status && iomode == PNFS_IOMODE_READ) {
/* fall back on READ if necessary */ /* fall back on READ if necessary */
status = file_layout_fetch(layout, session, status = file_layout_fetch(layout, session,
meta_file, state, iomode, offset, length); meta_file, stateid, iomode, offset, length);
} }
} }
@ -375,7 +378,7 @@ static enum pnfs_status file_layout_get(
IN OUT pnfs_file_layout *layout, IN OUT pnfs_file_layout *layout,
IN nfs41_session *session, IN nfs41_session *session,
IN nfs41_path_fh *meta_file, IN nfs41_path_fh *meta_file,
IN stateid4 *state, IN stateid_arg *stateid,
IN enum pnfs_iomode iomode, IN enum pnfs_iomode iomode,
IN uint64_t offset, IN uint64_t offset,
IN uint64_t length) IN uint64_t length)
@ -384,7 +387,7 @@ static enum pnfs_status file_layout_get(
/* request a range for the entire file */ /* request a range for the entire file */
status = file_layout_cache(layout, session, status = file_layout_cache(layout, session,
meta_file, state, iomode, 0, NFS4_UINT64_MAX); meta_file, stateid, iomode, 0, NFS4_UINT64_MAX);
if (status) { if (status) {
dprintf(FLLVL, "file_layout_cache() failed with %s\n", dprintf(FLLVL, "file_layout_cache() failed with %s\n",
pnfs_error_string(status)); pnfs_error_string(status));
@ -509,6 +512,7 @@ enum pnfs_status pnfs_open_state_layout(
IN uint64_t length, IN uint64_t length,
OUT pnfs_file_layout **layout_out) OUT pnfs_file_layout **layout_out)
{ {
stateid_arg stateid;
pnfs_file_layout *layout; pnfs_file_layout *layout;
enum pnfs_status status; enum pnfs_status status;
@ -547,9 +551,11 @@ enum pnfs_status pnfs_open_state_layout(
goto out; goto out;
} }
nfs41_open_stateid_arg(state, &stateid);
/* make sure the layout can satisfy this request */ /* make sure the layout can satisfy this request */
status = file_layout_get(layout, session, &state->file, status = file_layout_get(layout, session, &state->file,
&state->stateid, iomode, offset, length); &stateid, iomode, offset, length);
if (status) { if (status) {
dprintf(FLLVL, "file_layout_get() failed with %s\n", dprintf(FLLVL, "file_layout_get() failed with %s\n",
pnfs_error_string(status)); pnfs_error_string(status));

View file

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

View file

@ -101,13 +101,11 @@ static int handle_nfs41_setattr(setattr_upcall_args *args)
PFILE_BASIC_INFO basic_info = (PFILE_BASIC_INFO)args->buf; PFILE_BASIC_INFO basic_info = (PFILE_BASIC_INFO)args->buf;
nfs41_open_state *state = args->state; nfs41_open_state *state = args->state;
nfs41_superblock *superblock = state->file.fh.superblock; nfs41_superblock *superblock = state->file.fh.superblock;
stateid4 stateid, *pstateid; stateid_arg stateid;
nfs41_file_info info; nfs41_file_info info;
int status = NO_ERROR; int status = NO_ERROR;
pstateid = nfs41_lock_stateid_copy(&state->last_lock, &stateid); nfs41_lock_stateid_arg(state, &stateid);
if (pstateid == NULL)
pstateid = &state->stateid;
ZeroMemory(&info, sizeof(info)); ZeroMemory(&info, sizeof(info));
@ -159,7 +157,7 @@ static int handle_nfs41_setattr(setattr_upcall_args *args)
if (!info.attrmask.count) if (!info.attrmask.count)
goto out; goto out;
status = nfs41_setattr(state->session, &state->file, pstateid, &info); status = nfs41_setattr(state->session, &state->file, &stateid, &info);
if (status) { if (status) {
dprintf(1, "nfs41_setattr() failed with error %s.\n", dprintf(1, "nfs41_setattr() failed with error %s.\n",
nfs_error_string(status)); nfs_error_string(status));
@ -313,18 +311,15 @@ out:
static int handle_nfs41_set_size(setattr_upcall_args *args) static int handle_nfs41_set_size(setattr_upcall_args *args)
{ {
nfs41_open_state *state = args->state; nfs41_file_info info;
int status; stateid_arg stateid;
/* note: this is called with either FILE_END_OF_FILE_INFO or /* note: this is called with either FILE_END_OF_FILE_INFO or
* FILE_ALLOCATION_INFO, both of which contain a single LARGE_INTEGER */ * FILE_ALLOCATION_INFO, both of which contain a single LARGE_INTEGER */
PLARGE_INTEGER size = (PLARGE_INTEGER)args->buf; PLARGE_INTEGER size = (PLARGE_INTEGER)args->buf;
stateid4 stateid, *pstateid; nfs41_open_state *state = args->state;
nfs41_file_info info; int status;
pstateid = nfs41_lock_stateid_copy(&state->last_lock, &stateid); nfs41_lock_stateid_arg(state, &stateid);
if (pstateid == NULL)
pstateid = &state->stateid;
ZeroMemory(&info, sizeof(info)); ZeroMemory(&info, sizeof(info));
info.size = size->QuadPart; info.size = size->QuadPart;
@ -333,7 +328,7 @@ static int handle_nfs41_set_size(setattr_upcall_args *args)
info.attrmask.arr[0] = FATTR4_WORD0_SIZE; info.attrmask.arr[0] = FATTR4_WORD0_SIZE;
dprintf(2, "calling setattr() with size=%lld\n", info.size); dprintf(2, "calling setattr() with size=%lld\n", info.size);
status = nfs41_setattr(state->session, &state->file, pstateid, &info); status = nfs41_setattr(state->session, &state->file, &stateid, &info);
if (status) if (status)
dprintf(1, "nfs41_setattr() failed with error %s.\n", dprintf(1, "nfs41_setattr() failed with error %s.\n",
nfs_error_string(status)); nfs_error_string(status));
@ -518,12 +513,10 @@ static int handle_setexattr(nfs41_upcall *upcall)
int status; int status;
setexattr_upcall_args *args = &upcall->args.setexattr; setexattr_upcall_args *args = &upcall->args.setexattr;
nfs41_open_state *state = args->state; nfs41_open_state *state = args->state;
stateid4 stateid, *pstateid; stateid_arg stateid;
nfs41_file_info info; nfs41_file_info info;
pstateid = nfs41_lock_stateid_copy(&state->last_lock, &stateid); nfs41_lock_stateid_arg(state, &stateid);
if (pstateid == NULL)
pstateid = &state->stateid;
ZeroMemory(&info, sizeof(info)); ZeroMemory(&info, sizeof(info));
@ -532,7 +525,7 @@ static int handle_setexattr(nfs41_upcall *upcall)
info.attrmask.arr[1] |= FATTR4_WORD1_MODE; info.attrmask.arr[1] |= FATTR4_WORD1_MODE;
info.attrmask.count = 2; info.attrmask.count = 2;
status = nfs41_setattr(state->session, &state->file, pstateid, &info); status = nfs41_setattr(state->session, &state->file, &stateid, &info);
if (status) if (status)
dprintf(1, "nfs41_setattr() failed with error %s.\n", dprintf(1, "nfs41_setattr() failed with error %s.\n",
nfs_error_string(status)); nfs_error_string(status));