+static void nfs_pread_mcb(struct rpc_context *rpc _U_, int status, void *command_data, void *private_data)
+{
+ struct nfs_mcb_data *mdata = private_data;
+ struct nfs_cb_data *data = mdata->data;
+ struct nfs_context *nfs = data->nfs;
+ READ3res *res;
+
+ data->num_calls--;
+
+ if (status == RPC_STATUS_ERROR) {
+ /* flag the failure but do not invoke callback until we have received all responses */
+ data->error = 1;
+ }
+ if (status == RPC_STATUS_CANCEL) {
+ /* flag the cancellation but do not invoke callback until we have received all responses */
+ data->cancel = 1;
+ }
+
+ /* reassemble the data into the buffer */
+ if (status == RPC_STATUS_SUCCESS) {
+ res = command_data;
+ if (res->status != NFS3_OK) {
+ rpc_set_error(nfs->rpc, "NFS: Read failed with %s(%d)", nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status));
+ data->error = 1;
+ } else {
+ memcpy(&data->buffer[mdata->offset], res->READ3res_u.resok.data.data_val, res->READ3res_u.resok.count);
+ if (data->max_offset < mdata->offset + res->READ3res_u.resok.count) {
+ data->max_offset = mdata->offset + res->READ3res_u.resok.count;
+ }
+ }
+ }
+
+ if (data->num_calls > 0) {
+ /* still waiting for more replies */
+ free(mdata);
+ return;
+ }
+
+
+ if (data->error != 0) {
+ data->cb(-EFAULT, nfs, command_data, data->private_data);
+ free_nfs_cb_data(data);
+ free(mdata);
+ return;
+ }
+ if (data->cancel != 0) {
+ data->cb(-EINTR, nfs, "Command was cancelled", data->private_data);
+ free_nfs_cb_data(data);
+ free(mdata);
+ return;
+ }
+
+ data->nfsfh->offset = data->max_offset;
+ data->cb(data->max_offset - data->start_offset, nfs, data->buffer, data->private_data);
+ free_nfs_cb_data(data);
+ free(mdata);
+}
+