Blame view

fs/gfs2/log.c 33.3 KB
7336d0e65   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
b3b94faa5   David Teigland   [GFS2] The core o...
2
3
  /*
   * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
da6dd40d5   Bob Peterson   [GFS2] Journal ex...
4
   * Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
b3b94faa5   David Teigland   [GFS2] The core o...
5
6
7
8
9
10
11
   */
  
  #include <linux/sched.h>
  #include <linux/slab.h>
  #include <linux/spinlock.h>
  #include <linux/completion.h>
  #include <linux/buffer_head.h>
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
12
  #include <linux/gfs2_ondisk.h>
71b86f562   Steven Whitehouse   [GFS2] Further up...
13
  #include <linux/crc32.h>
c1696fb85   Bob Peterson   GFS2: Introduce n...
14
  #include <linux/crc32c.h>
a25311c8e   Steven Whitehouse   [GFS2] Move gfs2_...
15
  #include <linux/delay.h>
ec69b1888   Steven Whitehouse   [GFS2] Move gfs2_...
16
17
  #include <linux/kthread.h>
  #include <linux/freezer.h>
254db57f9   Steven Whitehouse   GFS2: Support for...
18
  #include <linux/bio.h>
885bceca7   Steven Whitehouse   GFS2: Plug on AIL...
19
  #include <linux/blkdev.h>
4667a0ec3   Steven Whitehouse   GFS2: Make writeb...
20
  #include <linux/writeback.h>
4a36d08d0   Bob Peterson   GFS2: Sort the or...
21
  #include <linux/list_sort.h>
b3b94faa5   David Teigland   [GFS2] The core o...
22
23
  
  #include "gfs2.h"
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
24
  #include "incore.h"
b3b94faa5   David Teigland   [GFS2] The core o...
25
26
27
28
29
  #include "bmap.h"
  #include "glock.h"
  #include "log.h"
  #include "lops.h"
  #include "meta_io.h"
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
30
  #include "util.h"
71b86f562   Steven Whitehouse   [GFS2] Further up...
31
  #include "dir.h"
63997775b   Steven Whitehouse   GFS2: Add tracepo...
32
  #include "trace_gfs2.h"
b839dadae   Bob Peterson   gfs2: new slab fo...
33
  #include "trans.h"
b3b94faa5   David Teigland   [GFS2] The core o...
34

feed98a8e   Bob Peterson   gfs2: make gfs2_l...
35
  static void gfs2_log_shutdown(struct gfs2_sbd *sdp);
b3b94faa5   David Teigland   [GFS2] The core o...
36
37
38
39
  /**
   * gfs2_struct2blk - compute stuff
   * @sdp: the filesystem
   * @nstruct: the number of structures
b3b94faa5   David Teigland   [GFS2] The core o...
40
41
42
43
44
45
   *
   * Compute the number of log descriptor blocks needed to hold a certain number
   * of structures of a certain size.
   *
   * Returns: the number of blocks needed (minimum is always 1)
   */
2e9eeaa11   Bob Peterson   gfs2: eliminate s...
46
  unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct)
b3b94faa5   David Teigland   [GFS2] The core o...
47
48
49
50
51
  {
  	unsigned int blks;
  	unsigned int first, second;
  
  	blks = 1;
2e9eeaa11   Bob Peterson   gfs2: eliminate s...
52
  	first = sdp->sd_ldptrs;
b3b94faa5   David Teigland   [GFS2] The core o...
53
54
  
  	if (nstruct > first) {
2e9eeaa11   Bob Peterson   gfs2: eliminate s...
55
  		second = sdp->sd_inptrs;
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
56
  		blks += DIV_ROUND_UP(nstruct - first, second);
b3b94faa5   David Teigland   [GFS2] The core o...
57
58
59
60
  	}
  
  	return blks;
  }
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
61
  /**
1e1a3d03e   Steven Whitehouse   [GFS2] Introduce ...
62
63
64
65
   * gfs2_remove_from_ail - Remove an entry from the ail lists, updating counters
   * @mapping: The associated mapping (maybe NULL)
   * @bd: The gfs2_bufdata to remove
   *
c618e87a5   Steven Whitehouse   GFS2: Update to A...
66
   * The ail lock _must_ be held when calling this function
1e1a3d03e   Steven Whitehouse   [GFS2] Introduce ...
67
68
   *
   */
9bc980cdb   Bob Peterson   GFS2: Make functi...
69
  static void gfs2_remove_from_ail(struct gfs2_bufdata *bd)
1e1a3d03e   Steven Whitehouse   [GFS2] Introduce ...
70
  {
16ca9412d   Benjamin Marzinski   GFS2: replace gfs...
71
  	bd->bd_tr = NULL;
1ad38c437   Steven Whitehouse   [GFS2] Clean up g...
72
73
  	list_del_init(&bd->bd_ail_st_list);
  	list_del_init(&bd->bd_ail_gl_list);
1e1a3d03e   Steven Whitehouse   [GFS2] Introduce ...
74
  	atomic_dec(&bd->bd_gl->gl_ail_count);
1e1a3d03e   Steven Whitehouse   [GFS2] Introduce ...
75
76
77
78
  	brelse(bd->bd_bh);
  }
  
  /**
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
79
80
   * gfs2_ail1_start_one - Start I/O on a part of the AIL
   * @sdp: the filesystem
4667a0ec3   Steven Whitehouse   GFS2: Make writeb...
81
82
   * @wbc: The writeback control structure
   * @ai: The ail structure
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
83
84
   *
   */
4f1de0182   Steven Whitehouse   GFS2: Fix ail lis...
85
86
  static int gfs2_ail1_start_one(struct gfs2_sbd *sdp,
  			       struct writeback_control *wbc,
69511080b   Bob Peterson   gfs2: Introduce c...
87
  			       struct gfs2_trans *tr)
d6a079e82   Dave Chinner   GFS2: introduce A...
88
89
  __releases(&sdp->sd_ail_lock)
  __acquires(&sdp->sd_ail_lock)
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
90
  {
5ac048bb7   Steven Whitehouse   GFS2: Use filemap...
91
  	struct gfs2_glock *gl = NULL;
4667a0ec3   Steven Whitehouse   GFS2: Make writeb...
92
  	struct address_space *mapping;
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
93
94
  	struct gfs2_bufdata *bd, *s;
  	struct buffer_head *bh;
b1676cbb1   Bob Peterson   gfs2: Withdraw in...
95
  	int ret = 0;
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
96

16ca9412d   Benjamin Marzinski   GFS2: replace gfs...
97
  	list_for_each_entry_safe_reverse(bd, s, &tr->tr_ail1_list, bd_ail_st_list) {
4667a0ec3   Steven Whitehouse   GFS2: Make writeb...
98
  		bh = bd->bd_bh;
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
99

16ca9412d   Benjamin Marzinski   GFS2: replace gfs...
100
  		gfs2_assert(sdp, bd->bd_tr == tr);
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
101

4667a0ec3   Steven Whitehouse   GFS2: Make writeb...
102
  		if (!buffer_busy(bh)) {
30fe70a85   Bob Peterson   gfs2: clear ail1 ...
103
104
105
106
107
  			if (buffer_uptodate(bh)) {
  				list_move(&bd->bd_ail_st_list,
  					  &tr->tr_ail2_list);
  				continue;
  			}
036330c91   Bob Peterson   gfs2: log error r...
108
  			if (!cmpxchg(&sdp->sd_log_error, 0, -EIO)) {
4667a0ec3   Steven Whitehouse   GFS2: Make writeb...
109
  				gfs2_io_error_bh(sdp, bh);
69511080b   Bob Peterson   gfs2: Introduce c...
110
  				gfs2_withdraw_delayed(sdp);
9e1a9ecd1   Andreas Gruenbacher   gfs2: Don't withd...
111
  			}
4667a0ec3   Steven Whitehouse   GFS2: Make writeb...
112
  		}
30fe70a85   Bob Peterson   gfs2: clear ail1 ...
113
114
115
116
  		if (gfs2_withdrawn(sdp)) {
  			gfs2_remove_from_ail(bd);
  			continue;
  		}
4667a0ec3   Steven Whitehouse   GFS2: Make writeb...
117
118
119
120
121
  		if (!buffer_dirty(bh))
  			continue;
  		if (gl == bd->bd_gl)
  			continue;
  		gl = bd->bd_gl;
16ca9412d   Benjamin Marzinski   GFS2: replace gfs...
122
  		list_move(&bd->bd_ail_st_list, &tr->tr_ail1_list);
4667a0ec3   Steven Whitehouse   GFS2: Make writeb...
123
  		mapping = bh->b_page->mapping;
4f1de0182   Steven Whitehouse   GFS2: Fix ail lis...
124
125
  		if (!mapping)
  			continue;
4667a0ec3   Steven Whitehouse   GFS2: Make writeb...
126
  		spin_unlock(&sdp->sd_ail_lock);
b1676cbb1   Bob Peterson   gfs2: Withdraw in...
127
  		ret = generic_writepages(mapping, wbc);
4667a0ec3   Steven Whitehouse   GFS2: Make writeb...
128
  		spin_lock(&sdp->sd_ail_lock);
b1676cbb1   Bob Peterson   gfs2: Withdraw in...
129
  		if (ret || wbc->nr_to_write <= 0)
4667a0ec3   Steven Whitehouse   GFS2: Make writeb...
130
  			break;
b1676cbb1   Bob Peterson   gfs2: Withdraw in...
131
  		return -EBUSY;
4667a0ec3   Steven Whitehouse   GFS2: Make writeb...
132
  	}
4f1de0182   Steven Whitehouse   GFS2: Fix ail lis...
133

b1676cbb1   Bob Peterson   gfs2: Withdraw in...
134
  	return ret;
4667a0ec3   Steven Whitehouse   GFS2: Make writeb...
135
  }
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
136

