fix do_sync_(read|write) to properly handle aio retries
PATCH 1/1 fix do_sync_(read|write) to properly handle aio retries
When do_sync_(read|write) encounters an aio method that makes use of the retry mechanism, they fail to correctly retry the operation. This fixes that by adding the appropriate sleep and retry mechanism.
-ben
Signed-off-by Benjamin LaHaise <[email protected]>
fs/read_write.c +18 -2
@@ -203,6 +203,16 @@ Einval:return -EINVAL ; } +static void wait_on_retry_sync_kiocb (struct kiocb *iocb) +{ +set_current_state (TASK_UNINTERRUPTIBLE ); +if (!kiocbIsKicked (iocb)) +schedule (); +else +kiocbClearKicked (iocb); +__set_current_state (TASK_RUNNING ); +} +ssize_t do_sync_read (struct file *filp,char __user *buf,size_t len,loff_t *ppos) {struct kiocb kiocb;
@@ -210,7 +220,10 @@ ssize_t do_sync_read(struct file *filp,init_sync_kiocb (&kiocb, filp); kiocb.ki_pos = *ppos; - ret = filp->f_op->aio_read (&kiocb, buf, len, kiocb.ki_pos); +while (-EIOCBRETRY == + (ret = filp->f_op->aio_read (&kiocb, buf, len, kiocb.ki_pos))) +wait_on_retry_sync_kiocb (&kiocb); +if (-EIOCBQUEUED == ret) ret =wait_on_sync_kiocb (&kiocb); *ppos = kiocb.ki_pos;
@@ -258,7 +271,10 @@ ssize_t do_sync_write(struct file *filp,init_sync_kiocb (&kiocb, filp); kiocb.ki_pos = *ppos; - ret = filp->f_op->aio_write (&kiocb, buf, len, kiocb.ki_pos); +while (-EIOCBRETRY == + (ret = filp->f_op->aio_write (&kiocb, buf, len, kiocb.ki_pos))) +wait_on_retry_sync_kiocb (&kiocb); +if (-EIOCBQUEUED == ret) ret =wait_on_sync_kiocb (&kiocb); *ppos = kiocb.ki_pos;
Quoted 1 line · Benjamin LaHaise
When
do_sync_(read|write)encounters an aio method that makes use of the retry mechanism, they fail to correctly retry the operation. This fixes that by adding the appropriate sleep and retry mechanism.
Don't forget to send patches to [email protected] as well. He's evolved into the main collector of random patches, as well as being the 2.6 series maintainer.
Jeff