Release 4.10 fs/ext4/super.c
/*
* linux/fs/ext4/super.c
*
* Copyright (C) 1992, 1993, 1994, 1995
* Remy Card (card@masi.ibp.fr)
* Laboratoire MASI - Institut Blaise Pascal
* Universite Pierre et Marie Curie (Paris VI)
*
* from
*
* linux/fs/minix/inode.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*
* Big-endian to little-endian byte-swapping/bitmaps by
* David S. Miller (davem@caip.rutgers.edu), 1995
*/
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fs.h>
#include <linux/time.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/backing-dev.h>
#include <linux/parser.h>
#include <linux/buffer_head.h>
#include <linux/exportfs.h>
#include <linux/vfs.h>
#include <linux/random.h>
#include <linux/mount.h>
#include <linux/namei.h>
#include <linux/quotaops.h>
#include <linux/seq_file.h>
#include <linux/ctype.h>
#include <linux/log2.h>
#include <linux/crc16.h>
#include <linux/cleancache.h>
#include <linux/uaccess.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
#include "ext4.h"
#include "ext4_extents.h" /* Needed for trace points definition */
#include "ext4_jbd2.h"
#include "xattr.h"
#include "acl.h"
#include "mballoc.h"
#define CREATE_TRACE_POINTS
#include <trace/events/ext4.h>
static struct ext4_lazy_init *ext4_li_info;
static struct mutex ext4_li_mtx;
static struct ratelimit_state ext4_mount_msg_ratelimit;
static int ext4_load_journal(struct super_block *, struct ext4_super_block *,
unsigned long journal_devnum);
static int ext4_show_options(struct seq_file *seq, struct dentry *root);
static int ext4_commit_super(struct super_block *sb, int sync);
static void ext4_mark_recovery_complete(struct super_block *sb,
struct ext4_super_block *es);
static void ext4_clear_journal_err(struct super_block *sb,
struct ext4_super_block *es);
static int ext4_sync_fs(struct super_block *sb, int wait);
static int ext4_remount(struct super_block *sb, int *flags, char *data);
static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf);
static int ext4_unfreeze(struct super_block *sb);
static int ext4_freeze(struct super_block *sb);
static struct dentry *ext4_mount(struct file_system_type *fs_type, int flags,
const char *dev_name, void *data);
static inline int ext2_feature_set_ok(struct super_block *sb);
static inline int ext3_feature_set_ok(struct super_block *sb);
static int ext4_feature_set_ok(struct super_block *sb, int readonly);
static void ext4_destroy_lazyinit_thread(void);
static void ext4_unregister_li_request(struct super_block *sb);
static void ext4_clear_request_list(void);
static struct inode *ext4_get_journal_inode(struct super_block *sb,
unsigned int journal_inum);
/*
* Lock ordering
*
* Note the difference between i_mmap_sem (EXT4_I(inode)->i_mmap_sem) and
* i_mmap_rwsem (inode->i_mmap_rwsem)!
*
* page fault path:
* mmap_sem -> sb_start_pagefault -> i_mmap_sem (r) -> transaction start ->
* page lock -> i_data_sem (rw)
*
* buffered write path:
* sb_start_write -> i_mutex -> mmap_sem
* sb_start_write -> i_mutex -> transaction start -> page lock ->
* i_data_sem (rw)
*
* truncate:
* sb_start_write -> i_mutex -> EXT4_STATE_DIOREAD_LOCK (w) -> i_mmap_sem (w) ->
* i_mmap_rwsem (w) -> page lock
* sb_start_write -> i_mutex -> EXT4_STATE_DIOREAD_LOCK (w) -> i_mmap_sem (w) ->
* transaction start -> i_data_sem (rw)
*
* direct IO:
* sb_start_write -> i_mutex -> EXT4_STATE_DIOREAD_LOCK (r) -> mmap_sem
* sb_start_write -> i_mutex -> EXT4_STATE_DIOREAD_LOCK (r) ->
* transaction start -> i_data_sem (rw)
*
* writepages:
* transaction start -> page lock(s) -> i_data_sem (rw)
*/
#if !defined(CONFIG_EXT2_FS) && !defined(CONFIG_EXT2_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT2)
static struct file_system_type ext2_fs_type = {
.owner = THIS_MODULE,
.name = "ext2",
.mount = ext4_mount,
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
};
MODULE_ALIAS_FS("ext2");
MODULE_ALIAS("ext2");
#define IS_EXT2_SB(sb) ((sb)->s_bdev->bd_holder == &ext2_fs_type)
#else
#define IS_EXT2_SB(sb) (0)
#endif
static struct file_system_type ext3_fs_type = {
.owner = THIS_MODULE,
.name = "ext3",
.mount = ext4_mount,
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
};
MODULE_ALIAS_FS("ext3");
MODULE_ALIAS("ext3");
#define IS_EXT3_SB(sb) ((sb)->s_bdev->bd_holder == &ext3_fs_type)
static int ext4_verify_csum_type(struct super_block *sb,
struct ext4_super_block *es)
{
if (!ext4_has_feature_metadata_csum(sb))
return 1;
return es->s_checksum_type == EXT4_CRC32C_CHKSUM;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
darrick j. wong | darrick j. wong | 34 | 100.00% | 2 | 100.00% |
| Total | 34 | 100.00% | 2 | 100.00% |
static __le32 ext4_superblock_csum(struct super_block *sb,
struct ext4_super_block *es)
{
struct ext4_sb_info *sbi = EXT4_SB(sb);
int offset = offsetof(struct ext4_super_block, s_checksum);
__u32 csum;
csum = ext4_chksum(sbi, ~0, (char *)es, offset);
return cpu_to_le32(csum);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
darrick j. wong | darrick j. wong | 64 | 100.00% | 1 | 100.00% |
| Total | 64 | 100.00% | 1 | 100.00% |
static int ext4_superblock_csum_verify(struct super_block *sb,
struct ext4_super_block *es)
{
if (!ext4_has_metadata_csum(sb))
return 1;
return es->s_checksum == ext4_superblock_csum(sb, es);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
darrick j. wong | darrick j. wong | 37 | 94.87% | 1 | 33.33% |
dmitriy monakhov | dmitriy monakhov | 1 | 2.56% | 1 | 33.33% |
stephen hemminger | stephen hemminger | 1 | 2.56% | 1 | 33.33% |
| Total | 39 | 100.00% | 3 | 100.00% |
void ext4_superblock_csum_set(struct super_block *sb)
{
struct ext4_super_block *es = EXT4_SB(sb)->s_es;
if (!ext4_has_metadata_csum(sb))
return;
es->s_checksum = ext4_superblock_csum(sb, es);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
darrick j. wong | darrick j. wong | 31 | 73.81% | 1 | 33.33% |
theodore tso | theodore tso | 10 | 23.81% | 1 | 33.33% |
dmitriy monakhov | dmitriy monakhov | 1 | 2.38% | 1 | 33.33% |
| Total | 42 | 100.00% | 3 | 100.00% |
void *ext4_kvmalloc(size_t size, gfp_t flags)
{
void *ret;
ret = kmalloc(size, flags | __GFP_NOWARN);
if (!ret)
ret = __vmalloc(size, flags, PAGE_KERNEL);
return ret;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
theodore tso | theodore tso | 44 | 95.65% | 1 | 50.00% |
joe perches | joe perches | 2 | 4.35% | 1 | 50.00% |
| Total | 46 | 100.00% | 2 | 100.00% |
void *ext4_kvzalloc(size_t size, gfp_t flags)
{
void *ret;
ret = kzalloc(size, flags | __GFP_NOWARN);
if (!ret)
ret = __vmalloc(size, flags | __GFP_ZERO, PAGE_KERNEL);
return ret;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
theodore tso | theodore tso | 45 | 93.75% | 1 | 33.33% |
joe perches | joe perches | 2 | 4.17% | 1 | 33.33% |
mathias krause | mathias krause | 1 | 2.08% | 1 | 33.33% |
| Total | 48 | 100.00% | 3 | 100.00% |
ext4_fsblk_t ext4_block_bitmap(struct super_block *sb,
struct ext4_group_desc *bg)
{
return le32_to_cpu(bg->bg_block_bitmap_lo) |
(EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
(ext4_fsblk_t)le32_to_cpu(bg->bg_block_bitmap_hi) << 32 : 0);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
laurent vivier | laurent vivier | 30 | 65.22% | 1 | 33.33% |
alexandre ratchov | alexandre ratchov | 15 | 32.61% | 1 | 33.33% |
aneesh kumar | aneesh kumar | 1 | 2.17% | 1 | 33.33% |
| Total | 46 | 100.00% | 3 | 100.00% |
ext4_fsblk_t ext4_inode_bitmap(struct super_block *sb,
struct ext4_group_desc *bg)
{
return le32_to_cpu(bg->bg_inode_bitmap_lo) |
(EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
(ext4_fsblk_t)le32_to_cpu(bg->bg_inode_bitmap_hi) << 32 : 0);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
laurent vivier | laurent vivier | 30 | 65.22% | 1 | 33.33% |
alexandre ratchov | alexandre ratchov | 15 | 32.61% | 1 | 33.33% |
aneesh kumar | aneesh kumar | 1 | 2.17% | 1 | 33.33% |
| Total | 46 | 100.00% | 3 | 100.00% |
ext4_fsblk_t ext4_inode_table(struct super_block *sb,
struct ext4_group_desc *bg)
{
return le32_to_cpu(bg->bg_inode_table_lo) |
(EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
(ext4_fsblk_t)le32_to_cpu(bg->bg_inode_table_hi) << 32 : 0);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
laurent vivier | laurent vivier | 30 | 65.22% | 1 | 33.33% |
alexandre ratchov | alexandre ratchov | 15 | 32.61% | 1 | 33.33% |
aneesh kumar | aneesh kumar | 1 | 2.17% | 1 | 33.33% |
| Total | 46 | 100.00% | 3 | 100.00% |
__u32 ext4_free_group_clusters(struct super_block *sb,
struct ext4_group_desc *bg)
{
return le16_to_cpu(bg->bg_free_blocks_count_lo) |
(EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
(__u32)le16_to_cpu(bg->bg_free_blocks_count_hi) << 16 : 0);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
aneesh kumar | aneesh kumar | 45 | 97.83% | 1 | 50.00% |
theodore tso | theodore tso | 1 | 2.17% | 1 | 50.00% |
| Total | 46 | 100.00% | 2 | 100.00% |
__u32 ext4_free_inodes_count(struct super_block *sb,
struct ext4_group_desc *bg)
{
return le16_to_cpu(bg->bg_free_inodes_count_lo) |
(EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
(__u32)le16_to_cpu(bg->bg_free_inodes_count_hi) << 16 : 0);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
aneesh kumar | aneesh kumar | 46 | 100.00% | 1 | 100.00% |
| Total | 46 | 100.00% | 1 | 100.00% |
__u32 ext4_used_dirs_count(struct super_block *sb,
struct ext4_group_desc *bg)
{
return le16_to_cpu(bg->bg_used_dirs_count_lo) |
(EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
(__u32)le16_to_cpu(bg->bg_used_dirs_count_hi) << 16 : 0);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
aneesh kumar | aneesh kumar | 46 | 100.00% | 1 | 100.00% |
| Total | 46 | 100.00% | 1 | 100.00% |
__u32 ext4_itable_unused_count(struct super_block *sb,
struct ext4_group_desc *bg)
{
return le16_to_cpu(bg->bg_itable_unused_lo) |
(EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
(__u32)le16_to_cpu(bg->bg_itable_unused_hi) << 16 : 0);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
aneesh kumar | aneesh kumar | 46 | 100.00% | 1 | 100.00% |
| Total | 46 | 100.00% | 1 | 100.00% |
void ext4_block_bitmap_set(struct super_block *sb,
struct ext4_group_desc *bg, ext4_fsblk_t blk)
{
bg->bg_block_bitmap_lo = cpu_to_le32((u32)blk);
if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
bg->bg_block_bitmap_hi = cpu_to_le32(blk >> 32);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
laurent vivier | laurent vivier | 34 | 68.00% | 1 | 33.33% |
alexandre ratchov | alexandre ratchov | 15 | 30.00% | 1 | 33.33% |
aneesh kumar | aneesh kumar | 1 | 2.00% | 1 | 33.33% |
| Total | 50 | 100.00% | 3 | 100.00% |
void ext4_inode_bitmap_set(struct super_block *sb,
struct ext4_group_desc *bg, ext4_fsblk_t blk)
{
bg->bg_inode_bitmap_lo = cpu_to_le32((u32)blk);
if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
bg->bg_inode_bitmap_hi = cpu_to_le32(blk >> 32);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
laurent vivier | laurent vivier | 34 | 68.00% | 1 | 33.33% |
alexandre ratchov | alexandre ratchov | 15 | 30.00% | 1 | 33.33% |
aneesh kumar | aneesh kumar | 1 | 2.00% | 1 | 33.33% |
| Total | 50 | 100.00% | 3 | 100.00% |
void ext4_inode_table_set(struct super_block *sb,
struct ext4_group_desc *bg, ext4_fsblk_t blk)
{
bg->bg_inode_table_lo = cpu_to_le32((u32)blk);
if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
bg->bg_inode_table_hi = cpu_to_le32(blk >> 32);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
laurent vivier | laurent vivier | 34 | 68.00% | 1 | 33.33% |
alexandre ratchov | alexandre ratchov | 15 | 30.00% | 1 | 33.33% |
aneesh kumar | aneesh kumar | 1 | 2.00% | 1 | 33.33% |
| Total | 50 | 100.00% | 3 | 100.00% |
void ext4_free_group_clusters_set(struct super_block *sb,
struct ext4_group_desc *bg, __u32 count)
{
bg->bg_free_blocks_count_lo = cpu_to_le16((__u16)count);
if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
bg->bg_free_blocks_count_hi = cpu_to_le16(count >> 16);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
aneesh kumar | aneesh kumar | 49 | 98.00% | 1 | 50.00% |
theodore tso | theodore tso | 1 | 2.00% | 1 | 50.00% |
| Total | 50 | 100.00% | 2 | 100.00% |
void ext4_free_inodes_set(struct super_block *sb,
struct ext4_group_desc *bg, __u32 count)
{
bg->bg_free_inodes_count_lo = cpu_to_le16((__u16)count);
if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
bg->bg_free_inodes_count_hi = cpu_to_le16(count >> 16);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
aneesh kumar | aneesh kumar | 50 | 100.00% | 1 | 100.00% |
| Total | 50 | 100.00% | 1 | 100.00% |
void ext4_used_dirs_set(struct super_block *sb,
struct ext4_group_desc *bg, __u32 count)
{
bg->bg_used_dirs_count_lo = cpu_to_le16((__u16)count);
if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
bg->bg_used_dirs_count_hi = cpu_to_le16(count >> 16);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
aneesh kumar | aneesh kumar | 50 | 100.00% | 1 | 100.00% |
| Total | 50 | 100.00% | 1 | 100.00% |
void ext4_itable_unused_set(struct super_block *sb,
struct ext4_group_desc *bg, __u32 count)
{
bg->bg_itable_unused_lo = cpu_to_le16((__u16)count);
if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
bg->bg_itable_unused_hi = cpu_to_le16(count >> 16);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
aneesh kumar | aneesh kumar | 30 | 60.00% | 1 | 33.33% |
laurent vivier | laurent vivier | 11 | 22.00% | 1 | 33.33% |
alexandre ratchov | alexandre ratchov | 9 | 18.00% | 1 | 33.33% |
| Total | 50 | 100.00% | 3 | 100.00% |
static void __save_error_info(struct super_block *sb, const char *func,
unsigned int line)
{
struct ext4_super_block *es = EXT4_SB(sb)->s_es;
EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS;
if (bdev_read_only(sb->s_bdev))
return;
es->s_state |= cpu_to_le16(EXT4_ERROR_FS);
es->s_last_error_time = cpu_to_le32(get_seconds());
strncpy(es->s_last_error_func, func, sizeof(es->s_last_error_func));
es->s_last_error_line = cpu_to_le32(line);
if (!es->s_first_error_time) {
es->s_first_error_time = es->s_last_error_time;
strncpy(es->s_first_error_func, func,
sizeof(es->s_first_error_func));
es->s_first_error_line = cpu_to_le32(line);
es->s_first_error_ino = es->s_last_error_ino;
es->s_first_error_block = es->s_last_error_block;
}
/*
* Start the daily error reporting function if it hasn't been
* started already
*/
if (!es->s_error_count)
mod_timer(&EXT4_SB(sb)->s_err_report, jiffies + 24*60*60*HZ);
le32_add_cpu(&es->s_error_count, 1);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
theodore tso | theodore tso | 150 | 78.12% | 3 | 50.00% |
dave kleikamp | dave kleikamp | 34 | 17.71% | 1 | 16.67% |
mingming cao | mingming cao | 5 | 2.60% | 1 | 16.67% |
wei yongjun | wei yongjun | 3 | 1.56% | 1 | 16.67% |
| Total | 192 | 100.00% | 6 | 100.00% |
static void save_error_info(struct super_block *sb, const char *func,
unsigned int line)
{
__save_error_info(sb, func, line);
ext4_commit_super(sb, 1);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
theodore tso | theodore tso | 36 | 100.00% | 1 | 100.00% |
| Total | 36 | 100.00% | 1 | 100.00% |
/*
* The del_gendisk() function uninitializes the disk-specific data
* structures, including the bdi structure, without telling anyone
* else. Once this happens, any attempt to call mark_buffer_dirty()
* (for example, by ext4_commit_super), will cause a kernel OOPS.
* This is a kludge to prevent these oops until we can put in a proper
* hook in del_gendisk() to inform the VFS and file system layers.
*/
static int block_device_ejected(struct super_block *sb)
{
struct inode *bd_inode = sb->s_bdev->bd_inode;
struct backing_dev_info *bdi = inode_to_bdi(bd_inode);
return bdi->dev == NULL;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
theodore tso | theodore tso | 39 | 100.00% | 1 | 100.00% |
| Total | 39 | 100.00% | 1 | 100.00% |
static void ext4_journal_commit_callback(journal_t *journal, transaction_t *txn)
{
struct super_block *sb = journal->j_private;
struct ext4_sb_info *sbi = EXT4_SB(sb);
int error = is_journal_aborted(journal);
struct ext4_journal_cb_entry *jce;
BUG_ON(txn->t_state == T_FINISHED);
spin_lock(&sbi->s_md_lock);
while (!list_empty(&txn->t_private_list)) {
jce = list_entry(txn->t_private_list.next,
struct ext4_journal_cb_entry, jce_list);
list_del_init(&jce->jce_list);
spin_unlock(&sbi->s_md_lock);
jce->jce_func(sb, jce, error);
spin_lock(&sbi->s_md_lock);
}
spin_unlock(&sbi->s_md_lock);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
bobi jam | bobi jam | 102 | 75.56% | 1 | 50.00% |
dmitriy monakhov | dmitriy monakhov | 33 | 24.44% | 1 | 50.00% |
| Total | 135 | 100.00% | 2 | 100.00% |
/* Deal with the reporting of failure conditions on a filesystem such as
* inconsistencies detected or read IO failures.
*
* On ext2, we can store the error state of the filesystem in the
* superblock. That is not possible on ext4, because we may have other
* write ordering constraints on the superblock which prevent us from
* writing it out straight away; and given that the journal is about to
* be aborted, we can't rely on the current, or future, transactions to
* write out the superblock safely.
*
* We'll just use the jbd2_journal_abort() error code to record an error in
* the journal instead. On recovery, the journal will complain about
* that error until we've noted it down and cleared it.
*/
static void ext4_handle_error(struct super_block *sb)
{
if (sb->s_flags & MS_RDONLY)
return;
if (!test_opt(sb, ERRORS_CONT)) {
journal_t *journal = EXT4_SB(sb)->s_journal;
EXT4_SB(sb)->s_mount_flags |= EXT4_MF_FS_ABORTED;
if (journal)
jbd2_journal_abort(journal, -EIO);
}
if (test_opt(sb, ERRORS_RO)) {
ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only");
/*
* Make sure updated value of ->s_mount_flags will be visible
* before ->s_flags update
*/
smp_wmb();
sb->s_flags |= MS_RDONLY;
}
if (test_opt(sb, ERRORS_PANIC)) {
if (EXT4_SB(sb)->s_journal &&
!(EXT4_SB(sb)->s_journal->j_flags & JBD2_REC_ERR))
return;
panic("EXT4-fs (device %s): panic forced after error\n",
sb->s_id);
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
dave kleikamp | dave kleikamp | 87 | 63.04% | 1 | 12.50% |
daeho jeong | daeho jeong | 26 | 18.84% | 1 | 12.50% |
theodore tso | theodore tso | 12 | 8.70% | 2 | 25.00% |
eric sandeen | eric sandeen | 5 | 3.62% | 1 | 12.50% |
mingming cao | mingming cao | 4 | 2.90% | 2 | 25.00% |
dmitriy monakhov | dmitriy monakhov | 4 | 2.90% | 1 | 12.50% |
| Total | 138 | 100.00% | 8 | 100.00% |
#define ext4_error_ratelimit(sb) \
___ratelimit(&(EXT4_SB(sb)->s_err_ratelimit_state), \
"EXT4-fs error")
void __ext4_error(struct super_block *sb, const char *function,
unsigned int line, const char *fmt, ...)
{
struct va_format vaf;
va_list args;
if (ext4_error_ratelimit(sb)) {
va_start(args, fmt);
vaf.fmt = fmt;
vaf.va = &args;
printk(KERN_CRIT
"EXT4-fs error (device %s): %s:%d: comm %s: %pV\n",
sb->s_id, function, line, current->comm, &vaf);
va_end(args);
}
save_error_info(sb, function, line);
ext4_handle_error(sb);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
dave kleikamp | dave kleikamp | 52 | 50.98% | 1 | 14.29% |
theodore tso | theodore tso | 28 | 27.45% | 3 | 42.86% |
joe perches | joe perches | 20 | 19.61% | 1 | 14.29% |
mingming cao | mingming cao | 1 | 0.98% | 1 | 14.29% |
eric sandeen | eric sandeen | 1 | 0.98% | 1 | 14.29% |
| Total | 102 | 100.00% | 7 | 100.00% |
void __ext4_error_inode(struct inode *inode, const char *function,
unsigned int line, ext4_fsblk_t block,
const char *fmt, ...)
{
va_list args;
struct va_format vaf;
struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es;
es->s_last_error_ino = cpu_to_le32(inode->i_ino);
es->s_last_error_block = cpu_to_le64(block);
if (ext4_error_ratelimit(inode->i_sb)) {
va_start(args, fmt);
vaf.fmt = fmt;
vaf.va = &args;
if (block)
printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: "
"inode #%lu: block %llu: comm %s: %pV\n",
inode->i_sb->s_id, function, line, inode->i_ino,
block, current->comm, &vaf);
else
printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: "
"inode #%lu: comm %s: %pV\n",
inode->i_sb->s_id, function, line, inode->i_ino,
current->comm, &vaf);
va_end(args);
}
save_error_info(inode->i_sb, function, line);
ext4_handle_error(inode->i_sb);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
theodore tso | theodore tso | 94 | 50.27% | 4 | 57.14% |
frank mayhar | frank mayhar | 61 | 32.62% | 1 | 14.29% |
joe perches | joe perches | 32 | 17.11% | 2 | 28.57% |
| Total | 187 | 100.00% | 7 | 100.00% |
void __ext4_error_file(struct file *file, const char *function,
unsigned int line, ext4_fsblk_t block,
const char *fmt, ...)
{
va_list args;
struct va_format vaf;
struct ext4_super_block *es;
struct inode *inode = file_inode(file);
char pathname[80], *path;
es = EXT4_SB(inode->i_sb)->s_es;
es->s_last_error_ino = cpu_to_le32(inode->i_ino);
if (ext4_error_ratelimit(inode->i_sb)) {
path = file_path(file, pathname, sizeof(pathname));
if (IS_ERR(path))
path = "(unknown)";
va_start(args, fmt);
vaf.fmt = fmt;
vaf.va = &args;
if (block)
printk(KERN_CRIT
"EXT4-fs error (device %s): %s:%d: inode #%lu: "
"block %llu: comm %s: path %s: %pV\n",
inode->i_sb->s_id, function, line, inode->i_ino,
block, current->comm, path, &vaf);
else
printk(KERN_CRIT
"EXT4-fs error (device %s): %s:%d: inode #%lu: "
"comm %s: path %s: %pV\n",
inode->i_sb->s_id, function, line, inode->i_ino,
current->comm, path, &vaf);
va_end(args);
}
save_error_info(inode->i_sb, function, line);
ext4_handle_error(inode->i_sb);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
frank mayhar | frank mayhar | 89 | 39.04% | 1 | 10.00% |
theodore tso | theodore tso | 81 | 35.53% | 4 | 40.00% |
joe perches | joe perches | 51 | 22.37% | 2 | 20.00% |
dan carpenter | dan carpenter | 3 | 1.32% | 1 | 10.00% |
al viro | al viro | 3 | 1.32% | 1 | 10.00% |
miklos szeredi | miklos szeredi | 1 | 0.44% | 1 | 10.00% |
| Total | 228 | 100.00% | 10 | 100.00% |
const char *ext4_decode_error(struct super_block *sb, int errno,
char nbuf[16])
{
char *errstr = NULL;
switch (errno) {
case -EFSCORRUPTED:
errstr = "Corrupt filesystem";
break;
case -EFSBADCRC:
errstr = "Filesystem failed CRC";
break;
case -EIO:
errstr = "IO failure";
break;
case -ENOMEM:
errstr = "Out of memory";
break;
case -EROFS:
if (!sb || (EXT4_SB(sb)->s_journal &&
EXT4_SB(sb)->s_journal->j_flags & JBD2_ABORT))
errstr = "Journal has aborted";
else
errstr = "Readonly filesystem";
break;
default:
/* If the caller passed in an extra buffer for unknown
* errors, textualise them now. Else we just return
* NULL. */
if (nbuf) {
/* Check for truncated error codes... */
if (snprintf(nbuf, 16, "error %d", -errno) >= 0)
errstr = nbuf;
}
break;
}
return errstr;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
dave kleikamp | dave kleikamp | 111 | 78.72% | 1 | 20.00% |
darrick j. wong | darrick j. wong | 18 | 12.77% | 1 | 20.00% |
theodore tso | theodore tso | 9 | 6.38% | 1 | 20.00% |
mingming cao | mingming cao | 3 | 2.13% | 2 | 40.00% |
| Total | 141 | 100.00% | 5 | 100.00% |
/* __ext4_std_error decodes expected errors from journaling functions
* automatically and invokes the appropriate error response. */
void __ext4_std_error(struct super_block *sb, const char *function,
unsigned int line, int errno)
{
char nbuf[16];
const char *errstr;
/* Special case: if the error is EROFS, and we're not already
* inside a transaction, then there's really no point in logging
* an error. */
if (errno == -EROFS && journal_current_handle() == NULL &&
(sb->s_flags & MS_RDONLY))
return;
if (ext4_error_ratelimit(sb)) {
errstr = ext4_decode_error(sb, errno, nbuf);
printk(KERN_CRIT "EXT4-fs error (device %s) in %s:%d: %s\n",
sb->s_id, function, line, errstr);
}
save_error_info(sb, function, line);
ext4_handle_error(sb);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
dave kleikamp | dave kleikamp | 77 | 73.33% | 1 | 20.00% |
theodore tso | theodore tso | 25 | 23.81% | 3 | 60.00% |
mingming cao | mingming cao | 3 | 2.86% | 1 | 20.00% |
| Total | 105 | 100.00% | 5 | 100.00% |
/*
* ext4_abort is a much stronger failure handler than ext4_error. The
* abort function may be used to deal with unrecoverable failures such
* as journal IO errors or ENOMEM at a critical moment in log management.
*
* We unconditionally force the filesystem into an ABORT|READONLY state,
* unless the error response on the fs has been set to panic in which
* case we take the easy way out and panic immediately.
*/
void __ext4_abort(struct super_block *sb, const char *function,
unsigned int line, const char *fmt, ...)
{
struct va_format vaf;
va_list args;
save_error_info(sb, function, line);
va_start(args, fmt);
vaf.fmt = fmt;
vaf.va = &args;
printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: %pV\n",
sb->s_id, function, line, &