- diff --git a/daemon/nfs41_ops.c b/daemon/nfs41_ops.c
 - index a4e059d..bdd754d 100644
 - --- a/daemon/nfs41_ops.c
 - +++ b/daemon/nfs41_ops.c
 - @@ -908,6 +908,74 @@ out:
 - return status;
 - }
 - +#if 1
 - +int nfs42_read_plus(
 - + IN nfs41_session *session,
 - + IN nfs41_path_fh *file,
 - + IN stateid_arg *stateid,
 - + IN uint64_t offset,
 - + IN uint32_t count,
 - + OUT unsigned char *data_out,
 - + OUT uint32_t *data_len_out,
 - + OUT bool_t *eof_out)
 - +{
 - + int status;
 - + nfs41_compound compound;
 - + nfs_argop4 argops[4];
 - + nfs_resop4 resops[4];
 - + nfs41_sequence_args sequence_args;
 - + nfs41_sequence_res sequence_res;
 - + nfs41_putfh_args putfh_args;
 - + nfs41_putfh_res putfh_res;
 - + nfs42_read_plus_args read_plus_args;
 - + nfs42_read_plus_res read_plus_res;
 - +
 - +#if 1 /* debug */
 - + (void)memset(&read_plus_args, 0, sizeof(read_plus_args));
 - + (void)memset(&read_plus_res, 0, sizeof(read_plus_res));
 - +#endif
 - +
 - + compound_init(&compound, session->client->root->nfsminorvers,
 - + argops, resops,
 - + stateid->stateid.seqid == 0 ? "ds read_plus" : "read_plus");
 - +
 - + compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
 - + nfs41_session_sequence(&sequence_args, session, 0);
 - +
 - + compound_add_op(&compound, OP_PUTFH, &putfh_args, &putfh_res);
 - + putfh_args.file = file;
 - + putfh_args.in_recovery = 0;
 - +
 - + compound_add_op(&compound, OP_READ_PLUS, &read_plus_args, &read_plus_res);
 - + read_plus_args.stateid = stateid;
 - + read_plus_args.offset = offset;
 - + read_plus_args.count = count;
 - + read_plus_res.resok4.data_len = count;
 - + read_plus_res.resok4.data = data_out;
 - +
 - + status = compound_encode_send_decode(session, &compound, TRUE);
 - + if (status)
 - + goto out;
 - +
 - + if (compound_error(status = compound.res.status))
 - + goto out;
 - +
 - + *data_len_out = read_plus_res.resok4.data_len;
 - + *eof_out = read_plus_res.resok4.eof;
 - +
 - + /* we shouldn't ever see this, but a buggy server could
 - + * send us into an infinite loop. return NFS4ERR_IO */
 - + if (!read_plus_res.resok4.data_len && !read_plus_res.resok4.eof) {
 - + status = NFS4ERR_IO;
 - + eprintf("READ_PLUS succeeded with len=0 and eof=0; returning '%s'\n",
 - + nfs_error_string(status));
 - + }
 - +out:
 - + return status;
 - +}
 - +#endif
 - +
 - +
 - int nfs41_commit(
 - IN nfs41_session *session,
 - IN nfs41_path_fh *file,
 - diff --git a/daemon/nfs41_ops.h b/daemon/nfs41_ops.h
 - index 8dc1d7d..b581cd8 100644
 - --- a/daemon/nfs41_ops.h
 - +++ b/daemon/nfs41_ops.h
 - @@ -726,6 +726,57 @@ typedef struct __nfs41_read_res {
 - nfs41_read_res_ok resok4;
 - } nfs41_read_res;
 - +#if 1
 - +typedef struct __data4 {
 - + uint64_t offset;
 - + uint32_t count;
 - + uint32_t data_len;
 - + unsigned char *data;
 - +} data4;
 - +
 - +typedef struct __data_info4 {
 - + uint64_t offset;
 - + uint64_t length;
 - +} data_info4;
 - +
 - +typedef enum __data_content4 {
 - + NFS4_CONTENT_DATA = 0,
 - + NFS4_CONTENT_HOLE = 1
 - +} data_content4;
 - +
 - +/* OP_READ_PLUS */
 - +typedef struct __nfs42_read_plus_args {
 - + stateid_arg *stateid; /* -> nfs41_op_open_res_ok.stateid */
 - + uint64_t offset;
 - + uint32_t count;
 - +} nfs42_read_plus_args;
 - +
 - +typedef union __nfs42_read_plus_content {
 - + /* switch (data_content4 rpc_content) */
 - + data_content4 content;
 - + /* case NFS4_CONTENT_DATA: */
 - + data4 data;
 - + /* case NFS4_CONTENT_HOLE: */
 - + data_info4 hole;
 - + /* default: */
 - +} nfs42_read_plus_content;
 - +
 - +typedef struct __nfs42_read_plus_res_ok {
 - + bool_t eof;
 - + uint32_t count;
 - + nfs42_read_plus_content *contents;
 - +
 - + unsigned char *data; /* caller-allocated */
 - + uint32_t data_len;
 - +} nfs42_read_plus_res_ok;
 - +
 - +typedef struct __nfs42_read_plus_res {
 - + uint32_t status;
 - + /* case NFS4_OK: */
 - + nfs42_read_plus_res_ok resok4;
 - +} nfs42_read_plus_res;
 - +
 - +#endif
 - /* OP_READDIR */
 - typedef struct __nfs41_readdir_args {
 - @@ -1112,6 +1163,18 @@ int nfs41_read(
 - OUT uint32_t *data_len_out,
 - OUT bool_t *eof_out);
 - +#if 1
 - +int nfs42_read_plus(
 - + IN nfs41_session *session,
 - + IN nfs41_path_fh *file,
 - + IN stateid_arg *stateid,
 - + IN uint64_t offset,
 - + IN uint32_t count,
 - + OUT unsigned char *data_out,
 - + OUT uint32_t *data_len_out,
 - + OUT bool_t *eof_out);
 - +#endif
 - +
 - int nfs41_commit(
 - IN nfs41_session *session,
 - IN nfs41_path_fh *file,
 - diff --git a/daemon/nfs41_xdr.c b/daemon/nfs41_xdr.c
 - index f899b7b..1653a9b 100644
 - --- a/daemon/nfs41_xdr.c
 - +++ b/daemon/nfs41_xdr.c
 - @@ -2287,6 +2287,165 @@ static bool_t decode_op_read(
 - return TRUE;
 - }
 - +#if 1
 - +/*
 - + * OP_READ_PLUS
 - + */
 - +static bool_t encode_op_read_plus(
 - + XDR *xdr,
 - + nfs_argop4 *argop)
 - +{
 - + nfs42_read_plus_args *args = (nfs42_read_plus_args *)argop->arg;
 - +
 - + if (unexpected_op(argop->op, OP_READ_PLUS))
 - + return FALSE;
 - +
 - + if (!xdr_stateid4(xdr, &args->stateid->stateid))
 - + return FALSE;
 - +
 - + if (!xdr_u_hyper(xdr, &args->offset))
 - + return FALSE;
 - +
 - + return xdr_u_int32_t(xdr, &args->count);
 - +}
 - +
 - +static bool_t decode_read_plus_res_ok(
 - + XDR *xdr,
 - + nfs42_read_plus_res_ok *res)
 - +{
 - + unsigned char *data = res->data;
 - +
 - +// DPRINTF(0, ("decode_read_plus_res_ok: start\n"));
 - +
 - + if (!xdr_bool(xdr, &res->eof)) {
 - + DPRINTF(0, ("decode eof failed\n"));
 - + return FALSE;
 - + }
 - +
 - +// DPRINTF(0, ("decode_read_plus_res_ok: #mark1, res->eof=%d\n", (int)res->eof));
 - +
 - + if (!xdr_u_int32_t(xdr, &res->count)) {
 - + DPRINTF(0, ("decode count failed\n"));
 - + return FALSE;
 - + }
 - +
 - + /*
 - + * Note that |res->count==0| is a valid value for "READ_PLUS"
 - + * replies
 - + */
 - + if (res->count == 0) {
 - + res->contents = NULL;
 - + res->data_len = 0L;
 - + return TRUE;
 - + }
 - +
 - +// DPRINTF(0, ("decode_read_plus_res_ok: #mark2, res->count=%d\n", (int)res->count));
 - +
 - + /* fixme: Use |malloc()|. Be careful to handle the |res->count == 0| case */
 - + res->contents = calloc(res->count, sizeof(nfs42_read_plus_content));
 - + if (res->contents == NULL)
 - + return FALSE;
 - +
 - +// DPRINTF(0, ("decode_read_plus_res_ok: #mark3\n"));
 - +
 - + uint32_t i, co;
 - +
 - + for (i = 0 ; i < res->count ; i++) {
 - + if (!xdr_u_int32_t(xdr, &co)) {
 - + DPRINTF(0, ("i=%d, decode co failed\n", (int)i));
 - + return FALSE;
 - + }
 - + res->contents[i].content = co;
 - +
 - + switch(co) {
 - + case NFS4_CONTENT_DATA:
 - +// DPRINTF(0, ("i=%d, 'NFS4_CONTENT_DATA' content\n", (int)i));
 - + if (!xdr_u_hyper(xdr, &res->contents[i].data.offset)) {
 - + DPRINTF(0, ("i=%d, decoding 'offset' failed\n", (int)i));
 - + return FALSE;
 - + }
 - +#if 0
 - + DPRINTF(0, ("decode_read_plus_res_ok: data decoded offset=%lld\n",
 - + (long long)res->contents[i].data.data_len));
 - +
 - + res->contents[i].data.data = data;
 - + u_int readsize = 0;
 - +
 - + if (!xdr_bytes(xdr, (char **)&(res->contents[i].data.data), &readsize, NFS41_MAX_FILEIO_SIZE)) {
 - + DPRINTF(0, ("i=%d, decoding 'bytes' failed\n", (int)i));
 - + return FALSE;
 - + }
 - + res->contents[i].data.count = res->contents[i].data.data_len = readsize;
 - + data += res->contents[i].data.count;
 - +#else
 - + if (!xdr_u_int32_t(xdr, &res->contents[i].data.count)) {
 - + DPRINTF(0, ("i=%d, decoding 'count' failed\n", (int)i));
 - + return FALSE;
 - + }
 - +
 - +// DPRINTF(0, ("decode_read_plus_res_ok: data decoded offset=%lld, count=%ld\n",
 - +// (long long)res->contents[i].data.data_len,
 - +// (long)res->contents[i].data.count));
 - +
 - + res->contents[i].data.data = data;
 - + res->contents[i].data.data_len = res->contents[i].data.count;
 - + if (!xdr_opaque(xdr, (char *)res->contents[i].data.data, res->contents[i].data.data_len)) {
 - + DPRINTF(0, ("i=%d, decoding 'bytes' failed\n", (int)i));
 - + return FALSE;
 - + }
 - + data += res->contents[i].data.count;
 - +#endif
 - + break;
 - + case NFS4_CONTENT_HOLE:
 - + DPRINTF(0, ("i=%d, 'NFS4_CONTENT_HOLE' content\n", (int)i));
 - + if (!xdr_u_hyper(xdr, &res->contents[i].hole.offset))
 - + return FALSE;
 - + if (!xdr_u_hyper(xdr, &res->contents[i].hole.length))
 - + return FALSE;
 - +
 - + /*
 - + * fixme: READ_PLUS is required to return the whole hole,
 - + * even if it is bigger than the requested size
 - + */
 - + EASSERT(((data+res->contents[i].hole.length)-res->data) < res->data_len);
 - + (void)memset(data, 0, res->contents[i].hole.length);
 - + data += res->contents[i].hole.length;
 - + default:
 - + DPRINTF(0, ("decode_read_plus_res_ok: unknown co=%d\n", (int)co));
 - + return FALSE;
 - + }
 - +
 - + EASSERT((data - res->data) <= res->data_len);
 - + }
 - +
 - + EASSERT((data - res->data) < UINT_MAX);
 - + res->data_len = (uint32_t)(data - res->data);
 - +
 - +// DPRINTF(0, ("decode_read_plus_res_ok: SUCCESS\n"));
 - + return TRUE;
 - +}
 - +
 - +static bool_t decode_op_read_plus(
 - + XDR *xdr,
 - + nfs_resop4 *resop)
 - +{
 - + nfs42_read_plus_res *res = (nfs42_read_plus_res *)resop->res;
 - +
 - + if (unexpected_op(resop->op, OP_READ_PLUS))
 - + return FALSE;
 - +
 - + if (!xdr_u_int32_t(xdr, &res->status))
 - + return FALSE;
 - +
 - + if (res->status == NFS4_OK)
 - + return decode_read_plus_res_ok(xdr, &res->resok4);
 - +
 - + return TRUE;
 - +}
 - +
 - +#endif
 - +
 - +
 - /*
 - * OP_READDIR
 - @@ -3638,7 +3797,7 @@ static const op_table_entry g_op_table[] = {
 - { NULL, NULL }, /* OP_LAYOUTSTATS = 65, */
 - { NULL, NULL }, /* OP_OFFLOAD_CANCEL = 66, */
 - { NULL, NULL }, /* OP_OFFLOAD_STATUS = 67, */
 - - { NULL, NULL }, /* OP_READ_PLUS = 68, */
 - + { encode_op_read_plus, decode_op_read_plus }, /* OP_READ_PLUS = 68, */
 - { NULL, NULL }, /* OP_SEEK = 69, */
 - { NULL, NULL }, /* OP_WRITE_SAME = 70, */
 - { NULL, NULL }, /* OP_CLONE = 71, */
 - diff --git a/daemon/readwrite.c b/daemon/readwrite.c
 - index 355336a..402db22 100644
 - --- a/daemon/readwrite.c
 - +++ b/daemon/readwrite.c
 - @@ -77,8 +77,13 @@ static int read_from_mds(
 - while(to_rcv > 0) {
 - uint32_t bytes_read = 0, chunk = min(to_rcv, maxreadsize);
 - +#if 1
 - + status = nfs42_read_plus(session, file, stateid, args->offset + reloffset, chunk,
 - + p, &bytes_read, &eof);
 - +#else
 - status = nfs41_read(session, file, stateid, args->offset + reloffset, chunk,
 - p, &bytes_read, &eof);
 - +#endif
 - if (status == NFS4ERR_OPENMODE && !len) {
 - stateid->type = STATEID_SPECIAL;
 - stateid4_cpy(&stateid->stateid, &special_read_stateid);
 - diff --git a/daemon/recovery.c b/daemon/recovery.c
 - index eee4031..1cb23ea 100644
 - --- a/daemon/recovery.c
 - +++ b/daemon/recovery.c
 - @@ -805,6 +805,11 @@ bool_t nfs41_recover_stateid(
 - } else if (argop->op == OP_READ) {
 - nfs41_read_args *read = (nfs41_read_args*)argop->arg;
 - stateid = read->stateid;
 - +#if 1
 - + } else if (argop->op == OP_READ_PLUS) {
 - + nfs42_read_plus_args *read_plus = (nfs42_read_plus_args *)argop->arg;
 - + stateid = read_plus->stateid;
 - +#endif
 - } else if (argop->op == OP_WRITE) {
 - nfs41_write_args *write = (nfs41_write_args*)argop->arg;
 - stateid = write->stateid;
 
ms-nfs42-client READ_PLUS prototype
Posted by Anonymous on Thu 23rd Jan 2025 16:52
raw | new post
modification of post by Anonymous (view diff)
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.
 nrubsig.kpaste.net RSS