#include <linux/export.h>
 #include <linux/syscalls.h>
 #include <linux/backing-dev.h>
+#include <linux/refcount.h>
 #include <linux/uio.h>
 
 #include <linux/sched/signal.h>
 
        struct list_head        ki_list;        /* the aio core uses this
                                                 * for cancellation */
+       refcount_t              ki_refcnt;
 
        /*
         * If the aio_resfd field of the userspace iocb is not zero,
 
        percpu_ref_get(&ctx->reqs);
        INIT_LIST_HEAD(&req->ki_list);
+       refcount_set(&req->ki_refcnt, 0);
        req->ki_ctx = ctx;
        return req;
 out_put:
        return ret;
 }
 
+static inline void iocb_put(struct aio_kiocb *iocb)
+{
+       if (refcount_read(&iocb->ki_refcnt) == 0 ||
+           refcount_dec_and_test(&iocb->ki_refcnt)) {
+               percpu_ref_put(&iocb->ki_ctx->reqs);
+               kmem_cache_free(kiocb_cachep, iocb);
+       }
+}
+
 /* aio_complete
  *     Called when the io request on the given iocb is complete.
  */
                eventfd_ctx_put(iocb->ki_eventfd);
        }
 
-       kmem_cache_free(kiocb_cachep, iocb);
-
        /*
         * We have to order our ring_info tail store above and test
         * of the wait list below outside the wait lock.  This is
 
        if (waitqueue_active(&ctx->wait))
                wake_up(&ctx->wait);
-
-       percpu_ref_put(&ctx->reqs);
+       iocb_put(iocb);
 }
 
 /* aio_read_events_ring