diff options
author | David Teigland <teigland@redhat.com> | 2006-04-20 17:03:48 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2006-04-20 17:03:48 -0400 |
commit | c63e31c2cc1ec67372920b5e1aff8204d04dd172 (patch) | |
tree | 950b2537b5a7e83e35a14a973da7bac84e844a52 /fs | |
parent | 190562bd84a484bf6590425aa2bb4d6d611c112b (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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/gfs2/ops_fstype.c | 5 | ||||
-rw-r--r-- | fs/gfs2/recovery.c | 13 | ||||
-rw-r--r-- | fs/gfs2/recovery.h | 2 |
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 | ||
429 | int gfs2_recover_journal(struct gfs2_jdesc *jd, int wait) | 428 | int 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 | ||
26 | int gfs2_find_jhead(struct gfs2_jdesc *jd, | 26 | int gfs2_find_jhead(struct gfs2_jdesc *jd, |
27 | struct gfs2_log_header *head); | 27 | struct gfs2_log_header *head); |
28 | int gfs2_recover_journal(struct gfs2_jdesc *gfs2_jd, int wait); | 28 | int gfs2_recover_journal(struct gfs2_jdesc *gfs2_jd); |
29 | void gfs2_check_journals(struct gfs2_sbd *sdp); | 29 | void gfs2_check_journals(struct gfs2_sbd *sdp); |
30 | 30 | ||
31 | #endif /* __RECOVERY_DOT_H__ */ | 31 | #endif /* __RECOVERY_DOT_H__ */ |