2013-01-25 08:20:16 +00:00
|
|
|
/**
|
|
|
|
* libf2fs.c
|
|
|
|
*
|
|
|
|
* Copyright (c) 2013 Samsung Electronics Co., Ltd.
|
|
|
|
* http://www.samsung.com/
|
|
|
|
*
|
2014-04-07 03:10:59 +00:00
|
|
|
* Dual licensed under the GPL or LGPL version 2 licenses.
|
2013-01-25 08:20:16 +00:00
|
|
|
*/
|
|
|
|
#define _LARGEFILE64_SOURCE
|
2018-10-17 01:40:56 +00:00
|
|
|
#define _FILE_OFFSET_BITS 64
|
2013-01-25 08:20:16 +00:00
|
|
|
|
2017-11-14 18:53:32 +00:00
|
|
|
#include <f2fs_fs.h>
|
2013-01-25 08:20:16 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2013-08-02 08:03:10 +00:00
|
|
|
#include <errno.h>
|
2013-01-25 08:20:16 +00:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <fcntl.h>
|
2019-08-02 02:47:48 +00:00
|
|
|
#include <libgen.h>
|
2017-11-14 18:53:32 +00:00
|
|
|
#ifdef HAVE_MNTENT_H
|
2013-01-25 08:20:16 +00:00
|
|
|
#include <mntent.h>
|
2017-11-14 18:53:32 +00:00
|
|
|
#endif
|
2013-01-25 08:20:16 +00:00
|
|
|
#include <time.h>
|
|
|
|
#include <sys/stat.h>
|
2017-12-01 23:03:30 +00:00
|
|
|
#ifndef ANDROID_WINDOWS_HOST
|
2013-01-25 08:20:16 +00:00
|
|
|
#include <sys/mount.h>
|
|
|
|
#include <sys/ioctl.h>
|
2017-12-01 23:03:30 +00:00
|
|
|
#endif
|
2017-11-14 18:53:32 +00:00
|
|
|
#ifdef HAVE_SYS_SYSMACROS_H
|
2017-11-12 23:07:54 +00:00
|
|
|
#include <sys/sysmacros.h>
|
2017-11-14 18:53:32 +00:00
|
|
|
#endif
|
2018-05-01 20:54:25 +00:00
|
|
|
#ifdef HAVE_SYS_UTSNAME_H
|
|
|
|
#include <sys/utsname.h>
|
|
|
|
#endif
|
2016-10-12 21:42:16 +00:00
|
|
|
#ifndef WITH_ANDROID
|
2017-11-14 18:53:32 +00:00
|
|
|
#ifdef HAVE_SCSI_SG_H
|
2016-08-05 02:30:02 +00:00
|
|
|
#include <scsi/sg.h>
|
2016-10-12 21:42:16 +00:00
|
|
|
#endif
|
2017-11-14 18:53:32 +00:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_LINUX_HDREG_H
|
2013-01-25 08:20:16 +00:00
|
|
|
#include <linux/hdreg.h>
|
2017-11-14 18:53:32 +00:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_LINUX_LIMITS_H
|
libf2fs: increase robustness when called on root device
On some systems '/proc/mounts' contains the entry '/dev/root'
as alias for the root device, while that alias doesn't actually
exist as symlink in /dev.
/proc/mounts:
/dev/root / f2fs rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6 0 0
mount:
/dev/mmcblk1p1 on / type f2fs (rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6)
If the root device is mounted RO, and we try to scan it, via
'fsck.f2fs /dev/mmcblk1p1', then fsck.f2fs exits because it can't
find the entry in /proc/mounts.
Try harder to identify the root device of the system first, and
in case we are operating on it, check also for '/dev/root' in mounts.
Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
2016-09-28 17:28:03 +00:00
|
|
|
#include <linux/limits.h>
|
2017-11-14 18:53:32 +00:00
|
|
|
#endif
|
2013-01-25 08:20:16 +00:00
|
|
|
|
2016-10-12 21:42:16 +00:00
|
|
|
#ifndef WITH_ANDROID
|
2016-08-05 02:30:02 +00:00
|
|
|
/* SCSI command for standard inquiry*/
|
|
|
|
#define MODELINQUIRY 0x12,0x00,0x00,0x00,0x4A,0x00
|
2016-10-12 21:42:16 +00:00
|
|
|
#endif
|
2016-08-05 02:30:02 +00:00
|
|
|
|
2017-12-01 23:03:30 +00:00
|
|
|
#ifndef ANDROID_WINDOWS_HOST /* O_BINARY is windows-specific flag */
|
2017-06-16 18:32:58 +00:00
|
|
|
#define O_BINARY 0
|
2017-12-01 23:03:30 +00:00
|
|
|
#else
|
|
|
|
/* On Windows, wchar_t is 8 bit sized and it causes compilation errors. */
|
|
|
|
#define wchar_t int
|
2017-06-16 18:32:58 +00:00
|
|
|
#endif
|
|
|
|
|
2015-12-14 22:29:41 +00:00
|
|
|
/*
|
|
|
|
* UTF conversion codes are Copied from exfat tools.
|
|
|
|
*/
|
|
|
|
static const char *utf8_to_wchar(const char *input, wchar_t *wc,
|
|
|
|
size_t insize)
|
|
|
|
{
|
|
|
|
if ((input[0] & 0x80) == 0 && insize >= 1) {
|
|
|
|
*wc = (wchar_t) input[0];
|
|
|
|
return input + 1;
|
|
|
|
}
|
|
|
|
if ((input[0] & 0xe0) == 0xc0 && insize >= 2) {
|
|
|
|
*wc = (((wchar_t) input[0] & 0x1f) << 6) |
|
|
|
|
((wchar_t) input[1] & 0x3f);
|
|
|
|
return input + 2;
|
|
|
|
}
|
|
|
|
if ((input[0] & 0xf0) == 0xe0 && insize >= 3) {
|
|
|
|
*wc = (((wchar_t) input[0] & 0x0f) << 12) |
|
|
|
|
(((wchar_t) input[1] & 0x3f) << 6) |
|
|
|
|
((wchar_t) input[2] & 0x3f);
|
|
|
|
return input + 3;
|
|
|
|
}
|
|
|
|
if ((input[0] & 0xf8) == 0xf0 && insize >= 4) {
|
|
|
|
*wc = (((wchar_t) input[0] & 0x07) << 18) |
|
|
|
|
(((wchar_t) input[1] & 0x3f) << 12) |
|
|
|
|
(((wchar_t) input[2] & 0x3f) << 6) |
|
|
|
|
((wchar_t) input[3] & 0x3f);
|
|
|
|
return input + 4;
|
|
|
|
}
|
|
|
|
if ((input[0] & 0xfc) == 0xf8 && insize >= 5) {
|
|
|
|
*wc = (((wchar_t) input[0] & 0x03) << 24) |
|
|
|
|
(((wchar_t) input[1] & 0x3f) << 18) |
|
|
|
|
(((wchar_t) input[2] & 0x3f) << 12) |
|
|
|
|
(((wchar_t) input[3] & 0x3f) << 6) |
|
|
|
|
((wchar_t) input[4] & 0x3f);
|
|
|
|
return input + 5;
|
|
|
|
}
|
|
|
|
if ((input[0] & 0xfe) == 0xfc && insize >= 6) {
|
|
|
|
*wc = (((wchar_t) input[0] & 0x01) << 30) |
|
|
|
|
(((wchar_t) input[1] & 0x3f) << 24) |
|
|
|
|
(((wchar_t) input[2] & 0x3f) << 18) |
|
|
|
|
(((wchar_t) input[3] & 0x3f) << 12) |
|
|
|
|
(((wchar_t) input[4] & 0x3f) << 6) |
|
|
|
|
((wchar_t) input[5] & 0x3f);
|
|
|
|
return input + 6;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static u_int16_t *wchar_to_utf16(u_int16_t *output, wchar_t wc, size_t outsize)
|
|
|
|
{
|
|
|
|
if (wc <= 0xffff) {
|
|
|
|
if (outsize == 0)
|
|
|
|
return NULL;
|
|
|
|
output[0] = cpu_to_le16(wc);
|
|
|
|
return output + 1;
|
|
|
|
}
|
|
|
|
if (outsize < 2)
|
|
|
|
return NULL;
|
|
|
|
wc -= 0x10000;
|
|
|
|
output[0] = cpu_to_le16(0xd800 | ((wc >> 10) & 0x3ff));
|
|
|
|
output[1] = cpu_to_le16(0xdc00 | (wc & 0x3ff));
|
|
|
|
return output + 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
int utf8_to_utf16(u_int16_t *output, const char *input, size_t outsize,
|
|
|
|
size_t insize)
|
|
|
|
{
|
|
|
|
const char *inp = input;
|
|
|
|
u_int16_t *outp = output;
|
|
|
|
wchar_t wc;
|
|
|
|
|
2016-01-13 19:51:33 +00:00
|
|
|
while ((size_t)(inp - input) < insize && *inp) {
|
2015-12-14 22:29:41 +00:00
|
|
|
inp = utf8_to_wchar(inp, &wc, insize - (inp - input));
|
|
|
|
if (inp == NULL) {
|
|
|
|
DBG(0, "illegal UTF-8 sequence\n");
|
|
|
|
return -EILSEQ;
|
|
|
|
}
|
|
|
|
outp = wchar_to_utf16(outp, wc, outsize - (outp - output));
|
|
|
|
if (outp == NULL) {
|
|
|
|
DBG(0, "name is too long\n");
|
|
|
|
return -ENAMETOOLONG;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*outp = cpu_to_le16(0);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const u_int16_t *utf16_to_wchar(const u_int16_t *input, wchar_t *wc,
|
|
|
|
size_t insize)
|
|
|
|
{
|
|
|
|
if ((le16_to_cpu(input[0]) & 0xfc00) == 0xd800) {
|
|
|
|
if (insize < 2 || (le16_to_cpu(input[1]) & 0xfc00) != 0xdc00)
|
|
|
|
return NULL;
|
|
|
|
*wc = ((wchar_t) (le16_to_cpu(input[0]) & 0x3ff) << 10);
|
|
|
|
*wc |= (le16_to_cpu(input[1]) & 0x3ff);
|
|
|
|
*wc += 0x10000;
|
|
|
|
return input + 2;
|
|
|
|
} else {
|
|
|
|
*wc = le16_to_cpu(*input);
|
|
|
|
return input + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *wchar_to_utf8(char *output, wchar_t wc, size_t outsize)
|
|
|
|
{
|
|
|
|
if (wc <= 0x7f) {
|
|
|
|
if (outsize < 1)
|
|
|
|
return NULL;
|
|
|
|
*output++ = (char) wc;
|
|
|
|
} else if (wc <= 0x7ff) {
|
|
|
|
if (outsize < 2)
|
|
|
|
return NULL;
|
|
|
|
*output++ = 0xc0 | (wc >> 6);
|
|
|
|
*output++ = 0x80 | (wc & 0x3f);
|
|
|
|
} else if (wc <= 0xffff) {
|
|
|
|
if (outsize < 3)
|
|
|
|
return NULL;
|
|
|
|
*output++ = 0xe0 | (wc >> 12);
|
|
|
|
*output++ = 0x80 | ((wc >> 6) & 0x3f);
|
|
|
|
*output++ = 0x80 | (wc & 0x3f);
|
|
|
|
} else if (wc <= 0x1fffff) {
|
|
|
|
if (outsize < 4)
|
|
|
|
return NULL;
|
|
|
|
*output++ = 0xf0 | (wc >> 18);
|
|
|
|
*output++ = 0x80 | ((wc >> 12) & 0x3f);
|
|
|
|
*output++ = 0x80 | ((wc >> 6) & 0x3f);
|
|
|
|
*output++ = 0x80 | (wc & 0x3f);
|
|
|
|
} else if (wc <= 0x3ffffff) {
|
|
|
|
if (outsize < 5)
|
|
|
|
return NULL;
|
|
|
|
*output++ = 0xf8 | (wc >> 24);
|
|
|
|
*output++ = 0x80 | ((wc >> 18) & 0x3f);
|
|
|
|
*output++ = 0x80 | ((wc >> 12) & 0x3f);
|
|
|
|
*output++ = 0x80 | ((wc >> 6) & 0x3f);
|
|
|
|
*output++ = 0x80 | (wc & 0x3f);
|
|
|
|
} else if (wc <= 0x7fffffff) {
|
|
|
|
if (outsize < 6)
|
|
|
|
return NULL;
|
|
|
|
*output++ = 0xfc | (wc >> 30);
|
|
|
|
*output++ = 0x80 | ((wc >> 24) & 0x3f);
|
|
|
|
*output++ = 0x80 | ((wc >> 18) & 0x3f);
|
|
|
|
*output++ = 0x80 | ((wc >> 12) & 0x3f);
|
|
|
|
*output++ = 0x80 | ((wc >> 6) & 0x3f);
|
|
|
|
*output++ = 0x80 | (wc & 0x3f);
|
|
|
|
} else
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
|
|
|
int utf16_to_utf8(char *output, const u_int16_t *input, size_t outsize,
|
|
|
|
size_t insize)
|
2013-01-25 08:20:16 +00:00
|
|
|
{
|
2015-12-14 22:29:41 +00:00
|
|
|
const u_int16_t *inp = input;
|
|
|
|
char *outp = output;
|
|
|
|
wchar_t wc;
|
2013-01-25 08:20:16 +00:00
|
|
|
|
2016-01-13 19:51:33 +00:00
|
|
|
while ((size_t)(inp - input) < insize && le16_to_cpu(*inp)) {
|
2015-12-14 22:29:41 +00:00
|
|
|
inp = utf16_to_wchar(inp, &wc, insize - (inp - input));
|
|
|
|
if (inp == NULL) {
|
|
|
|
DBG(0, "illegal UTF-16 sequence\n");
|
|
|
|
return -EILSEQ;
|
|
|
|
}
|
|
|
|
outp = wchar_to_utf8(outp, wc, outsize - (outp - output));
|
|
|
|
if (outp == NULL) {
|
|
|
|
DBG(0, "name is too long\n");
|
|
|
|
return -ENAMETOOLONG;
|
|
|
|
}
|
2013-01-25 08:20:16 +00:00
|
|
|
}
|
2015-12-14 22:29:41 +00:00
|
|
|
*outp = '\0';
|
|
|
|
return 0;
|
2013-01-25 08:20:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
*/
|
f2fs-tools: add fsck.f2fs and dump.f2fs
fsck.f2fs checks file system consistency, but does not repair a broken
file system yet.
dump.f2fs shows the information of a specific inode and makes dump file
of SSA and SIT.
f2fs checks file system consistency as follows:
o When data about used area and its metadata are identical,
f2fs is considered consistent. To verify such consistency, we use
three bitmaps: nat_area_bitmap, sit_area_bitmap, and main_area_bitmap.
First, each bit in nat_area_bitmap corresponds to a nid in NAT.
Second, each bit in sit_area_bitmap corresponds to a valid block in a
segment. This bitmap is same to the total valid_map of f2fs_sit_entries
in SIT.
Last, each bit in main_area_bitmap corresponds to a block in main area
except meta area.
After a consistency check of each block, we set or clear the
corresponding bit of each bitmap.
From the root node, we start consistency check. The verified
information varies according to block type.
1. NODE
- Read information of node block from NAT
- Check if block address is allocated using node info.
- Check if the type of f2fs_summary related to nid in SSA is NODE.
- Update the corresponding bit in nat_area_bitmap.
- Update the corresponding bit in sit_area_bitmap.
- Set the corresponding bit in main_area_bitmap to 1.
- Then, read node block. According to its attribute, explore
inode/direct node/indirect node/double indirect node
recursively.
- If it is an inode block, we also check its xattr and hard link.
2. DATA
- Check if the type of f2fs_summary related to nid in SSA is DATA.
- Set the corresponding bits of sit_area_bitmap and
main_area_bitmap to visited
- If it is a dentry block, traverse each dentries that may be
regular
file or directory. At this time, it will check inode block again.
Finally, we verify whether
- every nat_area_bitmap is visited
- any unreachable hard link exists
- values of sit_area_bitmap and main_area_bitmap are identical
- total_valid_block_count/node_count/inode_count are correct
Usage:
o fsck.f2fs
# fsck.f2fs /dev/sdx
options:
-d debug level [default:0]
o dump.f2fs
# dump.f2fs -i [ino] /dev/sdx
# dump.f2fs -s 0~-1 /dev/sdx (SIT dump)
# dump.f2fs -a 0~-1 /dev/sdx (SSA dump)
options:
-d debug level [default:0]
-i inode no (hex)
-s [SIT dump segno from #1~#2 (decimal), for all 0~-1]
-a [SSA dump segno from #1~#2 (decimal), for all 0~-1]
Note: To use dump.f2fs, please run make install or ln -s fsck.f2fs
dump.f2fs
Signed-off-by: Changman Lee <cm224.lee@samsung.com>
Signed-off-by: Byoung Geun Kim <bgbg.kim@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
2013-07-04 08:11:32 +00:00
|
|
|
static const int bits_in_byte[256] = {
|
|
|
|
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
|
|
|
|
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
|
|
|
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
|
|
|
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
|
|
|
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
|
|
|
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
|
|
|
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
|
|
|
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
|
|
|
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
|
|
|
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
|
|
|
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
|
|
|
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
|
|
|
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
|
|
|
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
|
|
|
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
|
|
|
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
|
|
|
|
};
|
|
|
|
|
|
|
|
int get_bits_in_byte(unsigned char n)
|
|
|
|
{
|
|
|
|
return bits_in_byte[n];
|
|
|
|
}
|
|
|
|
|
2015-12-15 19:13:25 +00:00
|
|
|
int test_and_set_bit_le(u32 nr, u8 *addr)
|
f2fs-tools: add fsck.f2fs and dump.f2fs
fsck.f2fs checks file system consistency, but does not repair a broken
file system yet.
dump.f2fs shows the information of a specific inode and makes dump file
of SSA and SIT.
f2fs checks file system consistency as follows:
o When data about used area and its metadata are identical,
f2fs is considered consistent. To verify such consistency, we use
three bitmaps: nat_area_bitmap, sit_area_bitmap, and main_area_bitmap.
First, each bit in nat_area_bitmap corresponds to a nid in NAT.
Second, each bit in sit_area_bitmap corresponds to a valid block in a
segment. This bitmap is same to the total valid_map of f2fs_sit_entries
in SIT.
Last, each bit in main_area_bitmap corresponds to a block in main area
except meta area.
After a consistency check of each block, we set or clear the
corresponding bit of each bitmap.
From the root node, we start consistency check. The verified
information varies according to block type.
1. NODE
- Read information of node block from NAT
- Check if block address is allocated using node info.
- Check if the type of f2fs_summary related to nid in SSA is NODE.
- Update the corresponding bit in nat_area_bitmap.
- Update the corresponding bit in sit_area_bitmap.
- Set the corresponding bit in main_area_bitmap to 1.
- Then, read node block. According to its attribute, explore
inode/direct node/indirect node/double indirect node
recursively.
- If it is an inode block, we also check its xattr and hard link.
2. DATA
- Check if the type of f2fs_summary related to nid in SSA is DATA.
- Set the corresponding bits of sit_area_bitmap and
main_area_bitmap to visited
- If it is a dentry block, traverse each dentries that may be
regular
file or directory. At this time, it will check inode block again.
Finally, we verify whether
- every nat_area_bitmap is visited
- any unreachable hard link exists
- values of sit_area_bitmap and main_area_bitmap are identical
- total_valid_block_count/node_count/inode_count are correct
Usage:
o fsck.f2fs
# fsck.f2fs /dev/sdx
options:
-d debug level [default:0]
o dump.f2fs
# dump.f2fs -i [ino] /dev/sdx
# dump.f2fs -s 0~-1 /dev/sdx (SIT dump)
# dump.f2fs -a 0~-1 /dev/sdx (SSA dump)
options:
-d debug level [default:0]
-i inode no (hex)
-s [SIT dump segno from #1~#2 (decimal), for all 0~-1]
-a [SSA dump segno from #1~#2 (decimal), for all 0~-1]
Note: To use dump.f2fs, please run make install or ln -s fsck.f2fs
dump.f2fs
Signed-off-by: Changman Lee <cm224.lee@samsung.com>
Signed-off-by: Byoung Geun Kim <bgbg.kim@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
2013-07-04 08:11:32 +00:00
|
|
|
{
|
2015-12-09 19:44:31 +00:00
|
|
|
int mask, retval;
|
f2fs-tools: add fsck.f2fs and dump.f2fs
fsck.f2fs checks file system consistency, but does not repair a broken
file system yet.
dump.f2fs shows the information of a specific inode and makes dump file
of SSA and SIT.
f2fs checks file system consistency as follows:
o When data about used area and its metadata are identical,
f2fs is considered consistent. To verify such consistency, we use
three bitmaps: nat_area_bitmap, sit_area_bitmap, and main_area_bitmap.
First, each bit in nat_area_bitmap corresponds to a nid in NAT.
Second, each bit in sit_area_bitmap corresponds to a valid block in a
segment. This bitmap is same to the total valid_map of f2fs_sit_entries
in SIT.
Last, each bit in main_area_bitmap corresponds to a block in main area
except meta area.
After a consistency check of each block, we set or clear the
corresponding bit of each bitmap.
From the root node, we start consistency check. The verified
information varies according to block type.
1. NODE
- Read information of node block from NAT
- Check if block address is allocated using node info.
- Check if the type of f2fs_summary related to nid in SSA is NODE.
- Update the corresponding bit in nat_area_bitmap.
- Update the corresponding bit in sit_area_bitmap.
- Set the corresponding bit in main_area_bitmap to 1.
- Then, read node block. According to its attribute, explore
inode/direct node/indirect node/double indirect node
recursively.
- If it is an inode block, we also check its xattr and hard link.
2. DATA
- Check if the type of f2fs_summary related to nid in SSA is DATA.
- Set the corresponding bits of sit_area_bitmap and
main_area_bitmap to visited
- If it is a dentry block, traverse each dentries that may be
regular
file or directory. At this time, it will check inode block again.
Finally, we verify whether
- every nat_area_bitmap is visited
- any unreachable hard link exists
- values of sit_area_bitmap and main_area_bitmap are identical
- total_valid_block_count/node_count/inode_count are correct
Usage:
o fsck.f2fs
# fsck.f2fs /dev/sdx
options:
-d debug level [default:0]
o dump.f2fs
# dump.f2fs -i [ino] /dev/sdx
# dump.f2fs -s 0~-1 /dev/sdx (SIT dump)
# dump.f2fs -a 0~-1 /dev/sdx (SSA dump)
options:
-d debug level [default:0]
-i inode no (hex)
-s [SIT dump segno from #1~#2 (decimal), for all 0~-1]
-a [SSA dump segno from #1~#2 (decimal), for all 0~-1]
Note: To use dump.f2fs, please run make install or ln -s fsck.f2fs
dump.f2fs
Signed-off-by: Changman Lee <cm224.lee@samsung.com>
Signed-off-by: Byoung Geun Kim <bgbg.kim@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
2013-07-04 08:11:32 +00:00
|
|
|
|
2015-12-15 18:10:15 +00:00
|
|
|
addr += nr >> 3;
|
f2fs-tools: add fsck.f2fs and dump.f2fs
fsck.f2fs checks file system consistency, but does not repair a broken
file system yet.
dump.f2fs shows the information of a specific inode and makes dump file
of SSA and SIT.
f2fs checks file system consistency as follows:
o When data about used area and its metadata are identical,
f2fs is considered consistent. To verify such consistency, we use
three bitmaps: nat_area_bitmap, sit_area_bitmap, and main_area_bitmap.
First, each bit in nat_area_bitmap corresponds to a nid in NAT.
Second, each bit in sit_area_bitmap corresponds to a valid block in a
segment. This bitmap is same to the total valid_map of f2fs_sit_entries
in SIT.
Last, each bit in main_area_bitmap corresponds to a block in main area
except meta area.
After a consistency check of each block, we set or clear the
corresponding bit of each bitmap.
From the root node, we start consistency check. The verified
information varies according to block type.
1. NODE
- Read information of node block from NAT
- Check if block address is allocated using node info.
- Check if the type of f2fs_summary related to nid in SSA is NODE.
- Update the corresponding bit in nat_area_bitmap.
- Update the corresponding bit in sit_area_bitmap.
- Set the corresponding bit in main_area_bitmap to 1.
- Then, read node block. According to its attribute, explore
inode/direct node/indirect node/double indirect node
recursively.
- If it is an inode block, we also check its xattr and hard link.
2. DATA
- Check if the type of f2fs_summary related to nid in SSA is DATA.
- Set the corresponding bits of sit_area_bitmap and
main_area_bitmap to visited
- If it is a dentry block, traverse each dentries that may be
regular
file or directory. At this time, it will check inode block again.
Finally, we verify whether
- every nat_area_bitmap is visited
- any unreachable hard link exists
- values of sit_area_bitmap and main_area_bitmap are identical
- total_valid_block_count/node_count/inode_count are correct
Usage:
o fsck.f2fs
# fsck.f2fs /dev/sdx
options:
-d debug level [default:0]
o dump.f2fs
# dump.f2fs -i [ino] /dev/sdx
# dump.f2fs -s 0~-1 /dev/sdx (SIT dump)
# dump.f2fs -a 0~-1 /dev/sdx (SSA dump)
options:
-d debug level [default:0]
-i inode no (hex)
-s [SIT dump segno from #1~#2 (decimal), for all 0~-1]
-a [SSA dump segno from #1~#2 (decimal), for all 0~-1]
Note: To use dump.f2fs, please run make install or ln -s fsck.f2fs
dump.f2fs
Signed-off-by: Changman Lee <cm224.lee@samsung.com>
Signed-off-by: Byoung Geun Kim <bgbg.kim@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
2013-07-04 08:11:32 +00:00
|
|
|
mask = 1 << ((nr & 0x07));
|
2015-12-15 18:10:15 +00:00
|
|
|
retval = mask & *addr;
|
|
|
|
*addr |= mask;
|
f2fs-tools: add fsck.f2fs and dump.f2fs
fsck.f2fs checks file system consistency, but does not repair a broken
file system yet.
dump.f2fs shows the information of a specific inode and makes dump file
of SSA and SIT.
f2fs checks file system consistency as follows:
o When data about used area and its metadata are identical,
f2fs is considered consistent. To verify such consistency, we use
three bitmaps: nat_area_bitmap, sit_area_bitmap, and main_area_bitmap.
First, each bit in nat_area_bitmap corresponds to a nid in NAT.
Second, each bit in sit_area_bitmap corresponds to a valid block in a
segment. This bitmap is same to the total valid_map of f2fs_sit_entries
in SIT.
Last, each bit in main_area_bitmap corresponds to a block in main area
except meta area.
After a consistency check of each block, we set or clear the
corresponding bit of each bitmap.
From the root node, we start consistency check. The verified
information varies according to block type.
1. NODE
- Read information of node block from NAT
- Check if block address is allocated using node info.
- Check if the type of f2fs_summary related to nid in SSA is NODE.
- Update the corresponding bit in nat_area_bitmap.
- Update the corresponding bit in sit_area_bitmap.
- Set the corresponding bit in main_area_bitmap to 1.
- Then, read node block. According to its attribute, explore
inode/direct node/indirect node/double indirect node
recursively.
- If it is an inode block, we also check its xattr and hard link.
2. DATA
- Check if the type of f2fs_summary related to nid in SSA is DATA.
- Set the corresponding bits of sit_area_bitmap and
main_area_bitmap to visited
- If it is a dentry block, traverse each dentries that may be
regular
file or directory. At this time, it will check inode block again.
Finally, we verify whether
- every nat_area_bitmap is visited
- any unreachable hard link exists
- values of sit_area_bitmap and main_area_bitmap are identical
- total_valid_block_count/node_count/inode_count are correct
Usage:
o fsck.f2fs
# fsck.f2fs /dev/sdx
options:
-d debug level [default:0]
o dump.f2fs
# dump.f2fs -i [ino] /dev/sdx
# dump.f2fs -s 0~-1 /dev/sdx (SIT dump)
# dump.f2fs -a 0~-1 /dev/sdx (SSA dump)
options:
-d debug level [default:0]
-i inode no (hex)
-s [SIT dump segno from #1~#2 (decimal), for all 0~-1]
-a [SSA dump segno from #1~#2 (decimal), for all 0~-1]
Note: To use dump.f2fs, please run make install or ln -s fsck.f2fs
dump.f2fs
Signed-off-by: Changman Lee <cm224.lee@samsung.com>
Signed-off-by: Byoung Geun Kim <bgbg.kim@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
2013-07-04 08:11:32 +00:00
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2015-12-15 19:13:25 +00:00
|
|
|
int test_and_clear_bit_le(u32 nr, u8 *addr)
|
f2fs-tools: add fsck.f2fs and dump.f2fs
fsck.f2fs checks file system consistency, but does not repair a broken
file system yet.
dump.f2fs shows the information of a specific inode and makes dump file
of SSA and SIT.
f2fs checks file system consistency as follows:
o When data about used area and its metadata are identical,
f2fs is considered consistent. To verify such consistency, we use
three bitmaps: nat_area_bitmap, sit_area_bitmap, and main_area_bitmap.
First, each bit in nat_area_bitmap corresponds to a nid in NAT.
Second, each bit in sit_area_bitmap corresponds to a valid block in a
segment. This bitmap is same to the total valid_map of f2fs_sit_entries
in SIT.
Last, each bit in main_area_bitmap corresponds to a block in main area
except meta area.
After a consistency check of each block, we set or clear the
corresponding bit of each bitmap.
From the root node, we start consistency check. The verified
information varies according to block type.
1. NODE
- Read information of node block from NAT
- Check if block address is allocated using node info.
- Check if the type of f2fs_summary related to nid in SSA is NODE.
- Update the corresponding bit in nat_area_bitmap.
- Update the corresponding bit in sit_area_bitmap.
- Set the corresponding bit in main_area_bitmap to 1.
- Then, read node block. According to its attribute, explore
inode/direct node/indirect node/double indirect node
recursively.
- If it is an inode block, we also check its xattr and hard link.
2. DATA
- Check if the type of f2fs_summary related to nid in SSA is DATA.
- Set the corresponding bits of sit_area_bitmap and
main_area_bitmap to visited
- If it is a dentry block, traverse each dentries that may be
regular
file or directory. At this time, it will check inode block again.
Finally, we verify whether
- every nat_area_bitmap is visited
- any unreachable hard link exists
- values of sit_area_bitmap and main_area_bitmap are identical
- total_valid_block_count/node_count/inode_count are correct
Usage:
o fsck.f2fs
# fsck.f2fs /dev/sdx
options:
-d debug level [default:0]
o dump.f2fs
# dump.f2fs -i [ino] /dev/sdx
# dump.f2fs -s 0~-1 /dev/sdx (SIT dump)
# dump.f2fs -a 0~-1 /dev/sdx (SSA dump)
options:
-d debug level [default:0]
-i inode no (hex)
-s [SIT dump segno from #1~#2 (decimal), for all 0~-1]
-a [SSA dump segno from #1~#2 (decimal), for all 0~-1]
Note: To use dump.f2fs, please run make install or ln -s fsck.f2fs
dump.f2fs
Signed-off-by: Changman Lee <cm224.lee@samsung.com>
Signed-off-by: Byoung Geun Kim <bgbg.kim@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
2013-07-04 08:11:32 +00:00
|
|
|
{
|
2015-12-09 19:44:31 +00:00
|
|
|
int mask, retval;
|
f2fs-tools: add fsck.f2fs and dump.f2fs
fsck.f2fs checks file system consistency, but does not repair a broken
file system yet.
dump.f2fs shows the information of a specific inode and makes dump file
of SSA and SIT.
f2fs checks file system consistency as follows:
o When data about used area and its metadata are identical,
f2fs is considered consistent. To verify such consistency, we use
three bitmaps: nat_area_bitmap, sit_area_bitmap, and main_area_bitmap.
First, each bit in nat_area_bitmap corresponds to a nid in NAT.
Second, each bit in sit_area_bitmap corresponds to a valid block in a
segment. This bitmap is same to the total valid_map of f2fs_sit_entries
in SIT.
Last, each bit in main_area_bitmap corresponds to a block in main area
except meta area.
After a consistency check of each block, we set or clear the
corresponding bit of each bitmap.
From the root node, we start consistency check. The verified
information varies according to block type.
1. NODE
- Read information of node block from NAT
- Check if block address is allocated using node info.
- Check if the type of f2fs_summary related to nid in SSA is NODE.
- Update the corresponding bit in nat_area_bitmap.
- Update the corresponding bit in sit_area_bitmap.
- Set the corresponding bit in main_area_bitmap to 1.
- Then, read node block. According to its attribute, explore
inode/direct node/indirect node/double indirect node
recursively.
- If it is an inode block, we also check its xattr and hard link.
2. DATA
- Check if the type of f2fs_summary related to nid in SSA is DATA.
- Set the corresponding bits of sit_area_bitmap and
main_area_bitmap to visited
- If it is a dentry block, traverse each dentries that may be
regular
file or directory. At this time, it will check inode block again.
Finally, we verify whether
- every nat_area_bitmap is visited
- any unreachable hard link exists
- values of sit_area_bitmap and main_area_bitmap are identical
- total_valid_block_count/node_count/inode_count are correct
Usage:
o fsck.f2fs
# fsck.f2fs /dev/sdx
options:
-d debug level [default:0]
o dump.f2fs
# dump.f2fs -i [ino] /dev/sdx
# dump.f2fs -s 0~-1 /dev/sdx (SIT dump)
# dump.f2fs -a 0~-1 /dev/sdx (SSA dump)
options:
-d debug level [default:0]
-i inode no (hex)
-s [SIT dump segno from #1~#2 (decimal), for all 0~-1]
-a [SSA dump segno from #1~#2 (decimal), for all 0~-1]
Note: To use dump.f2fs, please run make install or ln -s fsck.f2fs
dump.f2fs
Signed-off-by: Changman Lee <cm224.lee@samsung.com>
Signed-off-by: Byoung Geun Kim <bgbg.kim@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
2013-07-04 08:11:32 +00:00
|
|
|
|
2015-12-15 18:10:15 +00:00
|
|
|
addr += nr >> 3;
|
f2fs-tools: add fsck.f2fs and dump.f2fs
fsck.f2fs checks file system consistency, but does not repair a broken
file system yet.
dump.f2fs shows the information of a specific inode and makes dump file
of SSA and SIT.
f2fs checks file system consistency as follows:
o When data about used area and its metadata are identical,
f2fs is considered consistent. To verify such consistency, we use
three bitmaps: nat_area_bitmap, sit_area_bitmap, and main_area_bitmap.
First, each bit in nat_area_bitmap corresponds to a nid in NAT.
Second, each bit in sit_area_bitmap corresponds to a valid block in a
segment. This bitmap is same to the total valid_map of f2fs_sit_entries
in SIT.
Last, each bit in main_area_bitmap corresponds to a block in main area
except meta area.
After a consistency check of each block, we set or clear the
corresponding bit of each bitmap.
From the root node, we start consistency check. The verified
information varies according to block type.
1. NODE
- Read information of node block from NAT
- Check if block address is allocated using node info.
- Check if the type of f2fs_summary related to nid in SSA is NODE.
- Update the corresponding bit in nat_area_bitmap.
- Update the corresponding bit in sit_area_bitmap.
- Set the corresponding bit in main_area_bitmap to 1.
- Then, read node block. According to its attribute, explore
inode/direct node/indirect node/double indirect node
recursively.
- If it is an inode block, we also check its xattr and hard link.
2. DATA
- Check if the type of f2fs_summary related to nid in SSA is DATA.
- Set the corresponding bits of sit_area_bitmap and
main_area_bitmap to visited
- If it is a dentry block, traverse each dentries that may be
regular
file or directory. At this time, it will check inode block again.
Finally, we verify whether
- every nat_area_bitmap is visited
- any unreachable hard link exists
- values of sit_area_bitmap and main_area_bitmap are identical
- total_valid_block_count/node_count/inode_count are correct
Usage:
o fsck.f2fs
# fsck.f2fs /dev/sdx
options:
-d debug level [default:0]
o dump.f2fs
# dump.f2fs -i [ino] /dev/sdx
# dump.f2fs -s 0~-1 /dev/sdx (SIT dump)
# dump.f2fs -a 0~-1 /dev/sdx (SSA dump)
options:
-d debug level [default:0]
-i inode no (hex)
-s [SIT dump segno from #1~#2 (decimal), for all 0~-1]
-a [SSA dump segno from #1~#2 (decimal), for all 0~-1]
Note: To use dump.f2fs, please run make install or ln -s fsck.f2fs
dump.f2fs
Signed-off-by: Changman Lee <cm224.lee@samsung.com>
Signed-off-by: Byoung Geun Kim <bgbg.kim@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
2013-07-04 08:11:32 +00:00
|
|
|
mask = 1 << ((nr & 0x07));
|
2015-12-15 18:10:15 +00:00
|
|
|
retval = mask & *addr;
|
|
|
|
*addr &= ~mask;
|
f2fs-tools: add fsck.f2fs and dump.f2fs
fsck.f2fs checks file system consistency, but does not repair a broken
file system yet.
dump.f2fs shows the information of a specific inode and makes dump file
of SSA and SIT.
f2fs checks file system consistency as follows:
o When data about used area and its metadata are identical,
f2fs is considered consistent. To verify such consistency, we use
three bitmaps: nat_area_bitmap, sit_area_bitmap, and main_area_bitmap.
First, each bit in nat_area_bitmap corresponds to a nid in NAT.
Second, each bit in sit_area_bitmap corresponds to a valid block in a
segment. This bitmap is same to the total valid_map of f2fs_sit_entries
in SIT.
Last, each bit in main_area_bitmap corresponds to a block in main area
except meta area.
After a consistency check of each block, we set or clear the
corresponding bit of each bitmap.
From the root node, we start consistency check. The verified
information varies according to block type.
1. NODE
- Read information of node block from NAT
- Check if block address is allocated using node info.
- Check if the type of f2fs_summary related to nid in SSA is NODE.
- Update the corresponding bit in nat_area_bitmap.
- Update the corresponding bit in sit_area_bitmap.
- Set the corresponding bit in main_area_bitmap to 1.
- Then, read node block. According to its attribute, explore
inode/direct node/indirect node/double indirect node
recursively.
- If it is an inode block, we also check its xattr and hard link.
2. DATA
- Check if the type of f2fs_summary related to nid in SSA is DATA.
- Set the corresponding bits of sit_area_bitmap and
main_area_bitmap to visited
- If it is a dentry block, traverse each dentries that may be
regular
file or directory. At this time, it will check inode block again.
Finally, we verify whether
- every nat_area_bitmap is visited
- any unreachable hard link exists
- values of sit_area_bitmap and main_area_bitmap are identical
- total_valid_block_count/node_count/inode_count are correct
Usage:
o fsck.f2fs
# fsck.f2fs /dev/sdx
options:
-d debug level [default:0]
o dump.f2fs
# dump.f2fs -i [ino] /dev/sdx
# dump.f2fs -s 0~-1 /dev/sdx (SIT dump)
# dump.f2fs -a 0~-1 /dev/sdx (SSA dump)
options:
-d debug level [default:0]
-i inode no (hex)
-s [SIT dump segno from #1~#2 (decimal), for all 0~-1]
-a [SSA dump segno from #1~#2 (decimal), for all 0~-1]
Note: To use dump.f2fs, please run make install or ln -s fsck.f2fs
dump.f2fs
Signed-off-by: Changman Lee <cm224.lee@samsung.com>
Signed-off-by: Byoung Geun Kim <bgbg.kim@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
2013-07-04 08:11:32 +00:00
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2015-12-15 19:13:25 +00:00
|
|
|
int test_bit_le(u32 nr, const u8 *addr)
|
f2fs-tools: add fsck.f2fs and dump.f2fs
fsck.f2fs checks file system consistency, but does not repair a broken
file system yet.
dump.f2fs shows the information of a specific inode and makes dump file
of SSA and SIT.
f2fs checks file system consistency as follows:
o When data about used area and its metadata are identical,
f2fs is considered consistent. To verify such consistency, we use
three bitmaps: nat_area_bitmap, sit_area_bitmap, and main_area_bitmap.
First, each bit in nat_area_bitmap corresponds to a nid in NAT.
Second, each bit in sit_area_bitmap corresponds to a valid block in a
segment. This bitmap is same to the total valid_map of f2fs_sit_entries
in SIT.
Last, each bit in main_area_bitmap corresponds to a block in main area
except meta area.
After a consistency check of each block, we set or clear the
corresponding bit of each bitmap.
From the root node, we start consistency check. The verified
information varies according to block type.
1. NODE
- Read information of node block from NAT
- Check if block address is allocated using node info.
- Check if the type of f2fs_summary related to nid in SSA is NODE.
- Update the corresponding bit in nat_area_bitmap.
- Update the corresponding bit in sit_area_bitmap.
- Set the corresponding bit in main_area_bitmap to 1.
- Then, read node block. According to its attribute, explore
inode/direct node/indirect node/double indirect node
recursively.
- If it is an inode block, we also check its xattr and hard link.
2. DATA
- Check if the type of f2fs_summary related to nid in SSA is DATA.
- Set the corresponding bits of sit_area_bitmap and
main_area_bitmap to visited
- If it is a dentry block, traverse each dentries that may be
regular
file or directory. At this time, it will check inode block again.
Finally, we verify whether
- every nat_area_bitmap is visited
- any unreachable hard link exists
- values of sit_area_bitmap and main_area_bitmap are identical
- total_valid_block_count/node_count/inode_count are correct
Usage:
o fsck.f2fs
# fsck.f2fs /dev/sdx
options:
-d debug level [default:0]
o dump.f2fs
# dump.f2fs -i [ino] /dev/sdx
# dump.f2fs -s 0~-1 /dev/sdx (SIT dump)
# dump.f2fs -a 0~-1 /dev/sdx (SSA dump)
options:
-d debug level [default:0]
-i inode no (hex)
-s [SIT dump segno from #1~#2 (decimal), for all 0~-1]
-a [SSA dump segno from #1~#2 (decimal), for all 0~-1]
Note: To use dump.f2fs, please run make install or ln -s fsck.f2fs
dump.f2fs
Signed-off-by: Changman Lee <cm224.lee@samsung.com>
Signed-off-by: Byoung Geun Kim <bgbg.kim@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
2013-07-04 08:11:32 +00:00
|
|
|
{
|
2015-12-15 18:10:15 +00:00
|
|
|
return ((1 << (nr & 7)) & (addr[nr >> 3]));
|
f2fs-tools: add fsck.f2fs and dump.f2fs
fsck.f2fs checks file system consistency, but does not repair a broken
file system yet.
dump.f2fs shows the information of a specific inode and makes dump file
of SSA and SIT.
f2fs checks file system consistency as follows:
o When data about used area and its metadata are identical,
f2fs is considered consistent. To verify such consistency, we use
three bitmaps: nat_area_bitmap, sit_area_bitmap, and main_area_bitmap.
First, each bit in nat_area_bitmap corresponds to a nid in NAT.
Second, each bit in sit_area_bitmap corresponds to a valid block in a
segment. This bitmap is same to the total valid_map of f2fs_sit_entries
in SIT.
Last, each bit in main_area_bitmap corresponds to a block in main area
except meta area.
After a consistency check of each block, we set or clear the
corresponding bit of each bitmap.
From the root node, we start consistency check. The verified
information varies according to block type.
1. NODE
- Read information of node block from NAT
- Check if block address is allocated using node info.
- Check if the type of f2fs_summary related to nid in SSA is NODE.
- Update the corresponding bit in nat_area_bitmap.
- Update the corresponding bit in sit_area_bitmap.
- Set the corresponding bit in main_area_bitmap to 1.
- Then, read node block. According to its attribute, explore
inode/direct node/indirect node/double indirect node
recursively.
- If it is an inode block, we also check its xattr and hard link.
2. DATA
- Check if the type of f2fs_summary related to nid in SSA is DATA.
- Set the corresponding bits of sit_area_bitmap and
main_area_bitmap to visited
- If it is a dentry block, traverse each dentries that may be
regular
file or directory. At this time, it will check inode block again.
Finally, we verify whether
- every nat_area_bitmap is visited
- any unreachable hard link exists
- values of sit_area_bitmap and main_area_bitmap are identical
- total_valid_block_count/node_count/inode_count are correct
Usage:
o fsck.f2fs
# fsck.f2fs /dev/sdx
options:
-d debug level [default:0]
o dump.f2fs
# dump.f2fs -i [ino] /dev/sdx
# dump.f2fs -s 0~-1 /dev/sdx (SIT dump)
# dump.f2fs -a 0~-1 /dev/sdx (SSA dump)
options:
-d debug level [default:0]
-i inode no (hex)
-s [SIT dump segno from #1~#2 (decimal), for all 0~-1]
-a [SSA dump segno from #1~#2 (decimal), for all 0~-1]
Note: To use dump.f2fs, please run make install or ln -s fsck.f2fs
dump.f2fs
Signed-off-by: Changman Lee <cm224.lee@samsung.com>
Signed-off-by: Byoung Geun Kim <bgbg.kim@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
2013-07-04 08:11:32 +00:00
|
|
|
}
|
|
|
|
|
2013-01-25 08:20:16 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
f2fs-tools: add fsck.f2fs and dump.f2fs
fsck.f2fs checks file system consistency, but does not repair a broken
file system yet.
dump.f2fs shows the information of a specific inode and makes dump file
of SSA and SIT.
f2fs checks file system consistency as follows:
o When data about used area and its metadata are identical,
f2fs is considered consistent. To verify such consistency, we use
three bitmaps: nat_area_bitmap, sit_area_bitmap, and main_area_bitmap.
First, each bit in nat_area_bitmap corresponds to a nid in NAT.
Second, each bit in sit_area_bitmap corresponds to a valid block in a
segment. This bitmap is same to the total valid_map of f2fs_sit_entries
in SIT.
Last, each bit in main_area_bitmap corresponds to a block in main area
except meta area.
After a consistency check of each block, we set or clear the
corresponding bit of each bitmap.
From the root node, we start consistency check. The verified
information varies according to block type.
1. NODE
- Read information of node block from NAT
- Check if block address is allocated using node info.
- Check if the type of f2fs_summary related to nid in SSA is NODE.
- Update the corresponding bit in nat_area_bitmap.
- Update the corresponding bit in sit_area_bitmap.
- Set the corresponding bit in main_area_bitmap to 1.
- Then, read node block. According to its attribute, explore
inode/direct node/indirect node/double indirect node
recursively.
- If it is an inode block, we also check its xattr and hard link.
2. DATA
- Check if the type of f2fs_summary related to nid in SSA is DATA.
- Set the corresponding bits of sit_area_bitmap and
main_area_bitmap to visited
- If it is a dentry block, traverse each dentries that may be
regular
file or directory. At this time, it will check inode block again.
Finally, we verify whether
- every nat_area_bitmap is visited
- any unreachable hard link exists
- values of sit_area_bitmap and main_area_bitmap are identical
- total_valid_block_count/node_count/inode_count are correct
Usage:
o fsck.f2fs
# fsck.f2fs /dev/sdx
options:
-d debug level [default:0]
o dump.f2fs
# dump.f2fs -i [ino] /dev/sdx
# dump.f2fs -s 0~-1 /dev/sdx (SIT dump)
# dump.f2fs -a 0~-1 /dev/sdx (SSA dump)
options:
-d debug level [default:0]
-i inode no (hex)
-s [SIT dump segno from #1~#2 (decimal), for all 0~-1]
-a [SSA dump segno from #1~#2 (decimal), for all 0~-1]
Note: To use dump.f2fs, please run make install or ln -s fsck.f2fs
dump.f2fs
Signed-off-by: Changman Lee <cm224.lee@samsung.com>
Signed-off-by: Byoung Geun Kim <bgbg.kim@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
2013-07-04 08:11:32 +00:00
|
|
|
int f2fs_set_bit(unsigned int nr, char *addr)
|
2013-01-25 08:20:16 +00:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2015-12-15 19:13:25 +00:00
|
|
|
static inline u64 __ffs(u8 word)
|
2013-07-30 07:39:06 +00:00
|
|
|
{
|
|
|
|
int num = 0;
|
|
|
|
|
|
|
|
if ((word & 0xf) == 0) {
|
|
|
|
num += 4;
|
|
|
|
word >>= 4;
|
|
|
|
}
|
|
|
|
if ((word & 0x3) == 0) {
|
|
|
|
num += 2;
|
|
|
|
word >>= 2;
|
|
|
|
}
|
|
|
|
if ((word & 0x1) == 0)
|
|
|
|
num += 1;
|
|
|
|
return num;
|
|
|
|
}
|
|
|
|
|
2015-12-09 19:44:31 +00:00
|
|
|
/* Copied from linux/lib/find_bit.c */
|
|
|
|
#define BITMAP_FIRST_BYTE_MASK(start) (0xff << ((start) & (BITS_PER_BYTE - 1)))
|
|
|
|
|
2015-12-15 19:13:25 +00:00
|
|
|
static u64 _find_next_bit_le(const u8 *addr, u64 nbits, u64 start, char invert)
|
2015-12-09 19:44:31 +00:00
|
|
|
{
|
2015-12-15 19:13:25 +00:00
|
|
|
u8 tmp;
|
2015-12-09 19:44:31 +00:00
|
|
|
|
|
|
|
if (!nbits || start >= nbits)
|
|
|
|
return nbits;
|
|
|
|
|
|
|
|
tmp = addr[start / BITS_PER_BYTE] ^ invert;
|
|
|
|
|
|
|
|
/* Handle 1st word. */
|
|
|
|
tmp &= BITMAP_FIRST_BYTE_MASK(start);
|
|
|
|
start = round_down(start, BITS_PER_BYTE);
|
|
|
|
|
|
|
|
while (!tmp) {
|
|
|
|
start += BITS_PER_BYTE;
|
|
|
|
if (start >= nbits)
|
|
|
|
return nbits;
|
|
|
|
|
|
|
|
tmp = addr[start / BITS_PER_BYTE] ^ invert;
|
|
|
|
}
|
|
|
|
|
|
|
|
return min(start + __ffs(tmp), nbits);
|
|
|
|
}
|
|
|
|
|
2015-12-15 19:13:25 +00:00
|
|
|
u64 find_next_bit_le(const u8 *addr, u64 size, u64 offset)
|
2015-12-09 19:44:31 +00:00
|
|
|
{
|
|
|
|
return _find_next_bit_le(addr, size, offset, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-12-15 19:13:25 +00:00
|
|
|
u64 find_next_zero_bit_le(const u8 *addr, u64 size, u64 offset)
|
2013-07-30 07:39:06 +00:00
|
|
|
{
|
2015-12-09 19:44:31 +00:00
|
|
|
return _find_next_bit_le(addr, size, offset, 0xff);
|
2013-07-30 07:39:06 +00:00
|
|
|
}
|
|
|
|
|
f2fs-tools: add fsck.f2fs and dump.f2fs
fsck.f2fs checks file system consistency, but does not repair a broken
file system yet.
dump.f2fs shows the information of a specific inode and makes dump file
of SSA and SIT.
f2fs checks file system consistency as follows:
o When data about used area and its metadata are identical,
f2fs is considered consistent. To verify such consistency, we use
three bitmaps: nat_area_bitmap, sit_area_bitmap, and main_area_bitmap.
First, each bit in nat_area_bitmap corresponds to a nid in NAT.
Second, each bit in sit_area_bitmap corresponds to a valid block in a
segment. This bitmap is same to the total valid_map of f2fs_sit_entries
in SIT.
Last, each bit in main_area_bitmap corresponds to a block in main area
except meta area.
After a consistency check of each block, we set or clear the
corresponding bit of each bitmap.
From the root node, we start consistency check. The verified
information varies according to block type.
1. NODE
- Read information of node block from NAT
- Check if block address is allocated using node info.
- Check if the type of f2fs_summary related to nid in SSA is NODE.
- Update the corresponding bit in nat_area_bitmap.
- Update the corresponding bit in sit_area_bitmap.
- Set the corresponding bit in main_area_bitmap to 1.
- Then, read node block. According to its attribute, explore
inode/direct node/indirect node/double indirect node
recursively.
- If it is an inode block, we also check its xattr and hard link.
2. DATA
- Check if the type of f2fs_summary related to nid in SSA is DATA.
- Set the corresponding bits of sit_area_bitmap and
main_area_bitmap to visited
- If it is a dentry block, traverse each dentries that may be
regular
file or directory. At this time, it will check inode block again.
Finally, we verify whether
- every nat_area_bitmap is visited
- any unreachable hard link exists
- values of sit_area_bitmap and main_area_bitmap are identical
- total_valid_block_count/node_count/inode_count are correct
Usage:
o fsck.f2fs
# fsck.f2fs /dev/sdx
options:
-d debug level [default:0]
o dump.f2fs
# dump.f2fs -i [ino] /dev/sdx
# dump.f2fs -s 0~-1 /dev/sdx (SIT dump)
# dump.f2fs -a 0~-1 /dev/sdx (SSA dump)
options:
-d debug level [default:0]
-i inode no (hex)
-s [SIT dump segno from #1~#2 (decimal), for all 0~-1]
-a [SSA dump segno from #1~#2 (decimal), for all 0~-1]
Note: To use dump.f2fs, please run make install or ln -s fsck.f2fs
dump.f2fs
Signed-off-by: Changman Lee <cm224.lee@samsung.com>
Signed-off-by: Byoung Geun Kim <bgbg.kim@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
2013-07-04 08:11:32 +00:00
|
|
|
/*
|
|
|
|
* Hashing code adapted from ext3
|
|
|
|
*/
|
|
|
|
#define DELTA 0x9E3779B9
|
|
|
|
|
|
|
|
static void TEA_transform(unsigned int buf[4], unsigned int const in[])
|
|
|
|
{
|
|
|
|
__u32 sum = 0;
|
|
|
|
__u32 b0 = buf[0], b1 = buf[1];
|
|
|
|
__u32 a = in[0], b = in[1], c = in[2], d = in[3];
|
|
|
|
int n = 16;
|
|
|
|
|
|
|
|
do {
|
|
|
|
sum += DELTA;
|
|
|
|
b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b);
|
|
|
|
b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d);
|
|
|
|
} while (--n);
|
|
|
|
|
|
|
|
buf[0] += b0;
|
|
|
|
buf[1] += b1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2014-08-26 23:28:12 +00:00
|
|
|
static void str2hashbuf(const unsigned char *msg, int len,
|
|
|
|
unsigned int *buf, int num)
|
f2fs-tools: add fsck.f2fs and dump.f2fs
fsck.f2fs checks file system consistency, but does not repair a broken
file system yet.
dump.f2fs shows the information of a specific inode and makes dump file
of SSA and SIT.
f2fs checks file system consistency as follows:
o When data about used area and its metadata are identical,
f2fs is considered consistent. To verify such consistency, we use
three bitmaps: nat_area_bitmap, sit_area_bitmap, and main_area_bitmap.
First, each bit in nat_area_bitmap corresponds to a nid in NAT.
Second, each bit in sit_area_bitmap corresponds to a valid block in a
segment. This bitmap is same to the total valid_map of f2fs_sit_entries
in SIT.
Last, each bit in main_area_bitmap corresponds to a block in main area
except meta area.
After a consistency check of each block, we set or clear the
corresponding bit of each bitmap.
From the root node, we start consistency check. The verified
information varies according to block type.
1. NODE
- Read information of node block from NAT
- Check if block address is allocated using node info.
- Check if the type of f2fs_summary related to nid in SSA is NODE.
- Update the corresponding bit in nat_area_bitmap.
- Update the corresponding bit in sit_area_bitmap.
- Set the corresponding bit in main_area_bitmap to 1.
- Then, read node block. According to its attribute, explore
inode/direct node/indirect node/double indirect node
recursively.
- If it is an inode block, we also check its xattr and hard link.
2. DATA
- Check if the type of f2fs_summary related to nid in SSA is DATA.
- Set the corresponding bits of sit_area_bitmap and
main_area_bitmap to visited
- If it is a dentry block, traverse each dentries that may be
regular
file or directory. At this time, it will check inode block again.
Finally, we verify whether
- every nat_area_bitmap is visited
- any unreachable hard link exists
- values of sit_area_bitmap and main_area_bitmap are identical
- total_valid_block_count/node_count/inode_count are correct
Usage:
o fsck.f2fs
# fsck.f2fs /dev/sdx
options:
-d debug level [default:0]
o dump.f2fs
# dump.f2fs -i [ino] /dev/sdx
# dump.f2fs -s 0~-1 /dev/sdx (SIT dump)
# dump.f2fs -a 0~-1 /dev/sdx (SSA dump)
options:
-d debug level [default:0]
-i inode no (hex)
-s [SIT dump segno from #1~#2 (decimal), for all 0~-1]
-a [SSA dump segno from #1~#2 (decimal), for all 0~-1]
Note: To use dump.f2fs, please run make install or ln -s fsck.f2fs
dump.f2fs
Signed-off-by: Changman Lee <cm224.lee@samsung.com>
Signed-off-by: Byoung Geun Kim <bgbg.kim@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
2013-07-04 08:11:32 +00:00
|
|
|
{
|
|
|
|
unsigned pad, val;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
pad = (__u32)len | ((__u32)len << 8);
|
|
|
|
pad |= pad << 16;
|
|
|
|
|
|
|
|
val = pad;
|
|
|
|
if (len > num * 4)
|
|
|
|
len = num * 4;
|
|
|
|
for (i = 0; i < len; i++) {
|
|
|
|
if ((i % 4) == 0)
|
|
|
|
val = pad;
|
|
|
|
val = msg[i] + (val << 8);
|
|
|
|
if ((i % 4) == 3) {
|
|
|
|
*buf++ = val;
|
|
|
|
val = pad;
|
|
|
|
num--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (--num >= 0)
|
|
|
|
*buf++ = val;
|
|
|
|
while (--num >= 0)
|
|
|
|
*buf++ = pad;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return hash value of directory entry
|
|
|
|
* @param name dentry name
|
|
|
|
* @param len name lenth
|
|
|
|
* @return return on success hash value, errno on failure
|
|
|
|
*/
|
2014-08-26 23:28:12 +00:00
|
|
|
f2fs_hash_t f2fs_dentry_hash(const unsigned char *name, int len)
|
f2fs-tools: add fsck.f2fs and dump.f2fs
fsck.f2fs checks file system consistency, but does not repair a broken
file system yet.
dump.f2fs shows the information of a specific inode and makes dump file
of SSA and SIT.
f2fs checks file system consistency as follows:
o When data about used area and its metadata are identical,
f2fs is considered consistent. To verify such consistency, we use
three bitmaps: nat_area_bitmap, sit_area_bitmap, and main_area_bitmap.
First, each bit in nat_area_bitmap corresponds to a nid in NAT.
Second, each bit in sit_area_bitmap corresponds to a valid block in a
segment. This bitmap is same to the total valid_map of f2fs_sit_entries
in SIT.
Last, each bit in main_area_bitmap corresponds to a block in main area
except meta area.
After a consistency check of each block, we set or clear the
corresponding bit of each bitmap.
From the root node, we start consistency check. The verified
information varies according to block type.
1. NODE
- Read information of node block from NAT
- Check if block address is allocated using node info.
- Check if the type of f2fs_summary related to nid in SSA is NODE.
- Update the corresponding bit in nat_area_bitmap.
- Update the corresponding bit in sit_area_bitmap.
- Set the corresponding bit in main_area_bitmap to 1.
- Then, read node block. According to its attribute, explore
inode/direct node/indirect node/double indirect node
recursively.
- If it is an inode block, we also check its xattr and hard link.
2. DATA
- Check if the type of f2fs_summary related to nid in SSA is DATA.
- Set the corresponding bits of sit_area_bitmap and
main_area_bitmap to visited
- If it is a dentry block, traverse each dentries that may be
regular
file or directory. At this time, it will check inode block again.
Finally, we verify whether
- every nat_area_bitmap is visited
- any unreachable hard link exists
- values of sit_area_bitmap and main_area_bitmap are identical
- total_valid_block_count/node_count/inode_count are correct
Usage:
o fsck.f2fs
# fsck.f2fs /dev/sdx
options:
-d debug level [default:0]
o dump.f2fs
# dump.f2fs -i [ino] /dev/sdx
# dump.f2fs -s 0~-1 /dev/sdx (SIT dump)
# dump.f2fs -a 0~-1 /dev/sdx (SSA dump)
options:
-d debug level [default:0]
-i inode no (hex)
-s [SIT dump segno from #1~#2 (decimal), for all 0~-1]
-a [SSA dump segno from #1~#2 (decimal), for all 0~-1]
Note: To use dump.f2fs, please run make install or ln -s fsck.f2fs
dump.f2fs
Signed-off-by: Changman Lee <cm224.lee@samsung.com>
Signed-off-by: Byoung Geun Kim <bgbg.kim@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
2013-07-04 08:11:32 +00:00
|
|
|
{
|
|
|
|
__u32 hash;
|
|
|
|
f2fs_hash_t f2fs_hash;
|
2014-08-26 23:28:12 +00:00
|
|
|
const unsigned char *p;
|
f2fs-tools: add fsck.f2fs and dump.f2fs
fsck.f2fs checks file system consistency, but does not repair a broken
file system yet.
dump.f2fs shows the information of a specific inode and makes dump file
of SSA and SIT.
f2fs checks file system consistency as follows:
o When data about used area and its metadata are identical,
f2fs is considered consistent. To verify such consistency, we use
three bitmaps: nat_area_bitmap, sit_area_bitmap, and main_area_bitmap.
First, each bit in nat_area_bitmap corresponds to a nid in NAT.
Second, each bit in sit_area_bitmap corresponds to a valid block in a
segment. This bitmap is same to the total valid_map of f2fs_sit_entries
in SIT.
Last, each bit in main_area_bitmap corresponds to a block in main area
except meta area.
After a consistency check of each block, we set or clear the
corresponding bit of each bitmap.
From the root node, we start consistency check. The verified
information varies according to block type.
1. NODE
- Read information of node block from NAT
- Check if block address is allocated using node info.
- Check if the type of f2fs_summary related to nid in SSA is NODE.
- Update the corresponding bit in nat_area_bitmap.
- Update the corresponding bit in sit_area_bitmap.
- Set the corresponding bit in main_area_bitmap to 1.
- Then, read node block. According to its attribute, explore
inode/direct node/indirect node/double indirect node
recursively.
- If it is an inode block, we also check its xattr and hard link.
2. DATA
- Check if the type of f2fs_summary related to nid in SSA is DATA.
- Set the corresponding bits of sit_area_bitmap and
main_area_bitmap to visited
- If it is a dentry block, traverse each dentries that may be
regular
file or directory. At this time, it will check inode block again.
Finally, we verify whether
- every nat_area_bitmap is visited
- any unreachable hard link exists
- values of sit_area_bitmap and main_area_bitmap are identical
- total_valid_block_count/node_count/inode_count are correct
Usage:
o fsck.f2fs
# fsck.f2fs /dev/sdx
options:
-d debug level [default:0]
o dump.f2fs
# dump.f2fs -i [ino] /dev/sdx
# dump.f2fs -s 0~-1 /dev/sdx (SIT dump)
# dump.f2fs -a 0~-1 /dev/sdx (SSA dump)
options:
-d debug level [default:0]
-i inode no (hex)
-s [SIT dump segno from #1~#2 (decimal), for all 0~-1]
-a [SSA dump segno from #1~#2 (decimal), for all 0~-1]
Note: To use dump.f2fs, please run make install or ln -s fsck.f2fs
dump.f2fs
Signed-off-by: Changman Lee <cm224.lee@samsung.com>
Signed-off-by: Byoung Geun Kim <bgbg.kim@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
2013-07-04 08:11:32 +00:00
|
|
|
__u32 in[8], buf[4];
|
|
|
|
|
|
|
|
/* special hash codes for special dentries */
|
2014-08-26 23:28:12 +00:00
|
|
|
if ((len <= 2) && (name[0] == '.') &&
|
|
|
|
(name[1] == '.' || name[1] == '\0'))
|
|
|
|
return 0;
|
f2fs-tools: add fsck.f2fs and dump.f2fs
fsck.f2fs checks file system consistency, but does not repair a broken
file system yet.
dump.f2fs shows the information of a specific inode and makes dump file
of SSA and SIT.
f2fs checks file system consistency as follows:
o When data about used area and its metadata are identical,
f2fs is considered consistent. To verify such consistency, we use
three bitmaps: nat_area_bitmap, sit_area_bitmap, and main_area_bitmap.
First, each bit in nat_area_bitmap corresponds to a nid in NAT.
Second, each bit in sit_area_bitmap corresponds to a valid block in a
segment. This bitmap is same to the total valid_map of f2fs_sit_entries
in SIT.
Last, each bit in main_area_bitmap corresponds to a block in main area
except meta area.
After a consistency check of each block, we set or clear the
corresponding bit of each bitmap.
From the root node, we start consistency check. The verified
information varies according to block type.
1. NODE
- Read information of node block from NAT
- Check if block address is allocated using node info.
- Check if the type of f2fs_summary related to nid in SSA is NODE.
- Update the corresponding bit in nat_area_bitmap.
- Update the corresponding bit in sit_area_bitmap.
- Set the corresponding bit in main_area_bitmap to 1.
- Then, read node block. According to its attribute, explore
inode/direct node/indirect node/double indirect node
recursively.
- If it is an inode block, we also check its xattr and hard link.
2. DATA
- Check if the type of f2fs_summary related to nid in SSA is DATA.
- Set the corresponding bits of sit_area_bitmap and
main_area_bitmap to visited
- If it is a dentry block, traverse each dentries that may be
regular
file or directory. At this time, it will check inode block again.
Finally, we verify whether
- every nat_area_bitmap is visited
- any unreachable hard link exists
- values of sit_area_bitmap and main_area_bitmap are identical
- total_valid_block_count/node_count/inode_count are correct
Usage:
o fsck.f2fs
# fsck.f2fs /dev/sdx
options:
-d debug level [default:0]
o dump.f2fs
# dump.f2fs -i [ino] /dev/sdx
# dump.f2fs -s 0~-1 /dev/sdx (SIT dump)
# dump.f2fs -a 0~-1 /dev/sdx (SSA dump)
options:
-d debug level [default:0]
-i inode no (hex)
-s [SIT dump segno from #1~#2 (decimal), for all 0~-1]
-a [SSA dump segno from #1~#2 (decimal), for all 0~-1]
Note: To use dump.f2fs, please run make install or ln -s fsck.f2fs
dump.f2fs
Signed-off-by: Changman Lee <cm224.lee@samsung.com>
Signed-off-by: Byoung Geun Kim <bgbg.kim@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
2013-07-04 08:11:32 +00:00
|
|
|
|
|
|
|
/* Initialize the default seed for the hash checksum functions */
|
|
|
|
buf[0] = 0x67452301;
|
|
|
|
buf[1] = 0xefcdab89;
|
|
|
|
buf[2] = 0x98badcfe;
|
|
|
|
buf[3] = 0x10325476;
|
|
|
|
|
|
|
|
p = name;
|
2014-08-26 23:28:12 +00:00
|
|
|
while (1) {
|
f2fs-tools: add fsck.f2fs and dump.f2fs
fsck.f2fs checks file system consistency, but does not repair a broken
file system yet.
dump.f2fs shows the information of a specific inode and makes dump file
of SSA and SIT.
f2fs checks file system consistency as follows:
o When data about used area and its metadata are identical,
f2fs is considered consistent. To verify such consistency, we use
three bitmaps: nat_area_bitmap, sit_area_bitmap, and main_area_bitmap.
First, each bit in nat_area_bitmap corresponds to a nid in NAT.
Second, each bit in sit_area_bitmap corresponds to a valid block in a
segment. This bitmap is same to the total valid_map of f2fs_sit_entries
in SIT.
Last, each bit in main_area_bitmap corresponds to a block in main area
except meta area.
After a consistency check of each block, we set or clear the
corresponding bit of each bitmap.
From the root node, we start consistency check. The verified
information varies according to block type.
1. NODE
- Read information of node block from NAT
- Check if block address is allocated using node info.
- Check if the type of f2fs_summary related to nid in SSA is NODE.
- Update the corresponding bit in nat_area_bitmap.
- Update the corresponding bit in sit_area_bitmap.
- Set the corresponding bit in main_area_bitmap to 1.
- Then, read node block. According to its attribute, explore
inode/direct node/indirect node/double indirect node
recursively.
- If it is an inode block, we also check its xattr and hard link.
2. DATA
- Check if the type of f2fs_summary related to nid in SSA is DATA.
- Set the corresponding bits of sit_area_bitmap and
main_area_bitmap to visited
- If it is a dentry block, traverse each dentries that may be
regular
file or directory. At this time, it will check inode block again.
Finally, we verify whether
- every nat_area_bitmap is visited
- any unreachable hard link exists
- values of sit_area_bitmap and main_area_bitmap are identical
- total_valid_block_count/node_count/inode_count are correct
Usage:
o fsck.f2fs
# fsck.f2fs /dev/sdx
options:
-d debug level [default:0]
o dump.f2fs
# dump.f2fs -i [ino] /dev/sdx
# dump.f2fs -s 0~-1 /dev/sdx (SIT dump)
# dump.f2fs -a 0~-1 /dev/sdx (SSA dump)
options:
-d debug level [default:0]
-i inode no (hex)
-s [SIT dump segno from #1~#2 (decimal), for all 0~-1]
-a [SSA dump segno from #1~#2 (decimal), for all 0~-1]
Note: To use dump.f2fs, please run make install or ln -s fsck.f2fs
dump.f2fs
Signed-off-by: Changman Lee <cm224.lee@samsung.com>
Signed-off-by: Byoung Geun Kim <bgbg.kim@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
2013-07-04 08:11:32 +00:00
|
|
|
str2hashbuf(p, len, in, 4);
|
|
|
|
TEA_transform(buf, in);
|
|
|
|
p += 16;
|
2014-08-26 23:28:12 +00:00
|
|
|
if (len <= 16)
|
|
|
|
break;
|
|
|
|
len -= 16;
|
f2fs-tools: add fsck.f2fs and dump.f2fs
fsck.f2fs checks file system consistency, but does not repair a broken
file system yet.
dump.f2fs shows the information of a specific inode and makes dump file
of SSA and SIT.
f2fs checks file system consistency as follows:
o When data about used area and its metadata are identical,
f2fs is considered consistent. To verify such consistency, we use
three bitmaps: nat_area_bitmap, sit_area_bitmap, and main_area_bitmap.
First, each bit in nat_area_bitmap corresponds to a nid in NAT.
Second, each bit in sit_area_bitmap corresponds to a valid block in a
segment. This bitmap is same to the total valid_map of f2fs_sit_entries
in SIT.
Last, each bit in main_area_bitmap corresponds to a block in main area
except meta area.
After a consistency check of each block, we set or clear the
corresponding bit of each bitmap.
From the root node, we start consistency check. The verified
information varies according to block type.
1. NODE
- Read information of node block from NAT
- Check if block address is allocated using node info.
- Check if the type of f2fs_summary related to nid in SSA is NODE.
- Update the corresponding bit in nat_area_bitmap.
- Update the corresponding bit in sit_area_bitmap.
- Set the corresponding bit in main_area_bitmap to 1.
- Then, read node block. According to its attribute, explore
inode/direct node/indirect node/double indirect node
recursively.
- If it is an inode block, we also check its xattr and hard link.
2. DATA
- Check if the type of f2fs_summary related to nid in SSA is DATA.
- Set the corresponding bits of sit_area_bitmap and
main_area_bitmap to visited
- If it is a dentry block, traverse each dentries that may be
regular
file or directory. At this time, it will check inode block again.
Finally, we verify whether
- every nat_area_bitmap is visited
- any unreachable hard link exists
- values of sit_area_bitmap and main_area_bitmap are identical
- total_valid_block_count/node_count/inode_count are correct
Usage:
o fsck.f2fs
# fsck.f2fs /dev/sdx
options:
-d debug level [default:0]
o dump.f2fs
# dump.f2fs -i [ino] /dev/sdx
# dump.f2fs -s 0~-1 /dev/sdx (SIT dump)
# dump.f2fs -a 0~-1 /dev/sdx (SSA dump)
options:
-d debug level [default:0]
-i inode no (hex)
-s [SIT dump segno from #1~#2 (decimal), for all 0~-1]
-a [SSA dump segno from #1~#2 (decimal), for all 0~-1]
Note: To use dump.f2fs, please run make install or ln -s fsck.f2fs
dump.f2fs
Signed-off-by: Changman Lee <cm224.lee@samsung.com>
Signed-off-by: Byoung Geun Kim <bgbg.kim@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
2013-07-04 08:11:32 +00:00
|
|
|
}
|
|
|
|
hash = buf[0];
|
|
|
|
|
2014-08-26 23:28:12 +00:00
|
|
|
f2fs_hash = cpu_to_le32(hash & ~F2FS_HASH_COL_BIT);
|
f2fs-tools: add fsck.f2fs and dump.f2fs
fsck.f2fs checks file system consistency, but does not repair a broken
file system yet.
dump.f2fs shows the information of a specific inode and makes dump file
of SSA and SIT.
f2fs checks file system consistency as follows:
o When data about used area and its metadata are identical,
f2fs is considered consistent. To verify such consistency, we use
three bitmaps: nat_area_bitmap, sit_area_bitmap, and main_area_bitmap.
First, each bit in nat_area_bitmap corresponds to a nid in NAT.
Second, each bit in sit_area_bitmap corresponds to a valid block in a
segment. This bitmap is same to the total valid_map of f2fs_sit_entries
in SIT.
Last, each bit in main_area_bitmap corresponds to a block in main area
except meta area.
After a consistency check of each block, we set or clear the
corresponding bit of each bitmap.
From the root node, we start consistency check. The verified
information varies according to block type.
1. NODE
- Read information of node block from NAT
- Check if block address is allocated using node info.
- Check if the type of f2fs_summary related to nid in SSA is NODE.
- Update the corresponding bit in nat_area_bitmap.
- Update the corresponding bit in sit_area_bitmap.
- Set the corresponding bit in main_area_bitmap to 1.
- Then, read node block. According to its attribute, explore
inode/direct node/indirect node/double indirect node
recursively.
- If it is an inode block, we also check its xattr and hard link.
2. DATA
- Check if the type of f2fs_summary related to nid in SSA is DATA.
- Set the corresponding bits of sit_area_bitmap and
main_area_bitmap to visited
- If it is a dentry block, traverse each dentries that may be
regular
file or directory. At this time, it will check inode block again.
Finally, we verify whether
- every nat_area_bitmap is visited
- any unreachable hard link exists
- values of sit_area_bitmap and main_area_bitmap are identical
- total_valid_block_count/node_count/inode_count are correct
Usage:
o fsck.f2fs
# fsck.f2fs /dev/sdx
options:
-d debug level [default:0]
o dump.f2fs
# dump.f2fs -i [ino] /dev/sdx
# dump.f2fs -s 0~-1 /dev/sdx (SIT dump)
# dump.f2fs -a 0~-1 /dev/sdx (SSA dump)
options:
-d debug level [default:0]
-i inode no (hex)
-s [SIT dump segno from #1~#2 (decimal), for all 0~-1]
-a [SSA dump segno from #1~#2 (decimal), for all 0~-1]
Note: To use dump.f2fs, please run make install or ln -s fsck.f2fs
dump.f2fs
Signed-off-by: Changman Lee <cm224.lee@samsung.com>
Signed-off-by: Byoung Geun Kim <bgbg.kim@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
2013-07-04 08:11:32 +00:00
|
|
|
return f2fs_hash;
|
|
|
|
}
|
|
|
|
|
2013-08-20 09:05:56 +00:00
|
|
|
unsigned int addrs_per_inode(struct f2fs_inode *i)
|
|
|
|
{
|
2017-09-04 10:58:29 +00:00
|
|
|
return CUR_ADDRS_PER_INODE(i) - get_inline_xattr_addrs(i);
|
2013-08-20 09:05:56 +00:00
|
|
|
}
|
|
|
|
|
2013-01-25 08:20:16 +00:00
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
}
|
|
|
|
|
2013-02-12 02:03:24 +00:00
|
|
|
int f2fs_crc_valid(u_int32_t blk_crc, void *buf, int len)
|
|
|
|
{
|
|
|
|
u_int32_t cal_crc = 0;
|
|
|
|
|
|
|
|
cal_crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, buf, len);
|
|
|
|
|
|
|
|
if (cal_crc != blk_crc) {
|
2014-05-12 13:03:46 +00:00
|
|
|
DBG(0,"CRC validation failed: cal_crc = %u, "
|
|
|
|
"blk_crc = %u buff_size = 0x%x\n",
|
2013-02-12 02:03:24 +00:00
|
|
|
cal_crc, blk_crc, len);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-07-26 15:01:35 +00:00
|
|
|
__u32 f2fs_inode_chksum(struct f2fs_node *node)
|
|
|
|
{
|
|
|
|
struct f2fs_inode *ri = &node->i;
|
|
|
|
__le32 ino = node->footer.ino;
|
|
|
|
__le32 gen = ri->i_generation;
|
|
|
|
__u32 chksum, chksum_seed;
|
|
|
|
__u32 dummy_cs = 0;
|
|
|
|
unsigned int offset = offsetof(struct f2fs_inode, i_inode_checksum);
|
|
|
|
unsigned int cs_size = sizeof(dummy_cs);
|
|
|
|
|
|
|
|
chksum = f2fs_cal_crc32(c.chksum_seed, (__u8 *)&ino,
|
|
|
|
sizeof(ino));
|
|
|
|
chksum_seed = f2fs_cal_crc32(chksum, (__u8 *)&gen, sizeof(gen));
|
|
|
|
|
|
|
|
chksum = f2fs_cal_crc32(chksum_seed, (__u8 *)ri, offset);
|
|
|
|
chksum = f2fs_cal_crc32(chksum, (__u8 *)&dummy_cs, cs_size);
|
|
|
|
offset += cs_size;
|
|
|
|
chksum = f2fs_cal_crc32(chksum, (__u8 *)ri + offset,
|
|
|
|
F2FS_BLKSIZE - offset);
|
|
|
|
return chksum;
|
|
|
|
}
|
|
|
|
|
2019-05-14 09:33:39 +00:00
|
|
|
__u32 f2fs_checkpoint_chksum(struct f2fs_checkpoint *cp)
|
|
|
|
{
|
|
|
|
unsigned int chksum_ofs = le32_to_cpu(cp->checksum_offset);
|
|
|
|
__u32 chksum;
|
|
|
|
|
|
|
|
chksum = f2fs_cal_crc32(F2FS_SUPER_MAGIC, cp, chksum_ofs);
|
|
|
|
if (chksum_ofs < CP_CHKSUM_OFFSET) {
|
|
|
|
chksum_ofs += sizeof(chksum);
|
|
|
|
chksum = f2fs_cal_crc32(chksum, (__u8 *)cp + chksum_ofs,
|
|
|
|
F2FS_BLKSIZE - chksum_ofs);
|
|
|
|
}
|
|
|
|
return chksum;
|
|
|
|
}
|
|
|
|
|
2019-05-24 07:28:11 +00:00
|
|
|
int write_inode(struct f2fs_node *inode, u64 blkaddr)
|
|
|
|
{
|
|
|
|
if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
|
|
|
|
inode->i.i_inode_checksum =
|
|
|
|
cpu_to_le32(f2fs_inode_chksum(inode));
|
|
|
|
return dev_write_block(inode, blkaddr);
|
|
|
|
}
|
|
|
|
|
libf2fs: increase robustness when called on root device
On some systems '/proc/mounts' contains the entry '/dev/root'
as alias for the root device, while that alias doesn't actually
exist as symlink in /dev.
/proc/mounts:
/dev/root / f2fs rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6 0 0
mount:
/dev/mmcblk1p1 on / type f2fs (rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6)
If the root device is mounted RO, and we try to scan it, via
'fsck.f2fs /dev/mmcblk1p1', then fsck.f2fs exits because it can't
find the entry in /proc/mounts.
Try harder to identify the root device of the system first, and
in case we are operating on it, check also for '/dev/root' in mounts.
Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
2016-09-28 17:28:03 +00:00
|
|
|
/*
|
|
|
|
* try to identify the root device
|
|
|
|
*/
|
2018-11-22 11:57:06 +00:00
|
|
|
char *get_rootdev()
|
libf2fs: increase robustness when called on root device
On some systems '/proc/mounts' contains the entry '/dev/root'
as alias for the root device, while that alias doesn't actually
exist as symlink in /dev.
/proc/mounts:
/dev/root / f2fs rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6 0 0
mount:
/dev/mmcblk1p1 on / type f2fs (rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6)
If the root device is mounted RO, and we try to scan it, via
'fsck.f2fs /dev/mmcblk1p1', then fsck.f2fs exits because it can't
find the entry in /proc/mounts.
Try harder to identify the root device of the system first, and
in case we are operating on it, check also for '/dev/root' in mounts.
Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
2016-09-28 17:28:03 +00:00
|
|
|
{
|
2018-05-01 02:33:10 +00:00
|
|
|
#if defined(ANDROID_WINDOWS_HOST) || defined(WITH_ANDROID)
|
2017-12-01 23:03:30 +00:00
|
|
|
return NULL;
|
|
|
|
#else
|
libf2fs: increase robustness when called on root device
On some systems '/proc/mounts' contains the entry '/dev/root'
as alias for the root device, while that alias doesn't actually
exist as symlink in /dev.
/proc/mounts:
/dev/root / f2fs rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6 0 0
mount:
/dev/mmcblk1p1 on / type f2fs (rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6)
If the root device is mounted RO, and we try to scan it, via
'fsck.f2fs /dev/mmcblk1p1', then fsck.f2fs exits because it can't
find the entry in /proc/mounts.
Try harder to identify the root device of the system first, and
in case we are operating on it, check also for '/dev/root' in mounts.
Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
2016-09-28 17:28:03 +00:00
|
|
|
struct stat sb;
|
|
|
|
int fd, ret;
|
2018-11-22 11:57:06 +00:00
|
|
|
char buf[PATH_MAX + 1];
|
libf2fs: increase robustness when called on root device
On some systems '/proc/mounts' contains the entry '/dev/root'
as alias for the root device, while that alias doesn't actually
exist as symlink in /dev.
/proc/mounts:
/dev/root / f2fs rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6 0 0
mount:
/dev/mmcblk1p1 on / type f2fs (rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6)
If the root device is mounted RO, and we try to scan it, via
'fsck.f2fs /dev/mmcblk1p1', then fsck.f2fs exits because it can't
find the entry in /proc/mounts.
Try harder to identify the root device of the system first, and
in case we are operating on it, check also for '/dev/root' in mounts.
Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
2016-09-28 17:28:03 +00:00
|
|
|
char *uevent, *ptr;
|
2018-11-22 11:57:06 +00:00
|
|
|
char *rootdev;
|
libf2fs: increase robustness when called on root device
On some systems '/proc/mounts' contains the entry '/dev/root'
as alias for the root device, while that alias doesn't actually
exist as symlink in /dev.
/proc/mounts:
/dev/root / f2fs rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6 0 0
mount:
/dev/mmcblk1p1 on / type f2fs (rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6)
If the root device is mounted RO, and we try to scan it, via
'fsck.f2fs /dev/mmcblk1p1', then fsck.f2fs exits because it can't
find the entry in /proc/mounts.
Try harder to identify the root device of the system first, and
in case we are operating on it, check also for '/dev/root' in mounts.
Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
2016-09-28 17:28:03 +00:00
|
|
|
|
|
|
|
if (stat("/", &sb) == -1)
|
|
|
|
return NULL;
|
|
|
|
|
2018-11-22 11:57:06 +00:00
|
|
|
snprintf(buf, PATH_MAX, "/sys/dev/block/%u:%u/uevent",
|
libf2fs: increase robustness when called on root device
On some systems '/proc/mounts' contains the entry '/dev/root'
as alias for the root device, while that alias doesn't actually
exist as symlink in /dev.
/proc/mounts:
/dev/root / f2fs rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6 0 0
mount:
/dev/mmcblk1p1 on / type f2fs (rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6)
If the root device is mounted RO, and we try to scan it, via
'fsck.f2fs /dev/mmcblk1p1', then fsck.f2fs exits because it can't
find the entry in /proc/mounts.
Try harder to identify the root device of the system first, and
in case we are operating on it, check also for '/dev/root' in mounts.
Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
2016-09-28 17:28:03 +00:00
|
|
|
major(sb.st_dev), minor(sb.st_dev));
|
|
|
|
|
|
|
|
fd = open(buf, O_RDONLY);
|
|
|
|
|
|
|
|
if (fd < 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
ret = lseek(fd, (off_t)0, SEEK_END);
|
|
|
|
(void)lseek(fd, (off_t)0, SEEK_SET);
|
|
|
|
|
|
|
|
if (ret == -1) {
|
|
|
|
close(fd);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
uevent = malloc(ret + 1);
|
2018-11-26 13:36:00 +00:00
|
|
|
ASSERT(uevent);
|
|
|
|
|
libf2fs: increase robustness when called on root device
On some systems '/proc/mounts' contains the entry '/dev/root'
as alias for the root device, while that alias doesn't actually
exist as symlink in /dev.
/proc/mounts:
/dev/root / f2fs rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6 0 0
mount:
/dev/mmcblk1p1 on / type f2fs (rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6)
If the root device is mounted RO, and we try to scan it, via
'fsck.f2fs /dev/mmcblk1p1', then fsck.f2fs exits because it can't
find the entry in /proc/mounts.
Try harder to identify the root device of the system first, and
in case we are operating on it, check also for '/dev/root' in mounts.
Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
2016-09-28 17:28:03 +00:00
|
|
|
uevent[ret] = '\0';
|
|
|
|
|
|
|
|
ret = read(fd, uevent, ret);
|
|
|
|
close(fd);
|
|
|
|
|
|
|
|
ptr = strstr(uevent, "DEVNAME");
|
|
|
|
if (!ptr)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
ret = sscanf(ptr, "DEVNAME=%s\n", buf);
|
2018-11-22 11:57:06 +00:00
|
|
|
if (strlen(buf) == 0)
|
|
|
|
return NULL;
|
libf2fs: increase robustness when called on root device
On some systems '/proc/mounts' contains the entry '/dev/root'
as alias for the root device, while that alias doesn't actually
exist as symlink in /dev.
/proc/mounts:
/dev/root / f2fs rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6 0 0
mount:
/dev/mmcblk1p1 on / type f2fs (rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6)
If the root device is mounted RO, and we try to scan it, via
'fsck.f2fs /dev/mmcblk1p1', then fsck.f2fs exits because it can't
find the entry in /proc/mounts.
Try harder to identify the root device of the system first, and
in case we are operating on it, check also for '/dev/root' in mounts.
Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
2016-09-28 17:28:03 +00:00
|
|
|
|
2018-11-22 11:57:06 +00:00
|
|
|
ret = strlen(buf) + 5;
|
|
|
|
rootdev = malloc(ret + 1);
|
|
|
|
if (!rootdev)
|
|
|
|
return NULL;
|
|
|
|
rootdev[ret] = '\0';
|
|
|
|
|
2019-03-18 06:39:55 +00:00
|
|
|
snprintf(rootdev, ret + 1, "/dev/%s", buf);
|
libf2fs: increase robustness when called on root device
On some systems '/proc/mounts' contains the entry '/dev/root'
as alias for the root device, while that alias doesn't actually
exist as symlink in /dev.
/proc/mounts:
/dev/root / f2fs rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6 0 0
mount:
/dev/mmcblk1p1 on / type f2fs (rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6)
If the root device is mounted RO, and we try to scan it, via
'fsck.f2fs /dev/mmcblk1p1', then fsck.f2fs exits because it can't
find the entry in /proc/mounts.
Try harder to identify the root device of the system first, and
in case we are operating on it, check also for '/dev/root' in mounts.
Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
2016-09-28 17:28:03 +00:00
|
|
|
return rootdev;
|
2017-12-01 23:03:30 +00:00
|
|
|
#endif
|
libf2fs: increase robustness when called on root device
On some systems '/proc/mounts' contains the entry '/dev/root'
as alias for the root device, while that alias doesn't actually
exist as symlink in /dev.
/proc/mounts:
/dev/root / f2fs rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6 0 0
mount:
/dev/mmcblk1p1 on / type f2fs (rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6)
If the root device is mounted RO, and we try to scan it, via
'fsck.f2fs /dev/mmcblk1p1', then fsck.f2fs exits because it can't
find the entry in /proc/mounts.
Try harder to identify the root device of the system first, and
in case we are operating on it, check also for '/dev/root' in mounts.
Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
2016-09-28 17:28:03 +00:00
|
|
|
}
|
|
|
|
|
2013-01-25 08:20:16 +00:00
|
|
|
/*
|
|
|
|
* device information
|
|
|
|
*/
|
2016-09-17 01:41:00 +00:00
|
|
|
void f2fs_init_configuration(void)
|
2013-01-25 08:20:16 +00:00
|
|
|
{
|
2016-11-02 00:23:40 +00:00
|
|
|
int i;
|
|
|
|
|
2018-02-06 04:31:22 +00:00
|
|
|
memset(&c, 0, sizeof(struct f2fs_configuration));
|
2016-11-02 00:23:40 +00:00
|
|
|
c.ndevs = 1;
|
2016-09-17 01:41:00 +00:00
|
|
|
c.sectors_per_blk = DEFAULT_SECTORS_PER_BLOCK;
|
|
|
|
c.blks_per_seg = DEFAULT_BLOCKS_PER_SEGMENT;
|
2016-11-02 00:23:40 +00:00
|
|
|
c.wanted_total_sectors = -1;
|
2018-03-27 05:25:46 +00:00
|
|
|
c.wanted_sector_size = -1;
|
2018-02-06 04:31:22 +00:00
|
|
|
#ifndef WITH_ANDROID
|
2017-11-08 19:20:47 +00:00
|
|
|
c.preserve_limits = 1;
|
|
|
|
#endif
|
2016-11-02 00:23:40 +00:00
|
|
|
|
|
|
|
for (i = 0; i < MAX_DEVICES; i++) {
|
2016-11-10 22:15:13 +00:00
|
|
|
c.devices[i].fd = -1;
|
2016-11-02 00:23:40 +00:00
|
|
|
c.devices[i].sector_size = DEFAULT_SECTOR_SIZE;
|
|
|
|
c.devices[i].end_blkaddr = -1;
|
|
|
|
c.devices[i].zoned_model = F2FS_ZONED_NONE;
|
|
|
|
}
|
2013-01-25 08:20:16 +00:00
|
|
|
|
|
|
|
/* calculated by overprovision ratio */
|
2016-09-17 01:41:00 +00:00
|
|
|
c.segs_per_sec = 1;
|
|
|
|
c.secs_per_zone = 1;
|
|
|
|
c.segs_per_zone = 1;
|
|
|
|
c.vol_label = "";
|
|
|
|
c.trim = 1;
|
2016-11-02 00:23:40 +00:00
|
|
|
c.kd = -1;
|
2017-11-30 01:21:12 +00:00
|
|
|
c.fixed_time = -1;
|
2018-07-27 08:12:32 +00:00
|
|
|
|
|
|
|
/* default root owner */
|
|
|
|
c.root_uid = getuid();
|
|
|
|
c.root_gid = getgid();
|
2013-01-25 08:20:16 +00:00
|
|
|
}
|
|
|
|
|
2019-04-23 02:42:20 +00:00
|
|
|
int f2fs_dev_is_writable(void)
|
|
|
|
{
|
|
|
|
return !c.ro || c.force;
|
|
|
|
}
|
|
|
|
|
2017-11-14 18:53:32 +00:00
|
|
|
#ifdef HAVE_SETMNTENT
|
2016-01-13 19:51:33 +00:00
|
|
|
static int is_mounted(const char *mpt, const char *device)
|
2013-01-25 08:20:16 +00:00
|
|
|
{
|
|
|
|
FILE *file = NULL;
|
|
|
|
struct mntent *mnt = NULL;
|
|
|
|
|
2013-08-02 08:03:10 +00:00
|
|
|
file = setmntent(mpt, "r");
|
|
|
|
if (file == NULL)
|
|
|
|
return 0;
|
2013-01-25 08:20:16 +00:00
|
|
|
|
2013-08-02 08:03:10 +00:00
|
|
|
while ((mnt = getmntent(file)) != NULL) {
|
2015-11-22 02:53:07 +00:00
|
|
|
if (!strcmp(device, mnt->mnt_fsname)) {
|
2016-01-13 19:51:33 +00:00
|
|
|
#ifdef MNTOPT_RO
|
2015-11-22 02:53:07 +00:00
|
|
|
if (hasmntopt(mnt, MNTOPT_RO))
|
2016-09-17 01:41:00 +00:00
|
|
|
c.ro = 1;
|
2016-01-13 19:51:33 +00:00
|
|
|
#endif
|
2013-01-25 08:20:16 +00:00
|
|
|
break;
|
2015-11-22 02:53:07 +00:00
|
|
|
}
|
2013-08-02 08:03:10 +00:00
|
|
|
}
|
|
|
|
endmntent(file);
|
|
|
|
return mnt ? 1 : 0;
|
|
|
|
}
|
2017-11-14 18:53:32 +00:00
|
|
|
#endif
|
2013-08-02 08:03:10 +00:00
|
|
|
|
2016-11-02 00:23:40 +00:00
|
|
|
int f2fs_dev_is_umounted(char *path)
|
2013-08-02 08:03:10 +00:00
|
|
|
{
|
2017-12-01 23:03:30 +00:00
|
|
|
#ifdef ANDROID_WINDOWS_HOST
|
|
|
|
return 0;
|
|
|
|
#else
|
2018-04-02 07:59:24 +00:00
|
|
|
struct stat *st_buf;
|
libf2fs: increase robustness when called on root device
On some systems '/proc/mounts' contains the entry '/dev/root'
as alias for the root device, while that alias doesn't actually
exist as symlink in /dev.
/proc/mounts:
/dev/root / f2fs rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6 0 0
mount:
/dev/mmcblk1p1 on / type f2fs (rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6)
If the root device is mounted RO, and we try to scan it, via
'fsck.f2fs /dev/mmcblk1p1', then fsck.f2fs exits because it can't
find the entry in /proc/mounts.
Try harder to identify the root device of the system first, and
in case we are operating on it, check also for '/dev/root' in mounts.
Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
2016-09-28 17:28:03 +00:00
|
|
|
int is_rootdev = 0;
|
2013-08-02 08:03:10 +00:00
|
|
|
int ret = 0;
|
2018-11-22 11:57:06 +00:00
|
|
|
char *rootdev_name = get_rootdev();
|
2013-08-02 08:03:10 +00:00
|
|
|
|
2018-11-22 11:57:06 +00:00
|
|
|
if (rootdev_name) {
|
|
|
|
if (!strcmp(path, rootdev_name))
|
|
|
|
is_rootdev = 1;
|
|
|
|
free(rootdev_name);
|
|
|
|
}
|
libf2fs: increase robustness when called on root device
On some systems '/proc/mounts' contains the entry '/dev/root'
as alias for the root device, while that alias doesn't actually
exist as symlink in /dev.
/proc/mounts:
/dev/root / f2fs rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6 0 0
mount:
/dev/mmcblk1p1 on / type f2fs (rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6)
If the root device is mounted RO, and we try to scan it, via
'fsck.f2fs /dev/mmcblk1p1', then fsck.f2fs exits because it can't
find the entry in /proc/mounts.
Try harder to identify the root device of the system first, and
in case we are operating on it, check also for '/dev/root' in mounts.
Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
2016-09-28 17:28:03 +00:00
|
|
|
|
2016-02-19 01:37:14 +00:00
|
|
|
/*
|
|
|
|
* try with /proc/mounts fist to detect RDONLY.
|
|
|
|
* f2fs_stop_checkpoint makes RO in /proc/mounts while RW in /etc/mtab.
|
|
|
|
*/
|
2017-11-14 18:53:32 +00:00
|
|
|
#ifdef __linux__
|
2016-11-02 00:23:40 +00:00
|
|
|
ret = is_mounted("/proc/mounts", path);
|
2013-08-02 08:03:10 +00:00
|
|
|
if (ret) {
|
2015-11-22 02:53:07 +00:00
|
|
|
MSG(0, "Info: Mounted device!\n");
|
2013-08-02 08:03:10 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2017-11-14 18:53:32 +00:00
|
|
|
#endif
|
|
|
|
#if defined(MOUNTED) || defined(_PATH_MOUNTED)
|
|
|
|
#ifndef MOUNTED
|
|
|
|
#define MOUNTED _PATH_MOUNTED
|
|
|
|
#endif
|
2016-11-02 00:23:40 +00:00
|
|
|
ret = is_mounted(MOUNTED, path);
|
2013-08-02 08:03:10 +00:00
|
|
|
if (ret) {
|
2015-11-22 02:53:07 +00:00
|
|
|
MSG(0, "Info: Mounted device!\n");
|
2013-08-02 08:03:10 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2017-11-14 18:53:32 +00:00
|
|
|
#endif
|
libf2fs: increase robustness when called on root device
On some systems '/proc/mounts' contains the entry '/dev/root'
as alias for the root device, while that alias doesn't actually
exist as symlink in /dev.
/proc/mounts:
/dev/root / f2fs rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6 0 0
mount:
/dev/mmcblk1p1 on / type f2fs (rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6)
If the root device is mounted RO, and we try to scan it, via
'fsck.f2fs /dev/mmcblk1p1', then fsck.f2fs exits because it can't
find the entry in /proc/mounts.
Try harder to identify the root device of the system first, and
in case we are operating on it, check also for '/dev/root' in mounts.
Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
2016-09-28 17:28:03 +00:00
|
|
|
/*
|
|
|
|
* If we are supposed to operate on the root device, then
|
|
|
|
* also check the mounts for '/dev/root', which sometimes
|
|
|
|
* functions as an alias for the root device.
|
|
|
|
*/
|
|
|
|
if (is_rootdev) {
|
2017-11-14 18:53:32 +00:00
|
|
|
#ifdef __linux__
|
libf2fs: increase robustness when called on root device
On some systems '/proc/mounts' contains the entry '/dev/root'
as alias for the root device, while that alias doesn't actually
exist as symlink in /dev.
/proc/mounts:
/dev/root / f2fs rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6 0 0
mount:
/dev/mmcblk1p1 on / type f2fs (rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6)
If the root device is mounted RO, and we try to scan it, via
'fsck.f2fs /dev/mmcblk1p1', then fsck.f2fs exits because it can't
find the entry in /proc/mounts.
Try harder to identify the root device of the system first, and
in case we are operating on it, check also for '/dev/root' in mounts.
Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
2016-09-28 17:28:03 +00:00
|
|
|
ret = is_mounted("/proc/mounts", "/dev/root");
|
|
|
|
if (ret) {
|
|
|
|
MSG(0, "Info: Mounted device!\n");
|
|
|
|
return -1;
|
|
|
|
}
|
2017-11-14 18:53:32 +00:00
|
|
|
#endif
|
libf2fs: increase robustness when called on root device
On some systems '/proc/mounts' contains the entry '/dev/root'
as alias for the root device, while that alias doesn't actually
exist as symlink in /dev.
/proc/mounts:
/dev/root / f2fs rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6 0 0
mount:
/dev/mmcblk1p1 on / type f2fs (rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6)
If the root device is mounted RO, and we try to scan it, via
'fsck.f2fs /dev/mmcblk1p1', then fsck.f2fs exits because it can't
find the entry in /proc/mounts.
Try harder to identify the root device of the system first, and
in case we are operating on it, check also for '/dev/root' in mounts.
Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
2016-09-28 17:28:03 +00:00
|
|
|
}
|
|
|
|
|
2013-08-02 08:03:10 +00:00
|
|
|
/*
|
|
|
|
* If f2fs is umounted with -l, the process can still use
|
|
|
|
* the file system. In this case, we should not format.
|
|
|
|
*/
|
2018-04-02 07:59:24 +00:00
|
|
|
st_buf = malloc(sizeof(struct stat));
|
2018-11-26 13:36:00 +00:00
|
|
|
ASSERT(st_buf);
|
|
|
|
|
2018-04-02 07:59:24 +00:00
|
|
|
if (stat(path, st_buf) == 0 && S_ISBLK(st_buf->st_mode)) {
|
2016-11-02 00:23:40 +00:00
|
|
|
int fd = open(path, O_RDONLY | O_EXCL);
|
2013-08-02 08:03:10 +00:00
|
|
|
|
|
|
|
if (fd >= 0) {
|
|
|
|
close(fd);
|
|
|
|
} else if (errno == EBUSY) {
|
|
|
|
MSG(0, "\tError: In use by the system!\n");
|
2018-04-02 07:59:24 +00:00
|
|
|
free(st_buf);
|
2013-01-25 08:20:16 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2018-04-02 07:59:24 +00:00
|
|
|
free(st_buf);
|
2017-11-14 18:53:32 +00:00
|
|
|
return ret;
|
2017-12-01 23:03:30 +00:00
|
|
|
#endif
|
2013-01-25 08:20:16 +00:00
|
|
|
}
|
|
|
|
|
2016-11-02 00:23:40 +00:00
|
|
|
int f2fs_devs_are_umounted(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < c.ndevs; i++)
|
|
|
|
if (f2fs_dev_is_umounted((char *)c.devices[i].path))
|
|
|
|
return -1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-11-07 03:34:40 +00:00
|
|
|
void get_kernel_version(__u8 *version)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < VERSION_LEN; i++) {
|
|
|
|
if (version[i] == '\n')
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
memset(version + i, 0, VERSION_LEN + 1 - i);
|
|
|
|
}
|
|
|
|
|
2018-05-01 20:54:25 +00:00
|
|
|
void get_kernel_uname_version(__u8 *version)
|
|
|
|
{
|
|
|
|
#ifdef HAVE_SYS_UTSNAME_H
|
|
|
|
struct utsname buf;
|
|
|
|
|
|
|
|
memset(version, 0, VERSION_LEN);
|
|
|
|
if (uname(&buf))
|
|
|
|
return;
|
|
|
|
|
2018-10-19 22:42:40 +00:00
|
|
|
#if !defined(WITH_KERNEL_VERSION)
|
2018-05-01 20:54:25 +00:00
|
|
|
snprintf((char *)version,
|
|
|
|
VERSION_LEN, "%s %s", buf.release, buf.version);
|
2018-10-19 22:42:40 +00:00
|
|
|
#else
|
|
|
|
snprintf((char *)version,
|
|
|
|
VERSION_LEN, "%s", buf.release);
|
|
|
|
#endif
|
2018-05-01 20:54:25 +00:00
|
|
|
#else
|
|
|
|
memset(version, 0, VERSION_LEN);
|
|
|
|
#endif
|
|
|
|
}
|
2017-11-14 18:53:32 +00:00
|
|
|
|
|
|
|
#if defined(__linux__) && defined(_IO) && !defined(BLKGETSIZE)
|
|
|
|
#define BLKGETSIZE _IO(0x12,96)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(__linux__) && defined(_IOR) && !defined(BLKGETSIZE64)
|
|
|
|
#define BLKGETSIZE64 _IOR(0x12,114, size_t)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(__linux__) && defined(_IO) && !defined(BLKSSZGET)
|
|
|
|
#define BLKSSZGET _IO(0x12,104)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(__APPLE__)
|
|
|
|
#include <sys/disk.h>
|
|
|
|
#define BLKGETSIZE DKIOCGETBLOCKCOUNT
|
|
|
|
#define BLKSSZGET DKIOCGETBLOCKCOUNT
|
|
|
|
#endif /* APPLE_DARWIN */
|
|
|
|
|
2017-12-01 23:03:30 +00:00
|
|
|
#ifndef ANDROID_WINDOWS_HOST
|
2019-04-16 18:46:31 +00:00
|
|
|
static int open_check_fs(char *path, int flag)
|
|
|
|
{
|
2019-07-29 15:39:36 +00:00
|
|
|
if (c.func != DUMP && (c.func != FSCK || c.fix_on || c.auto_fix))
|
2019-04-16 18:46:31 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
/* allow to open ro */
|
|
|
|
return open(path, O_RDONLY | flag);
|
|
|
|
}
|
|
|
|
|
2016-11-02 00:23:40 +00:00
|
|
|
int get_device_info(int i)
|
2013-01-25 08:20:16 +00:00
|
|
|
{
|
|
|
|
int32_t fd = 0;
|
2014-05-14 00:02:55 +00:00
|
|
|
uint32_t sector_size;
|
2014-09-26 05:05:12 +00:00
|
|
|
#ifndef BLKGETSIZE64
|
|
|
|
uint32_t total_sectors;
|
|
|
|
#endif
|
2018-04-02 07:59:24 +00:00
|
|
|
struct stat *stat_buf;
|
2017-11-14 18:53:32 +00:00
|
|
|
#ifdef HDIO_GETGIO
|
2013-01-25 08:20:16 +00:00
|
|
|
struct hd_geometry geom;
|
2017-11-14 18:53:32 +00:00
|
|
|
#endif
|
|
|
|
#if !defined(WITH_ANDROID) && defined(__linux__)
|
2016-08-05 02:30:02 +00:00
|
|
|
sg_io_hdr_t io_hdr;
|
2016-10-13 21:39:16 +00:00
|
|
|
unsigned char reply_buffer[96] = {0};
|
2016-08-05 02:30:02 +00:00
|
|
|
unsigned char model_inq[6] = {MODELINQUIRY};
|
2016-10-12 21:42:16 +00:00
|
|
|
#endif
|
2016-11-02 00:23:40 +00:00
|
|
|
struct device_info *dev = c.devices + i;
|
2013-01-25 08:20:16 +00:00
|
|
|
|
2018-11-16 05:54:02 +00:00
|
|
|
if (c.sparse_mode) {
|
|
|
|
fd = open(dev->path, O_RDWR | O_CREAT | O_BINARY, 0644);
|
|
|
|
if (fd < 0) {
|
2019-04-16 18:46:31 +00:00
|
|
|
fd = open_check_fs(dev->path, O_BINARY);
|
|
|
|
if (fd < 0) {
|
|
|
|
MSG(0, "\tError: Failed to open a sparse file!\n");
|
|
|
|
return -1;
|
|
|
|
}
|
2018-11-16 05:54:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-04 09:50:45 +00:00
|
|
|
stat_buf = malloc(sizeof(struct stat));
|
|
|
|
ASSERT(stat_buf);
|
|
|
|
|
2018-11-16 05:54:02 +00:00
|
|
|
if (!c.sparse_mode) {
|
|
|
|
if (stat(dev->path, stat_buf) < 0 ) {
|
|
|
|
MSG(0, "\tError: Failed to get the device stat!\n");
|
|
|
|
free(stat_buf);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2019-07-29 15:39:36 +00:00
|
|
|
if (S_ISBLK(stat_buf->st_mode) && !c.force && c.func != DUMP) {
|
2018-07-04 09:50:45 +00:00
|
|
|
fd = open(dev->path, O_RDWR | O_EXCL);
|
2019-04-16 18:46:31 +00:00
|
|
|
if (fd < 0)
|
|
|
|
fd = open_check_fs(dev->path, O_EXCL);
|
|
|
|
} else {
|
2018-07-04 09:50:45 +00:00
|
|
|
fd = open(dev->path, O_RDWR);
|
2019-04-16 18:46:31 +00:00
|
|
|
if (fd < 0)
|
|
|
|
fd = open_check_fs(dev->path, 0);
|
|
|
|
}
|
2017-06-16 18:32:58 +00:00
|
|
|
}
|
2013-01-25 08:20:16 +00:00
|
|
|
if (fd < 0) {
|
|
|
|
MSG(0, "\tError: Failed to open the device!\n");
|
2018-07-04 09:50:45 +00:00
|
|
|
free(stat_buf);
|
2013-01-25 08:20:16 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2016-11-02 00:23:40 +00:00
|
|
|
dev->fd = fd;
|
|
|
|
|
2017-11-30 04:34:37 +00:00
|
|
|
if (c.sparse_mode) {
|
2018-07-04 09:50:45 +00:00
|
|
|
if (f2fs_init_sparse_file()) {
|
|
|
|
free(stat_buf);
|
2017-11-30 04:34:37 +00:00
|
|
|
return -1;
|
2018-07-04 09:50:45 +00:00
|
|
|
}
|
2017-11-30 04:34:37 +00:00
|
|
|
}
|
|
|
|
|
2016-11-02 00:23:40 +00:00
|
|
|
if (c.kd == -1) {
|
2018-05-01 20:54:25 +00:00
|
|
|
#if !defined(WITH_ANDROID) && defined(__linux__)
|
2016-11-02 00:23:40 +00:00
|
|
|
c.kd = open("/proc/version", O_RDONLY);
|
2018-05-01 20:54:25 +00:00
|
|
|
#endif
|
2016-11-02 00:23:40 +00:00
|
|
|
if (c.kd < 0) {
|
|
|
|
MSG(0, "\tInfo: No support kernel version!\n");
|
|
|
|
c.kd = -2;
|
|
|
|
}
|
|
|
|
}
|
2014-11-07 03:34:40 +00:00
|
|
|
|
2017-06-16 18:32:58 +00:00
|
|
|
if (c.sparse_mode) {
|
|
|
|
dev->total_sectors = c.device_size / dev->sector_size;
|
2018-04-02 07:59:24 +00:00
|
|
|
} else if (S_ISREG(stat_buf->st_mode)) {
|
|
|
|
dev->total_sectors = stat_buf->st_size / dev->sector_size;
|
|
|
|
} else if (S_ISBLK(stat_buf->st_mode)) {
|
2017-11-14 18:53:32 +00:00
|
|
|
#ifdef BLKSSZGET
|
2016-11-02 00:23:40 +00:00
|
|
|
if (ioctl(fd, BLKSSZGET, §or_size) < 0)
|
2013-01-25 08:20:16 +00:00
|
|
|
MSG(0, "\tError: Using the default sector size\n");
|
2016-11-02 00:23:40 +00:00
|
|
|
else if (dev->sector_size < sector_size)
|
|
|
|
dev->sector_size = sector_size;
|
2017-11-14 18:53:32 +00:00
|
|
|
#endif
|
2014-09-26 05:05:12 +00:00
|
|
|
#ifdef BLKGETSIZE64
|
2016-11-02 00:23:40 +00:00
|
|
|
if (ioctl(fd, BLKGETSIZE64, &dev->total_sectors) < 0) {
|
2013-01-25 08:20:16 +00:00
|
|
|
MSG(0, "\tError: Cannot get the device size\n");
|
2018-04-02 07:59:24 +00:00
|
|
|
free(stat_buf);
|
2013-01-25 08:20:16 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2014-09-26 05:05:12 +00:00
|
|
|
#else
|
|
|
|
if (ioctl(fd, BLKGETSIZE, &total_sectors) < 0) {
|
|
|
|
MSG(0, "\tError: Cannot get the device size\n");
|
2018-04-02 07:59:24 +00:00
|
|
|
free(stat_buf);
|
2014-09-26 05:05:12 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2016-11-02 00:23:40 +00:00
|
|
|
dev->total_sectors = total_sectors;
|
2014-09-26 05:05:12 +00:00
|
|
|
#endif
|
2016-11-02 00:23:40 +00:00
|
|
|
dev->total_sectors /= dev->sector_size;
|
|
|
|
|
2017-03-18 08:00:10 +00:00
|
|
|
if (i == 0) {
|
2017-11-14 18:53:32 +00:00
|
|
|
#ifdef HDIO_GETGIO
|
2017-03-18 08:00:10 +00:00
|
|
|
if (ioctl(fd, HDIO_GETGEO, &geom) < 0)
|
|
|
|
c.start_sector = 0;
|
|
|
|
else
|
|
|
|
c.start_sector = geom.start;
|
2017-11-14 18:53:32 +00:00
|
|
|
#else
|
|
|
|
c.start_sector = 0;
|
|
|
|
#endif
|
2017-03-18 08:00:10 +00:00
|
|
|
}
|
2016-08-05 02:30:02 +00:00
|
|
|
|
2017-11-14 18:53:32 +00:00
|
|
|
#if !defined(WITH_ANDROID) && defined(__linux__)
|
2016-08-05 02:30:02 +00:00
|
|
|
/* Send INQUIRY command */
|
|
|
|
memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
|
|
|
|
io_hdr.interface_id = 'S';
|
|
|
|
io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
|
|
|
|
io_hdr.dxfer_len = sizeof(reply_buffer);
|
|
|
|
io_hdr.dxferp = reply_buffer;
|
|
|
|
io_hdr.cmd_len = sizeof(model_inq);
|
|
|
|
io_hdr.cmdp = model_inq;
|
|
|
|
io_hdr.timeout = 1000;
|
|
|
|
|
2016-11-02 00:23:40 +00:00
|
|
|
if (!ioctl(fd, SG_IO, &io_hdr)) {
|
2018-05-24 21:17:01 +00:00
|
|
|
MSG(0, "Info: [%s] Disk Model: %.16s\n",
|
|
|
|
dev->path, reply_buffer+16);
|
2016-08-05 02:30:02 +00:00
|
|
|
}
|
2016-10-12 21:42:16 +00:00
|
|
|
#endif
|
2013-01-25 08:20:16 +00:00
|
|
|
} else {
|
|
|
|
MSG(0, "\tError: Volume type is not supported!!!\n");
|
2018-04-02 07:59:24 +00:00
|
|
|
free(stat_buf);
|
2013-01-25 08:20:16 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2016-11-02 00:23:40 +00:00
|
|
|
|
|
|
|
if (!c.sector_size) {
|
|
|
|
c.sector_size = dev->sector_size;
|
|
|
|
c.sectors_per_blk = F2FS_BLKSIZE / c.sector_size;
|
|
|
|
} else if (c.sector_size != c.devices[i].sector_size) {
|
|
|
|
MSG(0, "\tError: Different sector sizes!!!\n");
|
2018-04-02 07:59:24 +00:00
|
|
|
free(stat_buf);
|
2016-02-23 13:43:41 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2016-05-27 21:20:43 +00:00
|
|
|
|
2017-11-14 18:53:32 +00:00
|
|
|
#if !defined(WITH_ANDROID) && defined(__linux__)
|
2019-04-02 02:44:53 +00:00
|
|
|
if (S_ISBLK(stat_buf->st_mode)) {
|
|
|
|
if (f2fs_get_zoned_model(i) < 0) {
|
|
|
|
free(stat_buf);
|
|
|
|
return -1;
|
2019-04-02 02:44:54 +00:00
|
|
|
}
|
2019-04-02 02:44:53 +00:00
|
|
|
}
|
2016-11-02 00:23:40 +00:00
|
|
|
|
|
|
|
if (dev->zoned_model != F2FS_ZONED_NONE) {
|
|
|
|
|
2019-04-02 02:44:55 +00:00
|
|
|
/* Get the number of blocks per zones */
|
2016-11-02 00:23:40 +00:00
|
|
|
if (f2fs_get_zone_blocks(i)) {
|
2016-10-28 07:57:00 +00:00
|
|
|
MSG(0, "\tError: Failed to get number of blocks per zone\n");
|
2018-04-02 07:59:24 +00:00
|
|
|
free(stat_buf);
|
2016-10-28 07:57:00 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2019-04-02 02:44:55 +00:00
|
|
|
/*
|
|
|
|
* Check zone configuration: for the first disk of a
|
|
|
|
* multi-device volume, conventional zones are needed.
|
|
|
|
*/
|
2016-11-02 00:23:40 +00:00
|
|
|
if (f2fs_check_zones(i)) {
|
2016-10-28 07:57:00 +00:00
|
|
|
MSG(0, "\tError: Failed to check zone configuration\n");
|
2018-04-02 07:59:24 +00:00
|
|
|
free(stat_buf);
|
2016-05-27 21:20:43 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2016-10-28 07:57:00 +00:00
|
|
|
MSG(0, "Info: Host-%s zoned block device:\n",
|
2016-11-02 00:23:40 +00:00
|
|
|
(dev->zoned_model == F2FS_ZONED_HA) ?
|
2016-10-28 07:57:00 +00:00
|
|
|
"aware" : "managed");
|
|
|
|
MSG(0, " %u zones, %u randomly writeable zones\n",
|
2016-11-02 00:23:40 +00:00
|
|
|
dev->nr_zones, dev->nr_rnd_zones);
|
2016-10-28 07:57:00 +00:00
|
|
|
MSG(0, " %lu blocks per zone\n",
|
2016-11-02 00:23:40 +00:00
|
|
|
dev->zone_blocks);
|
|
|
|
}
|
|
|
|
#endif
|
2018-03-27 05:25:46 +00:00
|
|
|
/* adjust wanted_total_sectors */
|
|
|
|
if (c.wanted_total_sectors != -1) {
|
|
|
|
MSG(0, "Info: wanted sectors = %"PRIu64" (in %"PRIu64" bytes)\n",
|
|
|
|
c.wanted_total_sectors, c.wanted_sector_size);
|
|
|
|
if (c.wanted_sector_size == -1) {
|
|
|
|
c.wanted_sector_size = dev->sector_size;
|
|
|
|
} else if (dev->sector_size != c.wanted_sector_size) {
|
|
|
|
c.wanted_total_sectors *= c.wanted_sector_size;
|
|
|
|
c.wanted_total_sectors /= dev->sector_size;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-02 00:23:40 +00:00
|
|
|
c.total_sectors += dev->total_sectors;
|
2018-04-02 07:59:24 +00:00
|
|
|
free(stat_buf);
|
2016-11-02 00:23:40 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-12-01 23:03:30 +00:00
|
|
|
#else
|
|
|
|
|
|
|
|
#include "windows.h"
|
|
|
|
#include "winioctl.h"
|
|
|
|
|
|
|
|
#if (_WIN32_WINNT >= 0x0500)
|
|
|
|
#define HAVE_GET_FILE_SIZE_EX 1
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static int win_get_device_size(const char *file, uint64_t *device_size)
|
|
|
|
{
|
|
|
|
HANDLE dev;
|
|
|
|
PARTITION_INFORMATION pi;
|
|
|
|
DISK_GEOMETRY gi;
|
|
|
|
DWORD retbytes;
|
|
|
|
#ifdef HAVE_GET_FILE_SIZE_EX
|
|
|
|
LARGE_INTEGER filesize;
|
|
|
|
#else
|
|
|
|
DWORD filesize;
|
|
|
|
#endif /* HAVE_GET_FILE_SIZE_EX */
|
|
|
|
|
|
|
|
dev = CreateFile(file, GENERIC_READ,
|
|
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE ,
|
|
|
|
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
|
|
|
|
|
if (dev == INVALID_HANDLE_VALUE)
|
|
|
|
return EBADF;
|
|
|
|
if (DeviceIoControl(dev, IOCTL_DISK_GET_PARTITION_INFO,
|
|
|
|
&pi, sizeof(PARTITION_INFORMATION),
|
|
|
|
&pi, sizeof(PARTITION_INFORMATION),
|
|
|
|
&retbytes, NULL)) {
|
|
|
|
|
|
|
|
*device_size = pi.PartitionLength.QuadPart;
|
|
|
|
|
|
|
|
} else if (DeviceIoControl(dev, IOCTL_DISK_GET_DRIVE_GEOMETRY,
|
|
|
|
&gi, sizeof(DISK_GEOMETRY),
|
|
|
|
&gi, sizeof(DISK_GEOMETRY),
|
|
|
|
&retbytes, NULL)) {
|
|
|
|
|
|
|
|
*device_size = gi.BytesPerSector *
|
|
|
|
gi.SectorsPerTrack *
|
|
|
|
gi.TracksPerCylinder *
|
|
|
|
gi.Cylinders.QuadPart;
|
|
|
|
|
|
|
|
#ifdef HAVE_GET_FILE_SIZE_EX
|
|
|
|
} else if (GetFileSizeEx(dev, &filesize)) {
|
|
|
|
*device_size = filesize.QuadPart;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
} else {
|
|
|
|
filesize = GetFileSize(dev, NULL);
|
|
|
|
if (INVALID_FILE_SIZE != filesize)
|
|
|
|
return -1;
|
|
|
|
*device_size = filesize;
|
|
|
|
}
|
|
|
|
#endif /* HAVE_GET_FILE_SIZE_EX */
|
|
|
|
|
|
|
|
CloseHandle(dev);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int get_device_info(int i)
|
|
|
|
{
|
|
|
|
struct device_info *dev = c.devices + i;
|
|
|
|
uint64_t device_size = 0;
|
|
|
|
int32_t fd = 0;
|
|
|
|
|
|
|
|
/* Block device target is not supported on Windows. */
|
|
|
|
if (!c.sparse_mode) {
|
|
|
|
if (win_get_device_size(dev->path, &device_size)) {
|
|
|
|
MSG(0, "\tError: Failed to get device size!\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
device_size = c.device_size;
|
|
|
|
}
|
|
|
|
if (c.sparse_mode) {
|
|
|
|
fd = open((char *)dev->path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
|
|
|
|
} else {
|
|
|
|
fd = open((char *)dev->path, O_RDWR | O_BINARY);
|
|
|
|
}
|
|
|
|
if (fd < 0) {
|
|
|
|
MSG(0, "\tError: Failed to open the device!\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
dev->fd = fd;
|
|
|
|
dev->total_sectors = device_size / dev->sector_size;
|
|
|
|
c.start_sector = 0;
|
|
|
|
c.sector_size = dev->sector_size;
|
|
|
|
c.sectors_per_blk = F2FS_BLKSIZE / c.sector_size;
|
|
|
|
c.total_sectors += dev->total_sectors;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-11-02 00:23:40 +00:00
|
|
|
int f2fs_get_device_info(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < c.ndevs; i++)
|
|
|
|
if (get_device_info(i))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (c.wanted_total_sectors < c.total_sectors) {
|
|
|
|
MSG(0, "Info: total device sectors = %"PRIu64" (in %u bytes)\n",
|
|
|
|
c.total_sectors, c.sector_size);
|
|
|
|
c.total_sectors = c.wanted_total_sectors;
|
|
|
|
c.devices[0].total_sectors = c.total_sectors;
|
|
|
|
}
|
|
|
|
if (c.total_sectors * c.sector_size >
|
|
|
|
(u_int64_t)F2FS_MAX_SEGMENT * 2 * 1024 * 1024) {
|
|
|
|
MSG(0, "\tError: F2FS can support 16TB at most!!!\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2019-04-02 02:44:55 +00:00
|
|
|
/*
|
|
|
|
* Check device types and determine the final volume operation mode:
|
|
|
|
* - If all devices are regular block devices, default operation.
|
|
|
|
* - If at least one HM device is found, operate in HM mode (BLKZONED
|
|
|
|
* feature will be enabled by mkfs).
|
|
|
|
* - If an HA device is found, let mkfs decide based on the -m option
|
|
|
|
* setting by the user.
|
|
|
|
*/
|
|
|
|
c.zoned_model = F2FS_ZONED_NONE;
|
2016-11-02 00:23:40 +00:00
|
|
|
for (i = 0; i < c.ndevs; i++) {
|
2019-04-02 02:44:55 +00:00
|
|
|
switch (c.devices[i].zoned_model) {
|
|
|
|
case F2FS_ZONED_NONE:
|
|
|
|
continue;
|
|
|
|
case F2FS_ZONED_HM:
|
|
|
|
c.zoned_model = F2FS_ZONED_HM;
|
|
|
|
break;
|
|
|
|
case F2FS_ZONED_HA:
|
|
|
|
if (c.zoned_model != F2FS_ZONED_HM)
|
|
|
|
c.zoned_model = F2FS_ZONED_HA;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (c.zoned_model != F2FS_ZONED_NONE) {
|
|
|
|
|
|
|
|
/*
|
|
|
|
* For zoned model, the zones sizes of all zoned devices must
|
|
|
|
* be equal.
|
|
|
|
*/
|
|
|
|
for (i = 0; i < c.ndevs; i++) {
|
|
|
|
if (c.devices[i].zoned_model == F2FS_ZONED_NONE)
|
|
|
|
continue;
|
2016-11-02 00:23:40 +00:00
|
|
|
if (c.zone_blocks &&
|
|
|
|
c.zone_blocks != c.devices[i].zone_blocks) {
|
2019-04-02 02:44:55 +00:00
|
|
|
MSG(0, "\tError: zones of different size are "
|
|
|
|
"not supported\n");
|
2016-11-02 00:23:40 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
c.zone_blocks = c.devices[i].zone_blocks;
|
|
|
|
}
|
|
|
|
|
2019-04-02 02:44:55 +00:00
|
|
|
/*
|
|
|
|
* Align sections to the device zone size and align F2FS zones
|
|
|
|
* to the device zones. For F2FS_ZONED_HA model without the
|
|
|
|
* BLKZONED feature set at format time, this is only an
|
|
|
|
* optimization as sequential writes will not be enforced.
|
|
|
|
*/
|
2016-10-28 07:57:00 +00:00
|
|
|
c.segs_per_sec = c.zone_blocks / DEFAULT_BLOCKS_PER_SEGMENT;
|
|
|
|
c.secs_per_zone = 1;
|
2016-11-02 00:23:40 +00:00
|
|
|
} else {
|
2019-08-02 02:47:48 +00:00
|
|
|
if(c.zoned_mode != 0) {
|
|
|
|
MSG(0, "\n Error: %s may not be a zoned block device \n",
|
|
|
|
c.devices[0].path);
|
|
|
|
return -1;
|
|
|
|
}
|
2016-05-27 21:20:43 +00:00
|
|
|
}
|
2016-11-02 00:23:40 +00:00
|
|
|
|
2016-09-17 01:41:00 +00:00
|
|
|
c.segs_per_zone = c.segs_per_sec * c.secs_per_zone;
|
2016-05-27 21:20:43 +00:00
|
|
|
|
2016-09-17 01:41:00 +00:00
|
|
|
MSG(0, "Info: Segments per section = %d\n", c.segs_per_sec);
|
|
|
|
MSG(0, "Info: Sections per zone = %d\n", c.secs_per_zone);
|
|
|
|
MSG(0, "Info: sector size = %u\n", c.sector_size);
|
2015-03-20 23:41:59 +00:00
|
|
|
MSG(0, "Info: total sectors = %"PRIu64" (%"PRIu64" MB)\n",
|
2016-09-17 01:41:00 +00:00
|
|
|
c.total_sectors, (c.total_sectors *
|
|
|
|
(c.sector_size >> 9)) >> 11);
|
2013-01-25 08:20:16 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2019-04-28 09:17:37 +00:00
|
|
|
|
|
|
|
unsigned int calc_extra_isize(void)
|
|
|
|
{
|
|
|
|
unsigned int size = offsetof(struct f2fs_inode, i_projid);
|
|
|
|
|
|
|
|
if (c.feature & cpu_to_le32(F2FS_FEATURE_FLEXIBLE_INLINE_XATTR))
|
|
|
|
size = offsetof(struct f2fs_inode, i_projid);
|
|
|
|
if (c.feature & cpu_to_le32(F2FS_FEATURE_PRJQUOTA))
|
|
|
|
size = offsetof(struct f2fs_inode, i_inode_checksum);
|
|
|
|
if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
|
|
|
|
size = offsetof(struct f2fs_inode, i_crtime);
|
|
|
|
if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CRTIME))
|
|
|
|
size = offsetof(struct f2fs_inode, i_extra_end);
|
|
|
|
|
|
|
|
return size - F2FS_EXTRA_ISIZE_OFFSET;
|
|
|
|
}
|