Linux-Block Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH 1/3] drbd: Use refcount_t for refcount
@ 2019-08-08 13:10 Chuhong Yuan
  0 siblings, 0 replies; only message in thread
From: Chuhong Yuan @ 2019-08-08 13:10 UTC (permalink / raw)
  To: unlisted-recipients:; (no To-header on input)
  Cc: Philipp Reisner, Lars Ellenberg, Jens Axboe, drbd-dev,
	linux-block, linux-kernel, Chuhong Yuan

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 <hslester96@gmail.com>
---
 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


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, back to index

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-08 13:10 [PATCH 1/3] drbd: Use refcount_t for refcount Chuhong Yuan

Linux-Block Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-block/0 linux-block/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-block linux-block/ https://lore.kernel.org/linux-block \
		linux-block@vger.kernel.org linux-block@archiver.kernel.org
	public-inbox-index linux-block


Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-block


AGPL code for this site: git clone https://public-inbox.org/ public-inbox