lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date:   Fri, 11 Nov 2022 20:10:28 +0800
From:   Zhihao Cheng <chengzhihao1@...wei.com>
To:     <snitzer@...nel.org>, <Martin.Wilck@...e.com>, <ejt@...hat.com>,
        <jack@...e.cz>, <tytso@....edu>, <yi.zhang@...wei.com>,
        <chengzhihao1@...wei.com>
CC:     <dm-devel@...hat.com>, <linux-ext4@...r.kernel.org>
Subject: [dm-devel] [PATCH 2/3] dm bufio: Split main logic out of dm_bufio_client creation/destroy

Split main logic excepts shrinker register/unregister out of
dm_bufio_client creation/destroy, the extracted code is wrapped
into new helpers __do_init and __do_destroy.
This commit is prepare to support dm_bufio_client resetting.

Signed-off-by: Zhihao Cheng <chengzhihao1@...wei.com>
---
 drivers/md/dm-bufio.c    | 144 +++++++++++++++++++++++++++------------
 include/linux/dm-bufio.h |   4 +-
 2 files changed, 101 insertions(+), 47 deletions(-)

diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c
index bb786c39545e..5859d69d6944 100644
--- a/drivers/md/dm-bufio.c
+++ b/drivers/md/dm-bufio.c
@@ -1731,31 +1731,17 @@ static unsigned long dm_bufio_shrink_count(struct shrinker *shrink, struct shrin
 	return count;
 }
 
-/*
- * Create the buffering interface
- */
-struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsigned block_size,
-					       unsigned reserved_buffers, unsigned aux_size,
-					       void (*alloc_callback)(struct dm_buffer *),
-					       void (*write_callback)(struct dm_buffer *),
-					       unsigned int flags)
-{
-	int r;
-	struct dm_bufio_client *c;
-	unsigned i;
+static int __do_init(struct dm_bufio_client *c, struct block_device *bdev,
+		     unsigned int block_size, unsigned int reserved_buffers,
+		     unsigned int aux_size,
+		     void (*alloc_callback)(struct dm_buffer *),
+		     void (*write_callback)(struct dm_buffer *),
+		     unsigned int flags)
+{
+	int r = 0;
+	unsigned int i;
 	char slab_name[27];
 
-	if (!block_size || block_size & ((1 << SECTOR_SHIFT) - 1)) {
-		DMERR("%s: block size not specified or is not multiple of 512b", __func__);
-		r = -EINVAL;
-		goto bad_client;
-	}
-
-	c = kzalloc(sizeof(*c), GFP_KERNEL);
-	if (!c) {
-		r = -ENOMEM;
-		goto bad_client;
-	}
 	c->buffer_tree = RB_ROOT;
 
 	c->bdev = bdev;
@@ -1829,6 +1815,63 @@ struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsign
 	INIT_WORK(&c->shrink_work, shrink_work);
 	atomic_long_set(&c->need_shrink, 0);
 
+	return 0;
+
+bad:
+	while (!list_empty(&c->reserved_buffers)) {
+		struct dm_buffer *b = list_entry(c->reserved_buffers.next,
+						 struct dm_buffer, lru_list);
+		list_del(&b->lru_list);
+		free_buffer(b);
+	}
+	kmem_cache_destroy(c->slab_cache);
+	c->slab_cache = NULL;
+	kmem_cache_destroy(c->slab_buffer);
+	c->slab_buffer = NULL;
+	dm_io_client_destroy(c->dm_io);
+bad_dm_io:
+	c->dm_io = NULL;
+	mutex_destroy(&c->lock);
+	c->need_reserved_buffers = 0;
+	if (c->no_sleep) {
+		static_branch_dec(&no_sleep_enabled);
+		c->no_sleep = false;
+	}
+	return r;
+}
+
+/*
+ * Create the buffering interface
+ */
+struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev,
+					       unsigned int block_size,
+					       unsigned int reserved_buffers,
+					       unsigned int aux_size,
+					       void (*alloc_callback)(struct dm_buffer *),
+					       void (*write_callback)(struct dm_buffer *),
+					       unsigned int flags)
+{
+	int r;
+	struct dm_bufio_client *c;
+	char slab_name[27];
+
+	if (!block_size || block_size & ((1 << SECTOR_SHIFT) - 1)) {
+		DMERR("%s: block size not specified or is not multiple of 512b", __func__);
+		r = -EINVAL;
+		goto bad_client;
+	}
+
+	c = kzalloc(sizeof(*c), GFP_KERNEL);
+	if (!c) {
+		r = -ENOMEM;
+		goto bad_client;
+	}
+
+	r = __do_init(c, bdev, block_size, reserved_buffers, aux_size,
+		      alloc_callback, write_callback, flags);
+	if (r)
+		goto bad_do_init;
+
 	c->shrinker.count_objects = dm_bufio_shrink_count;
 	c->shrinker.scan_objects = dm_bufio_shrink_scan;
 	c->shrinker.seeks = 1;
@@ -1856,36 +1899,19 @@ struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsign
 	kmem_cache_destroy(c->slab_cache);
 	kmem_cache_destroy(c->slab_buffer);
 	dm_io_client_destroy(c->dm_io);
-bad_dm_io:
 	mutex_destroy(&c->lock);
 	if (c->no_sleep)
 		static_branch_dec(&no_sleep_enabled);
+bad_do_init:
 	kfree(c);
 bad_client:
 	return ERR_PTR(r);
 }
 EXPORT_SYMBOL_GPL(dm_bufio_client_create);
 
