ocfs2: Respond to on-disk corruption in the extent map code.
The extent map code has long noticed when the on-disk extent information is corrupt. However, so far it has only returned an error. We should take the filesystem read-only, as it is corrupt. Signed-off-by: Joel Becker <joel.becker@oracle.com> Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
This commit is contained in:
parent
93cc9ac455
commit
110ba90858
1 changed files with 36 additions and 2 deletions
|
@ -181,6 +181,12 @@ static int ocfs2_extent_map_find_leaf(struct inode *inode,
|
||||||
ret = -EBADR;
|
ret = -EBADR;
|
||||||
if (rec_end > OCFS2_I(inode)->ip_clusters) {
|
if (rec_end > OCFS2_I(inode)->ip_clusters) {
|
||||||
mlog_errno(ret);
|
mlog_errno(ret);
|
||||||
|
ocfs2_error(inode->i_sb,
|
||||||
|
"Extent %d at e_blkno %"MLFu64" of inode %"MLFu64" goes past ip_clusters of %u\n",
|
||||||
|
i,
|
||||||
|
le64_to_cpu(rec->e_blkno),
|
||||||
|
OCFS2_I(inode)->ip_blkno,
|
||||||
|
OCFS2_I(inode)->ip_clusters);
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,6 +232,12 @@ static int ocfs2_extent_map_find_leaf(struct inode *inode,
|
||||||
ret = -EBADR;
|
ret = -EBADR;
|
||||||
if (blkno) {
|
if (blkno) {
|
||||||
mlog_errno(ret);
|
mlog_errno(ret);
|
||||||
|
ocfs2_error(inode->i_sb,
|
||||||
|
"Multiple extents for (cpos = %u, clusters = %u) on inode %"MLFu64"; e_blkno %"MLFu64" and rec %d at e_blkno %"MLFu64"\n",
|
||||||
|
cpos, clusters,
|
||||||
|
OCFS2_I(inode)->ip_blkno,
|
||||||
|
blkno, i,
|
||||||
|
le64_to_cpu(rec->e_blkno));
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,6 +250,10 @@ static int ocfs2_extent_map_find_leaf(struct inode *inode,
|
||||||
*/
|
*/
|
||||||
ret = -EBADR;
|
ret = -EBADR;
|
||||||
if (!blkno) {
|
if (!blkno) {
|
||||||
|
ocfs2_error(inode->i_sb,
|
||||||
|
"No record found for (cpos = %u, clusters = %u) on inode %"MLFu64"\n",
|
||||||
|
cpos, clusters,
|
||||||
|
OCFS2_I(inode)->ip_blkno);
|
||||||
mlog_errno(ret);
|
mlog_errno(ret);
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
@ -266,6 +282,20 @@ static int ocfs2_extent_map_find_leaf(struct inode *inode,
|
||||||
|
|
||||||
for (i = 0; i < le16_to_cpu(el->l_next_free_rec); i++) {
|
for (i = 0; i < le16_to_cpu(el->l_next_free_rec); i++) {
|
||||||
rec = &el->l_recs[i];
|
rec = &el->l_recs[i];
|
||||||
|
|
||||||
|
if ((le32_to_cpu(rec->e_cpos) + le32_to_cpu(rec->e_clusters)) >
|
||||||
|
OCFS2_I(inode)->ip_clusters) {
|
||||||
|
ret = -EBADR;
|
||||||
|
mlog_errno(ret);
|
||||||
|
ocfs2_error(inode->i_sb,
|
||||||
|
"Extent %d at e_blkno %"MLFu64" of inode %"MLFu64" goes past ip_clusters of %u\n",
|
||||||
|
i,
|
||||||
|
le64_to_cpu(rec->e_blkno),
|
||||||
|
OCFS2_I(inode)->ip_blkno,
|
||||||
|
OCFS2_I(inode)->ip_clusters);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
ret = ocfs2_extent_map_insert(inode, rec,
|
ret = ocfs2_extent_map_insert(inode, rec,
|
||||||
le16_to_cpu(el->l_tree_depth));
|
le16_to_cpu(el->l_tree_depth));
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -526,6 +556,10 @@ static int ocfs2_extent_map_insert(struct inode *inode,
|
||||||
OCFS2_I(inode)->ip_map.em_clusters) {
|
OCFS2_I(inode)->ip_map.em_clusters) {
|
||||||
ret = -EBADR;
|
ret = -EBADR;
|
||||||
mlog_errno(ret);
|
mlog_errno(ret);
|
||||||
|
ocfs2_error(inode->i_sb,
|
||||||
|
"Zero e_clusters on non-tail extent record at e_blkno %"MLFu64" on inode %"MLFu64"\n",
|
||||||
|
le64_to_cpu(rec->e_blkno),
|
||||||
|
OCFS2_I(inode)->ip_blkno);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -588,12 +622,12 @@ static int ocfs2_extent_map_insert(struct inode *inode,
|
||||||
* Existing record in the extent map:
|
* Existing record in the extent map:
|
||||||
*
|
*
|
||||||
* cpos = 10, len = 10
|
* cpos = 10, len = 10
|
||||||
* |---------|
|
* |---------|
|
||||||
*
|
*
|
||||||
* New Record:
|
* New Record:
|
||||||
*
|
*
|
||||||
* cpos = 10, len = 20
|
* cpos = 10, len = 20
|
||||||
* |------------------|
|
* |------------------|
|
||||||
*
|
*
|
||||||
* The passed record is the new on-disk record. The new_clusters value
|
* The passed record is the new on-disk record. The new_clusters value
|
||||||
* is how many clusters were added to the file. If the append is a
|
* is how many clusters were added to the file. If the append is a
|
||||||
|
|
Loading…
Reference in a new issue