NFS: Fix an Oops when truncating a file

The VM/VFS does not allow mapping->a_ops->invalidatepage() to fail.
Unfortunately, nfs_wb_page_cancel() may fail if a fatal signal occurs.
Since the NFS code assumes that the page stays mapped for as long as the
writeback is active, we can end up Oopsing (among other things).

The only safe fix here is to convert nfs_wait_on_request(), so as to make
it uninterruptible (as is already the case with wait_on_page_writeback()).


Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Cc: stable@kernel.org

+9 -8
+9 -8
fs/nfs/pagelist.c
··· 176 176 kref_put(&req->wb_kref, nfs_free_request); 177 177 } 178 178 179 + static int nfs_wait_bit_uninterruptible(void *word) 180 + { 181 + io_schedule(); 182 + return 0; 183 + } 184 + 179 185 /** 180 186 * nfs_wait_on_request - Wait for a request to complete. 181 187 * @req: request to wait upon. ··· 192 186 int 193 187 nfs_wait_on_request(struct nfs_page *req) 194 188 { 195 - int ret = 0; 196 - 197 - if (!test_bit(PG_BUSY, &req->wb_flags)) 198 - goto out; 199 - ret = out_of_line_wait_on_bit(&req->wb_flags, PG_BUSY, 200 - nfs_wait_bit_killable, TASK_KILLABLE); 201 - out: 202 - return ret; 189 + return wait_on_bit(&req->wb_flags, PG_BUSY, 190 + nfs_wait_bit_uninterruptible, 191 + TASK_UNINTERRUPTIBLE); 203 192 } 204 193 205 194 /**