mirror of
https://gitee.com/openharmony/third_party_f2fs-tools
synced 2024-11-26 19:51:32 +00:00
build: make several base functions as a library
Let's make a library and relocate functions for other tools like fsck.f2fs. Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
This commit is contained in:
parent
2784bd55dd
commit
e69e437850
47
.gitignore
vendored
47
.gitignore
vendored
@ -1,20 +1,47 @@
|
||||
.*
|
||||
*~
|
||||
*.[ao]
|
||||
*.orig
|
||||
*.tar.*
|
||||
*.s
|
||||
*.lo
|
||||
*.la
|
||||
*.so
|
||||
*.so.dbg
|
||||
*.mod.c
|
||||
*.lst
|
||||
*.orig
|
||||
*.rej
|
||||
|
||||
.deps/
|
||||
.libs/
|
||||
CVS
|
||||
!.gitignore
|
||||
tags
|
||||
TAGS
|
||||
GPATH
|
||||
GRTAGS
|
||||
GSYMS
|
||||
GTAGS
|
||||
|
||||
#
|
||||
# Generated files
|
||||
#
|
||||
compile
|
||||
install-sh
|
||||
missing
|
||||
depcomp
|
||||
INSTALL
|
||||
aclocal.m4
|
||||
autoconf-[0-9].*
|
||||
autom4te.cache
|
||||
build-aux
|
||||
Makefile
|
||||
Makefile.in
|
||||
|
||||
/aclocal.m4
|
||||
/autom4te.cache/
|
||||
/build-aux/
|
||||
/config.*
|
||||
/configure*
|
||||
/stamp-h1
|
||||
config.*
|
||||
configure
|
||||
configure.scan
|
||||
ltmain.sh
|
||||
libtool
|
||||
stamp-h
|
||||
stamp-h1
|
||||
|
||||
/mkfs/mkfs.f2fs
|
||||
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
SUBDIRS = man mkfs
|
||||
SUBDIRS = man lib mkfs
|
||||
|
15
configure.ac
15
configure.ac
@ -29,11 +29,12 @@ AC_CHECK_FILE(.git,
|
||||
"f2fs_tools_date",
|
||||
[f2fs-tools date based on Source releases]))
|
||||
|
||||
AC_CONFIG_SRCDIR([config.h.in])
|
||||
AC_CONFIG_HEADER([config.h])
|
||||
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AM_INIT_AUTOMAKE([foreign tar-pax dist-xz])
|
||||
AC_CONFIG_SRCDIR([mkfs/f2fs_format.c])
|
||||
|
||||
AC_CHECK_HEADERS_ONCE([
|
||||
fcntl.h
|
||||
mntent.h
|
||||
@ -46,6 +47,10 @@ AC_CHECK_HEADERS_ONCE([
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_LIBTOOL
|
||||
AC_PATH_PROG([LDCONFIG], [ldconfig],
|
||||
[AC_MSG_ERROR([ldconfig not found])],
|
||||
[$PATH:/sbin])
|
||||
|
||||
# Checks for libraries.
|
||||
PKG_CHECK_MODULES([libuuid], [uuid])
|
||||
@ -67,9 +72,15 @@ AC_CHECK_FUNCS_ONCE([
|
||||
memset
|
||||
])
|
||||
|
||||
# Install directories
|
||||
AC_PREFIX_DEFAULT([/usr])
|
||||
AC_SUBST([sbindir], [/sbin])
|
||||
AC_SUBST([sysconfdir], [/etc])
|
||||
AC_SUBST([localstatedir], [/var])
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
man/Makefile
|
||||
lib/Makefile
|
||||
mkfs/Makefile
|
||||
])
|
||||
|
||||
|
@ -11,7 +11,9 @@
|
||||
#ifndef __F2FS_FS_H__
|
||||
#define __F2FS_FS_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <linux/types.h>
|
||||
#include <sys/types.h>
|
||||
#include <endian.h>
|
||||
#include <byteswap.h>
|
||||
|
||||
@ -35,6 +37,88 @@
|
||||
#define cpu_to_le64(x) bswap_64(x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Debugging interfaces
|
||||
*/
|
||||
#define ASSERT_MSG(exp, fmt, ...) \
|
||||
do { \
|
||||
if (!(exp)) { \
|
||||
printf("\nAssertion failed!\n"); \
|
||||
printf("[%s:%4d] " #exp, __func__, __LINE__); \
|
||||
printf("\n --> "fmt, ##__VA_ARGS__); \
|
||||
exit(-1); \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
#define ASSERT(exp) \
|
||||
do { \
|
||||
if (!(exp)) { \
|
||||
printf("\nAssertion failed!\n"); \
|
||||
printf("[%s:%4d] " #exp"\n", __func__, __LINE__);\
|
||||
exit(-1); \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
#define MSG(n, fmt, ...) \
|
||||
do { \
|
||||
if (config.dbg_lv >= n) { \
|
||||
printf(fmt, ##__VA_ARGS__); \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
#define DBG(n, fmt, ...) \
|
||||
do { \
|
||||
if (config.dbg_lv >= n) { \
|
||||
printf("[%s:%4d] " fmt, \
|
||||
__func__, __LINE__, ##__VA_ARGS__); \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
/* Display on console */
|
||||
#define DISP(fmt, ptr, member) \
|
||||
do { \
|
||||
printf("%-30s" fmt, #member, ((ptr)->member)); \
|
||||
} while (0);
|
||||
|
||||
#define DISP_u32(ptr, member) \
|
||||
do { \
|
||||
assert(sizeof((ptr)->member) <= 4); \
|
||||
printf("%-30s" "\t\t[0x%8x : %u]\n", \
|
||||
#member, ((ptr)->member), ((ptr)->member) ); \
|
||||
} while (0);
|
||||
|
||||
#define DISP_u64(ptr, member) \
|
||||
do { \
|
||||
assert(sizeof((ptr)->member) == 8); \
|
||||
printf("%-30s" "\t\t[0x%8llx : %llu]\n", \
|
||||
#member, ((ptr)->member), ((ptr)->member) ); \
|
||||
} while (0);
|
||||
|
||||
#define DISP_utf(ptr, member) \
|
||||
do { \
|
||||
printf(#member "\t\t\t\t[%s]\n", ((ptr)->member) ); \
|
||||
} while (0);
|
||||
|
||||
/* Display to buffer */
|
||||
#define BUF_DISP_u32(buf, data, len, ptr, member) \
|
||||
do { \
|
||||
assert(sizeof((ptr)->member) <= 4); \
|
||||
snprintf(buf, len, #member); \
|
||||
snprintf(data, len, "0x%x : %u", ((ptr)->member), ((ptr)->member)); \
|
||||
} while (0);
|
||||
|
||||
#define BUF_DISP_u64(buf, data, len, ptr, member) \
|
||||
do { \
|
||||
assert(sizeof((ptr)->member) == 8); \
|
||||
snprintf(buf, len, #member); \
|
||||
snprintf(data, len, "0x%llx : %llu", ((ptr)->member), ((ptr)->member)); \
|
||||
} while (0);
|
||||
|
||||
#define BUF_DISP_utf(buf, data, len, ptr, member) \
|
||||
do { \
|
||||
snprintf(buf, len, #member); \
|
||||
} while (0);
|
||||
|
||||
/* these are defined in kernel */
|
||||
#define PAGE_SIZE 4096
|
||||
#define PAGE_CACHE_SIZE 4096
|
||||
@ -48,10 +132,8 @@
|
||||
#define DEFAULT_SECTORS_PER_BLOCK 8
|
||||
#define DEFAULT_BLOCKS_PER_SEGMENT 512
|
||||
#define DEFAULT_SEGMENTS_PER_SECTION 1
|
||||
#define F2FS_CP_BLOCK_SIZE (DEFAULT_SECTOR_SIZE * \
|
||||
DEFAULT_SECTORS_PER_BLOCK)
|
||||
|
||||
struct f2fs_global_parameters {
|
||||
struct f2fs_configuration {
|
||||
u_int32_t sector_size;
|
||||
u_int32_t reserved_segments;
|
||||
u_int32_t overprovision;
|
||||
@ -67,6 +149,7 @@ struct f2fs_global_parameters {
|
||||
int32_t fd;
|
||||
char *device_name;
|
||||
char *extension_list;
|
||||
int dbg_lv;
|
||||
} __attribute__((packed));
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
@ -500,4 +583,23 @@ enum {
|
||||
F2FS_FT_MAX
|
||||
};
|
||||
|
||||
void ASCIIToUNICODE(u_int16_t *, u_int8_t *);
|
||||
int log_base_2(u_int32_t);
|
||||
|
||||
int f2fs_test_bit(unsigned int, const char *);
|
||||
int f2fs_set_bit(unsigned int, unsigned char *);
|
||||
int f2fs_clear_bit(unsigned int, char *);
|
||||
|
||||
u_int32_t f2fs_cal_crc32(u_int32_t, void *, int);
|
||||
|
||||
void f2fs_init_configuration(struct f2fs_configuration *);
|
||||
int f2fs_dev_is_mounted(struct f2fs_configuration *);
|
||||
int f2fs_get_device_info(struct f2fs_configuration *);
|
||||
|
||||
int dev_read(int, void *, __u64, size_t);
|
||||
int dev_write(int, void *, __u64, size_t);
|
||||
|
||||
int dev_read_block(int, void *, __u64);
|
||||
int dev_read_blocks(int, void *, __u64, __u32 );
|
||||
|
||||
#endif //__F2FS_FS_H__
|
||||
|
7
lib/Makefile.am
Normal file
7
lib/Makefile.am
Normal file
@ -0,0 +1,7 @@
|
||||
## Makefile.am
|
||||
|
||||
lib_LTLIBRARIES = libf2fs.la
|
||||
|
||||
libf2fs_la_SOURCES = libf2fs.c
|
||||
libf2fs_la_CFLAGS = -Wall
|
||||
libf2fs_la_CPPFLAGS = -I$(top_srcdir)/include
|
247
lib/libf2fs.c
Normal file
247
lib/libf2fs.c
Normal file
@ -0,0 +1,247 @@
|
||||
/**
|
||||
* libf2fs.c
|
||||
*
|
||||
* Copyright (c) 2013 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 _LARGEFILE64_SOURCE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <mntent.h>
|
||||
#include <time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/hdreg.h>
|
||||
#include <linux/fs.h>
|
||||
|
||||
#include "f2fs_fs.h"
|
||||
|
||||
struct f2fs_configuration config;
|
||||
|
||||
void ASCIIToUNICODE(u_int16_t *out_buf, u_int8_t *in_buf)
|
||||
{
|
||||
u_int8_t *pchTempPtr = in_buf;
|
||||
u_int16_t *pwTempPtr = out_buf;
|
||||
|
||||
while (*pchTempPtr != '\0') {
|
||||
*pwTempPtr = (u_int16_t)*pchTempPtr;
|
||||
pchTempPtr++;
|
||||
pwTempPtr++;
|
||||
}
|
||||
*pwTempPtr = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
int log_base_2(u_int32_t num)
|
||||
{
|
||||
int ret = 0;
|
||||
if (num <= 0 || (num & (num - 1)) != 0)
|
||||
return -1;
|
||||
|
||||
while (num >>= 1)
|
||||
ret++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* f2fs bit operations
|
||||
*/
|
||||
int f2fs_test_bit(unsigned int nr, const char *p)
|
||||
{
|
||||
int mask;
|
||||
char *addr = (char *)p;
|
||||
|
||||
addr += (nr >> 3);
|
||||
mask = 1 << (7 - (nr & 0x07));
|
||||
return (mask & *addr) != 0;
|
||||
}
|
||||
|
||||
int f2fs_set_bit(unsigned int nr, unsigned char *addr)
|
||||
{
|
||||
int mask;
|
||||
int ret;
|
||||
|
||||
addr += (nr >> 3);
|
||||
mask = 1 << (7 - (nr & 0x07));
|
||||
ret = mask & *addr;
|
||||
*addr |= mask;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int f2fs_clear_bit(unsigned int nr, char *addr)
|
||||
{
|
||||
int mask;
|
||||
int ret;
|
||||
|
||||
addr += (nr >> 3);
|
||||
mask = 1 << (7 - (nr & 0x07));
|
||||
ret = mask & *addr;
|
||||
*addr &= ~mask;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* CRC32
|
||||
*/
|
||||
#define CRCPOLY_LE 0xedb88320
|
||||
|
||||
u_int32_t f2fs_cal_crc32(u_int32_t crc, void *buf, int len)
|
||||
{
|
||||
int i;
|
||||
unsigned char *p = (unsigned char *)buf;
|
||||
while (len--) {
|
||||
crc ^= *p++;
|
||||
for (i = 0; i < 8; i++)
|
||||
crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
/*
|
||||
* device information
|
||||
*/
|
||||
void f2fs_init_configuration(struct f2fs_configuration *c)
|
||||
{
|
||||
c->sector_size = DEFAULT_SECTOR_SIZE;
|
||||
c->sectors_per_blk = DEFAULT_SECTORS_PER_BLOCK;
|
||||
c->blks_per_seg = DEFAULT_BLOCKS_PER_SEGMENT;
|
||||
|
||||
/* calculated by overprovision ratio */
|
||||
c->reserved_segments = 48;
|
||||
c->overprovision = 5;
|
||||
c->segs_per_sec = 1;
|
||||
c->secs_per_zone = 1;
|
||||
c->heap = 1;
|
||||
memset(c->vol_label, 0, sizeof(c->vol_label));
|
||||
|
||||
c->vol_label[0] = 'F';
|
||||
c->vol_label[1] = '2';
|
||||
c->vol_label[2] = 'F';
|
||||
c->vol_label[3] = 'S';
|
||||
c->vol_label[4] = '\0';
|
||||
c->device_name = NULL;
|
||||
}
|
||||
|
||||
int f2fs_dev_is_mounted(struct f2fs_configuration *c)
|
||||
{
|
||||
FILE *file = NULL;
|
||||
struct mntent *mnt = NULL;
|
||||
|
||||
file = setmntent(MOUNTED, "r");
|
||||
if (file == NULL)
|
||||
return 0;
|
||||
|
||||
while (1) {
|
||||
mnt = getmntent(file);
|
||||
if (mnt == NULL)
|
||||
break;
|
||||
if (!strcmp(c->device_name, mnt->mnt_fsname)) {
|
||||
endmntent(file);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
endmntent(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int f2fs_get_device_info(struct f2fs_configuration *c)
|
||||
{
|
||||
int32_t fd = 0;
|
||||
int32_t sector_size;
|
||||
struct stat stat_buf;
|
||||
struct hd_geometry geom;
|
||||
|
||||
fd = open(c->device_name, O_RDWR);
|
||||
if (fd < 0) {
|
||||
MSG(0, "\tError: Failed to open the device!\n");
|
||||
return -1;
|
||||
}
|
||||
c->fd = fd;
|
||||
|
||||
if (fstat(fd, &stat_buf) < 0 ) {
|
||||
MSG(0, "\tError: Failed to get the device stat!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (S_ISREG(stat_buf.st_mode)) {
|
||||
c->total_sectors = stat_buf.st_size / c->sector_size;
|
||||
} else if (S_ISBLK(stat_buf.st_mode)) {
|
||||
if (ioctl(fd, BLKSSZGET, §or_size) < 0) {
|
||||
MSG(0, "\tError: Using the default sector size\n");
|
||||
} else {
|
||||
if (c->sector_size < sector_size) {
|
||||
MSG(0, "\tError: Cannot set the sector size to:"
|
||||
" %d as the device does not support"
|
||||
"\nSetting the sector size to : %d\n",
|
||||
c->sector_size, sector_size);
|
||||
c->sector_size = sector_size;
|
||||
c->sectors_per_blk = PAGE_SIZE / sector_size;
|
||||
}
|
||||
}
|
||||
|
||||
if (ioctl(fd, BLKGETSIZE, &c->total_sectors) < 0) {
|
||||
MSG(0, "\tError: Cannot get the device size\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ioctl(fd, HDIO_GETGEO, &geom) < 0)
|
||||
c->start_sector = 0;
|
||||
else
|
||||
c->start_sector = geom.start;
|
||||
} else {
|
||||
MSG(0, "\tError: Volume type is not supported!!!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
MSG(0, "Info: sector size = %u\n", c->sector_size);
|
||||
MSG(0, "Info: total sectors = %"PRIu64" (in 512bytes)\n",
|
||||
c->total_sectors);
|
||||
if (c->total_sectors <
|
||||
(F2FS_MIN_VOLUME_SIZE / DEFAULT_SECTOR_SIZE)) {
|
||||
MSG(0, "Error: Min volume size supported is %d\n",
|
||||
F2FS_MIN_VOLUME_SIZE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* IO interfaces
|
||||
*/
|
||||
int dev_read(int fd, void *buf, __u64 offset, size_t len)
|
||||
{
|
||||
if (lseek64(fd, (off64_t)offset, SEEK_SET) < 0)
|
||||
return -1;
|
||||
if (read(fd, buf, len) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dev_write(int fd, void *buf, __u64 offset, size_t len)
|
||||
{
|
||||
if (lseek64(fd, (off64_t)offset, SEEK_SET) < 0)
|
||||
return -1;
|
||||
if (write(fd, buf, len) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dev_read_block(int fd, void *buf, __u64 blk_addr)
|
||||
{
|
||||
return dev_read(fd, buf, blk_addr * F2FS_BLKSIZE, F2FS_BLKSIZE);
|
||||
}
|
||||
|
||||
int dev_read_blocks(int fd, void *buf, __u64 addr, __u32 nr_blks)
|
||||
{
|
||||
return dev_read(fd, buf, addr * F2FS_BLKSIZE, nr_blks * F2FS_BLKSIZE);
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
.\" Copyright (C) 2007-2012 Nippon Telegraph and Telephone Corporation.
|
||||
.\" Written by Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
|
||||
.\" Copyright (c) 2012 Samsung Electronics Co., Ltd.
|
||||
.\" http://www.samsung.com/
|
||||
.\" Written by Jaegeuk Kim <jaegeuk.kim@samsung.com>
|
||||
.\"
|
||||
.TH MKFS.F2FS 8 "August 2012" "f2fs-tools version 1.0"
|
||||
.TH MKFS.F2FS 8 "January 2013" "f2fs-tools version 1.2.0"
|
||||
.SH NAME
|
||||
mkfs.f2fs \- create an F2FS file system
|
||||
.SH SYNOPSIS
|
||||
@ -26,6 +27,14 @@ mkfs.f2fs \- create an F2FS file system
|
||||
.B \-z
|
||||
.I #-of-sections-per-zone
|
||||
]
|
||||
[
|
||||
.B \-e
|
||||
.I extenstion-list
|
||||
]
|
||||
[
|
||||
.B \-d
|
||||
.I debugging-level
|
||||
]
|
||||
.I device
|
||||
.SH DESCRIPTION
|
||||
.B mkfs.f2fs
|
||||
@ -60,12 +69,23 @@ The default number is 0, which means one segment is assigned to a section.
|
||||
Specify the number of sections per zone. A zone consists of multiple sections.
|
||||
F2FS allocates segments for active logs with separated zones as much as possible.
|
||||
The default number is 1, which means a zone consists of one section.
|
||||
.TP
|
||||
.BI \-e " extension-list"
|
||||
Specify a file extension list in order f2fs to treat them as cold files.
|
||||
The data of files having those extensions will be stored to the cold log.
|
||||
The default list includes most of multimedia file extensions such as jpg, gif,
|
||||
mpeg, mkv, and so on.
|
||||
.TP
|
||||
.BI \-d " debug-level"
|
||||
Specify the level of debugging options.
|
||||
The default number is 0, which shows basic debugging messages.
|
||||
.TP
|
||||
.SH AUTHOR
|
||||
This version of
|
||||
.B mkfs.f2fs
|
||||
has been written by Jaegeuk Kim <jaegeuk.kim@samsung.com>.
|
||||
.SH AVAILABILITY
|
||||
.B mkfs.f2fs
|
||||
is available from http://sourceforge.net/projects/f2fs-tools/.
|
||||
is available from git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs-tools.git.
|
||||
.SH SEE ALSO
|
||||
.BR mkfs (8).
|
||||
|
@ -4,4 +4,4 @@ AM_CPPFLAGS = ${libuuid_CFLAGS} -I$(top_srcdir)/include
|
||||
AM_CFLAGS = -Wall
|
||||
sbin_PROGRAMS = mkfs.f2fs
|
||||
mkfs_f2fs_SOURCES = f2fs_format.c
|
||||
mkfs_f2fs_LDADD = ${libuuid_LIBS}
|
||||
mkfs_f2fs_LDADD = ${libuuid_LIBS} $(top_builddir)/lib/libf2fs.la
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user