diff --git a/include/libnfs-private.h b/include/libnfs-private.h index b51fe0a..86c738a 100644 --- a/include/libnfs-private.h +++ b/include/libnfs-private.h @@ -318,6 +318,7 @@ struct nfs_context { int multithreading_enabled; libnfs_mutex_t nfs_mutex; libnfs_thread_t service_thread; + libnfs_mutex_t nfs4_open_mutex; #endif /* HAVE_MULTITHREADING */ }; diff --git a/lib/libnfs-sync.c b/lib/libnfs-sync.c index 29c2281..4a01549 100644 --- a/lib/libnfs-sync.c +++ b/lib/libnfs-sync.c @@ -517,7 +517,7 @@ nfs_open(struct nfs_context *nfs, const char *path, int flags, return -1; } - if (nfs_open_async(nfs, path, flags, open_cb, &cb_data) != 0) { + if (nfs_open_async(nfs, path, flags, open_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_open_async failed. %s", nfs_get_error(nfs)); nfs_destroy_cb_sem(&cb_data); diff --git a/lib/libnfs.c b/lib/libnfs.c index 4ed3b1d..541a6f6 100755 --- a/lib/libnfs.c +++ b/lib/libnfs.c @@ -549,6 +549,7 @@ nfs_init_context(void) #ifdef HAVE_MULTITHREADING nfs_mt_mutex_init(&nfs->nfs_mutex); + nfs_mt_mutex_init(&nfs->nfs4_open_mutex); #endif /* HAVE_MULTITHREADING */ return nfs; } @@ -603,6 +604,7 @@ nfs_destroy_context(struct nfs_context *nfs) } #ifdef HAVE_MULTITHREADING + nfs_mt_mutex_destroy(&nfs->nfs4_open_mutex); nfs_mt_mutex_destroy(&nfs->nfs_mutex); #endif /* HAVE_MULTITHREADING */ free(nfs); diff --git a/lib/nfs_v4.c b/lib/nfs_v4.c index 3ff314e..69d6e8f 100644 --- a/lib/nfs_v4.c +++ b/lib/nfs_v4.c @@ -152,6 +152,7 @@ struct nfs4_cb_data { */ #define LOOKUP_FLAG_NO_FOLLOW 0x0001 #define LOOKUP_FLAG_IS_STATVFS64 0x0002 +#define MUTEX_HELD 0x0004 int flags; /* Internal callback for open-with-continuation use */ @@ -243,6 +244,11 @@ nfs4_resolve_path(struct nfs_context *nfs, const char *path) static void free_nfs4_cb_data(struct nfs4_cb_data *data) { +#ifdef HAVE_MULTITHREADING + if (data->flags & MUTEX_HELD) { + nfs_mt_mutex_unlock(&data->nfs->nfs4_open_mutex); + } +#endif free(data->path); free(data->filler.data); if (data->filler.blob0.val && data->filler.blob0.free) { @@ -2456,7 +2462,8 @@ nfs4_open_async(struct nfs_context *nfs, const char *path, int flags, { struct nfs4_cb_data *data; uint32_t m; - + int ret; + data = init_cb_data_split_path(nfs, path); if (data == NULL) { return -1; @@ -2502,7 +2509,14 @@ nfs4_open_async(struct nfs_context *nfs, const char *path, int flags, memcpy(data->filler.blob3.val, &m, sizeof(uint32_t)); } - return nfs4_open_async_internal(nfs, data, flags, mode); +#ifdef HAVE_MULTITHREADING + if (nfs->multithreading_enabled) { + nfs_mt_mutex_lock(&nfs->nfs4_open_mutex); + data->flags |= MUTEX_HELD; + } +#endif + ret = nfs4_open_async_internal(nfs, data, flags, mode); + return ret; } int @@ -2661,6 +2675,12 @@ nfs4_close_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, } memset(data, 0, sizeof(*data)); +#ifdef HAVE_MULTITHREADING + if (nfs->multithreading_enabled) { + nfs_mt_mutex_lock(&nfs->nfs4_open_mutex); + data->flags |= MUTEX_HELD; + } +#endif data->nfs = nfs; data->cb = cb; data->private_data = private_data; @@ -3855,6 +3875,12 @@ nfs4_truncate_async(struct nfs_context *nfs, const char *path, uint64_t length, length = nfs_hton64(length); memcpy(data->filler.blob3.val, &length, sizeof(uint64_t)); +#ifdef HAVE_MULTITHREADING + if (nfs->multithreading_enabled) { + nfs_mt_mutex_lock(&nfs->nfs4_open_mutex); + data->flags |= MUTEX_HELD; + } +#endif if (nfs4_open_async_internal(nfs, data, O_WRONLY, 0) < 0) { return -1; }