9592ea80a   Bob Peterson   gfs2: instrumenta...
137
138
139
140
141
  static void dump_ail_list(struct gfs2_sbd *sdp)
  {
  	struct gfs2_trans *tr;
  	struct gfs2_bufdata *bd;
  	struct buffer_head *bh;
9592ea80a   Bob Peterson   gfs2: instrumenta...
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
  	list_for_each_entry_reverse(tr, &sdp->sd_ail1_list, tr_list) {
  		list_for_each_entry_reverse(bd, &tr->tr_ail1_list,
  					    bd_ail_st_list) {
  			bh = bd->bd_bh;
  			fs_err(sdp, "bd %p: blk:0x%llx bh=%p ", bd,
  			       (unsigned long long)bd->bd_blkno, bh);
  			if (!bh) {
  				fs_err(sdp, "
  ");
  				continue;
  			}
  			fs_err(sdp, "0x%llx up2:%d dirt:%d lkd:%d req:%d "
  			       "map:%d new:%d ar:%d aw:%d delay:%d "
  			       "io err:%d unwritten:%d dfr:%d pin:%d esc:%d
  ",
  			       (unsigned long long)bh->b_blocknr,
  			       buffer_uptodate(bh), buffer_dirty(bh),
  			       buffer_locked(bh), buffer_req(bh),
  			       buffer_mapped(bh), buffer_new(bh),
  			       buffer_async_read(bh), buffer_async_write(bh),
  			       buffer_delay(bh), buffer_write_io_error(bh),
  			       buffer_unwritten(bh),
  			       buffer_defer_completion(bh),
  			       buffer_pinned(bh), buffer_escaped(bh));
  		}
  	}
  }
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
169

4667a0ec3   Steven Whitehouse   GFS2: Make writeb...
170
171
172
173
174
175
176
177
  /**
   * gfs2_ail1_flush - start writeback of some ail1 entries 
   * @sdp: The super block
   * @wbc: The writeback control structure
   *
   * Writes back some ail1 entries, according to the limits in the
   * writeback control structure
   */
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
178

4667a0ec3   Steven Whitehouse   GFS2: Make writeb...
179
180
181
  void gfs2_ail1_flush(struct gfs2_sbd *sdp, struct writeback_control *wbc)
  {
  	struct list_head *head = &sdp->sd_ail1_list;
16ca9412d   Benjamin Marzinski   GFS2: replace gfs...
182
  	struct gfs2_trans *tr;
885bceca7   Steven Whitehouse   GFS2: Plug on AIL...
183
  	struct blk_plug plug;
75b46c437   Bob Peterson   gfs2: Fix oversig...
184
  	int ret;
9592ea80a   Bob Peterson   gfs2: instrumenta...
185
  	unsigned long flush_start = jiffies;
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
186

c83ae9cad   Steven Whitehouse   GFS2: Add an AIL ...
187
  	trace_gfs2_ail_flush(sdp, wbc, 1);
885bceca7   Steven Whitehouse   GFS2: Plug on AIL...
188
  	blk_start_plug(&plug);
4667a0ec3   Steven Whitehouse   GFS2: Make writeb...
189
  	spin_lock(&sdp->sd_ail_lock);
4f1de0182   Steven Whitehouse   GFS2: Fix ail lis...
190
  restart:
75b46c437   Bob Peterson   gfs2: Fix oversig...
191
  	ret = 0;
9592ea80a   Bob Peterson   gfs2: instrumenta...
192
  	if (time_after(jiffies, flush_start + (HZ * 600))) {
d5dc3d967   Bob Peterson   gfs2: instrumenta...
193
194
195
  		fs_err(sdp, "Error: In %s for ten minutes! t=%d
  ",
  		       __func__, current->journal_info ? 1 : 0);
9592ea80a   Bob Peterson   gfs2: instrumenta...
196
197
198
  		dump_ail_list(sdp);
  		goto out;
  	}
16ca9412d   Benjamin Marzinski   GFS2: replace gfs...
199
  	list_for_each_entry_reverse(tr, head, tr_list) {
4667a0ec3   Steven Whitehouse   GFS2: Make writeb...
200
  		if (wbc->nr_to_write <= 0)
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
201
  			break;
b1676cbb1   Bob Peterson   gfs2: Withdraw in...
202
203
204
205
206
207
  		ret = gfs2_ail1_start_one(sdp, wbc, tr);
  		if (ret) {
  			if (ret == -EBUSY)
  				goto restart;
  			break;
  		}
4667a0ec3   Steven Whitehouse   GFS2: Make writeb...
208
  	}
9592ea80a   Bob Peterson   gfs2: instrumenta...
209
  out:
4667a0ec3   Steven Whitehouse   GFS2: Make writeb...
210
  	spin_unlock(&sdp->sd_ail_lock);
885bceca7   Steven Whitehouse   GFS2: Plug on AIL...
211
  	blk_finish_plug(&plug);
490031281   Bob Peterson   gfs2: Additional ...
212
213
214
215
  	if (ret) {
  		gfs2_lm(sdp, "gfs2_ail1_start_one (generic_writepages) "
  			"returned: %d
  ", ret);
badb55ec2   Andreas Gruenbacher   gfs2: Split gfs2_...
216
  		gfs2_withdraw(sdp);
490031281   Bob Peterson   gfs2: Additional ...
217
  	}
c83ae9cad   Steven Whitehouse   GFS2: Add an AIL ...
218
  	trace_gfs2_ail_flush(sdp, wbc, 0);
4667a0ec3   Steven Whitehouse   GFS2: Make writeb...
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
  }
  
  /**
   * gfs2_ail1_start - start writeback of all ail1 entries
   * @sdp: The superblock
   */
  
  static void gfs2_ail1_start(struct gfs2_sbd *sdp)
  {
  	struct writeback_control wbc = {
  		.sync_mode = WB_SYNC_NONE,
  		.nr_to_write = LONG_MAX,
  		.range_start = 0,
  		.range_end = LLONG_MAX,
  	};
  
  	return gfs2_ail1_flush(sdp, &wbc);
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
236
237
238
239
240
  }
  
  /**
   * gfs2_ail1_empty_one - Check whether or not a trans in the AIL has been synced
   * @sdp: the filesystem
5e4c7632a   Bob Peterson   gfs2: Issue revok...
241
242
   * @tr: the transaction
   * @max_revokes: If nonzero, issue revokes for the bd items for written buffers
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
243
244
   *
   */
5e4c7632a   Bob Peterson   gfs2: Issue revok...
245
246
  static void gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_trans *tr,
  				int *max_revokes)
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
247
248
249
  {
  	struct gfs2_bufdata *bd, *s;
  	struct buffer_head *bh;
16ca9412d   Benjamin Marzinski   GFS2: replace gfs...
250
  	list_for_each_entry_safe_reverse(bd, s, &tr->tr_ail1_list,
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
251
252
  					 bd_ail_st_list) {
  		bh = bd->bd_bh;
16ca9412d   Benjamin Marzinski   GFS2: replace gfs...
253
  		gfs2_assert(sdp, bd->bd_tr == tr);
036330c91   Bob Peterson   gfs2: log error r...
254
255
256
257
258
259
260
261
262
263
  		/*
  		 * If another process flagged an io error, e.g. writing to the
  		 * journal, error all other bhs and move them off the ail1 to
  		 * prevent a tight loop when unmount tries to flush ail1,
  		 * regardless of whether they're still busy. If no outside
  		 * errors were found and the buffer is busy, move to the next.
  		 * If the ail buffer is not busy and caught an error, flag it
  		 * for others.
  		 */
  		if (!sdp->sd_log_error && buffer_busy(bh))
4667a0ec3   Steven Whitehouse   GFS2: Make writeb...
264
  			continue;
b524abcc0   Bob Peterson   gfs2: slow the de...
265
  		if (!buffer_uptodate(bh) &&
036330c91   Bob Peterson   gfs2: log error r...
266
  		    !cmpxchg(&sdp->sd_log_error, 0, -EIO)) {
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
267
  			gfs2_io_error_bh(sdp, bh);
69511080b   Bob Peterson   gfs2: Introduce c...
268
  			gfs2_withdraw_delayed(sdp);
9e1a9ecd1   Andreas Gruenbacher   gfs2: Don't withd...
269
  		}
5e4c7632a   Bob Peterson   gfs2: Issue revok...
270
271
272
273
274
275
276
277
278
279
280
  		/*
  		 * If we have space for revokes and the bd is no longer on any
  		 * buf list, we can just add a revoke for it immediately and
  		 * avoid having to put it on the ail2 list, where it would need
  		 * to be revoked later.
  		 */
  		if (*max_revokes && list_empty(&bd->bd_list)) {
  			gfs2_add_revoke(sdp, bd);
  			(*max_revokes)--;
  			continue;
  		}
16ca9412d   Benjamin Marzinski   GFS2: replace gfs...
281
  		list_move(&bd->bd_ail_st_list, &tr->tr_ail2_list);
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
282
  	}
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
283
  }
4667a0ec3   Steven Whitehouse   GFS2: Make writeb...
284
285
286
  /**
   * gfs2_ail1_empty - Try to empty the ail1 lists
   * @sdp: The superblock
5e4c7632a   Bob Peterson   gfs2: Issue revok...
287
   * @max_revokes: If non-zero, add revokes where appropriate
4667a0ec3   Steven Whitehouse   GFS2: Make writeb...
288
289
290
   *
   * Tries to empty the ail1 lists, starting with the oldest first
   */
b3b94faa5   David Teigland   [GFS2] The core o...
291

5e4c7632a   Bob Peterson   gfs2: Issue revok...
292
  static int gfs2_ail1_empty(struct gfs2_sbd *sdp, int max_revokes)
b3b94faa5   David Teigland   [GFS2] The core o...
293
  {
16ca9412d   Benjamin Marzinski   GFS2: replace gfs...
294
  	struct gfs2_trans *tr, *s;
5d054964f   Benjamin Marzinski   GFS2: aggressivel...
295
  	int oldest_tr = 1;
b3b94faa5   David Teigland   [GFS2] The core o...
296
  	int ret;
d6a079e82   Dave Chinner   GFS2: introduce A...
297
  	spin_lock(&sdp->sd_ail_lock);
16ca9412d   Benjamin Marzinski   GFS2: replace gfs...
298
  	list_for_each_entry_safe_reverse(tr, s, &sdp->sd_ail1_list, tr_list) {
5e4c7632a   Bob Peterson   gfs2: Issue revok...
299
  		gfs2_ail1_empty_one(sdp, tr, &max_revokes);
5d054964f   Benjamin Marzinski   GFS2: aggressivel...
300
  		if (list_empty(&tr->tr_ail1_list) && oldest_tr)
16ca9412d   Benjamin Marzinski   GFS2: replace gfs...
301
  			list_move(&tr->tr_list, &sdp->sd_ail2_list);
4667a0ec3   Steven Whitehouse   GFS2: Make writeb...
302
  		else
5d054964f   Benjamin Marzinski   GFS2: aggressivel...
303
  			oldest_tr = 0;
b3b94faa5   David Teigland   [GFS2] The core o...
304
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
305
  	ret = list_empty(&sdp->sd_ail1_list);
d6a079e82   Dave Chinner   GFS2: introduce A...
306
  	spin_unlock(&sdp->sd_ail_lock);
b3b94faa5   David Teigland   [GFS2] The core o...
307

69511080b   Bob Peterson   gfs2: Introduce c...
308
  	if (test_bit(SDF_WITHDRAWING, &sdp->sd_flags)) {
badb55ec2   Andreas Gruenbacher   gfs2: Split gfs2_...
309
310
311
312
  		gfs2_lm(sdp, "fatal: I/O error(s)
  ");
  		gfs2_withdraw(sdp);
  	}
9e1a9ecd1   Andreas Gruenbacher   gfs2: Don't withd...
313

b3b94faa5   David Teigland   [GFS2] The core o...
314
315
  	return ret;
  }
26b06a695   Steven Whitehouse   GFS2: Wait proper...
316
317
  static void gfs2_ail1_wait(struct gfs2_sbd *sdp)
  {
16ca9412d   Benjamin Marzinski   GFS2: replace gfs...
318
  	struct gfs2_trans *tr;
26b06a695   Steven Whitehouse   GFS2: Wait proper...
319
320
321
322
  	struct gfs2_bufdata *bd;
  	struct buffer_head *bh;
  
  	spin_lock(&sdp->sd_ail_lock);
16ca9412d   Benjamin Marzinski   GFS2: replace gfs...
323
324
  	list_for_each_entry_reverse(tr, &sdp->sd_ail1_list, tr_list) {
  		list_for_each_entry(bd, &tr->tr_ail1_list, bd_ail_st_list) {
26b06a695   Steven Whitehouse   GFS2: Wait proper...
325
326
327
328
329
330
331
332
333
334
335
336
  			bh = bd->bd_bh;
  			if (!buffer_locked(bh))
  				continue;
  			get_bh(bh);
  			spin_unlock(&sdp->sd_ail_lock);
  			wait_on_buffer(bh);
  			brelse(bh);
  			return;
  		}
  	}
  	spin_unlock(&sdp->sd_ail_lock);
  }
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
337
338
  
  /**
2ca0c2fbf   Bob Peterson   gfs2: drain the a...
339
   * gfs2_ail_empty_tr - empty one of the ail lists for a transaction
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
340
   */
2ca0c2fbf   Bob Peterson   gfs2: drain the a...
341
342
  static void gfs2_ail_empty_tr(struct gfs2_sbd *sdp, struct gfs2_trans *tr,
  			      struct list_head *head)
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
343
  {
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
344
345
346
  	struct gfs2_bufdata *bd;
  
  	while (!list_empty(head)) {
2ca0c2fbf   Bob Peterson   gfs2: drain the a...
347
348
  		bd = list_first_entry(head, struct gfs2_bufdata,
  				      bd_ail_st_list);
16ca9412d   Benjamin Marzinski   GFS2: replace gfs...
349
  		gfs2_assert(sdp, bd->bd_tr == tr);
f91a0d3e2   Steven Whitehouse   [GFS2] Remove use...
350
  		gfs2_remove_from_ail(bd);
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
351
352
  	}
  }
b3b94faa5   David Teigland   [GFS2] The core o...
353
354
  static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail)
  {
16ca9412d   Benjamin Marzinski   GFS2: replace gfs...
355
  	struct gfs2_trans *tr, *safe;
b3b94faa5   David Teigland   [GFS2] The core o...
356
357
358
  	unsigned int old_tail = sdp->sd_log_tail;
  	int wrap = (new_tail < old_tail);
  	int a, b, rm;
d6a079e82   Dave Chinner   GFS2: introduce A...
359
  	spin_lock(&sdp->sd_ail_lock);
b3b94faa5   David Teigland   [GFS2] The core o...
360

16ca9412d   Benjamin Marzinski   GFS2: replace gfs...
361
362
363
  	list_for_each_entry_safe(tr, safe, &sdp->sd_ail2_list, tr_list) {
  		a = (old_tail <= tr->tr_first);
  		b = (tr->tr_first < new_tail);
b3b94faa5   David Teigland   [GFS2] The core o...
364
365
366
  		rm = (wrap) ? (a || b) : (a && b);
  		if (!rm)
  			continue;
2ca0c2fbf   Bob Peterson   gfs2: drain the a...
367
  		gfs2_ail_empty_tr(sdp, tr, &tr->tr_ail2_list);
16ca9412d   Benjamin Marzinski   GFS2: replace gfs...
368
369
370
  		list_del(&tr->tr_list);
  		gfs2_assert_warn(sdp, list_empty(&tr->tr_ail1_list));
  		gfs2_assert_warn(sdp, list_empty(&tr->tr_ail2_list));
b839dadae   Bob Peterson   gfs2: new slab fo...
371
  		gfs2_trans_free(sdp, tr);
b3b94faa5   David Teigland   [GFS2] The core o...
372
  	}
d6a079e82   Dave Chinner   GFS2: introduce A...
373
  	spin_unlock(&sdp->sd_ail_lock);
b3b94faa5   David Teigland   [GFS2] The core o...
374
375
376
  }
  
  /**
24972557b   Benjamin Marzinski   GFS2: remove tran...
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
   * gfs2_log_release - Release a given number of log blocks
   * @sdp: The GFS2 superblock
   * @blks: The number of blocks
   *
   */
  
  void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks)
  {
  
  	atomic_add(blks, &sdp->sd_log_blks_free);
  	trace_gfs2_log_blocks(sdp, blks);
  	gfs2_assert_withdraw(sdp, atomic_read(&sdp->sd_log_blks_free) <=
  				  sdp->sd_jdesc->jd_blocks);
  	up_read(&sdp->sd_log_flush_lock);
  }
  
  /**
b3b94faa5   David Teigland   [GFS2] The core o...
394
395
396
397
   * gfs2_log_reserve - Make a log reservation
   * @sdp: The GFS2 superblock
   * @blks: The number of blocks to reserve
   *
89918647a   Steven Whitehouse   [GFS2] Make the l...
398
   * Note that we never give out the last few blocks of the journal. Thats
2332c4435   Robert Peterson   [GFS2] assertion ...
399
   * due to the fact that there is a small number of header blocks
b004157ab   Steven Whitehouse   [GFS2] Fix journa...
400
401
402
403
   * associated with each log flush. The exact number can't be known until
   * flush time, so we ensure that we have just enough free blocks at all
   * times to avoid running out during a log flush.
   *
5e687eac1   Benjamin Marzinski   GFS2: Various gfs...
404
405
406
407
408
409
   * We no longer flush the log here, instead we wake up logd to do that
   * for us. To avoid the thundering herd and to ensure that we deal fairly
   * with queued waiters, we use an exclusive wait. This means that when we
   * get woken with enough journal space to get our reservation, we need to
   * wake the next waiter on the list.
   *
b3b94faa5   David Teigland   [GFS2] The core o...
410
411
412
413
414
   * Returns: errno
   */
  
  int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks)
  {
2e60d7683   Benjamin Marzinski   GFS2: update free...
415
  	int ret = 0;
5d054964f   Benjamin Marzinski   GFS2: aggressivel...
416
  	unsigned reserved_blks = 7 * (4096 / sdp->sd_vfs->s_blocksize);
5e687eac1   Benjamin Marzinski   GFS2: Various gfs...
417
418
419
420
  	unsigned wanted = blks + reserved_blks;
  	DEFINE_WAIT(wait);
  	int did_wait = 0;
  	unsigned int free_blocks;
b3b94faa5   David Teigland   [GFS2] The core o...
421
422
423
424
  
  	if (gfs2_assert_warn(sdp, blks) ||
  	    gfs2_assert_warn(sdp, blks <= sdp->sd_jdesc->jd_blocks))
  		return -EINVAL;
f07b35202   Bob Peterson   GFS2: Made logd d...
425
  	atomic_add(blks, &sdp->sd_log_blks_needed);
5e687eac1   Benjamin Marzinski   GFS2: Various gfs...
426
427
428
429
430
431
432
433
434
435
436
437
438
  retry:
  	free_blocks = atomic_read(&sdp->sd_log_blks_free);
  	if (unlikely(free_blocks <= wanted)) {
  		do {
  			prepare_to_wait_exclusive(&sdp->sd_log_waitq, &wait,
  					TASK_UNINTERRUPTIBLE);
  			wake_up(&sdp->sd_logd_waitq);
  			did_wait = 1;
  			if (atomic_read(&sdp->sd_log_blks_free) <= wanted)
  				io_schedule();
  			free_blocks = atomic_read(&sdp->sd_log_blks_free);
  		} while(free_blocks <= wanted);
  		finish_wait(&sdp->sd_log_waitq, &wait);
b3b94faa5   David Teigland   [GFS2] The core o...
439
  	}
2e60d7683   Benjamin Marzinski   GFS2: update free...
440
  	atomic_inc(&sdp->sd_reserving_log);
5e687eac1   Benjamin Marzinski   GFS2: Various gfs...
441
  	if (atomic_cmpxchg(&sdp->sd_log_blks_free, free_blocks,
2e60d7683   Benjamin Marzinski   GFS2: update free...
442
443
444
  				free_blocks - blks) != free_blocks) {
  		if (atomic_dec_and_test(&sdp->sd_reserving_log))
  			wake_up(&sdp->sd_reserving_log_wait);
5e687eac1   Benjamin Marzinski   GFS2: Various gfs...
445
  		goto retry;
2e60d7683   Benjamin Marzinski   GFS2: update free...
446
  	}
f07b35202   Bob Peterson   GFS2: Made logd d...
447
  	atomic_sub(blks, &sdp->sd_log_blks_needed);
63997775b   Steven Whitehouse   GFS2: Add tracepo...
448
  	trace_gfs2_log_blocks(sdp, -blks);
5e687eac1   Benjamin Marzinski   GFS2: Various gfs...
449
450
451
452
453
454
455
  
  	/*
  	 * If we waited, then so might others, wake them up _after_ we get
  	 * our share of the log.
  	 */
  	if (unlikely(did_wait))
  		wake_up(&sdp->sd_log_waitq);
484adff8a   Steven Whitehouse   [GFS2] Update loc...
456
457
  
  	down_read(&sdp->sd_log_flush_lock);
24972557b   Benjamin Marzinski   GFS2: remove tran...
458
459
  	if (unlikely(!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags))) {
  		gfs2_log_release(sdp, blks);
2e60d7683   Benjamin Marzinski   GFS2: update free...
460
  		ret = -EROFS;
24972557b   Benjamin Marzinski   GFS2: remove tran...
461
  	}
