diff --git a/kernel/dev.c b/kernel/dev.c index 1bff1eb..7036153 100644 --- a/kernel/dev.c +++ b/kernel/dev.c @@ -173,7 +173,7 @@ static void request_wait(struct fuse_conn *fc) DECLARE_WAITQUEUE(wait, current); add_wait_queue_exclusive(&fc->waitq, &wait); - while(list_empty(&fc->pending)) { + while(fc->sb != NULL && list_empty(&fc->pending)) { set_current_state(TASK_INTERRUPTIBLE); if(signal_pending(current)) break; @@ -230,17 +230,16 @@ static ssize_t fuse_dev_read(struct file *file, char *buf, size_t nbytes, struct fuse_conn *fc = DEV_FC(file); struct fuse_req *req = NULL; - if(fc->sb == NULL) - return -EPERM; - spin_lock(&fuse_lock); request_wait(fc); - if(!list_empty(&fc->pending)) { + if(fc->sb != NULL && !list_empty(&fc->pending)) { req = list_entry(fc->pending.next, struct fuse_req, list); list_del_init(&req->list); req->locked = 1; } spin_unlock(&fuse_lock); + if(fc->sb == NULL) + return -ENODEV; if(req == NULL) return -ERESTARTSYS; diff --git a/kernel/inode.c b/kernel/inode.c index df402ba..0f5fc8c 100644 --- a/kernel/inode.c +++ b/kernel/inode.c @@ -64,6 +64,8 @@ static void fuse_put_super(struct super_block *sb) fc->flags = 0; fuse_release_conn(fc); sb->u.generic_sbp = NULL; + /* Flush all readers on this fs */ + wake_up_all(&fc->waitq); spin_unlock(&fuse_lock); } diff --git a/lib/fuse.c b/lib/fuse.c index c8bc3e4..ab10df5 100644 --- a/lib/fuse.c +++ b/lib/fuse.c @@ -305,7 +305,7 @@ static int fill_dir(struct fuse_dirhandle *dh, char *name, int type) reclen = FUSE_DIRENT_SIZE(&dirent); res = fwrite(&dirent, reclen, 1, dh->fp); if(res == 0) { - perror("writing directory file"); + perror("fuse: writing directory file"); return -EIO; } return 0; @@ -330,7 +330,7 @@ static void send_reply_raw(struct fuse *f, char *outbuf, size_t outsize) if(res == -1) { /* ENOENT means the operation was interrupted */ if(errno != ENOENT) - perror("writing fuse device"); + perror("fuse: writing device"); } } @@ -342,7 +342,7 @@ static void send_reply(struct fuse *f, struct fuse_in_header *in, int error, struct fuse_out_header *out; if(error > 0) { - fprintf(stderr, "positive error code: %i\n", error); + fprintf(stderr, "fuse: positive error code: %i\n", error); error = -ERANGE; } @@ -861,8 +861,11 @@ struct fuse_cmd *__fuse_read_cmd(struct fuse *f) res = read(f->fd, cmd->buf, FUSE_MAX_IN); if(res == -1) { - perror("reading fuse device"); - /* BAD... This will happen again */ + /* ENODEV means we got unmounted, so we silenty return failure */ + if(errno != ENODEV) { + perror("fuse: reading device"); + /* BAD... This will happen again */ + } free_cmd(cmd); return NULL; } diff --git a/lib/fuse_mt.c b/lib/fuse_mt.c index d33682c..4534d0f 100644 --- a/lib/fuse_mt.c +++ b/lib/fuse_mt.c @@ -34,7 +34,7 @@ static void *do_work(void *data) while(1) { struct fuse_cmd *cmd = __fuse_read_cmd(w->f); if(cmd == NULL) - exit(1); + pthread_exit(NULL); if(f->numavail == 0 && f->numworker < FUSE_MAX_WORKERS) { pthread_mutex_lock(&f->lock);