blob: 6c91face740c25f5ba10dc788d4305cf79338664 [file] [log] [blame]
/* 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