Skip to content

Commit 1c634f9

Browse files
committed
gfs2: Do proper error checking for go_sync family of glops functions
Before this patch, function do_xmote would try to sync out the glock dirty data by calling the appropriate glops function XXX_go_sync() but it did not check for a good return code. If the sync was not possible due to an io error or whatever, do_xmote would continue on and call go_inval and release the glock to other cluster nodes. When those nodes go to replay the journal, they may already be holding glocks for the journal records that should have been synced, but were not due to the ignored error. This patch introduces proper error code checking to the go_sync family of glops functions. Signed-off-by: Bob Peterson <[email protected]> Reviewed-by: Andreas Gruenbacher <[email protected]>
1 parent df5db5f commit 1c634f9

File tree

3 files changed

+34
-14
lines changed

3 files changed

+34
-14
lines changed

fs/gfs2/glock.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -602,8 +602,20 @@ __acquires(&gl->gl_lockref.lock)
602602
(lck_flags & (LM_FLAG_TRY|LM_FLAG_TRY_1CB)))
603603
clear_bit(GLF_BLOCKING, &gl->gl_flags);
604604
spin_unlock(&gl->gl_lockref.lock);
605-
if (glops->go_sync)
606-
glops->go_sync(gl);
605+
if (glops->go_sync) {
606+
ret = glops->go_sync(gl);
607+
/* If we had a problem syncing (due to io errors or whatever,
608+
* we should not invalidate the metadata or tell dlm to
609+
* release the glock to other nodes.
610+
*/
611+
if (ret) {
612+
if (cmpxchg(&sdp->sd_log_error, 0, ret)) {
613+
fs_err(sdp, "Error %d syncing glock \n", ret);
614+
gfs2_dump_glock(NULL, gl, true);
615+
}
616+
return;
617+
}
618+
}
607619
if (test_bit(GLF_INVALIDATE_IN_PROGRESS, &gl->gl_flags)) {
608620
/*
609621
* The call to go_sync should have cleared out the ail list.

fs/gfs2/glops.c

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,11 @@ static void __gfs2_ail_flush(struct gfs2_glock *gl, bool fsync,
8282
}
8383

8484

85-
static void gfs2_ail_empty_gl(struct gfs2_glock *gl)
85+
static int gfs2_ail_empty_gl(struct gfs2_glock *gl)
8686
{
8787
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
8888
struct gfs2_trans tr;
89+
int ret;
8990

9091
memset(&tr, 0, sizeof(tr));
9192
INIT_LIST_HEAD(&tr.tr_buf);
@@ -116,16 +117,17 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl)
116117
goto flush;
117118
if (log_in_flight)
118119
log_flush_wait(sdp);
119-
return;
120+
return 0;
120121
}
121122

122123
/* A shortened, inline version of gfs2_trans_begin()
123124
* tr->alloced is not set since the transaction structure is
124125
* on the stack */
125126
tr.tr_reserved = 1 + gfs2_struct2blk(sdp, tr.tr_revokes);
126127
tr.tr_ip = _RET_IP_;
127-
if (gfs2_log_reserve(sdp, tr.tr_reserved) < 0)
128-
return;
128+
ret = gfs2_log_reserve(sdp, tr.tr_reserved);
129+
if (ret < 0)
130+
return ret;
129131
WARN_ON_ONCE(current->journal_info);
130132
current->journal_info = &tr;
131133

@@ -135,6 +137,7 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl)
135137
flush:
136138
gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL |
137139
GFS2_LFC_AIL_EMPTY_GL);
140+
return 0;
138141
}
139142

140143
void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync)
@@ -168,29 +171,32 @@ void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync)
168171
* return to caller to demote/unlock the glock until I/O is complete.
169172
*/
170173

171-
static void rgrp_go_sync(struct gfs2_glock *gl)
174+
static int rgrp_go_sync(struct gfs2_glock *gl)
172175
{
173176
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
174177
struct address_space *mapping = &sdp->sd_aspace;
175178
struct gfs2_rgrpd *rgd = gfs2_glock2rgrp(gl);
176179
int error;
177180

178181
if (!test_and_clear_bit(GLF_DIRTY, &gl->gl_flags))
179-
return;
182+
return 0;
180183
GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_EXCLUSIVE);
181184

182185
gfs2_log_flush(sdp, gl, GFS2_LOG_HEAD_FLUSH_NORMAL |
183186
GFS2_LFC_RGRP_GO_SYNC);
184187
filemap_fdatawrite_range(mapping, gl->gl_vm.start, gl->gl_vm.end);
185188
error = filemap_fdatawait_range(mapping, gl->gl_vm.start, gl->gl_vm.end);
189+
WARN_ON_ONCE(error);
186190
mapping_set_error(mapping, error);
187-
gfs2_ail_empty_gl(gl);
191+
if (!error)
192+
error = gfs2_ail_empty_gl(gl);
188193

189194
spin_lock(&gl->gl_lockref.lock);
190195
rgd = gl->gl_object;
191196
if (rgd)
192197
gfs2_free_clones(rgd);
193198
spin_unlock(&gl->gl_lockref.lock);
199+
return error;
194200
}
195201

196202
/**
@@ -257,12 +263,12 @@ static void gfs2_clear_glop_pending(struct gfs2_inode *ip)
257263
*
258264
*/
259265

260-
static void inode_go_sync(struct gfs2_glock *gl)
266+
static int inode_go_sync(struct gfs2_glock *gl)
261267
{
262268
struct gfs2_inode *ip = gfs2_glock2inode(gl);
263269
int isreg = ip && S_ISREG(ip->i_inode.i_mode);
264270
struct address_space *metamapping = gfs2_glock2aspace(gl);
265-
int error;
271+
int error = 0;
266272

267273
if (isreg) {
268274
if (test_and_clear_bit(GIF_SW_PAGED, &ip->i_flags))
@@ -295,6 +301,7 @@ static void inode_go_sync(struct gfs2_glock *gl)
295301

296302
out:
297303
gfs2_clear_glop_pending(ip);
304+
return error;
298305
}
299306

300307
/**
@@ -515,7 +522,7 @@ static void inode_go_dump(struct seq_file *seq, struct gfs2_glock *gl,
515522
*
516523
*/
517524

518-
static void freeze_go_sync(struct gfs2_glock *gl)
525+
static int freeze_go_sync(struct gfs2_glock *gl)
519526
{
520527
int error = 0;
521528
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
@@ -529,14 +536,15 @@ static void freeze_go_sync(struct gfs2_glock *gl)
529536
error);
530537
if (gfs2_withdrawn(sdp)) {
531538
atomic_set(&sdp->sd_freeze_state, SFS_UNFROZEN);
532-
return;
539+
return 0;
533540
}
534541
gfs2_assert_withdraw(sdp, 0);
535542
}
536543
queue_work(gfs2_freeze_wq, &sdp->sd_freeze_work);
537544
gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_FREEZE |
538545
GFS2_LFC_FREEZE_GO_SYNC);
539546
}
547+
return 0;
540548
}
541549

542550
/**

fs/gfs2/incore.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ struct lm_lockname {
234234

235235

236236
struct gfs2_glock_operations {
237-
void (*go_sync) (struct gfs2_glock *gl);
237+
int (*go_sync) (struct gfs2_glock *gl);
238238
int (*go_xmote_bh) (struct gfs2_glock *gl, struct gfs2_holder *gh);
239239
void (*go_inval) (struct gfs2_glock *gl, int flags);
240240
int (*go_demote_ok) (const struct gfs2_glock *gl);

0 commit comments

Comments
 (0)