1 /* -*- mode: c; c-basic-offset: 8; -*-
2 * vim: noexpandtab sw=8 ts=8 sts=0:
6 * Copyright (C) 2009 Oracle. All rights reserved.
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.
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.
18 #define MLOG_MASK_PREFIX ML_REFCOUNT
19 #include <cluster/masklog.h>
27 #include "buffer_head_io.h"
28 #include "blockcheck.h"
29 #include "refcounttree.h"
31 static inline struct ocfs2_refcount_tree *
32 cache_info_to_refcount(struct ocfs2_caching_info *ci)
34 return container_of(ci, struct ocfs2_refcount_tree, rf_ci);
37 static int ocfs2_validate_refcount_block(struct super_block *sb,
38 struct buffer_head *bh)
41 struct ocfs2_refcount_block *rb =
42 (struct ocfs2_refcount_block *)bh->b_data;
44 mlog(0, "Validating refcount block %llu\n",
45 (unsigned long long)bh->b_blocknr);
47 BUG_ON(!buffer_uptodate(bh));
50 * If the ecc fails, we return the error but otherwise
51 * leave the filesystem running. We know any error is
52 * local to this block.
54 rc = ocfs2_validate_meta_ecc(sb, bh->b_data, &rb->rf_check);
56 mlog(ML_ERROR, "Checksum failed for refcount block %llu\n",
57 (unsigned long long)bh->b_blocknr);
62 if (!OCFS2_IS_VALID_REFCOUNT_BLOCK(rb)) {
64 "Refcount block #%llu has bad signature %.*s",
65 (unsigned long long)bh->b_blocknr, 7,
70 if (le64_to_cpu(rb->rf_blkno) != bh->b_blocknr) {
72 "Refcount block #%llu has an invalid rf_blkno "
74 (unsigned long long)bh->b_blocknr,
75 (unsigned long long)le64_to_cpu(rb->rf_blkno));
79 if (le32_to_cpu(rb->rf_fs_generation) != OCFS2_SB(sb)->fs_generation) {
81 "Refcount block #%llu has an invalid "
82 "rf_fs_generation of #%u",
83 (unsigned long long)bh->b_blocknr,
84 le32_to_cpu(rb->rf_fs_generation));
91 static int ocfs2_read_refcount_block(struct ocfs2_caching_info *ci,
93 struct buffer_head **bh)
96 struct buffer_head *tmp = *bh;
98 rc = ocfs2_read_block(ci, rb_blkno, &tmp,
99 ocfs2_validate_refcount_block);
101 /* If ocfs2_read_block() got us a new bh, pass it up. */
108 static u64 ocfs2_refcount_cache_owner(struct ocfs2_caching_info *ci)
110 struct ocfs2_refcount_tree *rf = cache_info_to_refcount(ci);
115 static struct super_block *
116 ocfs2_refcount_cache_get_super(struct ocfs2_caching_info *ci)
118 struct ocfs2_refcount_tree *rf = cache_info_to_refcount(ci);
123 static void ocfs2_refcount_cache_lock(struct ocfs2_caching_info *ci)
125 struct ocfs2_refcount_tree *rf = cache_info_to_refcount(ci);
127 spin_lock(&rf->rf_lock);
130 static void ocfs2_refcount_cache_unlock(struct ocfs2_caching_info *ci)
132 struct ocfs2_refcount_tree *rf = cache_info_to_refcount(ci);
134 spin_unlock(&rf->rf_lock);
137 static void ocfs2_refcount_cache_io_lock(struct ocfs2_caching_info *ci)
139 struct ocfs2_refcount_tree *rf = cache_info_to_refcount(ci);
141 mutex_lock(&rf->rf_io_mutex);
144 static void ocfs2_refcount_cache_io_unlock(struct ocfs2_caching_info *ci)
146 struct ocfs2_refcount_tree *rf = cache_info_to_refcount(ci);
148 mutex_unlock(&rf->rf_io_mutex);
151 static const struct ocfs2_caching_operations ocfs2_refcount_caching_ops = {
152 .co_owner = ocfs2_refcount_cache_owner,
153 .co_get_super = ocfs2_refcount_cache_get_super,
154 .co_cache_lock = ocfs2_refcount_cache_lock,
155 .co_cache_unlock = ocfs2_refcount_cache_unlock,
156 .co_io_lock = ocfs2_refcount_cache_io_lock,
157 .co_io_unlock = ocfs2_refcount_cache_io_unlock,