Browse Source

Add debugging of mutexes (#1470)

When DEBUG defined it will used timed locks which will log when held
too long along with where.
pull/1472/head
trapexit 4 months ago
committed by GitHub
parent
commit
92312c8507
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 5
      libfuse/Makefile
  2. 7
      libfuse/include/mutex.hpp
  3. 128
      libfuse/include/mutex_debug.hpp
  4. 60
      libfuse/include/mutex_ndebug.hpp
  5. 164
      libfuse/lib/fuse.cpp
  6. 19
      libfuse/lib/fuse_lowlevel.cpp
  7. 14
      libfuse/lib/fuse_misc.h
  8. 224
      libfuse/lib/fuse_node.c
  9. 36
      libfuse/lib/fuse_node.h
  10. 66
      libfuse/lib/lfmp.h
  11. 6
      libfuse/lib/node.cpp
  12. 10
      libfuse/lib/node.hpp
  13. 6
      src/fs_statvfs_cache.cpp
  14. 15
      src/locked_fixed_mem_pool.hpp
  15. 24
      src/policy_cache.cpp

5
libfuse/Makefile

@ -43,8 +43,6 @@ SRC_C = \
lib/debug.c \
lib/fuse_dirents.c \
lib/fuse_lowlevel.c \
lib/node.c \
lib/fuse_node.c \
lib/fuse_opt.c \
lib/fuse_session.c \
lib/fuse_signals.c \
@ -57,7 +55,8 @@ SRC_CPP = \
lib/fuse_loop.cpp \
lib/fuse_msgbuf.cpp \
lib/pin_threads.cpp \
lib/format.cpp
lib/format.cpp \
lib/node.cpp
OBJS_C = $(SRC_C:lib/%.c=build/%.o)
OBJS_CPP = $(SRC_CPP:lib/%.cpp=build/%.o)

7
libfuse/include/mutex.hpp

@ -0,0 +1,7 @@
#pragma once
#ifdef DEBUG
#include "mutex_debug.hpp"
#else
#include "mutex_ndebug.hpp"
#endif

128
libfuse/include/mutex_debug.hpp

@ -0,0 +1,128 @@
#pragma once
#include "fmt/core.h"
#include <cstdlib>
#include <pthread.h>
#include <time.h>
#define mutex_init(M) _mutex_init(M,__FILE__,__func__,__LINE__)
#define mutex_destroy(M) _mutex_destroy(M,__FILE__,__func__,__LINE__)
#define mutex_lock(M) _mutex_lock(M,__FILE__,__func__,__LINE__)
#define mutex_unlock(M) _mutex_unlock(M,__FILE__,__func__,__LINE__)
static
inline
void
_print_error_and_abort(const char *func1_,
const int errno_,
const char *file_,
const char *func2_,
const int linenum_)
{
fmt::println(stderr,
"ERROR: {} returned {} ({}) - ({}:{}:{})",
func1_,
errno_,
strerror(errno_),
file_,
func2_,
linenum_);
abort();
}
static
inline
void
_mutex_init(pthread_mutex_t *mutex_,
const char *file_,
const char *func_,
const int linenum_)
{
int rv;
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_ADAPTIVE_NP);
rv = pthread_mutex_init(mutex_,&attr);
if(rv != 0)
_print_error_and_abort(__func__,rv,file_,func_,linenum_);
pthread_mutexattr_destroy(&attr);
}
static
inline
void
_mutex_destroy(pthread_mutex_t *mutex_,
const char *file_,
const char *func_,
const int linenum_)
{
int rv;
rv = pthread_mutex_destroy(mutex_);
if(rv != 0)
_print_error_and_abort(__func__,rv,file_,func_,linenum_);
}
static
inline
void
_mutex_lock(pthread_mutex_t *mutex_,
const char *file_,
const char *func_,
const int linenum_)
{
int rv;
int cnt = 0;
timespec timeout;
while(true)
{
clock_gettime(CLOCK_REALTIME,&timeout);
timeout.tv_nsec += 1000000 * 1; // 1ms
if(timeout.tv_nsec >= 1000000000)
{
timeout.tv_sec += 1;
timeout.tv_nsec -= 1000000000;
}
rv = pthread_mutex_timedlock(mutex_,&timeout);
switch(rv)
{
case 0:
return;
case ETIMEDOUT:
cnt++;
fmt::println(stderr,
"NOTICE: pthread_mutex_timedlock expired - count={}; ({}:{}:{})",
cnt,
file_,
func_,
linenum_);
continue;
default:
_print_error_and_abort(__func__,rv,file_,func_,linenum_);
return;
}
}
}
static
inline
void
_mutex_unlock(pthread_mutex_t *mutex_,
const char *file_,
const char *func_,
const int linenum_)
{
int rv;
rv = pthread_mutex_unlock(mutex_);
if(rv != 0)
_print_error_and_abort(__func__,rv,file_,func_,linenum_);
}

60
libfuse/include/mutex_ndebug.hpp

