Skip to content

Commit d6b32bb

Browse files
Joel BeckerMark Fasheh
Joel Becker
authored and
Mark Fasheh
committed
ocfs2: block read meta ecc.
Add block check calls to the read_block validate functions. This is the almost all of the read-side checking of metaecc. xattr buckets are not checked yet. Writes are also unchecked, and so a read-write mount will quickly fail. Signed-off-by: Joel Becker <joel.becker@oracle.com> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
1 parent 684ef27 commit d6b32bb

File tree

6 files changed

+101
-4
lines changed

6 files changed

+101
-4
lines changed

fs/ocfs2/alloc.c

+17
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737

3838
#include "alloc.h"
3939
#include "aops.h"
40+
#include "blockcheck.h"
4041
#include "dlmglue.h"
4142
#include "extent_map.h"
4243
#include "inode.h"
@@ -682,12 +683,28 @@ struct ocfs2_merge_ctxt {
682683
static int ocfs2_validate_extent_block(struct super_block *sb,
683684
struct buffer_head *bh)
684685
{
686+
int rc;
685687
struct ocfs2_extent_block *eb =
686688
(struct ocfs2_extent_block *)bh->b_data;
687689

688690
mlog(0, "Validating extent block %llu\n",
689691
(unsigned long long)bh->b_blocknr);
690692

693+
BUG_ON(!buffer_uptodate(bh));
694+
695+
/*
696+
* If the ecc fails, we return the error but otherwise
697+
* leave the filesystem running. We know any error is
698+
* local to this block.
699+
*/
700+
rc = ocfs2_validate_meta_ecc(sb, bh->b_data, &eb->h_check);
701+
if (rc)
702+
return rc;
703+
704+
/*
705+
* Errors after here are fatal.
706+
*/
707+
691708
if (!OCFS2_IS_VALID_EXTENT_BLOCK(eb)) {
692709
ocfs2_error(sb,
693710
"Extent block #%llu has bad signature %.*s",

fs/ocfs2/blockcheck.c

+9
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include <linux/bitops.h>
2525
#include <asm/byteorder.h>
2626

27+
#include <cluster/masklog.h>
28+
2729
#include "ocfs2.h"
2830

2931
#include "blockcheck.h"
@@ -292,6 +294,10 @@ int ocfs2_block_check_validate(void *data, size_t blocksize,
292294
if (crc == check.bc_crc32e)
293295
goto out;
294296

297+
mlog(ML_ERROR,
298+
"CRC32 failed: stored: %u, computed %u. Applying ECC.\n",
299+
(unsigned int)check.bc_crc32e, (unsigned int)crc);
300+
295301
/* Ok, try ECC fixups */
296302
ecc = ocfs2_hamming_encode_block(data, blocksize);
297303
ocfs2_hamming_fix_block(data, blocksize, ecc ^ check.bc_ecc);
@@ -301,6 +307,9 @@ int ocfs2_block_check_validate(void *data, size_t blocksize,
301307
if (crc == check.bc_crc32e)
302308
goto out;
303309

310+
mlog(ML_ERROR, "Fixed CRC32 failed: stored: %u, computed %u\n",
311+
(unsigned int)check.bc_crc32e, (unsigned int)crc);
312+
304313
rc = -EIO;
305314

306315
out:

fs/ocfs2/inode.c

+17-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "ocfs2.h"
3939

4040
#include "alloc.h"
41+
#include "blockcheck.h"
4142
#include "dlmglue.h"
4243
#include "extent_map.h"
4344
#include "file.h"
@@ -1262,14 +1263,29 @@ void ocfs2_refresh_inode(struct inode *inode,
12621263
int ocfs2_validate_inode_block(struct super_block *sb,
12631264
struct buffer_head *bh)
12641265
{
1265-
int rc = -EINVAL;
1266+
int rc;
12661267
struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data;
12671268

12681269
mlog(0, "Validating dinode %llu\n",
12691270
(unsigned long long)bh->b_blocknr);
12701271

12711272
BUG_ON(!buffer_uptodate(bh));
12721273

1274+
/*
1275+
* If the ecc fails, we return the error but otherwise
1276+
* leave the filesystem running. We know any error is
1277+
* local to this block.
1278+
*/
1279+
rc = ocfs2_validate_meta_ecc(sb, bh->b_data, &di->i_check);
1280+
if (rc)
1281+
goto bail;
1282+
1283+
/*
1284+
* Errors after here are fatal.
1285+
*/
1286+
1287+
rc = -EINVAL;
1288+
12731289
if (!OCFS2_IS_VALID_DINODE(di)) {
12741290
ocfs2_error(sb, "Invalid dinode #%llu: signature = %.*s\n",
12751291
(unsigned long long)bh->b_blocknr, 7,

fs/ocfs2/quota_global.c

+11-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "ocfs2_fs.h"
1717
#include "ocfs2.h"
1818
#include "alloc.h"
19+
#include "blockcheck.h"
1920
#include "inode.h"
2021
#include "journal.h"
2122
#include "file.h"
@@ -90,12 +91,20 @@ struct qtree_fmt_operations ocfs2_global_ops = {
9091
static int ocfs2_validate_quota_block(struct super_block *sb,
9192
struct buffer_head *bh)
9293
{
93-
struct ocfs2_disk_dqtrailer *dqt = ocfs2_dq_trailer(sb, bh->b_data);
94+
struct ocfs2_disk_dqtrailer *dqt =
95+
ocfs2_block_dqtrailer(sb->s_blocksize, bh->b_data);
9496

9597
mlog(0, "Validating quota block %llu\n",
9698
(unsigned long long)bh->b_blocknr);
9799

98-
return 0;
100+
BUG_ON(!buffer_uptodate(bh));
101+
102+
/*
103+
* If the ecc fails, we return the error but otherwise
104+
* leave the filesystem running. We know any error is
105+
* local to this block.
106+
*/
107+
return ocfs2_validate_meta_ecc(sb, bh->b_data, &dqt->dq_check);
99108
}
100109

101110
int ocfs2_read_quota_block(struct inode *inode, u64 v_block,

fs/ocfs2/suballoc.c

+30-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "ocfs2.h"
3636

3737
#include "alloc.h"
38+
#include "blockcheck.h"
3839
#include "dlmglue.h"
3940
#include "inode.h"
4041
#include "journal.h"
@@ -250,8 +251,18 @@ int ocfs2_check_group_descriptor(struct super_block *sb,
250251
struct buffer_head *bh)
251252
{
252253
int rc;
254+
struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data;
255+
256+
BUG_ON(!buffer_uptodate(bh));
253257

254-
rc = ocfs2_validate_gd_self(sb, bh, 1);
258+
/*
259+
* If the ecc fails, we return the error but otherwise
260+
* leave the filesystem running. We know any error is
261+
* local to this block.
262+
*/
263+
rc = ocfs2_validate_meta_ecc(sb, bh->b_data, &gd->bg_check);
264+
if (!rc)
265+
rc = ocfs2_validate_gd_self(sb, bh, 1);
255266
if (!rc)
256267
rc = ocfs2_validate_gd_parent(sb, di, bh, 1);
257268

@@ -261,9 +272,27 @@ int ocfs2_check_group_descriptor(struct super_block *sb,
261272
static int ocfs2_validate_group_descriptor(struct super_block *sb,
262273
struct buffer_head *bh)
263274
{
275+
int rc;
276+
struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data;
277+
264278
mlog(0, "Validating group descriptor %llu\n",
265279
(unsigned long long)bh->b_blocknr);
266280

281+
BUG_ON(!buffer_uptodate(bh));
282+
283+
/*
284+
* If the ecc fails, we return the error but otherwise
285+
* leave the filesystem running. We know any error is
286+
* local to this block.
287+
*/
288+
rc = ocfs2_validate_meta_ecc(sb, bh->b_data, &gd->bg_check);
289+
if (rc)
290+
return rc;
291+
292+
/*
293+
* Errors after here are fatal.
294+
*/
295+
267296
return ocfs2_validate_gd_self(sb, bh, 0);
268297
}
269298

fs/ocfs2/xattr.c

+17
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242

4343
#include "ocfs2.h"
4444
#include "alloc.h"
45+
#include "blockcheck.h"
4546
#include "dlmglue.h"
4647
#include "file.h"
4748
#include "symlink.h"
@@ -322,12 +323,28 @@ static void ocfs2_xattr_bucket_copy_data(struct ocfs2_xattr_bucket *dest,
322323
static int ocfs2_validate_xattr_block(struct super_block *sb,
323324
struct buffer_head *bh)
324325
{
326+
int rc;
325327
struct ocfs2_xattr_block *xb =
326328
(struct ocfs2_xattr_block *)bh->b_data;
327329

328330
mlog(0, "Validating xattr block %llu\n",
329331
(unsigned long long)bh->b_blocknr);
330332

333+
BUG_ON(!buffer_uptodate(bh));
334+
335+
/*
336+
* If the ecc fails, we return the error but otherwise
337+
* leave the filesystem running. We know any error is
338+
* local to this block.
339+
*/
340+
rc = ocfs2_validate_meta_ecc(sb, bh->b_data, &xb->xb_check);
341+
if (rc)
342+
return rc;
343+
344+
/*
345+
* Errors after here are fatal
346+
*/
347+
331348
if (!OCFS2_IS_VALID_XATTR_BLOCK(xb)) {
332349
ocfs2_error(sb,
333350
"Extended attribute block #%llu has bad "

0 commit comments

Comments
 (0)