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