Blame view

fs/gfs2/trans.c 4.52 KB
b3b94faa5   David Teigland   [GFS2] The core o...
1
2
  /*
   * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
3a8a9a103   Steven Whitehouse   [GFS2] Update cop...
3
   * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
b3b94faa5   David Teigland   [GFS2] The core o...
4
5
6
   *
   * This copyrighted material is made available to anyone wishing to use,
   * modify, copy, or redistribute it subject to the terms and conditions
e9fc2aa09   Steven Whitehouse   [GFS2] Update cop...
7
   * of the GNU General Public License version 2.
b3b94faa5   David Teigland   [GFS2] The core o...
8
9
10
11
12
13
14
   */
  
  #include <linux/sched.h>
  #include <linux/slab.h>
  #include <linux/spinlock.h>
  #include <linux/completion.h>
  #include <linux/buffer_head.h>
d0dc80dba   Steven Whitehouse   [GFS2] Update deb...
15
  #include <linux/kallsyms.h>
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
16
  #include <linux/gfs2_ondisk.h>
b3b94faa5   David Teigland   [GFS2] The core o...
17
18
  
  #include "gfs2.h"
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
19
  #include "incore.h"
b3b94faa5   David Teigland   [GFS2] The core o...
20
21
22
23
24
  #include "glock.h"
  #include "log.h"
  #include "lops.h"
  #include "meta_io.h"
  #include "trans.h"
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
25
  #include "util.h"
5e687eac1   Benjamin Marzinski   GFS2: Various gfs...
26
  #include "trace_gfs2.h"
b3b94faa5   David Teigland   [GFS2] The core o...
27

d0dc80dba   Steven Whitehouse   [GFS2] Update deb...
28
29
  int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks,
  		     unsigned int revokes)
b3b94faa5   David Teigland   [GFS2] The core o...
30
31
32
  {
  	struct gfs2_trans *tr;
  	int error;
d0dc80dba   Steven Whitehouse   [GFS2] Update deb...
33
34
  	BUG_ON(current->journal_info);
  	BUG_ON(blocks == 0 && revokes == 0);
b3b94faa5   David Teigland   [GFS2] The core o...
35

a1c0643ff   Steven Whitehouse   GFS2: Move journa...
36
37
  	if (!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags))
  		return -EROFS;
f55ab26a8   Steven Whitehouse   [GFS2] Use mutice...
38
  	tr = kzalloc(sizeof(struct gfs2_trans), GFP_NOFS);
b3b94faa5   David Teigland   [GFS2] The core o...
39
40
  	if (!tr)
  		return -ENOMEM;
d0dc80dba   Steven Whitehouse   [GFS2] Update deb...
41
  	tr->tr_ip = (unsigned long)__builtin_return_address(0);
b3b94faa5   David Teigland   [GFS2] The core o...
42
43
44
45
  	tr->tr_blocks = blocks;
  	tr->tr_revokes = revokes;
  	tr->tr_reserved = 1;
  	if (blocks)
f4154ea03   Steven Whitehouse   [GFS2] Update jou...
46
  		tr->tr_reserved += 6 + blocks;
b3b94faa5   David Teigland   [GFS2] The core o...
47
48
  	if (revokes)
  		tr->tr_reserved += gfs2_struct2blk(sdp, revokes,
cd915493f   Steven Whitehouse   [GFS2] Change all...
49
  						   sizeof(u64));
b3b94faa5   David Teigland   [GFS2] The core o...
50
  	INIT_LIST_HEAD(&tr->tr_list_buf);
579b78a43   Steven Whitehouse   [GFS2] Remove GL_...
51
  	gfs2_holder_init(sdp->sd_trans_gl, LM_ST_SHARED, 0, &tr->tr_t_gh);
b3b94faa5   David Teigland   [GFS2] The core o...
52

e317ffcb7   Steven Whitehouse   [GFS2] Remove une...
53
  	error = gfs2_glock_nq(&tr->tr_t_gh);
b3b94faa5   David Teigland   [GFS2] The core o...
54
  	if (error)
e317ffcb7   Steven Whitehouse   [GFS2] Remove une...
55
  		goto fail_holder_uninit;
