Skip to contentSkip to conversation

f2fs-tools: build tools selectively

PATCH New Jaegeuk Kim 1 participant 6 messages Dec 1, 2017 Library code

lore
Share & tools
lore
#0 lore raw

PATCH 1/6 f2fs-tools: build tools selectively

This patch enables to build tools except mkfs.f2fs selectively.

---
 fsck/main.c       | 11 ++++++++++-
 include/f2fs_fs.h |  5 +++++
 2 files changed, 15 insertions(+), 1 deletion(-)
fsck/main.c +10 -1
index 543c10f..9d9cc0c 100644
@@ -637,23 +637,32 @@ fsck_again:
 	case FSCK:
 		do_fsck(sbi);
 		break;
+#ifdef WITH_DUMP
 	case DUMP:
 		do_dump(sbi);
 		break;
-#ifndef WITH_ANDROID
+#endif
+#ifdef WITH_DEFRAG
 	case DEFRAG:
 		ret = do_defrag(sbi);
 		if (ret)
 			goto out_err;
 		break;
+#endif
+#ifdef WITH_RESIZE
 	case RESIZE:
 		if (do_resize(sbi))
 			goto out_err;
 		break;
+#endif
+#ifdef WITH_SLOAD
 	case SLOAD:
 		do_sload(sbi);
 		break;
 #endif
+	default:
+		ERR_MSG("Wrong program name\n");
+		ASSERT(0);
 	}
 
 	f2fs_do_umount(sbi);
include/f2fs_fs.h +5 -0
index 2b39d12..7e766a8 100644
@@ -22,6 +22,11 @@
 
 #ifdef WITH_ANDROID
 #include <android_config.h>
+#else
+#define WITH_DUMP
+#define WITH_DEFRAG
+#define WITH_RESIZE
+#define WITH_SLOAD
 #endif
 
 #include <inttypes.h>
Signature · 6 lines
2.15.0.403.gc27cc4dac6-goog


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
#1 lore raw

PATCH 2/6 mkfs.f2fs: show debug message for quota data writes

This patch shows debugging message for quota.

---
 mkfs/f2fs_format.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
mkfs/f2fs_format.c +2 -1
index 9fc0398..45963c8 100644
@@ -1118,7 +1118,8 @@ static int f2fs_write_default_quota(int qtype, unsigned int blkaddr)
 		free(filebuf);
 		return -1;
 	}
-
+	DBG(1, "\tWriting quota data, at offset %08x, %08x\n",
+					blkaddr, blkaddr + 1);
 	free(filebuf);
 	return 0;
 }
Signature · 6 lines
2.15.0.403.gc27cc4dac6-goog


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
#2 lore raw

PATCH 3/6 mkfs.f2fs: match uid/gid/projid between root inode and quota info

In reply to Jaegeuk Kim

This patch fixes mismatched root inode and quota info.

---
 mkfs/f2fs_format.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)
mkfs/f2fs_format.c +13 -3
index 45963c8..ddd0809 100644
@@ -1061,7 +1061,8 @@ static int f2fs_write_root_inode(void)
 	return 0;
 }
 
