aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2006-04-20 17:03:48 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2006-04-20 17:03:48 -0400
commitc63e31c2cc1ec67372920b5e1aff8204d04dd172 (patch)
tree950b2537b5a7e83e35a14a973da7bac84e844a52
parent190562bd84a484bf6590425aa2bb4d6d611c112b (diff)
[GFS2] journal recovery patch
This is one of the changes related to journal recovery I mentioned a couple weeks ago. We can get into a situation where there are only readonly nodes currently mounting the fs, but there are journals that need to be recovered. Since the readonly nodes can't recover journals, the next rw mounter needs to go through and check all journals and recover any that are dirty (i.e. what the first node to mount the fs does). This rw mounter needs to skip the journals held by the existing readonly nodes. Skipping those journals amounts to using the TRY flag on the journal locks so acquiring the lock of a journal held by a readonly node will fail instead of blocking indefinately. Signed-off-by: David Teigland <teigland@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
-rw-r--r--fs/gfs2/ops_fstype.c5
-rw-r--r--fs/gfs2/recovery.c13
-rw-r--r--fs/gfs2/recovery.h2
3 files changed, 8 insertions, 12 deletions
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 4538a1e621e8..70745f3561a6 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -444,8 +444,7 @@ static int init_journal(struct gfs2_sbd *sdp, int undo)
444 if (sdp->sd_lockstruct.ls_first) { 444 if (sdp->sd_lockstruct.ls_first) {
445 unsigned int x; 445 unsigned int x;
446 for (x = 0; x < sdp->sd_journals; x++) { 446 for (x = 0; x < sdp->sd_journals; x++) {
447 error = gfs2_recover_journal(gfs2_jdesc_find(sdp, x), 447 error = gfs2_recover_journal(gfs2_jdesc_find(sdp, x));
448 WAIT);
449 if (error) { 448 if (error) {
450 fs_err(sdp, "error recovering journal %u: %d\n", 449 fs_err(sdp, "error recovering journal %u: %d\n",
451 x, error); 450 x, error);
@@ -455,7 +454,7 @@ static int init_journal(struct gfs2_sbd *sdp, int undo)
455 454
456 gfs2_lm_others_may_mount(sdp); 455 gfs2_lm_others_may_mount(sdp);
457 } else if (!sdp->sd_args.ar_spectator) { 456 } else if (!sdp->sd_args.ar_spectator) {
458 error = gfs2_recover_journal(sdp->sd_jdesc, WAIT); 457 error = gfs2_recover_journal(sdp->sd_jdesc);
459 if (error) { 458 if (error) {
460 fs_err(sdp, "error recovering my journal: %d\n", error); 459 fs_err(sdp, "error recovering my journal: %d\n", error);
461 goto fail_jinode_gh; 460 goto fail_jinode_gh;
diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c
index 68c85610fb5b..e91c2bda6c32 100644
--- a/fs/gfs2/recovery.c
+++ b/fs/gfs2/recovery.c
@@ -418,7 +418,6 @@ static int clean_journal(struct gfs2_jdesc *jd, struct gfs2_log_header *head)
418/** 418/**
419 * gfs2_recover_journal - recovery a given journal 419 * gfs2_recover_journal - recovery a given journal
420 * @jd: the struct gfs2_jdesc describing the journal 420 * @jd: the struct gfs2_jdesc describing the journal
421 * @wait: Don't return until the journal is clean (or an error is encountered)
422 * 421 *
423 * Acquire the journal's lock, check to see if the journal is clean, and 422 * Acquire the journal's lock, check to see if the journal is clean, and
424 * do recovery if necessary. 423 * do recovery if necessary.
@@ -426,7 +425,7 @@ static int clean_journal(struct gfs2_jdesc *jd, struct gfs2_log_header *head)
426 * Returns: errno 425 * Returns: errno
427 */ 426 */
428 427
429int gfs2_recover_journal(struct gfs2_jdesc *jd, int wait) 428int gfs2_recover_journal(struct gfs2_jdesc *jd)
430{ 429{
431 struct gfs2_inode *ip = jd->jd_inode->u.generic_ip; 430 struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
432 struct gfs2_sbd *sdp = ip->i_sbd; 431 struct gfs2_sbd *sdp = ip->i_sbd;
@@ -441,12 +440,10 @@ int gfs2_recover_journal(struct gfs2_jdesc *jd, int wait)
441 440
442 /* Aquire the journal lock so we can do recovery */ 441 /* Aquire the journal lock so we can do recovery */
443 442
444 error = gfs2_glock_nq_num(sdp, 443 error = gfs2_glock_nq_num(sdp, jd->jd_jid, &gfs2_journal_glops,
445 jd->jd_jid, &gfs2_journal_glops,
446 LM_ST_EXCLUSIVE, 444 LM_ST_EXCLUSIVE,
447 LM_FLAG_NOEXP | 445 LM_FLAG_NOEXP | LM_FLAG_TRY | GL_NOCACHE,
448 ((wait) ? 0 : LM_FLAG_TRY) | 446 &j_gh);
449 GL_NOCACHE, &j_gh);
450 switch (error) { 447 switch (error) {
451 case 0: 448 case 0:
452 break; 449 break;
@@ -574,7 +571,7 @@ void gfs2_check_journals(struct gfs2_sbd *sdp)
574 break; 571 break;
575 572
576 if (jd != sdp->sd_jdesc) 573 if (jd != sdp->sd_jdesc)
577 gfs2_recover_journal(jd, NO_WAIT); 574 gfs2_recover_journal(jd);
578 } 575 }
579} 576}
580 577
diff --git a/fs/gfs2/recovery.h b/fs/gfs2/recovery.h
index 50d7eb57881c..248481189300 100644
--- a/fs/gfs2/recovery.h
+++ b/fs/gfs2/recovery.h
@@ -25,7 +25,7 @@ void gfs2_revoke_clean(struct gfs2_sbd *sdp);
25 25
26int gfs2_find_jhead(struct gfs2_jdesc *jd, 26int gfs2_find_jhead(struct gfs2_jdesc *jd,
27 struct gfs2_log_header *head); 27 struct gfs2_log_header *head);
28int gfs2_recover_journal(struct gfs2_jdesc *gfs2_jd, int wait); 28int gfs2_recover_journal(struct gfs2_jdesc *gfs2_jd);
29void gfs2_check_journals(struct gfs2_sbd *sdp); 29void gfs2_check_journals(struct gfs2_sbd *sdp);
30 30
31#endif /* __RECOVERY_DOT_H__ */ 31#endif /* __RECOVERY_DOT_H__ */