|
@@ -1234,9 +1234,10 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
|
|
if (err)
|
|
if (err)
|
|
goto err_unlock;
|
|
goto err_unlock;
|
|
|
|
|
|
- err = -ENODEV;
|
|
|
|
- if (!fiq->connected)
|
|
|
|
|
|
+ if (!fiq->connected) {
|
|
|
|
+ err = (fc->aborted && fc->abort_err) ? -ECONNABORTED : -ENODEV;
|
|
goto err_unlock;
|
|
goto err_unlock;
|
|
|
|
+ }
|
|
|
|
|
|
if (!list_empty(&fiq->interrupts)) {
|
|
if (!list_empty(&fiq->interrupts)) {
|
|
req = list_entry(fiq->interrupts.next, struct fuse_req,
|
|
req = list_entry(fiq->interrupts.next, struct fuse_req,
|
|
@@ -1287,7 +1288,7 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
|
|
spin_lock(&fpq->lock);
|
|
spin_lock(&fpq->lock);
|
|
clear_bit(FR_LOCKED, &req->flags);
|
|
clear_bit(FR_LOCKED, &req->flags);
|
|
if (!fpq->connected) {
|
|
if (!fpq->connected) {
|
|
- err = -ENODEV;
|
|
|
|
|
|
+ err = (fc->aborted && fc->abort_err) ? -ECONNABORTED : -ENODEV;
|
|
goto out_end;
|
|
goto out_end;
|
|
}
|
|
}
|
|
if (err) {
|
|
if (err) {
|
|
@@ -2076,7 +2077,7 @@ static void end_polls(struct fuse_conn *fc)
|
|
* is OK, the request will in that case be removed from the list before we touch
|
|
* is OK, the request will in that case be removed from the list before we touch
|
|
* it.
|
|
* it.
|
|
*/
|
|
*/
|
|
-void fuse_abort_conn(struct fuse_conn *fc)
|
|
|
|
|
|
+void fuse_abort_conn(struct fuse_conn *fc, bool is_abort)
|
|
{
|
|
{
|
|
struct fuse_iqueue *fiq = &fc->iq;
|
|
struct fuse_iqueue *fiq = &fc->iq;
|
|
|
|
|
|
@@ -2089,6 +2090,7 @@ void fuse_abort_conn(struct fuse_conn *fc)
|
|
|
|
|
|
fc->connected = 0;
|
|
fc->connected = 0;
|
|
fc->blocked = 0;
|
|
fc->blocked = 0;
|
|
|
|
+ fc->aborted = is_abort;
|
|
fuse_set_initialized(fc);
|
|
fuse_set_initialized(fc);
|
|
list_for_each_entry(fud, &fc->devices, entry) {
|
|
list_for_each_entry(fud, &fc->devices, entry) {
|
|
struct fuse_pqueue *fpq = &fud->pq;
|
|
struct fuse_pqueue *fpq = &fud->pq;
|
|
@@ -2151,7 +2153,7 @@ int fuse_dev_release(struct inode *inode, struct file *file)
|
|
/* Are we the last open device? */
|
|
/* Are we the last open device? */
|
|
if (atomic_dec_and_test(&fc->dev_count)) {
|
|
if (atomic_dec_and_test(&fc->dev_count)) {
|
|
WARN_ON(fc->iq.fasync != NULL);
|
|
WARN_ON(fc->iq.fasync != NULL);
|
|
- fuse_abort_conn(fc);
|
|
|
|
|
|
+ fuse_abort_conn(fc, false);
|
|
}
|
|
}
|
|
fuse_dev_free(fud);
|
|
fuse_dev_free(fud);
|
|
}
|
|
}
|