@ -0,0 +1,60 @@
#pragma once
#include <cstdlib>
#include <pthread.h>
static
inline
void
mutex_init(pthread_mutex_t *mutex_)
{
int rv;
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_ADAPTIVE_NP);
rv = pthread_mutex_init(mutex_,&attr);
if(rv != 0)
abort();
pthread_mutexattr_destroy(&attr);
}
static
inline
void
mutex_lock(pthread_mutex_t *mutex_)
{
int rv;
rv = pthread_mutex_lock(mutex_);
if(rv != 0)
abort();
}
static
inline
void
mutex_unlock(pthread_mutex_t *mutex_)
{
int rv;
rv = pthread_mutex_unlock(mutex_);
if(rv != 0)
abort();
}
static
inline
void
mutex_destroy(pthread_mutex_t *mutex_)
{
int rv;
rv = pthread_mutex_destroy(mutex_);
if(rv != 0)
abort();
}

164
libfuse/lib/fuse.cpp

@ -12,11 +12,11 @@
#endif
#include "crc32b.h"
#include "fuse_node.h"
#include "khash.h"
#include "kvec.h"
#include "mutex.hpp"
#include "node.hpp"
#include "node.h"
#include "config.h"
#include "fuse_dirents.h"
#include "fuse_i.h"
@ -736,7 +736,7 @@ find_node(struct fuse *f,
{
node_t *node;
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
if(!name)
node = get_node(f,parent);
else
@ -766,7 +766,7 @@ find_node(struct fuse *f,
}
inc_nlookup(node);
out_err:
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
return node;
}
@ -1071,7 +1071,7 @@ get_path_common(struct fuse *f,
{
int err;
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
err = try_get_path(f,nodeid,name,path,wnode,true);
if(err == -EAGAIN)
{
@ -1084,7 +1084,7 @@ get_path_common(struct fuse *f,
err = wait_path(f,&qe);
}
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
return err;
}
@ -1133,7 +1133,7 @@ get_path2(struct fuse *f,
{
int err;
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
err = try_get_path2(f,nodeid1,name1,nodeid2,name2,
path1,path2,wnode1,wnode2);
if(err == -EAGAIN)
@ -1151,7 +1151,7 @@ get_path2(struct fuse *f,
err = wait_path(f,&qe);
}
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
return err;
}
@ -1163,11 +1163,11 @@ free_path_wrlock(struct fuse *f,
node_t *wnode,
char *path)
{
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
unlock_path(f,nodeid,wnode,NULL);
if(f->lockq)
wake_up_queued(f);
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
free(path);
}
@ -1191,11 +1191,11 @@ free_path2(struct fuse *f,
char *path1,
char *path2)
{
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
unlock_path(f,nodeid1,wnode1,NULL);
unlock_path(f,nodeid2,wnode2,NULL);
wake_up_queued(f);
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
free(path1);
free(path2);
}
@ -1211,7 +1211,7 @@ forget_node(struct fuse *f,
if(nodeid == FUSE_ROOT_ID)
return;
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
node = get_node(f,nodeid);
/*
@ -1252,7 +1252,7 @@ forget_node(struct fuse *f,
kv_push(remembered_node_t,f->remembered_nodes,fn);
}
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
}
static
@ -1276,11 +1276,11 @@ remove_node(struct fuse *f,
{
node_t *node;
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
node = lookup_node(f,dir,name);
if(node != NULL)
unlink_node(f,node);
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
}
static
@ -1295,7 +1295,7 @@ rename_node(struct fuse *f,
node_t *newnode;
int err = 0;
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
node = lookup_node(f,olddir,oldname);
newnode = lookup_node(f,newdir,newname);
if(node == NULL)
@ -1312,7 +1312,7 @@ rename_node(struct fuse *f,
}
out:
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
return err;
}
@ -1375,9 +1375,9 @@ set_path_info(struct fuse *f,
e->ino = node->nodeid;
e->generation = ((e->ino == FUSE_ROOT_ID) ? 0 : f->nodeid_gen.generation);
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
update_stat(node,&e->attr);
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
set_stat(f,e->ino,&e->attr);
@ -1452,7 +1452,7 @@ int
fuse_create_context_key(void)
{
int err = 0;
pthread_mutex_lock(&fuse_context_lock);
mutex_lock(&fuse_context_lock);
if(!fuse_context_ref)
{
err = pthread_key_create(&fuse_context_key,fuse_freecontext);
@ -1460,12 +1460,12 @@ fuse_create_context_key(void)
{
fprintf(stderr,"fuse: failed to create thread specific key: %s\n",
strerror(err));
pthread_mutex_unlock(&fuse_context_lock);
mutex_unlock(&fuse_context_lock);
return -1;
}
}
fuse_context_ref++;
pthread_mutex_unlock(&fuse_context_lock);
mutex_unlock(&fuse_context_lock);
return 0;
}
@ -1473,14 +1473,14 @@ static
void
fuse_delete_context_key(void)
{
pthread_mutex_lock(&fuse_context_lock);
mutex_lock(&fuse_context_lock);
fuse_context_ref--;
if(!fuse_context_ref)
{
free(pthread_getspecific(fuse_context_key));
pthread_key_delete(fuse_context_key);
}
pthread_mutex_unlock(&fuse_context_lock);
mutex_unlock(&fuse_context_lock);
}
static
@ -1569,16 +1569,16 @@ fuse_lib_lookup(fuse_req_t req,
if(name[1] == '\0')
{
name = NULL;
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
dot = get_node_nocheck(f,nodeid);
if(dot == NULL)
{
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
reply_entry(req,&e,-ESTALE);
return;
}
dot->refctr++;
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
}
else if((name[1] == '.') && (name[2] == '\0'))
{
@ -1589,9 +1589,9 @@ fuse_lib_lookup(fuse_req_t req,
}
name = NULL;
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
nodeid = get_node(f,nodeid)->parent->nodeid;
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
}
}
@ -1609,9 +1609,9 @@ fuse_lib_lookup(fuse_req_t req,
if(dot)
{
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
unref_node(f,dot);
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
}
reply_entry(req,&e,err);
@ -1688,11 +1688,11 @@ fuse_lib_getattr(fuse_req_t req,
}
else
{
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
node = get_node(f,hdr_->nodeid);
if(node->hidden_fh)
ffi.fh = node->hidden_fh;
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
}
memset(&buf,0,sizeof(buf));
@ -1713,10 +1713,10 @@ fuse_lib_getattr(fuse_req_t req,
if(!err)
{
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
node = get_node(f,hdr_->nodeid);
update_stat(node,&buf);
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
set_stat(f,hdr_->nodeid,&buf);
fuse_reply_attr(req,&buf,timeout.attr);
}
@ -1823,14 +1823,14 @@ fuse_lib_setattr(fuse_req_t req,
}
else
{
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
node = get_node(f,hdr_->nodeid);
if(node->hidden_fh)
{
fi = &ffi;
fi->fh = node->hidden_fh;
}
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
}
err = 0;
@ -1909,9 +1909,9 @@ fuse_lib_setattr(fuse_req_t req,
if(!err)
{
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
update_stat(get_node(f,hdr_->nodeid),&stbuf);
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
set_stat(f,hdr_->nodeid,&stbuf);
fuse_reply_attr(req,&stbuf,timeout.attr);
}
@ -2076,10 +2076,10 @@ fuse_lib_unlink(fuse_req_t req,
if(!err)
{
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
if(node_open(wnode))
err = f->fs->op.prepare_hide(path,&wnode->hidden_fh);
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
err = f->fs->op.unlink(path);
if(!err)
@ -2172,10 +2172,10 @@ fuse_lib_rename(fuse_req_t req,
if(!err)
{
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
if(node_open(wnode2))
err = f->fs->op.prepare_hide(newpath,&wnode2->hidden_fh);
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
err = f->fs->op.rename(oldpath,newpath);
if(!err)
@ -2251,7 +2251,7 @@ fuse_do_release(struct fuse *f,
f->fs->op.release(fi);
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
{
node = get_node(f,ino);
assert(node->open_count > 0);
@ -2263,7 +2263,7 @@ fuse_do_release(struct fuse *f,
node->hidden_fh = 0;
}
}
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
if(fh)
f->fs->op.free_hide(fh);
@ -2316,9 +2316,9 @@ fuse_lib_create(fuse_req_t req,
if(!err)
{
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
get_node(f,e.ino)->open_count++;
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
if(fuse_reply_create(req,&e,&ffi) == -ENOENT)
{
@ -2346,7 +2346,7 @@ open_auto_cache(struct fuse *f,
node_t *node;
fuse_timeouts_t timeout;
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
node = get_node(f,ino);
if(node->is_stat_cache_valid)
@ -2354,9 +2354,9 @@ open_auto_cache(struct fuse *f,
int err;
struct stat stbuf;
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
err = f->fs->op.fgetattr(fi,&stbuf,&timeout);
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
if(!err)
update_stat(node,&stbuf);
@ -2369,7 +2369,7 @@ open_auto_cache(struct fuse *f,
node->is_stat_cache_valid = 1;
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
}
static
@ -2402,9 +2402,9 @@ fuse_lib_open(fuse_req_t req,
if(!err)
{
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
get_node(f,hdr_->nodeid)->open_count++;
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
/* The open syscall was interrupted,so it must be cancelled */
if(fuse_reply_open(req,&ffi) == -ENOENT)
fuse_do_release(f,hdr_->nodeid,&ffi);
@ -2544,7 +2544,7 @@ fuse_lib_opendir(fuse_req_t req,
}
fuse_dirents_init(&dh->d);
fuse_mutex_init(&dh->lock);
mutex_init(&dh->lock);
llffi.fh = (uintptr_t)dh;
ffi.flags = llffi.flags;
@ -2565,14 +2565,14 @@ fuse_lib_opendir(fuse_req_t req,
/* The opendir syscall was interrupted,so it
must be cancelled */
f->fs->op.releasedir(&ffi);
pthread_mutex_destroy(&dh->lock);
mutex_destroy(&dh->lock);
free(dh);
}
}
else
{
fuse_reply_err(req,err);
pthread_mutex_destroy(&dh->lock);
mutex_destroy(&dh->lock);
free(dh);
}
@ -2626,7 +2626,7 @@ fuse_lib_readdir(fuse_req_t req_,
dh = get_dirhandle(&llffi,&ffi);
d = &dh->d;
pthread_mutex_lock(&dh->lock);
mutex_lock(&dh->lock);
rv = 0;
if((arg->offset == 0) || (kv_size(d->data) == 0))
@ -2645,7 +2645,7 @@ fuse_lib_readdir(fuse_req_t req_,
size);
out:
pthread_mutex_unlock(&dh->lock);
mutex_unlock(&dh->lock);
}
static
@ -2670,7 +2670,7 @@ fuse_lib_readdir_plus(fuse_req_t req_,
dh = get_dirhandle(&llffi,&ffi);
d = &dh->d;
pthread_mutex_lock(&dh->lock);
mutex_lock(&dh->lock);
rv = 0;
if((arg->offset == 0) || (kv_size(d->data) == 0))
@ -2689,7 +2689,7 @@ fuse_lib_readdir_plus(fuse_req_t req_,
size);
out:
pthread_mutex_unlock(&dh->lock);
mutex_unlock(&dh->lock);
}
static
@ -2713,9 +2713,9 @@ fuse_lib_releasedir(fuse_req_t req_,
f->fs->op.releasedir(&ffi);
/* Done to keep race condition between last readdir reply and the unlock */
pthread_mutex_lock(&dh->lock);
pthread_mutex_unlock(&dh->lock);
pthread_mutex_destroy(&dh->lock);
mutex_lock(&dh->lock);
mutex_unlock(&dh->lock);
mutex_destroy(&dh->lock);
fuse_dirents_free(&dh->d);
free(dh);
fuse_reply_err(req_,0);
@ -3057,9 +3057,9 @@ fuse_lib_tmpfile(fuse_req_t req_,
if(!err)
{
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
get_node(f,e.ino)->open_count++;
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
if(fuse_reply_create(req_,&e,&ffi) == -ENOENT)
{
@ -3241,9 +3241,9 @@ fuse_flush_common(struct fuse *f,
{
flock_to_lock(&lock,&l);
l.owner = fi->lock_owner;
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
locks_insert(get_node(f,ino),&l);
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
/* if op.lock() is defined FLUSH is needed regardless
of op.flush() */
@ -3371,11 +3371,11 @@ fuse_lib_getlk(fuse_req_t req,
flock_to_lock(&flk,&lk);
lk.owner = ffi.lock_owner;
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
conflict = locks_conflict(get_node(f,hdr_->nodeid),&lk);
if(conflict)
lock_to_flock(conflict,&flk);
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
if(!conflict)
err = fuse_lock_common(req,hdr_->nodeid,&ffi,&flk,F_GETLK);
else
@ -3403,9 +3403,9 @@ fuse_lib_setlk(fuse_req_t req,
lock_t l;
flock_to_lock(lock,&l);
l.owner = fi->lock_owner;
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
locks_insert(get_node(f,ino),&l);
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
}
fuse_reply_err(req,err);
@ -3600,12 +3600,12 @@ static
void
remembered_nodes_sort(struct fuse *f_)
{
pthread_mutex_lock(&f_->lock);
mutex_lock(&f_->lock);
qsort(&kv_first(f_->remembered_nodes),
kv_size(f_->remembered_nodes),
sizeof(remembered_node_t),
remembered_node_cmp);
pthread_mutex_unlock(&f_->lock);
mutex_unlock(&f_->lock);
}
#define MAX_PRUNE 100
@ -3619,7 +3619,7 @@ fuse_prune_some_remembered_nodes(struct fuse *f_,
int pruned;
int checked;
pthread_mutex_lock(&f_->lock);
mutex_lock(&f_->lock);
pruned = 0;
checked = 0;
@ -3654,7 +3654,7 @@ fuse_prune_some_remembered_nodes(struct fuse *f_,
pruned++;
}
pthread_mutex_unlock(&f_->lock);
mutex_unlock(&f_->lock);
if((pruned < MAX_PRUNE) && (checked < MAX_CHECK))
*offset_ = -1;
@ -4008,7 +4008,7 @@ fuse_invalidate_all_nodes()
struct fuse *f = fuse_get_fuse_obj();
std::vector<std::string> names;
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
for(size_t i = 0; i < f->id_table.size; i++)
{
node_t *node;
@ -4027,7 +4027,7 @@ fuse_invalidate_all_nodes()
names.emplace_back(node->name);
}
}
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
syslog(LOG_INFO,
"invalidating %ld file entries",
@ -4098,9 +4098,9 @@ fuse_start_maintenance_thread(struct fuse *f_)
void
fuse_stop_maintenance_thread(struct fuse *f_)
{
pthread_mutex_lock(&f_->lock);
mutex_lock(&f_->lock);
pthread_cancel(f_->maintenance_thread);
pthread_mutex_unlock(&f_->lock);
mutex_unlock(&f_->lock);
pthread_join(f_->maintenance_thread,NULL);
}
@ -4159,7 +4159,7 @@ fuse_new_common(struct fuse_chan *ch,
if(node_table_init(&f->id_table) == -1)
goto out_free_name_table;
fuse_mutex_init(&f->lock);
mutex_init(&f->lock);
kv_init(f->remembered_nodes);
@ -4249,7 +4249,7 @@ fuse_destroy(struct fuse *f)
free(f->id_table.array);
free(f->name_table.array);
pthread_mutex_destroy(&f->lock);
mutex_destroy(&f->lock);
fuse_session_destroy(f->se);
kv_destroy(f->remembered_nodes);
fuse_delete_context_key();

19
libfuse/lib/fuse_lowlevel.cpp

@ -10,6 +10,7 @@
#define _GNU_SOURCE
#endif
#include "mutex.hpp"
#include "lfmp.h"
#include "config.h"
@ -1361,7 +1362,7 @@ do_notify_reply(fuse_req_t req,
struct fuse_notify_req *nreq;
struct fuse_notify_req *head;
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
head = &f->notify_list;
for(nreq = head->next; nreq != head; nreq = nreq->next)
{
@ -1371,7 +1372,7 @@ do_notify_reply(fuse_req_t req,
break;
}
}
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
if(nreq != head)
nreq->reply(nreq, req, hdr_->nodeid, &hdr_[1]);
@ -1666,12 +1667,12 @@ fuse_lowlevel_notify_retrieve(struct fuse_chan *ch,
if(rreq == NULL)
return -ENOMEM;
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
rreq->cookie = cookie;
rreq->nreq.unique = f->notify_ctr++;
rreq->nreq.reply = fuse_ll_retrieve_reply;
list_add_nreq(&rreq->nreq, &f->notify_list);
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
outarg.notify_unique = rreq->nreq.unique;
outarg.nodeid = ino;
@ -1684,9 +1685,9 @@ fuse_lowlevel_notify_retrieve(struct fuse_chan *ch,
err = send_notify_iov(f, ch, FUSE_NOTIFY_RETRIEVE, iov, 2);
if(err)
{
pthread_mutex_lock(&f->lock);
mutex_lock(&f->lock);
list_del_nreq(&rreq->nreq);
pthread_mutex_unlock(&f->lock);
mutex_unlock(&f->lock);
free(rreq);
}
@ -1866,7 +1867,7 @@ fuse_ll_destroy(void *data)
if(llp != NULL)
fuse_ll_pipe_free(llp);
pthread_key_delete(f->pipe_key);
pthread_mutex_destroy(&f->lock);
mutex_destroy(&f->lock);
free(f);
lfmp_clear(&g_FMP_fuse_req);
@ -2033,7 +2034,7 @@ fuse_lowlevel_new_common(struct fuse_args *args,
f->conn.max_readahead = UINT_MAX;
list_init_nreq(&f->notify_list);
f->notify_ctr = 1;
fuse_mutex_init(&f->lock);
mutex_init(&f->lock);
err = pthread_key_create(&f->pipe_key, fuse_ll_pipe_destructor);
if(err)
@ -2063,7 +2064,7 @@ fuse_lowlevel_new_common(struct fuse_args *args,
out_key_destroy:
pthread_key_delete(f->pipe_key);
out_free:
pthread_mutex_destroy(&f->lock);
mutex_destroy(&f->lock);
free(f);
out:
return NULL;

14
libfuse/lib/fuse_misc.h

@ -23,20 +23,6 @@
#define FUSE_SYMVER(x)
#endif
#ifndef USE_UCLIBC
#define fuse_mutex_init(mut) pthread_mutex_init(mut, NULL)
#else
/* Is this hack still needed? */
static inline void fuse_mutex_init(pthread_mutex_t *mut)
{
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP);
pthread_mutex_init(mut, &attr);
pthread_mutexattr_destroy(&attr);
}
#endif
#ifdef HAVE_STRUCT_STAT_ST_ATIM
/* Linux */
#define ST_ATIM_NSEC(stbuf) ((stbuf)->st_atim.tv_nsec)

224
libfuse/lib/fuse_node.c

@ -1,224 +0,0 @@
#include "fuse_node.h"
#include "khash.h"
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <stdio.h> // for debugging
#define UNKNOWN_INO UINT64_MAX
#define ROOT_NODE_ID 0
#define ROOT_NODE_NAME "/"
typedef struct node_idname_t node_idname_t;
struct node_idname_t
{
uint64_t id;
const char *name;
};
static khint_t idname_hash_func(const node_idname_t idname);
static int idname_hash_equal(const node_idname_t idname0, const node_idname_t idname1);
KHASH_INIT(node,node_idname_t,fuse_node_t*,1,idname_hash_func,idname_hash_equal);
typedef struct fuse_node_hashtable_t fuse_node_hashtable_t;
struct fuse_node_hashtable_t
{
kh_node_t *ht;
uint64_t id;
uint64_t generation;
};
static
inline
khint_t
idname_hash_func(const node_idname_t idname_)
{
if(idname_.name == NULL)
return idname_.id;
return (idname_.id ^ kh_str_hash_func(idname_.name));
}
static
inline
int
idname_hash_equal(const node_idname_t idname0_,
const node_idname_t idname1_)
{
return ((idname0_.id == idname1_.id) &&
((idname0_.name == idname1_.name) ||
(strcmp(idname0_.name,idname1_.name) == 0)));
}
static
inline
fuse_node_t*
fuse_node_alloc(const uint64_t id_,
const char *name_)
{
fuse_node_t *node;
node = (fuse_node_t*)calloc(1,sizeof(fuse_node_t));
node->id = id_;
node->name = strdup(name_);
node->ref_count = 1;
node->lookup_count = 1;
return node;
}
static
inline
void
fuse_node_free(fuse_node_t *node_)
{
free(node_->name);
free(node_);
}
static
inline
uint64_t
rand64()
{
uint64_t rv;
rv = rand();
rv <<= 32;
rv |= rand();
return rv;
}
static
inline
void
node_hashtable_gen_unique_id(fuse_node_hashtable_t *ht_)
{
do
{
ht_->id++;
if(ht_->id == 0)
ht_->generation++;
}
while((ht_->id == 0) || (ht_->id == UNKNOWN_INO));
}
static
inline
void
node_hashtable_put_root(fuse_node_hashtable_t *ht_)
{
int rv;
khint_t k;
fuse_node_t *root_node;
const node_idname_t idname0 = {ROOT_NODE_ID,""};
const node_idname_t idname1 = {ROOT_NODE_ID,ROOT_NODE_NAME};
root_node = fuse_node_alloc(ROOT_NODE_ID,ROOT_NODE_NAME);
k = kh_put_node(ht_->ht,idname0,&rv);
kh_value(ht_->ht,k) = root_node;
k = kh_put_node(ht_->ht,idname1,&rv);
kh_value(ht_->ht,k) = root_node;
}
static
inline
void
node_hashtable_set_id_gen(fuse_node_hashtable_t *ht_,
fuse_node_t *node_)
{
node_hashtable_gen_unique_id(ht_);
node_->id = ht_->id;
node_->generation = ht_->generation;
}
fuse_node_hashtable_t*
fuse_node_hashtable_init()
{
fuse_node_hashtable_t *ht;
ht = (fuse_node_hashtable_t*)calloc(sizeof(fuse_node_hashtable_t),1);
if(ht == NULL)
return NULL;
ht->ht = kh_init_node();
if(ht->ht == NULL)
{
free(ht);
return NULL;
}
srand(time(NULL));
ht->id = 0;
ht->generation = rand64();
node_hashtable_put_root(ht);
return ht;
}
fuse_node_t*
fuse_node_hashtable_put(fuse_node_hashtable_t *ht_,
const uint64_t parent_id_,
const uint64_t child_id_,
const char *child_name_)
{
int rv;
khint_t k;
fuse_node_t *child_node;
const node_idname_t p_idname = {parent_id_,""};
const node_idname_t c0_idname = {child_id_,child_name_};
const node_idname_t c1_idname = {parent_id_,child_name_};
child_node = fuse_node_alloc(child_id_,child_name_);
k = kh_get_node(ht_->ht,p_idname);
child_node->parent = kh_value(ht_->ht,k);
child_node->parent->ref_count++;
k = kh_put_node(ht_->ht,c0_idname,&rv);
kh_value(ht_->ht,k) = child_node;
k = kh_put_node(ht_->ht,c1_idname,&rv);
kh_value(ht_->ht,k) = child_node;
return child_node;
}
fuse_node_t*
fuse_node_hashtable_get(fuse_node_hashtable_t *ht_,
const uint64_t id_)
{
return fuse_node_hashtable_get_child(ht_,id_,"");
}
fuse_node_t*
fuse_node_hashtable_get_child(fuse_node_hashtable_t *ht_,
const uint64_t parent_id_,
const char *child_name_)
{
khint_t k;
fuse_node_t *node;
const node_idname_t idname = {parent_id_,child_name_};
k = kh_get_node(ht_->ht,idname);
node = ((k != kh_end(ht_->ht)) ?
kh_value(ht_->ht,k) :
NULL);
return node;
}
void
fuse_node_hashtable_del(fuse_node_hashtable_t *ht_,
fuse_node_t *node_)
{
}

36
libfuse/lib/fuse_node.h

@ -1,36 +0,0 @@
#include <stdint.h>
typedef struct fuse_node_t fuse_node_t;
struct fuse_node_t
{
uint64_t id;
uint64_t generation;
char *name;
fuse_node_t *parent;
uint32_t ref_count;
uint64_t lookup_count;
uint64_t open_count;
};
struct fuse_node_hashtable_t;
typedef struct fuse_node_hashtable_t fuse_node_hashtable_t;
fuse_node_hashtable_t *fuse_node_hashtable_init();
fuse_node_t *fuse_node_hashtable_put(fuse_node_hashtable_t *ht,
const uint64_t parent_id,
const uint64_t child_id,
const char *child_name);
fuse_node_t* fuse_node_hashtable_get(fuse_node_hashtable_t *ht,
const uint64_t id);
fuse_node_t* fuse_node_hashtable_get_child(fuse_node_hashtable_t *ht,
const uint64_t id,
const char *name);
void fuse_node_hashtable_del(fuse_node_hashtable_t *ht,
fuse_node_t *node);
void fuse_node_hashtable_get_path(fuse_node_hashtable_t *ht,
char *buf,
uint32_t buflen);

66
libfuse/lib/lfmp.h

@ -20,6 +20,8 @@
#include "fmp.h"
#include "mutex.hpp"
#include <pthread.h>
@ -39,7 +41,7 @@ lfmp_init(lfmp_t *lfmp_,
const uint64_t page_multiple_)
{
fmp_init(&lfmp_->fmp,obj_size_,page_multiple_);
pthread_mutex_init(&lfmp_->lock,NULL);
mutex_init(&lfmp_->lock);
}
static
@ -47,7 +49,7 @@ inline
void
lfmp_lock(lfmp_t *lfmp_)
{
pthread_mutex_lock(&lfmp_->lock);
mutex_lock(&lfmp_->lock);
}
static
@ -55,7 +57,7 @@ inline
void
lfmp_unlock(lfmp_t *lfmp_)
{
pthread_mutex_unlock(&lfmp_->lock);
mutex_unlock(&lfmp_->lock);
}
static
@ -65,9 +67,9 @@ lfmp_slab_count(lfmp_t *lfmp_)
{
uint64_t rv;
pthread_mutex_lock(&lfmp_->lock);
mutex_lock(&lfmp_->lock);
rv = fmp_slab_count(&lfmp_->fmp);
pthread_mutex_unlock(&lfmp_->lock);
mutex_unlock(&lfmp_->lock);
return rv;
}
@ -79,9 +81,9 @@ lfmp_slab_alloc(lfmp_t *lfmp_)
{
int rv;
pthread_mutex_lock(&lfmp_->lock);
mutex_lock(&lfmp_->lock);
rv = fmp_slab_alloc(&lfmp_->fmp);
pthread_mutex_unlock(&lfmp_->lock);
mutex_unlock(&lfmp_->lock);
return rv;
}
@ -93,9 +95,9 @@ lfmp_alloc(lfmp_t *lfmp_)
{
void *rv;
pthread_mutex_lock(&lfmp_->lock);
mutex_lock(&lfmp_->lock);
rv = fmp_alloc(&lfmp_->fmp);
pthread_mutex_unlock(&lfmp_->lock);
mutex_unlock(&lfmp_->lock);
return rv;
}
@ -107,9 +109,9 @@ lfmp_calloc(lfmp_t *lfmp_)
{
void *rv;
pthread_mutex_lock(&lfmp_->lock);
mutex_lock(&lfmp_->lock);
rv = fmp_calloc(&lfmp_->fmp);
pthread_mutex_unlock(&lfmp_->lock);
mutex_unlock(&lfmp_->lock);
return rv;
}
@ -120,9 +122,9 @@ void
lfmp_free(lfmp_t *lfmp_,
void *obj_)
{
pthread_mutex_lock(&lfmp_->lock);
mutex_lock(&lfmp_->lock);
fmp_free(&lfmp_->fmp,obj_);
pthread_mutex_unlock(&lfmp_->lock);
mutex_unlock(&lfmp_->lock);
}
static
@ -130,9 +132,9 @@ inline
void
lfmp_clear(lfmp_t *lfmp_)
{
pthread_mutex_lock(&lfmp_->lock);
mutex_lock(&lfmp_->lock);
fmp_clear(&lfmp_->fmp);
pthread_mutex_unlock(&lfmp_->lock);
mutex_unlock(&lfmp_->lock);
}
static
@ -140,10 +142,10 @@ inline
void
lfmp_destroy(lfmp_t *lfmp_)
{
pthread_mutex_lock(&lfmp_->lock);
mutex_lock(&lfmp_->lock);
fmp_destroy(&lfmp_->fmp);
pthread_mutex_unlock(&lfmp_->lock);
pthread_mutex_destroy(&lfmp_->lock);
mutex_unlock(&lfmp_->lock);
mutex_destroy(&lfmp_->lock);
}
static
@ -153,9 +155,9 @@ lfmp_avail_objs(lfmp_t *lfmp_)
{
uint64_t rv;
pthread_mutex_lock(&lfmp_->lock);
mutex_lock(&lfmp_->lock);
rv = fmp_avail_objs(&lfmp_->fmp);
pthread_mutex_unlock(&lfmp_->lock);
mutex_unlock(&lfmp_->lock);
return rv;
}
@ -168,9 +170,9 @@ lfmp_objs_in_slab(lfmp_t *lfmp_,
{
uint64_t rv;
pthread_mutex_lock(&lfmp_->lock);
mutex_lock(&lfmp_->lock);
rv = fmp_objs_in_slab(&lfmp_->fmp,slab_);
pthread_mutex_unlock(&lfmp_->lock);
mutex_unlock(&lfmp_->lock);
return rv;
}
@ -181,9 +183,9 @@ void
lfmp_remove_objs_in_slab(lfmp_t *lfmp_,
void *slab_)
{
pthread_mutex_lock(&lfmp_->lock);
mutex_lock(&lfmp_->lock);
fmp_remove_objs_in_slab(&lfmp_->fmp,slab_);
pthread_mutex_unlock(&lfmp_->lock);
mutex_unlock(&lfmp_->lock);
}
static
@ -193,9 +195,9 @@ lfmp_gc(lfmp_t *lfmp_)
{
int rv;
pthread_mutex_lock(&lfmp_->lock);
mutex_lock(&lfmp_->lock);
rv = fmp_gc(&lfmp_->fmp);
pthread_mutex_unlock(&lfmp_->lock);
mutex_unlock(&lfmp_->lock);
return rv;
}
@ -207,9 +209,9 @@ lfmp_objs_per_slab(lfmp_t *lfmp_)
{
uint64_t rv;
pthread_mutex_lock(&lfmp_->lock);
mutex_lock(&lfmp_->lock);
rv = fmp_objs_per_slab(&lfmp_->fmp);
pthread_mutex_unlock(&lfmp_->lock);
mutex_unlock(&lfmp_->lock);
return rv;
}
@ -221,9 +223,9 @@ lfmp_slab_usage_ratio(lfmp_t *lfmp_)
{
double rv;
pthread_mutex_lock(&lfmp_->lock);
mutex_lock(&lfmp_->lock);
rv = fmp_slab_usage_ratio(&lfmp_->fmp);
pthread_mutex_unlock(&lfmp_->lock);
mutex_unlock(&lfmp_->lock);
return rv;
}
@ -235,9 +237,9 @@ lfmp_total_allocated_memory(lfmp_t *lfmp_)
{
uint64_t rv;
pthread_mutex_lock(&lfmp_->lock);
mutex_lock(&lfmp_->lock);
rv = fmp_total_allocated_memory(&lfmp_->fmp);
pthread_mutex_unlock(&lfmp_->lock);
mutex_unlock(&lfmp_->lock);
return rv;
}

6
libfuse/lib/node.c → libfuse/lib/node.cpp

@ -1,4 +1,4 @@
#include "node.h"
#include "node.hpp"
#include "lfmp.h"
@ -20,10 +20,10 @@ node_destructor()
lfmp_destroy(&g_NODE_FMP);
}
node_t *
node_t*
node_alloc()
{
return lfmp_calloc(&g_NODE_FMP);
return (node_t*)lfmp_calloc(&g_NODE_FMP);
}
void

10
libfuse/lib/node.h → libfuse/lib/node.hpp

@ -25,18 +25,8 @@ struct node_s
uint8_t is_stat_cache_valid:1;
};
#ifdef __cplusplus
extern "C"
{
#endif
node_t *node_alloc();
void node_free(node_t*);
int node_gc1();
void node_gc();
lfmp_t *node_lfmp();
#ifdef __cplusplus
}
#endif

6
src/fs_statvfs_cache.cpp

@ -19,6 +19,8 @@
#include "fs_statvfs.hpp"
#include "statvfs_util.hpp"
#include "mutex.hpp"
#include <cstdint>
#include <map>
#include <string>
@ -82,7 +84,7 @@ namespace fs
rv = 0;
now = l::get_time();
pthread_mutex_lock(&g_cache_lock);
mutex_lock(&g_cache_lock);
e = &g_cache[path_];
@ -94,7 +96,7 @@ namespace fs
*st_ = e->st;
pthread_mutex_unlock(&g_cache_lock);
mutex_unlock(&g_cache_lock);
return rv;
}

15
src/locked_fixed_mem_pool.hpp

@ -20,20 +20,23 @@
#include "fixed_mem_pool.hpp"
#include "mutex.hpp"
#include <pthread.h>
template<size_t SIZE>
class LockedFixedMemPool
{
public:
LockedFixedMemPool()
{
pthread_mutex_init(&_mutex,NULL);
mutex_init(&_mutex);
}
~LockedFixedMemPool()
{
pthread_mutex_destroy(&_mutex);
mutex_destroy(&_mutex);
}
public:
@ -42,9 +45,9 @@ public:
{
void *mem;
pthread_mutex_lock(&_mutex);
mutex_lock(&_mutex);
mem = _fmp.alloc();
pthread_mutex_unlock(&_mutex);
mutex_unlock(&_mutex);
return mem;
}
@ -52,9 +55,9 @@ public:
void
free(void *mem_)
{
pthread_mutex_lock(&_mutex);
mutex_lock(&_mutex);
_fmp.free(mem_);
pthread_mutex_unlock(&_mutex);
mutex_unlock(&_mutex);
}
uint64_t

24
src/policy_cache.cpp

@ -1,5 +1,7 @@
#include "policy_cache.hpp"
#include "mutex.hpp"
#include <cstdlib>
#include <map>
#include <string>
@ -36,7 +38,7 @@ PolicyCache::Value::Value()
PolicyCache::PolicyCache(void)
: timeout(DEFAULT_TIMEOUT)
{
pthread_mutex_init(&_lock,NULL);
mutex_init(&_lock);
}
void
@ -45,11 +47,11 @@ PolicyCache::erase(const char *fusepath_)
if(timeout == 0)
return;
pthread_mutex_lock(&_lock);
mutex_lock(&_lock);
_cache.erase(fusepath_);
pthread_mutex_unlock(&_lock);
mutex_unlock(&_lock);
}
void
@ -66,7 +68,7 @@ PolicyCache::cleanup(const int prob_)
now = l::get_time();
pthread_mutex_lock(&_lock);
mutex_lock(&_lock);
i = _cache.begin();
while(i != _cache.end())
@ -77,17 +79,17 @@ PolicyCache::cleanup(const int prob_)
++i;
}
pthread_mutex_unlock(&_lock);
mutex_unlock(&_lock);
}
void
PolicyCache::clear(void)
{
pthread_mutex_lock(&_lock);
mutex_lock(&_lock);
_cache.clear();
pthread_mutex_unlock(&_lock);
mutex_unlock(&_lock);
}
int
@ -105,18 +107,18 @@ PolicyCache::operator()(const Policy::Search &policy_,
now = l::get_time();
pthread_mutex_lock(&_lock);
mutex_lock(&_lock);
v = &_cache[fusepath_];
if((now - v->time) >= timeout)
{
pthread_mutex_unlock(&_lock);
mutex_unlock(&_lock);
rv = policy_(branches_,fusepath_,paths_);
if(rv == -1)
return -1;
pthread_mutex_lock(&_lock);
mutex_lock(&_lock);
v->time = now;
v->paths = paths_;
}
@ -125,7 +127,7 @@ PolicyCache::operator()(const Policy::Search &policy_,
paths_ = v->paths;
}
pthread_mutex_unlock(&_lock);
mutex_unlock(&_lock);
return 0;
}
Loading…
Cancel
Save