apparently spurious I/O errors in readdir().
To reproduce, create a stack of the following:
ReiserFS (noatime)
dm-crypt (aes256-cbc-essiv:sha256)
lvm2
md RAID5 (5 disks)
SATA disks
When the md-RAID5 array is in recovery mode, readdir() will occasionally
return -EIO, especially when the system is under heavy load from other
operations on the same filesystem. No data ever seems to go permanently
missing, and retrying the readdir() operation usually succeeds.
dm-crypt seems to be critical to reproducing the problem, since other
filesystems on the same machine at the same time do not show these
symptoms, or show them much less often.
RAID5 recovery seems to be important as well, as I have observed no
spurious errors while recovery is not running. That could mean that
either they occur much less often, or not at all.
/* There is corrupted data in entry,
* We'd better stop here */
pathrelse(&path_to_entry);
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
ret = -EIO;
goto out;
}
blkdev_issue_flush(p_s_inode->i_sb->s_bdev, NULL);
if (barrier_done < 0)
return barrier_done;
- return (n_err < 0) ? -EIO : 0;
+ if (n_err < 0) {
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
+ return -EIO;
+ } else {
+ return 0;
+ }
}
/* taken fs/buffer.c:__block_commit_write */
*/
if (!buffer_uptodate(bh) && buffer_dirty(bh)) {
clear_buffer_dirty(bh);
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
ret = -EIO;
}
if (buffer_dirty(bh)) {
spin_lock(lock);
}
if (!buffer_uptodate(bh)) {
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
ret = -EIO;
}
/* ugly interaction with invalidatepage here.
#ifdef CONFIG_REISERFS_CHECK
reiserfs_warning(s, "journal-601, buffer write failed");
#endif
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
retval = -EIO;
}
put_bh(tbh); /* once for journal_find_get_block */
#ifdef CONFIG_REISERFS_CHECK
reiserfs_warning(s, "journal-615: buffer write failed");
#endif
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
retval = -EIO;
}
bforget(jl->j_commit_bh);
struct reiserfs_journal_header *jh;
struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
- if (reiserfs_is_journal_aborted(journal))
+ if (reiserfs_is_journal_aborted(journal)) {
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
return -EIO;
+ }
if (trans_id >= journal->j_last_flush_trans_id) {
if (buffer_locked((journal->j_header_bh))) {
{
struct super_block *s = th->t_super;
int ret = 0;
- if (th->t_trans_id)
+ if (th->t_trans_id) {
ret = journal_end(th, th->t_super, th->t_blocks_allocated);
- else
+ } else {
ret = -EIO;
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
+ }
if (th->t_refcount == 0) {
SB_JOURNAL(s)->j_persistent_trans--;
kfree(th);
if (!th->t_trans_id) {
WARN_ON(1);
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
return -EIO;
}
}
reiserfs_write_unlock(dir->i_sb);
if (retval == IO_ERROR) {
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
return ERR_PTR(-EIO);
}
pathrelse(&path);
if (retval == IO_ERROR) {
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
return -EIO;
}
retval = -ENOENT;
goto end_rmdir;
} else if (retval == IO_ERROR) {
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
retval = -EIO;
goto end_rmdir;
}
if (de.de_objectid != inode->i_ino) {
// FIXME: compare key of an object and a key found in the
// entry
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
retval = -EIO;
goto end_rmdir;
}
retval = -ENOENT;
goto end_unlink;
} else if (retval == IO_ERROR) {
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
retval = -EIO;
goto end_unlink;
}
if (de.de_objectid != inode->i_ino) {
// FIXME: compare key of an object and a key found in the
// entry
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
retval = -EIO;
goto end_unlink;
}
pathrelse(&old_entry_path);
if (retval == IO_ERROR) {
reiserfs_write_unlock(old_dir->i_sb);
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
return -EIO;
}
pathrelse(&dot_dot_entry_path);
if (retval != NAME_FOUND) {
reiserfs_write_unlock(old_dir->i_sb);
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
return -EIO;
}
/* inode number of .. must equal old_dir->i_ino */
if (dot_dot_de.de_objectid != old_dir->i_ino) {
reiserfs_write_unlock(old_dir->i_sb);
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
return -EIO;
}
}
pathrelse(&old_entry_path);
journal_end(&th, old_dir->i_sb, jbegin_count);
reiserfs_write_unlock(old_dir->i_sb);
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
return -EIO;
}
pathrelse(&old_entry_path);
journal_end(&th, old_dir->i_sb, jbegin_count);
reiserfs_write_unlock(old_dir->i_sb);
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
return -EIO;
}
pathrelse(&old_entry_path);
journal_end(&th, old_dir->i_sb, jbegin_count);
reiserfs_write_unlock(old_dir->i_sb);
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
return -EIO;
}
copy_item_head(&dot_dot_ih,
bh = sb_bread(s, i * s->s_blocksize * 8);
if (!bh) {
vfree(bitmap);
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
return -EIO;
}
memset(bh->b_data, 0, sb_blocksize(sb));
int jerr = journal_end(&th, s, 10);
if (jerr)
return jerr;
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
return -EIO;
}
int jerr = journal_end(&th, s, 10);
if (jerr)
return jerr;
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
return -EIO;
}
if (n_ret_value == NO_DISK_SPACE)
reiserfs_warning(p_s_sb, "NO_DISK_SPACE");
unfix_nodes(&s_cut_balance);
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
return -EIO;
}
search_for_position_by_key(th->t_super, p_s_key,
p_s_search_path);
if (retval == IO_ERROR) {
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
retval = -EIO;
goto error_out;
}
PROC_INFO_INC(th->t_super, insert_item_restarted);
retval = search_item(th->t_super, key, p_s_path);
if (retval == IO_ERROR) {
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
retval = -EIO;
goto error_out;
}
memset(data, 0, tocopy);
else {
bh = sb_bread(sb, tmp_bh.b_blocknr);
- if (!bh)
+ if (!bh) {
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
return -EIO;
+ }
memcpy(data, bh->b_data + offset, tocopy);
brelse(bh);
}
else
bh = sb_getblk(sb, tmp_bh.b_blocknr);
if (!bh) {
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
err = -EIO;
goto out;
}
"pasted or inserted byte exists in the tree %K. "
"Use fsck to repair.", &end_key);
pathrelse(path);
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
return -EIO;
}
// FIXME: we could just skip part of directory which could
// not be read
pathrelse(&path_to_entry);
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
return -EIO;
}
fail:
reiserfs_put_page(page);
+ printk("reiserfs: returning EIO at %s:%d\n", __FILE__, __LINE__);
return ERR_PTR(-EIO);
}