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 */
stateid4* nfs41_lock_stateid_copy(
IN nfs41_lock_state *lock_state,
IN OUT stateid4 *dest)
void nfs41_lock_stateid_arg(
IN nfs41_open_state *state,
OUT stateid_arg *arg)
{
stateid4 *result;
AcquireSRWLockShared(&lock_state->lock);
if (lock_state->initialized) {
memcpy(dest, &lock_state->stateid, sizeof(stateid4));
result = dest;
dprintf(LKLVL, "nfs41_lock_stateid_copy: copying existing stateid "
"with seqid=%u\n", result->seqid);
AcquireSRWLockShared(&state->last_lock.lock);
if (state->last_lock.initialized) {
/* use lock stateid where available */
memcpy(&arg->stateid, &state->last_lock.stateid, sizeof(stateid4));
arg->type = STATEID_LOCK;
ReleaseSRWLockShared(&state->last_lock.lock);
} else {
result = NULL;
dprintf(LKLVL, "nfs41_lock_stateid_copy: no existing lock state\n");
ReleaseSRWLockShared(&state->last_lock.lock);
/* fall back on open stateid */
nfs41_open_stateid_arg(state, arg);
}
ReleaseSRWLockShared(&lock_state->lock);
return result;
}
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)
{
int status;
stateid_arg stateid;
lock_upcall_args *args = &upcall->args.lock;
nfs41_open_state *state = args->state;
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);
if (status) {
dprintf(LKLVL, "nfs41_lock failed with %s\n",
@ -141,27 +140,27 @@ static int handle_lock(nfs41_upcall *upcall)
goto out;
}
update_last_lock_state(&state->last_lock, &stateid);
update_last_lock_state(&state->last_lock, &stateid.stateid);
out:
return status;
}
static void cancel_lock(IN nfs41_upcall *upcall)
{
int status = NO_ERROR;
stateid_arg stateid;
lock_upcall_args *args = &upcall->args.lock;
nfs41_open_state *state = args->state;
stateid4 stateid, *prev_stateid;
int status = NO_ERROR;
dprintf(1, "--> cancel_lock()\n");
if (upcall->status)
goto out;
prev_stateid = nfs41_lock_stateid_copy(&state->last_lock, &stateid);
nfs41_lock_stateid_arg(state, &stateid);
status = nfs41_unlock(state->session, state,
prev_stateid, args->offset, args->length);
status = nfs41_unlock(state->session, &state->file,
args->offset, args->length, &stateid);
if (status) {
dprintf(LKLVL, "cancel_lock: nfs41_unlock() failed with %s\n",
nfs_error_string(status));
@ -169,7 +168,7 @@ static void cancel_lock(IN nfs41_upcall *upcall)
goto out;
}
update_last_lock_state(&state->last_lock, &stateid);
update_last_lock_state(&state->last_lock, &stateid.stateid);
out:
dprintf(1, "<-- cancel_lock() returning %d\n", status);
}
@ -201,17 +200,18 @@ out:
static int handle_unlock(nfs41_upcall *upcall)
{
int status;
stateid_arg stateid;
unlock_upcall_args *args = &upcall->args.unlock;
nfs41_open_state *state = args->state;
stateid4 stateid;
uint32_t i, nsuccess = 0;
unsigned char *buf = args->buf;
uint32_t buf_len = args->buf_len;
uint64_t offset;
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");
status = ERROR_NOT_LOCKED;
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, &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) {
nsuccess++;
} else {
@ -233,7 +234,7 @@ static int handle_unlock(nfs41_upcall *upcall)
}
if (nsuccess) {
update_last_lock_state(&state->last_lock, &stateid);
update_last_lock_state(&state->last_lock, &stateid.stateid);
status = NO_ERROR;
}
out:

View file

