free(data);
}
+static void rpc_connect_program_5_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data)
+{
+ struct rpc_cb_data *data = private_data;
+
+ assert(rpc->magic == RPC_CONTEXT_MAGIC);
+
+ /* Dont want any more callbacks even if the socket is closed */
+ rpc->connect_cb = NULL;
+
+ if (status == RPC_STATUS_ERROR) {
+ data->cb(rpc, status, command_data, data->private_data);
+ free_rpc_cb_data(data);
+ return;
+ }
+ if (status == RPC_STATUS_CANCEL) {
+ data->cb(rpc, status, "Command was cancelled", data->private_data);
+ free_rpc_cb_data(data);
+ return;
+ }
+
+ data->cb(rpc, status, NULL, data->private_data);
+ free_rpc_cb_data(data);
+}
+
static void rpc_connect_program_4_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data)
{
struct rpc_cb_data *data = private_data;
return;
}
+ switch (data->program) {
+ case MOUNT_PROGRAM:
+ if (rpc_mount3_null_async(rpc, rpc_connect_program_5_cb,
+ data) != 0) {
+ data->cb(rpc, status, command_data, data->private_data);
+ free_rpc_cb_data(data);
+ return;
+ }
+ return;
+ case NFS_PROGRAM:
+ if (rpc_nfs3_null_async(rpc, rpc_connect_program_5_cb,
+ data) != 0) {
+ data->cb(rpc, status, command_data, data->private_data);
+ free_rpc_cb_data(data);
+ return;
+ }
+ return;
+ }
+
data->cb(rpc, status, NULL, data->private_data);
free_rpc_cb_data(data);
}
return;
}
- if (rpc_pmap_getport_async(rpc, data->program, data->version, IPPROTO_TCP, rpc_connect_program_3_cb, private_data) != 0) {
+ if (rpc_pmap2_getport_async(rpc, data->program, data->version, IPPROTO_TCP, rpc_connect_program_3_cb, private_data) != 0) {
data->cb(rpc, status, command_data, data->private_data);
free_rpc_cb_data(data);
return;
return;
}
- if (rpc_pmap_null_async(rpc, rpc_connect_program_2_cb, data) != 0) {
+ if (rpc_pmap2_null_async(rpc, rpc_connect_program_2_cb, data) != 0) {
data->cb(rpc, status, command_data, data->private_data);
free_rpc_cb_data(data);
return;
}
}
-int rpc_connect_program_async(struct rpc_context *rpc, char *server, int program, int version, rpc_cb cb, void *private_data)
+int rpc_connect_program_async(struct rpc_context *rpc, const char *server, int program, int version, rpc_cb cb, void *private_data)
{
struct rpc_cb_data *data;
}
}
-
-static void nfs_mount_7_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data)
-{
- struct nfs_cb_data *data = private_data;
- struct nfs_context *nfs = data->nfs;
-
- assert(rpc->magic == RPC_CONTEXT_MAGIC);
-
- /* Dont want any more callbacks even if the socket is closed */
- rpc->connect_cb = NULL;
-
- if (status == RPC_STATUS_ERROR) {
- data->cb(-EFAULT, nfs, command_data, data->private_data);
- free_nfs_cb_data(data);
- return;
- }
- if (status == RPC_STATUS_CANCEL) {
- data->cb(-EINTR, nfs, "Command was cancelled", data->private_data);
- free_nfs_cb_data(data);
- return;
- }
-
- if (rpc_nfs3_null_async(rpc, nfs_mount_8_cb, data) != 0) {
- data->cb(-ENOMEM, nfs, command_data, data->private_data);
- free_nfs_cb_data(data);
- return;
- }
-}
-
-
static void nfs_mount_6_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data)
{
struct nfs_cb_data *data = private_data;
memcpy(nfs->rootfh.data.data_val, res->mountres3_u.mountinfo.fhandle.fhandle3_val, nfs->rootfh.data.data_len);
rpc_disconnect(rpc, "normal disconnect");
- if (rpc_connect_async(rpc, nfs->server, 2049, nfs_mount_7_cb, data) != 0) {
+
+ if (rpc_connect_program_async(nfs->rpc, nfs->server, NFS_PROGRAM, NFS_V3, nfs_mount_8_cb, data) != 0) {
data->cb(-ENOMEM, nfs, command_data, data->private_data);
free_nfs_cb_data(data);
return;
}
+
/* NFS TCP connections we want to autoreconnect after sessions are torn down (due to inactivity or error) */
rpc_set_autoreconnect(rpc);
}
}
}
-static void nfs_mount_4_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data)
-{
- struct nfs_cb_data *data = private_data;
- struct nfs_context *nfs = data->nfs;
-
- assert(rpc->magic == RPC_CONTEXT_MAGIC);
-
- /* Dont want any more callbacks even if the socket is closed */
- rpc->connect_cb = NULL;
-
- if (status == RPC_STATUS_ERROR) {
- data->cb(-EFAULT, nfs, command_data, data->private_data);
- free_nfs_cb_data(data);
- return;
- }
- if (status == RPC_STATUS_CANCEL) {
- data->cb(-EINTR, nfs, "Command was cancelled", data->private_data);
- free_nfs_cb_data(data);
- return;
- }
-
- if (rpc_mount3_null_async(rpc, nfs_mount_5_cb, data) != 0) {
- data->cb(-ENOMEM, nfs, command_data, data->private_data);
- free_nfs_cb_data(data);
- return;
- }
-}
-
-static void nfs_mount_3_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data)
-{
- struct nfs_cb_data *data = private_data;
- struct nfs_context *nfs = data->nfs;
- uint32_t mount_port;
-
- assert(rpc->magic == RPC_CONTEXT_MAGIC);
-
- if (status == RPC_STATUS_ERROR) {
- data->cb(-EFAULT, nfs, command_data, data->private_data);
- free_nfs_cb_data(data);
- return;
- }
- if (status == RPC_STATUS_CANCEL) {
- data->cb(-EINTR, nfs, "Command was cancelled", data->private_data);
- free_nfs_cb_data(data);
- return;
- }
-
- mount_port = *(uint32_t *)command_data;
- if (mount_port == 0) {
- rpc_set_error(rpc, "RPC error. Mount program is not available on %s", nfs->server);
- data->cb(-ENOENT, nfs, command_data, data->private_data);
- free_nfs_cb_data(data);
- return;
- }
-
- rpc_disconnect(rpc, "normal disconnect");
- if (rpc_connect_async(rpc, nfs->server, mount_port, nfs_mount_4_cb, data) != 0) {
- data->cb(-ENOMEM, nfs, command_data, data->private_data);
- free_nfs_cb_data(data);
- return;
- }
-}
-
-
-static void nfs_mount_2_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data)
-{
- struct nfs_cb_data *data = private_data;
- struct nfs_context *nfs = data->nfs;
-
- assert(rpc->magic == RPC_CONTEXT_MAGIC);
-
- if (status == RPC_STATUS_ERROR) {
- data->cb(-EFAULT, nfs, command_data, data->private_data);
- free_nfs_cb_data(data);
- return;
- }
- if (status == RPC_STATUS_CANCEL) {
- data->cb(-EINTR, nfs, "Command was cancelled", data->private_data);
- free_nfs_cb_data(data);
- return;
- }
-
- if (rpc_pmap_getport_async(rpc, MOUNT_PROGRAM, MOUNT_V3, IPPROTO_TCP, nfs_mount_3_cb, private_data) != 0) {
- data->cb(-ENOMEM, nfs, command_data, data->private_data);
- free_nfs_cb_data(data);
- return;
- }
-}
-
-static void nfs_mount_1_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data)
-{
- struct nfs_cb_data *data = private_data;
- struct nfs_context *nfs = data->nfs;
-
- assert(rpc->magic == RPC_CONTEXT_MAGIC);
-
- /* Dont want any more callbacks even if the socket is closed */
- rpc->connect_cb = NULL;
-
- if (status == RPC_STATUS_ERROR) {
- data->cb(-EFAULT, nfs, command_data, data->private_data);
- free_nfs_cb_data(data);
- return;
- }
- if (status == RPC_STATUS_CANCEL) {
- data->cb(-EINTR, nfs, "Command was cancelled", data->private_data);
- free_nfs_cb_data(data);
- return;
- }
-
- if (rpc_pmap_null_async(rpc, nfs_mount_2_cb, data) != 0) {
- data->cb(-ENOMEM, nfs, command_data, data->private_data);
- free_nfs_cb_data(data);
- return;
- }
-}
-
/*
* Async call for mounting an nfs share and geting the root filehandle
*/
data->cb = cb;
data->private_data = private_data;
- if (rpc_connect_async(nfs->rpc, server, 111, nfs_mount_1_cb, data) != 0) {
+ if (rpc_connect_program_async(nfs->rpc, server, MOUNT_PROGRAM, MOUNT_V3, nfs_mount_5_cb, data) != 0) {
rpc_set_error(nfs->rpc, "Failed to start connection");
free_nfs_cb_data(data);
return -1;
assert(data->num_calls == 0);
- /* trying to read more than maximum server read size, we has to chop it up into smaller
- * reads and collect into a reassembly buffer.
+ /* chop requests into chunks of at most READMAX bytes if necessary.
* we send all reads in parallel so that performance is still good.
*/
data->max_offset = offset;
return -1;
}
data->oom = 1;
+ break;
}
memset(mdata, 0, sizeof(struct nfs_mcb_data));
mdata->data = data;
return -1;
}
data->oom = 1;
+ break;
}
count -= readcount;
/* hello, clang-analyzer */
assert(data->num_calls == 0);
- /* trying to write more than maximum server write size, we has to chop it up into smaller
- * chunks.
+ /* chop requests into chunks of at most WRITEMAX bytes if necessary.
* we send all writes in parallel so that performance is still good.
*/
data->max_offset = offset;
return -1;
}
data->oom = 1;
+ break;
}
memset(mdata, 0, sizeof(struct nfs_mcb_data));
mdata->data = data;
return -1;
}
data->oom = 1;
+ break;
}
count -= writecount;
}
}
-static void mount_export_3_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data)
-{
- struct mount_cb_data *data = private_data;
- uint32_t mount_port;
-
- assert(rpc->magic == RPC_CONTEXT_MAGIC);
-
- if (status == RPC_STATUS_ERROR) {
- data->cb(rpc, -EFAULT, command_data, data->private_data);
- free_mount_cb_data(data);
- return;
- }
- if (status == RPC_STATUS_CANCEL) {
- data->cb(rpc, -EINTR, "Command was cancelled", data->private_data);
- free_mount_cb_data(data);
- return;
- }
-
- mount_port = *(uint32_t *)command_data;
- if (mount_port == 0) {
- rpc_set_error(rpc, "RPC error. Mount program is not available");
- data->cb(rpc, -ENOENT, command_data, data->private_data);
- free_mount_cb_data(data);
- return;
- }
-
- rpc_disconnect(rpc, "normal disconnect");
- if (rpc_connect_async(rpc, data->server, mount_port, mount_export_4_cb, data) != 0) {
- data->cb(rpc, -ENOMEM, command_data, data->private_data);
- free_mount_cb_data(data);
- return;
- }
-}
-
-static void mount_export_2_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data)
-{
- struct mount_cb_data *data = private_data;
-
- assert(rpc->magic == RPC_CONTEXT_MAGIC);
-
- if (status == RPC_STATUS_ERROR) {
- data->cb(rpc, -EFAULT, command_data, data->private_data);
- free_mount_cb_data(data);
- return;
- }
- if (status == RPC_STATUS_CANCEL) {
- data->cb(rpc, -EINTR, "Command was cancelled", data->private_data);
- free_mount_cb_data(data);
- return;
- }
-
- if (rpc_pmap_getport_async(rpc, MOUNT_PROGRAM, MOUNT_V3, IPPROTO_TCP, mount_export_3_cb, private_data) != 0) {
- data->cb(rpc, -ENOMEM, command_data, data->private_data);
- free_mount_cb_data(data);
- return;
- }
-}
-
-static void mount_export_1_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data)
-{
- struct mount_cb_data *data = private_data;
-
- assert(rpc->magic == RPC_CONTEXT_MAGIC);
-
- /* Dont want any more callbacks even if the socket is closed */
- rpc->connect_cb = NULL;
-
- if (status == RPC_STATUS_ERROR) {
- data->cb(rpc, -EFAULT, command_data, data->private_data);
- free_mount_cb_data(data);
- return;
- }
- if (status == RPC_STATUS_CANCEL) {
- data->cb(rpc, -EINTR, "Command was cancelled", data->private_data);
- free_mount_cb_data(data);
- return;
- }
-
- if (rpc_pmap_null_async(rpc, mount_export_2_cb, data) != 0) {
- data->cb(rpc, -ENOMEM, command_data, data->private_data);
- free_mount_cb_data(data);
- return;
- }
-}
-
int mount_getexports_async(struct rpc_context *rpc, const char *server, rpc_cb cb, void *private_data)
{
struct mount_cb_data *data;
free_mount_cb_data(data);
return -1;
}
- if (rpc_connect_async(rpc, data->server, 111, mount_export_1_cb, data) != 0) {
+ if (rpc_connect_program_async(rpc, data->server, MOUNT_PROGRAM, MOUNT_V3, mount_export_4_cb, data) != 0) {
+ rpc_set_error(rpc, "Failed to start connection");
free_mount_cb_data(data);
return -1;
}