@@ -942,6 +942,22 @@ check_next:
if (f2fs_test_main_bitmap(sbi, ni->blk_addr) == 0) {
f2fs_set_main_bitmap(sbi, ni->blk_addr,
CURSEG_WARM_NODE);
+
+ if (i_links == 0 && (ftype == F2FS_FT_CHRDEV ||
+ ftype == F2FS_FT_BLKDEV ||
+ ftype == F2FS_FT_FIFO ||
+ ftype == F2FS_FT_SOCK ||
+ ftype == F2FS_FT_SYMLINK ||
+ ftype == F2FS_FT_REG_FILE)) {
+ ASSERT_MSG("ino: 0x%x ftype: %d has i_links: %u",
+ nid, ftype, i_links);
+ if (c.fix_on) {
+ node_blk->i.i_links = cpu_to_le32(1);
+ need_fix = 1;
+ FIX_MSG("ino: 0x%x ftype: %d fix i_links: %u -> 1",
+ nid, ftype, i_links);
+ }
+ }
if (i_links > 1 && ftype != F2FS_FT_ORPHAN &&
!is_qf_ino(F2FS_RAW_SUPER(sbi), nid)) {
/* First time. Create new hard link node */
fsck.f2fs missed to check and repair zeroed i_links for char, block, fifo, sock, symlink and regular inode, fix it. Tested w/ below testcase: dev=/dev/vda mp=/mnt/f2fs for ((i=0;i<14;i++)) do echo "testcase #"$i mkfs.f2fs -f $dev >/dev/null 2>&1 if [ $? != 0 ]; then exit fi mount $dev $mp cd $mp if [ $i == 0 ]; then touch file nlink=0 elif [ $i == 1 ]; then mkdir dir nlink=1 elif [ $i == 2 ]; then mknod charactor c 9 0 nlink=0 elif [ $i == 3 ]; then mknod blockdev b 8 0 nlink=0 elif [ $i == 4 ]; then mkfifo pipe nlink=0 elif [ $i == 5 ]; then socket -s $mp/sock & sleep 2 fuser -k $mp/sock nlink=0 elif [ $i == 6 ]; then ln -s file symlink nlink=0 elif [ $i == 7 ]; then # orphan inode touch atomic f2fs_io write 1 0 1 zero atomic_commit ./atomic 2000 & rm atomic sync f2fs_io shutdown 2 ./ nlink=1 sleep 2 elif [ $i == 8 ]; then # hardlink on file touch file ln file hardlink nlink=0 elif [ $i == 9 ]; then # hardlink on charactor mknod charactor c 9 0 ln charactor hardlink nlink=0 elif [ $i == 10 ]; then # hardlink on blockdev mknod blockdev b 8 0 ln blockdev hardlink nlink=0 elif [ $i == 11 ]; then # hardlink on pipe mkfifo pipe ln pipe hardlink nlink=0 elif [ $i == 12 ]; then # hardlink on socket socket -s $mp/sock & sleep 2 fuser -k $mp/sock ln sock hardlink nlink=0 elif [ $i == 13 ]; then # hardlink on symlink ln -s file symlink ln symlink hardlink nlink=0 fi cd ~/ umount $mp inject.f2fs --node --mb i_links --nid 4 --val $nlink $dev if [ $? != 0 ]; then exit fi fsck.f2fs -f $dev if [ $? != 1 ]; then exit fi fsck.f2fs $dev if [ $? != 0 ]; then exit fi mount $dev $mp stat $mp/* umount $mp done Signed-off-by: Chao Yu <chao@kernel.org> --- v2: - update testcase to cover hardlink of non-dir inode - fix zeroed i_links only fsck/fsck.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)