@ -400,4 +400,14 @@ void nfs41_open_state_ref(
void nfs41_open_state_deref(
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__ */

View file

@ -590,7 +590,8 @@ out:
int nfs41_close(
IN nfs41_session *session,
IN nfs41_open_state *state)
IN nfs41_path_fh *file,
IN stateid_arg *stateid)
{
int status;
nfs41_compound compound;
@ -617,11 +618,11 @@ int nfs41_close(
goto out;
compound_add_op(&compound, OP_PUTFH, &putfh_args, &putfh_res);
putfh_args.file = &state->file;
putfh_args.file = file;
putfh_args.in_recovery = 0;
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);
getattr_args.attr_request = &attr_request;
@ -639,7 +640,7 @@ int nfs41_close(
memcpy(&info.attrmask, &getattr_res.obj_attributes.attrmask,
sizeof(bitmap4));
nfs41_attr_cache_update(session_name_cache(session),
state->file.fh.fileid, &info);
file->fh.fileid, &info);
out:
return status;
@ -648,7 +649,7 @@ out:
int nfs41_write(
IN nfs41_session *session,
IN nfs41_path_fh *file,
IN stateid4 *stateid,
IN stateid_arg *stateid,
IN unsigned char *data,
IN uint32_t data_len,
IN uint64_t offset,
@ -732,7 +733,7 @@ out:
int nfs41_read(
IN nfs41_session *session,
IN nfs41_path_fh *file,
IN stateid4 *stateid,
IN stateid_arg *stateid,
IN uint64_t offset,
IN uint32_t count,
OUT unsigned char *data_out,
@ -857,12 +858,12 @@ out:
int nfs41_lock(
IN nfs41_session *session,
IN nfs41_open_state *open_state,
IN stateid4 *lock_state OPTIONAL,
IN nfs41_path_fh *file,
IN state_owner4 *owner,
IN uint32_t type,
IN uint64_t offset,
IN uint64_t length,
OUT stateid4 *stateid_out)
IN OUT stateid_arg *stateid)
{
int status;
nfs41_compound compound;
@ -883,7 +884,7 @@ int nfs41_lock(
goto out;
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;
compound_add_op(&compound, OP_LOCK, &lock_args, &lock_res);
@ -891,18 +892,18 @@ int nfs41_lock(
lock_args.reclaim = 0;
lock_args.offset = offset;
lock_args.length = length;
if (lock_state) {
if (stateid->type == STATEID_LOCK) {
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 */
} else {
lock_args.locker.new_lock_owner = 1;
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_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;
status = compound_encode_send_decode(session, &compound, 0, 0);
@ -914,57 +915,12 @@ out:
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(
IN nfs41_session *session,
IN nfs41_open_state *open_state,
IN OUT stateid4 *lock_state,
IN nfs41_path_fh *file,
IN uint64_t offset,
IN uint64_t length)
IN uint64_t length,
IN OUT stateid_arg *stateid)
{
int status;
nfs41_compound compound;
@ -985,7 +941,7 @@ int nfs41_unlock(
goto out;
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;
compound_add_op(&compound, OP_LOCKU, &locku_args, &locku_res);
@ -993,8 +949,8 @@ int nfs41_unlock(
locku_args.locktype = READ_LT;
locku_args.offset = offset;
locku_args.length = length;
locku_args.lock_stateid = lock_state;
locku_res.lock_stateid = lock_state;
locku_args.lock_stateid = stateid;
locku_res.lock_stateid = &stateid->stateid;
status = compound_encode_send_decode(session, &compound, 0, 0);
if (status)
@ -1299,7 +1255,7 @@ out:
int nfs41_setattr(
IN nfs41_session *session,
IN nfs41_path_fh *file,
IN stateid4 *stateid,
IN stateid_arg *stateid,
IN nfs41_file_info *info)
{
int status;
@ -1662,7 +1618,7 @@ out:
enum nfsstat4 pnfs_rpc_layoutget(
IN nfs41_session *session,
IN nfs41_path_fh *file,
IN stateid4 *state,
IN stateid_arg *stateid,
IN enum pnfs_iomode iomode,
IN uint64_t offset,
IN uint64_t length,
@ -1697,7 +1653,7 @@ enum nfsstat4 pnfs_rpc_layoutget(
layoutget_args.iomode = iomode;
layoutget_args.offset = offset;
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_res.u.res_ok.layout = layout;

View file

@ -244,6 +244,22 @@ typedef struct __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 */
enum {
ACCESS4_READ = 0x00000001,
@ -269,13 +285,11 @@ typedef struct __nfs41_access_res {
/* OP_CLOSE */
typedef struct __nfs41_op_close_args {
// uint32_t seqid; // not used, always 0
stateid4 *open_stateid; /* -> nfs41_op_open_res_ok.stateid */
stateid_arg *stateid;
} nfs41_op_close_args;
typedef struct __nfs41_op_close_res {
uint32_t status;
/* case NFS4_OK: */
stateid4 open_stateid;
} nfs41_op_close_res;
@ -360,13 +374,13 @@ enum {
typedef struct __open_to_lock_owner4 {
uint32_t open_seqid;
stateid4 *open_stateid;
stateid_arg *open_stateid;
uint32_t lock_seqid;
state_owner4 *lock_owner;
} open_to_lock_owner4;
typedef struct __exist_lock_owner4 {
stateid4 *lock_stateid;
stateid_arg *lock_stateid;
uint32_t lock_seqid;
} exist_lock_owner4;
@ -431,7 +445,7 @@ typedef struct __nfs41_lockt_res {
typedef struct __nfs41_locku_args {
uint32_t locktype;
uint32_t seqid;
stateid4 *lock_stateid;
stateid_arg *lock_stateid;
uint64_t offset;
uint64_t length;
} nfs41_locku_args;
@ -628,7 +642,7 @@ typedef struct __nfs41_op_open_res {
/* OP_READ */
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;
uint32_t count;
} nfs41_read_args;
@ -726,7 +740,7 @@ enum time_how4 {
};
typedef struct __nfs41_setattr_args {
stateid4 *stateid;
stateid_arg *stateid;
nfs41_file_info *info;
} nfs41_setattr_args;
@ -750,7 +764,7 @@ typedef struct __nfs41_write_verf {
} nfs41_write_verf;
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;
uint32_t stable; /* stable_how4 */
uint32_t data_len;
@ -777,7 +791,7 @@ typedef struct __pnfs_layoutget_args {
uint64_t offset;
uint64_t length;
uint64_t minlength;
stateid4 *stateid;
stateid_arg *stateid;
uint32_t maxcount;
} pnfs_layoutget_args;
@ -923,12 +937,13 @@ int nfs41_create(
int nfs41_close(
IN nfs41_session *session,
IN nfs41_open_state *state);
IN nfs41_path_fh *file,
IN stateid_arg *stateid);
int nfs41_write(
IN nfs41_session *session,
IN nfs41_path_fh *file,
IN stateid4 *stateid,
IN stateid_arg *stateid,
IN unsigned char *data,
IN uint32_t data_len,
IN uint64_t offset,
@ -939,7 +954,7 @@ int nfs41_write(
int nfs41_read(
IN nfs41_session *session,
IN nfs41_path_fh *file,
IN stateid4 *stateid,
IN stateid_arg *stateid,
IN uint64_t offset,
IN uint32_t count,
OUT unsigned char *data_out,
@ -955,26 +970,19 @@ int nfs41_commit(
int nfs41_lock(
IN nfs41_session *session,
IN nfs41_open_state *open_state,
IN stateid4 *lock_state OPTIONAL,
IN nfs41_path_fh *file,
IN state_owner4 *owner,
IN uint32_t type,
IN uint64_t offset,
IN uint64_t length,
OUT stateid4 *stateid_out);
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);
IN OUT stateid_arg *stateid);
int nfs41_unlock(
IN nfs41_session *session,
IN nfs41_open_state *open_state,
IN OUT stateid4 *lock_state,
IN nfs41_path_fh *file,
IN uint64_t offset,
IN uint64_t length);
IN uint64_t length,
IN OUT stateid_arg *stateid);
stateid4* nfs41_lock_stateid_copy(
IN nfs41_lock_state *lock_state,
@ -1019,7 +1027,7 @@ int nfs41_rename(
int nfs41_setattr(
IN nfs41_session *session,
IN nfs41_path_fh *file,
IN stateid4 *stateid,
IN stateid_arg *stateid,
IN nfs41_file_info *info);
int nfs41_link(
@ -1070,7 +1078,7 @@ enum nfsstat4 nfs41_fs_locations(
enum nfsstat4 pnfs_rpc_layoutget(
IN nfs41_session *session,
IN nfs41_path_fh *file,
IN stateid4 *state,
IN stateid_arg *stateid,
IN enum pnfs_iomode iomode,
IN uint64_t offset,
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
return FALSE;
return xdr_stateid4(xdr, args->open_stateid);
return xdr_stateid4(xdr, &args->stateid->stateid);
}
static bool_t decode_op_close(
XDR *xdr,
nfs_resop4 *resop)
{
stateid4 ignored;
nfs41_op_close_res *res = (nfs41_op_close_res*)resop->res;
if (unexpected_op(resop->op, OP_CLOSE))
@ -1117,7 +1118,7 @@ static bool_t decode_op_close(
return FALSE;
if (res->status == NFS4_OK)
return xdr_stateid4(xdr, &res->open_stateid);
return xdr_stateid4(xdr, &ignored);
return TRUE;
}
@ -1315,7 +1316,7 @@ static bool_t xdr_locker4(
if (!xdr_u_int32_t(xdr, &locker->u.open_owner.open_seqid))
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;
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);
} else {
/* 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 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))
return FALSE;
if (!xdr_stateid4(xdr, args->lock_stateid))
if (!xdr_stateid4(xdr, &args->lock_stateid->stateid))
return FALSE;
if (!xdr_u_hyper(xdr, &args->offset))
@ -1974,7 +1975,7 @@ static bool_t encode_op_read(
if (unexpected_op(argop->op, OP_READ))
return FALSE;
if (!xdr_stateid4(xdr, args->stateid))
if (!xdr_stateid4(xdr, &args->stateid->stateid))
return FALSE;
if (!xdr_u_hyper(xdr, &args->offset))
@ -2409,7 +2410,7 @@ static bool_t encode_op_setattr(
if (unexpected_op(argop->op, OP_SETATTR))
return FALSE;
if (!xdr_stateid4(xdr, args->stateid))
if (!xdr_stateid4(xdr, &args->stateid->stateid))
return FALSE;
/* 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))
return FALSE;
if (!xdr_stateid4(xdr, args->stateid))
if (!xdr_stateid4(xdr, &args->stateid->stateid))
return FALSE;
if (!xdr_u_hyper(xdr, &args->offset))
@ -2811,7 +2812,7 @@ static bool_t encode_op_layoutget(
if (!xdr_u_hyper(xdr, &args->minlength))
return FALSE;
if (!xdr_stateid4(xdr, args->stateid))
if (!xdr_stateid4(xdr, &args->stateid->stateid))
return FALSE;
return xdr_u_int32_t(xdr, &args->maxcount);

View file

@ -94,6 +94,17 @@ void nfs41_open_state_deref(
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 */
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 */
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)
dprintf(1, "cancel_open: nfs41_close() failed with %s\n",
nfs_error_string(status));
@ -569,7 +583,10 @@ static int handle_close(nfs41_upcall *upcall)
}
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) {
dprintf(1, "nfs41_close() failed with error %s.\n",
nfs_error_string(status));

View file

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

View file

@ -281,7 +281,7 @@ static enum pnfs_status get_sparse_fh(
} else if (filehandle_count == 1) {
*file_out = &layout->filehandles.arr[0];
} else if (filehandle_count == 0) {
*file_out = pattern->meta_file;
*file_out = &pattern->state->file;
} else {
eprintf("invalid sparse layout! has %u file handles "
"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(
IN pnfs_io_pattern *pattern,
IN nfs41_root *root,
IN nfs41_path_fh *meta_file,
IN stateid4 *stateid,
IN nfs41_open_state *state,
IN pnfs_file_layout *layout,
IN unsigned char *buffer,
IN uint64_t offset,
@ -76,12 +75,7 @@ static enum pnfs_status pattern_init(
}
pattern->root = root;
pattern->meta_file = meta_file;
/* 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->state = state;
pattern->layout = layout;
pattern->buffer = buffer;
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)
{
pnfs_io_unit io;
stateid_arg stateid;
pnfs_io_thread *thread = (pnfs_io_thread*)args;
pnfs_io_pattern *pattern = thread->pattern;
stateid4 *state = &pattern->stateid;
pnfs_data_server *server;
nfs41_client *client;
uint32_t maxreadsize, bytes_read, total_read;
@ -329,13 +323,16 @@ static uint32_t WINAPI file_layout_read_thread(void *args)
goto out;
}
nfs41_lock_stateid_arg(pattern->state, &stateid);
stateid.stateid.seqid = 0;
total_read = 0;
while ((status = thread_next_unit(thread, &io)) == PNFS_PENDING) {
maxreadsize = max_read_size(client->session, &io.file->fh);
if (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);
if (nfsstat) {
eprintf("nfs41_read() failed with %s\n",
@ -363,10 +360,10 @@ out:
static uint32_t WINAPI file_layout_write_thread(void *args)
{
pnfs_io_unit io;
stateid_arg stateid;
nfs41_write_verf verf;
pnfs_io_thread *thread = (pnfs_io_thread*)args;
pnfs_io_pattern *pattern = thread->pattern;
stateid4 *state = &pattern->stateid;
pnfs_data_server *server;
pnfs_file_layout *layout = pattern->layout;
nfs41_client *client;
@ -395,6 +392,9 @@ static uint32_t WINAPI file_layout_write_thread(void *args)
goto out;
}
nfs41_lock_stateid_arg(pattern->state, &stateid);
stateid.stateid.seqid = 0;
retry_write:
thread->offset = offset_start;
thread->stable = DATA_SYNC4;
@ -406,7 +406,7 @@ retry_write:
if (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);
if (nfsstat) {
eprintf("nfs41_write() failed with %s\n",
@ -460,8 +460,7 @@ out:
enum pnfs_status pnfs_read(
IN nfs41_root *root,
IN nfs41_session *session,
IN nfs41_path_fh *file,
IN stateid4 *stateid,
IN nfs41_open_state *state,
IN pnfs_file_layout *layout,
IN uint64_t offset,
IN uint64_t length,
@ -475,8 +474,8 @@ enum pnfs_status pnfs_read(
*len_out = 0;
status = pattern_init(&pattern, root, file, stateid,
layout, buffer_out, offset, length, session->lease_time);
status = pattern_init(&pattern, root, state, layout,
buffer_out, offset, length, session->lease_time);
if (status) {
eprintf("pattern_init() failed with %s\n",
pnfs_error_string(status));
@ -500,8 +499,7 @@ out:
enum pnfs_status pnfs_write(
IN nfs41_root *root,
IN nfs41_session *session,
IN nfs41_path_fh *file,
IN stateid4 *stateid,
IN nfs41_open_state *state,
IN pnfs_file_layout *layout,
IN uint64_t offset,
IN uint64_t length,
@ -518,8 +516,8 @@ enum pnfs_status pnfs_write(
*len_out = 0;
status = pattern_init(&pattern, root, file, stateid,
layout, buffer, offset, length, session->lease_time);
status = pattern_init(&pattern, root, state, layout,
buffer, offset, length, session->lease_time);
if (status) {
eprintf("pattern_init() failed with %s\n",
pnfs_error_string(status));
@ -541,7 +539,7 @@ enum pnfs_status pnfs_write(
* after LAYOUTCOMMIT */
dprintf(1, "sending COMMIT to meta server for offset=%d and len=%d\n",
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) {
dprintf(IOLVL, "nfs41_commit() failed with %s\n",
nfs_error_string(nfsstat));
@ -553,7 +551,7 @@ enum pnfs_status pnfs_write(
/* send LAYOUTCOMMIT */
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,
&new_last_offset, NULL);
if (nfsstat) {

View file

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

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;

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