123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563 |
- /*
- * 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)
- #define sdfat_debug_warn_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 */
|