aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/glops.c
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2006-01-16 11:50:04 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2006-01-16 11:50:04 -0500
commitb3b94faa5fe5968827ba0640ee9fba4b3e7f736e (patch)
tree70bd6068b050d2c46e338484f8b03fae4365c6c3 /fs/gfs2/glops.c
parentf7825dcf8c7301cfd3724eb40c5b443cc85ab7b8 (diff)
[GFS2] The core of GFS2
This patch contains all the core files for GFS2. Signed-off-by: David Teigland <teigland@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/glops.c')
-rw-r--r--fs/gfs2/glops.c487
1 files changed, 487 insertions, 0 deletions
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
new file mode 100644
index 000000000000..127008146a57
--- /dev/null
+++ b/fs/gfs2/glops.c
@@ -0,0 +1,487 @@
1/*
2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
3 * Copyright (C) 2004-2005 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 v.2.
8 */
9
10#include <linux/sched.h>
11#include <linux/slab.h>
12#include <linux/spinlock.h>
13#include <linux/completion.h>
14#include <linux/buffer_head.h>
15#include <asm/semaphore.h>
16
17#include "gfs2.h"
18#include "bmap.h"
19#include "glock.h"
20#include "glops.h"
21#include "inode.h"
22#include "log.h"
23#include "meta_io.h"
24#include "page.h"
25#include "recovery.h"
26#include "rgrp.h"
27
28/**
29 * meta_go_sync - sync out the metadata for this glock
30 * @gl: the glock
31 * @flags: DIO_*
32 *
33 * Called when demoting or unlocking an EX glock. We must flush
34 * to disk all dirty buffers/pages relating to this glock, and must not
35 * not return to caller to demote/unlock the glock until I/O is complete.
36 */
37
38static void meta_go_sync(struct gfs2_glock *gl, int flags)
39{
40 if (!(flags & DIO_METADATA))
41 return;
42
43 if (test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) {
44 gfs2_log_flush_glock(gl);
45 gfs2_meta_sync(gl, flags | DIO_START | DIO_WAIT);
46 if (flags & DIO_RELEASE)
47 gfs2_ail_empty_gl(gl);
48 }
49
50 clear_bit(GLF_SYNC, &gl->gl_flags);
51}
52
53/**
54 * meta_go_inval - invalidate the metadata for this glock
55 * @gl: the glock
56 * @flags:
57 *
58 */
59
60static void meta_go_inval(struct gfs2_glock *gl, int flags)
61{
62 if (!(flags & DIO_METADATA))
63 return;
64
65 gfs2_meta_inval(gl);
66 gl->gl_vn++;
67}
68
69/**
70 * meta_go_demote_ok - Check to see if it's ok to unlock a glock
71 * @gl: the glock
72 *
73 * Returns: 1 if we have no cached data; ok to demote meta glock
74 */
75
76static int meta_go_demote_ok(struct gfs2_glock *gl)
77{
78 return !gl->gl_aspace->i_mapping->nrpages;
79}
80
81/**
82 * inode_go_xmote_th - promote/demote a glock
83 * @gl: the glock
84 * @state: the requested state
85 * @flags:
86 *
87 */
88
89static void inode_go_xmote_th(struct gfs2_glock *gl, unsigned int state,
90 int flags)
91{
92 if (gl->gl_state != LM_ST_UNLOCKED)
93 gfs2_pte_inval(gl);
94 gfs2_glock_xmote_th(gl, state, flags);
95}
96
97/**
98 * inode_go_xmote_bh - After promoting/demoting a glock
99 * @gl: the glock
100 *
101 */
102
103static void inode_go_xmote_bh(struct gfs2_glock *gl)
104{
105 struct gfs2_holder *gh = gl->gl_req_gh;
106 struct buffer_head *bh;
107 int error;
108
109 if (gl->gl_state != LM_ST_UNLOCKED &&
110 (!gh || !(gh->gh_flags & GL_SKIP))) {
111 error = gfs2_meta_read(gl, gl->gl_name.ln_number, DIO_START,
112 &bh);
113 if (!error)
114 brelse(bh);
115 }
116}
117
118/**
119 * inode_go_drop_th - unlock a glock
120 * @gl: the glock
121 *
122 * Invoked from rq_demote().
123 * Another node needs the lock in EXCLUSIVE mode, or lock (unused for too long)
124 * is being purged from our node's glock cache; we're dropping lock.
125 */
126
127static void inode_go_drop_th(struct gfs2_glock *gl)
128{
129 gfs2_pte_inval(gl);
130 gfs2_glock_drop_th(gl);
131}
132
133/**
134 * inode_go_sync - Sync the dirty data and/or metadata for an inode glock
135 * @gl: the glock protecting the inode
136 * @flags:
137 *
138 */
139
140static void inode_go_sync(struct gfs2_glock *gl, int flags)
141{
142 int meta = (flags & DIO_METADATA);
143 int data = (flags & DIO_DATA);
144
145 if (test_bit(GLF_DIRTY, &gl->gl_flags)) {
146 if (meta && data) {
147 gfs2_page_sync(gl, flags | DIO_START);
148 gfs2_log_flush_glock(gl);
149 gfs2_meta_sync(gl, flags | DIO_START | DIO_WAIT);
150 gfs2_page_sync(gl, flags | DIO_WAIT);
151 clear_bit(GLF_DIRTY, &gl->gl_flags);
152 } else if (meta) {
153 gfs2_log_flush_glock(gl);
154 gfs2_meta_sync(gl, flags | DIO_START | DIO_WAIT);
155 } else if (data)
156 gfs2_page_sync(gl, flags | DIO_START | DIO_WAIT);
157 if (flags & DIO_RELEASE)
158 gfs2_ail_empty_gl(gl);
159 }
160
161 clear_bit(GLF_SYNC, &gl->gl_flags);
162}
163
164/**
165 * inode_go_inval - prepare a inode glock to be released
166 * @gl: the glock
167 * @flags:
168 *
169 */
170
171static void inode_go_inval(struct gfs2_glock *gl, int flags)
172{
173 int meta = (flags & DIO_METADATA);
174 int data = (flags & DIO_DATA);
175
176 if (meta) {
177 gfs2_meta_inval(gl);
178 gl->gl_vn++;
179 }
180 if (data)
181 gfs2_page_inval(gl);
182}
183
184/**
185 * inode_go_demote_ok - Check to see if it's ok to unlock an inode glock
186 * @gl: the glock
187 *
188 * Returns: 1 if it's ok
189 */
190
191static int inode_go_demote_ok(struct gfs2_glock *gl)
192{
193 struct gfs2_sbd *sdp = gl->gl_sbd;
194 int demote = 0;
195
196 if (!get_gl2ip(gl) && !gl->gl_aspace->i_mapping->nrpages)
197 demote = 1;
198 else if (!sdp->sd_args.ar_localcaching &&
199 time_after_eq(jiffies, gl->gl_stamp +
200 gfs2_tune_get(sdp, gt_demote_secs) * HZ))
201 demote = 1;
202
203 return demote;
204}
205
206/**
207 * inode_go_lock - operation done after an inode lock is locked by a process
208 * @gl: the glock
209 * @flags:
210 *
211 * Returns: errno
212 */
213
214static int inode_go_lock(struct gfs2_holder *gh)
215{
216 struct gfs2_glock *gl = gh->gh_gl;
217 struct gfs2_inode *ip = get_gl2ip(gl);
218 int error = 0;
219
220 if (!ip)
221 return 0;
222
223 if (ip->i_vn != gl->gl_vn) {
224 error = gfs2_inode_refresh(ip);
225 if (error)
226 return error;
227 gfs2_inode_attr_in(ip);
228 }
229
230 if ((ip->i_di.di_flags & GFS2_DIF_TRUNC_IN_PROG) &&
231 (gl->gl_state == LM_ST_EXCLUSIVE) &&
232 (gh->gh_flags & GL_LOCAL_EXCL))
233 error = gfs2_truncatei_resume(ip);
234
235 return error;
236}
237
238/**
239 * inode_go_unlock - operation done before an inode lock is unlocked by a
240 * process
241 * @gl: the glock
242 * @flags:
243 *
244 */
245
246static void inode_go_unlock(struct gfs2_holder *gh)
247{
248 struct gfs2_glock *gl = gh->gh_gl;
249 struct gfs2_inode *ip = get_gl2ip(gl);
250
251 if (ip && test_bit(GLF_DIRTY, &gl->gl_flags))
252 gfs2_inode_attr_in(ip);
253
254 if (ip)
255 gfs2_meta_cache_flush(ip);
256}
257
258/**
259 * inode_greedy -
260 * @gl: the glock
261 *
262 */
263
264static void inode_greedy(struct gfs2_glock *gl)
265{
266 struct gfs2_sbd *sdp = gl->gl_sbd;
267 struct gfs2_inode *ip = get_gl2ip(gl);
268 unsigned int quantum = gfs2_tune_get(sdp, gt_greedy_quantum);
269 unsigned int max = gfs2_tune_get(sdp, gt_greedy_max);
270 unsigned int new_time;
271
272 spin_lock(&ip->i_spin);
273
274 if (time_after(ip->i_last_pfault + quantum, jiffies)) {
275 new_time = ip->i_greedy + quantum;
276 if (new_time > max)
277 new_time = max;
278 } else {
279 new_time = ip->i_greedy - quantum;
280 if (!new_time || new_time > max)
281 new_time = 1;
282 }
283
284 ip->i_greedy = new_time;
285
286 spin_unlock(&ip->i_spin);
287
288 gfs2_inode_put(ip);
289}
290
291/**
292 * rgrp_go_demote_ok - Check to see if it's ok to unlock a RG's glock
293 * @gl: the glock
294 *
295 * Returns: 1 if it's ok
296 */
297
298static int rgrp_go_demote_ok(struct gfs2_glock *gl)
299{
300 return !gl->gl_aspace->i_mapping->nrpages;
301}
302
303/**
304 * rgrp_go_lock - operation done after an rgrp lock is locked by
305 * a first holder on this node.
306 * @gl: the glock
307 * @flags:
308 *
309 * Returns: errno
310 */
311
312static int rgrp_go_lock(struct gfs2_holder *gh)
313{
314 return gfs2_rgrp_bh_get(get_gl2rgd(gh->gh_gl));
315}
316
317/**
318 * rgrp_go_unlock - operation done before an rgrp lock is unlocked by
319 * a last holder on this node.
320 * @gl: the glock
321 * @flags:
322 *
323 */
324
325static void rgrp_go_unlock(struct gfs2_holder *gh)
326{
327 gfs2_rgrp_bh_put(get_gl2rgd(gh->gh_gl));
328}
329
330/**
331 * trans_go_xmote_th - promote/demote the transaction glock
332 * @gl: the glock
333 * @state: the requested state
334 * @flags:
335 *
336 */
337
338static void trans_go_xmote_th(struct gfs2_glock *gl, unsigned int state,
339 int flags)
340{
341 struct gfs2_sbd *sdp = gl->gl_sbd;
342
343 if (gl->gl_state != LM_ST_UNLOCKED &&
344 test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
345 gfs2_meta_syncfs(sdp);
346 gfs2_log_shutdown(sdp);
347 }
348
349 gfs2_glock_xmote_th(gl, state, flags);
350}
351
352/**
353 * trans_go_xmote_bh - After promoting/demoting the transaction glock
354 * @gl: the glock
355 *
356 */
357
358static void trans_go_xmote_bh(struct gfs2_glock *gl)
359{
360 struct gfs2_sbd *sdp = gl->gl_sbd;
361 struct gfs2_glock *j_gl = sdp->sd_jdesc->jd_inode->i_gl;
362 struct gfs2_log_header head;
363 int error;
364
365 if (gl->gl_state != LM_ST_UNLOCKED &&
366 test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
367 gfs2_meta_cache_flush(sdp->sd_jdesc->jd_inode);
368 j_gl->gl_ops->go_inval(j_gl, DIO_METADATA | DIO_DATA);
369
370 error = gfs2_find_jhead(sdp->sd_jdesc, &head);
371 if (error)
372 gfs2_consist(sdp);
373 if (!(head.lh_flags & GFS2_LOG_HEAD_UNMOUNT))
374 gfs2_consist(sdp);
375
376 /* Initialize some head of the log stuff */
377 if (!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) {
378 sdp->sd_log_sequence = head.lh_sequence + 1;
379 gfs2_log_pointers_init(sdp, head.lh_blkno);
380 }
381 }
382}
383
384/**
385 * trans_go_drop_th - unlock the transaction glock
386 * @gl: the glock
387 *
388 * We want to sync the device even with localcaching. Remember
389 * that localcaching journal replay only marks buffers dirty.
390 */
391
392static void trans_go_drop_th(struct gfs2_glock *gl)
393{
394 struct gfs2_sbd *sdp = gl->gl_sbd;
395
396 if (test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
397 gfs2_meta_syncfs(sdp);
398 gfs2_log_shutdown(sdp);
399 }
400
401 gfs2_glock_drop_th(gl);
402}
403
404/**
405 * quota_go_demote_ok - Check to see if it's ok to unlock a quota glock
406 * @gl: the glock
407 *
408 * Returns: 1 if it's ok
409 */
410
411static int quota_go_demote_ok(struct gfs2_glock *gl)
412{
413 return !atomic_read(&gl->gl_lvb_count);
414}
415
416struct gfs2_glock_operations gfs2_meta_glops = {
417 .go_xmote_th = gfs2_glock_xmote_th,
418 .go_drop_th = gfs2_glock_drop_th,
419 .go_sync = meta_go_sync,
420 .go_inval = meta_go_inval,
421 .go_demote_ok = meta_go_demote_ok,
422 .go_type = LM_TYPE_META
423};
424
425struct gfs2_glock_operations gfs2_inode_glops = {
426 .go_xmote_th = inode_go_xmote_th,
427 .go_xmote_bh = inode_go_xmote_bh,
428 .go_drop_th = inode_go_drop_th,
429 .go_sync = inode_go_sync,
430 .go_inval = inode_go_inval,
431 .go_demote_ok = inode_go_demote_ok,
432 .go_lock = inode_go_lock,
433 .go_unlock = inode_go_unlock,
434 .go_greedy = inode_greedy,
435 .go_type = LM_TYPE_INODE
436};
437
438struct gfs2_glock_operations gfs2_rgrp_glops = {
439 .go_xmote_th = gfs2_glock_xmote_th,
440 .go_drop_th = gfs2_glock_drop_th,
441 .go_sync = meta_go_sync,
442 .go_inval = meta_go_inval,
443 .go_demote_ok = rgrp_go_demote_ok,
444 .go_lock = rgrp_go_lock,
445 .go_unlock = rgrp_go_unlock,
446 .go_type = LM_TYPE_RGRP
447};
448
449struct gfs2_glock_operations gfs2_trans_glops = {
450 .go_xmote_th = trans_go_xmote_th,
451 .go_xmote_bh = trans_go_xmote_bh,
452 .go_drop_th = trans_go_drop_th,
453 .go_type = LM_TYPE_NONDISK
454};
455
456struct gfs2_glock_operations gfs2_iopen_glops = {
457 .go_xmote_th = gfs2_glock_xmote_th,
458 .go_drop_th = gfs2_glock_drop_th,
459 .go_callback = gfs2_iopen_go_callback,
460 .go_type = LM_TYPE_IOPEN
461};
462
463struct gfs2_glock_operations gfs2_flock_glops = {
464 .go_xmote_th = gfs2_glock_xmote_th,
465 .go_drop_th = gfs2_glock_drop_th,
466 .go_type = LM_TYPE_FLOCK
467};
468
469struct gfs2_glock_operations gfs2_nondisk_glops = {
470 .go_xmote_th = gfs2_glock_xmote_th,
471 .go_drop_th = gfs2_glock_drop_th,
472 .go_type = LM_TYPE_NONDISK
473};
474
475struct gfs2_glock_operations gfs2_quota_glops = {
476 .go_xmote_th = gfs2_glock_xmote_th,
477 .go_drop_th = gfs2_glock_drop_th,
478 .go_demote_ok = quota_go_demote_ok,
479 .go_type = LM_TYPE_QUOTA
480};
481
482struct gfs2_glock_operations gfs2_journal_glops = {
483 .go_xmote_th = gfs2_glock_xmote_th,
484 .go_drop_th = gfs2_glock_drop_th,
485 .go_type = LM_TYPE_JOURNAL
486};
487