pdu: drop the rpc->encodebuf
the only call thar really needs a big encodebuf is WRITE. So give each PDU its private encodebuf. This avoids the need to memcpy the data from the static rpc->encodebuf to the pdu->outdata.data. Signed-off-by: Peter Lieven <pl@kamp.de>libnfs-4.0.0-vitalif
parent
21c466254a
commit
9cb49494c7
|
@ -82,6 +82,8 @@ struct rpc_queue {
|
||||||
#define HASHES 1024
|
#define HASHES 1024
|
||||||
#define NFS_RA_TIMEOUT 5
|
#define NFS_RA_TIMEOUT 5
|
||||||
#define NFS_MAX_XFER_SIZE (1024 * 1024)
|
#define NFS_MAX_XFER_SIZE (1024 * 1024)
|
||||||
|
#define ZDR_ENCODE_OVERHEAD 1024
|
||||||
|
#define ZDR_ENCODEBUF_MINSIZE 4096
|
||||||
|
|
||||||
struct rpc_context {
|
struct rpc_context {
|
||||||
uint32_t magic;
|
uint32_t magic;
|
||||||
|
@ -97,10 +99,6 @@ struct rpc_context {
|
||||||
struct AUTH *auth;
|
struct AUTH *auth;
|
||||||
uint32_t xid;
|
uint32_t xid;
|
||||||
|
|
||||||
/* buffer used for encoding RPC PDU */
|
|
||||||
char *encodebuf;
|
|
||||||
int encodebuflen;
|
|
||||||
|
|
||||||
struct rpc_queue outqueue;
|
struct rpc_queue outqueue;
|
||||||
struct sockaddr_storage udp_src;
|
struct sockaddr_storage udp_src;
|
||||||
struct rpc_queue waitpdu[HASHES];
|
struct rpc_queue waitpdu[HASHES];
|
||||||
|
@ -156,6 +154,7 @@ void rpc_return_to_queue(struct rpc_queue *q, struct rpc_pdu *pdu);
|
||||||
unsigned int rpc_hash_xid(uint32_t xid);
|
unsigned int rpc_hash_xid(uint32_t xid);
|
||||||
|
|
||||||
struct rpc_pdu *rpc_allocate_pdu(struct rpc_context *rpc, int program, int version, int procedure, rpc_cb cb, void *private_data, zdrproc_t zdr_decode_fn, int zdr_bufsize);
|
struct rpc_pdu *rpc_allocate_pdu(struct rpc_context *rpc, int program, int version, int procedure, rpc_cb cb, void *private_data, zdrproc_t zdr_decode_fn, int zdr_bufsize);
|
||||||
|
struct rpc_pdu *rpc_allocate_pdu2(struct rpc_context *rpc, int program, int version, int procedure, rpc_cb cb, void *private_data, zdrproc_t zdr_decode_fn, int zdr_bufsize, size_t alloc_hint);
|
||||||
void rpc_free_pdu(struct rpc_context *rpc, struct rpc_pdu *pdu);
|
void rpc_free_pdu(struct rpc_context *rpc, struct rpc_pdu *pdu);
|
||||||
int rpc_queue_pdu(struct rpc_context *rpc, struct rpc_pdu *pdu);
|
int rpc_queue_pdu(struct rpc_context *rpc, struct rpc_pdu *pdu);
|
||||||
uint32_t rpc_get_pdu_size(char *buf);
|
uint32_t rpc_get_pdu_size(char *buf);
|
||||||
|
|
|
@ -31,7 +31,7 @@ extern "C" {
|
||||||
|
|
||||||
struct rpc_data {
|
struct rpc_data {
|
||||||
int size;
|
int size;
|
||||||
unsigned char *data;
|
char *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rpc_context;
|
struct rpc_context;
|
||||||
|
|
14
lib/init.c
14
lib/init.c
|
@ -62,17 +62,8 @@ struct rpc_context *rpc_init_context(void)
|
||||||
|
|
||||||
rpc->magic = RPC_CONTEXT_MAGIC;
|
rpc->magic = RPC_CONTEXT_MAGIC;
|
||||||
|
|
||||||
/* Allow NFS_MAX_XFER_SIZE of data (for writes) and some */
|
|
||||||
rpc->encodebuflen = NFS_MAX_XFER_SIZE + 4096;
|
|
||||||
rpc->encodebuf = malloc(rpc->encodebuflen);
|
|
||||||
if (rpc->encodebuf == NULL) {
|
|
||||||
free(rpc);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
rpc->auth = authunix_create_default();
|
rpc->auth = authunix_create_default();
|
||||||
if (rpc->auth == NULL) {
|
if (rpc->auth == NULL) {
|
||||||
free(rpc->encodebuf);
|
|
||||||
free(rpc);
|
free(rpc);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -316,11 +307,6 @@ void rpc_destroy_context(struct rpc_context *rpc)
|
||||||
close(rpc->fd);
|
close(rpc->fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rpc->encodebuf != NULL) {
|
|
||||||
free(rpc->encodebuf);
|
|
||||||
rpc->encodebuf = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rpc->error_string != NULL) {
|
if (rpc->error_string != NULL) {
|
||||||
free(rpc->error_string);
|
free(rpc->error_string);
|
||||||
rpc->error_string = NULL;
|
rpc->error_string = NULL;
|
||||||
|
|
25
lib/pdu.c
25
lib/pdu.c
|
@ -86,7 +86,7 @@ unsigned int rpc_hash_xid(uint32_t xid)
|
||||||
|
|
||||||
#define PAD_TO_8_BYTES(x) ((x + 0x07) & ~0x07)
|
#define PAD_TO_8_BYTES(x) ((x + 0x07) & ~0x07)
|
||||||
|
|
||||||
struct rpc_pdu *rpc_allocate_pdu(struct rpc_context *rpc, int program, int version, int procedure, rpc_cb cb, void *private_data, zdrproc_t zdr_decode_fn, int zdr_decode_bufsize)
|
struct rpc_pdu *rpc_allocate_pdu2(struct rpc_context *rpc, int program, int version, int procedure, rpc_cb cb, void *private_data, zdrproc_t zdr_decode_fn, int zdr_decode_bufsize, size_t alloc_hint)
|
||||||
{
|
{
|
||||||
struct rpc_pdu *pdu;
|
struct rpc_pdu *pdu;
|
||||||
struct rpc_msg msg;
|
struct rpc_msg msg;
|
||||||
|
@ -112,7 +112,13 @@ struct rpc_pdu *rpc_allocate_pdu(struct rpc_context *rpc, int program, int versi
|
||||||
pdu->zdr_decode_fn = zdr_decode_fn;
|
pdu->zdr_decode_fn = zdr_decode_fn;
|
||||||
pdu->zdr_decode_bufsize = zdr_decode_bufsize;
|
pdu->zdr_decode_bufsize = zdr_decode_bufsize;
|
||||||
|
|
||||||
zdrmem_create(&pdu->zdr, rpc->encodebuf, rpc->encodebuflen, ZDR_ENCODE);
|
pdu->outdata.data = malloc(ZDR_ENCODEBUF_MINSIZE + alloc_hint);
|
||||||
|
if (pdu->outdata.data == NULL) {
|
||||||
|
rpc_set_error(rpc, "Out of memory: Failed to allocate encode buffer");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
zdrmem_create(&pdu->zdr, pdu->outdata.data, ZDR_ENCODEBUF_MINSIZE + alloc_hint, ZDR_ENCODE);
|
||||||
if (rpc->is_udp == 0) {
|
if (rpc->is_udp == 0) {
|
||||||
zdr_setpos(&pdu->zdr, 4); /* skip past the record marker */
|
zdr_setpos(&pdu->zdr, 4); /* skip past the record marker */
|
||||||
}
|
}
|
||||||
|
@ -138,6 +144,11 @@ struct rpc_pdu *rpc_allocate_pdu(struct rpc_context *rpc, int program, int versi
|
||||||
return pdu;
|
return pdu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct rpc_pdu *rpc_allocate_pdu(struct rpc_context *rpc, int program, int version, int procedure, rpc_cb cb, void *private_data, zdrproc_t zdr_decode_fn, int zdr_decode_bufsize)
|
||||||
|
{
|
||||||
|
return rpc_allocate_pdu2(rpc, program, version, procedure, cb, private_data, zdr_decode_fn, zdr_decode_bufsize, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void rpc_free_pdu(struct rpc_context *rpc, struct rpc_pdu *pdu)
|
void rpc_free_pdu(struct rpc_context *rpc, struct rpc_pdu *pdu)
|
||||||
{
|
{
|
||||||
assert(rpc->magic == RPC_CONTEXT_MAGIC);
|
assert(rpc->magic == RPC_CONTEXT_MAGIC);
|
||||||
|
@ -175,7 +186,7 @@ int rpc_queue_pdu(struct rpc_context *rpc, struct rpc_pdu *pdu)
|
||||||
unsigned int hash;
|
unsigned int hash;
|
||||||
|
|
||||||
// XXX add a rpc->udp_dest_sock_size and get rid of sys/socket.h and netinet/in.h
|
// XXX add a rpc->udp_dest_sock_size and get rid of sys/socket.h and netinet/in.h
|
||||||
if (sendto(rpc->fd, rpc->encodebuf, size, MSG_DONTWAIT, rpc->udp_dest, sizeof(struct sockaddr_in)) < 0) {
|
if (sendto(rpc->fd, pdu->zdr.buf, size, MSG_DONTWAIT, rpc->udp_dest, sizeof(struct sockaddr_in)) < 0) {
|
||||||
rpc_set_error(rpc, "Sendto failed with errno %s", strerror(errno));
|
rpc_set_error(rpc, "Sendto failed with errno %s", strerror(errno));
|
||||||
rpc_free_pdu(rpc, pdu);
|
rpc_free_pdu(rpc, pdu);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -192,14 +203,6 @@ int rpc_queue_pdu(struct rpc_context *rpc, struct rpc_pdu *pdu)
|
||||||
zdr_int(&pdu->zdr, &recordmarker);
|
zdr_int(&pdu->zdr, &recordmarker);
|
||||||
|
|
||||||
pdu->outdata.size = size;
|
pdu->outdata.size = size;
|
||||||
pdu->outdata.data = malloc(pdu->outdata.size);
|
|
||||||
if (pdu->outdata.data == NULL) {
|
|
||||||
rpc_set_error(rpc, "Out of memory. Failed to allocate buffer for pdu\n");
|
|
||||||
rpc_free_pdu(rpc, pdu);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(pdu->outdata.data, rpc->encodebuf, pdu->outdata.size);
|
|
||||||
rpc_enqueue(&rpc->outqueue, pdu);
|
rpc_enqueue(&rpc->outqueue, pdu);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -318,7 +318,7 @@ int rpc_nfs3_write_async(struct rpc_context *rpc, rpc_cb cb, struct WRITE3args *
|
||||||
{
|
{
|
||||||
struct rpc_pdu *pdu;
|
struct rpc_pdu *pdu;
|
||||||
|
|
||||||
pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_WRITE, cb, private_data, (zdrproc_t)zdr_WRITE3res, sizeof(WRITE3res));
|
pdu = rpc_allocate_pdu2(rpc, NFS_PROGRAM, NFS_V3, NFS3_WRITE, cb, private_data, (zdrproc_t)zdr_WRITE3res, sizeof(WRITE3res), args->count);
|
||||||
if (pdu == NULL) {
|
if (pdu == NULL) {
|
||||||
rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/WRITE call");
|
rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/WRITE call");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1064,7 +1064,7 @@ int rpc_nfs2_write_async(struct rpc_context *rpc, rpc_cb cb, struct WRITE2args *
|
||||||
{
|
{
|
||||||
struct rpc_pdu *pdu;
|
struct rpc_pdu *pdu;
|
||||||
|
|
||||||
pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_WRITE, cb, private_data, (zdrproc_t)zdr_WRITE2res, sizeof(WRITE2res));
|
pdu = rpc_allocate_pdu2(rpc, NFS_PROGRAM, NFS_V2, NFS2_WRITE, cb, private_data, (zdrproc_t)zdr_WRITE2res, sizeof(WRITE2res), args->totalcount);
|
||||||
if (pdu == NULL) {
|
if (pdu == NULL) {
|
||||||
rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/WRITE call");
|
rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/WRITE call");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
Loading…
Reference in New Issue