Blame view

fs/btrfs/transaction.c 36.3 KB
6cbd55707   Chris Mason   Btrfs: add GPLv2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  /*
   * Copyright (C) 2007 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 v2 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.
   *
   * You should have received a copy of the GNU General Public
   * License along with this program; if not, write to the
   * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   * Boston, MA 021110-1307, USA.
   */
79154b1b5   Chris Mason   Btrfs: transactio...
18
  #include <linux/fs.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
19
  #include <linux/slab.h>
340887809   Chris Mason   Btrfs: i386 fixes...
20
  #include <linux/sched.h>
d3c2fdcf7   Chris Mason   Btrfs: Use balanc...
21
  #include <linux/writeback.h>
5f39d397d   Chris Mason   Btrfs: Create ext...
22
  #include <linux/pagemap.h>
5f2cc086c   Chris Mason   Btrfs: Avoid unpl...
23
  #include <linux/blkdev.h>
79154b1b5   Chris Mason   Btrfs: transactio...
24
25
26
  #include "ctree.h"
  #include "disk-io.h"
  #include "transaction.h"
925baeddc   Chris Mason   Btrfs: Start btre...
27
  #include "locking.h"
e02119d5a   Chris Mason   Btrfs: Add a writ...
28
  #include "tree-log.h"
581bb0509   Li Zefan   Btrfs: Cache free...
29
  #include "inode-map.h"
79154b1b5   Chris Mason   Btrfs: transactio...
30

0f7d52f44   Chris Mason   Btrfs: groundwork...
31
  #define BTRFS_ROOT_TRANS_TAG 0
80b6794d1   Chris Mason   Btrfs: Lower stac...
32
  static noinline void put_transaction(struct btrfs_transaction *transaction)
79154b1b5   Chris Mason   Btrfs: transactio...
33
  {
13c5a93e7   Josef Bacik   Btrfs: avoid taki...
34
35
  	WARN_ON(atomic_read(&transaction->use_count) == 0);
  	if (atomic_dec_and_test(&transaction->use_count)) {
a4abeea41   Josef Bacik   Btrfs: kill trans...
36
  		BUG_ON(!list_empty(&transaction->list));
2c90e5d65   Chris Mason   Btrfs: still corr...
37
38
  		memset(transaction, 0, sizeof(*transaction));
  		kmem_cache_free(btrfs_transaction_cachep, transaction);
78fae27eb   Chris Mason   Btrfs: leak fixes...
39
  	}
79154b1b5   Chris Mason   Btrfs: transactio...
40
  }
817d52f8d   Josef Bacik   Btrfs: async bloc...
41
42
  static noinline void switch_commit_root(struct btrfs_root *root)
  {
817d52f8d   Josef Bacik   Btrfs: async bloc...
43
44
  	free_extent_buffer(root->commit_root);
  	root->commit_root = btrfs_root_node(root);
817d52f8d   Josef Bacik   Btrfs: async bloc...
45
  }
d352ac681   Chris Mason   Btrfs: add and im...
46
47
48
  /*
   * either allocate a new transaction or hop into the existing one
   */
a4abeea41   Josef Bacik   Btrfs: kill trans...
49
  static noinline int join_transaction(struct btrfs_root *root, int nofail)
79154b1b5   Chris Mason   Btrfs: transactio...
50
51
  {
  	struct btrfs_transaction *cur_trans;
a4abeea41   Josef Bacik   Btrfs: kill trans...
52
53
  
  	spin_lock(&root->fs_info->trans_lock);
d43317dcd   Chris Mason   Btrfs: fix race d...
54
  loop:
a4abeea41   Josef Bacik   Btrfs: kill trans...
55
56
57
58
59
60
  	if (root->fs_info->trans_no_join) {
  		if (!nofail) {
  			spin_unlock(&root->fs_info->trans_lock);
  			return -EBUSY;
  		}
  	}
79154b1b5   Chris Mason   Btrfs: transactio...
61
  	cur_trans = root->fs_info->running_transaction;
a4abeea41   Josef Bacik   Btrfs: kill trans...
62
63
  	if (cur_trans) {
  		atomic_inc(&cur_trans->use_count);
13c5a93e7   Josef Bacik   Btrfs: avoid taki...
64
  		atomic_inc(&cur_trans->num_writers);
15ee9bc7e   Josef Bacik   Btrfs: delay comm...
65
  		cur_trans->num_joined++;
a4abeea41   Josef Bacik   Btrfs: kill trans...
66
67
  		spin_unlock(&root->fs_info->trans_lock);
  		return 0;
79154b1b5   Chris Mason   Btrfs: transactio...
68
  	}
a4abeea41   Josef Bacik   Btrfs: kill trans...
69
70
71
72
73
  	spin_unlock(&root->fs_info->trans_lock);
  
  	cur_trans = kmem_cache_alloc(btrfs_transaction_cachep, GFP_NOFS);
  	if (!cur_trans)
  		return -ENOMEM;
d43317dcd   Chris Mason   Btrfs: fix race d...
74

a4abeea41   Josef Bacik   Btrfs: kill trans...
75
76
  	spin_lock(&root->fs_info->trans_lock);
  	if (root->fs_info->running_transaction) {
d43317dcd   Chris Mason   Btrfs: fix race d...
77
78
79
80
  		/*
  		 * someone started a transaction after we unlocked.  Make sure
  		 * to redo the trans_no_join checks above
  		 */
a4abeea41   Josef Bacik   Btrfs: kill trans...
81
82
  		kmem_cache_free(btrfs_transaction_cachep, cur_trans);
  		cur_trans = root->fs_info->running_transaction;
d43317dcd   Chris Mason   Btrfs: fix race d...
83
  		goto loop;
79154b1b5   Chris Mason   Btrfs: transactio...
84
  	}
d43317dcd   Chris Mason   Btrfs: fix race d...
85

a4abeea41   Josef Bacik   Btrfs: kill trans...
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
  	atomic_set(&cur_trans->num_writers, 1);
  	cur_trans->num_joined = 0;
  	init_waitqueue_head(&cur_trans->writer_wait);
  	init_waitqueue_head(&cur_trans->commit_wait);
  	cur_trans->in_commit = 0;
  	cur_trans->blocked = 0;
  	/*
  	 * One for this trans handle, one so it will live on until we
  	 * commit the transaction.
  	 */
  	atomic_set(&cur_trans->use_count, 2);
  	cur_trans->commit_done = 0;
  	cur_trans->start_time = get_seconds();
  
  	cur_trans->delayed_refs.root = RB_ROOT;
  	cur_trans->delayed_refs.num_entries = 0;
  	cur_trans->delayed_refs.num_heads_ready = 0;
  	cur_trans->delayed_refs.num_heads = 0;
  	cur_trans->delayed_refs.flushing = 0;
  	cur_trans->delayed_refs.run_delayed_start = 0;
  	spin_lock_init(&cur_trans->commit_lock);
  	spin_lock_init(&cur_trans->delayed_refs.lock);
  
  	INIT_LIST_HEAD(&cur_trans->pending_snapshots);
  	list_add_tail(&cur_trans->list, &root->fs_info->trans_list);
  	extent_io_tree_init(&cur_trans->dirty_pages,
ff5714cca   Chris Mason   Merge branch 'for...
112
  			     root->fs_info->btree_inode->i_mapping);
a4abeea41   Josef Bacik   Btrfs: kill trans...
113
114
115
116
  	root->fs_info->generation++;
  	cur_trans->transid = root->fs_info->generation;
  	root->fs_info->running_transaction = cur_trans;
  	spin_unlock(&root->fs_info->trans_lock);
15ee9bc7e   Josef Bacik   Btrfs: delay comm...
117

79154b1b5   Chris Mason   Btrfs: transactio...
118
119
  	return 0;
  }
d352ac681   Chris Mason   Btrfs: add and im...
120
  /*
d397712bc   Chris Mason   Btrfs: Fix checkp...
121
122
123
124
   * this does all the record keeping required to make sure that a reference
   * counted root is properly recorded in a given transaction.  This is required
   * to make sure the old root from before we joined the transaction is deleted
   * when the transaction commits
d352ac681   Chris Mason   Btrfs: add and im...
125
   */
7585717f3   Chris Mason   Btrfs: fix reloca...
126
  static int record_root_in_trans(struct btrfs_trans_handle *trans,
a4abeea41   Josef Bacik   Btrfs: kill trans...
127
  			       struct btrfs_root *root)
6702ed490   Chris Mason   Btrfs: Add run ti...
128
  {
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
129
  	if (root->ref_cows && root->last_trans < trans->transid) {
6702ed490   Chris Mason   Btrfs: Add run ti...
130
  		WARN_ON(root == root->fs_info->extent_root);
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
131
  		WARN_ON(root->commit_root != root->node);
7585717f3   Chris Mason   Btrfs: fix reloca...
132
133
134
135
136
137
138
139
140
141
142
  		/*
  		 * see below for in_trans_setup usage rules
  		 * we have the reloc mutex held now, so there
  		 * is only one writer in this function
  		 */
  		root->in_trans_setup = 1;
  
  		/* make sure readers find in_trans_setup before
  		 * they find our root->last_trans update
  		 */
  		smp_wmb();
a4abeea41   Josef Bacik   Btrfs: kill trans...
143
144
145
146
147
  		spin_lock(&root->fs_info->fs_roots_radix_lock);
  		if (root->last_trans == trans->transid) {
  			spin_unlock(&root->fs_info->fs_roots_radix_lock);
  			return 0;
  		}
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
148
149
150
  		radix_tree_tag_set(&root->fs_info->fs_roots_radix,
  			   (unsigned long)root->root_key.objectid,
  			   BTRFS_ROOT_TRANS_TAG);
a4abeea41   Josef Bacik   Btrfs: kill trans...
151
  		spin_unlock(&root->fs_info->fs_roots_radix_lock);
7585717f3   Chris Mason   Btrfs: fix reloca...
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
  		root->last_trans = trans->transid;
  
  		/* this is pretty tricky.  We don't want to
  		 * take the relocation lock in btrfs_record_root_in_trans
  		 * unless we're really doing the first setup for this root in
  		 * this transaction.
  		 *
  		 * Normally we'd use root->last_trans as a flag to decide
  		 * if we want to take the expensive mutex.
  		 *
  		 * But, we have to set root->last_trans before we
  		 * init the relocation root, otherwise, we trip over warnings
  		 * in ctree.c.  The solution used here is to flag ourselves
  		 * with root->in_trans_setup.  When this is 1, we're still
  		 * fixing up the reloc trees and everyone must wait.
  		 *
  		 * When this is zero, they can trust root->last_trans and fly
  		 * through btrfs_record_root_in_trans without having to take the
  		 * lock.  smp_wmb() makes sure that all the writes above are
  		 * done before we pop in the zero below
  		 */
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
173
  		btrfs_init_reloc_root(trans, root);
7585717f3   Chris Mason   Btrfs: fix reloca...
174
175
  		smp_wmb();
  		root->in_trans_setup = 0;
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
176
177
178
  	}
  	return 0;
  }
bcc63abbf   Yan   Btrfs: implement ...
179