2e60d7683   Benjamin Marzinski   GFS2: update free...
462
463
464
  	if (atomic_dec_and_test(&sdp->sd_reserving_log))
  		wake_up(&sdp->sd_reserving_log_wait);
  	return ret;
b3b94faa5   David Teigland   [GFS2] The core o...
465
  }
b3b94faa5   David Teigland   [GFS2] The core o...
466
467
468
469
470
471
472
473
474
475
476
  /**
   * log_distance - Compute distance between two journal blocks
   * @sdp: The GFS2 superblock
   * @newer: The most recent journal block of the pair
   * @older: The older journal block of the pair
   *
   *   Compute the distance (in the journal direction) between two
   *   blocks in the journal
   *
   * Returns: the distance in blocks
   */
faa31ce85   Steven Whitehouse   [GFS2] Tidy up log.c
477
  static inline unsigned int log_distance(struct gfs2_sbd *sdp, unsigned int newer,
b3b94faa5   David Teigland   [GFS2] The core o...
478
479
480
481
482
483
484
485
486
487
  					unsigned int older)
  {
  	int dist;
  
  	dist = newer - older;
  	if (dist < 0)
  		dist += sdp->sd_jdesc->jd_blocks;
  
  	return dist;
  }
2332c4435   Robert Peterson   [GFS2] assertion ...
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
  /**
   * calc_reserved - Calculate the number of blocks to reserve when
   *                 refunding a transaction's unused buffers.
   * @sdp: The GFS2 superblock
   *
   * This is complex.  We need to reserve room for all our currently used
   * metadata buffers (e.g. normal file I/O rewriting file time stamps) and 
   * all our journaled data buffers for journaled files (e.g. files in the 
   * meta_fs like rindex, or files for which chattr +j was done.)
   * If we don't reserve enough space, gfs2_log_refund and gfs2_log_flush
   * will count it as free space (sd_log_blks_free) and corruption will follow.
   *
   * We can have metadata bufs and jdata bufs in the same journal.  So each
   * type gets its own log header, for which we need to reserve a block.
   * In fact, each type has the potential for needing more than one header 
   * in cases where we have more buffers than will fit on a journal page.
   * Metadata journal entries take up half the space of journaled buffer entries.
   * Thus, metadata entries have buf_limit (502) and journaled buffers have
   * databuf_limit (251) before they cause a wrap around.
   *
   * Also, we need to reserve blocks for revoke journal entries and one for an
   * overall header for the lot.
   *
   * Returns: the number of blocks reserved
   */
  static unsigned int calc_reserved(struct gfs2_sbd *sdp)
  {
  	unsigned int reserved = 0;
022ef4fee   Steven Whitehouse   GFS2: Move log bu...
516
517
518
  	unsigned int mbuf;
  	unsigned int dbuf;
  	struct gfs2_trans *tr = sdp->sd_log_tr;
2332c4435   Robert Peterson   [GFS2] assertion ...
519

022ef4fee   Steven Whitehouse   GFS2: Move log bu...
520
521
522
523
524
525
526
527
  	if (tr) {
  		mbuf = tr->tr_num_buf_new - tr->tr_num_buf_rm;
  		dbuf = tr->tr_num_databuf_new - tr->tr_num_databuf_rm;
  		reserved = mbuf + dbuf;
  		/* Account for header blocks */
  		reserved += DIV_ROUND_UP(mbuf, buf_limit(sdp));
  		reserved += DIV_ROUND_UP(dbuf, databuf_limit(sdp));
  	}
2332c4435   Robert Peterson   [GFS2] assertion ...
528

5d4397585   Andreas Gruenbacher   gfs2: Fix incorre...
529
530
  	if (sdp->sd_log_committed_revoke > 0)
  		reserved += gfs2_struct2blk(sdp, sdp->sd_log_committed_revoke);
2332c4435   Robert Peterson   [GFS2] assertion ...
531
532
533
534
535
  	/* One for the overall header */
  	if (reserved)
  		reserved++;
  	return reserved;
  }
