linux/fs/f2fs/recovery.c

// SPDX-License-Identifier: GPL-2.0
/*
 * fs/f2fs/recovery.c
 *
 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
 *             http://www.samsung.com/
 */
#include <asm/unaligned.h>
#include <linux/fs.h>
#include <linux/f2fs_fs.h>
#include <linux/sched/mm.h>
#include "f2fs.h"
#include "node.h"
#include "segment.h"

/*
 * Roll forward recovery scenarios.
 *
 * [Term] F: fsync_mark, D: dentry_mark
 *
 * 1. inode(x) | CP | inode(x) | dnode(F)
 * -> Update the latest inode(x).
 *
 * 2. inode(x) | CP | inode(F) | dnode(F)
 * -> No problem.
 *
 * 3. inode(x) | CP | dnode(F) | inode(x)
 * -> Recover to the latest dnode(F), and drop the last inode(x)
 *
 * 4. inode(x) | CP | dnode(F) | inode(F)
 * -> No problem.
 *
 * 5. CP | inode(x) | dnode(F)
 * -> The inode(DF) was missing. Should drop this dnode(F).
 *
 * 6. CP | inode(DF) | dnode(F)
 * -> No problem.
 *
 * 7. CP | dnode(F) | inode(DF)
 * -> If f2fs_iget fails, then goto next to find inode(DF).
 *
 * 8. CP | dnode(F) | inode(x)
 * -> If f2fs_iget fails, then goto next to find inode(DF).
 *    But it will fail due to no inode(DF).
 */

static struct kmem_cache *fsync_entry_slab;

bool f2fs_space_for_roll_forward(struct f2fs_sb_info *sbi)
{}

static struct fsync_inode_entry *get_fsync_inode(struct list_head *head,
								nid_t ino)
{}

static struct fsync_inode_entry *add_fsync_inode(struct f2fs_sb_info *sbi,
			struct list_head *head, nid_t ino, bool quota_inode)
{}

static void del_fsync_inode(struct fsync_inode_entry *entry, int drop)
{}

static int init_recovered_filename(const struct inode *dir,
				   struct f2fs_inode *raw_inode,
				   struct f2fs_filename *fname,
				   struct qstr *usr_fname)
{}

static int recover_dentry(struct inode *inode, struct page *ipage,
						struct list_head *dir_list)
{}

static int recover_quota_data(struct inode *inode, struct page *page)
{}

static void recover_inline_flags(struct inode *inode, struct f2fs_inode *ri)
{}

static int recover_inode(struct inode *inode, struct page *page)
{}

static unsigned int adjust_por_ra_blocks(struct f2fs_sb_info *sbi,
				unsigned int ra_blocks, unsigned int blkaddr,
				unsigned int next_blkaddr)
{}

/* Detect looped node chain with Floyd's cycle detection algorithm. */
static int sanity_check_node_chain(struct f2fs_sb_info *sbi, block_t blkaddr,
		block_t *blkaddr_fast, bool *is_detecting)
{}

static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head,
				bool check_only)
{}

static void destroy_fsync_dnodes(struct list_head *head, int drop)
{}

static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
			block_t blkaddr, struct dnode_of_data *dn)
{}

static int f2fs_reserve_new_block_retry(struct dnode_of_data *dn)
{}

static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
					struct page *page)
{}

static int recover_data(struct f2fs_sb_info *sbi, struct list_head *inode_list,
		struct list_head *tmp_inode_list, struct list_head *dir_list)
{}

int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only)
{}

int __init f2fs_create_recovery_cache(void)
{}

void f2fs_destroy_recovery_cache(void)
{}