Reference counters are preferred to use refcount_t instead of
atomic_t.
This is because the implementation of refcount_t can prevent
overflows and detect possible use-after-free.
So convert atomic_t ref counters to refcount_t.

Signed-off-by: Chuhong Yuan <[email protected]>
---
 drivers/block/drbd/drbd_int.h  |  3 ++-
 drivers/block/drbd/drbd_main.c |  4 ++--
 drivers/block/drbd/drbd_req.c  | 16 ++++++++--------
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index ddbf56014c51..d5167a7a87db 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -30,6 +30,7 @@
 #include <linux/genhd.h>
 #include <linux/idr.h>
 #include <linux/dynamic_debug.h>
+#include <linux/refcount.h>
 #include <net/tcp.h>
 #include <linux/lru_cache.h>
 #include <linux/prefetch.h>
@@ -354,7 +355,7 @@ struct drbd_request {
 
 
        /* once it hits 0, we may complete the master_bio */
-       atomic_t completion_ref;
+       refcount_t completion_ref;
        /* once it hits 0, we may destroy this drbd_request object */
        struct kref kref;
 
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 9bd4ddd12b25..37746708ee84 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2295,14 +2295,14 @@ static void do_retry(struct work_struct *ws)
                bool expected;
 
                expected =
-                       expect(atomic_read(&req->completion_ref) == 0) &&
+                       expect(refcount_read(&req->completion_ref) == 0) &&
                        expect(req->rq_state & RQ_POSTPONED) &&
                        expect((req->rq_state & RQ_LOCAL_PENDING) == 0 ||
                                (req->rq_state & RQ_LOCAL_ABORTED) != 0);
 
                if (!expected)
                        drbd_err(device, "req=%p completion_ref=%d 
rq_state=%x\n",
-                               req, atomic_read(&req->completion_ref),
+                               req, refcount_read(&req->completion_ref),
                                req->rq_state);
 
                /* We still need to put one kref associated with the
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index f86cea4c0f8d..cb5d573e7ea2 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -69,7 +69,7 @@ static struct drbd_request *drbd_req_new(struct drbd_device 
*device, struct bio
        INIT_LIST_HEAD(&req->req_pending_local);
 
        /* one reference to be put by __drbd_make_request */
-       atomic_set(&req->completion_ref, 1);
+       refcount_set(&req->completion_ref, 1);
        /* one kref as long as completion_ref > 0 */
        kref_init(&req->kref);
        return req;
@@ -95,11 +95,11 @@ void drbd_req_destroy(struct kref *kref)
        const unsigned s = req->rq_state;
 
        if ((req->master_bio && !(s & RQ_POSTPONED)) ||
-               atomic_read(&req->completion_ref) ||
+               refcount_read(&req->completion_ref) ||
                (s & RQ_LOCAL_PENDING) ||
                ((s & RQ_NET_MASK) && !(s & RQ_NET_DONE))) {
                drbd_err(device, "drbd_req_destroy: Logic BUG rq_state = 0x%x, 
completion_ref = %d\n",
-                               s, atomic_read(&req->completion_ref));
+                               s, refcount_read(&req->completion_ref));
                return;
        }
 
@@ -315,7 +315,7 @@ static void drbd_req_put_completion_ref(struct drbd_request 
*req, struct bio_and
        if (!put)
                return;
 
-       if (!atomic_sub_and_test(put, &req->completion_ref))
+       if (!refcount_sub_and_test(put, &req->completion_ref))
                return;
 
        drbd_req_complete(req, m);
@@ -440,15 +440,15 @@ static void mod_rq_state(struct drbd_request *req, struct 
bio_and_error *m,
        kref_get(&req->kref);
 
        if (!(s & RQ_LOCAL_PENDING) && (set & RQ_LOCAL_PENDING))
-               atomic_inc(&req->completion_ref);
+               refcount_inc(&req->completion_ref);
 
        if (!(s & RQ_NET_PENDING) && (set & RQ_NET_PENDING)) {
                inc_ap_pending(device);
-               atomic_inc(&req->completion_ref);
+               refcount_inc(&req->completion_ref);
        }
 
        if (!(s & RQ_NET_QUEUED) && (set & RQ_NET_QUEUED)) {
-               atomic_inc(&req->completion_ref);
+               refcount_inc(&req->completion_ref);
                set_if_null_req_next(peer_device, req);
        }
 
@@ -466,7 +466,7 @@ static void mod_rq_state(struct drbd_request *req, struct 
bio_and_error *m,
        }
 
        if (!(s & RQ_COMPLETION_SUSP) && (set & RQ_COMPLETION_SUSP))
-               atomic_inc(&req->completion_ref);
+               refcount_inc(&req->completion_ref);
 
        /* progress: put references */
 
-- 
2.20.1

Reply via email to