b3b94faa5   David Teigland   [GFS2] The core o...
536
537
  static unsigned int current_tail(struct gfs2_sbd *sdp)
  {
16ca9412d   Benjamin Marzinski   GFS2: replace gfs...
538
  	struct gfs2_trans *tr;
b3b94faa5   David Teigland   [GFS2] The core o...
539
  	unsigned int tail;
d6a079e82   Dave Chinner   GFS2: introduce A...
540
  	spin_lock(&sdp->sd_ail_lock);
b3b94faa5   David Teigland   [GFS2] The core o...
541

faa31ce85   Steven Whitehouse   [GFS2] Tidy up log.c
542
  	if (list_empty(&sdp->sd_ail1_list)) {
b3b94faa5   David Teigland   [GFS2] The core o...
543
  		tail = sdp->sd_log_head;
faa31ce85   Steven Whitehouse   [GFS2] Tidy up log.c
544
  	} else {
969183bc6   Andreas Gruenbacher   gfs2: Switch to l...
545
  		tr = list_last_entry(&sdp->sd_ail1_list, struct gfs2_trans,
16ca9412d   Benjamin Marzinski   GFS2: replace gfs...
546
547
  				tr_list);
  		tail = tr->tr_first;
b3b94faa5   David Teigland   [GFS2] The core o...
548
  	}
d6a079e82   Dave Chinner   GFS2: introduce A...
549
  	spin_unlock(&sdp->sd_ail_lock);
b3b94faa5   David Teigland   [GFS2] The core o...
550
551
552
  
  	return tail;
  }
2332c4435   Robert Peterson   [GFS2] assertion ...
553
  static void log_pull_tail(struct gfs2_sbd *sdp, unsigned int new_tail)
b3b94faa5   David Teigland   [GFS2] The core o...
554
555
556
557
  {
  	unsigned int dist = log_distance(sdp, new_tail, sdp->sd_log_tail);
  
  	ail2_empty(sdp, new_tail);
fd041f0b4   Steven Whitehouse   [GFS2] Use atomic...
558
  	atomic_add(dist, &sdp->sd_log_blks_free);
63997775b   Steven Whitehouse   GFS2: Add tracepo...
559
  	trace_gfs2_log_blocks(sdp, dist);
5e687eac1   Benjamin Marzinski   GFS2: Various gfs...
560
561
  	gfs2_assert_withdraw(sdp, atomic_read(&sdp->sd_log_blks_free) <=
  			     sdp->sd_jdesc->jd_blocks);
b3b94faa5   David Teigland   [GFS2] The core o...
562
563
564
  
  	sdp->sd_log_tail = new_tail;
  }
b3b94faa5   David Teigland   [GFS2] The core o...
565

9ff782893   Bob Peterson   gfs2: Do log_flus...
566
  void log_flush_wait(struct gfs2_sbd *sdp)