7585717f3   Chris Mason   Btrfs: fix reloca...
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
  
  int btrfs_record_root_in_trans(struct btrfs_trans_handle *trans,
  			       struct btrfs_root *root)
  {
  	if (!root->ref_cows)
  		return 0;
  
  	/*
  	 * see record_root_in_trans for comments about in_trans_setup usage
  	 * and barriers
  	 */
  	smp_rmb();
  	if (root->last_trans == trans->transid &&
  	    !root->in_trans_setup)
  		return 0;
  
  	mutex_lock(&root->fs_info->reloc_mutex);
  	record_root_in_trans(trans, root);
  	mutex_unlock(&root->fs_info->reloc_mutex);
  
  	return 0;
  }
d352ac681   Chris Mason   Btrfs: add and im...
202
203
204
205
  /* wait for commit against the current transaction to become unblocked
   * when this is done, it is safe to start a new transaction, but the current
   * transaction might not be fully on disk.
   */
37d1aeee3   Chris Mason   Btrfs: Throttle t...
206
  static void wait_current_trans(struct btrfs_root *root)
79154b1b5   Chris Mason   Btrfs: transactio...
207
  {
f92957493   Chris Mason   btrfs_start_trans...
208
  	struct btrfs_transaction *cur_trans;
79154b1b5   Chris Mason   Btrfs: transactio...
209

a4abeea41   Josef Bacik   Btrfs: kill trans...
210
  	spin_lock(&root->fs_info->trans_lock);
f92957493   Chris Mason   btrfs_start_trans...
211
  	cur_trans = root->fs_info->running_transaction;
37d1aeee3   Chris Mason   Btrfs: Throttle t...
212
  	if (cur_trans && cur_trans->blocked) {
13c5a93e7   Josef Bacik   Btrfs: avoid taki...
213
  		atomic_inc(&cur_trans->use_count);
a4abeea41   Josef Bacik   Btrfs: kill trans...
214
  		spin_unlock(&root->fs_info->trans_lock);
72d63ed64   Li Zefan   Btrfs: use wait_e...
215
216
217
  
  		wait_event(root->fs_info->transaction_wait,
  			   !cur_trans->blocked);
f92957493   Chris Mason   btrfs_start_trans...
218
  		put_transaction(cur_trans);
a4abeea41   Josef Bacik   Btrfs: kill trans...
219
220
  	} else {
  		spin_unlock(&root->fs_info->trans_lock);
f92957493   Chris Mason   btrfs_start_trans...
221
  	}
37d1aeee3   Chris Mason   Btrfs: Throttle t...
222
  }
249ac1e55   Josef Bacik   Btrfs: cleanup tr...
223
224
225
226
  enum btrfs_trans_type {
  	TRANS_START,
  	TRANS_JOIN,
  	TRANS_USERSPACE,
0af3d00ba   Josef Bacik   Btrfs: create spe...
227
  	TRANS_JOIN_NOLOCK,
249ac1e55   Josef Bacik   Btrfs: cleanup tr...
228
  };
a22285a6a   Yan, Zheng   Btrfs: Integrate ...
229
230
  static int may_wait_transaction(struct btrfs_root *root, int type)
  {
a4abeea41   Josef Bacik   Btrfs: kill trans...
231
232
233
234
235
236
237
238
  	if (root->fs_info->log_root_recovering)
  		return 0;
  
  	if (type == TRANS_USERSPACE)
  		return 1;
  
  	if (type == TRANS_START &&
  	    !atomic_read(&root->fs_info->open_ioctl_trans))
a22285a6a   Yan, Zheng   Btrfs: Integrate ...
239
  		return 1;
a4abeea41   Josef Bacik   Btrfs: kill trans...
240

a22285a6a   Yan, Zheng   Btrfs: Integrate ...
241
242
  	return 0;
  }
e02119d5a   Chris Mason   Btrfs: Add a writ...
243
  static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
a22285a6a   Yan, Zheng   Btrfs: Integrate ...
244
  						    u64 num_items, int type)
37d1aeee3   Chris Mason   Btrfs: Throttle t...
245
  {
a22285a6a   Yan, Zheng   Btrfs: Integrate ...
246
247
  	struct btrfs_trans_handle *h;
  	struct btrfs_transaction *cur_trans;
b5009945b   Josef Bacik   Btrfs: do transac...
248
  	u64 num_bytes = 0;
37d1aeee3   Chris Mason   Btrfs: Throttle t...
249
  	int ret;
acce952b0   liubo   Btrfs: forced rea...
250
251
252
  
  	if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR)
  		return ERR_PTR(-EROFS);
2a1eb4614   Josef Bacik   Btrfs: if we've a...
253
254
255
256
257
258
259
260
261
  
  	if (current->journal_info) {
  		WARN_ON(type != TRANS_JOIN && type != TRANS_JOIN_NOLOCK);
  		h = current->journal_info;
  		h->use_count++;
  		h->orig_rsv = h->block_rsv;
  		h->block_rsv = NULL;
  		goto got_it;
  	}
b5009945b   Josef Bacik   Btrfs: do transac...
262
263
264
265
266
267
268
  
  	/*
  	 * Do the reservation before we join the transaction so we can do all
  	 * the appropriate flushing if need be.
  	 */
  	if (num_items > 0 && root != root->fs_info->chunk_root) {
  		num_bytes = btrfs_calc_trans_metadata_size(root, num_items);
4a92b1b8d   Josef Bacik   Btrfs: stop passi...
269
  		ret = btrfs_block_rsv_add(root,
b5009945b   Josef Bacik   Btrfs: do transac...
270
271
272
273
274
  					  &root->fs_info->trans_block_rsv,
  					  num_bytes);
  		if (ret)
  			return ERR_PTR(ret);
  	}
a22285a6a   Yan, Zheng   Btrfs: Integrate ...
275
276
277
278
  again:
  	h = kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS);
  	if (!h)
  		return ERR_PTR(-ENOMEM);
37d1aeee3   Chris Mason   Btrfs: Throttle t...
279

a22285a6a   Yan, Zheng   Btrfs: Integrate ...
280
  	if (may_wait_transaction(root, type))
37d1aeee3   Chris Mason   Btrfs: Throttle t...
281
  		wait_current_trans(root);
a22285a6a   Yan, Zheng   Btrfs: Integrate ...
282

a4abeea41   Josef Bacik   Btrfs: kill trans...
283
284
285
286
287
  	do {
  		ret = join_transaction(root, type == TRANS_JOIN_NOLOCK);
  		if (ret == -EBUSY)
  			wait_current_trans(root);
  	} while (ret == -EBUSY);
db5b493ac   Tsutomu Itoh   Btrfs: cleanup so...
288
  	if (ret < 0) {
6e8df2ae8   Yoshinori Sano   Btrfs: fix memory...
289
  		kmem_cache_free(btrfs_trans_handle_cachep, h);
db5b493ac   Tsutomu Itoh   Btrfs: cleanup so...
290
291
  		return ERR_PTR(ret);
  	}
0f7d52f44   Chris Mason   Btrfs: groundwork...
292

a22285a6a   Yan, Zheng   Btrfs: Integrate ...
293
  	cur_trans = root->fs_info->running_transaction;
a22285a6a   Yan, Zheng   Btrfs: Integrate ...
294
295
296
  
  	h->transid = cur_trans->transid;
  	h->transaction = cur_trans;
79154b1b5   Chris Mason   Btrfs: transactio...
297
  	h->blocks_used = 0;
a22285a6a   Yan, Zheng   Btrfs: Integrate ...
298
  	h->bytes_reserved = 0;
56bec294d   Chris Mason   Btrfs: do extent ...
299
  	h->delayed_ref_updates = 0;
2a1eb4614   Josef Bacik   Btrfs: if we've a...
300
  	h->use_count = 1;
f0486c68e   Yan, Zheng   Btrfs: Introduce ...
301
  	h->block_rsv = NULL;
2a1eb4614   Josef Bacik   Btrfs: if we've a...
302
  	h->orig_rsv = NULL;
b7ec40d78   Chris Mason   Btrfs: reduce sta...
303

a22285a6a   Yan, Zheng   Btrfs: Integrate ...
304
305
306
307
308
  	smp_mb();
  	if (cur_trans->blocked && may_wait_transaction(root, type)) {
  		btrfs_commit_transaction(h, root);
  		goto again;
  	}
b5009945b   Josef Bacik   Btrfs: do transac...
309
310
311
  	if (num_bytes) {
  		h->block_rsv = &root->fs_info->trans_block_rsv;
  		h->bytes_reserved = num_bytes;
a22285a6a   Yan, Zheng   Btrfs: Integrate ...
312
  	}
9ed74f2db   Josef Bacik   Btrfs: proper -EN...
313

2a1eb4614   Josef Bacik   Btrfs: if we've a...
314
  got_it:
a4abeea41   Josef Bacik   Btrfs: kill trans...
315
  	btrfs_record_root_in_trans(h, root);
a22285a6a   Yan, Zheng   Btrfs: Integrate ...
316
317
318
  
  	if (!current->journal_info && type != TRANS_USERSPACE)
  		current->journal_info = h;
79154b1b5   Chris Mason   Btrfs: transactio...
319
320
  	return h;
  }
f92957493   Chris Mason   btrfs_start_trans...
321
  struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
a22285a6a   Yan, Zheng   Btrfs: Integrate ...
322
  						   int num_items)
f92957493   Chris Mason   btrfs_start_trans...
323
  {
a22285a6a   Yan, Zheng   Btrfs: Integrate ...
324
  	return start_transaction(root, num_items, TRANS_START);
f92957493   Chris Mason   btrfs_start_trans...
325
  }
7a7eaa40a   Josef Bacik   Btrfs: take away ...
326
  struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root)
f92957493   Chris Mason   btrfs_start_trans...
327
  {
a22285a6a   Yan, Zheng   Btrfs: Integrate ...
328
  	return start_transaction(root, 0, TRANS_JOIN);
f92957493   Chris Mason   btrfs_start_trans...
329
  }
7a7eaa40a   Josef Bacik   Btrfs: take away ...
330
  struct btrfs_trans_handle *btrfs_join_transaction_nolock(struct btrfs_root *root)
0af3d00ba   Josef Bacik   Btrfs: create spe...
331
332
333
  {
  	return start_transaction(root, 0, TRANS_JOIN_NOLOCK);
  }
7a7eaa40a   Josef Bacik   Btrfs: take away ...
334
  struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *root)
9ca9ee09c   Sage Weil   Btrfs: fix ioctl-...
335
  {
7a7eaa40a   Josef Bacik   Btrfs: take away ...
336
  	return start_transaction(root, 0, TRANS_USERSPACE);
9ca9ee09c   Sage Weil   Btrfs: fix ioctl-...
337
  }
d352ac681   Chris Mason   Btrfs: add and im...
338
  /* wait for a transaction commit to be fully complete */
b9c8300c2   Li Zefan   Btrfs: remove a B...
339
  static noinline void wait_for_commit(struct btrfs_root *root,
89ce8a63d   Chris Mason   Add btrfs_end_tra...
340
341
  				    struct btrfs_transaction *commit)
  {
72d63ed64   Li Zefan   Btrfs: use wait_e...
342
  	wait_event(commit->commit_wait, commit->commit_done);
89ce8a63d   Chris Mason   Add btrfs_end_tra...
343
  }