-static int f2fs_write_default_quota(int qtype, unsigned int blkaddr)
+static int f2fs_write_default_quota(int qtype, unsigned int blkaddr,
+						__le32 raw_id)
 {
 	char *filebuf = calloc(F2FS_BLKSIZE, 2);
 	int file_magics[] = INITQMAGICS;
@@ -1098,7 +1099,7 @@ static int f2fs_write_default_quota(int qtype, unsigned int blkaddr)
 
 	filebuf[5120 + 8] = 1;
 
-	dqblk.dqb_id = cpu_to_le32(0);
+	dqblk.dqb_id = raw_id;
 	dqblk.dqb_pad = cpu_to_le32(0);
 	dqblk.dqb_ihardlimit = cpu_to_le64(0);
 	dqblk.dqb_isoftlimit = cpu_to_le64(0);
@@ -1129,6 +1130,7 @@ static int f2fs_write_qf_inode(int qtype)
 	struct f2fs_node *raw_node = NULL;
 	u_int64_t data_blk_nor;
 	u_int64_t main_area_node_seg_blk_offset = 0;
+	__le32 raw_id;
 	int i;
 
 	raw_node = calloc(F2FS_BLKSIZE, 1);
@@ -1180,9 +1182,17 @@ static int f2fs_write_qf_inode(int qtype)
 	for (i = 0; i < qtype; i++)
 		if (sb->qf_ino[i])
 			data_blk_nor += QUOTA_DATA(i);
+	if (qtype == 0)
+		raw_id = raw_node->i.i_uid;
+	else if (qtype == 1)
+		raw_id = raw_node->i.i_gid;
+	else if (qtype == 2)
+		raw_id = raw_node->i.i_projid;
+	else
+		ASSERT(0);
 
 	/* write two blocks */
-	if (f2fs_write_default_quota(qtype, data_blk_nor)) {
+	if (f2fs_write_default_quota(qtype, data_blk_nor, raw_id)) {
 		free(raw_node);
 		return -1;
 	}
Signature · 6 lines
2.15.0.403.gc27cc4dac6-goog


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
#3 lore raw

PATCH 4/6 f2fs-tools: allow multiple prog names

In reply to Jaegeuk Kim

This patch allows different prog names like fsck_f2fs, sload_f2fs, etc for android.

---
 fsck/main.c | 8 ++++++++
 1 file changed, 8 insertions(+)
fsck/main.c +8 -0
index 9d9cc0c..ba247d4 100644
@@ -113,7 +113,15 @@ void f2fs_parse_options(int argc, char *argv[])
 	int option = 0;
 	char *prog = basename(argv[0]);
 	int err = NOERROR;
+#ifdef WITH_ANDROID
+	int i;
 
+	/* Allow prog names (e.g, sload_f2fs, fsck_f2fs, etc) */
+	for (i = 0; i < strlen(prog); i++) {
+		if (prog[i] == '_')
+			prog[i] = '.';
+	}
+#endif
 	if (argc < 2) {
 		MSG(0, "\tError: Device not specified\n");
 		error_out(prog);
Signature · 6 lines
2.15.0.403.gc27cc4dac6-goog


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
#4 lore raw

PATCH 5/6 sload.f2fs: update build for android

In reply to Jaegeuk Kim

This patch updates sload.f2fs for android build.

- do fsck() after sload() to update quota information.
- return success, if there's no source directory

-C fs_config

-f source directory [path of the source directory]

-p product out directory
: path on fs_config file for uid/gid/mode

-s file_contexts
: selabel file

-t mount point [prefix of target fs path, default:/]
: path stored in selabel/fs_config files

-T timestamp

---
 fsck/dir.c               |   9 +-
 fsck/fsck.h              |   3 +-
 fsck/main.c              |  79 ++++++++++++--
 fsck/mount.c             |   3 +
 fsck/segment.c           |   7 +-
 fsck/sload.c             | 276 ++++++++++++++++++++++++++++-------------------
 fsck/xattr.c             |   1 -
 include/android_config.h |   8 ++
 include/f2fs_fs.h        |  12 +++
 lib/libf2fs.c            |   1 +
 10 files changed, 273 insertions(+), 126 deletions(-)
fsck/dir.c +6 -3
index 273e762..b2ea18f 100644
@@ -620,9 +620,12 @@ int f2fs_create(struct f2fs_sb_info *sbi, struct dentry *de)
 	ASSERT(ret >= 0);
 
 	update_free_segments(sbi);
-	MSG(1, "Info: Create \"%s\" type=%x, ino=%x / %x into \"%s\"\n",
-			de->full_path, de->file_type,
-			de->ino, de->pino, de->path);
+	MSG(1, "Info: Create %s -> %s\n"
+		"  -- ino=%x, type=%x, mode=%x, uid=%x, "
+		"gid=%x, cap=%"PRIx64", size=%lu, pino=%x\n",
+		de->full_path, de->path,
+		de->ino, de->file_type, de->mode,
+		de->uid, de->gid, de->capabilities, de->size, de->pino);
 free_child_dir:
 	free(child);
 free_parent_dir:
fsck/fsck.h +1 -2
index 15ac848..0343fbd 100644
@@ -216,8 +216,7 @@ int f2fs_defragment(struct f2fs_sb_info *, u64, u64, u64, int);
 int f2fs_resize(struct f2fs_sb_info *);
 
 /* sload.c */
-int f2fs_sload(struct f2fs_sb_info *, const char *, const char *,
-		const char *, struct selabel_handle *);
+int f2fs_sload(struct f2fs_sb_info *);
 
 /* segment.c */
 void reserve_new_block(struct f2fs_sb_info *, block_t *,
fsck/main.c +71 -8

129 lines not on this page · raw message

fsck/mount.c +3 -0
index 3efa298..f16f046 100644
@@ -47,6 +47,9 @@ void update_free_segments(struct f2fs_sb_info *sbi)
 	char *progress = "-*|*-";
 	static int i = 0;
 
+	if (c.dbg_lv)
+		return;
+
 	MSG(0, "\r [ %c ] Free segments: 0x%x", progress[i % 5], get_free_segments(sbi));
 	fflush(stdout);
 	i++;
fsck/segment.c +6 -1
index 695fc6a..4f8bdb4 100644
@@ -328,6 +328,11 @@ int f2fs_build_file(struct f2fs_sb_info *sbi, struct dentry *de)
 
 	update_free_segments(sbi);
 
-	MSG(1, "Info: built a file %s, size=%lu\n", de->full_path, de->size);
+	MSG(1, "Info: Create %s -> %s\n"
+		"  -- ino=%x, type=%x, mode=%x, uid=%x, "
+		"gid=%x, cap=%"PRIx64", size=%lu, pino=%x\n",
+		de->full_path, de->path,
+		de->ino, de->file_type, de->mode,
+		de->uid, de->gid, de->capabilities, de->size, de->pino);
 	return 0;
 }
fsck/sload.c +165 -111

350 lines not on this page · raw message

fsck/xattr.c +0 -1
index f2576cd..1d15d1b 100644
@@ -77,7 +77,6 @@ static void write_all_xattrs(struct f2fs_sb_info *sbi,
 	u64 inline_size = inline_xattr_size(&inode->i);
 	int ret;
 
-	ASSERT(inode->i.i_inline & F2FS_INLINE_XATTR);
 	memcpy(inline_xattr_addr(&inode->i), txattr_addr, inline_size);
 
 	if (hsize <= inline_size)
include/android_config.h +8 -0
index bfc4105..59ba1ee 100644
@@ -28,6 +28,10 @@
 #define HAVE_LSEEK64 1
 #define HAVE_MEMSET 1
 #define HAVE_SETMNTENT 1
+
+#ifdef WITH_SLOAD
+#define HAVE_LIBSELINUX 1
+#endif
 #endif
 
 #if defined(__APPLE__)
@@ -51,4 +55,8 @@
 #define HAVE_KEYCTL 1
 #define HAVE_LLSEEK 1
 #define HAVE_MEMSET 1
+
+#ifdef WITH_SLOAD
+#define HAVE_LIBSELINUX 1
+#endif
 #endif
include/f2fs_fs.h +12 -0
index 7e766a8..3084cce 100644
@@ -39,6 +39,11 @@
 #include <linux/blkzoned.h>
 #endif
 
+#ifdef HAVE_LIBSELINUX
+#include <selinux/selinux.h>
+#include <selinux/label.h>
+#endif
+
 #ifdef UNUSED
 #elif defined(__GNUC__)
 # define UNUSED(x) UNUSED_ ## x __attribute__((unused))
@@ -359,6 +364,13 @@ struct f2fs_configuration {
 	/* sload parameters */
 	char *from_dir;
 	char *mount_point;
+	char *target_out_dir;
+	char *fs_config_file;
+	time_t fixed_time;
+#ifdef HAVE_LIBSELINUX
+	struct selinux_opt seopt_file[8];
+	int nr_opt;
+#endif
 
 	/* precomputed fs UUID checksum for seeding other checksums */
 	u_int32_t chksum_seed;
lib/libf2fs.c +1 -0
index 1e63843..bbe3a8b 100644
@@ -614,6 +614,7 @@ void f2fs_init_configuration(void)
 	c.ro = 0;
 	c.kd = -1;
 	c.dry_run = 0;
+	c.fixed_time = -1;
 }
 
 #ifdef HAVE_SETMNTENT
Signature · 6 lines
2.15.0.403.gc27cc4dac6-goog


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
#5 lore raw

PATCH 6/6 f2fs-tools: enable sparse_file opeartions

In reply to Jaegeuk Kim

This adds reading data from sparse_file.

Change-Id Icd8ec8f401a5ba87d6d9a26dd07062cc003de1e4
---
 fsck/main.c             |  30 +++++++-
 fsck/mount.c            |   6 +-
 include/f2fs_fs.h       |   2 +
 lib/libf2fs.c           |   7 +-
 lib/libf2fs_io.c        | 191 +++++++++++++++++++++++++++++++++++++-----------
 mkfs/f2fs_format_main.c |  12 +--
 6 files changed, 190 insertions(+), 58 deletions(-)
fsck/main.c +26 -4
index a09ca76..db5c413 100644
@@ -23,6 +23,11 @@
 
 struct f2fs_fsck gfsck;
 
+#ifdef WITH_ANDROID
+#include <sparse/sparse.h>
+extern struct sparse_file *f2fs_sparse_file;
+#endif
+
 static char *absolute_path(const char *file)
 {
 	char *ret;
@@ -49,6 +54,7 @@ void fsck_usage()
 	MSG(0, "  -d debug level [default:0]\n");
 	MSG(0, "  -f check/fix entire partition\n");
 	MSG(0, "  -p preen mode [default:0 the same as -a [0|1]]\n");
+	MSG(0, "  -S sparse_mode\n");
 	MSG(0, "  -t show directory tree\n");
 	MSG(0, "  -q preserve quota limits\n");
 	MSG(0, "  --dry-run do not really fix corruptions\n");
@@ -63,6 +69,7 @@ void dump_usage()
 	MSG(0, "  -i inode no (hex)\n");
 	MSG(0, "  -n [NAT dump segno from #1~#2 (decimal), for all 0~-1]\n");
 	MSG(0, "  -s [SIT dump segno from #1~#2 (decimal), for all 0~-1]\n");
+	MSG(0, "  -S sparse_mode\n");
 	MSG(0, "  -a [SSA dump segno from #1~#2 (decimal), for all 0~-1]\n");
 	MSG(0, "  -b blk_addr (in 4KB)\n");
 
@@ -75,6 +82,7 @@ void defrag_usage()
 	MSG(0, "[options]:\n");
 	MSG(0, "  -d debug level [default:0]\n");
 	MSG(0, "  -s start block address [default: main_blkaddr]\n");
+	MSG(0, "  -S sparse_mode\n");
 	MSG(0, "  -l length [default:512 (2MB)]\n");
 	MSG(0, "  -t target block address [default: main_blkaddr + 2MB]\n");
 	MSG(0, "  -i set direction as shrink [default: expand]\n");
@@ -98,6 +106,7 @@ void sload_usage()
 	MSG(0, "  -f source directory [path of the source directory]\n");
 	MSG(0, "  -p product out directory\n");
 	MSG(0, "  -s file_contexts\n");
+	MSG(0, "  -S sparse_mode\n");
 	MSG(0, "  -t mount point [prefix of target fs path, default:/]\n");
 	MSG(0, "  -T timestamp\n");
 	MSG(0, "  -d debug level [default:0]\n");
@@ -150,7 +159,7 @@ void f2fs_parse_options(int argc, char *argv[])
 	}
 
 	if (!strcmp("fsck.f2fs", prog)) {
-		const char *option_string = ":ad:fp:q:t";
+		const char *option_string = ":ad:fp:q:St";
 		int opt = 0;
 		struct option long_opt[] = {
 			{"dry-run", no_argument, 0, 1},
@@ -212,6 +221,9 @@ void f2fs_parse_options(int argc, char *argv[])
 				MSG(0, "Info: Preserve quota limits = %d\n",
 					c.preserve_limits);
 				break;
+			case 'S':
+				c.sparse_mode = 1;
+				break;
 			case 't':
 				c.show_dentry = 1;
 				break;
@@ -236,7 +248,7 @@ void f2fs_parse_options(int argc, char *argv[])
 				break;
 		}
 	} else if (!strcmp("dump.f2fs", prog)) {
-		const char *option_string = "d:i:n:s:a:b:";
+		const char *option_string = "d:i:n:s:Sa:b:";
 		static struct dump_option dump_opt = {
 			.nid = 0,	/* default root ino */
 			.start_nat = -1,
@@ -280,6 +292,9 @@ void f2fs_parse_options(int argc, char *argv[])
 							&dump_opt.start_sit,
 							&dump_opt.end_sit);
 				break;
+			case 'S':
+				c.sparse_mode = 1;
+				break;
 			case 'a':
 				ret = sscanf(optarg, "%d~%d",
 							&dump_opt.start_ssa,
@@ -304,7 +319,7 @@ void f2fs_parse_options(int argc, char *argv[])
 
 		c.private = &dump_opt;
 	} else if (!strcmp("defrag.f2fs", prog)) {
-		const char *option_string = "d:s:l:t:i";
+		const char *option_string = "d:s:Sl:t:i";
 
 		c.func = DEFRAG;
 		while ((option = getopt(argc, argv, option_string)) != EOF) {
@@ -328,6 +343,9 @@ void f2fs_parse_options(int argc, char *argv[])
 					ret = sscanf(optarg, "%"PRIx64"",
 							&c.defrag_start);
 				break;
+			case 'S':
+				c.sparse_mode = 1;
+				break;
 			case 'l':
 				if (strncmp(optarg, "0x", 2))
 					ret = sscanf(optarg, "%"PRIu64"",
@@ -389,7 +407,7 @@ void f2fs_parse_options(int argc, char *argv[])
 				break;
 		}
 	} else if (!strcmp("sload.f2fs", prog)) {
-		const char *option_string = "C:d:f:p:s:t:T:";
+		const char *option_string = "C:d:f:p:s:St:T:";
 #ifdef HAVE_LIBSELINUX
 		int max_nr_opt = (int)sizeof(c.seopt_file) /
 			sizeof(c.seopt_file[0]);
@@ -438,6 +456,9 @@ void f2fs_parse_options(int argc, char *argv[])
 				MSG(0, "Info: Not support selinux opts\n");
 #endif
 				break;
+			case 'S':
+				c.sparse_mode = 1;
+				break;
 			case 't':
 				c.mount_point = (char *)optarg;
 				break;
@@ -683,6 +704,7 @@ int main(int argc, char **argv)
 	/* Get device */
 	if (f2fs_get_device_info() < 0)
 		return -1;
+
 fsck_again:
 	memset(&gfsck, 0, sizeof(gfsck));
 	gfsck.sbi.fsck = &gfsck;
fsck/mount.c +5 -1
index f16f046..678eeae 100644
@@ -590,6 +590,7 @@ int sanity_check_raw_super(struct f2fs_super_block *sb, u64 offset)
 int validate_super_block(struct f2fs_sb_info *sbi, int block)
 {
 	u64 offset;
+	char buf[F2FS_BLKSIZE];
 
 	sbi->raw_super = malloc(sizeof(struct f2fs_super_block));
 
@@ -598,9 +599,12 @@ int validate_super_block(struct f2fs_sb_info *sbi, int block)
 	else
 		offset = F2FS_BLKSIZE + F2FS_SUPER_OFFSET;
 
-	if (dev_read(sbi->raw_super, offset, sizeof(struct f2fs_super_block)))
+	if (dev_read_block(buf, block))
 		return -1;
 
+	memcpy(sbi->raw_super, buf + F2FS_SUPER_OFFSET,
+					sizeof(struct f2fs_super_block));
+
 	if (!sanity_check_raw_super(sbi->raw_super, offset)) {
 		/* get kernel version */
 		if (c.kd >= 0) {
include/f2fs_fs.h +2 -0
index 3084cce..a18ddc4 100644
@@ -284,6 +284,7 @@ static inline uint64_t bswap_64(uint64_t val)
 #define VERSION_LEN	256
 
 enum f2fs_config_func {
+	MKFS,
 	FSCK,
 	DUMP,
 	DEFRAG,
@@ -1077,6 +1078,7 @@ extern int f2fs_devs_are_umounted(void);
 extern int f2fs_dev_is_umounted(char *);
 extern int f2fs_get_device_info(void);
 extern int get_device_info(int);
+extern int f2fs_init_sparse_file(void);
 extern int f2fs_finalize_device(void);
 extern int f2fs_fsync_device(void);
 
lib/libf2fs.c +6 -1
index bbe3a8b..9e1c9a6 100644
@@ -761,7 +761,7 @@ int get_device_info(int i)
 	struct device_info *dev = c.devices + i;
 
 	if (c.sparse_mode) {
-		fd = open((char *)dev->path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
+		fd = open((char *)dev->path, O_RDWR | O_CREAT | O_BINARY, 0644);
 	} else {
 		fd = open((char *)dev->path, O_RDWR);
 	}
@@ -772,6 +772,11 @@ int get_device_info(int i)
 
 	dev->fd = fd;
 
+	if (c.sparse_mode) {
+		if (f2fs_init_sparse_file())
+			return -1;
+	}
+
 	if (c.kd == -1) {
 		c.kd = open("/proc/version", O_RDONLY);
 		if (c.kd < 0) {
lib/libf2fs_io.c +147 -44

236 lines not on this page · raw message

mkfs/f2fs_format_main.c +4 -8
index 21caff8..973266c 100644
@@ -291,6 +291,8 @@ int main(int argc, char *argv[])
 
 	f2fs_show_info();
 
+	c.func = MKFS;
+
 	if (!force_overwrite && f2fs_check_overwrite()) {
 		MSG(0, "\tUse the -f option to force overwrite.\n");
 		return -1;
@@ -320,14 +322,8 @@ int main(int argc, char *argv[])
 	}
 
 	if (c.sparse_mode) {
-#ifndef WITH_ANDROID
-		MSG(0, "\tError: Sparse mode is only supported for android\n");
-		return -1;
-#else
-		if (f2fs_sparse_file)
-			sparse_file_destroy(f2fs_sparse_file);
-		f2fs_sparse_file = sparse_file_new(F2FS_BLKSIZE, c.device_size);
-#endif
+		if (f2fs_init_sparse_file())
+			return -1;
 	}
 
 	if (f2fs_format_device() < 0)
Signature · 6 lines
2.15.0.403.gc27cc4dac6-goog


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot