Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aaa04b48 authored by OGAWA Hirofumi's avatar OGAWA Hirofumi Committed by Linus Torvalds
Browse files

fatfs: ratelimit corruption report

parent f40c396a
Loading
Loading
Loading
Loading
+7 −6
Original line number Original line Diff line number Diff line
@@ -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;
+10 −2
Original line number Original line Diff line number Diff line
@@ -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,
+2 −0
Original line number Original line Diff line number Diff line
@@ -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)
+12 −10
Original line number Original line Diff line number Diff line
@@ -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 */