b3b94faa5   David Teigland   [GFS2] The core o...
567
  {
16615be18   Steven Whitehouse   [GFS2] Clean up j...
568
569
570
571
572
573
574
575
576
577
  	DEFINE_WAIT(wait);
  
  	if (atomic_read(&sdp->sd_log_in_flight)) {
  		do {
  			prepare_to_wait(&sdp->sd_log_flush_wait, &wait,
  					TASK_UNINTERRUPTIBLE);
  			if (atomic_read(&sdp->sd_log_in_flight))
  				io_schedule();
  		} while(atomic_read(&sdp->sd_log_in_flight));
  		finish_wait(&sdp->sd_log_flush_wait, &wait);
b3b94faa5   David Teigland   [GFS2] The core o...
578
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
579
  }
451389909   Steven Whitehouse   GFS2: Use ->write...
580
  static int ip_cmp(void *priv, struct list_head *a, struct list_head *b)
4a36d08d0   Bob Peterson   GFS2: Sort the or...
581
  {
451389909   Steven Whitehouse   GFS2: Use ->write...
582
  	struct gfs2_inode *ipa, *ipb;
4a36d08d0   Bob Peterson   GFS2: Sort the or...
583

451389909   Steven Whitehouse   GFS2: Use ->write...
584
585
  	ipa = list_entry(a, struct gfs2_inode, i_ordered);
  	ipb = list_entry(b, struct gfs2_inode, i_ordered);
4a36d08d0   Bob Peterson   GFS2: Sort the or...
586

451389909   Steven Whitehouse   GFS2: Use ->write...
587
  	if (ipa->i_no_addr < ipb->i_no_addr)
4a36d08d0   Bob Peterson   GFS2: Sort the or...
588
  		return -1;
451389909   Steven Whitehouse   GFS2: Use ->write...
589
  	if (ipa->i_no_addr > ipb->i_no_addr)
4a36d08d0   Bob Peterson   GFS2: Sort the or...
590
591
592
  		return 1;
  	return 0;
  }
7542486b8   Bob Peterson   gfs2: eliminate G...
593
594
595
596
597
  static void __ordered_del_inode(struct gfs2_inode *ip)
  {
  	if (!list_empty(&ip->i_ordered))
  		list_del_init(&ip->i_ordered);
  }
d7b616e25   Steven Whitehouse   [GFS2] Clean up o...
598
599
  static void gfs2_ordered_write(struct gfs2_sbd *sdp)
  {
451389909   Steven Whitehouse   GFS2: Use ->write...
600
  	struct gfs2_inode *ip;
d7b616e25   Steven Whitehouse   [GFS2] Clean up o...
601
  	LIST_HEAD(written);
451389909   Steven Whitehouse   GFS2: Use ->write...
602
  	spin_lock(&sdp->sd_ordered_lock);
a5b1d3fc5   Andreas Gruenbacher   gfs2: Rename sd_l...
603
604
  	list_sort(NULL, &sdp->sd_log_ordered, &ip_cmp);
  	while (!list_empty(&sdp->sd_log_ordered)) {
969183bc6   Andreas Gruenbacher   gfs2: Switch to l...
605
  		ip = list_first_entry(&sdp->sd_log_ordered, struct gfs2_inode, i_ordered);
1f23bc786   Abhi Das   gfs2: Trim the or...
606
  		if (ip->i_inode.i_mapping->nrpages == 0) {
7542486b8   Bob Peterson   gfs2: eliminate G...
607
  			__ordered_del_inode(ip);
d7b616e25   Steven Whitehouse   [GFS2] Clean up o...
608
  			continue;
1f23bc786   Abhi Das   gfs2: Trim the or...
609
610
  		}
  		list_move(&ip->i_ordered, &written);
451389909   Steven Whitehouse   GFS2: Use ->write...
611
612
613
  		spin_unlock(&sdp->sd_ordered_lock);
  		filemap_fdatawrite(ip->i_inode.i_mapping);
  		spin_lock(&sdp->sd_ordered_lock);
d7b616e25   Steven Whitehouse   [GFS2] Clean up o...
614
  	}
a5b1d3fc5   Andreas Gruenbacher   gfs2: Rename sd_l...
615
  	list_splice(&written, &sdp->sd_log_ordered);
451389909   Steven Whitehouse   GFS2: Use ->write...
616
  	spin_unlock(&sdp->sd_ordered_lock);
d7b616e25   Steven Whitehouse   [GFS2] Clean up o...
617
618
619
620
  }
  
  static void gfs2_ordered_wait(struct gfs2_sbd *sdp)
  {
451389909   Steven Whitehouse   GFS2: Use ->write...
621
  	struct gfs2_inode *ip;
d7b616e25   Steven Whitehouse   [GFS2] Clean up o...
622

451389909   Steven Whitehouse   GFS2: Use ->write...
623
  	spin_lock(&sdp->sd_ordered_lock);
a5b1d3fc5   Andreas Gruenbacher   gfs2: Rename sd_l...
624
  	while (!list_empty(&sdp->sd_log_ordered)) {
969183bc6   Andreas Gruenbacher   gfs2: Switch to l...
625
  		ip = list_first_entry(&sdp->sd_log_ordered, struct gfs2_inode, i_ordered);
7542486b8   Bob Peterson   gfs2: eliminate G...
626
  		__ordered_del_inode(ip);
451389909   Steven Whitehouse   GFS2: Use ->write...
627
  		if (ip->i_inode.i_mapping->nrpages == 0)
d7b616e25   Steven Whitehouse   [GFS2] Clean up o...
628
  			continue;
451389909   Steven Whitehouse   GFS2: Use ->write...
629
630
631
  		spin_unlock(&sdp->sd_ordered_lock);
  		filemap_fdatawait(ip->i_inode.i_mapping);
  		spin_lock(&sdp->sd_ordered_lock);
d7b616e25   Steven Whitehouse   [GFS2] Clean up o...
632
  	}
451389909   Steven Whitehouse   GFS2: Use ->write...
633
634
635
636
637
638
639
640
  	spin_unlock(&sdp->sd_ordered_lock);
  }
  
  void gfs2_ordered_del_inode(struct gfs2_inode *ip)
  {
  	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
  
  	spin_lock(&sdp->sd_ordered_lock);
7542486b8   Bob Peterson   gfs2: eliminate G...
641
  	__ordered_del_inode(ip);
451389909   Steven Whitehouse   GFS2: Use ->write...
642
  	spin_unlock(&sdp->sd_ordered_lock);
d7b616e25   Steven Whitehouse   [GFS2] Clean up o...
643
  }
5d054964f   Benjamin Marzinski   GFS2: aggressivel...
644
645
646
647
  void gfs2_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
  {
  	struct buffer_head *bh = bd->bd_bh;
  	struct gfs2_glock *gl = bd->bd_gl;
f4e2f5e1a   Andreas Gruenbacher   gfs2: Grab glock ...
648
649
650
  	sdp->sd_log_num_revoke++;
  	if (atomic_inc_return(&gl->gl_revokes) == 1)
  		gfs2_glock_hold(gl);
5d054964f   Benjamin Marzinski   GFS2: aggressivel...
651
652
  	bh->b_private = NULL;
  	bd->bd_blkno = bh->b_blocknr;
9290a9a7c   Bob Peterson   GFS2: Fix use-aft...
653
654
  	gfs2_remove_from_ail(bd); /* drops ref on bh */
  	bd->bd_bh = NULL;
5d054964f   Benjamin Marzinski   GFS2: aggressivel...
655
  	set_bit(GLF_LFLUSH, &gl->gl_flags);
a5b1d3fc5   Andreas Gruenbacher   gfs2: Rename sd_l...
656
  	list_add(&bd->bd_list, &sdp->sd_log_revokes);
5d054964f   Benjamin Marzinski   GFS2: aggressivel...
657
  }
fe5e7ba11   Bob Peterson   gfs2: fix glock r...
658
659
660
661
662
663
664
  void gfs2_glock_remove_revoke(struct gfs2_glock *gl)
  {
  	if (atomic_dec_return(&gl->gl_revokes) == 0) {
  		clear_bit(GLF_LFLUSH, &gl->gl_flags);
  		gfs2_glock_queue_put(gl);
  	}
  }
5e4c7632a   Bob Peterson   gfs2: Issue revok...
665
666
667
668
669
670
671
672
673
674
675
676
  /**
   * gfs2_write_revokes - Add as many revokes to the system transaction as we can
   * @sdp: The GFS2 superblock
   *
   * Our usual strategy is to defer writing revokes as much as we can in the hope
   * that we'll eventually overwrite the journal, which will make those revokes
   * go away.  This changes when we flush the log: at that point, there will
   * likely be some left-over space in the last revoke block of that transaction.
   * We can fill that space with additional revokes for blocks that have already
   * been written back.  This will basically come at no cost now, and will save
   * us from having to keep track of those blocks on the AIL2 list later.
   */
5d054964f   Benjamin Marzinski   GFS2: aggressivel...
677
678
  void gfs2_write_revokes(struct gfs2_sbd *sdp)
  {
5e4c7632a   Bob Peterson   gfs2: Issue revok...
679
  	/* number of revokes we still have room for */
5d054964f   Benjamin Marzinski   GFS2: aggressivel...
680
  	int max_revokes = (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_log_descriptor)) / sizeof(u64);
5e4c7632a   Bob Peterson   gfs2: Issue revok...
681
  	gfs2_log_lock(sdp);
5d054964f   Benjamin Marzinski   GFS2: aggressivel...
682
683
684
685
686
687
688
689
690
691
  	while (sdp->sd_log_num_revoke > max_revokes)
  		max_revokes += (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header)) / sizeof(u64);
  	max_revokes -= sdp->sd_log_num_revoke;
  	if (!sdp->sd_log_num_revoke) {
  		atomic_dec(&sdp->sd_log_blks_free);
  		/* If no blocks have been reserved, we need to also
  		 * reserve a block for the header */
  		if (!sdp->sd_log_blks_reserved)
  			atomic_dec(&sdp->sd_log_blks_free);
  	}
5e4c7632a   Bob Peterson   gfs2: Issue revok...
692
  	gfs2_ail1_empty(sdp, max_revokes);
5d054964f   Benjamin Marzinski   GFS2: aggressivel...
693
694
695
696
697
698
699
700
  	gfs2_log_unlock(sdp);
  
  	if (!sdp->sd_log_num_revoke) {
  		atomic_inc(&sdp->sd_log_blks_free);
  		if (!sdp->sd_log_blks_reserved)
  			atomic_inc(&sdp->sd_log_blks_free);
  	}
  }
b3b94faa5   David Teigland   [GFS2] The core o...
701
  /**
7c70b8969   Bob Peterson   gfs2: clean_journ...
702
   * gfs2_write_log_header - Write a journal log header buffer at lblock
34cc1781c   Steven Whitehouse   GFS2: Clean up lo...
703
   * @sdp: The GFS2 superblock
c1696fb85   Bob Peterson   GFS2: Introduce n...
704
   * @jd: journal descriptor of the journal to which we are writing
588bff95c   Bob Peterson   GFS2: Reduce code...
705
706
   * @seq: sequence number
   * @tail: tail of the log
7c70b8969   Bob Peterson   gfs2: clean_journ...
707
   * @lblock: value for lh_blkno (block number relative to start of journal)
c1696fb85   Bob Peterson   GFS2: Introduce n...
708
   * @flags: log header flags GFS2_LOG_HEAD_*
588bff95c   Bob Peterson   GFS2: Reduce code...
709
   * @op_flags: flags to pass to the bio
34cc1781c   Steven Whitehouse   GFS2: Clean up lo...
710
711
712
   *
   * Returns: the initialized log buffer descriptor
   */
c1696fb85   Bob Peterson   GFS2: Introduce n...
713
  void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd,
7c70b8969   Bob Peterson   gfs2: clean_journ...
714
715
  			   u64 seq, u32 tail, u32 lblock, u32 flags,
  			   int op_flags)
