If we got a reconnect error from async readv we re-add pages back to page_list and continue loop. That is wrong because these pages have been already added to the pagecache but page_list has pages that have not been added to the pagecache yet. This ends up with a general protection fault in put_pages after readpages. Fix it by not retrying the read of these pages and falling back to readpage instead. Fixes debian bug 762306
Unified · Split
| @@ -3568,15 +3568,9 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, · 3567 unmodified lines | ||
| 3568 | 3568 | lru_cache_add_file(page); |
| 3569 | 3569 | unlock_page(page); |
| 3570 | 3570 | page_cache_release(page); |
| 3571 | − if (rc == -EAGAIN) | |
| 3572 | − list_add_tail(&page->lru, &tmplist); | |
| 3573 | 3571 | } |
| 3572 | + /* Fallback to the readpage in error/reconnect cases */ | |
| 3574 | 3573 | kref_put(&rdata->refcount, cifs_readdata_release); |
| 3575 | − if (rc == -EAGAIN) { | |
| 3576 | − /* Re-add pages to the page_list and retry */ | |
| 3577 | − list_splice(&tmplist, page_list); | |
| 3578 | − continue; | |
| 3579 | − } | |
| 3580 | 3574 | break; |
| 3581 | 3575 | } |
| 3582 | 3576 | |