xref: /openbmc/linux/fs/ocfs2/refcounttree.c (revision f2c870e3)
1f2c870e3STao Ma /* -*- mode: c; c-basic-offset: 8; -*-
2f2c870e3STao Ma  * vim: noexpandtab sw=8 ts=8 sts=0:
3f2c870e3STao Ma  *
4f2c870e3STao Ma  * refcounttree.c
5f2c870e3STao Ma  *
6f2c870e3STao Ma  * Copyright (C) 2009 Oracle.  All rights reserved.
7f2c870e3STao Ma  *
8f2c870e3STao Ma  * This program is free software; you can redistribute it and/or
9f2c870e3STao Ma  * modify it under the terms of the GNU General Public
10f2c870e3STao Ma  * License version 2 as published by the Free Software Foundation.
11f2c870e3STao Ma  *
12f2c870e3STao Ma  * This program is distributed in the hope that it will be useful,
13f2c870e3STao Ma  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14f2c870e3STao Ma  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15f2c870e3STao Ma  * General Public License for more details.
16f2c870e3STao Ma  */
17f2c870e3STao Ma 
18f2c870e3STao Ma #define MLOG_MASK_PREFIX ML_REFCOUNT
19f2c870e3STao Ma #include <cluster/masklog.h>
20f2c870e3STao Ma #include "ocfs2.h"
21f2c870e3STao Ma #include "inode.h"
22f2c870e3STao Ma #include "alloc.h"
23f2c870e3STao Ma #include "suballoc.h"
24f2c870e3STao Ma #include "journal.h"
25f2c870e3STao Ma #include "uptodate.h"
26f2c870e3STao Ma #include "super.h"
27f2c870e3STao Ma #include "buffer_head_io.h"
28f2c870e3STao Ma #include "blockcheck.h"
29f2c870e3STao Ma 
30f2c870e3STao Ma static int ocfs2_validate_refcount_block(struct super_block *sb,
31f2c870e3STao Ma 					 struct buffer_head *bh)
32f2c870e3STao Ma {
33f2c870e3STao Ma 	int rc;
34f2c870e3STao Ma 	struct ocfs2_refcount_block *rb =
35f2c870e3STao Ma 		(struct ocfs2_refcount_block *)bh->b_data;
36f2c870e3STao Ma 
37f2c870e3STao Ma 	mlog(0, "Validating refcount block %llu\n",
38f2c870e3STao Ma 	     (unsigned long long)bh->b_blocknr);
39f2c870e3STao Ma 
40f2c870e3STao Ma 	BUG_ON(!buffer_uptodate(bh));
41f2c870e3STao Ma 
42f2c870e3STao Ma 	/*
43f2c870e3STao Ma 	 * If the ecc fails, we return the error but otherwise
44f2c870e3STao Ma 	 * leave the filesystem running.  We know any error is
45f2c870e3STao Ma 	 * local to this block.
46f2c870e3STao Ma 	 */
47f2c870e3STao Ma 	rc = ocfs2_validate_meta_ecc(sb, bh->b_data, &rb->rf_check);
48f2c870e3STao Ma 	if (rc) {
49f2c870e3STao Ma 		mlog(ML_ERROR, "Checksum failed for refcount block %llu\n",
50f2c870e3STao Ma 		     (unsigned long long)bh->b_blocknr);
51f2c870e3STao Ma 		return rc;
52f2c870e3STao Ma 	}
53f2c870e3STao Ma 
54f2c870e3STao Ma 
55f2c870e3STao Ma 	if (!OCFS2_IS_VALID_REFCOUNT_BLOCK(rb)) {
56f2c870e3STao Ma 		ocfs2_error(sb,
57f2c870e3STao Ma 			    "Refcount block #%llu has bad signature %.*s",
58f2c870e3STao Ma 			    (unsigned long long)bh->b_blocknr, 7,
59f2c870e3STao Ma 			    rb->rf_signature);
60f2c870e3STao Ma 		return -EINVAL;
61f2c870e3STao Ma 	}
62f2c870e3STao Ma 
63f2c870e3STao Ma 	if (le64_to_cpu(rb->rf_blkno) != bh->b_blocknr) {
64f2c870e3STao Ma 		ocfs2_error(sb,
65f2c870e3STao Ma 			    "Refcount block #%llu has an invalid rf_blkno "
66f2c870e3STao Ma 			    "of %llu",
67f2c870e3STao Ma 			    (unsigned long long)bh->b_blocknr,
68f2c870e3STao Ma 			    (unsigned long long)le64_to_cpu(rb->rf_blkno));
69f2c870e3STao Ma 		return -EINVAL;
70f2c870e3STao Ma 	}
71f2c870e3STao Ma 
72f2c870e3STao Ma 	if (le32_to_cpu(rb->rf_fs_generation) != OCFS2_SB(sb)->fs_generation) {
73f2c870e3STao Ma 		ocfs2_error(sb,
74f2c870e3STao Ma 			    "Refcount block #%llu has an invalid "
75f2c870e3STao Ma 			    "rf_fs_generation of #%u",
76f2c870e3STao Ma 			    (unsigned long long)bh->b_blocknr,
77f2c870e3STao Ma 			    le32_to_cpu(rb->rf_fs_generation));
78f2c870e3STao Ma 		return -EINVAL;
79f2c870e3STao Ma 	}
80f2c870e3STao Ma 
81f2c870e3STao Ma 	return 0;
82f2c870e3STao Ma }
83f2c870e3STao Ma 
84f2c870e3STao Ma static int ocfs2_read_refcount_block(struct ocfs2_caching_info *ci,
85f2c870e3STao Ma 				     u64 rb_blkno,
86f2c870e3STao Ma 				     struct buffer_head **bh)
87f2c870e3STao Ma {
88f2c870e3STao Ma 	int rc;
89f2c870e3STao Ma 	struct buffer_head *tmp = *bh;
90f2c870e3STao Ma 
91f2c870e3STao Ma 	rc = ocfs2_read_block(ci, rb_blkno, &tmp,
92f2c870e3STao Ma 			      ocfs2_validate_refcount_block);
93f2c870e3STao Ma 
94f2c870e3STao Ma 	/* If ocfs2_read_block() got us a new bh, pass it up. */
95f2c870e3STao Ma 	if (!rc && !*bh)
96f2c870e3STao Ma 		*bh = tmp;
97f2c870e3STao Ma 
98f2c870e3STao Ma 	return rc;
99f2c870e3STao Ma }
100