462045928   Sage Weil   Btrfs: add START_...
344
345
346
347
  int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid)
  {
  	struct btrfs_transaction *cur_trans = NULL, *t;
  	int ret;
462045928   Sage Weil   Btrfs: add START_...
348
349
350
  	ret = 0;
  	if (transid) {
  		if (transid <= root->fs_info->last_trans_committed)
a4abeea41   Josef Bacik   Btrfs: kill trans...
351
  			goto out;
462045928   Sage Weil   Btrfs: add START_...
352
353
  
  		/* find specified transaction */
a4abeea41   Josef Bacik   Btrfs: kill trans...
354
  		spin_lock(&root->fs_info->trans_lock);
462045928   Sage Weil   Btrfs: add START_...
355
356
357
  		list_for_each_entry(t, &root->fs_info->trans_list, list) {
  			if (t->transid == transid) {
  				cur_trans = t;
a4abeea41   Josef Bacik   Btrfs: kill trans...
358
  				atomic_inc(&cur_trans->use_count);
462045928   Sage Weil   Btrfs: add START_...
359
360
361
362
363
  				break;
  			}
  			if (t->transid > transid)
  				break;
  		}
a4abeea41   Josef Bacik   Btrfs: kill trans...
364
  		spin_unlock(&root->fs_info->trans_lock);
462045928   Sage Weil   Btrfs: add START_...
365
366
  		ret = -EINVAL;
  		if (!cur_trans)
a4abeea41   Josef Bacik   Btrfs: kill trans...
367
  			goto out;  /* bad transid */
462045928   Sage Weil   Btrfs: add START_...
368
369
  	} else {
  		/* find newest transaction that is committing | committed */
a4abeea41   Josef Bacik   Btrfs: kill trans...
370
  		spin_lock(&root->fs_info->trans_lock);
462045928   Sage Weil   Btrfs: add START_...
371
372
373
374
  		list_for_each_entry_reverse(t, &root->fs_info->trans_list,
  					    list) {
  			if (t->in_commit) {
  				if (t->commit_done)
3473f3c06   Josef Bacik   Btrfs: unlock the...
375
  					break;
462045928   Sage Weil   Btrfs: add START_...
376
  				cur_trans = t;
a4abeea41   Josef Bacik   Btrfs: kill trans...
377
  				atomic_inc(&cur_trans->use_count);
462045928   Sage Weil   Btrfs: add START_...
378
379
380
  				break;
  			}
  		}
a4abeea41   Josef Bacik   Btrfs: kill trans...
381
  		spin_unlock(&root->fs_info->trans_lock);
462045928   Sage Weil   Btrfs: add START_...
382
  		if (!cur_trans)
a4abeea41   Josef Bacik   Btrfs: kill trans...
383
  			goto out;  /* nothing committing|committed */
462045928   Sage Weil   Btrfs: add START_...
384
  	}
462045928   Sage Weil   Btrfs: add START_...
385
  	wait_for_commit(root, cur_trans);
462045928   Sage Weil   Btrfs: add START_...
386
387
  	put_transaction(cur_trans);
  	ret = 0;
a4abeea41   Josef Bacik   Btrfs: kill trans...
388
  out:
462045928   Sage Weil   Btrfs: add START_...
389
390
  	return ret;
  }
37d1aeee3   Chris Mason   Btrfs: Throttle t...
391
392
  void btrfs_throttle(struct btrfs_root *root)
  {
a4abeea41   Josef Bacik   Btrfs: kill trans...
393
  	if (!atomic_read(&root->fs_info->open_ioctl_trans))
9ca9ee09c   Sage Weil   Btrfs: fix ioctl-...
394
  		wait_current_trans(root);
37d1aeee3   Chris Mason   Btrfs: Throttle t...
395
  }
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
396
397
398
399
  static int should_end_transaction(struct btrfs_trans_handle *trans,
  				  struct btrfs_root *root)
  {
  	int ret;
36ba022ac   Josef Bacik   Btrfs: seperate o...
400
401
  
  	ret = btrfs_block_rsv_check(root, &root->fs_info->global_block_rsv, 5);
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
402
403
404
405
406
407
408
  	return ret ? 1 : 0;
  }
  
  int btrfs_should_end_transaction(struct btrfs_trans_handle *trans,
  				 struct btrfs_root *root)
  {
  	struct btrfs_transaction *cur_trans = trans->transaction;
9c8d86db9   Josef Bacik   Btrfs: make sure ...
409
  	struct btrfs_block_rsv *rsv = trans->block_rsv;
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
410
  	int updates;
a4abeea41   Josef Bacik   Btrfs: kill trans...
411
  	smp_mb();
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
412
413
  	if (cur_trans->blocked || cur_trans->delayed_refs.flushing)
  		return 1;
9c8d86db9   Josef Bacik   Btrfs: make sure ...
414
415
416
417
418
  	/*
  	 * We need to do this in case we're deleting csums so the global block
  	 * rsv get's used instead of the csum block rsv.
  	 */
  	trans->block_rsv = NULL;
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
419
420
421
422
  	updates = trans->delayed_ref_updates;
  	trans->delayed_ref_updates = 0;
  	if (updates)
  		btrfs_run_delayed_refs(trans, root, updates);
9c8d86db9   Josef Bacik   Btrfs: make sure ...
423
  	trans->block_rsv = rsv;
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
424
425
  	return should_end_transaction(trans, root);
  }
89ce8a63d   Chris Mason   Add btrfs_end_tra...
426
  static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
0af3d00ba   Josef Bacik   Btrfs: create spe...
427
  			  struct btrfs_root *root, int throttle, int lock)
79154b1b5   Chris Mason   Btrfs: transactio...
428
  {
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
429
  	struct btrfs_transaction *cur_trans = trans->transaction;
ab78c84de   Chris Mason   Btrfs: Throttle o...
430
  	struct btrfs_fs_info *info = root->fs_info;
c3e69d58e   Chris Mason   Btrfs: process th...
431
  	int count = 0;
2a1eb4614   Josef Bacik   Btrfs: if we've a...
432
433
434
435
  	if (--trans->use_count) {
  		trans->block_rsv = trans->orig_rsv;
  		return 0;
  	}
b24e03db0   Josef Bacik   Btrfs: release tr...
436
  	btrfs_trans_release_metadata(trans, root);
4c13d758b   Josef Bacik   Btrfs: use the tr...
437
  	trans->block_rsv = NULL;
c3e69d58e   Chris Mason   Btrfs: process th...
438
439
440
441
442
443
  	while (count < 4) {
  		unsigned long cur = trans->delayed_ref_updates;
  		trans->delayed_ref_updates = 0;
  		if (cur &&
  		    trans->transaction->delayed_refs.num_heads_ready > 64) {
  			trans->delayed_ref_updates = 0;
b7ec40d78   Chris Mason   Btrfs: reduce sta...
444
445
446
447
448
449
450
  
  			/*
  			 * do a full flush if the transaction is trying
  			 * to close
  			 */
  			if (trans->transaction->delayed_refs.flushing)
  				cur = 0;
c3e69d58e   Chris Mason   Btrfs: process th...
451
452
453
454
455
  			btrfs_run_delayed_refs(trans, root, cur);
  		} else {
  			break;
  		}
  		count++;
56bec294d   Chris Mason   Btrfs: do extent ...
456
  	}
a4abeea41   Josef Bacik   Btrfs: kill trans...
457
458
  	if (lock && !atomic_read(&root->fs_info->open_ioctl_trans) &&
  	    should_end_transaction(trans, root)) {
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
459
  		trans->transaction->blocked = 1;
a4abeea41   Josef Bacik   Btrfs: kill trans...
460
461
  		smp_wmb();
  	}
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
462

0af3d00ba   Josef Bacik   Btrfs: create spe...
463
  	if (lock && cur_trans->blocked && !cur_trans->in_commit) {
81317fded   Josef Bacik   Btrfs: fix deadlo...
464
465
466
467
468
469
470
  		if (throttle) {
  			/*
  			 * We may race with somebody else here so end up having
  			 * to call end_transaction on ourselves again, so inc
  			 * our use_count.
  			 */
  			trans->use_count++;
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
471
  			return btrfs_commit_transaction(trans, root);
81317fded   Josef Bacik   Btrfs: fix deadlo...
472
  		} else {
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
473
  			wake_up_process(info->transaction_kthread);
81317fded   Josef Bacik   Btrfs: fix deadlo...
474
  		}
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
475
  	}
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
476
  	WARN_ON(cur_trans != info->running_transaction);
13c5a93e7   Josef Bacik   Btrfs: avoid taki...
477
478
  	WARN_ON(atomic_read(&cur_trans->num_writers) < 1);
  	atomic_dec(&cur_trans->num_writers);
89ce8a63d   Chris Mason   Add btrfs_end_tra...
479

99d16cbca   Sage Weil   Btrfs: fix deadlo...
480
  	smp_mb();
79154b1b5   Chris Mason   Btrfs: transactio...
481
482
  	if (waitqueue_active(&cur_trans->writer_wait))
  		wake_up(&cur_trans->writer_wait);
79154b1b5   Chris Mason   Btrfs: transactio...
483
  	put_transaction(cur_trans);
9ed74f2db   Josef Bacik   Btrfs: proper -EN...
484
485
486
  
  	if (current->journal_info == trans)
  		current->journal_info = NULL;
d60255795   Chris Mason   Btrfs: corruption...
487
  	memset(trans, 0, sizeof(*trans));
2c90e5d65   Chris Mason   Btrfs: still corr...
488
  	kmem_cache_free(btrfs_trans_handle_cachep, trans);
ab78c84de   Chris Mason   Btrfs: Throttle o...
489

24bbcf044   Yan, Zheng   Btrfs: Add delaye...
490
491
  	if (throttle)
  		btrfs_run_delayed_iputs(root);
79154b1b5   Chris Mason   Btrfs: transactio...
492
493
  	return 0;
  }
89ce8a63d   Chris Mason   Add btrfs_end_tra...
494
495
496
  int btrfs_end_transaction(struct btrfs_trans_handle *trans,
  			  struct btrfs_root *root)
  {
16cdcec73   Miao Xie   btrfs: implement ...
497
498
499
500
501
502
  	int ret;
  
  	ret = __btrfs_end_transaction(trans, root, 0, 1);
  	if (ret)
  		return ret;
  	return 0;
89ce8a63d   Chris Mason   Add btrfs_end_tra...
503
504
505
506
507
  }
  
  int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans,
  				   struct btrfs_root *root)
  {
16cdcec73   Miao Xie   btrfs: implement ...
508
509
510
511
512
513
  	int ret;
  
  	ret = __btrfs_end_transaction(trans, root, 1, 1);
  	if (ret)
  		return ret;
  	return 0;
0af3d00ba   Josef Bacik   Btrfs: create spe...
514
515
516
517
518
  }
  
  int btrfs_end_transaction_nolock(struct btrfs_trans_handle *trans,
  				 struct btrfs_root *root)
  {
16cdcec73   Miao Xie   btrfs: implement ...
519
520
521
522
523
524
525
526
527
528
529
530
  	int ret;
  
  	ret = __btrfs_end_transaction(trans, root, 0, 0);
  	if (ret)
  		return ret;
  	return 0;
  }
  
  int btrfs_end_transaction_dmeta(struct btrfs_trans_handle *trans,
  				struct btrfs_root *root)
  {
  	return __btrfs_end_transaction(trans, root, 1, 1);
89ce8a63d   Chris Mason   Add btrfs_end_tra...
531
  }
