Skip to contentSkip to conversation

f2fs-tools: support multiple devices

PATCH New Jaegeuk Kim 1 participant 1 message Nov 9, 2016 Library code

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 f2fs-tools: support multiple devices

This patch adds an option to specify multiple devices for an f2fs instance.

Up to 7 devices in addition to the default device can be added.

---
 fsck/main.c              |   4 +-
 fsck/mount.c             |  34 +++++++++-
 include/f2fs_fs.h        |  57 +++++++++++-----
 lib/libf2fs.c            | 170 ++++++++++++++++++++++++++++++++---------------
 lib/libf2fs_io.c         |  62 +++++++++++++----
 lib/libf2fs_zoned.c      |  84 ++++++++++++-----------
 man/mkfs.f2fs.8          |   8 +++
 mkfs/f2fs_format.c       |  52 ++++++++++++---
 mkfs/f2fs_format_main.c  |  29 +++++++-
 mkfs/f2fs_format_utils.c |  21 ++++--
 mkfs/f2fs_format_utils.h |   1 +
 11 files changed, 382 insertions(+), 140 deletions(-)
fsck/main.c +2 -2
index 64537cc..39ef8d3 100644
@@ -301,7 +301,7 @@ void f2fs_parse_options(int argc, char *argv[])
 		else if (c.func == SLOAD)
 			sload_usage();
 	}
-	c.device_name = argv[optind];
+	c.devices[0].path = strdup(argv[optind]);
 }
 
 static void do_fsck(struct f2fs_sb_info *sbi)
@@ -474,7 +474,7 @@ int main(int argc, char **argv)
 
 	f2fs_parse_options(argc, argv);
 
