fs: Add sdfat
[GitHub/LineageOS/android_kernel_samsung_universal7580.git] / fs / sdfat / sdfat.h
1 /*
2 * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #ifndef _SDFAT_H
19 #define _SDFAT_H
20
21 #include <linux/buffer_head.h>
22 #include <linux/string.h>
23 #include <linux/types.h>
24 #include <linux/nls.h>
25 #include <linux/fs.h>
26 #include <linux/mutex.h>
27 #include <linux/ratelimit.h>
28 #include <linux/version.h>
29 #include <linux/kobject.h>
30 #include "api.h"
31
32 #ifdef CONFIG_SDFAT_DFR
33 #include "dfr.h"
34 #endif
35
36 /*
37 * sdfat error flags
38 */
39 #define SDFAT_ERRORS_CONT (1) /* ignore error and continue */
40 #define SDFAT_ERRORS_PANIC (2) /* panic on error */
41 #define SDFAT_ERRORS_RO (3) /* remount r/o on error */
42
43 /*
44 * sdfat allocator flags
45 */
46 #define SDFAT_ALLOC_DELAY (1) /* Delayed allocation */
47 #define SDFAT_ALLOC_SMART (2) /* Smart allocation */
48
49 /*
50 * sdfat allocator destination for smart allocation
51 */
52 #define ALLOC_NOWHERE (0)
53 #define ALLOC_COLD (1)
54 #define ALLOC_HOT (16)
55 #define ALLOC_COLD_ALIGNED (1)
56 #define ALLOC_COLD_PACKING (2)
57 #define ALLOC_COLD_SEQ (4)
58
59 /*
60 * sdfat nls lossy flag
61 */
62 #define NLS_NAME_NO_LOSSY (0x00) /* no lossy */
63 #define NLS_NAME_LOSSY (0x01) /* just detected incorrect filename(s) */
64 #define NLS_NAME_OVERLEN (0x02) /* the length is over than its limit */
65
66 /*
67 * sdfat common MACRO
68 */
69 #define CLUSTER_16(x) ((u16)((x) & 0xFFFFU))
70 #define CLUSTER_32(x) ((u32)((x) & 0xFFFFFFFFU))
71 #define CLUS_EOF CLUSTER_32(~0)
72 #define CLUS_BAD (0xFFFFFFF7U)
73 #define CLUS_FREE (0)
74 #define CLUS_BASE (2)
75 #define IS_CLUS_EOF(x) ((x) == CLUS_EOF)
76 #define IS_CLUS_BAD(x) ((x) == CLUS_BAD)
77 #define IS_CLUS_FREE(x) ((x) == CLUS_FREE)
78 #define IS_LAST_SECT_IN_CLUS(fsi, sec) \
79 ((((sec) - (fsi)->data_start_sector + 1) \
80 & ((1 << (fsi)->sect_per_clus_bits) - 1)) == 0)
81
82 #define CLUS_TO_SECT(fsi, x) \
83 ((((x) - CLUS_BASE) << (fsi)->sect_per_clus_bits) + (fsi)->data_start_sector)
84
85 #define SECT_TO_CLUS(fsi, sec) \
86 ((((sec) - (fsi)->data_start_sector) >> (fsi)->sect_per_clus_bits) + CLUS_BASE)
87
88 /* variables defined at sdfat.c */
89 extern const char *FS_TYPE_STR[];
90
91 enum {
92 FS_TYPE_AUTO,
93 FS_TYPE_EXFAT,
94 FS_TYPE_VFAT,
95 FS_TYPE_MAX
96 };
97
98 /*
99 * sdfat mount in-memory data
100 */
101 struct sdfat_mount_options {
102 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
103 kuid_t fs_uid;
104 kgid_t fs_gid;
105 #else /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) */
106 uid_t fs_uid;
107 gid_t fs_gid;
108 #endif
109 unsigned short fs_fmask;
110 unsigned short fs_dmask;
111 unsigned short allow_utime; /* permission for setting the [am]time */
112 unsigned short codepage; /* codepage for shortname conversions */
113 char *iocharset; /* charset for filename input/display */
114 struct {
115 unsigned int pack_ratio;
116 unsigned int sect_per_au;
117 unsigned int misaligned_sect;
118 } amap_opt; /* AMAP-related options (see amap.c) */
119
120 unsigned char utf8;
121 unsigned char casesensitive;
122 unsigned char adj_hidsect;
123 unsigned char tz_utc;
124 unsigned char improved_allocation;
125 unsigned char defrag;
126 unsigned char symlink; /* support symlink operation */
127 unsigned char errors; /* on error: continue, panic, remount-ro */
128 unsigned char discard; /* flag on if -o dicard specified and device support discard() */
129 unsigned char fs_type; /* fs_type that user specified */
130 unsigned short adj_req; /* support aligned mpage write */
131 };
132
133 #define SDFAT_HASH_BITS 8
134 #define SDFAT_HASH_SIZE (1UL << SDFAT_HASH_BITS)
135
136 /*
137 * SDFAT file system superblock in-memory data
138 */
139 struct sdfat_sb_info {
140 FS_INFO_T fsi; /* private filesystem info */
141
142 struct mutex s_vlock; /* volume lock */
143 int use_vmalloc;
144
145 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0)
146 int s_dirt;
147 struct mutex s_lock; /* superblock lock */
148 int write_super_queued; /* Write_super work is pending? */
149 struct delayed_work write_super_work; /* Work_queue data structrue for write_super() */
150 spinlock_t work_lock; /* Lock for WQ */
151 #endif
152 struct super_block *host_sb; /* sb pointer */
153 struct sdfat_mount_options options;
154 struct nls_table *nls_disk; /* Codepage used on disk */
155 struct nls_table *nls_io; /* Charset used for input and display */
156 struct ratelimit_state ratelimit;
157
158 spinlock_t inode_hash_lock;
159 struct hlist_head inode_hashtable[SDFAT_HASH_SIZE];
160 struct kobject sb_kobj;
161 #ifdef CONFIG_SDFAT_DBG_IOCTL
162 long debug_flags;
163 #endif /* CONFIG_SDFAT_DBG_IOCTL */
164
165 #ifdef CONFIG_SDFAT_DFR
166 struct defrag_info dfr_info;
167 struct completion dfr_complete;
168 unsigned int *dfr_new_clus;
169 int dfr_new_idx;
170 unsigned int *dfr_page_wb;
171 void **dfr_pagep;
172 unsigned int dfr_hint_clus;
173 unsigned int dfr_hint_idx;
174 int dfr_reserved_clus;
175
176 #ifdef CONFIG_SDFAT_DFR_DEBUG
177 int dfr_spo_flag;
178 #endif /* CONFIG_SDFAT_DFR_DEBUG */
179
180 #endif /* CONFIG_SDFAT_DFR */
181
182 #ifdef CONFIG_SDFAT_TRACE_IO
183 /* Statistics for allocator */
184 unsigned int stat_n_pages_written; /* # of written pages in total */
185 unsigned int stat_n_pages_added; /* # of added blocks in total */
186 unsigned int stat_n_bdev_pages_written; /* # of written pages owned by bdev inode */
187 unsigned int stat_n_pages_confused;
188 #endif
189 atomic_t stat_n_pages_queued; /* # of pages in the request queue (approx.) */
190 };
191
192 /*
193 * SDFAT file system inode in-memory data
194 */
195 struct sdfat_inode_info {
196 FILE_ID_T fid;
197 char *target;
198 /* NOTE: i_size_ondisk is 64bits, so must hold ->inode_lock to access */
199 loff_t i_size_ondisk; /* physically allocated size */
200 loff_t i_size_aligned; /* block-aligned i_size (used in cont_write_begin) */
201 loff_t i_pos; /* on-disk position of directory entry or 0 */
202 struct hlist_node i_hash_fat; /* hash by i_location */
203 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
204 struct rw_semaphore truncate_lock; /* protect bmap against truncate */
205 #endif
206 #ifdef CONFIG_SDFAT_DFR
207 struct defrag_info dfr_info;
208 #endif
209 struct inode vfs_inode;
210 };
211
212 /*
213 * FIXME : needs on-disk-slot in-memory data
214 */
215
216 /* static inline functons */
217 static inline const char *sdfat_get_vol_type_str(unsigned int type)
218 {
219 if (type == EXFAT)
220 return "exfat";
221 else if (type == FAT32)
222 return "vfat:32";
223 else if (type == FAT16)
224 return "vfat:16";
225 else if (type == FAT12)
226 return "vfat:12";
227
228 return "unknown";
229 }
230
231 static inline struct sdfat_sb_info *SDFAT_SB(struct super_block *sb)
232 {
233 return (struct sdfat_sb_info *)sb->s_fs_info;
234 }
235
236 static inline struct sdfat_inode_info *SDFAT_I(struct inode *inode)
237 {
238 return container_of(inode, struct sdfat_inode_info, vfs_inode);
239 }
240
241 /*
242 * If ->i_mode can't hold S_IWUGO (i.e. ATTR_RO), we use ->i_attrs to
243 * save ATTR_RO instead of ->i_mode.
244 *
245 * If it's directory and !sbi->options.rodir, ATTR_RO isn't read-only
246 * bit, it's just used as flag for app.
247 */
248 static inline int sdfat_mode_can_hold_ro(struct inode *inode)
249 {
250 struct sdfat_sb_info *sbi = SDFAT_SB(inode->i_sb);
251
252 if (S_ISDIR(inode->i_mode))
253 return 0;
254
255 if ((~sbi->options.fs_fmask) & S_IWUGO)
256 return 1;
257 return 0;
258 }
259
260 /*
261 * FIXME : needs to check symlink option.
262 */
263 /* Convert attribute bits and a mask to the UNIX mode. */
264 static inline mode_t sdfat_make_mode(struct sdfat_sb_info *sbi,
265 u32 attr, mode_t mode)
266 {
267 if ((attr & ATTR_READONLY) && !(attr & ATTR_SUBDIR))
268 mode &= ~S_IWUGO;
269
270 if (attr & ATTR_SUBDIR)
271 return (mode & ~sbi->options.fs_dmask) | S_IFDIR;
272 else if (attr & ATTR_SYMLINK)
273 return (mode & ~sbi->options.fs_dmask) | S_IFLNK;
274 else
275 return (mode & ~sbi->options.fs_fmask) | S_IFREG;
276 }
277
278 /* Return the FAT attribute byte for this inode */
279 static inline u32 sdfat_make_attr(struct inode *inode)
280 {
281 u32 attrs = SDFAT_I(inode)->fid.attr;
282
283 if (S_ISDIR(inode->i_mode))
284 attrs |= ATTR_SUBDIR;
285 if (sdfat_mode_can_hold_ro(inode) && !(inode->i_mode & S_IWUGO))
286 attrs |= ATTR_READONLY;
287 return attrs;
288 }
289
290 static inline void sdfat_save_attr(struct inode *inode, u32 attr)
291 {
292 if (sdfat_mode_can_hold_ro(inode))
293 SDFAT_I(inode)->fid.attr = attr & ATTR_RWMASK;
294 else
295 SDFAT_I(inode)->fid.attr = attr & (ATTR_RWMASK | ATTR_READONLY);
296 }
297
298 /* sdfat/statistics.c */
299 /* bigdata function */
300 #ifdef CONFIG_SDFAT_STATISTICS
301 extern int sdfat_statistics_init(struct kset *sdfat_kset);
302 extern void sdfat_statistics_uninit(void);
303 extern void sdfat_statistics_set_mnt(FS_INFO_T *fsi);
304 extern void sdfat_statistics_set_mkdir(u8 flags);
305 extern void sdfat_statistics_set_create(u8 flags);
306 extern void sdfat_statistics_set_rw(u8 flags, u32 clu_offset, s32 create);
307 extern void sdfat_statistics_set_trunc(u8 flags, CHAIN_T *clu);
308 extern void sdfat_statistics_set_vol_size(struct super_block *sb);
309 #else
310 static inline int sdfat_statistics_init(struct kset *sdfat_kset)
311 {
312 return 0;
313 }
314 static inline void sdfat_statistics_uninit(void) {};
315 static inline void sdfat_statistics_set_mnt(FS_INFO_T *fsi) {};
316 static inline void sdfat_statistics_set_mkdir(u8 flags) {};
317 static inline void sdfat_statistics_set_create(u8 flags) {};
318 static inline void sdfat_statistics_set_rw(u8 flags, u32 clu_offset, s32 create) {};
319 static inline void sdfat_statistics_set_trunc(u8 flags, CHAIN_T *clu) {};
320 static inline void sdfat_statistics_set_vol_size(struct super_block *sb) {};
321 #endif
322
323 /* sdfat/nls.c */
324 /* NLS management function */
325 s32 nls_cmp_sfn(struct super_block *sb, u8 *a, u8 *b);
326 s32 nls_cmp_uniname(struct super_block *sb, u16 *a, u16 *b);
327 s32 nls_uni16s_to_sfn(struct super_block *sb, UNI_NAME_T *p_uniname, DOS_NAME_T *p_dosname, s32 *p_lossy);
328 s32 nls_sfn_to_uni16s(struct super_block *sb, DOS_NAME_T *p_dosname, UNI_NAME_T *p_uniname);
329 s32 nls_uni16s_to_vfsname(struct super_block *sb, UNI_NAME_T *uniname, u8 *p_cstring, s32 len);
330 s32 nls_vfsname_to_uni16s(struct super_block *sb, const u8 *p_cstring,
331 const s32 len, UNI_NAME_T *uniname, s32 *p_lossy);
332
333 /* sdfat/mpage.c */
334 #ifdef CONFIG_SDFAT_ALIGNED_MPAGE_WRITE
335 int sdfat_mpage_writepages(struct address_space *mapping,
336 struct writeback_control *wbc, get_block_t *get_block);
337 #endif
338
339 /* sdfat/xattr.c */
340 #ifdef CONFIG_SDFAT_VIRTUAL_XATTR
341 void setup_sdfat_xattr_handler(struct super_block *sb);
342 extern int sdfat_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags);
343 extern ssize_t sdfat_getxattr(struct dentry *dentry, const char *name, void *value, size_t size);
344 extern ssize_t sdfat_listxattr(struct dentry *dentry, char *list, size_t size);
345 extern int sdfat_removexattr(struct dentry *dentry, const char *name);
346 #else
347 static inline void setup_sdfat_xattr_handler(struct super_block *sb) {};
348 #endif
349
350 /* sdfat/misc.c */
351 extern void
352 __sdfat_fs_error(struct super_block *sb, int report, const char *fmt, ...)
353 __printf(3, 4) __cold;
354 #define sdfat_fs_error(sb, fmt, args...) \
355 __sdfat_fs_error(sb, 1, fmt, ## args)
356 #define sdfat_fs_error_ratelimit(sb, fmt, args...) \
357 __sdfat_fs_error(sb, __ratelimit(&SDFAT_SB(sb)->ratelimit), fmt, ## args)
358 extern void
359 __sdfat_msg(struct super_block *sb, const char *lv, int st, const char *fmt, ...)
360 __printf(4, 5) __cold;
361 #define sdfat_msg(sb, lv, fmt, args...) \
362 __sdfat_msg(sb, lv, 0, fmt, ## args)
363 #define sdfat_log_msg(sb, lv, fmt, args...) \
364 __sdfat_msg(sb, lv, 1, fmt, ## args)
365 extern void sdfat_log_version(void);
366 extern void sdfat_time_fat2unix(struct sdfat_sb_info *sbi, struct timespec *ts,
367 DATE_TIME_T *tp);
368 extern void sdfat_time_unix2fat(struct sdfat_sb_info *sbi, struct timespec *ts,
369 DATE_TIME_T *tp);
370 extern TIMESTAMP_T *tm_now(struct sdfat_sb_info *sbi, TIMESTAMP_T *tm);
371
372 #ifdef CONFIG_SDFAT_DEBUG
373
374 #ifdef CONFIG_SDFAT_DBG_CAREFUL
375 void sdfat_debug_check_clusters(struct inode *inode);
376 #else
377 #define sdfat_debug_check_clusters(inode)
378 #endif /* CONFIG_SDFAT_DBG_CAREFUL */
379
380 #ifdef CONFIG_SDFAT_DBG_BUGON
381 #define sdfat_debug_bug_on(expr) BUG_ON(expr)
382 #else
383 #define sdfat_debug_bug_on(expr)
384 #endif
385
386 #ifdef CONFIG_SDFAT_DBG_WARNON
387 #define sdfat_debug_warn_on(expr) WARN_ON(expr)
388 #else
389 #define sdfat_debug_warn_on(expr)
390 #endif
391
392 #else /* CONFIG_SDFAT_DEBUG */
393
394 #define sdfat_debug_check_clusters(inode)
395 #define sdfat_debug_bug_on(expr)
396
397 #endif /* CONFIG_SDFAT_DEBUG */
398
399 #ifdef CONFIG_SDFAT_TRACE_ELAPSED_TIME
400 u32 sdfat_time_current_usec(struct timeval *tv);
401 extern struct timeval __t1;
402 extern struct timeval __t2;
403
404 #define TIME_GET(tv) sdfat_time_current_usec(tv)
405 #define TIME_START(s) sdfat_time_current_usec(s)
406 #define TIME_END(e) sdfat_time_current_usec(e)
407 #define TIME_ELAPSED(s, e) ((u32)(((e)->tv_sec - (s)->tv_sec) * 1000000 + \
408 ((e)->tv_usec - (s)->tv_usec)))
409 #define PRINT_TIME(n) pr_info("[SDFAT] Elapsed time %d = %d (usec)\n", n, (__t2 - __t1))
410 #else /* CONFIG_SDFAT_TRACE_ELAPSED_TIME */
411 #define TIME_GET(tv) (0)
412 #define TIME_START(s)
413 #define TIME_END(e)
414 #define TIME_ELAPSED(s, e) (0)
415 #define PRINT_TIME(n)
416 #endif /* CONFIG_SDFAT_TRACE_ELAPSED_TIME */
417
418 #define SDFAT_MSG_LV_NONE (0x00000000)
419 #define SDFAT_MSG_LV_ERR (0x00000001)
420 #define SDFAT_MSG_LV_INFO (0x00000002)
421 #define SDFAT_MSG_LV_DBG (0x00000003)
422 #define SDFAT_MSG_LV_MORE (0x00000004)
423 #define SDFAT_MSG_LV_TRACE (0x00000005)
424 #define SDFAT_MSG_LV_ALL (0x00000006)
425
426 #define SDFAT_MSG_LEVEL SDFAT_MSG_LV_INFO
427
428 #define SDFAT_TAG_NAME "SDFAT"
429 #define __S(x) #x
430 #define _S(x) __S(x)
431
432 extern void __sdfat_dmsg(int level, const char *fmt, ...) __printf(2, 3) __cold;
433
434 #define SDFAT_EMSG_T(level, ...) \
435 __sdfat_dmsg(level, KERN_ERR "[" SDFAT_TAG_NAME "] [" _S(__FILE__) "(" _S(__LINE__) ")] " __VA_ARGS__)
436 #define SDFAT_DMSG_T(level, ...) \
437 __sdfat_dmsg(level, KERN_INFO "[" SDFAT_TAG_NAME "] " __VA_ARGS__)
438
439 #define SDFAT_EMSG(...) SDFAT_EMSG_T(SDFAT_MSG_LV_ERR, __VA_ARGS__)
440 #define SDFAT_IMSG(...) SDFAT_DMSG_T(SDFAT_MSG_LV_INFO, __VA_ARGS__)
441 #define SDFAT_DMSG(...) SDFAT_DMSG_T(SDFAT_MSG_LV_DBG, __VA_ARGS__)
442 #define SDFAT_MMSG(...) SDFAT_DMSG_T(SDFAT_MSG_LV_MORE, __VA_ARGS__)
443 #define SDFAT_TMSG(...) SDFAT_DMSG_T(SDFAT_MSG_LV_TRACE, __VA_ARGS__)
444
445 #define EMSG(...)
446 #define IMSG(...)
447 #define DMSG(...)
448 #define MMSG(...)
449 #define TMSG(...)
450
451 #define EMSG_VAR(exp)
452 #define IMSG_VAR(exp)
453 #define DMSG_VAR(exp)
454 #define MMSG_VAR(exp)
455 #define TMSG_VAR(exp)
456
457 #ifdef CONFIG_SDFAT_DBG_MSG
458
459
460 #if (SDFAT_MSG_LEVEL >= SDFAT_MSG_LV_ERR)
461 #undef EMSG
462 #undef EMSG_VAR
463 #define EMSG(...) SDFAT_EMSG(__VA_ARGS__)
464 #define EMSG_VAR(exp) exp
465 #endif
466
467 #if (SDFAT_MSG_LEVEL >= SDFAT_MSG_LV_INFO)
468 #undef IMSG
469 #undef IMSG_VAR
470 #define IMSG(...) SDFAT_IMSG(__VA_ARGS__)
471 #define IMSG_VAR(exp) exp
472 #endif
473
474 #if (SDFAT_MSG_LEVEL >= SDFAT_MSG_LV_DBG)
475 #undef DMSG
476 #undef DMSG_VAR
477 #define DMSG(...) SDFAT_DMSG(__VA_ARGS__)
478 #define DMSG_VAR(exp) exp
479 #endif
480
481 #if (SDFAT_MSG_LEVEL >= SDFAT_MSG_LV_MORE)
482 #undef MMSG
483 #undef MMSG_VAR
484 #define MMSG(...) SDFAT_MMSG(__VA_ARGS__)
485 #define MMSG_VAR(exp) exp
486 #endif
487
488 /* should replace with trace function */
489 #if (SDFAT_MSG_LEVEL >= SDFAT_MSG_LV_TRACE)
490 #undef TMSG
491 #undef TMSG_VAR
492 #define TMSG(...) SDFAT_TMSG(__VA_ARGS__)
493 #define TMSG_VAR(exp) exp
494 #endif
495
496 #endif /* CONFIG_SDFAT_DBG_MSG */
497
498
499 #define ASSERT(expr) { \
500 if (!(expr)) { \
501 pr_err("Assertion failed! %s\n", #expr); \
502 BUG_ON(1); \
503 } \
504 }
505
506 #endif /* !_SDFAT_H */
507