d352ac681   Chris Mason   Btrfs: add and im...
532
533
534
  /*
   * when btree blocks are allocated, they have some corresponding bits set for
   * them in one of two extent_io trees.  This is used to make sure all of
690587d10   Chris Mason   Btrfs: streamline...
535
   * those extents are sent to disk but does not wait on them
d352ac681   Chris Mason   Btrfs: add and im...
536
   */
690587d10   Chris Mason   Btrfs: streamline...
537
  int btrfs_write_marked_extents(struct btrfs_root *root,
8cef4e160   Yan, Zheng   Btrfs: Avoid supe...
538
  			       struct extent_io_tree *dirty_pages, int mark)
79154b1b5   Chris Mason   Btrfs: transactio...
539
  {
777e6bd70   Chris Mason   Btrfs: Transactio...
540
  	int err = 0;
7c4452b9a   Chris Mason   Btrfs: smarter tr...
541
  	int werr = 0;
1728366ef   Josef Bacik   Btrfs: stop using...
542
  	struct address_space *mapping = root->fs_info->btree_inode->i_mapping;
777e6bd70   Chris Mason   Btrfs: Transactio...
543
  	u64 start = 0;
5f39d397d   Chris Mason   Btrfs: Create ext...
544
  	u64 end;
7c4452b9a   Chris Mason   Btrfs: smarter tr...
545

1728366ef   Josef Bacik   Btrfs: stop using...
546
547
548
549
550
551
552
553
554
  	while (!find_first_extent_bit(dirty_pages, start, &start, &end,
  				      mark)) {
  		convert_extent_bit(dirty_pages, start, end, EXTENT_NEED_WAIT, mark,
  				   GFP_NOFS);
  		err = filemap_fdatawrite_range(mapping, start, end);
  		if (err)
  			werr = err;
  		cond_resched();
  		start = end + 1;
7c4452b9a   Chris Mason   Btrfs: smarter tr...
555
  	}
690587d10   Chris Mason   Btrfs: streamline...
556
557
558
559
560
561
562
563
564
565
566
567
  	if (err)
  		werr = err;
  	return werr;
  }
  
  /*
   * when btree blocks are allocated, they have some corresponding bits set for
   * them in one of two extent_io trees.  This is used to make sure all of
   * those extents are on disk for transaction or log commit.  We wait
   * on all the pages and clear them from the dirty pages state tree
   */
  int btrfs_wait_marked_extents(struct btrfs_root *root,
8cef4e160   Yan, Zheng   Btrfs: Avoid supe...
568
  			      struct extent_io_tree *dirty_pages, int mark)
690587d10   Chris Mason   Btrfs: streamline...
569
  {
690587d10   Chris Mason   Btrfs: streamline...
570
571
  	int err = 0;
  	int werr = 0;
1728366ef   Josef Bacik   Btrfs: stop using...
572
  	struct address_space *mapping = root->fs_info->btree_inode->i_mapping;
690587d10   Chris Mason   Btrfs: streamline...
573
574
  	u64 start = 0;
  	u64 end;
777e6bd70   Chris Mason   Btrfs: Transactio...
575

1728366ef   Josef Bacik   Btrfs: stop using...
576
577
578
579
580
581
582
583
  	while (!find_first_extent_bit(dirty_pages, start, &start, &end,
  				      EXTENT_NEED_WAIT)) {
  		clear_extent_bits(dirty_pages, start, end, EXTENT_NEED_WAIT, GFP_NOFS);
  		err = filemap_fdatawait_range(mapping, start, end);
  		if (err)
  			werr = err;
  		cond_resched();
  		start = end + 1;
777e6bd70   Chris Mason   Btrfs: Transactio...
584
  	}
7c4452b9a   Chris Mason   Btrfs: smarter tr...
585
586
587
  	if (err)
  		werr = err;
  	return werr;
79154b1b5   Chris Mason   Btrfs: transactio...
588
  }
690587d10   Chris Mason   Btrfs: streamline...
589
590
591
592
593
594
  /*
   * when btree blocks are allocated, they have some corresponding bits set for
   * them in one of two extent_io trees.  This is used to make sure all of
   * those extents are on disk for transaction or log commit
   */
  int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
8cef4e160   Yan, Zheng   Btrfs: Avoid supe...
595
  				struct extent_io_tree *dirty_pages, int mark)
690587d10   Chris Mason   Btrfs: streamline...
596
597
598
  {
  	int ret;
  	int ret2;
8cef4e160   Yan, Zheng   Btrfs: Avoid supe...
599
600
  	ret = btrfs_write_marked_extents(root, dirty_pages, mark);
  	ret2 = btrfs_wait_marked_extents(root, dirty_pages, mark);
bf0da8c18   Chris Mason   Btrfs: ClearPageE...
601
602
603
604
605
606
  
  	if (ret)
  		return ret;
  	if (ret2)
  		return ret2;
  	return 0;
690587d10   Chris Mason   Btrfs: streamline...
607
  }
d0c803c40   Chris Mason   Btrfs: Record dir...
608
609
610
611
612
613
614
615
616
  int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
  				     struct btrfs_root *root)
  {
  	if (!trans || !trans->transaction) {
  		struct inode *btree_inode;
  		btree_inode = root->fs_info->btree_inode;
  		return filemap_write_and_wait(btree_inode->i_mapping);
  	}
  	return btrfs_write_and_wait_marked_extents(root,
8cef4e160   Yan, Zheng   Btrfs: Avoid supe...
617
618
  					   &trans->transaction->dirty_pages,
  					   EXTENT_DIRTY);
d0c803c40   Chris Mason   Btrfs: Record dir...
619
  }
d352ac681   Chris Mason   Btrfs: add and im...
620
621
622
623
624
625
626
627
628
629
  /*
   * this is used to update the root pointer in the tree of tree roots.
   *
   * But, in the case of the extent allocation tree, updating the root
   * pointer may allocate blocks which may change the root of the extent
   * allocation tree.
   *
   * So, this loops and repeats and makes sure the cowonly root didn't
   * change while the root pointer was being updated in the metadata.
   */
0b86a832a   Chris Mason   Btrfs: Add suppor...
630
631
  static int update_cowonly_root(struct btrfs_trans_handle *trans,
  			       struct btrfs_root *root)
79154b1b5   Chris Mason   Btrfs: transactio...
632
633
  {
  	int ret;
0b86a832a   Chris Mason   Btrfs: Add suppor...
634
  	u64 old_root_bytenr;
86b9f2eca   Yan, Zheng   Btrfs: Fix per ro...
635
  	u64 old_root_used;
0b86a832a   Chris Mason   Btrfs: Add suppor...
636
  	struct btrfs_root *tree_root = root->fs_info->tree_root;
79154b1b5   Chris Mason   Btrfs: transactio...
637

86b9f2eca   Yan, Zheng   Btrfs: Fix per ro...
638
  	old_root_used = btrfs_root_used(&root->root_item);
0b86a832a   Chris Mason   Btrfs: Add suppor...
639
  	btrfs_write_dirty_block_groups(trans, root);
56bec294d   Chris Mason   Btrfs: do extent ...
640

d397712bc   Chris Mason   Btrfs: Fix checkp...
641
  	while (1) {
0b86a832a   Chris Mason   Btrfs: Add suppor...
642
  		old_root_bytenr = btrfs_root_bytenr(&root->root_item);
86b9f2eca   Yan, Zheng   Btrfs: Fix per ro...
643
644
  		if (old_root_bytenr == root->node->start &&
  		    old_root_used == btrfs_root_used(&root->root_item))
79154b1b5   Chris Mason   Btrfs: transactio...
645
  			break;
87ef2bb46   Chris Mason   Btrfs: prevent lo...
646

5d4f98a28   Yan Zheng   Btrfs: Mixed back...
647
  		btrfs_set_root_node(&root->root_item, root->node);
79154b1b5   Chris Mason   Btrfs: transactio...
648
  		ret = btrfs_update_root(trans, tree_root,
0b86a832a   Chris Mason   Btrfs: Add suppor...
649
650
  					&root->root_key,
  					&root->root_item);
79154b1b5   Chris Mason   Btrfs: transactio...
651
  		BUG_ON(ret);
56bec294d   Chris Mason   Btrfs: do extent ...
652

86b9f2eca   Yan, Zheng   Btrfs: Fix per ro...
653
  		old_root_used = btrfs_root_used(&root->root_item);
4a8c9a62d   Yan Zheng   Btrfs: make sure ...
654
  		ret = btrfs_write_dirty_block_groups(trans, root);
56bec294d   Chris Mason   Btrfs: do extent ...
655
  		BUG_ON(ret);
0b86a832a   Chris Mason   Btrfs: Add suppor...
656
  	}
276e680d1   Yan Zheng   Btrfs: preserve c...
657
658
659
  
  	if (root != root->fs_info->extent_root)
  		switch_commit_root(root);
0b86a832a   Chris Mason   Btrfs: Add suppor...
660
661
  	return 0;
  }
d352ac681   Chris Mason   Btrfs: add and im...
662
663
664
  /*
   * update all the cowonly tree roots on disk
   */
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
665
666
  static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans,
  					 struct btrfs_root *root)
0b86a832a   Chris Mason   Btrfs: Add suppor...
667
668
669
  {
  	struct btrfs_fs_info *fs_info = root->fs_info;
  	struct list_head *next;
84234f3a1   Yan Zheng   Btrfs: Add root t...
670
  	struct extent_buffer *eb;
56bec294d   Chris Mason   Btrfs: do extent ...
671
  	int ret;
84234f3a1   Yan Zheng   Btrfs: Add root t...
672

56bec294d   Chris Mason   Btrfs: do extent ...
673
674
  	ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1);
  	BUG_ON(ret);
87ef2bb46   Chris Mason   Btrfs: prevent lo...
675

84234f3a1   Yan Zheng   Btrfs: Add root t...
676
  	eb = btrfs_lock_root_node(fs_info->tree_root);
9fa8cfe70   Chris Mason   Btrfs: don't prea...
677
  	btrfs_cow_block(trans, fs_info->tree_root, eb, NULL, 0, &eb);
84234f3a1   Yan Zheng   Btrfs: Add root t...
678
679
  	btrfs_tree_unlock(eb);
  	free_extent_buffer(eb);
0b86a832a   Chris Mason   Btrfs: Add suppor...
680

56bec294d   Chris Mason   Btrfs: do extent ...
681
682
  	ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1);
  	BUG_ON(ret);
87ef2bb46   Chris Mason   Btrfs: prevent lo...
683

d397712bc   Chris Mason   Btrfs: Fix checkp...
684
  	while (!list_empty(&fs_info->dirty_cowonly_roots)) {
0b86a832a   Chris Mason   Btrfs: Add suppor...
685
686
687
  		next = fs_info->dirty_cowonly_roots.next;
  		list_del_init(next);
  		root = list_entry(next, struct btrfs_root, dirty_list);
87ef2bb46   Chris Mason   Btrfs: prevent lo...
688

0b86a832a   Chris Mason   Btrfs: Add suppor...
689
  		update_cowonly_root(trans, root);
79154b1b5   Chris Mason   Btrfs: transactio...
690
  	}
276e680d1   Yan Zheng   Btrfs: preserve c...
691
692
693
694
  
  	down_write(&fs_info->extent_commit_sem);
  	switch_commit_root(fs_info->extent_root);
  	up_write(&fs_info->extent_commit_sem);
79154b1b5   Chris Mason   Btrfs: transactio...
695
696
  	return 0;
  }
