summaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/refcounttree.h
blob: e9e862be4a1e51cb55fe129d996bf08731d8c220 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/* -*- mode: c; c-basic-offset: 8; -*-
 * vim: noexpandtab sw=8 ts=8 sts=0:
 *
 * refcounttree.h
 *
 * Copyright (C) 2009 Oracle.  All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 */
#ifndef OCFS2_REFCOUNTTREE_H
#define OCFS2_REFCOUNTTREE_H

struct ocfs2_refcount_tree {
	struct rb_node rf_node;
	u64 rf_blkno;
	u32 rf_generation;
	struct kref rf_getcnt;
	struct rw_semaphore rf_sem;
	struct ocfs2_lock_res rf_lockres;
	int rf_removed;

	/* the following 4 fields are used by caching_info. */
	spinlock_t rf_lock;
	struct ocfs2_caching_info rf_ci;
	struct mutex rf_io_mutex;
	struct super_block *rf_sb;
};

void ocfs2_purge_refcount_trees(struct ocfs2_super *osb);
int ocfs2_lock_refcount_tree(struct ocfs2_super *osb, u64 ref_blkno, int rw,
			     struct ocfs2_refcount_tree **tree,
			     struct buffer_head **ref_bh);
void ocfs2_unlock_refcount_tree(struct ocfs2_super *osb,
				struct ocfs2_refcount_tree *tree,
				int rw);

int ocfs2_decrease_refcount(struct inode *inode,
			    handle_t *handle, u32 cpos, u32 len,
			    struct ocfs2_alloc_context *meta_ac,
			    struct ocfs2_cached_dealloc_ctxt *dealloc,
			    int delete);
int ocfs2_prepare_refcount_change_for_del(struct inode *inode,
					  u64 refcount_loc,
					  u64 phys_blkno,
					  u32 clusters,
					  int *credits,
					  int *ref_blocks);
int ocfs2_refcount_cow(struct inode *inode,
		       struct buffer_head *di_bh,
		       u32 cpos, u32 write_len, u32 max_cpos);

typedef int (ocfs2_post_refcount_func)(struct inode *inode,
				       handle_t *handle,
				       void *para);
/*
 * Some refcount caller need to do more work after we modify the data b-tree
 * during refcount operation(including CoW and add refcount flag), and make the
 * transaction complete. So it must give us this structure so that we can do it
 * within our transaction.
 *
 */
struct ocfs2_post_refcount {
	int credits;			/* credits it need for journal. */
	ocfs2_post_refcount_func *func;	/* real function. */
	void *para;
};

int ocfs2_refcounted_xattr_delete_need(struct inode *inode,
				       struct ocfs2_caching_info *ref_ci,
				       struct buffer_head *ref_root_bh,
				       struct ocfs2_xattr_value_root *xv,
				       int *meta_add, int *credits);
int ocfs2_refcount_cow_xattr(struct inode *inode,
			     struct ocfs2_dinode *di,
			     struct ocfs2_xattr_value_buf *vb,
			     struct ocfs2_refcount_tree *ref_tree,
			     struct buffer_head *ref_root_bh,
			     u32 cpos, u32 write_len,
			     struct ocfs2_post_refcount *post);
int ocfs2_duplicate_clusters_by_page(handle_t *handle,
				     struct inode *inode,
				     u32 cpos, u32 old_cluster,
				     u32 new_cluster, u32 new_len);
int ocfs2_duplicate_clusters_by_jbd(handle_t *handle,
				    struct inode *inode,
				    u32 cpos, u32 old_cluster,
				    u32 new_cluster, u32 new_len);
int ocfs2_cow_sync_writeback(struct super_block *sb,
			     struct inode *inode,
			     u32 cpos, u32 num_clusters);
int ocfs2_add_refcount_flag(struct inode *inode,
			    struct ocfs2_extent_tree *data_et,
			    struct ocfs2_caching_info *ref_ci,
			    struct buffer_head *ref_root_bh,
			    u32 cpos, u32 p_cluster, u32 num_clusters,
			    struct ocfs2_cached_dealloc_ctxt *dealloc,
			    struct ocfs2_post_refcount *post);
int ocfs2_remove_refcount_tree(struct inode *inode, struct buffer_head *di_bh);
int ocfs2_try_remove_refcount_tree(struct inode *inode,
				   struct buffer_head *di_bh);
int ocfs2_increase_refcount(handle_t *handle,
			    struct ocfs2_caching_info *ci,
			    struct buffer_head *ref_root_bh,
			    u64 cpos, u32 len,
			    struct ocfs2_alloc_context *meta_ac,
			    struct ocfs2_cached_dealloc_ctxt *dealloc);
int ocfs2_reflink_ioctl(struct inode *inode,
			const char __user *oldname,
			const char __user *newname,
			bool preserve);
loff_t ocfs2_reflink_remap_blocks(struct inode *s_inode,
				  struct buffer_head *s_bh,
				  loff_t pos_in,
				  struct inode *t_inode,
				  struct buffer_head *t_bh,
				  loff_t pos_out,
				  loff_t len);
int ocfs2_reflink_inodes_lock(struct inode *s_inode,
			      struct buffer_head **bh1,
			      struct inode *t_inode,
			      struct buffer_head **bh2);
void ocfs2_reflink_inodes_unlock(struct inode *s_inode,
				 struct buffer_head *s_bh,
				 struct inode *t_inode,
				 struct buffer_head *t_bh);
int ocfs2_reflink_update_dest(struct inode *dest,
			      struct buffer_head *d_bh,
			      loff_t newlen);

#endif /* OCFS2_REFCOUNTTREE_H */