-	if (f2fs_dev_is_umounted() < 0) {
+	if (f2fs_devs_are_umounted() < 0) {
 		if (!c.ro || c.func == DEFRAG) {
 			MSG(0, "\tError: Not available on mounted device!\n");
 			return -1;
fsck/mount.c +33 -1
index 9fcb008..6c29a1a 100644
@@ -400,7 +400,7 @@ int sanity_check_raw_super(struct f2fs_super_block *sb, u64 offset)
 		return -1;
 
 	/* Check zoned block device feature */
-	if (c.zoned_model == F2FS_ZONED_HM &&
+	if (c.devices[0].zoned_model == F2FS_ZONED_HM &&
 			!(sb->feature & cpu_to_le32(F2FS_FEATURE_BLKZONED))) {
 		MSG(0, "\tMissing zoned block device feature\n");
 		return -1;
@@ -470,6 +470,7 @@ int init_sb_info(struct f2fs_sb_info *sbi)
 {
 	struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);
 	u64 total_sectors;
+	int i;
 
 	sbi->log_sectors_per_block = get_sb(log_sectors_per_block);
 	sbi->log_blocksize = get_sb(log_blocksize);
@@ -486,6 +487,37 @@ int init_sb_info(struct f2fs_sb_info *sbi)
 	sbi->meta_ino_num = get_sb(meta_ino);
 	sbi->cur_victim_sec = NULL_SEGNO;
 
+	for (i = 0; i < MAX_DEVICES; i++) {
+		if (!sb->devs[i].path[0])
+			break;
+
+		if (i) {
+			c.devices[i].path = strdup((char *)sb->devs[i].path);
+			if (get_device_info(i))
+				ASSERT(0);
+		} else {
+			ASSERT(!strcmp((char *)sb->devs[i].path,
+						(char *)c.devices[i].path));
+		}
+
+		c.devices[i].total_segments =
+			le32_to_cpu(sb->devs[i].total_segments);
+		if (i)
+			c.devices[i].start_blkaddr =
+				c.devices[i - 1].end_blkaddr + 1;
+		c.devices[i].end_blkaddr = c.devices[i].start_blkaddr +
+			c.devices[i].total_segments *
+			c.blks_per_seg - 1;
+		if (i == 0)
+			c.devices[i].end_blkaddr += get_sb(segment0_blkaddr);
+
+		c.ndevs = i + 1;
+		MSG(0, "Info: Device[%d] : %s blkaddr = %"PRIx64"--%"PRIx64"\n",
+				i, c.devices[i].path,
+				c.devices[i].start_blkaddr,
+				c.devices[i].end_blkaddr);
+	}
+
 	total_sectors = get_sb(block_count) << sbi->log_sectors_per_block;
 	MSG(0, "Info: total FS sectors = %"PRIu64" (%"PRIu64" MB)\n",
 				total_sectors, total_sectors >>
include/f2fs_fs.h +41 -16

117 lines not on this page · raw message

lib/libf2fs.c +116 -54

295 lines not on this page · raw message

lib/libf2fs_io.c +50 -12

109 lines not on this page · raw message

lib/libf2fs_zoned.c +46 -38

234 lines not on this page · raw message

man/mkfs.f2fs.8 +8 -0
index 0e54fe8..bdb9755 100644
@@ -12,6 +12,10 @@ mkfs.f2fs \- create an F2FS file system
 .I heap-based-allocation
 ]
 [
+.B \-c
+.I device
+]
+[
 .B \-l
 .I volume-label
 ]
@@ -55,6 +59,10 @@ If the value is equal to 1, each of active log areas are initially
 assigned separately according to the whole volume size.
 The default value is 1.
 .TP
+.BI \-c " device"
+Build f2fs with this device additionally, so that user can see all
+the devices as one big volume.
+.TP
 .BI \-l " volume-label"
 Specify the volume label to the partition mounted as F2FS.
 .TP
mkfs/f2fs_format.c +42 -10

93 lines not on this page · raw message

mkfs/f2fs_format_main.c +26 -3
index 6fd2f2a..70ed77a 100644
@@ -28,6 +28,7 @@ static void mkfs_usage()
 	MSG(0, "\nUsage: mkfs.f2fs [options] device [sectors]\n");
 	MSG(0, "[options]:\n");
 	MSG(0, "  -a heap-based allocation [default:1]\n");
+	MSG(0, "  -c [device path]\n");
 	MSG(0, "  -d debug level [default:0]\n");
 	MSG(0, "  -e [extension list] e.g. \"mp3,gif,mov\"\n");
 	MSG(0, "  -l label\n");
@@ -71,7 +72,7 @@ static void parse_feature(const char *features)
 
 static void f2fs_parse_options(int argc, char *argv[])
 {
-	static const char *option_string = "qa:d:e:l:mo:O:s:z:t:";
+	static const char *option_string = "qa:c:d:e:l:mo:O:s:z:t:";
 	int32_t option=0;
 
 	while ((option = getopt(argc,argv,option_string)) != EOF) {
@@ -82,6 +83,14 @@ static void f2fs_parse_options(int argc, char *argv[])
 		case 'a':
 			c.heap = atoi(optarg);
 			break;
+		case 'c':
+			if (strlen(optarg) > MAX_PATH_LEN) {
+				MSG(0, "Error: device path should be less than "
+					"%d characters\n", MAX_PATH_LEN);
+				mkfs_usage();
+			}
+			c.devices[c.ndevs++].path = strdup(optarg);
+			break;
 		case 'd':
 			c.dbg_lv = atoi(optarg);
 			break;
@@ -125,7 +134,21 @@ static void f2fs_parse_options(int argc, char *argv[])
 		MSG(0, "\tError: Device not specified\n");
 		mkfs_usage();
 	}
-	c.device_name = argv[optind];
+
+	/* [0] : META, [1 to MAX_DEVICES + 1] : NODE/DATA */
+	c.devices[0].path = strdup(argv[optind]);
+	if (c.ndevs > MAX_DEVICES) {
+		MSG(0, "\tError: Too many devices\n");
+		mkfs_usage();
+	}
+
+	if ((optind + 1) < argc) {
+		if (c.ndevs > 1) {
+			MSG(0, "\tError: Not support custom size on multi-devs.\n");
+			mkfs_usage();
+		}
+		c.wanted_total_sectors = atoll(argv[optind+1]);
+	}
 
 	if ((optind + 1) < argc)
 		c.total_sectors = atoll(argv[optind+1]);
@@ -142,7 +165,7 @@ int main(int argc, char *argv[])
 
 	f2fs_show_info();
 
-	if (f2fs_dev_is_umounted() < 0) {
+	if (f2fs_devs_are_umounted() < 0) {
 		MSG(0, "\tError: Not available on mounted device!\n");
 		return -1;
 	}
mkfs/f2fs_format_utils.c +17 -4
index d204bd4..fc80ec6 100644
@@ -34,10 +34,13 @@
 #define BLKSECDISCARD	_IO(0x12,125)
 #endif
 
-int f2fs_trim_device(int fd, u_int64_t bytes)
+static int trim_device(int i)
 {
 	unsigned long long range[2];
 	struct stat stat_buf;
+	struct device_info *dev = c.devices + i;
+	u_int64_t bytes = dev->total_sectors * dev->sector_size;
+	int fd = dev->fd;
 
 	if (fstat(fd, &stat_buf) < 0 ) {
 		MSG(1, "\tError: Failed to get the device stat!!!\n");
@@ -48,7 +51,7 @@ int f2fs_trim_device(int fd, u_int64_t bytes)
 	range[1] = bytes;
 
 #if defined(WITH_BLKDISCARD) && defined(BLKDISCARD)
-	MSG(0, "Info: Discarding device\n");
+	MSG(0, "Info: [%s] Discarding device\n", dev->path);
 	if (S_ISREG(stat_buf.st_mode)) {
 #if defined(HAVE_FALLOCATE) && defined(FALLOC_FL_PUNCH_HOLE)
 		if (fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
@@ -58,8 +61,8 @@ int f2fs_trim_device(int fd, u_int64_t bytes)
 #endif
 		return 0;
 	} else if (S_ISBLK(stat_buf.st_mode)) {
-		if (c.zoned_mode)
-			return f2fs_reset_zones();
+		if (dev->zoned_model != F2FS_ZONED_NONE)
+			return f2fs_reset_zones(i);
 #ifdef BLKSECDISCARD
 		if (ioctl(fd, BLKSECDISCARD, &range) < 0) {
 			MSG(0, "Info: This device doesn't support BLKSECDISCARD\n");
@@ -79,3 +82,13 @@ int f2fs_trim_device(int fd, u_int64_t bytes)
 #endif
 	return 0;
 }
+
+int f2fs_trim_devices(void)
+{
+	int i;
+
+	for (i = 0; i < c.ndevs; i++)
+		if (trim_device(i))
+			return -1;
+	return 0;
+}
mkfs/f2fs_format_utils.h +1 -0
index ed28c58..274db7b 100644
@@ -13,4 +13,5 @@
 extern struct f2fs_configuration c;
 
 int f2fs_trim_device(int, u_int64_t);
+int f2fs_trim_devices(void);
 int f2fs_format_device(void);
Signature · 9 lines
2.8.3


------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today. http://sdm.link/xeonphi