d352ac681   Chris Mason   Btrfs: add and im...
697
698
699
700
701
  /*
   * dead roots are old snapshots that need to be deleted.  This allocates
   * a dirty root struct and adds it into the list of dead roots that need to
   * be deleted
   */
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
702
  int btrfs_add_dead_root(struct btrfs_root *root)
5eda7b5e9   Chris Mason   Btrfs: Add the ab...
703
  {
a4abeea41   Josef Bacik   Btrfs: kill trans...
704
  	spin_lock(&root->fs_info->trans_lock);
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
705
  	list_add(&root->root_list, &root->fs_info->dead_roots);
a4abeea41   Josef Bacik   Btrfs: kill trans...
706
  	spin_unlock(&root->fs_info->trans_lock);
5eda7b5e9   Chris Mason   Btrfs: Add the ab...
707
708
  	return 0;
  }
d352ac681   Chris Mason   Btrfs: add and im...
709
  /*
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
710
   * update all the cowonly tree roots on disk
d352ac681   Chris Mason   Btrfs: add and im...
711
   */
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
712
713
  static noinline int commit_fs_roots(struct btrfs_trans_handle *trans,
  				    struct btrfs_root *root)
0f7d52f44   Chris Mason   Btrfs: groundwork...
714
  {
0f7d52f44   Chris Mason   Btrfs: groundwork...
715
  	struct btrfs_root *gang[8];
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
716
  	struct btrfs_fs_info *fs_info = root->fs_info;
0f7d52f44   Chris Mason   Btrfs: groundwork...
717
718
  	int i;
  	int ret;
54aa1f4df   Chris Mason   Btrfs: Audit call...
719
  	int err = 0;
a4abeea41   Josef Bacik   Btrfs: kill trans...
720
  	spin_lock(&fs_info->fs_roots_radix_lock);
d397712bc   Chris Mason   Btrfs: Fix checkp...
721
  	while (1) {
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
722
723
  		ret = radix_tree_gang_lookup_tag(&fs_info->fs_roots_radix,
  						 (void **)gang, 0,
0f7d52f44   Chris Mason   Btrfs: groundwork...
724
725
726
727
728
729
  						 ARRAY_SIZE(gang),
  						 BTRFS_ROOT_TRANS_TAG);
  		if (ret == 0)
  			break;
  		for (i = 0; i < ret; i++) {
  			root = gang[i];
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
730
731
732
  			radix_tree_tag_clear(&fs_info->fs_roots_radix,
  					(unsigned long)root->root_key.objectid,
  					BTRFS_ROOT_TRANS_TAG);
a4abeea41   Josef Bacik   Btrfs: kill trans...
733
  			spin_unlock(&fs_info->fs_roots_radix_lock);
31153d812   Yan Zheng   Btrfs: Add a leaf...
734

e02119d5a   Chris Mason   Btrfs: Add a writ...
735
  			btrfs_free_log(trans, root);
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
736
  			btrfs_update_reloc_root(trans, root);
d68fc57b7   Yan, Zheng   Btrfs: Metadata r...
737
  			btrfs_orphan_commit_root(trans, root);
bcc63abbf   Yan   Btrfs: implement ...
738

82d5902d9   Li Zefan   Btrfs: Support re...
739
  			btrfs_save_ino_cache(root, trans);
f1ebcc74d   Liu Bo   Btrfs: fix tree c...
740
741
742
  			/* see comments in should_cow_block() */
  			root->force_cow = 0;
  			smp_wmb();
978d910d3   Yan Zheng   Btrfs: always upd...
743
  			if (root->commit_root != root->node) {
581bb0509   Li Zefan   Btrfs: Cache free...
744
  				mutex_lock(&root->fs_commit_mutex);
817d52f8d   Josef Bacik   Btrfs: async bloc...
745
  				switch_commit_root(root);
581bb0509   Li Zefan   Btrfs: Cache free...
746
747
  				btrfs_unpin_free_ino(root);
  				mutex_unlock(&root->fs_commit_mutex);
978d910d3   Yan Zheng   Btrfs: always upd...
748
749
750
  				btrfs_set_root_node(&root->root_item,
  						    root->node);
  			}
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
751

5d4f98a28   Yan Zheng   Btrfs: Mixed back...
752
  			err = btrfs_update_root(trans, fs_info->tree_root,
0f7d52f44   Chris Mason   Btrfs: groundwork...
753
754
  						&root->root_key,
  						&root->root_item);
a4abeea41   Josef Bacik   Btrfs: kill trans...
755
  			spin_lock(&fs_info->fs_roots_radix_lock);
54aa1f4df   Chris Mason   Btrfs: Audit call...
756
757
  			if (err)
  				break;
0f7d52f44   Chris Mason   Btrfs: groundwork...
758
759
  		}
  	}
a4abeea41   Josef Bacik   Btrfs: kill trans...
760
  	spin_unlock(&fs_info->fs_roots_radix_lock);
54aa1f4df   Chris Mason   Btrfs: Audit call...
761
  	return err;
0f7d52f44   Chris Mason   Btrfs: groundwork...
762
  }
d352ac681   Chris Mason   Btrfs: add and im...
763
764
765
766
  /*
   * defrag a given btree.  If cacheonly == 1, this won't read from the disk,
   * otherwise every leaf in the btree is read and defragged.
   */
e9d0b13b5   Chris Mason   Btrfs: Btree defr...
767
768
769
  int btrfs_defrag_root(struct btrfs_root *root, int cacheonly)
  {
  	struct btrfs_fs_info *info = root->fs_info;
e9d0b13b5   Chris Mason   Btrfs: Btree defr...
770
  	struct btrfs_trans_handle *trans;
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
771
  	int ret;
d3c2fdcf7   Chris Mason   Btrfs: Use balanc...
772
  	unsigned long nr;
e9d0b13b5   Chris Mason   Btrfs: Btree defr...
773

8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
774
  	if (xchg(&root->defrag_running, 1))
e9d0b13b5   Chris Mason   Btrfs: Btree defr...
775
  		return 0;
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
776

6b80053d0   Chris Mason   Btrfs: Add back t...
777
  	while (1) {
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
778
779
780
  		trans = btrfs_start_transaction(root, 0);
  		if (IS_ERR(trans))
  			return PTR_ERR(trans);
e9d0b13b5   Chris Mason   Btrfs: Btree defr...
781
  		ret = btrfs_defrag_leaves(trans, root, cacheonly);
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
782

d3c2fdcf7   Chris Mason   Btrfs: Use balanc...
783
  		nr = trans->blocks_used;
e9d0b13b5   Chris Mason   Btrfs: Btree defr...
784
  		btrfs_end_transaction(trans, root);
d3c2fdcf7   Chris Mason   Btrfs: Use balanc...
785
  		btrfs_btree_balance_dirty(info->tree_root, nr);
e9d0b13b5   Chris Mason   Btrfs: Btree defr...
786
  		cond_resched();
7841cb289   David Sterba   btrfs: add helper...
787
  		if (btrfs_fs_closing(root->fs_info) || ret != -EAGAIN)
e9d0b13b5   Chris Mason   Btrfs: Btree defr...
788
789
790
  			break;
  	}
  	root->defrag_running = 0;
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
791
  	return ret;
e9d0b13b5   Chris Mason   Btrfs: Btree defr...
792
  }
d352ac681   Chris Mason   Btrfs: add and im...
793
794
795
796
  /*
   * new snapshots need to be created at a very specific time in the
   * transaction commit.  This does the actual creation
   */
80b6794d1   Chris Mason   Btrfs: Lower stac...
797
  static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
3063d29f2   Chris Mason   Btrfs: Move snaps...
798
799
800
801
  				   struct btrfs_fs_info *fs_info,
  				   struct btrfs_pending_snapshot *pending)
  {
  	struct btrfs_key key;
80b6794d1   Chris Mason   Btrfs: Lower stac...
802
  	struct btrfs_root_item *new_root_item;
3063d29f2   Chris Mason   Btrfs: Move snaps...
803
804
  	struct btrfs_root *tree_root = fs_info->tree_root;
  	struct btrfs_root *root = pending->root;
6bdb72ded   Sage Weil   Btrfs: create sna...
805
  	struct btrfs_root *parent_root;
98c9942ac   Liu Bo   Btrfs: fix misuse...
806
  	struct btrfs_block_rsv *rsv;
6bdb72ded   Sage Weil   Btrfs: create sna...
807
  	struct inode *parent_inode;
6a9122130   Josef Bacik   Btrfs: use dget_p...
808
  	struct dentry *parent;
a22285a6a   Yan, Zheng   Btrfs: Integrate ...
809
  	struct dentry *dentry;
3063d29f2   Chris Mason   Btrfs: Move snaps...
810
  	struct extent_buffer *tmp;
925baeddc   Chris Mason   Btrfs: Start btre...
811
  	struct extent_buffer *old;
3063d29f2   Chris Mason   Btrfs: Move snaps...
812
  	int ret;
d68fc57b7   Yan, Zheng   Btrfs: Metadata r...
813
  	u64 to_reserve = 0;
6bdb72ded   Sage Weil   Btrfs: create sna...
814
  	u64 index = 0;
a22285a6a   Yan, Zheng   Btrfs: Integrate ...
815
  	u64 objectid;
b83cc9693   Li Zefan   Btrfs: Add readon...
816
  	u64 root_flags;
3063d29f2   Chris Mason   Btrfs: Move snaps...
817

98c9942ac   Liu Bo   Btrfs: fix misuse...
818
  	rsv = trans->block_rsv;
80b6794d1   Chris Mason   Btrfs: Lower stac...
819
820
  	new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS);
  	if (!new_root_item) {
a22285a6a   Yan, Zheng   Btrfs: Integrate ...
821
  		pending->error = -ENOMEM;
80b6794d1   Chris Mason   Btrfs: Lower stac...
822
823
  		goto fail;
  	}
a22285a6a   Yan, Zheng   Btrfs: Integrate ...
824

581bb0509   Li Zefan   Btrfs: Cache free...
825
  	ret = btrfs_find_free_objectid(tree_root, &objectid);
a22285a6a   Yan, Zheng   Btrfs: Integrate ...
826
827
  	if (ret) {
  		pending->error = ret;
3063d29f2   Chris Mason   Btrfs: Move snaps...
828
  		goto fail;
a22285a6a   Yan, Zheng   Btrfs: Integrate ...
829
  	}
3063d29f2   Chris Mason   Btrfs: Move snaps...
830

3fd0a5585   Yan, Zheng   Btrfs: Metadata E...
831
  	btrfs_reloc_pre_snapshot(trans, pending, &to_reserve);
d68fc57b7   Yan, Zheng   Btrfs: Metadata r...
832
833
  
  	if (to_reserve > 0) {
62f30c546   Miao Xie   Btrfs: fix deadlo...
834
835
  		ret = btrfs_block_rsv_add_noflush(root, &pending->block_rsv,
  						  to_reserve);
d68fc57b7   Yan, Zheng   Btrfs: Metadata r...
836
837
838
839
840
  		if (ret) {
  			pending->error = ret;
  			goto fail;
  		}
  	}
3063d29f2   Chris Mason   Btrfs: Move snaps...
841
  	key.objectid = objectid;
a22285a6a   Yan, Zheng   Btrfs: Integrate ...
842
843
  	key.offset = (u64)-1;
  	key.type = BTRFS_ROOT_ITEM_KEY;
