Reapplication of sonic's patches originally done in r29201 and r29210:
[tangerine.git] / rom / devs / filesys / afs / misc.c
blob2f8f9167e32f8d9cfaeaef34ad637f20fa75bcc8
1 /*
2 Copyright © 1995-2008, The AROS Development Team. All rights reserved.
3 $Id$
4 */
5 /*
6 * -date------ -name------------------- -description-----------------------------
7 * 02-jan-2008 [Tomasz Wiszkowski] added disk validation
8 * 04-jan-2008 [Tomasz Wiszkowski] corrected tabulation
9 */
12 #ifndef DEBUG
13 #define DEBUG 0
14 #endif
16 #include "os.h"
17 #include "misc.h"
18 #include "afsblocks.h"
19 #include "bitmap.h"
20 #include "cache.h"
21 #include "checksums.h"
22 #include "extstrings.h"
23 #include "baseredef.h"
24 #include "validator.h"
26 extern ULONG error;
28 /**********************************************
29 Name : writeHeader
30 Descr.: update header information (time)
31 Input : volume -
32 blockbuffer - pointer to struct BlockCache
33 containing the headerblock
34 Output: 0 for success; error code otherwise
35 ***********************************************/
36 ULONG writeHeader
38 struct AFSBase *afsbase,
39 struct Volume *volume,
40 struct BlockCache *blockbuffer
43 struct DateStamp ds;
45 /* store current time as modification date for this object and all its ancestors */
46 DateStamp(&ds);
47 for (;;)
49 blockbuffer->buffer[BLK_DAYS(volume)] = OS_LONG2BE(ds.ds_Days);
50 blockbuffer->buffer[BLK_MINS(volume)] = OS_LONG2BE(ds.ds_Minute);
51 blockbuffer->buffer[BLK_TICKS(volume)] = OS_LONG2BE(ds.ds_Tick);
52 if (blockbuffer->buffer[BLK_PARENT(volume)] == 0)
53 break;
54 writeBlockDeferred(afsbase, volume, blockbuffer, BLK_CHECKSUM);
55 blockbuffer = getBlock
56 (afsbase, volume, OS_BE2LONG(blockbuffer->buffer[BLK_PARENT(volume)]));
57 if (blockbuffer == NULL)
58 return ERROR_UNKNOWN;
60 /* last block is not written yet - it's the rootblock */
61 /* we have to change BLK_VOLUME_xxx */
62 blockbuffer->buffer[BLK_VOLUME_DAYS(volume)] = OS_LONG2BE(ds.ds_Days);
63 blockbuffer->buffer[BLK_VOLUME_MINS(volume)] = OS_LONG2BE(ds.ds_Minute);
64 blockbuffer->buffer[BLK_VOLUME_TICKS(volume)] = OS_LONG2BE(ds.ds_Tick);
65 writeBlockDeferred(afsbase, volume, blockbuffer, BLK_CHECKSUM);
66 return 0;
69 /*******************************************
70 Name : getDiskInfo
71 Descr.: fills a InfoData structure with some
72 Disk info;
73 answer on ACTION_DISK_INFO
74 Input : id - InfoData structure to fill
75 Output: 0 = no error
76 ********************************************/
77 LONG getDiskInfo(struct Volume *volume, struct InfoData *id) {
79 id->id_NumSoftErrors = 0;
80 id->id_UnitNumber = volume->unit;
81 id->id_DiskState = volume->state;
82 id->id_NumBlocks = volume->countblocks-volume->bootblocks;
83 id->id_NumBlocksUsed = volume->usedblockscount;
84 id->id_BytesPerBlock = volume->dosflags==0 ? BLOCK_SIZE(volume)-24 : BLOCK_SIZE(volume);
85 id->id_DiskType = volume->dostype | volume->dosflags;
86 id->id_VolumeNode = volume->volumenode;
87 id->id_InUse = (LONG)TRUE; /* if we are here the device should be in use! */
88 return 0;
91 /*******************************************
92 Name : inhibit
93 Descr.: forbid/permit access for this volume
94 Input : volume - the volume
95 forbid - DOSTRUE to forbid
96 DOSFALSE to permit access
97 Output: 0 = no error
98 ********************************************/
99 LONG inhibit(struct AFSBase *afsbase, struct Volume *volume, ULONG forbid) {
100 D(bug("[afs 0x%08lX] inhibit(%ld)\n", volume, forbid));
101 if (forbid)
103 if (volume->inhibitcounter++ == 0)
105 D(bug("[afs 0x%08lX] inhibiting\n", volume));
106 /* if (exclusiveLocks(&volume->locklist)) return DOSFALSE; */
107 if (mediumPresent(&volume->ioh))
109 flush(afsbase, volume);
110 osMediumFree(afsbase, volume, FALSE);
114 else if (volume->inhibitcounter)
116 if (--volume->inhibitcounter == 0)
118 D(bug("[afs 0x%08lX] uninhibiting\n", volume));
119 if (diskPresent(afsbase, &volume->ioh))
121 D(bug("[afs 0x%08lX] media inserted\n", volume));
122 newMedium(afsbase, volume);
123 volume->ioh.ioflags |= IOHF_DISK_IN;
125 else
126 volume->ioh.ioflags &= ~IOHF_DISK_IN;
129 return 0;
132 /*******************************************
133 Name : markBitmaps
134 Descr.: mark newly allocated bitmapblocks
135 (for format)
136 Input : volume - the volume
137 Output: -
138 ********************************************/
139 void markBitmaps(struct AFSBase *afsbase, struct Volume *volume) {
140 struct BlockCache *blockbuffer;
141 ULONG i,curblock;
143 for (i=0; (i<=24) && (volume->bitmapblockpointers[i] != 0); i++)
144 markBlock(afsbase, volume, volume->bitmapblockpointers[i], 0);
145 curblock = volume->bitmapextensionblock;
146 while (curblock != 0)
148 blockbuffer = getBlock(afsbase, volume, curblock);
149 if (blockbuffer == NULL)
150 return;
151 blockbuffer->flags |= BCF_USED;
152 markBlock(afsbase, volume, curblock, 0);
153 for (i=0; i<volume->SizeBlock-1; i++)
155 if (blockbuffer->buffer[i] == 0)
156 break;
157 markBlock(afsbase, volume, OS_BE2LONG(blockbuffer->buffer[i]), 0);
159 curblock = OS_BE2LONG(blockbuffer->buffer[volume->SizeBlock-1]);
160 blockbuffer->flags &= ~BCF_USED;
164 /*******************************************
165 Name : format
166 Descr.: initialize a volume
167 Input : volume - volume to initialize
168 name - name of volume
169 dostype - DOS\0/...
170 Output: 0 for success; error code otherwise
171 ********************************************/
172 LONG format
173 (struct AFSBase *afsbase, struct Volume *volume, CONST_STRPTR name,
174 ULONG dostype)
176 struct BlockCache *blockbuffer;
177 struct DateStamp ds;
178 UWORD i;
180 blockbuffer = getFreeCacheBlock(afsbase, volume, 0);
181 if (blockbuffer != NULL)
183 blockbuffer->buffer[0] = OS_LONG2BE(dostype);
184 blockbuffer->buffer[2] = OS_LONG2BE(volume->rootblock);
185 writeBlock(afsbase, volume, blockbuffer, -1);
186 blockbuffer = getFreeCacheBlock(afsbase, volume, volume->rootblock);
187 if (blockbuffer != NULL)
189 blockbuffer->flags |= BCF_USED;
190 DateStamp(&ds);
191 blockbuffer->buffer[BLK_PRIMARY_TYPE] = OS_LONG2BE(T_SHORT);
192 blockbuffer->buffer[1] = 0;
193 blockbuffer->buffer[2] = 0;
194 blockbuffer->buffer[BLK_TABLE_SIZE] = OS_LONG2BE(volume->SizeBlock-56);
195 blockbuffer->buffer[4] = 0;
196 for (i=BLK_TABLE_START; i<=BLK_TABLE_END(volume); i++)
197 blockbuffer->buffer[i] = 0;
198 blockbuffer->buffer[BLK_BITMAP_VALID_FLAG(volume)] = -1;
199 createNewBitmapBlocks(afsbase, volume);
200 for (
201 i=BLK_BITMAP_POINTERS_START(volume);
202 i<=BLK_BITMAP_POINTERS_END(volume);
206 blockbuffer->buffer[i] = OS_LONG2BE
208 volume->bitmapblockpointers[i-BLK_BITMAP_POINTERS_START(volume)]
211 blockbuffer->buffer[BLK_BITMAP_EXTENSION(volume)] =
212 OS_LONG2BE(volume->bitmapextensionblock);
213 blockbuffer->buffer[BLK_ROOT_DAYS(volume)] = OS_LONG2BE(ds.ds_Days);
214 blockbuffer->buffer[BLK_ROOT_MINS(volume)] = OS_LONG2BE(ds.ds_Minute);
215 blockbuffer->buffer[BLK_ROOT_TICKS(volume)] = OS_LONG2BE(ds.ds_Tick);
216 StrCpyToBstr
218 name,
219 (APTR)((char *)blockbuffer->buffer+(BLK_DISKNAME_START(volume)*4)),
220 MAX_NAME_LENGTH
222 blockbuffer->buffer[volume->SizeBlock-12] = 0;
223 blockbuffer->buffer[volume->SizeBlock-11] = 0;
224 blockbuffer->buffer[BLK_VOLUME_DAYS(volume)] = OS_LONG2BE(ds.ds_Days);
225 blockbuffer->buffer[BLK_VOLUME_MINS(volume)] = OS_LONG2BE(ds.ds_Minute);
226 blockbuffer->buffer[BLK_VOLUME_TICKS(volume)] = OS_LONG2BE(ds.ds_Tick);
227 blockbuffer->buffer[BLK_CREATION_DAYS(volume)] = OS_LONG2BE(ds.ds_Days);
228 blockbuffer->buffer[BLK_CREATION_MINS(volume)] = OS_LONG2BE(ds.ds_Minute);
229 blockbuffer->buffer[BLK_CREATION_TICKS(volume)] = OS_LONG2BE(ds.ds_Tick);
230 blockbuffer->buffer[volume->SizeBlock-4] = 0;
231 blockbuffer->buffer[volume->SizeBlock-3] = 0;
232 blockbuffer->buffer[volume->SizeBlock-2] = 0;
233 blockbuffer->buffer[BLK_SECONDARY_TYPE(volume)] = OS_LONG2BE(ST_ROOT);
234 writeBlock(afsbase, volume, blockbuffer, BLK_CHECKSUM);
235 blockbuffer->flags &= ~BCF_USED;
236 invalidBitmap(afsbase, volume);
237 markBlock(afsbase, volume, volume->rootblock, 0);
238 markBitmaps(afsbase, volume);
239 validBitmap(afsbase, volume);
240 return 0;
243 return ERROR_UNKNOWN;
246 /*******************************************
247 Name : relabel
248 Descr.: rename a volume
249 Input : volume - volume to rename
250 name - new name for volume
251 Output: DOSTRUE for success; DOSFALSE otherwise
252 ********************************************/
253 LONG relabel(struct AFSBase *afsbase, struct Volume *volume,
254 CONST_STRPTR name) {
255 struct BlockCache *blockbuffer;
256 struct DateStamp ds;
258 if (0 == checkValid(afsbase, volume))
260 error = ERROR_DISK_WRITE_PROTECTED;
261 return DOSFALSE;
263 osMediumFree(afsbase, volume, FALSE);
264 blockbuffer=getBlock(afsbase, volume,volume->rootblock);
265 if (blockbuffer == NULL)
266 return DOSFALSE;
267 StrCpyToBstr
269 name,
270 (APTR)((char *)blockbuffer->buffer+(BLK_DISKNAME_START(volume)*4)),
271 MAX_NAME_LENGTH
273 DateStamp(&ds);
274 blockbuffer->buffer[BLK_ROOT_DAYS(volume)] = OS_LONG2BE(ds.ds_Days);
275 blockbuffer->buffer[BLK_ROOT_MINS(volume)] = OS_LONG2BE(ds.ds_Minute);
276 blockbuffer->buffer[BLK_ROOT_TICKS(volume)] = OS_LONG2BE(ds.ds_Tick);
277 blockbuffer->buffer[BLK_VOLUME_DAYS(volume)] = OS_LONG2BE(ds.ds_Days);
278 blockbuffer->buffer[BLK_VOLUME_MINS(volume)] = OS_LONG2BE(ds.ds_Minute);
279 blockbuffer->buffer[BLK_VOLUME_TICKS(volume)] = OS_LONG2BE(ds.ds_Tick);
280 writeBlock(afsbase, volume, blockbuffer, BLK_CHECKSUM);
281 /* update os specific information of the medium */
282 osMediumInit(afsbase, volume, blockbuffer);
283 return DOSTRUE;