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" 29c732eb16STao Ma #include "refcounttree.h" 30c732eb16STao Ma 31c732eb16STao Ma static inline struct ocfs2_refcount_tree * 32c732eb16STao Ma cache_info_to_refcount(struct ocfs2_caching_info *ci) 33c732eb16STao Ma { 34c732eb16STao Ma return container_of(ci, struct ocfs2_refcount_tree, rf_ci); 35c732eb16STao Ma } 36f2c870e3STao Ma 37f2c870e3STao Ma static int ocfs2_validate_refcount_block(struct super_block *sb, 38f2c870e3STao Ma struct buffer_head *bh) 39f2c870e3STao Ma { 40f2c870e3STao Ma int rc; 41f2c870e3STao Ma struct ocfs2_refcount_block *rb = 42f2c870e3STao Ma (struct ocfs2_refcount_block *)bh->b_data; 43f2c870e3STao Ma 44f2c870e3STao Ma mlog(0, "Validating refcount block %llu\n", 45f2c870e3STao Ma (unsigned long long)bh->b_blocknr); 46f2c870e3STao Ma 47f2c870e3STao Ma BUG_ON(!buffer_uptodate(bh)); 48f2c870e3STao Ma 49f2c870e3STao Ma /* 50f2c870e3STao Ma * If the ecc fails, we return the error but otherwise 51f2c870e3STao Ma * leave the filesystem running. We know any error is 52f2c870e3STao Ma * local to this block. 53f2c870e3STao Ma */ 54f2c870e3STao Ma rc = ocfs2_validate_meta_ecc(sb, bh->b_data, &rb->rf_check); 55f2c870e3STao Ma if (rc) { 56f2c870e3STao Ma mlog(ML_ERROR, "Checksum failed for refcount block %llu\n", 57f2c870e3STao Ma (unsigned long long)bh->b_blocknr); 58f2c870e3STao Ma return rc; 59f2c870e3STao Ma } 60f2c870e3STao Ma 61f2c870e3STao Ma 62f2c870e3STao Ma if (!OCFS2_IS_VALID_REFCOUNT_BLOCK(rb)) { 63f2c870e3STao Ma ocfs2_error(sb, 64f2c870e3STao Ma "Refcount block #%llu has bad signature %.*s", 65f2c870e3STao Ma (unsigned long long)bh->b_blocknr, 7, 66f2c870e3STao Ma rb->rf_signature); 67f2c870e3STao Ma return -EINVAL; 68f2c870e3STao Ma } 69f2c870e3STao Ma 70f2c870e3STao Ma if (le64_to_cpu(rb->rf_blkno) != bh->b_blocknr) { 71f2c870e3STao Ma ocfs2_error(sb, 72f2c870e3STao Ma "Refcount block #%llu has an invalid rf_blkno " 73f2c870e3STao Ma "of %llu", 74f2c870e3STao Ma (unsigned long long)bh->b_blocknr, 75f2c870e3STao Ma (unsigned long long)le64_to_cpu(rb->rf_blkno)); 76f2c870e3STao Ma return -EINVAL; 77f2c870e3STao Ma } 78f2c870e3STao Ma 79f2c870e3STao Ma if (le32_to_cpu(rb->rf_fs_generation) != OCFS2_SB(sb)->fs_generation) { 80f2c870e3STao Ma ocfs2_error(sb, 81f2c870e3STao Ma "Refcount block #%llu has an invalid " 82f2c870e3STao Ma "rf_fs_generation of #%u", 83f2c870e3STao Ma (unsigned long long)bh->b_blocknr, 84f2c870e3STao Ma le32_to_cpu(rb->rf_fs_generation)); 85f2c870e3STao Ma return -EINVAL; 86f2c870e3STao Ma } 87f2c870e3STao Ma 88f2c870e3STao Ma return 0; 89f2c870e3STao Ma } 90f2c870e3STao Ma 91f2c870e3STao Ma static int ocfs2_read_refcount_block(struct ocfs2_caching_info *ci, 92f2c870e3STao Ma u64 rb_blkno, 93f2c870e3STao Ma struct buffer_head **bh) 94f2c870e3STao Ma { 95f2c870e3STao Ma int rc; 96f2c870e3STao Ma struct buffer_head *tmp = *bh; 97f2c870e3STao Ma 98f2c870e3STao Ma rc = ocfs2_read_block(ci, rb_blkno, &tmp, 99f2c870e3STao Ma ocfs2_validate_refcount_block); 100f2c870e3STao Ma 101f2c870e3STao Ma /* If ocfs2_read_block() got us a new bh, pass it up. */ 102f2c870e3STao Ma if (!rc && !*bh) 103f2c870e3STao Ma *bh = tmp; 104f2c870e3STao Ma 105f2c870e3STao Ma return rc; 106f2c870e3STao Ma } 107c732eb16STao Ma 108c732eb16STao Ma static u64 ocfs2_refcount_cache_owner(struct ocfs2_caching_info *ci) 109c732eb16STao Ma { 110c732eb16STao Ma struct ocfs2_refcount_tree *rf = cache_info_to_refcount(ci); 111c732eb16STao Ma 112c732eb16STao Ma return rf->rf_blkno; 113c732eb16STao Ma } 114c732eb16STao Ma 115c732eb16STao Ma static struct super_block * 116c732eb16STao Ma ocfs2_refcount_cache_get_super(struct ocfs2_caching_info *ci) 117c732eb16STao Ma { 118c732eb16STao Ma struct ocfs2_refcount_tree *rf = cache_info_to_refcount(ci); 119c732eb16STao Ma 120c732eb16STao Ma return rf->rf_sb; 121c732eb16STao Ma } 122c732eb16STao Ma 123c732eb16STao Ma static void ocfs2_refcount_cache_lock(struct ocfs2_caching_info *ci) 124c732eb16STao Ma { 125c732eb16STao Ma struct ocfs2_refcount_tree *rf = cache_info_to_refcount(ci); 126c732eb16STao Ma 127c732eb16STao Ma spin_lock(&rf->rf_lock); 128c732eb16STao Ma } 129c732eb16STao Ma 130c732eb16STao Ma static void ocfs2_refcount_cache_unlock(struct ocfs2_caching_info *ci) 131c732eb16STao Ma { 132c732eb16STao Ma struct ocfs2_refcount_tree *rf = cache_info_to_refcount(ci); 133c732eb16STao Ma 134c732eb16STao Ma spin_unlock(&rf->rf_lock); 135c732eb16STao Ma } 136c732eb16STao Ma 137c732eb16STao Ma static void ocfs2_refcount_cache_io_lock(struct ocfs2_caching_info *ci) 138c732eb16STao Ma { 139c732eb16STao Ma struct ocfs2_refcount_tree *rf = cache_info_to_refcount(ci); 140c732eb16STao Ma 141c732eb16STao Ma mutex_lock(&rf->rf_io_mutex); 142c732eb16STao Ma } 143c732eb16STao Ma 144c732eb16STao Ma static void ocfs2_refcount_cache_io_unlock(struct ocfs2_caching_info *ci) 145c732eb16STao Ma { 146c732eb16STao Ma struct ocfs2_refcount_tree *rf = cache_info_to_refcount(ci); 147c732eb16STao Ma 148c732eb16STao Ma mutex_unlock(&rf->rf_io_mutex); 149c732eb16STao Ma } 150c732eb16STao Ma 151c732eb16STao Ma static const struct ocfs2_caching_operations ocfs2_refcount_caching_ops = { 152c732eb16STao Ma .co_owner = ocfs2_refcount_cache_owner, 153c732eb16STao Ma .co_get_super = ocfs2_refcount_cache_get_super, 154c732eb16STao Ma .co_cache_lock = ocfs2_refcount_cache_lock, 155c732eb16STao Ma .co_cache_unlock = ocfs2_refcount_cache_unlock, 156c732eb16STao Ma .co_io_lock = ocfs2_refcount_cache_io_lock, 157c732eb16STao Ma .co_io_unlock = ocfs2_refcount_cache_io_unlock, 158c732eb16STao Ma }; 159