proc: convert /proc/$PID/io to seq_file interface
[cascardo/linux.git] / fs / aio.c
index 955947e..bd7ec2c 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -506,6 +506,8 @@ static void free_ioctx(struct work_struct *work)
 
        aio_free_ring(ctx);
        free_percpu(ctx->cpu);
+       percpu_ref_exit(&ctx->reqs);
+       percpu_ref_exit(&ctx->users);
        kmem_cache_free(kioctx_cachep, ctx);
 }
 
@@ -715,8 +717,8 @@ err_ctx:
 err:
        mutex_unlock(&ctx->ring_lock);
        free_percpu(ctx->cpu);
-       free_percpu(ctx->reqs.pcpu_count);
-       free_percpu(ctx->users.pcpu_count);
+       percpu_ref_exit(&ctx->reqs);
+       percpu_ref_exit(&ctx->users);
        kmem_cache_free(kioctx_cachep, ctx);
        pr_debug("error allocating ioctx %d\n", err);
        return ERR_PTR(err);
@@ -830,16 +832,20 @@ void exit_aio(struct mm_struct *mm)
 static void put_reqs_available(struct kioctx *ctx, unsigned nr)
 {
        struct kioctx_cpu *kcpu;
+       unsigned long flags;
 
        preempt_disable();
        kcpu = this_cpu_ptr(ctx->cpu);
 
+       local_irq_save(flags);
        kcpu->reqs_available += nr;
+
        while (kcpu->reqs_available >= ctx->req_batch * 2) {
                kcpu->reqs_available -= ctx->req_batch;
                atomic_add(ctx->req_batch, &ctx->reqs_available);
        }
 
+       local_irq_restore(flags);
        preempt_enable();
 }
 
@@ -847,10 +853,12 @@ static bool get_reqs_available(struct kioctx *ctx)
 {
        struct kioctx_cpu *kcpu;
        bool ret = false;
+       unsigned long flags;
 
        preempt_disable();
        kcpu = this_cpu_ptr(ctx->cpu);
 
+       local_irq_save(flags);
        if (!kcpu->reqs_available) {
                int old, avail = atomic_read(&ctx->reqs_available);
 
@@ -869,6 +877,7 @@ static bool get_reqs_available(struct kioctx *ctx)
        ret = true;
        kcpu->reqs_available--;
 out:
+       local_irq_restore(flags);
        preempt_enable();
        return ret;
 }