HDFS-3306. fuse_dfs: don't lock release operations. Contributed by Colin Patrick McCabe

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1361022 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Eli Collins 2012-07-13 00:46:13 +00:00
parent 1a76841335
commit 0d9ef3c516
2 changed files with 26 additions and 44 deletions

View File

@ -134,6 +134,9 @@ Release 2.0.1-alpha - UNRELEASED
HDFS-799. libhdfs must call DetachCurrentThread when a thread is destroyed. HDFS-799. libhdfs must call DetachCurrentThread when a thread is destroyed.
(Colin Patrick McCabe via eli) (Colin Patrick McCabe via eli)
HDFS-3306. fuse_dfs: don't lock release operations.
(Colin Patrick McCabe via eli)
OPTIMIZATIONS OPTIMIZATIONS
HDFS-2982. Startup performance suffers when there are many edit log HDFS-2982. Startup performance suffers when there are many edit log

View File

@ -22,10 +22,17 @@
#include "fuse_connect.h" #include "fuse_connect.h"
/** /**
* This mutex is to protect releasing a file handle in case the user calls close in different threads * release a fuse_file_info structure.
* and fuse passes these calls to here. *
* When this function is invoked, there are no more references to our
* fuse_file_info structure that exist anywhere. So there is no need for
* locking to protect this structure here.
*
* Another thread could open() the same file, and get a separate, different file
* descriptor with a different, separate fuse_file_info structure. In HDFS,
* this results in one writer winning and overwriting everything the other
* writer has done.
*/ */
pthread_mutex_t release_mutex = PTHREAD_MUTEX_INITIALIZER;
int dfs_release (const char *path, struct fuse_file_info *fi) { int dfs_release (const char *path, struct fuse_file_info *fi) {
TRACE1("release", path) TRACE1("release", path)
@ -39,49 +46,21 @@ int dfs_release (const char *path, struct fuse_file_info *fi) {
assert('/' == *path); assert('/' == *path);
int ret = 0; int ret = 0;
//
// Critical section - protect from multiple close calls in different threads.
// (no returns until end)
//
pthread_mutex_lock(&release_mutex);
if (NULL != (void*)fi->fh) {
dfs_fh *fh = (dfs_fh*)fi->fh; dfs_fh *fh = (dfs_fh*)fi->fh;
assert(fh); assert(fh);
hdfsFile file_handle = (hdfsFile)fh->hdfsFH; hdfsFile file_handle = (hdfsFile)fh->hdfsFH;
if (NULL != file_handle) { if (NULL != file_handle) {
if (hdfsCloseFile(fh->fs, file_handle) != 0) { if (hdfsCloseFile(fh->fs, file_handle) != 0) {
ERROR("Could not close handle %ld for %s\n",(long)file_handle, path); ERROR("Could not close handle %ld for %s\n",(long)file_handle, path);
ret = -EIO; ret = -EIO;
} }
} }
if (fh->buf != NULL) {
free(fh->buf); free(fh->buf);
}
if (doDisconnect(fh->fs)) { if (doDisconnect(fh->fs)) {
ret = -EIO; ret = -EIO;
} }
// this is always created and initialized, so always destroy it. (see dfs_open)
pthread_mutex_destroy(&fh->mutex); pthread_mutex_destroy(&fh->mutex);
free(fh); free(fh);
fi->fh = 0;
fi->fh = (uint64_t)0;
}
pthread_mutex_unlock(&release_mutex);
//
// End critical section
//
return ret; return ret;
} }