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