pastebin - collaborative debugging tool
nrubsig.kpaste.net RSS


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)

  1. diff --git a/daemon/nfs41_ops.c b/daemon/nfs41_ops.c
  2. index a4e059d..bdd754d 100644
  3. --- a/daemon/nfs41_ops.c
  4. +++ b/daemon/nfs41_ops.c
  5. @@ -908,6 +908,74 @@ out:
  6.      return status;
  7.  }
  8.  
  9. +#if 1
  10. +int nfs42_read_plus(
  11. +    IN nfs41_session *session,
  12. +    IN nfs41_path_fh *file,
  13. +    IN stateid_arg *stateid,
  14. +    IN uint64_t offset,
  15. +    IN uint32_t count,
  16. +    OUT unsigned char *data_out,
  17. +    OUT uint32_t *data_len_out,
  18. +    OUT bool_t *eof_out)
  19. +{
  20. +    int status;
  21. +    nfs41_compound compound;
  22. +    nfs_argop4 argops[4];
  23. +    nfs_resop4 resops[4];
  24. +    nfs41_sequence_args sequence_args;
  25. +    nfs41_sequence_res sequence_res;
  26. +    nfs41_putfh_args putfh_args;
  27. +    nfs41_putfh_res putfh_res;
  28. +    nfs42_read_plus_args read_plus_args;
  29. +    nfs42_read_plus_res read_plus_res;
  30. +
  31. +#if 1 /* debug */
  32. +    (void)memset(&read_plus_args, 0, sizeof(read_plus_args));
  33. +    (void)memset(&read_plus_res, 0, sizeof(read_plus_res));
  34. +#endif
  35. +
  36. +    compound_init(&compound, session->client->root->nfsminorvers,
  37. +        argops, resops,
  38. +        stateid->stateid.seqid == 0 ? "ds read_plus" : "read_plus");
  39. +
  40. +    compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  41. +    nfs41_session_sequence(&sequence_args, session, 0);
  42. +
  43. +    compound_add_op(&compound, OP_PUTFH, &putfh_args, &putfh_res);
  44. +    putfh_args.file = file;
  45. +    putfh_args.in_recovery = 0;
  46. +
  47. +    compound_add_op(&compound, OP_READ_PLUS, &read_plus_args, &read_plus_res);
  48. +    read_plus_args.stateid = stateid;
  49. +    read_plus_args.offset = offset;
  50. +    read_plus_args.count = count;
  51. +    read_plus_res.resok4.data_len = count;
  52. +    read_plus_res.resok4.data = data_out;
  53. +
  54. +    status = compound_encode_send_decode(session, &compound, TRUE);
  55. +    if (status)
  56. +        goto out;
  57. +
  58. +    if (compound_error(status = compound.res.status))
  59. +        goto out;
  60. +
  61. +    *data_len_out = read_plus_res.resok4.data_len;
  62. +    *eof_out = read_plus_res.resok4.eof;
  63. +
  64. +    /* we shouldn't ever see this, but a buggy server could
  65. +     * send us into an infinite loop. return NFS4ERR_IO */
  66. +    if (!read_plus_res.resok4.data_len && !read_plus_res.resok4.eof) {
  67. +        status = NFS4ERR_IO;
  68. +        eprintf("READ_PLUS succeeded with len=0 and eof=0; returning '%s'\n",
  69. +            nfs_error_string(status));
  70. +    }
  71. +out:
  72. +    return status;
  73. +}
  74. +#endif
  75. +
  76. +
  77.  int nfs41_commit(
  78.      IN nfs41_session *session,
  79.      IN nfs41_path_fh *file,
  80. diff --git a/daemon/nfs41_ops.h b/daemon/nfs41_ops.h
  81. index 8dc1d7d..b581cd8 100644
  82. --- a/daemon/nfs41_ops.h
  83. +++ b/daemon/nfs41_ops.h
  84. @@ -726,6 +726,57 @@ typedef struct __nfs41_read_res {
  85.      nfs41_read_res_ok       resok4;
  86.  } nfs41_read_res;
  87.  
  88. +#if 1
  89. +typedef struct __data4 {
  90. +    uint64_t        offset;
  91. +    uint32_t        count;
  92. +    uint32_t        data_len;
  93. +    unsigned char   *data;
  94. +} data4;
  95. +
  96. +typedef struct __data_info4 {
  97. +    uint64_t offset;
  98. +    uint64_t length;
  99. +} data_info4;
  100. +
  101. +typedef enum __data_content4 {
  102. +    NFS4_CONTENT_DATA = 0,
  103. +    NFS4_CONTENT_HOLE = 1
  104. +} data_content4;
  105. +
  106. +/* OP_READ_PLUS */
  107. +typedef struct __nfs42_read_plus_args {
  108. +    stateid_arg     *stateid; /* -> nfs41_op_open_res_ok.stateid */
  109. +    uint64_t        offset;
  110. +    uint32_t        count;
  111. +} nfs42_read_plus_args;
  112. +
  113. +typedef union __nfs42_read_plus_content {
  114. +    /* switch (data_content4 rpc_content) */
  115. +    data_content4   content;
  116. +    /* case NFS4_CONTENT_DATA: */
  117. +    data4           data;
  118. +    /* case NFS4_CONTENT_HOLE: */
  119. +    data_info4      hole;
  120. +    /* default: */
  121. +} nfs42_read_plus_content;
  122. +
  123. +typedef struct __nfs42_read_plus_res_ok {
  124. +    bool_t                  eof;
  125. +    uint32_t                count;
  126. +    nfs42_read_plus_content *contents;
  127. +
  128. +    unsigned char           *data; /* caller-allocated */
  129. +    uint32_t                data_len;
  130. +} nfs42_read_plus_res_ok;
  131. +
  132. +typedef struct __nfs42_read_plus_res {
  133. +    uint32_t                status;
  134. +    /* case NFS4_OK: */
  135. +    nfs42_read_plus_res_ok  resok4;
  136. +} nfs42_read_plus_res;
  137. +
  138. +#endif
  139.  
  140.  /* OP_READDIR */
  141.  typedef struct __nfs41_readdir_args {
  142. @@ -1112,6 +1163,18 @@ int nfs41_read(
  143.      OUT uint32_t *data_len_out,
  144.      OUT bool_t *eof_out);
  145.  
  146. +#if 1
  147. +int nfs42_read_plus(
  148. +    IN nfs41_session *session,
  149. +    IN nfs41_path_fh *file,
  150. +    IN stateid_arg *stateid,
  151. +    IN uint64_t offset,
  152. +    IN uint32_t count,
  153. +    OUT unsigned char *data_out,
  154. +    OUT uint32_t *data_len_out,
  155. +    OUT bool_t *eof_out);
  156. +#endif
  157. +
  158.  int nfs41_commit(
  159.      IN nfs41_session *session,
  160.      IN nfs41_path_fh *file,
  161. diff --git a/daemon/nfs41_xdr.c b/daemon/nfs41_xdr.c
  162. index f899b7b..1653a9b 100644
  163. --- a/daemon/nfs41_xdr.c
  164. +++ b/daemon/nfs41_xdr.c
  165. @@ -2287,6 +2287,165 @@ static bool_t decode_op_read(
  166.      return TRUE;
  167.  }
  168.  
  169. +#if 1
  170. +/*
  171. + * OP_READ_PLUS
  172. + */
  173. +static bool_t encode_op_read_plus(
  174. +    XDR *xdr,
  175. +    nfs_argop4 *argop)
  176. +{
  177. +    nfs42_read_plus_args *args = (nfs42_read_plus_args *)argop->arg;
  178. +
  179. +    if (unexpected_op(argop->op, OP_READ_PLUS))
  180. +        return FALSE;
  181. +
  182. +    if (!xdr_stateid4(xdr, &args->stateid->stateid))
  183. +        return FALSE;
  184. +
  185. +    if (!xdr_u_hyper(xdr, &args->offset))
  186. +        return FALSE;
  187. +
  188. +    return xdr_u_int32_t(xdr, &args->count);
  189. +}
  190. +
  191. +static bool_t decode_read_plus_res_ok(
  192. +    XDR *xdr,
  193. +    nfs42_read_plus_res_ok *res)
  194. +{
  195. +    unsigned char *data = res->data;
  196. +
  197. +//    DPRINTF(0, ("decode_read_plus_res_ok: start\n"));
  198. +
  199. +    if (!xdr_bool(xdr, &res->eof)) {
  200. +        DPRINTF(0, ("decode eof failed\n"));
  201. +        return FALSE;
  202. +    }
  203. +
  204. +//    DPRINTF(0, ("decode_read_plus_res_ok: #mark1, res->eof=%d\n", (int)res->eof));
  205. +
  206. +    if (!xdr_u_int32_t(xdr, &res->count)) {
  207. +        DPRINTF(0, ("decode count failed\n"));
  208. +        return FALSE;
  209. +    }
  210. +
  211. +    /*
  212. +     * Note that |res->count==0| is a valid value for "READ_PLUS"
  213. +     * replies
  214. +     */
  215. +    if (res->count == 0) {
  216. +        res->contents = NULL;
  217. +        res->data_len = 0L;
  218. +        return TRUE;
  219. +    }
  220. +
  221. +//    DPRINTF(0, ("decode_read_plus_res_ok: #mark2, res->count=%d\n", (int)res->count));
  222. +
  223. +    /* fixme: Use |malloc()|. Be careful to handle the |res->count == 0| case */
  224. +    res->contents = calloc(res->count, sizeof(nfs42_read_plus_content));
  225. +    if (res->contents == NULL)
  226. +        return FALSE;
  227. +
  228. +//    DPRINTF(0, ("decode_read_plus_res_ok: #mark3\n"));
  229. +
  230. +    uint32_t i, co;
  231. +
  232. +    for (i = 0 ; i < res->count ; i++) {
  233. +        if (!xdr_u_int32_t(xdr, &co)) {
  234. +            DPRINTF(0, ("i=%d, decode co failed\n", (int)i));
  235. +            return FALSE;
  236. +        }
  237. +        res->contents[i].content = co;
  238. +
  239. +        switch(co) {
  240. +            case NFS4_CONTENT_DATA:
  241. +//                DPRINTF(0, ("i=%d, 'NFS4_CONTENT_DATA' content\n", (int)i));
  242. +                if (!xdr_u_hyper(xdr, &res->contents[i].data.offset)) {
  243. +                    DPRINTF(0, ("i=%d, decoding 'offset' failed\n", (int)i));
  244. +                    return FALSE;
  245. +                }
  246. +#if 0
  247. +                DPRINTF(0, ("decode_read_plus_res_ok: data decoded offset=%lld\n",
  248. +                    (long long)res->contents[i].data.data_len));
  249. +
  250. +                res->contents[i].data.data = data;
  251. +                u_int readsize = 0;
  252. +
  253. +                if (!xdr_bytes(xdr, (char **)&(res->contents[i].data.data), &readsize, NFS41_MAX_FILEIO_SIZE)) {
  254. +                    DPRINTF(0, ("i=%d, decoding 'bytes' failed\n", (int)i));
  255. +                    return FALSE;
  256. +                }
  257. +                res->contents[i].data.count = res->contents[i].data.data_len = readsize;
  258. +                data += res->contents[i].data.count;
  259. +#else
  260. +                if (!xdr_u_int32_t(xdr, &res->contents[i].data.count)) {
  261. +                    DPRINTF(0, ("i=%d, decoding 'count' failed\n", (int)i));
  262. +                    return FALSE;
  263. +                }
  264. +
  265. +//                DPRINTF(0, ("decode_read_plus_res_ok: data decoded offset=%lld, count=%ld\n",
  266. +//                    (long long)res->contents[i].data.data_len,
  267. +//                    (long)res->contents[i].data.count));
  268. +
  269. +                res->contents[i].data.data = data;
  270. +                res->contents[i].data.data_len = res->contents[i].data.count;
  271. +                if (!xdr_opaque(xdr, (char *)res->contents[i].data.data, res->contents[i].data.data_len)) {
  272. +                    DPRINTF(0, ("i=%d, decoding 'bytes' failed\n", (int)i));
  273. +                    return FALSE;
  274. +                }
  275. +                data += res->contents[i].data.count;
  276. +#endif
  277. +                break;
  278. +            case NFS4_CONTENT_HOLE:
  279. +                DPRINTF(0, ("i=%d, 'NFS4_CONTENT_HOLE' content\n", (int)i));
  280. +                if (!xdr_u_hyper(xdr, &res->contents[i].hole.offset))
  281. +                    return FALSE;
  282. +                if (!xdr_u_hyper(xdr, &res->contents[i].hole.length))
  283. +                    return FALSE;
  284. +
  285. +                /*
  286. +                 * fixme: READ_PLUS is required to return the whole hole,
  287. +                 * even if it is bigger than the requested size
  288. +                 */
  289. +                EASSERT(((data+res->contents[i].hole.length)-res->data) < res->data_len);
  290. +                (void)memset(data, 0, res->contents[i].hole.length);
  291. +                data += res->contents[i].hole.length;
  292. +            default:
  293. +                DPRINTF(0, ("decode_read_plus_res_ok: unknown co=%d\n", (int)co));
  294. +                return FALSE;
  295. +        }
  296. +
  297. +        EASSERT((data - res->data) <= res->data_len);
  298. +    }
  299. +
  300. +    EASSERT((data - res->data) < UINT_MAX);
  301. +    res->data_len = (uint32_t)(data - res->data);
  302. +
  303. +//    DPRINTF(0, ("decode_read_plus_res_ok: SUCCESS\n"));
  304. +    return TRUE;
  305. +}
  306. +
  307. +static bool_t decode_op_read_plus(
  308. +    XDR *xdr,
  309. +    nfs_resop4 *resop)
  310. +{
  311. +    nfs42_read_plus_res *res = (nfs42_read_plus_res *)resop->res;
  312. +
  313. +    if (unexpected_op(resop->op, OP_READ_PLUS))
  314. +        return FALSE;
  315. +
  316. +    if (!xdr_u_int32_t(xdr, &res->status))
  317. +        return FALSE;
  318. +
  319. +    if (res->status == NFS4_OK)
  320. +        return decode_read_plus_res_ok(xdr, &res->resok4);
  321. +
  322. +    return TRUE;
  323. +}
  324. +
  325. +#endif
  326. +
  327. +
  328.  
  329.  /*
  330.   * OP_READDIR
  331. @@ -3638,7 +3797,7 @@ static const op_table_entry g_op_table[] = {
  332.      { NULL, NULL }, /* OP_LAYOUTSTATS = 65, */
  333.      { NULL, NULL }, /* OP_OFFLOAD_CANCEL = 66, */
  334.      { NULL, NULL }, /* OP_OFFLOAD_STATUS = 67, */
  335. -    { NULL, NULL }, /* OP_READ_PLUS = 68, */
  336. +    { encode_op_read_plus, decode_op_read_plus }, /* OP_READ_PLUS = 68, */
  337.      { NULL, NULL }, /* OP_SEEK = 69, */
  338.      { NULL, NULL }, /* OP_WRITE_SAME = 70, */
  339.      { NULL, NULL }, /* OP_CLONE = 71, */
  340. diff --git a/daemon/readwrite.c b/daemon/readwrite.c
  341. index 355336a..402db22 100644
  342. --- a/daemon/readwrite.c
  343. +++ b/daemon/readwrite.c
  344. @@ -77,8 +77,13 @@ static int read_from_mds(
  345.      while(to_rcv > 0) {
  346.          uint32_t bytes_read = 0, chunk = min(to_rcv, maxreadsize);
  347.  
  348. +#if 1
  349. +        status = nfs42_read_plus(session, file, stateid, args->offset + reloffset, chunk,
  350. +                p, &bytes_read, &eof);
  351. +#else
  352.          status = nfs41_read(session, file, stateid, args->offset + reloffset, chunk,
  353.                  p, &bytes_read, &eof);
  354. +#endif
  355.          if (status == NFS4ERR_OPENMODE && !len) {
  356.              stateid->type = STATEID_SPECIAL;
  357.              stateid4_cpy(&stateid->stateid, &special_read_stateid);
  358. diff --git a/daemon/recovery.c b/daemon/recovery.c
  359. index eee4031..1cb23ea 100644
  360. --- a/daemon/recovery.c
  361. +++ b/daemon/recovery.c
  362. @@ -805,6 +805,11 @@ bool_t nfs41_recover_stateid(
  363.      } else if (argop->op == OP_READ) {
  364.          nfs41_read_args *read = (nfs41_read_args*)argop->arg;
  365.          stateid = read->stateid;
  366. +#if 1
  367. +    } else if (argop->op == OP_READ_PLUS) {
  368. +        nfs42_read_plus_args *read_plus = (nfs42_read_plus_args *)argop->arg;
  369. +        stateid = read_plus->stateid;
  370. +#endif
  371.      } else if (argop->op == OP_WRITE) {
  372.          nfs41_write_args *write = (nfs41_write_args*)argop->arg;
  373.          stateid = write->stateid;

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.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at