X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=lib%2Flibnfs.c;h=40b6a8dc18a1c2bd5bec7dc7c0c2ca6f6c5e23e6;hb=440a7dfced274c078b61fdb87301d26a4177fc70;hp=f4e8b0136c5b53b171cb4807153f00c19d3e3736;hpb=84004dbf9bb2ab8a7f8b968affc53ee3065fa911;p=deb_libnfs.git diff --git a/lib/libnfs.c b/lib/libnfs.c index f4e8b01..40b6a8d 100644 --- a/lib/libnfs.c +++ b/lib/libnfs.c @@ -19,6 +19,7 @@ */ #include +#include #include #include #include @@ -33,6 +34,12 @@ #include "libnfs-raw.h" #include "libnfs-raw-mount.h" #include "libnfs-raw-nfs.h" +#include "libnfs-private.h" + +struct nfsdir { + struct nfsdirent *entries; + struct nfsdirent *current; +}; struct nfsfh { struct nfs_fh3 fh; @@ -40,9 +47,13 @@ struct nfsfh { off_t offset; }; -struct nfsdir { - struct nfsdirent *entries; - struct nfsdirent *current; +struct nfs_context { + struct rpc_context *rpc; + char *server; + char *export; + struct nfs_fh3 rootfh; + size_t readmax; + size_t writemax; }; void nfs_free_nfsdir(struct nfsdir *nfsdir) @@ -58,13 +69,6 @@ void nfs_free_nfsdir(struct nfsdir *nfsdir) free(nfsdir); } -struct nfs_context { - struct rpc_context *rpc; - char *server; - char *export; - struct nfs_fh3 rootfh; -}; - struct nfs_cb_data; typedef int (*continue_func)(struct nfs_context *nfs, struct nfs_cb_data *data); @@ -82,6 +86,19 @@ struct nfs_cb_data { int continue_int; struct nfs_fh3 fh; + + /* for multi-read/write calls. */ + int error; + int cancel; + int num_calls; + off_t start_offset, max_offset; + char *buffer; +}; + +struct nfs_mcb_data { + struct nfs_cb_data *data; + off_t offset; + size_t count; }; static int nfs_lookup_path_async_internal(struct nfs_context *nfs, struct nfs_cb_data *data, struct nfs_fh3 *fh); @@ -118,12 +135,10 @@ struct nfs_context *nfs_init_context(void) nfs = malloc(sizeof(struct nfs_context)); if (nfs == NULL) { - printf("Failed to allocate nfs context\n"); return NULL; } nfs->rpc = rpc_init_context(); if (nfs->rpc == NULL) { - printf("Failed to allocate rpc sub-context\n"); free(nfs); return NULL; } @@ -171,6 +186,11 @@ void free_nfs_cb_data(struct nfs_cb_data *data) data->fh.data.data_val = NULL; } + if (data->buffer != NULL) { + free(data->buffer); + data->buffer = NULL; + } + free(data); } @@ -178,7 +198,7 @@ void free_nfs_cb_data(struct nfs_cb_data *data) -static void nfs_mount_9_cb(struct rpc_context *rpc _U_, int status, void *command_data, void *private_data) +static void nfs_mount_10_cb(struct rpc_context *rpc _U_, int status, void *command_data, void *private_data) { struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; @@ -198,10 +218,11 @@ static void nfs_mount_9_cb(struct rpc_context *rpc _U_, int status, void *comman free_nfs_cb_data(data); } -static void nfs_mount_8_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) +static void nfs_mount_9_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; + FSINFO3res *res = command_data; if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); @@ -214,14 +235,40 @@ static void nfs_mount_8_cb(struct rpc_context *rpc, int status, void *command_da return; } + 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) { + data->cb(-ENOMEM, nfs, command_data, data->private_data); + free_nfs_cb_data(data); + return; + } +} + +static void nfs_mount_8_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; + + 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_nfs_getattr_async(rpc, nfs_mount_9_cb, &nfs->rootfh, data) != 0) { + if (rpc_nfs_fsinfo_async(rpc, nfs_mount_9_cb, &nfs->rootfh, data) != 0) { data->cb(-ENOMEM, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } } + 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; @@ -425,8 +472,7 @@ int nfs_mount_async(struct nfs_context *nfs, const char *server, const char *exp data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { - rpc_set_error(nfs->rpc, "out of memory"); - printf("failed to allocate memory for nfs mount data\n"); + rpc_set_error(nfs->rpc, "out of memory. failed to allocate memory for nfs mount data"); return -1; } bzero(data, sizeof(struct nfs_cb_data)); @@ -437,9 +483,9 @@ int nfs_mount_async(struct nfs_context *nfs, const char *server, const char *exp data->private_data = private_data; if (rpc_connect_async(nfs->rpc, server, 111, nfs_mount_1_cb, data) != 0) { - printf("Failed to start connection\n"); + rpc_set_error(nfs->rpc, "Failed to start connection"); free_nfs_cb_data(data); - return -4; + return -1; } return 0; @@ -538,9 +584,7 @@ static int nfs_lookuppath_async(struct nfs_context *nfs, const char *path, nfs_c data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_cb_data structure"); - printf("failed to allocate memory for nfs cb data\n"); - free_nfs_cb_data(data); - return -2; + return -1; } bzero(data, sizeof(struct nfs_cb_data)); data->nfs = nfs; @@ -553,14 +597,12 @@ static int nfs_lookuppath_async(struct nfs_context *nfs, const char *path, nfs_c data->saved_path = strdup(path); if (data->saved_path == NULL) { rpc_set_error(nfs->rpc, "out of memory: failed to copy path string"); - printf("failed to allocate memory for path string\n"); free_nfs_cb_data(data); - return -2; + return -1; } data->path = data->saved_path; if (nfs_lookup_path_async_internal(nfs, data, &nfs->rootfh) != 0) { - printf("failed to lookup path\n"); /* return 0 here since the callback will be invoked if there is a failure */ return 0; } @@ -632,7 +674,7 @@ static int nfs_stat_continue_internal(struct nfs_context *nfs, struct nfs_cb_dat int nfs_stat_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data) { if (nfs_lookuppath_async(nfs, path, cb, private_data, nfs_stat_continue_internal, NULL, NULL, 0) != 0) { - printf("Out of memory: failed to start parsing the path components\n"); + rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } @@ -745,8 +787,8 @@ static int nfs_open_continue_internal(struct nfs_context *nfs, struct nfs_cb_dat int nfs_open_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data) { if (nfs_lookuppath_async(nfs, path, cb, private_data, nfs_open_continue_internal, NULL, NULL, mode) != 0) { - printf("Out of memory: failed to start parsing the path components\n"); - return -2; + rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); + return -1; } return 0; @@ -789,6 +831,64 @@ static void nfs_pread_cb(struct rpc_context *rpc _U_, int status, void *command_ free_nfs_cb_data(data); } +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 ((unsigned)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); +} + int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, size_t count, nfs_cb cb, void *private_data) { struct nfs_cb_data *data; @@ -796,8 +896,6 @@ int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_cb_data structure"); - printf("failed to allocate memory for nfs cb data\n"); - free_nfs_cb_data(data); return -1; } bzero(data, sizeof(struct nfs_cb_data)); @@ -807,13 +905,62 @@ int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, data->nfsfh = nfsfh; nfsfh->offset = offset; - if (rpc_nfs_read_async(nfs->rpc, nfs_pread_cb, &nfsfh->fh, offset, count, data) != 0) { - rpc_set_error(nfs->rpc, "RPC error: Failed to send READ call for %s", data->path); + + if (count <= nfs_get_readmax(nfs)) { + if (rpc_nfs_read_async(nfs->rpc, nfs_pread_cb, &nfsfh->fh, offset, count, 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); + return -1; + } + return 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. + * we send all reads in parallell so that performance is still good. + */ + data->start_offset = offset; + + data->buffer = malloc(count); + if (data->buffer == NULL) { + rpc_set_error(nfs->rpc, "Out-Of-Memory: Failed to allocate reassembly buffer for %d bytes", (int)count); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } - return 0; + + while (count > 0) { + size_t readcount = count; + struct nfs_mcb_data *mdata; + + if (readcount > nfs_get_readmax(nfs)) { + readcount = nfs_get_readmax(nfs); + } + + mdata = malloc(sizeof(struct nfs_mcb_data)); + if (mdata == NULL) { + rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_mcb_data structure"); + return -1; + } + bzero(mdata, sizeof(struct nfs_mcb_data)); + 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) { + 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); + return -1; + } + + count -= readcount; + offset += readcount; + data->num_calls++; + } + + return 0; } /* @@ -866,8 +1013,6 @@ int nfs_pwrite_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_cb_data structure"); - printf("failed to allocate memory for nfs cb data\n"); - free_nfs_cb_data(data); return -1; } bzero(data, sizeof(struct nfs_cb_data)); @@ -927,8 +1072,6 @@ int nfs_fstat_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, voi data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_cb_data structure"); - printf("failed to allocate memory for nfs cb data\n"); - free_nfs_cb_data(data); return -1; } bzero(data, sizeof(struct nfs_cb_data)); @@ -986,8 +1129,6 @@ int nfs_fsync_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, voi data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_cb_data structure"); - printf("failed to allocate memory for nfs cb data\n"); - free_nfs_cb_data(data); return -1; } bzero(data, sizeof(struct nfs_cb_data)); @@ -1047,8 +1188,6 @@ int nfs_ftruncate_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t leng data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_cb_data structure"); - printf("failed to allocate memory for nfs cb data\n"); - free_nfs_cb_data(data); return -1; } bzero(data, sizeof(struct nfs_cb_data)); @@ -1100,8 +1239,8 @@ int nfs_truncate_async(struct nfs_context *nfs, const char *path, off_t length, offset = length; if (nfs_lookuppath_async(nfs, path, cb, private_data, nfs_truncate_continue_internal, NULL, NULL, offset) != 0) { - printf("Out of memory: failed to start parsing the path components\n"); - return -2; + rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); + return -1; } return 0; @@ -1167,21 +1306,21 @@ int nfs_mkdir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void * new_path = strdup(path); if (new_path == NULL) { - printf("Out of memory, failed to allocate mode buffer for path\n"); + rpc_set_error(nfs->rpc, "Out of memory, failed to allocate mode buffer for path"); return -1; } ptr = rindex(new_path, '/'); if (ptr == NULL) { - printf("Invalid path %s\n", path); - return -2; + rpc_set_error(nfs->rpc, "Invalid path %s", path); + return -1; } *ptr = 0; /* new_path now points to the parent directory, and beyond the nul terminateor is the new directory to create */ if (nfs_lookuppath_async(nfs, new_path, cb, private_data, nfs_mkdir_continue_internal, new_path, free, 0) != 0) { - printf("Out of memory: failed to start parsing the path components\n"); - return -3; + rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path component"); + return -1; } return 0; @@ -1248,21 +1387,21 @@ int nfs_rmdir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void * new_path = strdup(path); if (new_path == NULL) { - printf("Out of memory, failed to allocate mode buffer for path\n"); + rpc_set_error(nfs->rpc, "Out of memory, failed to allocate mode buffer for path"); return -1; } ptr = rindex(new_path, '/'); if (ptr == NULL) { - printf("Invalid path %s\n", path); - return -2; + rpc_set_error(nfs->rpc, "Invalid path %s", path); + return -1; } *ptr = 0; /* new_path now points to the parent directory, and beyond the nul terminateor is the new directory to create */ if (nfs_lookuppath_async(nfs, new_path, cb, private_data, nfs_rmdir_continue_internal, new_path, free, 0) != 0) { - printf("Out of memory: failed to start parsing the path components\n"); - return -3; + rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); + return -1; } return 0; @@ -1380,21 +1519,21 @@ int nfs_creat_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb new_path = strdup(path); if (new_path == NULL) { - printf("Out of memory, failed to allocate mode buffer for path\n"); + rpc_set_error(nfs->rpc, "Out of memory, failed to allocate mode buffer for path"); return -1; } ptr = rindex(new_path, '/'); if (ptr == NULL) { - printf("Invalid path %s\n", path); - return -2; + rpc_set_error(nfs->rpc, "Invalid path %s", path); + return -1; } *ptr = 0; /* new_path now points to the parent directory, and beyond the nul terminateor 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) { - printf("Out of memory: failed to start parsing the path components\n"); - return -3; + rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); + return -1; } return 0; @@ -1460,21 +1599,21 @@ int nfs_unlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void new_path = strdup(path); if (new_path == NULL) { - printf("Out of memory, failed to allocate mode buffer for path\n"); + rpc_set_error(nfs->rpc, "Out of memory, failed to allocate mode buffer for path"); return -1; } ptr = rindex(new_path, '/'); if (ptr == NULL) { - printf("Invalid path %s\n", path); - return -2; + rpc_set_error(nfs->rpc, "Invalid path %s", path); + return -1; } *ptr = 0; /* new_path now points to the parent directory, and beyond the nul terminateor is the new directory to create */ if (nfs_lookuppath_async(nfs, new_path, cb, private_data, nfs_unlink_continue_internal, new_path, free, 0) != 0) { - printf("Out of memory: failed to start parsing the path components\n"); - return -3; + rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); + return -1; } return 0; @@ -1590,14 +1729,14 @@ int nfs_opendir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void nfsdir = malloc(sizeof(struct nfsdir)); if (nfsdir == NULL) { - printf("failed to allocate buffer for nfsdir\n"); + rpc_set_error(nfs->rpc, "failed to allocate buffer for nfsdir"); return -1; } bzero(nfsdir, sizeof(struct nfsdir)); if (nfs_lookuppath_async(nfs, path, cb, private_data, nfs_opendir_continue_internal, nfsdir, free, 0) != 0) { - printf("Out of memory: failed to start parsing the path components\n"); - return -2; + rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); + return -1; } return 0; @@ -1697,7 +1836,7 @@ int nfs_lseek_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, if (rpc_nfs_getattr_async(nfs->rpc, nfs_lseek_1_cb, &nfsfh->fh, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send LSEEK GETATTR call"); free(data); - return -2; + return -1; } return 0; } @@ -1764,7 +1903,7 @@ static int nfs_statvfs_continue_internal(struct nfs_context *nfs, struct nfs_cb_ int nfs_statvfs_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data) { if (nfs_lookuppath_async(nfs, path, cb, private_data, nfs_statvfs_continue_internal, NULL, NULL, 0) != 0) { - printf("Out of memory: failed to start parsing the path components\n"); + rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } @@ -1821,7 +1960,7 @@ static int nfs_readlink_continue_internal(struct nfs_context *nfs, struct nfs_cb int nfs_readlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data) { if (nfs_lookuppath_async(nfs, path, cb, private_data, nfs_readlink_continue_internal, NULL, NULL, 0) != 0) { - printf("Out of memory: failed to start parsing the path components\n"); + rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } @@ -1886,7 +2025,7 @@ static int nfs_chmod_continue_internal(struct nfs_context *nfs, struct nfs_cb_da int nfs_chmod_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data) { if (nfs_lookuppath_async(nfs, path, cb, private_data, nfs_chmod_continue_internal, NULL, NULL, mode) != 0) { - printf("Out of memory: failed to start parsing the path components\n"); + rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } @@ -1902,8 +2041,7 @@ int nfs_fchmod_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int mode, nfs data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { - rpc_set_error(nfs->rpc, "out of memory"); - printf("failed to allocate memory for nfs mount data\n"); + rpc_set_error(nfs->rpc, "out of memory. failed to allocate memory for nfs mount data"); return -1; } bzero(data, sizeof(struct nfs_cb_data)); @@ -2000,7 +2138,7 @@ int nfs_chown_async(struct nfs_context *nfs, const char *path, int uid, int gid, chown_data = malloc(sizeof(struct nfs_chown_data)); if (chown_data == NULL) { - printf("Failed to allocate memory for chown data structure\n"); + rpc_set_error(nfs->rpc, "Failed to allocate memory for chown data structure"); return -1; } @@ -2008,7 +2146,7 @@ int nfs_chown_async(struct nfs_context *nfs, const char *path, int uid, int gid, chown_data->gid = gid; if (nfs_lookuppath_async(nfs, path, cb, private_data, nfs_chown_continue_internal, chown_data, free, 0) != 0) { - printf("Out of memory: failed to start parsing the path components\n"); + rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } @@ -2026,7 +2164,7 @@ int nfs_fchown_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid, int chown_data = malloc(sizeof(struct nfs_chown_data)); if (chown_data == NULL) { - printf("Failed to allocate memory for chown data structure\n"); + rpc_set_error(nfs->rpc, "Failed to allocate memory for chown data structure"); return -1; } @@ -2036,8 +2174,7 @@ int nfs_fchown_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid, int data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { - rpc_set_error(nfs->rpc, "out of memory"); - printf("failed to allocate memory for fchown data\n"); + rpc_set_error(nfs->rpc, "out of memory. failed to allocate memory for fchown data"); return -1; } bzero(data, sizeof(struct nfs_cb_data)); @@ -2136,7 +2273,7 @@ int nfs_utimes_async(struct nfs_context *nfs, const char *path, struct timeval * if (times != NULL) { new_times = malloc(sizeof(struct timeval)*2); if (new_times == NULL) { - printf("Failed to allocate memory for timeval structure\n"); + rpc_set_error(nfs->rpc, "Failed to allocate memory for timeval structure"); return -1; } @@ -2144,7 +2281,7 @@ int nfs_utimes_async(struct nfs_context *nfs, const char *path, struct timeval * } if (nfs_lookuppath_async(nfs, path, cb, private_data, nfs_utimes_continue_internal, new_times, free, 0) != 0) { - printf("Out of memory: failed to start parsing the path components\n"); + rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } @@ -2161,7 +2298,7 @@ int nfs_utime_async(struct nfs_context *nfs, const char *path, struct utimbuf *t if (times != NULL) { new_times = malloc(sizeof(struct timeval)*2); if (new_times == NULL) { - printf("Failed to allocate memory for timeval structure\n"); + rpc_set_error(nfs->rpc, "Failed to allocate memory for timeval structure"); return -1; } @@ -2172,7 +2309,7 @@ int nfs_utime_async(struct nfs_context *nfs, const char *path, struct utimbuf *t } if (nfs_lookuppath_async(nfs, path, cb, private_data, nfs_utimes_continue_internal, new_times, free, 0) != 0) { - printf("Out of memory: failed to start parsing the path components\n"); + rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } @@ -2265,8 +2402,8 @@ static int nfs_access_continue_internal(struct nfs_context *nfs, struct nfs_cb_d int nfs_access_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data) { if (nfs_lookuppath_async(nfs, path, cb, private_data, nfs_access_continue_internal, NULL, NULL, mode) != 0) { - printf("Out of memory: failed to start parsing the path components\n"); - return -2; + rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); + return -1; } return 0; @@ -2349,44 +2486,44 @@ int nfs_symlink_async(struct nfs_context *nfs, const char *oldpath, const char * symlink_data = malloc(sizeof(struct nfs_symlink_data)); if (symlink_data == NULL) { - printf("Out of memory, failed to allocate buffer for symlink data\n"); + rpc_set_error(nfs->rpc, "Out of memory, failed to allocate buffer for symlink data"); return -1; } bzero(symlink_data, sizeof(struct nfs_symlink_data)); symlink_data->oldpath = strdup(oldpath); if (symlink_data->oldpath == NULL) { - printf("Out of memory, failed to allocate buffer for oldpath\n"); + rpc_set_error(nfs->rpc, "Out of memory, failed to allocate buffer for oldpath"); free_nfs_symlink_data(symlink_data); - return -2; + return -1; } symlink_data->newpathparent = strdup(newpath); if (symlink_data->newpathparent == NULL) { - printf("Out of memory, failed to allocate mode buffer for new path\n"); + rpc_set_error(nfs->rpc, "Out of memory, failed to allocate mode buffer for new path"); free_nfs_symlink_data(symlink_data); - return -3; + return -1; } ptr = rindex(symlink_data->newpathparent, '/'); if (ptr == NULL) { - printf("Invalid path %s\n", oldpath); + rpc_set_error(nfs->rpc, "Invalid path %s", oldpath); free_nfs_symlink_data(symlink_data); - return -4; + return -1; } *ptr = 0; ptr++; symlink_data->newpathobject = strdup(ptr); if (symlink_data->newpathobject == NULL) { - printf("Out of memory, failed to allocate mode buffer for new path\n"); + rpc_set_error(nfs->rpc, "Out of memory, failed to allocate mode buffer for new path"); free_nfs_symlink_data(symlink_data); - return -5; + return -1; } if (nfs_lookuppath_async(nfs, symlink_data->newpathparent, cb, private_data, nfs_symlink_continue_internal, symlink_data, free_nfs_symlink_data, 0) != 0) { - printf("Out of memory: failed to start parsing the path components\n"); - return -6; + rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); + return -1; } return 0; @@ -2503,22 +2640,22 @@ int nfs_rename_async(struct nfs_context *nfs, const char *oldpath, const char *n rename_data = malloc(sizeof(struct nfs_rename_data)); if (rename_data == NULL) { - printf("Out of memory, failed to allocate buffer for rename data\n"); + rpc_set_error(nfs->rpc, "Out of memory, failed to allocate buffer for rename data"); return -1; } bzero(rename_data, sizeof(struct nfs_rename_data)); rename_data->oldpath = strdup(oldpath); if (rename_data->oldpath == NULL) { - printf("Out of memory, failed to allocate buffer for oldpath\n"); + rpc_set_error(nfs->rpc, "Out of memory, failed to allocate buffer for oldpath"); free_nfs_rename_data(rename_data); - return -2; + return -1; } ptr = rindex(rename_data->oldpath, '/'); if (ptr == NULL) { - printf("Invalid path %s\n", oldpath); + rpc_set_error(nfs->rpc, "Invalid path %s", oldpath); free_nfs_rename_data(rename_data); - return -3; + return -1; } *ptr = 0; ptr++; @@ -2527,15 +2664,15 @@ int nfs_rename_async(struct nfs_context *nfs, const char *oldpath, const char *n rename_data->newpath = strdup(newpath); if (rename_data->newpath == NULL) { - printf("Out of memory, failed to allocate buffer for newpath\n"); + rpc_set_error(nfs->rpc, "Out of memory, failed to allocate buffer for newpath"); free_nfs_rename_data(rename_data); - return -4; + return -1; } ptr = rindex(rename_data->newpath, '/'); if (ptr == NULL) { - printf("Invalid path %s\n", newpath); + rpc_set_error(nfs->rpc, "Invalid path %s", newpath); free_nfs_rename_data(rename_data); - return -5; + return -1; } *ptr = 0; ptr++; @@ -2543,8 +2680,8 @@ int nfs_rename_async(struct nfs_context *nfs, const char *oldpath, const char *n if (nfs_lookuppath_async(nfs, rename_data->oldpath, cb, private_data, nfs_rename_continue_1_internal, rename_data, free_nfs_rename_data, 0) != 0) { - printf("Out of memory: failed to start parsing the path components\n"); - return -6; + rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); + return -1; } return 0; @@ -2659,29 +2796,29 @@ int nfs_link_async(struct nfs_context *nfs, const char *oldpath, const char *new link_data = malloc(sizeof(struct nfs_link_data)); if (link_data == NULL) { - printf("Out of memory, failed to allocate buffer for link data\n"); + rpc_set_error(nfs->rpc, "Out of memory, failed to allocate buffer for link data"); return -1; } bzero(link_data, sizeof(struct nfs_link_data)); link_data->oldpath = strdup(oldpath); if (link_data->oldpath == NULL) { - printf("Out of memory, failed to allocate buffer for oldpath\n"); + rpc_set_error(nfs->rpc, "Out of memory, failed to allocate buffer for oldpath"); free_nfs_link_data(link_data); - return -2; + return -1; } link_data->newpath = strdup(newpath); if (link_data->newpath == NULL) { - printf("Out of memory, failed to allocate buffer for newpath\n"); + rpc_set_error(nfs->rpc, "Out of memory, failed to allocate buffer for newpath"); free_nfs_link_data(link_data); - return -4; + return -1; } ptr = rindex(link_data->newpath, '/'); if (ptr == NULL) { - printf("Invalid path %s\n", newpath); + rpc_set_error(nfs->rpc, "Invalid path %s", newpath); free_nfs_link_data(link_data); - return -5; + return -1; } *ptr = 0; ptr++; @@ -2689,8 +2826,8 @@ int nfs_link_async(struct nfs_context *nfs, const char *oldpath, const char *new if (nfs_lookuppath_async(nfs, link_data->oldpath, cb, private_data, nfs_link_continue_1_internal, link_data, free_nfs_link_data, 0) != 0) { - printf("Out of memory: failed to start parsing the path components\n"); - return -6; + rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); + return -1; } return 0; @@ -2703,3 +2840,34 @@ off_t nfs_get_current_offset(struct nfsfh *nfsfh) return nfsfh->offset; } + + +/* + * Get the maximum supported READ3 size by the server + */ +size_t nfs_get_readmax(struct nfs_context *nfs) +{ + return nfs->readmax; +} + +/* + * Get the maximum supported WRITE3 size by the server + */ +size_t nfs_get_writemax(struct nfs_context *nfs) +{ + return nfs->writemax; +} + +void nfs_set_error(struct nfs_context *nfs, char *error_string, ...) +{ + va_list ap; + char *str; + + if (nfs->rpc->error_string != NULL) { + free(nfs->rpc->error_string); + } + va_start(ap, error_string); + vasprintf(&str, error_string, ap); + nfs->rpc->error_string = str; + va_end(ap); +}