-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathrecon.c
120 lines (95 loc) · 2.45 KB
/
recon.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// SPDX-License-Identifier: GPL-2.0
/* See module.c for license details. */
#include "pmfs2.h"
struct pmfs2_recon_info {
struct super_block *sb;
struct pmfs2_sb_info *sbi;
struct pmfs2_inode *root_pi;
ulong num_inodes;
};
static void _init_recon_info(struct pmfs2_recon_info *pri,
struct super_block *sb, struct inode *root_i)
{
pri->sb = sb;
pri->sbi = PMFS2_SB(sb);
pri->root_pi = PMFS2_I(root_i)->pi;
pri->num_inodes = 0;
}
/*
* The first of each PMEM device is reserved for MDT and therefore must marked
* as active.
*/
static int _recon_mdt_pages(struct pmfs2_recon_info *pri)
{
int i, err;
struct multi_devices *md = pri->sbi->md;
for (i = 0; i < md->t1_count; ++i) {
struct md_dev_info *mdi = md_t1_dev(md, i);
ulong reserved_bn = pmfs2_o2b(mdi->offset);
err = pmfs2_mark_bn_active(pri->sb, reserved_bn);
if (unlikely(err))
return err;
}
return 0;
}
static int _recon_itable_root(struct pmfs2_recon_info *pri)
{
struct pmfs2_inode *it_pi, *root_pi;
struct pmfs2_sb_info *sbi = pri->sbi;
int err;
it_pi = pmfs2_inode_table(pri->sb);
if (unlikely(it_pi->i_btree.height > PMFS2_BTREE_HEIGHT_MAX))
return -EFSCORRUPTED;
err = pmfs2_btree_recon(pri->sb, it_pi);
if (unlikely(err))
return err;
root_pi = pmfs2_find_by_ino_it(pri->sb, it_pi, PMFS2_ROOT_INO);
if (unlikely(!root_pi))
return -EFSCORRUPTED;
err = pmfs2_pi_recon(pri->sb, root_pi);
if (unlikely(err))
return err;
sbi->s_itable_pi = it_pi;
sbi->s_root_pi = root_pi;
return 0;
}
static ulong _itable_ino_max(struct pmfs2_inode *it_pi)
{
ulong size;
size = pmfs2_pi_i_size(it_pi);
return pmfs2_o2b_up(size) * PMFS2_INODES_PER_BLOCK;
}
static int _recon_inodes(struct pmfs2_recon_info *pri)
{
struct pmfs2_inode *it_pi = pmfs2_inode_table(pri->sb);
struct pmfs2_inode *pi;
ulong ino, ino_max;
int err = 0;
ino_max = _itable_ino_max(it_pi);
for (ino = PMFS2_ROOT_INO; (ino < ino_max) && !err; ++ino) {
pi = pmfs2_pi_find_by_ino(pri->sb, ino);
BUG_ON(!pi);
BUG_ON(!pi->i_ino);
if (pmfs2_pi_active(pi))
err = pmfs2_pi_recon(pri->sb, pi);
else
pmfs2_enq_free_inode(pri->sb, pi);
}
return err;
}
int pmfs2_reconstruct(struct super_block *sb, struct inode *root_i)
{
struct pmfs2_recon_info pri;
int err;
_init_recon_info(&pri, sb, root_i);
err = _recon_mdt_pages(&pri);
if (unlikely(err))
return err;
err = _recon_itable_root(&pri);
if (unlikely(err))
return err;
err = _recon_inodes(&pri);
if (unlikely(err))
return err;
return 0;
}