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