Root/
1 | /* |
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
3 | * Copyright (C) 2004-2008 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 | */ |
9 | |
10 | #include <linux/slab.h> |
11 | #include <linux/spinlock.h> |
12 | #include <linux/completion.h> |
13 | #include <linux/buffer_head.h> |
14 | #include <linux/gfs2_ondisk.h> |
15 | #include <linux/bio.h> |
16 | |
17 | #include "gfs2.h" |
18 | #include "incore.h" |
19 | #include "bmap.h" |
20 | #include "glock.h" |
21 | #include "glops.h" |
22 | #include "inode.h" |
23 | #include "log.h" |
24 | #include "meta_io.h" |
25 | #include "recovery.h" |
26 | #include "rgrp.h" |
27 | #include "util.h" |
28 | #include "trans.h" |
29 | |
30 | /** |
31 | * ail_empty_gl - remove all buffers for a given lock from the AIL |
32 | * @gl: the glock |
33 | * |
34 | * None of the buffers should be dirty, locked, or pinned. |
35 | */ |
36 | |
37 | static void gfs2_ail_empty_gl(struct gfs2_glock *gl) |
38 | { |
39 | struct gfs2_sbd *sdp = gl->gl_sbd; |
40 | struct list_head *head = &gl->gl_ail_list; |
41 | struct gfs2_bufdata *bd; |
42 | struct buffer_head *bh; |
43 | struct gfs2_trans tr; |
44 | |
45 | memset(&tr, 0, sizeof(tr)); |
46 | tr.tr_revokes = atomic_read(&gl->gl_ail_count); |
47 | |
48 | if (!tr.tr_revokes) |
49 | return; |
50 | |
51 | /* A shortened, inline version of gfs2_trans_begin() */ |
52 | tr.tr_reserved = 1 + gfs2_struct2blk(sdp, tr.tr_revokes, sizeof(u64)); |
53 | tr.tr_ip = (unsigned long)__builtin_return_address(0); |
54 | INIT_LIST_HEAD(&tr.tr_list_buf); |
55 | gfs2_log_reserve(sdp, tr.tr_reserved); |
56 | BUG_ON(current->journal_info); |
57 | current->journal_info = &tr; |
58 | |
59 | gfs2_log_lock(sdp); |
60 | while (!list_empty(head)) { |
61 | bd = list_entry(head->next, struct gfs2_bufdata, |
62 | bd_ail_gl_list); |
63 | bh = bd->bd_bh; |
64 | gfs2_remove_from_ail(bd); |
65 | bd->bd_bh = NULL; |
66 | bh->b_private = NULL; |
67 | bd->bd_blkno = bh->b_blocknr; |
68 | gfs2_assert_withdraw(sdp, !buffer_busy(bh)); |
69 | gfs2_trans_add_revoke(sdp, bd); |
70 | } |
71 | gfs2_assert_withdraw(sdp, !atomic_read(&gl->gl_ail_count)); |
72 | gfs2_log_unlock(sdp); |
73 | |
74 | gfs2_trans_end(sdp); |
75 | gfs2_log_flush(sdp, NULL); |
76 | } |
77 | |
78 | /** |
79 | * rgrp_go_sync - sync out the metadata for this glock |
80 | * @gl: the glock |
81 | * |
82 | * Called when demoting or unlocking an EX glock. We must flush |
83 | * to disk all dirty buffers/pages relating to this glock, and must not |
84 | * not return to caller to demote/unlock the glock until I/O is complete. |
85 | */ |
86 | |
87 | static void rgrp_go_sync(struct gfs2_glock *gl) |
88 | { |
89 | struct address_space *metamapping = gl->gl_aspace->i_mapping; |
90 | int error; |
91 | |
92 | if (!test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) |
93 | return; |
94 | BUG_ON(gl->gl_state != LM_ST_EXCLUSIVE); |
95 | |
96 | gfs2_log_flush(gl->gl_sbd, gl); |
97 | filemap_fdatawrite(metamapping); |
98 | error = filemap_fdatawait(metamapping); |
99 | mapping_set_error(metamapping, error); |
100 | gfs2_ail_empty_gl(gl); |
101 | } |
102 | |
103 | /** |
104 | * rgrp_go_inval - invalidate the metadata for this glock |
105 | * @gl: the glock |
106 | * @flags: |
107 | * |
108 | * We never used LM_ST_DEFERRED with resource groups, so that we |
109 | * should always see the metadata flag set here. |
110 | * |
111 | */ |
112 | |
113 | static void rgrp_go_inval(struct gfs2_glock *gl, int flags) |
114 | { |
115 | struct address_space *mapping = gl->gl_aspace->i_mapping; |
116 | |
117 | BUG_ON(!(flags & DIO_METADATA)); |
118 | gfs2_assert_withdraw(gl->gl_sbd, !atomic_read(&gl->gl_ail_count)); |
119 | truncate_inode_pages(mapping, 0); |
120 | |
121 | if (gl->gl_object) { |
122 | struct gfs2_rgrpd *rgd = (struct gfs2_rgrpd *)gl->gl_object; |
123 | rgd->rd_flags &= ~GFS2_RDF_UPTODATE; |
124 | } |
125 | } |
126 | |
127 | /** |
128 | * inode_go_sync - Sync the dirty data and/or metadata for an inode glock |
129 | * @gl: the glock protecting the inode |
130 | * |
131 | */ |
132 | |
133 | static void inode_go_sync(struct gfs2_glock *gl) |
134 | { |
135 | struct gfs2_inode *ip = gl->gl_object; |
136 | struct address_space *metamapping = gl->gl_aspace->i_mapping; |
137 | int error; |
138 | |
139 | if (ip && !S_ISREG(ip->i_inode.i_mode)) |
140 | ip = NULL; |
141 | if (ip && test_and_clear_bit(GIF_SW_PAGED, &ip->i_flags)) |
142 | unmap_shared_mapping_range(ip->i_inode.i_mapping, 0, 0); |
143 | if (!test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) |
144 | return; |
145 | |
146 | BUG_ON(gl->gl_state != LM_ST_EXCLUSIVE); |
147 | |
148 | gfs2_log_flush(gl->gl_sbd, gl); |
149 | filemap_fdatawrite(metamapping); |
150 | if (ip) { |
151 | struct address_space *mapping = ip->i_inode.i_mapping; |
152 | filemap_fdatawrite(mapping); |
153 | error = filemap_fdatawait(mapping); |
154 | mapping_set_error(mapping, error); |
155 | } |
156 | error = filemap_fdatawait(metamapping); |
157 | mapping_set_error(metamapping, error); |
158 | gfs2_ail_empty_gl(gl); |
159 | /* |
160 | * Writeback of the data mapping may cause the dirty flag to be set |
161 | * so we have to clear it again here. |
162 | */ |
163 | smp_mb__before_clear_bit(); |
164 | clear_bit(GLF_DIRTY, &gl->gl_flags); |
165 | } |
166 | |
167 | /** |
168 | * inode_go_inval - prepare a inode glock to be released |
169 | * @gl: the glock |
170 | * @flags: |
171 | * |
172 | * Normally we invlidate everything, but if we are moving into |
173 | * LM_ST_DEFERRED from LM_ST_SHARED or LM_ST_EXCLUSIVE then we |
174 | * can keep hold of the metadata, since it won't have changed. |
175 | * |
176 | */ |
177 | |
178 | static void inode_go_inval(struct gfs2_glock *gl, int flags) |
179 | { |
180 | struct gfs2_inode *ip = gl->gl_object; |
181 | |
182 | gfs2_assert_withdraw(gl->gl_sbd, !atomic_read(&gl->gl_ail_count)); |
183 | |
184 | if (flags & DIO_METADATA) { |
185 | struct address_space *mapping = gl->gl_aspace->i_mapping; |
186 | truncate_inode_pages(mapping, 0); |
187 | if (ip) |
188 | set_bit(GIF_INVALID, &ip->i_flags); |
189 | } |
190 | |
191 | if (ip == GFS2_I(gl->gl_sbd->sd_rindex)) |
192 | gl->gl_sbd->sd_rindex_uptodate = 0; |
193 | if (ip && S_ISREG(ip->i_inode.i_mode)) |
194 | truncate_inode_pages(ip->i_inode.i_mapping, 0); |
195 | } |
196 | |
197 | /** |
198 | * inode_go_demote_ok - Check to see if it's ok to unlock an inode glock |
199 | * @gl: the glock |
200 | * |
201 | * Returns: 1 if it's ok |
202 | */ |
203 | |
204 | static int inode_go_demote_ok(const struct gfs2_glock *gl) |
205 | { |
206 | struct gfs2_sbd *sdp = gl->gl_sbd; |
207 | if (sdp->sd_jindex == gl->gl_object || sdp->sd_rindex == gl->gl_object) |
208 | return 0; |
209 | return 1; |
210 | } |
211 | |
212 | /** |
213 | * inode_go_lock - operation done after an inode lock is locked by a process |
214 | * @gl: the glock |
215 | * @flags: |
216 | * |
217 | * Returns: errno |
218 | */ |
219 | |
220 | static int inode_go_lock(struct gfs2_holder *gh) |
221 | { |
222 | struct gfs2_glock *gl = gh->gh_gl; |
223 | struct gfs2_sbd *sdp = gl->gl_sbd; |
224 | struct gfs2_inode *ip = gl->gl_object; |
225 | int error = 0; |
226 | |
227 | if (!ip || (gh->gh_flags & GL_SKIP)) |
228 | return 0; |
229 | |
230 | if (test_bit(GIF_INVALID, &ip->i_flags)) { |
231 | error = gfs2_inode_refresh(ip); |
232 | if (error) |
233 | return error; |
234 | } |
235 | |
236 | if ((ip->i_diskflags & GFS2_DIF_TRUNC_IN_PROG) && |
237 | (gl->gl_state == LM_ST_EXCLUSIVE) && |
238 | (gh->gh_state == LM_ST_EXCLUSIVE)) { |
239 | spin_lock(&sdp->sd_trunc_lock); |
240 | if (list_empty(&ip->i_trunc_list)) |
241 | list_add(&sdp->sd_trunc_list, &ip->i_trunc_list); |
242 | spin_unlock(&sdp->sd_trunc_lock); |
243 | wake_up(&sdp->sd_quota_wait); |
244 | return 1; |
245 | } |
246 | |
247 | return error; |
248 | } |
249 | |
250 | /** |
251 | * inode_go_dump - print information about an inode |
252 | * @seq: The iterator |
253 | * @ip: the inode |
254 | * |
255 | * Returns: 0 on success, -ENOBUFS when we run out of space |
256 | */ |
257 | |
258 | static int inode_go_dump(struct seq_file *seq, const struct gfs2_glock *gl) |
259 | { |
260 | const struct gfs2_inode *ip = gl->gl_object; |
261 | if (ip == NULL) |
262 | return 0; |
263 | gfs2_print_dbg(seq, " I: n:%llu/%llu t:%u f:0x%02lx d:0x%08x s:%llu/%llu\n", |
264 | (unsigned long long)ip->i_no_formal_ino, |
265 | (unsigned long long)ip->i_no_addr, |
266 | IF2DT(ip->i_inode.i_mode), ip->i_flags, |
267 | (unsigned int)ip->i_diskflags, |
268 | (unsigned long long)ip->i_inode.i_size, |
269 | (unsigned long long)ip->i_disksize); |
270 | return 0; |
271 | } |
272 | |
273 | /** |
274 | * rgrp_go_demote_ok - Check to see if it's ok to unlock a RG's glock |
275 | * @gl: the glock |
276 | * |
277 | * Returns: 1 if it's ok |
278 | */ |
279 | |
280 | static int rgrp_go_demote_ok(const struct gfs2_glock *gl) |
281 | { |
282 | return !gl->gl_aspace->i_mapping->nrpages; |
283 | } |
284 | |
285 | /** |
286 | * rgrp_go_lock - operation done after an rgrp lock is locked by |
287 | * a first holder on this node. |
288 | * @gl: the glock |
289 | * @flags: |
290 | * |
291 | * Returns: errno |
292 | */ |
293 | |
294 | static int rgrp_go_lock(struct gfs2_holder *gh) |
295 | { |
296 | return gfs2_rgrp_bh_get(gh->gh_gl->gl_object); |
297 | } |
298 | |
299 | /** |
300 | * rgrp_go_unlock - operation done before an rgrp lock is unlocked by |
301 | * a last holder on this node. |
302 | * @gl: the glock |
303 | * @flags: |
304 | * |
305 | */ |
306 | |
307 | static void rgrp_go_unlock(struct gfs2_holder *gh) |
308 | { |
309 | gfs2_rgrp_bh_put(gh->gh_gl->gl_object); |
310 | } |
311 | |
312 | /** |
313 | * trans_go_sync - promote/demote the transaction glock |
314 | * @gl: the glock |
315 | * @state: the requested state |
316 | * @flags: |
317 | * |
318 | */ |
319 | |
320 | static void trans_go_sync(struct gfs2_glock *gl) |
321 | { |
322 | struct gfs2_sbd *sdp = gl->gl_sbd; |
323 | |
324 | if (gl->gl_state != LM_ST_UNLOCKED && |
325 | test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { |
326 | flush_workqueue(gfs2_delete_workqueue); |
327 | gfs2_meta_syncfs(sdp); |
328 | gfs2_log_shutdown(sdp); |
329 | } |
330 | } |
331 | |
332 | /** |
333 | * trans_go_xmote_bh - After promoting/demoting the transaction glock |
334 | * @gl: the glock |
335 | * |
336 | */ |
337 | |
338 | static int trans_go_xmote_bh(struct gfs2_glock *gl, struct gfs2_holder *gh) |
339 | { |
340 | struct gfs2_sbd *sdp = gl->gl_sbd; |
341 | struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); |
342 | struct gfs2_glock *j_gl = ip->i_gl; |
343 | struct gfs2_log_header_host head; |
344 | int error; |
345 | |
346 | if (test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { |
347 | j_gl->gl_ops->go_inval(j_gl, DIO_METADATA); |
348 | |
349 | error = gfs2_find_jhead(sdp->sd_jdesc, &head); |
350 | if (error) |
351 | gfs2_consist(sdp); |
352 | if (!(head.lh_flags & GFS2_LOG_HEAD_UNMOUNT)) |
353 | gfs2_consist(sdp); |
354 | |
355 | /* Initialize some head of the log stuff */ |
356 | if (!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) { |
357 | sdp->sd_log_sequence = head.lh_sequence + 1; |
358 | gfs2_log_pointers_init(sdp, head.lh_blkno); |
359 | } |
360 | } |
361 | return 0; |
362 | } |
363 | |
364 | /** |
365 | * trans_go_demote_ok |
366 | * @gl: the glock |
367 | * |
368 | * Always returns 0 |
369 | */ |
370 | |
371 | static int trans_go_demote_ok(const struct gfs2_glock *gl) |
372 | { |
373 | return 0; |
374 | } |
375 | |
376 | /** |
377 | * iopen_go_callback - schedule the dcache entry for the inode to be deleted |
378 | * @gl: the glock |
379 | * |
380 | * gl_spin lock is held while calling this |
381 | */ |
382 | static void iopen_go_callback(struct gfs2_glock *gl) |
383 | { |
384 | struct gfs2_inode *ip = (struct gfs2_inode *)gl->gl_object; |
385 | |
386 | if (gl->gl_demote_state == LM_ST_UNLOCKED && |
387 | gl->gl_state == LM_ST_SHARED && |
388 | ip && test_bit(GIF_USER, &ip->i_flags)) { |
389 | gfs2_glock_hold(gl); |
390 | if (queue_work(gfs2_delete_workqueue, &gl->gl_delete) == 0) |
391 | gfs2_glock_put_nolock(gl); |
392 | } |
393 | } |
394 | |
395 | const struct gfs2_glock_operations gfs2_meta_glops = { |
396 | .go_type = LM_TYPE_META, |
397 | }; |
398 | |
399 | const struct gfs2_glock_operations gfs2_inode_glops = { |
400 | .go_xmote_th = inode_go_sync, |
401 | .go_inval = inode_go_inval, |
402 | .go_demote_ok = inode_go_demote_ok, |
403 | .go_lock = inode_go_lock, |
404 | .go_dump = inode_go_dump, |
405 | .go_type = LM_TYPE_INODE, |
406 | .go_min_hold_time = HZ / 5, |
407 | }; |
408 | |
409 | const struct gfs2_glock_operations gfs2_rgrp_glops = { |
410 | .go_xmote_th = rgrp_go_sync, |
411 | .go_inval = rgrp_go_inval, |
412 | .go_demote_ok = rgrp_go_demote_ok, |
413 | .go_lock = rgrp_go_lock, |
414 | .go_unlock = rgrp_go_unlock, |
415 | .go_dump = gfs2_rgrp_dump, |
416 | .go_type = LM_TYPE_RGRP, |
417 | .go_min_hold_time = HZ / 5, |
418 | }; |
419 | |
420 | const struct gfs2_glock_operations gfs2_trans_glops = { |
421 | .go_xmote_th = trans_go_sync, |
422 | .go_xmote_bh = trans_go_xmote_bh, |
423 | .go_demote_ok = trans_go_demote_ok, |
424 | .go_type = LM_TYPE_NONDISK, |
425 | }; |
426 | |
427 | const struct gfs2_glock_operations gfs2_iopen_glops = { |
428 | .go_type = LM_TYPE_IOPEN, |
429 | .go_callback = iopen_go_callback, |
430 | }; |
431 | |
432 | const struct gfs2_glock_operations gfs2_flock_glops = { |
433 | .go_type = LM_TYPE_FLOCK, |
434 | }; |
435 | |
436 | const struct gfs2_glock_operations gfs2_nondisk_glops = { |
437 | .go_type = LM_TYPE_NONDISK, |
438 | }; |
439 | |
440 | const struct gfs2_glock_operations gfs2_quota_glops = { |
441 | .go_type = LM_TYPE_QUOTA, |
442 | }; |
443 | |
444 | const struct gfs2_glock_operations gfs2_journal_glops = { |
445 | .go_type = LM_TYPE_JOURNAL, |
446 | }; |
447 | |
448 | const struct gfs2_glock_operations *gfs2_glops_list[] = { |
449 | [LM_TYPE_META] = &gfs2_meta_glops, |
450 | [LM_TYPE_INODE] = &gfs2_inode_glops, |
451 | [LM_TYPE_RGRP] = &gfs2_rgrp_glops, |
452 | [LM_TYPE_NONDISK] = &gfs2_trans_glops, |
453 | [LM_TYPE_IOPEN] = &gfs2_iopen_glops, |
454 | [LM_TYPE_FLOCK] = &gfs2_flock_glops, |
455 | [LM_TYPE_NONDISK] = &gfs2_nondisk_glops, |
456 | [LM_TYPE_QUOTA] = &gfs2_quota_glops, |
457 | [LM_TYPE_JOURNAL] = &gfs2_journal_glops, |
458 | }; |
459 | |
460 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9