diff options
author | Abhi Das <adas@redhat.com> | 2018-11-09 10:54:18 -0500 |
---|---|---|
committer | Andreas Gruenbacher <agruenba@redhat.com> | 2018-12-11 11:50:36 -0500 |
commit | 40e0e61e366bed56b71edb3b970245165090ec9a (patch) | |
tree | be18946d9501c6f3e12deab6430d982442ba1d00 /fs/gfs2 | |
parent | 5b84609532d6e48a769a735d214e2cd705ed395e (diff) |
gfs2: add a helper function to get_log_header that can be used elsewhere
Move and re-order the error checks and hash/crc computations into another
function __get_log_header() so it can be used in scenarios where buffer_heads
are not being used for the log header.
Signed-off-by: Abhi Das <adas@redhat.com>
Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/recovery.c | 53 | ||||
-rw-r--r-- | fs/gfs2/recovery.h | 3 |
2 files changed, 35 insertions, 21 deletions
diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c index b0717a074543..2dac43065382 100644 --- a/fs/gfs2/recovery.c +++ b/fs/gfs2/recovery.c | |||
@@ -120,6 +120,35 @@ void gfs2_revoke_clean(struct gfs2_jdesc *jd) | |||
120 | } | 120 | } |
121 | } | 121 | } |
122 | 122 | ||
123 | int __get_log_header(struct gfs2_sbd *sdp, const struct gfs2_log_header *lh, | ||
124 | unsigned int blkno, struct gfs2_log_header_host *head) | ||
125 | { | ||
126 | u32 hash, crc; | ||
127 | |||
128 | if (lh->lh_header.mh_magic != cpu_to_be32(GFS2_MAGIC) || | ||
129 | lh->lh_header.mh_type != cpu_to_be32(GFS2_METATYPE_LH) || | ||
130 | (blkno && be32_to_cpu(lh->lh_blkno) != blkno)) | ||
131 | return 1; | ||
132 | |||
133 | hash = crc32(~0, lh, LH_V1_SIZE - 4); | ||
134 | hash = ~crc32_le_shift(hash, 4); /* assume lh_hash is zero */ | ||
135 | |||
136 | if (be32_to_cpu(lh->lh_hash) != hash) | ||
137 | return 1; | ||
138 | |||
139 | crc = crc32c(~0, (void *)lh + LH_V1_SIZE + 4, | ||
140 | sdp->sd_sb.sb_bsize - LH_V1_SIZE - 4); | ||
141 | |||
142 | if ((lh->lh_crc != 0 && be32_to_cpu(lh->lh_crc) != crc)) | ||
143 | return 1; | ||
144 | |||
145 | head->lh_sequence = be64_to_cpu(lh->lh_sequence); | ||
146 | head->lh_flags = be32_to_cpu(lh->lh_flags); | ||
147 | head->lh_tail = be32_to_cpu(lh->lh_tail); | ||
148 | head->lh_blkno = be32_to_cpu(lh->lh_blkno); | ||
149 | |||
150 | return 0; | ||
151 | } | ||
123 | /** | 152 | /** |
124 | * get_log_header - read the log header for a given segment | 153 | * get_log_header - read the log header for a given segment |
125 | * @jd: the journal | 154 | * @jd: the journal |
@@ -137,36 +166,18 @@ void gfs2_revoke_clean(struct gfs2_jdesc *jd) | |||
137 | static int get_log_header(struct gfs2_jdesc *jd, unsigned int blk, | 166 | static int get_log_header(struct gfs2_jdesc *jd, unsigned int blk, |
138 | struct gfs2_log_header_host *head) | 167 | struct gfs2_log_header_host *head) |
139 | { | 168 | { |
140 | struct gfs2_log_header *lh; | 169 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); |
141 | struct buffer_head *bh; | 170 | struct buffer_head *bh; |
142 | u32 hash, crc; | ||
143 | int error; | 171 | int error; |
144 | 172 | ||
145 | error = gfs2_replay_read_block(jd, blk, &bh); | 173 | error = gfs2_replay_read_block(jd, blk, &bh); |
146 | if (error) | 174 | if (error) |
147 | return error; | 175 | return error; |
148 | lh = (void *)bh->b_data; | ||
149 | |||
150 | hash = crc32(~0, lh, LH_V1_SIZE - 4); | ||
151 | hash = ~crc32_le_shift(hash, 4); /* assume lh_hash is zero */ | ||
152 | |||
153 | crc = crc32c(~0, (void *)lh + LH_V1_SIZE + 4, | ||
154 | bh->b_size - LH_V1_SIZE - 4); | ||
155 | |||
156 | error = lh->lh_header.mh_magic != cpu_to_be32(GFS2_MAGIC) || | ||
157 | lh->lh_header.mh_type != cpu_to_be32(GFS2_METATYPE_LH) || | ||
158 | be32_to_cpu(lh->lh_blkno) != blk || | ||
159 | be32_to_cpu(lh->lh_hash) != hash || | ||
160 | (lh->lh_crc != 0 && be32_to_cpu(lh->lh_crc) != crc); | ||
161 | 176 | ||
177 | error = __get_log_header(sdp, (const struct gfs2_log_header *)bh->b_data, | ||
178 | blk, head); | ||
162 | brelse(bh); | 179 | brelse(bh); |
163 | 180 | ||
164 | if (!error) { | ||
165 | head->lh_sequence = be64_to_cpu(lh->lh_sequence); | ||
166 | head->lh_flags = be32_to_cpu(lh->lh_flags); | ||
167 | head->lh_tail = be32_to_cpu(lh->lh_tail); | ||
168 | head->lh_blkno = be32_to_cpu(lh->lh_blkno); | ||
169 | } | ||
170 | return error; | 181 | return error; |
171 | } | 182 | } |
172 | 183 | ||
diff --git a/fs/gfs2/recovery.h b/fs/gfs2/recovery.h index 11fdfab4bf99..11d81248be85 100644 --- a/fs/gfs2/recovery.h +++ b/fs/gfs2/recovery.h | |||
@@ -31,6 +31,9 @@ extern int gfs2_find_jhead(struct gfs2_jdesc *jd, | |||
31 | struct gfs2_log_header_host *head); | 31 | struct gfs2_log_header_host *head); |
32 | extern int gfs2_recover_journal(struct gfs2_jdesc *gfs2_jd, bool wait); | 32 | extern int gfs2_recover_journal(struct gfs2_jdesc *gfs2_jd, bool wait); |
33 | extern void gfs2_recover_func(struct work_struct *work); | 33 | extern void gfs2_recover_func(struct work_struct *work); |
34 | extern int __get_log_header(struct gfs2_sbd *sdp, | ||
35 | const struct gfs2_log_header *lh, unsigned int blkno, | ||
36 | struct gfs2_log_header_host *head); | ||
34 | 37 | ||
35 | #endif /* __RECOVERY_DOT_H__ */ | 38 | #endif /* __RECOVERY_DOT_H__ */ |
36 | 39 | ||