-/*
- * Free the buffering interface.
- * It is required that there are no references on any buffers.
- */
-void dm_bufio_client_destroy(struct dm_bufio_client *c)
+static void __do_destroy(struct dm_bufio_client *c)
 {
-	unsigned i;
-
-	drop_buffers(c);
-
-	unregister_shrinker(&c->shrinker);
-	flush_work(&c->shrink_work);
-
-	mutex_lock(&dm_bufio_clients_lock);
-
-	list_del(&c->client_list);
-	dm_bufio_client_count--;
-	__cache_size_refresh();
-
-	mutex_unlock(&dm_bufio_clients_lock);
+	unsigned int i;
 
 	BUG_ON(!RB_EMPTY_ROOT(&c->buffer_tree));
 	BUG_ON(c->need_reserved_buffers);
@@ -1905,11 +1931,39 @@ void dm_bufio_client_destroy(struct dm_bufio_client *c)
 		BUG_ON(c->n_buffers[i]);
 
 	kmem_cache_destroy(c->slab_cache);
+	c->slab_cache = NULL;
 	kmem_cache_destroy(c->slab_buffer);
-	dm_io_client_destroy(c->dm_io);
+	c->slab_buffer = NULL;
+	if (c->dm_io) {
+		dm_io_client_destroy(c->dm_io);
+		c->dm_io = NULL;
+	}
 	mutex_destroy(&c->lock);
-	if (c->no_sleep)
+	if (c->no_sleep) {
 		static_branch_dec(&no_sleep_enabled);
+		c->no_sleep = false;
+	}
+}
+
+/*
+ * Free the buffering interface.
+ * It is required that there are no references on any buffers.
+ */
+void dm_bufio_client_destroy(struct dm_bufio_client *c)
+{
+	drop_buffers(c);
+
+	unregister_shrinker(&c->shrinker);
+	flush_work(&c->shrink_work);
+
+	mutex_lock(&dm_bufio_clients_lock);
+	list_del(&c->client_list);
+	dm_bufio_client_count--;
+	__cache_size_refresh();
+	mutex_unlock(&dm_bufio_clients_lock);
+
+	__do_destroy(c);
+
 	kfree(c);
 }
 EXPORT_SYMBOL_GPL(dm_bufio_client_destroy);
diff --git a/include/linux/dm-bufio.h b/include/linux/dm-bufio.h
index 15d9e15ca830..ee4f19c170ab 100644
--- a/include/linux/dm-bufio.h
+++ b/include/linux/dm-bufio.h
@@ -26,8 +26,8 @@ struct dm_buffer;
  * Create a buffered IO cache on a given device
  */
 struct dm_bufio_client *
-dm_bufio_client_create(struct block_device *bdev, unsigned block_size,
-		       unsigned reserved_buffers, unsigned aux_size,
+dm_bufio_client_create(struct block_device *bdev, unsigned int block_size,
+		       unsigned int reserved_buffers, unsigned int aux_size,
 		       void (*alloc_callback)(struct dm_buffer *),
 		       void (*write_callback)(struct dm_buffer *),
 		       unsigned int flags);
-- 
2.31.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