3063d29f2   Chris Mason   Btrfs: Move snaps...
844

a22285a6a   Yan, Zheng   Btrfs: Integrate ...
845
  	trans->block_rsv = &pending->block_rsv;
3de4586c5   Chris Mason   Btrfs: Allow subv...
846

a22285a6a   Yan, Zheng   Btrfs: Integrate ...
847
  	dentry = pending->dentry;
6a9122130   Josef Bacik   Btrfs: use dget_p...
848
849
  	parent = dget_parent(dentry);
  	parent_inode = parent->d_inode;
a22285a6a   Yan, Zheng   Btrfs: Integrate ...
850
  	parent_root = BTRFS_I(parent_inode)->root;
7585717f3   Chris Mason   Btrfs: fix reloca...
851
  	record_root_in_trans(trans, parent_root);
a22285a6a   Yan, Zheng   Btrfs: Integrate ...
852

3063d29f2   Chris Mason   Btrfs: Move snaps...
853
854
855
  	/*
  	 * insert the directory item
  	 */
3de4586c5   Chris Mason   Btrfs: Allow subv...
856
  	ret = btrfs_set_inode_index(parent_inode, &index);
6bdb72ded   Sage Weil   Btrfs: create sna...
857
  	BUG_ON(ret);
0660b5af3   Chris Mason   Btrfs: Add backre...
858
  	ret = btrfs_insert_dir_item(trans, parent_root,
a22285a6a   Yan, Zheng   Btrfs: Integrate ...
859
  				dentry->d_name.name, dentry->d_name.len,
16cdcec73   Miao Xie   btrfs: implement ...
860
  				parent_inode, &key,
a22285a6a   Yan, Zheng   Btrfs: Integrate ...
861
  				BTRFS_FT_DIR, index);
6bdb72ded   Sage Weil   Btrfs: create sna...
862
  	BUG_ON(ret);
0660b5af3   Chris Mason   Btrfs: Add backre...
863

a22285a6a   Yan, Zheng   Btrfs: Integrate ...
864
865
  	btrfs_i_size_write(parent_inode, parent_inode->i_size +
  					 dentry->d_name.len * 2);
52c261799   Yan Zheng   Btrfs: update dir...
866
867
  	ret = btrfs_update_inode(trans, parent_root, parent_inode);
  	BUG_ON(ret);
e999376f0   Chris Mason   Btrfs: avoid dela...
868
869
870
871
872
873
874
875
  	/*
  	 * pull in the delayed directory update
  	 * and the delayed inode item
  	 * otherwise we corrupt the FS during
  	 * snapshot
  	 */
  	ret = btrfs_run_delayed_items(trans, root);
  	BUG_ON(ret);
7585717f3   Chris Mason   Btrfs: fix reloca...
876
  	record_root_in_trans(trans, root);
6bdb72ded   Sage Weil   Btrfs: create sna...
877
878
  	btrfs_set_root_last_snapshot(&root->root_item, trans->transid);
  	memcpy(new_root_item, &root->root_item, sizeof(*new_root_item));
08fe4db17   Li Zefan   Btrfs: Fix uninit...
879
  	btrfs_check_and_init_root_item(new_root_item);
6bdb72ded   Sage Weil   Btrfs: create sna...
880

b83cc9693   Li Zefan   Btrfs: Add readon...
881
882
883
884
885
886
  	root_flags = btrfs_root_flags(new_root_item);
  	if (pending->readonly)
  		root_flags |= BTRFS_ROOT_SUBVOL_RDONLY;
  	else
  		root_flags &= ~BTRFS_ROOT_SUBVOL_RDONLY;
  	btrfs_set_root_flags(new_root_item, root_flags);
6bdb72ded   Sage Weil   Btrfs: create sna...
887
888
889
890
891
892
893
  	old = btrfs_lock_root_node(root);
  	btrfs_cow_block(trans, root, old, NULL, 0, &old);
  	btrfs_set_lock_blocking(old);
  
  	btrfs_copy_root(trans, root, old, &tmp, objectid);
  	btrfs_tree_unlock(old);
  	free_extent_buffer(old);
f1ebcc74d   Liu Bo   Btrfs: fix tree c...
894
895
896
  	/* see comments in should_cow_block() */
  	root->force_cow = 1;
  	smp_wmb();
6bdb72ded   Sage Weil   Btrfs: create sna...
897
  	btrfs_set_root_node(new_root_item, tmp);
a22285a6a   Yan, Zheng   Btrfs: Integrate ...
898
899
900
  	/* record when the snapshot was created in key.offset */
  	key.offset = trans->transid;
  	ret = btrfs_insert_root(trans, tree_root, &key, new_root_item);
6bdb72ded   Sage Weil   Btrfs: create sna...
901
902
  	btrfs_tree_unlock(tmp);
  	free_extent_buffer(tmp);
a22285a6a   Yan, Zheng   Btrfs: Integrate ...
903
  	BUG_ON(ret);
6bdb72ded   Sage Weil   Btrfs: create sna...
904

a22285a6a   Yan, Zheng   Btrfs: Integrate ...
905
906
907
908
  	/*
  	 * insert root back/forward references
  	 */
  	ret = btrfs_add_root_ref(trans, tree_root, objectid,
0660b5af3   Chris Mason   Btrfs: Add backre...
909
  				 parent_root->root_key.objectid,
33345d015   Li Zefan   Btrfs: Always use...
910
  				 btrfs_ino(parent_inode), index,
a22285a6a   Yan, Zheng   Btrfs: Integrate ...
911
  				 dentry->d_name.name, dentry->d_name.len);
0660b5af3   Chris Mason   Btrfs: Add backre...
912
  	BUG_ON(ret);
6a9122130   Josef Bacik   Btrfs: use dget_p...
913
  	dput(parent);
0660b5af3   Chris Mason   Btrfs: Add backre...
914

a22285a6a   Yan, Zheng   Btrfs: Integrate ...
915
916
917
  	key.offset = (u64)-1;
  	pending->snap = btrfs_read_fs_root_no_name(root->fs_info, &key);
  	BUG_ON(IS_ERR(pending->snap));
d68fc57b7   Yan, Zheng   Btrfs: Metadata r...
918

3fd0a5585   Yan, Zheng   Btrfs: Metadata E...
919
  	btrfs_reloc_post_snapshot(trans, pending);
3063d29f2   Chris Mason   Btrfs: Move snaps...
920
  fail:
6bdb72ded   Sage Weil   Btrfs: create sna...
921
  	kfree(new_root_item);
98c9942ac   Liu Bo   Btrfs: fix misuse...
922
  	trans->block_rsv = rsv;
a22285a6a   Yan, Zheng   Btrfs: Integrate ...
923
924
  	btrfs_block_rsv_release(root, &pending->block_rsv, (u64)-1);
  	return 0;
3063d29f2   Chris Mason   Btrfs: Move snaps...
925
  }
d352ac681   Chris Mason   Btrfs: add and im...
926
927
928
  /*
   * create all the snapshots we've scheduled for creation
   */
80b6794d1   Chris Mason   Btrfs: Lower stac...
929
930
  static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans,
  					     struct btrfs_fs_info *fs_info)
3063d29f2   Chris Mason   Btrfs: Move snaps...
931
932
933
  {
  	struct btrfs_pending_snapshot *pending;
  	struct list_head *head = &trans->transaction->pending_snapshots;
3de4586c5   Chris Mason   Btrfs: Allow subv...
934
  	int ret;
c6e308713   Qinghuang Feng   Btrfs: simplify i...
935
  	list_for_each_entry(pending, head, list) {
3de4586c5   Chris Mason   Btrfs: Allow subv...
936
937
938
939
940
  		ret = create_pending_snapshot(trans, fs_info, pending);
  		BUG_ON(ret);
  	}
  	return 0;
  }
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
941
942
943
944
  static void update_super_roots(struct btrfs_root *root)
  {
  	struct btrfs_root_item *root_item;
  	struct btrfs_super_block *super;
6c41761fc   David Sterba   btrfs: separate s...
945
  	super = root->fs_info->super_copy;
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
946
947
948
949
950
951
952
953
954
955
  
  	root_item = &root->fs_info->chunk_root->root_item;
  	super->chunk_root = root_item->bytenr;
  	super->chunk_root_generation = root_item->generation;
  	super->chunk_root_level = root_item->level;
  
  	root_item = &root->fs_info->tree_root->root_item;
  	super->root = root_item->bytenr;
  	super->generation = root_item->generation;
  	super->root_level = root_item->level;
73bc18768   Josef Bacik   Btrfs: introduce ...
956
  	if (btrfs_test_opt(root, SPACE_CACHE))
0af3d00ba   Josef Bacik   Btrfs: create spe...
957
  		super->cache_generation = root_item->generation;
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
958
  }
f36f3042e   Chris Mason   Btrfs: be more po...
959
960
961
  int btrfs_transaction_in_commit(struct btrfs_fs_info *info)
  {
  	int ret = 0;
a4abeea41   Josef Bacik   Btrfs: kill trans...
962
  	spin_lock(&info->trans_lock);
f36f3042e   Chris Mason   Btrfs: be more po...
963
964
  	if (info->running_transaction)
  		ret = info->running_transaction->in_commit;
a4abeea41   Josef Bacik   Btrfs: kill trans...
965
  	spin_unlock(&info->trans_lock);
f36f3042e   Chris Mason   Btrfs: be more po...
966
967
  	return ret;
  }
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
968
969
970
  int btrfs_transaction_blocked(struct btrfs_fs_info *info)
  {
  	int ret = 0;
a4abeea41   Josef Bacik   Btrfs: kill trans...
971
  	spin_lock(&info->trans_lock);
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
972
973
  	if (info->running_transaction)
  		ret = info->running_transaction->blocked;
a4abeea41   Josef Bacik   Btrfs: kill trans...
974
  	spin_unlock(&info->trans_lock);
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
975
976
  	return ret;
  }
