aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/glops.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/glops.c')
-rw-r--r--fs/gfs2/glops.c100
1 files changed, 42 insertions, 58 deletions
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index dda68586f757..c4b0391b7aa2 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -117,12 +117,14 @@ static void gfs2_pte_inval(struct gfs2_glock *gl)
117 117
118static void meta_go_sync(struct gfs2_glock *gl) 118static void meta_go_sync(struct gfs2_glock *gl)
119{ 119{
120 if (gl->gl_state != LM_ST_EXCLUSIVE)
121 return;
122
120 if (test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) { 123 if (test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) {
121 gfs2_log_flush(gl->gl_sbd, gl); 124 gfs2_log_flush(gl->gl_sbd, gl);
122 gfs2_meta_sync(gl); 125 gfs2_meta_sync(gl);
123 gfs2_ail_empty_gl(gl); 126 gfs2_ail_empty_gl(gl);
124 } 127 }
125
126} 128}
127 129
128/** 130/**
@@ -142,6 +144,37 @@ static void meta_go_inval(struct gfs2_glock *gl, int flags)
142} 144}
143 145
144/** 146/**
147 * inode_go_sync - Sync the dirty data and/or metadata for an inode glock
148 * @gl: the glock protecting the inode
149 *
150 */
151
152static void inode_go_sync(struct gfs2_glock *gl)
153{
154 struct gfs2_inode *ip = gl->gl_object;
155
156 if (ip && !S_ISREG(ip->i_inode.i_mode))
157 ip = NULL;
158
159 if (test_bit(GLF_DIRTY, &gl->gl_flags)) {
160 gfs2_log_flush(gl->gl_sbd, gl);
161 if (ip)
162 filemap_fdatawrite(ip->i_inode.i_mapping);
163 gfs2_meta_sync(gl);
164 if (ip) {
165 struct address_space *mapping = ip->i_inode.i_mapping;
166 int error = filemap_fdatawait(mapping);
167 if (error == -ENOSPC)
168 set_bit(AS_ENOSPC, &mapping->flags);
169 else if (error)
170 set_bit(AS_EIO, &mapping->flags);
171 }
172 clear_bit(GLF_DIRTY, &gl->gl_flags);
173 gfs2_ail_empty_gl(gl);
174 }
175}
176
177/**
145 * inode_go_xmote_th - promote/demote a glock 178 * inode_go_xmote_th - promote/demote a glock
146 * @gl: the glock 179 * @gl: the glock
147 * @state: the requested state 180 * @state: the requested state
@@ -149,12 +182,12 @@ static void meta_go_inval(struct gfs2_glock *gl, int flags)
149 * 182 *
150 */ 183 */
151 184
152static void inode_go_xmote_th(struct gfs2_glock *gl, unsigned int state, 185static void inode_go_xmote_th(struct gfs2_glock *gl)
153 int flags)
154{ 186{
155 if (gl->gl_state != LM_ST_UNLOCKED) 187 if (gl->gl_state != LM_ST_UNLOCKED)
156 gfs2_pte_inval(gl); 188 gfs2_pte_inval(gl);
157 gfs2_glock_xmote_th(gl, state, flags); 189 if (gl->gl_state == LM_ST_EXCLUSIVE)
190 inode_go_sync(gl);
158} 191}
159 192
160/** 193/**
@@ -189,38 +222,8 @@ static void inode_go_xmote_bh(struct gfs2_glock *gl)
189static void inode_go_drop_th(struct gfs2_glock *gl) 222static void inode_go_drop_th(struct gfs2_glock *gl)
190{ 223{
191 gfs2_pte_inval(gl); 224 gfs2_pte_inval(gl);
192 gfs2_glock_drop_th(gl); 225 if (gl->gl_state == LM_ST_EXCLUSIVE)
193} 226 inode_go_sync(gl);
194
195/**
196 * inode_go_sync - Sync the dirty data and/or metadata for an inode glock
197 * @gl: the glock protecting the inode
198 *
199 */
200
201static void inode_go_sync(struct gfs2_glock *gl)
202{
203 struct gfs2_inode *ip = gl->gl_object;
204
205 if (ip && !S_ISREG(ip->i_inode.i_mode))
206 ip = NULL;
207
208 if (test_bit(GLF_DIRTY, &gl->gl_flags)) {
209 gfs2_log_flush(gl->gl_sbd, gl);
210 if (ip)
211 filemap_fdatawrite(ip->i_inode.i_mapping);
212 gfs2_meta_sync(gl);
213 if (ip) {
214 struct address_space *mapping = ip->i_inode.i_mapping;
215 int error = filemap_fdatawait(mapping);
216 if (error == -ENOSPC)
217 set_bit(AS_ENOSPC, &mapping->flags);
218 else if (error)
219 set_bit(AS_EIO, &mapping->flags);
220 }
221 clear_bit(GLF_DIRTY, &gl->gl_flags);
222 gfs2_ail_empty_gl(gl);
223 }
224} 227}
225 228
226/** 229/**
@@ -365,8 +368,7 @@ static void rgrp_go_unlock(struct gfs2_holder *gh)
365 * 368 *
366 */ 369 */
367 370
368static void trans_go_xmote_th(struct gfs2_glock *gl, unsigned int state, 371static void trans_go_xmote_th(struct gfs2_glock *gl)
369 int flags)
370{ 372{
371 struct gfs2_sbd *sdp = gl->gl_sbd; 373 struct gfs2_sbd *sdp = gl->gl_sbd;
372 374
@@ -375,8 +377,6 @@ static void trans_go_xmote_th(struct gfs2_glock *gl, unsigned int state,
375 gfs2_meta_syncfs(sdp); 377 gfs2_meta_syncfs(sdp);
376 gfs2_log_shutdown(sdp); 378 gfs2_log_shutdown(sdp);
377 } 379 }
378
379 gfs2_glock_xmote_th(gl, state, flags);
380} 380}
381 381
382/** 382/**
@@ -428,8 +428,6 @@ static void trans_go_drop_th(struct gfs2_glock *gl)
428 gfs2_meta_syncfs(sdp); 428 gfs2_meta_syncfs(sdp);
429 gfs2_log_shutdown(sdp); 429 gfs2_log_shutdown(sdp);
430 } 430 }
431
432 gfs2_glock_drop_th(gl);
433} 431}
434 432
435/** 433/**
@@ -445,8 +443,8 @@ static int quota_go_demote_ok(struct gfs2_glock *gl)
445} 443}
446 444
447const struct gfs2_glock_operations gfs2_meta_glops = { 445const struct gfs2_glock_operations gfs2_meta_glops = {
448 .go_xmote_th = gfs2_glock_xmote_th, 446 .go_xmote_th = meta_go_sync,
449 .go_drop_th = gfs2_glock_drop_th, 447 .go_drop_th = meta_go_sync,
450 .go_type = LM_TYPE_META, 448 .go_type = LM_TYPE_META,
451}; 449};
452 450
@@ -454,7 +452,6 @@ const struct gfs2_glock_operations gfs2_inode_glops = {
454 .go_xmote_th = inode_go_xmote_th, 452 .go_xmote_th = inode_go_xmote_th,
455 .go_xmote_bh = inode_go_xmote_bh, 453 .go_xmote_bh = inode_go_xmote_bh,
456 .go_drop_th = inode_go_drop_th, 454 .go_drop_th = inode_go_drop_th,
457 .go_sync = inode_go_sync,
458 .go_inval = inode_go_inval, 455 .go_inval = inode_go_inval,
459 .go_demote_ok = inode_go_demote_ok, 456 .go_demote_ok = inode_go_demote_ok,
460 .go_lock = inode_go_lock, 457 .go_lock = inode_go_lock,
@@ -463,9 +460,6 @@ const struct gfs2_glock_operations gfs2_inode_glops = {
463}; 460};
464 461
465const struct gfs2_glock_operations gfs2_rgrp_glops = { 462const struct gfs2_glock_operations gfs2_rgrp_glops = {
466 .go_xmote_th = gfs2_glock_xmote_th,
467 .go_drop_th = gfs2_glock_drop_th,
468 .go_sync = meta_go_sync,
469 .go_inval = meta_go_inval, 463 .go_inval = meta_go_inval,
470 .go_demote_ok = rgrp_go_demote_ok, 464 .go_demote_ok = rgrp_go_demote_ok,
471 .go_lock = rgrp_go_lock, 465 .go_lock = rgrp_go_lock,
@@ -481,33 +475,23 @@ const struct gfs2_glock_operations gfs2_trans_glops = {
481}; 475};
482 476
483const struct gfs2_glock_operations gfs2_iopen_glops = { 477const struct gfs2_glock_operations gfs2_iopen_glops = {
484 .go_xmote_th = gfs2_glock_xmote_th,
485 .go_drop_th = gfs2_glock_drop_th,
486 .go_type = LM_TYPE_IOPEN, 478 .go_type = LM_TYPE_IOPEN,
487}; 479};
488 480
489const struct gfs2_glock_operations gfs2_flock_glops = { 481const struct gfs2_glock_operations gfs2_flock_glops = {
490 .go_xmote_th = gfs2_glock_xmote_th,
491 .go_drop_th = gfs2_glock_drop_th,
492 .go_type = LM_TYPE_FLOCK, 482 .go_type = LM_TYPE_FLOCK,
493}; 483};
494 484
495const struct gfs2_glock_operations gfs2_nondisk_glops = { 485const struct gfs2_glock_operations gfs2_nondisk_glops = {
496 .go_xmote_th = gfs2_glock_xmote_th,
497 .go_drop_th = gfs2_glock_drop_th,
498 .go_type = LM_TYPE_NONDISK, 486 .go_type = LM_TYPE_NONDISK,
499}; 487};
500 488
501const struct gfs2_glock_operations gfs2_quota_glops = { 489const struct gfs2_glock_operations gfs2_quota_glops = {
502 .go_xmote_th = gfs2_glock_xmote_th,
503 .go_drop_th = gfs2_glock_drop_th,
504 .go_demote_ok = quota_go_demote_ok, 490 .go_demote_ok = quota_go_demote_ok,
505 .go_type = LM_TYPE_QUOTA, 491 .go_type = LM_TYPE_QUOTA,
506}; 492};
507 493
508const struct gfs2_glock_operations gfs2_journal_glops = { 494const struct gfs2_glock_operations gfs2_journal_glops = {
509 .go_xmote_th = gfs2_glock_xmote_th,
510 .go_drop_th = gfs2_glock_drop_th,
511 .go_type = LM_TYPE_JOURNAL, 495 .go_type = LM_TYPE_JOURNAL,
512}; 496};
513 497