diff --git a/include/fusd.h b/include/fusd.h index a6f1ca0..9f44dd8 100755 --- a/include/fusd.h +++ b/include/fusd.h @@ -66,6 +66,8 @@ __BEGIN_DECLS #define FUSD_KOR_HACKED_VERSION +#ifndef __KERNEL__ + struct fusd_file_info; /* forward decl */ typedef @@ -105,6 +107,7 @@ struct fusd_file_info { /* other info might be added later, e.g. state needed to complete operations... */ + pthread_mutex_t lock; /* request message associated with this call */ int fd; @@ -112,8 +115,8 @@ struct fusd_file_info { } fusd_file_info_t; - - +#define FILE_LOCK(__f) pthread_mutex_lock(&__f->lock) +#define FILE_UNLOCK(__f) pthread_mutex_unlock(&__f->lock) /*************************** Library Functions ****************************/ @@ -278,6 +281,8 @@ static inline int fusd_get_poll_diff_cached_state(struct fusd_file_info *file) /* returns static string representing the flagset (e.g. RWE) */ char *fusd_unparse_flags(int flags); +#endif /* !__KERNEL__ */ + #ifndef __KERNEL__ __END_DECLS #endif diff --git a/libfusd/libfusd.c b/libfusd/libfusd.c index e1f72e5..5e01dac 100755 --- a/libfusd/libfusd.c +++ b/libfusd/libfusd.c @@ -53,6 +53,11 @@ char libfusd_c_id[] = "$Id: libfusd.c 12351 2007-01-19 07:22:54Z xiphmont $"; #include #include +#include + +#include +#include + #include "fusd.h" #include "fusd_msg.h" @@ -72,7 +77,7 @@ char *dev_root = NULL; * struct for each fusd fd. */ static fusd_file_operations_t fusd_fops_set[FD_SETSIZE]; -fusd_file_operations_t null_fops = { NULL }; +fusd_file_operations_t null_fops = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; /* * accessor macros @@ -389,6 +394,11 @@ static int fusd_dispatch_one(int fd, fusd_file_operations_t *fops) /* fill the file info struct */ memset(file, '\0', sizeof(fusd_file_info_t)); + + pthread_mutex_init(&file->lock, NULL); + + FILE_LOCK(file); + file->fd = fd; file->device_info = msg->parm.fops_msg.device_info; file->private_data = msg->parm.fops_msg.private_info; @@ -398,6 +408,8 @@ static int fusd_dispatch_one(int fd, fusd_file_operations_t *fops) file->gid = msg->parm.fops_msg.gid; file->fusd_msg = msg; + FILE_UNLOCK(file); + /* right now we only handle fops requests */ if (msg->cmd != FUSD_FOPS_CALL && msg->cmd != FUSD_FOPS_NONBLOCK && msg->cmd != FUSD_FOPS_CALL_DROPREPLY) { @@ -602,20 +614,28 @@ int fusd_return(fusd_file_info_t *file, ssize_t retval) int driver_retval = 0; struct iovec iov[2]; - if (file == NULL) { + if (file == NULL) + { fprintf(stderr, "fusd_return: NULL file\n"); - return -EINVAL; + ret = -EINVAL; + goto exit; } + FILE_LOCK(file); + fd = file->fd; - if (!FUSD_FD_VALID(fd)) { + if (!FUSD_FD_VALID(fd)) + { fprintf(stderr, "fusd_return: badfd (fd %d)\n", fd); - return -EBADF; + ret = -EBADF; + goto exit_unlock; } - if ((msg = file->fusd_msg) == NULL) { + if ((msg = file->fusd_msg) == NULL) + { fprintf(stderr, "fusd_return: fusd_msg is gone\n"); - return -EINVAL; + ret = -EINVAL; + goto exit_unlock; } /* if this was a "DONTREPLY" message, just free the struct */ @@ -668,13 +688,23 @@ int fusd_return(fusd_file_info_t *file, ssize_t retval) driver_retval = write(fd, msg, sizeof(fusd_msg_t)); } +free_memory: + FILE_UNLOCK(file); free_memory: fusd_destroy(file); + ret = 0; if (driver_retval < 0) return -errno; else return 0; + goto exit; + +exit_unlock: + FILE_UNLOCK(file); + +exit: + return ret; }