aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2
diff options
context:
space:
mode:
authorAbhi Das <adas@redhat.com>2018-11-09 10:54:18 -0500
committerAndreas Gruenbacher <agruenba@redhat.com>2018-12-11 11:50:36 -0500
commit40e0e61e366bed56b71edb3b970245165090ec9a (patch)
treebe18946d9501c6f3e12deab6430d982442ba1d00 /fs/gfs2
parent5b84609532d6e48a769a735d214e2cd705ed395e (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.c53
-rw-r--r--fs/gfs2/recovery.h3
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
123int __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)
137static int get_log_header(struct gfs2_jdesc *jd, unsigned int blk, 166static 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);
32extern int gfs2_recover_journal(struct gfs2_jdesc *gfs2_jd, bool wait); 32extern int gfs2_recover_journal(struct gfs2_jdesc *gfs2_jd, bool wait);
33extern void gfs2_recover_func(struct work_struct *work); 33extern void gfs2_recover_func(struct work_struct *work);
34extern 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