bb9c12c94   Sage Weil   Btrfs: async tran...
977
978
979
980
981
982
983
  /*
   * wait for the current transaction commit to start and block subsequent
   * transaction joins
   */
  static void wait_current_trans_commit_start(struct btrfs_root *root,
  					    struct btrfs_transaction *trans)
  {
72d63ed64   Li Zefan   Btrfs: use wait_e...
984
  	wait_event(root->fs_info->transaction_blocked_wait, trans->in_commit);
bb9c12c94   Sage Weil   Btrfs: async tran...
985
986
987
988
989
990
991
992
993
  }
  
  /*
   * wait for the current transaction to start and then become unblocked.
   * caller holds ref.
   */
  static void wait_current_trans_commit_start_and_unblock(struct btrfs_root *root,
  					 struct btrfs_transaction *trans)
  {
72d63ed64   Li Zefan   Btrfs: use wait_e...
994
995
  	wait_event(root->fs_info->transaction_wait,
  		   trans->commit_done || (trans->in_commit && !trans->blocked));
bb9c12c94   Sage Weil   Btrfs: async tran...
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
  }
  
  /*
   * commit transactions asynchronously. once btrfs_commit_transaction_async
   * returns, any subsequent transaction will not be allowed to join.
   */
  struct btrfs_async_commit {
  	struct btrfs_trans_handle *newtrans;
  	struct btrfs_root *root;
  	struct delayed_work work;
  };
  
  static void do_async_commit(struct work_struct *work)
  {
  	struct btrfs_async_commit *ac =
  		container_of(work, struct btrfs_async_commit, work.work);
  
  	btrfs_commit_transaction(ac->newtrans, ac->root);
  	kfree(ac);
  }
  
  int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans,
  				   struct btrfs_root *root,
  				   int wait_for_unblock)
  {
  	struct btrfs_async_commit *ac;
  	struct btrfs_transaction *cur_trans;
  
  	ac = kmalloc(sizeof(*ac), GFP_NOFS);
db5b493ac   Tsutomu Itoh   Btrfs: cleanup so...
1025
1026
  	if (!ac)
  		return -ENOMEM;
bb9c12c94   Sage Weil   Btrfs: async tran...
1027
1028
1029
  
  	INIT_DELAYED_WORK(&ac->work, do_async_commit);
  	ac->root = root;
7a7eaa40a   Josef Bacik   Btrfs: take away ...
1030
  	ac->newtrans = btrfs_join_transaction(root);
3612b4959   Tsutomu Itoh   btrfs: fix return...
1031
1032
1033
1034
1035
  	if (IS_ERR(ac->newtrans)) {
  		int err = PTR_ERR(ac->newtrans);
  		kfree(ac);
  		return err;
  	}
bb9c12c94   Sage Weil   Btrfs: async tran...
1036
1037
  
  	/* take transaction reference */
bb9c12c94   Sage Weil   Btrfs: async tran...
1038
  	cur_trans = trans->transaction;
13c5a93e7   Josef Bacik   Btrfs: avoid taki...
1039
  	atomic_inc(&cur_trans->use_count);
bb9c12c94   Sage Weil   Btrfs: async tran...
1040
1041
1042
1043
1044
  
  	btrfs_end_transaction(trans, root);
  	schedule_delayed_work(&ac->work, 0);
  
  	/* wait for transaction to start and unblock */
bb9c12c94   Sage Weil   Btrfs: async tran...
1045
1046
1047
1048
  	if (wait_for_unblock)
  		wait_current_trans_commit_start_and_unblock(root, cur_trans);
  	else
  		wait_current_trans_commit_start(root, cur_trans);
bb9c12c94   Sage Weil   Btrfs: async tran...
1049

38e880540   Sage Weil   Btrfs: clear curr...
1050
1051
1052
1053
  	if (current->journal_info == trans)
  		current->journal_info = NULL;
  
  	put_transaction(cur_trans);
bb9c12c94   Sage Weil   Btrfs: async tran...
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
  	return 0;
  }
  
  /*
   * btrfs_transaction state sequence:
   *    in_commit = 0, blocked = 0  (initial)
   *    in_commit = 1, blocked = 1
   *    blocked = 0
   *    commit_done = 1
   */
79154b1b5   Chris Mason   Btrfs: transactio...
1064
1065
1066
  int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
  			     struct btrfs_root *root)
  {
15ee9bc7e   Josef Bacik   Btrfs: delay comm...
1067
  	unsigned long joined = 0;
79154b1b5   Chris Mason   Btrfs: transactio...
1068
  	struct btrfs_transaction *cur_trans;
8fd17795b   Chris Mason   Btrfs: early fsyn...
1069
  	struct btrfs_transaction *prev_trans = NULL;
79154b1b5   Chris Mason   Btrfs: transactio...
1070
  	DEFINE_WAIT(wait);
15ee9bc7e   Josef Bacik   Btrfs: delay comm...
1071
  	int ret;
89573b9c5   Chris Mason   Btrfs: Only let v...
1072
1073
  	int should_grow = 0;
  	unsigned long now = get_seconds();
dccae9999   Sage Weil   Btrfs: add flusho...
1074
  	int flush_on_commit = btrfs_test_opt(root, FLUSHONCOMMIT);
79154b1b5   Chris Mason   Btrfs: transactio...
1075

5a3f23d51   Chris Mason   Btrfs: add extra ...
1076
  	btrfs_run_ordered_operations(root, 0);
b24e03db0   Josef Bacik   Btrfs: release tr...
1077
  	btrfs_trans_release_metadata(trans, root);
9c8d86db9   Josef Bacik   Btrfs: make sure ...
1078
  	trans->block_rsv = NULL;
56bec294d   Chris Mason   Btrfs: do extent ...
1079
1080
1081
1082
1083
  	/* make a pass through all the delayed refs we have so far
  	 * any runnings procs may add more while we are here
  	 */
  	ret = btrfs_run_delayed_refs(trans, root, 0);
  	BUG_ON(ret);
b7ec40d78   Chris Mason   Btrfs: reduce sta...
1084
  	cur_trans = trans->transaction;
56bec294d   Chris Mason   Btrfs: do extent ...
1085
1086
1087
1088
  	/*
  	 * set the flushing flag so procs in this transaction have to
  	 * start sending their work down.
  	 */
b7ec40d78   Chris Mason   Btrfs: reduce sta...
1089
  	cur_trans->delayed_refs.flushing = 1;
56bec294d   Chris Mason   Btrfs: do extent ...
1090

c3e69d58e   Chris Mason   Btrfs: process th...
1091
  	ret = btrfs_run_delayed_refs(trans, root, 0);
56bec294d   Chris Mason   Btrfs: do extent ...
1092
  	BUG_ON(ret);
a4abeea41   Josef Bacik   Btrfs: kill trans...
1093
  	spin_lock(&cur_trans->commit_lock);
b7ec40d78   Chris Mason   Btrfs: reduce sta...
1094
  	if (cur_trans->in_commit) {
a4abeea41   Josef Bacik   Btrfs: kill trans...
1095
  		spin_unlock(&cur_trans->commit_lock);
13c5a93e7   Josef Bacik   Btrfs: avoid taki...
1096
  		atomic_inc(&cur_trans->use_count);
79154b1b5   Chris Mason   Btrfs: transactio...
1097
  		btrfs_end_transaction(trans, root);
ccd467d60   Chris Mason   Btrfs: crash reco...
1098

b9c8300c2   Li Zefan   Btrfs: remove a B...
1099
  		wait_for_commit(root, cur_trans);
15ee9bc7e   Josef Bacik   Btrfs: delay comm...
1100

79154b1b5   Chris Mason   Btrfs: transactio...
1101
  		put_transaction(cur_trans);
15ee9bc7e   Josef Bacik   Btrfs: delay comm...
1102

79154b1b5   Chris Mason   Btrfs: transactio...
1103
1104
  		return 0;
  	}
4313b3994   Chris Mason   Btrfs: Reduce sta...
1105

2c90e5d65   Chris Mason   Btrfs: still corr...
1106
  	trans->transaction->in_commit = 1;
f92957493   Chris Mason   btrfs_start_trans...
1107
  	trans->transaction->blocked = 1;
a4abeea41   Josef Bacik   Btrfs: kill trans...
1108
  	spin_unlock(&cur_trans->commit_lock);
bb9c12c94   Sage Weil   Btrfs: async tran...
1109
  	wake_up(&root->fs_info->transaction_blocked_wait);
a4abeea41   Josef Bacik   Btrfs: kill trans...
1110
  	spin_lock(&root->fs_info->trans_lock);
ccd467d60   Chris Mason   Btrfs: crash reco...
1111
1112
1113
1114
  	if (cur_trans->list.prev != &root->fs_info->trans_list) {
  		prev_trans = list_entry(cur_trans->list.prev,
  					struct btrfs_transaction, list);
  		if (!prev_trans->commit_done) {
13c5a93e7   Josef Bacik   Btrfs: avoid taki...
1115
  			atomic_inc(&prev_trans->use_count);
a4abeea41   Josef Bacik   Btrfs: kill trans...
1116
  			spin_unlock(&root->fs_info->trans_lock);
ccd467d60   Chris Mason   Btrfs: crash reco...
1117
1118
  
  			wait_for_commit(root, prev_trans);
ccd467d60   Chris Mason   Btrfs: crash reco...
1119

15ee9bc7e   Josef Bacik   Btrfs: delay comm...
1120
  			put_transaction(prev_trans);
a4abeea41   Josef Bacik   Btrfs: kill trans...
1121
1122
  		} else {
  			spin_unlock(&root->fs_info->trans_lock);
ccd467d60   Chris Mason   Btrfs: crash reco...
1123
  		}
a4abeea41   Josef Bacik   Btrfs: kill trans...
1124
1125
  	} else {
  		spin_unlock(&root->fs_info->trans_lock);
ccd467d60   Chris Mason   Btrfs: crash reco...
1126
  	}
15ee9bc7e   Josef Bacik   Btrfs: delay comm...
1127

89573b9c5   Chris Mason   Btrfs: Only let v...
1128
1129
  	if (now < cur_trans->start_time || now - cur_trans->start_time < 1)
  		should_grow = 1;
15ee9bc7e   Josef Bacik   Btrfs: delay comm...
1130
  	do {
7ea394f11   Yan Zheng   Btrfs: Fix nodata...
1131
  		int snap_pending = 0;
a4abeea41   Josef Bacik   Btrfs: kill trans...
1132

15ee9bc7e   Josef Bacik   Btrfs: delay comm...
1133
  		joined = cur_trans->num_joined;
7ea394f11   Yan Zheng   Btrfs: Fix nodata...
1134
1135
  		if (!list_empty(&trans->transaction->pending_snapshots))
  			snap_pending = 1;
2c90e5d65   Chris Mason   Btrfs: still corr...
1136
  		WARN_ON(cur_trans != trans->transaction);
15ee9bc7e   Josef Bacik   Btrfs: delay comm...
1137

0bdb1db29   Sage Weil   Btrfs: flush data...
1138
  		if (flush_on_commit || snap_pending) {
24bbcf044   Yan, Zheng   Btrfs: Add delaye...
1139
1140
  			btrfs_start_delalloc_inodes(root, 1);
  			ret = btrfs_wait_ordered_extents(root, 0, 1);
ebecd3d9d   Sage Weil   Btrfs: make flush...
1141
  			BUG_ON(ret);
7ea394f11   Yan Zheng   Btrfs: Fix nodata...
1142
  		}
16cdcec73   Miao Xie   btrfs: implement ...
1143
1144
  		ret = btrfs_run_delayed_items(trans, root);
  		BUG_ON(ret);
5a3f23d51   Chris Mason   Btrfs: add extra ...
1145
1146
1147
1148
1149
1150
1151
1152
  		/*
  		 * rename don't use btrfs_join_transaction, so, once we
  		 * set the transaction to blocked above, we aren't going
  		 * to get any new ordered operations.  We can safely run
  		 * it here and no for sure that nothing new will be added
  		 * to the list
  		 */
  		btrfs_run_ordered_operations(root, 1);
ed3b3d314   Chris Mason   Btrfs: don't walk...
1153
1154
  		prepare_to_wait(&cur_trans->writer_wait, &wait,
  				TASK_UNINTERRUPTIBLE);
13c5a93e7   Josef Bacik   Btrfs: avoid taki...
1155
  		if (atomic_read(&cur_trans->num_writers) > 1)
99d16cbca   Sage Weil   Btrfs: fix deadlo...
1156
1157
1158
  			schedule_timeout(MAX_SCHEDULE_TIMEOUT);
  		else if (should_grow)
  			schedule_timeout(1);
15ee9bc7e   Josef Bacik   Btrfs: delay comm...
1159

15ee9bc7e   Josef Bacik   Btrfs: delay comm...
1160
  		finish_wait(&cur_trans->writer_wait, &wait);
13c5a93e7   Josef Bacik   Btrfs: avoid taki...
1161
  	} while (atomic_read(&cur_trans->num_writers) > 1 ||
89573b9c5   Chris Mason   Btrfs: Only let v...
1162
  		 (should_grow && cur_trans->num_joined != joined));
15ee9bc7e   Josef Bacik   Btrfs: delay comm...
1163

7585717f3   Chris Mason   Btrfs: fix reloca...
1164
  	/*
ed0ca1402   Josef Bacik   Btrfs: set no_tra...
1165
1166
1167
1168
1169
1170
1171
1172
1173
  	 * Ok now we need to make sure to block out any other joins while we
  	 * commit the transaction.  We could have started a join before setting
  	 * no_join so make sure to wait for num_writers to == 1 again.
  	 */
  	spin_lock(&root->fs_info->trans_lock);
  	root->fs_info->trans_no_join = 1;
  	spin_unlock(&root->fs_info->trans_lock);
  	wait_event(cur_trans->writer_wait,
  		   atomic_read(&cur_trans->num_writers) == 1);
e038dca80   Chris Mason   Merge branch 'for...
1174
  	/*
7585717f3   Chris Mason   Btrfs: fix reloca...
1175
1176
1177
1178
1179
  	 * the reloc mutex makes sure that we stop
  	 * the balancing code from coming in and moving
  	 * extents around in the middle of the commit
  	 */
  	mutex_lock(&root->fs_info->reloc_mutex);
e999376f0   Chris Mason   Btrfs: avoid dela...
1180
  	ret = btrfs_run_delayed_items(trans, root);
3063d29f2   Chris Mason   Btrfs: Move snaps...
1181
  	BUG_ON(ret);
e999376f0   Chris Mason   Btrfs: avoid dela...
1182
  	ret = create_pending_snapshots(trans, root->fs_info);
16cdcec73   Miao Xie   btrfs: implement ...
1183
  	BUG_ON(ret);
56bec294d   Chris Mason   Btrfs: do extent ...
1184
1185
  	ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1);
  	BUG_ON(ret);
