X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=lib%2Flibnfs.c;h=e99c561054b116914727e868fba83a9f513e9ec4;hb=463d59bf8e5ff1a3ac27ab4fedf77b237394d1a6;hp=deab4f1c1036ef1e1584ea904d3f2cd28214c6a3;hpb=717cc58e61cd43db43353027c383883cadde8251;p=deb_libnfs.git diff --git a/lib/libnfs.c b/lib/libnfs.c index deab4f1..e99c561 100644 --- a/lib/libnfs.c +++ b/lib/libnfs.c @@ -17,23 +17,48 @@ /* * High level api to nfs filesystems */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef AROS +#include "aros_compat.h" +#endif + #ifdef WIN32 #include "win32_compat.h" -#define DllExport -#else -#include -#ifndef ANDROID -#include -#else -#include -#define statvfs statfs #endif + +#ifdef HAVE_UTIME_H #include -#include -#endif/*WIN32*/ +#endif + +#ifdef ANDROID +#define statvfs statfs +#endif #define _GNU_SOURCE +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_SYS_VFS_H +#include +#endif + +#ifdef HAVE_SYS_STATVFS_H +#include +#endif + +#ifdef HAVE_NETINET_IN_H +#include +#endif + +#ifdef HAVE_STRINGS_H +#include +#endif + #include #include #include @@ -43,7 +68,6 @@ #include #include #include -#include #include "libnfs-zdr.h" #include "libnfs.h" #include "libnfs-raw.h" @@ -195,6 +219,155 @@ void nfs_destroy_context(struct nfs_context *nfs) free(nfs); } +struct rpc_cb_data { + char *server; + uint32_t program; + uint32_t version; + + rpc_cb cb; + void *private_data; +}; + +void free_rpc_cb_data(struct rpc_cb_data *data) +{ + free(data->server); + data->server = NULL; + free(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; + + 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_3_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) +{ + struct rpc_cb_data *data = private_data; + uint32_t rpc_port; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + 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; + } + + rpc_port = *(uint32_t *)command_data; + if (rpc_port == 0) { + rpc_set_error(rpc, "RPC error. Program is not available on %s", data->server); + data->cb(rpc, RPC_STATUS_ERROR, rpc_get_error(rpc), data->private_data); + free_rpc_cb_data(data); + return; + } + + rpc_disconnect(rpc, "normal disconnect"); + if (rpc_connect_async(rpc, data->server, rpc_port, rpc_connect_program_4_cb, data) != 0) { + data->cb(rpc, status, command_data, data->private_data); + free_rpc_cb_data(data); + return; + } +} + +static void rpc_connect_program_2_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); + + 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; + } + + if (rpc_pmap_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; + } +} + +static void rpc_connect_program_1_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; + } + + if (rpc_pmap_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) +{ + struct rpc_cb_data *data; + + data = malloc(sizeof(struct rpc_cb_data)); + if (data == NULL) { + return -1; + } + memset(data, 0, sizeof(struct rpc_cb_data)); + data->server = strdup(server); + data->program = program; + data->version = version; + + data->cb = cb; + data->private_data = private_data; + + if (rpc_connect_async(rpc, server, 111, rpc_connect_program_1_cb, data) != 0) { + rpc_set_error(rpc, "Failed to start connection"); + free_rpc_cb_data(data); + return -1; + } + return 0; +} + void free_nfs_cb_data(struct nfs_cb_data *data) { if (data->saved_path != NULL) { @@ -251,6 +424,7 @@ static void nfs_mount_9_cb(struct rpc_context *rpc, int status, void *command_da struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; FSINFO3res *res = command_data; + struct GETATTR3args args; assert(rpc->magic == RPC_CONTEXT_MAGIC); @@ -268,7 +442,11 @@ static void nfs_mount_9_cb(struct rpc_context *rpc, int status, void *command_da nfs->readmax = res->FSINFO3res_u.resok.rtmax; nfs->writemax = res->FSINFO3res_u.resok.wtmax; - if (rpc_nfs_getattr_async(rpc, nfs_mount_10_cb, &nfs->rootfh, data) != 0) { + memset(&args, 0, sizeof(GETATTR3args)); + args.object.data.data_len = nfs->rootfh.data.data_len; + args.object.data.data_val = nfs->rootfh.data.data_val; + + if (rpc_nfs3_getattr_async(rpc, nfs_mount_10_cb, &args, data) != 0) { data->cb(-ENOMEM, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; @@ -601,6 +779,7 @@ static void nfs_lookup_path_1_cb(struct rpc_context *rpc, int status, void *comm static int nfs_lookup_path_async_internal(struct nfs_context *nfs, struct nfs_cb_data *data, struct nfs_fh3 *fh) { char *path, *str; + LOOKUP3args args; while (*data->path == '/') { data->path++; @@ -631,7 +810,13 @@ static int nfs_lookup_path_async_internal(struct nfs_context *nfs, struct nfs_cb return 0; } - if (rpc_nfs_lookup_async(nfs->rpc, nfs_lookup_path_1_cb, fh, path, data) != 0) { + + memset(&args, 0, sizeof(LOOKUP3args)); + args.what.dir.data.data_len = fh->data.data_len; + args.what.dir.data.data_val = fh->data.data_val; + args.what.name = path; + + if (rpc_nfs3_lookup_async(nfs->rpc, nfs_lookup_path_1_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send lookup call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -644,8 +829,8 @@ static int nfs_lookuppath_async(struct nfs_context *nfs, const char *path, nfs_c { struct nfs_cb_data *data; - if (path[0] != '/') { - rpc_set_error(nfs->rpc, "Pathname is not absulute %s", path); + if (path[0] != 0 && path[0] != '/') { + rpc_set_error(nfs->rpc, "Pathname is not absolute %s", path); return -1; } @@ -740,7 +925,13 @@ static void nfs_stat_1_cb(struct rpc_context *rpc, int status, void *command_dat static int nfs_stat_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data) { - if (rpc_nfs_getattr_async(nfs->rpc, nfs_stat_1_cb, &data->fh, data) != 0) { + struct GETATTR3args args; + + memset(&args, 0, sizeof(GETATTR3args)); + args.object.data.data_len = data->fh.data.data_len; + args.object.data.data_val = data->fh.data.data_val; + + if (rpc_nfs3_getattr_async(nfs->rpc, nfs_stat_1_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send STAT GETATTR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -844,6 +1035,7 @@ static void nfs_open_cb(struct rpc_context *rpc, int status, void *command_data, static int nfs_open_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data) { int nfsmode = 0; + ACCESS3args args; if (data->continue_int & O_WRONLY) { nfsmode |= ACCESS3_MODIFY; @@ -855,7 +1047,12 @@ static int nfs_open_continue_internal(struct nfs_context *nfs, struct nfs_cb_dat nfsmode |= ACCESS3_READ; } - if (rpc_nfs_access_async(nfs->rpc, nfs_open_cb, &data->fh, nfsmode, data) != 0) { + memset(&args, 0, sizeof(ACCESS3args)); + args.object.data.data_len = data->fh.data.data_len; + args.object.data.data_val = data->fh.data.data_val; + args.access = nfsmode; + + if (rpc_nfs3_access_async(nfs->rpc, nfs_open_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send OPEN ACCESS call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -993,7 +1190,15 @@ int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offse nfsfh->offset = offset; if (count <= nfs_get_readmax(nfs)) { - if (rpc_nfs_read_async(nfs->rpc, nfs_pread_cb, &nfsfh->fh, offset, count, data) != 0) { + READ3args args; + + memset(&args, 0, sizeof(READ3args)); + args.file.data.data_len = nfsfh->fh.data.data_len; + args.file.data.data_val = nfsfh->fh.data.data_val; + args.offset = offset; + args.count = count; + + if (rpc_nfs3_read_async(nfs->rpc, nfs_pread_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send READ call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -1004,7 +1209,7 @@ int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offse /* trying to read more than maximum server read size, we has to chop it up into smaller * reads and collect into a reassembly buffer. - * we send all reads in parallell so that performance is still good. + * we send all reads in parallel so that performance is still good. */ data->max_offset = offset; data->start_offset = offset; @@ -1020,6 +1225,7 @@ int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offse while (count > 0) { uint64_t readcount = count; struct nfs_mcb_data *mdata; + READ3args args; if (readcount > nfs_get_readmax(nfs)) { readcount = nfs_get_readmax(nfs); @@ -1034,7 +1240,14 @@ int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offse mdata->data = data; mdata->offset = offset; mdata->count = readcount; - if (rpc_nfs_read_async(nfs->rpc, nfs_pread_mcb, &nfsfh->fh, offset, readcount, mdata) != 0) { + + memset(&args, 0, sizeof(READ3args)); + args.file.data.data_len = nfsfh->fh.data.data_len; + args.file.data.data_val = nfsfh->fh.data.data_val; + args.offset = offset; + args.count = readcount; + + if (rpc_nfs3_read_async(nfs->rpc, nfs_pread_mcb, &args, mdata) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send READ call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free(mdata); @@ -1173,7 +1386,18 @@ int nfs_pwrite_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offs nfsfh->offset = offset; if (count <= nfs_get_writemax(nfs)) { - if (rpc_nfs_write_async(nfs->rpc, nfs_pwrite_cb, &nfsfh->fh, buf, offset, count, nfsfh->is_sync?FILE_SYNC:UNSTABLE, data) != 0) { + WRITE3args args; + + memset(&args, 0, sizeof(WRITE3args)); + args.file.data.data_len = nfsfh->fh.data.data_len; + args.file.data.data_val = nfsfh->fh.data.data_val; + args.offset = offset; + args.count = count; + args.stable = nfsfh->is_sync?FILE_SYNC:UNSTABLE; + args.data.data_len = count; + args.data.data_val = buf; + + if (rpc_nfs3_write_async(nfs->rpc, nfs_pwrite_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send WRITE call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -1184,7 +1408,7 @@ int nfs_pwrite_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offs /* trying to write more than maximum server write size, we has to chop it up into smaller * chunks. - * we send all writes in parallell so that performance is still good. + * we send all writes in parallel so that performance is still good. */ data->max_offset = offset; data->start_offset = offset; @@ -1192,6 +1416,7 @@ int nfs_pwrite_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offs while (count > 0) { uint64_t writecount = count; struct nfs_mcb_data *mdata; + WRITE3args args; if (writecount > nfs_get_writemax(nfs)) { writecount = nfs_get_writemax(nfs); @@ -1207,7 +1432,16 @@ int nfs_pwrite_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offs mdata->offset = offset; mdata->count = writecount; - if (rpc_nfs_write_async(nfs->rpc, nfs_pwrite_mcb, &nfsfh->fh, &buf[offset - data->start_offset], offset, writecount, nfsfh->is_sync?FILE_SYNC:UNSTABLE, mdata) != 0) { + memset(&args, 0, sizeof(WRITE3args)); + args.file.data.data_len = nfsfh->fh.data.data_len; + args.file.data.data_val = nfsfh->fh.data.data_val; + args.offset = offset; + args.count = writecount; + args.stable = nfsfh->is_sync?FILE_SYNC:UNSTABLE; + args.data.data_len = writecount; + args.data.data_val = &buf[offset - data->start_offset]; + + if (rpc_nfs3_write_async(nfs->rpc, nfs_pwrite_mcb, &args, mdata) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send WRITE call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free(mdata); @@ -1259,6 +1493,7 @@ int nfs_close_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, voi int nfs_fstat_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, void *private_data) { struct nfs_cb_data *data; + struct GETATTR3args args; data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { @@ -1270,7 +1505,11 @@ int nfs_fstat_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, voi data->cb = cb; data->private_data = private_data; - if (rpc_nfs_getattr_async(nfs->rpc, nfs_stat_1_cb, &nfsfh->fh, data) != 0) { + memset(&args, 0, sizeof(GETATTR3args)); + args.object.data.data_len = nfsfh->fh.data.data_len; + args.object.data.data_val = nfsfh->fh.data.data_val; + + if (rpc_nfs3_getattr_async(nfs->rpc, nfs_stat_1_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send STAT GETATTR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -1659,10 +1898,10 @@ static void nfs_create_2_cb(struct rpc_context *rpc, int status, void *command_d } memset(nfsfh, 0, sizeof(struct nfsfh)); - /* steal the filehandle */ - nfsfh->fh.data.data_len = data->fh.data.data_len; - nfsfh->fh.data.data_val = data->fh.data.data_val; - data->fh.data.data_val = NULL; + /* copy the filehandle */ + nfsfh->fh.data.data_len = res->LOOKUP3res_u.resok.object.data.data_len; + nfsfh->fh.data.data_val = malloc(nfsfh->fh.data.data_len); + memcpy(nfsfh->fh.data.data_val, res->LOOKUP3res_u.resok.object.data.data_val, nfsfh->fh.data.data_len); data->cb(0, nfs, nfsfh, data->private_data); free_nfs_cb_data(data); @@ -1676,6 +1915,7 @@ static void nfs_creat_1_cb(struct rpc_context *rpc, int status, void *command_da struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; char *str = data->continue_data; + LOOKUP3args args; assert(rpc->magic == RPC_CONTEXT_MAGIC); @@ -1695,11 +1935,16 @@ static void nfs_creat_1_cb(struct rpc_context *rpc, int status, void *command_da if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: CREATE of %s/%s failed with %s(%d)", data->saved_path, str, nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); - + free_nfs_cb_data(data); return; } - if (rpc_nfs_lookup_async(nfs->rpc, nfs_create_2_cb, &data->fh, str, data) != 0) { + memset(&args, 0, sizeof(LOOKUP3args)); + args.what.dir.data.data_len = data->fh.data.data_len; + args.what.dir.data.data_val = data->fh.data.data_val; + args.what.name = str; + + if (rpc_nfs3_lookup_async(nfs->rpc, nfs_create_2_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send lookup call for %s/%s", data->saved_path, str); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -1715,7 +1960,6 @@ static int nfs_creat_continue_internal(struct nfs_context *nfs, struct nfs_cb_da str = &str[strlen(str) + 1]; - memset(&args, 0, sizeof(CREATE3args)); args.where.dir.data.data_len = data->fh.data.data_len; args.where.dir.data.data_val = data->fh.data.data_val; @@ -1751,7 +1995,7 @@ int nfs_creat_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb } *ptr = 0; - /* new_path now points to the parent directory, and beyond the nul terminateor is the new directory to create */ + /* new_path now points to the parent directory, and beyond the nul terminator is the new directory to create */ if (nfs_lookuppath_async(nfs, new_path, cb, private_data, nfs_creat_continue_internal, new_path, free, mode) != 0) { rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; @@ -2110,12 +2354,18 @@ static void nfs_opendir2_cb(struct rpc_context *rpc, int status, void *command_d rdpe_cb_data->data = data; for (nfsdirent = nfsdir->entries; nfsdirent; nfsdirent = nfsdirent->next) { struct rdpe_lookup_cb_data *rdpe_lookup_cb_data; + LOOKUP3args args; rdpe_lookup_cb_data = malloc(sizeof(struct rdpe_lookup_cb_data)); rdpe_lookup_cb_data->rdpe_cb_data = rdpe_cb_data; rdpe_lookup_cb_data->nfsdirent = nfsdirent; - if (rpc_nfs_lookup_async(nfs->rpc, nfs_opendir3_cb, &data->fh, nfsdirent->name, rdpe_lookup_cb_data) != 0) { + memset(&args, 0, sizeof(LOOKUP3args)); + args.what.dir.data.data_len = data->fh.data.data_len; + args.what.dir.data.data_val = data->fh.data.data_val; + args.what.name = nfsdirent->name; + + if (rpc_nfs3_lookup_async(nfs->rpc, nfs_opendir3_cb, &args, rdpe_lookup_cb_data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send READDIR LOOKUP call"); /* if we have already commands in flight, we cant just stop, we have to wait for the @@ -2346,6 +2596,7 @@ static void nfs_lseek_1_cb(struct rpc_context *rpc, int status, void *command_da int nfs_lseek_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, int whence, nfs_cb cb, void *private_data) { struct lseek_cb_data *data; + struct GETATTR3args args; if (whence == SEEK_SET) { nfsfh->offset = offset; @@ -2370,7 +2621,11 @@ int nfs_lseek_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offse data->cb = cb; data->private_data = private_data; - if (rpc_nfs_getattr_async(nfs->rpc, nfs_lseek_1_cb, &nfsfh->fh, data) != 0) { + memset(&args, 0, sizeof(GETATTR3args)); + args.object.data.data_len = nfsfh->fh.data.data_len; + args.object.data.data_val = nfsfh->fh.data.data_val; + + if (rpc_nfs3_getattr_async(nfs->rpc, nfs_lseek_1_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send LSEEK GETATTR call"); free(data); return -1; @@ -2871,9 +3126,6 @@ int nfs_utime_async(struct nfs_context *nfs, const char *path, struct utimbuf *t } - - - /* * Async access() */ @@ -2935,6 +3187,7 @@ static void nfs_access_cb(struct rpc_context *rpc, int status, void *command_dat static int nfs_access_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data) { int nfsmode = 0; + ACCESS3args args; if (data->continue_int & R_OK) { nfsmode |= ACCESS3_READ; @@ -2946,7 +3199,12 @@ static int nfs_access_continue_internal(struct nfs_context *nfs, struct nfs_cb_d nfsmode |= ACCESS3_EXECUTE; } - if (rpc_nfs_access_async(nfs->rpc, nfs_access_cb, &data->fh, nfsmode, data) != 0) { + memset(&args, 0, sizeof(ACCESS3args)); + args.object.data.data_len = data->fh.data.data_len; + args.object.data.data_val = data->fh.data.data_val; + args.access = nfsmode; + + if (rpc_nfs3_access_async(nfs->rpc, nfs_access_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send OPEN ACCESS call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -3426,11 +3684,7 @@ uint64_t nfs_get_readmax(struct nfs_context *nfs) */ uint64_t nfs_get_writemax(struct nfs_context *nfs) { - /* Some ZDR libraries can not marshall PDUs bigger than this */ - if (nfs->writemax < 32768) { - return nfs->writemax; - } - return 32768; + return nfs->writemax; } void nfs_set_error(struct nfs_context *nfs, char *error_string, ...)