summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2006-03-01 02:58:36 +0100
committerMark Fasheh <mark.fasheh@oracle.com>2006-03-01 20:44:50 +0100
commit110ba90858a7f619ff26c6b9b43c27b3c0872335 (patch)
tree2a28b91a66b7570b576a581f50e512f3f316a8af
parentocfs2: Set .owner on masklog sysfs attributes. (diff)
downloadlinux-110ba90858a7f619ff26c6b9b43c27b3c0872335.tar.xz
linux-110ba90858a7f619ff26c6b9b43c27b3c0872335.zip
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>
-rw-r--r--fs/ocfs2/extent_map.c38
1 files changed, 36 insertions, 2 deletions
diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c
index b6ba292e9544..e6f207eebab4 100644
--- a/fs/ocfs2/extent_map.c
+++ b/fs/ocfs2/extent_map.c
@@ -181,6 +181,12 @@ static int ocfs2_extent_map_find_leaf(struct inode *inode,
ret = -EBADR;
if (rec_end > OCFS2_I(inode)->ip_clusters) {
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;
}
@@ -226,6 +232,12 @@ static int ocfs2_extent_map_find_leaf(struct inode *inode,
ret = -EBADR;
if (blkno) {
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;
}
@@ -238,6 +250,10 @@ static int ocfs2_extent_map_find_leaf(struct inode *inode,
*/
ret = -EBADR;
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);
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++) {
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,
le16_to_cpu(el->l_tree_depth));
if (ret) {
@@ -526,6 +556,10 @@ static int ocfs2_extent_map_insert(struct inode *inode,
OCFS2_I(inode)->ip_map.em_clusters) {
ret = -EBADR;
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;
}
@@ -588,12 +622,12 @@ static int ocfs2_extent_map_insert(struct inode *inode,
* Existing record in the extent map:
*
* cpos = 10, len = 10
- * |---------|
+ * |---------|
*
* New Record:
*
* cpos = 10, len = 20
- * |------------------|
+ * |------------------|
*
* 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