aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/gfs2/glock.c29
-rw-r--r--fs/gfs2/glock.h4
-rw-r--r--fs/gfs2/glops.c100
-rw-r--r--fs/gfs2/incore.h3
4 files changed, 59 insertions, 77 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 1345c3d44ede..5b772bb0210f 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -43,6 +43,8 @@ typedef void (*glock_examiner) (struct gfs2_glock * gl);
43static int gfs2_dump_lockstate(struct gfs2_sbd *sdp); 43static int gfs2_dump_lockstate(struct gfs2_sbd *sdp);
44static int dump_glock(struct gfs2_glock *gl); 44static int dump_glock(struct gfs2_glock *gl);
45static int dump_inode(struct gfs2_inode *ip); 45static int dump_inode(struct gfs2_inode *ip);
46static void gfs2_glock_xmote_th(struct gfs2_holder *gh);
47static void gfs2_glock_drop_th(struct gfs2_glock *gl);
46 48
47#define GFS2_GL_HASH_SHIFT 15 49#define GFS2_GL_HASH_SHIFT 15
48#define GFS2_GL_HASH_SIZE (1 << GFS2_GL_HASH_SHIFT) 50#define GFS2_GL_HASH_SIZE (1 << GFS2_GL_HASH_SHIFT)
@@ -524,7 +526,6 @@ static int rq_promote(struct gfs2_holder *gh)
524{ 526{
525 struct gfs2_glock *gl = gh->gh_gl; 527 struct gfs2_glock *gl = gh->gh_gl;
526 struct gfs2_sbd *sdp = gl->gl_sbd; 528 struct gfs2_sbd *sdp = gl->gl_sbd;
527 const struct gfs2_glock_operations *glops = gl->gl_ops;
528 529
529 if (!relaxed_state_ok(gl->gl_state, gh->gh_state, gh->gh_flags)) { 530 if (!relaxed_state_ok(gl->gl_state, gh->gh_state, gh->gh_flags)) {
530 if (list_empty(&gl->gl_holders)) { 531 if (list_empty(&gl->gl_holders)) {
@@ -539,7 +540,7 @@ static int rq_promote(struct gfs2_holder *gh)
539 gfs2_reclaim_glock(sdp); 540 gfs2_reclaim_glock(sdp);
540 } 541 }
541 542
542 glops->go_xmote_th(gl, gh->gh_state, gh->gh_flags); 543 gfs2_glock_xmote_th(gh);
543 spin_lock(&gl->gl_spin); 544 spin_lock(&gl->gl_spin);
544 } 545 }
545 return 1; 546 return 1;
@@ -577,7 +578,6 @@ static int rq_promote(struct gfs2_holder *gh)
577static int rq_demote(struct gfs2_holder *gh) 578static int rq_demote(struct gfs2_holder *gh)
578{ 579{
579 struct gfs2_glock *gl = gh->gh_gl; 580 struct gfs2_glock *gl = gh->gh_gl;
580 const struct gfs2_glock_operations *glops = gl->gl_ops;
581 581
582 if (!list_empty(&gl->gl_holders)) 582 if (!list_empty(&gl->gl_holders))
583 return 1; 583 return 1;
@@ -595,9 +595,9 @@ static int rq_demote(struct gfs2_holder *gh)
595 595
596 if (gh->gh_state == LM_ST_UNLOCKED || 596 if (gh->gh_state == LM_ST_UNLOCKED ||
597 gl->gl_state != LM_ST_EXCLUSIVE) 597 gl->gl_state != LM_ST_EXCLUSIVE)
598 glops->go_drop_th(gl); 598 gfs2_glock_drop_th(gl);
599 else 599 else
600 glops->go_xmote_th(gl, gh->gh_state, gh->gh_flags); 600 gfs2_glock_xmote_th(gh);
601 601
602 spin_lock(&gl->gl_spin); 602 spin_lock(&gl->gl_spin);
603 } 603 }
@@ -909,23 +909,26 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret)
909 * 909 *
910 */ 910 */
911 911
912void gfs2_glock_xmote_th(struct gfs2_glock *gl, unsigned int state, int flags) 912void gfs2_glock_xmote_th(struct gfs2_holder *gh)
913{ 913{
914 struct gfs2_glock *gl = gh->gh_gl;
914 struct gfs2_sbd *sdp = gl->gl_sbd; 915 struct gfs2_sbd *sdp = gl->gl_sbd;
916 int flags = gh->gh_flags;
917 unsigned state = gh->gh_state;
915 const struct gfs2_glock_operations *glops = gl->gl_ops; 918 const struct gfs2_glock_operations *glops = gl->gl_ops;
916 int lck_flags = flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB | 919 int lck_flags = flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB |
917 LM_FLAG_NOEXP | LM_FLAG_ANY | 920 LM_FLAG_NOEXP | LM_FLAG_ANY |
918 LM_FLAG_PRIORITY); 921 LM_FLAG_PRIORITY);
919 unsigned int lck_ret; 922 unsigned int lck_ret;
920 923
924 if (glops->go_xmote_th)
925 glops->go_xmote_th(gl);
926
921 gfs2_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags)); 927 gfs2_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags));
922 gfs2_assert_warn(sdp, queue_empty(gl, &gl->gl_holders)); 928 gfs2_assert_warn(sdp, queue_empty(gl, &gl->gl_holders));
923 gfs2_assert_warn(sdp, state != LM_ST_UNLOCKED); 929 gfs2_assert_warn(sdp, state != LM_ST_UNLOCKED);
924 gfs2_assert_warn(sdp, state != gl->gl_state); 930 gfs2_assert_warn(sdp, state != gl->gl_state);
925 931
926 if (gl->gl_state == LM_ST_EXCLUSIVE && glops->go_sync)
927 glops->go_sync(gl);
928
929 gfs2_glock_hold(gl); 932 gfs2_glock_hold(gl);
930 gl->gl_req_bh = xmote_bh; 933 gl->gl_req_bh = xmote_bh;
931 934
@@ -994,19 +997,19 @@ static void drop_bh(struct gfs2_glock *gl, unsigned int ret)
994 * 997 *
995 */ 998 */
996 999
997void gfs2_glock_drop_th(struct gfs2_glock *gl) 1000static void gfs2_glock_drop_th(struct gfs2_glock *gl)
998{ 1001{
999 struct gfs2_sbd *sdp = gl->gl_sbd; 1002 struct gfs2_sbd *sdp = gl->gl_sbd;
1000 const struct gfs2_glock_operations *glops = gl->gl_ops; 1003 const struct gfs2_glock_operations *glops = gl->gl_ops;
1001 unsigned int ret; 1004 unsigned int ret;
1002 1005
1006 if (glops->go_drop_th)
1007 glops->go_drop_th(gl);
1008
1003 gfs2_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags)); 1009 gfs2_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags));
1004 gfs2_assert_warn(sdp, queue_empty(gl, &gl->gl_holders)); 1010 gfs2_assert_warn(sdp, queue_empty(gl, &gl->gl_holders));
1005 gfs2_assert_warn(sdp, gl->gl_state != LM_ST_UNLOCKED); 1011 gfs2_assert_warn(sdp, gl->gl_state != LM_ST_UNLOCKED);
1006 1012
1007 if (gl->gl_state == LM_ST_EXCLUSIVE && glops->go_sync)
1008 glops->go_sync(gl);
1009
1010 gfs2_glock_hold(gl); 1013 gfs2_glock_hold(gl);
1011 gl->gl_req_bh = drop_bh; 1014 gl->gl_req_bh = drop_bh;
1012 1015
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h
index 1eaeacdd14a4..f50e40ceca43 100644
--- a/fs/gfs2/glock.h
+++ b/fs/gfs2/glock.h
@@ -82,10 +82,6 @@ void gfs2_holder_init(struct gfs2_glock *gl, unsigned int state, unsigned flags,
82void gfs2_holder_reinit(unsigned int state, unsigned flags, 82void gfs2_holder_reinit(unsigned int state, unsigned flags,
83 struct gfs2_holder *gh); 83 struct gfs2_holder *gh);
84void gfs2_holder_uninit(struct gfs2_holder *gh); 84void gfs2_holder_uninit(struct gfs2_holder *gh);
85
86void gfs2_glock_xmote_th(struct gfs2_glock *gl, unsigned int state, int flags);
87void gfs2_glock_drop_th(struct gfs2_glock *gl);
88
89int gfs2_glock_nq(struct gfs2_holder *gh); 85int gfs2_glock_nq(struct gfs2_holder *gh);
90int gfs2_glock_poll(struct gfs2_holder *gh); 86int gfs2_glock_poll(struct gfs2_holder *gh);
91int gfs2_glock_wait(struct gfs2_holder *gh); 87int gfs2_glock_wait(struct gfs2_holder *gh);
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
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 1acbcc2415ee..12c80fd28db5 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -101,11 +101,10 @@ struct gfs2_bufdata {
101}; 101};
102 102
103struct gfs2_glock_operations { 103struct gfs2_glock_operations {
104 void (*go_xmote_th) (struct gfs2_glock *gl, unsigned int state, int flags); 104 void (*go_xmote_th) (struct gfs2_glock *gl);
105 void (*go_xmote_bh) (struct gfs2_glock *gl); 105 void (*go_xmote_bh) (struct gfs2_glock *gl);
106 void (*go_drop_th) (struct gfs2_glock *gl); 106 void (*go_drop_th) (struct gfs2_glock *gl);
107 void (*go_drop_bh) (struct gfs2_glock *gl); 107 void (*go_drop_bh) (struct gfs2_glock *gl);
108 void (*go_sync) (struct gfs2_glock *gl);
109 void (*go_inval) (struct gfs2_glock *gl, int flags); 108 void (*go_inval) (struct gfs2_glock *gl, int flags);
110 int (*go_demote_ok) (struct gfs2_glock *gl); 109 int (*go_demote_ok) (struct gfs2_glock *gl);
111 int (*go_lock) (struct gfs2_holder *gh); 110 int (*go_lock) (struct gfs2_holder *gh);