e999376f0   Chris Mason   Btrfs: avoid dela...
1186
1187
1188
1189
1190
  	/*
  	 * make sure none of the code above managed to slip in a
  	 * delayed item
  	 */
  	btrfs_assert_delayed_root_empty(root);
2c90e5d65   Chris Mason   Btrfs: still corr...
1191
  	WARN_ON(cur_trans != trans->transaction);
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
1192

a2de733c7   Arne Jansen   btrfs: scrub
1193
  	btrfs_scrub_pause(root);
e02119d5a   Chris Mason   Btrfs: Add a writ...
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
  	/* btrfs_commit_tree_roots is responsible for getting the
  	 * various roots consistent with each other.  Every pointer
  	 * in the tree of tree roots has to point to the most up to date
  	 * root for every subvolume and other tree.  So, we have to keep
  	 * the tree logging code from jumping in and changing any
  	 * of the trees.
  	 *
  	 * At this point in the commit, there can't be any tree-log
  	 * writers, but a little lower down we drop the trans mutex
  	 * and let new people in.  By holding the tree_log_mutex
  	 * from now until after the super is written, we avoid races
  	 * with the tree-log code.
  	 */
  	mutex_lock(&root->fs_info->tree_log_mutex);
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
1208
  	ret = commit_fs_roots(trans, root);
54aa1f4df   Chris Mason   Btrfs: Audit call...
1209
  	BUG_ON(ret);
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
1210
  	/* commit_fs_roots gets rid of all the tree log roots, it is now
e02119d5a   Chris Mason   Btrfs: Add a writ...
1211
1212
1213
  	 * safe to free the root of tree log roots
  	 */
  	btrfs_free_log_root_tree(trans, root->fs_info);
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
1214
  	ret = commit_cowonly_roots(trans, root);
79154b1b5   Chris Mason   Btrfs: transactio...
1215
  	BUG_ON(ret);
54aa1f4df   Chris Mason   Btrfs: Audit call...
1216

11833d66b   Yan Zheng   Btrfs: improve as...
1217
  	btrfs_prepare_extent_commit(trans, root);
78fae27eb   Chris Mason   Btrfs: leak fixes...
1218
  	cur_trans = root->fs_info->running_transaction;
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
1219
1220
1221
  
  	btrfs_set_root_node(&root->fs_info->tree_root->root_item,
  			    root->fs_info->tree_root->node);
817d52f8d   Josef Bacik   Btrfs: async bloc...
1222
  	switch_commit_root(root->fs_info->tree_root);
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
1223
1224
1225
  
  	btrfs_set_root_node(&root->fs_info->chunk_root->root_item,
  			    root->fs_info->chunk_root->node);
817d52f8d   Josef Bacik   Btrfs: async bloc...
1226
  	switch_commit_root(root->fs_info->chunk_root);
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
1227
1228
  
  	update_super_roots(root);
e02119d5a   Chris Mason   Btrfs: Add a writ...
1229
1230
  
  	if (!root->fs_info->log_root_recovering) {
6c41761fc   David Sterba   btrfs: separate s...
1231
1232
  		btrfs_set_super_log_root(root->fs_info->super_copy, 0);
  		btrfs_set_super_log_root_level(root->fs_info->super_copy, 0);
e02119d5a   Chris Mason   Btrfs: Add a writ...
1233
  	}
6c41761fc   David Sterba   btrfs: separate s...
1234
1235
  	memcpy(root->fs_info->super_for_commit, root->fs_info->super_copy,
  	       sizeof(*root->fs_info->super_copy));
ccd467d60   Chris Mason   Btrfs: crash reco...
1236

f92957493   Chris Mason   btrfs_start_trans...
1237
  	trans->transaction->blocked = 0;
a4abeea41   Josef Bacik   Btrfs: kill trans...
1238
1239
1240
1241
  	spin_lock(&root->fs_info->trans_lock);
  	root->fs_info->running_transaction = NULL;
  	root->fs_info->trans_no_join = 0;
  	spin_unlock(&root->fs_info->trans_lock);
7585717f3   Chris Mason   Btrfs: fix reloca...
1242
  	mutex_unlock(&root->fs_info->reloc_mutex);
b7ec40d78   Chris Mason   Btrfs: reduce sta...
1243

f92957493   Chris Mason   btrfs_start_trans...
1244
  	wake_up(&root->fs_info->transaction_wait);
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
1245

79154b1b5   Chris Mason   Btrfs: transactio...
1246
1247
  	ret = btrfs_write_and_wait_transaction(trans, root);
  	BUG_ON(ret);
a512bbf85   Yan Zheng   Btrfs: superblock...
1248
  	write_ctree_super(trans, root, 0);
4313b3994   Chris Mason   Btrfs: Reduce sta...
1249

e02119d5a   Chris Mason   Btrfs: Add a writ...
1250
1251
1252
1253
1254
  	/*
  	 * the super is written, we can safely allow the tree-loggers
  	 * to go about their business
  	 */
  	mutex_unlock(&root->fs_info->tree_log_mutex);
11833d66b   Yan Zheng   Btrfs: improve as...
1255
  	btrfs_finish_extent_commit(trans, root);
4313b3994   Chris Mason   Btrfs: Reduce sta...
1256

2c90e5d65   Chris Mason   Btrfs: still corr...
1257
  	cur_trans->commit_done = 1;
b7ec40d78   Chris Mason   Btrfs: reduce sta...
1258

15ee9bc7e   Josef Bacik   Btrfs: delay comm...
1259
  	root->fs_info->last_trans_committed = cur_trans->transid;
817d52f8d   Josef Bacik   Btrfs: async bloc...
1260

2c90e5d65   Chris Mason   Btrfs: still corr...
1261
  	wake_up(&cur_trans->commit_wait);
3de4586c5   Chris Mason   Btrfs: Allow subv...
1262

a4abeea41   Josef Bacik   Btrfs: kill trans...
1263
  	spin_lock(&root->fs_info->trans_lock);
13c5a93e7   Josef Bacik   Btrfs: avoid taki...
1264
  	list_del_init(&cur_trans->list);
a4abeea41   Josef Bacik   Btrfs: kill trans...
1265
  	spin_unlock(&root->fs_info->trans_lock);
78fae27eb   Chris Mason   Btrfs: leak fixes...
1266
  	put_transaction(cur_trans);
79154b1b5   Chris Mason   Btrfs: transactio...
1267
  	put_transaction(cur_trans);
58176a960   Josef Bacik   Btrfs: Add per-ro...
1268

1abe9b8a1   liubo   Btrfs: add initia...
1269
  	trace_btrfs_transaction_commit(root);
a2de733c7   Arne Jansen   btrfs: scrub
1270
  	btrfs_scrub_continue(root);
9ed74f2db   Josef Bacik   Btrfs: proper -EN...
1271
1272
  	if (current->journal_info == trans)
  		current->journal_info = NULL;
2c90e5d65   Chris Mason   Btrfs: still corr...
1273
  	kmem_cache_free(btrfs_trans_handle_cachep, trans);
24bbcf044   Yan, Zheng   Btrfs: Add delaye...
1274
1275
1276
  
  	if (current != root->fs_info->transaction_kthread)
  		btrfs_run_delayed_iputs(root);
79154b1b5   Chris Mason   Btrfs: transactio...
1277
1278
  	return ret;
  }
d352ac681   Chris Mason   Btrfs: add and im...
1279
1280
1281
  /*
   * interface function to delete all the snapshots we have scheduled for deletion
   */
e9d0b13b5   Chris Mason   Btrfs: Btree defr...
1282
1283
  int btrfs_clean_old_snapshots(struct btrfs_root *root)
  {
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
1284
1285
  	LIST_HEAD(list);
  	struct btrfs_fs_info *fs_info = root->fs_info;
a4abeea41   Josef Bacik   Btrfs: kill trans...
1286
  	spin_lock(&fs_info->trans_lock);
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
1287
  	list_splice_init(&fs_info->dead_roots, &list);
a4abeea41   Josef Bacik   Btrfs: kill trans...
1288
  	spin_unlock(&fs_info->trans_lock);
e9d0b13b5   Chris Mason   Btrfs: Btree defr...
1289

5d4f98a28   Yan Zheng   Btrfs: Mixed back...
1290
1291
  	while (!list_empty(&list)) {
  		root = list_entry(list.next, struct btrfs_root, root_list);
76dda93c6   Yan, Zheng   Btrfs: add snapsh...
1292
  		list_del(&root->root_list);
16cdcec73   Miao Xie   btrfs: implement ...
1293
  		btrfs_kill_all_delayed_nodes(root);
76dda93c6   Yan, Zheng   Btrfs: add snapsh...
1294
1295
  		if (btrfs_header_backref_rev(root->node) <
  		    BTRFS_MIXED_BACKREF_REV)
3fd0a5585   Yan, Zheng   Btrfs: Metadata E...
1296
  			btrfs_drop_snapshot(root, NULL, 0);
76dda93c6   Yan, Zheng   Btrfs: add snapsh...
1297
  		else
3fd0a5585   Yan, Zheng   Btrfs: Metadata E...
1298
  			btrfs_drop_snapshot(root, NULL, 1);
e9d0b13b5   Chris Mason   Btrfs: Btree defr...
1299
1300
1301
  	}
  	return 0;
  }