Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/fs/btrfs/delayed-inode.h
29267 views
1
/* SPDX-License-Identifier: GPL-2.0 */
2
/*
3
* Copyright (C) 2011 Fujitsu. All rights reserved.
4
* Written by Miao Xie <[email protected]>
5
*/
6
7
#ifndef BTRFS_DELAYED_INODE_H
8
#define BTRFS_DELAYED_INODE_H
9
10
#include <linux/types.h>
11
#include <linux/rbtree.h>
12
#include <linux/spinlock.h>
13
#include <linux/mutex.h>
14
#include <linux/list.h>
15
#include <linux/wait.h>
16
#include <linux/fs.h>
17
#include <linux/atomic.h>
18
#include <linux/refcount.h>
19
#include <linux/ref_tracker.h>
20
#include "ctree.h"
21
22
struct btrfs_disk_key;
23
struct btrfs_fs_info;
24
struct btrfs_inode;
25
struct btrfs_root;
26
struct btrfs_trans_handle;
27
28
enum btrfs_delayed_item_type {
29
BTRFS_DELAYED_INSERTION_ITEM,
30
BTRFS_DELAYED_DELETION_ITEM
31
};
32
33
struct btrfs_delayed_root {
34
spinlock_t lock;
35
struct list_head node_list;
36
/*
37
* Used for delayed nodes which is waiting to be dealt with by the
38
* worker. If the delayed node is inserted into the work queue, we
39
* drop it from this list.
40
*/
41
struct list_head prepare_list;
42
atomic_t items; /* for delayed items */
43
atomic_t items_seq; /* for delayed items */
44
int nodes; /* for delayed nodes */
45
wait_queue_head_t wait;
46
};
47
48
struct btrfs_ref_tracker_dir {
49
#ifdef CONFIG_BTRFS_DEBUG
50
struct ref_tracker_dir dir;
51
#else
52
struct {} tracker;
53
#endif
54
};
55
56
struct btrfs_ref_tracker {
57
#ifdef CONFIG_BTRFS_DEBUG
58
struct ref_tracker *tracker;
59
#else
60
struct {} tracker;
61
#endif
62
};
63
64
#define BTRFS_DELAYED_NODE_IN_LIST 0
65
#define BTRFS_DELAYED_NODE_INODE_DIRTY 1
66
#define BTRFS_DELAYED_NODE_DEL_IREF 2
67
68
struct btrfs_delayed_node {
69
u64 inode_id;
70
u64 bytes_reserved;
71
struct btrfs_root *root;
72
/* Used to add the node into the delayed root's node list. */
73
struct list_head n_list;
74
/*
75
* Used to add the node into the prepare list, the nodes in this list
76
* is waiting to be dealt with by the async worker.
77
*/
78
struct list_head p_list;
79
struct rb_root_cached ins_root;
80
struct rb_root_cached del_root;
81
struct mutex mutex;
82
struct btrfs_inode_item inode_item;
83
refcount_t refs;
84
int count;
85
u64 index_cnt;
86
unsigned long flags;
87
/*
88
* The size of the next batch of dir index items to insert (if this
89
* node is from a directory inode). Protected by @mutex.
90
*/
91
u32 curr_index_batch_size;
92
/*
93
* Number of leaves reserved for inserting dir index items (if this
94
* node belongs to a directory inode). This may be larger then the
95
* actual number of leaves we end up using. Protected by @mutex.
96
*/
97
u32 index_item_leaves;
98
/* Track all references to this delayed node. */
99
struct btrfs_ref_tracker_dir ref_dir;
100
/* Track delayed node reference stored in node list. */
101
struct btrfs_ref_tracker node_list_tracker;
102
/* Track delayed node reference stored in inode cache. */
103
struct btrfs_ref_tracker inode_cache_tracker;
104
};
105
106
struct btrfs_delayed_item {
107
struct rb_node rb_node;
108
/* Offset value of the corresponding dir index key. */
109
u64 index;
110
struct list_head tree_list; /* used for batch insert/delete items */
111
struct list_head readdir_list; /* used for readdir items */
112
/*
113
* Used when logging a directory.
114
* Insertions and deletions to this list are protected by the parent
115
* delayed node's mutex.
116
*/
117
struct list_head log_list;
118
u64 bytes_reserved;
119
struct btrfs_delayed_node *delayed_node;
120
refcount_t refs;
121
enum btrfs_delayed_item_type type:8;
122
/*
123
* Track if this delayed item was already logged.
124
* Protected by the mutex of the parent delayed inode.
125
*/
126
bool logged;
127
/* The maximum leaf size is 64K, so u16 is more than enough. */
128
u16 data_len;
129
char data[] __counted_by(data_len);
130
};
131
132
void btrfs_init_delayed_root(struct btrfs_delayed_root *delayed_root);
133
int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans,
134
const char *name, int name_len,
135
struct btrfs_inode *dir,
136
const struct btrfs_disk_key *disk_key, u8 flags,
137
u64 index);
138
139
int btrfs_delete_delayed_dir_index(struct btrfs_trans_handle *trans,
140
struct btrfs_inode *dir, u64 index);
141
142
int btrfs_inode_delayed_dir_index_count(struct btrfs_inode *inode);
143
144
int btrfs_run_delayed_items(struct btrfs_trans_handle *trans);
145
int btrfs_run_delayed_items_nr(struct btrfs_trans_handle *trans, int nr);
146
147
void btrfs_balance_delayed_items(struct btrfs_fs_info *fs_info);
148
149
int btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans,
150
struct btrfs_inode *inode);
151
/* Used for evicting the inode. */
152
void btrfs_remove_delayed_node(struct btrfs_inode *inode);
153
void btrfs_kill_delayed_inode_items(struct btrfs_inode *inode);
154
int btrfs_commit_inode_delayed_inode(struct btrfs_inode *inode);
155
156
157
int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans,
158
struct btrfs_inode *inode);
159
int btrfs_fill_inode(struct btrfs_inode *inode, u32 *rdev);
160
int btrfs_delayed_delete_inode_ref(struct btrfs_inode *inode);
161
162
/* Used for drop dead root */
163
void btrfs_kill_all_delayed_nodes(struct btrfs_root *root);
164
165
/* Used for clean the transaction */
166
void btrfs_destroy_delayed_inodes(struct btrfs_fs_info *fs_info);
167
168
/* Used for readdir() */
169
bool btrfs_readdir_get_delayed_items(struct btrfs_inode *inode,
170
u64 last_index,
171
struct list_head *ins_list,
172
struct list_head *del_list);
173
void btrfs_readdir_put_delayed_items(struct btrfs_inode *inode,
174
struct list_head *ins_list,
175
struct list_head *del_list);
176
bool btrfs_should_delete_dir_index(const struct list_head *del_list, u64 index);
177
bool btrfs_readdir_delayed_dir_index(struct dir_context *ctx,
178
const struct list_head *ins_list);
179
180
/* Used during directory logging. */
181
void btrfs_log_get_delayed_items(struct btrfs_inode *inode,
182
struct list_head *ins_list,
183
struct list_head *del_list);
184
void btrfs_log_put_delayed_items(struct btrfs_inode *inode,
185
struct list_head *ins_list,
186
struct list_head *del_list);
187
188
/* for init */
189
int __init btrfs_delayed_inode_init(void);
190
void __cold btrfs_delayed_inode_exit(void);
191
192
/* for debugging */
193
void btrfs_assert_delayed_root_empty(struct btrfs_fs_info *fs_info);
194
195
#define BTRFS_DELAYED_NODE_REF_TRACKER_QUARANTINE_COUNT 16
196
#define BTRFS_DELAYED_NODE_REF_TRACKER_DISPLAY_LIMIT 16
197
198
#ifdef CONFIG_BTRFS_DEBUG
199
static inline void btrfs_delayed_node_ref_tracker_dir_init(struct btrfs_delayed_node *node)
200
{
201
if (!btrfs_test_opt(node->root->fs_info, REF_TRACKER))
202
return;
203
204
ref_tracker_dir_init(&node->ref_dir.dir,
205
BTRFS_DELAYED_NODE_REF_TRACKER_QUARANTINE_COUNT,
206
"delayed_node");
207
}
208
209
static inline void btrfs_delayed_node_ref_tracker_dir_exit(struct btrfs_delayed_node *node)
210
{
211
if (!btrfs_test_opt(node->root->fs_info, REF_TRACKER))
212
return;
213
214
ref_tracker_dir_exit(&node->ref_dir.dir);
215
}
216
217
static inline void btrfs_delayed_node_ref_tracker_dir_print(struct btrfs_delayed_node *node)
218
{
219
if (!btrfs_test_opt(node->root->fs_info, REF_TRACKER))
220
return;
221
222
ref_tracker_dir_print(&node->ref_dir.dir,
223
BTRFS_DELAYED_NODE_REF_TRACKER_DISPLAY_LIMIT);
224
}
225
226
static inline int btrfs_delayed_node_ref_tracker_alloc(struct btrfs_delayed_node *node,
227
struct btrfs_ref_tracker *tracker,
228
gfp_t gfp)
229
{
230
if (!btrfs_test_opt(node->root->fs_info, REF_TRACKER))
231
return 0;
232
233
return ref_tracker_alloc(&node->ref_dir.dir, &tracker->tracker, gfp);
234
}
235
236
static inline int btrfs_delayed_node_ref_tracker_free(struct btrfs_delayed_node *node,
237
struct btrfs_ref_tracker *tracker)
238
{
239
if (!btrfs_test_opt(node->root->fs_info, REF_TRACKER))
240
return 0;
241
242
return ref_tracker_free(&node->ref_dir.dir, &tracker->tracker);
243
}
244
#else
245
static inline void btrfs_delayed_node_ref_tracker_dir_init(struct btrfs_delayed_node *node) { }
246
247
static inline void btrfs_delayed_node_ref_tracker_dir_exit(struct btrfs_delayed_node *node) { }
248
249
static inline void btrfs_delayed_node_ref_tracker_dir_print(struct btrfs_delayed_node *node) { }
250
251
static inline int btrfs_delayed_node_ref_tracker_alloc(struct btrfs_delayed_node *node,
252
struct btrfs_ref_tracker *tracker,
253
gfp_t gfp)
254
{
255
return 0;
256
}
257
258
static inline int btrfs_delayed_node_ref_tracker_free(struct btrfs_delayed_node *node,
259
struct btrfs_ref_tracker *tracker)
260
{
261
return 0;
262
}
263
#endif
264
265
#endif
266
267