.. | .. |
---|
| 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-2006 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 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
---|
.. | .. |
---|
28 | 25 | #include "util.h" |
---|
29 | 26 | #include "trace_gfs2.h" |
---|
30 | 27 | |
---|
| 28 | +static void gfs2_print_trans(struct gfs2_sbd *sdp, const struct gfs2_trans *tr) |
---|
| 29 | +{ |
---|
| 30 | + fs_warn(sdp, "Transaction created at: %pSR\n", (void *)tr->tr_ip); |
---|
| 31 | + fs_warn(sdp, "blocks=%u revokes=%u reserved=%u touched=%u\n", |
---|
| 32 | + tr->tr_blocks, tr->tr_revokes, tr->tr_reserved, |
---|
| 33 | + test_bit(TR_TOUCHED, &tr->tr_flags)); |
---|
| 34 | + fs_warn(sdp, "Buf %u/%u Databuf %u/%u Revoke %u/%u\n", |
---|
| 35 | + tr->tr_num_buf_new, tr->tr_num_buf_rm, |
---|
| 36 | + tr->tr_num_databuf_new, tr->tr_num_databuf_rm, |
---|
| 37 | + tr->tr_num_revoke, tr->tr_num_revoke_rm); |
---|
| 38 | +} |
---|
| 39 | + |
---|
31 | 40 | int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks, |
---|
32 | 41 | unsigned int revokes) |
---|
33 | 42 | { |
---|
34 | 43 | struct gfs2_trans *tr; |
---|
35 | 44 | int error; |
---|
36 | 45 | |
---|
37 | | - BUG_ON(current->journal_info); |
---|
| 46 | + if (current->journal_info) { |
---|
| 47 | + gfs2_print_trans(sdp, current->journal_info); |
---|
| 48 | + BUG(); |
---|
| 49 | + } |
---|
38 | 50 | BUG_ON(blocks == 0 && revokes == 0); |
---|
39 | 51 | |
---|
40 | 52 | if (!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) |
---|
41 | 53 | return -EROFS; |
---|
42 | 54 | |
---|
43 | | - tr = kzalloc(sizeof(struct gfs2_trans), GFP_NOFS); |
---|
| 55 | + tr = kmem_cache_zalloc(gfs2_trans_cachep, GFP_NOFS); |
---|
44 | 56 | if (!tr) |
---|
45 | 57 | return -ENOMEM; |
---|
46 | 58 | |
---|
.. | .. |
---|
52 | 64 | if (blocks) |
---|
53 | 65 | tr->tr_reserved += 6 + blocks; |
---|
54 | 66 | if (revokes) |
---|
55 | | - tr->tr_reserved += gfs2_struct2blk(sdp, revokes, |
---|
56 | | - sizeof(u64)); |
---|
| 67 | + tr->tr_reserved += gfs2_struct2blk(sdp, revokes); |
---|
57 | 68 | INIT_LIST_HEAD(&tr->tr_databuf); |
---|
58 | 69 | INIT_LIST_HEAD(&tr->tr_buf); |
---|
| 70 | + INIT_LIST_HEAD(&tr->tr_list); |
---|
59 | 71 | INIT_LIST_HEAD(&tr->tr_ail1_list); |
---|
60 | 72 | INIT_LIST_HEAD(&tr->tr_ail2_list); |
---|
61 | 73 | |
---|
.. | .. |
---|
71 | 83 | |
---|
72 | 84 | fail: |
---|
73 | 85 | sb_end_intwrite(sdp->sd_vfs); |
---|
74 | | - kfree(tr); |
---|
| 86 | + kmem_cache_free(gfs2_trans_cachep, tr); |
---|
75 | 87 | |
---|
76 | 88 | return error; |
---|
77 | | -} |
---|
78 | | - |
---|
79 | | -static void gfs2_print_trans(const struct gfs2_trans *tr) |
---|
80 | | -{ |
---|
81 | | - pr_warn("Transaction created at: %pSR\n", (void *)tr->tr_ip); |
---|
82 | | - pr_warn("blocks=%u revokes=%u reserved=%u touched=%u\n", |
---|
83 | | - tr->tr_blocks, tr->tr_revokes, tr->tr_reserved, |
---|
84 | | - test_bit(TR_TOUCHED, &tr->tr_flags)); |
---|
85 | | - pr_warn("Buf %u/%u Databuf %u/%u Revoke %u/%u\n", |
---|
86 | | - tr->tr_num_buf_new, tr->tr_num_buf_rm, |
---|
87 | | - tr->tr_num_databuf_new, tr->tr_num_databuf_rm, |
---|
88 | | - tr->tr_num_revoke, tr->tr_num_revoke_rm); |
---|
89 | 89 | } |
---|
90 | 90 | |
---|
91 | 91 | void gfs2_trans_end(struct gfs2_sbd *sdp) |
---|
.. | .. |
---|
99 | 99 | if (!test_bit(TR_TOUCHED, &tr->tr_flags)) { |
---|
100 | 100 | gfs2_log_release(sdp, tr->tr_reserved); |
---|
101 | 101 | if (alloced) { |
---|
102 | | - kfree(tr); |
---|
| 102 | + gfs2_trans_free(sdp, tr); |
---|
103 | 103 | sb_end_intwrite(sdp->sd_vfs); |
---|
104 | 104 | } |
---|
105 | 105 | return; |
---|
.. | .. |
---|
111 | 111 | |
---|
112 | 112 | if (gfs2_assert_withdraw(sdp, (nbuf <= tr->tr_blocks) && |
---|
113 | 113 | (tr->tr_num_revoke <= tr->tr_revokes))) |
---|
114 | | - gfs2_print_trans(tr); |
---|
| 114 | + gfs2_print_trans(sdp, tr); |
---|
115 | 115 | |
---|
116 | 116 | gfs2_log_commit(sdp, tr); |
---|
117 | 117 | if (alloced && !test_bit(TR_ATTACHED, &tr->tr_flags)) |
---|
118 | | - kfree(tr); |
---|
| 118 | + gfs2_trans_free(sdp, tr); |
---|
119 | 119 | up_read(&sdp->sd_log_flush_lock); |
---|
120 | 120 | |
---|
121 | 121 | if (sdp->sd_vfs->s_flags & SB_SYNCHRONOUS) |
---|
.. | .. |
---|
126 | 126 | } |
---|
127 | 127 | |
---|
128 | 128 | static struct gfs2_bufdata *gfs2_alloc_bufdata(struct gfs2_glock *gl, |
---|
129 | | - struct buffer_head *bh, |
---|
130 | | - const struct gfs2_log_operations *lops) |
---|
| 129 | + struct buffer_head *bh) |
---|
131 | 130 | { |
---|
132 | 131 | struct gfs2_bufdata *bd; |
---|
133 | 132 | |
---|
134 | 133 | bd = kmem_cache_zalloc(gfs2_bufdata_cachep, GFP_NOFS | __GFP_NOFAIL); |
---|
135 | 134 | bd->bd_bh = bh; |
---|
136 | 135 | bd->bd_gl = gl; |
---|
137 | | - bd->bd_ops = lops; |
---|
138 | 136 | INIT_LIST_HEAD(&bd->bd_list); |
---|
| 137 | + INIT_LIST_HEAD(&bd->bd_ail_st_list); |
---|
| 138 | + INIT_LIST_HEAD(&bd->bd_ail_gl_list); |
---|
139 | 139 | bh->b_private = bd; |
---|
140 | 140 | return bd; |
---|
141 | 141 | } |
---|
.. | .. |
---|
171 | 171 | gfs2_log_unlock(sdp); |
---|
172 | 172 | unlock_buffer(bh); |
---|
173 | 173 | if (bh->b_private == NULL) |
---|
174 | | - bd = gfs2_alloc_bufdata(gl, bh, &gfs2_databuf_lops); |
---|
| 174 | + bd = gfs2_alloc_bufdata(gl, bh); |
---|
175 | 175 | else |
---|
176 | 176 | bd = bh->b_private; |
---|
177 | 177 | lock_buffer(bh); |
---|
.. | .. |
---|
212 | 212 | unlock_buffer(bh); |
---|
213 | 213 | lock_page(bh->b_page); |
---|
214 | 214 | if (bh->b_private == NULL) |
---|
215 | | - bd = gfs2_alloc_bufdata(gl, bh, &gfs2_buf_lops); |
---|
| 215 | + bd = gfs2_alloc_bufdata(gl, bh); |
---|
216 | 216 | else |
---|
217 | 217 | bd = bh->b_private; |
---|
218 | 218 | unlock_page(bh->b_page); |
---|
.. | .. |
---|
227 | 227 | set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags); |
---|
228 | 228 | mh = (struct gfs2_meta_header *)bd->bd_bh->b_data; |
---|
229 | 229 | if (unlikely(mh->mh_magic != cpu_to_be32(GFS2_MAGIC))) { |
---|
230 | | - pr_err("Attempting to add uninitialised block to journal (inplace block=%lld)\n", |
---|
| 230 | + fs_err(sdp, "Attempting to add uninitialised block to " |
---|
| 231 | + "journal (inplace block=%lld)\n", |
---|
231 | 232 | (unsigned long long)bd->bd_bh->b_blocknr); |
---|
232 | 233 | BUG(); |
---|
233 | 234 | } |
---|
234 | 235 | if (unlikely(state == SFS_FROZEN)) { |
---|
235 | | - printk(KERN_INFO "GFS2:adding buf while frozen\n"); |
---|
| 236 | + fs_info(sdp, "GFS2:adding buf while frozen\n"); |
---|
236 | 237 | gfs2_assert_withdraw(sdp, 0); |
---|
| 238 | + } |
---|
| 239 | + if (unlikely(gfs2_withdrawn(sdp))) { |
---|
| 240 | + fs_info(sdp, "GFS2:adding buf while withdrawn! 0x%llx\n", |
---|
| 241 | + (unsigned long long)bd->bd_bh->b_blocknr); |
---|
237 | 242 | } |
---|
238 | 243 | gfs2_pin(sdp, bd->bd_bh); |
---|
239 | 244 | mh->__pad0 = cpu_to_be64(0); |
---|
.. | .. |
---|
256 | 261 | tr->tr_num_revoke++; |
---|
257 | 262 | } |
---|
258 | 263 | |
---|
259 | | -void gfs2_trans_add_unrevoke(struct gfs2_sbd *sdp, u64 blkno, unsigned int len) |
---|
| 264 | +void gfs2_trans_remove_revoke(struct gfs2_sbd *sdp, u64 blkno, unsigned int len) |
---|
260 | 265 | { |
---|
261 | 266 | struct gfs2_bufdata *bd, *tmp; |
---|
262 | 267 | struct gfs2_trans *tr = current->journal_info; |
---|
263 | 268 | unsigned int n = len; |
---|
264 | 269 | |
---|
265 | 270 | gfs2_log_lock(sdp); |
---|
266 | | - list_for_each_entry_safe(bd, tmp, &sdp->sd_log_le_revoke, bd_list) { |
---|
| 271 | + list_for_each_entry_safe(bd, tmp, &sdp->sd_log_revokes, bd_list) { |
---|
267 | 272 | if ((bd->bd_blkno >= blkno) && (bd->bd_blkno < (blkno + len))) { |
---|
268 | 273 | list_del_init(&bd->bd_list); |
---|
269 | 274 | gfs2_assert_withdraw(sdp, sdp->sd_log_num_revoke); |
---|
.. | .. |
---|
279 | 284 | gfs2_log_unlock(sdp); |
---|
280 | 285 | } |
---|
281 | 286 | |
---|
| 287 | +void gfs2_trans_free(struct gfs2_sbd *sdp, struct gfs2_trans *tr) |
---|
| 288 | +{ |
---|
| 289 | + if (tr == NULL) |
---|
| 290 | + return; |
---|
| 291 | + |
---|
| 292 | + gfs2_assert_warn(sdp, list_empty(&tr->tr_ail1_list)); |
---|
| 293 | + gfs2_assert_warn(sdp, list_empty(&tr->tr_ail2_list)); |
---|
| 294 | + gfs2_assert_warn(sdp, list_empty(&tr->tr_databuf)); |
---|
| 295 | + gfs2_assert_warn(sdp, list_empty(&tr->tr_buf)); |
---|
| 296 | + kmem_cache_free(gfs2_trans_cachep, tr); |
---|
| 297 | +} |
---|