grub2: bring back build of aros-side grub2 tools
[AROS.git] / rom / filesys / afs / misc.c
blob6bddc83501590821021ec07f3edb72b2426085f6
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 /**********************************************
27 Name : writeHeader
28 Descr.: update header information (time)
29 Input : volume -
30 blockbuffer - pointer to struct BlockCache
31 containing the headerblock
32 Output: 0 for success; error code otherwise
33 ***********************************************/
34 ULONG writeHeader
36 struct AFSBase *afsbase,
37 struct Volume *volume,
38 struct BlockCache *blockbuffer
41 struct DateStamp ds;
43 /* store current time as modification date for this object and all its ancestors */
44 DateStamp(&ds);
45 for (;;)
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)
51 break;
52 writeBlockDeferred(afsbase, volume, blockbuffer, BLK_CHECKSUM);
53 blockbuffer = getBlock
54 (afsbase, volume, OS_BE2LONG(blockbuffer->buffer[BLK_PARENT(volume)]));
55 if (blockbuffer == NULL)
56 return ERROR_UNKNOWN;
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);
64 return 0;
67 /*******************************************
68 Name : getDiskInfo
69 Descr.: fills a InfoData structure with some
70 Disk info;
71 answer on ACTION_DISK_INFO
72 Input : id - InfoData structure to fill
73 Output: 0 = no error
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! */
86 return 0;
89 /*******************************************
90 Name : inhibit
91 Descr.: forbid/permit access for this volume
92 Input : volume - the volume
93 forbid - DOSTRUE to forbid
94 DOSFALSE to permit access
95 Output: 0 = no error
96 ********************************************/
97 LONG inhibit(struct AFSBase *afsbase, struct Volume *volume, ULONG forbid) {
98 D(bug("[afs 0x%08lX] inhibit(%ld)\n", volume, forbid));
99 if (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;
123 else
124 volume->ioh.ioflags &= ~IOHF_DISK_IN;
127 return 0;
130 /*******************************************
131 Name : markBitmaps
132 Descr.: mark newly allocated bitmapblocks
133 (for format)
134 Input : volume - the volume
135 Output: -
136 ********************************************/
137 void markBitmaps(struct AFSBase *afsbase, struct Volume *volume) {
138 struct BlockCache *blockbuffer;
139 ULONG i,curblock;
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)
148 return;
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)
154 break;
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 /*******************************************
163 Name : format
164 Descr.: initialize a volume
165 Input : volume - volume to initialize
166 name - name of volume
167 dostype - DOS\0/...
168 Output: 0 for success; error code otherwise
169 ********************************************/
170 LONG format
171 (struct AFSBase *afsbase, struct Volume *volume, CONST_STRPTR name,
172 ULONG dostype)
174 struct BlockCache *blockbuffer;
175 struct DateStamp ds;
176 UWORD i;
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;
188 DateStamp(&ds);
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);
198 for (
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);
214 StrCpyToBstr
216 name,
217 (APTR)((char *)blockbuffer->buffer+(BLK_DISKNAME_START(volume)*4)),
218 MAX_NAME_LENGTH
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);
238 return 0;
241 return ERROR_UNKNOWN;
244 /*******************************************
245 Name : relabel
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;
254 struct DateStamp ds;
256 if (0 == checkValid(afsbase, volume))
258 *error = ERROR_DISK_WRITE_PROTECTED;
259 return DOSFALSE;
261 osMediumFree(afsbase, volume, FALSE);
262 blockbuffer=getBlock(afsbase, volume,volume->rootblock);
263 if (blockbuffer == NULL)
264 return DOSFALSE;
265 if (strlen(name) > MAX_NAME_LENGTH)
267 *error = ERROR_LINE_TOO_LONG;
268 return DOSFALSE;
270 StrCpyToBstr
272 name,
273 (APTR)((char *)blockbuffer->buffer+(BLK_DISKNAME_START(volume)*4)),
274 MAX_NAME_LENGTH
276 DateStamp(&ds);
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);
286 return DOSTRUE;