LCOV - code coverage report
Current view: top level - fsck.ubifs - fsck.ubifs.h (source / functions) Hit Total Coverage
Test: a simple test Lines: 2 2 100.0 %
Date: 2024-06-05 20:10:43 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  * Copyright (C) 2024, Huawei Technologies Co, Ltd.
       4             :  *
       5             :  * Authors: Zhihao Cheng <chengzhihao1@huawei.com>
       6             :  */
       7             : 
       8             : #ifndef __FSCK_UBIFS_H__
       9             : #define __FSCK_UBIFS_H__
      10             : 
      11             : /* Exit codes used by fsck-type programs */
      12             : #define FSCK_OK                 0       /* No errors */
      13             : #define FSCK_NONDESTRUCT        1       /* File system errors corrected */
      14             : #define FSCK_REBOOT             2       /* System should be rebooted */
      15             : #define FSCK_UNCORRECTED        4       /* File system errors left uncorrected */
      16             : #define FSCK_ERROR              8       /* Operational error */
      17             : #define FSCK_USAGE              16      /* Usage or syntax error */
      18             : #define FSCK_CANCELED           32      /* Aborted with a signal or ^C */
      19             : #define FSCK_LIBRARY            128     /* Shared library error */
      20             : 
      21             : /*
      22             :  * There are 6 working modes for fsck:
      23             :  * NORMAL_MODE: Check the filesystem, ask user whether or not to fix the
      24             :  *              problem as long as inconsistent data is found during checking.
      25             :  * SAFE_MODE:   Check and safely repair the filesystem, if there are any
      26             :  *              data dropping operations needed by fixing, fsck will fail.
      27             :  * DANGER_MODE0:Check and repair the filesystem according to TNC, data dropping
      28             :  *              will be reported. If TNC/master/log is corrupted, fsck will fail.
      29             :  * DANGER_MODE1:Check and forcedly repair the filesystem according to TNC,
      30             :  *              turns to @REBUILD_MODE mode automatically if TNC/master/log is
      31             :  *              corrupted.
      32             :  * REBUILD_MODE:Scan entire UBI volume to find all nodes, and rebuild the
      33             :  *              filesystem, always make fsck success.
      34             :  * CHECK_MODE:  Make no changes to the filesystem, only check the filesystem.
      35             :  */
      36             : enum { NORMAL_MODE = 0, SAFE_MODE, DANGER_MODE0,
      37             :        DANGER_MODE1, REBUILD_MODE, CHECK_MODE };
      38             : 
      39             : /* Types of inconsistent problems */
      40             : enum { SB_CORRUPTED = 0, MST_CORRUPTED, LOG_CORRUPTED, BUD_CORRUPTED,
      41             :        TNC_CORRUPTED, TNC_DATA_CORRUPTED, ORPHAN_CORRUPTED, INVALID_INO_NODE,
      42             :        INVALID_DENT_NODE, INVALID_DATA_NODE, SCAN_CORRUPTED, FILE_HAS_NO_INODE,
      43             :        FILE_HAS_0_NLINK_INODE, FILE_HAS_INCONSIST_TYPE, FILE_HAS_TOO_MANY_DENT,
      44             :        FILE_SHOULDNT_HAVE_DATA, FILE_HAS_NO_DENT, XATTR_HAS_NO_HOST,
      45             :        XATTR_HAS_WRONG_HOST, FILE_HAS_NO_ENCRYPT, FILE_IS_DISCONNECTED,
      46             :        FILE_ROOT_HAS_DENT, DENTRY_IS_UNREACHABLE, FILE_IS_INCONSISTENT,
      47             :        EMPTY_TNC, LPT_CORRUPTED, NNODE_INCORRECT, PNODE_INCORRECT,
      48             :        LP_INCORRECT, SPACE_STAT_INCORRECT, LTAB_INCORRECT, INCORRECT_IDX_SZ,
      49             :        ROOT_DIR_NOT_FOUND, DISCONNECTED_FILE_CANNOT_BE_RECOVERED };
      50             : 
      51             : enum { HAS_DATA_CORRUPTED = 1, HAS_TNC_CORRUPTED = 2 };
      52             : 
      53             : typedef int (*calculate_lp_callback)(struct ubifs_info *c,
      54             :                                      int index, int *free, int *dirty,
      55             :                                      int *is_idx);
      56             : 
      57             : struct scanned_file;
      58             : 
      59             : /**
      60             :  * scanned_node - common header node.
      61             :  * @exist: whether the node is found by scanning
      62             :  * @lnum: LEB number of the scanned node
      63             :  * @offs: scanned node's offset within @lnum
      64             :  * @len: length of scanned node
      65             :  * @sqnum: sequence number
      66             :  */
      67             : struct scanned_node {
      68             :         bool exist;
      69             :         int lnum;
      70             :         int offs;
      71             :         int len;
      72             :         unsigned long long sqnum;
      73             : };
      74             : 
      75             : /**
      76             :  * scanned_ino_node - scanned inode node.
      77             :  * @header: common header of scanned node
      78             :  * @key: the key of inode node
      79             :  * @is_xattr: %1 for xattr inode, otherwise %0
      80             :  * @is_encrypted: %1 for encrypted inode, otherwise %0
      81             :  * @mode: file mode
      82             :  * @nlink: number of hard links
      83             :  * @xcnt: count of extended attributes this inode has
      84             :  * @xsz: summarized size of all extended attributes in bytes
      85             :  * @xnms: sum of lengths of all extended attribute names
      86             :  * @size: inode size in bytes
      87             :  * @rb: link in the tree of valid inode nodes or deleted inode nodes
      88             :  */
      89             : struct scanned_ino_node {
      90             :         struct scanned_node header;
      91             :         union ubifs_key key;
      92             :         unsigned int is_xattr:1;
      93             :         unsigned int is_encrypted:1;
      94             :         unsigned int mode;
      95             :         unsigned int nlink;
      96             :         unsigned int xcnt;
      97             :         unsigned int xsz;
      98             :         unsigned int xnms;
      99             :         unsigned long long size;
     100             :         struct rb_node rb;
     101             : };
     102             : 
     103             : /**
     104             :  * scanned_dent_node - scanned dentry node.
     105             :  * @header: common header of scanned node
     106             :  * @key: the key of dentry node
     107             :  * @can_be_found: whether this dentry can be found from '/'
     108             :  * @type: file type, reg/dir/symlink/block/char/fifo/sock
     109             :  * @nlen: name length
     110             :  * @name: dentry name
     111             :  * @inum: target inode number
     112             :  * @file: corresponding file
     113             :  * @rb: link in the trees of:
     114             :  *  1) valid dentry nodes or deleted dentry node
     115             :  *  2) all scanned dentry nodes from same file
     116             :  * @list: link in the list dentries for looking up/deleting
     117             :  */
     118             : struct scanned_dent_node {
     119             :         struct scanned_node header;
     120             :         union ubifs_key key;
     121             :         bool can_be_found;
     122             :         unsigned int type;
     123             :         unsigned int nlen;
     124             :         char name[UBIFS_MAX_NLEN + 1];
     125             :         ino_t inum;
     126             :         struct scanned_file *file;
     127             :         struct rb_node rb;
     128             :         struct list_head list;
     129             : };
     130             : 
     131             : /**
     132             :  * scanned_data_node - scanned data node.
     133             :  * @header: common header of scanned node
     134             :  * @key: the key of data node
     135             :  * @size: uncompressed data size in bytes
     136             :  * @rb: link in the tree of all scanned data nodes from same file
     137             :  * @list: link in the list for deleting
     138             :  */
     139             : struct scanned_data_node {
     140             :         struct scanned_node header;
     141             :         union ubifs_key key;
     142             :         unsigned int size;
     143             :         struct rb_node rb;
     144             :         struct list_head list;
     145             : };
     146             : 
     147             : /**
     148             :  * scanned_trun_node - scanned truncation node.
     149             :  * @header: common header of scanned node
     150             :  * @new_size: size after truncation
     151             :  */
     152             : struct scanned_trun_node {
     153             :         struct scanned_node header;
     154             :         unsigned long long new_size;
     155             : };
     156             : 
     157             : /**
     158             :  * scanned_file - file info scanned from UBIFS volume.
     159             :  *
     160             :  * @calc_nlink: calculated count of directory entries refer this inode
     161             :  * @calc_xcnt: calculated count of extended attributes
     162             :  * @calc_xsz: calculated summary size of all extended attributes
     163             :  * @calc_xnms: calculated sum of lengths of all extended attribute names
     164             :  * @calc_size: calculated file size
     165             :  * @has_encrypted_info: whether the file has encryption related xattrs
     166             :  *
     167             :  * @inum: inode number
     168             :  * @ino: inode node
     169             :  * @trun: truncation node
     170             :  *
     171             :  * @rb: link in the tree of all scanned files
     172             :  * @list: link in the list files for kinds of processing
     173             :  * @dent_nodes: tree of all scanned dentry nodes
     174             :  * @data_nodes: tree of all scanned data nodes
     175             :  * @xattr_files: tree of all scanned xattr files
     176             :  */
     177             : struct scanned_file {
     178             :         unsigned int calc_nlink;
     179             :         unsigned int calc_xcnt;
     180             :         unsigned int calc_xsz;
     181             :         unsigned int calc_xnms;
     182             :         unsigned long long calc_size;
     183             :         bool has_encrypted_info;
     184             : 
     185             :         ino_t inum;
     186             :         struct scanned_ino_node ino;
     187             :         struct scanned_trun_node trun;
     188             : 
     189             :         struct rb_node rb;
     190             :         struct list_head list;
     191             :         struct rb_root dent_nodes;
     192             :         struct rb_root data_nodes;
     193             :         struct rb_root xattr_files;
     194             : };
     195             : 
     196             : /**
     197             :  * invalid_file_problem - problem instance for invalid file.
     198             :  * @file: invalid file instance
     199             :  * @priv: invalid instance in @file, could be a dent_node or data_node
     200             :  */
     201             : struct invalid_file_problem {
     202             :         struct scanned_file *file;
     203             :         void *priv;
     204             : };
     205             : 
     206             : /**
     207             :  * nnode_problem - problem instance for incorrect nnode
     208             :  * @nnode: incorrect nnode
     209             :  * @parent_nnode: the parent nnode of @nnode, could be NULL if @nnode is root
     210             :  * @num: calculated num
     211             :  */
     212             : struct nnode_problem {
     213             :         struct ubifs_nnode *nnode;
     214             :         struct ubifs_nnode *parent_nnode;
     215             :         int num;
     216             : };
     217             : 
     218             : /**
     219             :  * pnode_problem - problem instance for incorrect pnode
     220             :  * @pnode: incorrect pnode
     221             :  * @num: calculated num
     222             :  */
     223             : struct pnode_problem {
     224             :         struct ubifs_pnode *pnode;
     225             :         int num;
     226             : };
     227             : 
     228             : /**
     229             :  * lp_problem - problem instance for incorrect LEB proerties
     230             :  * @lp: incorrect LEB properties
     231             :  * @lnum: LEB number
     232             :  * @free: calculated free space in LEB
     233             :  * @dirty: calculated dirty bytes in LEB
     234             :  * @is_idx: %true means that the LEB is an index LEB
     235             :  */
     236             : struct lp_problem {
     237             :         struct ubifs_lprops *lp;
     238             :         int lnum;
     239             :         int free;
     240             :         int dirty;
     241             :         int is_idx;
     242             : };
     243             : 
     244             : /**
     245             :  * space_stat_problem - problem instance for incorrect space statistics
     246             :  * @lst: current space statistics
     247             :  * @calc_lst: calculated space statistics
     248             :  */
     249             : struct space_stat_problem {
     250             :         struct ubifs_lp_stats *lst;
     251             :         struct ubifs_lp_stats *calc_lst;
     252             : };
     253             : 
     254             : /**
     255             :  * ubifs_rebuild_info - UBIFS rebuilding information.
     256             :  * @write_buf: write buffer for LEB @head_lnum
     257             :  * @head_lnum: current writing LEB number
     258             :  * @head_offs: current writing position in LEB @head_lnum
     259             :  * @need_update_lpt: whether to update lpt while writing index nodes
     260             :  */
     261             : struct ubifs_rebuild_info {
     262             :         void *write_buf;
     263             :         int head_lnum;
     264             :         int head_offs;
     265             :         bool need_update_lpt;
     266             : };
     267             : 
     268             : /**
     269             :  * struct ubifs_fsck_info - UBIFS fsck information.
     270             :  * @mode: working mode
     271             :  * @failure_reason: reasons for failed operations
     272             :  * @lpt_status: the status of lpt, could be: %0(OK), %FR_LPT_CORRUPTED or
     273             :  *              %FR_LPT_INCORRECT
     274             :  * @scanned_files: tree of all scanned files
     275             :  * @used_lebs: a bitmap used for recording used lebs
     276             :  * @disconnected_files: regular files without dentries
     277             :  * @lpts: lprops table
     278             :  * @try_rebuild: %true means that try to rebuild fs when fsck failed
     279             :  * @rebuild: rebuilding-related information
     280             :  * @lost_and_found: inode number of the lost+found directory, %0 means invalid
     281             :  */
     282             : struct ubifs_fsck_info {
     283             :         int mode;
     284             :         unsigned int failure_reason;
     285             :         unsigned int lpt_status;
     286             :         struct rb_root scanned_files;
     287             :         unsigned long *used_lebs;
     288             :         struct list_head disconnected_files;
     289             :         struct ubifs_lprops *lpts;
     290             :         bool try_rebuild;
     291             :         struct ubifs_rebuild_info *rebuild;
     292             :         ino_t lost_and_found;
     293             : };
     294             : 
     295             : #define FSCK(c) ((struct ubifs_fsck_info*)c->private)
     296             : 
     297             : static inline const char *mode_name(const struct ubifs_info *c)
     298             : {
     299      359782 :         if (!c->private)
     300             :                 return "";
     301             : 
     302      357659 :         switch (FSCK(c)->mode) {
     303             :         case NORMAL_MODE:
     304             :                 return ",normal mode";
     305             :         case SAFE_MODE:
     306             :                 return ",safe mode";
     307             :         case DANGER_MODE0:
     308             :                 return ",danger mode";
     309             :         case DANGER_MODE1:
     310             :                 return ",danger + rebuild mode";
     311             :         case REBUILD_MODE:
     312             :                 return ",rebuild mode";
     313             :         case CHECK_MODE:
     314             :                 return ",check mode";
     315             :         default:
     316             :                 return "";
     317             :         }
     318             : }
     319             : 
     320             : #define log_out(c, fmt, ...) do {                                       \
     321             :         printf("%s[%d] (%s%s): " fmt "\n", c->program_name ? : "noprog",\
     322             :                getpid(), c->dev_name ? : "-", mode_name(c),                \
     323             :                ##__VA_ARGS__);                                          \
     324             : } while (0)
     325             : 
     326             : #define log_err(c, err, fmt, ...) do {                                  \
     327             :         printf("%s[%d][ERROR] (%s%s): %s: " fmt,                      \
     328             :                c->program_name ? : "noprog", getpid(),                     \
     329             :                c->dev_name ? : "-", mode_name(c),                  \
     330             :                __FUNCTION__, ##__VA_ARGS__);                            \
     331             :         if (err)                                                        \
     332             :                 printf(" - %s", strerror(err));                               \
     333             :         printf("\n");                                                 \
     334             : } while (0)
     335             : 
     336             : /* Exit code for fsck program. */
     337             : extern int exit_code;
     338             : 
     339             : /* fsck.ubifs.c */
     340             : void handle_error(const struct ubifs_info *c, int reason_set);
     341             : 
     342             : /* problem.c */
     343             : bool fix_problem(const struct ubifs_info *c, int problem_type, const void *priv);
     344             : 
     345             : /* load_fs.c */
     346             : int ubifs_load_filesystem(struct ubifs_info *c);
     347             : void ubifs_destroy_filesystem(struct ubifs_info *c);
     348             : 
     349             : /* extract_files.c */
     350             : bool parse_ino_node(struct ubifs_info *c, int lnum, int offs, void *node,
     351             :                     union ubifs_key *key, struct scanned_ino_node *ino_node);
     352             : bool parse_dent_node(struct ubifs_info *c, int lnum, int offs, void *node,
     353             :                      union ubifs_key *key, struct scanned_dent_node *dent_node);
     354             : bool parse_data_node(struct ubifs_info *c, int lnum, int offs, void *node,
     355             :                      union ubifs_key *key, struct scanned_data_node *data_node);
     356             : bool parse_trun_node(struct ubifs_info *c, int lnum, int offs, void *node,
     357             :                      union ubifs_key *key, struct scanned_trun_node *trun_node);
     358             : int insert_or_update_file(struct ubifs_info *c, struct rb_root *file_tree,
     359             :                           struct scanned_node *sn, int key_type, ino_t inum);
     360             : void destroy_file_content(struct ubifs_info *c, struct scanned_file *file);
     361             : void destroy_file_tree(struct ubifs_info *c, struct rb_root *file_tree);
     362             : void destroy_file_list(struct ubifs_info *c, struct list_head *file_list);
     363             : struct scanned_file *lookup_file(struct rb_root *file_tree, ino_t inum);
     364             : int delete_file(struct ubifs_info *c, struct scanned_file *file);
     365             : int file_is_valid(struct ubifs_info *c, struct scanned_file *file,
     366             :                   struct rb_root *file_tree, int *is_diconnected);
     367             : bool file_is_reachable(struct ubifs_info *c, struct scanned_file *file,
     368             :                        struct rb_root *file_tree);
     369             : int check_and_correct_files(struct ubifs_info *c);
     370             : 
     371             : /* rebuild_fs.c */
     372             : int ubifs_rebuild_filesystem(struct ubifs_info *c);
     373             : 
     374             : /* check_files.c */
     375             : int traverse_tnc_and_construct_files(struct ubifs_info *c);
     376             : void update_files_size(struct ubifs_info *c);
     377             : int handle_invalid_files(struct ubifs_info *c);
     378             : int handle_dentry_tree(struct ubifs_info *c);
     379             : bool tnc_is_empty(struct ubifs_info *c);
     380             : int check_and_create_root(struct ubifs_info *c);
     381             : 
     382             : /* check_space.c */
     383             : int get_free_leb(struct ubifs_info *c);
     384             : int build_lpt(struct ubifs_info *c, calculate_lp_callback calculate_lp_cb,
     385             :               bool free_ltab);
     386             : int check_and_correct_space(struct ubifs_info *c);
     387             : int check_and_correct_index_size(struct ubifs_info *c);
     388             : 
     389             : /* handle_disconnected.c */
     390             : int check_and_create_lost_found(struct ubifs_info *c);
     391             : int handle_disonnected_files(struct ubifs_info *c);
     392             : 
     393             : #endif

Generated by: LCOV version 1.13