aboutsummaryrefslogtreecommitdiffstats
path: root/fs/read_write.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/read_write.c')
-rw-r--r--fs/read_write.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/fs/read_write.c b/fs/read_write.c
index c4c2bee373ed..9292f5fa4d62 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -203,6 +203,16 @@ Einval:
203 return -EINVAL; 203 return -EINVAL;
204} 204}
205 205
206static void wait_on_retry_sync_kiocb(struct kiocb *iocb)
207{
208 set_current_state(TASK_UNINTERRUPTIBLE);
209 if (!kiocbIsKicked(iocb))
210 schedule();
211 else
212 kiocbClearKicked(iocb);
213 __set_current_state(TASK_RUNNING);
214}
215
206ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos) 216ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
207{ 217{
208 struct kiocb kiocb; 218 struct kiocb kiocb;
@@ -210,7 +220,10 @@ ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *pp
210 220
211 init_sync_kiocb(&kiocb, filp); 221 init_sync_kiocb(&kiocb, filp);
212 kiocb.ki_pos = *ppos; 222 kiocb.ki_pos = *ppos;
213 ret = filp->f_op->aio_read(&kiocb, buf, len, kiocb.ki_pos); 223 while (-EIOCBRETRY ==
224 (ret = filp->f_op->aio_read(&kiocb, buf, len, kiocb.ki_pos)))
225 wait_on_retry_sync_kiocb(&kiocb);
226
214 if (-EIOCBQUEUED == ret) 227 if (-EIOCBQUEUED == ret)
215 ret = wait_on_sync_kiocb(&kiocb); 228 ret = wait_on_sync_kiocb(&kiocb);
216 *ppos = kiocb.ki_pos; 229 *ppos = kiocb.ki_pos;
@@ -258,7 +271,10 @@ ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, lof
258 271
259 init_sync_kiocb(&kiocb, filp); 272 init_sync_kiocb(&kiocb, filp);
260 kiocb.ki_pos = *ppos; 273 kiocb.ki_pos = *ppos;
261 ret = filp->f_op->aio_write(&kiocb, buf, len, kiocb.ki_pos); 274 while (-EIOCBRETRY ==
275 (ret = filp->f_op->aio_write(&kiocb, buf, len, kiocb.ki_pos)))
276 wait_on_retry_sync_kiocb(&kiocb);
277
262 if (-EIOCBQUEUED == ret) 278 if (-EIOCBQUEUED == ret)
263 ret = wait_on_sync_kiocb(&kiocb); 279 ret = wait_on_sync_kiocb(&kiocb);
264 *ppos = kiocb.ki_pos; 280 *ppos = kiocb.ki_pos;