diff options
Diffstat (limited to 'fs/aio.c')
-rw-r--r-- | fs/aio.c | 42 |
1 files changed, 16 insertions, 26 deletions
@@ -791,40 +791,30 @@ EXPORT_SYMBOL(wait_on_sync_kiocb); | |||
791 | */ | 791 | */ |
792 | void exit_aio(struct mm_struct *mm) | 792 | void exit_aio(struct mm_struct *mm) |
793 | { | 793 | { |
794 | struct kioctx_table *table; | 794 | struct kioctx_table *table = rcu_dereference_raw(mm->ioctx_table); |
795 | struct kioctx *ctx; | 795 | int i; |
796 | unsigned i = 0; | ||
797 | |||
798 | while (1) { | ||
799 | rcu_read_lock(); | ||
800 | table = rcu_dereference(mm->ioctx_table); | ||
801 | |||
802 | do { | ||
803 | if (!table || i >= table->nr) { | ||
804 | rcu_read_unlock(); | ||
805 | rcu_assign_pointer(mm->ioctx_table, NULL); | ||
806 | if (table) | ||
807 | kfree(table); | ||
808 | return; | ||
809 | } | ||
810 | 796 | ||
811 | ctx = table->table[i++]; | 797 | if (!table) |
812 | } while (!ctx); | 798 | return; |
813 | 799 | ||
814 | rcu_read_unlock(); | 800 | for (i = 0; i < table->nr; ++i) { |
801 | struct kioctx *ctx = table->table[i]; | ||
815 | 802 | ||
803 | if (!ctx) | ||
804 | continue; | ||
816 | /* | 805 | /* |
817 | * We don't need to bother with munmap() here - | 806 | * We don't need to bother with munmap() here - exit_mmap(mm) |
818 | * exit_mmap(mm) is coming and it'll unmap everything. | 807 | * is coming and it'll unmap everything. And we simply can't, |
819 | * Since aio_free_ring() uses non-zero ->mmap_size | 808 | * this is not necessarily our ->mm. |
820 | * as indicator that it needs to unmap the area, | 809 | * Since kill_ioctx() uses non-zero ->mmap_size as indicator |
821 | * just set it to 0; aio_free_ring() is the only | 810 | * that it needs to unmap the area, just set it to 0. |
822 | * place that uses ->mmap_size, so it's safe. | ||
823 | */ | 811 | */ |
824 | ctx->mmap_size = 0; | 812 | ctx->mmap_size = 0; |
825 | |||
826 | kill_ioctx(mm, ctx, NULL); | 813 | kill_ioctx(mm, ctx, NULL); |
827 | } | 814 | } |
815 | |||
816 | RCU_INIT_POINTER(mm->ioctx_table, NULL); | ||
817 | kfree(table); | ||
828 | } | 818 | } |
829 | 819 | ||
830 | static void put_reqs_available(struct kioctx *ctx, unsigned nr) | 820 | static void put_reqs_available(struct kioctx *ctx, unsigned nr) |