diff options
Diffstat (limited to 'fs/gfs2/glops.c')
-rw-r--r-- | fs/gfs2/glops.c | 100 |
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 | ||
118 | static void meta_go_sync(struct gfs2_glock *gl) | 118 | static 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 | |||
152 | static 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 | ||
152 | static void inode_go_xmote_th(struct gfs2_glock *gl, unsigned int state, | 185 | static 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) | |||
189 | static void inode_go_drop_th(struct gfs2_glock *gl) | 222 | static 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 | |||
201 | static 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 | ||
368 | static void trans_go_xmote_th(struct gfs2_glock *gl, unsigned int state, | 371 | static 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 | ||
447 | const struct gfs2_glock_operations gfs2_meta_glops = { | 445 | const 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 | ||
465 | const struct gfs2_glock_operations gfs2_rgrp_glops = { | 462 | const 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 | ||
483 | const struct gfs2_glock_operations gfs2_iopen_glops = { | 477 | const 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 | ||
489 | const struct gfs2_glock_operations gfs2_flock_glops = { | 481 | const 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 | ||
495 | const struct gfs2_glock_operations gfs2_nondisk_glops = { | 485 | const 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 | ||
501 | const struct gfs2_glock_operations gfs2_quota_glops = { | 489 | const 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 | ||
508 | const struct gfs2_glock_operations gfs2_journal_glops = { | 494 | const 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 | ||