b3b94faa5   David Teigland   [GFS2] The core o...
56

b3b94faa5   David Teigland   [GFS2] The core o...
57
58
59
  	error = gfs2_log_reserve(sdp, tr->tr_reserved);
  	if (error)
  		goto fail_gunlock;
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
60
  	current->journal_info = tr;
b3b94faa5   David Teigland   [GFS2] The core o...
61
62
  
  	return 0;
484adff8a   Steven Whitehouse   [GFS2] Update loc...
63
  fail_gunlock:
e317ffcb7   Steven Whitehouse   [GFS2] Remove une...
64
  	gfs2_glock_dq(&tr->tr_t_gh);
b3b94faa5   David Teigland   [GFS2] The core o...
65

484adff8a   Steven Whitehouse   [GFS2] Update loc...
66
  fail_holder_uninit:
e317ffcb7   Steven Whitehouse   [GFS2] Remove une...
67
  	gfs2_holder_uninit(&tr->tr_t_gh);
b3b94faa5   David Teigland   [GFS2] The core o...
68
69
70
71
  	kfree(tr);
  
  	return error;
  }
5e687eac1   Benjamin Marzinski   GFS2: Various gfs...
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
  /**
   * gfs2_log_release - Release a given number of log blocks
   * @sdp: The GFS2 superblock
   * @blks: The number of blocks
   *
   */
  
  static 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...
