2 Copyright © 1995-2008, The AROS Development Team. All rights reserved.
6 * -date------ -name------------------- -description-----------------------------
7 * 02-jan-2008 [Tomasz Wiszkowski] added disk validation
8 * 04-jan-2008 [Tomasz Wiszkowski] corrected tabulation
18 #include "afsblocks.h"
21 #include "checksums.h"
22 #include "extstrings.h"
23 #include "baseredef.h"
24 #include "validator.h"
26 /**********************************************
28 Descr.: update header information (time)
30 blockbuffer - pointer to struct BlockCache
31 containing the headerblock
32 Output: 0 for success; error code otherwise
33 ***********************************************/
36 struct AFSBase
*afsbase
,
37 struct Volume
*volume
,
38 struct BlockCache
*blockbuffer
43 /* store current time as modification date for this object and all its ancestors */
47 blockbuffer
->buffer
[BLK_DAYS(volume
)] = OS_LONG2BE(ds
.ds_Days
);
48 blockbuffer
->buffer
[BLK_MINS(volume
)] = OS_LONG2BE(ds
.ds_Minute
);
49 blockbuffer
->buffer
[BLK_TICKS(volume
)] = OS_LONG2BE(ds
.ds_Tick
);
50 if (blockbuffer
->buffer
[BLK_PARENT(volume
)] == 0)
52 writeBlockDeferred(afsbase
, volume
, blockbuffer
, BLK_CHECKSUM
);
53 blockbuffer
= getBlock
54 (afsbase
, volume
, OS_BE2LONG(blockbuffer
->buffer
[BLK_PARENT(volume
)]));
55 if (blockbuffer
== NULL
)
58 /* last block is not written yet - it's the rootblock */
59 /* we have to change BLK_VOLUME_xxx */
60 blockbuffer
->buffer
[BLK_VOLUME_DAYS(volume
)] = OS_LONG2BE(ds
.ds_Days
);
61 blockbuffer
->buffer
[BLK_VOLUME_MINS(volume
)] = OS_LONG2BE(ds
.ds_Minute
);
62 blockbuffer
->buffer
[BLK_VOLUME_TICKS(volume
)] = OS_LONG2BE(ds
.ds_Tick
);
63 writeBlockDeferred(afsbase
, volume
, blockbuffer
, BLK_CHECKSUM
);
67 /*******************************************
69 Descr.: fills a InfoData structure with some
71 answer on ACTION_DISK_INFO
72 Input : id - InfoData structure to fill
74 ********************************************/
75 LONG
getDiskInfo(struct Volume
*volume
, struct InfoData
*id
) {
77 id
->id_NumSoftErrors
= 0;
78 id
->id_UnitNumber
= volume
->unit
;
79 id
->id_DiskState
= volume
->state
;
80 id
->id_NumBlocks
= volume
->countblocks
-volume
->bootblocks
;
81 id
->id_NumBlocksUsed
= volume
->usedblockscount
;
82 id
->id_BytesPerBlock
= volume
->dosflags
==0 ? BLOCK_SIZE(volume
)-24 : BLOCK_SIZE(volume
);
83 id
->id_DiskType
= mediumPresent(&volume
->ioh
) ? (volume
->dostype
| volume
->dosflags
) : ID_NO_DISK_PRESENT
;
84 id
->id_VolumeNode
= MKBADDR(volume
->volumenode
);
85 id
->id_InUse
= (LONG
)TRUE
; /* if we are here the device should be in use! */
89 /*******************************************
91 Descr.: forbid/permit access for this volume
92 Input : volume - the volume
93 forbid - DOSTRUE to forbid
94 DOSFALSE to permit access
96 ********************************************/
97 LONG
inhibit(struct AFSBase
*afsbase
, struct Volume
*volume
, ULONG forbid
) {
98 D(bug("[afs 0x%08lX] inhibit(%ld)\n", volume
, forbid
));
101 if (volume
->inhibitcounter
++ == 0)
103 D(bug("[afs 0x%08lX] inhibiting\n", volume
));
104 /* if (exclusiveLocks(&volume->locklist)) return DOSFALSE; */
105 if (mediumPresent(&volume
->ioh
))
107 flush(afsbase
, volume
);
108 osMediumFree(afsbase
, volume
, FALSE
);
112 else if (volume
->inhibitcounter
)
114 if (--volume
->inhibitcounter
== 0)
116 D(bug("[afs 0x%08lX] uninhibiting\n", volume
));
117 if (diskPresent(afsbase
, &volume
->ioh
))
119 D(bug("[afs 0x%08lX] media inserted\n", volume
));
120 newMedium(afsbase
, volume
);
121 volume
->ioh
.ioflags
|= IOHF_DISK_IN
;
124 volume
->ioh
.ioflags
&= ~IOHF_DISK_IN
;
130 /*******************************************
132 Descr.: mark newly allocated bitmapblocks
134 Input : volume - the volume
136 ********************************************/
137 void markBitmaps(struct AFSBase
*afsbase
, struct Volume
*volume
) {
138 struct BlockCache
*blockbuffer
;
141 for (i
=0; (i
<=24) && (volume
->bitmapblockpointers
[i
] != 0); i
++)
142 markBlock(afsbase
, volume
, volume
->bitmapblockpointers
[i
], 0);
143 curblock
= volume
->bitmapextensionblock
;
144 while (curblock
!= 0)
146 blockbuffer
= getBlock(afsbase
, volume
, curblock
);
147 if (blockbuffer
== NULL
)
149 blockbuffer
->flags
|= BCF_USED
;
150 markBlock(afsbase
, volume
, curblock
, 0);
151 for (i
=0; i
<volume
->SizeBlock
-1; i
++)
153 if (blockbuffer
->buffer
[i
] == 0)
155 markBlock(afsbase
, volume
, OS_BE2LONG(blockbuffer
->buffer
[i
]), 0);
157 curblock
= OS_BE2LONG(blockbuffer
->buffer
[volume
->SizeBlock
-1]);
158 blockbuffer
->flags
&= ~BCF_USED
;
162 /*******************************************
164 Descr.: initialize a volume
165 Input : volume - volume to initialize
166 name - name of volume
168 Output: 0 for success; error code otherwise
169 ********************************************/
171 (struct AFSBase
*afsbase
, struct Volume
*volume
, CONST_STRPTR name
,
174 struct BlockCache
*blockbuffer
;
178 blockbuffer
= getFreeCacheBlock(afsbase
, volume
, 0);
179 if (blockbuffer
!= NULL
)
181 blockbuffer
->buffer
[0] = OS_LONG2BE(dostype
);
182 blockbuffer
->buffer
[2] = OS_LONG2BE(volume
->rootblock
);
183 writeBlock(afsbase
, volume
, blockbuffer
, -1);
184 blockbuffer
= getFreeCacheBlock(afsbase
, volume
, volume
->rootblock
);
185 if (blockbuffer
!= NULL
)
187 blockbuffer
->flags
|= BCF_USED
;
189 blockbuffer
->buffer
[BLK_PRIMARY_TYPE
] = OS_LONG2BE(T_SHORT
);
190 blockbuffer
->buffer
[1] = 0;
191 blockbuffer
->buffer
[2] = 0;
192 blockbuffer
->buffer
[BLK_TABLE_SIZE
] = OS_LONG2BE(volume
->SizeBlock
-56);
193 blockbuffer
->buffer
[4] = 0;
194 for (i
=BLK_TABLE_START
; i
<=BLK_TABLE_END(volume
); i
++)
195 blockbuffer
->buffer
[i
] = 0;
196 blockbuffer
->buffer
[BLK_BITMAP_VALID_FLAG(volume
)] = -1;
197 createNewBitmapBlocks(afsbase
, volume
);
199 i
=BLK_BITMAP_POINTERS_START(volume
);
200 i
<=BLK_BITMAP_POINTERS_END(volume
);
204 blockbuffer
->buffer
[i
] = OS_LONG2BE
206 volume
->bitmapblockpointers
[i
-BLK_BITMAP_POINTERS_START(volume
)]
209 blockbuffer
->buffer
[BLK_BITMAP_EXTENSION(volume
)] =
210 OS_LONG2BE(volume
->bitmapextensionblock
);
211 blockbuffer
->buffer
[BLK_ROOT_DAYS(volume
)] = OS_LONG2BE(ds
.ds_Days
);
212 blockbuffer
->buffer
[BLK_ROOT_MINS(volume
)] = OS_LONG2BE(ds
.ds_Minute
);
213 blockbuffer
->buffer
[BLK_ROOT_TICKS(volume
)] = OS_LONG2BE(ds
.ds_Tick
);
217 (APTR
)((char *)blockbuffer
->buffer
+(BLK_DISKNAME_START(volume
)*4)),
220 blockbuffer
->buffer
[volume
->SizeBlock
-12] = 0;
221 blockbuffer
->buffer
[volume
->SizeBlock
-11] = 0;
222 blockbuffer
->buffer
[BLK_VOLUME_DAYS(volume
)] = OS_LONG2BE(ds
.ds_Days
);
223 blockbuffer
->buffer
[BLK_VOLUME_MINS(volume
)] = OS_LONG2BE(ds
.ds_Minute
);
224 blockbuffer
->buffer
[BLK_VOLUME_TICKS(volume
)] = OS_LONG2BE(ds
.ds_Tick
);
225 blockbuffer
->buffer
[BLK_CREATION_DAYS(volume
)] = OS_LONG2BE(ds
.ds_Days
);
226 blockbuffer
->buffer
[BLK_CREATION_MINS(volume
)] = OS_LONG2BE(ds
.ds_Minute
);
227 blockbuffer
->buffer
[BLK_CREATION_TICKS(volume
)] = OS_LONG2BE(ds
.ds_Tick
);
228 blockbuffer
->buffer
[volume
->SizeBlock
-4] = 0;
229 blockbuffer
->buffer
[volume
->SizeBlock
-3] = 0;
230 blockbuffer
->buffer
[volume
->SizeBlock
-2] = 0;
231 blockbuffer
->buffer
[BLK_SECONDARY_TYPE(volume
)] = OS_LONG2BE(ST_ROOT
);
232 writeBlock(afsbase
, volume
, blockbuffer
, BLK_CHECKSUM
);
233 blockbuffer
->flags
&= ~BCF_USED
;
234 invalidBitmap(afsbase
, volume
);
235 markBlock(afsbase
, volume
, volume
->rootblock
, 0);
236 markBitmaps(afsbase
, volume
);
237 validBitmap(afsbase
, volume
);
241 return ERROR_UNKNOWN
;
244 /*******************************************
246 Descr.: rename a volume
247 Input : volume - volume to rename
248 name - new name for volume
249 Output: DOSTRUE for success; DOSFALSE otherwise
250 ********************************************/
251 LONG
relabel(struct AFSBase
*afsbase
, struct Volume
*volume
,
252 CONST_STRPTR name
, SIPTR
*error
) {
253 struct BlockCache
*blockbuffer
;
256 if (0 == checkValid(afsbase
, volume
))
258 *error
= ERROR_DISK_WRITE_PROTECTED
;
261 osMediumFree(afsbase
, volume
, FALSE
);
262 blockbuffer
=getBlock(afsbase
, volume
,volume
->rootblock
);
263 if (blockbuffer
== NULL
)
265 if (strlen(name
) > MAX_NAME_LENGTH
)
267 *error
= ERROR_LINE_TOO_LONG
;
273 (APTR
)((char *)blockbuffer
->buffer
+(BLK_DISKNAME_START(volume
)*4)),
277 blockbuffer
->buffer
[BLK_ROOT_DAYS(volume
)] = OS_LONG2BE(ds
.ds_Days
);
278 blockbuffer
->buffer
[BLK_ROOT_MINS(volume
)] = OS_LONG2BE(ds
.ds_Minute
);
279 blockbuffer
->buffer
[BLK_ROOT_TICKS(volume
)] = OS_LONG2BE(ds
.ds_Tick
);
280 blockbuffer
->buffer
[BLK_VOLUME_DAYS(volume
)] = OS_LONG2BE(ds
.ds_Days
);
281 blockbuffer
->buffer
[BLK_VOLUME_MINS(volume
)] = OS_LONG2BE(ds
.ds_Minute
);
282 blockbuffer
->buffer
[BLK_VOLUME_TICKS(volume
)] = OS_LONG2BE(ds
.ds_Tick
);
283 writeBlock(afsbase
, volume
, blockbuffer
, BLK_CHECKSUM
);
284 /* update os specific information of the medium */
285 osMediumInit(afsbase
, volume
, blockbuffer
);