2900 lines · 76.3 KB · C
RawDownload
/* -*- mode: c; c-basic-offset: 8; -*- * vim: noexpandtab sw=8 ts=8 sts=0: * * suballoc.c * * metadata alloc and free * Inspired by ext3 block groups. * * Copyright (C) 2002, 2004 Oracle.  All rights reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 021110-1307, USA. */ #include <linux/fs.h>#include <linux/types.h>#include <linux/slab.h>#include <linux/highmem.h> #include <cluster/masklog.h> #include "ocfs2.h" #include "alloc.h"#include "blockcheck.h"#include "dlmglue.h"#include "inode.h"#include "journal.h"#include "localalloc.h"#include "suballoc.h"#include "super.h"#include "sysfile.h"#include "uptodate.h"#include "ocfs2_trace.h" #include "buffer_head_io.h" #define NOT_ALLOC_NEW_GROUP		0#define ALLOC_NEW_GROUP			0x1#define ALLOC_GROUPS_FROM_GLOBAL	0x2 #define OCFS2_MAX_TO_STEAL		1024 struct ocfs2_suballoc_result {	u64		sr_bg_blkno;	/* The bg we allocated from.  Set					   to 0 when a block group is					   contiguous. */	u64		sr_bg_stable_blkno; /*					     * Doesn't change, always					     * set to target block					     * group descriptor					     * block.					     */	u64		sr_blkno;	/* The first allocated block */	unsigned int	sr_bit_offset;	/* The bit in the bg */	unsigned int	sr_bits;	/* How many bits we claimed */}; static u64 ocfs2_group_from_res(struct ocfs2_suballoc_result *res){	if (res->sr_blkno == 0)		return 0; 	if (res->sr_bg_blkno)		return res->sr_bg_blkno; 	return ocfs2_which_suballoc_group(res->sr_blkno, res->sr_bit_offset);} static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg);static inline void ocfs2_debug_suballoc_inode(struct ocfs2_dinode *fe);static inline u16 ocfs2_find_victim_chain(struct ocfs2_chain_list *cl);static int ocfs2_block_group_fill(handle_t *handle,				  struct inode *alloc_inode,				  struct buffer_head *bg_bh,				  u64 group_blkno,				  unsigned int group_clusters,				  u16 my_chain,				  struct ocfs2_chain_list *cl);static int ocfs2_block_group_alloc(struct ocfs2_super *osb,				   struct inode *alloc_inode,				   struct buffer_head *bh,				   u64 max_block,				   u64 *last_alloc_group,				   int flags); static int ocfs2_cluster_group_search(struct inode *inode,				      struct buffer_head *group_bh,				      u32 bits_wanted, u32 min_bits,				      u64 max_block,				      struct ocfs2_suballoc_result *res);static int ocfs2_block_group_search(struct inode *inode,				    struct buffer_head *group_bh,				    u32 bits_wanted, u32 min_bits,				    u64 max_block,				    struct ocfs2_suballoc_result *res);static int ocfs2_claim_suballoc_bits(struct ocfs2_alloc_context *ac,				     handle_t *handle,				     u32 bits_wanted,				     u32 min_bits,				     struct ocfs2_suballoc_result *res);static int ocfs2_test_bg_bit_allocatable(struct buffer_head *bg_bh,					 int nr);static inline int ocfs2_block_group_set_bits(handle_t *handle,					     struct inode *alloc_inode,					     struct ocfs2_group_desc *bg,					     struct buffer_head *group_bh,					     unsigned int bit_off,					     unsigned int num_bits);static int ocfs2_relink_block_group(handle_t *handle,				    struct inode *alloc_inode,				    struct buffer_head *fe_bh,				    struct buffer_head *bg_bh,				    struct buffer_head *prev_bg_bh,				    u16 chain);static inline int ocfs2_block_group_reasonably_empty(struct ocfs2_group_desc *bg,						     u32 wanted);static inline u32 ocfs2_desc_bitmap_to_cluster_off(struct inode *inode,						   u64 bg_blkno,						   u16 bg_bit_off);static inline void ocfs2_block_to_cluster_group(struct inode *inode,						u64 data_blkno,						u64 *bg_blkno,						u16 *bg_bit_off);static int ocfs2_reserve_clusters_with_limit(struct ocfs2_super *osb,					     u32 bits_wanted, u64 max_block,					     int flags,					     struct ocfs2_alloc_context **ac); void ocfs2_free_ac_resource(struct ocfs2_alloc_context *ac){	struct inode *inode = ac->ac_inode; 	if (inode) {		if (ac->ac_which != OCFS2_AC_USE_LOCAL)			ocfs2_inode_unlock(inode, 1); 		mutex_unlock(&inode->i_mutex); 		iput(inode);		ac->ac_inode = NULL;	}	brelse(ac->ac_bh);	ac->ac_bh = NULL;	ac->ac_resv = NULL;	if (ac->ac_find_loc_priv) {		kfree(ac->ac_find_loc_priv);		ac->ac_find_loc_priv = NULL;	}} void ocfs2_free_alloc_context(struct ocfs2_alloc_context *ac){	ocfs2_free_ac_resource(ac);	kfree(ac);} static u32 ocfs2_bits_per_group(struct ocfs2_chain_list *cl){	return (u32)le16_to_cpu(cl->cl_cpg) * (u32)le16_to_cpu(cl->cl_bpc);} #define do_error(fmt, ...)						\	do{								\		if (resize)					\			mlog(ML_ERROR, fmt "\n", ##__VA_ARGS__);	\		else							\			ocfs2_error(sb, fmt, ##__VA_ARGS__);		\	} while (0) static int ocfs2_validate_gd_self(struct super_block *sb,				  struct buffer_head *bh,				  int resize){	struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data; 	if (!OCFS2_IS_VALID_GROUP_DESC(gd)) {		do_error("Group descriptor #%llu has bad signature %.*s",			 (unsigned long long)bh->b_blocknr, 7,			 gd->bg_signature);		return -EINVAL;	} 	if (le64_to_cpu(gd->bg_blkno) != bh->b_blocknr) {		do_error("Group descriptor #%llu has an invalid bg_blkno "			 "of %llu",			 (unsigned long long)bh->b_blocknr,			 (unsigned long long)le64_to_cpu(gd->bg_blkno));		return -EINVAL;	} 	if (le32_to_cpu(gd->bg_generation) != OCFS2_SB(sb)->fs_generation) {		do_error("Group descriptor #%llu has an invalid "			 "fs_generation of #%u",			 (unsigned long long)bh->b_blocknr,			 le32_to_cpu(gd->bg_generation));		return -EINVAL;	} 	if (le16_to_cpu(gd->bg_free_bits_count) > le16_to_cpu(gd->bg_bits)) {		do_error("Group descriptor #%llu has bit count %u but "			 "claims that %u are free",			 (unsigned long long)bh->b_blocknr,			 le16_to_cpu(gd->bg_bits),			 le16_to_cpu(gd->bg_free_bits_count));		return -EINVAL;	} 	if (le16_to_cpu(gd->bg_bits) > (8 * le16_to_cpu(gd->bg_size))) {		do_error("Group descriptor #%llu has bit count %u but "			 "max bitmap bits of %u",			 (unsigned long long)bh->b_blocknr,			 le16_to_cpu(gd->bg_bits),			 8 * le16_to_cpu(gd->bg_size));		return -EINVAL;	} 	return 0;} static int ocfs2_validate_gd_parent(struct super_block *sb,				    struct ocfs2_dinode *di,				    struct buffer_head *bh,				    int resize){	unsigned int max_bits;	struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data; 	if (di->i_blkno != gd->bg_parent_dinode) {		do_error("Group descriptor #%llu has bad parent "			 "pointer (%llu, expected %llu)",			 (unsigned long long)bh->b_blocknr,			 (unsigned long long)le64_to_cpu(gd->bg_parent_dinode),			 (unsigned long long)le64_to_cpu(di->i_blkno));		return -EINVAL;	} 	max_bits = le16_to_cpu(di->id2.i_chain.cl_cpg) * le16_to_cpu(di->id2.i_chain.cl_bpc);	if (le16_to_cpu(gd->bg_bits) > max_bits) {		do_error("Group descriptor #%llu has bit count of %u",			 (unsigned long long)bh->b_blocknr,			 le16_to_cpu(gd->bg_bits));		return -EINVAL;	} 	/* In resize, we may meet the case bg_chain == cl_next_free_rec. */	if ((le16_to_cpu(gd->bg_chain) >	     le16_to_cpu(di->id2.i_chain.cl_next_free_rec)) ||	    ((le16_to_cpu(gd->bg_chain) ==	     le16_to_cpu(di->id2.i_chain.cl_next_free_rec)) && !resize)) {		do_error("Group descriptor #%llu has bad chain %u",			 (unsigned long long)bh->b_blocknr,			 le16_to_cpu(gd->bg_chain));		return -EINVAL;	} 	return 0;} #undef do_error /* * This version only prints errors.  It does not fail the filesystem, and * exists only for resize. */int ocfs2_check_group_descriptor(struct super_block *sb,				 struct ocfs2_dinode *di,				 struct buffer_head *bh){	int rc;	struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data; 	BUG_ON(!buffer_uptodate(bh)); 	/*	 * If the ecc fails, we return the error but otherwise	 * leave the filesystem running.  We know any error is	 * local to this block.	 */	rc = ocfs2_validate_meta_ecc(sb, bh->b_data, &gd->bg_check);	if (rc) {		mlog(ML_ERROR,		     "Checksum failed for group descriptor %llu\n",		     (unsigned long long)bh->b_blocknr);	} else		rc = ocfs2_validate_gd_self(sb, bh, 1);	if (!rc)		rc = ocfs2_validate_gd_parent(sb, di, bh, 1); 	return rc;} static int ocfs2_validate_group_descriptor(struct super_block *sb,					   struct buffer_head *bh){	int rc;	struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data; 	trace_ocfs2_validate_group_descriptor(					(unsigned long long)bh->b_blocknr); 	BUG_ON(!buffer_uptodate(bh)); 	/*	 * If the ecc fails, we return the error but otherwise	 * leave the filesystem running.  We know any error is	 * local to this block.	 */	rc = ocfs2_validate_meta_ecc(sb, bh->b_data, &gd->bg_check);	if (rc)		return rc; 	/*	 * Errors after here are fatal.	 */ 	return ocfs2_validate_gd_self(sb, bh, 0);} int ocfs2_read_group_descriptor(struct inode *inode, struct ocfs2_dinode *di,				u64 gd_blkno, struct buffer_head **bh){	int rc;	struct buffer_head *tmp = *bh; 	rc = ocfs2_read_block(INODE_CACHE(inode), gd_blkno, &tmp,			      ocfs2_validate_group_descriptor);	if (rc)		goto out; 	rc = ocfs2_validate_gd_parent(inode->i_sb, di, tmp, 0);	if (rc) {		brelse(tmp);		goto out;	} 	/* If ocfs2_read_block() got us a new bh, pass it up. */	if (!*bh)		*bh = tmp; out:	return rc;} static void ocfs2_bg_discontig_add_extent(struct ocfs2_super *osb,					  struct ocfs2_group_desc *bg,					  struct ocfs2_chain_list *cl,					  u64 p_blkno, unsigned int clusters){	struct ocfs2_extent_list *el = &bg->bg_list;	struct ocfs2_extent_rec *rec; 	BUG_ON(!ocfs2_supports_discontig_bg(osb));	if (!el->l_next_free_rec)		el->l_count = cpu_to_le16(ocfs2_extent_recs_per_gd(osb->sb));	rec = &el->l_recs[le16_to_cpu(el->l_next_free_rec)];	rec->e_blkno = cpu_to_le64(p_blkno);	rec->e_cpos = cpu_to_le32(le16_to_cpu(bg->bg_bits) /				  le16_to_cpu(cl->cl_bpc));	rec->e_leaf_clusters = cpu_to_le16(clusters);	le16_add_cpu(&bg->bg_bits, clusters * le16_to_cpu(cl->cl_bpc));	le16_add_cpu(&bg->bg_free_bits_count,		     clusters * le16_to_cpu(cl->cl_bpc));	le16_add_cpu(&el->l_next_free_rec, 1);} static int ocfs2_block_group_fill(handle_t *handle,				  struct inode *alloc_inode,				  struct buffer_head *bg_bh,				  u64 group_blkno,				  unsigned int group_clusters,				  u16 my_chain,				  struct ocfs2_chain_list *cl){	int status = 0;	struct ocfs2_super *osb = OCFS2_SB(alloc_inode->i_sb);	struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) bg_bh->b_data;	struct super_block * sb = alloc_inode->i_sb; 	if (((unsigned long long) bg_bh->b_blocknr) != group_blkno) {		ocfs2_error(alloc_inode->i_sb, "group block (%llu) != "			    "b_blocknr (%llu)",			    (unsigned long long)group_blkno,			    (unsigned long long) bg_bh->b_blocknr);		status = -EIO;		goto bail;	} 	status = ocfs2_journal_access_gd(handle,					 INODE_CACHE(alloc_inode),					 bg_bh,					 OCFS2_JOURNAL_ACCESS_CREATE);	if (status < 0) {		mlog_errno(status);		goto bail;	} 	memset(bg, 0, sb->s_blocksize);	strcpy(bg->bg_signature, OCFS2_GROUP_DESC_SIGNATURE);	bg->bg_generation = cpu_to_le32(OCFS2_SB(sb)->fs_generation);	bg->bg_size = cpu_to_le16(ocfs2_group_bitmap_size(sb, 1,						osb->s_feature_incompat));	bg->bg_chain = cpu_to_le16(my_chain);	bg->bg_next_group = cl->cl_recs[my_chain].c_blkno;	bg->bg_parent_dinode = cpu_to_le64(OCFS2_I(alloc_inode)->ip_blkno);	bg->bg_blkno = cpu_to_le64(group_blkno);	if (group_clusters == le16_to_cpu(cl->cl_cpg))		bg->bg_bits = cpu_to_le16(ocfs2_bits_per_group(cl));	else		ocfs2_bg_discontig_add_extent(osb, bg, cl, group_blkno,					      group_clusters); 	/* set the 1st bit in the bitmap to account for the descriptor block */	ocfs2_set_bit(0, (unsigned long *)bg->bg_bitmap);	bg->bg_free_bits_count = cpu_to_le16(le16_to_cpu(bg->bg_bits) - 1); 	ocfs2_journal_dirty(handle, bg_bh); 	/* There is no need to zero out or otherwise initialize the	 * other blocks in a group - All valid FS metadata in a block	 * group stores the superblock fs_generation value at	 * allocation time. */ bail:	if (status)		mlog_errno(status);	return status;} static inline u16 ocfs2_find_smallest_chain(struct ocfs2_chain_list *cl){	u16 curr, best; 	best = curr = 0;	while (curr < le16_to_cpu(cl->cl_count)) {		if (le32_to_cpu(cl->cl_recs[best].c_total) >		    le32_to_cpu(cl->cl_recs[curr].c_total))			best = curr;		curr++;	}	return best;} static struct buffer_head *ocfs2_block_group_alloc_contig(struct ocfs2_super *osb, handle_t *handle,			       struct inode *alloc_inode,			       struct ocfs2_alloc_context *ac,			       struct ocfs2_chain_list *cl){	int status;	u32 bit_off, num_bits;	u64 bg_blkno;	struct buffer_head *bg_bh;	unsigned int alloc_rec = ocfs2_find_smallest_chain(cl); 	status = ocfs2_claim_clusters(handle, ac,				      le16_to_cpu(cl->cl_cpg), &bit_off,				      &num_bits);	if (status < 0) {		if (status != -ENOSPC)			mlog_errno(status);		goto bail;	} 	/* setup the group */	bg_blkno = ocfs2_clusters_to_blocks(osb->sb, bit_off);	trace_ocfs2_block_group_alloc_contig(	     (unsigned long long)bg_blkno, alloc_rec); 	bg_bh = sb_getblk(osb->sb, bg_blkno);	if (!bg_bh) {		status = -ENOMEM;		mlog_errno(status);		goto bail;	}	ocfs2_set_new_buffer_uptodate(INODE_CACHE(alloc_inode), bg_bh); 	status = ocfs2_block_group_fill(handle, alloc_inode, bg_bh,					bg_blkno, num_bits, alloc_rec, cl);	if (status < 0) {		brelse(bg_bh);		mlog_errno(status);	} bail:	return status ? ERR_PTR(status) : bg_bh;} 

Lines 1–500 of 2900.