.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
---|
3 | 4 | * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. |
---|
4 | | - * |
---|
5 | | - * This copyrighted material is made available to anyone wishing to use, |
---|
6 | | - * modify, copy, or redistribute it subject to the terms and conditions |
---|
7 | | - * of the GNU General Public License version 2. |
---|
8 | 5 | */ |
---|
9 | 6 | |
---|
10 | 7 | #include <linux/sched.h> |
---|
.. | .. |
---|
33 | 30 | #include "util.h" |
---|
34 | 31 | #include "dir.h" |
---|
35 | 32 | #include "trace_gfs2.h" |
---|
| 33 | +#include "trans.h" |
---|
| 34 | + |
---|
| 35 | +static void gfs2_log_shutdown(struct gfs2_sbd *sdp); |
---|
36 | 36 | |
---|
37 | 37 | /** |
---|
38 | 38 | * gfs2_struct2blk - compute stuff |
---|
39 | 39 | * @sdp: the filesystem |
---|
40 | 40 | * @nstruct: the number of structures |
---|
41 | | - * @ssize: the size of the structures |
---|
42 | 41 | * |
---|
43 | 42 | * Compute the number of log descriptor blocks needed to hold a certain number |
---|
44 | 43 | * of structures of a certain size. |
---|
.. | .. |
---|
46 | 45 | * Returns: the number of blocks needed (minimum is always 1) |
---|
47 | 46 | */ |
---|
48 | 47 | |
---|
49 | | -unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct, |
---|
50 | | - unsigned int ssize) |
---|
| 48 | +unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct) |
---|
51 | 49 | { |
---|
52 | 50 | unsigned int blks; |
---|
53 | 51 | unsigned int first, second; |
---|
54 | 52 | |
---|
55 | 53 | blks = 1; |
---|
56 | | - first = (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_log_descriptor)) / ssize; |
---|
| 54 | + first = sdp->sd_ldptrs; |
---|
57 | 55 | |
---|
58 | 56 | if (nstruct > first) { |
---|
59 | | - second = (sdp->sd_sb.sb_bsize - |
---|
60 | | - sizeof(struct gfs2_meta_header)) / ssize; |
---|
| 57 | + second = sdp->sd_inptrs; |
---|
61 | 58 | blks += DIV_ROUND_UP(nstruct - first, second); |
---|
62 | 59 | } |
---|
63 | 60 | |
---|
.. | .. |
---|
73 | 70 | * |
---|
74 | 71 | */ |
---|
75 | 72 | |
---|
76 | | -static void gfs2_remove_from_ail(struct gfs2_bufdata *bd) |
---|
| 73 | +void gfs2_remove_from_ail(struct gfs2_bufdata *bd) |
---|
77 | 74 | { |
---|
78 | 75 | bd->bd_tr = NULL; |
---|
79 | 76 | list_del_init(&bd->bd_ail_st_list); |
---|
.. | .. |
---|
92 | 89 | |
---|
93 | 90 | static int gfs2_ail1_start_one(struct gfs2_sbd *sdp, |
---|
94 | 91 | struct writeback_control *wbc, |
---|
95 | | - struct gfs2_trans *tr, |
---|
96 | | - bool *withdraw) |
---|
| 92 | + struct gfs2_trans *tr) |
---|
97 | 93 | __releases(&sdp->sd_ail_lock) |
---|
98 | 94 | __acquires(&sdp->sd_ail_lock) |
---|
99 | 95 | { |
---|
.. | .. |
---|
101 | 97 | struct address_space *mapping; |
---|
102 | 98 | struct gfs2_bufdata *bd, *s; |
---|
103 | 99 | struct buffer_head *bh; |
---|
| 100 | + int ret = 0; |
---|
104 | 101 | |
---|
105 | 102 | list_for_each_entry_safe_reverse(bd, s, &tr->tr_ail1_list, bd_ail_st_list) { |
---|
106 | 103 | bh = bd->bd_bh; |
---|
.. | .. |
---|
108 | 105 | gfs2_assert(sdp, bd->bd_tr == tr); |
---|
109 | 106 | |
---|
110 | 107 | if (!buffer_busy(bh)) { |
---|
111 | | - if (!buffer_uptodate(bh) && |
---|
112 | | - !test_and_set_bit(SDF_AIL1_IO_ERROR, |
---|
113 | | - &sdp->sd_flags)) { |
---|
114 | | - gfs2_io_error_bh(sdp, bh); |
---|
115 | | - *withdraw = true; |
---|
| 108 | + if (buffer_uptodate(bh)) { |
---|
| 109 | + list_move(&bd->bd_ail_st_list, |
---|
| 110 | + &tr->tr_ail2_list); |
---|
| 111 | + continue; |
---|
116 | 112 | } |
---|
117 | | - list_move(&bd->bd_ail_st_list, &tr->tr_ail2_list); |
---|
118 | | - continue; |
---|
| 113 | + if (!cmpxchg(&sdp->sd_log_error, 0, -EIO)) { |
---|
| 114 | + gfs2_io_error_bh(sdp, bh); |
---|
| 115 | + gfs2_withdraw_delayed(sdp); |
---|
| 116 | + } |
---|
119 | 117 | } |
---|
120 | 118 | |
---|
| 119 | + if (gfs2_withdrawn(sdp)) { |
---|
| 120 | + gfs2_remove_from_ail(bd); |
---|
| 121 | + continue; |
---|
| 122 | + } |
---|
121 | 123 | if (!buffer_dirty(bh)) |
---|
122 | 124 | continue; |
---|
123 | 125 | if (gl == bd->bd_gl) |
---|
.. | .. |
---|
128 | 130 | if (!mapping) |
---|
129 | 131 | continue; |
---|
130 | 132 | spin_unlock(&sdp->sd_ail_lock); |
---|
131 | | - generic_writepages(mapping, wbc); |
---|
| 133 | + ret = generic_writepages(mapping, wbc); |
---|
132 | 134 | spin_lock(&sdp->sd_ail_lock); |
---|
133 | | - if (wbc->nr_to_write <= 0) |
---|
| 135 | + if (ret == -ENODATA) /* if a jdata write into a new hole */ |
---|
| 136 | + ret = 0; /* ignore it */ |
---|
| 137 | + if (ret || wbc->nr_to_write <= 0) |
---|
134 | 138 | break; |
---|
135 | | - return 1; |
---|
| 139 | + return -EBUSY; |
---|
136 | 140 | } |
---|
137 | 141 | |
---|
138 | | - return 0; |
---|
| 142 | + return ret; |
---|
139 | 143 | } |
---|
140 | 144 | |
---|
| 145 | +static void dump_ail_list(struct gfs2_sbd *sdp) |
---|
| 146 | +{ |
---|
| 147 | + struct gfs2_trans *tr; |
---|
| 148 | + struct gfs2_bufdata *bd; |
---|
| 149 | + struct buffer_head *bh; |
---|
| 150 | + |
---|
| 151 | + list_for_each_entry_reverse(tr, &sdp->sd_ail1_list, tr_list) { |
---|
| 152 | + list_for_each_entry_reverse(bd, &tr->tr_ail1_list, |
---|
| 153 | + bd_ail_st_list) { |
---|
| 154 | + bh = bd->bd_bh; |
---|
| 155 | + fs_err(sdp, "bd %p: blk:0x%llx bh=%p ", bd, |
---|
| 156 | + (unsigned long long)bd->bd_blkno, bh); |
---|
| 157 | + if (!bh) { |
---|
| 158 | + fs_err(sdp, "\n"); |
---|
| 159 | + continue; |
---|
| 160 | + } |
---|
| 161 | + fs_err(sdp, "0x%llx up2:%d dirt:%d lkd:%d req:%d " |
---|
| 162 | + "map:%d new:%d ar:%d aw:%d delay:%d " |
---|
| 163 | + "io err:%d unwritten:%d dfr:%d pin:%d esc:%d\n", |
---|
| 164 | + (unsigned long long)bh->b_blocknr, |
---|
| 165 | + buffer_uptodate(bh), buffer_dirty(bh), |
---|
| 166 | + buffer_locked(bh), buffer_req(bh), |
---|
| 167 | + buffer_mapped(bh), buffer_new(bh), |
---|
| 168 | + buffer_async_read(bh), buffer_async_write(bh), |
---|
| 169 | + buffer_delay(bh), buffer_write_io_error(bh), |
---|
| 170 | + buffer_unwritten(bh), |
---|
| 171 | + buffer_defer_completion(bh), |
---|
| 172 | + buffer_pinned(bh), buffer_escaped(bh)); |
---|
| 173 | + } |
---|
| 174 | + } |
---|
| 175 | +} |
---|
141 | 176 | |
---|
142 | 177 | /** |
---|
143 | 178 | * gfs2_ail1_flush - start writeback of some ail1 entries |
---|
.. | .. |
---|
153 | 188 | struct list_head *head = &sdp->sd_ail1_list; |
---|
154 | 189 | struct gfs2_trans *tr; |
---|
155 | 190 | struct blk_plug plug; |
---|
156 | | - bool withdraw = false; |
---|
| 191 | + int ret; |
---|
| 192 | + unsigned long flush_start = jiffies; |
---|
157 | 193 | |
---|
158 | 194 | trace_gfs2_ail_flush(sdp, wbc, 1); |
---|
159 | 195 | blk_start_plug(&plug); |
---|
160 | 196 | spin_lock(&sdp->sd_ail_lock); |
---|
161 | 197 | restart: |
---|
| 198 | + ret = 0; |
---|
| 199 | + if (time_after(jiffies, flush_start + (HZ * 600))) { |
---|
| 200 | + fs_err(sdp, "Error: In %s for ten minutes! t=%d\n", |
---|
| 201 | + __func__, current->journal_info ? 1 : 0); |
---|
| 202 | + dump_ail_list(sdp); |
---|
| 203 | + goto out; |
---|
| 204 | + } |
---|
162 | 205 | list_for_each_entry_reverse(tr, head, tr_list) { |
---|
163 | 206 | if (wbc->nr_to_write <= 0) |
---|
164 | 207 | break; |
---|
165 | | - if (gfs2_ail1_start_one(sdp, wbc, tr, &withdraw)) |
---|
166 | | - goto restart; |
---|
| 208 | + ret = gfs2_ail1_start_one(sdp, wbc, tr); |
---|
| 209 | + if (ret) { |
---|
| 210 | + if (ret == -EBUSY) |
---|
| 211 | + goto restart; |
---|
| 212 | + break; |
---|
| 213 | + } |
---|
167 | 214 | } |
---|
| 215 | +out: |
---|
168 | 216 | spin_unlock(&sdp->sd_ail_lock); |
---|
169 | 217 | blk_finish_plug(&plug); |
---|
170 | | - if (withdraw) |
---|
171 | | - gfs2_lm_withdraw(sdp, NULL); |
---|
| 218 | + if (ret) { |
---|
| 219 | + gfs2_lm(sdp, "gfs2_ail1_start_one (generic_writepages) " |
---|
| 220 | + "returned: %d\n", ret); |
---|
| 221 | + gfs2_withdraw(sdp); |
---|
| 222 | + } |
---|
172 | 223 | trace_gfs2_ail_flush(sdp, wbc, 0); |
---|
173 | 224 | } |
---|
174 | 225 | |
---|
.. | .. |
---|
192 | 243 | /** |
---|
193 | 244 | * gfs2_ail1_empty_one - Check whether or not a trans in the AIL has been synced |
---|
194 | 245 | * @sdp: the filesystem |
---|
195 | | - * @ai: the AIL entry |
---|
| 246 | + * @tr: the transaction |
---|
| 247 | + * @max_revokes: If nonzero, issue revokes for the bd items for written buffers |
---|
196 | 248 | * |
---|
| 249 | + * returns: the transaction's count of remaining active items |
---|
197 | 250 | */ |
---|
198 | 251 | |
---|
199 | | -static void gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_trans *tr, |
---|
200 | | - bool *withdraw) |
---|
| 252 | +static int gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_trans *tr, |
---|
| 253 | + int *max_revokes) |
---|
201 | 254 | { |
---|
202 | 255 | struct gfs2_bufdata *bd, *s; |
---|
203 | 256 | struct buffer_head *bh; |
---|
| 257 | + int active_count = 0; |
---|
204 | 258 | |
---|
205 | 259 | list_for_each_entry_safe_reverse(bd, s, &tr->tr_ail1_list, |
---|
206 | 260 | bd_ail_st_list) { |
---|
207 | 261 | bh = bd->bd_bh; |
---|
208 | 262 | gfs2_assert(sdp, bd->bd_tr == tr); |
---|
209 | | - if (buffer_busy(bh)) |
---|
| 263 | + /* |
---|
| 264 | + * If another process flagged an io error, e.g. writing to the |
---|
| 265 | + * journal, error all other bhs and move them off the ail1 to |
---|
| 266 | + * prevent a tight loop when unmount tries to flush ail1, |
---|
| 267 | + * regardless of whether they're still busy. If no outside |
---|
| 268 | + * errors were found and the buffer is busy, move to the next. |
---|
| 269 | + * If the ail buffer is not busy and caught an error, flag it |
---|
| 270 | + * for others. |
---|
| 271 | + */ |
---|
| 272 | + if (!sdp->sd_log_error && buffer_busy(bh)) { |
---|
| 273 | + active_count++; |
---|
210 | 274 | continue; |
---|
| 275 | + } |
---|
211 | 276 | if (!buffer_uptodate(bh) && |
---|
212 | | - !test_and_set_bit(SDF_AIL1_IO_ERROR, &sdp->sd_flags)) { |
---|
| 277 | + !cmpxchg(&sdp->sd_log_error, 0, -EIO)) { |
---|
213 | 278 | gfs2_io_error_bh(sdp, bh); |
---|
214 | | - *withdraw = true; |
---|
| 279 | + gfs2_withdraw_delayed(sdp); |
---|
| 280 | + } |
---|
| 281 | + /* |
---|
| 282 | + * If we have space for revokes and the bd is no longer on any |
---|
| 283 | + * buf list, we can just add a revoke for it immediately and |
---|
| 284 | + * avoid having to put it on the ail2 list, where it would need |
---|
| 285 | + * to be revoked later. |
---|
| 286 | + */ |
---|
| 287 | + if (*max_revokes && list_empty(&bd->bd_list)) { |
---|
| 288 | + gfs2_add_revoke(sdp, bd); |
---|
| 289 | + (*max_revokes)--; |
---|
| 290 | + continue; |
---|
215 | 291 | } |
---|
216 | 292 | list_move(&bd->bd_ail_st_list, &tr->tr_ail2_list); |
---|
217 | 293 | } |
---|
| 294 | + return active_count; |
---|
218 | 295 | } |
---|
219 | 296 | |
---|
220 | 297 | /** |
---|
221 | 298 | * gfs2_ail1_empty - Try to empty the ail1 lists |
---|
222 | 299 | * @sdp: The superblock |
---|
| 300 | + * @max_revokes: If non-zero, add revokes where appropriate |
---|
223 | 301 | * |
---|
224 | 302 | * Tries to empty the ail1 lists, starting with the oldest first |
---|
225 | 303 | */ |
---|
226 | 304 | |
---|
227 | | -static int gfs2_ail1_empty(struct gfs2_sbd *sdp) |
---|
| 305 | +static int gfs2_ail1_empty(struct gfs2_sbd *sdp, int max_revokes) |
---|
228 | 306 | { |
---|
229 | 307 | struct gfs2_trans *tr, *s; |
---|
230 | 308 | int oldest_tr = 1; |
---|
231 | 309 | int ret; |
---|
232 | | - bool withdraw = false; |
---|
233 | 310 | |
---|
234 | 311 | spin_lock(&sdp->sd_ail_lock); |
---|
235 | 312 | list_for_each_entry_safe_reverse(tr, s, &sdp->sd_ail1_list, tr_list) { |
---|
236 | | - gfs2_ail1_empty_one(sdp, tr, &withdraw); |
---|
237 | | - if (list_empty(&tr->tr_ail1_list) && oldest_tr) |
---|
| 313 | + if (!gfs2_ail1_empty_one(sdp, tr, &max_revokes) && oldest_tr) |
---|
238 | 314 | list_move(&tr->tr_list, &sdp->sd_ail2_list); |
---|
239 | 315 | else |
---|
240 | 316 | oldest_tr = 0; |
---|
.. | .. |
---|
242 | 318 | ret = list_empty(&sdp->sd_ail1_list); |
---|
243 | 319 | spin_unlock(&sdp->sd_ail_lock); |
---|
244 | 320 | |
---|
245 | | - if (withdraw) |
---|
246 | | - gfs2_lm_withdraw(sdp, "fatal: I/O error(s)\n"); |
---|
| 321 | + if (test_bit(SDF_WITHDRAWING, &sdp->sd_flags)) { |
---|
| 322 | + gfs2_lm(sdp, "fatal: I/O error(s)\n"); |
---|
| 323 | + gfs2_withdraw(sdp); |
---|
| 324 | + } |
---|
247 | 325 | |
---|
248 | 326 | return ret; |
---|
249 | 327 | } |
---|
.. | .. |
---|
271 | 349 | } |
---|
272 | 350 | |
---|
273 | 351 | /** |
---|
274 | | - * gfs2_ail2_empty_one - Check whether or not a trans in the AIL has been synced |
---|
275 | | - * @sdp: the filesystem |
---|
276 | | - * @ai: the AIL entry |
---|
277 | | - * |
---|
| 352 | + * gfs2_ail_empty_tr - empty one of the ail lists for a transaction |
---|
278 | 353 | */ |
---|
279 | 354 | |
---|
280 | | -static void gfs2_ail2_empty_one(struct gfs2_sbd *sdp, struct gfs2_trans *tr) |
---|
| 355 | +static void gfs2_ail_empty_tr(struct gfs2_sbd *sdp, struct gfs2_trans *tr, |
---|
| 356 | + struct list_head *head) |
---|
281 | 357 | { |
---|
282 | | - struct list_head *head = &tr->tr_ail2_list; |
---|
283 | 358 | struct gfs2_bufdata *bd; |
---|
284 | 359 | |
---|
285 | 360 | while (!list_empty(head)) { |
---|
286 | | - bd = list_entry(head->prev, struct gfs2_bufdata, |
---|
287 | | - bd_ail_st_list); |
---|
| 361 | + bd = list_first_entry(head, struct gfs2_bufdata, |
---|
| 362 | + bd_ail_st_list); |
---|
288 | 363 | gfs2_assert(sdp, bd->bd_tr == tr); |
---|
289 | 364 | gfs2_remove_from_ail(bd); |
---|
290 | 365 | } |
---|
.. | .. |
---|
306 | 381 | if (!rm) |
---|
307 | 382 | continue; |
---|
308 | 383 | |
---|
309 | | - gfs2_ail2_empty_one(sdp, tr); |
---|
| 384 | + gfs2_ail_empty_tr(sdp, tr, &tr->tr_ail2_list); |
---|
310 | 385 | list_del(&tr->tr_list); |
---|
311 | 386 | gfs2_assert_warn(sdp, list_empty(&tr->tr_ail1_list)); |
---|
312 | 387 | gfs2_assert_warn(sdp, list_empty(&tr->tr_ail2_list)); |
---|
313 | | - kfree(tr); |
---|
| 388 | + gfs2_trans_free(sdp, tr); |
---|
314 | 389 | } |
---|
315 | 390 | |
---|
316 | 391 | spin_unlock(&sdp->sd_ail_lock); |
---|
.. | .. |
---|
472 | 547 | reserved += DIV_ROUND_UP(dbuf, databuf_limit(sdp)); |
---|
473 | 548 | } |
---|
474 | 549 | |
---|
475 | | - if (sdp->sd_log_commited_revoke > 0) |
---|
476 | | - reserved += gfs2_struct2blk(sdp, sdp->sd_log_commited_revoke, |
---|
477 | | - sizeof(u64)); |
---|
| 550 | + if (sdp->sd_log_committed_revoke > 0) |
---|
| 551 | + reserved += gfs2_struct2blk(sdp, sdp->sd_log_committed_revoke); |
---|
478 | 552 | /* One for the overall header */ |
---|
479 | 553 | if (reserved) |
---|
480 | 554 | reserved++; |
---|
.. | .. |
---|
491 | 565 | if (list_empty(&sdp->sd_ail1_list)) { |
---|
492 | 566 | tail = sdp->sd_log_head; |
---|
493 | 567 | } else { |
---|
494 | | - tr = list_entry(sdp->sd_ail1_list.prev, struct gfs2_trans, |
---|
| 568 | + tr = list_last_entry(&sdp->sd_ail1_list, struct gfs2_trans, |
---|
495 | 569 | tr_list); |
---|
496 | 570 | tail = tr->tr_first; |
---|
497 | 571 | } |
---|
.. | .. |
---|
516 | 590 | } |
---|
517 | 591 | |
---|
518 | 592 | |
---|
519 | | -static void log_flush_wait(struct gfs2_sbd *sdp) |
---|
| 593 | +void log_flush_wait(struct gfs2_sbd *sdp) |
---|
520 | 594 | { |
---|
521 | 595 | DEFINE_WAIT(wait); |
---|
522 | 596 | |
---|
.. | .. |
---|
545 | 619 | return 0; |
---|
546 | 620 | } |
---|
547 | 621 | |
---|
| 622 | +static void __ordered_del_inode(struct gfs2_inode *ip) |
---|
| 623 | +{ |
---|
| 624 | + if (!list_empty(&ip->i_ordered)) |
---|
| 625 | + list_del_init(&ip->i_ordered); |
---|
| 626 | +} |
---|
| 627 | + |
---|
548 | 628 | static void gfs2_ordered_write(struct gfs2_sbd *sdp) |
---|
549 | 629 | { |
---|
550 | 630 | struct gfs2_inode *ip; |
---|
551 | 631 | LIST_HEAD(written); |
---|
552 | 632 | |
---|
553 | 633 | spin_lock(&sdp->sd_ordered_lock); |
---|
554 | | - list_sort(NULL, &sdp->sd_log_le_ordered, &ip_cmp); |
---|
555 | | - while (!list_empty(&sdp->sd_log_le_ordered)) { |
---|
556 | | - ip = list_entry(sdp->sd_log_le_ordered.next, struct gfs2_inode, i_ordered); |
---|
| 634 | + list_sort(NULL, &sdp->sd_log_ordered, &ip_cmp); |
---|
| 635 | + while (!list_empty(&sdp->sd_log_ordered)) { |
---|
| 636 | + ip = list_first_entry(&sdp->sd_log_ordered, struct gfs2_inode, i_ordered); |
---|
557 | 637 | if (ip->i_inode.i_mapping->nrpages == 0) { |
---|
558 | | - test_and_clear_bit(GIF_ORDERED, &ip->i_flags); |
---|
559 | | - list_del(&ip->i_ordered); |
---|
| 638 | + __ordered_del_inode(ip); |
---|
560 | 639 | continue; |
---|
561 | 640 | } |
---|
562 | 641 | list_move(&ip->i_ordered, &written); |
---|
.. | .. |
---|
564 | 643 | filemap_fdatawrite(ip->i_inode.i_mapping); |
---|
565 | 644 | spin_lock(&sdp->sd_ordered_lock); |
---|
566 | 645 | } |
---|
567 | | - list_splice(&written, &sdp->sd_log_le_ordered); |
---|
| 646 | + list_splice(&written, &sdp->sd_log_ordered); |
---|
568 | 647 | spin_unlock(&sdp->sd_ordered_lock); |
---|
569 | 648 | } |
---|
570 | 649 | |
---|
.. | .. |
---|
573 | 652 | struct gfs2_inode *ip; |
---|
574 | 653 | |
---|
575 | 654 | spin_lock(&sdp->sd_ordered_lock); |
---|
576 | | - while (!list_empty(&sdp->sd_log_le_ordered)) { |
---|
577 | | - ip = list_entry(sdp->sd_log_le_ordered.next, struct gfs2_inode, i_ordered); |
---|
578 | | - list_del(&ip->i_ordered); |
---|
579 | | - WARN_ON(!test_and_clear_bit(GIF_ORDERED, &ip->i_flags)); |
---|
| 655 | + while (!list_empty(&sdp->sd_log_ordered)) { |
---|
| 656 | + ip = list_first_entry(&sdp->sd_log_ordered, struct gfs2_inode, i_ordered); |
---|
| 657 | + __ordered_del_inode(ip); |
---|
580 | 658 | if (ip->i_inode.i_mapping->nrpages == 0) |
---|
581 | 659 | continue; |
---|
582 | 660 | spin_unlock(&sdp->sd_ordered_lock); |
---|
.. | .. |
---|
591 | 669 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
---|
592 | 670 | |
---|
593 | 671 | spin_lock(&sdp->sd_ordered_lock); |
---|
594 | | - if (test_and_clear_bit(GIF_ORDERED, &ip->i_flags)) |
---|
595 | | - list_del(&ip->i_ordered); |
---|
| 672 | + __ordered_del_inode(ip); |
---|
596 | 673 | spin_unlock(&sdp->sd_ordered_lock); |
---|
597 | 674 | } |
---|
598 | 675 | |
---|
.. | .. |
---|
601 | 678 | struct buffer_head *bh = bd->bd_bh; |
---|
602 | 679 | struct gfs2_glock *gl = bd->bd_gl; |
---|
603 | 680 | |
---|
| 681 | + sdp->sd_log_num_revoke++; |
---|
| 682 | + if (atomic_inc_return(&gl->gl_revokes) == 1) |
---|
| 683 | + gfs2_glock_hold(gl); |
---|
604 | 684 | bh->b_private = NULL; |
---|
605 | 685 | bd->bd_blkno = bh->b_blocknr; |
---|
606 | 686 | gfs2_remove_from_ail(bd); /* drops ref on bh */ |
---|
607 | 687 | bd->bd_bh = NULL; |
---|
608 | | - bd->bd_ops = &gfs2_revoke_lops; |
---|
609 | | - sdp->sd_log_num_revoke++; |
---|
610 | | - if (atomic_inc_return(&gl->gl_revokes) == 1) |
---|
611 | | - gfs2_glock_hold(gl); |
---|
612 | 688 | set_bit(GLF_LFLUSH, &gl->gl_flags); |
---|
613 | | - list_add(&bd->bd_list, &sdp->sd_log_le_revoke); |
---|
| 689 | + list_add(&bd->bd_list, &sdp->sd_log_revokes); |
---|
614 | 690 | } |
---|
615 | 691 | |
---|
616 | 692 | void gfs2_glock_remove_revoke(struct gfs2_glock *gl) |
---|
.. | .. |
---|
621 | 697 | } |
---|
622 | 698 | } |
---|
623 | 699 | |
---|
| 700 | +/** |
---|
| 701 | + * gfs2_write_revokes - Add as many revokes to the system transaction as we can |
---|
| 702 | + * @sdp: The GFS2 superblock |
---|
| 703 | + * |
---|
| 704 | + * Our usual strategy is to defer writing revokes as much as we can in the hope |
---|
| 705 | + * that we'll eventually overwrite the journal, which will make those revokes |
---|
| 706 | + * go away. This changes when we flush the log: at that point, there will |
---|
| 707 | + * likely be some left-over space in the last revoke block of that transaction. |
---|
| 708 | + * We can fill that space with additional revokes for blocks that have already |
---|
| 709 | + * been written back. This will basically come at no cost now, and will save |
---|
| 710 | + * us from having to keep track of those blocks on the AIL2 list later. |
---|
| 711 | + */ |
---|
624 | 712 | void gfs2_write_revokes(struct gfs2_sbd *sdp) |
---|
625 | 713 | { |
---|
626 | | - struct gfs2_trans *tr; |
---|
627 | | - struct gfs2_bufdata *bd, *tmp; |
---|
628 | | - int have_revokes = 0; |
---|
| 714 | + /* number of revokes we still have room for */ |
---|
629 | 715 | int max_revokes = (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_log_descriptor)) / sizeof(u64); |
---|
630 | 716 | |
---|
631 | | - gfs2_ail1_empty(sdp); |
---|
632 | | - spin_lock(&sdp->sd_ail_lock); |
---|
633 | | - list_for_each_entry(tr, &sdp->sd_ail1_list, tr_list) { |
---|
634 | | - list_for_each_entry(bd, &tr->tr_ail2_list, bd_ail_st_list) { |
---|
635 | | - if (list_empty(&bd->bd_list)) { |
---|
636 | | - have_revokes = 1; |
---|
637 | | - goto done; |
---|
638 | | - } |
---|
639 | | - } |
---|
640 | | - } |
---|
641 | | -done: |
---|
642 | | - spin_unlock(&sdp->sd_ail_lock); |
---|
643 | | - if (have_revokes == 0) |
---|
644 | | - return; |
---|
| 717 | + gfs2_log_lock(sdp); |
---|
645 | 718 | while (sdp->sd_log_num_revoke > max_revokes) |
---|
646 | 719 | max_revokes += (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header)) / sizeof(u64); |
---|
647 | 720 | max_revokes -= sdp->sd_log_num_revoke; |
---|
.. | .. |
---|
649 | 722 | atomic_dec(&sdp->sd_log_blks_free); |
---|
650 | 723 | /* If no blocks have been reserved, we need to also |
---|
651 | 724 | * reserve a block for the header */ |
---|
652 | | - if (!sdp->sd_log_blks_reserved) |
---|
| 725 | + if (!sdp->sd_log_blks_reserved) { |
---|
653 | 726 | atomic_dec(&sdp->sd_log_blks_free); |
---|
654 | | - } |
---|
655 | | - gfs2_log_lock(sdp); |
---|
656 | | - spin_lock(&sdp->sd_ail_lock); |
---|
657 | | - list_for_each_entry(tr, &sdp->sd_ail1_list, tr_list) { |
---|
658 | | - list_for_each_entry_safe(bd, tmp, &tr->tr_ail2_list, bd_ail_st_list) { |
---|
659 | | - if (max_revokes == 0) |
---|
660 | | - goto out_of_blocks; |
---|
661 | | - if (!list_empty(&bd->bd_list)) |
---|
662 | | - continue; |
---|
663 | | - gfs2_add_revoke(sdp, bd); |
---|
664 | | - max_revokes--; |
---|
| 727 | + trace_gfs2_log_blocks(sdp, -2); |
---|
| 728 | + } else { |
---|
| 729 | + trace_gfs2_log_blocks(sdp, -1); |
---|
665 | 730 | } |
---|
666 | 731 | } |
---|
667 | | -out_of_blocks: |
---|
668 | | - spin_unlock(&sdp->sd_ail_lock); |
---|
| 732 | + gfs2_ail1_empty(sdp, max_revokes); |
---|
669 | 733 | gfs2_log_unlock(sdp); |
---|
670 | 734 | |
---|
671 | 735 | if (!sdp->sd_log_num_revoke) { |
---|
672 | 736 | atomic_inc(&sdp->sd_log_blks_free); |
---|
673 | | - if (!sdp->sd_log_blks_reserved) |
---|
| 737 | + if (!sdp->sd_log_blks_reserved) { |
---|
674 | 738 | atomic_inc(&sdp->sd_log_blks_free); |
---|
| 739 | + trace_gfs2_log_blocks(sdp, 2); |
---|
| 740 | + } else { |
---|
| 741 | + trace_gfs2_log_blocks(sdp, 1); |
---|
| 742 | + } |
---|
675 | 743 | } |
---|
676 | 744 | } |
---|
677 | 745 | |
---|
678 | 746 | /** |
---|
679 | | - * write_log_header - Write a journal log header buffer at sd_log_flush_head |
---|
| 747 | + * gfs2_write_log_header - Write a journal log header buffer at lblock |
---|
680 | 748 | * @sdp: The GFS2 superblock |
---|
681 | 749 | * @jd: journal descriptor of the journal to which we are writing |
---|
682 | 750 | * @seq: sequence number |
---|
683 | 751 | * @tail: tail of the log |
---|
| 752 | + * @lblock: value for lh_blkno (block number relative to start of journal) |
---|
684 | 753 | * @flags: log header flags GFS2_LOG_HEAD_* |
---|
685 | 754 | * @op_flags: flags to pass to the bio |
---|
686 | 755 | * |
---|
.. | .. |
---|
688 | 757 | */ |
---|
689 | 758 | |
---|
690 | 759 | void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd, |
---|
691 | | - u64 seq, u32 tail, u32 flags, int op_flags) |
---|
| 760 | + u64 seq, u32 tail, u32 lblock, u32 flags, |
---|
| 761 | + int op_flags) |
---|
692 | 762 | { |
---|
693 | 763 | struct gfs2_log_header *lh; |
---|
694 | 764 | u32 hash, crc; |
---|
695 | | - struct page *page = mempool_alloc(gfs2_page_pool, GFP_NOIO); |
---|
| 765 | + struct page *page; |
---|
696 | 766 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; |
---|
697 | 767 | struct timespec64 tv; |
---|
698 | 768 | struct super_block *sb = sdp->sd_vfs; |
---|
699 | | - u64 addr; |
---|
| 769 | + u64 dblock; |
---|
700 | 770 | |
---|
| 771 | + if (gfs2_withdrawn(sdp)) |
---|
| 772 | + goto out; |
---|
| 773 | + |
---|
| 774 | + page = mempool_alloc(gfs2_page_pool, GFP_NOIO); |
---|
701 | 775 | lh = page_address(page); |
---|
702 | 776 | clear_page(lh); |
---|
703 | 777 | |
---|
.. | .. |
---|
709 | 783 | lh->lh_sequence = cpu_to_be64(seq); |
---|
710 | 784 | lh->lh_flags = cpu_to_be32(flags); |
---|
711 | 785 | lh->lh_tail = cpu_to_be32(tail); |
---|
712 | | - lh->lh_blkno = cpu_to_be32(sdp->sd_log_flush_head); |
---|
| 786 | + lh->lh_blkno = cpu_to_be32(lblock); |
---|
713 | 787 | hash = ~crc32(~0, lh, LH_V1_SIZE); |
---|
714 | 788 | lh->lh_hash = cpu_to_be32(hash); |
---|
715 | 789 | |
---|
716 | 790 | ktime_get_coarse_real_ts64(&tv); |
---|
717 | 791 | lh->lh_nsec = cpu_to_be32(tv.tv_nsec); |
---|
718 | 792 | lh->lh_sec = cpu_to_be64(tv.tv_sec); |
---|
719 | | - addr = gfs2_log_bmap(sdp); |
---|
720 | | - lh->lh_addr = cpu_to_be64(addr); |
---|
| 793 | + if (!list_empty(&jd->extent_list)) |
---|
| 794 | + dblock = gfs2_log_bmap(jd, lblock); |
---|
| 795 | + else { |
---|
| 796 | + int ret = gfs2_lblk_to_dblk(jd->jd_inode, lblock, &dblock); |
---|
| 797 | + if (gfs2_assert_withdraw(sdp, ret == 0)) |
---|
| 798 | + return; |
---|
| 799 | + } |
---|
| 800 | + lh->lh_addr = cpu_to_be64(dblock); |
---|
721 | 801 | lh->lh_jinode = cpu_to_be64(GFS2_I(jd->jd_inode)->i_no_addr); |
---|
722 | 802 | |
---|
723 | 803 | /* We may only write local statfs, quota, etc., when writing to our |
---|
.. | .. |
---|
742 | 822 | sb->s_blocksize - LH_V1_SIZE - 4); |
---|
743 | 823 | lh->lh_crc = cpu_to_be32(crc); |
---|
744 | 824 | |
---|
745 | | - gfs2_log_write(sdp, page, sb->s_blocksize, 0, addr); |
---|
746 | | - gfs2_log_flush_bio(sdp, REQ_OP_WRITE, op_flags); |
---|
| 825 | + gfs2_log_write(sdp, page, sb->s_blocksize, 0, dblock); |
---|
| 826 | + gfs2_log_submit_bio(&sdp->sd_log_bio, REQ_OP_WRITE | op_flags); |
---|
| 827 | +out: |
---|
747 | 828 | log_flush_wait(sdp); |
---|
748 | 829 | } |
---|
749 | 830 | |
---|
.. | .. |
---|
771 | 852 | } |
---|
772 | 853 | sdp->sd_log_idle = (tail == sdp->sd_log_flush_head); |
---|
773 | 854 | gfs2_write_log_header(sdp, sdp->sd_jdesc, sdp->sd_log_sequence++, tail, |
---|
774 | | - flags, op_flags); |
---|
| 855 | + sdp->sd_log_flush_head, flags, op_flags); |
---|
| 856 | + gfs2_log_incr_head(sdp); |
---|
775 | 857 | |
---|
776 | 858 | if (sdp->sd_log_tail != tail) |
---|
777 | 859 | log_pull_tail(sdp, tail); |
---|
| 860 | +} |
---|
| 861 | + |
---|
| 862 | +/** |
---|
| 863 | + * ail_drain - drain the ail lists after a withdraw |
---|
| 864 | + * @sdp: Pointer to GFS2 superblock |
---|
| 865 | + */ |
---|
| 866 | +static void ail_drain(struct gfs2_sbd *sdp) |
---|
| 867 | +{ |
---|
| 868 | + struct gfs2_trans *tr; |
---|
| 869 | + |
---|
| 870 | + spin_lock(&sdp->sd_ail_lock); |
---|
| 871 | + /* |
---|
| 872 | + * For transactions on the sd_ail1_list we need to drain both the |
---|
| 873 | + * ail1 and ail2 lists. That's because function gfs2_ail1_start_one |
---|
| 874 | + * (temporarily) moves items from its tr_ail1 list to tr_ail2 list |
---|
| 875 | + * before revokes are sent for that block. Items on the sd_ail2_list |
---|
| 876 | + * should have already gotten beyond that point, so no need. |
---|
| 877 | + */ |
---|
| 878 | + while (!list_empty(&sdp->sd_ail1_list)) { |
---|
| 879 | + tr = list_first_entry(&sdp->sd_ail1_list, struct gfs2_trans, |
---|
| 880 | + tr_list); |
---|
| 881 | + gfs2_ail_empty_tr(sdp, tr, &tr->tr_ail1_list); |
---|
| 882 | + gfs2_ail_empty_tr(sdp, tr, &tr->tr_ail2_list); |
---|
| 883 | + list_del(&tr->tr_list); |
---|
| 884 | + gfs2_trans_free(sdp, tr); |
---|
| 885 | + } |
---|
| 886 | + while (!list_empty(&sdp->sd_ail2_list)) { |
---|
| 887 | + tr = list_first_entry(&sdp->sd_ail2_list, struct gfs2_trans, |
---|
| 888 | + tr_list); |
---|
| 889 | + gfs2_ail_empty_tr(sdp, tr, &tr->tr_ail2_list); |
---|
| 890 | + list_del(&tr->tr_list); |
---|
| 891 | + gfs2_trans_free(sdp, tr); |
---|
| 892 | + } |
---|
| 893 | + spin_unlock(&sdp->sd_ail_lock); |
---|
| 894 | +} |
---|
| 895 | + |
---|
| 896 | +/** |
---|
| 897 | + * empty_ail1_list - try to start IO and empty the ail1 list |
---|
| 898 | + * @sdp: Pointer to GFS2 superblock |
---|
| 899 | + */ |
---|
| 900 | +static void empty_ail1_list(struct gfs2_sbd *sdp) |
---|
| 901 | +{ |
---|
| 902 | + unsigned long start = jiffies; |
---|
| 903 | + |
---|
| 904 | + for (;;) { |
---|
| 905 | + if (time_after(jiffies, start + (HZ * 600))) { |
---|
| 906 | + fs_err(sdp, "Error: In %s for 10 minutes! t=%d\n", |
---|
| 907 | + __func__, current->journal_info ? 1 : 0); |
---|
| 908 | + dump_ail_list(sdp); |
---|
| 909 | + return; |
---|
| 910 | + } |
---|
| 911 | + gfs2_ail1_start(sdp); |
---|
| 912 | + gfs2_ail1_wait(sdp); |
---|
| 913 | + if (gfs2_ail1_empty(sdp, 0)) |
---|
| 914 | + return; |
---|
| 915 | + } |
---|
| 916 | +} |
---|
| 917 | + |
---|
| 918 | +/** |
---|
| 919 | + * trans_drain - drain the buf and databuf queue for a failed transaction |
---|
| 920 | + * @tr: the transaction to drain |
---|
| 921 | + * |
---|
| 922 | + * When this is called, we're taking an error exit for a log write that failed |
---|
| 923 | + * but since we bypassed the after_commit functions, we need to remove the |
---|
| 924 | + * items from the buf and databuf queue. |
---|
| 925 | + */ |
---|
| 926 | +static void trans_drain(struct gfs2_trans *tr) |
---|
| 927 | +{ |
---|
| 928 | + struct gfs2_bufdata *bd; |
---|
| 929 | + struct list_head *head; |
---|
| 930 | + |
---|
| 931 | + if (!tr) |
---|
| 932 | + return; |
---|
| 933 | + |
---|
| 934 | + head = &tr->tr_buf; |
---|
| 935 | + while (!list_empty(head)) { |
---|
| 936 | + bd = list_first_entry(head, struct gfs2_bufdata, bd_list); |
---|
| 937 | + list_del_init(&bd->bd_list); |
---|
| 938 | + if (!list_empty(&bd->bd_ail_st_list)) |
---|
| 939 | + gfs2_remove_from_ail(bd); |
---|
| 940 | + kmem_cache_free(gfs2_bufdata_cachep, bd); |
---|
| 941 | + } |
---|
| 942 | + head = &tr->tr_databuf; |
---|
| 943 | + while (!list_empty(head)) { |
---|
| 944 | + bd = list_first_entry(head, struct gfs2_bufdata, bd_list); |
---|
| 945 | + list_del_init(&bd->bd_list); |
---|
| 946 | + if (!list_empty(&bd->bd_ail_st_list)) |
---|
| 947 | + gfs2_remove_from_ail(bd); |
---|
| 948 | + kmem_cache_free(gfs2_bufdata_cachep, bd); |
---|
| 949 | + } |
---|
778 | 950 | } |
---|
779 | 951 | |
---|
780 | 952 | /** |
---|
.. | .. |
---|
787 | 959 | |
---|
788 | 960 | void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags) |
---|
789 | 961 | { |
---|
790 | | - struct gfs2_trans *tr; |
---|
| 962 | + struct gfs2_trans *tr = NULL; |
---|
791 | 963 | enum gfs2_freeze_state state = atomic_read(&sdp->sd_freeze_state); |
---|
792 | 964 | |
---|
793 | 965 | down_write(&sdp->sd_log_flush_lock); |
---|
794 | 966 | |
---|
| 967 | + /* |
---|
| 968 | + * Do this check while holding the log_flush_lock to prevent new |
---|
| 969 | + * buffers from being added to the ail via gfs2_pin() |
---|
| 970 | + */ |
---|
| 971 | + if (gfs2_withdrawn(sdp)) |
---|
| 972 | + goto out; |
---|
| 973 | + |
---|
795 | 974 | /* Log might have been flushed while we waited for the flush lock */ |
---|
796 | | - if (gl && !test_bit(GLF_LFLUSH, &gl->gl_flags)) { |
---|
797 | | - up_write(&sdp->sd_log_flush_lock); |
---|
798 | | - return; |
---|
799 | | - } |
---|
| 975 | + if (gl && !test_bit(GLF_LFLUSH, &gl->gl_flags)) |
---|
| 976 | + goto out; |
---|
800 | 977 | trace_gfs2_log_flush(sdp, 1, flags); |
---|
801 | 978 | |
---|
802 | 979 | if (flags & GFS2_LOG_HEAD_FLUSH_SHUTDOWN) |
---|
.. | .. |
---|
808 | 985 | sdp->sd_log_tr = NULL; |
---|
809 | 986 | tr->tr_first = sdp->sd_log_flush_head; |
---|
810 | 987 | if (unlikely (state == SFS_FROZEN)) |
---|
811 | | - gfs2_assert_withdraw(sdp, !tr->tr_num_buf_new && !tr->tr_num_databuf_new); |
---|
| 988 | + if (gfs2_assert_withdraw_delayed(sdp, |
---|
| 989 | + !tr->tr_num_buf_new && !tr->tr_num_databuf_new)) |
---|
| 990 | + goto out_withdraw; |
---|
812 | 991 | } |
---|
813 | 992 | |
---|
814 | 993 | if (unlikely(state == SFS_FROZEN)) |
---|
815 | | - gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); |
---|
816 | | - gfs2_assert_withdraw(sdp, |
---|
817 | | - sdp->sd_log_num_revoke == sdp->sd_log_commited_revoke); |
---|
| 994 | + if (gfs2_assert_withdraw_delayed(sdp, !sdp->sd_log_num_revoke)) |
---|
| 995 | + goto out_withdraw; |
---|
| 996 | + if (gfs2_assert_withdraw_delayed(sdp, |
---|
| 997 | + sdp->sd_log_num_revoke == sdp->sd_log_committed_revoke)) |
---|
| 998 | + goto out_withdraw; |
---|
818 | 999 | |
---|
819 | 1000 | gfs2_ordered_write(sdp); |
---|
| 1001 | + if (gfs2_withdrawn(sdp)) |
---|
| 1002 | + goto out_withdraw; |
---|
820 | 1003 | lops_before_commit(sdp, tr); |
---|
821 | | - gfs2_log_flush_bio(sdp, REQ_OP_WRITE, 0); |
---|
| 1004 | + if (gfs2_withdrawn(sdp)) |
---|
| 1005 | + goto out_withdraw; |
---|
| 1006 | + gfs2_log_submit_bio(&sdp->sd_log_bio, REQ_OP_WRITE); |
---|
| 1007 | + if (gfs2_withdrawn(sdp)) |
---|
| 1008 | + goto out_withdraw; |
---|
822 | 1009 | |
---|
823 | 1010 | if (sdp->sd_log_head != sdp->sd_log_flush_head) { |
---|
824 | 1011 | log_flush_wait(sdp); |
---|
.. | .. |
---|
828 | 1015 | trace_gfs2_log_blocks(sdp, -1); |
---|
829 | 1016 | log_write_header(sdp, flags); |
---|
830 | 1017 | } |
---|
| 1018 | + if (gfs2_withdrawn(sdp)) |
---|
| 1019 | + goto out_withdraw; |
---|
831 | 1020 | lops_after_commit(sdp, tr); |
---|
832 | 1021 | |
---|
833 | 1022 | gfs2_log_lock(sdp); |
---|
834 | 1023 | sdp->sd_log_head = sdp->sd_log_flush_head; |
---|
835 | 1024 | sdp->sd_log_blks_reserved = 0; |
---|
836 | | - sdp->sd_log_commited_revoke = 0; |
---|
| 1025 | + sdp->sd_log_committed_revoke = 0; |
---|
837 | 1026 | |
---|
838 | 1027 | spin_lock(&sdp->sd_ail_lock); |
---|
839 | 1028 | if (tr && !list_empty(&tr->tr_ail1_list)) { |
---|
.. | .. |
---|
845 | 1034 | |
---|
846 | 1035 | if (!(flags & GFS2_LOG_HEAD_FLUSH_NORMAL)) { |
---|
847 | 1036 | if (!sdp->sd_log_idle) { |
---|
848 | | - for (;;) { |
---|
849 | | - gfs2_ail1_start(sdp); |
---|
850 | | - gfs2_ail1_wait(sdp); |
---|
851 | | - if (gfs2_ail1_empty(sdp)) |
---|
852 | | - break; |
---|
853 | | - } |
---|
| 1037 | + empty_ail1_list(sdp); |
---|
| 1038 | + if (gfs2_withdrawn(sdp)) |
---|
| 1039 | + goto out_withdraw; |
---|
854 | 1040 | atomic_dec(&sdp->sd_log_blks_free); /* Adjust for unreserved buffer */ |
---|
855 | 1041 | trace_gfs2_log_blocks(sdp, -1); |
---|
856 | 1042 | log_write_header(sdp, flags); |
---|
.. | .. |
---|
863 | 1049 | atomic_set(&sdp->sd_freeze_state, SFS_FROZEN); |
---|
864 | 1050 | } |
---|
865 | 1051 | |
---|
| 1052 | +out_end: |
---|
866 | 1053 | trace_gfs2_log_flush(sdp, 0, flags); |
---|
| 1054 | +out: |
---|
867 | 1055 | up_write(&sdp->sd_log_flush_lock); |
---|
| 1056 | + gfs2_trans_free(sdp, tr); |
---|
| 1057 | + if (gfs2_withdrawing(sdp)) |
---|
| 1058 | + gfs2_withdraw(sdp); |
---|
| 1059 | + return; |
---|
868 | 1060 | |
---|
869 | | - kfree(tr); |
---|
| 1061 | +out_withdraw: |
---|
| 1062 | + trans_drain(tr); |
---|
| 1063 | + /** |
---|
| 1064 | + * If the tr_list is empty, we're withdrawing during a log |
---|
| 1065 | + * flush that targets a transaction, but the transaction was |
---|
| 1066 | + * never queued onto any of the ail lists. Here we add it to |
---|
| 1067 | + * ail1 just so that ail_drain() will find and free it. |
---|
| 1068 | + */ |
---|
| 1069 | + spin_lock(&sdp->sd_ail_lock); |
---|
| 1070 | + if (tr && list_empty(&tr->tr_list)) |
---|
| 1071 | + list_add(&tr->tr_list, &sdp->sd_ail1_list); |
---|
| 1072 | + spin_unlock(&sdp->sd_ail_lock); |
---|
| 1073 | + ail_drain(sdp); /* frees all transactions */ |
---|
| 1074 | + tr = NULL; |
---|
| 1075 | + goto out_end; |
---|
870 | 1076 | } |
---|
871 | 1077 | |
---|
872 | 1078 | /** |
---|
.. | .. |
---|
913 | 1119 | set_bit(TR_ATTACHED, &tr->tr_flags); |
---|
914 | 1120 | } |
---|
915 | 1121 | |
---|
916 | | - sdp->sd_log_commited_revoke += tr->tr_num_revoke - tr->tr_num_revoke_rm; |
---|
| 1122 | + sdp->sd_log_committed_revoke += tr->tr_num_revoke - tr->tr_num_revoke_rm; |
---|
917 | 1123 | reserved = calc_reserved(sdp); |
---|
918 | 1124 | maxres = sdp->sd_log_blks_reserved + tr->tr_reserved; |
---|
919 | 1125 | gfs2_assert_withdraw(sdp, maxres >= reserved); |
---|
.. | .. |
---|
936 | 1142 | * or the total number of used blocks (pinned blocks plus AIL blocks) |
---|
937 | 1143 | * is greater than thresh2. |
---|
938 | 1144 | * |
---|
939 | | - * At mount time thresh1 is 1/3rd of journal size, thresh2 is 2/3rd of |
---|
| 1145 | + * At mount time thresh1 is 2/5ths of journal size, thresh2 is 4/5ths of |
---|
940 | 1146 | * journal size. |
---|
941 | 1147 | * |
---|
942 | 1148 | * Returns: errno |
---|
.. | .. |
---|
958 | 1164 | * |
---|
959 | 1165 | */ |
---|
960 | 1166 | |
---|
961 | | -void gfs2_log_shutdown(struct gfs2_sbd *sdp) |
---|
| 1167 | +static void gfs2_log_shutdown(struct gfs2_sbd *sdp) |
---|
962 | 1168 | { |
---|
963 | 1169 | gfs2_assert_withdraw(sdp, !sdp->sd_log_blks_reserved); |
---|
964 | 1170 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); |
---|
.. | .. |
---|
1010 | 1216 | |
---|
1011 | 1217 | while (!kthread_should_stop()) { |
---|
1012 | 1218 | |
---|
| 1219 | + if (gfs2_withdrawn(sdp)) { |
---|
| 1220 | + msleep_interruptible(HZ); |
---|
| 1221 | + continue; |
---|
| 1222 | + } |
---|
1013 | 1223 | /* Check for errors writing to the journal */ |
---|
1014 | 1224 | if (sdp->sd_log_error) { |
---|
1015 | | - gfs2_lm_withdraw(sdp, |
---|
1016 | | - "GFS2: fsid=%s: error %d: " |
---|
1017 | | - "withdrawing the file system to " |
---|
1018 | | - "prevent further damage.\n", |
---|
1019 | | - sdp->sd_fsname, sdp->sd_log_error); |
---|
| 1225 | + gfs2_lm(sdp, |
---|
| 1226 | + "GFS2: fsid=%s: error %d: " |
---|
| 1227 | + "withdrawing the file system to " |
---|
| 1228 | + "prevent further damage.\n", |
---|
| 1229 | + sdp->sd_fsname, sdp->sd_log_error); |
---|
| 1230 | + gfs2_withdraw(sdp); |
---|
| 1231 | + continue; |
---|
1020 | 1232 | } |
---|
1021 | 1233 | |
---|
1022 | 1234 | did_flush = false; |
---|
1023 | 1235 | if (gfs2_jrnl_flush_reqd(sdp) || t == 0) { |
---|
1024 | | - gfs2_ail1_empty(sdp); |
---|
| 1236 | + gfs2_ail1_empty(sdp, 0); |
---|
1025 | 1237 | gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL | |
---|
1026 | 1238 | GFS2_LFC_LOGD_JFLUSH_REQD); |
---|
1027 | 1239 | did_flush = true; |
---|
.. | .. |
---|
1030 | 1242 | if (gfs2_ail_flush_reqd(sdp)) { |
---|
1031 | 1243 | gfs2_ail1_start(sdp); |
---|
1032 | 1244 | gfs2_ail1_wait(sdp); |
---|
1033 | | - gfs2_ail1_empty(sdp); |
---|
| 1245 | + gfs2_ail1_empty(sdp, 0); |
---|
1034 | 1246 | gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL | |
---|
1035 | 1247 | GFS2_LFC_LOGD_AIL_FLUSH_REQD); |
---|
1036 | 1248 | did_flush = true; |
---|