1c2c66affSColin Finck /*
2c2c66affSColin Finck * COPYRIGHT: See COPYRIGHT.TXT
3c2c66affSColin Finck * PROJECT: Ext2 File System Driver for WinNT/2K/XP
4c2c66affSColin Finck * FILE: recover.c
5c2c66affSColin Finck * PROGRAMMER: Matt Wu <mattwu@163.com>
6c2c66affSColin Finck * HOMEPAGE: http://www.ext2fsd.com
7c2c66affSColin Finck * UPDATE HISTORY:
8c2c66affSColin Finck */
9c2c66affSColin Finck
10c2c66affSColin Finck /* INCLUDES *****************************************************************/
11c2c66affSColin Finck
12c2c66affSColin Finck #include <ext2fs.h>
13c2c66affSColin Finck #include <linux/jbd.h>
14c2c66affSColin Finck #include <linux/ext3_fs.h>
15c2c66affSColin Finck
16c2c66affSColin Finck /* GLOBALS ***************************************************************/
17c2c66affSColin Finck
18c2c66affSColin Finck extern PEXT2_GLOBAL Ext2Global;
19c2c66affSColin Finck
20c2c66affSColin Finck /* DEFINITIONS *************************************************************/
21c2c66affSColin Finck
22c2c66affSColin Finck #ifdef ALLOC_PRAGMA
23c2c66affSColin Finck #pragma alloc_text(PAGE, Ext2LoadInternalJournal)
24c2c66affSColin Finck #pragma alloc_text(PAGE, Ext2CheckJournal)
25c2c66affSColin Finck #pragma alloc_text(PAGE, Ext2RecoverJournal)
26c2c66affSColin Finck #endif
27c2c66affSColin Finck
28c2c66affSColin Finck PEXT2_MCB
Ext2LoadInternalJournal(PEXT2_VCB Vcb,ULONG jNo)29c2c66affSColin Finck Ext2LoadInternalJournal(
30c2c66affSColin Finck PEXT2_VCB Vcb,
31c2c66affSColin Finck ULONG jNo
32c2c66affSColin Finck )
33c2c66affSColin Finck {
34c2c66affSColin Finck PEXT2_MCB Jcb = NULL;
35c2c66affSColin Finck
36c2c66affSColin Finck Jcb = Ext2AllocateMcb(Vcb, NULL, NULL, 0);
37c2c66affSColin Finck if (!Jcb) {
38c2c66affSColin Finck goto errorout;
39c2c66affSColin Finck }
40c2c66affSColin Finck
41c2c66affSColin Finck Jcb->Inode.i_ino = jNo;
42c2c66affSColin Finck Jcb->Inode.i_sb = &Vcb->sb;
43c2c66affSColin Finck if (!Ext2LoadInode(Vcb, &Jcb->Inode)) {
44c2c66affSColin Finck DbgBreak();
45c2c66affSColin Finck Ext2FreeMcb(Vcb, Jcb);
46c2c66affSColin Finck goto errorout;
47c2c66affSColin Finck }
48c2c66affSColin Finck
49c2c66affSColin Finck errorout:
50c2c66affSColin Finck
51c2c66affSColin Finck return Jcb;
52c2c66affSColin Finck }
53c2c66affSColin Finck
54c2c66affSColin Finck INT
Ext2CheckJournal(PEXT2_VCB Vcb,PULONG jNo)55c2c66affSColin Finck Ext2CheckJournal(
56c2c66affSColin Finck PEXT2_VCB Vcb,
57c2c66affSColin Finck PULONG jNo
58c2c66affSColin Finck )
59c2c66affSColin Finck {
60c2c66affSColin Finck struct ext3_super_block* esb = NULL;
61c2c66affSColin Finck
62c2c66affSColin Finck /* check ext3 super block */
63c2c66affSColin Finck esb = (struct ext3_super_block *)Vcb->SuperBlock;
64c2c66affSColin Finck if (IsFlagOn(esb->s_feature_incompat,
65c2c66affSColin Finck EXT3_FEATURE_INCOMPAT_RECOVER)) {
66c2c66affSColin Finck SetLongFlag(Vcb->Flags, VCB_JOURNAL_RECOVER);
67c2c66affSColin Finck }
68c2c66affSColin Finck
69c2c66affSColin Finck /* must stop here if volume is read-only */
70c2c66affSColin Finck if (IsVcbReadOnly(Vcb)) {
71c2c66affSColin Finck goto errorout;
72c2c66affSColin Finck }
73c2c66affSColin Finck
74c2c66affSColin Finck /* journal is external ? */
75c2c66affSColin Finck if (esb->s_journal_inum == 0) {
76c2c66affSColin Finck goto errorout;
77c2c66affSColin Finck }
78c2c66affSColin Finck
79c2c66affSColin Finck /* oops: volume is corrupted */
80c2c66affSColin Finck if (esb->s_journal_dev) {
81c2c66affSColin Finck goto errorout;
82c2c66affSColin Finck }
83c2c66affSColin Finck
84c2c66affSColin Finck /* return the journal inode number */
85c2c66affSColin Finck *jNo = esb->s_journal_inum;
86c2c66affSColin Finck
87c2c66affSColin Finck return TRUE;
88c2c66affSColin Finck
89c2c66affSColin Finck errorout:
90c2c66affSColin Finck
91c2c66affSColin Finck return FALSE;
92c2c66affSColin Finck }
93c2c66affSColin Finck
94c2c66affSColin Finck INT
Ext2RecoverJournal(PEXT2_IRP_CONTEXT IrpContext,PEXT2_VCB Vcb)95c2c66affSColin Finck Ext2RecoverJournal(
96c2c66affSColin Finck PEXT2_IRP_CONTEXT IrpContext,
97c2c66affSColin Finck PEXT2_VCB Vcb
98c2c66affSColin Finck )
99c2c66affSColin Finck {
100c2c66affSColin Finck INT rc = 0;
101c2c66affSColin Finck ULONG jNo = 0;
102c2c66affSColin Finck PEXT2_MCB jcb = NULL;
103c2c66affSColin Finck struct block_device * bd = &Vcb->bd;
104c2c66affSColin Finck #ifndef __REACTOS__
105c2c66affSColin Finck struct super_block * sb = &Vcb->sb;
106c2c66affSColin Finck #endif
107c2c66affSColin Finck struct inode * ji = NULL;
108c2c66affSColin Finck journal_t * journal = NULL;
109c2c66affSColin Finck struct ext3_super_block *esb;
110c2c66affSColin Finck
111*a1d7e993SPierre Schweitzer ExAcquireResourceExclusiveLite(&Vcb->MainResource, TRUE);
112*a1d7e993SPierre Schweitzer
113c2c66affSColin Finck /* check journal inode number */
114c2c66affSColin Finck if (!Ext2CheckJournal(Vcb, &jNo)) {
115*a1d7e993SPierre Schweitzer rc = -1;
116*a1d7e993SPierre Schweitzer goto errorout;
117c2c66affSColin Finck }
118c2c66affSColin Finck
119c2c66affSColin Finck /* allocate journal Mcb */
120c2c66affSColin Finck jcb = Ext2LoadInternalJournal(Vcb, jNo);
121c2c66affSColin Finck if (!jcb) {
122c2c66affSColin Finck rc = -6;
123c2c66affSColin Finck goto errorout;
124c2c66affSColin Finck }
125c2c66affSColin Finck
126c2c66affSColin Finck /* allocate journal inode */
127c2c66affSColin Finck ji = &jcb->Inode;
128c2c66affSColin Finck
129c2c66affSColin Finck /* initialize journal file from inode */
130c2c66affSColin Finck journal = journal_init_inode(ji);
131c2c66affSColin Finck
132c2c66affSColin Finck /* initialzation succeeds ? */
133c2c66affSColin Finck if (!journal) {
134c2c66affSColin Finck iput(ji);
135c2c66affSColin Finck rc = -8;
136c2c66affSColin Finck goto errorout;
137c2c66affSColin Finck }
138c2c66affSColin Finck
139c2c66affSColin Finck /* start journal recovery */
140c2c66affSColin Finck rc = journal_load(journal);
141c2c66affSColin Finck if (0 != rc) {
142c2c66affSColin Finck rc = -9;
143c2c66affSColin Finck DbgPrint("Ext2Fsd: recover_journal: failed "
144c2c66affSColin Finck "to recover journal data.\n");
145c2c66affSColin Finck }
146c2c66affSColin Finck
147c2c66affSColin Finck /* reload super_block and group_description */
148c2c66affSColin Finck Ext2RefreshSuper(IrpContext, Vcb);
149c2c66affSColin Finck Ext2RefreshGroup(IrpContext, Vcb);
150c2c66affSColin Finck
151c2c66affSColin Finck /* wipe journal data and clear recover flag in sb */
152c2c66affSColin Finck if (rc == 0) {
153c2c66affSColin Finck journal_wipe_recovery(journal);
154c2c66affSColin Finck ClearLongFlag(
155c2c66affSColin Finck Vcb->SuperBlock->s_feature_incompat,
156c2c66affSColin Finck EXT3_FEATURE_INCOMPAT_RECOVER );
157c2c66affSColin Finck Ext2SaveSuper(IrpContext, Vcb);
158c2c66affSColin Finck sync_blockdev(bd);
159c2c66affSColin Finck ClearLongFlag(Vcb->Flags, VCB_JOURNAL_RECOVER);
160c2c66affSColin Finck }
161c2c66affSColin Finck
162c2c66affSColin Finck errorout:
163c2c66affSColin Finck
164c2c66affSColin Finck /* destroy journal structure */
165c2c66affSColin Finck if (journal) {
166c2c66affSColin Finck journal_destroy(journal);
167c2c66affSColin Finck }
168c2c66affSColin Finck
169c2c66affSColin Finck /* destory journal Mcb */
170c2c66affSColin Finck if (jcb) {
171c2c66affSColin Finck Ext2FreeMcb(Vcb, jcb);
172c2c66affSColin Finck }
173c2c66affSColin Finck
174*a1d7e993SPierre Schweitzer ExReleaseResourceLite(&Vcb->MainResource);
175*a1d7e993SPierre Schweitzer
176c2c66affSColin Finck return rc;
177c2c66affSColin Finck }
178