[PATCH 1/3] bcache-tools: set zoned size aligned data_offset on backing device for zoned devive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



If the backing device is a zoned device, e.g. host managed SMR hard
drive, the data_offset of the backing device should be set to a zone
size aligned value, this is necessary for the zoned device I/O LBA
and length requirement.

This patch set the data_offset for zoned backing device by following
rules,
- If no manually inputed data_offset specified, set it to default
  value:
  - If BDEV_DATA_START_DEFAULT >= zone size and aligned to zone size,
    keep data_offset as BDEV_DATA_START_DEFAULT.
  - If BDEV_DATA_START_DEFAULT < zone size, set data_offset to zone
    size.
  - If data_offset is manually set, it must be a non-zero value aligned
    to zone size. Of cause it can be multiple zones size, but must be
    aligned to zone size.

This patch also creates a new zone.c and zone.h and places all the
above zoned device related code there.

Signed-off-by: Coly Li <colyli@xxxxxxx>
---
 Makefile |  4 +--
 make.c   |  7 ++++-
 zoned.c  | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 zoned.h  | 13 +++++++++
 4 files changed, 110 insertions(+), 3 deletions(-)
 create mode 100644 zoned.c
 create mode 100644 zoned.h

diff --git a/Makefile b/Makefile
index 4359866..2c326cf 100644
--- a/Makefile
+++ b/Makefile
@@ -24,7 +24,7 @@ bcache-test: LDLIBS += `pkg-config --libs openssl` -lm
 
 make-bcache: LDLIBS += `pkg-config --libs uuid blkid smartcols`
 make-bcache: CFLAGS += `pkg-config --cflags uuid blkid smartcols`
-make-bcache: make.o crc64.o lib.o
+make-bcache: make.o crc64.o lib.o zoned.o
 
 probe-bcache: LDLIBS += `pkg-config --libs uuid blkid`
 probe-bcache: CFLAGS += `pkg-config --cflags uuid blkid`
@@ -38,4 +38,4 @@ bcache-register: bcache-register.o
 bcache: CFLAGS += `pkg-config --cflags blkid uuid smartcols`
 bcache: LDLIBS += `pkg-config --libs blkid uuid smartcols`
 bcache: CFLAGS += -std=gnu99
-bcache: crc64.o lib.o make.o
+bcache: crc64.o lib.o make.o zoned.o
diff --git a/make.c b/make.c
index d46d925..c1090a6 100644
--- a/make.c
+++ b/make.c
@@ -35,6 +35,7 @@
 #include "bcache.h"
 #include "lib.h"
 #include "bitwise.h"
+#include "zoned.h"
 
 #define max(x, y) ({				\
 	typeof(x) _max1 = (x);			\
@@ -636,11 +637,15 @@ int make_bcache(int argc, char **argv)
 			 cache_replacement_policy,
 			 data_offset, set_uuid, false, force, label);
 
-	for (i = 0; i < nbacking_devices; i++)
+	for (i = 0; i < nbacking_devices; i++) {
+		check_data_offset_for_zoned_device(backing_devices[i],
+						   &data_offset);
+
 		write_sb(backing_devices[i], block_size, bucket_size,
 			 writeback, discard, wipe_bcache,
 			 cache_replacement_policy,
 			 data_offset, set_uuid, true, force, label);
+	}
 
 	return 0;
 }
diff --git a/zoned.c b/zoned.c
new file mode 100644
index 0000000..31c9136
--- /dev/null
+++ b/zoned.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * This file is part of bcache tools.
+ * Copyright (c) 2020 SUSE Software Solutions
+ *
+ * Authors: Coly Li <colyli@xxxxxxx>
+ */
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libgen.h>
+
+#include "bcache.h"
+
+/*
+ * copied and modified from zonefs_get_dev_capacity() of
+ * zonefs-tools.
+ * returns   0: zone size 0 indicates a non-zoned device
+ *         > 0: actual zone size of the zoned device
+ */
+static size_t get_zone_size(char *devname)
+{
+	char str[128];
+	FILE *file;
+	int res;
+	size_t zone_size = 0;
+
+	snprintf(str, sizeof(str),
+		"/sys/block/%s/queue/chunk_sectors",
+		basename(devname));
+	file = fopen(str, "r");
+	if (!file)
+		goto out;
+
+	memset(str, 0, sizeof(str));
+	res = fscanf(file, "%s", str);
+	fclose(file);
+
+	if (res != 1)
+		goto out;
+
+	zone_size = atol(str);
+
+out:
+	return zone_size;
+}
+
+/*
+ * Update data_offset for zoned device, if the backing
+ * device is a zoned device,
+ * - just leave whole zone 0 to bcache super block on
+ *   backing device.
+ * - if data_offset is specified and larger than
+ *   BDEV_DATA_START_DEFAULT, then it should be a zone
+ *   size aligned value.
+ */
+void check_data_offset_for_zoned_device(char *devname,
+				       uint64_t *data_offset)
+{
+	uint64_t _data_offset = *data_offset;
+	size_t zone_size = get_zone_size(devname);
+
+	if (!zone_size)
+		return;
+
+	if (!_data_offset ||
+	    (_data_offset == BDEV_DATA_START_DEFAULT &&
+	     zone_size > BDEV_DATA_START_DEFAULT))
+		_data_offset = zone_size;
+
+	if (_data_offset < zone_size) {
+		fprintf(stderr,
+			"data_offset %lu should be larger than zone_size %lu for zoned device %s\n",
+			_data_offset, zone_size, devname);
+		exit(EXIT_FAILURE);
+	}
+
+	if (_data_offset & (zone_size - 1)) {
+		fprintf(stderr,
+			"data_offset %lu is not aligned to zone size %lu for zoned device %s\n",
+			_data_offset, zone_size, devname);
+	}
+
+	*data_offset = _data_offset;
+}
diff --git a/zoned.h b/zoned.h
new file mode 100644
index 0000000..1c5cce8
--- /dev/null
+++ b/zoned.h
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * This file is part of bcache tools.
+ * Copyright (c) 2020 SUSE Software Solutions
+ *
+ * Authors: Coly Li <colyli@xxxxxxx>
+ */
+#ifndef __ZONED_H
+#define __ZONED_H
+
+void check_data_offset_for_zoned_device(char *devname, uint64_t *data_offset);
+
+#endif
-- 
2.25.0




[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux