fatfs: ratelimit corruption report
Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
f40c396a9a
commit
aaa04b4875
|
@ -242,7 +242,8 @@ int fat_get_cluster(struct inode *inode, int cluster, int *fclus, int *dclus)
|
||||||
while (*fclus < cluster) {
|
while (*fclus < cluster) {
|
||||||
/* prevent the infinite loop of cluster chain */
|
/* prevent the infinite loop of cluster chain */
|
||||||
if (*fclus > limit) {
|
if (*fclus > limit) {
|
||||||
fat_fs_error(sb, "%s: detected the cluster chain loop"
|
fat_fs_error_ratelimit(sb,
|
||||||
|
"%s: detected the cluster chain loop"
|
||||||
" (i_pos %lld)", __func__,
|
" (i_pos %lld)", __func__,
|
||||||
MSDOS_I(inode)->i_pos);
|
MSDOS_I(inode)->i_pos);
|
||||||
nr = -EIO;
|
nr = -EIO;
|
||||||
|
@ -253,7 +254,7 @@ int fat_get_cluster(struct inode *inode, int cluster, int *fclus, int *dclus)
|
||||||
if (nr < 0)
|
if (nr < 0)
|
||||||
goto out;
|
goto out;
|
||||||
else if (nr == FAT_ENT_FREE) {
|
else if (nr == FAT_ENT_FREE) {
|
||||||
fat_fs_error(sb, "%s: invalid cluster chain"
|
fat_fs_error_ratelimit(sb, "%s: invalid cluster chain"
|
||||||
" (i_pos %lld)", __func__,
|
" (i_pos %lld)", __func__,
|
||||||
MSDOS_I(inode)->i_pos);
|
MSDOS_I(inode)->i_pos);
|
||||||
nr = -EIO;
|
nr = -EIO;
|
||||||
|
|
12
fs/fat/fat.h
12
fs/fat/fat.h
|
@ -6,6 +6,7 @@
|
||||||
#include <linux/nls.h>
|
#include <linux/nls.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
|
#include <linux/ratelimit.h>
|
||||||
#include <linux/msdos_fs.h>
|
#include <linux/msdos_fs.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -82,6 +83,8 @@ struct msdos_sb_info {
|
||||||
struct fatent_operations *fatent_ops;
|
struct fatent_operations *fatent_ops;
|
||||||
struct inode *fat_inode;
|
struct inode *fat_inode;
|
||||||
|
|
||||||
|
struct ratelimit_state ratelimit;
|
||||||
|
|
||||||
spinlock_t inode_hash_lock;
|
spinlock_t inode_hash_lock;
|
||||||
struct hlist_head inode_hashtable[FAT_HASH_SIZE];
|
struct hlist_head inode_hashtable[FAT_HASH_SIZE];
|
||||||
};
|
};
|
||||||
|
@ -322,8 +325,13 @@ extern int fat_fill_super(struct super_block *sb, void *data, int silent,
|
||||||
extern int fat_flush_inodes(struct super_block *sb, struct inode *i1,
|
extern int fat_flush_inodes(struct super_block *sb, struct inode *i1,
|
||||||
struct inode *i2);
|
struct inode *i2);
|
||||||
/* fat/misc.c */
|
/* fat/misc.c */
|
||||||
extern void fat_fs_error(struct super_block *s, const char *fmt, ...)
|
extern void
|
||||||
__attribute__ ((format (printf, 2, 3))) __cold;
|
__fat_fs_error(struct super_block *s, int report, const char *fmt, ...)
|
||||||
|
__attribute__ ((format (printf, 3, 4))) __cold;
|
||||||
|
#define fat_fs_error(s, fmt, args...) \
|
||||||
|
__fat_fs_error(s, 1, fmt , ## args)
|
||||||
|
#define fat_fs_error_ratelimit(s, fmt, args...) \
|
||||||
|
__fat_fs_error(s, __ratelimit(&MSDOS_SB(s)->ratelimit), fmt , ## args)
|
||||||
extern int fat_clusters_flush(struct super_block *sb);
|
extern int fat_clusters_flush(struct super_block *sb);
|
||||||
extern int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster);
|
extern int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster);
|
||||||
extern void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec *ts,
|
extern void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec *ts,
|
||||||
|
|
|
@ -1250,6 +1250,8 @@ int fat_fill_super(struct super_block *sb, void *data, int silent,
|
||||||
sb->s_op = &fat_sops;
|
sb->s_op = &fat_sops;
|
||||||
sb->s_export_op = &fat_export_ops;
|
sb->s_export_op = &fat_export_ops;
|
||||||
sbi->dir_ops = fs_dir_inode_ops;
|
sbi->dir_ops = fs_dir_inode_ops;
|
||||||
|
ratelimit_state_init(&sbi->ratelimit, DEFAULT_RATELIMIT_INTERVAL,
|
||||||
|
DEFAULT_RATELIMIT_BURST);
|
||||||
|
|
||||||
error = parse_options(data, isvfat, silent, &debug, &sbi->options);
|
error = parse_options(data, isvfat, silent, &debug, &sbi->options);
|
||||||
if (error)
|
if (error)
|
||||||
|
|
|
@ -20,11 +20,12 @@
|
||||||
* In case the file system is remounted read-only, it can be made writable
|
* In case the file system is remounted read-only, it can be made writable
|
||||||
* again by remounting it.
|
* again by remounting it.
|
||||||
*/
|
*/
|
||||||
void fat_fs_error(struct super_block *s, const char *fmt, ...)
|
void __fat_fs_error(struct super_block *s, int report, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
struct fat_mount_options *opts = &MSDOS_SB(s)->options;
|
struct fat_mount_options *opts = &MSDOS_SB(s)->options;
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
|
if (report) {
|
||||||
printk(KERN_ERR "FAT: Filesystem error (dev %s)\n", s->s_id);
|
printk(KERN_ERR "FAT: Filesystem error (dev %s)\n", s->s_id);
|
||||||
|
|
||||||
printk(KERN_ERR " ");
|
printk(KERN_ERR " ");
|
||||||
|
@ -32,15 +33,16 @@ void fat_fs_error(struct super_block *s, const char *fmt, ...)
|
||||||
vprintk(fmt, args);
|
vprintk(fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
printk("\n");
|
printk("\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (opts->errors == FAT_ERRORS_PANIC)
|
if (opts->errors == FAT_ERRORS_PANIC)
|
||||||
panic(" FAT fs panic from previous error\n");
|
panic("FAT: fs panic from previous error\n");
|
||||||
else if (opts->errors == FAT_ERRORS_RO && !(s->s_flags & MS_RDONLY)) {
|
else if (opts->errors == FAT_ERRORS_RO && !(s->s_flags & MS_RDONLY)) {
|
||||||
s->s_flags |= MS_RDONLY;
|
s->s_flags |= MS_RDONLY;
|
||||||
printk(KERN_ERR " File system has been set read-only\n");
|
printk(KERN_ERR "FAT: Filesystem has been set read-only\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(fat_fs_error);
|
EXPORT_SYMBOL_GPL(__fat_fs_error);
|
||||||
|
|
||||||
/* Flushes the number of free clusters on FAT32 */
|
/* Flushes the number of free clusters on FAT32 */
|
||||||
/* XXX: Need to write one per FSINFO block. Currently only writes 1 */
|
/* XXX: Need to write one per FSINFO block. Currently only writes 1 */
|
||||||
|
|
Loading…
Reference in New Issue