88
89
  void gfs2_trans_end(struct gfs2_sbd *sdp)
  {
f4154ea03   Steven Whitehouse   [GFS2] Update jou...
90
  	struct gfs2_trans *tr = current->journal_info;
b3b94faa5   David Teigland   [GFS2] The core o...
91

f4154ea03   Steven Whitehouse   [GFS2] Update jou...
92
  	BUG_ON(!tr);
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
93
  	current->journal_info = NULL;
b3b94faa5   David Teigland   [GFS2] The core o...
94

b3b94faa5   David Teigland   [GFS2] The core o...
95
96
  	if (!tr->tr_touched) {
  		gfs2_log_release(sdp, tr->tr_reserved);
d8348de06   Steven Whitehouse   GFS2: Fix deadloc...
97
98
99
100
101
  		if (tr->tr_t_gh.gh_gl) {
  			gfs2_glock_dq(&tr->tr_t_gh);
  			gfs2_holder_uninit(&tr->tr_t_gh);
  			kfree(tr);
  		}
b3b94faa5   David Teigland   [GFS2] The core o...
102
103
  		return;
  	}
d0dc80dba   Steven Whitehouse   [GFS2] Update deb...
104
105
106
107
108
109
  	if (gfs2_assert_withdraw(sdp, tr->tr_num_buf <= tr->tr_blocks)) {
  		fs_err(sdp, "tr_num_buf = %u, tr_blocks = %u ",
  		       tr->tr_num_buf, tr->tr_blocks);
  		print_symbol(KERN_WARNING "GFS2: Transaction created at: %s
  ", tr->tr_ip);
  	}
cd45697f0   Steven Whitehouse   [GFS2] Add missin...
110
  	if (gfs2_assert_withdraw(sdp, tr->tr_num_revoke <= tr->tr_revokes)) {
d0dc80dba   Steven Whitehouse   [GFS2] Update deb...
111
112
113
114
  		fs_err(sdp, "tr_num_revoke = %u, tr_revokes = %u ",
  		       tr->tr_num_revoke, tr->tr_revokes);
  		print_symbol(KERN_WARNING "GFS2: Transaction created at: %s
  ", tr->tr_ip);
cd45697f0   Steven Whitehouse   [GFS2] Add missin...
115
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
116
117
  
  	gfs2_log_commit(sdp, tr);
d8348de06   Steven Whitehouse   GFS2: Fix deadloc...
118
119
120
121
122
  	if (tr->tr_t_gh.gh_gl) {
  		gfs2_glock_dq(&tr->tr_t_gh);
  		gfs2_holder_uninit(&tr->tr_t_gh);
  		kfree(tr);
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
123
124
  
  	if (sdp->sd_vfs->s_flags & MS_SYNCHRONOUS)
b09e593d7   Steven Whitehouse   [GFS2] Fix a ref ...
125
  		gfs2_log_flush(sdp, NULL);
b3b94faa5   David Teigland   [GFS2] The core o...
126
  }
b3b94faa5   David Teigland   [GFS2] The core o...
127
128
129
130
  /**
   * gfs2_trans_add_bh - Add a to-be-modified buffer to the current transaction
   * @gl: the glock the buffer belongs to
   * @bh: The buffer to add
d4e9c4c3b   Steven Whitehouse   [GFS2] Add an add...
131
   * @meta: True in the case of adding metadata
b3b94faa5   David Teigland   [GFS2] The core o...
132
133
   *
   */
d4e9c4c3b   Steven Whitehouse   [GFS2] Add an add...
134
  void gfs2_trans_add_bh(struct gfs2_glock *gl, struct buffer_head *bh, int meta)
b3b94faa5   David Teigland   [GFS2] The core o...
135
136
137
  {
  	struct gfs2_sbd *sdp = gl->gl_sbd;
  	struct gfs2_bufdata *bd;
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
138
  	bd = bh->b_private;
b3b94faa5   David Teigland   [GFS2] The core o...
139
140
141
  	if (bd)
  		gfs2_assert(sdp, bd->bd_gl == gl);
  	else {
586dfdaaf   Steven Whitehouse   [GFS2] Make the n...
142
  		gfs2_attach_bufdata(gl, bh, meta);
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
143
  		bd = bh->b_private;
b3b94faa5   David Teigland   [GFS2] The core o...
144
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
145
146
  	lops_add(sdp, &bd->bd_le);
  }
1ad38c437   Steven Whitehouse   [GFS2] Clean up g...
147
  void gfs2_trans_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
b3b94faa5   David Teigland   [GFS2] The core o...
148
  {
1ad38c437   Steven Whitehouse   [GFS2] Clean up g...
149
150
151
  	BUG_ON(!list_empty(&bd->bd_le.le_list));
  	BUG_ON(!list_empty(&bd->bd_ail_st_list));
  	BUG_ON(!list_empty(&bd->bd_ail_gl_list));
82e86087b   Steven Whitehouse   [GFS2] Replace re...
152
  	lops_init_le(&bd->bd_le, &gfs2_revoke_lops);
82e86087b   Steven Whitehouse   [GFS2] Replace re...
153
  	lops_add(sdp, &bd->bd_le);
b3b94faa5   David Teigland   [GFS2] The core o...
154
  }
5731be53e   Steven Whitehouse   [GFS2] Update gfs...
155
  void gfs2_trans_add_unrevoke(struct gfs2_sbd *sdp, u64 blkno, unsigned int len)
b3b94faa5   David Teigland   [GFS2] The core o...
156
  {
5731be53e   Steven Whitehouse   [GFS2] Update gfs...
157
158
159
  	struct gfs2_bufdata *bd, *tmp;
  	struct gfs2_trans *tr = current->journal_info;
  	unsigned int n = len;
b3b94faa5   David Teigland   [GFS2] The core o...
160
161
  
  	gfs2_log_lock(sdp);
5731be53e   Steven Whitehouse   [GFS2] Update gfs...
162
163
  	list_for_each_entry_safe(bd, tmp, &sdp->sd_log_le_revoke, bd_le.le_list) {
  		if ((bd->bd_blkno >= blkno) && (bd->bd_blkno < (blkno + len))) {
1ad38c437   Steven Whitehouse   [GFS2] Clean up g...
164
  			list_del_init(&bd->bd_le.le_list);
b3b94faa5   David Teigland   [GFS2] The core o...
165
166
  			gfs2_assert_withdraw(sdp, sdp->sd_log_num_revoke);
  			sdp->sd_log_num_revoke--;
5731be53e   Steven Whitehouse   [GFS2] Update gfs...
167
168
169
170
  			kmem_cache_free(gfs2_bufdata_cachep, bd);
  			tr->tr_num_revoke_rm++;
  			if (--n == 0)
  				break;
b3b94faa5   David Teigland   [GFS2] The core o...
171
172
  		}
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
173
  	gfs2_log_unlock(sdp);
b3b94faa5   David Teigland   [GFS2] The core o...
174
  }