1/* 2 * @TAG(OTHER_GPL) 3 */ 4 5/* 6 * linux/fs/fat/fat.h 7 * 8 */ 9 10#ifndef _FAT_H 11#define _FAT_H 12 13#include <linux/buffer_head.h> 14#include <linux/nls.h> 15#include <linux/hash.h> 16#include <linux/ratelimit.h> 17#include <linux/msdos_fs.h> 18#include <linux/version.h> 19 20/* 21 * vfat shortname flags 22 */ 23#define VFAT_SFN_DISPLAY_LOWER 0x0001 /* convert to lowercase for display */ 24#define VFAT_SFN_DISPLAY_WIN95 0x0002 /* emulate win95 rule for display */ 25#define VFAT_SFN_DISPLAY_WINNT 0x0004 /* emulate winnt rule for display */ 26#define VFAT_SFN_CREATE_WIN95 0x0100 /* emulate win95 rule for create */ 27#define VFAT_SFN_CREATE_WINNT 0x0200 /* emulate winnt rule for create */ 28 29#define FAT_ERRORS_CONT 1 /* ignore error and continue */ 30#define FAT_ERRORS_PANIC 2 /* panic on error */ 31#define FAT_ERRORS_RO 3 /* remount r/o on error */ 32 33#define FAT_NFS_STALE_RW 1 /* NFS RW support, can cause ESTALE */ 34#define FAT_NFS_NOSTALE_RO 2 /* NFS RO support, no ESTALE issue */ 35 36struct fat_mount_options { 37 kuid_t fs_uid; 38 kgid_t fs_gid; 39 unsigned short fs_fmask; 40 unsigned short fs_dmask; 41 unsigned short codepage; /* Codepage for shortname conversions */ 42 int time_offset; /* Offset of timestamps from UTC (in minutes) */ 43 char *iocharset; /* Charset used for filename input/display */ 44 unsigned short shortname; /* flags for shortname display/create rule */ 45 unsigned char name_check; /* r = relaxed, n = normal, s = strict */ 46 unsigned char errors; /* On error: continue, panic, remount-ro */ 47 unsigned char nfs; /* NFS support: nostale_ro, stale_rw */ 48 unsigned short allow_utime;/* permission for setting the [am]time */ 49 unsigned quiet:1, /* set = fake successful chmods and chowns */ 50 showexec:1, /* set = only set x bit for com/exe/bat */ 51 sys_immutable:1, /* set = system files are immutable */ 52 dotsOK:1, /* set = hidden and system files are named '.filename' */ 53 isvfat:1, /* 0=no vfat long filename support, 1=vfat support */ 54 utf8:1, /* Use of UTF-8 character set (Default) */ 55 unicode_xlate:1, /* create escape sequences for unhandled Unicode */ 56 numtail:1, /* Does first alias have a numeric '~1' type tail? */ 57 flush:1, /* write things quickly */ 58 nocase:1, /* Does this need case conversion? 0=need case conversion*/ 59 usefree:1, /* Use free_clusters for FAT32 */ 60 tz_set:1, /* Filesystem timestamps' offset set */ 61 rodir:1, /* allow ATTR_RO for directory */ 62 discard:1, /* Issue discard requests on deletions */ 63 dos1xfloppy:1; /* Assume default BPB for DOS 1.x floppies */ 64}; 65 66#define FAT_HASH_BITS 8 67#define FAT_HASH_SIZE (1UL << FAT_HASH_BITS) 68 69/* 70 * MS-DOS file system in-core superblock data 71 */ 72struct msdos_sb_info { 73 unsigned short sec_per_clus; /* sectors/cluster */ 74 unsigned short cluster_bits; /* log2(cluster_size) */ 75 unsigned int cluster_size; /* cluster size */ 76 unsigned char fats, fat_bits; /* number of FATs, FAT bits (12,16 or 32) */ 77 unsigned short fat_start; 78 unsigned long fat_length; /* FAT start & length (sec.) */ 79 unsigned long dir_start; 80 unsigned short dir_entries; /* root dir start & entries */ 81 unsigned long data_start; /* first data sector */ 82 unsigned long max_cluster; /* maximum cluster number */ 83 unsigned long root_cluster; /* first cluster of the root directory */ 84 unsigned long fsinfo_sector; /* sector number of FAT32 fsinfo */ 85 struct mutex fat_lock; 86 struct mutex nfs_build_inode_lock; 87 struct mutex s_lock; 88 unsigned int prev_free; /* previously allocated cluster number */ 89 unsigned int free_clusters; /* -1 if undefined */ 90 unsigned int free_clus_valid; /* is free_clusters valid? */ 91 struct fat_mount_options options; 92 struct nls_table *nls_disk; /* Codepage used on disk */ 93 struct nls_table *nls_io; /* Charset used for input and display */ 94 const void *dir_ops; /* Opaque; default directory operations */ 95 int dir_per_block; /* dir entries per block */ 96 int dir_per_block_bits; /* log2(dir_per_block) */ 97 unsigned int vol_id; /*volume ID*/ 98 99 int fatent_shift; 100 struct fatent_operations *fatent_ops; 101 struct inode *fat_inode; 102 struct inode *fsinfo_inode; 103 104 struct ratelimit_state ratelimit; 105 106 spinlock_t inode_hash_lock; 107 struct hlist_head inode_hashtable[FAT_HASH_SIZE]; 108 109 spinlock_t dir_hash_lock; 110 struct hlist_head dir_hashtable[FAT_HASH_SIZE]; 111 112 unsigned int dirty; /* fs state before mount */ 113 struct rcu_head rcu; 114}; 115 116#define FAT_CACHE_VALID 0 /* special case for valid cache */ 117 118/* 119 * MS-DOS file system inode data in memory 120 */ 121struct msdos_inode_info { 122 spinlock_t cache_lru_lock; 123 struct list_head cache_lru; 124 int nr_caches; 125 /* for avoiding the race between fat_free() and fat_get_cluster() */ 126 unsigned int cache_valid_id; 127 128 /* NOTE: mmu_private is 64bits, so must hold inode lock to access */ 129 loff_t mmu_private; /* physically allocated size */ 130 131 int i_start; /* first cluster or 0 */ 132 int i_logstart; /* logical first cluster */ 133 int i_attrs; /* unused attribute bits */ 134 loff_t i_pos; /* on-disk position of directory entry or 0 */ 135 struct hlist_node i_fat_hash; /* hash by i_location */ 136 struct hlist_node i_dir_hash; /* hash by i_logstart */ 137 struct rw_semaphore truncate_lock; /* protect bmap against truncate */ 138 struct inode vfs_inode; 139}; 140 141struct fat_slot_info { 142 loff_t i_pos; /* on-disk position of directory entry */ 143 loff_t slot_off; /* offset for slot or de start */ 144 int nr_slots; /* number of slots + 1(de) in filename */ 145 struct msdos_dir_entry *de; 146 struct buffer_head *bh; 147}; 148 149static inline struct msdos_sb_info *MSDOS_SB(struct super_block *sb) 150{ 151 return sb->s_fs_info; 152} 153 154static inline struct msdos_inode_info *MSDOS_I(struct inode *inode) 155{ 156 return container_of(inode, struct msdos_inode_info, vfs_inode); 157} 158 159/* 160 * If ->i_mode can't hold S_IWUGO (i.e. ATTR_RO), we use ->i_attrs to 161 * save ATTR_RO instead of ->i_mode. 162 * 163 * If it's directory and !sbi->options.rodir, ATTR_RO isn't read-only 164 * bit, it's just used as flag for app. 165 */ 166static inline int fat_mode_can_hold_ro(struct inode *inode) 167{ 168 struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); 169 umode_t mask; 170 171 if (S_ISDIR(inode->i_mode)) { 172 if (!sbi->options.rodir) 173 return 0; 174 mask = ~sbi->options.fs_dmask; 175 } else 176 mask = ~sbi->options.fs_fmask; 177 178 if (!(mask & S_IWUGO)) 179 return 0; 180 return 1; 181} 182 183/* Convert attribute bits and a mask to the UNIX mode. */ 184static inline umode_t fat_make_mode(struct msdos_sb_info *sbi, 185 u8 attrs, umode_t mode) 186{ 187 if (attrs & ATTR_RO && !((attrs & ATTR_DIR) && !sbi->options.rodir)) 188 mode &= ~S_IWUGO; 189 190 if (attrs & ATTR_DIR) 191 return (mode & ~sbi->options.fs_dmask) | S_IFDIR; 192 else 193 return (mode & ~sbi->options.fs_fmask) | S_IFREG; 194} 195 196/* Return the FAT attribute byte for this inode */ 197static inline u8 fat_make_attrs(struct inode *inode) 198{ 199 u8 attrs = MSDOS_I(inode)->i_attrs; 200 if (S_ISDIR(inode->i_mode)) 201 attrs |= ATTR_DIR; 202 if (fat_mode_can_hold_ro(inode) && !(inode->i_mode & S_IWUGO)) 203 attrs |= ATTR_RO; 204 return attrs; 205} 206 207static inline void fat_save_attrs(struct inode *inode, u8 attrs) 208{ 209 if (fat_mode_can_hold_ro(inode)) 210 MSDOS_I(inode)->i_attrs = attrs & ATTR_UNUSED; 211 else 212 MSDOS_I(inode)->i_attrs = attrs & (ATTR_UNUSED | ATTR_RO); 213} 214 215static inline unsigned char fat_checksum(const __u8 *name) 216{ 217 unsigned char s = name[0]; 218 s = (s<<7) + (s>>1) + name[1]; s = (s<<7) + (s>>1) + name[2]; 219 s = (s<<7) + (s>>1) + name[3]; s = (s<<7) + (s>>1) + name[4]; 220 s = (s<<7) + (s>>1) + name[5]; s = (s<<7) + (s>>1) + name[6]; 221 s = (s<<7) + (s>>1) + name[7]; s = (s<<7) + (s>>1) + name[8]; 222 s = (s<<7) + (s>>1) + name[9]; s = (s<<7) + (s>>1) + name[10]; 223 return s; 224} 225 226static inline sector_t fat_clus_to_blknr(struct msdos_sb_info *sbi, int clus) 227{ 228 return ((sector_t)clus - FAT_START_ENT) * sbi->sec_per_clus 229 + sbi->data_start; 230} 231 232static inline void fat_get_blknr_offset(struct msdos_sb_info *sbi, 233 loff_t i_pos, sector_t *blknr, int *offset) 234{ 235 *blknr = i_pos >> sbi->dir_per_block_bits; 236 *offset = i_pos & (sbi->dir_per_block - 1); 237} 238 239static inline loff_t fat_i_pos_read(struct msdos_sb_info *sbi, 240 struct inode *inode) 241{ 242 loff_t i_pos; 243#if BITS_PER_LONG == 32 244 spin_lock(&sbi->inode_hash_lock); 245#endif 246 i_pos = MSDOS_I(inode)->i_pos; 247#if BITS_PER_LONG == 32 248 spin_unlock(&sbi->inode_hash_lock); 249#endif 250 return i_pos; 251} 252 253static inline void fat16_towchar(wchar_t *dst, const __u8 *src, size_t len) 254{ 255#ifdef __BIG_ENDIAN 256 while (len--) { 257 *dst++ = src[0] | (src[1] << 8); 258 src += 2; 259 } 260#else 261 memcpy(dst, src, len * 2); 262#endif 263} 264 265static inline int fat_get_start(const struct msdos_sb_info *sbi, 266 const struct msdos_dir_entry *de) 267{ 268 int cluster = le16_to_cpu(de->start); 269 if (sbi->fat_bits == 32) 270 cluster |= (le16_to_cpu(de->starthi) << 16); 271 return cluster; 272} 273 274static inline void fat_set_start(struct msdos_dir_entry *de, int cluster) 275{ 276 de->start = cpu_to_le16(cluster); 277 de->starthi = cpu_to_le16(cluster >> 16); 278} 279 280static inline void fatwchar_to16(__u8 *dst, const wchar_t *src, size_t len) 281{ 282#ifdef __BIG_ENDIAN 283 while (len--) { 284 dst[0] = *src & 0x00FF; 285 dst[1] = (*src & 0xFF00) >> 8; 286 dst += 2; 287 src++; 288 } 289#else 290 memcpy(dst, src, len * 2); 291#endif 292} 293 294/* fat/cache.c */ 295extern void fat_cache_inval_inode(struct inode *inode); 296extern int fat_get_cluster(struct inode *inode, int cluster, 297 int *fclus, int *dclus); 298extern int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys, 299 unsigned long *mapped_blocks, int create); 300 301/* fat/dir.c */ 302extern const struct file_operations fat_dir_operations; 303extern int fat_search_long(struct inode *inode, const unsigned char *name, 304 int name_len, struct fat_slot_info *sinfo); 305extern int fat_dir_empty(struct inode *dir); 306extern int fat_subdirs(struct inode *dir); 307extern int fat_scan(struct inode *dir, const unsigned char *name, 308 struct fat_slot_info *sinfo); 309extern int fat_scan_logstart(struct inode *dir, int i_logstart, 310 struct fat_slot_info *sinfo); 311extern int fat_get_dotdot_entry(struct inode *dir, struct buffer_head **bh, 312 struct msdos_dir_entry **de); 313extern int fat_alloc_new_dir(struct inode *dir, struct timespec *ts); 314extern int fat_add_entries(struct inode *dir, void *slots, int nr_slots, 315 struct fat_slot_info *sinfo); 316extern int fat_remove_entries(struct inode *dir, struct fat_slot_info *sinfo); 317 318/* fat/fatent.c */ 319struct fat_entry { 320 int entry; 321 union { 322 u8 *ent12_p[2]; 323 __le16 *ent16_p; 324 __le32 *ent32_p; 325 } u; 326 int nr_bhs; 327 struct buffer_head *bhs[2]; 328 struct inode *fat_inode; 329}; 330 331static inline void fatent_init(struct fat_entry *fatent) 332{ 333 fatent->nr_bhs = 0; 334 fatent->entry = 0; 335 fatent->u.ent32_p = NULL; 336 fatent->bhs[0] = fatent->bhs[1] = NULL; 337 fatent->fat_inode = NULL; 338} 339 340static inline void fatent_set_entry(struct fat_entry *fatent, int entry) 341{ 342 fatent->entry = entry; 343 fatent->u.ent32_p = NULL; 344} 345 346static inline void fatent_brelse(struct fat_entry *fatent) 347{ 348 int i; 349 fatent->u.ent32_p = NULL; 350 for (i = 0; i < fatent->nr_bhs; i++) 351 brelse(fatent->bhs[i]); 352 fatent->nr_bhs = 0; 353 fatent->bhs[0] = fatent->bhs[1] = NULL; 354 fatent->fat_inode = NULL; 355} 356 357extern void fat_ent_access_init(struct super_block *sb); 358extern int fat_ent_read(struct inode *inode, struct fat_entry *fatent, 359 int entry); 360extern int fat_ent_write(struct inode *inode, struct fat_entry *fatent, 361 int new, int wait); 362extern int fat_alloc_clusters(struct inode *inode, int *cluster, 363 int nr_cluster); 364extern int fat_free_clusters(struct inode *inode, int cluster); 365extern int fat_count_free_clusters(struct super_block *sb); 366 367/* fat/file.c */ 368extern long fat_generic_ioctl(struct file *filp, unsigned int cmd, 369 unsigned long arg); 370extern const struct file_operations fat_file_operations; 371extern const struct inode_operations fat_file_inode_operations; 372extern int fat_setattr(struct dentry *dentry, struct iattr *attr); 373extern void fat_truncate_blocks(struct inode *inode, loff_t offset); 374extern int fat_getattr(struct vfsmount *mnt, struct dentry *dentry, 375 struct kstat *stat); 376extern int fat_file_fsync(struct file *file, loff_t start, loff_t end, 377 int datasync); 378 379/* fat/inode.c */ 380extern int fat_block_truncate_page(struct inode *inode, loff_t from); 381extern void fat_attach(struct inode *inode, loff_t i_pos); 382extern void fat_detach(struct inode *inode); 383extern struct inode *fat_iget(struct super_block *sb, loff_t i_pos); 384extern struct inode *fat_build_inode(struct super_block *sb, 385 struct msdos_dir_entry *de, loff_t i_pos); 386extern int fat_sync_inode(struct inode *inode); 387extern int fat_fill_super(struct super_block *sb, void *data, int silent, 388 int isvfat, void (*setup)(struct super_block *)); 389extern int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de); 390 391extern int fat_flush_inodes(struct super_block *sb, struct inode *i1, 392 struct inode *i2); 393static inline unsigned long fat_dir_hash(int logstart) 394{ 395 return hash_32(logstart, FAT_HASH_BITS); 396} 397 398/* fat/misc.c */ 399extern __printf(3, 4) __cold 400void __fat_fs_error(struct super_block *sb, int report, const char *fmt, ...); 401#define fat_fs_error(sb, fmt, args...) \ 402 __fat_fs_error(sb, 1, fmt , ## args) 403#define fat_fs_error_ratelimit(sb, fmt, args...) \ 404 __fat_fs_error(sb, __ratelimit(&MSDOS_SB(sb)->ratelimit), fmt , ## args) 405__printf(3, 4) __cold 406void fat_msg(struct super_block *sb, const char *level, const char *fmt, ...); 407#define fat_msg_ratelimit(sb, level, fmt, args...) \ 408 do { \ 409 if (__ratelimit(&MSDOS_SB(sb)->ratelimit)) \ 410 fat_msg(sb, level, fmt, ## args); \ 411 } while (0) 412extern int fat_clusters_flush(struct super_block *sb); 413extern int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster); 414extern void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec *ts, 415 __le16 __time, __le16 __date, u8 time_cs); 416extern void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec *ts, 417 __le16 *time, __le16 *date, u8 *time_cs); 418extern int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs); 419 420int fat_cache_init(void); 421void fat_cache_destroy(void); 422 423/* fat/nfs.c */ 424extern const struct export_operations fat_export_ops; 425extern const struct export_operations fat_export_ops_nostale; 426 427/* helper for printk */ 428typedef unsigned long long llu; 429 430#endif /* !_FAT_H */ 431