diff options
Diffstat (limited to 'fs/aio.c')
-rw-r--r-- | fs/aio.c | 19 |
1 files changed, 12 insertions, 7 deletions
@@ -899,16 +899,24 @@ static void aio_kick_handler(void *data) | |||
899 | * and if required activate the aio work queue to process | 899 | * and if required activate the aio work queue to process |
900 | * it | 900 | * it |
901 | */ | 901 | */ |
902 | static void queue_kicked_iocb(struct kiocb *iocb) | 902 | static void try_queue_kicked_iocb(struct kiocb *iocb) |
903 | { | 903 | { |
904 | struct kioctx *ctx = iocb->ki_ctx; | 904 | struct kioctx *ctx = iocb->ki_ctx; |
905 | unsigned long flags; | 905 | unsigned long flags; |
906 | int run = 0; | 906 | int run = 0; |
907 | 907 | ||
908 | WARN_ON((!list_empty(&iocb->ki_wait.task_list))); | 908 | /* We're supposed to be the only path putting the iocb back on the run |
909 | * list. If we find that the iocb is *back* on a wait queue already | ||
910 | * than retry has happened before we could queue the iocb. This also | ||
911 | * means that the retry could have completed and freed our iocb, no | ||
912 | * good. */ | ||
913 | BUG_ON((!list_empty(&iocb->ki_wait.task_list))); | ||
909 | 914 | ||
910 | spin_lock_irqsave(&ctx->ctx_lock, flags); | 915 | spin_lock_irqsave(&ctx->ctx_lock, flags); |
911 | run = __queue_kicked_iocb(iocb); | 916 | /* set this inside the lock so that we can't race with aio_run_iocb() |
917 | * testing it and putting the iocb on the run list under the lock */ | ||
918 | if (!kiocbTryKick(iocb)) | ||
919 | run = __queue_kicked_iocb(iocb); | ||
912 | spin_unlock_irqrestore(&ctx->ctx_lock, flags); | 920 | spin_unlock_irqrestore(&ctx->ctx_lock, flags); |
913 | if (run) | 921 | if (run) |
914 | aio_queue_work(ctx); | 922 | aio_queue_work(ctx); |
@@ -931,10 +939,7 @@ void fastcall kick_iocb(struct kiocb *iocb) | |||
931 | return; | 939 | return; |
932 | } | 940 | } |
933 | 941 | ||
934 | /* If its already kicked we shouldn't queue it again */ | 942 | try_queue_kicked_iocb(iocb); |
935 | if (!kiocbTryKick(iocb)) { | ||
936 | queue_kicked_iocb(iocb); | ||
937 | } | ||
938 | } | 943 | } |
939 | EXPORT_SYMBOL(kick_iocb); | 944 | EXPORT_SYMBOL(kick_iocb); |
940 | 945 | ||