diffstat for f2fs-tools-1.0.0 f2fs-tools-1.1.0 .gitignore | 23 + README | 6 configure.ac | 30 + debian/changelog | 13 debian/control | 10 debian/f2fs-tools-udeb.install | 1 debian/watch | 9 mkfs/Makefile.am | 1 mkfs/f2fs_format.c | 779 +++++++++++++++++++++++------------------ mkfs/f2fs_format.h | 336 ++++++++++------- version.h | 10 11 files changed, 746 insertions(+), 472 deletions(-) diff -Nru f2fs-tools-1.0.0/.gitignore f2fs-tools-1.1.0/.gitignore --- f2fs-tools-1.0.0/.gitignore 1970-01-01 00:00:00.000000000 +0000 +++ f2fs-tools-1.1.0/.gitignore 2012-11-29 03:44:04.000000000 +0000 @@ -0,0 +1,23 @@ +*~ +*.[ao] + +.deps +.libs + +Makefile +Makefile.in + +/aclocal.m4 +/autom4te.cache +/config.h +/config.h.in +/config.log +/config.status +/configure +/depcomp +/install-sh +/missing +/stamp-h1 + +/mkfs/mkfs.f2fs + diff -Nru f2fs-tools-1.0.0/README f2fs-tools-1.1.0/README --- f2fs-tools-1.0.0/README 2012-08-27 00:34:34.000000000 +0000 +++ f2fs-tools-1.1.0/README 2012-11-29 03:44:04.000000000 +0000 @@ -4,6 +4,12 @@ To use f2fs filesystem, you should format the storage partition with this utilility. Otherwise, you cannot mount f2fs. +Before compilation +------------------ + +Your should install the following packages. + - libuuid-devel or uuid-dev + Initial compilation ------------------- diff -Nru f2fs-tools-1.0.0/configure.ac f2fs-tools-1.1.0/configure.ac --- f2fs-tools-1.0.0/configure.ac 2012-08-27 00:34:34.000000000 +0000 +++ f2fs-tools-1.1.0/configure.ac 2012-11-29 03:44:04.000000000 +0000 @@ -2,15 +2,27 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.68]) -AC_INIT([F2FS tools], [1.0.0], [TBD]) +AC_INIT([F2FS tools], [1.0.0], [http://sourceforge.net/projects/f2fs-tools/]) AM_INIT_AUTOMAKE AC_CONFIG_SRCDIR([mkfs/f2fs_format.c]) -AC_CONFIG_HEADERS([config.h]) +AC_CHECK_HEADERS_ONCE(m4_flatten([ + fcntl.h + mntent.h + stdlib.h + string.h + unistd.h + sys/ioctl.h + sys/mount.h +])) # Checks for programs. AC_PROG_CC # Checks for libraries. +AC_CHECK_LIB([uuid], [uuid_generate], + [AC_DEFINE([HAVE_LIBUUID], 1, + [Define to 1 if you have the 'uuid' library (-luuid).])], + [AC_MSG_ERROR([UUID library not found])]) # Checks for header files. AC_CHECK_HEADERS([fcntl.h mntent.h stdlib.h string.h sys/ioctl.h sys/mount.h unistd.h]) @@ -23,9 +35,15 @@ # Checks for library functions. AC_FUNC_GETMNTENT -AC_CHECK_FUNCS([getmntent memset]) +AC_CHECK_FUNCS_ONCE(m4_flatten([ + getmntent + memset +])) + +AC_CONFIG_FILES(m4_flatten([ + Makefile + man/Makefile + mkfs/Makefile +])) -AC_CONFIG_FILES([Makefile - man/Makefile - mkfs/Makefile]) AC_OUTPUT diff -Nru f2fs-tools-1.0.0/debian/changelog f2fs-tools-1.1.0/debian/changelog --- f2fs-tools-1.0.0/debian/changelog 2012-10-07 03:35:23.000000000 +0000 +++ f2fs-tools-1.1.0/debian/changelog 2013-04-16 08:07:34.000000000 +0000 @@ -1,3 +1,16 @@ +f2fs-tools (1.1.0-SprezzOS1) unstable; urgency=low + + * New upstream 1.1.0 + + -- nick black Fri, 16 Nov 2012 05:03:36 -0500 + +f2fs-tools (1.0.0-SprezzOS1) unstable; urgency=low + + * SprezzOS build + * Add udeb + + -- nick black Sun, 07 Oct 2012 21:55:51 -0400 + f2fs-tools (1.0.0-1) unstable; urgency=low * Initial release. diff -Nru f2fs-tools-1.0.0/debian/control f2fs-tools-1.1.0/debian/control --- f2fs-tools-1.0.0/debian/control 2012-10-07 03:35:22.000000000 +0000 +++ f2fs-tools-1.1.0/debian/control 2013-04-16 08:07:34.000000000 +0000 @@ -1,7 +1,8 @@ Source: f2fs-tools Section: admin Priority: optional -Maintainer: Daniel Baumann +Maintainer: Nick Black +XSBC-Original-Maintainer: Daniel Baumann Build-Depends: debhelper (>= 9), autoconf, automake Standards-Version: 3.9.4 Homepage: http://f2fs-tools.sourceforge.net/ @@ -25,3 +26,10 @@ System (LFS). . This package contains the debugging symbols. + +Package: f2fs-tools-udeb +Package-Type: udeb +Architecture: any +Depends: ${misc:Depends} +Description: Tools for Flash-Friendly File System + Installer version, not for regular setups. diff -Nru f2fs-tools-1.0.0/debian/f2fs-tools-udeb.install f2fs-tools-1.1.0/debian/f2fs-tools-udeb.install --- f2fs-tools-1.0.0/debian/f2fs-tools-udeb.install 1970-01-01 00:00:00.000000000 +0000 +++ f2fs-tools-1.1.0/debian/f2fs-tools-udeb.install 2013-04-16 08:07:34.000000000 +0000 @@ -0,0 +1 @@ +#sbin/mkfs.f2fs /sbin/mkfs.f2fs diff -Nru f2fs-tools-1.0.0/debian/watch f2fs-tools-1.1.0/debian/watch --- f2fs-tools-1.0.0/debian/watch 1970-01-01 00:00:00.000000000 +0000 +++ f2fs-tools-1.1.0/debian/watch 2013-04-16 08:07:34.000000000 +0000 @@ -0,0 +1,9 @@ +# Example watch control file for uscan +# Rename this file to "watch" and then you can run the "uscan" command +# to check for upstream updates and more. +# See uscan(1) for format + +# Compulsory line, this is a version 3 file +version=3 + +http://sf.net/f2fs-tools/f2fs-tools-(.+)\.(?:zip|tgz|tbz2|txz|tar\.gz|tar\.bz2|tar\.xz) diff -Nru f2fs-tools-1.0.0/mkfs/Makefile.am f2fs-tools-1.1.0/mkfs/Makefile.am --- f2fs-tools-1.0.0/mkfs/Makefile.am 2012-08-27 00:34:34.000000000 +0000 +++ f2fs-tools-1.1.0/mkfs/Makefile.am 2012-11-29 03:44:04.000000000 +0000 @@ -1,5 +1,6 @@ ## Makefile.am AM_CFLAGS = -Wall +LDADD = -luuid bin_PROGRAMS = mkfs.f2fs mkfs_f2fs_SOURCES = f2fs_format.c f2fs_format.h diff -Nru f2fs-tools-1.0.0/mkfs/f2fs_format.c f2fs-tools-1.1.0/mkfs/f2fs_format.c --- f2fs-tools-1.0.0/mkfs/f2fs_format.c 2012-08-27 00:34:34.000000000 +0000 +++ f2fs-tools-1.1.0/mkfs/f2fs_format.c 2012-11-29 03:44:04.000000000 +0000 @@ -10,6 +10,7 @@ */ #define _LARGEFILE64_SOURCE +#include #include #include #include @@ -24,8 +25,10 @@ #include #include #include +#include #include "f2fs_format.h" +#include "../version.h" struct f2fs_global_parameters f2fs_params; struct f2fs_super_block super_block; @@ -65,6 +68,7 @@ f2fs_params.blks_per_seg = DEFAULT_BLOCKS_PER_SEGMENT; f2fs_params.reserved_segments = 20; /* calculated by overprovision ratio */ f2fs_params.overprovision = 5; + f2fs_params.segs_per_sec = 1; f2fs_params.secs_per_zone = 1; f2fs_params.heap = 1; memset(f2fs_params.vol_label, 0, sizeof(f2fs_params.vol_label)); @@ -121,8 +125,9 @@ fprintf(stderr, "-l label\n"); fprintf(stderr, "-a heap-based allocation [default:1]\n"); fprintf(stderr, "-o overprovision ratio [default:5]\n"); - fprintf(stderr, "-s log-based # of segments per section [default:0]\n"); + fprintf(stderr, "-s # of segments per section [default:1]\n"); fprintf(stderr, "-z # of sections per zone [default:1]\n"); + fprintf(stderr, "-e [extension list] e.g. \"mp3,gif,mov\"\n"); exit(1); } @@ -134,17 +139,16 @@ */ static void f2fs_parse_options(int argc, char *argv[]) { - static const char *option_string = "l:o:z:a:s:"; + static const char *option_string = "l:o:z:a:s:e:"; int32_t option=0; while ((option = getopt(argc,argv,option_string)) != EOF) { switch (option) { case 'l': /*v: volume label */ - if (strlen(optarg) > 8) { + if (strlen(optarg) > 512) { printf("Error: Volume Label should be less than \ - 9 characters\n"); + 512 characters\n"); f2fs_usage(); - } sprintf((char *)f2fs_params.vol_label, "%s", optarg); break; @@ -153,8 +157,8 @@ printf("Info: Overprovision ratio = %u%%\n", atoi(optarg)); break; case 's': - f2fs_params.log_segs_per_sec = atoi(optarg); - printf("Info: segments per section = 2^%d\n", atoi(optarg)); + f2fs_params.segs_per_sec = atoi(optarg); + printf("Info: segments per section = %d\n", atoi(optarg)); break; case 'a': f2fs_params.heap = atoi(optarg); @@ -165,6 +169,9 @@ f2fs_params.secs_per_zone = atoi(optarg); printf("Info: sections per zone = %d\n", atoi(optarg)); break; + case 'e': + f2fs_params.extension_list = strdup(optarg); + break; default: printf("Error: Unknown option %c\n",option); f2fs_usage(); @@ -179,7 +186,7 @@ f2fs_params.reserved_segments = (100 / f2fs_params.overprovision + 5) - << f2fs_params.log_segs_per_sec; + * f2fs_params.segs_per_sec; f2fs_params.device_name = argv[optind]; } @@ -268,7 +275,8 @@ } printf("Info: sector size = %u\n", f2fs_params.sector_size); - printf("Info: total sectors = %lu (in 512bytes)\n", f2fs_params.total_sectors); + printf("Info: total sectors = %"PRIu64" (in 512bytes)\n", + f2fs_params.total_sectors); if (f2fs_params.total_sectors < (F2FS_MIN_VOLUME_SIZE / DEFAULT_SECTOR_SIZE)) { printf("Error: Min volume size supported is %d\n", @@ -279,6 +287,71 @@ return 0; } +const char *media_ext_lists[] = { + "jpg", + "gif", + "png", + "avi", + "divx", + "mp4", + "mp3", + "3gp", + "wmv", + "wma", + "mpeg", + "mkv", + "mov", + "asx", + "asf", + "wmx", + "svi", + "wvx", + "wm", + "mpg", + "mpe", + "rm", + "ogg", + NULL +}; + +static void configure_extension_list(void) +{ + const char **extlist = media_ext_lists; + char *ext_str = f2fs_params.extension_list; + char *ue; + int name_len; + int i = 0; + + super_block.extension_count = 0; + memset(super_block.extension_list, 0, + sizeof(super_block.extension_list)); + + while (*extlist) { + name_len = strlen(*extlist); + memcpy(super_block.extension_list[i++], *extlist, name_len); + extlist++; + } + super_block.extension_count = i - 1; + + if (!ext_str) + return; + + /* add user ext list */ + ue = strtok(ext_str, ","); + while (ue != NULL) { + name_len = strlen(ue); + memcpy(super_block.extension_list[i++], ue, name_len); + ue = strtok(NULL, ","); + if (i > F2FS_MAX_EXTENSION) + break; + } + + super_block.extension_count = i - 1; + + free(f2fs_params.extension_list); +} + + /** * @brief It writes buffer to disk or storage meant to be formatted * with F2FS. @@ -312,78 +385,68 @@ static int f2fs_prepare_super_block(void) { u_int32_t blk_size_bytes; - u_int32_t segment_size_bytes; - u_int32_t zone_size_bytes; - u_int32_t nor_blks_for_sit; - u_int32_t nor_blks_for_nat; - u_int32_t nor_blks_for_ssa; + u_int32_t log_sectorsize, log_sectors_per_block; + u_int32_t log_blocksize, log_blks_per_seg; + u_int32_t segment_size_bytes, zone_size_bytes; + u_int32_t sit_segments; + u_int32_t blocks_for_sit, blocks_for_nat, blocks_for_ssa; u_int32_t total_valid_blks_available; u_int64_t zone_align_start_offset, diff, total_meta_segments; u_int32_t sit_bitmap_size, max_nat_bitmap_size, max_nat_segments; u_int32_t total_zones; - super_block.magic = F2FS_SUPER_MAGIC; - super_block.major_ver = F2FS_MAJOR_VERSION; - super_block.minor_ver = F2FS_MINOR_VERSION; + super_block.magic = cpu_to_le32(F2FS_SUPER_MAGIC); + super_block.major_ver = cpu_to_le16(F2FS_MAJOR_VERSION); + super_block.minor_ver = cpu_to_le16(F2FS_MINOR_VERSION); + + log_sectorsize = log_base_2(f2fs_params.sector_size); + log_sectors_per_block = log_base_2(f2fs_params.sectors_per_blk); + log_blocksize = log_sectorsize + log_sectors_per_block; + log_blks_per_seg = log_base_2(f2fs_params.blks_per_seg); - super_block.log_sectorsize = log_base_2(f2fs_params.sector_size); + super_block.log_sectorsize = cpu_to_le32(log_sectorsize); - if (super_block.log_sectorsize < 0) { - super_block.log_sectorsize = log_base_2(DEFAULT_SECTOR_SIZE); - printf("\n\tError: Failed to get the sector size!!! \ - Setting to default as : %d", - 1 << super_block.log_sectorsize); + if (log_sectorsize < 0) { + printf("\n\tError: Failed to get the sector size: %u!\n", + f2fs_params.sector_size); return -1; } - super_block.log_sectors_per_block = - log_base_2(f2fs_params.sectors_per_blk); + super_block.log_sectors_per_block = cpu_to_le32(log_sectors_per_block); - if (super_block.log_sectors_per_block < 0) { - super_block.log_sectors_per_block = - log_base_2(DEFAULT_SECTORS_PER_BLOCK); - printf("\n\tError: Failed to get sectors per block!!! \ - Setting to default as : %d",\ - 1 << super_block.log_sectors_per_block); + if (log_sectors_per_block < 0) { + printf("\n\tError: Failed to get sectors per block: %u!\n", + f2fs_params.sectors_per_blk); + return -1; } - super_block.log_blocksize = - super_block.log_sectorsize + super_block.log_sectors_per_block; - - super_block.log_blocks_per_seg = log_base_2(f2fs_params.blks_per_seg); + super_block.log_blocksize = cpu_to_le32(log_blocksize); + super_block.log_blocks_per_seg = cpu_to_le32(log_blks_per_seg); - if (super_block.log_blocks_per_seg < 0) { - super_block.log_blocks_per_seg = - log_base_2(DEFAULT_BLOCKS_PER_SEGMENT); - printf("\n\tError: Failed to get block per segment!!! \ - Setting to default as : %d", - 1 << super_block.log_blocks_per_seg); + if (log_blks_per_seg < 0) { + printf("\n\tError: Failed to get block per segment: %u!\n", + f2fs_params.blks_per_seg); + return -1; } - super_block.log_segs_per_sec = f2fs_params.log_segs_per_sec; - super_block.secs_per_zone = f2fs_params.secs_per_zone; - blk_size_bytes = 1 << super_block.log_blocksize; - segment_size_bytes = blk_size_bytes * - (1 << super_block.log_blocks_per_seg); - zone_size_bytes = blk_size_bytes * super_block.secs_per_zone * - (1 << (super_block.log_segs_per_sec + - super_block.log_blocks_per_seg)); + super_block.segs_per_sec = cpu_to_le32(f2fs_params.segs_per_sec); + super_block.secs_per_zone = cpu_to_le32(f2fs_params.secs_per_zone); + blk_size_bytes = 1 << log_blocksize; + segment_size_bytes = blk_size_bytes * f2fs_params.blks_per_seg; + zone_size_bytes = + blk_size_bytes * f2fs_params.secs_per_zone * + f2fs_params.segs_per_sec * f2fs_params.blks_per_seg; super_block.checksum_offset = 0; - /* Get the number of blocks present in the volume - * (Voume Size - unaligned start address before block0)/block size - * TODO - reframe above comments clearly - */ - super_block.block_count = + super_block.block_count = cpu_to_le64( (f2fs_params.total_sectors * DEFAULT_SECTOR_SIZE) / - blk_size_bytes; + blk_size_bytes); zone_align_start_offset = (f2fs_params.start_sector * DEFAULT_SECTOR_SIZE + - F2FS_SUPER_OFFSET * F2FS_BLKSIZE + - sizeof(struct f2fs_super_block) * 2 + - zone_size_bytes - 1) / zone_size_bytes * zone_size_bytes - + 2 * F2FS_BLKSIZE + zone_size_bytes - 1) / + zone_size_bytes * zone_size_bytes - f2fs_params.start_sector * DEFAULT_SECTOR_SIZE; if (f2fs_params.start_sector % DEFAULT_SECTORS_PER_BLOCK) { @@ -394,169 +457,191 @@ DEFAULT_SECTORS_PER_BLOCK); } - /* Get the number of segments present in the volume - * (Voume Size - unaligned start address before segment0)/segment size - * TODO - reframe above comments clearly - */ - super_block.segment_count = + super_block.segment_count = cpu_to_le32( ((f2fs_params.total_sectors * DEFAULT_SECTOR_SIZE) - - zone_align_start_offset) / segment_size_bytes; + zone_align_start_offset) / segment_size_bytes); - super_block.segment0_blkaddr = zone_align_start_offset / blk_size_bytes; - printf("Info: zone aligned segment0 blkaddr: %llu\n", super_block.segment0_blkaddr); + super_block.segment0_blkaddr = + cpu_to_le32(zone_align_start_offset / blk_size_bytes); + super_block.cp_blkaddr = super_block.segment0_blkaddr; - super_block.start_segment_checkpoint = super_block.segment0_blkaddr; - super_block.segment_count_ckpt = F2FS_NUMBER_OF_CHECKPOINT_PACK; + printf("Info: zone aligned segment0 blkaddr: %u\n", + le32_to_cpu(super_block.segment0_blkaddr)); - super_block.sit_blkaddr = - super_block.start_segment_checkpoint + - (super_block.segment_count_ckpt * - (1 << super_block.log_blocks_per_seg)); + super_block.segment_count_ckpt = + cpu_to_le32(F2FS_NUMBER_OF_CHECKPOINT_PACK); - nor_blks_for_sit = super_block.segment_count / SIT_ENTRY_PER_BLOCK; + super_block.sit_blkaddr = cpu_to_le32( + le32_to_cpu(super_block.segment0_blkaddr) + + (le32_to_cpu(super_block.segment_count_ckpt) * + (1 << log_blks_per_seg))); - if (super_block.segment_count % SIT_ENTRY_PER_BLOCK) - nor_blks_for_sit++; + blocks_for_sit = (le32_to_cpu(super_block.segment_count) + + SIT_ENTRY_PER_BLOCK - 1) / SIT_ENTRY_PER_BLOCK; - super_block.segment_count_sit = - nor_blks_for_sit / (1 << super_block.log_blocks_per_seg); + sit_segments = (blocks_for_sit + f2fs_params.blks_per_seg - 1) + / f2fs_params.blks_per_seg; - if (nor_blks_for_sit % (1 << super_block.log_blocks_per_seg)) - super_block.segment_count_sit++; + super_block.segment_count_sit = cpu_to_le32(sit_segments * 2); - super_block.segment_count_sit = super_block.segment_count_sit * 2; + super_block.nat_blkaddr = cpu_to_le32( + le32_to_cpu(super_block.sit_blkaddr) + + (le32_to_cpu(super_block.segment_count_sit) * + f2fs_params.blks_per_seg)); - super_block.nat_blkaddr = super_block.sit_blkaddr + - (super_block.segment_count_sit * - (1 << super_block.log_blocks_per_seg)); + total_valid_blks_available = (le32_to_cpu(super_block.segment_count) - + (le32_to_cpu(super_block.segment_count_ckpt) + + le32_to_cpu(super_block.segment_count_sit))) * + f2fs_params.blks_per_seg; - total_valid_blks_available = (super_block.segment_count - - (super_block.segment_count_ckpt + - super_block.segment_count_sit)) * - (1 << super_block.log_blocks_per_seg); - - nor_blks_for_nat = total_valid_blks_available / NAT_ENTRY_PER_BLOCK; - - if (total_valid_blks_available % NAT_ENTRY_PER_BLOCK) - nor_blks_for_nat++; - - super_block.segment_count_nat = - nor_blks_for_nat / (1 << super_block.log_blocks_per_seg); - - if (nor_blks_for_nat % (1 << super_block.log_blocks_per_seg)) - super_block.segment_count_nat++; + blocks_for_nat = (total_valid_blks_available + NAT_ENTRY_PER_BLOCK - 1) + / NAT_ENTRY_PER_BLOCK; + super_block.segment_count_nat = cpu_to_le32( + (blocks_for_nat + f2fs_params.blks_per_seg - 1) / + f2fs_params.blks_per_seg); /* * The number of node segments should not be exceeded a "Threshold". * This number resizes NAT bitmap area in a CP page. * So the threshold is determined not to overflow one CP page */ - sit_bitmap_size = ((super_block.segment_count_sit / 2) << - super_block.log_blocks_per_seg) / 8; + sit_bitmap_size = ((le32_to_cpu(super_block.segment_count_sit) / 2) << + log_blks_per_seg) / 8; max_nat_bitmap_size = 4096 - sizeof(struct f2fs_checkpoint) + 1 - - sit_bitmap_size; - max_nat_segments = (max_nat_bitmap_size * 8) >> - super_block.log_blocks_per_seg; - - if (super_block.segment_count_nat > max_nat_segments) - super_block.segment_count_nat = max_nat_segments; - - super_block.segment_count_nat = super_block.segment_count_nat * 2; - - super_block.ssa_blkaddr = super_block.nat_blkaddr + - (super_block.segment_count_nat * - (1 << super_block.log_blocks_per_seg)); - - total_valid_blks_available = (super_block.segment_count - - (super_block.segment_count_ckpt + - super_block.segment_count_sit + - super_block.segment_count_nat)) * - (1 << super_block.log_blocks_per_seg) ; - - nor_blks_for_ssa = total_valid_blks_available - / ((1 << super_block.log_blocks_per_seg) + 1); - - super_block.segment_count_ssa = nor_blks_for_ssa - / (1 << super_block.log_blocks_per_seg); - - if (nor_blks_for_ssa % (1 << super_block.log_blocks_per_seg)) - super_block.segment_count_ssa++; - - total_meta_segments = super_block.segment_count_ckpt + - super_block.segment_count_sit + - super_block.segment_count_nat + - super_block.segment_count_ssa; - diff = total_meta_segments % ((1 << f2fs_params.log_segs_per_sec) * - f2fs_params.secs_per_zone); - if (diff) - super_block.segment_count_ssa += - (((1 << f2fs_params.log_segs_per_sec) * - f2fs_params.secs_per_zone) - diff); - - super_block.main_blkaddr = super_block.ssa_blkaddr + - (super_block.segment_count_ssa * - (1 << super_block.log_blocks_per_seg)); + sit_bitmap_size; + max_nat_segments = (max_nat_bitmap_size * 8) >> log_blks_per_seg; - super_block.segment_count_main = super_block.segment_count - - (super_block.segment_count_ckpt + super_block.segment_count_sit + - super_block.segment_count_nat + super_block.segment_count_ssa); + if (le32_to_cpu(super_block.segment_count_nat) > max_nat_segments) + super_block.segment_count_nat = cpu_to_le32(max_nat_segments); - super_block.section_count = super_block.segment_count_main >> - super_block.log_segs_per_sec; + super_block.segment_count_nat = cpu_to_le32( + le32_to_cpu(super_block.segment_count_nat) * 2); - super_block.segment_count_main = super_block.section_count << - super_block.log_segs_per_sec; + super_block.ssa_blkaddr = cpu_to_le32( + le32_to_cpu(super_block.nat_blkaddr) + + le32_to_cpu(super_block.segment_count_nat) * + f2fs_params.blks_per_seg); + + total_valid_blks_available = (le32_to_cpu(super_block.segment_count) - + (le32_to_cpu(super_block.segment_count_ckpt) + + le32_to_cpu(super_block.segment_count_sit) + + le32_to_cpu(super_block.segment_count_nat))) * + f2fs_params.blks_per_seg; + + blocks_for_ssa = total_valid_blks_available / + f2fs_params.blks_per_seg + 1; + + super_block.segment_count_ssa = cpu_to_le32( + (blocks_for_ssa + f2fs_params.blks_per_seg - 1) / + f2fs_params.blks_per_seg); + + total_meta_segments = le32_to_cpu(super_block.segment_count_ckpt) + + le32_to_cpu(super_block.segment_count_sit) + + le32_to_cpu(super_block.segment_count_nat) + + le32_to_cpu(super_block.segment_count_ssa); + diff = total_meta_segments % (f2fs_params.segs_per_sec * + f2fs_params.secs_per_zone); + if (diff) + super_block.segment_count_ssa = cpu_to_le32( + le32_to_cpu(super_block.segment_count_ssa) + + (f2fs_params.segs_per_sec * f2fs_params.secs_per_zone - + diff)); + + super_block.main_blkaddr = cpu_to_le32( + le32_to_cpu(super_block.ssa_blkaddr) + + (le32_to_cpu(super_block.segment_count_ssa) * + f2fs_params.blks_per_seg)); + + super_block.segment_count_main = cpu_to_le32( + le32_to_cpu(super_block.segment_count) - + (le32_to_cpu(super_block.segment_count_ckpt) + + le32_to_cpu(super_block.segment_count_sit) + + le32_to_cpu(super_block.segment_count_nat) + + le32_to_cpu(super_block.segment_count_ssa))); + + super_block.section_count = cpu_to_le32( + le32_to_cpu(super_block.segment_count_main) + / f2fs_params.segs_per_sec); + + super_block.segment_count_main = cpu_to_le32( + le32_to_cpu(super_block.section_count) * + f2fs_params.segs_per_sec); - if ((super_block.segment_count_main - 2) < f2fs_params.reserved_segments) { + if ((le32_to_cpu(super_block.segment_count_main) - 2) < + f2fs_params.reserved_segments) { printf("Error: Device size is not sufficient for F2FS volume, \ more segment needed =%u", f2fs_params.reserved_segments - - (super_block.segment_count_main-2)); + (le32_to_cpu(super_block.segment_count_main) - 2)); return -1; } - super_block.failure_safe_block_distance = 0; - super_block.volume_serial_number = 0; + uuid_generate(super_block.uuid); ASCIIToUNICODE(super_block.volume_name, f2fs_params.vol_label); - super_block.node_ino = 1; - super_block.meta_ino = 2; - super_block.root_ino = 3; - - total_zones = ((super_block.segment_count_main - 1) >> f2fs_params.log_segs_per_sec) / - f2fs_params.secs_per_zone; + super_block.node_ino = cpu_to_le32(1); + super_block.meta_ino = cpu_to_le32(2); + super_block.root_ino = cpu_to_le32(3); + + total_zones = ((le32_to_cpu(super_block.segment_count_main) - 1) / + f2fs_params.segs_per_sec) / + f2fs_params.secs_per_zone; if (total_zones <= 6) { - printf("\n\tError: %d zones: Need more zones by shrinking zone size\n", total_zones); + printf("\n\tError: %d zones: Need more zones \ + by shrinking zone size\n", total_zones); return -1; } if (f2fs_params.heap) { - f2fs_params.cur_seg[CURSEG_HOT_NODE] = ((total_zones - 1) << f2fs_params.log_segs_per_sec) * - f2fs_params.secs_per_zone + ((f2fs_params.secs_per_zone - 1) << - f2fs_params.log_segs_per_sec); - f2fs_params.cur_seg[CURSEG_WARM_NODE] = f2fs_params.cur_seg[CURSEG_HOT_NODE] - - (1 << f2fs_params.log_segs_per_sec) * f2fs_params.secs_per_zone; - f2fs_params.cur_seg[CURSEG_COLD_NODE] = f2fs_params.cur_seg[CURSEG_WARM_NODE] - - (1 << f2fs_params.log_segs_per_sec) * f2fs_params.secs_per_zone; - f2fs_params.cur_seg[CURSEG_HOT_DATA] = f2fs_params.cur_seg[CURSEG_COLD_NODE] - - (1 << f2fs_params.log_segs_per_sec) * f2fs_params.secs_per_zone; + f2fs_params.cur_seg[CURSEG_HOT_NODE] = (total_zones - 1) * + f2fs_params.segs_per_sec * + f2fs_params.secs_per_zone + + ((f2fs_params.secs_per_zone - 1) * + f2fs_params.segs_per_sec); + f2fs_params.cur_seg[CURSEG_WARM_NODE] = + f2fs_params.cur_seg[CURSEG_HOT_NODE] - + f2fs_params.segs_per_sec * + f2fs_params.secs_per_zone; + f2fs_params.cur_seg[CURSEG_COLD_NODE] = + f2fs_params.cur_seg[CURSEG_WARM_NODE] - + f2fs_params.segs_per_sec * + f2fs_params.secs_per_zone; + f2fs_params.cur_seg[CURSEG_HOT_DATA] = + f2fs_params.cur_seg[CURSEG_COLD_NODE] - + f2fs_params.segs_per_sec * + f2fs_params.secs_per_zone; f2fs_params.cur_seg[CURSEG_COLD_DATA] = 0; - f2fs_params.cur_seg[CURSEG_WARM_DATA] = f2fs_params.cur_seg[CURSEG_COLD_DATA] + - (1 << f2fs_params.log_segs_per_sec) * f2fs_params.secs_per_zone; + f2fs_params.cur_seg[CURSEG_WARM_DATA] = + f2fs_params.cur_seg[CURSEG_COLD_DATA] + + f2fs_params.segs_per_sec * + f2fs_params.secs_per_zone; } else { f2fs_params.cur_seg[CURSEG_HOT_NODE] = 0; - f2fs_params.cur_seg[CURSEG_WARM_NODE] = f2fs_params.cur_seg[CURSEG_HOT_NODE] + - (1 << f2fs_params.log_segs_per_sec) * f2fs_params.secs_per_zone; - f2fs_params.cur_seg[CURSEG_COLD_NODE] = f2fs_params.cur_seg[CURSEG_WARM_NODE] + - (1 << f2fs_params.log_segs_per_sec) * f2fs_params.secs_per_zone; - f2fs_params.cur_seg[CURSEG_HOT_DATA] = f2fs_params.cur_seg[CURSEG_COLD_NODE] + - (1 << f2fs_params.log_segs_per_sec) * f2fs_params.secs_per_zone; - f2fs_params.cur_seg[CURSEG_COLD_DATA] = f2fs_params.cur_seg[CURSEG_HOT_DATA] + - (1 << f2fs_params.log_segs_per_sec) * f2fs_params.secs_per_zone; - f2fs_params.cur_seg[CURSEG_WARM_DATA] = f2fs_params.cur_seg[CURSEG_COLD_DATA] + - (1 << f2fs_params.log_segs_per_sec) * f2fs_params.secs_per_zone; + f2fs_params.cur_seg[CURSEG_WARM_NODE] = + f2fs_params.cur_seg[CURSEG_HOT_NODE] + + f2fs_params.segs_per_sec * + f2fs_params.secs_per_zone; + f2fs_params.cur_seg[CURSEG_COLD_NODE] = + f2fs_params.cur_seg[CURSEG_WARM_NODE] + + f2fs_params.segs_per_sec * + f2fs_params.secs_per_zone; + f2fs_params.cur_seg[CURSEG_HOT_DATA] = + f2fs_params.cur_seg[CURSEG_COLD_NODE] + + f2fs_params.segs_per_sec * + f2fs_params.secs_per_zone; + f2fs_params.cur_seg[CURSEG_COLD_DATA] = + f2fs_params.cur_seg[CURSEG_HOT_DATA] + + f2fs_params.segs_per_sec * + f2fs_params.secs_per_zone; + f2fs_params.cur_seg[CURSEG_WARM_DATA] = + f2fs_params.cur_seg[CURSEG_COLD_DATA] + + f2fs_params.segs_per_sec * + f2fs_params.secs_per_zone; } + + configure_extension_list(); + return 0; } @@ -573,8 +658,9 @@ u_int64_t sit_seg_blk_offset = 0; u_int8_t *zero_buf = NULL; - blk_size_bytes = 1 << super_block.log_blocksize; - seg_size_bytes = (1 << super_block.log_blocks_per_seg) * blk_size_bytes; + blk_size_bytes = 1 << le32_to_cpu(super_block.log_blocksize); + seg_size_bytes = (1 << le32_to_cpu(super_block.log_blocks_per_seg)) * + blk_size_bytes; zero_buf = calloc(sizeof(u_int8_t), seg_size_bytes); if(zero_buf == NULL) { @@ -582,9 +668,12 @@ return -1; } - sit_seg_blk_offset = super_block.sit_blkaddr * blk_size_bytes; + sit_seg_blk_offset = le32_to_cpu(super_block.sit_blkaddr) * + blk_size_bytes; - for (index = 0; index < (super_block.segment_count_sit / 2); index++) { + for (index = 0; + index < (le32_to_cpu(super_block.segment_count_sit) / 2); + index++) { if (writetodisk(f2fs_params.fd, zero_buf, sit_seg_blk_offset, seg_size_bytes) < 0) { printf("\n\tError: While zeroing out the sit area \ @@ -596,7 +685,6 @@ free(zero_buf); return 0 ; - } /** @@ -612,8 +700,9 @@ u_int64_t nat_seg_blk_offset = 0; u_int8_t *nat_buf = NULL; - blk_size_bytes = 1 << super_block.log_blocksize; - seg_size_bytes = (1 << super_block.log_blocks_per_seg) * blk_size_bytes; + blk_size_bytes = 1 << le32_to_cpu(super_block.log_blocksize); + seg_size_bytes = (1 << le32_to_cpu(super_block.log_blocks_per_seg)) * + blk_size_bytes; nat_buf = calloc(sizeof(u_int8_t), seg_size_bytes); if (nat_buf == NULL) { @@ -621,9 +710,12 @@ return -1; } - nat_seg_blk_offset = super_block.nat_blkaddr * blk_size_bytes; + nat_seg_blk_offset = le32_to_cpu(super_block.nat_blkaddr); + nat_seg_blk_offset *= blk_size_bytes; - for (index = 0; index < (super_block.segment_count_nat / 2); index++) { + for (index = 0; + index < (le32_to_cpu(super_block.segment_count_nat) / 2); + index++) { if (writetodisk(f2fs_params.fd, nat_buf, nat_seg_blk_offset, seg_size_bytes) < 0) { printf("\n\tError: While zeroing out the nat area \ @@ -663,6 +755,7 @@ u_int32_t blk_size_bytes; u_int64_t cp_seg_blk_offset = 0; u_int32_t crc = 0; + int i; ckp = calloc(F2FS_CP_BLOCK_SIZE, 1); if (ckp == NULL) { @@ -678,48 +771,68 @@ /* 1. cp page 1 of checkpoint pack 1 */ ckp->checkpoint_ver = 1; - ckp->cur_node_segno[0] = f2fs_params.cur_seg[CURSEG_HOT_NODE]; - ckp->cur_node_segno[1] = f2fs_params.cur_seg[CURSEG_WARM_NODE]; - ckp->cur_node_segno[2] = f2fs_params.cur_seg[CURSEG_COLD_NODE]; - ckp->cur_data_segno[0] = f2fs_params.cur_seg[CURSEG_HOT_DATA]; - ckp->cur_data_segno[1] = f2fs_params.cur_seg[CURSEG_WARM_DATA]; - ckp->cur_data_segno[2] = f2fs_params.cur_seg[CURSEG_COLD_DATA]; - - ckp->cur_node_blkoff[0] = 1; - ckp->nat_upd_blkoff[0] = 1; - ckp->cur_data_blkoff[0] = 1; - ckp->valid_block_count = 2; /* inode + dentry block */ - ckp->rsvd_segment_count = f2fs_params.reserved_segments; - ckp->overprov_segment_count = (super_block.segment_count_main - - ckp->rsvd_segment_count) * - f2fs_params.overprovision / 100; - ckp->overprov_segment_count += ckp->rsvd_segment_count; + ckp->cur_node_segno[0] = + cpu_to_le32(f2fs_params.cur_seg[CURSEG_HOT_NODE]); + ckp->cur_node_segno[1] = + cpu_to_le32(f2fs_params.cur_seg[CURSEG_WARM_NODE]); + ckp->cur_node_segno[2] = + cpu_to_le32(f2fs_params.cur_seg[CURSEG_COLD_NODE]); + ckp->cur_data_segno[0] = + cpu_to_le32(f2fs_params.cur_seg[CURSEG_HOT_DATA]); + ckp->cur_data_segno[1] = + cpu_to_le32(f2fs_params.cur_seg[CURSEG_WARM_DATA]); + ckp->cur_data_segno[2] = + cpu_to_le32(f2fs_params.cur_seg[CURSEG_COLD_DATA]); + for (i = 3; i < MAX_ACTIVE_NODE_LOGS; i++) { + ckp->cur_node_segno[i] = 0xffffffff; + ckp->cur_data_segno[i] = 0xffffffff; + } + + ckp->cur_node_blkoff[0] = cpu_to_le16(1); + ckp->cur_data_blkoff[0] = cpu_to_le16(1); + ckp->valid_block_count = cpu_to_le64(2); + ckp->rsvd_segment_count = cpu_to_le32(f2fs_params.reserved_segments); + ckp->overprov_segment_count = cpu_to_le32( + (le32_to_cpu(super_block.segment_count_main) - + le32_to_cpu(ckp->rsvd_segment_count)) * + f2fs_params.overprovision / 100); + ckp->overprov_segment_count = cpu_to_le32( + le32_to_cpu(ckp->overprov_segment_count) + + le32_to_cpu(ckp->rsvd_segment_count)); /* main segments - reserved segments - (node + data segments) */ - ckp->free_segment_count = super_block.segment_count_main - 6; - ckp->user_block_count = ((ckp->free_segment_count + 6 - - ckp->overprov_segment_count) * - (1 << super_block.log_blocks_per_seg)); - ckp->cp_pack_total_block_count = 5; - ckp->cp_pack_start_sum = 1; - ckp->valid_node_count = 1; /* root dir inode */ - ckp->valid_inode_count = 1; /* root dir inode */ - ckp->next_free_nid = super_block.root_ino + 1; - - ckp->sit_ver_bitmap_bytesize = ((super_block.segment_count_sit / 2) << - super_block.log_blocks_per_seg) / 8; - - ckp->nat_ver_bitmap_bytesize = ((super_block.segment_count_nat / 2) << - super_block.log_blocks_per_seg) / 8; - - ckp->checksum_offset = 4092 ; /* last 4bytes in the block */ - - crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, ckp, ckp->checksum_offset); - *((u_int32_t *)((unsigned char *)ckp + ckp->checksum_offset)) = crc; - - blk_size_bytes = 1 << super_block.log_blocksize; - cp_seg_blk_offset = - super_block.start_segment_checkpoint * blk_size_bytes; + ckp->free_segment_count = cpu_to_le32( + le32_to_cpu(super_block.segment_count_main) - 6); + ckp->user_block_count = cpu_to_le64( + ((le32_to_cpu(ckp->free_segment_count) + 6 - + le32_to_cpu(ckp->overprov_segment_count)) * + f2fs_params.blks_per_seg)); + ckp->cp_pack_total_block_count = cpu_to_le32(8); + ckp->ckpt_flags |= CP_UMOUNT_FLAG; + ckp->cp_pack_start_sum = cpu_to_le32(1); + ckp->valid_node_count = cpu_to_le32(1); + ckp->valid_inode_count = cpu_to_le32(1); + ckp->next_free_nid = cpu_to_le32( + le32_to_cpu(super_block.root_ino) + 1); + + ckp->sit_ver_bitmap_bytesize = cpu_to_le32( + ((le32_to_cpu(super_block.segment_count_sit) / 2) << + le32_to_cpu(super_block.log_blocks_per_seg)) / 8); + + ckp->nat_ver_bitmap_bytesize = cpu_to_le32( + ((le32_to_cpu(super_block.segment_count_nat) / 2) << + le32_to_cpu(super_block.log_blocks_per_seg)) / 8); + + ckp->checksum_offset = cpu_to_le32(4092); + + crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, ckp, + le32_to_cpu(ckp->checksum_offset)); + *((u_int32_t *)((unsigned char *)ckp + + le32_to_cpu(ckp->checksum_offset))) = crc; + + blk_size_bytes = 1 << le32_to_cpu(super_block.log_blocksize); + cp_seg_blk_offset = le32_to_cpu(super_block.segment0_blkaddr); + cp_seg_blk_offset *= blk_size_bytes; if (writetodisk(f2fs_params.fd, ckp, cp_seg_blk_offset, F2FS_CP_BLOCK_SIZE) < 0) { @@ -728,10 +841,11 @@ } /* 2. Prepare and write Segment summary for data blocks */ + memset(sum, 0, sizeof(struct f2fs_summary_block)); SET_SUM_TYPE((&sum->footer), SUM_TYPE_DATA); sum->entries[0].nid = super_block.root_ino; - sum->entries[0].bidx = 0; + sum->entries[0].ofs_in_node = 0; cp_seg_blk_offset += blk_size_bytes; if (writetodisk(f2fs_params.fd, sum, cp_seg_blk_offset, @@ -742,6 +856,7 @@ /* 3. Fill segment summary for data block to zero. */ memset(sum, 0, sizeof(struct f2fs_summary_block)); + SET_SUM_TYPE((&sum->footer), SUM_TYPE_DATA); cp_seg_blk_offset += blk_size_bytes; if (writetodisk(f2fs_params.fd, sum, cp_seg_blk_offset, @@ -752,25 +867,26 @@ /* 4. Fill segment summary for data block to zero. */ memset(sum, 0, sizeof(struct f2fs_summary_block)); + SET_SUM_TYPE((&sum->footer), SUM_TYPE_DATA); /* inode sit for root */ - sum->n_sits = 6; + sum->n_sits = cpu_to_le16(6); sum->sit_j.entries[0].segno = ckp->cur_node_segno[0]; - sum->sit_j.entries[0].se.vblocks = (CURSEG_HOT_NODE << 10) | 1; + sum->sit_j.entries[0].se.vblocks = cpu_to_le16((CURSEG_HOT_NODE << 10) | 1); f2fs_set_bit(0, sum->sit_j.entries[0].se.valid_map); sum->sit_j.entries[1].segno = ckp->cur_node_segno[1]; - sum->sit_j.entries[1].se.vblocks = (CURSEG_WARM_NODE << 10); + sum->sit_j.entries[1].se.vblocks = cpu_to_le16((CURSEG_WARM_NODE << 10)); sum->sit_j.entries[2].segno = ckp->cur_node_segno[2]; - sum->sit_j.entries[2].se.vblocks = (CURSEG_COLD_NODE << 10); + sum->sit_j.entries[2].se.vblocks = cpu_to_le16((CURSEG_COLD_NODE << 10)); /* data sit for root */ sum->sit_j.entries[3].segno = ckp->cur_data_segno[0]; - sum->sit_j.entries[3].se.vblocks = (CURSEG_HOT_DATA << 10) | 1; + sum->sit_j.entries[3].se.vblocks = cpu_to_le16((CURSEG_HOT_DATA << 10) | 1); f2fs_set_bit(0, sum->sit_j.entries[3].se.valid_map); sum->sit_j.entries[4].segno = ckp->cur_data_segno[1]; - sum->sit_j.entries[4].se.vblocks = (CURSEG_WARM_DATA << 10); + sum->sit_j.entries[4].se.vblocks = cpu_to_le16((CURSEG_WARM_DATA << 10)); sum->sit_j.entries[5].segno = ckp->cur_data_segno[2]; - sum->sit_j.entries[5].se.vblocks = (CURSEG_COLD_DATA << 10); + sum->sit_j.entries[5].se.vblocks = cpu_to_le16((CURSEG_COLD_DATA << 10)); cp_seg_blk_offset += blk_size_bytes; if (writetodisk(f2fs_params.fd, sum, cp_seg_blk_offset, @@ -779,34 +895,13 @@ return -1; } - /* 5. cp page2 */ - cp_seg_blk_offset += blk_size_bytes; - if (writetodisk(f2fs_params.fd, ckp, cp_seg_blk_offset, - F2FS_CP_BLOCK_SIZE) < 0) { - printf("\n\tError: While writing the ckp to disk!!!\n"); - return -1; - } - - /* 6. cp page 1 of check point pack 2 - * Initiatialize other checkpoint pack with version zero - */ - ckp->checkpoint_ver = 0; - - crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, ckp, ckp->checksum_offset); - *((u_int32_t *)((unsigned char *)ckp + ckp->checksum_offset)) = crc; + /* 5. Prepare and write Segment summary for node blocks */ + memset(sum, 0, sizeof(struct f2fs_summary_block)); + SET_SUM_TYPE((&sum->footer), SUM_TYPE_NODE); - cp_seg_blk_offset = (super_block.start_segment_checkpoint + - (1 << super_block.log_blocks_per_seg)) * - blk_size_bytes; - if (writetodisk(f2fs_params.fd, ckp, - cp_seg_blk_offset, F2FS_CP_BLOCK_SIZE) < 0) { - printf("\n\tError: While writing the ckp to disk!!!\n"); - return -1; - } + sum->entries[0].nid = super_block.root_ino; + sum->entries[0].ofs_in_node = 0; - /* 7. */ - memset(sum, 0, sizeof(struct f2fs_summary_block)); - SET_SUM_TYPE((&sum->footer), SUM_TYPE_DATA); cp_seg_blk_offset += blk_size_bytes; if (writetodisk(f2fs_params.fd, sum, cp_seg_blk_offset, sizeof(struct f2fs_summary_block)) < 0) { @@ -814,8 +909,10 @@ return -1; } - /* 8. */ + /* 6. Fill segment summary for data block to zero. */ memset(sum, 0, sizeof(struct f2fs_summary_block)); + SET_SUM_TYPE((&sum->footer), SUM_TYPE_NODE); + cp_seg_blk_offset += blk_size_bytes; if (writetodisk(f2fs_params.fd, sum, cp_seg_blk_offset, sizeof(struct f2fs_summary_block)) < 0) { @@ -823,8 +920,9 @@ return -1; } - /* 9. */ + /* 7. Fill segment summary for data block to zero. */ memset(sum, 0, sizeof(struct f2fs_summary_block)); + SET_SUM_TYPE((&sum->footer), SUM_TYPE_NODE); cp_seg_blk_offset += blk_size_bytes; if (writetodisk(f2fs_params.fd, sum, cp_seg_blk_offset, sizeof(struct f2fs_summary_block)) < 0) { @@ -832,7 +930,7 @@ return -1; } - /* 10. cp page 2 of check point pack 2 */ + /* 8. cp page2 */ cp_seg_blk_offset += blk_size_bytes; if (writetodisk(f2fs_params.fd, ckp, cp_seg_blk_offset, F2FS_CP_BLOCK_SIZE) < 0) { @@ -840,6 +938,25 @@ return -1; } + /* 9. cp page 1 of check point pack 2 + * Initiatialize other checkpoint pack with version zero + */ + ckp->checkpoint_ver = 0; + + crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, ckp, + le32_to_cpu(ckp->checksum_offset)); + *((u_int32_t *)((unsigned char *)ckp + + le32_to_cpu(ckp->checksum_offset))) = crc; + + cp_seg_blk_offset = (le32_to_cpu(super_block.segment0_blkaddr) + + f2fs_params.blks_per_seg) * + blk_size_bytes; + if (writetodisk(f2fs_params.fd, ckp, + cp_seg_blk_offset, F2FS_CP_BLOCK_SIZE) < 0) { + printf("\n\tError: While writing the ckp to disk!!!\n"); + return -1; + } + free(sum) ; free(ckp) ; return 0; @@ -853,25 +970,24 @@ static int8_t f2fs_write_super_block(void) { u_int32_t index = 0; - u_int64_t super_blk_offset; u_int8_t *zero_buff; - zero_buff = calloc(f2fs_params.sector_size, 1); - super_blk_offset = F2FS_SUPER_OFFSET * F2FS_BLKSIZE; + zero_buff = calloc(F2FS_BLKSIZE, 1); + + memcpy(zero_buff + F2FS_SUPER_OFFSET, &super_block, + sizeof(super_block)); for (index = 0; index < 2; index++) { - if (writetodisk(f2fs_params.fd, &super_block, super_blk_offset, - sizeof(struct f2fs_super_block)) < 0) { + if (writetodisk(f2fs_params.fd, zero_buff, + index * F2FS_BLKSIZE, F2FS_BLKSIZE) < 0) { printf("\n\tError: While while writing supe_blk \ on disk!!! index : %d\n", index); return -1; } - super_blk_offset += F2FS_BLKSIZE; } free(zero_buff); return 0; - } /** @@ -882,8 +998,7 @@ static int8_t f2fs_write_root_inode(void) { struct f2fs_node *raw_node = NULL; - u_int32_t blk_size_bytes; - u_int64_t data_blk_nor; + u_int64_t blk_size_bytes, data_blk_nor; u_int64_t main_area_node_seg_blk_offset = 0; raw_node = calloc(sizeof(struct f2fs_node), 1); @@ -894,39 +1009,44 @@ raw_node->footer.nid = super_block.root_ino; raw_node->footer.ino = super_block.root_ino; - raw_node->footer.node_block_index = 0; - raw_node->footer.cp_ver = 1; - raw_node->footer.next_blkaddr = super_block.main_blkaddr + - f2fs_params.cur_seg[CURSEG_HOT_NODE] * (1 << super_block.log_blocks_per_seg) + 1; - - raw_node->i.i_mode = 0x41ed; - raw_node->i.i_links = 2; - raw_node->i.i_uid = getuid(); - raw_node->i.i_gid = getgid(); - - blk_size_bytes = 1 << super_block.log_blocksize; - raw_node->i.i_size = 1 * blk_size_bytes; /* dentry */ - raw_node->i.i_blocks = 2; /* 1 for raw_node & 1 for data blocks */ - - raw_node->i.i_atime = time(NULL); - raw_node->i.i_ctime = time(NULL); - raw_node->i.i_mtime = time(NULL); - raw_node->i.i_btime = time(NULL); + raw_node->footer.cp_ver = cpu_to_le64(1); + raw_node->footer.next_blkaddr = cpu_to_le32( + le32_to_cpu(super_block.main_blkaddr) + + f2fs_params.cur_seg[CURSEG_HOT_NODE] * + f2fs_params.blks_per_seg + 1); + + raw_node->i.i_mode = cpu_to_le16(0x41ed); + raw_node->i.i_links = cpu_to_le32(2); + raw_node->i.i_uid = cpu_to_le32(getuid()); + raw_node->i.i_gid = cpu_to_le32(getgid()); + + blk_size_bytes = 1 << le32_to_cpu(super_block.log_blocksize); + raw_node->i.i_size = cpu_to_le64(1 * blk_size_bytes); /* dentry */ + raw_node->i.i_blocks = cpu_to_le64(2); + + raw_node->i.i_atime = cpu_to_le32(time(NULL)); + raw_node->i.i_atime_nsec = 0; + raw_node->i.i_ctime = cpu_to_le32(time(NULL)); + raw_node->i.i_ctime_nsec = 0; + raw_node->i.i_mtime = cpu_to_le32(time(NULL)); + raw_node->i.i_mtime_nsec = 0; + raw_node->i.i_generation = 0; raw_node->i.i_xattr_nid = 0; raw_node->i.i_flags = 0; - raw_node->i.current_depth = 1; + raw_node->i.i_current_depth = cpu_to_le32(1); - data_blk_nor = super_block.main_blkaddr + - f2fs_params.cur_seg[CURSEG_HOT_DATA] * (1 << super_block.log_blocks_per_seg); - raw_node->i.i_addr[0] = data_blk_nor; + data_blk_nor = le32_to_cpu(super_block.main_blkaddr) + + f2fs_params.cur_seg[CURSEG_HOT_DATA] * f2fs_params.blks_per_seg; + raw_node->i.i_addr[0] = cpu_to_le32(data_blk_nor); raw_node->i.i_ext.fofs = 0; - raw_node->i.i_ext.blk_addr = data_blk_nor; - raw_node->i.i_ext.len = 1; + raw_node->i.i_ext.blk_addr = cpu_to_le32(data_blk_nor); + raw_node->i.i_ext.len = cpu_to_le32(1); - main_area_node_seg_blk_offset = (super_block.main_blkaddr + - f2fs_params.cur_seg[CURSEG_HOT_NODE] * (1 << super_block.log_blocks_per_seg)) * - blk_size_bytes; + main_area_node_seg_blk_offset = le32_to_cpu(super_block.main_blkaddr); + main_area_node_seg_blk_offset += f2fs_params.cur_seg[CURSEG_HOT_NODE] * + f2fs_params.blks_per_seg; + main_area_node_seg_blk_offset *= blk_size_bytes; if (writetodisk(f2fs_params.fd, raw_node, main_area_node_seg_blk_offset, sizeof(struct f2fs_node)) < 0) { @@ -935,6 +1055,7 @@ } memset(raw_node, 0xff, sizeof(struct f2fs_node)); + if (writetodisk(f2fs_params.fd, raw_node, main_area_node_seg_blk_offset + 4096, sizeof(struct f2fs_node)) < 0) { @@ -953,8 +1074,7 @@ static int8_t f2fs_update_nat_root(void) { struct f2fs_nat_block *nat_blk = NULL; - u_int32_t blk_size_bytes; - u_int64_t nat_seg_blk_offset = 0; + u_int64_t blk_size_bytes, nat_seg_blk_offset = 0; nat_blk = calloc(sizeof(struct f2fs_nat_block), 1); if(nat_blk == NULL) { @@ -963,23 +1083,22 @@ } /* update root */ - nat_blk->entries[super_block.root_ino].block_addr = - super_block.main_blkaddr + - f2fs_params.cur_seg[CURSEG_HOT_NODE] * (1 << super_block.log_blocks_per_seg); - nat_blk->entries[super_block.root_ino].ino = - super_block.root_ino; + nat_blk->entries[super_block.root_ino].block_addr = cpu_to_le32( + le32_to_cpu(super_block.main_blkaddr) + + f2fs_params.cur_seg[CURSEG_HOT_NODE] * f2fs_params.blks_per_seg); + nat_blk->entries[super_block.root_ino].ino = super_block.root_ino; + /* update node nat */ - nat_blk->entries[super_block.node_ino].block_addr = 1; - nat_blk->entries[super_block.node_ino].ino = - super_block.node_ino; - /* update meta nat */ - nat_blk->entries[super_block.meta_ino].block_addr = 1; - nat_blk->entries[super_block.meta_ino].ino = - super_block.meta_ino; + nat_blk->entries[super_block.node_ino].block_addr = cpu_to_le32(1); + nat_blk->entries[super_block.node_ino].ino = super_block.node_ino; - blk_size_bytes = 1 << super_block.log_blocksize; + /* update meta nat */ + nat_blk->entries[super_block.meta_ino].block_addr = cpu_to_le32(1); + nat_blk->entries[super_block.meta_ino].ino = super_block.meta_ino; - nat_seg_blk_offset = super_block.nat_blkaddr * blk_size_bytes; + blk_size_bytes = 1 << le32_to_cpu(super_block.log_blocksize); + nat_seg_blk_offset = le32_to_cpu(super_block.nat_blkaddr); + nat_seg_blk_offset *= blk_size_bytes; if (writetodisk(f2fs_params.fd, nat_blk, nat_seg_blk_offset, sizeof(struct f2fs_nat_block)) < 0) { @@ -999,8 +1118,7 @@ static int8_t f2fs_add_default_dentry_root(void) { struct f2fs_dentry_block *dent_blk = NULL; - u_int32_t blk_size_bytes; - u_int64_t data_blk_offset = 0; + u_int64_t blk_size_bytes, data_blk_offset = 0; dent_blk = calloc(sizeof(struct f2fs_dentry_block), 1); if(dent_blk == NULL) { @@ -1010,21 +1128,23 @@ dent_blk->dentry[0].hash_code = 0; dent_blk->dentry[0].ino = super_block.root_ino; - dent_blk->dentry[0].name_len = 1; + dent_blk->dentry[0].name_len = cpu_to_le16(1); dent_blk->dentry[0].file_type = F2FS_FT_DIR; memcpy(dent_blk->filename[0], ".", 1); dent_blk->dentry[1].hash_code = 0; dent_blk->dentry[1].ino = super_block.root_ino; - dent_blk->dentry[1].name_len = 2; + dent_blk->dentry[1].name_len = cpu_to_le16(2); dent_blk->dentry[1].file_type = F2FS_FT_DIR; memcpy(dent_blk->filename[1], "..", 2); - dent_blk->dentry_bitmap[0] = (1 << 1) | (1 << 0); // bitmap for . and .. - blk_size_bytes = 1 << super_block.log_blocksize; - data_blk_offset = (super_block.main_blkaddr + f2fs_params.cur_seg[CURSEG_HOT_DATA] * - (1 << super_block.log_blocks_per_seg)) * - blk_size_bytes; + /* bitmap for . and .. */ + dent_blk->dentry_bitmap[0] = (1 << 1) | (1 << 0); + blk_size_bytes = 1 << le32_to_cpu(super_block.log_blocksize); + data_blk_offset = le32_to_cpu(super_block.main_blkaddr); + data_blk_offset += f2fs_params.cur_seg[CURSEG_HOT_DATA] * + f2fs_params.blks_per_seg; + data_blk_offset *= blk_size_bytes; if (writetodisk(f2fs_params.fd, dent_blk, data_blk_offset, sizeof(struct f2fs_dentry_block)) < 0) { @@ -1165,6 +1285,9 @@ */ int main(int argc, char *argv[]) { + printf("\nF2FS-tools: Ver: %s (%s)\n", + F2FS_TOOLS_VERSION, + F2FS_TOOLS_DATE); f2fs_init_global_parameters(); f2fs_parse_options(argc, argv); diff -Nru f2fs-tools-1.0.0/mkfs/f2fs_format.h f2fs-tools-1.1.0/mkfs/f2fs_format.h --- f2fs-tools-1.0.0/mkfs/f2fs_format.h 2012-08-27 00:34:34.000000000 +0000 +++ f2fs-tools-1.1.0/mkfs/f2fs_format.h 2012-11-29 03:44:04.000000000 +0000 @@ -12,13 +12,29 @@ #define __F2FS_FORMAT_H__ #include +#include +#include + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define le16_to_cpu(x) ((__u16)(x)) +#define le32_to_cpu(x) ((__u32)(x)) +#define le64_to_cpu(x) ((__u64)(x)) +#define cpu_to_le16(x) ((__u16)(x)) +#define cpu_to_le32(x) ((__u32)(x)) +#define cpu_to_le64(x) ((__u64)(x)) +#elif __BYTE_ORDER == __BIG_ENDIAN +#define le16_to_cpu(x) bswap_16(x) +#define le32_to_cpu(x) bswap_32(x) +#define le64_to_cpu(x) bswap_64(x) +#define cpu_to_le16(x) bswap_16(x) +#define cpu_to_le32(x) bswap_32(x) +#define cpu_to_le64(x) bswap_64(x) +#endif /* these are defined in kernel */ #define PAGE_SIZE 4096 #define PAGE_CACHE_SIZE 4096 #define BITS_PER_BYTE 8 -#define cpu_to_le32(x) (x) -#define le32_to_cpu(x) (x) /* for mkfs */ #define F2FS_MIN_VOLUME_SIZE 104857600 @@ -39,12 +55,23 @@ #define DEFAULT_SEGMENTS_PER_SECTION 1 #define F2FS_CP_BLOCK_SIZE (DEFAULT_SECTOR_SIZE * \ DEFAULT_SECTORS_PER_BLOCK) + +/* + * For further optimization on multi-head logs, on-disk layout supports maximum + * 16 logs by default. The number, 16, is expected to cover all the cases + * enoughly. The implementaion currently uses no more than 6 logs. + * Half the logs are used for nodes, and the other half are used for data. + */ +#define MAX_ACTIVE_LOGS 16 +#define MAX_ACTIVE_NODE_LOGS 8 +#define MAX_ACTIVE_DATA_LOGS 8 + struct f2fs_global_parameters { u_int32_t sector_size; u_int32_t reserved_segments; u_int32_t overprovision; u_int32_t cur_seg[6]; - u_int32_t log_segs_per_sec; + u_int32_t segs_per_sec; u_int32_t secs_per_zone; u_int32_t start_sector; u_int64_t total_sectors; @@ -54,6 +81,7 @@ int heap; int32_t fd; char *device_name; + char *extension_list; } __attribute__((packed)); #ifdef CONFIG_64BIT @@ -69,89 +97,80 @@ * For superblock */ #define F2FS_SUPER_MAGIC 0xF2F52010 /* F2FS Magic Number */ -#define F2FS_SUPER_OFFSET 1 /* start sector # for sb */ +#define F2FS_SUPER_OFFSET 1024 /* byte-size offset */ #define F2FS_BLKSIZE 4096 +#define F2FS_MAX_EXTENSION 64 struct f2fs_super_block { - __le32 magic; /* Magic Number */ - __le16 major_ver; /* Major Version */ - __le16 minor_ver; /* Minor Version */ - __le32 log_sectorsize; /* log2 (Sector size in bytes) */ - __le32 log_sectors_per_block; /* log2 (Number of sectors per block */ - __le32 log_blocksize; /* log2 (Block size in bytes) */ - __le32 log_blocks_per_seg; /* log2 (Number of blocks per segment) */ - __le32 log_segs_per_sec; /* log2 (Number of segments per section) */ - __le32 secs_per_zone; /* Number of sections per zone) */ - __le32 checksum_offset; /* Checksum position in this super block */ - __le64 block_count; /* Total number of blocks */ - __le32 section_count; /* Total number of sections */ - __le32 segment_count; /* Total number of segments */ - __le32 segment_count_ckpt; /* Total number of segments - in Checkpoint area */ - __le32 segment_count_sit; /* Total number of segments - in Segment information table */ - __le32 segment_count_nat; /* Total number of segments - in Node address table */ - /*Total number of segments in Segment summary area */ - __le32 segment_count_ssa; - /* Total number of segments in Main area */ - __le32 segment_count_main; - __le32 failure_safe_block_distance; - __le64 segment0_blkaddr; /* Start block address of Segment 0 */ - __le64 start_segment_checkpoint; /* Start block address of ckpt */ - __le64 sit_blkaddr; /* Start block address of SIT */ - __le64 nat_blkaddr; /* Start block address of NAT */ - __le64 ssa_blkaddr; /* Start block address of SSA */ - __le64 main_blkaddr; /* Start block address of Main area */ - __le32 root_ino; /* Root directory inode number */ - __le32 node_ino; /* node inode number */ - __le32 meta_ino; /* meta inode number */ - __le32 volume_serial_number; /* VSN is optional field */ - __le16 volume_name[8]; /* Volume Name. 8 unicode characters */ + __le32 magic; /* Magic Number */ + __le16 major_ver; /* Major Version */ + __le16 minor_ver; /* Minor Version */ + __le32 log_sectorsize; /* log2 sector size in bytes */ + __le32 log_sectors_per_block; /* log2 # of sectors per block */ + __le32 log_blocksize; /* log2 block size in bytes */ + __le32 log_blocks_per_seg; /* log2 # of blocks per segment */ + __le32 segs_per_sec; /* # of segments per section */ + __le32 secs_per_zone; /* # of sections per zone */ + __le32 checksum_offset; /* checksum offset inside super block */ + __le64 block_count; /* total # of user blocks */ + __le32 section_count; /* total # of sections */ + __le32 segment_count; /* total # of segments */ + __le32 segment_count_ckpt; /* # of segments for checkpoint */ + __le32 segment_count_sit; /* # of segments for SIT */ + __le32 segment_count_nat; /* # of segments for NAT */ + __le32 segment_count_ssa; /* # of segments for SSA */ + __le32 segment_count_main; /* # of segments for main area */ + __le32 segment0_blkaddr; /* start block address of segment 0 */ + __le32 cp_blkaddr; /* start block address of checkpoint */ + __le32 sit_blkaddr; /* start block address of SIT */ + __le32 nat_blkaddr; /* start block address of NAT */ + __le32 ssa_blkaddr; /* start block address of SSA */ + __le32 main_blkaddr; /* start block address of main area */ + __le32 root_ino; /* root inode number */ + __le32 node_ino; /* node inode number */ + __le32 meta_ino; /* meta inode number */ + __u8 uuid[16]; /* 128-bit uuid for volume */ + __le16 volume_name[512]; /* volume name */ + __le32 extension_count; /* # of extensions below */ + __u8 extension_list[F2FS_MAX_EXTENSION][8]; /* extension array */ } __attribute__((packed)); /* * For checkpoint */ +#define CP_ERROR_FLAG 0x00000008 +#define CP_COMPACT_SUM_FLAG 0x00000004 +#define CP_ORPHAN_PRESENT_FLAG 0x00000002 +#define CP_UMOUNT_FLAG 0x00000001 + struct f2fs_checkpoint { - __le64 checkpoint_ver; /* Checkpoint block version number */ - __le64 user_block_count; /* Total number of blocks - in Main area excluding the number of - reserved blocks */ - __le64 valid_block_count; /* Total number of valid blocks - in Main area */ - __le32 rsvd_segment_count; /* Total number of reserved segments - (for garbage collection) */ - __le32 overprov_segment_count; /* Total number of overprovision segments */ - __le32 free_segment_count; /* Total number of free segments - in Main area */ - __le32 bad_segment_count; /* Total number of bad segments - in Main area */ - __le32 cur_node_segno[3]; /* Segment number of current node - segment */ - __le16 cur_node_blkoff[3]; /* Current node block offset - in the node segment */ - __le16 nat_upd_blkoff[3]; /* Block offset in current node segment - where the last NAT update happened */ - __le32 cur_data_segno[3]; /* Segment number of current log - segment */ - __le16 cur_data_blkoff[3]; /* Current data block offset - in the data segment */ + __le64 checkpoint_ver; /* checkpoint block version number */ + __le64 user_block_count; /* # of user blocks */ + __le64 valid_block_count; /* # of valid blocks in main area */ + __le32 rsvd_segment_count; /* # of reserved segments for gc */ + __le32 overprov_segment_count; /* # of overprovision segments */ + __le32 free_segment_count; /* # of free segments in main area */ + + /* information of current node segments */ + __le32 cur_node_segno[MAX_ACTIVE_NODE_LOGS]; + __le16 cur_node_blkoff[MAX_ACTIVE_NODE_LOGS]; + /* information of current data segments */ + __le32 cur_data_segno[MAX_ACTIVE_DATA_LOGS]; + __le16 cur_data_blkoff[MAX_ACTIVE_DATA_LOGS]; __le32 ckpt_flags; /* Flags : umount and journal_present */ - __le32 cp_pack_total_block_count; + __le32 cp_pack_total_block_count; /* total # of one cp pack */ __le32 cp_pack_start_sum; /* start block number of data summary */ __le32 valid_node_count; /* Total number of valid nodes */ __le32 valid_inode_count; /* Total number of valid inodes */ __le32 next_free_nid; /* Next free node number */ __le32 sit_ver_bitmap_bytesize; /* Default value 64 */ __le32 nat_ver_bitmap_bytesize; /* Default value 256 */ - __le32 checksum_offset; /* Checksum position - in this checkpoint block */ - __le64 elapsed_time; /* elapsed time while partition - is mounted */ - unsigned char alloc_type[6]; /* allocation type of current segment */ + __le32 checksum_offset; /* checksum offset inside cp block */ + __le64 elapsed_time; /* mounted time */ + /* allocation type of current segment */ + unsigned char alloc_type[MAX_ACTIVE_LOGS]; - /* SIt and NAT version bitmap */ + /* SIT and NAT version bitmap */ unsigned char sit_nat_version_bitmap[1]; } __attribute__((packed)); @@ -159,30 +178,34 @@ * For NODE structure */ struct f2fs_extent { - __le32 fofs; - __le32 blk_addr; - __le32 len; + __le32 fofs; /* start file offset of the extent */ + __le32 blk_addr; /* start block address of the extent */ + __le32 len; /* lengh of the extent */ } __attribute__((packed)); #define F2FS_MAX_NAME_LEN 256 -#define ADDRS_PER_INODE 929 /* Address Pointers in an Inode */ +#define ADDRS_PER_INODE 923 /* Address Pointers in an Inode */ #define ADDRS_PER_BLOCK 1018 /* Address Pointers in a Direct Block */ #define NIDS_PER_BLOCK 1018 /* Node IDs in an Indirect Block */ struct f2fs_inode { - __le16 i_mode; /* File mode */ - __le16 i_reserved; /* Reserved */ - __le32 i_uid; /* User ID */ - __le32 i_gid; /* Group ID */ - __le32 i_links; /* Links count */ - __le64 i_size; /* File size in bytes */ - __le64 i_blocks; /* File size in bytes */ - __le32 i_atime; /* Access time */ - __le32 i_ctime; /* inode Change time */ - __le32 i_mtime; /* Modification time */ - __le32 i_btime; /* file creation time*/ - __le32 current_depth; - __le32 i_xattr_nid; + __le16 i_mode; /* file mode */ + __u8 i_advise; /* file hints */ + __u8 i_reserved; /* reserved */ + __le32 i_uid; /* user ID */ + __le32 i_gid; /* group ID */ + __le32 i_links; /* links count */ + __le64 i_size; /* file size in bytes */ + __le64 i_blocks; /* file size in blocks */ + __le64 i_atime; /* access time */ + __le64 i_ctime; /* change time */ + __le64 i_mtime; /* modification time */ + __le32 i_atime_nsec; /* access time in nano scale */ + __le32 i_ctime_nsec; /* change time in nano scale */ + __le32 i_mtime_nsec; /* modification time in nano scale */ + __le32 i_generation; /* file version (for NFS) */ + __le32 i_current_depth; /* only for directory depth */ + __le32 i_xattr_nid; /* nid to save xattr */ __le32 i_flags; /* file attributes */ __le32 i_pino; /* parent inode number */ __le32 i_namelen; /* file name length */ @@ -205,17 +228,15 @@ } __attribute__((packed)); struct node_footer { - __le32 nid; /* node id */ - __le32 ino; /* iNode no */ - __le32 cold:1; /* cold mark */ - __le32 fsync:1; /* fsync mark */ - __le32 dentry:1; /* fsync mark */ - __le32 node_block_index:29; /* offset in inode's node space */ + __le32 nid; /* node id */ + __le32 ino; /* inode nunmber */ + __le32 flag; /* include cold/fsync/dentry marks and offset */ __le64 cp_ver; /* checkpoint version */ __le32 next_blkaddr; /* next node page block address */ } __attribute__((packed)); struct f2fs_node { + /* can be one of three types: inode, direct, and indirect types */ union { struct f2fs_inode i; struct direct_node dn; @@ -230,9 +251,9 @@ #define NAT_ENTRY_PER_BLOCK (PAGE_CACHE_SIZE / sizeof(struct f2fs_nat_entry)) struct f2fs_nat_entry { - __u8 version; - __le32 ino; - __le32 block_addr; + __u8 version; /* latest version of cached nat entry */ + __le32 ino; /* inode number */ + __le32 block_addr; /* block address */ } __attribute__((packed)); struct f2fs_nat_block { @@ -241,68 +262,85 @@ /* * For SIT entries + * + * Each segment is 2MB in size by default so that a bitmap for validity of + * there-in blocks should occupy 64 bytes, 512 bits. + * Not allow to change this. */ -#define CURSEG_NULL ((-1 << 10) >> 10) /* use 6bit - 0x3f */ +#define SIT_VBLOCK_MAP_SIZE 64 +#define SIT_ENTRY_PER_BLOCK (PAGE_CACHE_SIZE / sizeof(struct f2fs_sit_entry)) + enum { - CURSEG_HOT_DATA, /* directory entry pages */ - CURSEG_WARM_DATA, /* updated or appended user data pages */ - CURSEG_COLD_DATA, /* multimedia or GCed data pages */ - CURSEG_HOT_NODE, /* node pages to save index of directory entry pages */ - CURSEG_WARM_NODE, /* node pages to save index of user data pages */ - CURSEG_COLD_NODE, /* node page to save indirect node index */ + CURSEG_HOT_DATA = 0, /* directory entry blocks */ + CURSEG_WARM_DATA, /* data blocks */ + CURSEG_COLD_DATA, /* multimedia or GCed data blocks */ + CURSEG_HOT_NODE, /* direct node blocks of directory files */ + CURSEG_WARM_NODE, /* direct node blocks of normal files */ + CURSEG_COLD_NODE, /* indirect node blocks */ }; -#define SIT_VBLOCK_MAP_SIZE 64 -#define SIT_ENTRY_PER_BLOCK (PAGE_CACHE_SIZE / sizeof(struct f2fs_sit_entry)) +/* + * Note that f2fs_sit_entry->vblocks has the following bit-field information. + * [15:10] : allocation type such as CURSEG_XXXX_TYPE + * [9:0] : valid block count + */ +#define CURSEG_NULL ((-1 << 10) >> 10) /* use 6bit - 0x3f */ struct f2fs_sit_entry { - __le16 vblocks; - __u8 valid_map[SIT_VBLOCK_MAP_SIZE]; - __le64 mtime; + __le16 vblocks; /* reference above */ + __u8 valid_map[SIT_VBLOCK_MAP_SIZE]; /* bitmap for valid blocks */ + __le64 mtime; /* segment age for cleaning */ } __attribute__((packed)); struct f2fs_sit_block { struct f2fs_sit_entry entries[SIT_ENTRY_PER_BLOCK]; } __attribute__((packed)); +/** + * For segment summary + * + * One summary block contains exactly 512 summary entries, which represents + * exactly 2MB segment by default. Not allow to change the basic units. + * + * NOTE : For initializing fields, you must use set_summary + * + * - If data page, nid represents dnode's nid + * - If node page, nid represents the node page's nid. + * + * The ofs_in_node is used by only data page. It represents offset + * from node's page's beginning to get a data block address. + * ex) data_blkaddr = (block_t)(nodepage_start_address + ofs_in_node) + */ +#define ENTRIES_IN_SUM 512 +#define SUMMARY_SIZE (sizeof(struct f2fs_summary)) +#define SUM_FOOTER_SIZE (sizeof(struct summary_footer)) +#define SUM_ENTRY_SIZE (SUMMARY_SIZE * ENTRIES_IN_SUM) + +/* a summary entry for a 4KB-sized block in a segment */ struct f2fs_summary { __le32 nid; /* parent node id */ union { __u8 reserved[3]; struct { __u8 version; /* node version number */ - __le16 bidx; /* block index in parent node */ + __le16 ofs_in_node; /* block index in parent node */ } __attribute__((packed)); }; } __attribute__((packed)); -struct summary_footer { - unsigned char entry_type; - __u32 check_sum; -} __attribute__((packed)); - -#define SUM_TYPE_NODE (1) -#define SUM_TYPE_DATA (0) +/* summary block type, node or data, is stored to the summary_footer */ +#define SUM_TYPE_NODE (1) +#define SUM_TYPE_DATA (0) #define GET_SUM_TYPE(footer) (footer->entry_type) #define SET_SUM_TYPE(footer, type) (footer->entry_type = type) -#define SUMMARY_SIZE (sizeof(struct f2fs_summary)) -#define SUM_FOOTER_SIZE (sizeof(struct summary_footer)) -#define ENTRIES_IN_SUM 512 -#define SUM_ENTRY_SIZE (SUMMARY_SIZE * ENTRIES_IN_SUM) -#define SUM_JOURNAL_SIZE (PAGE_CACHE_SIZE - SUM_FOOTER_SIZE -\ - SUM_ENTRY_SIZE) - -struct nat_journal_entry { - __le32 nid; - struct f2fs_nat_entry ne; -} __attribute__((packed)); - -struct sit_journal_entry { - __le32 segno; - struct f2fs_sit_entry se; +struct summary_footer { + unsigned char entry_type; /* SUM_TYPE_XXX */ + __u32 check_sum; /* summary checksum */ } __attribute__((packed)); +#define SUM_JOURNAL_SIZE (PAGE_CACHE_SIZE - SUM_FOOTER_SIZE -\ + SUM_ENTRY_SIZE) #define NAT_JOURNAL_ENTRIES ((SUM_JOURNAL_SIZE - 2) /\ sizeof(struct nat_journal_entry)) #define NAT_JOURNAL_RESERVED ((SUM_JOURNAL_SIZE - 2) %\ @@ -311,27 +349,43 @@ sizeof(struct sit_journal_entry)) #define SIT_JOURNAL_RESERVED ((SUM_JOURNAL_SIZE - 2) %\ sizeof(struct sit_journal_entry)) +/* + * frequently updated NAT/SIT entries can be stored in the spare area in + * summary blocks + */ enum { NAT_JOURNAL = 0, SIT_JOURNAL }; +struct nat_journal_entry { + __le32 nid; + struct f2fs_nat_entry ne; +} __attribute__((packed)); + struct nat_journal { struct nat_journal_entry entries[NAT_JOURNAL_ENTRIES]; __u8 reserved[NAT_JOURNAL_RESERVED]; } __attribute__((packed)); +struct sit_journal_entry { + __le32 segno; + struct f2fs_sit_entry se; +} __attribute__((packed)); + struct sit_journal { struct sit_journal_entry entries[SIT_JOURNAL_ENTRIES]; __u8 reserved[SIT_JOURNAL_RESERVED]; } __attribute__((packed)); +/* 4KB-sized summary block structure */ struct f2fs_summary_block { struct f2fs_summary entries[ENTRIES_IN_SUM]; union { __le16 n_nats; __le16 n_sits; }; + /* spare area is used by NAT or SIT journals */ union { struct nat_journal nat_j; struct sit_journal sit_j; @@ -342,9 +396,14 @@ /* * For directory operations */ -#define F2FS_NAME_LEN 8 /* 256 Unicode */ -#define NR_DENTRY_IN_BLOCK 214 /* the number of dentry in a block */ -#define MAX_DIR_HASH_DEPTH 63 /* MAX level for dir lookup */ +/* One directory entry slot covers 8bytes-long file name */ +#define F2FS_NAME_LEN 8 + +/* the number of dentry in a block */ +#define NR_DENTRY_IN_BLOCK 214 + +/* MAX level for dir lookup */ +#define MAX_DIR_HASH_DEPTH 63 #define SIZE_OF_DIR_ENTRY 11 /* by byte */ #define SIZE_OF_DENTRY_BITMAP ((NR_DENTRY_IN_BLOCK + BITS_PER_BYTE - 1) / \ @@ -353,21 +412,24 @@ F2FS_NAME_LEN) * \ NR_DENTRY_IN_BLOCK + SIZE_OF_DENTRY_BITMAP)) +/* One directory entry slot representing F2FS_NAME_LEN-sized file name */ struct f2fs_dir_entry { __le32 hash_code; /* hash code of file name */ - __le32 ino; /* node number of inode */ - __le16 name_len; /* the size of file name - * length in unicode characters */ - __u8 file_type; + __le32 ino; /* inode number */ + __le16 name_len; /* lengh of file name */ + __u8 file_type; /* file type */ } __attribute__((packed)); +/* 4KB-sized directory entry block */ struct f2fs_dentry_block { + /* validity bitmap for directory entries in each block */ __u8 dentry_bitmap[SIZE_OF_DENTRY_BITMAP]; __u8 reserved[SIZE_OF_RESERVED]; struct f2fs_dir_entry dentry[NR_DENTRY_IN_BLOCK]; __u8 filename[NR_DENTRY_IN_BLOCK][F2FS_NAME_LEN]; } __attribute__((packed)); +/* file types used in inode_info->flags */ enum { F2FS_FT_UNKNOWN, F2FS_FT_REG_FILE, diff -Nru f2fs-tools-1.0.0/version.h f2fs-tools-1.1.0/version.h --- f2fs-tools-1.0.0/version.h 1970-01-01 00:00:00.000000000 +0000 +++ f2fs-tools-1.1.0/version.h 2012-11-29 03:44:04.000000000 +0000 @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#define F2FS_TOOLS_VERSION "1.1.0" +#define F2FS_TOOLS_DATE "29-Nov-2012"