18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/* -*- mode: c; c-basic-offset: 8; -*-
38c2ecf20Sopenharmony_ci * vim: noexpandtab sw=8 ts=8 sts=0:
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * refcounttree.c
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Copyright (C) 2009 Oracle.  All rights reserved.
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <linux/sort.h>
118c2ecf20Sopenharmony_ci#include <cluster/masklog.h>
128c2ecf20Sopenharmony_ci#include "ocfs2.h"
138c2ecf20Sopenharmony_ci#include "inode.h"
148c2ecf20Sopenharmony_ci#include "alloc.h"
158c2ecf20Sopenharmony_ci#include "suballoc.h"
168c2ecf20Sopenharmony_ci#include "journal.h"
178c2ecf20Sopenharmony_ci#include "uptodate.h"
188c2ecf20Sopenharmony_ci#include "super.h"
198c2ecf20Sopenharmony_ci#include "buffer_head_io.h"
208c2ecf20Sopenharmony_ci#include "blockcheck.h"
218c2ecf20Sopenharmony_ci#include "refcounttree.h"
228c2ecf20Sopenharmony_ci#include "sysfile.h"
238c2ecf20Sopenharmony_ci#include "dlmglue.h"
248c2ecf20Sopenharmony_ci#include "extent_map.h"
258c2ecf20Sopenharmony_ci#include "aops.h"
268c2ecf20Sopenharmony_ci#include "xattr.h"
278c2ecf20Sopenharmony_ci#include "namei.h"
288c2ecf20Sopenharmony_ci#include "ocfs2_trace.h"
298c2ecf20Sopenharmony_ci#include "file.h"
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci#include <linux/bio.h>
328c2ecf20Sopenharmony_ci#include <linux/blkdev.h>
338c2ecf20Sopenharmony_ci#include <linux/slab.h>
348c2ecf20Sopenharmony_ci#include <linux/writeback.h>
358c2ecf20Sopenharmony_ci#include <linux/pagevec.h>
368c2ecf20Sopenharmony_ci#include <linux/swap.h>
378c2ecf20Sopenharmony_ci#include <linux/security.h>
388c2ecf20Sopenharmony_ci#include <linux/fsnotify.h>
398c2ecf20Sopenharmony_ci#include <linux/quotaops.h>
408c2ecf20Sopenharmony_ci#include <linux/namei.h>
418c2ecf20Sopenharmony_ci#include <linux/mount.h>
428c2ecf20Sopenharmony_ci#include <linux/posix_acl.h>
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_cistruct ocfs2_cow_context {
458c2ecf20Sopenharmony_ci	struct inode *inode;
468c2ecf20Sopenharmony_ci	u32 cow_start;
478c2ecf20Sopenharmony_ci	u32 cow_len;
488c2ecf20Sopenharmony_ci	struct ocfs2_extent_tree data_et;
498c2ecf20Sopenharmony_ci	struct ocfs2_refcount_tree *ref_tree;
508c2ecf20Sopenharmony_ci	struct buffer_head *ref_root_bh;
518c2ecf20Sopenharmony_ci	struct ocfs2_alloc_context *meta_ac;
528c2ecf20Sopenharmony_ci	struct ocfs2_alloc_context *data_ac;
538c2ecf20Sopenharmony_ci	struct ocfs2_cached_dealloc_ctxt dealloc;
548c2ecf20Sopenharmony_ci	void *cow_object;
558c2ecf20Sopenharmony_ci	struct ocfs2_post_refcount *post_refcount;
568c2ecf20Sopenharmony_ci	int extra_credits;
578c2ecf20Sopenharmony_ci	int (*get_clusters)(struct ocfs2_cow_context *context,
588c2ecf20Sopenharmony_ci			    u32 v_cluster, u32 *p_cluster,
598c2ecf20Sopenharmony_ci			    u32 *num_clusters,
608c2ecf20Sopenharmony_ci			    unsigned int *extent_flags);
618c2ecf20Sopenharmony_ci	int (*cow_duplicate_clusters)(handle_t *handle,
628c2ecf20Sopenharmony_ci				      struct inode *inode,
638c2ecf20Sopenharmony_ci				      u32 cpos, u32 old_cluster,
648c2ecf20Sopenharmony_ci				      u32 new_cluster, u32 new_len);
658c2ecf20Sopenharmony_ci};
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_cistatic inline struct ocfs2_refcount_tree *
688c2ecf20Sopenharmony_cicache_info_to_refcount(struct ocfs2_caching_info *ci)
698c2ecf20Sopenharmony_ci{
708c2ecf20Sopenharmony_ci	return container_of(ci, struct ocfs2_refcount_tree, rf_ci);
718c2ecf20Sopenharmony_ci}
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_cistatic int ocfs2_validate_refcount_block(struct super_block *sb,
748c2ecf20Sopenharmony_ci					 struct buffer_head *bh)
758c2ecf20Sopenharmony_ci{
768c2ecf20Sopenharmony_ci	int rc;
778c2ecf20Sopenharmony_ci	struct ocfs2_refcount_block *rb =
788c2ecf20Sopenharmony_ci		(struct ocfs2_refcount_block *)bh->b_data;
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci	trace_ocfs2_validate_refcount_block((unsigned long long)bh->b_blocknr);
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci	BUG_ON(!buffer_uptodate(bh));
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci	/*
858c2ecf20Sopenharmony_ci	 * If the ecc fails, we return the error but otherwise
868c2ecf20Sopenharmony_ci	 * leave the filesystem running.  We know any error is
878c2ecf20Sopenharmony_ci	 * local to this block.
888c2ecf20Sopenharmony_ci	 */
898c2ecf20Sopenharmony_ci	rc = ocfs2_validate_meta_ecc(sb, bh->b_data, &rb->rf_check);
908c2ecf20Sopenharmony_ci	if (rc) {
918c2ecf20Sopenharmony_ci		mlog(ML_ERROR, "Checksum failed for refcount block %llu\n",
928c2ecf20Sopenharmony_ci		     (unsigned long long)bh->b_blocknr);
938c2ecf20Sopenharmony_ci		return rc;
948c2ecf20Sopenharmony_ci	}
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci	if (!OCFS2_IS_VALID_REFCOUNT_BLOCK(rb)) {
988c2ecf20Sopenharmony_ci		rc = ocfs2_error(sb,
998c2ecf20Sopenharmony_ci				 "Refcount block #%llu has bad signature %.*s\n",
1008c2ecf20Sopenharmony_ci				 (unsigned long long)bh->b_blocknr, 7,
1018c2ecf20Sopenharmony_ci				 rb->rf_signature);
1028c2ecf20Sopenharmony_ci		goto out;
1038c2ecf20Sopenharmony_ci	}
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci	if (le64_to_cpu(rb->rf_blkno) != bh->b_blocknr) {
1068c2ecf20Sopenharmony_ci		rc = ocfs2_error(sb,
1078c2ecf20Sopenharmony_ci				 "Refcount block #%llu has an invalid rf_blkno of %llu\n",
1088c2ecf20Sopenharmony_ci				 (unsigned long long)bh->b_blocknr,
1098c2ecf20Sopenharmony_ci				 (unsigned long long)le64_to_cpu(rb->rf_blkno));
1108c2ecf20Sopenharmony_ci		goto out;
1118c2ecf20Sopenharmony_ci	}
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ci	if (le32_to_cpu(rb->rf_fs_generation) != OCFS2_SB(sb)->fs_generation) {
1148c2ecf20Sopenharmony_ci		rc = ocfs2_error(sb,
1158c2ecf20Sopenharmony_ci				 "Refcount block #%llu has an invalid rf_fs_generation of #%u\n",
1168c2ecf20Sopenharmony_ci				 (unsigned long long)bh->b_blocknr,
1178c2ecf20Sopenharmony_ci				 le32_to_cpu(rb->rf_fs_generation));
1188c2ecf20Sopenharmony_ci		goto out;
1198c2ecf20Sopenharmony_ci	}
1208c2ecf20Sopenharmony_ciout:
1218c2ecf20Sopenharmony_ci	return rc;
1228c2ecf20Sopenharmony_ci}
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_cistatic int ocfs2_read_refcount_block(struct ocfs2_caching_info *ci,
1258c2ecf20Sopenharmony_ci				     u64 rb_blkno,
1268c2ecf20Sopenharmony_ci				     struct buffer_head **bh)
1278c2ecf20Sopenharmony_ci{
1288c2ecf20Sopenharmony_ci	int rc;
1298c2ecf20Sopenharmony_ci	struct buffer_head *tmp = *bh;
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci	rc = ocfs2_read_block(ci, rb_blkno, &tmp,
1328c2ecf20Sopenharmony_ci			      ocfs2_validate_refcount_block);
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ci	/* If ocfs2_read_block() got us a new bh, pass it up. */
1358c2ecf20Sopenharmony_ci	if (!rc && !*bh)
1368c2ecf20Sopenharmony_ci		*bh = tmp;
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ci	return rc;
1398c2ecf20Sopenharmony_ci}
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_cistatic u64 ocfs2_refcount_cache_owner(struct ocfs2_caching_info *ci)
1428c2ecf20Sopenharmony_ci{
1438c2ecf20Sopenharmony_ci	struct ocfs2_refcount_tree *rf = cache_info_to_refcount(ci);
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ci	return rf->rf_blkno;
1468c2ecf20Sopenharmony_ci}
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_cistatic struct super_block *
1498c2ecf20Sopenharmony_ciocfs2_refcount_cache_get_super(struct ocfs2_caching_info *ci)
1508c2ecf20Sopenharmony_ci{
1518c2ecf20Sopenharmony_ci	struct ocfs2_refcount_tree *rf = cache_info_to_refcount(ci);
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci	return rf->rf_sb;
1548c2ecf20Sopenharmony_ci}
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_cistatic void ocfs2_refcount_cache_lock(struct ocfs2_caching_info *ci)
1578c2ecf20Sopenharmony_ci__acquires(&rf->rf_lock)
1588c2ecf20Sopenharmony_ci{
1598c2ecf20Sopenharmony_ci	struct ocfs2_refcount_tree *rf = cache_info_to_refcount(ci);
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_ci	spin_lock(&rf->rf_lock);
1628c2ecf20Sopenharmony_ci}
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_cistatic void ocfs2_refcount_cache_unlock(struct ocfs2_caching_info *ci)
1658c2ecf20Sopenharmony_ci__releases(&rf->rf_lock)
1668c2ecf20Sopenharmony_ci{
1678c2ecf20Sopenharmony_ci	struct ocfs2_refcount_tree *rf = cache_info_to_refcount(ci);
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ci	spin_unlock(&rf->rf_lock);
1708c2ecf20Sopenharmony_ci}
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_cistatic void ocfs2_refcount_cache_io_lock(struct ocfs2_caching_info *ci)
1738c2ecf20Sopenharmony_ci{
1748c2ecf20Sopenharmony_ci	struct ocfs2_refcount_tree *rf = cache_info_to_refcount(ci);
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_ci	mutex_lock(&rf->rf_io_mutex);
1778c2ecf20Sopenharmony_ci}
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_cistatic void ocfs2_refcount_cache_io_unlock(struct ocfs2_caching_info *ci)
1808c2ecf20Sopenharmony_ci{
1818c2ecf20Sopenharmony_ci	struct ocfs2_refcount_tree *rf = cache_info_to_refcount(ci);
1828c2ecf20Sopenharmony_ci
1838c2ecf20Sopenharmony_ci	mutex_unlock(&rf->rf_io_mutex);
1848c2ecf20Sopenharmony_ci}
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_cistatic const struct ocfs2_caching_operations ocfs2_refcount_caching_ops = {
1878c2ecf20Sopenharmony_ci	.co_owner		= ocfs2_refcount_cache_owner,
1888c2ecf20Sopenharmony_ci	.co_get_super		= ocfs2_refcount_cache_get_super,
1898c2ecf20Sopenharmony_ci	.co_cache_lock		= ocfs2_refcount_cache_lock,
1908c2ecf20Sopenharmony_ci	.co_cache_unlock	= ocfs2_refcount_cache_unlock,
1918c2ecf20Sopenharmony_ci	.co_io_lock		= ocfs2_refcount_cache_io_lock,
1928c2ecf20Sopenharmony_ci	.co_io_unlock		= ocfs2_refcount_cache_io_unlock,
1938c2ecf20Sopenharmony_ci};
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_cistatic struct ocfs2_refcount_tree *
1968c2ecf20Sopenharmony_ciocfs2_find_refcount_tree(struct ocfs2_super *osb, u64 blkno)
1978c2ecf20Sopenharmony_ci{
1988c2ecf20Sopenharmony_ci	struct rb_node *n = osb->osb_rf_lock_tree.rb_node;
1998c2ecf20Sopenharmony_ci	struct ocfs2_refcount_tree *tree = NULL;
2008c2ecf20Sopenharmony_ci
2018c2ecf20Sopenharmony_ci	while (n) {
2028c2ecf20Sopenharmony_ci		tree = rb_entry(n, struct ocfs2_refcount_tree, rf_node);
2038c2ecf20Sopenharmony_ci
2048c2ecf20Sopenharmony_ci		if (blkno < tree->rf_blkno)
2058c2ecf20Sopenharmony_ci			n = n->rb_left;
2068c2ecf20Sopenharmony_ci		else if (blkno > tree->rf_blkno)
2078c2ecf20Sopenharmony_ci			n = n->rb_right;
2088c2ecf20Sopenharmony_ci		else
2098c2ecf20Sopenharmony_ci			return tree;
2108c2ecf20Sopenharmony_ci	}
2118c2ecf20Sopenharmony_ci
2128c2ecf20Sopenharmony_ci	return NULL;
2138c2ecf20Sopenharmony_ci}
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_ci/* osb_lock is already locked. */
2168c2ecf20Sopenharmony_cistatic void ocfs2_insert_refcount_tree(struct ocfs2_super *osb,
2178c2ecf20Sopenharmony_ci				       struct ocfs2_refcount_tree *new)
2188c2ecf20Sopenharmony_ci{
2198c2ecf20Sopenharmony_ci	u64 rf_blkno = new->rf_blkno;
2208c2ecf20Sopenharmony_ci	struct rb_node *parent = NULL;
2218c2ecf20Sopenharmony_ci	struct rb_node **p = &osb->osb_rf_lock_tree.rb_node;
2228c2ecf20Sopenharmony_ci	struct ocfs2_refcount_tree *tmp;
2238c2ecf20Sopenharmony_ci
2248c2ecf20Sopenharmony_ci	while (*p) {
2258c2ecf20Sopenharmony_ci		parent = *p;
2268c2ecf20Sopenharmony_ci
2278c2ecf20Sopenharmony_ci		tmp = rb_entry(parent, struct ocfs2_refcount_tree,
2288c2ecf20Sopenharmony_ci			       rf_node);
2298c2ecf20Sopenharmony_ci
2308c2ecf20Sopenharmony_ci		if (rf_blkno < tmp->rf_blkno)
2318c2ecf20Sopenharmony_ci			p = &(*p)->rb_left;
2328c2ecf20Sopenharmony_ci		else if (rf_blkno > tmp->rf_blkno)
2338c2ecf20Sopenharmony_ci			p = &(*p)->rb_right;
2348c2ecf20Sopenharmony_ci		else {
2358c2ecf20Sopenharmony_ci			/* This should never happen! */
2368c2ecf20Sopenharmony_ci			mlog(ML_ERROR, "Duplicate refcount block %llu found!\n",
2378c2ecf20Sopenharmony_ci			     (unsigned long long)rf_blkno);
2388c2ecf20Sopenharmony_ci			BUG();
2398c2ecf20Sopenharmony_ci		}
2408c2ecf20Sopenharmony_ci	}
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_ci	rb_link_node(&new->rf_node, parent, p);
2438c2ecf20Sopenharmony_ci	rb_insert_color(&new->rf_node, &osb->osb_rf_lock_tree);
2448c2ecf20Sopenharmony_ci}
2458c2ecf20Sopenharmony_ci
2468c2ecf20Sopenharmony_cistatic void ocfs2_free_refcount_tree(struct ocfs2_refcount_tree *tree)
2478c2ecf20Sopenharmony_ci{
2488c2ecf20Sopenharmony_ci	ocfs2_metadata_cache_exit(&tree->rf_ci);
2498c2ecf20Sopenharmony_ci	ocfs2_simple_drop_lockres(OCFS2_SB(tree->rf_sb), &tree->rf_lockres);
2508c2ecf20Sopenharmony_ci	ocfs2_lock_res_free(&tree->rf_lockres);
2518c2ecf20Sopenharmony_ci	kfree(tree);
2528c2ecf20Sopenharmony_ci}
2538c2ecf20Sopenharmony_ci
2548c2ecf20Sopenharmony_cistatic inline void
2558c2ecf20Sopenharmony_ciocfs2_erase_refcount_tree_from_list_no_lock(struct ocfs2_super *osb,
2568c2ecf20Sopenharmony_ci					struct ocfs2_refcount_tree *tree)
2578c2ecf20Sopenharmony_ci{
2588c2ecf20Sopenharmony_ci	rb_erase(&tree->rf_node, &osb->osb_rf_lock_tree);
2598c2ecf20Sopenharmony_ci	if (osb->osb_ref_tree_lru && osb->osb_ref_tree_lru == tree)
2608c2ecf20Sopenharmony_ci		osb->osb_ref_tree_lru = NULL;
2618c2ecf20Sopenharmony_ci}
2628c2ecf20Sopenharmony_ci
2638c2ecf20Sopenharmony_cistatic void ocfs2_erase_refcount_tree_from_list(struct ocfs2_super *osb,
2648c2ecf20Sopenharmony_ci					struct ocfs2_refcount_tree *tree)
2658c2ecf20Sopenharmony_ci{
2668c2ecf20Sopenharmony_ci	spin_lock(&osb->osb_lock);
2678c2ecf20Sopenharmony_ci	ocfs2_erase_refcount_tree_from_list_no_lock(osb, tree);
2688c2ecf20Sopenharmony_ci	spin_unlock(&osb->osb_lock);
2698c2ecf20Sopenharmony_ci}
2708c2ecf20Sopenharmony_ci
2718c2ecf20Sopenharmony_cistatic void ocfs2_kref_remove_refcount_tree(struct kref *kref)
2728c2ecf20Sopenharmony_ci{
2738c2ecf20Sopenharmony_ci	struct ocfs2_refcount_tree *tree =
2748c2ecf20Sopenharmony_ci		container_of(kref, struct ocfs2_refcount_tree, rf_getcnt);
2758c2ecf20Sopenharmony_ci
2768c2ecf20Sopenharmony_ci	ocfs2_free_refcount_tree(tree);
2778c2ecf20Sopenharmony_ci}
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_cistatic inline void
2808c2ecf20Sopenharmony_ciocfs2_refcount_tree_get(struct ocfs2_refcount_tree *tree)
2818c2ecf20Sopenharmony_ci{
2828c2ecf20Sopenharmony_ci	kref_get(&tree->rf_getcnt);
2838c2ecf20Sopenharmony_ci}
2848c2ecf20Sopenharmony_ci
2858c2ecf20Sopenharmony_cistatic inline void
2868c2ecf20Sopenharmony_ciocfs2_refcount_tree_put(struct ocfs2_refcount_tree *tree)
2878c2ecf20Sopenharmony_ci{
2888c2ecf20Sopenharmony_ci	kref_put(&tree->rf_getcnt, ocfs2_kref_remove_refcount_tree);
2898c2ecf20Sopenharmony_ci}
2908c2ecf20Sopenharmony_ci
2918c2ecf20Sopenharmony_cistatic inline void ocfs2_init_refcount_tree_ci(struct ocfs2_refcount_tree *new,
2928c2ecf20Sopenharmony_ci					       struct super_block *sb)
2938c2ecf20Sopenharmony_ci{
2948c2ecf20Sopenharmony_ci	ocfs2_metadata_cache_init(&new->rf_ci, &ocfs2_refcount_caching_ops);
2958c2ecf20Sopenharmony_ci	mutex_init(&new->rf_io_mutex);
2968c2ecf20Sopenharmony_ci	new->rf_sb = sb;
2978c2ecf20Sopenharmony_ci	spin_lock_init(&new->rf_lock);
2988c2ecf20Sopenharmony_ci}
2998c2ecf20Sopenharmony_ci
3008c2ecf20Sopenharmony_cistatic inline void ocfs2_init_refcount_tree_lock(struct ocfs2_super *osb,
3018c2ecf20Sopenharmony_ci					struct ocfs2_refcount_tree *new,
3028c2ecf20Sopenharmony_ci					u64 rf_blkno, u32 generation)
3038c2ecf20Sopenharmony_ci{
3048c2ecf20Sopenharmony_ci	init_rwsem(&new->rf_sem);
3058c2ecf20Sopenharmony_ci	ocfs2_refcount_lock_res_init(&new->rf_lockres, osb,
3068c2ecf20Sopenharmony_ci				     rf_blkno, generation);
3078c2ecf20Sopenharmony_ci}
3088c2ecf20Sopenharmony_ci
3098c2ecf20Sopenharmony_cistatic struct ocfs2_refcount_tree*
3108c2ecf20Sopenharmony_ciocfs2_allocate_refcount_tree(struct ocfs2_super *osb, u64 rf_blkno)
3118c2ecf20Sopenharmony_ci{
3128c2ecf20Sopenharmony_ci	struct ocfs2_refcount_tree *new;
3138c2ecf20Sopenharmony_ci
3148c2ecf20Sopenharmony_ci	new = kzalloc(sizeof(struct ocfs2_refcount_tree), GFP_NOFS);
3158c2ecf20Sopenharmony_ci	if (!new)
3168c2ecf20Sopenharmony_ci		return NULL;
3178c2ecf20Sopenharmony_ci
3188c2ecf20Sopenharmony_ci	new->rf_blkno = rf_blkno;
3198c2ecf20Sopenharmony_ci	kref_init(&new->rf_getcnt);
3208c2ecf20Sopenharmony_ci	ocfs2_init_refcount_tree_ci(new, osb->sb);
3218c2ecf20Sopenharmony_ci
3228c2ecf20Sopenharmony_ci	return new;
3238c2ecf20Sopenharmony_ci}
3248c2ecf20Sopenharmony_ci
3258c2ecf20Sopenharmony_cistatic int ocfs2_get_refcount_tree(struct ocfs2_super *osb, u64 rf_blkno,
3268c2ecf20Sopenharmony_ci				   struct ocfs2_refcount_tree **ret_tree)
3278c2ecf20Sopenharmony_ci{
3288c2ecf20Sopenharmony_ci	int ret = 0;
3298c2ecf20Sopenharmony_ci	struct ocfs2_refcount_tree *tree, *new = NULL;
3308c2ecf20Sopenharmony_ci	struct buffer_head *ref_root_bh = NULL;
3318c2ecf20Sopenharmony_ci	struct ocfs2_refcount_block *ref_rb;
3328c2ecf20Sopenharmony_ci
3338c2ecf20Sopenharmony_ci	spin_lock(&osb->osb_lock);
3348c2ecf20Sopenharmony_ci	if (osb->osb_ref_tree_lru &&
3358c2ecf20Sopenharmony_ci	    osb->osb_ref_tree_lru->rf_blkno == rf_blkno)
3368c2ecf20Sopenharmony_ci		tree = osb->osb_ref_tree_lru;
3378c2ecf20Sopenharmony_ci	else
3388c2ecf20Sopenharmony_ci		tree = ocfs2_find_refcount_tree(osb, rf_blkno);
3398c2ecf20Sopenharmony_ci	if (tree)
3408c2ecf20Sopenharmony_ci		goto out;
3418c2ecf20Sopenharmony_ci
3428c2ecf20Sopenharmony_ci	spin_unlock(&osb->osb_lock);
3438c2ecf20Sopenharmony_ci
3448c2ecf20Sopenharmony_ci	new = ocfs2_allocate_refcount_tree(osb, rf_blkno);
3458c2ecf20Sopenharmony_ci	if (!new) {
3468c2ecf20Sopenharmony_ci		ret = -ENOMEM;
3478c2ecf20Sopenharmony_ci		mlog_errno(ret);
3488c2ecf20Sopenharmony_ci		return ret;
3498c2ecf20Sopenharmony_ci	}
3508c2ecf20Sopenharmony_ci	/*
3518c2ecf20Sopenharmony_ci	 * We need the generation to create the refcount tree lock and since
3528c2ecf20Sopenharmony_ci	 * it isn't changed during the tree modification, we are safe here to
3538c2ecf20Sopenharmony_ci	 * read without protection.
3548c2ecf20Sopenharmony_ci	 * We also have to purge the cache after we create the lock since the
3558c2ecf20Sopenharmony_ci	 * refcount block may have the stale data. It can only be trusted when
3568c2ecf20Sopenharmony_ci	 * we hold the refcount lock.
3578c2ecf20Sopenharmony_ci	 */
3588c2ecf20Sopenharmony_ci	ret = ocfs2_read_refcount_block(&new->rf_ci, rf_blkno, &ref_root_bh);
3598c2ecf20Sopenharmony_ci	if (ret) {
3608c2ecf20Sopenharmony_ci		mlog_errno(ret);
3618c2ecf20Sopenharmony_ci		ocfs2_metadata_cache_exit(&new->rf_ci);
3628c2ecf20Sopenharmony_ci		kfree(new);
3638c2ecf20Sopenharmony_ci		return ret;
3648c2ecf20Sopenharmony_ci	}
3658c2ecf20Sopenharmony_ci
3668c2ecf20Sopenharmony_ci	ref_rb = (struct ocfs2_refcount_block *)ref_root_bh->b_data;
3678c2ecf20Sopenharmony_ci	new->rf_generation = le32_to_cpu(ref_rb->rf_generation);
3688c2ecf20Sopenharmony_ci	ocfs2_init_refcount_tree_lock(osb, new, rf_blkno,
3698c2ecf20Sopenharmony_ci				      new->rf_generation);
3708c2ecf20Sopenharmony_ci	ocfs2_metadata_cache_purge(&new->rf_ci);
3718c2ecf20Sopenharmony_ci
3728c2ecf20Sopenharmony_ci	spin_lock(&osb->osb_lock);
3738c2ecf20Sopenharmony_ci	tree = ocfs2_find_refcount_tree(osb, rf_blkno);
3748c2ecf20Sopenharmony_ci	if (tree)
3758c2ecf20Sopenharmony_ci		goto out;
3768c2ecf20Sopenharmony_ci
3778c2ecf20Sopenharmony_ci	ocfs2_insert_refcount_tree(osb, new);
3788c2ecf20Sopenharmony_ci
3798c2ecf20Sopenharmony_ci	tree = new;
3808c2ecf20Sopenharmony_ci	new = NULL;
3818c2ecf20Sopenharmony_ci
3828c2ecf20Sopenharmony_ciout:
3838c2ecf20Sopenharmony_ci	*ret_tree = tree;
3848c2ecf20Sopenharmony_ci
3858c2ecf20Sopenharmony_ci	osb->osb_ref_tree_lru = tree;
3868c2ecf20Sopenharmony_ci
3878c2ecf20Sopenharmony_ci	spin_unlock(&osb->osb_lock);
3888c2ecf20Sopenharmony_ci
3898c2ecf20Sopenharmony_ci	if (new)
3908c2ecf20Sopenharmony_ci		ocfs2_free_refcount_tree(new);
3918c2ecf20Sopenharmony_ci
3928c2ecf20Sopenharmony_ci	brelse(ref_root_bh);
3938c2ecf20Sopenharmony_ci	return ret;
3948c2ecf20Sopenharmony_ci}
3958c2ecf20Sopenharmony_ci
3968c2ecf20Sopenharmony_cistatic int ocfs2_get_refcount_block(struct inode *inode, u64 *ref_blkno)
3978c2ecf20Sopenharmony_ci{
3988c2ecf20Sopenharmony_ci	int ret;
3998c2ecf20Sopenharmony_ci	struct buffer_head *di_bh = NULL;
4008c2ecf20Sopenharmony_ci	struct ocfs2_dinode *di;
4018c2ecf20Sopenharmony_ci
4028c2ecf20Sopenharmony_ci	ret = ocfs2_read_inode_block(inode, &di_bh);
4038c2ecf20Sopenharmony_ci	if (ret) {
4048c2ecf20Sopenharmony_ci		mlog_errno(ret);
4058c2ecf20Sopenharmony_ci		goto out;
4068c2ecf20Sopenharmony_ci	}
4078c2ecf20Sopenharmony_ci
4088c2ecf20Sopenharmony_ci	BUG_ON(!ocfs2_is_refcount_inode(inode));
4098c2ecf20Sopenharmony_ci
4108c2ecf20Sopenharmony_ci	di = (struct ocfs2_dinode *)di_bh->b_data;
4118c2ecf20Sopenharmony_ci	*ref_blkno = le64_to_cpu(di->i_refcount_loc);
4128c2ecf20Sopenharmony_ci	brelse(di_bh);
4138c2ecf20Sopenharmony_ciout:
4148c2ecf20Sopenharmony_ci	return ret;
4158c2ecf20Sopenharmony_ci}
4168c2ecf20Sopenharmony_ci
4178c2ecf20Sopenharmony_cistatic int __ocfs2_lock_refcount_tree(struct ocfs2_super *osb,
4188c2ecf20Sopenharmony_ci				      struct ocfs2_refcount_tree *tree, int rw)
4198c2ecf20Sopenharmony_ci{
4208c2ecf20Sopenharmony_ci	int ret;
4218c2ecf20Sopenharmony_ci
4228c2ecf20Sopenharmony_ci	ret = ocfs2_refcount_lock(tree, rw);
4238c2ecf20Sopenharmony_ci	if (ret) {
4248c2ecf20Sopenharmony_ci		mlog_errno(ret);
4258c2ecf20Sopenharmony_ci		goto out;
4268c2ecf20Sopenharmony_ci	}
4278c2ecf20Sopenharmony_ci
4288c2ecf20Sopenharmony_ci	if (rw)
4298c2ecf20Sopenharmony_ci		down_write(&tree->rf_sem);
4308c2ecf20Sopenharmony_ci	else
4318c2ecf20Sopenharmony_ci		down_read(&tree->rf_sem);
4328c2ecf20Sopenharmony_ci
4338c2ecf20Sopenharmony_ciout:
4348c2ecf20Sopenharmony_ci	return ret;
4358c2ecf20Sopenharmony_ci}
4368c2ecf20Sopenharmony_ci
4378c2ecf20Sopenharmony_ci/*
4388c2ecf20Sopenharmony_ci * Lock the refcount tree pointed by ref_blkno and return the tree.
4398c2ecf20Sopenharmony_ci * In most case, we lock the tree and read the refcount block.
4408c2ecf20Sopenharmony_ci * So read it here if the caller really needs it.
4418c2ecf20Sopenharmony_ci *
4428c2ecf20Sopenharmony_ci * If the tree has been re-created by other node, it will free the
4438c2ecf20Sopenharmony_ci * old one and re-create it.
4448c2ecf20Sopenharmony_ci */
4458c2ecf20Sopenharmony_ciint ocfs2_lock_refcount_tree(struct ocfs2_super *osb,
4468c2ecf20Sopenharmony_ci			     u64 ref_blkno, int rw,
4478c2ecf20Sopenharmony_ci			     struct ocfs2_refcount_tree **ret_tree,
4488c2ecf20Sopenharmony_ci			     struct buffer_head **ref_bh)
4498c2ecf20Sopenharmony_ci{
4508c2ecf20Sopenharmony_ci	int ret, delete_tree = 0;
4518c2ecf20Sopenharmony_ci	struct ocfs2_refcount_tree *tree = NULL;
4528c2ecf20Sopenharmony_ci	struct buffer_head *ref_root_bh = NULL;
4538c2ecf20Sopenharmony_ci	struct ocfs2_refcount_block *rb;
4548c2ecf20Sopenharmony_ci
4558c2ecf20Sopenharmony_ciagain:
4568c2ecf20Sopenharmony_ci	ret = ocfs2_get_refcount_tree(osb, ref_blkno, &tree);
4578c2ecf20Sopenharmony_ci	if (ret) {
4588c2ecf20Sopenharmony_ci		mlog_errno(ret);
4598c2ecf20Sopenharmony_ci		return ret;
4608c2ecf20Sopenharmony_ci	}
4618c2ecf20Sopenharmony_ci
4628c2ecf20Sopenharmony_ci	ocfs2_refcount_tree_get(tree);
4638c2ecf20Sopenharmony_ci
4648c2ecf20Sopenharmony_ci	ret = __ocfs2_lock_refcount_tree(osb, tree, rw);
4658c2ecf20Sopenharmony_ci	if (ret) {
4668c2ecf20Sopenharmony_ci		mlog_errno(ret);
4678c2ecf20Sopenharmony_ci		ocfs2_refcount_tree_put(tree);
4688c2ecf20Sopenharmony_ci		goto out;
4698c2ecf20Sopenharmony_ci	}
4708c2ecf20Sopenharmony_ci
4718c2ecf20Sopenharmony_ci	ret = ocfs2_read_refcount_block(&tree->rf_ci, tree->rf_blkno,
4728c2ecf20Sopenharmony_ci					&ref_root_bh);
4738c2ecf20Sopenharmony_ci	if (ret) {
4748c2ecf20Sopenharmony_ci		mlog_errno(ret);
4758c2ecf20Sopenharmony_ci		ocfs2_unlock_refcount_tree(osb, tree, rw);
4768c2ecf20Sopenharmony_ci		goto out;
4778c2ecf20Sopenharmony_ci	}
4788c2ecf20Sopenharmony_ci
4798c2ecf20Sopenharmony_ci	rb = (struct ocfs2_refcount_block *)ref_root_bh->b_data;
4808c2ecf20Sopenharmony_ci	/*
4818c2ecf20Sopenharmony_ci	 * If the refcount block has been freed and re-created, we may need
4828c2ecf20Sopenharmony_ci	 * to recreate the refcount tree also.
4838c2ecf20Sopenharmony_ci	 *
4848c2ecf20Sopenharmony_ci	 * Here we just remove the tree from the rb-tree, and the last
4858c2ecf20Sopenharmony_ci	 * kref holder will unlock and delete this refcount_tree.
4868c2ecf20Sopenharmony_ci	 * Then we goto "again" and ocfs2_get_refcount_tree will create
4878c2ecf20Sopenharmony_ci	 * the new refcount tree for us.
4888c2ecf20Sopenharmony_ci	 */
4898c2ecf20Sopenharmony_ci	if (tree->rf_generation != le32_to_cpu(rb->rf_generation)) {
4908c2ecf20Sopenharmony_ci		if (!tree->rf_removed) {
4918c2ecf20Sopenharmony_ci			ocfs2_erase_refcount_tree_from_list(osb, tree);
4928c2ecf20Sopenharmony_ci			tree->rf_removed = 1;
4938c2ecf20Sopenharmony_ci			delete_tree = 1;
4948c2ecf20Sopenharmony_ci		}
4958c2ecf20Sopenharmony_ci
4968c2ecf20Sopenharmony_ci		ocfs2_unlock_refcount_tree(osb, tree, rw);
4978c2ecf20Sopenharmony_ci		/*
4988c2ecf20Sopenharmony_ci		 * We get an extra reference when we create the refcount
4998c2ecf20Sopenharmony_ci		 * tree, so another put will destroy it.
5008c2ecf20Sopenharmony_ci		 */
5018c2ecf20Sopenharmony_ci		if (delete_tree)
5028c2ecf20Sopenharmony_ci			ocfs2_refcount_tree_put(tree);
5038c2ecf20Sopenharmony_ci		brelse(ref_root_bh);
5048c2ecf20Sopenharmony_ci		ref_root_bh = NULL;
5058c2ecf20Sopenharmony_ci		goto again;
5068c2ecf20Sopenharmony_ci	}
5078c2ecf20Sopenharmony_ci
5088c2ecf20Sopenharmony_ci	*ret_tree = tree;
5098c2ecf20Sopenharmony_ci	if (ref_bh) {
5108c2ecf20Sopenharmony_ci		*ref_bh = ref_root_bh;
5118c2ecf20Sopenharmony_ci		ref_root_bh = NULL;
5128c2ecf20Sopenharmony_ci	}
5138c2ecf20Sopenharmony_ciout:
5148c2ecf20Sopenharmony_ci	brelse(ref_root_bh);
5158c2ecf20Sopenharmony_ci	return ret;
5168c2ecf20Sopenharmony_ci}
5178c2ecf20Sopenharmony_ci
5188c2ecf20Sopenharmony_civoid ocfs2_unlock_refcount_tree(struct ocfs2_super *osb,
5198c2ecf20Sopenharmony_ci				struct ocfs2_refcount_tree *tree, int rw)
5208c2ecf20Sopenharmony_ci{
5218c2ecf20Sopenharmony_ci	if (rw)
5228c2ecf20Sopenharmony_ci		up_write(&tree->rf_sem);
5238c2ecf20Sopenharmony_ci	else
5248c2ecf20Sopenharmony_ci		up_read(&tree->rf_sem);
5258c2ecf20Sopenharmony_ci
5268c2ecf20Sopenharmony_ci	ocfs2_refcount_unlock(tree, rw);
5278c2ecf20Sopenharmony_ci	ocfs2_refcount_tree_put(tree);
5288c2ecf20Sopenharmony_ci}
5298c2ecf20Sopenharmony_ci
5308c2ecf20Sopenharmony_civoid ocfs2_purge_refcount_trees(struct ocfs2_super *osb)
5318c2ecf20Sopenharmony_ci{
5328c2ecf20Sopenharmony_ci	struct rb_node *node;
5338c2ecf20Sopenharmony_ci	struct ocfs2_refcount_tree *tree;
5348c2ecf20Sopenharmony_ci	struct rb_root *root = &osb->osb_rf_lock_tree;
5358c2ecf20Sopenharmony_ci
5368c2ecf20Sopenharmony_ci	while ((node = rb_last(root)) != NULL) {
5378c2ecf20Sopenharmony_ci		tree = rb_entry(node, struct ocfs2_refcount_tree, rf_node);
5388c2ecf20Sopenharmony_ci
5398c2ecf20Sopenharmony_ci		trace_ocfs2_purge_refcount_trees(
5408c2ecf20Sopenharmony_ci				(unsigned long long) tree->rf_blkno);
5418c2ecf20Sopenharmony_ci
5428c2ecf20Sopenharmony_ci		rb_erase(&tree->rf_node, root);
5438c2ecf20Sopenharmony_ci		ocfs2_free_refcount_tree(tree);
5448c2ecf20Sopenharmony_ci	}
5458c2ecf20Sopenharmony_ci}
5468c2ecf20Sopenharmony_ci
5478c2ecf20Sopenharmony_ci/*
5488c2ecf20Sopenharmony_ci * Create a refcount tree for an inode.
5498c2ecf20Sopenharmony_ci * We take for granted that the inode is already locked.
5508c2ecf20Sopenharmony_ci */
5518c2ecf20Sopenharmony_cistatic int ocfs2_create_refcount_tree(struct inode *inode,
5528c2ecf20Sopenharmony_ci				      struct buffer_head *di_bh)
5538c2ecf20Sopenharmony_ci{
5548c2ecf20Sopenharmony_ci	int ret;
5558c2ecf20Sopenharmony_ci	handle_t *handle = NULL;
5568c2ecf20Sopenharmony_ci	struct ocfs2_alloc_context *meta_ac = NULL;
5578c2ecf20Sopenharmony_ci	struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
5588c2ecf20Sopenharmony_ci	struct ocfs2_inode_info *oi = OCFS2_I(inode);
5598c2ecf20Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
5608c2ecf20Sopenharmony_ci	struct buffer_head *new_bh = NULL;
5618c2ecf20Sopenharmony_ci	struct ocfs2_refcount_block *rb;
5628c2ecf20Sopenharmony_ci	struct ocfs2_refcount_tree *new_tree = NULL, *tree = NULL;
5638c2ecf20Sopenharmony_ci	u16 suballoc_bit_start;
5648c2ecf20Sopenharmony_ci	u32 num_got;
5658c2ecf20Sopenharmony_ci	u64 suballoc_loc, first_blkno;
5668c2ecf20Sopenharmony_ci
5678c2ecf20Sopenharmony_ci	BUG_ON(ocfs2_is_refcount_inode(inode));
5688c2ecf20Sopenharmony_ci
5698c2ecf20Sopenharmony_ci	trace_ocfs2_create_refcount_tree(
5708c2ecf20Sopenharmony_ci		(unsigned long long)oi->ip_blkno);
5718c2ecf20Sopenharmony_ci
5728c2ecf20Sopenharmony_ci	ret = ocfs2_reserve_new_metadata_blocks(osb, 1, &meta_ac);
5738c2ecf20Sopenharmony_ci	if (ret) {
5748c2ecf20Sopenharmony_ci		mlog_errno(ret);
5758c2ecf20Sopenharmony_ci		goto out;
5768c2ecf20Sopenharmony_ci	}
5778c2ecf20Sopenharmony_ci
5788c2ecf20Sopenharmony_ci	handle = ocfs2_start_trans(osb, OCFS2_REFCOUNT_TREE_CREATE_CREDITS);
5798c2ecf20Sopenharmony_ci	if (IS_ERR(handle)) {
5808c2ecf20Sopenharmony_ci		ret = PTR_ERR(handle);
5818c2ecf20Sopenharmony_ci		mlog_errno(ret);
5828c2ecf20Sopenharmony_ci		goto out;
5838c2ecf20Sopenharmony_ci	}
5848c2ecf20Sopenharmony_ci
5858c2ecf20Sopenharmony_ci	ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), di_bh,
5868c2ecf20Sopenharmony_ci				      OCFS2_JOURNAL_ACCESS_WRITE);
5878c2ecf20Sopenharmony_ci	if (ret) {
5888c2ecf20Sopenharmony_ci		mlog_errno(ret);
5898c2ecf20Sopenharmony_ci		goto out_commit;
5908c2ecf20Sopenharmony_ci	}
5918c2ecf20Sopenharmony_ci
5928c2ecf20Sopenharmony_ci	ret = ocfs2_claim_metadata(handle, meta_ac, 1, &suballoc_loc,
5938c2ecf20Sopenharmony_ci				   &suballoc_bit_start, &num_got,
5948c2ecf20Sopenharmony_ci				   &first_blkno);
5958c2ecf20Sopenharmony_ci	if (ret) {
5968c2ecf20Sopenharmony_ci		mlog_errno(ret);
5978c2ecf20Sopenharmony_ci		goto out_commit;
5988c2ecf20Sopenharmony_ci	}
5998c2ecf20Sopenharmony_ci
6008c2ecf20Sopenharmony_ci	new_tree = ocfs2_allocate_refcount_tree(osb, first_blkno);
6018c2ecf20Sopenharmony_ci	if (!new_tree) {
6028c2ecf20Sopenharmony_ci		ret = -ENOMEM;
6038c2ecf20Sopenharmony_ci		mlog_errno(ret);
6048c2ecf20Sopenharmony_ci		goto out_commit;
6058c2ecf20Sopenharmony_ci	}
6068c2ecf20Sopenharmony_ci
6078c2ecf20Sopenharmony_ci	new_bh = sb_getblk(inode->i_sb, first_blkno);
6088c2ecf20Sopenharmony_ci	if (!new_bh) {
6098c2ecf20Sopenharmony_ci		ret = -ENOMEM;
6108c2ecf20Sopenharmony_ci		mlog_errno(ret);
6118c2ecf20Sopenharmony_ci		goto out_commit;
6128c2ecf20Sopenharmony_ci	}
6138c2ecf20Sopenharmony_ci	ocfs2_set_new_buffer_uptodate(&new_tree->rf_ci, new_bh);
6148c2ecf20Sopenharmony_ci
6158c2ecf20Sopenharmony_ci	ret = ocfs2_journal_access_rb(handle, &new_tree->rf_ci, new_bh,
6168c2ecf20Sopenharmony_ci				      OCFS2_JOURNAL_ACCESS_CREATE);
6178c2ecf20Sopenharmony_ci	if (ret) {
6188c2ecf20Sopenharmony_ci		mlog_errno(ret);
6198c2ecf20Sopenharmony_ci		goto out_commit;
6208c2ecf20Sopenharmony_ci	}
6218c2ecf20Sopenharmony_ci
6228c2ecf20Sopenharmony_ci	/* Initialize ocfs2_refcount_block. */
6238c2ecf20Sopenharmony_ci	rb = (struct ocfs2_refcount_block *)new_bh->b_data;
6248c2ecf20Sopenharmony_ci	memset(rb, 0, inode->i_sb->s_blocksize);
6258c2ecf20Sopenharmony_ci	strcpy((void *)rb, OCFS2_REFCOUNT_BLOCK_SIGNATURE);
6268c2ecf20Sopenharmony_ci	rb->rf_suballoc_slot = cpu_to_le16(meta_ac->ac_alloc_slot);
6278c2ecf20Sopenharmony_ci	rb->rf_suballoc_loc = cpu_to_le64(suballoc_loc);
6288c2ecf20Sopenharmony_ci	rb->rf_suballoc_bit = cpu_to_le16(suballoc_bit_start);
6298c2ecf20Sopenharmony_ci	rb->rf_fs_generation = cpu_to_le32(osb->fs_generation);
6308c2ecf20Sopenharmony_ci	rb->rf_blkno = cpu_to_le64(first_blkno);
6318c2ecf20Sopenharmony_ci	rb->rf_count = cpu_to_le32(1);
6328c2ecf20Sopenharmony_ci	rb->rf_records.rl_count =
6338c2ecf20Sopenharmony_ci			cpu_to_le16(ocfs2_refcount_recs_per_rb(osb->sb));
6348c2ecf20Sopenharmony_ci	spin_lock(&osb->osb_lock);
6358c2ecf20Sopenharmony_ci	rb->rf_generation = osb->s_next_generation++;
6368c2ecf20Sopenharmony_ci	spin_unlock(&osb->osb_lock);
6378c2ecf20Sopenharmony_ci
6388c2ecf20Sopenharmony_ci	ocfs2_journal_dirty(handle, new_bh);
6398c2ecf20Sopenharmony_ci
6408c2ecf20Sopenharmony_ci	spin_lock(&oi->ip_lock);
6418c2ecf20Sopenharmony_ci	oi->ip_dyn_features |= OCFS2_HAS_REFCOUNT_FL;
6428c2ecf20Sopenharmony_ci	di->i_dyn_features = cpu_to_le16(oi->ip_dyn_features);
6438c2ecf20Sopenharmony_ci	di->i_refcount_loc = cpu_to_le64(first_blkno);
6448c2ecf20Sopenharmony_ci	spin_unlock(&oi->ip_lock);
6458c2ecf20Sopenharmony_ci
6468c2ecf20Sopenharmony_ci	trace_ocfs2_create_refcount_tree_blkno((unsigned long long)first_blkno);
6478c2ecf20Sopenharmony_ci
6488c2ecf20Sopenharmony_ci	ocfs2_journal_dirty(handle, di_bh);
6498c2ecf20Sopenharmony_ci
6508c2ecf20Sopenharmony_ci	/*
6518c2ecf20Sopenharmony_ci	 * We have to init the tree lock here since it will use
6528c2ecf20Sopenharmony_ci	 * the generation number to create it.
6538c2ecf20Sopenharmony_ci	 */
6548c2ecf20Sopenharmony_ci	new_tree->rf_generation = le32_to_cpu(rb->rf_generation);
6558c2ecf20Sopenharmony_ci	ocfs2_init_refcount_tree_lock(osb, new_tree, first_blkno,
6568c2ecf20Sopenharmony_ci				      new_tree->rf_generation);
6578c2ecf20Sopenharmony_ci
6588c2ecf20Sopenharmony_ci	spin_lock(&osb->osb_lock);
6598c2ecf20Sopenharmony_ci	tree = ocfs2_find_refcount_tree(osb, first_blkno);
6608c2ecf20Sopenharmony_ci
6618c2ecf20Sopenharmony_ci	/*
6628c2ecf20Sopenharmony_ci	 * We've just created a new refcount tree in this block.  If
6638c2ecf20Sopenharmony_ci	 * we found a refcount tree on the ocfs2_super, it must be
6648c2ecf20Sopenharmony_ci	 * one we just deleted.  We free the old tree before
6658c2ecf20Sopenharmony_ci	 * inserting the new tree.
6668c2ecf20Sopenharmony_ci	 */
6678c2ecf20Sopenharmony_ci	BUG_ON(tree && tree->rf_generation == new_tree->rf_generation);
6688c2ecf20Sopenharmony_ci	if (tree)
6698c2ecf20Sopenharmony_ci		ocfs2_erase_refcount_tree_from_list_no_lock(osb, tree);
6708c2ecf20Sopenharmony_ci	ocfs2_insert_refcount_tree(osb, new_tree);
6718c2ecf20Sopenharmony_ci	spin_unlock(&osb->osb_lock);
6728c2ecf20Sopenharmony_ci	new_tree = NULL;
6738c2ecf20Sopenharmony_ci	if (tree)
6748c2ecf20Sopenharmony_ci		ocfs2_refcount_tree_put(tree);
6758c2ecf20Sopenharmony_ci
6768c2ecf20Sopenharmony_ciout_commit:
6778c2ecf20Sopenharmony_ci	ocfs2_commit_trans(osb, handle);
6788c2ecf20Sopenharmony_ci
6798c2ecf20Sopenharmony_ciout:
6808c2ecf20Sopenharmony_ci	if (new_tree) {
6818c2ecf20Sopenharmony_ci		ocfs2_metadata_cache_exit(&new_tree->rf_ci);
6828c2ecf20Sopenharmony_ci		kfree(new_tree);
6838c2ecf20Sopenharmony_ci	}
6848c2ecf20Sopenharmony_ci
6858c2ecf20Sopenharmony_ci	brelse(new_bh);
6868c2ecf20Sopenharmony_ci	if (meta_ac)
6878c2ecf20Sopenharmony_ci		ocfs2_free_alloc_context(meta_ac);
6888c2ecf20Sopenharmony_ci
6898c2ecf20Sopenharmony_ci	return ret;
6908c2ecf20Sopenharmony_ci}
6918c2ecf20Sopenharmony_ci
6928c2ecf20Sopenharmony_cistatic int ocfs2_set_refcount_tree(struct inode *inode,
6938c2ecf20Sopenharmony_ci				   struct buffer_head *di_bh,
6948c2ecf20Sopenharmony_ci				   u64 refcount_loc)
6958c2ecf20Sopenharmony_ci{
6968c2ecf20Sopenharmony_ci	int ret;
6978c2ecf20Sopenharmony_ci	handle_t *handle = NULL;
6988c2ecf20Sopenharmony_ci	struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
6998c2ecf20Sopenharmony_ci	struct ocfs2_inode_info *oi = OCFS2_I(inode);
7008c2ecf20Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
7018c2ecf20Sopenharmony_ci	struct buffer_head *ref_root_bh = NULL;
7028c2ecf20Sopenharmony_ci	struct ocfs2_refcount_block *rb;
7038c2ecf20Sopenharmony_ci	struct ocfs2_refcount_tree *ref_tree;
7048c2ecf20Sopenharmony_ci
7058c2ecf20Sopenharmony_ci	BUG_ON(ocfs2_is_refcount_inode(inode));
7068c2ecf20Sopenharmony_ci
7078c2ecf20Sopenharmony_ci	ret = ocfs2_lock_refcount_tree(osb, refcount_loc, 1,
7088c2ecf20Sopenharmony_ci				       &ref_tree, &ref_root_bh);
7098c2ecf20Sopenharmony_ci	if (ret) {
7108c2ecf20Sopenharmony_ci		mlog_errno(ret);
7118c2ecf20Sopenharmony_ci		return ret;
7128c2ecf20Sopenharmony_ci	}
7138c2ecf20Sopenharmony_ci
7148c2ecf20Sopenharmony_ci	handle = ocfs2_start_trans(osb, OCFS2_REFCOUNT_TREE_SET_CREDITS);
7158c2ecf20Sopenharmony_ci	if (IS_ERR(handle)) {
7168c2ecf20Sopenharmony_ci		ret = PTR_ERR(handle);
7178c2ecf20Sopenharmony_ci		mlog_errno(ret);
7188c2ecf20Sopenharmony_ci		goto out;
7198c2ecf20Sopenharmony_ci	}
7208c2ecf20Sopenharmony_ci
7218c2ecf20Sopenharmony_ci	ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), di_bh,
7228c2ecf20Sopenharmony_ci				      OCFS2_JOURNAL_ACCESS_WRITE);
7238c2ecf20Sopenharmony_ci	if (ret) {
7248c2ecf20Sopenharmony_ci		mlog_errno(ret);
7258c2ecf20Sopenharmony_ci		goto out_commit;
7268c2ecf20Sopenharmony_ci	}
7278c2ecf20Sopenharmony_ci
7288c2ecf20Sopenharmony_ci	ret = ocfs2_journal_access_rb(handle, &ref_tree->rf_ci, ref_root_bh,
7298c2ecf20Sopenharmony_ci				      OCFS2_JOURNAL_ACCESS_WRITE);
7308c2ecf20Sopenharmony_ci	if (ret) {
7318c2ecf20Sopenharmony_ci		mlog_errno(ret);
7328c2ecf20Sopenharmony_ci		goto out_commit;
7338c2ecf20Sopenharmony_ci	}
7348c2ecf20Sopenharmony_ci
7358c2ecf20Sopenharmony_ci	rb = (struct ocfs2_refcount_block *)ref_root_bh->b_data;
7368c2ecf20Sopenharmony_ci	le32_add_cpu(&rb->rf_count, 1);
7378c2ecf20Sopenharmony_ci
7388c2ecf20Sopenharmony_ci	ocfs2_journal_dirty(handle, ref_root_bh);
7398c2ecf20Sopenharmony_ci
7408c2ecf20Sopenharmony_ci	spin_lock(&oi->ip_lock);
7418c2ecf20Sopenharmony_ci	oi->ip_dyn_features |= OCFS2_HAS_REFCOUNT_FL;
7428c2ecf20Sopenharmony_ci	di->i_dyn_features = cpu_to_le16(oi->ip_dyn_features);
7438c2ecf20Sopenharmony_ci	di->i_refcount_loc = cpu_to_le64(refcount_loc);
7448c2ecf20Sopenharmony_ci	spin_unlock(&oi->ip_lock);
7458c2ecf20Sopenharmony_ci	ocfs2_journal_dirty(handle, di_bh);
7468c2ecf20Sopenharmony_ci
7478c2ecf20Sopenharmony_ciout_commit:
7488c2ecf20Sopenharmony_ci	ocfs2_commit_trans(osb, handle);
7498c2ecf20Sopenharmony_ciout:
7508c2ecf20Sopenharmony_ci	ocfs2_unlock_refcount_tree(osb, ref_tree, 1);
7518c2ecf20Sopenharmony_ci	brelse(ref_root_bh);
7528c2ecf20Sopenharmony_ci
7538c2ecf20Sopenharmony_ci	return ret;
7548c2ecf20Sopenharmony_ci}
7558c2ecf20Sopenharmony_ci
7568c2ecf20Sopenharmony_ciint ocfs2_remove_refcount_tree(struct inode *inode, struct buffer_head *di_bh)
7578c2ecf20Sopenharmony_ci{
7588c2ecf20Sopenharmony_ci	int ret, delete_tree = 0;
7598c2ecf20Sopenharmony_ci	handle_t *handle = NULL;
7608c2ecf20Sopenharmony_ci	struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
7618c2ecf20Sopenharmony_ci	struct ocfs2_inode_info *oi = OCFS2_I(inode);
7628c2ecf20Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
7638c2ecf20Sopenharmony_ci	struct ocfs2_refcount_block *rb;
7648c2ecf20Sopenharmony_ci	struct inode *alloc_inode = NULL;
7658c2ecf20Sopenharmony_ci	struct buffer_head *alloc_bh = NULL;
7668c2ecf20Sopenharmony_ci	struct buffer_head *blk_bh = NULL;
7678c2ecf20Sopenharmony_ci	struct ocfs2_refcount_tree *ref_tree;
7688c2ecf20Sopenharmony_ci	int credits = OCFS2_REFCOUNT_TREE_REMOVE_CREDITS;
7698c2ecf20Sopenharmony_ci	u64 blk = 0, bg_blkno = 0, ref_blkno = le64_to_cpu(di->i_refcount_loc);
7708c2ecf20Sopenharmony_ci	u16 bit = 0;
7718c2ecf20Sopenharmony_ci
7728c2ecf20Sopenharmony_ci	if (!ocfs2_is_refcount_inode(inode))
7738c2ecf20Sopenharmony_ci		return 0;
7748c2ecf20Sopenharmony_ci
7758c2ecf20Sopenharmony_ci	BUG_ON(!ref_blkno);
7768c2ecf20Sopenharmony_ci	ret = ocfs2_lock_refcount_tree(osb, ref_blkno, 1, &ref_tree, &blk_bh);
7778c2ecf20Sopenharmony_ci	if (ret) {
7788c2ecf20Sopenharmony_ci		mlog_errno(ret);
7798c2ecf20Sopenharmony_ci		return ret;
7808c2ecf20Sopenharmony_ci	}
7818c2ecf20Sopenharmony_ci
7828c2ecf20Sopenharmony_ci	rb = (struct ocfs2_refcount_block *)blk_bh->b_data;
7838c2ecf20Sopenharmony_ci
7848c2ecf20Sopenharmony_ci	/*
7858c2ecf20Sopenharmony_ci	 * If we are the last user, we need to free the block.
7868c2ecf20Sopenharmony_ci	 * So lock the allocator ahead.
7878c2ecf20Sopenharmony_ci	 */
7888c2ecf20Sopenharmony_ci	if (le32_to_cpu(rb->rf_count) == 1) {
7898c2ecf20Sopenharmony_ci		blk = le64_to_cpu(rb->rf_blkno);
7908c2ecf20Sopenharmony_ci		bit = le16_to_cpu(rb->rf_suballoc_bit);
7918c2ecf20Sopenharmony_ci		if (rb->rf_suballoc_loc)
7928c2ecf20Sopenharmony_ci			bg_blkno = le64_to_cpu(rb->rf_suballoc_loc);
7938c2ecf20Sopenharmony_ci		else
7948c2ecf20Sopenharmony_ci			bg_blkno = ocfs2_which_suballoc_group(blk, bit);
7958c2ecf20Sopenharmony_ci
7968c2ecf20Sopenharmony_ci		alloc_inode = ocfs2_get_system_file_inode(osb,
7978c2ecf20Sopenharmony_ci					EXTENT_ALLOC_SYSTEM_INODE,
7988c2ecf20Sopenharmony_ci					le16_to_cpu(rb->rf_suballoc_slot));
7998c2ecf20Sopenharmony_ci		if (!alloc_inode) {
8008c2ecf20Sopenharmony_ci			ret = -ENOMEM;
8018c2ecf20Sopenharmony_ci			mlog_errno(ret);
8028c2ecf20Sopenharmony_ci			goto out;
8038c2ecf20Sopenharmony_ci		}
8048c2ecf20Sopenharmony_ci		inode_lock(alloc_inode);
8058c2ecf20Sopenharmony_ci
8068c2ecf20Sopenharmony_ci		ret = ocfs2_inode_lock(alloc_inode, &alloc_bh, 1);
8078c2ecf20Sopenharmony_ci		if (ret) {
8088c2ecf20Sopenharmony_ci			mlog_errno(ret);
8098c2ecf20Sopenharmony_ci			goto out_mutex;
8108c2ecf20Sopenharmony_ci		}
8118c2ecf20Sopenharmony_ci
8128c2ecf20Sopenharmony_ci		credits += OCFS2_SUBALLOC_FREE;
8138c2ecf20Sopenharmony_ci	}
8148c2ecf20Sopenharmony_ci
8158c2ecf20Sopenharmony_ci	handle = ocfs2_start_trans(osb, credits);
8168c2ecf20Sopenharmony_ci	if (IS_ERR(handle)) {
8178c2ecf20Sopenharmony_ci		ret = PTR_ERR(handle);
8188c2ecf20Sopenharmony_ci		mlog_errno(ret);
8198c2ecf20Sopenharmony_ci		goto out_unlock;
8208c2ecf20Sopenharmony_ci	}
8218c2ecf20Sopenharmony_ci
8228c2ecf20Sopenharmony_ci	ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), di_bh,
8238c2ecf20Sopenharmony_ci				      OCFS2_JOURNAL_ACCESS_WRITE);
8248c2ecf20Sopenharmony_ci	if (ret) {
8258c2ecf20Sopenharmony_ci		mlog_errno(ret);
8268c2ecf20Sopenharmony_ci		goto out_commit;
8278c2ecf20Sopenharmony_ci	}
8288c2ecf20Sopenharmony_ci
8298c2ecf20Sopenharmony_ci	ret = ocfs2_journal_access_rb(handle, &ref_tree->rf_ci, blk_bh,
8308c2ecf20Sopenharmony_ci				      OCFS2_JOURNAL_ACCESS_WRITE);
8318c2ecf20Sopenharmony_ci	if (ret) {
8328c2ecf20Sopenharmony_ci		mlog_errno(ret);
8338c2ecf20Sopenharmony_ci		goto out_commit;
8348c2ecf20Sopenharmony_ci	}
8358c2ecf20Sopenharmony_ci
8368c2ecf20Sopenharmony_ci	spin_lock(&oi->ip_lock);
8378c2ecf20Sopenharmony_ci	oi->ip_dyn_features &= ~OCFS2_HAS_REFCOUNT_FL;
8388c2ecf20Sopenharmony_ci	di->i_dyn_features = cpu_to_le16(oi->ip_dyn_features);
8398c2ecf20Sopenharmony_ci	di->i_refcount_loc = 0;
8408c2ecf20Sopenharmony_ci	spin_unlock(&oi->ip_lock);
8418c2ecf20Sopenharmony_ci	ocfs2_journal_dirty(handle, di_bh);
8428c2ecf20Sopenharmony_ci
8438c2ecf20Sopenharmony_ci	le32_add_cpu(&rb->rf_count , -1);
8448c2ecf20Sopenharmony_ci	ocfs2_journal_dirty(handle, blk_bh);
8458c2ecf20Sopenharmony_ci
8468c2ecf20Sopenharmony_ci	if (!rb->rf_count) {
8478c2ecf20Sopenharmony_ci		delete_tree = 1;
8488c2ecf20Sopenharmony_ci		ocfs2_erase_refcount_tree_from_list(osb, ref_tree);
8498c2ecf20Sopenharmony_ci		ret = ocfs2_free_suballoc_bits(handle, alloc_inode,
8508c2ecf20Sopenharmony_ci					       alloc_bh, bit, bg_blkno, 1);
8518c2ecf20Sopenharmony_ci		if (ret)
8528c2ecf20Sopenharmony_ci			mlog_errno(ret);
8538c2ecf20Sopenharmony_ci	}
8548c2ecf20Sopenharmony_ci
8558c2ecf20Sopenharmony_ciout_commit:
8568c2ecf20Sopenharmony_ci	ocfs2_commit_trans(osb, handle);
8578c2ecf20Sopenharmony_ciout_unlock:
8588c2ecf20Sopenharmony_ci	if (alloc_inode) {
8598c2ecf20Sopenharmony_ci		ocfs2_inode_unlock(alloc_inode, 1);
8608c2ecf20Sopenharmony_ci		brelse(alloc_bh);
8618c2ecf20Sopenharmony_ci	}
8628c2ecf20Sopenharmony_ciout_mutex:
8638c2ecf20Sopenharmony_ci	if (alloc_inode) {
8648c2ecf20Sopenharmony_ci		inode_unlock(alloc_inode);
8658c2ecf20Sopenharmony_ci		iput(alloc_inode);
8668c2ecf20Sopenharmony_ci	}
8678c2ecf20Sopenharmony_ciout:
8688c2ecf20Sopenharmony_ci	ocfs2_unlock_refcount_tree(osb, ref_tree, 1);
8698c2ecf20Sopenharmony_ci	if (delete_tree)
8708c2ecf20Sopenharmony_ci		ocfs2_refcount_tree_put(ref_tree);
8718c2ecf20Sopenharmony_ci	brelse(blk_bh);
8728c2ecf20Sopenharmony_ci
8738c2ecf20Sopenharmony_ci	return ret;
8748c2ecf20Sopenharmony_ci}
8758c2ecf20Sopenharmony_ci
8768c2ecf20Sopenharmony_cistatic void ocfs2_find_refcount_rec_in_rl(struct ocfs2_caching_info *ci,
8778c2ecf20Sopenharmony_ci					  struct buffer_head *ref_leaf_bh,
8788c2ecf20Sopenharmony_ci					  u64 cpos, unsigned int len,
8798c2ecf20Sopenharmony_ci					  struct ocfs2_refcount_rec *ret_rec,
8808c2ecf20Sopenharmony_ci					  int *index)
8818c2ecf20Sopenharmony_ci{
8828c2ecf20Sopenharmony_ci	int i = 0;
8838c2ecf20Sopenharmony_ci	struct ocfs2_refcount_block *rb =
8848c2ecf20Sopenharmony_ci		(struct ocfs2_refcount_block *)ref_leaf_bh->b_data;
8858c2ecf20Sopenharmony_ci	struct ocfs2_refcount_rec *rec = NULL;
8868c2ecf20Sopenharmony_ci
8878c2ecf20Sopenharmony_ci	for (; i < le16_to_cpu(rb->rf_records.rl_used); i++) {
8888c2ecf20Sopenharmony_ci		rec = &rb->rf_records.rl_recs[i];
8898c2ecf20Sopenharmony_ci
8908c2ecf20Sopenharmony_ci		if (le64_to_cpu(rec->r_cpos) +
8918c2ecf20Sopenharmony_ci		    le32_to_cpu(rec->r_clusters) <= cpos)
8928c2ecf20Sopenharmony_ci			continue;
8938c2ecf20Sopenharmony_ci		else if (le64_to_cpu(rec->r_cpos) > cpos)
8948c2ecf20Sopenharmony_ci			break;
8958c2ecf20Sopenharmony_ci
8968c2ecf20Sopenharmony_ci		/* ok, cpos fail in this rec. Just return. */
8978c2ecf20Sopenharmony_ci		if (ret_rec)
8988c2ecf20Sopenharmony_ci			*ret_rec = *rec;
8998c2ecf20Sopenharmony_ci		goto out;
9008c2ecf20Sopenharmony_ci	}
9018c2ecf20Sopenharmony_ci
9028c2ecf20Sopenharmony_ci	if (ret_rec) {
9038c2ecf20Sopenharmony_ci		/* We meet with a hole here, so fake the rec. */
9048c2ecf20Sopenharmony_ci		ret_rec->r_cpos = cpu_to_le64(cpos);
9058c2ecf20Sopenharmony_ci		ret_rec->r_refcount = 0;
9068c2ecf20Sopenharmony_ci		if (i < le16_to_cpu(rb->rf_records.rl_used) &&
9078c2ecf20Sopenharmony_ci		    le64_to_cpu(rec->r_cpos) < cpos + len)
9088c2ecf20Sopenharmony_ci			ret_rec->r_clusters =
9098c2ecf20Sopenharmony_ci				cpu_to_le32(le64_to_cpu(rec->r_cpos) - cpos);
9108c2ecf20Sopenharmony_ci		else
9118c2ecf20Sopenharmony_ci			ret_rec->r_clusters = cpu_to_le32(len);
9128c2ecf20Sopenharmony_ci	}
9138c2ecf20Sopenharmony_ci
9148c2ecf20Sopenharmony_ciout:
9158c2ecf20Sopenharmony_ci	*index = i;
9168c2ecf20Sopenharmony_ci}
9178c2ecf20Sopenharmony_ci
9188c2ecf20Sopenharmony_ci/*
9198c2ecf20Sopenharmony_ci * Try to remove refcount tree. The mechanism is:
9208c2ecf20Sopenharmony_ci * 1) Check whether i_clusters == 0, if no, exit.
9218c2ecf20Sopenharmony_ci * 2) check whether we have i_xattr_loc in dinode. if yes, exit.
9228c2ecf20Sopenharmony_ci * 3) Check whether we have inline xattr stored outside, if yes, exit.
9238c2ecf20Sopenharmony_ci * 4) Remove the tree.
9248c2ecf20Sopenharmony_ci */
9258c2ecf20Sopenharmony_ciint ocfs2_try_remove_refcount_tree(struct inode *inode,
9268c2ecf20Sopenharmony_ci				   struct buffer_head *di_bh)
9278c2ecf20Sopenharmony_ci{
9288c2ecf20Sopenharmony_ci	int ret;
9298c2ecf20Sopenharmony_ci	struct ocfs2_inode_info *oi = OCFS2_I(inode);
9308c2ecf20Sopenharmony_ci	struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
9318c2ecf20Sopenharmony_ci
9328c2ecf20Sopenharmony_ci	down_write(&oi->ip_xattr_sem);
9338c2ecf20Sopenharmony_ci	down_write(&oi->ip_alloc_sem);
9348c2ecf20Sopenharmony_ci
9358c2ecf20Sopenharmony_ci	if (oi->ip_clusters)
9368c2ecf20Sopenharmony_ci		goto out;
9378c2ecf20Sopenharmony_ci
9388c2ecf20Sopenharmony_ci	if ((oi->ip_dyn_features & OCFS2_HAS_XATTR_FL) && di->i_xattr_loc)
9398c2ecf20Sopenharmony_ci		goto out;
9408c2ecf20Sopenharmony_ci
9418c2ecf20Sopenharmony_ci	if (oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL &&
9428c2ecf20Sopenharmony_ci	    ocfs2_has_inline_xattr_value_outside(inode, di))
9438c2ecf20Sopenharmony_ci		goto out;
9448c2ecf20Sopenharmony_ci
9458c2ecf20Sopenharmony_ci	ret = ocfs2_remove_refcount_tree(inode, di_bh);
9468c2ecf20Sopenharmony_ci	if (ret)
9478c2ecf20Sopenharmony_ci		mlog_errno(ret);
9488c2ecf20Sopenharmony_ciout:
9498c2ecf20Sopenharmony_ci	up_write(&oi->ip_alloc_sem);
9508c2ecf20Sopenharmony_ci	up_write(&oi->ip_xattr_sem);
9518c2ecf20Sopenharmony_ci	return 0;
9528c2ecf20Sopenharmony_ci}
9538c2ecf20Sopenharmony_ci
9548c2ecf20Sopenharmony_ci/*
9558c2ecf20Sopenharmony_ci * Find the end range for a leaf refcount block indicated by
9568c2ecf20Sopenharmony_ci * el->l_recs[index].e_blkno.
9578c2ecf20Sopenharmony_ci */
9588c2ecf20Sopenharmony_cistatic int ocfs2_get_refcount_cpos_end(struct ocfs2_caching_info *ci,
9598c2ecf20Sopenharmony_ci				       struct buffer_head *ref_root_bh,
9608c2ecf20Sopenharmony_ci				       struct ocfs2_extent_block *eb,
9618c2ecf20Sopenharmony_ci				       struct ocfs2_extent_list *el,
9628c2ecf20Sopenharmony_ci				       int index,  u32 *cpos_end)
9638c2ecf20Sopenharmony_ci{
9648c2ecf20Sopenharmony_ci	int ret, i, subtree_root;
9658c2ecf20Sopenharmony_ci	u32 cpos;
9668c2ecf20Sopenharmony_ci	u64 blkno;
9678c2ecf20Sopenharmony_ci	struct super_block *sb = ocfs2_metadata_cache_get_super(ci);
9688c2ecf20Sopenharmony_ci	struct ocfs2_path *left_path = NULL, *right_path = NULL;
9698c2ecf20Sopenharmony_ci	struct ocfs2_extent_tree et;
9708c2ecf20Sopenharmony_ci	struct ocfs2_extent_list *tmp_el;
9718c2ecf20Sopenharmony_ci
9728c2ecf20Sopenharmony_ci	if (index < le16_to_cpu(el->l_next_free_rec) - 1) {
9738c2ecf20Sopenharmony_ci		/*
9748c2ecf20Sopenharmony_ci		 * We have a extent rec after index, so just use the e_cpos
9758c2ecf20Sopenharmony_ci		 * of the next extent rec.
9768c2ecf20Sopenharmony_ci		 */
9778c2ecf20Sopenharmony_ci		*cpos_end = le32_to_cpu(el->l_recs[index+1].e_cpos);
9788c2ecf20Sopenharmony_ci		return 0;
9798c2ecf20Sopenharmony_ci	}
9808c2ecf20Sopenharmony_ci
9818c2ecf20Sopenharmony_ci	if (!eb || (eb && !eb->h_next_leaf_blk)) {
9828c2ecf20Sopenharmony_ci		/*
9838c2ecf20Sopenharmony_ci		 * We are the last extent rec, so any high cpos should
9848c2ecf20Sopenharmony_ci		 * be stored in this leaf refcount block.
9858c2ecf20Sopenharmony_ci		 */
9868c2ecf20Sopenharmony_ci		*cpos_end = UINT_MAX;
9878c2ecf20Sopenharmony_ci		return 0;
9888c2ecf20Sopenharmony_ci	}
9898c2ecf20Sopenharmony_ci
9908c2ecf20Sopenharmony_ci	/*
9918c2ecf20Sopenharmony_ci	 * If the extent block isn't the last one, we have to find
9928c2ecf20Sopenharmony_ci	 * the subtree root between this extent block and the next
9938c2ecf20Sopenharmony_ci	 * leaf extent block and get the corresponding e_cpos from
9948c2ecf20Sopenharmony_ci	 * the subroot. Otherwise we may corrupt the b-tree.
9958c2ecf20Sopenharmony_ci	 */
9968c2ecf20Sopenharmony_ci	ocfs2_init_refcount_extent_tree(&et, ci, ref_root_bh);
9978c2ecf20Sopenharmony_ci
9988c2ecf20Sopenharmony_ci	left_path = ocfs2_new_path_from_et(&et);
9998c2ecf20Sopenharmony_ci	if (!left_path) {
10008c2ecf20Sopenharmony_ci		ret = -ENOMEM;
10018c2ecf20Sopenharmony_ci		mlog_errno(ret);
10028c2ecf20Sopenharmony_ci		goto out;
10038c2ecf20Sopenharmony_ci	}
10048c2ecf20Sopenharmony_ci
10058c2ecf20Sopenharmony_ci	cpos = le32_to_cpu(eb->h_list.l_recs[index].e_cpos);
10068c2ecf20Sopenharmony_ci	ret = ocfs2_find_path(ci, left_path, cpos);
10078c2ecf20Sopenharmony_ci	if (ret) {
10088c2ecf20Sopenharmony_ci		mlog_errno(ret);
10098c2ecf20Sopenharmony_ci		goto out;
10108c2ecf20Sopenharmony_ci	}
10118c2ecf20Sopenharmony_ci
10128c2ecf20Sopenharmony_ci	right_path = ocfs2_new_path_from_path(left_path);
10138c2ecf20Sopenharmony_ci	if (!right_path) {
10148c2ecf20Sopenharmony_ci		ret = -ENOMEM;
10158c2ecf20Sopenharmony_ci		mlog_errno(ret);
10168c2ecf20Sopenharmony_ci		goto out;
10178c2ecf20Sopenharmony_ci	}
10188c2ecf20Sopenharmony_ci
10198c2ecf20Sopenharmony_ci	ret = ocfs2_find_cpos_for_right_leaf(sb, left_path, &cpos);
10208c2ecf20Sopenharmony_ci	if (ret) {
10218c2ecf20Sopenharmony_ci		mlog_errno(ret);
10228c2ecf20Sopenharmony_ci		goto out;
10238c2ecf20Sopenharmony_ci	}
10248c2ecf20Sopenharmony_ci
10258c2ecf20Sopenharmony_ci	ret = ocfs2_find_path(ci, right_path, cpos);
10268c2ecf20Sopenharmony_ci	if (ret) {
10278c2ecf20Sopenharmony_ci		mlog_errno(ret);
10288c2ecf20Sopenharmony_ci		goto out;
10298c2ecf20Sopenharmony_ci	}
10308c2ecf20Sopenharmony_ci
10318c2ecf20Sopenharmony_ci	subtree_root = ocfs2_find_subtree_root(&et, left_path,
10328c2ecf20Sopenharmony_ci					       right_path);
10338c2ecf20Sopenharmony_ci
10348c2ecf20Sopenharmony_ci	tmp_el = left_path->p_node[subtree_root].el;
10358c2ecf20Sopenharmony_ci	blkno = left_path->p_node[subtree_root+1].bh->b_blocknr;
10368c2ecf20Sopenharmony_ci	for (i = 0; i < le16_to_cpu(tmp_el->l_next_free_rec); i++) {
10378c2ecf20Sopenharmony_ci		if (le64_to_cpu(tmp_el->l_recs[i].e_blkno) == blkno) {
10388c2ecf20Sopenharmony_ci			*cpos_end = le32_to_cpu(tmp_el->l_recs[i+1].e_cpos);
10398c2ecf20Sopenharmony_ci			break;
10408c2ecf20Sopenharmony_ci		}
10418c2ecf20Sopenharmony_ci	}
10428c2ecf20Sopenharmony_ci
10438c2ecf20Sopenharmony_ci	BUG_ON(i == le16_to_cpu(tmp_el->l_next_free_rec));
10448c2ecf20Sopenharmony_ci
10458c2ecf20Sopenharmony_ciout:
10468c2ecf20Sopenharmony_ci	ocfs2_free_path(left_path);
10478c2ecf20Sopenharmony_ci	ocfs2_free_path(right_path);
10488c2ecf20Sopenharmony_ci	return ret;
10498c2ecf20Sopenharmony_ci}
10508c2ecf20Sopenharmony_ci
10518c2ecf20Sopenharmony_ci/*
10528c2ecf20Sopenharmony_ci * Given a cpos and len, try to find the refcount record which contains cpos.
10538c2ecf20Sopenharmony_ci * 1. If cpos can be found in one refcount record, return the record.
10548c2ecf20Sopenharmony_ci * 2. If cpos can't be found, return a fake record which start from cpos
10558c2ecf20Sopenharmony_ci *    and end at a small value between cpos+len and start of the next record.
10568c2ecf20Sopenharmony_ci *    This fake record has r_refcount = 0.
10578c2ecf20Sopenharmony_ci */
10588c2ecf20Sopenharmony_cistatic int ocfs2_get_refcount_rec(struct ocfs2_caching_info *ci,
10598c2ecf20Sopenharmony_ci				  struct buffer_head *ref_root_bh,
10608c2ecf20Sopenharmony_ci				  u64 cpos, unsigned int len,
10618c2ecf20Sopenharmony_ci				  struct ocfs2_refcount_rec *ret_rec,
10628c2ecf20Sopenharmony_ci				  int *index,
10638c2ecf20Sopenharmony_ci				  struct buffer_head **ret_bh)
10648c2ecf20Sopenharmony_ci{
10658c2ecf20Sopenharmony_ci	int ret = 0, i, found;
10668c2ecf20Sopenharmony_ci	u32 low_cpos, cpos_end;
10678c2ecf20Sopenharmony_ci	struct ocfs2_extent_list *el;
10688c2ecf20Sopenharmony_ci	struct ocfs2_extent_rec *rec = NULL;
10698c2ecf20Sopenharmony_ci	struct ocfs2_extent_block *eb = NULL;
10708c2ecf20Sopenharmony_ci	struct buffer_head *eb_bh = NULL, *ref_leaf_bh = NULL;
10718c2ecf20Sopenharmony_ci	struct super_block *sb = ocfs2_metadata_cache_get_super(ci);
10728c2ecf20Sopenharmony_ci	struct ocfs2_refcount_block *rb =
10738c2ecf20Sopenharmony_ci			(struct ocfs2_refcount_block *)ref_root_bh->b_data;
10748c2ecf20Sopenharmony_ci
10758c2ecf20Sopenharmony_ci	if (!(le32_to_cpu(rb->rf_flags) & OCFS2_REFCOUNT_TREE_FL)) {
10768c2ecf20Sopenharmony_ci		ocfs2_find_refcount_rec_in_rl(ci, ref_root_bh, cpos, len,
10778c2ecf20Sopenharmony_ci					      ret_rec, index);
10788c2ecf20Sopenharmony_ci		*ret_bh = ref_root_bh;
10798c2ecf20Sopenharmony_ci		get_bh(ref_root_bh);
10808c2ecf20Sopenharmony_ci		return 0;
10818c2ecf20Sopenharmony_ci	}
10828c2ecf20Sopenharmony_ci
10838c2ecf20Sopenharmony_ci	el = &rb->rf_list;
10848c2ecf20Sopenharmony_ci	low_cpos = cpos & OCFS2_32BIT_POS_MASK;
10858c2ecf20Sopenharmony_ci
10868c2ecf20Sopenharmony_ci	if (el->l_tree_depth) {
10878c2ecf20Sopenharmony_ci		ret = ocfs2_find_leaf(ci, el, low_cpos, &eb_bh);
10888c2ecf20Sopenharmony_ci		if (ret) {
10898c2ecf20Sopenharmony_ci			mlog_errno(ret);
10908c2ecf20Sopenharmony_ci			goto out;
10918c2ecf20Sopenharmony_ci		}
10928c2ecf20Sopenharmony_ci
10938c2ecf20Sopenharmony_ci		eb = (struct ocfs2_extent_block *) eb_bh->b_data;
10948c2ecf20Sopenharmony_ci		el = &eb->h_list;
10958c2ecf20Sopenharmony_ci
10968c2ecf20Sopenharmony_ci		if (el->l_tree_depth) {
10978c2ecf20Sopenharmony_ci			ret = ocfs2_error(sb,
10988c2ecf20Sopenharmony_ci					  "refcount tree %llu has non zero tree depth in leaf btree tree block %llu\n",
10998c2ecf20Sopenharmony_ci					  (unsigned long long)ocfs2_metadata_cache_owner(ci),
11008c2ecf20Sopenharmony_ci					  (unsigned long long)eb_bh->b_blocknr);
11018c2ecf20Sopenharmony_ci			goto out;
11028c2ecf20Sopenharmony_ci		}
11038c2ecf20Sopenharmony_ci	}
11048c2ecf20Sopenharmony_ci
11058c2ecf20Sopenharmony_ci	found = 0;
11068c2ecf20Sopenharmony_ci	for (i = le16_to_cpu(el->l_next_free_rec) - 1; i >= 0; i--) {
11078c2ecf20Sopenharmony_ci		rec = &el->l_recs[i];
11088c2ecf20Sopenharmony_ci
11098c2ecf20Sopenharmony_ci		if (le32_to_cpu(rec->e_cpos) <= low_cpos) {
11108c2ecf20Sopenharmony_ci			found = 1;
11118c2ecf20Sopenharmony_ci			break;
11128c2ecf20Sopenharmony_ci		}
11138c2ecf20Sopenharmony_ci	}
11148c2ecf20Sopenharmony_ci
11158c2ecf20Sopenharmony_ci	if (found) {
11168c2ecf20Sopenharmony_ci		ret = ocfs2_get_refcount_cpos_end(ci, ref_root_bh,
11178c2ecf20Sopenharmony_ci						  eb, el, i, &cpos_end);
11188c2ecf20Sopenharmony_ci		if (ret) {
11198c2ecf20Sopenharmony_ci			mlog_errno(ret);
11208c2ecf20Sopenharmony_ci			goto out;
11218c2ecf20Sopenharmony_ci		}
11228c2ecf20Sopenharmony_ci
11238c2ecf20Sopenharmony_ci		if (cpos_end < low_cpos + len)
11248c2ecf20Sopenharmony_ci			len = cpos_end - low_cpos;
11258c2ecf20Sopenharmony_ci	}
11268c2ecf20Sopenharmony_ci
11278c2ecf20Sopenharmony_ci	ret = ocfs2_read_refcount_block(ci, le64_to_cpu(rec->e_blkno),
11288c2ecf20Sopenharmony_ci					&ref_leaf_bh);
11298c2ecf20Sopenharmony_ci	if (ret) {
11308c2ecf20Sopenharmony_ci		mlog_errno(ret);
11318c2ecf20Sopenharmony_ci		goto out;
11328c2ecf20Sopenharmony_ci	}
11338c2ecf20Sopenharmony_ci
11348c2ecf20Sopenharmony_ci	ocfs2_find_refcount_rec_in_rl(ci, ref_leaf_bh, cpos, len,
11358c2ecf20Sopenharmony_ci				      ret_rec, index);
11368c2ecf20Sopenharmony_ci	*ret_bh = ref_leaf_bh;
11378c2ecf20Sopenharmony_ciout:
11388c2ecf20Sopenharmony_ci	brelse(eb_bh);
11398c2ecf20Sopenharmony_ci	return ret;
11408c2ecf20Sopenharmony_ci}
11418c2ecf20Sopenharmony_ci
11428c2ecf20Sopenharmony_cienum ocfs2_ref_rec_contig {
11438c2ecf20Sopenharmony_ci	REF_CONTIG_NONE = 0,
11448c2ecf20Sopenharmony_ci	REF_CONTIG_LEFT,
11458c2ecf20Sopenharmony_ci	REF_CONTIG_RIGHT,
11468c2ecf20Sopenharmony_ci	REF_CONTIG_LEFTRIGHT,
11478c2ecf20Sopenharmony_ci};
11488c2ecf20Sopenharmony_ci
11498c2ecf20Sopenharmony_cistatic enum ocfs2_ref_rec_contig
11508c2ecf20Sopenharmony_ci	ocfs2_refcount_rec_adjacent(struct ocfs2_refcount_block *rb,
11518c2ecf20Sopenharmony_ci				    int index)
11528c2ecf20Sopenharmony_ci{
11538c2ecf20Sopenharmony_ci	if ((rb->rf_records.rl_recs[index].r_refcount ==
11548c2ecf20Sopenharmony_ci	    rb->rf_records.rl_recs[index + 1].r_refcount) &&
11558c2ecf20Sopenharmony_ci	    (le64_to_cpu(rb->rf_records.rl_recs[index].r_cpos) +
11568c2ecf20Sopenharmony_ci	    le32_to_cpu(rb->rf_records.rl_recs[index].r_clusters) ==
11578c2ecf20Sopenharmony_ci	    le64_to_cpu(rb->rf_records.rl_recs[index + 1].r_cpos)))
11588c2ecf20Sopenharmony_ci		return REF_CONTIG_RIGHT;
11598c2ecf20Sopenharmony_ci
11608c2ecf20Sopenharmony_ci	return REF_CONTIG_NONE;
11618c2ecf20Sopenharmony_ci}
11628c2ecf20Sopenharmony_ci
11638c2ecf20Sopenharmony_cistatic enum ocfs2_ref_rec_contig
11648c2ecf20Sopenharmony_ci	ocfs2_refcount_rec_contig(struct ocfs2_refcount_block *rb,
11658c2ecf20Sopenharmony_ci				  int index)
11668c2ecf20Sopenharmony_ci{
11678c2ecf20Sopenharmony_ci	enum ocfs2_ref_rec_contig ret = REF_CONTIG_NONE;
11688c2ecf20Sopenharmony_ci
11698c2ecf20Sopenharmony_ci	if (index < le16_to_cpu(rb->rf_records.rl_used) - 1)
11708c2ecf20Sopenharmony_ci		ret = ocfs2_refcount_rec_adjacent(rb, index);
11718c2ecf20Sopenharmony_ci
11728c2ecf20Sopenharmony_ci	if (index > 0) {
11738c2ecf20Sopenharmony_ci		enum ocfs2_ref_rec_contig tmp;
11748c2ecf20Sopenharmony_ci
11758c2ecf20Sopenharmony_ci		tmp = ocfs2_refcount_rec_adjacent(rb, index - 1);
11768c2ecf20Sopenharmony_ci
11778c2ecf20Sopenharmony_ci		if (tmp == REF_CONTIG_RIGHT) {
11788c2ecf20Sopenharmony_ci			if (ret == REF_CONTIG_RIGHT)
11798c2ecf20Sopenharmony_ci				ret = REF_CONTIG_LEFTRIGHT;
11808c2ecf20Sopenharmony_ci			else
11818c2ecf20Sopenharmony_ci				ret = REF_CONTIG_LEFT;
11828c2ecf20Sopenharmony_ci		}
11838c2ecf20Sopenharmony_ci	}
11848c2ecf20Sopenharmony_ci
11858c2ecf20Sopenharmony_ci	return ret;
11868c2ecf20Sopenharmony_ci}
11878c2ecf20Sopenharmony_ci
11888c2ecf20Sopenharmony_cistatic void ocfs2_rotate_refcount_rec_left(struct ocfs2_refcount_block *rb,
11898c2ecf20Sopenharmony_ci					   int index)
11908c2ecf20Sopenharmony_ci{
11918c2ecf20Sopenharmony_ci	BUG_ON(rb->rf_records.rl_recs[index].r_refcount !=
11928c2ecf20Sopenharmony_ci	       rb->rf_records.rl_recs[index+1].r_refcount);
11938c2ecf20Sopenharmony_ci
11948c2ecf20Sopenharmony_ci	le32_add_cpu(&rb->rf_records.rl_recs[index].r_clusters,
11958c2ecf20Sopenharmony_ci		     le32_to_cpu(rb->rf_records.rl_recs[index+1].r_clusters));
11968c2ecf20Sopenharmony_ci
11978c2ecf20Sopenharmony_ci	if (index < le16_to_cpu(rb->rf_records.rl_used) - 2)
11988c2ecf20Sopenharmony_ci		memmove(&rb->rf_records.rl_recs[index + 1],
11998c2ecf20Sopenharmony_ci			&rb->rf_records.rl_recs[index + 2],
12008c2ecf20Sopenharmony_ci			sizeof(struct ocfs2_refcount_rec) *
12018c2ecf20Sopenharmony_ci			(le16_to_cpu(rb->rf_records.rl_used) - index - 2));
12028c2ecf20Sopenharmony_ci
12038c2ecf20Sopenharmony_ci	memset(&rb->rf_records.rl_recs[le16_to_cpu(rb->rf_records.rl_used) - 1],
12048c2ecf20Sopenharmony_ci	       0, sizeof(struct ocfs2_refcount_rec));
12058c2ecf20Sopenharmony_ci	le16_add_cpu(&rb->rf_records.rl_used, -1);
12068c2ecf20Sopenharmony_ci}
12078c2ecf20Sopenharmony_ci
12088c2ecf20Sopenharmony_ci/*
12098c2ecf20Sopenharmony_ci * Merge the refcount rec if we are contiguous with the adjacent recs.
12108c2ecf20Sopenharmony_ci */
12118c2ecf20Sopenharmony_cistatic void ocfs2_refcount_rec_merge(struct ocfs2_refcount_block *rb,
12128c2ecf20Sopenharmony_ci				     int index)
12138c2ecf20Sopenharmony_ci{
12148c2ecf20Sopenharmony_ci	enum ocfs2_ref_rec_contig contig =
12158c2ecf20Sopenharmony_ci				ocfs2_refcount_rec_contig(rb, index);
12168c2ecf20Sopenharmony_ci
12178c2ecf20Sopenharmony_ci	if (contig == REF_CONTIG_NONE)
12188c2ecf20Sopenharmony_ci		return;
12198c2ecf20Sopenharmony_ci
12208c2ecf20Sopenharmony_ci	if (contig == REF_CONTIG_LEFT || contig == REF_CONTIG_LEFTRIGHT) {
12218c2ecf20Sopenharmony_ci		BUG_ON(index == 0);
12228c2ecf20Sopenharmony_ci		index--;
12238c2ecf20Sopenharmony_ci	}
12248c2ecf20Sopenharmony_ci
12258c2ecf20Sopenharmony_ci	ocfs2_rotate_refcount_rec_left(rb, index);
12268c2ecf20Sopenharmony_ci
12278c2ecf20Sopenharmony_ci	if (contig == REF_CONTIG_LEFTRIGHT)
12288c2ecf20Sopenharmony_ci		ocfs2_rotate_refcount_rec_left(rb, index);
12298c2ecf20Sopenharmony_ci}
12308c2ecf20Sopenharmony_ci
12318c2ecf20Sopenharmony_ci/*
12328c2ecf20Sopenharmony_ci * Change the refcount indexed by "index" in ref_bh.
12338c2ecf20Sopenharmony_ci * If refcount reaches 0, remove it.
12348c2ecf20Sopenharmony_ci */
12358c2ecf20Sopenharmony_cistatic int ocfs2_change_refcount_rec(handle_t *handle,
12368c2ecf20Sopenharmony_ci				     struct ocfs2_caching_info *ci,
12378c2ecf20Sopenharmony_ci				     struct buffer_head *ref_leaf_bh,
12388c2ecf20Sopenharmony_ci				     int index, int merge, int change)
12398c2ecf20Sopenharmony_ci{
12408c2ecf20Sopenharmony_ci	int ret;
12418c2ecf20Sopenharmony_ci	struct ocfs2_refcount_block *rb =
12428c2ecf20Sopenharmony_ci			(struct ocfs2_refcount_block *)ref_leaf_bh->b_data;
12438c2ecf20Sopenharmony_ci	struct ocfs2_refcount_list *rl = &rb->rf_records;
12448c2ecf20Sopenharmony_ci	struct ocfs2_refcount_rec *rec = &rl->rl_recs[index];
12458c2ecf20Sopenharmony_ci
12468c2ecf20Sopenharmony_ci	ret = ocfs2_journal_access_rb(handle, ci, ref_leaf_bh,
12478c2ecf20Sopenharmony_ci				      OCFS2_JOURNAL_ACCESS_WRITE);
12488c2ecf20Sopenharmony_ci	if (ret) {
12498c2ecf20Sopenharmony_ci		mlog_errno(ret);
12508c2ecf20Sopenharmony_ci		goto out;
12518c2ecf20Sopenharmony_ci	}
12528c2ecf20Sopenharmony_ci
12538c2ecf20Sopenharmony_ci	trace_ocfs2_change_refcount_rec(
12548c2ecf20Sopenharmony_ci		(unsigned long long)ocfs2_metadata_cache_owner(ci),
12558c2ecf20Sopenharmony_ci		index, le32_to_cpu(rec->r_refcount), change);
12568c2ecf20Sopenharmony_ci	le32_add_cpu(&rec->r_refcount, change);
12578c2ecf20Sopenharmony_ci
12588c2ecf20Sopenharmony_ci	if (!rec->r_refcount) {
12598c2ecf20Sopenharmony_ci		if (index != le16_to_cpu(rl->rl_used) - 1) {
12608c2ecf20Sopenharmony_ci			memmove(rec, rec + 1,
12618c2ecf20Sopenharmony_ci				(le16_to_cpu(rl->rl_used) - index - 1) *
12628c2ecf20Sopenharmony_ci				sizeof(struct ocfs2_refcount_rec));
12638c2ecf20Sopenharmony_ci			memset(&rl->rl_recs[le16_to_cpu(rl->rl_used) - 1],
12648c2ecf20Sopenharmony_ci			       0, sizeof(struct ocfs2_refcount_rec));
12658c2ecf20Sopenharmony_ci		}
12668c2ecf20Sopenharmony_ci
12678c2ecf20Sopenharmony_ci		le16_add_cpu(&rl->rl_used, -1);
12688c2ecf20Sopenharmony_ci	} else if (merge)
12698c2ecf20Sopenharmony_ci		ocfs2_refcount_rec_merge(rb, index);
12708c2ecf20Sopenharmony_ci
12718c2ecf20Sopenharmony_ci	ocfs2_journal_dirty(handle, ref_leaf_bh);
12728c2ecf20Sopenharmony_ciout:
12738c2ecf20Sopenharmony_ci	return ret;
12748c2ecf20Sopenharmony_ci}
12758c2ecf20Sopenharmony_ci
12768c2ecf20Sopenharmony_cistatic int ocfs2_expand_inline_ref_root(handle_t *handle,
12778c2ecf20Sopenharmony_ci					struct ocfs2_caching_info *ci,
12788c2ecf20Sopenharmony_ci					struct buffer_head *ref_root_bh,
12798c2ecf20Sopenharmony_ci					struct buffer_head **ref_leaf_bh,
12808c2ecf20Sopenharmony_ci					struct ocfs2_alloc_context *meta_ac)
12818c2ecf20Sopenharmony_ci{
12828c2ecf20Sopenharmony_ci	int ret;
12838c2ecf20Sopenharmony_ci	u16 suballoc_bit_start;
12848c2ecf20Sopenharmony_ci	u32 num_got;
12858c2ecf20Sopenharmony_ci	u64 suballoc_loc, blkno;
12868c2ecf20Sopenharmony_ci	struct super_block *sb = ocfs2_metadata_cache_get_super(ci);
12878c2ecf20Sopenharmony_ci	struct buffer_head *new_bh = NULL;
12888c2ecf20Sopenharmony_ci	struct ocfs2_refcount_block *new_rb;
12898c2ecf20Sopenharmony_ci	struct ocfs2_refcount_block *root_rb =
12908c2ecf20Sopenharmony_ci			(struct ocfs2_refcount_block *)ref_root_bh->b_data;
12918c2ecf20Sopenharmony_ci
12928c2ecf20Sopenharmony_ci	ret = ocfs2_journal_access_rb(handle, ci, ref_root_bh,
12938c2ecf20Sopenharmony_ci				      OCFS2_JOURNAL_ACCESS_WRITE);
12948c2ecf20Sopenharmony_ci	if (ret) {
12958c2ecf20Sopenharmony_ci		mlog_errno(ret);
12968c2ecf20Sopenharmony_ci		goto out;
12978c2ecf20Sopenharmony_ci	}
12988c2ecf20Sopenharmony_ci
12998c2ecf20Sopenharmony_ci	ret = ocfs2_claim_metadata(handle, meta_ac, 1, &suballoc_loc,
13008c2ecf20Sopenharmony_ci				   &suballoc_bit_start, &num_got,
13018c2ecf20Sopenharmony_ci				   &blkno);
13028c2ecf20Sopenharmony_ci	if (ret) {
13038c2ecf20Sopenharmony_ci		mlog_errno(ret);
13048c2ecf20Sopenharmony_ci		goto out;
13058c2ecf20Sopenharmony_ci	}
13068c2ecf20Sopenharmony_ci
13078c2ecf20Sopenharmony_ci	new_bh = sb_getblk(sb, blkno);
13088c2ecf20Sopenharmony_ci	if (new_bh == NULL) {
13098c2ecf20Sopenharmony_ci		ret = -ENOMEM;
13108c2ecf20Sopenharmony_ci		mlog_errno(ret);
13118c2ecf20Sopenharmony_ci		goto out;
13128c2ecf20Sopenharmony_ci	}
13138c2ecf20Sopenharmony_ci	ocfs2_set_new_buffer_uptodate(ci, new_bh);
13148c2ecf20Sopenharmony_ci
13158c2ecf20Sopenharmony_ci	ret = ocfs2_journal_access_rb(handle, ci, new_bh,
13168c2ecf20Sopenharmony_ci				      OCFS2_JOURNAL_ACCESS_CREATE);
13178c2ecf20Sopenharmony_ci	if (ret) {
13188c2ecf20Sopenharmony_ci		mlog_errno(ret);
13198c2ecf20Sopenharmony_ci		goto out;
13208c2ecf20Sopenharmony_ci	}
13218c2ecf20Sopenharmony_ci
13228c2ecf20Sopenharmony_ci	/*
13238c2ecf20Sopenharmony_ci	 * Initialize ocfs2_refcount_block.
13248c2ecf20Sopenharmony_ci	 * It should contain the same information as the old root.
13258c2ecf20Sopenharmony_ci	 * so just memcpy it and change the corresponding field.
13268c2ecf20Sopenharmony_ci	 */
13278c2ecf20Sopenharmony_ci	memcpy(new_bh->b_data, ref_root_bh->b_data, sb->s_blocksize);
13288c2ecf20Sopenharmony_ci
13298c2ecf20Sopenharmony_ci	new_rb = (struct ocfs2_refcount_block *)new_bh->b_data;
13308c2ecf20Sopenharmony_ci	new_rb->rf_suballoc_slot = cpu_to_le16(meta_ac->ac_alloc_slot);
13318c2ecf20Sopenharmony_ci	new_rb->rf_suballoc_loc = cpu_to_le64(suballoc_loc);
13328c2ecf20Sopenharmony_ci	new_rb->rf_suballoc_bit = cpu_to_le16(suballoc_bit_start);
13338c2ecf20Sopenharmony_ci	new_rb->rf_blkno = cpu_to_le64(blkno);
13348c2ecf20Sopenharmony_ci	new_rb->rf_cpos = cpu_to_le32(0);
13358c2ecf20Sopenharmony_ci	new_rb->rf_parent = cpu_to_le64(ref_root_bh->b_blocknr);
13368c2ecf20Sopenharmony_ci	new_rb->rf_flags = cpu_to_le32(OCFS2_REFCOUNT_LEAF_FL);
13378c2ecf20Sopenharmony_ci	ocfs2_journal_dirty(handle, new_bh);
13388c2ecf20Sopenharmony_ci
13398c2ecf20Sopenharmony_ci	/* Now change the root. */
13408c2ecf20Sopenharmony_ci	memset(&root_rb->rf_list, 0, sb->s_blocksize -
13418c2ecf20Sopenharmony_ci	       offsetof(struct ocfs2_refcount_block, rf_list));
13428c2ecf20Sopenharmony_ci	root_rb->rf_list.l_count = cpu_to_le16(ocfs2_extent_recs_per_rb(sb));
13438c2ecf20Sopenharmony_ci	root_rb->rf_clusters = cpu_to_le32(1);
13448c2ecf20Sopenharmony_ci	root_rb->rf_list.l_next_free_rec = cpu_to_le16(1);
13458c2ecf20Sopenharmony_ci	root_rb->rf_list.l_recs[0].e_blkno = cpu_to_le64(blkno);
13468c2ecf20Sopenharmony_ci	root_rb->rf_list.l_recs[0].e_leaf_clusters = cpu_to_le16(1);
13478c2ecf20Sopenharmony_ci	root_rb->rf_flags = cpu_to_le32(OCFS2_REFCOUNT_TREE_FL);
13488c2ecf20Sopenharmony_ci
13498c2ecf20Sopenharmony_ci	ocfs2_journal_dirty(handle, ref_root_bh);
13508c2ecf20Sopenharmony_ci
13518c2ecf20Sopenharmony_ci	trace_ocfs2_expand_inline_ref_root((unsigned long long)blkno,
13528c2ecf20Sopenharmony_ci		le16_to_cpu(new_rb->rf_records.rl_used));
13538c2ecf20Sopenharmony_ci
13548c2ecf20Sopenharmony_ci	*ref_leaf_bh = new_bh;
13558c2ecf20Sopenharmony_ci	new_bh = NULL;
13568c2ecf20Sopenharmony_ciout:
13578c2ecf20Sopenharmony_ci	brelse(new_bh);
13588c2ecf20Sopenharmony_ci	return ret;
13598c2ecf20Sopenharmony_ci}
13608c2ecf20Sopenharmony_ci
13618c2ecf20Sopenharmony_cistatic int ocfs2_refcount_rec_no_intersect(struct ocfs2_refcount_rec *prev,
13628c2ecf20Sopenharmony_ci					   struct ocfs2_refcount_rec *next)
13638c2ecf20Sopenharmony_ci{
13648c2ecf20Sopenharmony_ci	if (ocfs2_get_ref_rec_low_cpos(prev) + le32_to_cpu(prev->r_clusters) <=
13658c2ecf20Sopenharmony_ci		ocfs2_get_ref_rec_low_cpos(next))
13668c2ecf20Sopenharmony_ci		return 1;
13678c2ecf20Sopenharmony_ci
13688c2ecf20Sopenharmony_ci	return 0;
13698c2ecf20Sopenharmony_ci}
13708c2ecf20Sopenharmony_ci
13718c2ecf20Sopenharmony_cistatic int cmp_refcount_rec_by_low_cpos(const void *a, const void *b)
13728c2ecf20Sopenharmony_ci{
13738c2ecf20Sopenharmony_ci	const struct ocfs2_refcount_rec *l = a, *r = b;
13748c2ecf20Sopenharmony_ci	u32 l_cpos = ocfs2_get_ref_rec_low_cpos(l);
13758c2ecf20Sopenharmony_ci	u32 r_cpos = ocfs2_get_ref_rec_low_cpos(r);
13768c2ecf20Sopenharmony_ci
13778c2ecf20Sopenharmony_ci	if (l_cpos > r_cpos)
13788c2ecf20Sopenharmony_ci		return 1;
13798c2ecf20Sopenharmony_ci	if (l_cpos < r_cpos)
13808c2ecf20Sopenharmony_ci		return -1;
13818c2ecf20Sopenharmony_ci	return 0;
13828c2ecf20Sopenharmony_ci}
13838c2ecf20Sopenharmony_ci
13848c2ecf20Sopenharmony_cistatic int cmp_refcount_rec_by_cpos(const void *a, const void *b)
13858c2ecf20Sopenharmony_ci{
13868c2ecf20Sopenharmony_ci	const struct ocfs2_refcount_rec *l = a, *r = b;
13878c2ecf20Sopenharmony_ci	u64 l_cpos = le64_to_cpu(l->r_cpos);
13888c2ecf20Sopenharmony_ci	u64 r_cpos = le64_to_cpu(r->r_cpos);
13898c2ecf20Sopenharmony_ci
13908c2ecf20Sopenharmony_ci	if (l_cpos > r_cpos)
13918c2ecf20Sopenharmony_ci		return 1;
13928c2ecf20Sopenharmony_ci	if (l_cpos < r_cpos)
13938c2ecf20Sopenharmony_ci		return -1;
13948c2ecf20Sopenharmony_ci	return 0;
13958c2ecf20Sopenharmony_ci}
13968c2ecf20Sopenharmony_ci
13978c2ecf20Sopenharmony_cistatic void swap_refcount_rec(void *a, void *b, int size)
13988c2ecf20Sopenharmony_ci{
13998c2ecf20Sopenharmony_ci	struct ocfs2_refcount_rec *l = a, *r = b;
14008c2ecf20Sopenharmony_ci
14018c2ecf20Sopenharmony_ci	swap(*l, *r);
14028c2ecf20Sopenharmony_ci}
14038c2ecf20Sopenharmony_ci
14048c2ecf20Sopenharmony_ci/*
14058c2ecf20Sopenharmony_ci * The refcount cpos are ordered by their 64bit cpos,
14068c2ecf20Sopenharmony_ci * But we will use the low 32 bit to be the e_cpos in the b-tree.
14078c2ecf20Sopenharmony_ci * So we need to make sure that this pos isn't intersected with others.
14088c2ecf20Sopenharmony_ci *
14098c2ecf20Sopenharmony_ci * Note: The refcount block is already sorted by their low 32 bit cpos,
14108c2ecf20Sopenharmony_ci *       So just try the middle pos first, and we will exit when we find
14118c2ecf20Sopenharmony_ci *       the good position.
14128c2ecf20Sopenharmony_ci */
14138c2ecf20Sopenharmony_cistatic int ocfs2_find_refcount_split_pos(struct ocfs2_refcount_list *rl,
14148c2ecf20Sopenharmony_ci					 u32 *split_pos, int *split_index)
14158c2ecf20Sopenharmony_ci{
14168c2ecf20Sopenharmony_ci	int num_used = le16_to_cpu(rl->rl_used);
14178c2ecf20Sopenharmony_ci	int delta, middle = num_used / 2;
14188c2ecf20Sopenharmony_ci
14198c2ecf20Sopenharmony_ci	for (delta = 0; delta < middle; delta++) {
14208c2ecf20Sopenharmony_ci		/* Let's check delta earlier than middle */
14218c2ecf20Sopenharmony_ci		if (ocfs2_refcount_rec_no_intersect(
14228c2ecf20Sopenharmony_ci					&rl->rl_recs[middle - delta - 1],
14238c2ecf20Sopenharmony_ci					&rl->rl_recs[middle - delta])) {
14248c2ecf20Sopenharmony_ci			*split_index = middle - delta;
14258c2ecf20Sopenharmony_ci			break;
14268c2ecf20Sopenharmony_ci		}
14278c2ecf20Sopenharmony_ci
14288c2ecf20Sopenharmony_ci		/* For even counts, don't walk off the end */
14298c2ecf20Sopenharmony_ci		if ((middle + delta + 1) == num_used)
14308c2ecf20Sopenharmony_ci			continue;
14318c2ecf20Sopenharmony_ci
14328c2ecf20Sopenharmony_ci		/* Now try delta past middle */
14338c2ecf20Sopenharmony_ci		if (ocfs2_refcount_rec_no_intersect(
14348c2ecf20Sopenharmony_ci					&rl->rl_recs[middle + delta],
14358c2ecf20Sopenharmony_ci					&rl->rl_recs[middle + delta + 1])) {
14368c2ecf20Sopenharmony_ci			*split_index = middle + delta + 1;
14378c2ecf20Sopenharmony_ci			break;
14388c2ecf20Sopenharmony_ci		}
14398c2ecf20Sopenharmony_ci	}
14408c2ecf20Sopenharmony_ci
14418c2ecf20Sopenharmony_ci	if (delta >= middle)
14428c2ecf20Sopenharmony_ci		return -ENOSPC;
14438c2ecf20Sopenharmony_ci
14448c2ecf20Sopenharmony_ci	*split_pos = ocfs2_get_ref_rec_low_cpos(&rl->rl_recs[*split_index]);
14458c2ecf20Sopenharmony_ci	return 0;
14468c2ecf20Sopenharmony_ci}
14478c2ecf20Sopenharmony_ci
14488c2ecf20Sopenharmony_cistatic int ocfs2_divide_leaf_refcount_block(struct buffer_head *ref_leaf_bh,
14498c2ecf20Sopenharmony_ci					    struct buffer_head *new_bh,
14508c2ecf20Sopenharmony_ci					    u32 *split_cpos)
14518c2ecf20Sopenharmony_ci{
14528c2ecf20Sopenharmony_ci	int split_index = 0, num_moved, ret;
14538c2ecf20Sopenharmony_ci	u32 cpos = 0;
14548c2ecf20Sopenharmony_ci	struct ocfs2_refcount_block *rb =
14558c2ecf20Sopenharmony_ci			(struct ocfs2_refcount_block *)ref_leaf_bh->b_data;
14568c2ecf20Sopenharmony_ci	struct ocfs2_refcount_list *rl = &rb->rf_records;
14578c2ecf20Sopenharmony_ci	struct ocfs2_refcount_block *new_rb =
14588c2ecf20Sopenharmony_ci			(struct ocfs2_refcount_block *)new_bh->b_data;
14598c2ecf20Sopenharmony_ci	struct ocfs2_refcount_list *new_rl = &new_rb->rf_records;
14608c2ecf20Sopenharmony_ci
14618c2ecf20Sopenharmony_ci	trace_ocfs2_divide_leaf_refcount_block(
14628c2ecf20Sopenharmony_ci		(unsigned long long)ref_leaf_bh->b_blocknr,
14638c2ecf20Sopenharmony_ci		le16_to_cpu(rl->rl_count), le16_to_cpu(rl->rl_used));
14648c2ecf20Sopenharmony_ci
14658c2ecf20Sopenharmony_ci	/*
14668c2ecf20Sopenharmony_ci	 * XXX: Improvement later.
14678c2ecf20Sopenharmony_ci	 * If we know all the high 32 bit cpos is the same, no need to sort.
14688c2ecf20Sopenharmony_ci	 *
14698c2ecf20Sopenharmony_ci	 * In order to make the whole process safe, we do:
14708c2ecf20Sopenharmony_ci	 * 1. sort the entries by their low 32 bit cpos first so that we can
14718c2ecf20Sopenharmony_ci	 *    find the split cpos easily.
14728c2ecf20Sopenharmony_ci	 * 2. call ocfs2_insert_extent to insert the new refcount block.
14738c2ecf20Sopenharmony_ci	 * 3. move the refcount rec to the new block.
14748c2ecf20Sopenharmony_ci	 * 4. sort the entries by their 64 bit cpos.
14758c2ecf20Sopenharmony_ci	 * 5. dirty the new_rb and rb.
14768c2ecf20Sopenharmony_ci	 */
14778c2ecf20Sopenharmony_ci	sort(&rl->rl_recs, le16_to_cpu(rl->rl_used),
14788c2ecf20Sopenharmony_ci	     sizeof(struct ocfs2_refcount_rec),
14798c2ecf20Sopenharmony_ci	     cmp_refcount_rec_by_low_cpos, swap_refcount_rec);
14808c2ecf20Sopenharmony_ci
14818c2ecf20Sopenharmony_ci	ret = ocfs2_find_refcount_split_pos(rl, &cpos, &split_index);
14828c2ecf20Sopenharmony_ci	if (ret) {
14838c2ecf20Sopenharmony_ci		mlog_errno(ret);
14848c2ecf20Sopenharmony_ci		return ret;
14858c2ecf20Sopenharmony_ci	}
14868c2ecf20Sopenharmony_ci
14878c2ecf20Sopenharmony_ci	new_rb->rf_cpos = cpu_to_le32(cpos);
14888c2ecf20Sopenharmony_ci
14898c2ecf20Sopenharmony_ci	/* move refcount records starting from split_index to the new block. */
14908c2ecf20Sopenharmony_ci	num_moved = le16_to_cpu(rl->rl_used) - split_index;
14918c2ecf20Sopenharmony_ci	memcpy(new_rl->rl_recs, &rl->rl_recs[split_index],
14928c2ecf20Sopenharmony_ci	       num_moved * sizeof(struct ocfs2_refcount_rec));
14938c2ecf20Sopenharmony_ci
14948c2ecf20Sopenharmony_ci	/*ok, remove the entries we just moved over to the other block. */
14958c2ecf20Sopenharmony_ci	memset(&rl->rl_recs[split_index], 0,
14968c2ecf20Sopenharmony_ci	       num_moved * sizeof(struct ocfs2_refcount_rec));
14978c2ecf20Sopenharmony_ci
14988c2ecf20Sopenharmony_ci	/* change old and new rl_used accordingly. */
14998c2ecf20Sopenharmony_ci	le16_add_cpu(&rl->rl_used, -num_moved);
15008c2ecf20Sopenharmony_ci	new_rl->rl_used = cpu_to_le16(num_moved);
15018c2ecf20Sopenharmony_ci
15028c2ecf20Sopenharmony_ci	sort(&rl->rl_recs, le16_to_cpu(rl->rl_used),
15038c2ecf20Sopenharmony_ci	     sizeof(struct ocfs2_refcount_rec),
15048c2ecf20Sopenharmony_ci	     cmp_refcount_rec_by_cpos, swap_refcount_rec);
15058c2ecf20Sopenharmony_ci
15068c2ecf20Sopenharmony_ci	sort(&new_rl->rl_recs, le16_to_cpu(new_rl->rl_used),
15078c2ecf20Sopenharmony_ci	     sizeof(struct ocfs2_refcount_rec),
15088c2ecf20Sopenharmony_ci	     cmp_refcount_rec_by_cpos, swap_refcount_rec);
15098c2ecf20Sopenharmony_ci
15108c2ecf20Sopenharmony_ci	*split_cpos = cpos;
15118c2ecf20Sopenharmony_ci	return 0;
15128c2ecf20Sopenharmony_ci}
15138c2ecf20Sopenharmony_ci
15148c2ecf20Sopenharmony_cistatic int ocfs2_new_leaf_refcount_block(handle_t *handle,
15158c2ecf20Sopenharmony_ci					 struct ocfs2_caching_info *ci,
15168c2ecf20Sopenharmony_ci					 struct buffer_head *ref_root_bh,
15178c2ecf20Sopenharmony_ci					 struct buffer_head *ref_leaf_bh,
15188c2ecf20Sopenharmony_ci					 struct ocfs2_alloc_context *meta_ac)
15198c2ecf20Sopenharmony_ci{
15208c2ecf20Sopenharmony_ci	int ret;
15218c2ecf20Sopenharmony_ci	u16 suballoc_bit_start;
15228c2ecf20Sopenharmony_ci	u32 num_got, new_cpos;
15238c2ecf20Sopenharmony_ci	u64 suballoc_loc, blkno;
15248c2ecf20Sopenharmony_ci	struct super_block *sb = ocfs2_metadata_cache_get_super(ci);
15258c2ecf20Sopenharmony_ci	struct ocfs2_refcount_block *root_rb =
15268c2ecf20Sopenharmony_ci			(struct ocfs2_refcount_block *)ref_root_bh->b_data;
15278c2ecf20Sopenharmony_ci	struct buffer_head *new_bh = NULL;
15288c2ecf20Sopenharmony_ci	struct ocfs2_refcount_block *new_rb;
15298c2ecf20Sopenharmony_ci	struct ocfs2_extent_tree ref_et;
15308c2ecf20Sopenharmony_ci
15318c2ecf20Sopenharmony_ci	BUG_ON(!(le32_to_cpu(root_rb->rf_flags) & OCFS2_REFCOUNT_TREE_FL));
15328c2ecf20Sopenharmony_ci
15338c2ecf20Sopenharmony_ci	ret = ocfs2_journal_access_rb(handle, ci, ref_root_bh,
15348c2ecf20Sopenharmony_ci				      OCFS2_JOURNAL_ACCESS_WRITE);
15358c2ecf20Sopenharmony_ci	if (ret) {
15368c2ecf20Sopenharmony_ci		mlog_errno(ret);
15378c2ecf20Sopenharmony_ci		goto out;
15388c2ecf20Sopenharmony_ci	}
15398c2ecf20Sopenharmony_ci
15408c2ecf20Sopenharmony_ci	ret = ocfs2_journal_access_rb(handle, ci, ref_leaf_bh,
15418c2ecf20Sopenharmony_ci				      OCFS2_JOURNAL_ACCESS_WRITE);
15428c2ecf20Sopenharmony_ci	if (ret) {
15438c2ecf20Sopenharmony_ci		mlog_errno(ret);
15448c2ecf20Sopenharmony_ci		goto out;
15458c2ecf20Sopenharmony_ci	}
15468c2ecf20Sopenharmony_ci
15478c2ecf20Sopenharmony_ci	ret = ocfs2_claim_metadata(handle, meta_ac, 1, &suballoc_loc,
15488c2ecf20Sopenharmony_ci				   &suballoc_bit_start, &num_got,
15498c2ecf20Sopenharmony_ci				   &blkno);
15508c2ecf20Sopenharmony_ci	if (ret) {
15518c2ecf20Sopenharmony_ci		mlog_errno(ret);
15528c2ecf20Sopenharmony_ci		goto out;
15538c2ecf20Sopenharmony_ci	}
15548c2ecf20Sopenharmony_ci
15558c2ecf20Sopenharmony_ci	new_bh = sb_getblk(sb, blkno);
15568c2ecf20Sopenharmony_ci	if (new_bh == NULL) {
15578c2ecf20Sopenharmony_ci		ret = -ENOMEM;
15588c2ecf20Sopenharmony_ci		mlog_errno(ret);
15598c2ecf20Sopenharmony_ci		goto out;
15608c2ecf20Sopenharmony_ci	}
15618c2ecf20Sopenharmony_ci	ocfs2_set_new_buffer_uptodate(ci, new_bh);
15628c2ecf20Sopenharmony_ci
15638c2ecf20Sopenharmony_ci	ret = ocfs2_journal_access_rb(handle, ci, new_bh,
15648c2ecf20Sopenharmony_ci				      OCFS2_JOURNAL_ACCESS_CREATE);
15658c2ecf20Sopenharmony_ci	if (ret) {
15668c2ecf20Sopenharmony_ci		mlog_errno(ret);
15678c2ecf20Sopenharmony_ci		goto out;
15688c2ecf20Sopenharmony_ci	}
15698c2ecf20Sopenharmony_ci
15708c2ecf20Sopenharmony_ci	/* Initialize ocfs2_refcount_block. */
15718c2ecf20Sopenharmony_ci	new_rb = (struct ocfs2_refcount_block *)new_bh->b_data;
15728c2ecf20Sopenharmony_ci	memset(new_rb, 0, sb->s_blocksize);
15738c2ecf20Sopenharmony_ci	strcpy((void *)new_rb, OCFS2_REFCOUNT_BLOCK_SIGNATURE);
15748c2ecf20Sopenharmony_ci	new_rb->rf_suballoc_slot = cpu_to_le16(meta_ac->ac_alloc_slot);
15758c2ecf20Sopenharmony_ci	new_rb->rf_suballoc_loc = cpu_to_le64(suballoc_loc);
15768c2ecf20Sopenharmony_ci	new_rb->rf_suballoc_bit = cpu_to_le16(suballoc_bit_start);
15778c2ecf20Sopenharmony_ci	new_rb->rf_fs_generation = cpu_to_le32(OCFS2_SB(sb)->fs_generation);
15788c2ecf20Sopenharmony_ci	new_rb->rf_blkno = cpu_to_le64(blkno);
15798c2ecf20Sopenharmony_ci	new_rb->rf_parent = cpu_to_le64(ref_root_bh->b_blocknr);
15808c2ecf20Sopenharmony_ci	new_rb->rf_flags = cpu_to_le32(OCFS2_REFCOUNT_LEAF_FL);
15818c2ecf20Sopenharmony_ci	new_rb->rf_records.rl_count =
15828c2ecf20Sopenharmony_ci				cpu_to_le16(ocfs2_refcount_recs_per_rb(sb));
15838c2ecf20Sopenharmony_ci	new_rb->rf_generation = root_rb->rf_generation;
15848c2ecf20Sopenharmony_ci
15858c2ecf20Sopenharmony_ci	ret = ocfs2_divide_leaf_refcount_block(ref_leaf_bh, new_bh, &new_cpos);
15868c2ecf20Sopenharmony_ci	if (ret) {
15878c2ecf20Sopenharmony_ci		mlog_errno(ret);
15888c2ecf20Sopenharmony_ci		goto out;
15898c2ecf20Sopenharmony_ci	}
15908c2ecf20Sopenharmony_ci
15918c2ecf20Sopenharmony_ci	ocfs2_journal_dirty(handle, ref_leaf_bh);
15928c2ecf20Sopenharmony_ci	ocfs2_journal_dirty(handle, new_bh);
15938c2ecf20Sopenharmony_ci
15948c2ecf20Sopenharmony_ci	ocfs2_init_refcount_extent_tree(&ref_et, ci, ref_root_bh);
15958c2ecf20Sopenharmony_ci
15968c2ecf20Sopenharmony_ci	trace_ocfs2_new_leaf_refcount_block(
15978c2ecf20Sopenharmony_ci			(unsigned long long)new_bh->b_blocknr, new_cpos);
15988c2ecf20Sopenharmony_ci
15998c2ecf20Sopenharmony_ci	/* Insert the new leaf block with the specific offset cpos. */
16008c2ecf20Sopenharmony_ci	ret = ocfs2_insert_extent(handle, &ref_et, new_cpos, new_bh->b_blocknr,
16018c2ecf20Sopenharmony_ci				  1, 0, meta_ac);
16028c2ecf20Sopenharmony_ci	if (ret)
16038c2ecf20Sopenharmony_ci		mlog_errno(ret);
16048c2ecf20Sopenharmony_ci
16058c2ecf20Sopenharmony_ciout:
16068c2ecf20Sopenharmony_ci	brelse(new_bh);
16078c2ecf20Sopenharmony_ci	return ret;
16088c2ecf20Sopenharmony_ci}
16098c2ecf20Sopenharmony_ci
16108c2ecf20Sopenharmony_cistatic int ocfs2_expand_refcount_tree(handle_t *handle,
16118c2ecf20Sopenharmony_ci				      struct ocfs2_caching_info *ci,
16128c2ecf20Sopenharmony_ci				      struct buffer_head *ref_root_bh,
16138c2ecf20Sopenharmony_ci				      struct buffer_head *ref_leaf_bh,
16148c2ecf20Sopenharmony_ci				      struct ocfs2_alloc_context *meta_ac)
16158c2ecf20Sopenharmony_ci{
16168c2ecf20Sopenharmony_ci	int ret;
16178c2ecf20Sopenharmony_ci	struct buffer_head *expand_bh = NULL;
16188c2ecf20Sopenharmony_ci
16198c2ecf20Sopenharmony_ci	if (ref_root_bh == ref_leaf_bh) {
16208c2ecf20Sopenharmony_ci		/*
16218c2ecf20Sopenharmony_ci		 * the old root bh hasn't been expanded to a b-tree,
16228c2ecf20Sopenharmony_ci		 * so expand it first.
16238c2ecf20Sopenharmony_ci		 */
16248c2ecf20Sopenharmony_ci		ret = ocfs2_expand_inline_ref_root(handle, ci, ref_root_bh,
16258c2ecf20Sopenharmony_ci						   &expand_bh, meta_ac);
16268c2ecf20Sopenharmony_ci		if (ret) {
16278c2ecf20Sopenharmony_ci			mlog_errno(ret);
16288c2ecf20Sopenharmony_ci			goto out;
16298c2ecf20Sopenharmony_ci		}
16308c2ecf20Sopenharmony_ci	} else {
16318c2ecf20Sopenharmony_ci		expand_bh = ref_leaf_bh;
16328c2ecf20Sopenharmony_ci		get_bh(expand_bh);
16338c2ecf20Sopenharmony_ci	}
16348c2ecf20Sopenharmony_ci
16358c2ecf20Sopenharmony_ci
16368c2ecf20Sopenharmony_ci	/* Now add a new refcount block into the tree.*/
16378c2ecf20Sopenharmony_ci	ret = ocfs2_new_leaf_refcount_block(handle, ci, ref_root_bh,
16388c2ecf20Sopenharmony_ci					    expand_bh, meta_ac);
16398c2ecf20Sopenharmony_ci	if (ret)
16408c2ecf20Sopenharmony_ci		mlog_errno(ret);
16418c2ecf20Sopenharmony_ciout:
16428c2ecf20Sopenharmony_ci	brelse(expand_bh);
16438c2ecf20Sopenharmony_ci	return ret;
16448c2ecf20Sopenharmony_ci}
16458c2ecf20Sopenharmony_ci
16468c2ecf20Sopenharmony_ci/*
16478c2ecf20Sopenharmony_ci * Adjust the extent rec in b-tree representing ref_leaf_bh.
16488c2ecf20Sopenharmony_ci *
16498c2ecf20Sopenharmony_ci * Only called when we have inserted a new refcount rec at index 0
16508c2ecf20Sopenharmony_ci * which means ocfs2_extent_rec.e_cpos may need some change.
16518c2ecf20Sopenharmony_ci */
16528c2ecf20Sopenharmony_cistatic int ocfs2_adjust_refcount_rec(handle_t *handle,
16538c2ecf20Sopenharmony_ci				     struct ocfs2_caching_info *ci,
16548c2ecf20Sopenharmony_ci				     struct buffer_head *ref_root_bh,
16558c2ecf20Sopenharmony_ci				     struct buffer_head *ref_leaf_bh,
16568c2ecf20Sopenharmony_ci				     struct ocfs2_refcount_rec *rec)
16578c2ecf20Sopenharmony_ci{
16588c2ecf20Sopenharmony_ci	int ret = 0, i;
16598c2ecf20Sopenharmony_ci	u32 new_cpos, old_cpos;
16608c2ecf20Sopenharmony_ci	struct ocfs2_path *path = NULL;
16618c2ecf20Sopenharmony_ci	struct ocfs2_extent_tree et;
16628c2ecf20Sopenharmony_ci	struct ocfs2_refcount_block *rb =
16638c2ecf20Sopenharmony_ci		(struct ocfs2_refcount_block *)ref_root_bh->b_data;
16648c2ecf20Sopenharmony_ci	struct ocfs2_extent_list *el;
16658c2ecf20Sopenharmony_ci
16668c2ecf20Sopenharmony_ci	if (!(le32_to_cpu(rb->rf_flags) & OCFS2_REFCOUNT_TREE_FL))
16678c2ecf20Sopenharmony_ci		goto out;
16688c2ecf20Sopenharmony_ci
16698c2ecf20Sopenharmony_ci	rb = (struct ocfs2_refcount_block *)ref_leaf_bh->b_data;
16708c2ecf20Sopenharmony_ci	old_cpos = le32_to_cpu(rb->rf_cpos);
16718c2ecf20Sopenharmony_ci	new_cpos = le64_to_cpu(rec->r_cpos) & OCFS2_32BIT_POS_MASK;
16728c2ecf20Sopenharmony_ci	if (old_cpos <= new_cpos)
16738c2ecf20Sopenharmony_ci		goto out;
16748c2ecf20Sopenharmony_ci
16758c2ecf20Sopenharmony_ci	ocfs2_init_refcount_extent_tree(&et, ci, ref_root_bh);
16768c2ecf20Sopenharmony_ci
16778c2ecf20Sopenharmony_ci	path = ocfs2_new_path_from_et(&et);
16788c2ecf20Sopenharmony_ci	if (!path) {
16798c2ecf20Sopenharmony_ci		ret = -ENOMEM;
16808c2ecf20Sopenharmony_ci		mlog_errno(ret);
16818c2ecf20Sopenharmony_ci		goto out;
16828c2ecf20Sopenharmony_ci	}
16838c2ecf20Sopenharmony_ci
16848c2ecf20Sopenharmony_ci	ret = ocfs2_find_path(ci, path, old_cpos);
16858c2ecf20Sopenharmony_ci	if (ret) {
16868c2ecf20Sopenharmony_ci		mlog_errno(ret);
16878c2ecf20Sopenharmony_ci		goto out;
16888c2ecf20Sopenharmony_ci	}
16898c2ecf20Sopenharmony_ci
16908c2ecf20Sopenharmony_ci	/*
16918c2ecf20Sopenharmony_ci	 * 2 more credits, one for the leaf refcount block, one for
16928c2ecf20Sopenharmony_ci	 * the extent block contains the extent rec.
16938c2ecf20Sopenharmony_ci	 */
16948c2ecf20Sopenharmony_ci	ret = ocfs2_extend_trans(handle, 2);
16958c2ecf20Sopenharmony_ci	if (ret < 0) {
16968c2ecf20Sopenharmony_ci		mlog_errno(ret);
16978c2ecf20Sopenharmony_ci		goto out;
16988c2ecf20Sopenharmony_ci	}
16998c2ecf20Sopenharmony_ci
17008c2ecf20Sopenharmony_ci	ret = ocfs2_journal_access_rb(handle, ci, ref_leaf_bh,
17018c2ecf20Sopenharmony_ci				      OCFS2_JOURNAL_ACCESS_WRITE);
17028c2ecf20Sopenharmony_ci	if (ret < 0) {
17038c2ecf20Sopenharmony_ci		mlog_errno(ret);
17048c2ecf20Sopenharmony_ci		goto out;
17058c2ecf20Sopenharmony_ci	}
17068c2ecf20Sopenharmony_ci
17078c2ecf20Sopenharmony_ci	ret = ocfs2_journal_access_eb(handle, ci, path_leaf_bh(path),
17088c2ecf20Sopenharmony_ci				      OCFS2_JOURNAL_ACCESS_WRITE);
17098c2ecf20Sopenharmony_ci	if (ret < 0) {
17108c2ecf20Sopenharmony_ci		mlog_errno(ret);
17118c2ecf20Sopenharmony_ci		goto out;
17128c2ecf20Sopenharmony_ci	}
17138c2ecf20Sopenharmony_ci
17148c2ecf20Sopenharmony_ci	/* change the leaf extent block first. */
17158c2ecf20Sopenharmony_ci	el = path_leaf_el(path);
17168c2ecf20Sopenharmony_ci
17178c2ecf20Sopenharmony_ci	for (i = 0; i < le16_to_cpu(el->l_next_free_rec); i++)
17188c2ecf20Sopenharmony_ci		if (le32_to_cpu(el->l_recs[i].e_cpos) == old_cpos)
17198c2ecf20Sopenharmony_ci			break;
17208c2ecf20Sopenharmony_ci
17218c2ecf20Sopenharmony_ci	BUG_ON(i == le16_to_cpu(el->l_next_free_rec));
17228c2ecf20Sopenharmony_ci
17238c2ecf20Sopenharmony_ci	el->l_recs[i].e_cpos = cpu_to_le32(new_cpos);
17248c2ecf20Sopenharmony_ci
17258c2ecf20Sopenharmony_ci	/* change the r_cpos in the leaf block. */
17268c2ecf20Sopenharmony_ci	rb->rf_cpos = cpu_to_le32(new_cpos);
17278c2ecf20Sopenharmony_ci
17288c2ecf20Sopenharmony_ci	ocfs2_journal_dirty(handle, path_leaf_bh(path));
17298c2ecf20Sopenharmony_ci	ocfs2_journal_dirty(handle, ref_leaf_bh);
17308c2ecf20Sopenharmony_ci
17318c2ecf20Sopenharmony_ciout:
17328c2ecf20Sopenharmony_ci	ocfs2_free_path(path);
17338c2ecf20Sopenharmony_ci	return ret;
17348c2ecf20Sopenharmony_ci}
17358c2ecf20Sopenharmony_ci
17368c2ecf20Sopenharmony_cistatic int ocfs2_insert_refcount_rec(handle_t *handle,
17378c2ecf20Sopenharmony_ci				     struct ocfs2_caching_info *ci,
17388c2ecf20Sopenharmony_ci				     struct buffer_head *ref_root_bh,
17398c2ecf20Sopenharmony_ci				     struct buffer_head *ref_leaf_bh,
17408c2ecf20Sopenharmony_ci				     struct ocfs2_refcount_rec *rec,
17418c2ecf20Sopenharmony_ci				     int index, int merge,
17428c2ecf20Sopenharmony_ci				     struct ocfs2_alloc_context *meta_ac)
17438c2ecf20Sopenharmony_ci{
17448c2ecf20Sopenharmony_ci	int ret;
17458c2ecf20Sopenharmony_ci	struct ocfs2_refcount_block *rb =
17468c2ecf20Sopenharmony_ci			(struct ocfs2_refcount_block *)ref_leaf_bh->b_data;
17478c2ecf20Sopenharmony_ci	struct ocfs2_refcount_list *rf_list = &rb->rf_records;
17488c2ecf20Sopenharmony_ci	struct buffer_head *new_bh = NULL;
17498c2ecf20Sopenharmony_ci
17508c2ecf20Sopenharmony_ci	BUG_ON(le32_to_cpu(rb->rf_flags) & OCFS2_REFCOUNT_TREE_FL);
17518c2ecf20Sopenharmony_ci
17528c2ecf20Sopenharmony_ci	if (rf_list->rl_used == rf_list->rl_count) {
17538c2ecf20Sopenharmony_ci		u64 cpos = le64_to_cpu(rec->r_cpos);
17548c2ecf20Sopenharmony_ci		u32 len = le32_to_cpu(rec->r_clusters);
17558c2ecf20Sopenharmony_ci
17568c2ecf20Sopenharmony_ci		ret = ocfs2_expand_refcount_tree(handle, ci, ref_root_bh,
17578c2ecf20Sopenharmony_ci						 ref_leaf_bh, meta_ac);
17588c2ecf20Sopenharmony_ci		if (ret) {
17598c2ecf20Sopenharmony_ci			mlog_errno(ret);
17608c2ecf20Sopenharmony_ci			goto out;
17618c2ecf20Sopenharmony_ci		}
17628c2ecf20Sopenharmony_ci
17638c2ecf20Sopenharmony_ci		ret = ocfs2_get_refcount_rec(ci, ref_root_bh,
17648c2ecf20Sopenharmony_ci					     cpos, len, NULL, &index,
17658c2ecf20Sopenharmony_ci					     &new_bh);
17668c2ecf20Sopenharmony_ci		if (ret) {
17678c2ecf20Sopenharmony_ci			mlog_errno(ret);
17688c2ecf20Sopenharmony_ci			goto out;
17698c2ecf20Sopenharmony_ci		}
17708c2ecf20Sopenharmony_ci
17718c2ecf20Sopenharmony_ci		ref_leaf_bh = new_bh;
17728c2ecf20Sopenharmony_ci		rb = (struct ocfs2_refcount_block *)ref_leaf_bh->b_data;
17738c2ecf20Sopenharmony_ci		rf_list = &rb->rf_records;
17748c2ecf20Sopenharmony_ci	}
17758c2ecf20Sopenharmony_ci
17768c2ecf20Sopenharmony_ci	ret = ocfs2_journal_access_rb(handle, ci, ref_leaf_bh,
17778c2ecf20Sopenharmony_ci				      OCFS2_JOURNAL_ACCESS_WRITE);
17788c2ecf20Sopenharmony_ci	if (ret) {
17798c2ecf20Sopenharmony_ci		mlog_errno(ret);
17808c2ecf20Sopenharmony_ci		goto out;
17818c2ecf20Sopenharmony_ci	}
17828c2ecf20Sopenharmony_ci
17838c2ecf20Sopenharmony_ci	if (index < le16_to_cpu(rf_list->rl_used))
17848c2ecf20Sopenharmony_ci		memmove(&rf_list->rl_recs[index + 1],
17858c2ecf20Sopenharmony_ci			&rf_list->rl_recs[index],
17868c2ecf20Sopenharmony_ci			(le16_to_cpu(rf_list->rl_used) - index) *
17878c2ecf20Sopenharmony_ci			 sizeof(struct ocfs2_refcount_rec));
17888c2ecf20Sopenharmony_ci
17898c2ecf20Sopenharmony_ci	trace_ocfs2_insert_refcount_rec(
17908c2ecf20Sopenharmony_ci		(unsigned long long)ref_leaf_bh->b_blocknr, index,
17918c2ecf20Sopenharmony_ci		(unsigned long long)le64_to_cpu(rec->r_cpos),
17928c2ecf20Sopenharmony_ci		le32_to_cpu(rec->r_clusters), le32_to_cpu(rec->r_refcount));
17938c2ecf20Sopenharmony_ci
17948c2ecf20Sopenharmony_ci	rf_list->rl_recs[index] = *rec;
17958c2ecf20Sopenharmony_ci
17968c2ecf20Sopenharmony_ci	le16_add_cpu(&rf_list->rl_used, 1);
17978c2ecf20Sopenharmony_ci
17988c2ecf20Sopenharmony_ci	if (merge)
17998c2ecf20Sopenharmony_ci		ocfs2_refcount_rec_merge(rb, index);
18008c2ecf20Sopenharmony_ci
18018c2ecf20Sopenharmony_ci	ocfs2_journal_dirty(handle, ref_leaf_bh);
18028c2ecf20Sopenharmony_ci
18038c2ecf20Sopenharmony_ci	if (index == 0) {
18048c2ecf20Sopenharmony_ci		ret = ocfs2_adjust_refcount_rec(handle, ci,
18058c2ecf20Sopenharmony_ci						ref_root_bh,
18068c2ecf20Sopenharmony_ci						ref_leaf_bh, rec);
18078c2ecf20Sopenharmony_ci		if (ret)
18088c2ecf20Sopenharmony_ci			mlog_errno(ret);
18098c2ecf20Sopenharmony_ci	}
18108c2ecf20Sopenharmony_ciout:
18118c2ecf20Sopenharmony_ci	brelse(new_bh);
18128c2ecf20Sopenharmony_ci	return ret;
18138c2ecf20Sopenharmony_ci}
18148c2ecf20Sopenharmony_ci
18158c2ecf20Sopenharmony_ci/*
18168c2ecf20Sopenharmony_ci * Split the refcount_rec indexed by "index" in ref_leaf_bh.
18178c2ecf20Sopenharmony_ci * This is much simple than our b-tree code.
18188c2ecf20Sopenharmony_ci * split_rec is the new refcount rec we want to insert.
18198c2ecf20Sopenharmony_ci * If split_rec->r_refcount > 0, we are changing the refcount(in case we
18208c2ecf20Sopenharmony_ci * increase refcount or decrease a refcount to non-zero).
18218c2ecf20Sopenharmony_ci * If split_rec->r_refcount == 0, we are punching a hole in current refcount
18228c2ecf20Sopenharmony_ci * rec( in case we decrease a refcount to zero).
18238c2ecf20Sopenharmony_ci */
18248c2ecf20Sopenharmony_cistatic int ocfs2_split_refcount_rec(handle_t *handle,
18258c2ecf20Sopenharmony_ci				    struct ocfs2_caching_info *ci,
18268c2ecf20Sopenharmony_ci				    struct buffer_head *ref_root_bh,
18278c2ecf20Sopenharmony_ci				    struct buffer_head *ref_leaf_bh,
18288c2ecf20Sopenharmony_ci				    struct ocfs2_refcount_rec *split_rec,
18298c2ecf20Sopenharmony_ci				    int index, int merge,
18308c2ecf20Sopenharmony_ci				    struct ocfs2_alloc_context *meta_ac,
18318c2ecf20Sopenharmony_ci				    struct ocfs2_cached_dealloc_ctxt *dealloc)
18328c2ecf20Sopenharmony_ci{
18338c2ecf20Sopenharmony_ci	int ret, recs_need;
18348c2ecf20Sopenharmony_ci	u32 len;
18358c2ecf20Sopenharmony_ci	struct ocfs2_refcount_block *rb =
18368c2ecf20Sopenharmony_ci			(struct ocfs2_refcount_block *)ref_leaf_bh->b_data;
18378c2ecf20Sopenharmony_ci	struct ocfs2_refcount_list *rf_list = &rb->rf_records;
18388c2ecf20Sopenharmony_ci	struct ocfs2_refcount_rec *orig_rec = &rf_list->rl_recs[index];
18398c2ecf20Sopenharmony_ci	struct ocfs2_refcount_rec *tail_rec = NULL;
18408c2ecf20Sopenharmony_ci	struct buffer_head *new_bh = NULL;
18418c2ecf20Sopenharmony_ci
18428c2ecf20Sopenharmony_ci	BUG_ON(le32_to_cpu(rb->rf_flags) & OCFS2_REFCOUNT_TREE_FL);
18438c2ecf20Sopenharmony_ci
18448c2ecf20Sopenharmony_ci	trace_ocfs2_split_refcount_rec(le64_to_cpu(orig_rec->r_cpos),
18458c2ecf20Sopenharmony_ci		le32_to_cpu(orig_rec->r_clusters),
18468c2ecf20Sopenharmony_ci		le32_to_cpu(orig_rec->r_refcount),
18478c2ecf20Sopenharmony_ci		le64_to_cpu(split_rec->r_cpos),
18488c2ecf20Sopenharmony_ci		le32_to_cpu(split_rec->r_clusters),
18498c2ecf20Sopenharmony_ci		le32_to_cpu(split_rec->r_refcount));
18508c2ecf20Sopenharmony_ci
18518c2ecf20Sopenharmony_ci	/*
18528c2ecf20Sopenharmony_ci	 * If we just need to split the header or tail clusters,
18538c2ecf20Sopenharmony_ci	 * no more recs are needed, just split is OK.
18548c2ecf20Sopenharmony_ci	 * Otherwise we at least need one new recs.
18558c2ecf20Sopenharmony_ci	 */
18568c2ecf20Sopenharmony_ci	if (!split_rec->r_refcount &&
18578c2ecf20Sopenharmony_ci	    (split_rec->r_cpos == orig_rec->r_cpos ||
18588c2ecf20Sopenharmony_ci	     le64_to_cpu(split_rec->r_cpos) +
18598c2ecf20Sopenharmony_ci	     le32_to_cpu(split_rec->r_clusters) ==
18608c2ecf20Sopenharmony_ci	     le64_to_cpu(orig_rec->r_cpos) + le32_to_cpu(orig_rec->r_clusters)))
18618c2ecf20Sopenharmony_ci		recs_need = 0;
18628c2ecf20Sopenharmony_ci	else
18638c2ecf20Sopenharmony_ci		recs_need = 1;
18648c2ecf20Sopenharmony_ci
18658c2ecf20Sopenharmony_ci	/*
18668c2ecf20Sopenharmony_ci	 * We need one more rec if we split in the middle and the new rec have
18678c2ecf20Sopenharmony_ci	 * some refcount in it.
18688c2ecf20Sopenharmony_ci	 */
18698c2ecf20Sopenharmony_ci	if (split_rec->r_refcount &&
18708c2ecf20Sopenharmony_ci	    (split_rec->r_cpos != orig_rec->r_cpos &&
18718c2ecf20Sopenharmony_ci	     le64_to_cpu(split_rec->r_cpos) +
18728c2ecf20Sopenharmony_ci	     le32_to_cpu(split_rec->r_clusters) !=
18738c2ecf20Sopenharmony_ci	     le64_to_cpu(orig_rec->r_cpos) + le32_to_cpu(orig_rec->r_clusters)))
18748c2ecf20Sopenharmony_ci		recs_need++;
18758c2ecf20Sopenharmony_ci
18768c2ecf20Sopenharmony_ci	/* If the leaf block don't have enough record, expand it. */
18778c2ecf20Sopenharmony_ci	if (le16_to_cpu(rf_list->rl_used) + recs_need >
18788c2ecf20Sopenharmony_ci					 le16_to_cpu(rf_list->rl_count)) {
18798c2ecf20Sopenharmony_ci		struct ocfs2_refcount_rec tmp_rec;
18808c2ecf20Sopenharmony_ci		u64 cpos = le64_to_cpu(orig_rec->r_cpos);
18818c2ecf20Sopenharmony_ci		len = le32_to_cpu(orig_rec->r_clusters);
18828c2ecf20Sopenharmony_ci		ret = ocfs2_expand_refcount_tree(handle, ci, ref_root_bh,
18838c2ecf20Sopenharmony_ci						 ref_leaf_bh, meta_ac);
18848c2ecf20Sopenharmony_ci		if (ret) {
18858c2ecf20Sopenharmony_ci			mlog_errno(ret);
18868c2ecf20Sopenharmony_ci			goto out;
18878c2ecf20Sopenharmony_ci		}
18888c2ecf20Sopenharmony_ci
18898c2ecf20Sopenharmony_ci		/*
18908c2ecf20Sopenharmony_ci		 * We have to re-get it since now cpos may be moved to
18918c2ecf20Sopenharmony_ci		 * another leaf block.
18928c2ecf20Sopenharmony_ci		 */
18938c2ecf20Sopenharmony_ci		ret = ocfs2_get_refcount_rec(ci, ref_root_bh,
18948c2ecf20Sopenharmony_ci					     cpos, len, &tmp_rec, &index,
18958c2ecf20Sopenharmony_ci					     &new_bh);
18968c2ecf20Sopenharmony_ci		if (ret) {
18978c2ecf20Sopenharmony_ci			mlog_errno(ret);
18988c2ecf20Sopenharmony_ci			goto out;
18998c2ecf20Sopenharmony_ci		}
19008c2ecf20Sopenharmony_ci
19018c2ecf20Sopenharmony_ci		ref_leaf_bh = new_bh;
19028c2ecf20Sopenharmony_ci		rb = (struct ocfs2_refcount_block *)ref_leaf_bh->b_data;
19038c2ecf20Sopenharmony_ci		rf_list = &rb->rf_records;
19048c2ecf20Sopenharmony_ci		orig_rec = &rf_list->rl_recs[index];
19058c2ecf20Sopenharmony_ci	}
19068c2ecf20Sopenharmony_ci
19078c2ecf20Sopenharmony_ci	ret = ocfs2_journal_access_rb(handle, ci, ref_leaf_bh,
19088c2ecf20Sopenharmony_ci				      OCFS2_JOURNAL_ACCESS_WRITE);
19098c2ecf20Sopenharmony_ci	if (ret) {
19108c2ecf20Sopenharmony_ci		mlog_errno(ret);
19118c2ecf20Sopenharmony_ci		goto out;
19128c2ecf20Sopenharmony_ci	}
19138c2ecf20Sopenharmony_ci
19148c2ecf20Sopenharmony_ci	/*
19158c2ecf20Sopenharmony_ci	 * We have calculated out how many new records we need and store
19168c2ecf20Sopenharmony_ci	 * in recs_need, so spare enough space first by moving the records
19178c2ecf20Sopenharmony_ci	 * after "index" to the end.
19188c2ecf20Sopenharmony_ci	 */
19198c2ecf20Sopenharmony_ci	if (index != le16_to_cpu(rf_list->rl_used) - 1)
19208c2ecf20Sopenharmony_ci		memmove(&rf_list->rl_recs[index + 1 + recs_need],
19218c2ecf20Sopenharmony_ci			&rf_list->rl_recs[index + 1],
19228c2ecf20Sopenharmony_ci			(le16_to_cpu(rf_list->rl_used) - index - 1) *
19238c2ecf20Sopenharmony_ci			 sizeof(struct ocfs2_refcount_rec));
19248c2ecf20Sopenharmony_ci
19258c2ecf20Sopenharmony_ci	len = (le64_to_cpu(orig_rec->r_cpos) +
19268c2ecf20Sopenharmony_ci	      le32_to_cpu(orig_rec->r_clusters)) -
19278c2ecf20Sopenharmony_ci	      (le64_to_cpu(split_rec->r_cpos) +
19288c2ecf20Sopenharmony_ci	      le32_to_cpu(split_rec->r_clusters));
19298c2ecf20Sopenharmony_ci
19308c2ecf20Sopenharmony_ci	/*
19318c2ecf20Sopenharmony_ci	 * If we have "len", the we will split in the tail and move it
19328c2ecf20Sopenharmony_ci	 * to the end of the space we have just spared.
19338c2ecf20Sopenharmony_ci	 */
19348c2ecf20Sopenharmony_ci	if (len) {
19358c2ecf20Sopenharmony_ci		tail_rec = &rf_list->rl_recs[index + recs_need];
19368c2ecf20Sopenharmony_ci
19378c2ecf20Sopenharmony_ci		memcpy(tail_rec, orig_rec, sizeof(struct ocfs2_refcount_rec));
19388c2ecf20Sopenharmony_ci		le64_add_cpu(&tail_rec->r_cpos,
19398c2ecf20Sopenharmony_ci			     le32_to_cpu(tail_rec->r_clusters) - len);
19408c2ecf20Sopenharmony_ci		tail_rec->r_clusters = cpu_to_le32(len);
19418c2ecf20Sopenharmony_ci	}
19428c2ecf20Sopenharmony_ci
19438c2ecf20Sopenharmony_ci	/*
19448c2ecf20Sopenharmony_ci	 * If the split pos isn't the same as the original one, we need to
19458c2ecf20Sopenharmony_ci	 * split in the head.
19468c2ecf20Sopenharmony_ci	 *
19478c2ecf20Sopenharmony_ci	 * Note: We have the chance that split_rec.r_refcount = 0,
19488c2ecf20Sopenharmony_ci	 * recs_need = 0 and len > 0, which means we just cut the head from
19498c2ecf20Sopenharmony_ci	 * the orig_rec and in that case we have done some modification in
19508c2ecf20Sopenharmony_ci	 * orig_rec above, so the check for r_cpos is faked.
19518c2ecf20Sopenharmony_ci	 */
19528c2ecf20Sopenharmony_ci	if (split_rec->r_cpos != orig_rec->r_cpos && tail_rec != orig_rec) {
19538c2ecf20Sopenharmony_ci		len = le64_to_cpu(split_rec->r_cpos) -
19548c2ecf20Sopenharmony_ci		      le64_to_cpu(orig_rec->r_cpos);
19558c2ecf20Sopenharmony_ci		orig_rec->r_clusters = cpu_to_le32(len);
19568c2ecf20Sopenharmony_ci		index++;
19578c2ecf20Sopenharmony_ci	}
19588c2ecf20Sopenharmony_ci
19598c2ecf20Sopenharmony_ci	le16_add_cpu(&rf_list->rl_used, recs_need);
19608c2ecf20Sopenharmony_ci
19618c2ecf20Sopenharmony_ci	if (split_rec->r_refcount) {
19628c2ecf20Sopenharmony_ci		rf_list->rl_recs[index] = *split_rec;
19638c2ecf20Sopenharmony_ci		trace_ocfs2_split_refcount_rec_insert(
19648c2ecf20Sopenharmony_ci			(unsigned long long)ref_leaf_bh->b_blocknr, index,
19658c2ecf20Sopenharmony_ci			(unsigned long long)le64_to_cpu(split_rec->r_cpos),
19668c2ecf20Sopenharmony_ci			le32_to_cpu(split_rec->r_clusters),
19678c2ecf20Sopenharmony_ci			le32_to_cpu(split_rec->r_refcount));
19688c2ecf20Sopenharmony_ci
19698c2ecf20Sopenharmony_ci		if (merge)
19708c2ecf20Sopenharmony_ci			ocfs2_refcount_rec_merge(rb, index);
19718c2ecf20Sopenharmony_ci	}
19728c2ecf20Sopenharmony_ci
19738c2ecf20Sopenharmony_ci	ocfs2_journal_dirty(handle, ref_leaf_bh);
19748c2ecf20Sopenharmony_ci
19758c2ecf20Sopenharmony_ciout:
19768c2ecf20Sopenharmony_ci	brelse(new_bh);
19778c2ecf20Sopenharmony_ci	return ret;
19788c2ecf20Sopenharmony_ci}
19798c2ecf20Sopenharmony_ci
19808c2ecf20Sopenharmony_cistatic int __ocfs2_increase_refcount(handle_t *handle,
19818c2ecf20Sopenharmony_ci				     struct ocfs2_caching_info *ci,
19828c2ecf20Sopenharmony_ci				     struct buffer_head *ref_root_bh,
19838c2ecf20Sopenharmony_ci				     u64 cpos, u32 len, int merge,
19848c2ecf20Sopenharmony_ci				     struct ocfs2_alloc_context *meta_ac,
19858c2ecf20Sopenharmony_ci				     struct ocfs2_cached_dealloc_ctxt *dealloc)
19868c2ecf20Sopenharmony_ci{
19878c2ecf20Sopenharmony_ci	int ret = 0, index;
19888c2ecf20Sopenharmony_ci	struct buffer_head *ref_leaf_bh = NULL;
19898c2ecf20Sopenharmony_ci	struct ocfs2_refcount_rec rec;
19908c2ecf20Sopenharmony_ci	unsigned int set_len = 0;
19918c2ecf20Sopenharmony_ci
19928c2ecf20Sopenharmony_ci	trace_ocfs2_increase_refcount_begin(
19938c2ecf20Sopenharmony_ci	     (unsigned long long)ocfs2_metadata_cache_owner(ci),
19948c2ecf20Sopenharmony_ci	     (unsigned long long)cpos, len);
19958c2ecf20Sopenharmony_ci
19968c2ecf20Sopenharmony_ci	while (len) {
19978c2ecf20Sopenharmony_ci		ret = ocfs2_get_refcount_rec(ci, ref_root_bh,
19988c2ecf20Sopenharmony_ci					     cpos, len, &rec, &index,
19998c2ecf20Sopenharmony_ci					     &ref_leaf_bh);
20008c2ecf20Sopenharmony_ci		if (ret) {
20018c2ecf20Sopenharmony_ci			mlog_errno(ret);
20028c2ecf20Sopenharmony_ci			goto out;
20038c2ecf20Sopenharmony_ci		}
20048c2ecf20Sopenharmony_ci
20058c2ecf20Sopenharmony_ci		set_len = le32_to_cpu(rec.r_clusters);
20068c2ecf20Sopenharmony_ci
20078c2ecf20Sopenharmony_ci		/*
20088c2ecf20Sopenharmony_ci		 * Here we may meet with 3 situations:
20098c2ecf20Sopenharmony_ci		 *
20108c2ecf20Sopenharmony_ci		 * 1. If we find an already existing record, and the length
20118c2ecf20Sopenharmony_ci		 *    is the same, cool, we just need to increase the r_refcount
20128c2ecf20Sopenharmony_ci		 *    and it is OK.
20138c2ecf20Sopenharmony_ci		 * 2. If we find a hole, just insert it with r_refcount = 1.
20148c2ecf20Sopenharmony_ci		 * 3. If we are in the middle of one extent record, split
20158c2ecf20Sopenharmony_ci		 *    it.
20168c2ecf20Sopenharmony_ci		 */
20178c2ecf20Sopenharmony_ci		if (rec.r_refcount && le64_to_cpu(rec.r_cpos) == cpos &&
20188c2ecf20Sopenharmony_ci		    set_len <= len) {
20198c2ecf20Sopenharmony_ci			trace_ocfs2_increase_refcount_change(
20208c2ecf20Sopenharmony_ci				(unsigned long long)cpos, set_len,
20218c2ecf20Sopenharmony_ci				le32_to_cpu(rec.r_refcount));
20228c2ecf20Sopenharmony_ci			ret = ocfs2_change_refcount_rec(handle, ci,
20238c2ecf20Sopenharmony_ci							ref_leaf_bh, index,
20248c2ecf20Sopenharmony_ci							merge, 1);
20258c2ecf20Sopenharmony_ci			if (ret) {
20268c2ecf20Sopenharmony_ci				mlog_errno(ret);
20278c2ecf20Sopenharmony_ci				goto out;
20288c2ecf20Sopenharmony_ci			}
20298c2ecf20Sopenharmony_ci		} else if (!rec.r_refcount) {
20308c2ecf20Sopenharmony_ci			rec.r_refcount = cpu_to_le32(1);
20318c2ecf20Sopenharmony_ci
20328c2ecf20Sopenharmony_ci			trace_ocfs2_increase_refcount_insert(
20338c2ecf20Sopenharmony_ci			     (unsigned long long)le64_to_cpu(rec.r_cpos),
20348c2ecf20Sopenharmony_ci			     set_len);
20358c2ecf20Sopenharmony_ci			ret = ocfs2_insert_refcount_rec(handle, ci, ref_root_bh,
20368c2ecf20Sopenharmony_ci							ref_leaf_bh,
20378c2ecf20Sopenharmony_ci							&rec, index,
20388c2ecf20Sopenharmony_ci							merge, meta_ac);
20398c2ecf20Sopenharmony_ci			if (ret) {
20408c2ecf20Sopenharmony_ci				mlog_errno(ret);
20418c2ecf20Sopenharmony_ci				goto out;
20428c2ecf20Sopenharmony_ci			}
20438c2ecf20Sopenharmony_ci		} else  {
20448c2ecf20Sopenharmony_ci			set_len = min((u64)(cpos + len),
20458c2ecf20Sopenharmony_ci				      le64_to_cpu(rec.r_cpos) + set_len) - cpos;
20468c2ecf20Sopenharmony_ci			rec.r_cpos = cpu_to_le64(cpos);
20478c2ecf20Sopenharmony_ci			rec.r_clusters = cpu_to_le32(set_len);
20488c2ecf20Sopenharmony_ci			le32_add_cpu(&rec.r_refcount, 1);
20498c2ecf20Sopenharmony_ci
20508c2ecf20Sopenharmony_ci			trace_ocfs2_increase_refcount_split(
20518c2ecf20Sopenharmony_ci			     (unsigned long long)le64_to_cpu(rec.r_cpos),
20528c2ecf20Sopenharmony_ci			     set_len, le32_to_cpu(rec.r_refcount));
20538c2ecf20Sopenharmony_ci			ret = ocfs2_split_refcount_rec(handle, ci,
20548c2ecf20Sopenharmony_ci						       ref_root_bh, ref_leaf_bh,
20558c2ecf20Sopenharmony_ci						       &rec, index, merge,
20568c2ecf20Sopenharmony_ci						       meta_ac, dealloc);
20578c2ecf20Sopenharmony_ci			if (ret) {
20588c2ecf20Sopenharmony_ci				mlog_errno(ret);
20598c2ecf20Sopenharmony_ci				goto out;
20608c2ecf20Sopenharmony_ci			}
20618c2ecf20Sopenharmony_ci		}
20628c2ecf20Sopenharmony_ci
20638c2ecf20Sopenharmony_ci		cpos += set_len;
20648c2ecf20Sopenharmony_ci		len -= set_len;
20658c2ecf20Sopenharmony_ci		brelse(ref_leaf_bh);
20668c2ecf20Sopenharmony_ci		ref_leaf_bh = NULL;
20678c2ecf20Sopenharmony_ci	}
20688c2ecf20Sopenharmony_ci
20698c2ecf20Sopenharmony_ciout:
20708c2ecf20Sopenharmony_ci	brelse(ref_leaf_bh);
20718c2ecf20Sopenharmony_ci	return ret;
20728c2ecf20Sopenharmony_ci}
20738c2ecf20Sopenharmony_ci
20748c2ecf20Sopenharmony_cistatic int ocfs2_remove_refcount_extent(handle_t *handle,
20758c2ecf20Sopenharmony_ci				struct ocfs2_caching_info *ci,
20768c2ecf20Sopenharmony_ci				struct buffer_head *ref_root_bh,
20778c2ecf20Sopenharmony_ci				struct buffer_head *ref_leaf_bh,
20788c2ecf20Sopenharmony_ci				struct ocfs2_alloc_context *meta_ac,
20798c2ecf20Sopenharmony_ci				struct ocfs2_cached_dealloc_ctxt *dealloc)
20808c2ecf20Sopenharmony_ci{
20818c2ecf20Sopenharmony_ci	int ret;
20828c2ecf20Sopenharmony_ci	struct super_block *sb = ocfs2_metadata_cache_get_super(ci);
20838c2ecf20Sopenharmony_ci	struct ocfs2_refcount_block *rb =
20848c2ecf20Sopenharmony_ci			(struct ocfs2_refcount_block *)ref_leaf_bh->b_data;
20858c2ecf20Sopenharmony_ci	struct ocfs2_extent_tree et;
20868c2ecf20Sopenharmony_ci
20878c2ecf20Sopenharmony_ci	BUG_ON(rb->rf_records.rl_used);
20888c2ecf20Sopenharmony_ci
20898c2ecf20Sopenharmony_ci	trace_ocfs2_remove_refcount_extent(
20908c2ecf20Sopenharmony_ci		(unsigned long long)ocfs2_metadata_cache_owner(ci),
20918c2ecf20Sopenharmony_ci		(unsigned long long)ref_leaf_bh->b_blocknr,
20928c2ecf20Sopenharmony_ci		le32_to_cpu(rb->rf_cpos));
20938c2ecf20Sopenharmony_ci
20948c2ecf20Sopenharmony_ci	ocfs2_init_refcount_extent_tree(&et, ci, ref_root_bh);
20958c2ecf20Sopenharmony_ci	ret = ocfs2_remove_extent(handle, &et, le32_to_cpu(rb->rf_cpos),
20968c2ecf20Sopenharmony_ci				  1, meta_ac, dealloc);
20978c2ecf20Sopenharmony_ci	if (ret) {
20988c2ecf20Sopenharmony_ci		mlog_errno(ret);
20998c2ecf20Sopenharmony_ci		goto out;
21008c2ecf20Sopenharmony_ci	}
21018c2ecf20Sopenharmony_ci
21028c2ecf20Sopenharmony_ci	ocfs2_remove_from_cache(ci, ref_leaf_bh);
21038c2ecf20Sopenharmony_ci
21048c2ecf20Sopenharmony_ci	/*
21058c2ecf20Sopenharmony_ci	 * add the freed block to the dealloc so that it will be freed
21068c2ecf20Sopenharmony_ci	 * when we run dealloc.
21078c2ecf20Sopenharmony_ci	 */
21088c2ecf20Sopenharmony_ci	ret = ocfs2_cache_block_dealloc(dealloc, EXTENT_ALLOC_SYSTEM_INODE,
21098c2ecf20Sopenharmony_ci					le16_to_cpu(rb->rf_suballoc_slot),
21108c2ecf20Sopenharmony_ci					le64_to_cpu(rb->rf_suballoc_loc),
21118c2ecf20Sopenharmony_ci					le64_to_cpu(rb->rf_blkno),
21128c2ecf20Sopenharmony_ci					le16_to_cpu(rb->rf_suballoc_bit));
21138c2ecf20Sopenharmony_ci	if (ret) {
21148c2ecf20Sopenharmony_ci		mlog_errno(ret);
21158c2ecf20Sopenharmony_ci		goto out;
21168c2ecf20Sopenharmony_ci	}
21178c2ecf20Sopenharmony_ci
21188c2ecf20Sopenharmony_ci	ret = ocfs2_journal_access_rb(handle, ci, ref_root_bh,
21198c2ecf20Sopenharmony_ci				      OCFS2_JOURNAL_ACCESS_WRITE);
21208c2ecf20Sopenharmony_ci	if (ret) {
21218c2ecf20Sopenharmony_ci		mlog_errno(ret);
21228c2ecf20Sopenharmony_ci		goto out;
21238c2ecf20Sopenharmony_ci	}
21248c2ecf20Sopenharmony_ci
21258c2ecf20Sopenharmony_ci	rb = (struct ocfs2_refcount_block *)ref_root_bh->b_data;
21268c2ecf20Sopenharmony_ci
21278c2ecf20Sopenharmony_ci	le32_add_cpu(&rb->rf_clusters, -1);
21288c2ecf20Sopenharmony_ci
21298c2ecf20Sopenharmony_ci	/*
21308c2ecf20Sopenharmony_ci	 * check whether we need to restore the root refcount block if
21318c2ecf20Sopenharmony_ci	 * there is no leaf extent block at atll.
21328c2ecf20Sopenharmony_ci	 */
21338c2ecf20Sopenharmony_ci	if (!rb->rf_list.l_next_free_rec) {
21348c2ecf20Sopenharmony_ci		BUG_ON(rb->rf_clusters);
21358c2ecf20Sopenharmony_ci
21368c2ecf20Sopenharmony_ci		trace_ocfs2_restore_refcount_block(
21378c2ecf20Sopenharmony_ci		     (unsigned long long)ref_root_bh->b_blocknr);
21388c2ecf20Sopenharmony_ci
21398c2ecf20Sopenharmony_ci		rb->rf_flags = 0;
21408c2ecf20Sopenharmony_ci		rb->rf_parent = 0;
21418c2ecf20Sopenharmony_ci		rb->rf_cpos = 0;
21428c2ecf20Sopenharmony_ci		memset(&rb->rf_records, 0, sb->s_blocksize -
21438c2ecf20Sopenharmony_ci		       offsetof(struct ocfs2_refcount_block, rf_records));
21448c2ecf20Sopenharmony_ci		rb->rf_records.rl_count =
21458c2ecf20Sopenharmony_ci				cpu_to_le16(ocfs2_refcount_recs_per_rb(sb));
21468c2ecf20Sopenharmony_ci	}
21478c2ecf20Sopenharmony_ci
21488c2ecf20Sopenharmony_ci	ocfs2_journal_dirty(handle, ref_root_bh);
21498c2ecf20Sopenharmony_ci
21508c2ecf20Sopenharmony_ciout:
21518c2ecf20Sopenharmony_ci	return ret;
21528c2ecf20Sopenharmony_ci}
21538c2ecf20Sopenharmony_ci
21548c2ecf20Sopenharmony_ciint ocfs2_increase_refcount(handle_t *handle,
21558c2ecf20Sopenharmony_ci			    struct ocfs2_caching_info *ci,
21568c2ecf20Sopenharmony_ci			    struct buffer_head *ref_root_bh,
21578c2ecf20Sopenharmony_ci			    u64 cpos, u32 len,
21588c2ecf20Sopenharmony_ci			    struct ocfs2_alloc_context *meta_ac,
21598c2ecf20Sopenharmony_ci			    struct ocfs2_cached_dealloc_ctxt *dealloc)
21608c2ecf20Sopenharmony_ci{
21618c2ecf20Sopenharmony_ci	return __ocfs2_increase_refcount(handle, ci, ref_root_bh,
21628c2ecf20Sopenharmony_ci					 cpos, len, 1,
21638c2ecf20Sopenharmony_ci					 meta_ac, dealloc);
21648c2ecf20Sopenharmony_ci}
21658c2ecf20Sopenharmony_ci
21668c2ecf20Sopenharmony_cistatic int ocfs2_decrease_refcount_rec(handle_t *handle,
21678c2ecf20Sopenharmony_ci				struct ocfs2_caching_info *ci,
21688c2ecf20Sopenharmony_ci				struct buffer_head *ref_root_bh,
21698c2ecf20Sopenharmony_ci				struct buffer_head *ref_leaf_bh,
21708c2ecf20Sopenharmony_ci				int index, u64 cpos, unsigned int len,
21718c2ecf20Sopenharmony_ci				struct ocfs2_alloc_context *meta_ac,
21728c2ecf20Sopenharmony_ci				struct ocfs2_cached_dealloc_ctxt *dealloc)
21738c2ecf20Sopenharmony_ci{
21748c2ecf20Sopenharmony_ci	int ret;
21758c2ecf20Sopenharmony_ci	struct ocfs2_refcount_block *rb =
21768c2ecf20Sopenharmony_ci			(struct ocfs2_refcount_block *)ref_leaf_bh->b_data;
21778c2ecf20Sopenharmony_ci	struct ocfs2_refcount_rec *rec = &rb->rf_records.rl_recs[index];
21788c2ecf20Sopenharmony_ci
21798c2ecf20Sopenharmony_ci	BUG_ON(cpos < le64_to_cpu(rec->r_cpos));
21808c2ecf20Sopenharmony_ci	BUG_ON(cpos + len >
21818c2ecf20Sopenharmony_ci	       le64_to_cpu(rec->r_cpos) + le32_to_cpu(rec->r_clusters));
21828c2ecf20Sopenharmony_ci
21838c2ecf20Sopenharmony_ci	trace_ocfs2_decrease_refcount_rec(
21848c2ecf20Sopenharmony_ci		(unsigned long long)ocfs2_metadata_cache_owner(ci),
21858c2ecf20Sopenharmony_ci		(unsigned long long)cpos, len);
21868c2ecf20Sopenharmony_ci
21878c2ecf20Sopenharmony_ci	if (cpos == le64_to_cpu(rec->r_cpos) &&
21888c2ecf20Sopenharmony_ci	    len == le32_to_cpu(rec->r_clusters))
21898c2ecf20Sopenharmony_ci		ret = ocfs2_change_refcount_rec(handle, ci,
21908c2ecf20Sopenharmony_ci						ref_leaf_bh, index, 1, -1);
21918c2ecf20Sopenharmony_ci	else {
21928c2ecf20Sopenharmony_ci		struct ocfs2_refcount_rec split = *rec;
21938c2ecf20Sopenharmony_ci		split.r_cpos = cpu_to_le64(cpos);
21948c2ecf20Sopenharmony_ci		split.r_clusters = cpu_to_le32(len);
21958c2ecf20Sopenharmony_ci
21968c2ecf20Sopenharmony_ci		le32_add_cpu(&split.r_refcount, -1);
21978c2ecf20Sopenharmony_ci
21988c2ecf20Sopenharmony_ci		ret = ocfs2_split_refcount_rec(handle, ci,
21998c2ecf20Sopenharmony_ci					       ref_root_bh, ref_leaf_bh,
22008c2ecf20Sopenharmony_ci					       &split, index, 1,
22018c2ecf20Sopenharmony_ci					       meta_ac, dealloc);
22028c2ecf20Sopenharmony_ci	}
22038c2ecf20Sopenharmony_ci
22048c2ecf20Sopenharmony_ci	if (ret) {
22058c2ecf20Sopenharmony_ci		mlog_errno(ret);
22068c2ecf20Sopenharmony_ci		goto out;
22078c2ecf20Sopenharmony_ci	}
22088c2ecf20Sopenharmony_ci
22098c2ecf20Sopenharmony_ci	/* Remove the leaf refcount block if it contains no refcount record. */
22108c2ecf20Sopenharmony_ci	if (!rb->rf_records.rl_used && ref_leaf_bh != ref_root_bh) {
22118c2ecf20Sopenharmony_ci		ret = ocfs2_remove_refcount_extent(handle, ci, ref_root_bh,
22128c2ecf20Sopenharmony_ci						   ref_leaf_bh, meta_ac,
22138c2ecf20Sopenharmony_ci						   dealloc);
22148c2ecf20Sopenharmony_ci		if (ret)
22158c2ecf20Sopenharmony_ci			mlog_errno(ret);
22168c2ecf20Sopenharmony_ci	}
22178c2ecf20Sopenharmony_ci
22188c2ecf20Sopenharmony_ciout:
22198c2ecf20Sopenharmony_ci	return ret;
22208c2ecf20Sopenharmony_ci}
22218c2ecf20Sopenharmony_ci
22228c2ecf20Sopenharmony_cistatic int __ocfs2_decrease_refcount(handle_t *handle,
22238c2ecf20Sopenharmony_ci				     struct ocfs2_caching_info *ci,
22248c2ecf20Sopenharmony_ci				     struct buffer_head *ref_root_bh,
22258c2ecf20Sopenharmony_ci				     u64 cpos, u32 len,
22268c2ecf20Sopenharmony_ci				     struct ocfs2_alloc_context *meta_ac,
22278c2ecf20Sopenharmony_ci				     struct ocfs2_cached_dealloc_ctxt *dealloc,
22288c2ecf20Sopenharmony_ci				     int delete)
22298c2ecf20Sopenharmony_ci{
22308c2ecf20Sopenharmony_ci	int ret = 0, index = 0;
22318c2ecf20Sopenharmony_ci	struct ocfs2_refcount_rec rec;
22328c2ecf20Sopenharmony_ci	unsigned int r_count = 0, r_len;
22338c2ecf20Sopenharmony_ci	struct super_block *sb = ocfs2_metadata_cache_get_super(ci);
22348c2ecf20Sopenharmony_ci	struct buffer_head *ref_leaf_bh = NULL;
22358c2ecf20Sopenharmony_ci
22368c2ecf20Sopenharmony_ci	trace_ocfs2_decrease_refcount(
22378c2ecf20Sopenharmony_ci		(unsigned long long)ocfs2_metadata_cache_owner(ci),
22388c2ecf20Sopenharmony_ci		(unsigned long long)cpos, len, delete);
22398c2ecf20Sopenharmony_ci
22408c2ecf20Sopenharmony_ci	while (len) {
22418c2ecf20Sopenharmony_ci		ret = ocfs2_get_refcount_rec(ci, ref_root_bh,
22428c2ecf20Sopenharmony_ci					     cpos, len, &rec, &index,
22438c2ecf20Sopenharmony_ci					     &ref_leaf_bh);
22448c2ecf20Sopenharmony_ci		if (ret) {
22458c2ecf20Sopenharmony_ci			mlog_errno(ret);
22468c2ecf20Sopenharmony_ci			goto out;
22478c2ecf20Sopenharmony_ci		}
22488c2ecf20Sopenharmony_ci
22498c2ecf20Sopenharmony_ci		r_count = le32_to_cpu(rec.r_refcount);
22508c2ecf20Sopenharmony_ci		BUG_ON(r_count == 0);
22518c2ecf20Sopenharmony_ci		if (!delete)
22528c2ecf20Sopenharmony_ci			BUG_ON(r_count > 1);
22538c2ecf20Sopenharmony_ci
22548c2ecf20Sopenharmony_ci		r_len = min((u64)(cpos + len), le64_to_cpu(rec.r_cpos) +
22558c2ecf20Sopenharmony_ci			      le32_to_cpu(rec.r_clusters)) - cpos;
22568c2ecf20Sopenharmony_ci
22578c2ecf20Sopenharmony_ci		ret = ocfs2_decrease_refcount_rec(handle, ci, ref_root_bh,
22588c2ecf20Sopenharmony_ci						  ref_leaf_bh, index,
22598c2ecf20Sopenharmony_ci						  cpos, r_len,
22608c2ecf20Sopenharmony_ci						  meta_ac, dealloc);
22618c2ecf20Sopenharmony_ci		if (ret) {
22628c2ecf20Sopenharmony_ci			mlog_errno(ret);
22638c2ecf20Sopenharmony_ci			goto out;
22648c2ecf20Sopenharmony_ci		}
22658c2ecf20Sopenharmony_ci
22668c2ecf20Sopenharmony_ci		if (le32_to_cpu(rec.r_refcount) == 1 && delete) {
22678c2ecf20Sopenharmony_ci			ret = ocfs2_cache_cluster_dealloc(dealloc,
22688c2ecf20Sopenharmony_ci					  ocfs2_clusters_to_blocks(sb, cpos),
22698c2ecf20Sopenharmony_ci							  r_len);
22708c2ecf20Sopenharmony_ci			if (ret) {
22718c2ecf20Sopenharmony_ci				mlog_errno(ret);
22728c2ecf20Sopenharmony_ci				goto out;
22738c2ecf20Sopenharmony_ci			}
22748c2ecf20Sopenharmony_ci		}
22758c2ecf20Sopenharmony_ci
22768c2ecf20Sopenharmony_ci		cpos += r_len;
22778c2ecf20Sopenharmony_ci		len -= r_len;
22788c2ecf20Sopenharmony_ci		brelse(ref_leaf_bh);
22798c2ecf20Sopenharmony_ci		ref_leaf_bh = NULL;
22808c2ecf20Sopenharmony_ci	}
22818c2ecf20Sopenharmony_ci
22828c2ecf20Sopenharmony_ciout:
22838c2ecf20Sopenharmony_ci	brelse(ref_leaf_bh);
22848c2ecf20Sopenharmony_ci	return ret;
22858c2ecf20Sopenharmony_ci}
22868c2ecf20Sopenharmony_ci
22878c2ecf20Sopenharmony_ci/* Caller must hold refcount tree lock. */
22888c2ecf20Sopenharmony_ciint ocfs2_decrease_refcount(struct inode *inode,
22898c2ecf20Sopenharmony_ci			    handle_t *handle, u32 cpos, u32 len,
22908c2ecf20Sopenharmony_ci			    struct ocfs2_alloc_context *meta_ac,
22918c2ecf20Sopenharmony_ci			    struct ocfs2_cached_dealloc_ctxt *dealloc,
22928c2ecf20Sopenharmony_ci			    int delete)
22938c2ecf20Sopenharmony_ci{
22948c2ecf20Sopenharmony_ci	int ret;
22958c2ecf20Sopenharmony_ci	u64 ref_blkno;
22968c2ecf20Sopenharmony_ci	struct buffer_head *ref_root_bh = NULL;
22978c2ecf20Sopenharmony_ci	struct ocfs2_refcount_tree *tree;
22988c2ecf20Sopenharmony_ci
22998c2ecf20Sopenharmony_ci	BUG_ON(!ocfs2_is_refcount_inode(inode));
23008c2ecf20Sopenharmony_ci
23018c2ecf20Sopenharmony_ci	ret = ocfs2_get_refcount_block(inode, &ref_blkno);
23028c2ecf20Sopenharmony_ci	if (ret) {
23038c2ecf20Sopenharmony_ci		mlog_errno(ret);
23048c2ecf20Sopenharmony_ci		goto out;
23058c2ecf20Sopenharmony_ci	}
23068c2ecf20Sopenharmony_ci
23078c2ecf20Sopenharmony_ci	ret = ocfs2_get_refcount_tree(OCFS2_SB(inode->i_sb), ref_blkno, &tree);
23088c2ecf20Sopenharmony_ci	if (ret) {
23098c2ecf20Sopenharmony_ci		mlog_errno(ret);
23108c2ecf20Sopenharmony_ci		goto out;
23118c2ecf20Sopenharmony_ci	}
23128c2ecf20Sopenharmony_ci
23138c2ecf20Sopenharmony_ci	ret = ocfs2_read_refcount_block(&tree->rf_ci, tree->rf_blkno,
23148c2ecf20Sopenharmony_ci					&ref_root_bh);
23158c2ecf20Sopenharmony_ci	if (ret) {
23168c2ecf20Sopenharmony_ci		mlog_errno(ret);
23178c2ecf20Sopenharmony_ci		goto out;
23188c2ecf20Sopenharmony_ci	}
23198c2ecf20Sopenharmony_ci
23208c2ecf20Sopenharmony_ci	ret = __ocfs2_decrease_refcount(handle, &tree->rf_ci, ref_root_bh,
23218c2ecf20Sopenharmony_ci					cpos, len, meta_ac, dealloc, delete);
23228c2ecf20Sopenharmony_ci	if (ret)
23238c2ecf20Sopenharmony_ci		mlog_errno(ret);
23248c2ecf20Sopenharmony_ciout:
23258c2ecf20Sopenharmony_ci	brelse(ref_root_bh);
23268c2ecf20Sopenharmony_ci	return ret;
23278c2ecf20Sopenharmony_ci}
23288c2ecf20Sopenharmony_ci
23298c2ecf20Sopenharmony_ci/*
23308c2ecf20Sopenharmony_ci * Mark the already-existing extent at cpos as refcounted for len clusters.
23318c2ecf20Sopenharmony_ci * This adds the refcount extent flag.
23328c2ecf20Sopenharmony_ci *
23338c2ecf20Sopenharmony_ci * If the existing extent is larger than the request, initiate a
23348c2ecf20Sopenharmony_ci * split. An attempt will be made at merging with adjacent extents.
23358c2ecf20Sopenharmony_ci *
23368c2ecf20Sopenharmony_ci * The caller is responsible for passing down meta_ac if we'll need it.
23378c2ecf20Sopenharmony_ci */
23388c2ecf20Sopenharmony_cistatic int ocfs2_mark_extent_refcounted(struct inode *inode,
23398c2ecf20Sopenharmony_ci				struct ocfs2_extent_tree *et,
23408c2ecf20Sopenharmony_ci				handle_t *handle, u32 cpos,
23418c2ecf20Sopenharmony_ci				u32 len, u32 phys,
23428c2ecf20Sopenharmony_ci				struct ocfs2_alloc_context *meta_ac,
23438c2ecf20Sopenharmony_ci				struct ocfs2_cached_dealloc_ctxt *dealloc)
23448c2ecf20Sopenharmony_ci{
23458c2ecf20Sopenharmony_ci	int ret;
23468c2ecf20Sopenharmony_ci
23478c2ecf20Sopenharmony_ci	trace_ocfs2_mark_extent_refcounted(OCFS2_I(inode)->ip_blkno,
23488c2ecf20Sopenharmony_ci					   cpos, len, phys);
23498c2ecf20Sopenharmony_ci
23508c2ecf20Sopenharmony_ci	if (!ocfs2_refcount_tree(OCFS2_SB(inode->i_sb))) {
23518c2ecf20Sopenharmony_ci		ret = ocfs2_error(inode->i_sb, "Inode %lu want to use refcount tree, but the feature bit is not set in the super block\n",
23528c2ecf20Sopenharmony_ci				  inode->i_ino);
23538c2ecf20Sopenharmony_ci		goto out;
23548c2ecf20Sopenharmony_ci	}
23558c2ecf20Sopenharmony_ci
23568c2ecf20Sopenharmony_ci	ret = ocfs2_change_extent_flag(handle, et, cpos,
23578c2ecf20Sopenharmony_ci				       len, phys, meta_ac, dealloc,
23588c2ecf20Sopenharmony_ci				       OCFS2_EXT_REFCOUNTED, 0);
23598c2ecf20Sopenharmony_ci	if (ret)
23608c2ecf20Sopenharmony_ci		mlog_errno(ret);
23618c2ecf20Sopenharmony_ci
23628c2ecf20Sopenharmony_ciout:
23638c2ecf20Sopenharmony_ci	return ret;
23648c2ecf20Sopenharmony_ci}
23658c2ecf20Sopenharmony_ci
23668c2ecf20Sopenharmony_ci/*
23678c2ecf20Sopenharmony_ci * Given some contiguous physical clusters, calculate what we need
23688c2ecf20Sopenharmony_ci * for modifying their refcount.
23698c2ecf20Sopenharmony_ci */
23708c2ecf20Sopenharmony_cistatic int ocfs2_calc_refcount_meta_credits(struct super_block *sb,
23718c2ecf20Sopenharmony_ci					    struct ocfs2_caching_info *ci,
23728c2ecf20Sopenharmony_ci					    struct buffer_head *ref_root_bh,
23738c2ecf20Sopenharmony_ci					    u64 start_cpos,
23748c2ecf20Sopenharmony_ci					    u32 clusters,
23758c2ecf20Sopenharmony_ci					    int *meta_add,
23768c2ecf20Sopenharmony_ci					    int *credits)
23778c2ecf20Sopenharmony_ci{
23788c2ecf20Sopenharmony_ci	int ret = 0, index, ref_blocks = 0, recs_add = 0;
23798c2ecf20Sopenharmony_ci	u64 cpos = start_cpos;
23808c2ecf20Sopenharmony_ci	struct ocfs2_refcount_block *rb;
23818c2ecf20Sopenharmony_ci	struct ocfs2_refcount_rec rec;
23828c2ecf20Sopenharmony_ci	struct buffer_head *ref_leaf_bh = NULL, *prev_bh = NULL;
23838c2ecf20Sopenharmony_ci	u32 len;
23848c2ecf20Sopenharmony_ci
23858c2ecf20Sopenharmony_ci	while (clusters) {
23868c2ecf20Sopenharmony_ci		ret = ocfs2_get_refcount_rec(ci, ref_root_bh,
23878c2ecf20Sopenharmony_ci					     cpos, clusters, &rec,
23888c2ecf20Sopenharmony_ci					     &index, &ref_leaf_bh);
23898c2ecf20Sopenharmony_ci		if (ret) {
23908c2ecf20Sopenharmony_ci			mlog_errno(ret);
23918c2ecf20Sopenharmony_ci			goto out;
23928c2ecf20Sopenharmony_ci		}
23938c2ecf20Sopenharmony_ci
23948c2ecf20Sopenharmony_ci		if (ref_leaf_bh != prev_bh) {
23958c2ecf20Sopenharmony_ci			/*
23968c2ecf20Sopenharmony_ci			 * Now we encounter a new leaf block, so calculate
23978c2ecf20Sopenharmony_ci			 * whether we need to extend the old leaf.
23988c2ecf20Sopenharmony_ci			 */
23998c2ecf20Sopenharmony_ci			if (prev_bh) {
24008c2ecf20Sopenharmony_ci				rb = (struct ocfs2_refcount_block *)
24018c2ecf20Sopenharmony_ci							prev_bh->b_data;
24028c2ecf20Sopenharmony_ci
24038c2ecf20Sopenharmony_ci				if (le16_to_cpu(rb->rf_records.rl_used) +
24048c2ecf20Sopenharmony_ci				    recs_add >
24058c2ecf20Sopenharmony_ci				    le16_to_cpu(rb->rf_records.rl_count))
24068c2ecf20Sopenharmony_ci					ref_blocks++;
24078c2ecf20Sopenharmony_ci			}
24088c2ecf20Sopenharmony_ci
24098c2ecf20Sopenharmony_ci			recs_add = 0;
24108c2ecf20Sopenharmony_ci			*credits += 1;
24118c2ecf20Sopenharmony_ci			brelse(prev_bh);
24128c2ecf20Sopenharmony_ci			prev_bh = ref_leaf_bh;
24138c2ecf20Sopenharmony_ci			get_bh(prev_bh);
24148c2ecf20Sopenharmony_ci		}
24158c2ecf20Sopenharmony_ci
24168c2ecf20Sopenharmony_ci		trace_ocfs2_calc_refcount_meta_credits_iterate(
24178c2ecf20Sopenharmony_ci				recs_add, (unsigned long long)cpos, clusters,
24188c2ecf20Sopenharmony_ci				(unsigned long long)le64_to_cpu(rec.r_cpos),
24198c2ecf20Sopenharmony_ci				le32_to_cpu(rec.r_clusters),
24208c2ecf20Sopenharmony_ci				le32_to_cpu(rec.r_refcount), index);
24218c2ecf20Sopenharmony_ci
24228c2ecf20Sopenharmony_ci		len = min((u64)cpos + clusters, le64_to_cpu(rec.r_cpos) +
24238c2ecf20Sopenharmony_ci			  le32_to_cpu(rec.r_clusters)) - cpos;
24248c2ecf20Sopenharmony_ci		/*
24258c2ecf20Sopenharmony_ci		 * We record all the records which will be inserted to the
24268c2ecf20Sopenharmony_ci		 * same refcount block, so that we can tell exactly whether
24278c2ecf20Sopenharmony_ci		 * we need a new refcount block or not.
24288c2ecf20Sopenharmony_ci		 *
24298c2ecf20Sopenharmony_ci		 * If we will insert a new one, this is easy and only happens
24308c2ecf20Sopenharmony_ci		 * during adding refcounted flag to the extent, so we don't
24318c2ecf20Sopenharmony_ci		 * have a chance of spliting. We just need one record.
24328c2ecf20Sopenharmony_ci		 *
24338c2ecf20Sopenharmony_ci		 * If the refcount rec already exists, that would be a little
24348c2ecf20Sopenharmony_ci		 * complicated. we may have to:
24358c2ecf20Sopenharmony_ci		 * 1) split at the beginning if the start pos isn't aligned.
24368c2ecf20Sopenharmony_ci		 *    we need 1 more record in this case.
24378c2ecf20Sopenharmony_ci		 * 2) split int the end if the end pos isn't aligned.
24388c2ecf20Sopenharmony_ci		 *    we need 1 more record in this case.
24398c2ecf20Sopenharmony_ci		 * 3) split in the middle because of file system fragmentation.
24408c2ecf20Sopenharmony_ci		 *    we need 2 more records in this case(we can't detect this
24418c2ecf20Sopenharmony_ci		 *    beforehand, so always think of the worst case).
24428c2ecf20Sopenharmony_ci		 */
24438c2ecf20Sopenharmony_ci		if (rec.r_refcount) {
24448c2ecf20Sopenharmony_ci			recs_add += 2;
24458c2ecf20Sopenharmony_ci			/* Check whether we need a split at the beginning. */
24468c2ecf20Sopenharmony_ci			if (cpos == start_cpos &&
24478c2ecf20Sopenharmony_ci			    cpos != le64_to_cpu(rec.r_cpos))
24488c2ecf20Sopenharmony_ci				recs_add++;
24498c2ecf20Sopenharmony_ci
24508c2ecf20Sopenharmony_ci			/* Check whether we need a split in the end. */
24518c2ecf20Sopenharmony_ci			if (cpos + clusters < le64_to_cpu(rec.r_cpos) +
24528c2ecf20Sopenharmony_ci			    le32_to_cpu(rec.r_clusters))
24538c2ecf20Sopenharmony_ci				recs_add++;
24548c2ecf20Sopenharmony_ci		} else
24558c2ecf20Sopenharmony_ci			recs_add++;
24568c2ecf20Sopenharmony_ci
24578c2ecf20Sopenharmony_ci		brelse(ref_leaf_bh);
24588c2ecf20Sopenharmony_ci		ref_leaf_bh = NULL;
24598c2ecf20Sopenharmony_ci		clusters -= len;
24608c2ecf20Sopenharmony_ci		cpos += len;
24618c2ecf20Sopenharmony_ci	}
24628c2ecf20Sopenharmony_ci
24638c2ecf20Sopenharmony_ci	if (prev_bh) {
24648c2ecf20Sopenharmony_ci		rb = (struct ocfs2_refcount_block *)prev_bh->b_data;
24658c2ecf20Sopenharmony_ci
24668c2ecf20Sopenharmony_ci		if (le16_to_cpu(rb->rf_records.rl_used) + recs_add >
24678c2ecf20Sopenharmony_ci		    le16_to_cpu(rb->rf_records.rl_count))
24688c2ecf20Sopenharmony_ci			ref_blocks++;
24698c2ecf20Sopenharmony_ci
24708c2ecf20Sopenharmony_ci		*credits += 1;
24718c2ecf20Sopenharmony_ci	}
24728c2ecf20Sopenharmony_ci
24738c2ecf20Sopenharmony_ci	if (!ref_blocks)
24748c2ecf20Sopenharmony_ci		goto out;
24758c2ecf20Sopenharmony_ci
24768c2ecf20Sopenharmony_ci	*meta_add += ref_blocks;
24778c2ecf20Sopenharmony_ci	*credits += ref_blocks;
24788c2ecf20Sopenharmony_ci
24798c2ecf20Sopenharmony_ci	/*
24808c2ecf20Sopenharmony_ci	 * So we may need ref_blocks to insert into the tree.
24818c2ecf20Sopenharmony_ci	 * That also means we need to change the b-tree and add that number
24828c2ecf20Sopenharmony_ci	 * of records since we never merge them.
24838c2ecf20Sopenharmony_ci	 * We need one more block for expansion since the new created leaf
24848c2ecf20Sopenharmony_ci	 * block is also full and needs split.
24858c2ecf20Sopenharmony_ci	 */
24868c2ecf20Sopenharmony_ci	rb = (struct ocfs2_refcount_block *)ref_root_bh->b_data;
24878c2ecf20Sopenharmony_ci	if (le32_to_cpu(rb->rf_flags) & OCFS2_REFCOUNT_TREE_FL) {
24888c2ecf20Sopenharmony_ci		struct ocfs2_extent_tree et;
24898c2ecf20Sopenharmony_ci
24908c2ecf20Sopenharmony_ci		ocfs2_init_refcount_extent_tree(&et, ci, ref_root_bh);
24918c2ecf20Sopenharmony_ci		*meta_add += ocfs2_extend_meta_needed(et.et_root_el);
24928c2ecf20Sopenharmony_ci		*credits += ocfs2_calc_extend_credits(sb,
24938c2ecf20Sopenharmony_ci						      et.et_root_el);
24948c2ecf20Sopenharmony_ci	} else {
24958c2ecf20Sopenharmony_ci		*credits += OCFS2_EXPAND_REFCOUNT_TREE_CREDITS;
24968c2ecf20Sopenharmony_ci		*meta_add += 1;
24978c2ecf20Sopenharmony_ci	}
24988c2ecf20Sopenharmony_ci
24998c2ecf20Sopenharmony_ciout:
25008c2ecf20Sopenharmony_ci
25018c2ecf20Sopenharmony_ci	trace_ocfs2_calc_refcount_meta_credits(
25028c2ecf20Sopenharmony_ci		(unsigned long long)start_cpos, clusters,
25038c2ecf20Sopenharmony_ci		*meta_add, *credits);
25048c2ecf20Sopenharmony_ci	brelse(ref_leaf_bh);
25058c2ecf20Sopenharmony_ci	brelse(prev_bh);
25068c2ecf20Sopenharmony_ci	return ret;
25078c2ecf20Sopenharmony_ci}
25088c2ecf20Sopenharmony_ci
25098c2ecf20Sopenharmony_ci/*
25108c2ecf20Sopenharmony_ci * For refcount tree, we will decrease some contiguous clusters
25118c2ecf20Sopenharmony_ci * refcount count, so just go through it to see how many blocks
25128c2ecf20Sopenharmony_ci * we gonna touch and whether we need to create new blocks.
25138c2ecf20Sopenharmony_ci *
25148c2ecf20Sopenharmony_ci * Normally the refcount blocks store these refcount should be
25158c2ecf20Sopenharmony_ci * contiguous also, so that we can get the number easily.
25168c2ecf20Sopenharmony_ci * We will at most add split 2 refcount records and 2 more
25178c2ecf20Sopenharmony_ci * refcount blocks, so just check it in a rough way.
25188c2ecf20Sopenharmony_ci *
25198c2ecf20Sopenharmony_ci * Caller must hold refcount tree lock.
25208c2ecf20Sopenharmony_ci */
25218c2ecf20Sopenharmony_ciint ocfs2_prepare_refcount_change_for_del(struct inode *inode,
25228c2ecf20Sopenharmony_ci					  u64 refcount_loc,
25238c2ecf20Sopenharmony_ci					  u64 phys_blkno,
25248c2ecf20Sopenharmony_ci					  u32 clusters,
25258c2ecf20Sopenharmony_ci					  int *credits,
25268c2ecf20Sopenharmony_ci					  int *ref_blocks)
25278c2ecf20Sopenharmony_ci{
25288c2ecf20Sopenharmony_ci	int ret;
25298c2ecf20Sopenharmony_ci	struct buffer_head *ref_root_bh = NULL;
25308c2ecf20Sopenharmony_ci	struct ocfs2_refcount_tree *tree;
25318c2ecf20Sopenharmony_ci	u64 start_cpos = ocfs2_blocks_to_clusters(inode->i_sb, phys_blkno);
25328c2ecf20Sopenharmony_ci
25338c2ecf20Sopenharmony_ci	if (!ocfs2_refcount_tree(OCFS2_SB(inode->i_sb))) {
25348c2ecf20Sopenharmony_ci		ret = ocfs2_error(inode->i_sb, "Inode %lu want to use refcount tree, but the feature bit is not set in the super block\n",
25358c2ecf20Sopenharmony_ci				  inode->i_ino);
25368c2ecf20Sopenharmony_ci		goto out;
25378c2ecf20Sopenharmony_ci	}
25388c2ecf20Sopenharmony_ci
25398c2ecf20Sopenharmony_ci	BUG_ON(!ocfs2_is_refcount_inode(inode));
25408c2ecf20Sopenharmony_ci
25418c2ecf20Sopenharmony_ci	ret = ocfs2_get_refcount_tree(OCFS2_SB(inode->i_sb),
25428c2ecf20Sopenharmony_ci				      refcount_loc, &tree);
25438c2ecf20Sopenharmony_ci	if (ret) {
25448c2ecf20Sopenharmony_ci		mlog_errno(ret);
25458c2ecf20Sopenharmony_ci		goto out;
25468c2ecf20Sopenharmony_ci	}
25478c2ecf20Sopenharmony_ci
25488c2ecf20Sopenharmony_ci	ret = ocfs2_read_refcount_block(&tree->rf_ci, refcount_loc,
25498c2ecf20Sopenharmony_ci					&ref_root_bh);
25508c2ecf20Sopenharmony_ci	if (ret) {
25518c2ecf20Sopenharmony_ci		mlog_errno(ret);
25528c2ecf20Sopenharmony_ci		goto out;
25538c2ecf20Sopenharmony_ci	}
25548c2ecf20Sopenharmony_ci
25558c2ecf20Sopenharmony_ci	ret = ocfs2_calc_refcount_meta_credits(inode->i_sb,
25568c2ecf20Sopenharmony_ci					       &tree->rf_ci,
25578c2ecf20Sopenharmony_ci					       ref_root_bh,
25588c2ecf20Sopenharmony_ci					       start_cpos, clusters,
25598c2ecf20Sopenharmony_ci					       ref_blocks, credits);
25608c2ecf20Sopenharmony_ci	if (ret) {
25618c2ecf20Sopenharmony_ci		mlog_errno(ret);
25628c2ecf20Sopenharmony_ci		goto out;
25638c2ecf20Sopenharmony_ci	}
25648c2ecf20Sopenharmony_ci
25658c2ecf20Sopenharmony_ci	trace_ocfs2_prepare_refcount_change_for_del(*ref_blocks, *credits);
25668c2ecf20Sopenharmony_ci
25678c2ecf20Sopenharmony_ciout:
25688c2ecf20Sopenharmony_ci	brelse(ref_root_bh);
25698c2ecf20Sopenharmony_ci	return ret;
25708c2ecf20Sopenharmony_ci}
25718c2ecf20Sopenharmony_ci
25728c2ecf20Sopenharmony_ci#define	MAX_CONTIG_BYTES	1048576
25738c2ecf20Sopenharmony_ci
25748c2ecf20Sopenharmony_cistatic inline unsigned int ocfs2_cow_contig_clusters(struct super_block *sb)
25758c2ecf20Sopenharmony_ci{
25768c2ecf20Sopenharmony_ci	return ocfs2_clusters_for_bytes(sb, MAX_CONTIG_BYTES);
25778c2ecf20Sopenharmony_ci}
25788c2ecf20Sopenharmony_ci
25798c2ecf20Sopenharmony_cistatic inline unsigned int ocfs2_cow_contig_mask(struct super_block *sb)
25808c2ecf20Sopenharmony_ci{
25818c2ecf20Sopenharmony_ci	return ~(ocfs2_cow_contig_clusters(sb) - 1);
25828c2ecf20Sopenharmony_ci}
25838c2ecf20Sopenharmony_ci
25848c2ecf20Sopenharmony_ci/*
25858c2ecf20Sopenharmony_ci * Given an extent that starts at 'start' and an I/O that starts at 'cpos',
25868c2ecf20Sopenharmony_ci * find an offset (start + (n * contig_clusters)) that is closest to cpos
25878c2ecf20Sopenharmony_ci * while still being less than or equal to it.
25888c2ecf20Sopenharmony_ci *
25898c2ecf20Sopenharmony_ci * The goal is to break the extent at a multiple of contig_clusters.
25908c2ecf20Sopenharmony_ci */
25918c2ecf20Sopenharmony_cistatic inline unsigned int ocfs2_cow_align_start(struct super_block *sb,
25928c2ecf20Sopenharmony_ci						 unsigned int start,
25938c2ecf20Sopenharmony_ci						 unsigned int cpos)
25948c2ecf20Sopenharmony_ci{
25958c2ecf20Sopenharmony_ci	BUG_ON(start > cpos);
25968c2ecf20Sopenharmony_ci
25978c2ecf20Sopenharmony_ci	return start + ((cpos - start) & ocfs2_cow_contig_mask(sb));
25988c2ecf20Sopenharmony_ci}
25998c2ecf20Sopenharmony_ci
26008c2ecf20Sopenharmony_ci/*
26018c2ecf20Sopenharmony_ci * Given a cluster count of len, pad it out so that it is a multiple
26028c2ecf20Sopenharmony_ci * of contig_clusters.
26038c2ecf20Sopenharmony_ci */
26048c2ecf20Sopenharmony_cistatic inline unsigned int ocfs2_cow_align_length(struct super_block *sb,
26058c2ecf20Sopenharmony_ci						  unsigned int len)
26068c2ecf20Sopenharmony_ci{
26078c2ecf20Sopenharmony_ci	unsigned int padded =
26088c2ecf20Sopenharmony_ci		(len + (ocfs2_cow_contig_clusters(sb) - 1)) &
26098c2ecf20Sopenharmony_ci		ocfs2_cow_contig_mask(sb);
26108c2ecf20Sopenharmony_ci
26118c2ecf20Sopenharmony_ci	/* Did we wrap? */
26128c2ecf20Sopenharmony_ci	if (padded < len)
26138c2ecf20Sopenharmony_ci		padded = UINT_MAX;
26148c2ecf20Sopenharmony_ci
26158c2ecf20Sopenharmony_ci	return padded;
26168c2ecf20Sopenharmony_ci}
26178c2ecf20Sopenharmony_ci
26188c2ecf20Sopenharmony_ci/*
26198c2ecf20Sopenharmony_ci * Calculate out the start and number of virtual clusters we need to to CoW.
26208c2ecf20Sopenharmony_ci *
26218c2ecf20Sopenharmony_ci * cpos is vitual start cluster position we want to do CoW in a
26228c2ecf20Sopenharmony_ci * file and write_len is the cluster length.
26238c2ecf20Sopenharmony_ci * max_cpos is the place where we want to stop CoW intentionally.
26248c2ecf20Sopenharmony_ci *
26258c2ecf20Sopenharmony_ci * Normal we will start CoW from the beginning of extent record cotaining cpos.
26268c2ecf20Sopenharmony_ci * We try to break up extents on boundaries of MAX_CONTIG_BYTES so that we
26278c2ecf20Sopenharmony_ci * get good I/O from the resulting extent tree.
26288c2ecf20Sopenharmony_ci */
26298c2ecf20Sopenharmony_cistatic int ocfs2_refcount_cal_cow_clusters(struct inode *inode,
26308c2ecf20Sopenharmony_ci					   struct ocfs2_extent_list *el,
26318c2ecf20Sopenharmony_ci					   u32 cpos,
26328c2ecf20Sopenharmony_ci					   u32 write_len,
26338c2ecf20Sopenharmony_ci					   u32 max_cpos,
26348c2ecf20Sopenharmony_ci					   u32 *cow_start,
26358c2ecf20Sopenharmony_ci					   u32 *cow_len)
26368c2ecf20Sopenharmony_ci{
26378c2ecf20Sopenharmony_ci	int ret = 0;
26388c2ecf20Sopenharmony_ci	int tree_height = le16_to_cpu(el->l_tree_depth), i;
26398c2ecf20Sopenharmony_ci	struct buffer_head *eb_bh = NULL;
26408c2ecf20Sopenharmony_ci	struct ocfs2_extent_block *eb = NULL;
26418c2ecf20Sopenharmony_ci	struct ocfs2_extent_rec *rec;
26428c2ecf20Sopenharmony_ci	unsigned int want_clusters, rec_end = 0;
26438c2ecf20Sopenharmony_ci	int contig_clusters = ocfs2_cow_contig_clusters(inode->i_sb);
26448c2ecf20Sopenharmony_ci	int leaf_clusters;
26458c2ecf20Sopenharmony_ci
26468c2ecf20Sopenharmony_ci	BUG_ON(cpos + write_len > max_cpos);
26478c2ecf20Sopenharmony_ci
26488c2ecf20Sopenharmony_ci	if (tree_height > 0) {
26498c2ecf20Sopenharmony_ci		ret = ocfs2_find_leaf(INODE_CACHE(inode), el, cpos, &eb_bh);
26508c2ecf20Sopenharmony_ci		if (ret) {
26518c2ecf20Sopenharmony_ci			mlog_errno(ret);
26528c2ecf20Sopenharmony_ci			goto out;
26538c2ecf20Sopenharmony_ci		}
26548c2ecf20Sopenharmony_ci
26558c2ecf20Sopenharmony_ci		eb = (struct ocfs2_extent_block *) eb_bh->b_data;
26568c2ecf20Sopenharmony_ci		el = &eb->h_list;
26578c2ecf20Sopenharmony_ci
26588c2ecf20Sopenharmony_ci		if (el->l_tree_depth) {
26598c2ecf20Sopenharmony_ci			ret = ocfs2_error(inode->i_sb,
26608c2ecf20Sopenharmony_ci					  "Inode %lu has non zero tree depth in leaf block %llu\n",
26618c2ecf20Sopenharmony_ci					  inode->i_ino,
26628c2ecf20Sopenharmony_ci					  (unsigned long long)eb_bh->b_blocknr);
26638c2ecf20Sopenharmony_ci			goto out;
26648c2ecf20Sopenharmony_ci		}
26658c2ecf20Sopenharmony_ci	}
26668c2ecf20Sopenharmony_ci
26678c2ecf20Sopenharmony_ci	*cow_len = 0;
26688c2ecf20Sopenharmony_ci	for (i = 0; i < le16_to_cpu(el->l_next_free_rec); i++) {
26698c2ecf20Sopenharmony_ci		rec = &el->l_recs[i];
26708c2ecf20Sopenharmony_ci
26718c2ecf20Sopenharmony_ci		if (ocfs2_is_empty_extent(rec)) {
26728c2ecf20Sopenharmony_ci			mlog_bug_on_msg(i != 0, "Inode %lu has empty record in "
26738c2ecf20Sopenharmony_ci					"index %d\n", inode->i_ino, i);
26748c2ecf20Sopenharmony_ci			continue;
26758c2ecf20Sopenharmony_ci		}
26768c2ecf20Sopenharmony_ci
26778c2ecf20Sopenharmony_ci		if (le32_to_cpu(rec->e_cpos) +
26788c2ecf20Sopenharmony_ci		    le16_to_cpu(rec->e_leaf_clusters) <= cpos)
26798c2ecf20Sopenharmony_ci			continue;
26808c2ecf20Sopenharmony_ci
26818c2ecf20Sopenharmony_ci		if (*cow_len == 0) {
26828c2ecf20Sopenharmony_ci			/*
26838c2ecf20Sopenharmony_ci			 * We should find a refcounted record in the
26848c2ecf20Sopenharmony_ci			 * first pass.
26858c2ecf20Sopenharmony_ci			 */
26868c2ecf20Sopenharmony_ci			BUG_ON(!(rec->e_flags & OCFS2_EXT_REFCOUNTED));
26878c2ecf20Sopenharmony_ci			*cow_start = le32_to_cpu(rec->e_cpos);
26888c2ecf20Sopenharmony_ci		}
26898c2ecf20Sopenharmony_ci
26908c2ecf20Sopenharmony_ci		/*
26918c2ecf20Sopenharmony_ci		 * If we encounter a hole, a non-refcounted record or
26928c2ecf20Sopenharmony_ci		 * pass the max_cpos, stop the search.
26938c2ecf20Sopenharmony_ci		 */
26948c2ecf20Sopenharmony_ci		if ((!(rec->e_flags & OCFS2_EXT_REFCOUNTED)) ||
26958c2ecf20Sopenharmony_ci		    (*cow_len && rec_end != le32_to_cpu(rec->e_cpos)) ||
26968c2ecf20Sopenharmony_ci		    (max_cpos <= le32_to_cpu(rec->e_cpos)))
26978c2ecf20Sopenharmony_ci			break;
26988c2ecf20Sopenharmony_ci
26998c2ecf20Sopenharmony_ci		leaf_clusters = le16_to_cpu(rec->e_leaf_clusters);
27008c2ecf20Sopenharmony_ci		rec_end = le32_to_cpu(rec->e_cpos) + leaf_clusters;
27018c2ecf20Sopenharmony_ci		if (rec_end > max_cpos) {
27028c2ecf20Sopenharmony_ci			rec_end = max_cpos;
27038c2ecf20Sopenharmony_ci			leaf_clusters = rec_end - le32_to_cpu(rec->e_cpos);
27048c2ecf20Sopenharmony_ci		}
27058c2ecf20Sopenharmony_ci
27068c2ecf20Sopenharmony_ci		/*
27078c2ecf20Sopenharmony_ci		 * How many clusters do we actually need from
27088c2ecf20Sopenharmony_ci		 * this extent?  First we see how many we actually
27098c2ecf20Sopenharmony_ci		 * need to complete the write.  If that's smaller
27108c2ecf20Sopenharmony_ci		 * than contig_clusters, we try for contig_clusters.
27118c2ecf20Sopenharmony_ci		 */
27128c2ecf20Sopenharmony_ci		if (!*cow_len)
27138c2ecf20Sopenharmony_ci			want_clusters = write_len;
27148c2ecf20Sopenharmony_ci		else
27158c2ecf20Sopenharmony_ci			want_clusters = (cpos + write_len) -
27168c2ecf20Sopenharmony_ci				(*cow_start + *cow_len);
27178c2ecf20Sopenharmony_ci		if (want_clusters < contig_clusters)
27188c2ecf20Sopenharmony_ci			want_clusters = contig_clusters;
27198c2ecf20Sopenharmony_ci
27208c2ecf20Sopenharmony_ci		/*
27218c2ecf20Sopenharmony_ci		 * If the write does not cover the whole extent, we
27228c2ecf20Sopenharmony_ci		 * need to calculate how we're going to split the extent.
27238c2ecf20Sopenharmony_ci		 * We try to do it on contig_clusters boundaries.
27248c2ecf20Sopenharmony_ci		 *
27258c2ecf20Sopenharmony_ci		 * Any extent smaller than contig_clusters will be
27268c2ecf20Sopenharmony_ci		 * CoWed in its entirety.
27278c2ecf20Sopenharmony_ci		 */
27288c2ecf20Sopenharmony_ci		if (leaf_clusters <= contig_clusters)
27298c2ecf20Sopenharmony_ci			*cow_len += leaf_clusters;
27308c2ecf20Sopenharmony_ci		else if (*cow_len || (*cow_start == cpos)) {
27318c2ecf20Sopenharmony_ci			/*
27328c2ecf20Sopenharmony_ci			 * This extent needs to be CoW'd from its
27338c2ecf20Sopenharmony_ci			 * beginning, so all we have to do is compute
27348c2ecf20Sopenharmony_ci			 * how many clusters to grab.  We align
27358c2ecf20Sopenharmony_ci			 * want_clusters to the edge of contig_clusters
27368c2ecf20Sopenharmony_ci			 * to get better I/O.
27378c2ecf20Sopenharmony_ci			 */
27388c2ecf20Sopenharmony_ci			want_clusters = ocfs2_cow_align_length(inode->i_sb,
27398c2ecf20Sopenharmony_ci							       want_clusters);
27408c2ecf20Sopenharmony_ci
27418c2ecf20Sopenharmony_ci			if (leaf_clusters < want_clusters)
27428c2ecf20Sopenharmony_ci				*cow_len += leaf_clusters;
27438c2ecf20Sopenharmony_ci			else
27448c2ecf20Sopenharmony_ci				*cow_len += want_clusters;
27458c2ecf20Sopenharmony_ci		} else if ((*cow_start + contig_clusters) >=
27468c2ecf20Sopenharmony_ci			   (cpos + write_len)) {
27478c2ecf20Sopenharmony_ci			/*
27488c2ecf20Sopenharmony_ci			 * Breaking off contig_clusters at the front
27498c2ecf20Sopenharmony_ci			 * of the extent will cover our write.  That's
27508c2ecf20Sopenharmony_ci			 * easy.
27518c2ecf20Sopenharmony_ci			 */
27528c2ecf20Sopenharmony_ci			*cow_len = contig_clusters;
27538c2ecf20Sopenharmony_ci		} else if ((rec_end - cpos) <= contig_clusters) {
27548c2ecf20Sopenharmony_ci			/*
27558c2ecf20Sopenharmony_ci			 * Breaking off contig_clusters at the tail of
27568c2ecf20Sopenharmony_ci			 * this extent will cover cpos.
27578c2ecf20Sopenharmony_ci			 */
27588c2ecf20Sopenharmony_ci			*cow_start = rec_end - contig_clusters;
27598c2ecf20Sopenharmony_ci			*cow_len = contig_clusters;
27608c2ecf20Sopenharmony_ci		} else if ((rec_end - cpos) <= want_clusters) {
27618c2ecf20Sopenharmony_ci			/*
27628c2ecf20Sopenharmony_ci			 * While we can't fit the entire write in this
27638c2ecf20Sopenharmony_ci			 * extent, we know that the write goes from cpos
27648c2ecf20Sopenharmony_ci			 * to the end of the extent.  Break that off.
27658c2ecf20Sopenharmony_ci			 * We try to break it at some multiple of
27668c2ecf20Sopenharmony_ci			 * contig_clusters from the front of the extent.
27678c2ecf20Sopenharmony_ci			 * Failing that (ie, cpos is within
27688c2ecf20Sopenharmony_ci			 * contig_clusters of the front), we'll CoW the
27698c2ecf20Sopenharmony_ci			 * entire extent.
27708c2ecf20Sopenharmony_ci			 */
27718c2ecf20Sopenharmony_ci			*cow_start = ocfs2_cow_align_start(inode->i_sb,
27728c2ecf20Sopenharmony_ci							   *cow_start, cpos);
27738c2ecf20Sopenharmony_ci			*cow_len = rec_end - *cow_start;
27748c2ecf20Sopenharmony_ci		} else {
27758c2ecf20Sopenharmony_ci			/*
27768c2ecf20Sopenharmony_ci			 * Ok, the entire write lives in the middle of
27778c2ecf20Sopenharmony_ci			 * this extent.  Let's try to slice the extent up
27788c2ecf20Sopenharmony_ci			 * nicely.  Optimally, our CoW region starts at
27798c2ecf20Sopenharmony_ci			 * m*contig_clusters from the beginning of the
27808c2ecf20Sopenharmony_ci			 * extent and goes for n*contig_clusters,
27818c2ecf20Sopenharmony_ci			 * covering the entire write.
27828c2ecf20Sopenharmony_ci			 */
27838c2ecf20Sopenharmony_ci			*cow_start = ocfs2_cow_align_start(inode->i_sb,
27848c2ecf20Sopenharmony_ci							   *cow_start, cpos);
27858c2ecf20Sopenharmony_ci
27868c2ecf20Sopenharmony_ci			want_clusters = (cpos + write_len) - *cow_start;
27878c2ecf20Sopenharmony_ci			want_clusters = ocfs2_cow_align_length(inode->i_sb,
27888c2ecf20Sopenharmony_ci							       want_clusters);
27898c2ecf20Sopenharmony_ci			if (*cow_start + want_clusters <= rec_end)
27908c2ecf20Sopenharmony_ci				*cow_len = want_clusters;
27918c2ecf20Sopenharmony_ci			else
27928c2ecf20Sopenharmony_ci				*cow_len = rec_end - *cow_start;
27938c2ecf20Sopenharmony_ci		}
27948c2ecf20Sopenharmony_ci
27958c2ecf20Sopenharmony_ci		/* Have we covered our entire write yet? */
27968c2ecf20Sopenharmony_ci		if ((*cow_start + *cow_len) >= (cpos + write_len))
27978c2ecf20Sopenharmony_ci			break;
27988c2ecf20Sopenharmony_ci
27998c2ecf20Sopenharmony_ci		/*
28008c2ecf20Sopenharmony_ci		 * If we reach the end of the extent block and don't get enough
28018c2ecf20Sopenharmony_ci		 * clusters, continue with the next extent block if possible.
28028c2ecf20Sopenharmony_ci		 */
28038c2ecf20Sopenharmony_ci		if (i + 1 == le16_to_cpu(el->l_next_free_rec) &&
28048c2ecf20Sopenharmony_ci		    eb && eb->h_next_leaf_blk) {
28058c2ecf20Sopenharmony_ci			brelse(eb_bh);
28068c2ecf20Sopenharmony_ci			eb_bh = NULL;
28078c2ecf20Sopenharmony_ci
28088c2ecf20Sopenharmony_ci			ret = ocfs2_read_extent_block(INODE_CACHE(inode),
28098c2ecf20Sopenharmony_ci					       le64_to_cpu(eb->h_next_leaf_blk),
28108c2ecf20Sopenharmony_ci					       &eb_bh);
28118c2ecf20Sopenharmony_ci			if (ret) {
28128c2ecf20Sopenharmony_ci				mlog_errno(ret);
28138c2ecf20Sopenharmony_ci				goto out;
28148c2ecf20Sopenharmony_ci			}
28158c2ecf20Sopenharmony_ci
28168c2ecf20Sopenharmony_ci			eb = (struct ocfs2_extent_block *) eb_bh->b_data;
28178c2ecf20Sopenharmony_ci			el = &eb->h_list;
28188c2ecf20Sopenharmony_ci			i = -1;
28198c2ecf20Sopenharmony_ci		}
28208c2ecf20Sopenharmony_ci	}
28218c2ecf20Sopenharmony_ci
28228c2ecf20Sopenharmony_ciout:
28238c2ecf20Sopenharmony_ci	brelse(eb_bh);
28248c2ecf20Sopenharmony_ci	return ret;
28258c2ecf20Sopenharmony_ci}
28268c2ecf20Sopenharmony_ci
28278c2ecf20Sopenharmony_ci/*
28288c2ecf20Sopenharmony_ci * Prepare meta_ac, data_ac and calculate credits when we want to add some
28298c2ecf20Sopenharmony_ci * num_clusters in data_tree "et" and change the refcount for the old
28308c2ecf20Sopenharmony_ci * clusters(starting form p_cluster) in the refcount tree.
28318c2ecf20Sopenharmony_ci *
28328c2ecf20Sopenharmony_ci * Note:
28338c2ecf20Sopenharmony_ci * 1. since we may split the old tree, so we at most will need num_clusters + 2
28348c2ecf20Sopenharmony_ci *    more new leaf records.
28358c2ecf20Sopenharmony_ci * 2. In some case, we may not need to reserve new clusters(e.g, reflink), so
28368c2ecf20Sopenharmony_ci *    just give data_ac = NULL.
28378c2ecf20Sopenharmony_ci */
28388c2ecf20Sopenharmony_cistatic int ocfs2_lock_refcount_allocators(struct super_block *sb,
28398c2ecf20Sopenharmony_ci					u32 p_cluster, u32 num_clusters,
28408c2ecf20Sopenharmony_ci					struct ocfs2_extent_tree *et,
28418c2ecf20Sopenharmony_ci					struct ocfs2_caching_info *ref_ci,
28428c2ecf20Sopenharmony_ci					struct buffer_head *ref_root_bh,
28438c2ecf20Sopenharmony_ci					struct ocfs2_alloc_context **meta_ac,
28448c2ecf20Sopenharmony_ci					struct ocfs2_alloc_context **data_ac,
28458c2ecf20Sopenharmony_ci					int *credits)
28468c2ecf20Sopenharmony_ci{
28478c2ecf20Sopenharmony_ci	int ret = 0, meta_add = 0;
28488c2ecf20Sopenharmony_ci	int num_free_extents = ocfs2_num_free_extents(et);
28498c2ecf20Sopenharmony_ci
28508c2ecf20Sopenharmony_ci	if (num_free_extents < 0) {
28518c2ecf20Sopenharmony_ci		ret = num_free_extents;
28528c2ecf20Sopenharmony_ci		mlog_errno(ret);
28538c2ecf20Sopenharmony_ci		goto out;
28548c2ecf20Sopenharmony_ci	}
28558c2ecf20Sopenharmony_ci
28568c2ecf20Sopenharmony_ci	if (num_free_extents < num_clusters + 2)
28578c2ecf20Sopenharmony_ci		meta_add =
28588c2ecf20Sopenharmony_ci			ocfs2_extend_meta_needed(et->et_root_el);
28598c2ecf20Sopenharmony_ci
28608c2ecf20Sopenharmony_ci	*credits += ocfs2_calc_extend_credits(sb, et->et_root_el);
28618c2ecf20Sopenharmony_ci
28628c2ecf20Sopenharmony_ci	ret = ocfs2_calc_refcount_meta_credits(sb, ref_ci, ref_root_bh,
28638c2ecf20Sopenharmony_ci					       p_cluster, num_clusters,
28648c2ecf20Sopenharmony_ci					       &meta_add, credits);
28658c2ecf20Sopenharmony_ci	if (ret) {
28668c2ecf20Sopenharmony_ci		mlog_errno(ret);
28678c2ecf20Sopenharmony_ci		goto out;
28688c2ecf20Sopenharmony_ci	}
28698c2ecf20Sopenharmony_ci
28708c2ecf20Sopenharmony_ci	trace_ocfs2_lock_refcount_allocators(meta_add, *credits);
28718c2ecf20Sopenharmony_ci	ret = ocfs2_reserve_new_metadata_blocks(OCFS2_SB(sb), meta_add,
28728c2ecf20Sopenharmony_ci						meta_ac);
28738c2ecf20Sopenharmony_ci	if (ret) {
28748c2ecf20Sopenharmony_ci		mlog_errno(ret);
28758c2ecf20Sopenharmony_ci		goto out;
28768c2ecf20Sopenharmony_ci	}
28778c2ecf20Sopenharmony_ci
28788c2ecf20Sopenharmony_ci	if (data_ac) {
28798c2ecf20Sopenharmony_ci		ret = ocfs2_reserve_clusters(OCFS2_SB(sb), num_clusters,
28808c2ecf20Sopenharmony_ci					     data_ac);
28818c2ecf20Sopenharmony_ci		if (ret)
28828c2ecf20Sopenharmony_ci			mlog_errno(ret);
28838c2ecf20Sopenharmony_ci	}
28848c2ecf20Sopenharmony_ci
28858c2ecf20Sopenharmony_ciout:
28868c2ecf20Sopenharmony_ci	if (ret) {
28878c2ecf20Sopenharmony_ci		if (*meta_ac) {
28888c2ecf20Sopenharmony_ci			ocfs2_free_alloc_context(*meta_ac);
28898c2ecf20Sopenharmony_ci			*meta_ac = NULL;
28908c2ecf20Sopenharmony_ci		}
28918c2ecf20Sopenharmony_ci	}
28928c2ecf20Sopenharmony_ci
28938c2ecf20Sopenharmony_ci	return ret;
28948c2ecf20Sopenharmony_ci}
28958c2ecf20Sopenharmony_ci
28968c2ecf20Sopenharmony_cistatic int ocfs2_clear_cow_buffer(handle_t *handle, struct buffer_head *bh)
28978c2ecf20Sopenharmony_ci{
28988c2ecf20Sopenharmony_ci	BUG_ON(buffer_dirty(bh));
28998c2ecf20Sopenharmony_ci
29008c2ecf20Sopenharmony_ci	clear_buffer_mapped(bh);
29018c2ecf20Sopenharmony_ci
29028c2ecf20Sopenharmony_ci	return 0;
29038c2ecf20Sopenharmony_ci}
29048c2ecf20Sopenharmony_ci
29058c2ecf20Sopenharmony_ciint ocfs2_duplicate_clusters_by_page(handle_t *handle,
29068c2ecf20Sopenharmony_ci				     struct inode *inode,
29078c2ecf20Sopenharmony_ci				     u32 cpos, u32 old_cluster,
29088c2ecf20Sopenharmony_ci				     u32 new_cluster, u32 new_len)
29098c2ecf20Sopenharmony_ci{
29108c2ecf20Sopenharmony_ci	int ret = 0, partial;
29118c2ecf20Sopenharmony_ci	struct super_block *sb = inode->i_sb;
29128c2ecf20Sopenharmony_ci	u64 new_block = ocfs2_clusters_to_blocks(sb, new_cluster);
29138c2ecf20Sopenharmony_ci	struct page *page;
29148c2ecf20Sopenharmony_ci	pgoff_t page_index;
29158c2ecf20Sopenharmony_ci	unsigned int from, to;
29168c2ecf20Sopenharmony_ci	loff_t offset, end, map_end;
29178c2ecf20Sopenharmony_ci	struct address_space *mapping = inode->i_mapping;
29188c2ecf20Sopenharmony_ci
29198c2ecf20Sopenharmony_ci	trace_ocfs2_duplicate_clusters_by_page(cpos, old_cluster,
29208c2ecf20Sopenharmony_ci					       new_cluster, new_len);
29218c2ecf20Sopenharmony_ci
29228c2ecf20Sopenharmony_ci	offset = ((loff_t)cpos) << OCFS2_SB(sb)->s_clustersize_bits;
29238c2ecf20Sopenharmony_ci	end = offset + (new_len << OCFS2_SB(sb)->s_clustersize_bits);
29248c2ecf20Sopenharmony_ci	/*
29258c2ecf20Sopenharmony_ci	 * We only duplicate pages until we reach the page contains i_size - 1.
29268c2ecf20Sopenharmony_ci	 * So trim 'end' to i_size.
29278c2ecf20Sopenharmony_ci	 */
29288c2ecf20Sopenharmony_ci	if (end > i_size_read(inode))
29298c2ecf20Sopenharmony_ci		end = i_size_read(inode);
29308c2ecf20Sopenharmony_ci
29318c2ecf20Sopenharmony_ci	while (offset < end) {
29328c2ecf20Sopenharmony_ci		page_index = offset >> PAGE_SHIFT;
29338c2ecf20Sopenharmony_ci		map_end = ((loff_t)page_index + 1) << PAGE_SHIFT;
29348c2ecf20Sopenharmony_ci		if (map_end > end)
29358c2ecf20Sopenharmony_ci			map_end = end;
29368c2ecf20Sopenharmony_ci
29378c2ecf20Sopenharmony_ci		/* from, to is the offset within the page. */
29388c2ecf20Sopenharmony_ci		from = offset & (PAGE_SIZE - 1);
29398c2ecf20Sopenharmony_ci		to = PAGE_SIZE;
29408c2ecf20Sopenharmony_ci		if (map_end & (PAGE_SIZE - 1))
29418c2ecf20Sopenharmony_ci			to = map_end & (PAGE_SIZE - 1);
29428c2ecf20Sopenharmony_ci
29438c2ecf20Sopenharmony_ciretry:
29448c2ecf20Sopenharmony_ci		page = find_or_create_page(mapping, page_index, GFP_NOFS);
29458c2ecf20Sopenharmony_ci		if (!page) {
29468c2ecf20Sopenharmony_ci			ret = -ENOMEM;
29478c2ecf20Sopenharmony_ci			mlog_errno(ret);
29488c2ecf20Sopenharmony_ci			break;
29498c2ecf20Sopenharmony_ci		}
29508c2ecf20Sopenharmony_ci
29518c2ecf20Sopenharmony_ci		/*
29528c2ecf20Sopenharmony_ci		 * In case PAGE_SIZE <= CLUSTER_SIZE, we do not expect a dirty
29538c2ecf20Sopenharmony_ci		 * page, so write it back.
29548c2ecf20Sopenharmony_ci		 */
29558c2ecf20Sopenharmony_ci		if (PAGE_SIZE <= OCFS2_SB(sb)->s_clustersize) {
29568c2ecf20Sopenharmony_ci			if (PageDirty(page)) {
29578c2ecf20Sopenharmony_ci				/*
29588c2ecf20Sopenharmony_ci				 * write_on_page will unlock the page on return
29598c2ecf20Sopenharmony_ci				 */
29608c2ecf20Sopenharmony_ci				ret = write_one_page(page);
29618c2ecf20Sopenharmony_ci				goto retry;
29628c2ecf20Sopenharmony_ci			}
29638c2ecf20Sopenharmony_ci		}
29648c2ecf20Sopenharmony_ci
29658c2ecf20Sopenharmony_ci		if (!PageUptodate(page)) {
29668c2ecf20Sopenharmony_ci			ret = block_read_full_page(page, ocfs2_get_block);
29678c2ecf20Sopenharmony_ci			if (ret) {
29688c2ecf20Sopenharmony_ci				mlog_errno(ret);
29698c2ecf20Sopenharmony_ci				goto unlock;
29708c2ecf20Sopenharmony_ci			}
29718c2ecf20Sopenharmony_ci			lock_page(page);
29728c2ecf20Sopenharmony_ci		}
29738c2ecf20Sopenharmony_ci
29748c2ecf20Sopenharmony_ci		if (page_has_buffers(page)) {
29758c2ecf20Sopenharmony_ci			ret = walk_page_buffers(handle, page_buffers(page),
29768c2ecf20Sopenharmony_ci						from, to, &partial,
29778c2ecf20Sopenharmony_ci						ocfs2_clear_cow_buffer);
29788c2ecf20Sopenharmony_ci			if (ret) {
29798c2ecf20Sopenharmony_ci				mlog_errno(ret);
29808c2ecf20Sopenharmony_ci				goto unlock;
29818c2ecf20Sopenharmony_ci			}
29828c2ecf20Sopenharmony_ci		}
29838c2ecf20Sopenharmony_ci
29848c2ecf20Sopenharmony_ci		ocfs2_map_and_dirty_page(inode,
29858c2ecf20Sopenharmony_ci					 handle, from, to,
29868c2ecf20Sopenharmony_ci					 page, 0, &new_block);
29878c2ecf20Sopenharmony_ci		mark_page_accessed(page);
29888c2ecf20Sopenharmony_ciunlock:
29898c2ecf20Sopenharmony_ci		unlock_page(page);
29908c2ecf20Sopenharmony_ci		put_page(page);
29918c2ecf20Sopenharmony_ci		page = NULL;
29928c2ecf20Sopenharmony_ci		offset = map_end;
29938c2ecf20Sopenharmony_ci		if (ret)
29948c2ecf20Sopenharmony_ci			break;
29958c2ecf20Sopenharmony_ci	}
29968c2ecf20Sopenharmony_ci
29978c2ecf20Sopenharmony_ci	return ret;
29988c2ecf20Sopenharmony_ci}
29998c2ecf20Sopenharmony_ci
30008c2ecf20Sopenharmony_ciint ocfs2_duplicate_clusters_by_jbd(handle_t *handle,
30018c2ecf20Sopenharmony_ci				    struct inode *inode,
30028c2ecf20Sopenharmony_ci				    u32 cpos, u32 old_cluster,
30038c2ecf20Sopenharmony_ci				    u32 new_cluster, u32 new_len)
30048c2ecf20Sopenharmony_ci{
30058c2ecf20Sopenharmony_ci	int ret = 0;
30068c2ecf20Sopenharmony_ci	struct super_block *sb = inode->i_sb;
30078c2ecf20Sopenharmony_ci	struct ocfs2_caching_info *ci = INODE_CACHE(inode);
30088c2ecf20Sopenharmony_ci	int i, blocks = ocfs2_clusters_to_blocks(sb, new_len);
30098c2ecf20Sopenharmony_ci	u64 old_block = ocfs2_clusters_to_blocks(sb, old_cluster);
30108c2ecf20Sopenharmony_ci	u64 new_block = ocfs2_clusters_to_blocks(sb, new_cluster);
30118c2ecf20Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(sb);
30128c2ecf20Sopenharmony_ci	struct buffer_head *old_bh = NULL;
30138c2ecf20Sopenharmony_ci	struct buffer_head *new_bh = NULL;
30148c2ecf20Sopenharmony_ci
30158c2ecf20Sopenharmony_ci	trace_ocfs2_duplicate_clusters_by_page(cpos, old_cluster,
30168c2ecf20Sopenharmony_ci					       new_cluster, new_len);
30178c2ecf20Sopenharmony_ci
30188c2ecf20Sopenharmony_ci	for (i = 0; i < blocks; i++, old_block++, new_block++) {
30198c2ecf20Sopenharmony_ci		new_bh = sb_getblk(osb->sb, new_block);
30208c2ecf20Sopenharmony_ci		if (new_bh == NULL) {
30218c2ecf20Sopenharmony_ci			ret = -ENOMEM;
30228c2ecf20Sopenharmony_ci			mlog_errno(ret);
30238c2ecf20Sopenharmony_ci			break;
30248c2ecf20Sopenharmony_ci		}
30258c2ecf20Sopenharmony_ci
30268c2ecf20Sopenharmony_ci		ocfs2_set_new_buffer_uptodate(ci, new_bh);
30278c2ecf20Sopenharmony_ci
30288c2ecf20Sopenharmony_ci		ret = ocfs2_read_block(ci, old_block, &old_bh, NULL);
30298c2ecf20Sopenharmony_ci		if (ret) {
30308c2ecf20Sopenharmony_ci			mlog_errno(ret);
30318c2ecf20Sopenharmony_ci			break;
30328c2ecf20Sopenharmony_ci		}
30338c2ecf20Sopenharmony_ci
30348c2ecf20Sopenharmony_ci		ret = ocfs2_journal_access(handle, ci, new_bh,
30358c2ecf20Sopenharmony_ci					   OCFS2_JOURNAL_ACCESS_CREATE);
30368c2ecf20Sopenharmony_ci		if (ret) {
30378c2ecf20Sopenharmony_ci			mlog_errno(ret);
30388c2ecf20Sopenharmony_ci			break;
30398c2ecf20Sopenharmony_ci		}
30408c2ecf20Sopenharmony_ci
30418c2ecf20Sopenharmony_ci		memcpy(new_bh->b_data, old_bh->b_data, sb->s_blocksize);
30428c2ecf20Sopenharmony_ci		ocfs2_journal_dirty(handle, new_bh);
30438c2ecf20Sopenharmony_ci
30448c2ecf20Sopenharmony_ci		brelse(new_bh);
30458c2ecf20Sopenharmony_ci		brelse(old_bh);
30468c2ecf20Sopenharmony_ci		new_bh = NULL;
30478c2ecf20Sopenharmony_ci		old_bh = NULL;
30488c2ecf20Sopenharmony_ci	}
30498c2ecf20Sopenharmony_ci
30508c2ecf20Sopenharmony_ci	brelse(new_bh);
30518c2ecf20Sopenharmony_ci	brelse(old_bh);
30528c2ecf20Sopenharmony_ci	return ret;
30538c2ecf20Sopenharmony_ci}
30548c2ecf20Sopenharmony_ci
30558c2ecf20Sopenharmony_cistatic int ocfs2_clear_ext_refcount(handle_t *handle,
30568c2ecf20Sopenharmony_ci				    struct ocfs2_extent_tree *et,
30578c2ecf20Sopenharmony_ci				    u32 cpos, u32 p_cluster, u32 len,
30588c2ecf20Sopenharmony_ci				    unsigned int ext_flags,
30598c2ecf20Sopenharmony_ci				    struct ocfs2_alloc_context *meta_ac,
30608c2ecf20Sopenharmony_ci				    struct ocfs2_cached_dealloc_ctxt *dealloc)
30618c2ecf20Sopenharmony_ci{
30628c2ecf20Sopenharmony_ci	int ret, index;
30638c2ecf20Sopenharmony_ci	struct ocfs2_extent_rec replace_rec;
30648c2ecf20Sopenharmony_ci	struct ocfs2_path *path = NULL;
30658c2ecf20Sopenharmony_ci	struct ocfs2_extent_list *el;
30668c2ecf20Sopenharmony_ci	struct super_block *sb = ocfs2_metadata_cache_get_super(et->et_ci);
30678c2ecf20Sopenharmony_ci	u64 ino = ocfs2_metadata_cache_owner(et->et_ci);
30688c2ecf20Sopenharmony_ci
30698c2ecf20Sopenharmony_ci	trace_ocfs2_clear_ext_refcount((unsigned long long)ino,
30708c2ecf20Sopenharmony_ci				       cpos, len, p_cluster, ext_flags);
30718c2ecf20Sopenharmony_ci
30728c2ecf20Sopenharmony_ci	memset(&replace_rec, 0, sizeof(replace_rec));
30738c2ecf20Sopenharmony_ci	replace_rec.e_cpos = cpu_to_le32(cpos);
30748c2ecf20Sopenharmony_ci	replace_rec.e_leaf_clusters = cpu_to_le16(len);
30758c2ecf20Sopenharmony_ci	replace_rec.e_blkno = cpu_to_le64(ocfs2_clusters_to_blocks(sb,
30768c2ecf20Sopenharmony_ci								   p_cluster));
30778c2ecf20Sopenharmony_ci	replace_rec.e_flags = ext_flags;
30788c2ecf20Sopenharmony_ci	replace_rec.e_flags &= ~OCFS2_EXT_REFCOUNTED;
30798c2ecf20Sopenharmony_ci
30808c2ecf20Sopenharmony_ci	path = ocfs2_new_path_from_et(et);
30818c2ecf20Sopenharmony_ci	if (!path) {
30828c2ecf20Sopenharmony_ci		ret = -ENOMEM;
30838c2ecf20Sopenharmony_ci		mlog_errno(ret);
30848c2ecf20Sopenharmony_ci		goto out;
30858c2ecf20Sopenharmony_ci	}
30868c2ecf20Sopenharmony_ci
30878c2ecf20Sopenharmony_ci	ret = ocfs2_find_path(et->et_ci, path, cpos);
30888c2ecf20Sopenharmony_ci	if (ret) {
30898c2ecf20Sopenharmony_ci		mlog_errno(ret);
30908c2ecf20Sopenharmony_ci		goto out;
30918c2ecf20Sopenharmony_ci	}
30928c2ecf20Sopenharmony_ci
30938c2ecf20Sopenharmony_ci	el = path_leaf_el(path);
30948c2ecf20Sopenharmony_ci
30958c2ecf20Sopenharmony_ci	index = ocfs2_search_extent_list(el, cpos);
30968c2ecf20Sopenharmony_ci	if (index == -1) {
30978c2ecf20Sopenharmony_ci		ret = ocfs2_error(sb,
30988c2ecf20Sopenharmony_ci				  "Inode %llu has an extent at cpos %u which can no longer be found\n",
30998c2ecf20Sopenharmony_ci				  (unsigned long long)ino, cpos);
31008c2ecf20Sopenharmony_ci		goto out;
31018c2ecf20Sopenharmony_ci	}
31028c2ecf20Sopenharmony_ci
31038c2ecf20Sopenharmony_ci	ret = ocfs2_split_extent(handle, et, path, index,
31048c2ecf20Sopenharmony_ci				 &replace_rec, meta_ac, dealloc);
31058c2ecf20Sopenharmony_ci	if (ret)
31068c2ecf20Sopenharmony_ci		mlog_errno(ret);
31078c2ecf20Sopenharmony_ci
31088c2ecf20Sopenharmony_ciout:
31098c2ecf20Sopenharmony_ci	ocfs2_free_path(path);
31108c2ecf20Sopenharmony_ci	return ret;
31118c2ecf20Sopenharmony_ci}
31128c2ecf20Sopenharmony_ci
31138c2ecf20Sopenharmony_cistatic int ocfs2_replace_clusters(handle_t *handle,
31148c2ecf20Sopenharmony_ci				  struct ocfs2_cow_context *context,
31158c2ecf20Sopenharmony_ci				  u32 cpos, u32 old,
31168c2ecf20Sopenharmony_ci				  u32 new, u32 len,
31178c2ecf20Sopenharmony_ci				  unsigned int ext_flags)
31188c2ecf20Sopenharmony_ci{
31198c2ecf20Sopenharmony_ci	int ret;
31208c2ecf20Sopenharmony_ci	struct ocfs2_caching_info *ci = context->data_et.et_ci;
31218c2ecf20Sopenharmony_ci	u64 ino = ocfs2_metadata_cache_owner(ci);
31228c2ecf20Sopenharmony_ci
31238c2ecf20Sopenharmony_ci	trace_ocfs2_replace_clusters((unsigned long long)ino,
31248c2ecf20Sopenharmony_ci				     cpos, old, new, len, ext_flags);
31258c2ecf20Sopenharmony_ci
31268c2ecf20Sopenharmony_ci	/*If the old clusters is unwritten, no need to duplicate. */
31278c2ecf20Sopenharmony_ci	if (!(ext_flags & OCFS2_EXT_UNWRITTEN)) {
31288c2ecf20Sopenharmony_ci		ret = context->cow_duplicate_clusters(handle, context->inode,
31298c2ecf20Sopenharmony_ci						      cpos, old, new, len);
31308c2ecf20Sopenharmony_ci		if (ret) {
31318c2ecf20Sopenharmony_ci			mlog_errno(ret);
31328c2ecf20Sopenharmony_ci			goto out;
31338c2ecf20Sopenharmony_ci		}
31348c2ecf20Sopenharmony_ci	}
31358c2ecf20Sopenharmony_ci
31368c2ecf20Sopenharmony_ci	ret = ocfs2_clear_ext_refcount(handle, &context->data_et,
31378c2ecf20Sopenharmony_ci				       cpos, new, len, ext_flags,
31388c2ecf20Sopenharmony_ci				       context->meta_ac, &context->dealloc);
31398c2ecf20Sopenharmony_ci	if (ret)
31408c2ecf20Sopenharmony_ci		mlog_errno(ret);
31418c2ecf20Sopenharmony_ciout:
31428c2ecf20Sopenharmony_ci	return ret;
31438c2ecf20Sopenharmony_ci}
31448c2ecf20Sopenharmony_ci
31458c2ecf20Sopenharmony_ciint ocfs2_cow_sync_writeback(struct super_block *sb,
31468c2ecf20Sopenharmony_ci			     struct inode *inode,
31478c2ecf20Sopenharmony_ci			     u32 cpos, u32 num_clusters)
31488c2ecf20Sopenharmony_ci{
31498c2ecf20Sopenharmony_ci	int ret = 0;
31508c2ecf20Sopenharmony_ci	loff_t offset, end, map_end;
31518c2ecf20Sopenharmony_ci	pgoff_t page_index;
31528c2ecf20Sopenharmony_ci	struct page *page;
31538c2ecf20Sopenharmony_ci
31548c2ecf20Sopenharmony_ci	if (ocfs2_should_order_data(inode))
31558c2ecf20Sopenharmony_ci		return 0;
31568c2ecf20Sopenharmony_ci
31578c2ecf20Sopenharmony_ci	offset = ((loff_t)cpos) << OCFS2_SB(sb)->s_clustersize_bits;
31588c2ecf20Sopenharmony_ci	end = offset + (num_clusters << OCFS2_SB(sb)->s_clustersize_bits);
31598c2ecf20Sopenharmony_ci
31608c2ecf20Sopenharmony_ci	ret = filemap_fdatawrite_range(inode->i_mapping,
31618c2ecf20Sopenharmony_ci				       offset, end - 1);
31628c2ecf20Sopenharmony_ci	if (ret < 0) {
31638c2ecf20Sopenharmony_ci		mlog_errno(ret);
31648c2ecf20Sopenharmony_ci		return ret;
31658c2ecf20Sopenharmony_ci	}
31668c2ecf20Sopenharmony_ci
31678c2ecf20Sopenharmony_ci	while (offset < end) {
31688c2ecf20Sopenharmony_ci		page_index = offset >> PAGE_SHIFT;
31698c2ecf20Sopenharmony_ci		map_end = ((loff_t)page_index + 1) << PAGE_SHIFT;
31708c2ecf20Sopenharmony_ci		if (map_end > end)
31718c2ecf20Sopenharmony_ci			map_end = end;
31728c2ecf20Sopenharmony_ci
31738c2ecf20Sopenharmony_ci		page = find_or_create_page(inode->i_mapping,
31748c2ecf20Sopenharmony_ci					   page_index, GFP_NOFS);
31758c2ecf20Sopenharmony_ci		BUG_ON(!page);
31768c2ecf20Sopenharmony_ci
31778c2ecf20Sopenharmony_ci		wait_on_page_writeback(page);
31788c2ecf20Sopenharmony_ci		if (PageError(page)) {
31798c2ecf20Sopenharmony_ci			ret = -EIO;
31808c2ecf20Sopenharmony_ci			mlog_errno(ret);
31818c2ecf20Sopenharmony_ci		} else
31828c2ecf20Sopenharmony_ci			mark_page_accessed(page);
31838c2ecf20Sopenharmony_ci
31848c2ecf20Sopenharmony_ci		unlock_page(page);
31858c2ecf20Sopenharmony_ci		put_page(page);
31868c2ecf20Sopenharmony_ci		page = NULL;
31878c2ecf20Sopenharmony_ci		offset = map_end;
31888c2ecf20Sopenharmony_ci		if (ret)
31898c2ecf20Sopenharmony_ci			break;
31908c2ecf20Sopenharmony_ci	}
31918c2ecf20Sopenharmony_ci
31928c2ecf20Sopenharmony_ci	return ret;
31938c2ecf20Sopenharmony_ci}
31948c2ecf20Sopenharmony_ci
31958c2ecf20Sopenharmony_cistatic int ocfs2_di_get_clusters(struct ocfs2_cow_context *context,
31968c2ecf20Sopenharmony_ci				 u32 v_cluster, u32 *p_cluster,
31978c2ecf20Sopenharmony_ci				 u32 *num_clusters,
31988c2ecf20Sopenharmony_ci				 unsigned int *extent_flags)
31998c2ecf20Sopenharmony_ci{
32008c2ecf20Sopenharmony_ci	return ocfs2_get_clusters(context->inode, v_cluster, p_cluster,
32018c2ecf20Sopenharmony_ci				  num_clusters, extent_flags);
32028c2ecf20Sopenharmony_ci}
32038c2ecf20Sopenharmony_ci
32048c2ecf20Sopenharmony_cistatic int ocfs2_make_clusters_writable(struct super_block *sb,
32058c2ecf20Sopenharmony_ci					struct ocfs2_cow_context *context,
32068c2ecf20Sopenharmony_ci					u32 cpos, u32 p_cluster,
32078c2ecf20Sopenharmony_ci					u32 num_clusters, unsigned int e_flags)
32088c2ecf20Sopenharmony_ci{
32098c2ecf20Sopenharmony_ci	int ret, delete, index, credits =  0;
32108c2ecf20Sopenharmony_ci	u32 new_bit, new_len, orig_num_clusters;
32118c2ecf20Sopenharmony_ci	unsigned int set_len;
32128c2ecf20Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(sb);
32138c2ecf20Sopenharmony_ci	handle_t *handle;
32148c2ecf20Sopenharmony_ci	struct buffer_head *ref_leaf_bh = NULL;
32158c2ecf20Sopenharmony_ci	struct ocfs2_caching_info *ref_ci = &context->ref_tree->rf_ci;
32168c2ecf20Sopenharmony_ci	struct ocfs2_refcount_rec rec;
32178c2ecf20Sopenharmony_ci
32188c2ecf20Sopenharmony_ci	trace_ocfs2_make_clusters_writable(cpos, p_cluster,
32198c2ecf20Sopenharmony_ci					   num_clusters, e_flags);
32208c2ecf20Sopenharmony_ci
32218c2ecf20Sopenharmony_ci	ret = ocfs2_lock_refcount_allocators(sb, p_cluster, num_clusters,
32228c2ecf20Sopenharmony_ci					     &context->data_et,
32238c2ecf20Sopenharmony_ci					     ref_ci,
32248c2ecf20Sopenharmony_ci					     context->ref_root_bh,
32258c2ecf20Sopenharmony_ci					     &context->meta_ac,
32268c2ecf20Sopenharmony_ci					     &context->data_ac, &credits);
32278c2ecf20Sopenharmony_ci	if (ret) {
32288c2ecf20Sopenharmony_ci		mlog_errno(ret);
32298c2ecf20Sopenharmony_ci		return ret;
32308c2ecf20Sopenharmony_ci	}
32318c2ecf20Sopenharmony_ci
32328c2ecf20Sopenharmony_ci	if (context->post_refcount)
32338c2ecf20Sopenharmony_ci		credits += context->post_refcount->credits;
32348c2ecf20Sopenharmony_ci
32358c2ecf20Sopenharmony_ci	credits += context->extra_credits;
32368c2ecf20Sopenharmony_ci	handle = ocfs2_start_trans(osb, credits);
32378c2ecf20Sopenharmony_ci	if (IS_ERR(handle)) {
32388c2ecf20Sopenharmony_ci		ret = PTR_ERR(handle);
32398c2ecf20Sopenharmony_ci		mlog_errno(ret);
32408c2ecf20Sopenharmony_ci		goto out;
32418c2ecf20Sopenharmony_ci	}
32428c2ecf20Sopenharmony_ci
32438c2ecf20Sopenharmony_ci	orig_num_clusters = num_clusters;
32448c2ecf20Sopenharmony_ci
32458c2ecf20Sopenharmony_ci	while (num_clusters) {
32468c2ecf20Sopenharmony_ci		ret = ocfs2_get_refcount_rec(ref_ci, context->ref_root_bh,
32478c2ecf20Sopenharmony_ci					     p_cluster, num_clusters,
32488c2ecf20Sopenharmony_ci					     &rec, &index, &ref_leaf_bh);
32498c2ecf20Sopenharmony_ci		if (ret) {
32508c2ecf20Sopenharmony_ci			mlog_errno(ret);
32518c2ecf20Sopenharmony_ci			goto out_commit;
32528c2ecf20Sopenharmony_ci		}
32538c2ecf20Sopenharmony_ci
32548c2ecf20Sopenharmony_ci		BUG_ON(!rec.r_refcount);
32558c2ecf20Sopenharmony_ci		set_len = min((u64)p_cluster + num_clusters,
32568c2ecf20Sopenharmony_ci			      le64_to_cpu(rec.r_cpos) +
32578c2ecf20Sopenharmony_ci			      le32_to_cpu(rec.r_clusters)) - p_cluster;
32588c2ecf20Sopenharmony_ci
32598c2ecf20Sopenharmony_ci		/*
32608c2ecf20Sopenharmony_ci		 * There are many different situation here.
32618c2ecf20Sopenharmony_ci		 * 1. If refcount == 1, remove the flag and don't COW.
32628c2ecf20Sopenharmony_ci		 * 2. If refcount > 1, allocate clusters.
32638c2ecf20Sopenharmony_ci		 *    Here we may not allocate r_len once at a time, so continue
32648c2ecf20Sopenharmony_ci		 *    until we reach num_clusters.
32658c2ecf20Sopenharmony_ci		 */
32668c2ecf20Sopenharmony_ci		if (le32_to_cpu(rec.r_refcount) == 1) {
32678c2ecf20Sopenharmony_ci			delete = 0;
32688c2ecf20Sopenharmony_ci			ret = ocfs2_clear_ext_refcount(handle,
32698c2ecf20Sopenharmony_ci						       &context->data_et,
32708c2ecf20Sopenharmony_ci						       cpos, p_cluster,
32718c2ecf20Sopenharmony_ci						       set_len, e_flags,
32728c2ecf20Sopenharmony_ci						       context->meta_ac,
32738c2ecf20Sopenharmony_ci						       &context->dealloc);
32748c2ecf20Sopenharmony_ci			if (ret) {
32758c2ecf20Sopenharmony_ci				mlog_errno(ret);
32768c2ecf20Sopenharmony_ci				goto out_commit;
32778c2ecf20Sopenharmony_ci			}
32788c2ecf20Sopenharmony_ci		} else {
32798c2ecf20Sopenharmony_ci			delete = 1;
32808c2ecf20Sopenharmony_ci
32818c2ecf20Sopenharmony_ci			ret = __ocfs2_claim_clusters(handle,
32828c2ecf20Sopenharmony_ci						     context->data_ac,
32838c2ecf20Sopenharmony_ci						     1, set_len,
32848c2ecf20Sopenharmony_ci						     &new_bit, &new_len);
32858c2ecf20Sopenharmony_ci			if (ret) {
32868c2ecf20Sopenharmony_ci				mlog_errno(ret);
32878c2ecf20Sopenharmony_ci				goto out_commit;
32888c2ecf20Sopenharmony_ci			}
32898c2ecf20Sopenharmony_ci
32908c2ecf20Sopenharmony_ci			ret = ocfs2_replace_clusters(handle, context,
32918c2ecf20Sopenharmony_ci						     cpos, p_cluster, new_bit,
32928c2ecf20Sopenharmony_ci						     new_len, e_flags);
32938c2ecf20Sopenharmony_ci			if (ret) {
32948c2ecf20Sopenharmony_ci				mlog_errno(ret);
32958c2ecf20Sopenharmony_ci				goto out_commit;
32968c2ecf20Sopenharmony_ci			}
32978c2ecf20Sopenharmony_ci			set_len = new_len;
32988c2ecf20Sopenharmony_ci		}
32998c2ecf20Sopenharmony_ci
33008c2ecf20Sopenharmony_ci		ret = __ocfs2_decrease_refcount(handle, ref_ci,
33018c2ecf20Sopenharmony_ci						context->ref_root_bh,
33028c2ecf20Sopenharmony_ci						p_cluster, set_len,
33038c2ecf20Sopenharmony_ci						context->meta_ac,
33048c2ecf20Sopenharmony_ci						&context->dealloc, delete);
33058c2ecf20Sopenharmony_ci		if (ret) {
33068c2ecf20Sopenharmony_ci			mlog_errno(ret);
33078c2ecf20Sopenharmony_ci			goto out_commit;
33088c2ecf20Sopenharmony_ci		}
33098c2ecf20Sopenharmony_ci
33108c2ecf20Sopenharmony_ci		cpos += set_len;
33118c2ecf20Sopenharmony_ci		p_cluster += set_len;
33128c2ecf20Sopenharmony_ci		num_clusters -= set_len;
33138c2ecf20Sopenharmony_ci		brelse(ref_leaf_bh);
33148c2ecf20Sopenharmony_ci		ref_leaf_bh = NULL;
33158c2ecf20Sopenharmony_ci	}
33168c2ecf20Sopenharmony_ci
33178c2ecf20Sopenharmony_ci	/* handle any post_cow action. */
33188c2ecf20Sopenharmony_ci	if (context->post_refcount && context->post_refcount->func) {
33198c2ecf20Sopenharmony_ci		ret = context->post_refcount->func(context->inode, handle,
33208c2ecf20Sopenharmony_ci						context->post_refcount->para);
33218c2ecf20Sopenharmony_ci		if (ret) {
33228c2ecf20Sopenharmony_ci			mlog_errno(ret);
33238c2ecf20Sopenharmony_ci			goto out_commit;
33248c2ecf20Sopenharmony_ci		}
33258c2ecf20Sopenharmony_ci	}
33268c2ecf20Sopenharmony_ci
33278c2ecf20Sopenharmony_ci	/*
33288c2ecf20Sopenharmony_ci	 * Here we should write the new page out first if we are
33298c2ecf20Sopenharmony_ci	 * in write-back mode.
33308c2ecf20Sopenharmony_ci	 */
33318c2ecf20Sopenharmony_ci	if (context->get_clusters == ocfs2_di_get_clusters) {
33328c2ecf20Sopenharmony_ci		ret = ocfs2_cow_sync_writeback(sb, context->inode, cpos,
33338c2ecf20Sopenharmony_ci					       orig_num_clusters);
33348c2ecf20Sopenharmony_ci		if (ret)
33358c2ecf20Sopenharmony_ci			mlog_errno(ret);
33368c2ecf20Sopenharmony_ci	}
33378c2ecf20Sopenharmony_ci
33388c2ecf20Sopenharmony_ciout_commit:
33398c2ecf20Sopenharmony_ci	ocfs2_commit_trans(osb, handle);
33408c2ecf20Sopenharmony_ci
33418c2ecf20Sopenharmony_ciout:
33428c2ecf20Sopenharmony_ci	if (context->data_ac) {
33438c2ecf20Sopenharmony_ci		ocfs2_free_alloc_context(context->data_ac);
33448c2ecf20Sopenharmony_ci		context->data_ac = NULL;
33458c2ecf20Sopenharmony_ci	}
33468c2ecf20Sopenharmony_ci	if (context->meta_ac) {
33478c2ecf20Sopenharmony_ci		ocfs2_free_alloc_context(context->meta_ac);
33488c2ecf20Sopenharmony_ci		context->meta_ac = NULL;
33498c2ecf20Sopenharmony_ci	}
33508c2ecf20Sopenharmony_ci	brelse(ref_leaf_bh);
33518c2ecf20Sopenharmony_ci
33528c2ecf20Sopenharmony_ci	return ret;
33538c2ecf20Sopenharmony_ci}
33548c2ecf20Sopenharmony_ci
33558c2ecf20Sopenharmony_cistatic int ocfs2_replace_cow(struct ocfs2_cow_context *context)
33568c2ecf20Sopenharmony_ci{
33578c2ecf20Sopenharmony_ci	int ret = 0;
33588c2ecf20Sopenharmony_ci	struct inode *inode = context->inode;
33598c2ecf20Sopenharmony_ci	u32 cow_start = context->cow_start, cow_len = context->cow_len;
33608c2ecf20Sopenharmony_ci	u32 p_cluster, num_clusters;
33618c2ecf20Sopenharmony_ci	unsigned int ext_flags;
33628c2ecf20Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
33638c2ecf20Sopenharmony_ci
33648c2ecf20Sopenharmony_ci	if (!ocfs2_refcount_tree(osb)) {
33658c2ecf20Sopenharmony_ci		return ocfs2_error(inode->i_sb, "Inode %lu want to use refcount tree, but the feature bit is not set in the super block\n",
33668c2ecf20Sopenharmony_ci				   inode->i_ino);
33678c2ecf20Sopenharmony_ci	}
33688c2ecf20Sopenharmony_ci
33698c2ecf20Sopenharmony_ci	ocfs2_init_dealloc_ctxt(&context->dealloc);
33708c2ecf20Sopenharmony_ci
33718c2ecf20Sopenharmony_ci	while (cow_len) {
33728c2ecf20Sopenharmony_ci		ret = context->get_clusters(context, cow_start, &p_cluster,
33738c2ecf20Sopenharmony_ci					    &num_clusters, &ext_flags);
33748c2ecf20Sopenharmony_ci		if (ret) {
33758c2ecf20Sopenharmony_ci			mlog_errno(ret);
33768c2ecf20Sopenharmony_ci			break;
33778c2ecf20Sopenharmony_ci		}
33788c2ecf20Sopenharmony_ci
33798c2ecf20Sopenharmony_ci		BUG_ON(!(ext_flags & OCFS2_EXT_REFCOUNTED));
33808c2ecf20Sopenharmony_ci
33818c2ecf20Sopenharmony_ci		if (cow_len < num_clusters)
33828c2ecf20Sopenharmony_ci			num_clusters = cow_len;
33838c2ecf20Sopenharmony_ci
33848c2ecf20Sopenharmony_ci		ret = ocfs2_make_clusters_writable(inode->i_sb, context,
33858c2ecf20Sopenharmony_ci						   cow_start, p_cluster,
33868c2ecf20Sopenharmony_ci						   num_clusters, ext_flags);
33878c2ecf20Sopenharmony_ci		if (ret) {
33888c2ecf20Sopenharmony_ci			mlog_errno(ret);
33898c2ecf20Sopenharmony_ci			break;
33908c2ecf20Sopenharmony_ci		}
33918c2ecf20Sopenharmony_ci
33928c2ecf20Sopenharmony_ci		cow_len -= num_clusters;
33938c2ecf20Sopenharmony_ci		cow_start += num_clusters;
33948c2ecf20Sopenharmony_ci	}
33958c2ecf20Sopenharmony_ci
33968c2ecf20Sopenharmony_ci	if (ocfs2_dealloc_has_cluster(&context->dealloc)) {
33978c2ecf20Sopenharmony_ci		ocfs2_schedule_truncate_log_flush(osb, 1);
33988c2ecf20Sopenharmony_ci		ocfs2_run_deallocs(osb, &context->dealloc);
33998c2ecf20Sopenharmony_ci	}
34008c2ecf20Sopenharmony_ci
34018c2ecf20Sopenharmony_ci	return ret;
34028c2ecf20Sopenharmony_ci}
34038c2ecf20Sopenharmony_ci
34048c2ecf20Sopenharmony_ci/*
34058c2ecf20Sopenharmony_ci * Starting at cpos, try to CoW write_len clusters.  Don't CoW
34068c2ecf20Sopenharmony_ci * past max_cpos.  This will stop when it runs into a hole or an
34078c2ecf20Sopenharmony_ci * unrefcounted extent.
34088c2ecf20Sopenharmony_ci */
34098c2ecf20Sopenharmony_cistatic int ocfs2_refcount_cow_hunk(struct inode *inode,
34108c2ecf20Sopenharmony_ci				   struct buffer_head *di_bh,
34118c2ecf20Sopenharmony_ci				   u32 cpos, u32 write_len, u32 max_cpos)
34128c2ecf20Sopenharmony_ci{
34138c2ecf20Sopenharmony_ci	int ret;
34148c2ecf20Sopenharmony_ci	u32 cow_start = 0, cow_len = 0;
34158c2ecf20Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
34168c2ecf20Sopenharmony_ci	struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
34178c2ecf20Sopenharmony_ci	struct buffer_head *ref_root_bh = NULL;
34188c2ecf20Sopenharmony_ci	struct ocfs2_refcount_tree *ref_tree;
34198c2ecf20Sopenharmony_ci	struct ocfs2_cow_context *context = NULL;
34208c2ecf20Sopenharmony_ci
34218c2ecf20Sopenharmony_ci	BUG_ON(!ocfs2_is_refcount_inode(inode));
34228c2ecf20Sopenharmony_ci
34238c2ecf20Sopenharmony_ci	ret = ocfs2_refcount_cal_cow_clusters(inode, &di->id2.i_list,
34248c2ecf20Sopenharmony_ci					      cpos, write_len, max_cpos,
34258c2ecf20Sopenharmony_ci					      &cow_start, &cow_len);
34268c2ecf20Sopenharmony_ci	if (ret) {
34278c2ecf20Sopenharmony_ci		mlog_errno(ret);
34288c2ecf20Sopenharmony_ci		goto out;
34298c2ecf20Sopenharmony_ci	}
34308c2ecf20Sopenharmony_ci
34318c2ecf20Sopenharmony_ci	trace_ocfs2_refcount_cow_hunk(OCFS2_I(inode)->ip_blkno,
34328c2ecf20Sopenharmony_ci				      cpos, write_len, max_cpos,
34338c2ecf20Sopenharmony_ci				      cow_start, cow_len);
34348c2ecf20Sopenharmony_ci
34358c2ecf20Sopenharmony_ci	BUG_ON(cow_len == 0);
34368c2ecf20Sopenharmony_ci
34378c2ecf20Sopenharmony_ci	context = kzalloc(sizeof(struct ocfs2_cow_context), GFP_NOFS);
34388c2ecf20Sopenharmony_ci	if (!context) {
34398c2ecf20Sopenharmony_ci		ret = -ENOMEM;
34408c2ecf20Sopenharmony_ci		mlog_errno(ret);
34418c2ecf20Sopenharmony_ci		goto out;
34428c2ecf20Sopenharmony_ci	}
34438c2ecf20Sopenharmony_ci
34448c2ecf20Sopenharmony_ci	ret = ocfs2_lock_refcount_tree(osb, le64_to_cpu(di->i_refcount_loc),
34458c2ecf20Sopenharmony_ci				       1, &ref_tree, &ref_root_bh);
34468c2ecf20Sopenharmony_ci	if (ret) {
34478c2ecf20Sopenharmony_ci		mlog_errno(ret);
34488c2ecf20Sopenharmony_ci		goto out;
34498c2ecf20Sopenharmony_ci	}
34508c2ecf20Sopenharmony_ci
34518c2ecf20Sopenharmony_ci	context->inode = inode;
34528c2ecf20Sopenharmony_ci	context->cow_start = cow_start;
34538c2ecf20Sopenharmony_ci	context->cow_len = cow_len;
34548c2ecf20Sopenharmony_ci	context->ref_tree = ref_tree;
34558c2ecf20Sopenharmony_ci	context->ref_root_bh = ref_root_bh;
34568c2ecf20Sopenharmony_ci	context->cow_duplicate_clusters = ocfs2_duplicate_clusters_by_page;
34578c2ecf20Sopenharmony_ci	context->get_clusters = ocfs2_di_get_clusters;
34588c2ecf20Sopenharmony_ci
34598c2ecf20Sopenharmony_ci	ocfs2_init_dinode_extent_tree(&context->data_et,
34608c2ecf20Sopenharmony_ci				      INODE_CACHE(inode), di_bh);
34618c2ecf20Sopenharmony_ci
34628c2ecf20Sopenharmony_ci	ret = ocfs2_replace_cow(context);
34638c2ecf20Sopenharmony_ci	if (ret)
34648c2ecf20Sopenharmony_ci		mlog_errno(ret);
34658c2ecf20Sopenharmony_ci
34668c2ecf20Sopenharmony_ci	/*
34678c2ecf20Sopenharmony_ci	 * truncate the extent map here since no matter whether we meet with
34688c2ecf20Sopenharmony_ci	 * any error during the action, we shouldn't trust cached extent map
34698c2ecf20Sopenharmony_ci	 * any more.
34708c2ecf20Sopenharmony_ci	 */
34718c2ecf20Sopenharmony_ci	ocfs2_extent_map_trunc(inode, cow_start);
34728c2ecf20Sopenharmony_ci
34738c2ecf20Sopenharmony_ci	ocfs2_unlock_refcount_tree(osb, ref_tree, 1);
34748c2ecf20Sopenharmony_ci	brelse(ref_root_bh);
34758c2ecf20Sopenharmony_ciout:
34768c2ecf20Sopenharmony_ci	kfree(context);
34778c2ecf20Sopenharmony_ci	return ret;
34788c2ecf20Sopenharmony_ci}
34798c2ecf20Sopenharmony_ci
34808c2ecf20Sopenharmony_ci/*
34818c2ecf20Sopenharmony_ci * CoW any and all clusters between cpos and cpos+write_len.
34828c2ecf20Sopenharmony_ci * Don't CoW past max_cpos.  If this returns successfully, all
34838c2ecf20Sopenharmony_ci * clusters between cpos and cpos+write_len are safe to modify.
34848c2ecf20Sopenharmony_ci */
34858c2ecf20Sopenharmony_ciint ocfs2_refcount_cow(struct inode *inode,
34868c2ecf20Sopenharmony_ci		       struct buffer_head *di_bh,
34878c2ecf20Sopenharmony_ci		       u32 cpos, u32 write_len, u32 max_cpos)
34888c2ecf20Sopenharmony_ci{
34898c2ecf20Sopenharmony_ci	int ret = 0;
34908c2ecf20Sopenharmony_ci	u32 p_cluster, num_clusters;
34918c2ecf20Sopenharmony_ci	unsigned int ext_flags;
34928c2ecf20Sopenharmony_ci
34938c2ecf20Sopenharmony_ci	while (write_len) {
34948c2ecf20Sopenharmony_ci		ret = ocfs2_get_clusters(inode, cpos, &p_cluster,
34958c2ecf20Sopenharmony_ci					 &num_clusters, &ext_flags);
34968c2ecf20Sopenharmony_ci		if (ret) {
34978c2ecf20Sopenharmony_ci			mlog_errno(ret);
34988c2ecf20Sopenharmony_ci			break;
34998c2ecf20Sopenharmony_ci		}
35008c2ecf20Sopenharmony_ci
35018c2ecf20Sopenharmony_ci		if (write_len < num_clusters)
35028c2ecf20Sopenharmony_ci			num_clusters = write_len;
35038c2ecf20Sopenharmony_ci
35048c2ecf20Sopenharmony_ci		if (ext_flags & OCFS2_EXT_REFCOUNTED) {
35058c2ecf20Sopenharmony_ci			ret = ocfs2_refcount_cow_hunk(inode, di_bh, cpos,
35068c2ecf20Sopenharmony_ci						      num_clusters, max_cpos);
35078c2ecf20Sopenharmony_ci			if (ret) {
35088c2ecf20Sopenharmony_ci				mlog_errno(ret);
35098c2ecf20Sopenharmony_ci				break;
35108c2ecf20Sopenharmony_ci			}
35118c2ecf20Sopenharmony_ci		}
35128c2ecf20Sopenharmony_ci
35138c2ecf20Sopenharmony_ci		write_len -= num_clusters;
35148c2ecf20Sopenharmony_ci		cpos += num_clusters;
35158c2ecf20Sopenharmony_ci	}
35168c2ecf20Sopenharmony_ci
35178c2ecf20Sopenharmony_ci	return ret;
35188c2ecf20Sopenharmony_ci}
35198c2ecf20Sopenharmony_ci
35208c2ecf20Sopenharmony_cistatic int ocfs2_xattr_value_get_clusters(struct ocfs2_cow_context *context,
35218c2ecf20Sopenharmony_ci					  u32 v_cluster, u32 *p_cluster,
35228c2ecf20Sopenharmony_ci					  u32 *num_clusters,
35238c2ecf20Sopenharmony_ci					  unsigned int *extent_flags)
35248c2ecf20Sopenharmony_ci{
35258c2ecf20Sopenharmony_ci	struct inode *inode = context->inode;
35268c2ecf20Sopenharmony_ci	struct ocfs2_xattr_value_root *xv = context->cow_object;
35278c2ecf20Sopenharmony_ci
35288c2ecf20Sopenharmony_ci	return ocfs2_xattr_get_clusters(inode, v_cluster, p_cluster,
35298c2ecf20Sopenharmony_ci					num_clusters, &xv->xr_list,
35308c2ecf20Sopenharmony_ci					extent_flags);
35318c2ecf20Sopenharmony_ci}
35328c2ecf20Sopenharmony_ci
35338c2ecf20Sopenharmony_ci/*
35348c2ecf20Sopenharmony_ci * Given a xattr value root, calculate the most meta/credits we need for
35358c2ecf20Sopenharmony_ci * refcount tree change if we truncate it to 0.
35368c2ecf20Sopenharmony_ci */
35378c2ecf20Sopenharmony_ciint ocfs2_refcounted_xattr_delete_need(struct inode *inode,
35388c2ecf20Sopenharmony_ci				       struct ocfs2_caching_info *ref_ci,
35398c2ecf20Sopenharmony_ci				       struct buffer_head *ref_root_bh,
35408c2ecf20Sopenharmony_ci				       struct ocfs2_xattr_value_root *xv,
35418c2ecf20Sopenharmony_ci				       int *meta_add, int *credits)
35428c2ecf20Sopenharmony_ci{
35438c2ecf20Sopenharmony_ci	int ret = 0, index, ref_blocks = 0;
35448c2ecf20Sopenharmony_ci	u32 p_cluster, num_clusters;
35458c2ecf20Sopenharmony_ci	u32 cpos = 0, clusters = le32_to_cpu(xv->xr_clusters);
35468c2ecf20Sopenharmony_ci	struct ocfs2_refcount_block *rb;
35478c2ecf20Sopenharmony_ci	struct ocfs2_refcount_rec rec;
35488c2ecf20Sopenharmony_ci	struct buffer_head *ref_leaf_bh = NULL;
35498c2ecf20Sopenharmony_ci
35508c2ecf20Sopenharmony_ci	while (cpos < clusters) {
35518c2ecf20Sopenharmony_ci		ret = ocfs2_xattr_get_clusters(inode, cpos, &p_cluster,
35528c2ecf20Sopenharmony_ci					       &num_clusters, &xv->xr_list,
35538c2ecf20Sopenharmony_ci					       NULL);
35548c2ecf20Sopenharmony_ci		if (ret) {
35558c2ecf20Sopenharmony_ci			mlog_errno(ret);
35568c2ecf20Sopenharmony_ci			goto out;
35578c2ecf20Sopenharmony_ci		}
35588c2ecf20Sopenharmony_ci
35598c2ecf20Sopenharmony_ci		cpos += num_clusters;
35608c2ecf20Sopenharmony_ci
35618c2ecf20Sopenharmony_ci		while (num_clusters) {
35628c2ecf20Sopenharmony_ci			ret = ocfs2_get_refcount_rec(ref_ci, ref_root_bh,
35638c2ecf20Sopenharmony_ci						     p_cluster, num_clusters,
35648c2ecf20Sopenharmony_ci						     &rec, &index,
35658c2ecf20Sopenharmony_ci						     &ref_leaf_bh);
35668c2ecf20Sopenharmony_ci			if (ret) {
35678c2ecf20Sopenharmony_ci				mlog_errno(ret);
35688c2ecf20Sopenharmony_ci				goto out;
35698c2ecf20Sopenharmony_ci			}
35708c2ecf20Sopenharmony_ci
35718c2ecf20Sopenharmony_ci			BUG_ON(!rec.r_refcount);
35728c2ecf20Sopenharmony_ci
35738c2ecf20Sopenharmony_ci			rb = (struct ocfs2_refcount_block *)ref_leaf_bh->b_data;
35748c2ecf20Sopenharmony_ci
35758c2ecf20Sopenharmony_ci			/*
35768c2ecf20Sopenharmony_ci			 * We really don't know whether the other clusters is in
35778c2ecf20Sopenharmony_ci			 * this refcount block or not, so just take the worst
35788c2ecf20Sopenharmony_ci			 * case that all the clusters are in this block and each
35798c2ecf20Sopenharmony_ci			 * one will split a refcount rec, so totally we need
35808c2ecf20Sopenharmony_ci			 * clusters * 2 new refcount rec.
35818c2ecf20Sopenharmony_ci			 */
35828c2ecf20Sopenharmony_ci			if (le16_to_cpu(rb->rf_records.rl_used) + clusters * 2 >
35838c2ecf20Sopenharmony_ci			    le16_to_cpu(rb->rf_records.rl_count))
35848c2ecf20Sopenharmony_ci				ref_blocks++;
35858c2ecf20Sopenharmony_ci
35868c2ecf20Sopenharmony_ci			*credits += 1;
35878c2ecf20Sopenharmony_ci			brelse(ref_leaf_bh);
35888c2ecf20Sopenharmony_ci			ref_leaf_bh = NULL;
35898c2ecf20Sopenharmony_ci
35908c2ecf20Sopenharmony_ci			if (num_clusters <= le32_to_cpu(rec.r_clusters))
35918c2ecf20Sopenharmony_ci				break;
35928c2ecf20Sopenharmony_ci			else
35938c2ecf20Sopenharmony_ci				num_clusters -= le32_to_cpu(rec.r_clusters);
35948c2ecf20Sopenharmony_ci			p_cluster += num_clusters;
35958c2ecf20Sopenharmony_ci		}
35968c2ecf20Sopenharmony_ci	}
35978c2ecf20Sopenharmony_ci
35988c2ecf20Sopenharmony_ci	*meta_add += ref_blocks;
35998c2ecf20Sopenharmony_ci	if (!ref_blocks)
36008c2ecf20Sopenharmony_ci		goto out;
36018c2ecf20Sopenharmony_ci
36028c2ecf20Sopenharmony_ci	rb = (struct ocfs2_refcount_block *)ref_root_bh->b_data;
36038c2ecf20Sopenharmony_ci	if (le32_to_cpu(rb->rf_flags) & OCFS2_REFCOUNT_TREE_FL)
36048c2ecf20Sopenharmony_ci		*credits += OCFS2_EXPAND_REFCOUNT_TREE_CREDITS;
36058c2ecf20Sopenharmony_ci	else {
36068c2ecf20Sopenharmony_ci		struct ocfs2_extent_tree et;
36078c2ecf20Sopenharmony_ci
36088c2ecf20Sopenharmony_ci		ocfs2_init_refcount_extent_tree(&et, ref_ci, ref_root_bh);
36098c2ecf20Sopenharmony_ci		*credits += ocfs2_calc_extend_credits(inode->i_sb,
36108c2ecf20Sopenharmony_ci						      et.et_root_el);
36118c2ecf20Sopenharmony_ci	}
36128c2ecf20Sopenharmony_ci
36138c2ecf20Sopenharmony_ciout:
36148c2ecf20Sopenharmony_ci	brelse(ref_leaf_bh);
36158c2ecf20Sopenharmony_ci	return ret;
36168c2ecf20Sopenharmony_ci}
36178c2ecf20Sopenharmony_ci
36188c2ecf20Sopenharmony_ci/*
36198c2ecf20Sopenharmony_ci * Do CoW for xattr.
36208c2ecf20Sopenharmony_ci */
36218c2ecf20Sopenharmony_ciint ocfs2_refcount_cow_xattr(struct inode *inode,
36228c2ecf20Sopenharmony_ci			     struct ocfs2_dinode *di,
36238c2ecf20Sopenharmony_ci			     struct ocfs2_xattr_value_buf *vb,
36248c2ecf20Sopenharmony_ci			     struct ocfs2_refcount_tree *ref_tree,
36258c2ecf20Sopenharmony_ci			     struct buffer_head *ref_root_bh,
36268c2ecf20Sopenharmony_ci			     u32 cpos, u32 write_len,
36278c2ecf20Sopenharmony_ci			     struct ocfs2_post_refcount *post)
36288c2ecf20Sopenharmony_ci{
36298c2ecf20Sopenharmony_ci	int ret;
36308c2ecf20Sopenharmony_ci	struct ocfs2_xattr_value_root *xv = vb->vb_xv;
36318c2ecf20Sopenharmony_ci	struct ocfs2_cow_context *context = NULL;
36328c2ecf20Sopenharmony_ci	u32 cow_start, cow_len;
36338c2ecf20Sopenharmony_ci
36348c2ecf20Sopenharmony_ci	BUG_ON(!ocfs2_is_refcount_inode(inode));
36358c2ecf20Sopenharmony_ci
36368c2ecf20Sopenharmony_ci	ret = ocfs2_refcount_cal_cow_clusters(inode, &xv->xr_list,
36378c2ecf20Sopenharmony_ci					      cpos, write_len, UINT_MAX,
36388c2ecf20Sopenharmony_ci					      &cow_start, &cow_len);
36398c2ecf20Sopenharmony_ci	if (ret) {
36408c2ecf20Sopenharmony_ci		mlog_errno(ret);
36418c2ecf20Sopenharmony_ci		goto out;
36428c2ecf20Sopenharmony_ci	}
36438c2ecf20Sopenharmony_ci
36448c2ecf20Sopenharmony_ci	BUG_ON(cow_len == 0);
36458c2ecf20Sopenharmony_ci
36468c2ecf20Sopenharmony_ci	context = kzalloc(sizeof(struct ocfs2_cow_context), GFP_NOFS);
36478c2ecf20Sopenharmony_ci	if (!context) {
36488c2ecf20Sopenharmony_ci		ret = -ENOMEM;
36498c2ecf20Sopenharmony_ci		mlog_errno(ret);
36508c2ecf20Sopenharmony_ci		goto out;
36518c2ecf20Sopenharmony_ci	}
36528c2ecf20Sopenharmony_ci
36538c2ecf20Sopenharmony_ci	context->inode = inode;
36548c2ecf20Sopenharmony_ci	context->cow_start = cow_start;
36558c2ecf20Sopenharmony_ci	context->cow_len = cow_len;
36568c2ecf20Sopenharmony_ci	context->ref_tree = ref_tree;
36578c2ecf20Sopenharmony_ci	context->ref_root_bh = ref_root_bh;
36588c2ecf20Sopenharmony_ci	context->cow_object = xv;
36598c2ecf20Sopenharmony_ci
36608c2ecf20Sopenharmony_ci	context->cow_duplicate_clusters = ocfs2_duplicate_clusters_by_jbd;
36618c2ecf20Sopenharmony_ci	/* We need the extra credits for duplicate_clusters by jbd. */
36628c2ecf20Sopenharmony_ci	context->extra_credits =
36638c2ecf20Sopenharmony_ci		ocfs2_clusters_to_blocks(inode->i_sb, 1) * cow_len;
36648c2ecf20Sopenharmony_ci	context->get_clusters = ocfs2_xattr_value_get_clusters;
36658c2ecf20Sopenharmony_ci	context->post_refcount = post;
36668c2ecf20Sopenharmony_ci
36678c2ecf20Sopenharmony_ci	ocfs2_init_xattr_value_extent_tree(&context->data_et,
36688c2ecf20Sopenharmony_ci					   INODE_CACHE(inode), vb);
36698c2ecf20Sopenharmony_ci
36708c2ecf20Sopenharmony_ci	ret = ocfs2_replace_cow(context);
36718c2ecf20Sopenharmony_ci	if (ret)
36728c2ecf20Sopenharmony_ci		mlog_errno(ret);
36738c2ecf20Sopenharmony_ci
36748c2ecf20Sopenharmony_ciout:
36758c2ecf20Sopenharmony_ci	kfree(context);
36768c2ecf20Sopenharmony_ci	return ret;
36778c2ecf20Sopenharmony_ci}
36788c2ecf20Sopenharmony_ci
36798c2ecf20Sopenharmony_ci/*
36808c2ecf20Sopenharmony_ci * Insert a new extent into refcount tree and mark a extent rec
36818c2ecf20Sopenharmony_ci * as refcounted in the dinode tree.
36828c2ecf20Sopenharmony_ci */
36838c2ecf20Sopenharmony_ciint ocfs2_add_refcount_flag(struct inode *inode,
36848c2ecf20Sopenharmony_ci			    struct ocfs2_extent_tree *data_et,
36858c2ecf20Sopenharmony_ci			    struct ocfs2_caching_info *ref_ci,
36868c2ecf20Sopenharmony_ci			    struct buffer_head *ref_root_bh,
36878c2ecf20Sopenharmony_ci			    u32 cpos, u32 p_cluster, u32 num_clusters,
36888c2ecf20Sopenharmony_ci			    struct ocfs2_cached_dealloc_ctxt *dealloc,
36898c2ecf20Sopenharmony_ci			    struct ocfs2_post_refcount *post)
36908c2ecf20Sopenharmony_ci{
36918c2ecf20Sopenharmony_ci	int ret;
36928c2ecf20Sopenharmony_ci	handle_t *handle;
36938c2ecf20Sopenharmony_ci	int credits = 1, ref_blocks = 0;
36948c2ecf20Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
36958c2ecf20Sopenharmony_ci	struct ocfs2_alloc_context *meta_ac = NULL;
36968c2ecf20Sopenharmony_ci
36978c2ecf20Sopenharmony_ci	/* We need to be able to handle at least an extent tree split. */
36988c2ecf20Sopenharmony_ci	ref_blocks = ocfs2_extend_meta_needed(data_et->et_root_el);
36998c2ecf20Sopenharmony_ci
37008c2ecf20Sopenharmony_ci	ret = ocfs2_calc_refcount_meta_credits(inode->i_sb,
37018c2ecf20Sopenharmony_ci					       ref_ci, ref_root_bh,
37028c2ecf20Sopenharmony_ci					       p_cluster, num_clusters,
37038c2ecf20Sopenharmony_ci					       &ref_blocks, &credits);
37048c2ecf20Sopenharmony_ci	if (ret) {
37058c2ecf20Sopenharmony_ci		mlog_errno(ret);
37068c2ecf20Sopenharmony_ci		goto out;
37078c2ecf20Sopenharmony_ci	}
37088c2ecf20Sopenharmony_ci
37098c2ecf20Sopenharmony_ci	trace_ocfs2_add_refcount_flag(ref_blocks, credits);
37108c2ecf20Sopenharmony_ci
37118c2ecf20Sopenharmony_ci	if (ref_blocks) {
37128c2ecf20Sopenharmony_ci		ret = ocfs2_reserve_new_metadata_blocks(osb,
37138c2ecf20Sopenharmony_ci							ref_blocks, &meta_ac);
37148c2ecf20Sopenharmony_ci		if (ret) {
37158c2ecf20Sopenharmony_ci			mlog_errno(ret);
37168c2ecf20Sopenharmony_ci			goto out;
37178c2ecf20Sopenharmony_ci		}
37188c2ecf20Sopenharmony_ci	}
37198c2ecf20Sopenharmony_ci
37208c2ecf20Sopenharmony_ci	if (post)
37218c2ecf20Sopenharmony_ci		credits += post->credits;
37228c2ecf20Sopenharmony_ci
37238c2ecf20Sopenharmony_ci	handle = ocfs2_start_trans(osb, credits);
37248c2ecf20Sopenharmony_ci	if (IS_ERR(handle)) {
37258c2ecf20Sopenharmony_ci		ret = PTR_ERR(handle);
37268c2ecf20Sopenharmony_ci		mlog_errno(ret);
37278c2ecf20Sopenharmony_ci		goto out;
37288c2ecf20Sopenharmony_ci	}
37298c2ecf20Sopenharmony_ci
37308c2ecf20Sopenharmony_ci	ret = ocfs2_mark_extent_refcounted(inode, data_et, handle,
37318c2ecf20Sopenharmony_ci					   cpos, num_clusters, p_cluster,
37328c2ecf20Sopenharmony_ci					   meta_ac, dealloc);
37338c2ecf20Sopenharmony_ci	if (ret) {
37348c2ecf20Sopenharmony_ci		mlog_errno(ret);
37358c2ecf20Sopenharmony_ci		goto out_commit;
37368c2ecf20Sopenharmony_ci	}
37378c2ecf20Sopenharmony_ci
37388c2ecf20Sopenharmony_ci	ret = __ocfs2_increase_refcount(handle, ref_ci, ref_root_bh,
37398c2ecf20Sopenharmony_ci					p_cluster, num_clusters, 0,
37408c2ecf20Sopenharmony_ci					meta_ac, dealloc);
37418c2ecf20Sopenharmony_ci	if (ret) {
37428c2ecf20Sopenharmony_ci		mlog_errno(ret);
37438c2ecf20Sopenharmony_ci		goto out_commit;
37448c2ecf20Sopenharmony_ci	}
37458c2ecf20Sopenharmony_ci
37468c2ecf20Sopenharmony_ci	if (post && post->func) {
37478c2ecf20Sopenharmony_ci		ret = post->func(inode, handle, post->para);
37488c2ecf20Sopenharmony_ci		if (ret)
37498c2ecf20Sopenharmony_ci			mlog_errno(ret);
37508c2ecf20Sopenharmony_ci	}
37518c2ecf20Sopenharmony_ci
37528c2ecf20Sopenharmony_ciout_commit:
37538c2ecf20Sopenharmony_ci	ocfs2_commit_trans(osb, handle);
37548c2ecf20Sopenharmony_ciout:
37558c2ecf20Sopenharmony_ci	if (meta_ac)
37568c2ecf20Sopenharmony_ci		ocfs2_free_alloc_context(meta_ac);
37578c2ecf20Sopenharmony_ci	return ret;
37588c2ecf20Sopenharmony_ci}
37598c2ecf20Sopenharmony_ci
37608c2ecf20Sopenharmony_cistatic int ocfs2_change_ctime(struct inode *inode,
37618c2ecf20Sopenharmony_ci			      struct buffer_head *di_bh)
37628c2ecf20Sopenharmony_ci{
37638c2ecf20Sopenharmony_ci	int ret;
37648c2ecf20Sopenharmony_ci	handle_t *handle;
37658c2ecf20Sopenharmony_ci	struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
37668c2ecf20Sopenharmony_ci
37678c2ecf20Sopenharmony_ci	handle = ocfs2_start_trans(OCFS2_SB(inode->i_sb),
37688c2ecf20Sopenharmony_ci				   OCFS2_INODE_UPDATE_CREDITS);
37698c2ecf20Sopenharmony_ci	if (IS_ERR(handle)) {
37708c2ecf20Sopenharmony_ci		ret = PTR_ERR(handle);
37718c2ecf20Sopenharmony_ci		mlog_errno(ret);
37728c2ecf20Sopenharmony_ci		goto out;
37738c2ecf20Sopenharmony_ci	}
37748c2ecf20Sopenharmony_ci
37758c2ecf20Sopenharmony_ci	ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), di_bh,
37768c2ecf20Sopenharmony_ci				      OCFS2_JOURNAL_ACCESS_WRITE);
37778c2ecf20Sopenharmony_ci	if (ret) {
37788c2ecf20Sopenharmony_ci		mlog_errno(ret);
37798c2ecf20Sopenharmony_ci		goto out_commit;
37808c2ecf20Sopenharmony_ci	}
37818c2ecf20Sopenharmony_ci
37828c2ecf20Sopenharmony_ci	inode->i_ctime = current_time(inode);
37838c2ecf20Sopenharmony_ci	di->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec);
37848c2ecf20Sopenharmony_ci	di->i_ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec);
37858c2ecf20Sopenharmony_ci
37868c2ecf20Sopenharmony_ci	ocfs2_journal_dirty(handle, di_bh);
37878c2ecf20Sopenharmony_ci
37888c2ecf20Sopenharmony_ciout_commit:
37898c2ecf20Sopenharmony_ci	ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
37908c2ecf20Sopenharmony_ciout:
37918c2ecf20Sopenharmony_ci	return ret;
37928c2ecf20Sopenharmony_ci}
37938c2ecf20Sopenharmony_ci
37948c2ecf20Sopenharmony_cistatic int ocfs2_attach_refcount_tree(struct inode *inode,
37958c2ecf20Sopenharmony_ci				      struct buffer_head *di_bh)
37968c2ecf20Sopenharmony_ci{
37978c2ecf20Sopenharmony_ci	int ret, data_changed = 0;
37988c2ecf20Sopenharmony_ci	struct buffer_head *ref_root_bh = NULL;
37998c2ecf20Sopenharmony_ci	struct ocfs2_inode_info *oi = OCFS2_I(inode);
38008c2ecf20Sopenharmony_ci	struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
38018c2ecf20Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
38028c2ecf20Sopenharmony_ci	struct ocfs2_refcount_tree *ref_tree;
38038c2ecf20Sopenharmony_ci	unsigned int ext_flags;
38048c2ecf20Sopenharmony_ci	loff_t size;
38058c2ecf20Sopenharmony_ci	u32 cpos, num_clusters, clusters, p_cluster;
38068c2ecf20Sopenharmony_ci	struct ocfs2_cached_dealloc_ctxt dealloc;
38078c2ecf20Sopenharmony_ci	struct ocfs2_extent_tree di_et;
38088c2ecf20Sopenharmony_ci
38098c2ecf20Sopenharmony_ci	ocfs2_init_dealloc_ctxt(&dealloc);
38108c2ecf20Sopenharmony_ci
38118c2ecf20Sopenharmony_ci	if (!ocfs2_is_refcount_inode(inode)) {
38128c2ecf20Sopenharmony_ci		ret = ocfs2_create_refcount_tree(inode, di_bh);
38138c2ecf20Sopenharmony_ci		if (ret) {
38148c2ecf20Sopenharmony_ci			mlog_errno(ret);
38158c2ecf20Sopenharmony_ci			goto out;
38168c2ecf20Sopenharmony_ci		}
38178c2ecf20Sopenharmony_ci	}
38188c2ecf20Sopenharmony_ci
38198c2ecf20Sopenharmony_ci	BUG_ON(!di->i_refcount_loc);
38208c2ecf20Sopenharmony_ci	ret = ocfs2_lock_refcount_tree(osb,
38218c2ecf20Sopenharmony_ci				       le64_to_cpu(di->i_refcount_loc), 1,
38228c2ecf20Sopenharmony_ci				       &ref_tree, &ref_root_bh);
38238c2ecf20Sopenharmony_ci	if (ret) {
38248c2ecf20Sopenharmony_ci		mlog_errno(ret);
38258c2ecf20Sopenharmony_ci		goto out;
38268c2ecf20Sopenharmony_ci	}
38278c2ecf20Sopenharmony_ci
38288c2ecf20Sopenharmony_ci	if (oi->ip_dyn_features & OCFS2_INLINE_DATA_FL)
38298c2ecf20Sopenharmony_ci		goto attach_xattr;
38308c2ecf20Sopenharmony_ci
38318c2ecf20Sopenharmony_ci	ocfs2_init_dinode_extent_tree(&di_et, INODE_CACHE(inode), di_bh);
38328c2ecf20Sopenharmony_ci
38338c2ecf20Sopenharmony_ci	size = i_size_read(inode);
38348c2ecf20Sopenharmony_ci	clusters = ocfs2_clusters_for_bytes(inode->i_sb, size);
38358c2ecf20Sopenharmony_ci
38368c2ecf20Sopenharmony_ci	cpos = 0;
38378c2ecf20Sopenharmony_ci	while (cpos < clusters) {
38388c2ecf20Sopenharmony_ci		ret = ocfs2_get_clusters(inode, cpos, &p_cluster,
38398c2ecf20Sopenharmony_ci					 &num_clusters, &ext_flags);
38408c2ecf20Sopenharmony_ci		if (ret) {
38418c2ecf20Sopenharmony_ci			mlog_errno(ret);
38428c2ecf20Sopenharmony_ci			goto unlock;
38438c2ecf20Sopenharmony_ci		}
38448c2ecf20Sopenharmony_ci		if (p_cluster && !(ext_flags & OCFS2_EXT_REFCOUNTED)) {
38458c2ecf20Sopenharmony_ci			ret = ocfs2_add_refcount_flag(inode, &di_et,
38468c2ecf20Sopenharmony_ci						      &ref_tree->rf_ci,
38478c2ecf20Sopenharmony_ci						      ref_root_bh, cpos,
38488c2ecf20Sopenharmony_ci						      p_cluster, num_clusters,
38498c2ecf20Sopenharmony_ci						      &dealloc, NULL);
38508c2ecf20Sopenharmony_ci			if (ret) {
38518c2ecf20Sopenharmony_ci				mlog_errno(ret);
38528c2ecf20Sopenharmony_ci				goto unlock;
38538c2ecf20Sopenharmony_ci			}
38548c2ecf20Sopenharmony_ci
38558c2ecf20Sopenharmony_ci			data_changed = 1;
38568c2ecf20Sopenharmony_ci		}
38578c2ecf20Sopenharmony_ci		cpos += num_clusters;
38588c2ecf20Sopenharmony_ci	}
38598c2ecf20Sopenharmony_ci
38608c2ecf20Sopenharmony_ciattach_xattr:
38618c2ecf20Sopenharmony_ci	if (oi->ip_dyn_features & OCFS2_HAS_XATTR_FL) {
38628c2ecf20Sopenharmony_ci		ret = ocfs2_xattr_attach_refcount_tree(inode, di_bh,
38638c2ecf20Sopenharmony_ci						       &ref_tree->rf_ci,
38648c2ecf20Sopenharmony_ci						       ref_root_bh,
38658c2ecf20Sopenharmony_ci						       &dealloc);
38668c2ecf20Sopenharmony_ci		if (ret) {
38678c2ecf20Sopenharmony_ci			mlog_errno(ret);
38688c2ecf20Sopenharmony_ci			goto unlock;
38698c2ecf20Sopenharmony_ci		}
38708c2ecf20Sopenharmony_ci	}
38718c2ecf20Sopenharmony_ci
38728c2ecf20Sopenharmony_ci	if (data_changed) {
38738c2ecf20Sopenharmony_ci		ret = ocfs2_change_ctime(inode, di_bh);
38748c2ecf20Sopenharmony_ci		if (ret)
38758c2ecf20Sopenharmony_ci			mlog_errno(ret);
38768c2ecf20Sopenharmony_ci	}
38778c2ecf20Sopenharmony_ci
38788c2ecf20Sopenharmony_ciunlock:
38798c2ecf20Sopenharmony_ci	ocfs2_unlock_refcount_tree(osb, ref_tree, 1);
38808c2ecf20Sopenharmony_ci	brelse(ref_root_bh);
38818c2ecf20Sopenharmony_ci
38828c2ecf20Sopenharmony_ci	if (!ret && ocfs2_dealloc_has_cluster(&dealloc)) {
38838c2ecf20Sopenharmony_ci		ocfs2_schedule_truncate_log_flush(osb, 1);
38848c2ecf20Sopenharmony_ci		ocfs2_run_deallocs(osb, &dealloc);
38858c2ecf20Sopenharmony_ci	}
38868c2ecf20Sopenharmony_ciout:
38878c2ecf20Sopenharmony_ci	/*
38888c2ecf20Sopenharmony_ci	 * Empty the extent map so that we may get the right extent
38898c2ecf20Sopenharmony_ci	 * record from the disk.
38908c2ecf20Sopenharmony_ci	 */
38918c2ecf20Sopenharmony_ci	ocfs2_extent_map_trunc(inode, 0);
38928c2ecf20Sopenharmony_ci
38938c2ecf20Sopenharmony_ci	return ret;
38948c2ecf20Sopenharmony_ci}
38958c2ecf20Sopenharmony_ci
38968c2ecf20Sopenharmony_cistatic int ocfs2_add_refcounted_extent(struct inode *inode,
38978c2ecf20Sopenharmony_ci				   struct ocfs2_extent_tree *et,
38988c2ecf20Sopenharmony_ci				   struct ocfs2_caching_info *ref_ci,
38998c2ecf20Sopenharmony_ci				   struct buffer_head *ref_root_bh,
39008c2ecf20Sopenharmony_ci				   u32 cpos, u32 p_cluster, u32 num_clusters,
39018c2ecf20Sopenharmony_ci				   unsigned int ext_flags,
39028c2ecf20Sopenharmony_ci				   struct ocfs2_cached_dealloc_ctxt *dealloc)
39038c2ecf20Sopenharmony_ci{
39048c2ecf20Sopenharmony_ci	int ret;
39058c2ecf20Sopenharmony_ci	handle_t *handle;
39068c2ecf20Sopenharmony_ci	int credits = 0;
39078c2ecf20Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
39088c2ecf20Sopenharmony_ci	struct ocfs2_alloc_context *meta_ac = NULL;
39098c2ecf20Sopenharmony_ci
39108c2ecf20Sopenharmony_ci	ret = ocfs2_lock_refcount_allocators(inode->i_sb,
39118c2ecf20Sopenharmony_ci					     p_cluster, num_clusters,
39128c2ecf20Sopenharmony_ci					     et, ref_ci,
39138c2ecf20Sopenharmony_ci					     ref_root_bh, &meta_ac,
39148c2ecf20Sopenharmony_ci					     NULL, &credits);
39158c2ecf20Sopenharmony_ci	if (ret) {
39168c2ecf20Sopenharmony_ci		mlog_errno(ret);
39178c2ecf20Sopenharmony_ci		goto out;
39188c2ecf20Sopenharmony_ci	}
39198c2ecf20Sopenharmony_ci
39208c2ecf20Sopenharmony_ci	handle = ocfs2_start_trans(osb, credits);
39218c2ecf20Sopenharmony_ci	if (IS_ERR(handle)) {
39228c2ecf20Sopenharmony_ci		ret = PTR_ERR(handle);
39238c2ecf20Sopenharmony_ci		mlog_errno(ret);
39248c2ecf20Sopenharmony_ci		goto out;
39258c2ecf20Sopenharmony_ci	}
39268c2ecf20Sopenharmony_ci
39278c2ecf20Sopenharmony_ci	ret = ocfs2_insert_extent(handle, et, cpos,
39288c2ecf20Sopenharmony_ci			ocfs2_clusters_to_blocks(inode->i_sb, p_cluster),
39298c2ecf20Sopenharmony_ci			num_clusters, ext_flags, meta_ac);
39308c2ecf20Sopenharmony_ci	if (ret) {
39318c2ecf20Sopenharmony_ci		mlog_errno(ret);
39328c2ecf20Sopenharmony_ci		goto out_commit;
39338c2ecf20Sopenharmony_ci	}
39348c2ecf20Sopenharmony_ci
39358c2ecf20Sopenharmony_ci	ret = ocfs2_increase_refcount(handle, ref_ci, ref_root_bh,
39368c2ecf20Sopenharmony_ci				      p_cluster, num_clusters,
39378c2ecf20Sopenharmony_ci				      meta_ac, dealloc);
39388c2ecf20Sopenharmony_ci	if (ret) {
39398c2ecf20Sopenharmony_ci		mlog_errno(ret);
39408c2ecf20Sopenharmony_ci		goto out_commit;
39418c2ecf20Sopenharmony_ci	}
39428c2ecf20Sopenharmony_ci
39438c2ecf20Sopenharmony_ci	ret = dquot_alloc_space_nodirty(inode,
39448c2ecf20Sopenharmony_ci		ocfs2_clusters_to_bytes(osb->sb, num_clusters));
39458c2ecf20Sopenharmony_ci	if (ret)
39468c2ecf20Sopenharmony_ci		mlog_errno(ret);
39478c2ecf20Sopenharmony_ci
39488c2ecf20Sopenharmony_ciout_commit:
39498c2ecf20Sopenharmony_ci	ocfs2_commit_trans(osb, handle);
39508c2ecf20Sopenharmony_ciout:
39518c2ecf20Sopenharmony_ci	if (meta_ac)
39528c2ecf20Sopenharmony_ci		ocfs2_free_alloc_context(meta_ac);
39538c2ecf20Sopenharmony_ci	return ret;
39548c2ecf20Sopenharmony_ci}
39558c2ecf20Sopenharmony_ci
39568c2ecf20Sopenharmony_cistatic int ocfs2_duplicate_inline_data(struct inode *s_inode,
39578c2ecf20Sopenharmony_ci				       struct buffer_head *s_bh,
39588c2ecf20Sopenharmony_ci				       struct inode *t_inode,
39598c2ecf20Sopenharmony_ci				       struct buffer_head *t_bh)
39608c2ecf20Sopenharmony_ci{
39618c2ecf20Sopenharmony_ci	int ret;
39628c2ecf20Sopenharmony_ci	handle_t *handle;
39638c2ecf20Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(s_inode->i_sb);
39648c2ecf20Sopenharmony_ci	struct ocfs2_dinode *s_di = (struct ocfs2_dinode *)s_bh->b_data;
39658c2ecf20Sopenharmony_ci	struct ocfs2_dinode *t_di = (struct ocfs2_dinode *)t_bh->b_data;
39668c2ecf20Sopenharmony_ci
39678c2ecf20Sopenharmony_ci	BUG_ON(!(OCFS2_I(s_inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL));
39688c2ecf20Sopenharmony_ci
39698c2ecf20Sopenharmony_ci	handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
39708c2ecf20Sopenharmony_ci	if (IS_ERR(handle)) {
39718c2ecf20Sopenharmony_ci		ret = PTR_ERR(handle);
39728c2ecf20Sopenharmony_ci		mlog_errno(ret);
39738c2ecf20Sopenharmony_ci		goto out;
39748c2ecf20Sopenharmony_ci	}
39758c2ecf20Sopenharmony_ci
39768c2ecf20Sopenharmony_ci	ret = ocfs2_journal_access_di(handle, INODE_CACHE(t_inode), t_bh,
39778c2ecf20Sopenharmony_ci				      OCFS2_JOURNAL_ACCESS_WRITE);
39788c2ecf20Sopenharmony_ci	if (ret) {
39798c2ecf20Sopenharmony_ci		mlog_errno(ret);
39808c2ecf20Sopenharmony_ci		goto out_commit;
39818c2ecf20Sopenharmony_ci	}
39828c2ecf20Sopenharmony_ci
39838c2ecf20Sopenharmony_ci	t_di->id2.i_data.id_count = s_di->id2.i_data.id_count;
39848c2ecf20Sopenharmony_ci	memcpy(t_di->id2.i_data.id_data, s_di->id2.i_data.id_data,
39858c2ecf20Sopenharmony_ci	       le16_to_cpu(s_di->id2.i_data.id_count));
39868c2ecf20Sopenharmony_ci	spin_lock(&OCFS2_I(t_inode)->ip_lock);
39878c2ecf20Sopenharmony_ci	OCFS2_I(t_inode)->ip_dyn_features |= OCFS2_INLINE_DATA_FL;
39888c2ecf20Sopenharmony_ci	t_di->i_dyn_features = cpu_to_le16(OCFS2_I(t_inode)->ip_dyn_features);
39898c2ecf20Sopenharmony_ci	spin_unlock(&OCFS2_I(t_inode)->ip_lock);
39908c2ecf20Sopenharmony_ci
39918c2ecf20Sopenharmony_ci	ocfs2_journal_dirty(handle, t_bh);
39928c2ecf20Sopenharmony_ci
39938c2ecf20Sopenharmony_ciout_commit:
39948c2ecf20Sopenharmony_ci	ocfs2_commit_trans(osb, handle);
39958c2ecf20Sopenharmony_ciout:
39968c2ecf20Sopenharmony_ci	return ret;
39978c2ecf20Sopenharmony_ci}
39988c2ecf20Sopenharmony_ci
39998c2ecf20Sopenharmony_cistatic int ocfs2_duplicate_extent_list(struct inode *s_inode,
40008c2ecf20Sopenharmony_ci				struct inode *t_inode,
40018c2ecf20Sopenharmony_ci				struct buffer_head *t_bh,
40028c2ecf20Sopenharmony_ci				struct ocfs2_caching_info *ref_ci,
40038c2ecf20Sopenharmony_ci				struct buffer_head *ref_root_bh,
40048c2ecf20Sopenharmony_ci				struct ocfs2_cached_dealloc_ctxt *dealloc)
40058c2ecf20Sopenharmony_ci{
40068c2ecf20Sopenharmony_ci	int ret = 0;
40078c2ecf20Sopenharmony_ci	u32 p_cluster, num_clusters, clusters, cpos;
40088c2ecf20Sopenharmony_ci	loff_t size;
40098c2ecf20Sopenharmony_ci	unsigned int ext_flags;
40108c2ecf20Sopenharmony_ci	struct ocfs2_extent_tree et;
40118c2ecf20Sopenharmony_ci
40128c2ecf20Sopenharmony_ci	ocfs2_init_dinode_extent_tree(&et, INODE_CACHE(t_inode), t_bh);
40138c2ecf20Sopenharmony_ci
40148c2ecf20Sopenharmony_ci	size = i_size_read(s_inode);
40158c2ecf20Sopenharmony_ci	clusters = ocfs2_clusters_for_bytes(s_inode->i_sb, size);
40168c2ecf20Sopenharmony_ci
40178c2ecf20Sopenharmony_ci	cpos = 0;
40188c2ecf20Sopenharmony_ci	while (cpos < clusters) {
40198c2ecf20Sopenharmony_ci		ret = ocfs2_get_clusters(s_inode, cpos, &p_cluster,
40208c2ecf20Sopenharmony_ci					 &num_clusters, &ext_flags);
40218c2ecf20Sopenharmony_ci		if (ret) {
40228c2ecf20Sopenharmony_ci			mlog_errno(ret);
40238c2ecf20Sopenharmony_ci			goto out;
40248c2ecf20Sopenharmony_ci		}
40258c2ecf20Sopenharmony_ci		if (p_cluster) {
40268c2ecf20Sopenharmony_ci			ret = ocfs2_add_refcounted_extent(t_inode, &et,
40278c2ecf20Sopenharmony_ci							  ref_ci, ref_root_bh,
40288c2ecf20Sopenharmony_ci							  cpos, p_cluster,
40298c2ecf20Sopenharmony_ci							  num_clusters,
40308c2ecf20Sopenharmony_ci							  ext_flags,
40318c2ecf20Sopenharmony_ci							  dealloc);
40328c2ecf20Sopenharmony_ci			if (ret) {
40338c2ecf20Sopenharmony_ci				mlog_errno(ret);
40348c2ecf20Sopenharmony_ci				goto out;
40358c2ecf20Sopenharmony_ci			}
40368c2ecf20Sopenharmony_ci		}
40378c2ecf20Sopenharmony_ci
40388c2ecf20Sopenharmony_ci		cpos += num_clusters;
40398c2ecf20Sopenharmony_ci	}
40408c2ecf20Sopenharmony_ci
40418c2ecf20Sopenharmony_ciout:
40428c2ecf20Sopenharmony_ci	return ret;
40438c2ecf20Sopenharmony_ci}
40448c2ecf20Sopenharmony_ci
40458c2ecf20Sopenharmony_ci/*
40468c2ecf20Sopenharmony_ci * change the new file's attributes to the src.
40478c2ecf20Sopenharmony_ci *
40488c2ecf20Sopenharmony_ci * reflink creates a snapshot of a file, that means the attributes
40498c2ecf20Sopenharmony_ci * must be identical except for three exceptions - nlink, ino, and ctime.
40508c2ecf20Sopenharmony_ci */
40518c2ecf20Sopenharmony_cistatic int ocfs2_complete_reflink(struct inode *s_inode,
40528c2ecf20Sopenharmony_ci				  struct buffer_head *s_bh,
40538c2ecf20Sopenharmony_ci				  struct inode *t_inode,
40548c2ecf20Sopenharmony_ci				  struct buffer_head *t_bh,
40558c2ecf20Sopenharmony_ci				  bool preserve)
40568c2ecf20Sopenharmony_ci{
40578c2ecf20Sopenharmony_ci	int ret;
40588c2ecf20Sopenharmony_ci	handle_t *handle;
40598c2ecf20Sopenharmony_ci	struct ocfs2_dinode *s_di = (struct ocfs2_dinode *)s_bh->b_data;
40608c2ecf20Sopenharmony_ci	struct ocfs2_dinode *di = (struct ocfs2_dinode *)t_bh->b_data;
40618c2ecf20Sopenharmony_ci	loff_t size = i_size_read(s_inode);
40628c2ecf20Sopenharmony_ci
40638c2ecf20Sopenharmony_ci	handle = ocfs2_start_trans(OCFS2_SB(t_inode->i_sb),
40648c2ecf20Sopenharmony_ci				   OCFS2_INODE_UPDATE_CREDITS);
40658c2ecf20Sopenharmony_ci	if (IS_ERR(handle)) {
40668c2ecf20Sopenharmony_ci		ret = PTR_ERR(handle);
40678c2ecf20Sopenharmony_ci		mlog_errno(ret);
40688c2ecf20Sopenharmony_ci		return ret;
40698c2ecf20Sopenharmony_ci	}
40708c2ecf20Sopenharmony_ci
40718c2ecf20Sopenharmony_ci	ret = ocfs2_journal_access_di(handle, INODE_CACHE(t_inode), t_bh,
40728c2ecf20Sopenharmony_ci				      OCFS2_JOURNAL_ACCESS_WRITE);
40738c2ecf20Sopenharmony_ci	if (ret) {
40748c2ecf20Sopenharmony_ci		mlog_errno(ret);
40758c2ecf20Sopenharmony_ci		goto out_commit;
40768c2ecf20Sopenharmony_ci	}
40778c2ecf20Sopenharmony_ci
40788c2ecf20Sopenharmony_ci	spin_lock(&OCFS2_I(t_inode)->ip_lock);
40798c2ecf20Sopenharmony_ci	OCFS2_I(t_inode)->ip_clusters = OCFS2_I(s_inode)->ip_clusters;
40808c2ecf20Sopenharmony_ci	OCFS2_I(t_inode)->ip_attr = OCFS2_I(s_inode)->ip_attr;
40818c2ecf20Sopenharmony_ci	OCFS2_I(t_inode)->ip_dyn_features = OCFS2_I(s_inode)->ip_dyn_features;
40828c2ecf20Sopenharmony_ci	spin_unlock(&OCFS2_I(t_inode)->ip_lock);
40838c2ecf20Sopenharmony_ci	i_size_write(t_inode, size);
40848c2ecf20Sopenharmony_ci	t_inode->i_blocks = s_inode->i_blocks;
40858c2ecf20Sopenharmony_ci
40868c2ecf20Sopenharmony_ci	di->i_xattr_inline_size = s_di->i_xattr_inline_size;
40878c2ecf20Sopenharmony_ci	di->i_clusters = s_di->i_clusters;
40888c2ecf20Sopenharmony_ci	di->i_size = s_di->i_size;
40898c2ecf20Sopenharmony_ci	di->i_dyn_features = s_di->i_dyn_features;
40908c2ecf20Sopenharmony_ci	di->i_attr = s_di->i_attr;
40918c2ecf20Sopenharmony_ci
40928c2ecf20Sopenharmony_ci	if (preserve) {
40938c2ecf20Sopenharmony_ci		t_inode->i_uid = s_inode->i_uid;
40948c2ecf20Sopenharmony_ci		t_inode->i_gid = s_inode->i_gid;
40958c2ecf20Sopenharmony_ci		t_inode->i_mode = s_inode->i_mode;
40968c2ecf20Sopenharmony_ci		di->i_uid = s_di->i_uid;
40978c2ecf20Sopenharmony_ci		di->i_gid = s_di->i_gid;
40988c2ecf20Sopenharmony_ci		di->i_mode = s_di->i_mode;
40998c2ecf20Sopenharmony_ci
41008c2ecf20Sopenharmony_ci		/*
41018c2ecf20Sopenharmony_ci		 * update time.
41028c2ecf20Sopenharmony_ci		 * we want mtime to appear identical to the source and
41038c2ecf20Sopenharmony_ci		 * update ctime.
41048c2ecf20Sopenharmony_ci		 */
41058c2ecf20Sopenharmony_ci		t_inode->i_ctime = current_time(t_inode);
41068c2ecf20Sopenharmony_ci
41078c2ecf20Sopenharmony_ci		di->i_ctime = cpu_to_le64(t_inode->i_ctime.tv_sec);
41088c2ecf20Sopenharmony_ci		di->i_ctime_nsec = cpu_to_le32(t_inode->i_ctime.tv_nsec);
41098c2ecf20Sopenharmony_ci
41108c2ecf20Sopenharmony_ci		t_inode->i_mtime = s_inode->i_mtime;
41118c2ecf20Sopenharmony_ci		di->i_mtime = s_di->i_mtime;
41128c2ecf20Sopenharmony_ci		di->i_mtime_nsec = s_di->i_mtime_nsec;
41138c2ecf20Sopenharmony_ci	}
41148c2ecf20Sopenharmony_ci
41158c2ecf20Sopenharmony_ci	ocfs2_journal_dirty(handle, t_bh);
41168c2ecf20Sopenharmony_ci
41178c2ecf20Sopenharmony_ciout_commit:
41188c2ecf20Sopenharmony_ci	ocfs2_commit_trans(OCFS2_SB(t_inode->i_sb), handle);
41198c2ecf20Sopenharmony_ci	return ret;
41208c2ecf20Sopenharmony_ci}
41218c2ecf20Sopenharmony_ci
41228c2ecf20Sopenharmony_cistatic int ocfs2_create_reflink_node(struct inode *s_inode,
41238c2ecf20Sopenharmony_ci				     struct buffer_head *s_bh,
41248c2ecf20Sopenharmony_ci				     struct inode *t_inode,
41258c2ecf20Sopenharmony_ci				     struct buffer_head *t_bh,
41268c2ecf20Sopenharmony_ci				     bool preserve)
41278c2ecf20Sopenharmony_ci{
41288c2ecf20Sopenharmony_ci	int ret;
41298c2ecf20Sopenharmony_ci	struct buffer_head *ref_root_bh = NULL;
41308c2ecf20Sopenharmony_ci	struct ocfs2_cached_dealloc_ctxt dealloc;
41318c2ecf20Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(s_inode->i_sb);
41328c2ecf20Sopenharmony_ci	struct ocfs2_dinode *di = (struct ocfs2_dinode *)s_bh->b_data;
41338c2ecf20Sopenharmony_ci	struct ocfs2_refcount_tree *ref_tree;
41348c2ecf20Sopenharmony_ci
41358c2ecf20Sopenharmony_ci	ocfs2_init_dealloc_ctxt(&dealloc);
41368c2ecf20Sopenharmony_ci
41378c2ecf20Sopenharmony_ci	ret = ocfs2_set_refcount_tree(t_inode, t_bh,
41388c2ecf20Sopenharmony_ci				      le64_to_cpu(di->i_refcount_loc));
41398c2ecf20Sopenharmony_ci	if (ret) {
41408c2ecf20Sopenharmony_ci		mlog_errno(ret);
41418c2ecf20Sopenharmony_ci		goto out;
41428c2ecf20Sopenharmony_ci	}
41438c2ecf20Sopenharmony_ci
41448c2ecf20Sopenharmony_ci	if (OCFS2_I(s_inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
41458c2ecf20Sopenharmony_ci		ret = ocfs2_duplicate_inline_data(s_inode, s_bh,
41468c2ecf20Sopenharmony_ci						  t_inode, t_bh);
41478c2ecf20Sopenharmony_ci		if (ret)
41488c2ecf20Sopenharmony_ci			mlog_errno(ret);
41498c2ecf20Sopenharmony_ci		goto out;
41508c2ecf20Sopenharmony_ci	}
41518c2ecf20Sopenharmony_ci
41528c2ecf20Sopenharmony_ci	ret = ocfs2_lock_refcount_tree(osb, le64_to_cpu(di->i_refcount_loc),
41538c2ecf20Sopenharmony_ci				       1, &ref_tree, &ref_root_bh);
41548c2ecf20Sopenharmony_ci	if (ret) {
41558c2ecf20Sopenharmony_ci		mlog_errno(ret);
41568c2ecf20Sopenharmony_ci		goto out;
41578c2ecf20Sopenharmony_ci	}
41588c2ecf20Sopenharmony_ci
41598c2ecf20Sopenharmony_ci	ret = ocfs2_duplicate_extent_list(s_inode, t_inode, t_bh,
41608c2ecf20Sopenharmony_ci					  &ref_tree->rf_ci, ref_root_bh,
41618c2ecf20Sopenharmony_ci					  &dealloc);
41628c2ecf20Sopenharmony_ci	if (ret) {
41638c2ecf20Sopenharmony_ci		mlog_errno(ret);
41648c2ecf20Sopenharmony_ci		goto out_unlock_refcount;
41658c2ecf20Sopenharmony_ci	}
41668c2ecf20Sopenharmony_ci
41678c2ecf20Sopenharmony_ciout_unlock_refcount:
41688c2ecf20Sopenharmony_ci	ocfs2_unlock_refcount_tree(osb, ref_tree, 1);
41698c2ecf20Sopenharmony_ci	brelse(ref_root_bh);
41708c2ecf20Sopenharmony_ciout:
41718c2ecf20Sopenharmony_ci	if (ocfs2_dealloc_has_cluster(&dealloc)) {
41728c2ecf20Sopenharmony_ci		ocfs2_schedule_truncate_log_flush(osb, 1);
41738c2ecf20Sopenharmony_ci		ocfs2_run_deallocs(osb, &dealloc);
41748c2ecf20Sopenharmony_ci	}
41758c2ecf20Sopenharmony_ci
41768c2ecf20Sopenharmony_ci	return ret;
41778c2ecf20Sopenharmony_ci}
41788c2ecf20Sopenharmony_ci
41798c2ecf20Sopenharmony_cistatic int __ocfs2_reflink(struct dentry *old_dentry,
41808c2ecf20Sopenharmony_ci			   struct buffer_head *old_bh,
41818c2ecf20Sopenharmony_ci			   struct inode *new_inode,
41828c2ecf20Sopenharmony_ci			   bool preserve)
41838c2ecf20Sopenharmony_ci{
41848c2ecf20Sopenharmony_ci	int ret;
41858c2ecf20Sopenharmony_ci	struct inode *inode = d_inode(old_dentry);
41868c2ecf20Sopenharmony_ci	struct buffer_head *new_bh = NULL;
41878c2ecf20Sopenharmony_ci
41888c2ecf20Sopenharmony_ci	if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_SYSTEM_FILE) {
41898c2ecf20Sopenharmony_ci		ret = -EINVAL;
41908c2ecf20Sopenharmony_ci		mlog_errno(ret);
41918c2ecf20Sopenharmony_ci		goto out;
41928c2ecf20Sopenharmony_ci	}
41938c2ecf20Sopenharmony_ci
41948c2ecf20Sopenharmony_ci	ret = filemap_fdatawrite(inode->i_mapping);
41958c2ecf20Sopenharmony_ci	if (ret) {
41968c2ecf20Sopenharmony_ci		mlog_errno(ret);
41978c2ecf20Sopenharmony_ci		goto out;
41988c2ecf20Sopenharmony_ci	}
41998c2ecf20Sopenharmony_ci
42008c2ecf20Sopenharmony_ci	ret = ocfs2_attach_refcount_tree(inode, old_bh);
42018c2ecf20Sopenharmony_ci	if (ret) {
42028c2ecf20Sopenharmony_ci		mlog_errno(ret);
42038c2ecf20Sopenharmony_ci		goto out;
42048c2ecf20Sopenharmony_ci	}
42058c2ecf20Sopenharmony_ci
42068c2ecf20Sopenharmony_ci	inode_lock_nested(new_inode, I_MUTEX_CHILD);
42078c2ecf20Sopenharmony_ci	ret = ocfs2_inode_lock_nested(new_inode, &new_bh, 1,
42088c2ecf20Sopenharmony_ci				      OI_LS_REFLINK_TARGET);
42098c2ecf20Sopenharmony_ci	if (ret) {
42108c2ecf20Sopenharmony_ci		mlog_errno(ret);
42118c2ecf20Sopenharmony_ci		goto out_unlock;
42128c2ecf20Sopenharmony_ci	}
42138c2ecf20Sopenharmony_ci
42148c2ecf20Sopenharmony_ci	ret = ocfs2_create_reflink_node(inode, old_bh,
42158c2ecf20Sopenharmony_ci					new_inode, new_bh, preserve);
42168c2ecf20Sopenharmony_ci	if (ret) {
42178c2ecf20Sopenharmony_ci		mlog_errno(ret);
42188c2ecf20Sopenharmony_ci		goto inode_unlock;
42198c2ecf20Sopenharmony_ci	}
42208c2ecf20Sopenharmony_ci
42218c2ecf20Sopenharmony_ci	if (OCFS2_I(inode)->ip_dyn_features & OCFS2_HAS_XATTR_FL) {
42228c2ecf20Sopenharmony_ci		ret = ocfs2_reflink_xattrs(inode, old_bh,
42238c2ecf20Sopenharmony_ci					   new_inode, new_bh,
42248c2ecf20Sopenharmony_ci					   preserve);
42258c2ecf20Sopenharmony_ci		if (ret) {
42268c2ecf20Sopenharmony_ci			mlog_errno(ret);
42278c2ecf20Sopenharmony_ci			goto inode_unlock;
42288c2ecf20Sopenharmony_ci		}
42298c2ecf20Sopenharmony_ci	}
42308c2ecf20Sopenharmony_ci
42318c2ecf20Sopenharmony_ci	ret = ocfs2_complete_reflink(inode, old_bh,
42328c2ecf20Sopenharmony_ci				     new_inode, new_bh, preserve);
42338c2ecf20Sopenharmony_ci	if (ret)
42348c2ecf20Sopenharmony_ci		mlog_errno(ret);
42358c2ecf20Sopenharmony_ci
42368c2ecf20Sopenharmony_ciinode_unlock:
42378c2ecf20Sopenharmony_ci	ocfs2_inode_unlock(new_inode, 1);
42388c2ecf20Sopenharmony_ci	brelse(new_bh);
42398c2ecf20Sopenharmony_ciout_unlock:
42408c2ecf20Sopenharmony_ci	inode_unlock(new_inode);
42418c2ecf20Sopenharmony_ciout:
42428c2ecf20Sopenharmony_ci	if (!ret) {
42438c2ecf20Sopenharmony_ci		ret = filemap_fdatawait(inode->i_mapping);
42448c2ecf20Sopenharmony_ci		if (ret)
42458c2ecf20Sopenharmony_ci			mlog_errno(ret);
42468c2ecf20Sopenharmony_ci	}
42478c2ecf20Sopenharmony_ci	return ret;
42488c2ecf20Sopenharmony_ci}
42498c2ecf20Sopenharmony_ci
42508c2ecf20Sopenharmony_cistatic int ocfs2_reflink(struct dentry *old_dentry, struct inode *dir,
42518c2ecf20Sopenharmony_ci			 struct dentry *new_dentry, bool preserve)
42528c2ecf20Sopenharmony_ci{
42538c2ecf20Sopenharmony_ci	int error, had_lock;
42548c2ecf20Sopenharmony_ci	struct inode *inode = d_inode(old_dentry);
42558c2ecf20Sopenharmony_ci	struct buffer_head *old_bh = NULL;
42568c2ecf20Sopenharmony_ci	struct inode *new_orphan_inode = NULL;
42578c2ecf20Sopenharmony_ci	struct ocfs2_lock_holder oh;
42588c2ecf20Sopenharmony_ci
42598c2ecf20Sopenharmony_ci	if (!ocfs2_refcount_tree(OCFS2_SB(inode->i_sb)))
42608c2ecf20Sopenharmony_ci		return -EOPNOTSUPP;
42618c2ecf20Sopenharmony_ci
42628c2ecf20Sopenharmony_ci
42638c2ecf20Sopenharmony_ci	error = ocfs2_create_inode_in_orphan(dir, inode->i_mode,
42648c2ecf20Sopenharmony_ci					     &new_orphan_inode);
42658c2ecf20Sopenharmony_ci	if (error) {
42668c2ecf20Sopenharmony_ci		mlog_errno(error);
42678c2ecf20Sopenharmony_ci		goto out;
42688c2ecf20Sopenharmony_ci	}
42698c2ecf20Sopenharmony_ci
42708c2ecf20Sopenharmony_ci	error = ocfs2_rw_lock(inode, 1);
42718c2ecf20Sopenharmony_ci	if (error) {
42728c2ecf20Sopenharmony_ci		mlog_errno(error);
42738c2ecf20Sopenharmony_ci		goto out;
42748c2ecf20Sopenharmony_ci	}
42758c2ecf20Sopenharmony_ci
42768c2ecf20Sopenharmony_ci	error = ocfs2_inode_lock(inode, &old_bh, 1);
42778c2ecf20Sopenharmony_ci	if (error) {
42788c2ecf20Sopenharmony_ci		mlog_errno(error);
42798c2ecf20Sopenharmony_ci		ocfs2_rw_unlock(inode, 1);
42808c2ecf20Sopenharmony_ci		goto out;
42818c2ecf20Sopenharmony_ci	}
42828c2ecf20Sopenharmony_ci
42838c2ecf20Sopenharmony_ci	down_write(&OCFS2_I(inode)->ip_xattr_sem);
42848c2ecf20Sopenharmony_ci	down_write(&OCFS2_I(inode)->ip_alloc_sem);
42858c2ecf20Sopenharmony_ci	error = __ocfs2_reflink(old_dentry, old_bh,
42868c2ecf20Sopenharmony_ci				new_orphan_inode, preserve);
42878c2ecf20Sopenharmony_ci	up_write(&OCFS2_I(inode)->ip_alloc_sem);
42888c2ecf20Sopenharmony_ci	up_write(&OCFS2_I(inode)->ip_xattr_sem);
42898c2ecf20Sopenharmony_ci
42908c2ecf20Sopenharmony_ci	ocfs2_inode_unlock(inode, 1);
42918c2ecf20Sopenharmony_ci	ocfs2_rw_unlock(inode, 1);
42928c2ecf20Sopenharmony_ci	brelse(old_bh);
42938c2ecf20Sopenharmony_ci
42948c2ecf20Sopenharmony_ci	if (error) {
42958c2ecf20Sopenharmony_ci		mlog_errno(error);
42968c2ecf20Sopenharmony_ci		goto out;
42978c2ecf20Sopenharmony_ci	}
42988c2ecf20Sopenharmony_ci
42998c2ecf20Sopenharmony_ci	had_lock = ocfs2_inode_lock_tracker(new_orphan_inode, NULL, 1,
43008c2ecf20Sopenharmony_ci					    &oh);
43018c2ecf20Sopenharmony_ci	if (had_lock < 0) {
43028c2ecf20Sopenharmony_ci		error = had_lock;
43038c2ecf20Sopenharmony_ci		mlog_errno(error);
43048c2ecf20Sopenharmony_ci		goto out;
43058c2ecf20Sopenharmony_ci	}
43068c2ecf20Sopenharmony_ci
43078c2ecf20Sopenharmony_ci	/* If the security isn't preserved, we need to re-initialize them. */
43088c2ecf20Sopenharmony_ci	if (!preserve) {
43098c2ecf20Sopenharmony_ci		error = ocfs2_init_security_and_acl(dir, new_orphan_inode,
43108c2ecf20Sopenharmony_ci						    &new_dentry->d_name);
43118c2ecf20Sopenharmony_ci		if (error)
43128c2ecf20Sopenharmony_ci			mlog_errno(error);
43138c2ecf20Sopenharmony_ci	}
43148c2ecf20Sopenharmony_ci	if (!error) {
43158c2ecf20Sopenharmony_ci		error = ocfs2_mv_orphaned_inode_to_new(dir, new_orphan_inode,
43168c2ecf20Sopenharmony_ci						       new_dentry);
43178c2ecf20Sopenharmony_ci		if (error)
43188c2ecf20Sopenharmony_ci			mlog_errno(error);
43198c2ecf20Sopenharmony_ci	}
43208c2ecf20Sopenharmony_ci	ocfs2_inode_unlock_tracker(new_orphan_inode, 1, &oh, had_lock);
43218c2ecf20Sopenharmony_ci
43228c2ecf20Sopenharmony_ciout:
43238c2ecf20Sopenharmony_ci	if (new_orphan_inode) {
43248c2ecf20Sopenharmony_ci		/*
43258c2ecf20Sopenharmony_ci		 * We need to open_unlock the inode no matter whether we
43268c2ecf20Sopenharmony_ci		 * succeed or not, so that other nodes can delete it later.
43278c2ecf20Sopenharmony_ci		 */
43288c2ecf20Sopenharmony_ci		ocfs2_open_unlock(new_orphan_inode);
43298c2ecf20Sopenharmony_ci		if (error)
43308c2ecf20Sopenharmony_ci			iput(new_orphan_inode);
43318c2ecf20Sopenharmony_ci	}
43328c2ecf20Sopenharmony_ci
43338c2ecf20Sopenharmony_ci	return error;
43348c2ecf20Sopenharmony_ci}
43358c2ecf20Sopenharmony_ci
43368c2ecf20Sopenharmony_ci/*
43378c2ecf20Sopenharmony_ci * Below here are the bits used by OCFS2_IOC_REFLINK() to fake
43388c2ecf20Sopenharmony_ci * sys_reflink().  This will go away when vfs_reflink() exists in
43398c2ecf20Sopenharmony_ci * fs/namei.c.
43408c2ecf20Sopenharmony_ci */
43418c2ecf20Sopenharmony_ci
43428c2ecf20Sopenharmony_ci/* copied from may_create in VFS. */
43438c2ecf20Sopenharmony_cistatic inline int ocfs2_may_create(struct inode *dir, struct dentry *child)
43448c2ecf20Sopenharmony_ci{
43458c2ecf20Sopenharmony_ci	if (d_really_is_positive(child))
43468c2ecf20Sopenharmony_ci		return -EEXIST;
43478c2ecf20Sopenharmony_ci	if (IS_DEADDIR(dir))
43488c2ecf20Sopenharmony_ci		return -ENOENT;
43498c2ecf20Sopenharmony_ci	return inode_permission(dir, MAY_WRITE | MAY_EXEC);
43508c2ecf20Sopenharmony_ci}
43518c2ecf20Sopenharmony_ci
43528c2ecf20Sopenharmony_ci/**
43538c2ecf20Sopenharmony_ci * ocfs2_vfs_reflink - Create a reference-counted link
43548c2ecf20Sopenharmony_ci *
43558c2ecf20Sopenharmony_ci * @old_dentry:        source dentry + inode
43568c2ecf20Sopenharmony_ci * @dir:       directory to create the target
43578c2ecf20Sopenharmony_ci * @new_dentry:        target dentry
43588c2ecf20Sopenharmony_ci * @preserve:  if true, preserve all file attributes
43598c2ecf20Sopenharmony_ci */
43608c2ecf20Sopenharmony_cistatic int ocfs2_vfs_reflink(struct dentry *old_dentry, struct inode *dir,
43618c2ecf20Sopenharmony_ci			     struct dentry *new_dentry, bool preserve)
43628c2ecf20Sopenharmony_ci{
43638c2ecf20Sopenharmony_ci	struct inode *inode = d_inode(old_dentry);
43648c2ecf20Sopenharmony_ci	int error;
43658c2ecf20Sopenharmony_ci
43668c2ecf20Sopenharmony_ci	if (!inode)
43678c2ecf20Sopenharmony_ci		return -ENOENT;
43688c2ecf20Sopenharmony_ci
43698c2ecf20Sopenharmony_ci	error = ocfs2_may_create(dir, new_dentry);
43708c2ecf20Sopenharmony_ci	if (error)
43718c2ecf20Sopenharmony_ci		return error;
43728c2ecf20Sopenharmony_ci
43738c2ecf20Sopenharmony_ci	if (dir->i_sb != inode->i_sb)
43748c2ecf20Sopenharmony_ci		return -EXDEV;
43758c2ecf20Sopenharmony_ci
43768c2ecf20Sopenharmony_ci	/*
43778c2ecf20Sopenharmony_ci	 * A reflink to an append-only or immutable file cannot be created.
43788c2ecf20Sopenharmony_ci	 */
43798c2ecf20Sopenharmony_ci	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
43808c2ecf20Sopenharmony_ci		return -EPERM;
43818c2ecf20Sopenharmony_ci
43828c2ecf20Sopenharmony_ci	/* Only regular files can be reflinked. */
43838c2ecf20Sopenharmony_ci	if (!S_ISREG(inode->i_mode))
43848c2ecf20Sopenharmony_ci		return -EPERM;
43858c2ecf20Sopenharmony_ci
43868c2ecf20Sopenharmony_ci	/*
43878c2ecf20Sopenharmony_ci	 * If the caller wants to preserve ownership, they require the
43888c2ecf20Sopenharmony_ci	 * rights to do so.
43898c2ecf20Sopenharmony_ci	 */
43908c2ecf20Sopenharmony_ci	if (preserve) {
43918c2ecf20Sopenharmony_ci		if (!uid_eq(current_fsuid(), inode->i_uid) && !capable(CAP_CHOWN))
43928c2ecf20Sopenharmony_ci			return -EPERM;
43938c2ecf20Sopenharmony_ci		if (!in_group_p(inode->i_gid) && !capable(CAP_CHOWN))
43948c2ecf20Sopenharmony_ci			return -EPERM;
43958c2ecf20Sopenharmony_ci	}
43968c2ecf20Sopenharmony_ci
43978c2ecf20Sopenharmony_ci	/*
43988c2ecf20Sopenharmony_ci	 * If the caller is modifying any aspect of the attributes, they
43998c2ecf20Sopenharmony_ci	 * are not creating a snapshot.  They need read permission on the
44008c2ecf20Sopenharmony_ci	 * file.
44018c2ecf20Sopenharmony_ci	 */
44028c2ecf20Sopenharmony_ci	if (!preserve) {
44038c2ecf20Sopenharmony_ci		error = inode_permission(inode, MAY_READ);
44048c2ecf20Sopenharmony_ci		if (error)
44058c2ecf20Sopenharmony_ci			return error;
44068c2ecf20Sopenharmony_ci	}
44078c2ecf20Sopenharmony_ci
44088c2ecf20Sopenharmony_ci	inode_lock(inode);
44098c2ecf20Sopenharmony_ci	error = dquot_initialize(dir);
44108c2ecf20Sopenharmony_ci	if (!error)
44118c2ecf20Sopenharmony_ci		error = ocfs2_reflink(old_dentry, dir, new_dentry, preserve);
44128c2ecf20Sopenharmony_ci	inode_unlock(inode);
44138c2ecf20Sopenharmony_ci	if (!error)
44148c2ecf20Sopenharmony_ci		fsnotify_create(dir, new_dentry);
44158c2ecf20Sopenharmony_ci	return error;
44168c2ecf20Sopenharmony_ci}
44178c2ecf20Sopenharmony_ci/*
44188c2ecf20Sopenharmony_ci * Most codes are copied from sys_linkat.
44198c2ecf20Sopenharmony_ci */
44208c2ecf20Sopenharmony_ciint ocfs2_reflink_ioctl(struct inode *inode,
44218c2ecf20Sopenharmony_ci			const char __user *oldname,
44228c2ecf20Sopenharmony_ci			const char __user *newname,
44238c2ecf20Sopenharmony_ci			bool preserve)
44248c2ecf20Sopenharmony_ci{
44258c2ecf20Sopenharmony_ci	struct dentry *new_dentry;
44268c2ecf20Sopenharmony_ci	struct path old_path, new_path;
44278c2ecf20Sopenharmony_ci	int error;
44288c2ecf20Sopenharmony_ci
44298c2ecf20Sopenharmony_ci	if (!ocfs2_refcount_tree(OCFS2_SB(inode->i_sb)))
44308c2ecf20Sopenharmony_ci		return -EOPNOTSUPP;
44318c2ecf20Sopenharmony_ci
44328c2ecf20Sopenharmony_ci	error = user_path_at(AT_FDCWD, oldname, 0, &old_path);
44338c2ecf20Sopenharmony_ci	if (error) {
44348c2ecf20Sopenharmony_ci		mlog_errno(error);
44358c2ecf20Sopenharmony_ci		return error;
44368c2ecf20Sopenharmony_ci	}
44378c2ecf20Sopenharmony_ci
44388c2ecf20Sopenharmony_ci	new_dentry = user_path_create(AT_FDCWD, newname, &new_path, 0);
44398c2ecf20Sopenharmony_ci	error = PTR_ERR(new_dentry);
44408c2ecf20Sopenharmony_ci	if (IS_ERR(new_dentry)) {
44418c2ecf20Sopenharmony_ci		mlog_errno(error);
44428c2ecf20Sopenharmony_ci		goto out;
44438c2ecf20Sopenharmony_ci	}
44448c2ecf20Sopenharmony_ci
44458c2ecf20Sopenharmony_ci	error = -EXDEV;
44468c2ecf20Sopenharmony_ci	if (old_path.mnt != new_path.mnt) {
44478c2ecf20Sopenharmony_ci		mlog_errno(error);
44488c2ecf20Sopenharmony_ci		goto out_dput;
44498c2ecf20Sopenharmony_ci	}
44508c2ecf20Sopenharmony_ci
44518c2ecf20Sopenharmony_ci	error = ocfs2_vfs_reflink(old_path.dentry,
44528c2ecf20Sopenharmony_ci				  d_inode(new_path.dentry),
44538c2ecf20Sopenharmony_ci				  new_dentry, preserve);
44548c2ecf20Sopenharmony_ciout_dput:
44558c2ecf20Sopenharmony_ci	done_path_create(&new_path, new_dentry);
44568c2ecf20Sopenharmony_ciout:
44578c2ecf20Sopenharmony_ci	path_put(&old_path);
44588c2ecf20Sopenharmony_ci
44598c2ecf20Sopenharmony_ci	return error;
44608c2ecf20Sopenharmony_ci}
44618c2ecf20Sopenharmony_ci
44628c2ecf20Sopenharmony_ci/* Update destination inode size, if necessary. */
44638c2ecf20Sopenharmony_ciint ocfs2_reflink_update_dest(struct inode *dest,
44648c2ecf20Sopenharmony_ci			      struct buffer_head *d_bh,
44658c2ecf20Sopenharmony_ci			      loff_t newlen)
44668c2ecf20Sopenharmony_ci{
44678c2ecf20Sopenharmony_ci	handle_t *handle;
44688c2ecf20Sopenharmony_ci	int ret;
44698c2ecf20Sopenharmony_ci
44708c2ecf20Sopenharmony_ci	dest->i_blocks = ocfs2_inode_sector_count(dest);
44718c2ecf20Sopenharmony_ci
44728c2ecf20Sopenharmony_ci	if (newlen <= i_size_read(dest))
44738c2ecf20Sopenharmony_ci		return 0;
44748c2ecf20Sopenharmony_ci
44758c2ecf20Sopenharmony_ci	handle = ocfs2_start_trans(OCFS2_SB(dest->i_sb),
44768c2ecf20Sopenharmony_ci				   OCFS2_INODE_UPDATE_CREDITS);
44778c2ecf20Sopenharmony_ci	if (IS_ERR(handle)) {
44788c2ecf20Sopenharmony_ci		ret = PTR_ERR(handle);
44798c2ecf20Sopenharmony_ci		mlog_errno(ret);
44808c2ecf20Sopenharmony_ci		return ret;
44818c2ecf20Sopenharmony_ci	}
44828c2ecf20Sopenharmony_ci
44838c2ecf20Sopenharmony_ci	/* Extend i_size if needed. */
44848c2ecf20Sopenharmony_ci	spin_lock(&OCFS2_I(dest)->ip_lock);
44858c2ecf20Sopenharmony_ci	if (newlen > i_size_read(dest))
44868c2ecf20Sopenharmony_ci		i_size_write(dest, newlen);
44878c2ecf20Sopenharmony_ci	spin_unlock(&OCFS2_I(dest)->ip_lock);
44888c2ecf20Sopenharmony_ci	dest->i_ctime = dest->i_mtime = current_time(dest);
44898c2ecf20Sopenharmony_ci
44908c2ecf20Sopenharmony_ci	ret = ocfs2_mark_inode_dirty(handle, dest, d_bh);
44918c2ecf20Sopenharmony_ci	if (ret) {
44928c2ecf20Sopenharmony_ci		mlog_errno(ret);
44938c2ecf20Sopenharmony_ci		goto out_commit;
44948c2ecf20Sopenharmony_ci	}
44958c2ecf20Sopenharmony_ci
44968c2ecf20Sopenharmony_ciout_commit:
44978c2ecf20Sopenharmony_ci	ocfs2_commit_trans(OCFS2_SB(dest->i_sb), handle);
44988c2ecf20Sopenharmony_ci	return ret;
44998c2ecf20Sopenharmony_ci}
45008c2ecf20Sopenharmony_ci
45018c2ecf20Sopenharmony_ci/* Remap the range pos_in:len in s_inode to pos_out:len in t_inode. */
45028c2ecf20Sopenharmony_cistatic loff_t ocfs2_reflink_remap_extent(struct inode *s_inode,
45038c2ecf20Sopenharmony_ci					 struct buffer_head *s_bh,
45048c2ecf20Sopenharmony_ci					 loff_t pos_in,
45058c2ecf20Sopenharmony_ci					 struct inode *t_inode,
45068c2ecf20Sopenharmony_ci					 struct buffer_head *t_bh,
45078c2ecf20Sopenharmony_ci					 loff_t pos_out,
45088c2ecf20Sopenharmony_ci					 loff_t len,
45098c2ecf20Sopenharmony_ci					 struct ocfs2_cached_dealloc_ctxt *dealloc)
45108c2ecf20Sopenharmony_ci{
45118c2ecf20Sopenharmony_ci	struct ocfs2_extent_tree s_et;
45128c2ecf20Sopenharmony_ci	struct ocfs2_extent_tree t_et;
45138c2ecf20Sopenharmony_ci	struct ocfs2_dinode *dis;
45148c2ecf20Sopenharmony_ci	struct buffer_head *ref_root_bh = NULL;
45158c2ecf20Sopenharmony_ci	struct ocfs2_refcount_tree *ref_tree;
45168c2ecf20Sopenharmony_ci	struct ocfs2_super *osb;
45178c2ecf20Sopenharmony_ci	loff_t remapped_bytes = 0;
45188c2ecf20Sopenharmony_ci	loff_t pstart, plen;
45198c2ecf20Sopenharmony_ci	u32 p_cluster, num_clusters, slast, spos, tpos, remapped_clus = 0;
45208c2ecf20Sopenharmony_ci	unsigned int ext_flags;
45218c2ecf20Sopenharmony_ci	int ret = 0;
45228c2ecf20Sopenharmony_ci
45238c2ecf20Sopenharmony_ci	osb = OCFS2_SB(s_inode->i_sb);
45248c2ecf20Sopenharmony_ci	dis = (struct ocfs2_dinode *)s_bh->b_data;
45258c2ecf20Sopenharmony_ci	ocfs2_init_dinode_extent_tree(&s_et, INODE_CACHE(s_inode), s_bh);
45268c2ecf20Sopenharmony_ci	ocfs2_init_dinode_extent_tree(&t_et, INODE_CACHE(t_inode), t_bh);
45278c2ecf20Sopenharmony_ci
45288c2ecf20Sopenharmony_ci	spos = ocfs2_bytes_to_clusters(s_inode->i_sb, pos_in);
45298c2ecf20Sopenharmony_ci	tpos = ocfs2_bytes_to_clusters(t_inode->i_sb, pos_out);
45308c2ecf20Sopenharmony_ci	slast = ocfs2_clusters_for_bytes(s_inode->i_sb, pos_in + len);
45318c2ecf20Sopenharmony_ci
45328c2ecf20Sopenharmony_ci	while (spos < slast) {
45338c2ecf20Sopenharmony_ci		if (fatal_signal_pending(current)) {
45348c2ecf20Sopenharmony_ci			ret = -EINTR;
45358c2ecf20Sopenharmony_ci			goto out;
45368c2ecf20Sopenharmony_ci		}
45378c2ecf20Sopenharmony_ci
45388c2ecf20Sopenharmony_ci		/* Look up the extent. */
45398c2ecf20Sopenharmony_ci		ret = ocfs2_get_clusters(s_inode, spos, &p_cluster,
45408c2ecf20Sopenharmony_ci					 &num_clusters, &ext_flags);
45418c2ecf20Sopenharmony_ci		if (ret) {
45428c2ecf20Sopenharmony_ci			mlog_errno(ret);
45438c2ecf20Sopenharmony_ci			goto out;
45448c2ecf20Sopenharmony_ci		}
45458c2ecf20Sopenharmony_ci
45468c2ecf20Sopenharmony_ci		num_clusters = min_t(u32, num_clusters, slast - spos);
45478c2ecf20Sopenharmony_ci
45488c2ecf20Sopenharmony_ci		/* Punch out the dest range. */
45498c2ecf20Sopenharmony_ci		pstart = ocfs2_clusters_to_bytes(t_inode->i_sb, tpos);
45508c2ecf20Sopenharmony_ci		plen = ocfs2_clusters_to_bytes(t_inode->i_sb, num_clusters);
45518c2ecf20Sopenharmony_ci		ret = ocfs2_remove_inode_range(t_inode, t_bh, pstart, plen);
45528c2ecf20Sopenharmony_ci		if (ret) {
45538c2ecf20Sopenharmony_ci			mlog_errno(ret);
45548c2ecf20Sopenharmony_ci			goto out;
45558c2ecf20Sopenharmony_ci		}
45568c2ecf20Sopenharmony_ci
45578c2ecf20Sopenharmony_ci		if (p_cluster == 0)
45588c2ecf20Sopenharmony_ci			goto next_loop;
45598c2ecf20Sopenharmony_ci
45608c2ecf20Sopenharmony_ci		/* Lock the refcount btree... */
45618c2ecf20Sopenharmony_ci		ret = ocfs2_lock_refcount_tree(osb,
45628c2ecf20Sopenharmony_ci					       le64_to_cpu(dis->i_refcount_loc),
45638c2ecf20Sopenharmony_ci					       1, &ref_tree, &ref_root_bh);
45648c2ecf20Sopenharmony_ci		if (ret) {
45658c2ecf20Sopenharmony_ci			mlog_errno(ret);
45668c2ecf20Sopenharmony_ci			goto out;
45678c2ecf20Sopenharmony_ci		}
45688c2ecf20Sopenharmony_ci
45698c2ecf20Sopenharmony_ci		/* Mark s_inode's extent as refcounted. */
45708c2ecf20Sopenharmony_ci		if (!(ext_flags & OCFS2_EXT_REFCOUNTED)) {
45718c2ecf20Sopenharmony_ci			ret = ocfs2_add_refcount_flag(s_inode, &s_et,
45728c2ecf20Sopenharmony_ci						      &ref_tree->rf_ci,
45738c2ecf20Sopenharmony_ci						      ref_root_bh, spos,
45748c2ecf20Sopenharmony_ci						      p_cluster, num_clusters,
45758c2ecf20Sopenharmony_ci						      dealloc, NULL);
45768c2ecf20Sopenharmony_ci			if (ret) {
45778c2ecf20Sopenharmony_ci				mlog_errno(ret);
45788c2ecf20Sopenharmony_ci				goto out_unlock_refcount;
45798c2ecf20Sopenharmony_ci			}
45808c2ecf20Sopenharmony_ci		}
45818c2ecf20Sopenharmony_ci
45828c2ecf20Sopenharmony_ci		/* Map in the new extent. */
45838c2ecf20Sopenharmony_ci		ext_flags |= OCFS2_EXT_REFCOUNTED;
45848c2ecf20Sopenharmony_ci		ret = ocfs2_add_refcounted_extent(t_inode, &t_et,
45858c2ecf20Sopenharmony_ci						  &ref_tree->rf_ci,
45868c2ecf20Sopenharmony_ci						  ref_root_bh,
45878c2ecf20Sopenharmony_ci						  tpos, p_cluster,
45888c2ecf20Sopenharmony_ci						  num_clusters,
45898c2ecf20Sopenharmony_ci						  ext_flags,
45908c2ecf20Sopenharmony_ci						  dealloc);
45918c2ecf20Sopenharmony_ci		if (ret) {
45928c2ecf20Sopenharmony_ci			mlog_errno(ret);
45938c2ecf20Sopenharmony_ci			goto out_unlock_refcount;
45948c2ecf20Sopenharmony_ci		}
45958c2ecf20Sopenharmony_ci
45968c2ecf20Sopenharmony_ci		ocfs2_unlock_refcount_tree(osb, ref_tree, 1);
45978c2ecf20Sopenharmony_ci		brelse(ref_root_bh);
45988c2ecf20Sopenharmony_cinext_loop:
45998c2ecf20Sopenharmony_ci		spos += num_clusters;
46008c2ecf20Sopenharmony_ci		tpos += num_clusters;
46018c2ecf20Sopenharmony_ci		remapped_clus += num_clusters;
46028c2ecf20Sopenharmony_ci	}
46038c2ecf20Sopenharmony_ci
46048c2ecf20Sopenharmony_ci	goto out;
46058c2ecf20Sopenharmony_ciout_unlock_refcount:
46068c2ecf20Sopenharmony_ci	ocfs2_unlock_refcount_tree(osb, ref_tree, 1);
46078c2ecf20Sopenharmony_ci	brelse(ref_root_bh);
46088c2ecf20Sopenharmony_ciout:
46098c2ecf20Sopenharmony_ci	remapped_bytes = ocfs2_clusters_to_bytes(t_inode->i_sb, remapped_clus);
46108c2ecf20Sopenharmony_ci	remapped_bytes = min_t(loff_t, len, remapped_bytes);
46118c2ecf20Sopenharmony_ci
46128c2ecf20Sopenharmony_ci	return remapped_bytes > 0 ? remapped_bytes : ret;
46138c2ecf20Sopenharmony_ci}
46148c2ecf20Sopenharmony_ci
46158c2ecf20Sopenharmony_ci/* Set up refcount tree and remap s_inode to t_inode. */
46168c2ecf20Sopenharmony_ciloff_t ocfs2_reflink_remap_blocks(struct inode *s_inode,
46178c2ecf20Sopenharmony_ci				  struct buffer_head *s_bh,
46188c2ecf20Sopenharmony_ci				  loff_t pos_in,
46198c2ecf20Sopenharmony_ci				  struct inode *t_inode,
46208c2ecf20Sopenharmony_ci				  struct buffer_head *t_bh,
46218c2ecf20Sopenharmony_ci				  loff_t pos_out,
46228c2ecf20Sopenharmony_ci				  loff_t len)
46238c2ecf20Sopenharmony_ci{
46248c2ecf20Sopenharmony_ci	struct ocfs2_cached_dealloc_ctxt dealloc;
46258c2ecf20Sopenharmony_ci	struct ocfs2_super *osb;
46268c2ecf20Sopenharmony_ci	struct ocfs2_dinode *dis;
46278c2ecf20Sopenharmony_ci	struct ocfs2_dinode *dit;
46288c2ecf20Sopenharmony_ci	loff_t ret;
46298c2ecf20Sopenharmony_ci
46308c2ecf20Sopenharmony_ci	osb = OCFS2_SB(s_inode->i_sb);
46318c2ecf20Sopenharmony_ci	dis = (struct ocfs2_dinode *)s_bh->b_data;
46328c2ecf20Sopenharmony_ci	dit = (struct ocfs2_dinode *)t_bh->b_data;
46338c2ecf20Sopenharmony_ci	ocfs2_init_dealloc_ctxt(&dealloc);
46348c2ecf20Sopenharmony_ci
46358c2ecf20Sopenharmony_ci	/*
46368c2ecf20Sopenharmony_ci	 * If we're reflinking the entire file and the source is inline
46378c2ecf20Sopenharmony_ci	 * data, just copy the contents.
46388c2ecf20Sopenharmony_ci	 */
46398c2ecf20Sopenharmony_ci	if (pos_in == pos_out && pos_in == 0 && len == i_size_read(s_inode) &&
46408c2ecf20Sopenharmony_ci	    i_size_read(t_inode) <= len &&
46418c2ecf20Sopenharmony_ci	    (OCFS2_I(s_inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL)) {
46428c2ecf20Sopenharmony_ci		ret = ocfs2_duplicate_inline_data(s_inode, s_bh, t_inode, t_bh);
46438c2ecf20Sopenharmony_ci		if (ret)
46448c2ecf20Sopenharmony_ci			mlog_errno(ret);
46458c2ecf20Sopenharmony_ci		goto out;
46468c2ecf20Sopenharmony_ci	}
46478c2ecf20Sopenharmony_ci
46488c2ecf20Sopenharmony_ci	/*
46498c2ecf20Sopenharmony_ci	 * If both inodes belong to two different refcount groups then
46508c2ecf20Sopenharmony_ci	 * forget it because we don't know how (or want) to go merging
46518c2ecf20Sopenharmony_ci	 * refcount trees.
46528c2ecf20Sopenharmony_ci	 */
46538c2ecf20Sopenharmony_ci	ret = -EOPNOTSUPP;
46548c2ecf20Sopenharmony_ci	if (ocfs2_is_refcount_inode(s_inode) &&
46558c2ecf20Sopenharmony_ci	    ocfs2_is_refcount_inode(t_inode) &&
46568c2ecf20Sopenharmony_ci	    le64_to_cpu(dis->i_refcount_loc) !=
46578c2ecf20Sopenharmony_ci	    le64_to_cpu(dit->i_refcount_loc))
46588c2ecf20Sopenharmony_ci		goto out;
46598c2ecf20Sopenharmony_ci
46608c2ecf20Sopenharmony_ci	/* Neither inode has a refcount tree.  Add one to s_inode. */
46618c2ecf20Sopenharmony_ci	if (!ocfs2_is_refcount_inode(s_inode) &&
46628c2ecf20Sopenharmony_ci	    !ocfs2_is_refcount_inode(t_inode)) {
46638c2ecf20Sopenharmony_ci		ret = ocfs2_create_refcount_tree(s_inode, s_bh);
46648c2ecf20Sopenharmony_ci		if (ret) {
46658c2ecf20Sopenharmony_ci			mlog_errno(ret);
46668c2ecf20Sopenharmony_ci			goto out;
46678c2ecf20Sopenharmony_ci		}
46688c2ecf20Sopenharmony_ci	}
46698c2ecf20Sopenharmony_ci
46708c2ecf20Sopenharmony_ci	/* Ensure that both inodes end up with the same refcount tree. */
46718c2ecf20Sopenharmony_ci	if (!ocfs2_is_refcount_inode(s_inode)) {
46728c2ecf20Sopenharmony_ci		ret = ocfs2_set_refcount_tree(s_inode, s_bh,
46738c2ecf20Sopenharmony_ci					      le64_to_cpu(dit->i_refcount_loc));
46748c2ecf20Sopenharmony_ci		if (ret) {
46758c2ecf20Sopenharmony_ci			mlog_errno(ret);
46768c2ecf20Sopenharmony_ci			goto out;
46778c2ecf20Sopenharmony_ci		}
46788c2ecf20Sopenharmony_ci	}
46798c2ecf20Sopenharmony_ci	if (!ocfs2_is_refcount_inode(t_inode)) {
46808c2ecf20Sopenharmony_ci		ret = ocfs2_set_refcount_tree(t_inode, t_bh,
46818c2ecf20Sopenharmony_ci					      le64_to_cpu(dis->i_refcount_loc));
46828c2ecf20Sopenharmony_ci		if (ret) {
46838c2ecf20Sopenharmony_ci			mlog_errno(ret);
46848c2ecf20Sopenharmony_ci			goto out;
46858c2ecf20Sopenharmony_ci		}
46868c2ecf20Sopenharmony_ci	}
46878c2ecf20Sopenharmony_ci
46888c2ecf20Sopenharmony_ci	/* Turn off inline data in the dest file. */
46898c2ecf20Sopenharmony_ci	if (OCFS2_I(t_inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
46908c2ecf20Sopenharmony_ci		ret = ocfs2_convert_inline_data_to_extents(t_inode, t_bh);
46918c2ecf20Sopenharmony_ci		if (ret) {
46928c2ecf20Sopenharmony_ci			mlog_errno(ret);
46938c2ecf20Sopenharmony_ci			goto out;
46948c2ecf20Sopenharmony_ci		}
46958c2ecf20Sopenharmony_ci	}
46968c2ecf20Sopenharmony_ci
46978c2ecf20Sopenharmony_ci	/* Actually remap extents now. */
46988c2ecf20Sopenharmony_ci	ret = ocfs2_reflink_remap_extent(s_inode, s_bh, pos_in, t_inode, t_bh,
46998c2ecf20Sopenharmony_ci					 pos_out, len, &dealloc);
47008c2ecf20Sopenharmony_ci	if (ret < 0) {
47018c2ecf20Sopenharmony_ci		mlog_errno(ret);
47028c2ecf20Sopenharmony_ci		goto out;
47038c2ecf20Sopenharmony_ci	}
47048c2ecf20Sopenharmony_ci
47058c2ecf20Sopenharmony_ciout:
47068c2ecf20Sopenharmony_ci	if (ocfs2_dealloc_has_cluster(&dealloc)) {
47078c2ecf20Sopenharmony_ci		ocfs2_schedule_truncate_log_flush(osb, 1);
47088c2ecf20Sopenharmony_ci		ocfs2_run_deallocs(osb, &dealloc);
47098c2ecf20Sopenharmony_ci	}
47108c2ecf20Sopenharmony_ci
47118c2ecf20Sopenharmony_ci	return ret;
47128c2ecf20Sopenharmony_ci}
47138c2ecf20Sopenharmony_ci
47148c2ecf20Sopenharmony_ci/* Lock an inode and grab a bh pointing to the inode. */
47158c2ecf20Sopenharmony_ciint ocfs2_reflink_inodes_lock(struct inode *s_inode,
47168c2ecf20Sopenharmony_ci			      struct buffer_head **bh_s,
47178c2ecf20Sopenharmony_ci			      struct inode *t_inode,
47188c2ecf20Sopenharmony_ci			      struct buffer_head **bh_t)
47198c2ecf20Sopenharmony_ci{
47208c2ecf20Sopenharmony_ci	struct inode *inode1 = s_inode;
47218c2ecf20Sopenharmony_ci	struct inode *inode2 = t_inode;
47228c2ecf20Sopenharmony_ci	struct ocfs2_inode_info *oi1;
47238c2ecf20Sopenharmony_ci	struct ocfs2_inode_info *oi2;
47248c2ecf20Sopenharmony_ci	struct buffer_head *bh1 = NULL;
47258c2ecf20Sopenharmony_ci	struct buffer_head *bh2 = NULL;
47268c2ecf20Sopenharmony_ci	bool same_inode = (s_inode == t_inode);
47278c2ecf20Sopenharmony_ci	bool need_swap = (inode1->i_ino > inode2->i_ino);
47288c2ecf20Sopenharmony_ci	int status;
47298c2ecf20Sopenharmony_ci
47308c2ecf20Sopenharmony_ci	/* First grab the VFS and rw locks. */
47318c2ecf20Sopenharmony_ci	lock_two_nondirectories(s_inode, t_inode);
47328c2ecf20Sopenharmony_ci	if (need_swap)
47338c2ecf20Sopenharmony_ci		swap(inode1, inode2);
47348c2ecf20Sopenharmony_ci
47358c2ecf20Sopenharmony_ci	status = ocfs2_rw_lock(inode1, 1);
47368c2ecf20Sopenharmony_ci	if (status) {
47378c2ecf20Sopenharmony_ci		mlog_errno(status);
47388c2ecf20Sopenharmony_ci		goto out_i1;
47398c2ecf20Sopenharmony_ci	}
47408c2ecf20Sopenharmony_ci	if (!same_inode) {
47418c2ecf20Sopenharmony_ci		status = ocfs2_rw_lock(inode2, 1);
47428c2ecf20Sopenharmony_ci		if (status) {
47438c2ecf20Sopenharmony_ci			mlog_errno(status);
47448c2ecf20Sopenharmony_ci			goto out_i2;
47458c2ecf20Sopenharmony_ci		}
47468c2ecf20Sopenharmony_ci	}
47478c2ecf20Sopenharmony_ci
47488c2ecf20Sopenharmony_ci	/* Now go for the cluster locks */
47498c2ecf20Sopenharmony_ci	oi1 = OCFS2_I(inode1);
47508c2ecf20Sopenharmony_ci	oi2 = OCFS2_I(inode2);
47518c2ecf20Sopenharmony_ci
47528c2ecf20Sopenharmony_ci	trace_ocfs2_double_lock((unsigned long long)oi1->ip_blkno,
47538c2ecf20Sopenharmony_ci				(unsigned long long)oi2->ip_blkno);
47548c2ecf20Sopenharmony_ci
47558c2ecf20Sopenharmony_ci	/* We always want to lock the one with the lower lockid first. */
47568c2ecf20Sopenharmony_ci	if (oi1->ip_blkno > oi2->ip_blkno)
47578c2ecf20Sopenharmony_ci		mlog_errno(-ENOLCK);
47588c2ecf20Sopenharmony_ci
47598c2ecf20Sopenharmony_ci	/* lock id1 */
47608c2ecf20Sopenharmony_ci	status = ocfs2_inode_lock_nested(inode1, &bh1, 1,
47618c2ecf20Sopenharmony_ci					 OI_LS_REFLINK_TARGET);
47628c2ecf20Sopenharmony_ci	if (status < 0) {
47638c2ecf20Sopenharmony_ci		if (status != -ENOENT)
47648c2ecf20Sopenharmony_ci			mlog_errno(status);
47658c2ecf20Sopenharmony_ci		goto out_rw2;
47668c2ecf20Sopenharmony_ci	}
47678c2ecf20Sopenharmony_ci
47688c2ecf20Sopenharmony_ci	/* lock id2 */
47698c2ecf20Sopenharmony_ci	if (!same_inode) {
47708c2ecf20Sopenharmony_ci		status = ocfs2_inode_lock_nested(inode2, &bh2, 1,
47718c2ecf20Sopenharmony_ci						 OI_LS_REFLINK_TARGET);
47728c2ecf20Sopenharmony_ci		if (status < 0) {
47738c2ecf20Sopenharmony_ci			if (status != -ENOENT)
47748c2ecf20Sopenharmony_ci				mlog_errno(status);
47758c2ecf20Sopenharmony_ci			goto out_cl1;
47768c2ecf20Sopenharmony_ci		}
47778c2ecf20Sopenharmony_ci	} else {
47788c2ecf20Sopenharmony_ci		bh2 = bh1;
47798c2ecf20Sopenharmony_ci	}
47808c2ecf20Sopenharmony_ci
47818c2ecf20Sopenharmony_ci	/*
47828c2ecf20Sopenharmony_ci	 * If we swapped inode order above, we have to swap the buffer heads
47838c2ecf20Sopenharmony_ci	 * before passing them back to the caller.
47848c2ecf20Sopenharmony_ci	 */
47858c2ecf20Sopenharmony_ci	if (need_swap)
47868c2ecf20Sopenharmony_ci		swap(bh1, bh2);
47878c2ecf20Sopenharmony_ci	*bh_s = bh1;
47888c2ecf20Sopenharmony_ci	*bh_t = bh2;
47898c2ecf20Sopenharmony_ci
47908c2ecf20Sopenharmony_ci	trace_ocfs2_double_lock_end(
47918c2ecf20Sopenharmony_ci			(unsigned long long)oi1->ip_blkno,
47928c2ecf20Sopenharmony_ci			(unsigned long long)oi2->ip_blkno);
47938c2ecf20Sopenharmony_ci
47948c2ecf20Sopenharmony_ci	return 0;
47958c2ecf20Sopenharmony_ci
47968c2ecf20Sopenharmony_ciout_cl1:
47978c2ecf20Sopenharmony_ci	ocfs2_inode_unlock(inode1, 1);
47988c2ecf20Sopenharmony_ci	brelse(bh1);
47998c2ecf20Sopenharmony_ciout_rw2:
48008c2ecf20Sopenharmony_ci	ocfs2_rw_unlock(inode2, 1);
48018c2ecf20Sopenharmony_ciout_i2:
48028c2ecf20Sopenharmony_ci	ocfs2_rw_unlock(inode1, 1);
48038c2ecf20Sopenharmony_ciout_i1:
48048c2ecf20Sopenharmony_ci	unlock_two_nondirectories(s_inode, t_inode);
48058c2ecf20Sopenharmony_ci	return status;
48068c2ecf20Sopenharmony_ci}
48078c2ecf20Sopenharmony_ci
48088c2ecf20Sopenharmony_ci/* Unlock both inodes and release buffers. */
48098c2ecf20Sopenharmony_civoid ocfs2_reflink_inodes_unlock(struct inode *s_inode,
48108c2ecf20Sopenharmony_ci				 struct buffer_head *s_bh,
48118c2ecf20Sopenharmony_ci				 struct inode *t_inode,
48128c2ecf20Sopenharmony_ci				 struct buffer_head *t_bh)
48138c2ecf20Sopenharmony_ci{
48148c2ecf20Sopenharmony_ci	ocfs2_inode_unlock(s_inode, 1);
48158c2ecf20Sopenharmony_ci	ocfs2_rw_unlock(s_inode, 1);
48168c2ecf20Sopenharmony_ci	brelse(s_bh);
48178c2ecf20Sopenharmony_ci	if (s_inode != t_inode) {
48188c2ecf20Sopenharmony_ci		ocfs2_inode_unlock(t_inode, 1);
48198c2ecf20Sopenharmony_ci		ocfs2_rw_unlock(t_inode, 1);
48208c2ecf20Sopenharmony_ci		brelse(t_bh);
48218c2ecf20Sopenharmony_ci	}
48228c2ecf20Sopenharmony_ci	unlock_two_nondirectories(s_inode, t_inode);
48238c2ecf20Sopenharmony_ci}
4824