34cc1781c   Steven Whitehouse   GFS2: Clean up lo...
716
  {
34cc1781c   Steven Whitehouse   GFS2: Clean up lo...
717
  	struct gfs2_log_header *lh;
c1696fb85   Bob Peterson   GFS2: Introduce n...
718
  	u32 hash, crc;
ade480889   Bob Peterson   gfs2: Don't write...
719
  	struct page *page;
c1696fb85   Bob Peterson   GFS2: Introduce n...
720
721
722
  	struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
  	struct timespec64 tv;
  	struct super_block *sb = sdp->sd_vfs;
7c70b8969   Bob Peterson   gfs2: clean_journ...
723
  	u64 dblock;
588bff95c   Bob Peterson   GFS2: Reduce code...
724

ade480889   Bob Peterson   gfs2: Don't write...
725
726
727
728
  	if (gfs2_withdrawn(sdp))
  		goto out;
  
  	page = mempool_alloc(gfs2_page_pool, GFP_NOIO);
e8c92ed76   Steven Whitehouse   GFS2: Clean up lo...
729
730
  	lh = page_address(page);
  	clear_page(lh);
34cc1781c   Steven Whitehouse   GFS2: Clean up lo...
731

34cc1781c   Steven Whitehouse   GFS2: Clean up lo...
732
733
734
735
736
  	lh->lh_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
  	lh->lh_header.mh_type = cpu_to_be32(GFS2_METATYPE_LH);
  	lh->lh_header.__pad0 = cpu_to_be64(0);
  	lh->lh_header.mh_format = cpu_to_be32(GFS2_FORMAT_LH);
  	lh->lh_header.mh_jid = cpu_to_be32(sdp->sd_jdesc->jd_jid);
588bff95c   Bob Peterson   GFS2: Reduce code...
737
  	lh->lh_sequence = cpu_to_be64(seq);
34cc1781c   Steven Whitehouse   GFS2: Clean up lo...
738
739
  	lh->lh_flags = cpu_to_be32(flags);
  	lh->lh_tail = cpu_to_be32(tail);
7c70b8969   Bob Peterson   gfs2: clean_journ...
740
  	lh->lh_blkno = cpu_to_be32(lblock);
c1696fb85   Bob Peterson   GFS2: Introduce n...
741
  	hash = ~crc32(~0, lh, LH_V1_SIZE);
34cc1781c   Steven Whitehouse   GFS2: Clean up lo...
742
  	lh->lh_hash = cpu_to_be32(hash);
ee9c7f9ae   Arnd Bergmann   gfs2: call ktime_...
743
  	ktime_get_coarse_real_ts64(&tv);
c1696fb85   Bob Peterson   GFS2: Introduce n...
744
745
  	lh->lh_nsec = cpu_to_be32(tv.tv_nsec);
  	lh->lh_sec = cpu_to_be64(tv.tv_sec);
7c70b8969   Bob Peterson   gfs2: clean_journ...
746
  	if (!list_empty(&jd->extent_list))
19ebc050e   Andreas Gruenbacher   gfs2: Remove acti...
747
  		dblock = gfs2_log_bmap(jd, lblock);
7c70b8969   Bob Peterson   gfs2: clean_journ...
748
749
750
751
752
753
  	else {
  		int ret = gfs2_lblk_to_dblk(jd->jd_inode, lblock, &dblock);
  		if (gfs2_assert_withdraw(sdp, ret == 0))
  			return;
  	}
  	lh->lh_addr = cpu_to_be64(dblock);
c1696fb85   Bob Peterson   GFS2: Introduce n...
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
  	lh->lh_jinode = cpu_to_be64(GFS2_I(jd->jd_inode)->i_no_addr);
  
  	/* We may only write local statfs, quota, etc., when writing to our
  	   own journal. The values are left 0 when recovering a journal
  	   different from our own. */
  	if (!(flags & GFS2_LOG_HEAD_RECOVERY)) {
  		lh->lh_statfs_addr =
  			cpu_to_be64(GFS2_I(sdp->sd_sc_inode)->i_no_addr);
  		lh->lh_quota_addr =
  			cpu_to_be64(GFS2_I(sdp->sd_qc_inode)->i_no_addr);
  
  		spin_lock(&sdp->sd_statfs_spin);
  		lh->lh_local_total = cpu_to_be64(l_sc->sc_total);
  		lh->lh_local_free = cpu_to_be64(l_sc->sc_free);
  		lh->lh_local_dinodes = cpu_to_be64(l_sc->sc_dinodes);
  		spin_unlock(&sdp->sd_statfs_spin);
  	}
  
  	BUILD_BUG_ON(offsetof(struct gfs2_log_header, lh_crc) != LH_V1_SIZE);
  
  	crc = crc32c(~0, (void *)lh + LH_V1_SIZE + 4,
  		     sb->s_blocksize - LH_V1_SIZE - 4);
  	lh->lh_crc = cpu_to_be32(crc);
7c70b8969   Bob Peterson   gfs2: clean_journ...
777
  	gfs2_log_write(sdp, page, sb->s_blocksize, 0, dblock);
f4686c26e   Abhi Das   gfs2: read journa...
778
  	gfs2_log_submit_bio(&sdp->sd_log_bio, REQ_OP_WRITE | op_flags);
ade480889   Bob Peterson   gfs2: Don't write...
779
  out:
588bff95c   Bob Peterson   GFS2: Reduce code...
780
781
782
783
784
785
  	log_flush_wait(sdp);
  }
  
  /**
   * log_write_header - Get and initialize a journal header buffer
   * @sdp: The GFS2 superblock
c1696fb85   Bob Peterson   GFS2: Introduce n...
786
   * @flags: The log header flags, including log header origin
588bff95c   Bob Peterson   GFS2: Reduce code...
787
788
789
790
791
792
793
794
795
796
797
798
   *
   * Returns: the initialized log buffer descriptor
   */
  
  static void log_write_header(struct gfs2_sbd *sdp, u32 flags)
  {
  	unsigned int tail;
  	int op_flags = REQ_PREFLUSH | REQ_FUA | REQ_META | REQ_SYNC;
  	enum gfs2_freeze_state state = atomic_read(&sdp->sd_freeze_state);
  
  	gfs2_assert_withdraw(sdp, (state != SFS_FROZEN));
  	tail = current_tail(sdp);
34cc1781c   Steven Whitehouse   GFS2: Clean up lo...
799
800
801
  	if (test_bit(SDF_NOBARRIERS, &sdp->sd_flags)) {
  		gfs2_ordered_wait(sdp);
  		log_flush_wait(sdp);
70fd76140   Christoph Hellwig   block,fs: use REQ...
802
  		op_flags = REQ_SYNC | REQ_META | REQ_PRIO;
34cc1781c   Steven Whitehouse   GFS2: Clean up lo...
803
  	}
e8c92ed76   Steven Whitehouse   GFS2: Clean up lo...
804
  	sdp->sd_log_idle = (tail == sdp->sd_log_flush_head);
c1696fb85   Bob Peterson   GFS2: Introduce n...
805
  	gfs2_write_log_header(sdp, sdp->sd_jdesc, sdp->sd_log_sequence++, tail,
7c70b8969   Bob Peterson   gfs2: clean_journ...
806
  			      sdp->sd_log_flush_head, flags, op_flags);
19ebc050e   Andreas Gruenbacher   gfs2: Remove acti...
807
  	gfs2_log_incr_head(sdp);
34cc1781c   Steven Whitehouse   GFS2: Clean up lo...
808
809
810
  
  	if (sdp->sd_log_tail != tail)
  		log_pull_tail(sdp, tail);
34cc1781c   Steven Whitehouse   GFS2: Clean up lo...
811
812
813
  }
  
  /**
2ca0c2fbf   Bob Peterson   gfs2: drain the a...
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
   * ail_drain - drain the ail lists after a withdraw
   * @sdp: Pointer to GFS2 superblock
   */
  static void ail_drain(struct gfs2_sbd *sdp)
  {
  	struct gfs2_trans *tr;
  
  	spin_lock(&sdp->sd_ail_lock);
  	/*
  	 * For transactions on the sd_ail1_list we need to drain both the
  	 * ail1 and ail2 lists. That's because function gfs2_ail1_start_one
  	 * (temporarily) moves items from its tr_ail1 list to tr_ail2 list
  	 * before revokes are sent for that block. Items on the sd_ail2_list
  	 * should have already gotten beyond that point, so no need.
  	 */
  	while (!list_empty(&sdp->sd_ail1_list)) {
  		tr = list_first_entry(&sdp->sd_ail1_list, struct gfs2_trans,
  				      tr_list);
  		gfs2_ail_empty_tr(sdp, tr, &tr->tr_ail1_list);
  		gfs2_ail_empty_tr(sdp, tr, &tr->tr_ail2_list);
  		list_del(&tr->tr_list);
b839dadae   Bob Peterson   gfs2: new slab fo...
835
  		gfs2_trans_free(sdp, tr);
2ca0c2fbf   Bob Peterson   gfs2: drain the a...
836
837
838
839
840
841
  	}
  	while (!list_empty(&sdp->sd_ail2_list)) {
  		tr = list_first_entry(&sdp->sd_ail2_list, struct gfs2_trans,
  				      tr_list);
  		gfs2_ail_empty_tr(sdp, tr, &tr->tr_ail2_list);
  		list_del(&tr->tr_list);
b839dadae   Bob Peterson   gfs2: new slab fo...
842
  		gfs2_trans_free(sdp, tr);
2ca0c2fbf   Bob Peterson   gfs2: drain the a...
843
844
845
846
847
  	}
  	spin_unlock(&sdp->sd_ail_lock);
  }
  
  /**
d5dc3d967   Bob Peterson   gfs2: instrumenta...
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
   * empty_ail1_list - try to start IO and empty the ail1 list
   * @sdp: Pointer to GFS2 superblock
   */
  static void empty_ail1_list(struct gfs2_sbd *sdp)
  {
  	unsigned long start = jiffies;
  
  	for (;;) {
  		if (time_after(jiffies, start + (HZ * 600))) {
  			fs_err(sdp, "Error: In %s for 10 minutes! t=%d
  ",
  			       __func__, current->journal_info ? 1 : 0);
  			dump_ail_list(sdp);
  			return;
  		}
  		gfs2_ail1_start(sdp);
  		gfs2_ail1_wait(sdp);
  		if (gfs2_ail1_empty(sdp, 0))
  			return;
  	}
  }
  
  /**
b09e593d7   Steven Whitehouse   [GFS2] Fix a ref ...
871
   * gfs2_log_flush - flush incore transaction(s)
b3b94faa5   David Teigland   [GFS2] The core o...
872
873
   * @sdp: the filesystem
   * @gl: The glock structure to flush.  If NULL, flush the whole incore log
805c09075   Bob Peterson   GFS2: Log the rea...
874
   * @flags: The log header flags: GFS2_LOG_HEAD_FLUSH_* and debug flags
b3b94faa5   David Teigland   [GFS2] The core o...
875
876
   *
   */
c1696fb85   Bob Peterson   GFS2: Introduce n...
877
  void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags)
