gfs2: read journal in large chunks to locate the head

Use bio(s) to read in the journal sequentially in large chunks and
locate the head of the journal.

This version addresses the issues Christoph pointed out w.r.t error handling
and using deprecated API.

Signed-off-by: Abhi Das <adas@redhat.com>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Cc: Christoph Hellwig <hch@infradead.org>
此提交包含在:
Abhi Das
2018-11-09 09:57:20 -06:00
提交者 Andreas Gruenbacher
父節點 40e0e61e36
當前提交 2a5f14f279
共有 8 個檔案被更改,包括 192 行新增134 行删除

查看文件

@@ -181,129 +181,6 @@ static int get_log_header(struct gfs2_jdesc *jd, unsigned int blk,
return error;
}
/**
* find_good_lh - find a good log header
* @jd: the journal
* @blk: the segment to start searching from
* @lh: the log header to fill in
* @forward: if true search forward in the log, else search backward
*
* Call get_log_header() to get a log header for a segment, but if the
* segment is bad, either scan forward or backward until we find a good one.
*
* Returns: errno
*/
static int find_good_lh(struct gfs2_jdesc *jd, unsigned int *blk,
struct gfs2_log_header_host *head)
{
unsigned int orig_blk = *blk;
int error;
for (;;) {
error = get_log_header(jd, *blk, head);
if (error <= 0)
return error;
if (++*blk == jd->jd_blocks)
*blk = 0;
if (*blk == orig_blk) {
gfs2_consist_inode(GFS2_I(jd->jd_inode));
return -EIO;
}
}
}
/**
* jhead_scan - make sure we've found the head of the log
* @jd: the journal
* @head: this is filled in with the log descriptor of the head
*
* At this point, seg and lh should be either the head of the log or just
* before. Scan forward until we find the head.
*
* Returns: errno
*/
static int jhead_scan(struct gfs2_jdesc *jd, struct gfs2_log_header_host *head)
{
unsigned int blk = head->lh_blkno;
struct gfs2_log_header_host lh;
int error;
for (;;) {
if (++blk == jd->jd_blocks)
blk = 0;
error = get_log_header(jd, blk, &lh);
if (error < 0)
return error;
if (error == 1)
continue;
if (lh.lh_sequence == head->lh_sequence) {
gfs2_consist_inode(GFS2_I(jd->jd_inode));
return -EIO;
}
if (lh.lh_sequence < head->lh_sequence)
break;
*head = lh;
}
return 0;
}
/**
* gfs2_find_jhead - find the head of a log
* @jd: the journal
* @head: the log descriptor for the head of the log is returned here
*
* Do a binary search of a journal and find the valid log entry with the
* highest sequence number. (i.e. the log head)
*
* Returns: errno
*/
int gfs2_find_jhead(struct gfs2_jdesc *jd, struct gfs2_log_header_host *head)
{
struct gfs2_log_header_host lh_1, lh_m;
u32 blk_1, blk_2, blk_m;
int error;
blk_1 = 0;
blk_2 = jd->jd_blocks - 1;
for (;;) {
blk_m = (blk_1 + blk_2) / 2;
error = find_good_lh(jd, &blk_1, &lh_1);
if (error)
return error;
error = find_good_lh(jd, &blk_m, &lh_m);
if (error)
return error;
if (blk_1 == blk_m || blk_m == blk_2)
break;
if (lh_1.lh_sequence <= lh_m.lh_sequence)
blk_1 = blk_m;
else
blk_2 = blk_m;
}
error = jhead_scan(jd, &lh_1);
if (error)
return error;
*head = lh_1;
return error;
}
/**
* foreach_descriptor - go through the active part of the log
* @jd: the journal