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:
Jaegeuk Kim 2013-01-25 17:20:16 +09:00
parent 2784bd55dd
commit e69e437850
9 changed files with 704 additions and 584 deletions

47
.gitignore vendored
View File

@ -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

View File

@ -2,4 +2,4 @@
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = man mkfs
SUBDIRS = man lib mkfs

View File

@ -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
])

View File

@ -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
View 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
View 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, &sector_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);
}

View File

@ -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).

View File

@ -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