| /* |
| * 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_H |
| #define _SDFAT_H |
| |
| #include <linux/buffer_head.h> |
| #include <linux/string.h> |
| #include <linux/types.h> |
| #include <linux/nls.h> |
| #include <linux/fs.h> |
| #include <linux/mutex.h> |
| #include <linux/ratelimit.h> |
| #include <linux/version.h> |
| #include <linux/kobject.h> |
| #include "api.h" |
| |
| #ifdef CONFIG_SDFAT_DFR |
| #include "dfr.h" |
| #endif |
| |
| /* |
| * sdfat error flags |
| */ |
| #define SDFAT_ERRORS_CONT (1) /* ignore error and continue */ |
| #define SDFAT_ERRORS_PANIC (2) /* panic on error */ |
| #define SDFAT_ERRORS_RO (3) /* remount r/o on error */ |
| |
| /* |
| * sdfat allocator flags |
| */ |
| #define SDFAT_ALLOC_DELAY (1) /* Delayed allocation */ |
| #define SDFAT_ALLOC_SMART (2) /* Smart allocation */ |
| |
| /* |
| * sdfat allocator destination for smart allocation |
| */ |
| #define ALLOC_NOWHERE (0) |
| #define ALLOC_COLD (1) |
| #define ALLOC_HOT (16) |
| #define ALLOC_COLD_ALIGNED (1) |
| #define ALLOC_COLD_PACKING (2) |
| #define ALLOC_COLD_SEQ (4) |
| |
| /* |
| * sdfat nls lossy flag |
| */ |
| #define NLS_NAME_NO_LOSSY (0x00) /* no lossy */ |
| #define NLS_NAME_LOSSY (0x01) /* just detected incorrect filename(s) */ |
| #define NLS_NAME_OVERLEN (0x02) /* the length is over than its limit */ |
| |
| /* |
| * sdfat common MACRO |
| */ |
| #define CLUSTER_16(x) ((u16)((x) & 0xFFFFU)) |
| #define CLUSTER_32(x) ((u32)((x) & 0xFFFFFFFFU)) |
| #define CLUS_EOF CLUSTER_32(~0) |
| #define CLUS_BAD (0xFFFFFFF7U) |
| #define CLUS_FREE (0) |
| #define CLUS_BASE (2) |
| #define IS_CLUS_EOF(x) ((x) == CLUS_EOF) |
| #define IS_CLUS_BAD(x) ((x) == CLUS_BAD) |
| #define IS_CLUS_FREE(x) ((x) == CLUS_FREE) |
| #define IS_LAST_SECT_IN_CLUS(fsi, sec) \ |
| ((((sec) - (fsi)->data_start_sector + 1) \ |
| & ((1 << (fsi)->sect_per_clus_bits) - 1)) == 0) |
| |
| #define CLUS_TO_SECT(fsi, x) \ |
| ((((unsigned long long)(x) - CLUS_BASE) << (fsi)->sect_per_clus_bits) + (fsi)->data_start_sector) |
| |
| #define SECT_TO_CLUS(fsi, sec) \ |
| ((u32)((((sec) - (fsi)->data_start_sector) >> (fsi)->sect_per_clus_bits) + CLUS_BASE)) |
| |
| /* variables defined at sdfat.c */ |
| extern const char *FS_TYPE_STR[]; |
| |
| enum { |
| FS_TYPE_AUTO, |
| FS_TYPE_EXFAT, |
| FS_TYPE_VFAT, |
| FS_TYPE_MAX |
| }; |
| |
| /* |
| * sdfat mount in-memory data |
| */ |
| struct sdfat_mount_options { |
| #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0) |
| kuid_t fs_uid; |
| kgid_t fs_gid; |
| #else /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) */ |
| uid_t fs_uid; |
| gid_t fs_gid; |
| #endif |
| unsigned short fs_fmask; |
| unsigned short fs_dmask; |
| unsigned short allow_utime; /* permission for setting the [am]time */ |
| unsigned short codepage; /* codepage for shortname conversions */ |
| char *iocharset; /* charset for filename input/display */ |
| struct { |
| unsigned int pack_ratio; |
| unsigned int sect_per_au; |
| unsigned int misaligned_sect; |
| } amap_opt; /* AMAP-related options (see amap.c) */ |
| |
| unsigned char utf8; |
| unsigned char casesensitive; |
| unsigned char adj_hidsect; |
| unsigned char tz_utc; |
| unsigned char improved_allocation; |
| unsigned char defrag; |
| unsigned char symlink; /* support symlink operation */ |
| unsigned char errors; /* on error: continue, panic, remount-ro */ |
| unsigned char discard; /* flag on if -o dicard specified and device support discard() */ |
| unsigned char fs_type; /* fs_type that user specified */ |
| unsigned short adj_req; /* support aligned mpage write */ |
| }; |
| |
| #define SDFAT_HASH_BITS 8 |
| #define SDFAT_HASH_SIZE (1UL << SDFAT_HASH_BITS) |
| |
| /* |
| * SDFAT file system superblock in-memory data |
| */ |
| struct sdfat_sb_info { |
| FS_INFO_T fsi; /* private filesystem info */ |
| |
| struct mutex s_vlock; /* volume lock */ |
| int use_vmalloc; |
| |
| #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) |
| struct rcu_head rcu; |
| #endif |
| #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0) |
| int s_dirt; |
| struct mutex s_lock; /* superblock lock */ |
| int write_super_queued; /* Write_super work is pending? */ |
| struct delayed_work write_super_work; /* Work_queue data structrue for write_super() */ |
| spinlock_t work_lock; /* Lock for WQ */ |
| #endif |
| struct super_block *host_sb; /* sb pointer */ |
| struct sdfat_mount_options options; |
| struct nls_table *nls_disk; /* Codepage used on disk */ |
| struct nls_table *nls_io; /* Charset used for input and display */ |
| struct ratelimit_state ratelimit; |
| |
| spinlock_t inode_hash_lock; |
| struct hlist_head inode_hashtable[SDFAT_HASH_SIZE]; |
| struct kobject sb_kobj; |
| #ifdef CONFIG_SDFAT_DBG_IOCTL |
| long debug_flags; |
| #endif /* CONFIG_SDFAT_DBG_IOCTL */ |
| |
| #ifdef CONFIG_SDFAT_DFR |
| struct defrag_info dfr_info; |
| struct completion dfr_complete; |
| unsigned int *dfr_new_clus; |
| int dfr_new_idx; |
| unsigned int *dfr_page_wb; |
| void **dfr_pagep; |
| unsigned int dfr_hint_clus; |
| unsigned int dfr_hint_idx; |
| int dfr_reserved_clus; |
| |
| #ifdef CONFIG_SDFAT_DFR_DEBUG |
| int dfr_spo_flag; |
| #endif /* CONFIG_SDFAT_DFR_DEBUG */ |
| |
| #endif /* CONFIG_SDFAT_DFR */ |
| |
| #ifdef CONFIG_SDFAT_TRACE_IO |
| /* Statistics for allocator */ |
| unsigned int stat_n_pages_written; /* # of written pages in total */ |
| unsigned int stat_n_pages_added; /* # of added blocks in total */ |
| unsigned int stat_n_bdev_pages_written; /* # of written pages owned by bdev inode */ |
| unsigned int stat_n_pages_confused; |
| #endif |
| atomic_t stat_n_pages_queued; /* # of pages in the request queue (approx.) */ |
| }; |
| |
| /* |
| * SDFAT file system inode in-memory data |
| */ |
| struct sdfat_inode_info { |
| FILE_ID_T fid; |
| char *target; |
| /* NOTE: i_size_ondisk is 64bits, so must hold ->inode_lock to access */ |
| loff_t i_size_ondisk; /* physically allocated size */ |
| loff_t i_size_aligned; /* block-aligned i_size (used in cont_write_begin) */ |
| loff_t i_pos; /* on-disk position of directory entry or 0 */ |
| struct hlist_node i_hash_fat; /* hash by i_location */ |
| #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) |
| struct rw_semaphore truncate_lock; /* protect bmap against truncate */ |
| #endif |
| #ifdef CONFIG_SDFAT_DFR |
| struct defrag_info dfr_info; |
| #endif |
| struct inode vfs_inode; |
| }; |
| |
| #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) |
| typedef struct timespec64 sdfat_timespec_t; |
| #else /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 18, 0) */ |
| typedef struct timespec sdfat_timespec_t; |
| #endif |
| |
| |
| #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) |
| |
| #else /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) */ |
| /* |
| * sb->s_flags. Note that these mirror the equivalent MS_* flags where |
| * represented in both. |
| */ |
| #define SB_RDONLY 1 /* Mount read-only */ |
| #define SB_NODIRATIME 2048 /* Do not update directory access times */ |
| static inline bool sb_rdonly(const struct super_block *sb) |
| { |
| return sb->s_flags & MS_RDONLY; |
| } |
| #endif |
| |
| #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) |
| /* EMPTY */ |
| #else |
| static inline sdfat_timespec_t current_time(struct inode *inode) |
| { |
| return CURRENT_TIME_SEC; |
| } |
| #endif |
| /* |
| * FIXME : needs on-disk-slot in-memory data |
| */ |
| |
| /* static inline functons */ |
| static inline const char *sdfat_get_vol_type_str(unsigned int type) |
| { |
| if (type == EXFAT) |
| return "exfat"; |
| else if (type == FAT32) |
| return "vfat:32"; |
| else if (type == FAT16) |
| return "vfat:16"; |
| else if (type == FAT12) |
| return "vfat:12"; |
| |
| return "unknown"; |
| } |
| |
| static inline struct sdfat_sb_info *SDFAT_SB(struct super_block *sb) |
| { |
| return (struct sdfat_sb_info *)sb->s_fs_info; |
| } |
| |
| static inline struct sdfat_inode_info *SDFAT_I(struct inode *inode) |
| { |
| return container_of(inode, struct sdfat_inode_info, vfs_inode); |
| } |
| |
| /* |
| * If ->i_mode can't hold S_IWUGO (i.e. ATTR_RO), we use ->i_attrs to |
| * save ATTR_RO instead of ->i_mode. |
| * |
| * If it's directory and !sbi->options.rodir, ATTR_RO isn't read-only |
| * bit, it's just used as flag for app. |
| */ |
| static inline int sdfat_mode_can_hold_ro(struct inode *inode) |
| { |
| struct sdfat_sb_info *sbi = SDFAT_SB(inode->i_sb); |
| |
| if (S_ISDIR(inode->i_mode)) |
| return 0; |
| |
| if ((~sbi->options.fs_fmask) & S_IWUGO) |
| return 1; |
| return 0; |
| } |
| |
| /* |
| * FIXME : needs to check symlink option. |
| */ |
| /* Convert attribute bits and a mask to the UNIX mode. */ |
| static inline mode_t sdfat_make_mode(struct sdfat_sb_info *sbi, |
| u32 attr, mode_t mode) |
| { |
| if ((attr & ATTR_READONLY) && !(attr & ATTR_SUBDIR)) |
| mode &= ~S_IWUGO; |
| |
| if (attr & ATTR_SUBDIR) |
| return (mode & ~sbi->options.fs_dmask) | S_IFDIR; |
| else if (attr & ATTR_SYMLINK) |
| return (mode & ~sbi->options.fs_dmask) | S_IFLNK; |
| else |
| return (mode & ~sbi->options.fs_fmask) | S_IFREG; |
| } |
| |
| /* Return the FAT attribute byte for this inode */ |
| static inline u32 sdfat_make_attr(struct inode *inode) |
| { |
| u32 attrs = SDFAT_I(inode)->fid.attr; |
| |
| if (S_ISDIR(inode->i_mode)) |
| attrs |= ATTR_SUBDIR; |
| if (sdfat_mode_can_hold_ro(inode) && !(inode->i_mode & S_IWUGO)) |
| attrs |= ATTR_READONLY; |
| return attrs; |
| } |
| |
| static inline void sdfat_save_attr(struct inode *inode, u32 attr) |
| { |
| if (sdfat_mode_can_hold_ro(inode)) |
| SDFAT_I(inode)->fid.attr = attr & ATTR_RWMASK; |
| else |
| SDFAT_I(inode)->fid.attr = attr & (ATTR_RWMASK | ATTR_READONLY); |
| } |
| |
| /* sdfat/statistics.c */ |
| /* bigdata function */ |
| #ifdef CONFIG_SDFAT_STATISTICS |
| extern int sdfat_statistics_init(struct kset *sdfat_kset); |
| extern void sdfat_statistics_uninit(void); |
| extern void sdfat_statistics_set_mnt(FS_INFO_T *fsi); |
| extern void sdfat_statistics_set_mnt_ro(void); |
| extern void sdfat_statistics_set_mkdir(u8 flags); |
| extern void sdfat_statistics_set_create(u8 flags); |
| extern void sdfat_statistics_set_rw(u8 flags, u32 clu_offset, s32 create); |
| extern void sdfat_statistics_set_trunc(u8 flags, CHAIN_T *clu); |
| extern void sdfat_statistics_set_vol_size(struct super_block *sb); |
| #else |
| static inline int sdfat_statistics_init(struct kset *sdfat_kset) |
| { |
| return 0; |
| } |
| static inline void sdfat_statistics_uninit(void) {}; |
| static inline void sdfat_statistics_set_mnt(FS_INFO_T *fsi) {}; |
| static inline void sdfat_statistics_set_mnt_ro(void) {}; |
| static inline void sdfat_statistics_set_mkdir(u8 flags) {}; |
| static inline void sdfat_statistics_set_create(u8 flags) {}; |
| static inline void sdfat_statistics_set_rw(u8 flags, u32 clu_offset, s32 create) {}; |
| static inline void sdfat_statistics_set_trunc(u8 flags, CHAIN_T *clu) {}; |
| static inline void sdfat_statistics_set_vol_size(struct super_block *sb) {}; |
| #endif |
| |
| /* sdfat/nls.c */ |
| /* NLS management function */ |
| s32 nls_cmp_sfn(struct super_block *sb, u8 *a, u8 *b); |
| s32 nls_cmp_uniname(struct super_block *sb, u16 *a, u16 *b); |
| s32 nls_uni16s_to_sfn(struct super_block *sb, UNI_NAME_T *p_uniname, DOS_NAME_T *p_dosname, s32 *p_lossy); |
| s32 nls_sfn_to_uni16s(struct super_block *sb, DOS_NAME_T *p_dosname, UNI_NAME_T *p_uniname); |
| s32 nls_uni16s_to_vfsname(struct super_block *sb, UNI_NAME_T *uniname, u8 *p_cstring, s32 len); |
| s32 nls_vfsname_to_uni16s(struct super_block *sb, const u8 *p_cstring, |
| const s32 len, UNI_NAME_T *uniname, s32 *p_lossy); |
| |
| /* sdfat/mpage.c */ |
| #ifdef CONFIG_SDFAT_ALIGNED_MPAGE_WRITE |
| int sdfat_mpage_writepages(struct address_space *mapping, |
| struct writeback_control *wbc, get_block_t *get_block); |
| #endif |
| |
| /* sdfat/xattr.c */ |
| #ifdef CONFIG_SDFAT_VIRTUAL_XATTR |
| void setup_sdfat_xattr_handler(struct super_block *sb); |
| extern int sdfat_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags); |
| extern ssize_t sdfat_getxattr(struct dentry *dentry, const char *name, void *value, size_t size); |
| extern ssize_t sdfat_listxattr(struct dentry *dentry, char *list, size_t size); |
| extern int sdfat_removexattr(struct dentry *dentry, const char *name); |
| #else |
| static inline void setup_sdfat_xattr_handler(struct super_block *sb) {}; |
| #endif |
| |
| /* sdfat/misc.c */ |
| #ifdef CONFIG_SDFAT_UEVENT |
| extern int sdfat_uevent_init(struct kset *sdfat_kset); |
| extern void sdfat_uevent_uninit(void); |
| extern void sdfat_uevent_ro_remount(struct super_block *sb); |
| #else |
| static inline int sdfat_uevent_init(struct kset *sdfat_kset) |
| { |
| return 0; |
| } |
| static inline void sdfat_uevent_uninit(void) {}; |
| static inline void sdfat_uevent_ro_remount(struct super_block *sb) {}; |
| #endif |
| extern void |
| __sdfat_fs_error(struct super_block *sb, int report, const char *fmt, ...) |
| __printf(3, 4) __cold; |
| #define sdfat_fs_error(sb, fmt, args...) \ |
| __sdfat_fs_error(sb, 1, fmt, ## args) |
| #define sdfat_fs_error_ratelimit(sb, fmt, args...) \ |
| __sdfat_fs_error(sb, __ratelimit(&SDFAT_SB(sb)->ratelimit), fmt, ## args) |
| extern void |
| __sdfat_msg(struct super_block *sb, const char *lv, int st, const char *fmt, ...) |
| __printf(4, 5) __cold; |
| #define sdfat_msg(sb, lv, fmt, args...) \ |
| __sdfat_msg(sb, lv, 0, fmt, ## args) |
| #define sdfat_log_msg(sb, lv, fmt, args...) \ |
| __sdfat_msg(sb, lv, 1, fmt, ## args) |
| extern void sdfat_log_version(void); |
| extern void sdfat_time_fat2unix(struct sdfat_sb_info *sbi, sdfat_timespec_t *ts, |
| DATE_TIME_T *tp); |
| extern void sdfat_time_unix2fat(struct sdfat_sb_info *sbi, sdfat_timespec_t *ts, |
| DATE_TIME_T *tp); |
| extern TIMESTAMP_T *tm_now(struct inode *inode, TIMESTAMP_T *tm); |
| static inline TIMESTAMP_T *tm_now_sb(struct super_block *sb, TIMESTAMP_T *tm) |
| { |
| struct inode fake_inode; |
| |
| fake_inode.i_sb = sb; |
| return tm_now(&fake_inode, tm); |
| } |
| |
| #ifdef CONFIG_SDFAT_DEBUG |
| |
| #ifdef CONFIG_SDFAT_DBG_CAREFUL |
| void sdfat_debug_check_clusters(struct inode *inode); |
| #else |
| #define sdfat_debug_check_clusters(inode) |
| #endif /* CONFIG_SDFAT_DBG_CAREFUL */ |
| |
| #ifdef CONFIG_SDFAT_DBG_BUGON |
| #define sdfat_debug_bug_on(expr) BUG_ON(expr) |
| #else |
| #define sdfat_debug_bug_on(expr) |
| #endif |
| |
| #ifdef CONFIG_SDFAT_DBG_WARNON |
| #define sdfat_debug_warn_on(expr) WARN_ON(expr) |
| #else |
| #define sdfat_debug_warn_on(expr) |
| #endif |
| |
| #else /* CONFIG_SDFAT_DEBUG */ |
| |
| #define sdfat_debug_check_clusters(inode) |
| #define sdfat_debug_bug_on(expr) |
| |
| #endif /* CONFIG_SDFAT_DEBUG */ |
| |
| #ifdef CONFIG_SDFAT_TRACE_ELAPSED_TIME |
| u32 sdfat_time_current_usec(struct timeval *tv); |
| extern struct timeval __t1; |
| extern struct timeval __t2; |
| |
| #define TIME_GET(tv) sdfat_time_current_usec(tv) |
| #define TIME_START(s) sdfat_time_current_usec(s) |
| #define TIME_END(e) sdfat_time_current_usec(e) |
| #define TIME_ELAPSED(s, e) ((u32)(((e)->tv_sec - (s)->tv_sec) * 1000000 + \ |
| ((e)->tv_usec - (s)->tv_usec))) |
| #define PRINT_TIME(n) pr_info("[SDFAT] Elapsed time %d = %d (usec)\n", n, (__t2 - __t1)) |
| #else /* CONFIG_SDFAT_TRACE_ELAPSED_TIME */ |
| #define TIME_GET(tv) (0) |
| #define TIME_START(s) |
| #define TIME_END(e) |
| #define TIME_ELAPSED(s, e) (0) |
| #define PRINT_TIME(n) |
| #endif /* CONFIG_SDFAT_TRACE_ELAPSED_TIME */ |
| |
| #define SDFAT_MSG_LV_NONE (0x00000000) |
| #define SDFAT_MSG_LV_ERR (0x00000001) |
| #define SDFAT_MSG_LV_INFO (0x00000002) |
| #define SDFAT_MSG_LV_DBG (0x00000003) |
| #define SDFAT_MSG_LV_MORE (0x00000004) |
| #define SDFAT_MSG_LV_TRACE (0x00000005) |
| #define SDFAT_MSG_LV_ALL (0x00000006) |
| |
| #define SDFAT_MSG_LEVEL SDFAT_MSG_LV_INFO |
| |
| #define SDFAT_TAG_NAME "SDFAT" |
| #define __S(x) #x |
| #define _S(x) __S(x) |
| |
| extern void __sdfat_dmsg(int level, const char *fmt, ...) __printf(2, 3) __cold; |
| |
| #define SDFAT_EMSG_T(level, ...) \ |
| __sdfat_dmsg(level, KERN_ERR "[" SDFAT_TAG_NAME "] [" _S(__FILE__) "(" _S(__LINE__) ")] " __VA_ARGS__) |
| #define SDFAT_DMSG_T(level, ...) \ |
| __sdfat_dmsg(level, KERN_INFO "[" SDFAT_TAG_NAME "] " __VA_ARGS__) |
| |
| #define SDFAT_EMSG(...) SDFAT_EMSG_T(SDFAT_MSG_LV_ERR, __VA_ARGS__) |
| #define SDFAT_IMSG(...) SDFAT_DMSG_T(SDFAT_MSG_LV_INFO, __VA_ARGS__) |
| #define SDFAT_DMSG(...) SDFAT_DMSG_T(SDFAT_MSG_LV_DBG, __VA_ARGS__) |
| #define SDFAT_MMSG(...) SDFAT_DMSG_T(SDFAT_MSG_LV_MORE, __VA_ARGS__) |
| #define SDFAT_TMSG(...) SDFAT_DMSG_T(SDFAT_MSG_LV_TRACE, __VA_ARGS__) |
| |
| #define EMSG(...) |
| #define IMSG(...) |
| #define DMSG(...) |
| #define MMSG(...) |
| #define TMSG(...) |
| |
| #define EMSG_VAR(exp) |
| #define IMSG_VAR(exp) |
| #define DMSG_VAR(exp) |
| #define MMSG_VAR(exp) |
| #define TMSG_VAR(exp) |
| |
| #ifdef CONFIG_SDFAT_DBG_MSG |
| |
| |
| #if (SDFAT_MSG_LEVEL >= SDFAT_MSG_LV_ERR) |
| #undef EMSG |
| #undef EMSG_VAR |
| #define EMSG(...) SDFAT_EMSG(__VA_ARGS__) |
| #define EMSG_VAR(exp) exp |
| #endif |
| |
| #if (SDFAT_MSG_LEVEL >= SDFAT_MSG_LV_INFO) |
| #undef IMSG |
| #undef IMSG_VAR |
| #define IMSG(...) SDFAT_IMSG(__VA_ARGS__) |
| #define IMSG_VAR(exp) exp |
| #endif |
| |
| #if (SDFAT_MSG_LEVEL >= SDFAT_MSG_LV_DBG) |
| #undef DMSG |
| #undef DMSG_VAR |
| #define DMSG(...) SDFAT_DMSG(__VA_ARGS__) |
| #define DMSG_VAR(exp) exp |
| #endif |
| |
| #if (SDFAT_MSG_LEVEL >= SDFAT_MSG_LV_MORE) |
| #undef MMSG |
| #undef MMSG_VAR |
| #define MMSG(...) SDFAT_MMSG(__VA_ARGS__) |
| #define MMSG_VAR(exp) exp |
| #endif |
| |
| /* should replace with trace function */ |
| #if (SDFAT_MSG_LEVEL >= SDFAT_MSG_LV_TRACE) |
| #undef TMSG |
| #undef TMSG_VAR |
| #define TMSG(...) SDFAT_TMSG(__VA_ARGS__) |
| #define TMSG_VAR(exp) exp |
| #endif |
| |
| #endif /* CONFIG_SDFAT_DBG_MSG */ |
| |
| |
| #define ASSERT(expr) { \ |
| if (!(expr)) { \ |
| pr_err("Assertion failed! %s\n", #expr); \ |
| BUG_ON(1); \ |
| } \ |
| } |
| |
| #endif /* !_SDFAT_H */ |
| |