|
@@ -317,6 +317,7 @@ static void queue_request(struct fuse_conn *fc, struct fuse_req *req)
|
|
|
list_add_tail(&req->list, &fc->pending);
|
|
|
req->state = FUSE_REQ_PENDING;
|
|
|
wake_up(&fc->waitq);
|
|
|
+ kill_fasync(&fc->fasync, SIGIO, POLL_IN);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -901,6 +902,7 @@ void fuse_abort_conn(struct fuse_conn *fc)
|
|
|
end_requests(fc, &fc->pending);
|
|
|
end_requests(fc, &fc->processing);
|
|
|
wake_up_all(&fc->waitq);
|
|
|
+ kill_fasync(&fc->fasync, SIGIO, POLL_IN);
|
|
|
}
|
|
|
spin_unlock(&fuse_lock);
|
|
|
}
|
|
@@ -917,12 +919,24 @@ static int fuse_dev_release(struct inode *inode, struct file *file)
|
|
|
end_requests(fc, &fc->processing);
|
|
|
}
|
|
|
spin_unlock(&fuse_lock);
|
|
|
- if (fc)
|
|
|
+ if (fc) {
|
|
|
+ fasync_helper(-1, file, 0, &fc->fasync);
|
|
|
kobject_put(&fc->kobj);
|
|
|
+ }
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int fuse_dev_fasync(int fd, struct file *file, int on)
|
|
|
+{
|
|
|
+ struct fuse_conn *fc = fuse_get_conn(file);
|
|
|
+ if (!fc)
|
|
|
+ return -ENODEV;
|
|
|
+
|
|
|
+ /* No locking - fasync_helper does its own locking */
|
|
|
+ return fasync_helper(fd, file, on, &fc->fasync);
|
|
|
+}
|
|
|
+
|
|
|
const struct file_operations fuse_dev_operations = {
|
|
|
.owner = THIS_MODULE,
|
|
|
.llseek = no_llseek,
|
|
@@ -932,6 +946,7 @@ const struct file_operations fuse_dev_operations = {
|
|
|
.writev = fuse_dev_writev,
|
|
|
.poll = fuse_dev_poll,
|
|
|
.release = fuse_dev_release,
|
|
|
+ .fasync = fuse_dev_fasync,
|
|
|
};
|
|
|
|
|
|
static struct miscdevice fuse_miscdevice = {
|