417 lines
12 KiB
C
417 lines
12 KiB
C
|
/*
|
||
|
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
||
|
*
|
||
|
* This program is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU General Public License
|
||
|
* as published by the Free Software Foundation; either version 2
|
||
|
* of the License, or (at your option) any later version.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
|
||
|
#ifndef _SDFAT_FS_H
|
||
|
#define _SDFAT_FS_H
|
||
|
|
||
|
#include <linux/types.h>
|
||
|
#include <linux/magic.h>
|
||
|
#include <asm/byteorder.h>
|
||
|
|
||
|
/*----------------------------------------------------------------------*/
|
||
|
/* Constant & Macro Definitions */
|
||
|
/*----------------------------------------------------------------------*/
|
||
|
#ifndef MSDOS_SUPER_MAGIC
|
||
|
#define MSDOS_SUPER_MAGIC 0x4d44 /* MD */
|
||
|
#endif
|
||
|
|
||
|
#ifndef EXFAT_SUPER_MAGIC
|
||
|
#define EXFAT_SUPER_MAGIC (0x2011BAB0UL)
|
||
|
#endif /* EXFAT_SUPER_MAGIC */
|
||
|
|
||
|
#ifndef SDFAT_SUPER_MAGIC
|
||
|
#define SDFAT_SUPER_MAGIC (0x5EC5DFA4UL)
|
||
|
#endif /* SDFAT_SUPER_MAGIC */
|
||
|
|
||
|
#define SDFAT_ROOT_INO 1
|
||
|
|
||
|
/* FAT types */
|
||
|
#define FAT12 0x01 // FAT12
|
||
|
#define FAT16 0x0E // Win95 FAT16 (LBA)
|
||
|
#define FAT32 0x0C // Win95 FAT32 (LBA)
|
||
|
#define EXFAT 0x07 // exFAT
|
||
|
|
||
|
/* directory file name */
|
||
|
#define DOS_CUR_DIR_NAME ". "
|
||
|
#define DOS_PAR_DIR_NAME ".. "
|
||
|
|
||
|
#ifdef __LITTLE_ENDIAN
|
||
|
#define UNI_CUR_DIR_NAME ".\0"
|
||
|
#define UNI_PAR_DIR_NAME ".\0.\0"
|
||
|
#else
|
||
|
#define UNI_CUR_DIR_NAME "\0."
|
||
|
#define UNI_PAR_DIR_NAME "\0.\0."
|
||
|
#endif
|
||
|
|
||
|
/* file name lengths */
|
||
|
/* NOTE :
|
||
|
* The maximum length of input or output is limited to 256 including NULL,
|
||
|
* But we allocate 4 extra bytes for utf8 translation reside in last position,
|
||
|
* because utf8 can uses memory upto 6 bytes per one character.
|
||
|
* Therefore, MAX_CHARSET_SIZE supports upto 6 bytes for utf8
|
||
|
*/
|
||
|
#define MAX_UNINAME_BUF_SIZE (((MAX_NAME_LENGTH+1)*2)+4)
|
||
|
#define MAX_DOSNAME_BUF_SIZE ((DOS_NAME_LENGTH+2)+6)
|
||
|
#define MAX_VFSNAME_BUF_SIZE ((MAX_NAME_LENGTH+1)*MAX_CHARSET_SIZE)
|
||
|
#define MAX_CHARSET_SIZE 6 // max size of multi-byte character
|
||
|
#define MAX_NAME_LENGTH 255 // max len of file name excluding NULL
|
||
|
#define DOS_NAME_LENGTH 11 // DOS file name length excluding NULL
|
||
|
|
||
|
#define SECTOR_SIZE_BITS 9 /* VFS sector size is 512 bytes */
|
||
|
|
||
|
#define DENTRY_SIZE 32 /* directory entry size */
|
||
|
#define DENTRY_SIZE_BITS 5
|
||
|
|
||
|
#define MAX_FAT_DENTRIES 65536 /* FAT allows 65536 directory entries */
|
||
|
#define MAX_EXFAT_DENTRIES 8388608 /* exFAT allows 8388608(256MB) directory entries */
|
||
|
|
||
|
/* PBR entries */
|
||
|
#define PBR_SIGNATURE 0xAA55
|
||
|
#define EXT_SIGNATURE 0xAA550000
|
||
|
#define VOL_LABEL "NO NAME " /* size should be 11 */
|
||
|
#define OEM_NAME "MSWIN4.1" /* size should be 8 */
|
||
|
#define STR_FAT12 "FAT12 " /* size should be 8 */
|
||
|
#define STR_FAT16 "FAT16 " /* size should be 8 */
|
||
|
#define STR_FAT32 "FAT32 " /* size should be 8 */
|
||
|
#define STR_EXFAT "EXFAT " /* size should be 8 */
|
||
|
|
||
|
#define VOL_CLEAN 0x0000
|
||
|
#define VOL_DIRTY 0x0002
|
||
|
|
||
|
#define FAT_VOL_DIRTY 0x01
|
||
|
|
||
|
/* max number of clusters */
|
||
|
#define FAT12_THRESHOLD 4087 // 2^12 - 1 + 2 (clu 0 & 1)
|
||
|
#define FAT16_THRESHOLD 65527 // 2^16 - 1 + 2
|
||
|
#define FAT32_THRESHOLD 268435457 // 2^28 - 1 + 2
|
||
|
#define EXFAT_THRESHOLD 268435457 // 2^28 - 1 + 2
|
||
|
|
||
|
/* dentry types */
|
||
|
#define MSDOS_DELETED 0xE5 /* deleted mark */
|
||
|
#define MSDOS_UNUSED 0x00 /* end of directory */
|
||
|
|
||
|
#define EXFAT_UNUSED 0x00 /* end of directory */
|
||
|
#define IS_EXFAT_DELETED(x) ((x) < 0x80) /* deleted file (0x01~0x7F) */
|
||
|
#define EXFAT_INVAL 0x80 /* invalid value */
|
||
|
#define EXFAT_BITMAP 0x81 /* allocation bitmap */
|
||
|
#define EXFAT_UPCASE 0x82 /* upcase table */
|
||
|
#define EXFAT_VOLUME 0x83 /* volume label */
|
||
|
#define EXFAT_FILE 0x85 /* file or dir */
|
||
|
#define EXFAT_STREAM 0xC0 /* stream entry */
|
||
|
#define EXFAT_NAME 0xC1 /* file name entry */
|
||
|
#define EXFAT_ACL 0xC2 /* stream entry */
|
||
|
|
||
|
/* specific flag */
|
||
|
#define MSDOS_LAST_LFN 0x40
|
||
|
|
||
|
/* file attributes */
|
||
|
#define ATTR_NORMAL 0x0000
|
||
|
#define ATTR_READONLY 0x0001
|
||
|
#define ATTR_HIDDEN 0x0002
|
||
|
#define ATTR_SYSTEM 0x0004
|
||
|
#define ATTR_VOLUME 0x0008
|
||
|
#define ATTR_SUBDIR 0x0010
|
||
|
#define ATTR_ARCHIVE 0x0020
|
||
|
#define ATTR_SYMLINK 0x0040
|
||
|
#define ATTR_EXTEND (ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | \
|
||
|
ATTR_VOLUME) /* 0x000F */
|
||
|
|
||
|
#define ATTR_EXTEND_MASK (ATTR_EXTEND | ATTR_SUBDIR | ATTR_ARCHIVE)
|
||
|
#define ATTR_RWMASK (ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME | \
|
||
|
ATTR_SUBDIR | ATTR_ARCHIVE | ATTR_SYMLINK)/* 0x007E */
|
||
|
|
||
|
/* file creation modes */
|
||
|
#define FM_REGULAR 0x00
|
||
|
#define FM_SYMLINK 0x40
|
||
|
|
||
|
/* time modes */
|
||
|
#define TM_CREATE 0
|
||
|
#define TM_MODIFY 1
|
||
|
#define TM_ACCESS 2
|
||
|
|
||
|
/* checksum types */
|
||
|
#define CS_DIR_ENTRY 0
|
||
|
#define CS_PBR_SECTOR 1
|
||
|
#define CS_DEFAULT 2
|
||
|
|
||
|
/* time min/max */
|
||
|
/* Jan 1 GMT 00:00:00 1980 */
|
||
|
#define SDFAT_MIN_TIMESTAMP_SECS 315532800LL
|
||
|
/* Dec 31 GMT 23:59:59 2107 */
|
||
|
#define SDFAT_MAX_TIMESTAMP_SECS 4354819199LL
|
||
|
|
||
|
|
||
|
/*
|
||
|
* ioctl command
|
||
|
*/
|
||
|
#define SDFAT_IOCTL_GET_VOLUME_ID _IOR('r', 0x12, __u32)
|
||
|
#define SDFAT_IOCTL_DFR_INFO _IOC(_IOC_NONE, 'E', 0x13, sizeof(u32))
|
||
|
#define SDFAT_IOCTL_DFR_TRAV _IOC(_IOC_NONE, 'E', 0x14, sizeof(u32))
|
||
|
#define SDFAT_IOCTL_DFR_REQ _IOC(_IOC_NONE, 'E', 0x15, sizeof(u32))
|
||
|
#define SDFAT_IOCTL_DFR_SPO_FLAG _IOC(_IOC_NONE, 'E', 0x16, sizeof(u32))
|
||
|
#define SDFAT_IOCTL_PANIC _IOC(_IOC_NONE, 'E', 0x17, sizeof(u32))
|
||
|
|
||
|
/*
|
||
|
* ioctl command for debugging
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* IOCTL code 'f' used by
|
||
|
* - file systems typically #0~0x1F
|
||
|
* - embedded terminal devices #128~
|
||
|
* - exts for debugging purpose #99
|
||
|
* number 100 and 101 is available now but has possible conflicts
|
||
|
*
|
||
|
* NOTE : This is available only If CONFIG_SDFAT_DVBG_IOCTL is enabled.
|
||
|
*
|
||
|
*/
|
||
|
#define SDFAT_IOC_GET_DEBUGFLAGS _IOR('f', 100, long)
|
||
|
#define SDFAT_IOC_SET_DEBUGFLAGS _IOW('f', 101, long)
|
||
|
|
||
|
#define SDFAT_DEBUGFLAGS_INVALID_UMOUNT 0x01
|
||
|
#define SDFAT_DEBUGFLAGS_ERROR_RW 0x02
|
||
|
|
||
|
/*----------------------------------------------------------------------*/
|
||
|
/* On-Disk Type Definitions */
|
||
|
/*----------------------------------------------------------------------*/
|
||
|
|
||
|
/* FAT12/16/32 BIOS parameter block (64 bytes) */
|
||
|
typedef struct {
|
||
|
__u8 jmp_boot[3];
|
||
|
__u8 oem_name[8];
|
||
|
|
||
|
__u8 sect_size[2]; /* unaligned */
|
||
|
__u8 sect_per_clus;
|
||
|
__le16 num_reserved; /* . */
|
||
|
__u8 num_fats;
|
||
|
__u8 num_root_entries[2]; /* unaligned */
|
||
|
__u8 num_sectors[2]; /* unaligned */
|
||
|
__u8 media_type;
|
||
|
__le16 num_fat_sectors;
|
||
|
__le16 sectors_in_track;
|
||
|
__le16 num_heads;
|
||
|
__le32 num_hid_sectors; /* . */
|
||
|
__le32 num_huge_sectors;
|
||
|
|
||
|
union {
|
||
|
struct {
|
||
|
__u8 phy_drv_no;
|
||
|
__u8 state; /* used by WinNT for mount state */
|
||
|
__u8 ext_signature;
|
||
|
__u8 vol_serial[4];
|
||
|
__u8 vol_label[11];
|
||
|
__u8 vol_type[8];
|
||
|
__le16 nouse;
|
||
|
} f16;
|
||
|
|
||
|
struct {
|
||
|
__le32 num_fat32_sectors;
|
||
|
__le16 ext_flags;
|
||
|
__u8 fs_version[2];
|
||
|
__le32 root_cluster; /* . */
|
||
|
__le16 fsinfo_sector;
|
||
|
__le16 backup_sector;
|
||
|
__le16 reserved[6]; /* . */
|
||
|
} f32;
|
||
|
};
|
||
|
} bpb_t;
|
||
|
|
||
|
/* FAT32 EXTEND BIOS parameter block (32 bytes) */
|
||
|
typedef struct {
|
||
|
__u8 phy_drv_no;
|
||
|
__u8 state; /* used by WindowsNT for mount state */
|
||
|
__u8 ext_signature;
|
||
|
__u8 vol_serial[4];
|
||
|
__u8 vol_label[11];
|
||
|
__u8 vol_type[8];
|
||
|
__le16 dummy[3];
|
||
|
} bsx32_t;
|
||
|
|
||
|
/* EXFAT BIOS parameter block (64 bytes) */
|
||
|
typedef struct {
|
||
|
__u8 jmp_boot[3];
|
||
|
__u8 oem_name[8];
|
||
|
__u8 res_zero[53];
|
||
|
} bpb64_t;
|
||
|
|
||
|
/* EXFAT EXTEND BIOS parameter block (56 bytes) */
|
||
|
typedef struct {
|
||
|
__le64 vol_offset;
|
||
|
__le64 vol_length;
|
||
|
__le32 fat_offset;
|
||
|
__le32 fat_length;
|
||
|
__le32 clu_offset;
|
||
|
__le32 clu_count;
|
||
|
__le32 root_cluster;
|
||
|
__le32 vol_serial;
|
||
|
__u8 fs_version[2];
|
||
|
__le16 vol_flags;
|
||
|
__u8 sect_size_bits;
|
||
|
__u8 sect_per_clus_bits;
|
||
|
__u8 num_fats;
|
||
|
__u8 phy_drv_no;
|
||
|
__u8 perc_in_use;
|
||
|
__u8 reserved2[7];
|
||
|
} bsx64_t;
|
||
|
|
||
|
/* FAT32 PBR (64 bytes) */
|
||
|
typedef struct {
|
||
|
bpb_t bpb;
|
||
|
} pbr16_t;
|
||
|
|
||
|
/* FAT32 PBR[BPB+BSX] (96 bytes) */
|
||
|
typedef struct {
|
||
|
bpb_t bpb;
|
||
|
bsx32_t bsx;
|
||
|
} pbr32_t;
|
||
|
|
||
|
/* EXFAT PBR[BPB+BSX] (120 bytes) */
|
||
|
typedef struct {
|
||
|
bpb64_t bpb;
|
||
|
bsx64_t bsx;
|
||
|
} pbr64_t;
|
||
|
|
||
|
/* Common PBR[Partition Boot Record] (512 bytes) */
|
||
|
typedef struct {
|
||
|
union {
|
||
|
__u8 raw[64];
|
||
|
bpb_t fat;
|
||
|
bpb64_t f64;
|
||
|
} bpb;
|
||
|
union {
|
||
|
__u8 raw[56];
|
||
|
bsx32_t f32;
|
||
|
bsx64_t f64;
|
||
|
} bsx;
|
||
|
__u8 boot_code[390];
|
||
|
__le16 signature;
|
||
|
} pbr_t;
|
||
|
|
||
|
/* FAT32 filesystem information sector (512 bytes) */
|
||
|
typedef struct {
|
||
|
__le32 signature1; // aligned
|
||
|
__u8 reserved1[480];
|
||
|
__le32 signature2; // aligned
|
||
|
__le32 free_cluster; // aligned
|
||
|
__le32 next_cluster; // aligned
|
||
|
__u8 reserved2[14];
|
||
|
__le16 signature3[2];
|
||
|
} fat32_fsi_t;
|
||
|
|
||
|
/* FAT directory entry (32 bytes) */
|
||
|
typedef struct {
|
||
|
__u8 dummy[32];
|
||
|
} DENTRY_T;
|
||
|
|
||
|
typedef struct {
|
||
|
__u8 name[DOS_NAME_LENGTH]; /* 11 chars */
|
||
|
__u8 attr;
|
||
|
__u8 lcase;
|
||
|
__u8 create_time_ms;
|
||
|
__le16 create_time; // aligned
|
||
|
__le16 create_date; // aligned
|
||
|
__le16 access_date; // aligned
|
||
|
__le16 start_clu_hi; // aligned
|
||
|
__le16 modify_time; // aligned
|
||
|
__le16 modify_date; // aligned
|
||
|
__le16 start_clu_lo; // aligned
|
||
|
__le32 size; // aligned
|
||
|
} DOS_DENTRY_T;
|
||
|
|
||
|
/* FAT extended directory entry (32 bytes) */
|
||
|
typedef struct {
|
||
|
__u8 order;
|
||
|
__u8 unicode_0_4[10];
|
||
|
__u8 attr;
|
||
|
__u8 sysid;
|
||
|
__u8 checksum;
|
||
|
__le16 unicode_5_10[6]; // aligned
|
||
|
__le16 start_clu; // aligned
|
||
|
__le16 unicode_11_12[2]; // aligned
|
||
|
} EXT_DENTRY_T;
|
||
|
|
||
|
/* EXFAT file directory entry (32 bytes) */
|
||
|
typedef struct {
|
||
|
__u8 type;
|
||
|
__u8 num_ext;
|
||
|
__le16 checksum; // aligned
|
||
|
__le16 attr; // aligned
|
||
|
__le16 reserved1;
|
||
|
__le16 create_time; // aligned
|
||
|
__le16 create_date; // aligned
|
||
|
__le16 modify_time; // aligned
|
||
|
__le16 modify_date; // aligned
|
||
|
__le16 access_time; // aligned
|
||
|
__le16 access_date; // aligned
|
||
|
__u8 create_time_ms;
|
||
|
__u8 modify_time_ms;
|
||
|
__u8 create_tz;
|
||
|
__u8 modify_tz;
|
||
|
__u8 access_tz;
|
||
|
__u8 reserved2[7];
|
||
|
} FILE_DENTRY_T;
|
||
|
|
||
|
/* EXFAT stream extension directory entry (32 bytes) */
|
||
|
typedef struct {
|
||
|
__u8 type;
|
||
|
__u8 flags;
|
||
|
__u8 reserved1;
|
||
|
__u8 name_len;
|
||
|
__le16 name_hash; // aligned
|
||
|
__le16 reserved2;
|
||
|
__le64 valid_size; // aligned
|
||
|
__le32 reserved3; // aligned
|
||
|
__le32 start_clu; // aligned
|
||
|
__le64 size; // aligned
|
||
|
} STRM_DENTRY_T;
|
||
|
|
||
|
/* EXFAT file name directory entry (32 bytes) */
|
||
|
typedef struct {
|
||
|
__u8 type;
|
||
|
__u8 flags;
|
||
|
__le16 unicode_0_14[15]; // aligned
|
||
|
} NAME_DENTRY_T;
|
||
|
|
||
|
/* EXFAT allocation bitmap directory entry (32 bytes) */
|
||
|
typedef struct {
|
||
|
__u8 type;
|
||
|
__u8 flags;
|
||
|
__u8 reserved[18];
|
||
|
__le32 start_clu; // aligned
|
||
|
__le64 size; // aligned
|
||
|
} BMAP_DENTRY_T;
|
||
|
|
||
|
/* EXFAT up-case table directory entry (32 bytes) */
|
||
|
typedef struct {
|
||
|
__u8 type;
|
||
|
__u8 reserved1[3];
|
||
|
__le32 checksum; // aligned
|
||
|
__u8 reserved2[12];
|
||
|
__le32 start_clu; // aligned
|
||
|
__le64 size; // aligned
|
||
|
} CASE_DENTRY_T;
|
||
|
|
||
|
/* EXFAT volume label directory entry (32 bytes) */
|
||
|
typedef struct {
|
||
|
__u8 type;
|
||
|
__u8 label_len;
|
||
|
__le16 unicode_0_10[11]; // aligned
|
||
|
__u8 reserved[8];
|
||
|
} VOLM_DENTRY_T;
|
||
|
|
||
|
#endif /* _SDFAT_FS_H */
|