From 29b4cea00fd32656b60eb96b878da07c5f0d81a2 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Tue, 11 Jan 2022 18:22:44 +1000 Subject: [PATCH] multithreading: make nfs_get_error() work for multithreaded applications This mostly consists of creating one slave nfs_context for each nfs thread to track the error-string. Signed-off-by: Ronnie Sahlberg --- .gitignore | 15 ++ examples/nfs-io.c | 2 +- examples/nfs-pthreads-fstat.c | 2 +- include/libnfs-multithreading.h | 3 + include/libnfs-private.h | 55 ++-- lib/libnfs-sync.c | 132 +++++---- lib/libnfs.c | 325 +++++++++++++---------- lib/multithreading.c | 37 ++- lib/nfs_v3.c | 133 +++++----- lib/nfs_v4.c | 92 ++++--- win32/libnfs/x64/Debug/libnfs.dll.recipe | 11 + 11 files changed, 469 insertions(+), 338 deletions(-) create mode 100644 win32/libnfs/x64/Debug/libnfs.dll.recipe diff --git a/.gitignore b/.gitignore index e520777..3bc91ac 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,18 @@ stamp-h1 libnfs.pc !libnfs.pc.in build +/win32/libnfs/x64/Debug/libnfs.tlog/CL.command.1.tlog +/win32/libnfs/x64/Debug/libnfs.tlog/libnfs.lastbuildstate +/win32/libnfs/x64/Debug/libnfs.tlog/unsuccessfulbuild +/win32/libnfs/x64/Debug/libnfs.log +/win32/libnfs/x64/Debug/vc143.idb +/win32/nfs-cp/x64/Debug/nfs-cp.tlog/CL.command.1.tlog +*.tlog +/win32/nfs-cp/x64/Debug/nfs-cp.exe.recipe +/win32/nfs-cp/x64/Debug/nfs-cp.log +/win32/nfs-cp/x64/Debug/vc143.idb +/win32/nfs-ls/x64/Debug/nfs-ls.exe.recipe +/win32/nfs-ls/x64/Debug/nfs-ls.log +/win32/nfs-ls/x64/Debug/vc143.idb +/win32/libnfs/x64/Debug/libnfs.vcxproj.FileListAbsolute.txt +/win32/libnfs/x64/Debug/version.res diff --git a/examples/nfs-io.c b/examples/nfs-io.c index 49106af..5bde80d 100644 --- a/examples/nfs-io.c +++ b/examples/nfs-io.c @@ -208,7 +208,7 @@ int main(int argc, char *argv[]) } else if (!strncmp(argv[1], "acl", 3)) { ret = nfs_open(nfs, url->file, 0600, &nfsfh); if (ret != 0) { - printf("failed to open %s\n", url->file); + printf("failed to open %s. %s\n", url->file, nfs_get_error(nfs)); goto finished; } diff --git a/examples/nfs-pthreads-fstat.c b/examples/nfs-pthreads-fstat.c index fcdfb85..a239b34 100644 --- a/examples/nfs-pthreads-fstat.c +++ b/examples/nfs-pthreads-fstat.c @@ -82,7 +82,7 @@ static void *nfs_stat_thread(void *arg) while(!sd->is_finished) { ret = nfs_open(sd->nfs, sd->path, 0600, &nfsfh); if (ret != 0) { - printf("failed to open %s\n", sd->path); + printf("failed to open %s. %s\n", sd->path, nfs_get_error(sd->nfs)); exit(10); } if (nfsfh == NULL) { diff --git a/include/libnfs-multithreading.h b/include/libnfs-multithreading.h index c05a7c7..79433b6 100644 --- a/include/libnfs-multithreading.h +++ b/include/libnfs-multithreading.h @@ -35,14 +35,17 @@ extern "C" { typedef pthread_t libnfs_thread_t; typedef pthread_mutex_t libnfs_mutex_t; typedef sem_t libnfs_sem_t; +typedef pid_t nfs_tid_t; #endif /* HAVE_PTHREAD */ #ifdef WIN32 typedef HANDLE libnfs_thread_t; typedef HANDLE libnfs_mutex_t; typedef HANDLE libnfs_sem_t; +typedef DWORD nfs_tid_t; #endif +nfs_tid_t nfs_mt_get_tid(void); int nfs_mt_mutex_init(libnfs_mutex_t *mutex); int nfs_mt_mutex_destroy(libnfs_mutex_t *mutex); int nfs_mt_mutex_lock(libnfs_mutex_t *mutex); diff --git a/include/libnfs-private.h b/include/libnfs-private.h index c3c4e2d..255c2fd 100644 --- a/include/libnfs-private.h +++ b/include/libnfs-private.h @@ -287,40 +287,57 @@ struct nfs_fh { char *val; }; -struct nfs_context { - struct rpc_context *rpc; +struct nfs_context_internal { char *server; char *export; + char *cwd; struct nfs_fh rootfh; uint64_t readmax; uint64_t writemax; - char *cwd; - int dircache_enabled; int auto_reconnect; + int dircache_enabled; struct nfsdir *dircache; uint16_t mask; - int auto_traverse_mounts; struct nested_mounts *nested_mounts; + int version; + int nfsport; + int mountport; - int version; - int nfsport; - int mountport; - - /* NFSv4 specific fields */ - verifier4 verifier; - char *client_name; - uint64_t clientid; - verifier4 setclientid_confirm; - uint32_t open_counter; - int has_lock_owner; + /* NFSv4 specific fields */ + verifier4 verifier; + char *client_name; + uint64_t clientid; + verifier4 setclientid_confirm; + uint32_t open_counter; + int has_lock_owner; #ifdef HAVE_MULTITHREADING - int multithreading_enabled; - libnfs_thread_t service_thread; - libnfs_mutex_t nfs4_open_mutex; + int multithreading_enabled; + libnfs_thread_t service_thread; + libnfs_mutex_t nfs_mutex; + libnfs_mutex_t nfs4_open_mutex; + struct nfs_thread_context *thread_ctx; +#endif /* HAVE_MULTITHREADING */ +}; + +struct nfs_context { + struct rpc_context *rpc; + struct nfs_context_internal *nfsi; + char *error_string; + +#ifdef HAVE_MULTITHREADING + struct nfs_context *master_ctx; #endif /* HAVE_MULTITHREADING */ }; +#ifdef HAVE_MULTITHREADING +struct nfs_thread_context { + struct nfs_thread_context *next; + nfs_tid_t tid; + struct nfs_context nfs; +}; +#endif /* HAVE_MULTITHREADING */ + typedef int (*continue_func)(struct nfs_context *nfs, struct nfs_attr *attr, struct nfs_cb_data *data); diff --git a/lib/libnfs-sync.c b/lib/libnfs-sync.c index 4a01549..557935f 100644 --- a/lib/libnfs-sync.c +++ b/lib/libnfs-sync.c @@ -121,18 +121,46 @@ struct sync_cb_data { }; static inline int -nfs_init_cb_data(struct nfs_context *nfs, struct sync_cb_data *cb_data) +nfs_init_cb_data(struct nfs_context **nfs, struct sync_cb_data *cb_data) { cb_data->is_finished = 0; #ifdef HAVE_MULTITHREADING + if (nfs && (*nfs)->nfsi->multithreading_enabled && (*nfs)->master_ctx == NULL) { + struct nfs_thread_context *ntc; + + for(ntc = (*nfs)->nfsi->thread_ctx; ntc; ntc = ntc->next) { + if (nfs_mt_get_tid() == ntc->tid) { + break; + } + } + if (ntc) { + *nfs = &ntc->nfs; + } else { + ntc = calloc(1, sizeof(struct nfs_thread_context)); + if (ntc == NULL) { + return -1; + } + nfs_mt_mutex_lock(&(*nfs)->rpc->rpc_mutex); + ntc->next = (*nfs)->nfsi->thread_ctx; + ntc->tid = nfs_mt_get_tid(); + (*nfs)->nfsi->thread_ctx = ntc; + nfs_mt_mutex_unlock(&(*nfs)->rpc->rpc_mutex); + memcpy(&ntc->nfs, *nfs, sizeof(struct nfs_context)); + ntc->nfs.error_string = NULL; + ntc->nfs.master_ctx = *nfs; + + *nfs = &ntc->nfs; + } + } + /* * Create a semaphore and initialize it to zero. So that we * can wait for it and immetiately block until the service thread * has received the reply. */ if (nfs_mt_sem_init(&cb_data->wait_sem, 0)) { - if (nfs) { - nfs_set_error(nfs, "Failed to initialize semaphore"); + if (nfs && *nfs) { + nfs_set_error(*nfs, "Failed to initialize semaphore"); } return -1; } @@ -232,7 +260,7 @@ wait_for_nfs_reply(struct nfs_context *nfs, struct sync_cb_data *cb_data) int ret; #ifdef HAVE_MULTITHREADING - if(nfs->multithreading_enabled) { + if(nfs->nfsi->multithreading_enabled) { nfs_mt_sem_wait(&cb_data->wait_sem); return; } @@ -288,7 +316,7 @@ nfs_mount(struct nfs_context *nfs, const char *server, const char *export) assert(rpc->magic == RPC_CONTEXT_MAGIC); - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -343,7 +371,7 @@ nfs_umount(struct nfs_context *nfs) assert(rpc->magic == RPC_CONTEXT_MAGIC); - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -405,7 +433,7 @@ nfs_stat(struct nfs_context *nfs, const char *path, struct stat *st) struct sync_cb_data cb_data; cb_data.return_data = st; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -443,7 +471,7 @@ nfs_stat64(struct nfs_context *nfs, const char *path, struct nfs_stat_64 *st) struct sync_cb_data cb_data; cb_data.return_data = st; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -466,7 +494,7 @@ nfs_lstat64(struct nfs_context *nfs, const char *path, struct nfs_stat_64 *st) struct sync_cb_data cb_data; cb_data.return_data = st; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -513,7 +541,7 @@ nfs_open(struct nfs_context *nfs, const char *path, int flags, struct sync_cb_data cb_data; cb_data.return_data = nfsfh; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -537,7 +565,7 @@ nfs_open2(struct nfs_context *nfs, const char *path, int flags, struct sync_cb_data cb_data; cb_data.return_data = nfsfh; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -577,7 +605,7 @@ nfs_chdir(struct nfs_context *nfs, const char *path) { struct sync_cb_data cb_data; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -625,7 +653,7 @@ nfs_pread(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, cb_data.return_data = buffer; cb_data.call = "pread"; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -654,7 +682,7 @@ nfs_read(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t count, cb_data.return_data = buffer; cb_data.call = "read"; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -694,7 +722,7 @@ nfs_close(struct nfs_context *nfs, struct nfsfh *nfsfh) { struct sync_cb_data cb_data; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -725,7 +753,7 @@ nfs_fstat(struct nfs_context *nfs, struct nfsfh *nfsfh, struct stat *st) struct sync_cb_data cb_data; cb_data.return_data = st; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -751,7 +779,7 @@ nfs_fstat64(struct nfs_context *nfs, struct nfsfh *nfsfh, struct sync_cb_data cb_data; cb_data.return_data = st; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -794,7 +822,7 @@ nfs_pwrite(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, struct sync_cb_data cb_data; cb_data.call = "pwrite"; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -822,7 +850,7 @@ nfs_write(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t count, struct sync_cb_data cb_data; cb_data.call = "write"; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -863,7 +891,7 @@ nfs_fsync(struct nfs_context *nfs, struct nfsfh *nfsfh) { struct sync_cb_data cb_data; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -905,7 +933,7 @@ nfs_ftruncate(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t length) { struct sync_cb_data cb_data; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -947,7 +975,7 @@ int nfs_truncate(struct nfs_context *nfs, const char *path, uint64_t length) { struct sync_cb_data cb_data; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -988,7 +1016,7 @@ nfs_mkdir(struct nfs_context *nfs, const char *path) { struct sync_cb_data cb_data; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -1010,7 +1038,7 @@ nfs_mkdir2(struct nfs_context *nfs, const char *path, int mode) { struct sync_cb_data cb_data; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -1051,7 +1079,7 @@ int nfs_rmdir(struct nfs_context *nfs, const char *path) { struct sync_cb_data cb_data; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -1100,7 +1128,7 @@ nfs_create(struct nfs_context *nfs, const char *path, int flags, int mode, struct sync_cb_data cb_data; cb_data.return_data = nfsfh; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -1147,7 +1175,7 @@ nfs_mknod(struct nfs_context *nfs, const char *path, int mode, int dev) { struct sync_cb_data cb_data; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -1188,7 +1216,7 @@ nfs_unlink(struct nfs_context *nfs, const char *path) { struct sync_cb_data cb_data; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -1236,7 +1264,7 @@ nfs_opendir(struct nfs_context *nfs, const char *path, struct nfsdir **nfsdir) struct sync_cb_data cb_data; cb_data.return_data = nfsdir; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -1282,7 +1310,7 @@ nfs_lseek(struct nfs_context *nfs, struct nfsfh *nfsfh, int64_t offset, int when struct sync_cb_data cb_data; cb_data.return_data = current_offset; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -1325,7 +1353,7 @@ nfs_lockf(struct nfs_context *nfs, struct nfsfh *nfsfh, { struct sync_cb_data cb_data; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -1367,7 +1395,7 @@ nfs_fcntl(struct nfs_context *nfs, struct nfsfh *nfsfh, { struct sync_cb_data cb_data; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -1411,7 +1439,7 @@ nfs_statvfs(struct nfs_context *nfs, const char *path, struct statvfs *svfs) struct sync_cb_data cb_data; cb_data.return_data = svfs; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -1456,7 +1484,7 @@ nfs_statvfs64(struct nfs_context *nfs, const char *path, struct sync_cb_data cb_data; cb_data.return_data = svfs; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -1506,7 +1534,7 @@ nfs_readlink(struct nfs_context *nfs, const char *path, char *buf, int bufsize) cb_data.return_data = buf; cb_data.return_int = bufsize; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -1557,7 +1585,7 @@ nfs_readlink2(struct nfs_context *nfs, const char *path, char **bufptr) *bufptr = NULL; cb_data.return_data = bufptr; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -1598,7 +1626,7 @@ nfs_chmod(struct nfs_context *nfs, const char *path, int mode) { struct sync_cb_data cb_data; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -1620,7 +1648,7 @@ nfs_lchmod(struct nfs_context *nfs, const char *path, int mode) { struct sync_cb_data cb_data; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -1663,7 +1691,7 @@ nfs_fchmod(struct nfs_context *nfs, struct nfsfh *nfsfh, int mode) { struct sync_cb_data cb_data; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -1706,7 +1734,7 @@ nfs_chown(struct nfs_context *nfs, const char *path, int uid, int gid) { struct sync_cb_data cb_data; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -1731,7 +1759,7 @@ nfs_lchown(struct nfs_context *nfs, const char *path, int uid, int gid) { struct sync_cb_data cb_data; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -1771,7 +1799,7 @@ nfs_fchown(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid, int gid) { struct sync_cb_data cb_data; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -1813,7 +1841,7 @@ nfs_utimes(struct nfs_context *nfs, const char *path, struct timeval *times) { struct sync_cb_data cb_data; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -1835,7 +1863,7 @@ nfs_lutimes(struct nfs_context *nfs, const char *path, struct timeval *times) { struct sync_cb_data cb_data; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -1877,7 +1905,7 @@ nfs_utime(struct nfs_context *nfs, const char *path, struct utimbuf *times) { struct sync_cb_data cb_data; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -1917,7 +1945,7 @@ nfs_access(struct nfs_context *nfs, const char *path, int mode) { struct sync_cb_data cb_data; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -1959,7 +1987,7 @@ nfs_access2(struct nfs_context *nfs, const char *path) { struct sync_cb_data cb_data; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -2001,7 +2029,7 @@ nfs_symlink(struct nfs_context *nfs, const char *target, const char *linkname) { struct sync_cb_data cb_data; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -2043,7 +2071,7 @@ nfs_rename(struct nfs_context *nfs, const char *oldpath, const char *newpath) { struct sync_cb_data cb_data; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -2085,7 +2113,7 @@ nfs_link(struct nfs_context *nfs, const char *oldpath, const char *newpath) { struct sync_cb_data cb_data; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -2146,7 +2174,7 @@ nfs3_getacl(struct nfs_context *nfs, struct nfsfh *nfsfh, struct sync_cb_data cb_data; cb_data.return_data = acl; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } @@ -2225,7 +2253,7 @@ nfs4_getacl(struct nfs_context *nfs, struct nfsfh *nfsfh, struct sync_cb_data cb_data; cb_data.return_data = acl; - if (nfs_init_cb_data(nfs, &cb_data)) { + if (nfs_init_cb_data(&nfs, &cb_data)) { return -1; } diff --git a/lib/libnfs.c b/lib/libnfs.c index e8b4daa..5a5836f 100755 --- a/lib/libnfs.c +++ b/lib/libnfs.c @@ -109,15 +109,21 @@ void nfs_dircache_add(struct nfs_context *nfs, struct nfsdir *nfsdir) { int i = 0; - LIBNFS_LIST_ADD(&nfs->dircache, nfsdir); +#ifdef HAVE_MULTITHREADING + nfs_mt_mutex_lock(&nfs->rpc->rpc_mutex); +#endif + LIBNFS_LIST_ADD(&nfs->nfsi->dircache, nfsdir); - for (nfsdir = nfs->dircache; nfsdir; nfsdir = nfsdir->next, i++) { + for (nfsdir = nfs->nfsi->dircache; nfsdir; nfsdir = nfsdir->next, i++) { if (i > MAX_DIR_CACHE) { - LIBNFS_LIST_REMOVE(&nfs->dircache, nfsdir); + LIBNFS_LIST_REMOVE(&nfs->nfsi->dircache, nfsdir); nfs_free_nfsdir(nfsdir); break; } } +#ifdef HAVE_MULTITHREADING + nfs_mt_mutex_unlock(&nfs->rpc->rpc_mutex); +#endif } struct nfsdir * @@ -125,15 +131,21 @@ nfs_dircache_find(struct nfs_context *nfs, struct nfs_fh *fh) { struct nfsdir *nfsdir; - for (nfsdir = nfs->dircache; nfsdir; nfsdir = nfsdir->next) { +#ifdef HAVE_MULTITHREADING + nfs_mt_mutex_lock(&nfs->rpc->rpc_mutex); +#endif + for (nfsdir = nfs->nfsi->dircache; nfsdir; nfsdir = nfsdir->next) { if (nfsdir->fh.len == fh->len && !memcmp(nfsdir->fh.val, fh->val, fh->len)) { - LIBNFS_LIST_REMOVE(&nfs->dircache, nfsdir); - return nfsdir; + LIBNFS_LIST_REMOVE(&nfs->nfsi->dircache, nfsdir); + break; } } - return NULL; +#ifdef HAVE_MULTITHREADING + nfs_mt_mutex_unlock(&nfs->rpc->rpc_mutex); +#endif + return nfsdir; } void @@ -258,11 +270,18 @@ char * nfs_get_error(struct nfs_context *nfs) { #ifdef HAVE_MULTITHREADING - if(nfs->multithreading_enabled) { - return "nfs_get_error disabled while multithreading is active"; + if (nfs && nfs->nfsi->multithreading_enabled) { + struct nfs_thread_context *ntc; + + for(ntc = nfs->nfsi->thread_ctx; ntc; ntc = ntc->next) { + if (nfs_mt_get_tid() == ntc->tid) { + nfs = &ntc->nfs; + break; + } + } } -#endif /* HAVE_MULTITHREADING */ - return rpc_get_error(nfs->rpc); +#endif + return nfs->error_string ? nfs->error_string : ""; }; #ifdef HAVE_SO_BINDTODEVICE @@ -289,7 +308,7 @@ nfs_set_context_args(struct nfs_context *nfs, const char *arg, const char *val) } else if (!strcmp(arg, "debug")) { rpc_set_debug(nfs_get_rpc_context(nfs), atoi(val)); } else if (!strcmp(arg, "auto-traverse-mounts")) { - nfs->auto_traverse_mounts = atoi(val); + nfs->nfsi->auto_traverse_mounts = atoi(val); } else if (!strcmp(arg, "dircache")) { nfs_set_dircache(nfs, atoi(val)); } else if (!strcmp(arg, "autoreconnect")) { @@ -305,9 +324,9 @@ nfs_set_context_args(struct nfs_context *nfs, const char *arg, const char *val) return -1; } } else if (!strcmp(arg, "nfsport")) { - nfs->nfsport = atoi(val); + nfs->nfsi->nfsport = atoi(val); } else if (!strcmp(arg, "mountport")) { - nfs->mountport = atoi(val); + nfs->nfsi->mountport = atoi(val); } return 0; } @@ -408,7 +427,7 @@ nfs_parse_url(struct nfs_context *nfs, const char *url, int dir, int incomplete) strp = strchr(urls->server, ':'); if (strp) { *strp++ = 0; - nfs->nfsport = atoi(strp); + nfs->nfsi->nfsport = atoi(strp); } if (dir) { @@ -509,30 +528,39 @@ struct nfs_context * nfs_init_context(void) { struct nfs_context *nfs; + struct nfs_context_internal *nfsi; int i; uint64_t v; verifier4 verifier; char client_name[MAX_CLIENT_NAME]; + nfsi = malloc(sizeof(struct nfs_context_internal)); + if (nfsi == NULL) { + return NULL; + } + memset(nfsi, 0, sizeof(struct nfs_context_internal)); + nfs = malloc(sizeof(struct nfs_context)); if (nfs == NULL) { + free(nfsi); return NULL; } memset(nfs, 0, sizeof(struct nfs_context)); + nfs->nfsi = nfsi; nfs->rpc = rpc_init_context(); if (nfs->rpc == NULL) { free(nfs); return NULL; } - nfs->cwd = strdup("/"); - nfs->mask = 022; - nfs->auto_traverse_mounts = 1; - nfs->dircache_enabled = 1; + nfs->nfsi->cwd = strdup("/"); + nfs->nfsi->mask = 022; + nfs->nfsi->auto_traverse_mounts = 1; + nfs->nfsi->dircache_enabled = 1; /* Default is never give up, never surrender */ - nfs->auto_reconnect = -1; - nfs->version = NFS_V3; + nfs->nfsi->auto_reconnect = -1; + nfs->nfsi->version = NFS_V3; /* NFSv4 parameters */ /* We need a "random" initial verifier */ @@ -548,7 +576,8 @@ nfs_init_context(void) nfs4_set_client_name(nfs, client_name); #ifdef HAVE_MULTITHREADING - nfs_mt_mutex_init(&nfs->nfs4_open_mutex); + nfs_mt_mutex_init(&nfs->nfsi->nfs_mutex); + nfs_mt_mutex_init(&nfs->nfsi->nfs4_open_mutex); #endif /* HAVE_MULTITHREADING */ return nfs; } @@ -556,22 +585,22 @@ nfs_init_context(void) void nfs4_set_client_name(struct nfs_context *nfs, const char *client_name) { - nfs->client_name = strdup(client_name); + nfs->nfsi->client_name = strdup(client_name); } void nfs4_set_verifier(struct nfs_context *nfs, const char *verifier) { - memcpy(nfs->verifier, verifier, NFS4_VERIFIER_SIZE); + memcpy(nfs->nfsi->verifier, verifier, NFS4_VERIFIER_SIZE); } void nfs_destroy_context(struct nfs_context *nfs) { - while (nfs->nested_mounts) { - struct nested_mounts *mnt = nfs->nested_mounts; + while (nfs->nfsi->nested_mounts) { + struct nested_mounts *mnt = nfs->nfsi->nested_mounts; - LIBNFS_LIST_REMOVE(&nfs->nested_mounts, mnt); + LIBNFS_LIST_REMOVE(&nfs->nfsi->nested_mounts, mnt); free(mnt->path); free(mnt->fh.val); free(mnt); @@ -580,31 +609,32 @@ nfs_destroy_context(struct nfs_context *nfs) rpc_destroy_context(nfs->rpc); nfs->rpc = NULL; - free(nfs->server); - nfs->server = NULL; + free(nfs->error_string); + nfs->error_string = NULL; + + free(nfs->nfsi->server); + free(nfs->nfsi->export); + free(nfs->nfsi->cwd); + free(nfs->nfsi->rootfh.val); + free(nfs->nfsi->client_name); - free(nfs->export); - nfs->export = NULL; - - free(nfs->cwd); - nfs->cwd = NULL; - - free(nfs->rootfh.val); - nfs->rootfh.len = 0; - nfs->rootfh.val = NULL; - - free(nfs->client_name); - nfs->client_name = NULL; - - while (nfs->dircache) { - struct nfsdir *nfsdir = nfs->dircache; - LIBNFS_LIST_REMOVE(&nfs->dircache, nfsdir); + while (nfs->nfsi->dircache) { + struct nfsdir *nfsdir = nfs->nfsi->dircache; + LIBNFS_LIST_REMOVE(&nfs->nfsi->dircache, nfsdir); nfs_free_nfsdir(nfsdir); } #ifdef HAVE_MULTITHREADING - nfs_mt_mutex_destroy(&nfs->nfs4_open_mutex); + nfs_mt_mutex_destroy(&nfs->nfsi->nfs4_open_mutex); + nfs_mt_mutex_destroy(&nfs->nfsi->nfs_mutex); + while (nfs->nfsi->thread_ctx) { + struct nfs_thread_context *tmp = nfs->nfsi->thread_ctx->next; + free(nfs->nfsi->thread_ctx->nfs.error_string); + free(nfs->nfsi->thread_ctx); + nfs->nfsi->thread_ctx = tmp; + } #endif /* HAVE_MULTITHREADING */ + free(nfs->nfsi); free(nfs); } @@ -916,14 +946,14 @@ int nfs_mount_async(struct nfs_context *nfs, const char *server, const char *export, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_mount_async(nfs, server, export, cb, private_data); case NFS_V4: return nfs4_mount_async(nfs, server, export, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -934,7 +964,7 @@ nfs_mount_async(struct nfs_context *nfs, const char *server, int nfs_umount_async(struct nfs_context *nfs, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_umount_async(nfs, cb, private_data); case NFS_V4: @@ -943,7 +973,7 @@ nfs_umount_async(struct nfs_context *nfs, nfs_cb cb, void *private_data) return 0; default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1053,7 +1083,7 @@ int nfs_stat_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_stat_async(nfs, path, cb, private_data); default: @@ -1067,7 +1097,7 @@ int nfs_stat64_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_stat64_async(nfs, path, 0, cb, private_data); @@ -1076,7 +1106,7 @@ nfs_stat64_async(struct nfs_context *nfs, const char *path, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1085,7 +1115,7 @@ int nfs_lstat64_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_stat64_async(nfs, path, 1, cb, private_data); @@ -1094,7 +1124,7 @@ nfs_lstat64_async(struct nfs_context *nfs, const char *path, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1103,7 +1133,7 @@ int nfs_open2_async(struct nfs_context *nfs, const char *path, int flags, int mode, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_open_async(nfs, path, flags, mode, cb, private_data); @@ -1112,7 +1142,7 @@ nfs_open2_async(struct nfs_context *nfs, const char *path, int flags, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1121,7 +1151,7 @@ int nfs_open_async(struct nfs_context *nfs, const char *path, int flags, nfs_cb cb, void *private_data) { - return nfs_open2_async(nfs, path, flags, 0666 & ~nfs->mask, + return nfs_open2_async(nfs, path, flags, 0666 & ~nfs->nfsi->mask, cb, private_data); } @@ -1129,14 +1159,14 @@ int nfs_chdir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_chdir_async(nfs, path, cb, private_data); case NFS_V4: return nfs4_chdir_async(nfs, path, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1145,7 +1175,7 @@ int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, uint64_t count, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_pread_async_internal(nfs, nfsfh, offset, (size_t)count, @@ -1156,7 +1186,7 @@ nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, cb, private_data, 0); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1165,7 +1195,7 @@ int nfs_read_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t count, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_pread_async_internal(nfs, nfsfh, nfsfh->offset, (size_t)count, @@ -1176,7 +1206,7 @@ nfs_read_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t count, cb, private_data, 1); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1185,7 +1215,7 @@ int nfs_pwrite_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, uint64_t count, const void *buf, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_pwrite_async_internal(nfs, nfsfh, offset, (size_t)count, buf, @@ -1196,7 +1226,7 @@ nfs_pwrite_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, cb, private_data, 0); default: nfs_set_error(nfs, "%s does not support NFSv%d.", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1205,7 +1235,7 @@ int nfs_write_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t count, const void *buf, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_write_async(nfs, nfsfh, count, buf, cb, private_data); @@ -1214,7 +1244,7 @@ nfs_write_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t count, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1223,14 +1253,14 @@ int nfs_close_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_close_async(nfs, nfsfh, cb, private_data); case NFS_V4: return nfs4_close_async(nfs, nfsfh, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1239,7 +1269,7 @@ int nfs_fstat_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_fstat_async(nfs, nfsfh, cb, private_data); default: @@ -1253,14 +1283,14 @@ int nfs_fstat64_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_fstat64_async(nfs, nfsfh, cb, private_data); case NFS_V4: return nfs4_fstat64_async(nfs, nfsfh, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1269,14 +1299,14 @@ int nfs_fsync_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_fsync_async(nfs, nfsfh, cb, private_data); case NFS_V4: return nfs4_fsync_async(nfs, nfsfh, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1285,7 +1315,7 @@ int nfs_ftruncate_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t length, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_ftruncate_async(nfs, nfsfh, length, cb, private_data); @@ -1294,7 +1324,7 @@ nfs_ftruncate_async(struct nfs_context *nfs, struct nfsfh *nfsfh, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1303,14 +1333,14 @@ int nfs_truncate_async(struct nfs_context *nfs, const char *path, uint64_t length, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_truncate_async(nfs, path, length, cb, private_data); case NFS_V4: return nfs4_truncate_async(nfs, path, length, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1319,14 +1349,14 @@ int nfs_mkdir2_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_mkdir2_async(nfs, path, mode, cb, private_data); case NFS_V4: return nfs4_mkdir2_async(nfs, path, mode, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1342,14 +1372,14 @@ int nfs_rmdir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_rmdir_async(nfs, path, cb, private_data); case NFS_V4: return nfs4_rmdir_async(nfs, path, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1358,7 +1388,7 @@ int nfs_create_async(struct nfs_context *nfs, const char *path, int flags, int mode, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_create_async(nfs, path, flags, mode, cb, private_data); @@ -1367,7 +1397,7 @@ nfs_create_async(struct nfs_context *nfs, const char *path, int flags, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1383,14 +1413,14 @@ int nfs_unlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_unlink_async(nfs, path, cb, private_data); case NFS_V4: return nfs4_unlink_async(nfs, path, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1399,14 +1429,14 @@ int nfs_mknod_async(struct nfs_context *nfs, const char *path, int mode, int dev, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_mknod_async(nfs, path, mode, dev, cb, private_data); case NFS_V4: return nfs4_mknod_async(nfs, path, mode, dev, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1415,7 +1445,7 @@ int nfs_opendir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_opendir_async(nfs, path, cb, private_data); case NFS_V4: @@ -1473,7 +1503,7 @@ nfs_rewinddir(struct nfs_context *nfs _U_, struct nfsdir *nfsdir) void nfs_closedir(struct nfs_context *nfs, struct nfsdir *nfsdir) { - if (nfs && nfs->dircache_enabled) { + if (nfs && nfs->nfsi->dircache_enabled) { nfs_dircache_add(nfs, nfsdir); } else { nfs_free_nfsdir(nfsdir); @@ -1484,7 +1514,7 @@ void nfs_getcwd(struct nfs_context *nfs, const char **cwd) { if (cwd) { - *cwd = nfs->cwd; + *cwd = nfs->nfsi->cwd; } } @@ -1492,7 +1522,7 @@ int nfs_lseek_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int64_t offset, int whence, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_lseek_async(nfs, nfsfh, offset, whence, cb, private_data); @@ -1501,7 +1531,7 @@ nfs_lseek_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int64_t offset, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1511,13 +1541,13 @@ nfs_lockf_async(struct nfs_context *nfs, struct nfsfh *nfsfh, enum nfs4_lock_op op, uint64_t count, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V4: return nfs4_lockf_async(nfs, nfsfh, op, count, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1527,13 +1557,13 @@ nfs_fcntl_async(struct nfs_context *nfs, struct nfsfh *nfsfh, enum nfs4_fcntl_op cmd, void *arg, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V4: return nfs4_fcntl_async(nfs, nfsfh, cmd, arg, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1542,14 +1572,14 @@ int nfs_statvfs_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_statvfs_async(nfs, path, cb, private_data); case NFS_V4: return nfs4_statvfs_async(nfs, path, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1558,14 +1588,14 @@ int nfs_statvfs64_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_statvfs64_async(nfs, path, cb, private_data); case NFS_V4: return nfs4_statvfs64_async(nfs, path, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1574,14 +1604,14 @@ int nfs_readlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_readlink_async(nfs, path, cb, private_data); case NFS_V4: return nfs4_readlink_async(nfs, path, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1590,7 +1620,7 @@ int nfs_chmod_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_chmod_async_internal(nfs, path, 0, mode, cb, private_data); @@ -1599,7 +1629,7 @@ nfs_chmod_async(struct nfs_context *nfs, const char *path, int mode, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1608,7 +1638,7 @@ int nfs_lchmod_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_chmod_async_internal(nfs, path, 1, mode, cb, private_data); @@ -1617,7 +1647,7 @@ nfs_lchmod_async(struct nfs_context *nfs, const char *path, int mode, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1626,14 +1656,14 @@ int nfs_fchmod_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int mode, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_fchmod_async(nfs, nfsfh, mode, cb, private_data); case NFS_V4: return nfs4_fchmod_async(nfs, nfsfh, mode, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1642,7 +1672,7 @@ int nfs_chown_async(struct nfs_context *nfs, const char *path, int uid, int gid, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_chown_async_internal(nfs, path, 0, uid, gid, cb, private_data); @@ -1651,7 +1681,7 @@ nfs_chown_async(struct nfs_context *nfs, const char *path, int uid, int gid, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1660,7 +1690,7 @@ int nfs_lchown_async(struct nfs_context *nfs, const char *path, int uid, int gid, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_chown_async_internal(nfs, path, 1, uid, gid, cb, private_data); @@ -1669,7 +1699,7 @@ nfs_lchown_async(struct nfs_context *nfs, const char *path, int uid, int gid, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1678,7 +1708,7 @@ int nfs_fchown_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid, int gid, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_fchown_async(nfs, nfsfh, uid, gid, cb, private_data); @@ -1687,7 +1717,7 @@ nfs_fchown_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1696,7 +1726,7 @@ int nfs_utimes_async(struct nfs_context *nfs, const char *path, struct timeval *times, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_utimes_async_internal(nfs, path, 0, times, cb, private_data); @@ -1705,7 +1735,7 @@ nfs_utimes_async(struct nfs_context *nfs, const char *path, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1714,7 +1744,7 @@ int nfs_lutimes_async(struct nfs_context *nfs, const char *path, struct timeval *times, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_utimes_async_internal(nfs, path, 1, times, cb, private_data); @@ -1723,7 +1753,7 @@ nfs_lutimes_async(struct nfs_context *nfs, const char *path, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1732,7 +1762,7 @@ int nfs_utime_async(struct nfs_context *nfs, const char *path, struct utimbuf *times, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_utime_async(nfs, path, times, cb, private_data); case NFS_V4: @@ -1748,14 +1778,14 @@ int nfs_access_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_access_async(nfs, path, mode, cb, private_data); case NFS_V4: return nfs4_access_async(nfs, path, mode, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1764,7 +1794,7 @@ int nfs_access2_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_access2_async(nfs, path, cb, private_data); case NFS_V4: @@ -1780,7 +1810,7 @@ int nfs_symlink_async(struct nfs_context *nfs, const char *target, const char *newpath, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_symlink_async(nfs, target, newpath, cb, private_data); @@ -1789,7 +1819,7 @@ nfs_symlink_async(struct nfs_context *nfs, const char *target, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1798,7 +1828,7 @@ int nfs_rename_async(struct nfs_context *nfs, const char *oldpath, const char *newpath, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_rename_async(nfs, oldpath, newpath, cb, private_data); @@ -1807,7 +1837,7 @@ nfs_rename_async(struct nfs_context *nfs, const char *oldpath, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1816,7 +1846,7 @@ int nfs_link_async(struct nfs_context *nfs, const char *oldpath, const char *newpath, nfs_cb cb, void *private_data) { - switch (nfs->version) { + switch (nfs->nfsi->version) { case NFS_V3: return nfs3_link_async(nfs, oldpath, newpath, cb, private_data); @@ -1825,7 +1855,7 @@ nfs_link_async(struct nfs_context *nfs, const char *oldpath, cb, private_data); default: nfs_set_error(nfs, "%s does not support NFSv%d", - __FUNCTION__, nfs->version); + __FUNCTION__, nfs->nfsi->version); return -1; } } @@ -1836,12 +1866,12 @@ nfs_link_async(struct nfs_context *nfs, const char *oldpath, uint64_t nfs_get_readmax(struct nfs_context *nfs) { - return nfs->readmax; + return nfs->nfsi->readmax; } void nfs_set_readmax(struct nfs_context *nfs, uint64_t readmax) { - nfs->readmax = readmax; + nfs->nfsi->readmax = readmax; } /* @@ -1850,12 +1880,12 @@ nfs_set_readmax(struct nfs_context *nfs, uint64_t readmax) uint64_t nfs_get_writemax(struct nfs_context *nfs) { - return nfs->writemax; + return nfs->nfsi->writemax; } void nfs_set_writemax(struct nfs_context *nfs, uint64_t writemax) { - nfs->writemax = writemax; + nfs->nfsi->writemax = writemax; } void @@ -1895,12 +1925,12 @@ nfs_set_debug(struct nfs_context *nfs, int level) { void nfs_set_dircache(struct nfs_context *nfs, int enabled) { - nfs->dircache_enabled = enabled; + nfs->nfsi->dircache_enabled = enabled; } void nfs_set_autoreconnect(struct nfs_context *nfs, int num_retries) { - nfs->auto_reconnect = num_retries; + nfs->nfsi->auto_reconnect = num_retries; } int @@ -1908,7 +1938,7 @@ nfs_set_version(struct nfs_context *nfs, int version) { switch (version) { case NFS_V3: case NFS_V4: - nfs->version = version; + nfs->nfsi->version = version; break; default: nfs_set_error(nfs, "NFS version %d is not supported", version); @@ -1919,7 +1949,7 @@ nfs_set_version(struct nfs_context *nfs, int version) { int nfs_get_version(struct nfs_context *nfs) { - return nfs->version; + return nfs->nfsi->version; } void @@ -1929,15 +1959,18 @@ nfs_set_error(struct nfs_context *nfs, char *error_string, ...) char *str = NULL; #ifdef HAVE_MULTITHREADING + /* All thread contexts share the same rpc_context so + * use the mutex from the rpc_context. + */ nfs_mt_mutex_lock(&nfs->rpc->rpc_mutex); #endif /* HAVE_MULTITHREADING */ va_start(ap, error_string); str = malloc(1024); vsnprintf(str, 1024, error_string, ap); - if (nfs->rpc->error_string != NULL) { - free(nfs->rpc->error_string); + if (nfs->error_string != NULL) { + free(nfs->error_string); } - nfs->rpc->error_string = str; + nfs->error_string = str; va_end(ap); #ifdef HAVE_MULTITHREADING nfs_mt_mutex_unlock(&nfs->rpc->rpc_mutex); @@ -2046,17 +2079,17 @@ nfs_get_rpc_context(struct nfs_context *nfs) const char * nfs_get_server(struct nfs_context *nfs) { - return nfs->server; + return nfs->nfsi->server; } const char * nfs_get_export(struct nfs_context *nfs) { - return nfs->export; + return nfs->nfsi->export; } const struct nfs_fh * nfs_get_rootfh(struct nfs_context *nfs) { - return &nfs->rootfh; + return &nfs->nfsi->rootfh; } struct nfs_fh * @@ -2066,8 +2099,8 @@ nfs_get_fh(struct nfsfh *nfsfh) { uint16_t nfs_umask(struct nfs_context *nfs, uint16_t mask) { - uint16_t tmp = nfs->mask; - nfs->mask = mask; + uint16_t tmp = nfs->nfsi->mask; + nfs->nfsi->mask = mask; return tmp; } diff --git a/lib/multithreading.c b/lib/multithreading.c index 307f9b1..82cd743 100644 --- a/lib/multithreading.c +++ b/lib/multithreading.c @@ -54,6 +54,13 @@ #ifdef HAVE_MULTITHREADING #ifdef HAVE_PTHREAD +pid_t gettid(void); + +nfs_tid_t nfs_mt_get_tid(void) +{ + return gettid(); +} + static void *nfs_mt_service_thread(void *arg) { struct nfs_context *nfs = (struct nfs_context *)arg; @@ -61,9 +68,9 @@ static void *nfs_mt_service_thread(void *arg) int revents; int ret; - nfs->multithreading_enabled = 1; + nfs->nfsi->multithreading_enabled = 1; - while (nfs->multithreading_enabled) { + while (nfs->nfsi->multithreading_enabled) { pfd.fd = nfs_get_fd(nfs); pfd.events = nfs_which_events(nfs); pfd.revents = 0; @@ -85,12 +92,12 @@ static void *nfs_mt_service_thread(void *arg) int nfs_mt_service_thread_start(struct nfs_context *nfs) { - if (pthread_create(&nfs->service_thread, NULL, + if (pthread_create(&nfs->nfsi->service_thread, NULL, &nfs_mt_service_thread, nfs)) { nfs_set_error(nfs, "Failed to start service thread"); return -1; } - while (nfs->multithreading_enabled == 0) { + while (nfs->nfsi->multithreading_enabled == 0) { struct timespec ts = {0, 1000000}; nanosleep(&ts, NULL); } @@ -99,8 +106,8 @@ int nfs_mt_service_thread_start(struct nfs_context *nfs) void nfs_mt_service_thread_stop(struct nfs_context *nfs) { - nfs->multithreading_enabled = 0; - pthread_join(nfs->service_thread, NULL); + nfs->nfsi->multithreading_enabled = 0; + pthread_join(nfs->nfsi->service_thread, NULL); } int nfs_mt_mutex_init(libnfs_mutex_t *mutex) @@ -146,6 +153,10 @@ int nfs_mt_sem_wait(libnfs_sem_t *sem) } #elif WIN32 +nfs_tid_t nfs_mt_get_tid(void) +{ + return GetCurrentThreadId(); +} static void* nfs_mt_service_thread(void* arg) { struct nfs_context* nfs = (struct nfs_context*)arg; @@ -153,9 +164,9 @@ static void* nfs_mt_service_thread(void* arg) int revents; int ret; - nfs->multithreading_enabled = 1; + nfs->nfsi->multithreading_enabled = 1; - while (nfs->multithreading_enabled) { + while (nfs->nfsi->multithreading_enabled) { pfd.fd = nfs_get_fd(nfs); pfd.events = nfs_which_events(nfs); pfd.revents = 0; @@ -193,12 +204,12 @@ static DWORD WINAPI service_thread_init(LPVOID lpParam) int nfs_mt_service_thread_start(struct nfs_context* nfs) { - nfs->service_thread = CreateThread(NULL, 1024*1024, service_thread_init, nfs, 0, NULL); - if (nfs->service_thread == NULL) { + nfs->nfsi->service_thread = CreateThread(NULL, 1024*1024, service_thread_init, nfs, 0, NULL); + if (nfs->nfsi->service_thread == NULL) { nfs_set_error(nfs, "Failed to start service thread"); return -1; } - while (nfs->multithreading_enabled == 0) { + while (nfs->nfsi->multithreading_enabled == 0) { Sleep(100); } return 0; @@ -206,8 +217,8 @@ int nfs_mt_service_thread_start(struct nfs_context* nfs) void nfs_mt_service_thread_stop(struct nfs_context* nfs) { - nfs->multithreading_enabled = 0; - while (WaitForSingleObject(nfs->service_thread, INFINITE) != WAIT_OBJECT_0); + nfs->nfsi->multithreading_enabled = 0; + while (WaitForSingleObject(nfs->nfsi->service_thread, INFINITE) != WAIT_OBJECT_0); } int nfs_mt_mutex_init(libnfs_mutex_t* mutex) diff --git a/lib/nfs_v3.c b/lib/nfs_v3.c index 4495d66..9e98036 100644 --- a/lib/nfs_v3.c +++ b/lib/nfs_v3.c @@ -192,8 +192,8 @@ nfs3_lookup_path_2_cb(struct rpc_context *rpc, int status, void *command_data, /* Handle absolute paths, ensuring that the path lies within the * export. */ if (path[0] == '/') { - if (strstr(path, nfs->export) == path) { - char *ptr = path + strlen(nfs->export); + if (strstr(path, nfs_get_export(nfs)) == path) { + char *ptr = path + strlen(nfs_get_export(nfs)); if (*ptr == '/') { newpath = strdup(ptr); } else if (*ptr == '\0') { @@ -248,7 +248,7 @@ nfs3_lookup_path_2_cb(struct rpc_context *rpc, int status, void *command_data, } data->path = data->saved_path; - nfs3_lookup_path_async_internal(nfs, NULL, data, &nfs->rootfh); + nfs3_lookup_path_async_internal(nfs, NULL, data, &nfs->nfsi->rootfh); return; nomem: @@ -459,7 +459,7 @@ nfs3_lookup_path_getattr_cb(struct rpc_context *rpc, int status, /* This function will always invoke the callback and cleanup * for failures. So no need to check the return value. */ - nfs3_lookup_path_async_internal(nfs, &attr, data, &nfs->rootfh); + nfs3_lookup_path_async_internal(nfs, &attr, data, &nfs->nfsi->rootfh); } /* This function will free continue_data on error */ @@ -498,14 +498,14 @@ nfs3_lookuppath_async(struct nfs_context *nfs, const char *path, int no_follow, if (path[0] == '/') { data->saved_path = strdup(path); } else { - data->saved_path = malloc(strlen(path) + strlen(nfs->cwd) + 2); + data->saved_path = malloc(strlen(path) + strlen(nfs->nfsi->cwd) + 2); if (data->saved_path == NULL) { nfs_set_error(nfs, "Out of memory: failed to " "allocate path string"); free_nfs_cb_data(data); return -1; } - sprintf(data->saved_path, "%s/%s", nfs->cwd, path); + sprintf(data->saved_path, "%s/%s", nfs->nfsi->cwd, path); } if (data->saved_path == NULL) { @@ -520,7 +520,7 @@ nfs3_lookuppath_async(struct nfs_context *nfs, const char *path, int no_follow, } data->path = data->saved_path; - fh = &nfs->rootfh; + fh = &nfs->nfsi->rootfh; if (data->path[0]) { struct nested_mounts *mnt; @@ -531,7 +531,7 @@ nfs3_lookuppath_async(struct nfs_context *nfs, const char *path, int no_follow, size_t max_match_len = 0; /* Do we need to switch to a different nested export ? */ - for (mnt = nfs->nested_mounts; mnt; mnt = mnt->next) { + for (mnt = nfs->nfsi->nested_mounts; mnt; mnt = mnt->next) { if (strlen(mnt->path) < max_match_len) continue; if (strncmp(mnt->path, data->saved_path, @@ -620,7 +620,7 @@ nfs3_mount_7_cb(struct rpc_context *rpc, int status, void *command_data, return; } - if (!nfs->nested_mounts) + if (!nfs->nfsi->nested_mounts) goto finished; /* nested mount traversals are best-effort only, so any @@ -633,7 +633,7 @@ nfs3_mount_7_cb(struct rpc_context *rpc, int status, void *command_data, memset(ma, 0, sizeof(struct mount_attr_cb)); ma->data = data; - for(mnt = nfs->nested_mounts; mnt; mnt = mnt->next) { + for(mnt = nfs->nfsi->nested_mounts; mnt; mnt = mnt->next) { struct mount_attr_item_cb *ma_item; struct GETATTR3args args; @@ -685,7 +685,7 @@ nfs3_mount_6_cb(struct rpc_context *rpc, int status, void *command_data, if (res->status != NFS3_OK) { nfs_set_error(nfs, "NFS: FSINFO of %s failed with %s(%d)", - nfs->export, nfsstat3_to_str(res->status), + nfs_get_export(nfs), nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, nfs_get_error(nfs), data->private_data); @@ -693,35 +693,35 @@ nfs3_mount_6_cb(struct rpc_context *rpc, int status, void *command_data, return; } - nfs->readmax = res->FSINFO3res_u.resok.rtmax; - nfs->writemax = res->FSINFO3res_u.resok.wtmax; + nfs->nfsi->readmax = res->FSINFO3res_u.resok.rtmax; + nfs->nfsi->writemax = res->FSINFO3res_u.resok.wtmax; /* The server supports sizes up to rtmax and wtmax, so it is legal * to use smaller transfers sizes. */ - if (nfs->readmax > NFS_MAX_XFER_SIZE) - nfs->readmax = NFS_MAX_XFER_SIZE; - else if (nfs->readmax < NFSMAXDATA2) { + if (nfs->nfsi->readmax > NFS_MAX_XFER_SIZE) + nfs->nfsi->readmax = NFS_MAX_XFER_SIZE; + else if (nfs->nfsi->readmax < NFSMAXDATA2) { nfs_set_error(nfs, "server max rsize of %" PRIu64, - nfs->readmax); + nfs->nfsi->readmax); data->cb(-EINVAL, nfs, nfs_get_error(nfs), data->private_data); free_nfs_cb_data(data); return; } - if (nfs->writemax > NFS_MAX_XFER_SIZE) - nfs->writemax = NFS_MAX_XFER_SIZE; - else if (nfs->writemax < NFSMAXDATA2) { + if (nfs->nfsi->writemax > NFS_MAX_XFER_SIZE) + nfs->nfsi->writemax = NFS_MAX_XFER_SIZE; + else if (nfs->nfsi->writemax < NFSMAXDATA2) { nfs_set_error(nfs, "server max wsize of %" PRIu64, - nfs->writemax); + nfs->nfsi->writemax); data->cb(-EINVAL, nfs, nfs_get_error(nfs), data->private_data); free_nfs_cb_data(data); return; } memset(&args, 0, sizeof(GETATTR3args)); - args.object.data.data_len = nfs->rootfh.len; - args.object.data.data_val = nfs->rootfh.val; + args.object.data.data_len = nfs->nfsi->rootfh.len; + args.object.data.data_val = nfs->nfsi->rootfh.val; if (rpc_nfs3_getattr_async(rpc, nfs3_mount_7_cb, &args, data) != 0) { nfs_set_error(nfs, "%s: %s", __FUNCTION__, nfs_get_error(nfs)); @@ -749,10 +749,10 @@ nfs3_mount_5_cb(struct rpc_context *rpc, int status, void *command_data, /* NFS TCP: As we are connected now we can pass on the auto-reconnect * settings to the RPC layer. */ - rpc_set_autoreconnect(rpc, nfs->auto_reconnect); + rpc_set_autoreconnect(rpc, nfs->nfsi->auto_reconnect); - args.fsroot.data.data_len = nfs->rootfh.len; - args.fsroot.data.data_val = nfs->rootfh.val; + args.fsroot.data.data_len = nfs->nfsi->rootfh.len; + args.fsroot.data.data_val = nfs->nfsi->rootfh.val; if (rpc_nfs3_fsinfo_async(rpc, nfs3_mount_6_cb, &args, data) != 0) { nfs_set_error(nfs, "%s: %s", __FUNCTION__, nfs_get_error(nfs)); data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); @@ -836,7 +836,7 @@ nfs3_mount_4_cb(struct rpc_context *rpc, int status, void *command_data, mnt->path = md_item_cb->path; md_item_cb->path = NULL; - LIBNFS_LIST_ADD(&nfs->nested_mounts, mnt); + LIBNFS_LIST_ADD(&nfs->nfsi->nested_mounts, mnt); finished: free(md_item_cb->path); @@ -861,8 +861,9 @@ finished: return; } - if (nfs->nfsport) { - if (rpc_connect_port_async(nfs->rpc, nfs->server, nfs->nfsport, + if (nfs->nfsi->nfsport) { + if (rpc_connect_port_async(nfs->rpc, nfs_get_server(nfs), + nfs->nfsi->nfsport, NFS_PROGRAM, NFS_V3, nfs3_mount_5_cb, data) != 0) { nfs_set_error(nfs, "%s: %s", __FUNCTION__, @@ -876,7 +877,8 @@ finished: return; } - if (rpc_connect_program_async(nfs->rpc, nfs->server, NFS_PROGRAM, + if (rpc_connect_program_async(nfs->rpc, nfs_get_server(nfs), + NFS_PROGRAM, NFS_V3, nfs3_mount_5_cb, data) != 0) { nfs_set_error(nfs, "%s: %s", __FUNCTION__, nfs_get_error(nfs)); data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); @@ -907,7 +909,7 @@ nfs3_mount_3_cb(struct rpc_context *rpc, int status, void *command_data, /* Iterate over all exports and check if there are any mounts nested * below the current mount. */ - len = strlen(nfs->export); + len = strlen(nfs_get_export(nfs)); if (!len) { data->cb(-EFAULT, nfs, "Export is empty", data->private_data); free_nfs_cb_data(data); @@ -917,7 +919,7 @@ nfs3_mount_3_cb(struct rpc_context *rpc, int status, void *command_data, while (res) { struct mount_discovery_item_cb *md_item_cb; - if (strncmp(nfs->export, res->ex_dir, len)) { + if (strncmp(nfs_get_export(nfs), res->ex_dir, len)) { res = res->ex_next; continue; } @@ -938,7 +940,7 @@ nfs3_mount_3_cb(struct rpc_context *rpc, int status, void *command_data, memset(md_item_cb, 0, sizeof(*md_item_cb)); md_item_cb->path = strdup(res->ex_dir + len - - (nfs->export[len -1] == '/')); + - (nfs_get_export(nfs)[len -1] == '/')); if (md_item_cb->path == NULL) { free(md_item_cb); continue; @@ -983,8 +985,9 @@ nfs3_mount_3_cb(struct rpc_context *rpc, int status, void *command_data, */ rpc_disconnect(rpc, "normal disconnect"); - if (nfs->nfsport) { - if (rpc_connect_port_async(nfs->rpc, nfs->server, nfs->nfsport, + if (nfs->nfsi->nfsport) { + if (rpc_connect_port_async(nfs->rpc, nfs_get_server(nfs), + nfs->nfsi->nfsport, NFS_PROGRAM, NFS_V3, nfs3_mount_5_cb, data) != 0) { nfs_set_error(nfs, "%s: %s", __FUNCTION__, @@ -997,7 +1000,8 @@ nfs3_mount_3_cb(struct rpc_context *rpc, int status, void *command_data, return; } - if (rpc_connect_program_async(nfs->rpc, nfs->server, NFS_PROGRAM, + if (rpc_connect_program_async(nfs->rpc, nfs_get_server(nfs), + NFS_PROGRAM, NFS_V3, nfs3_mount_5_cb, data) != 0) { nfs_set_error(nfs, "%s: %s", __FUNCTION__, nfs_get_error(nfs)); data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); @@ -1035,19 +1039,19 @@ nfs3_mount_2_cb(struct rpc_context *rpc, int status, void *command_data, return; } - nfs->rootfh.len = res->mountres3_u.mountinfo.fhandle.fhandle3_len; - nfs->rootfh.val = malloc(nfs->rootfh.len); - if (nfs->rootfh.val == NULL) { + nfs->nfsi->rootfh.len = res->mountres3_u.mountinfo.fhandle.fhandle3_len; + nfs->nfsi->rootfh.val = malloc(nfs->nfsi->rootfh.len); + if (nfs->nfsi->rootfh.val == NULL) { nfs_set_error(nfs, "%s: %s", __FUNCTION__, nfs_get_error(nfs)); data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); free_nfs_cb_data(data); return; } - memcpy(nfs->rootfh.val, + memcpy(nfs->nfsi->rootfh.val, res->mountres3_u.mountinfo.fhandle.fhandle3_val, - nfs->rootfh.len); + nfs->nfsi->rootfh.len); - if (nfs->auto_traverse_mounts) { + if (nfs->nfsi->auto_traverse_mounts) { if (rpc_mount3_export_async(rpc, nfs3_mount_3_cb, data) != 0) { nfs_set_error(nfs, "%s: %s", __FUNCTION__, nfs_get_error(nfs)); @@ -1060,8 +1064,9 @@ nfs3_mount_2_cb(struct rpc_context *rpc, int status, void *command_data, } rpc_disconnect(rpc, "normal disconnect"); - if (nfs->nfsport) { - if (rpc_connect_port_async(nfs->rpc, nfs->server, nfs->nfsport, + if (nfs->nfsi->nfsport) { + if (rpc_connect_port_async(nfs->rpc, nfs_get_server(nfs), + nfs->nfsi->nfsport, NFS_PROGRAM, NFS_V3, nfs3_mount_5_cb, data) != 0) { nfs_set_error(nfs, "%s: %s", __FUNCTION__, @@ -1074,7 +1079,8 @@ nfs3_mount_2_cb(struct rpc_context *rpc, int status, void *command_data, return; } - if (rpc_connect_program_async(nfs->rpc, nfs->server, NFS_PROGRAM, + if (rpc_connect_program_async(nfs->rpc, nfs_get_server(nfs), + NFS_PROGRAM, NFS_V3, nfs3_mount_5_cb, data) != 0) { nfs_set_error(nfs, "%s: %s", __FUNCTION__, nfs_get_error(nfs)); data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); @@ -1098,7 +1104,7 @@ nfs3_mount_1_cb(struct rpc_context *rpc, int status, void *command_data, return; } - if (rpc_mount3_mnt_async(rpc, nfs3_mount_2_cb, nfs->export, + if (rpc_mount3_mnt_async(rpc, nfs3_mount_2_cb, nfs->nfsi->export, data) != 0) { nfs_set_error(nfs, "%s: %s.", __FUNCTION__, nfs_get_error(nfs)); data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); @@ -1123,20 +1129,20 @@ nfs3_mount_async(struct nfs_context *nfs, const char *server, memset(data, 0, sizeof(struct nfs_cb_data)); new_server = strdup(server); new_export = strdup(export); - if (nfs->server != NULL) { - free(nfs->server); + if (nfs->nfsi->server != NULL) { + free(nfs->nfsi->server); } - nfs->server = new_server; - if (nfs->export != NULL) { - free(nfs->export); + nfs->nfsi->server = new_server; + if (nfs->nfsi->export != NULL) { + free(nfs->nfsi->export); } - nfs->export = new_export; + nfs->nfsi->export = new_export; data->nfs = nfs; data->cb = cb; data->private_data = private_data; - if (nfs->mountport) { - if (rpc_connect_port_async(nfs->rpc, server, nfs->mountport, + if (nfs->nfsi->mountport) { + if (rpc_connect_port_async(nfs->rpc, server, nfs->nfsi->mountport, MOUNT_PROGRAM, MOUNT_V3, nfs3_mount_1_cb, data) != 0) { nfs_set_error(nfs, "Failed to start connection. %s", @@ -1192,7 +1198,7 @@ nfs3_umount_1_cb(struct rpc_context *rpc, int status, void *command_data, return; } - if (rpc_mount3_umnt_async(rpc, nfs3_umount_2_cb, nfs->export, + if (rpc_mount3_umnt_async(rpc, nfs3_umount_2_cb, nfs->nfsi->export, data) != 0) { nfs_set_error(nfs, "%s: %s.", __FUNCTION__, nfs_get_error(nfs)); data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); @@ -1220,9 +1226,9 @@ nfs3_umount_async(struct nfs_context *nfs, nfs_cb cb, void *private_data) rpc_disconnect(nfs->rpc, "umount"); - if (nfs->mountport) { - if (rpc_connect_port_async(nfs->rpc, nfs->server, - nfs->mountport, + if (nfs->nfsi->mountport) { + if (rpc_connect_port_async(nfs->rpc, nfs_get_server(nfs), + nfs->nfsi->mountport, MOUNT_PROGRAM, MOUNT_V3, nfs3_umount_1_cb, data) != 0) { nfs_set_error(nfs, "Failed to start connection. %s", @@ -1233,7 +1239,7 @@ nfs3_umount_async(struct nfs_context *nfs, nfs_cb cb, void *private_data) return 0; } - if (rpc_connect_program_async(nfs->rpc, nfs->server, + if (rpc_connect_program_async(nfs->rpc, nfs_get_server(nfs), MOUNT_PROGRAM, MOUNT_V3, nfs3_umount_1_cb, data) != 0) { nfs_set_error(nfs, "Failed to start connection. %s", @@ -2927,7 +2933,7 @@ nfs3_opendir_cb(struct rpc_context *rpc, int status, void *command_data, splen = 0; /* No name attributes. Is it a nested mount then?*/ - for(mnt = nfs->nested_mounts; mnt; mnt = mnt->next) { + for(mnt = nfs->nfsi->nested_mounts; mnt; mnt = mnt->next) { if (strncmp(data->saved_path, mnt->path, splen)) continue; if (mnt->path[splen] != '/') @@ -4977,8 +4983,11 @@ nfs3_chdir_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data) { /* steal saved_path */ - free(nfs->cwd); - nfs->cwd = data->saved_path; + nfs_mt_mutex_lock(&nfs->rpc->rpc_mutex); + free(nfs->nfsi->cwd); + nfs->nfsi->cwd = data->saved_path; + nfs_mt_mutex_unlock(&nfs->rpc->rpc_mutex); + data->saved_path = NULL; data->cb(0, nfs, NULL, data->private_data); diff --git a/lib/nfs_v4.c b/lib/nfs_v4.c index e1e3ca3..f1a29d1 100644 --- a/lib/nfs_v4.c +++ b/lib/nfs_v4.c @@ -223,9 +223,9 @@ nfs4_resolve_path(struct nfs_context *nfs, const char *path) if (path[0] == '/') { new_path = strdup(path); } else { - new_path = malloc(strlen(path) + strlen(nfs->cwd) + 2); + new_path = malloc(strlen(path) + strlen(nfs->nfsi->cwd) + 2); if (new_path != NULL) { - sprintf(new_path, "%s/%s", nfs->cwd, path); + sprintf(new_path, "%s/%s", nfs->nfsi->cwd, path); } } if (new_path == NULL) { @@ -651,7 +651,7 @@ nfs4_op_release_lockowner(struct nfs_context *nfs, nfs_argop4 *op, struct nfsfh op->argop = OP_RELEASE_LOCKOWNER; rlargs = &op->nfs_argop4_u.oprelease_lockowner; - rlargs->lock_owner.clientid = nfs->clientid; + rlargs->lock_owner.clientid = nfs->nfsi->clientid; rlargs->lock_owner.owner.owner_len = 4; rlargs->lock_owner.owner.owner_val = (char *)&fh->lock_owner; @@ -963,7 +963,7 @@ nfs4_op_lock(struct nfs_context *nfs, nfs_argop4 *op, struct nfsfh *fh, largs->offset = offset; largs->length = length; - if (nfs->has_lock_owner) { + if (nfs->nfsi->has_lock_owner) { largs->locker.new_lock_owner = 0; largs->locker.locker4_u.lock_owner.lock_stateid.seqid = fh->lock_stateid.seqid; @@ -980,11 +980,11 @@ nfs4_op_lock(struct nfs_context *nfs, nfs_argop4 *op, struct nfsfh *fh, memcpy(largs->locker.locker4_u.open_owner.open_stateid.other, fh->stateid.other, 12); largs->locker.locker4_u.open_owner.lock_owner.clientid = - nfs->clientid; + nfs->nfsi->clientid; largs->locker.locker4_u.open_owner.lock_owner.owner.owner_len = - strlen(nfs->client_name); + strlen(nfs->nfsi->client_name); largs->locker.locker4_u.open_owner.lock_owner.owner.owner_val = - nfs->client_name; + nfs->nfsi->client_name; largs->locker.locker4_u.open_owner.lock_seqid = fh->lock_seqid; } @@ -1026,9 +1026,9 @@ nfs4_op_lockt(struct nfs_context *nfs, nfs_argop4 *op, struct nfsfh *fh, ltargs->offset = offset; ltargs->length = length; - ltargs->owner.clientid = nfs->clientid; - ltargs->owner.owner.owner_len = strlen(nfs->client_name); - ltargs->owner.owner.owner_val = nfs->client_name; + ltargs->owner.clientid = nfs->nfsi->clientid; + ltargs->owner.owner.owner_len = strlen(nfs->nfsi->client_name); + ltargs->owner.owner.owner_val = nfs->nfsi->client_name; return 1; } @@ -1133,11 +1133,11 @@ nfs4_allocate_op(struct nfs_context *nfs, nfs_argop4 **op, } i = 0; - if (nfs->rootfh.len) { + if (nfs->nfsi->rootfh.len) { struct nfsfh fh; - fh.fh.len = nfs->rootfh.len; - fh.fh.val = nfs->rootfh.val; + fh.fh.len = nfs->nfsi->rootfh.len; + fh.fh.val = nfs->nfsi->rootfh.val; i += nfs4_op_putfh(nfs, &(*op)[i], &fh); } else { i += nfs4_op_putrootfh(nfs, &(*op)[i]); @@ -1497,17 +1497,17 @@ nfs4_mount_4_cb(struct rpc_context *rpc, int status, void *command_data, } gfhresok = &res->resarray.resarray_val[i].nfs_resop4_u.opgetfh.GETFH4res_u.resok4; - nfs->rootfh.len = gfhresok->object.nfs_fh4_len; - nfs->rootfh.val = malloc(nfs->rootfh.len); - if (nfs->rootfh.val == NULL) { + nfs->nfsi->rootfh.len = gfhresok->object.nfs_fh4_len; + nfs->nfsi->rootfh.val = malloc(nfs->nfsi->rootfh.len); + if (nfs->nfsi->rootfh.val == NULL) { nfs_set_error(nfs, "%s: %s", __FUNCTION__, nfs_get_error(nfs)); data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); free_nfs4_cb_data(data); return; } - memcpy(nfs->rootfh.val, + memcpy(nfs->nfsi->rootfh.val, gfhresok->object.nfs_fh4_val, - nfs->rootfh.len); + nfs->nfsi->rootfh.len); data->cb(0, nfs, NULL, data->private_data); @@ -1567,15 +1567,15 @@ nfs4_mount_2_cb(struct rpc_context *rpc, int status, void *command_data, } scidresok = &res->resarray.resarray_val[0].nfs_resop4_u.opsetclientid.SETCLIENTID4res_u.resok4; - nfs->clientid = scidresok->clientid; - memcpy(nfs->setclientid_confirm, + nfs->nfsi->clientid = scidresok->clientid; + memcpy(nfs->nfsi->setclientid_confirm, scidresok->setclientid_confirm, NFS4_VERIFIER_SIZE); memset(op, 0, sizeof(op)); - i = nfs4_op_setclientid_confirm(nfs, &op[0], nfs->clientid, - nfs->setclientid_confirm); + i = nfs4_op_setclientid_confirm(nfs, &op[0], nfs->nfsi->clientid, + nfs->nfsi->setclientid_confirm); memset(&args, 0, sizeof(args)); args.argarray.argarray_len = i; @@ -1609,7 +1609,7 @@ nfs4_mount_1_cb(struct rpc_context *rpc, int status, void *command_data, memset(op, 0, sizeof(op)); - i = nfs4_op_setclientid(nfs, &op[0], nfs->verifier, nfs->client_name); + i = nfs4_op_setclientid(nfs, &op[0], nfs->nfsi->verifier, nfs->nfsi->client_name); memset(&args, 0, sizeof(args)); args.argarray.argarray_len = i; @@ -1633,8 +1633,8 @@ nfs4_mount_async(struct nfs_context *nfs, const char *server, int port; new_server = strdup(server); - free(nfs->server); - nfs->server = new_server; + free(nfs->nfsi->server); + nfs->nfsi->server = new_server; new_export = strdup(export); if (nfs_normalize_path(nfs, new_export)) { @@ -1643,8 +1643,8 @@ nfs4_mount_async(struct nfs_context *nfs, const char *server, free(new_export); return -1; } - free(nfs->export); - nfs->export = new_export; + free(nfs->nfsi->export); + nfs->nfsi->export = new_export; data = malloc(sizeof(*data)); @@ -1660,7 +1660,7 @@ nfs4_mount_async(struct nfs_context *nfs, const char *server, data->private_data = private_data; data->path = strdup(new_export); - port = nfs->nfsport ? nfs->nfsport : 2049; + port = nfs->nfsi->nfsport ? nfs->nfsi->nfsport : 2049; if (rpc_connect_port_async(nfs->rpc, server, port, NFS4_PROGRAM, NFS_V4, nfs4_mount_1_cb, data) != 0) { @@ -1687,8 +1687,11 @@ nfs4_chdir_1_cb(struct rpc_context *rpc, int status, void *command_data, } /* Ok, all good. Lets steal the path string. */ - free(nfs->cwd); - nfs->cwd = data->path; + nfs_mt_mutex_lock(&nfs->rpc->rpc_mutex); + free(nfs->nfsi->cwd); + nfs->nfsi->cwd = data->path; + nfs_mt_mutex_unlock(&nfs->rpc->rpc_mutex); + data->path = NULL; data->cb(0, nfs, NULL, data->private_data); @@ -2248,7 +2251,7 @@ nfs4_populate_open(struct nfs4_cb_data *data, nfs_argop4 *op) oargs->share_access |= OPEN4_SHARE_ACCESS_WRITE; } oargs->share_deny = OPEN4_SHARE_DENY_NONE; - oargs->owner.clientid = nfs->clientid; + oargs->owner.clientid = nfs->nfsi->clientid; oargs->owner.owner.owner_len = 4; oargs->owner.owner.owner_val = (char *)&data->lock_owner; oargs->seqid = 0; @@ -2343,12 +2346,13 @@ nfs4_open_readlink_cb(struct rpc_context *rpc, int status, void *command_data, data_split_path(data); #ifdef HAVE_MULTITHREADING - nfs_mt_mutex_lock(&data->nfs->nfs4_open_mutex); -#endif - data->lock_owner = nfs->open_counter++; -#ifdef HAVE_MULTITHREADING - nfs_mt_mutex_unlock(&data->nfs->nfs4_open_mutex); -#endif + nfs_mt_mutex_lock(&data->nfs->nfsi->nfs4_open_mutex); + data->lock_owner = nfs->nfsi->open_counter++; + nfs_mt_mutex_unlock(&data->nfs->nfsi->nfs4_open_mutex); +#else + data->lock_owner = nfs->nfsi->open_counter++; +#endif + data->filler.func = nfs4_populate_open; data->filler.max_op = 3; @@ -2466,11 +2470,11 @@ nfs4_open_async_internal(struct nfs_context *nfs, struct nfs4_cb_data *data, } #ifdef HAVE_MULTITHREADING - nfs_mt_mutex_lock(&data->nfs->nfs4_open_mutex); + nfs_mt_mutex_lock(&data->nfs->nfsi->nfs4_open_mutex); #endif - data->lock_owner = nfs->open_counter++; + data->lock_owner = nfs->nfsi->open_counter++; #ifdef HAVE_MULTITHREADING - nfs_mt_mutex_unlock(&data->nfs->nfs4_open_mutex); + nfs_mt_mutex_unlock(&data->nfs->nfsi->nfs4_open_mutex); #endif data->filler.func = nfs4_populate_open; data->filler.max_op = 3; @@ -4156,7 +4160,7 @@ nfs4_lockf_cb(struct rpc_context *rpc, int status, void *command_data, } lresok = &res->resarray.resarray_val[i].nfs_resop4_u.oplock.LOCK4res_u.resok4; - nfs->has_lock_owner = 1; + nfs->nfsi->has_lock_owner = 1; fh->lock_stateid.seqid = lresok->lock_stateid.seqid; memcpy(fh->lock_stateid.other, lresok->lock_stateid.other, 12); break; @@ -4275,7 +4279,7 @@ nfs4_fcntl_cb(struct rpc_context *rpc, int status, void *command_data, } lresok = &res->resarray.resarray_val[i].nfs_resop4_u.oplock.LOCK4res_u.resok4; - nfs->has_lock_owner = 1; + nfs->nfsi->has_lock_owner = 1; fh->lock_stateid.seqid = lresok->lock_stateid.seqid; memcpy(fh->lock_stateid.other, lresok->lock_stateid.other, 12); @@ -4700,8 +4704,8 @@ nfs4_statvfs_async_internal(struct nfs_context *nfs, const char *path, data->flags |= LOOKUP_FLAG_IS_STATVFS64; } - fh.fh.len = nfs->rootfh.len; - fh.fh.val = nfs->rootfh.val; + fh.fh.len = nfs->nfsi->rootfh.len; + fh.fh.val = nfs->nfsi->rootfh.val; i = nfs4_op_putfh(nfs, &op[0], &fh); i += nfs4_op_getattr(nfs, &op[i], statvfs_attributes, 2); diff --git a/win32/libnfs/x64/Debug/libnfs.dll.recipe b/win32/libnfs/x64/Debug/libnfs.dll.recipe new file mode 100644 index 0000000..b7c8cee --- /dev/null +++ b/win32/libnfs/x64/Debug/libnfs.dll.recipe @@ -0,0 +1,11 @@ + + + + + C:\Users\User\source\repos\sahlberg\libnfs\win32\libnfs\x64\Debug\libnfs.dll + + + + + + \ No newline at end of file