fs/ocfs2/refcounttree.c

Source file repositories/reference/linux-study-clean/fs/ocfs2/refcounttree.c

File Facts

System
Linux kernel
Corpus path
fs/ocfs2/refcounttree.c
Extension
.c
Size
123515 bytes
Lines
4812
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

struct ocfs2_cow_context {
	struct inode *inode;
	u32 cow_start;
	u32 cow_len;
	struct ocfs2_extent_tree data_et;
	struct ocfs2_refcount_tree *ref_tree;
	struct buffer_head *ref_root_bh;
	struct ocfs2_alloc_context *meta_ac;
	struct ocfs2_alloc_context *data_ac;
	struct ocfs2_cached_dealloc_ctxt dealloc;
	void *cow_object;
	struct ocfs2_post_refcount *post_refcount;
	int extra_credits;
	int (*get_clusters)(struct ocfs2_cow_context *context,
			    u32 v_cluster, u32 *p_cluster,
			    u32 *num_clusters,
			    unsigned int *extent_flags);
	int (*cow_duplicate_clusters)(handle_t *handle,
				      struct inode *inode,
				      u32 cpos, u32 old_cluster,
				      u32 new_cluster, u32 new_len);
};

static inline struct ocfs2_refcount_tree *
cache_info_to_refcount(struct ocfs2_caching_info *ci)
{
	return container_of(ci, struct ocfs2_refcount_tree, rf_ci);
}

static int ocfs2_validate_refcount_block(struct super_block *sb,
					 struct buffer_head *bh)
{
	int rc;
	struct ocfs2_refcount_block *rb =
		(struct ocfs2_refcount_block *)bh->b_data;

	trace_ocfs2_validate_refcount_block((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, &rb->rf_check);
	if (rc) {
		mlog(ML_ERROR, "Checksum failed for refcount block %llu\n",
		     (unsigned long long)bh->b_blocknr);
		return rc;
	}


	if (!OCFS2_IS_VALID_REFCOUNT_BLOCK(rb)) {
		rc = ocfs2_error(sb,
				 "Refcount block #%llu has bad signature %.*s\n",
				 (unsigned long long)bh->b_blocknr, 7,
				 rb->rf_signature);
		goto out;
	}

	if (le64_to_cpu(rb->rf_blkno) != bh->b_blocknr) {
		rc = ocfs2_error(sb,
				 "Refcount block #%llu has an invalid rf_blkno of %llu\n",
				 (unsigned long long)bh->b_blocknr,
				 (unsigned long long)le64_to_cpu(rb->rf_blkno));
		goto out;
	}

	if (le32_to_cpu(rb->rf_fs_generation) != OCFS2_SB(sb)->fs_generation) {
		rc = ocfs2_error(sb,
				 "Refcount block #%llu has an invalid rf_fs_generation of #%u\n",
				 (unsigned long long)bh->b_blocknr,
				 le32_to_cpu(rb->rf_fs_generation));
		goto out;
	}
out:
	return rc;
}

static int ocfs2_read_refcount_block(struct ocfs2_caching_info *ci,
				     u64 rb_blkno,
				     struct buffer_head **bh)
{
	int rc;
	struct buffer_head *tmp = *bh;

	rc = ocfs2_read_block(ci, rb_blkno, &tmp,
			      ocfs2_validate_refcount_block);

Annotation

Implementation Notes