b3b94faa5   David Teigland   [GFS2] The core o...
878
  {
2ca0c2fbf   Bob Peterson   gfs2: drain the a...
879
  	struct gfs2_trans *tr = NULL;
2e60d7683   Benjamin Marzinski   GFS2: update free...
880
  	enum gfs2_freeze_state state = atomic_read(&sdp->sd_freeze_state);
b3b94faa5   David Teigland   [GFS2] The core o...
881

484adff8a   Steven Whitehouse   [GFS2] Update loc...
882
  	down_write(&sdp->sd_log_flush_lock);
f55ab26a8   Steven Whitehouse   [GFS2] Use mutice...
883

2ca0c2fbf   Bob Peterson   gfs2: drain the a...
884
885
886
887
888
889
  	/*
  	 * Do this check while holding the log_flush_lock to prevent new
  	 * buffers from being added to the ail via gfs2_pin()
  	 */
  	if (gfs2_withdrawn(sdp))
  		goto out;
2bcd610d2   Steven Whitehouse   [GFS2] Don't add ...
890
891
892
893
  	/* Log might have been flushed while we waited for the flush lock */
  	if (gl && !test_bit(GLF_LFLUSH, &gl->gl_flags)) {
  		up_write(&sdp->sd_log_flush_lock);
  		return;
f55ab26a8   Steven Whitehouse   [GFS2] Use mutice...
894
  	}
805c09075   Bob Peterson   GFS2: Log the rea...
895
  	trace_gfs2_log_flush(sdp, 1, flags);
f55ab26a8   Steven Whitehouse   [GFS2] Use mutice...
896

c1696fb85   Bob Peterson   GFS2: Introduce n...
897
  	if (flags & GFS2_LOG_HEAD_FLUSH_SHUTDOWN)
400ac52e8   Benjamin Marzinski   gfs2: clear journ...
898
  		clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
b1ab1e44b   Steven Whitehouse   GFS2: Remove extr...
899
  	sdp->sd_log_flush_head = sdp->sd_log_head;
16ca9412d   Benjamin Marzinski   GFS2: replace gfs...
900
901
902
  	tr = sdp->sd_log_tr;
  	if (tr) {
  		sdp->sd_log_tr = NULL;
b1ab1e44b   Steven Whitehouse   GFS2: Remove extr...
903
  		tr->tr_first = sdp->sd_log_flush_head;
2e60d7683   Benjamin Marzinski   GFS2: update free...
904
  		if (unlikely (state == SFS_FROZEN))
ca399c96e   Bob Peterson   gfs2: flesh out d...
905
906
907
  			if (gfs2_assert_withdraw_delayed(sdp,
  			       !tr->tr_num_buf_new && !tr->tr_num_databuf_new))
  				goto out;
16ca9412d   Benjamin Marzinski   GFS2: replace gfs...
908
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
909

2e60d7683   Benjamin Marzinski   GFS2: update free...
910
  	if (unlikely(state == SFS_FROZEN))
ca399c96e   Bob Peterson   gfs2: flesh out d...
911
912
913
914
915
  		if (gfs2_assert_withdraw_delayed(sdp, !sdp->sd_log_num_revoke))
  			goto out;
  	if (gfs2_assert_withdraw_delayed(sdp,
  			sdp->sd_log_num_revoke == sdp->sd_log_committed_revoke))
  		goto out;
b3b94faa5   David Teigland   [GFS2] The core o...
916

d7b616e25   Steven Whitehouse   [GFS2] Clean up o...
917
  	gfs2_ordered_write(sdp);
2ca0c2fbf   Bob Peterson   gfs2: drain the a...
918
919
  	if (gfs2_withdrawn(sdp))
  		goto out;
d69a3c656   Steven Whitehouse   GFS2: Move log bu...
920
  	lops_before_commit(sdp, tr);
2ca0c2fbf   Bob Peterson   gfs2: drain the a...
921
922
  	if (gfs2_withdrawn(sdp))
  		goto out;
f4686c26e   Abhi Das   gfs2: read journa...
923
  	gfs2_log_submit_bio(&sdp->sd_log_bio, REQ_OP_WRITE);
2ca0c2fbf   Bob Peterson   gfs2: drain the a...
924
925
  	if (gfs2_withdrawn(sdp))
  		goto out;
d7b616e25   Steven Whitehouse   [GFS2] Clean up o...
926

34cc1781c   Steven Whitehouse   GFS2: Clean up lo...
927
  	if (sdp->sd_log_head != sdp->sd_log_flush_head) {
428fd95d8   Bob Peterson   GFS2: Re-add a ca...
928
  		log_flush_wait(sdp);
c1696fb85   Bob Peterson   GFS2: Introduce n...
929
  		log_write_header(sdp, flags);
34cc1781c   Steven Whitehouse   GFS2: Clean up lo...
930
  	} else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle){
fd041f0b4   Steven Whitehouse   [GFS2] Use atomic...
931
  		atomic_dec(&sdp->sd_log_blks_free); /* Adjust for unreserved buffer */
63997775b   Steven Whitehouse   GFS2: Add tracepo...
932
  		trace_gfs2_log_blocks(sdp, -1);
c1696fb85   Bob Peterson   GFS2: Introduce n...
933
  		log_write_header(sdp, flags);
2332c4435   Robert Peterson   [GFS2] assertion ...
934
  	}
2ca0c2fbf   Bob Peterson   gfs2: drain the a...
935
936
  	if (gfs2_withdrawn(sdp))
  		goto out;
16ca9412d   Benjamin Marzinski   GFS2: replace gfs...
937
  	lops_after_commit(sdp, tr);
b09e593d7   Steven Whitehouse   [GFS2] Fix a ref ...
938

fe1a698ff   Steven Whitehouse   [GFS2] Fix bug wh...
939
940
  	gfs2_log_lock(sdp);
  	sdp->sd_log_head = sdp->sd_log_flush_head;
faa31ce85   Steven Whitehouse   [GFS2] Tidy up log.c
941
  	sdp->sd_log_blks_reserved = 0;
5d4397585   Andreas Gruenbacher   gfs2: Fix incorre...
942
  	sdp->sd_log_committed_revoke = 0;
b3b94faa5   David Teigland   [GFS2] The core o...
943

d6a079e82   Dave Chinner   GFS2: introduce A...
944
  	spin_lock(&sdp->sd_ail_lock);
16ca9412d   Benjamin Marzinski   GFS2: replace gfs...
945
946
947
  	if (tr && !list_empty(&tr->tr_ail1_list)) {
  		list_add(&tr->tr_list, &sdp->sd_ail1_list);
  		tr = NULL;
b3b94faa5   David Teigland   [GFS2] The core o...
948
  	}
d6a079e82   Dave Chinner   GFS2: introduce A...
949
  	spin_unlock(&sdp->sd_ail_lock);
b3b94faa5   David Teigland   [GFS2] The core o...
950
  	gfs2_log_unlock(sdp);
24972557b   Benjamin Marzinski   GFS2: remove tran...
951

c1696fb85   Bob Peterson   GFS2: Introduce n...
952
  	if (!(flags & GFS2_LOG_HEAD_FLUSH_NORMAL)) {
24972557b   Benjamin Marzinski   GFS2: remove tran...
953
  		if (!sdp->sd_log_idle) {
d5dc3d967   Bob Peterson   gfs2: instrumenta...
954
  			empty_ail1_list(sdp);
30fe70a85   Bob Peterson   gfs2: clear ail1 ...
955
956
  			if (gfs2_withdrawn(sdp))
  				goto out;
24972557b   Benjamin Marzinski   GFS2: remove tran...
957
958
  			atomic_dec(&sdp->sd_log_blks_free); /* Adjust for unreserved buffer */
  			trace_gfs2_log_blocks(sdp, -1);
c1696fb85   Bob Peterson   GFS2: Introduce n...
959
  			log_write_header(sdp, flags);
24972557b   Benjamin Marzinski   GFS2: remove tran...
960
961
  			sdp->sd_log_head = sdp->sd_log_flush_head;
  		}
c1696fb85   Bob Peterson   GFS2: Introduce n...
962
963
  		if (flags & (GFS2_LOG_HEAD_FLUSH_SHUTDOWN |
  			     GFS2_LOG_HEAD_FLUSH_FREEZE))
24972557b   Benjamin Marzinski   GFS2: remove tran...
964
  			gfs2_log_shutdown(sdp);
c1696fb85   Bob Peterson   GFS2: Introduce n...
965
  		if (flags & GFS2_LOG_HEAD_FLUSH_FREEZE)
2e60d7683   Benjamin Marzinski   GFS2: update free...
966
  			atomic_set(&sdp->sd_freeze_state, SFS_FROZEN);
24972557b   Benjamin Marzinski   GFS2: remove tran...
967
  	}
30fe70a85   Bob Peterson   gfs2: clear ail1 ...
968
  out:
2ca0c2fbf   Bob Peterson   gfs2: drain the a...
969
  	if (gfs2_withdrawn(sdp)) {
58e08e8d8   Bob Peterson   gfs2: fix trans s...
970
971
972
973
974
975
976
977
978
979
  		/**
  		 * If the tr_list is empty, we're withdrawing during a log
  		 * flush that targets a transaction, but the transaction was
  		 * never queued onto any of the ail lists. Here we add it to
  		 * ail1 just so that ail_drain() will find and free it.
  		 */
  		spin_lock(&sdp->sd_ail_lock);
  		if (tr && list_empty(&tr->tr_list))
  			list_add(&tr->tr_list, &sdp->sd_ail1_list);
  		spin_unlock(&sdp->sd_ail_lock);
2ca0c2fbf   Bob Peterson   gfs2: drain the a...
980
981
982
  		ail_drain(sdp); /* frees all transactions */
  		tr = NULL;
  	}
805c09075   Bob Peterson   GFS2: Log the rea...
983
  	trace_gfs2_log_flush(sdp, 0, flags);
484adff8a   Steven Whitehouse   [GFS2] Update loc...
984
  	up_write(&sdp->sd_log_flush_lock);
b3b94faa5   David Teigland   [GFS2] The core o...
985

b839dadae   Bob Peterson   gfs2: new slab fo...
986
  	gfs2_trans_free(sdp, tr);
b3b94faa5   David Teigland   [GFS2] The core o...
987
  }
d69a3c656   Steven Whitehouse   GFS2: Move log bu...
988
989
990
991
992
  /**
   * gfs2_merge_trans - Merge a new transaction into a cached transaction
   * @old: Original transaction to be expanded
   * @new: New transaction to be merged
   */
83d060ca8   Bob Peterson   gfs2: fix use-aft...
993
  static void gfs2_merge_trans(struct gfs2_sbd *sdp, struct gfs2_trans *new)
d69a3c656   Steven Whitehouse   GFS2: Move log bu...
994
  {
83d060ca8   Bob Peterson   gfs2: fix use-aft...
995
  	struct gfs2_trans *old = sdp->sd_log_tr;
9862ca056   Bob Peterson   GFS2: Switch tr_t...
996
  	WARN_ON_ONCE(!test_bit(TR_ATTACHED, &old->tr_flags));
d69a3c656   Steven Whitehouse   GFS2: Move log bu...
997
998
999
1000
1001
1002
  
  	old->tr_num_buf_new	+= new->tr_num_buf_new;
  	old->tr_num_databuf_new	+= new->tr_num_databuf_new;
  	old->tr_num_buf_rm	+= new->tr_num_buf_rm;
  	old->tr_num_databuf_rm	+= new->tr_num_databuf_rm;
  	old->tr_num_revoke	+= new->tr_num_revoke;
a31b4ec53   Bob Peterson   Revert "gfs2: eli...
1003
  	old->tr_num_revoke_rm	+= new->tr_num_revoke_rm;
d69a3c656   Steven Whitehouse   GFS2: Move log bu...
1004
1005
1006
  
  	list_splice_tail_init(&new->tr_databuf, &old->tr_databuf);
  	list_splice_tail_init(&new->tr_buf, &old->tr_buf);
83d060ca8   Bob Peterson   gfs2: fix use-aft...
1007
1008
1009
1010
1011
  
  	spin_lock(&sdp->sd_ail_lock);
  	list_splice_tail_init(&new->tr_ail1_list, &old->tr_ail1_list);
  	list_splice_tail_init(&new->tr_ail2_list, &old->tr_ail2_list);
  	spin_unlock(&sdp->sd_ail_lock);
d69a3c656   Steven Whitehouse   GFS2: Move log bu...
1012
  }
