| /* SPDX-License-Identifier: GPL-2.0-or-later */ |
| /* |
| * Copyright (C) 2020 Hyunchul Lee <hyc.lee@gmail.com> |
| */ |
| #ifndef _FSCK_H |
| #define _FSCK_H |
| |
| #include "list.h" |
| |
| typedef __u32 clus_t; |
| |
| struct exfat_inode { |
| struct exfat_inode *parent; |
| struct list_head children; |
| struct list_head sibling; |
| struct list_head list; |
| clus_t first_clus; |
| clus_t last_lclus; |
| clus_t last_pclus; |
| __u16 attr; |
| uint64_t size; |
| bool is_contiguous; |
| __le16 name[0]; /* only for directory */ |
| }; |
| |
| #define EXFAT_NAME_MAX 255 |
| #define NAME_BUFFER_SIZE ((EXFAT_NAME_MAX+1)*2) |
| |
| struct buffer_desc { |
| clus_t p_clus; |
| unsigned int offset; |
| char *buffer; |
| char *dirty; |
| }; |
| |
| struct exfat_de_iter { |
| struct exfat *exfat; |
| struct exfat_inode *parent; |
| struct buffer_desc *buffer_desc; /* cluster * 2 */ |
| clus_t ra_next_clus; |
| unsigned int ra_begin_offset; |
| unsigned int ra_partial_size; |
| unsigned int read_size; /* cluster size */ |
| unsigned int write_size; /* sector size */ |
| off_t de_file_offset; |
| off_t next_read_offset; |
| int max_skip_dentries; |
| }; |
| |
| enum fsck_ui_options { |
| FSCK_OPTS_REPAIR_ASK = 0x01, |
| FSCK_OPTS_REPAIR_YES = 0x02, |
| FSCK_OPTS_REPAIR_NO = 0x04, |
| FSCK_OPTS_REPAIR_AUTO = 0x08, |
| FSCK_OPTS_REPAIR_WRITE = 0x0b, |
| FSCK_OPTS_REPAIR_ALL = 0x0f, |
| }; |
| |
| struct exfat { |
| enum fsck_ui_options options; |
| bool dirty:1; |
| bool dirty_fat:1; |
| struct exfat_blk_dev *blk_dev; |
| struct pbr *bs; |
| char volume_label[VOLUME_LABEL_BUFFER_SIZE]; |
| struct exfat_inode *root; |
| struct list_head dir_list; |
| clus_t clus_count; |
| unsigned int clus_size; |
| unsigned int sect_size; |
| struct exfat_de_iter de_iter; |
| struct buffer_desc buffer_desc[2]; /* cluster * 2 */ |
| char *alloc_bitmap; |
| char *disk_bitmap; |
| clus_t disk_bitmap_clus; |
| unsigned int disk_bitmap_size; |
| }; |
| |
| #define EXFAT_CLUSTER_SIZE(pbr) (1 << ((pbr)->bsx.sect_size_bits + \ |
| (pbr)->bsx.sect_per_clus_bits)) |
| #define EXFAT_SECTOR_SIZE(pbr) (1 << (pbr)->bsx.sect_size_bits) |
| |
| /* fsck.c */ |
| off_t exfat_c2o(struct exfat *exfat, unsigned int clus); |
| int get_next_clus(struct exfat *exfat, struct exfat_inode *node, |
| clus_t clus, clus_t *next); |
| |
| /* de_iter.c */ |
| int exfat_de_iter_init(struct exfat_de_iter *iter, struct exfat *exfat, |
| struct exfat_inode *dir); |
| int exfat_de_iter_get(struct exfat_de_iter *iter, |
| int ith, struct exfat_dentry **dentry); |
| int exfat_de_iter_get_dirty(struct exfat_de_iter *iter, |
| int ith, struct exfat_dentry **dentry); |
| int exfat_de_iter_flush(struct exfat_de_iter *iter); |
| int exfat_de_iter_advance(struct exfat_de_iter *iter, int skip_dentries); |
| off_t exfat_de_iter_file_offset(struct exfat_de_iter *iter); |
| |
| #endif |