2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
7 * -date------ -name------------------- -description-----------------------------
8 * 26-dec-2007 [Tomasz Wiszkowski] added disk validation
9 * 04-jan-2008 [Tomasz Wiszkowski] corrected tabulation
10 * 05-jan-2008 [Tomasz Wiszkowski] removed requester prompting for validation
11 * to allow volume validation during boot-up
20 #include "checksums.h"
22 #include "afsblocks.h"
23 #include "baseredef.h"
24 #include "validator.h"
27 BOOL
mediumPresent(struct IOHandle
*ioh
) {
28 return (ioh
->ioflags
& IOHF_DISK_IN
)==IOHF_DISK_IN
;
31 /*******************************************
33 Descr.: build infos for a new medium
35 Output: 0 for success; error code otherwise
36 ********************************************/
37 LONG
newMedium(struct AFSBase
*afsbase
, struct Volume
*volume
) {
38 struct BlockCache
*blockbuffer
;
42 /* Check validity of root block first, since boot block may be left over
43 from an overwritten partition of a different size */
44 blockbuffer
=getBlock(afsbase
, volume
,volume
->rootblock
);
45 if (blockbuffer
== NULL
)
47 if (calcChkSum(volume
->SizeBlock
, blockbuffer
->buffer
) != 0 ||
48 OS_BE2LONG(blockbuffer
->buffer
[BLK_SECONDARY_TYPE(volume
)]) != ST_ROOT
)
49 return ERROR_NOT_A_DOS_DISK
;
51 blockbuffer
=getBlock(afsbase
, volume
,0);
52 if (blockbuffer
== NULL
)
54 volume
->dostype
=OS_BE2LONG(blockbuffer
->buffer
[0]) & 0xFFFFFF00;
55 if (volume
->dostype
!= 0x444F5300)
57 blockbuffer
=getBlock(afsbase
, volume
, 1);
58 volume
->dostype
=OS_BE2LONG(blockbuffer
->buffer
[0]) & 0xFFFFFF00;
60 volume
->dosflags
= OS_BE2LONG(blockbuffer
->buffer
[0]) & 0xFF;
61 if (volume
->dostype
!= 0x444F5300)
62 return ERROR_NOT_A_DOS_DISK
;
63 blockbuffer
=getBlock(afsbase
, volume
,volume
->rootblock
);
64 if (blockbuffer
== NULL
)
68 volume
->bitmapblockpointers
[i
]=OS_BE2LONG
70 blockbuffer
->buffer
[BLK_BITMAP_POINTERS_START(volume
)+i
]
73 volume
->bitmapextensionblock
=OS_BE2LONG
75 blockbuffer
->buffer
[BLK_BITMAP_EXTENSION(volume
)]
77 if (!blockbuffer
->buffer
[BLK_BITMAP_VALID_FLAG(volume
)])
79 /* since our disk is invalid at this point, *
80 * we want to spawn a new process that will *
81 * perform disk validation while we move on */
83 volume
->usedblockscount
=0;
84 volume
->state
= ID_VALIDATING
;
86 launchValidator(afsbase
, volume
);
90 * it's safe to assume that the block is still there
92 blockbuffer
=getBlock(afsbase
, volume
,volume
->rootblock
);
94 if (blockbuffer
->buffer
[BLK_BITMAP_VALID_FLAG(volume
)])
96 blockbuffer
->flags
|= BCF_USED
; // won't be cleared until volume is ejected
97 volume
->usedblockscount
=countUsedBlocks(afsbase
, volume
);
98 volume
->state
= (volume
->dosflags
& 0xFC) ? ID_WRITE_PROTECTED
: ID_VALIDATED
;
100 error
= osMediumInit(afsbase
, volume
, blockbuffer
);
103 /* for free block searching */
104 volume
->lastaccess
=volume
->rootblock
;
108 /*******************************************
110 Descr.: maybe a better name would be mountVolume
111 allocate resources for a new mounted device
112 Input : device - device pointer
113 blockdevice - name of blockdevice
114 unit - unit number of blockdevice
115 devicedef - medium geometry data
116 error - return error code
117 Output: 0 on error (error set dos dos error);
118 pointer to struct Volume on success
119 ********************************************/
120 struct Volume
*initVolume
122 struct AFSBase
*afsbase
,
123 struct Device
*device
,
126 struct DosEnvec
*devicedef
,
130 struct Volume
*volume
;
132 volume
= AllocMem(sizeof(struct Volume
),MEMF_PUBLIC
| MEMF_CLEAR
);
135 volume
->device
= device
;
136 volume
->ioh
.blockdevice
= blockdevice
;
137 volume
->ioh
.unit
= unit
;
138 volume
->ioh
.flags
= 0;
139 volume
->SizeBlock
=devicedef
->de_SizeBlock
;
140 if (devicedef
->de_TableSize
>=20)
141 volume
->bootblocks
=devicedef
->de_BootBlocks
;
143 volume
->bootblocks
=devicedef
->de_Reserved
;
144 volume
->blockcache
=initCache(afsbase
, volume
, devicedef
->de_NumBuffers
);
145 if (volume
->blockcache
!= NULL
)
147 if (openBlockDevice(afsbase
, &volume
->ioh
)!= NULL
)
149 volume
->countblocks
=
152 devicedef
->de_HighCyl
-devicedef
->de_LowCyl
+1
153 )*devicedef
->de_Surfaces
*devicedef
->de_BlocksPerTrack
155 volume
->rootblock
=(volume
->countblocks
-1+devicedef
->de_Reserved
)/2;
157 devicedef
->de_LowCyl
*
158 devicedef
->de_Surfaces
*
159 devicedef
->de_BlocksPerTrack
;
162 (devicedef
->de_HighCyl
+1)
163 *devicedef
->de_Surfaces
164 *devicedef
->de_BlocksPerTrack
166 check64BitSupport(afsbase
, volume
);
167 volume
->ah
.volume
=volume
;
168 if (mediumPresent(&volume
->ioh
))
170 *error
= newMedium(afsbase
, volume
);
174 if ((*error
== 0) || (*error
== ERROR_NOT_A_DOS_DISK
))
176 D(bug("[afs] initVolume: BootBlocks=%d\n",volume
->bootblocks
));
177 D(bug("[afs] initVolume: RootBlock=%ld\n",volume
->rootblock
));
178 volume
->ah
.header_block
= volume
->rootblock
;
184 *error
=ERROR_NO_FREE_STORE
;
186 freeCache(afsbase
, volume
->blockcache
);
190 *error
=ERROR_NO_FREE_STORE
;
192 FreeMem(volume
,sizeof(struct Volume
));
195 *error
=ERROR_NO_FREE_STORE
;
199 /*******************************************
201 Descr.: maybe a better name would be unmountVolume
202 free resources allocated by initVolume
203 Input : volume - volume to unmount
205 ********************************************/
206 void uninitVolume(struct AFSBase
*afsbase
, struct Volume
*volume
) {
208 osMediumFree(afsbase
, volume
, TRUE
);
209 if (volume
->blockcache
!= NULL
)
210 freeCache(afsbase
, volume
->blockcache
);
211 closeBlockDevice(afsbase
, &volume
->ioh
);
212 FreeMem(volume
,sizeof(struct Volume
));
215 /* vim: set noet ts=3 ai fdm=marker fmr={,} :*/