b3b94faa5   David Teigland   [GFS2] The core o...
1013
1014
  static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
  {
2332c4435   Robert Peterson   [GFS2] assertion ...
1015
  	unsigned int reserved;
ac39aadd0   Steven Whitehouse   [GFS2] Fix assert...
1016
  	unsigned int unused;
022ef4fee   Steven Whitehouse   GFS2: Move log bu...
1017
  	unsigned int maxres;
b3b94faa5   David Teigland   [GFS2] The core o...
1018
1019
  
  	gfs2_log_lock(sdp);
022ef4fee   Steven Whitehouse   GFS2: Move log bu...
1020
  	if (sdp->sd_log_tr) {
83d060ca8   Bob Peterson   gfs2: fix use-aft...
1021
  		gfs2_merge_trans(sdp, tr);
022ef4fee   Steven Whitehouse   GFS2: Move log bu...
1022
  	} else if (tr->tr_num_buf_new || tr->tr_num_databuf_new) {
9862ca056   Bob Peterson   GFS2: Switch tr_t...
1023
  		gfs2_assert_withdraw(sdp, test_bit(TR_ALLOCED, &tr->tr_flags));
022ef4fee   Steven Whitehouse   GFS2: Move log bu...
1024
  		sdp->sd_log_tr = tr;
9862ca056   Bob Peterson   GFS2: Switch tr_t...
1025
  		set_bit(TR_ATTACHED, &tr->tr_flags);
022ef4fee   Steven Whitehouse   GFS2: Move log bu...
1026
  	}
a31b4ec53   Bob Peterson   Revert "gfs2: eli...
1027
  	sdp->sd_log_committed_revoke += tr->tr_num_revoke - tr->tr_num_revoke_rm;
2332c4435   Robert Peterson   [GFS2] assertion ...
1028
  	reserved = calc_reserved(sdp);
022ef4fee   Steven Whitehouse   GFS2: Move log bu...
1029
1030
1031
  	maxres = sdp->sd_log_blks_reserved + tr->tr_reserved;
  	gfs2_assert_withdraw(sdp, maxres >= reserved);
  	unused = maxres - reserved;
ac39aadd0   Steven Whitehouse   [GFS2] Fix assert...
1032
  	atomic_add(unused, &sdp->sd_log_blks_free);
63997775b   Steven Whitehouse   GFS2: Add tracepo...
1033
  	trace_gfs2_log_blocks(sdp, unused);
fd041f0b4   Steven Whitehouse   [GFS2] Use atomic...
1034
  	gfs2_assert_withdraw(sdp, atomic_read(&sdp->sd_log_blks_free) <=
2332c4435   Robert Peterson   [GFS2] assertion ...
1035
  			     sdp->sd_jdesc->jd_blocks);
b3b94faa5   David Teigland   [GFS2] The core o...
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
  	sdp->sd_log_blks_reserved = reserved;
  
  	gfs2_log_unlock(sdp);
  }
  
  /**
   * gfs2_log_commit - Commit a transaction to the log
   * @sdp: the filesystem
   * @tr: the transaction
   *
5e687eac1   Benjamin Marzinski   GFS2: Various gfs...
1046
1047
1048
1049
1050
1051
1052
   * We wake up gfs2_logd if the number of pinned blocks exceed thresh1
   * or the total number of used blocks (pinned blocks plus AIL blocks)
   * is greater than thresh2.
   *
   * At mount time thresh1 is 1/3rd of journal size, thresh2 is 2/3rd of
   * journal size.
   *
b3b94faa5   David Teigland   [GFS2] The core o...
1053
1054
1055
1056
1057
1058
   * Returns: errno
   */
  
  void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
  {
  	log_refund(sdp, tr);
b3b94faa5   David Teigland   [GFS2] The core o...
1059

5e687eac1   Benjamin Marzinski   GFS2: Various gfs...
1060
1061
1062
1063
  	if (atomic_read(&sdp->sd_log_pinned) > atomic_read(&sdp->sd_log_thresh1) ||
  	    ((sdp->sd_jdesc->jd_blocks - atomic_read(&sdp->sd_log_blks_free)) >
  	    atomic_read(&sdp->sd_log_thresh2)))
  		wake_up(&sdp->sd_logd_waitq);
b3b94faa5   David Teigland   [GFS2] The core o...
1064
1065
1066
1067
1068
1069
1070
  }
  
  /**
   * gfs2_log_shutdown - write a shutdown header into a journal
   * @sdp: the filesystem
   *
   */
feed98a8e   Bob Peterson   gfs2: make gfs2_l...
1071
  static void gfs2_log_shutdown(struct gfs2_sbd *sdp)
b3b94faa5   David Teigland   [GFS2] The core o...
1072
  {
b3b94faa5   David Teigland   [GFS2] The core o...
1073
  	gfs2_assert_withdraw(sdp, !sdp->sd_log_blks_reserved);
b3b94faa5   David Teigland   [GFS2] The core o...
1074
  	gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke);
b3b94faa5   David Teigland   [GFS2] The core o...
1075
1076
1077
  	gfs2_assert_withdraw(sdp, list_empty(&sdp->sd_ail1_list));
  
  	sdp->sd_log_flush_head = sdp->sd_log_head;
b3b94faa5   David Teigland   [GFS2] The core o...
1078

805c09075   Bob Peterson   GFS2: Log the rea...
1079
  	log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT | GFS2_LFC_SHUTDOWN);
b3b94faa5   David Teigland   [GFS2] The core o...
1080

a74604bee   Steven Whitehouse   [GFS2] sem -> mut...
1081
1082
  	gfs2_assert_warn(sdp, sdp->sd_log_head == sdp->sd_log_tail);
  	gfs2_assert_warn(sdp, list_empty(&sdp->sd_ail2_list));
b3b94faa5   David Teigland   [GFS2] The core o...
1083
1084
  
  	sdp->sd_log_head = sdp->sd_log_flush_head;
b3b94faa5   David Teigland   [GFS2] The core o...
1085
  	sdp->sd_log_tail = sdp->sd_log_head;
a25311c8e   Steven Whitehouse   [GFS2] Move gfs2_...
1086
  }
5e687eac1   Benjamin Marzinski   GFS2: Various gfs...
1087
1088
  static inline int gfs2_jrnl_flush_reqd(struct gfs2_sbd *sdp)
  {
f07b35202   Bob Peterson   GFS2: Made logd d...
1089
1090
1091
  	return (atomic_read(&sdp->sd_log_pinned) +
  		atomic_read(&sdp->sd_log_blks_needed) >=
  		atomic_read(&sdp->sd_log_thresh1));
5e687eac1   Benjamin Marzinski   GFS2: Various gfs...
1092
1093
1094
1095
1096
  }
  
  static inline int gfs2_ail_flush_reqd(struct gfs2_sbd *sdp)
  {
  	unsigned int used_blocks = sdp->sd_jdesc->jd_blocks - atomic_read(&sdp->sd_log_blks_free);
b066a4eeb   Abhi Das   gfs2: forcibly fl...
1097
1098
1099
  
  	if (test_and_clear_bit(SDF_FORCE_AIL_FLUSH, &sdp->sd_flags))
  		return 1;
f07b35202   Bob Peterson   GFS2: Made logd d...
1100
1101
  	return used_blocks + atomic_read(&sdp->sd_log_blks_needed) >=
  		atomic_read(&sdp->sd_log_thresh2);
5e687eac1   Benjamin Marzinski   GFS2: Various gfs...
1102
  }
ec69b1888   Steven Whitehouse   [GFS2] Move gfs2_...
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
  
  /**
   * gfs2_logd - Update log tail as Active Items get flushed to in-place blocks
   * @sdp: Pointer to GFS2 superblock
   *
   * Also, periodically check to make sure that we're using the most recent
   * journal index.
   */
  
  int gfs2_logd(void *data)
  {
  	struct gfs2_sbd *sdp = data;
5e687eac1   Benjamin Marzinski   GFS2: Various gfs...
1115
1116
  	unsigned long t = 1;
  	DEFINE_WAIT(wait);
b63f5e848   Bob Peterson   GFS2: Wake up io ...
1117
  	bool did_flush;
ec69b1888   Steven Whitehouse   [GFS2] Move gfs2_...
1118
1119
  
  	while (!kthread_should_stop()) {
ec69b1888   Steven Whitehouse   [GFS2] Move gfs2_...
1120

d22f69a08   Bob Peterson   gfs2: Fix use-aft...
1121
1122
1123
1124
  		if (gfs2_withdrawn(sdp)) {
  			msleep_interruptible(HZ);
  			continue;
  		}
942b0cddf   Bob Peterson   GFS2: Withdraw fo...
1125
1126
  		/* Check for errors writing to the journal */
  		if (sdp->sd_log_error) {
badb55ec2   Andreas Gruenbacher   gfs2: Split gfs2_...
1127
1128
1129
1130
1131
1132
1133
  			gfs2_lm(sdp,
  				"GFS2: fsid=%s: error %d: "
  				"withdrawing the file system to "
  				"prevent further damage.
  ",
  				sdp->sd_fsname, sdp->sd_log_error);
  			gfs2_withdraw(sdp);
d22f69a08   Bob Peterson   gfs2: Fix use-aft...
1134
  			continue;
942b0cddf   Bob Peterson   GFS2: Withdraw fo...
1135
  		}
b63f5e848   Bob Peterson   GFS2: Wake up io ...
1136
  		did_flush = false;
5e687eac1   Benjamin Marzinski   GFS2: Various gfs...
1137
  		if (gfs2_jrnl_flush_reqd(sdp) || t == 0) {
5e4c7632a   Bob Peterson   gfs2: Issue revok...
1138
  			gfs2_ail1_empty(sdp, 0);
805c09075   Bob Peterson   GFS2: Log the rea...
1139
1140
  			gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL |
  				       GFS2_LFC_LOGD_JFLUSH_REQD);
b63f5e848   Bob Peterson   GFS2: Wake up io ...
1141
  			did_flush = true;
5e687eac1   Benjamin Marzinski   GFS2: Various gfs...
1142
  		}
ec69b1888   Steven Whitehouse   [GFS2] Move gfs2_...
1143

5e687eac1   Benjamin Marzinski   GFS2: Various gfs...
1144
1145
  		if (gfs2_ail_flush_reqd(sdp)) {
  			gfs2_ail1_start(sdp);
26b06a695   Steven Whitehouse   GFS2: Wait proper...
1146
  			gfs2_ail1_wait(sdp);
5e4c7632a   Bob Peterson   gfs2: Issue revok...
1147
  			gfs2_ail1_empty(sdp, 0);
805c09075   Bob Peterson   GFS2: Log the rea...
1148
1149
  			gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL |
  				       GFS2_LFC_LOGD_AIL_FLUSH_REQD);
b63f5e848   Bob Peterson   GFS2: Wake up io ...
1150
  			did_flush = true;
ec69b1888   Steven Whitehouse   [GFS2] Move gfs2_...
1151
  		}
b63f5e848   Bob Peterson   GFS2: Wake up io ...
1152
  		if (!gfs2_ail_flush_reqd(sdp) || did_flush)
26b06a695   Steven Whitehouse   GFS2: Wait proper...
1153
  			wake_up(&sdp->sd_log_waitq);
ec69b1888   Steven Whitehouse   [GFS2] Move gfs2_...
1154
  		t = gfs2_tune_get(sdp, gt_logd_secs) * HZ;
a0acae0e8   Tejun Heo   freezer: unexport...
1155
1156
  
  		try_to_freeze();
5e687eac1   Benjamin Marzinski   GFS2: Various gfs...
1157
1158
1159
  
  		do {
  			prepare_to_wait(&sdp->sd_logd_waitq, &wait,
5f4874903   Steven Whitehouse   GFS2: gfs2_logd s...
1160
  					TASK_INTERRUPTIBLE);
5e687eac1   Benjamin Marzinski   GFS2: Various gfs...
1161
1162
1163
1164
1165
1166
1167
1168
  			if (!gfs2_ail_flush_reqd(sdp) &&
  			    !gfs2_jrnl_flush_reqd(sdp) &&
  			    !kthread_should_stop())
  				t = schedule_timeout(t);
  		} while(t && !gfs2_ail_flush_reqd(sdp) &&
  			!gfs2_jrnl_flush_reqd(sdp) &&
  			!kthread_should_stop());
  		finish_wait(&sdp->sd_logd_waitq, &wait);
ec69b1888   Steven Whitehouse   [GFS2] Move gfs2_...
1169
1170
1171
1172
  	}
  
  	return 0;
  }