1 /* 2 affs.c -- parted support for affs file systems 3 Copyright (C) 1998-2000, 2007 Free Software Foundation, Inc. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #include <config.h> 20 21 #include <parted/parted.h> 22 #include <parted/debug.h> 23 #include <parted/endian.h> 24 25 #include "amiga.h" 26 #include "affs.h" 27 28 #if ENABLE_NLS 29 # include <libintl.h> 30 # define _(String) dgettext (PACKAGE, String) 31 #else 32 # define _(String) (String) 33 #endif /* ENABLE_NLS */ 34 35 static int 36 _affs_probe_root (uint32_t *block, int blocksize) { 37 int i; 38 uint32_t sum; 39 40 if (PED_BE32_TO_CPU (block[0]) != 2) return 0; 41 if (PED_BE32_TO_CPU (block[128*blocksize-1]) != 1) return 0; 42 for (i = 0, sum = 0; i < 128*blocksize; i++) 43 sum += PED_BE32_TO_CPU (block[i]); 44 if (sum) return 0; 45 return 1; 46 } 47 48 static PedGeometry* 49 _generic_affs_probe (PedGeometry* geom, uint32_t kind) 50 { 51 uint32_t *block; 52 PedSector root, len, pos; 53 struct PartitionBlock * part; 54 int blocksize = 1, reserved = 2, prealloc = 0; 55 56 PED_ASSERT (geom != NULL, return NULL); 57 PED_ASSERT (geom->dev != NULL, return NULL); 58 59 /* Finds the blocksize, prealloc and reserved values of the partition block */ 60 if (!(part = ped_malloc (PED_SECTOR_SIZE_DEFAULT*blocksize))) { 61 ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, 62 _("%s : Failed to allocate partition block\n"), __func__); 63 goto error_part; 64 } 65 if (amiga_find_part(geom, part) != NULL) { 66 prealloc = PED_BE32_TO_CPU (part->de_PreAlloc); 67 reserved = PED_BE32_TO_CPU (part->de_Reserved); 68 reserved = reserved == 0 ? 1 : reserved; 69 blocksize = PED_BE32_TO_CPU (part->de_SizeBlock) 70 * PED_BE32_TO_CPU (part->de_SectorPerBlock) / 128; 71 } 72 ped_free (part); 73 74 /* Test boot block */ 75 if (!(block = ped_malloc (PED_SECTOR_SIZE_DEFAULT*blocksize))) { 76 ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, 77 _("%s : Failed to allocate block\n"), __func__); 78 goto error_block; 79 } 80 if (!ped_device_read (geom->dev, block, geom->start, blocksize)) { 81 ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, 82 _("%s : Couldn't read boot block %llu\n"), __func__, geom->start); 83 goto error; 84 } 85 if (PED_BE32_TO_CPU (block[0]) != kind) { 86 goto error; 87 } 88 89 /* Find and test the root block */ 90 len = geom->length / blocksize - reserved; 91 pos = (len - 1) / 2; 92 root = geom->start + (pos + reserved) * blocksize; 93 printf ("Pralloc = %d, Reserved = %d, blocksize = %d, root block at %llu\n", 94 prealloc, reserved, blocksize, root); 95 96 if (!ped_device_read (geom->dev, block, root, blocksize)) { 97 ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, 98 _("%s : Couldn't read root block %llu\n"), __func__, root); 99 goto error; 100 } 101 if (_affs_probe_root(block, blocksize) == 1) { 102 ped_free (block); 103 return ped_geometry_duplicate (geom); 104 } 105 106 error: 107 ped_free (block); 108 error_block: 109 error_part: 110 return NULL; 111 } 112 static PedGeometry* 113 _affs0_probe (PedGeometry* geom) { 114 return _generic_affs_probe (geom, 0x444f5300); 115 } 116 static PedGeometry* 117 _affs1_probe (PedGeometry* geom) { 118 return _generic_affs_probe (geom, 0x444f5301); 119 } 120 static PedGeometry* 121 _affs2_probe (PedGeometry* geom) { 122 return _generic_affs_probe (geom, 0x444f5302); 123 } 124 static PedGeometry* 125 _affs3_probe (PedGeometry* geom) { 126 return _generic_affs_probe (geom, 0x444f5303); 127 } 128 static PedGeometry* 129 _affs4_probe (PedGeometry* geom) { 130 return _generic_affs_probe (geom, 0x444f5304); 131 } 132 static PedGeometry* 133 _affs5_probe (PedGeometry* geom) { 134 return _generic_affs_probe (geom, 0x444f5305); 135 } 136 static PedGeometry* 137 _affs6_probe (PedGeometry* geom) { 138 return _generic_affs_probe (geom, 0x444f5306); 139 } 140 static PedGeometry* 141 _affs7_probe (PedGeometry* geom) { 142 return _generic_affs_probe (geom, 0x444f5307); 143 } 144 static PedGeometry* 145 _amufs_probe (PedGeometry* geom) { 146 return _generic_affs_probe (geom, 0x6d754653); 147 } 148 static PedGeometry* 149 _amufs0_probe (PedGeometry* geom) { 150 return _generic_affs_probe (geom, 0x6d754600); 151 } 152 static PedGeometry* 153 _amufs1_probe (PedGeometry* geom) { 154 return _generic_affs_probe (geom, 0x6d754601); 155 } 156 static PedGeometry* 157 _amufs2_probe (PedGeometry* geom) { 158 return _generic_affs_probe (geom, 0x6d754602); 159 } 160 static PedGeometry* 161 _amufs3_probe (PedGeometry* geom) { 162 return _generic_affs_probe (geom, 0x6d754603); 163 } 164 static PedGeometry* 165 _amufs4_probe (PedGeometry* geom) { 166 return _generic_affs_probe (geom, 0x6d754604); 167 } 168 static PedGeometry* 169 _amufs5_probe (PedGeometry* geom) { 170 return _generic_affs_probe (geom, 0x6d754605); 171 } 172 173 static PedFileSystemOps _affs0_ops = { 174 .probe = _affs0_probe, 175 .clobber = NULL, 176 .open = NULL, 177 .create = NULL, 178 .close = NULL, 179 .check = NULL, 180 .resize = NULL, 181 .copy = NULL, 182 .get_create_constraint = NULL, 183 .get_copy_constraint = NULL, 184 .get_resize_constraint = NULL 185 }; 186 static PedFileSystemOps _affs1_ops = { 187 .probe = _affs1_probe, 188 .clobber = NULL, 189 .open = NULL, 190 .create = NULL, 191 .close = NULL, 192 .check = NULL, 193 .resize = NULL, 194 .copy = NULL, 195 .get_create_constraint = NULL, 196 .get_copy_constraint = NULL, 197 .get_resize_constraint = NULL 198 }; 199 static PedFileSystemOps _affs2_ops = { 200 .probe = _affs2_probe, 201 .clobber = NULL, 202 .open = NULL, 203 .create = NULL, 204 .close = NULL, 205 .check = NULL, 206 .resize = NULL, 207 .copy = NULL, 208 .get_create_constraint = NULL, 209 .get_copy_constraint = NULL, 210 .get_resize_constraint = NULL 211 }; 212 static PedFileSystemOps _affs3_ops = { 213 .probe = _affs3_probe, 214 .clobber = NULL, 215 .open = NULL, 216 .create = NULL, 217 .close = NULL, 218 .check = NULL, 219 .resize = NULL, 220 .copy = NULL, 221 .get_create_constraint = NULL, 222 .get_copy_constraint = NULL, 223 .get_resize_constraint = NULL 224 }; 225 static PedFileSystemOps _affs4_ops = { 226 .probe = _affs4_probe, 227 .clobber = NULL, 228 .open = NULL, 229 .create = NULL, 230 .close = NULL, 231 .check = NULL, 232 .resize = NULL, 233 .copy = NULL, 234 .get_create_constraint = NULL, 235 .get_copy_constraint = NULL, 236 .get_resize_constraint = NULL 237 }; 238 static PedFileSystemOps _affs5_ops = { 239 .probe = _affs5_probe, 240 .clobber = NULL, 241 .open = NULL, 242 .create = NULL, 243 .close = NULL, 244 .check = NULL, 245 .resize = NULL, 246 .copy = NULL, 247 .get_create_constraint = NULL, 248 .get_copy_constraint = NULL, 249 .get_resize_constraint = NULL 250 }; 251 static PedFileSystemOps _affs6_ops = { 252 .probe = _affs6_probe, 253 .clobber = NULL, 254 .open = NULL, 255 .create = NULL, 256 .close = NULL, 257 .check = NULL, 258 .resize = NULL, 259 .copy = NULL, 260 .get_create_constraint = NULL, 261 .get_copy_constraint = NULL, 262 .get_resize_constraint = NULL 263 }; 264 static PedFileSystemOps _affs7_ops = { 265 .probe = _affs7_probe, 266 .clobber = NULL, 267 .open = NULL, 268 .create = NULL, 269 .close = NULL, 270 .check = NULL, 271 .resize = NULL, 272 .copy = NULL, 273 .get_create_constraint = NULL, 274 .get_copy_constraint = NULL, 275 .get_resize_constraint = NULL 276 }; 277 static PedFileSystemOps _amufs_ops = { 278 .probe = _amufs_probe, 279 .clobber = NULL, 280 .open = NULL, 281 .create = NULL, 282 .close = NULL, 283 .check = NULL, 284 .resize = NULL, 285 .copy = NULL, 286 .get_create_constraint = NULL, 287 .get_copy_constraint = NULL, 288 .get_resize_constraint = NULL 289 }; 290 static PedFileSystemOps _amufs0_ops = { 291 .probe = _amufs0_probe, 292 .clobber = NULL, 293 .open = NULL, 294 .create = NULL, 295 .close = NULL, 296 .check = NULL, 297 .resize = NULL, 298 .copy = NULL, 299 .get_create_constraint = NULL, 300 .get_copy_constraint = NULL, 301 .get_resize_constraint = NULL 302 }; 303 static PedFileSystemOps _amufs1_ops = { 304 .probe = _amufs1_probe, 305 .clobber = NULL, 306 .open = NULL, 307 .create = NULL, 308 .close = NULL, 309 .check = NULL, 310 .resize = NULL, 311 .copy = NULL, 312 .get_create_constraint = NULL, 313 .get_copy_constraint = NULL, 314 .get_resize_constraint = NULL 315 }; 316 static PedFileSystemOps _amufs2_ops = { 317 .probe = _amufs2_probe, 318 .clobber = NULL, 319 .open = NULL, 320 .create = NULL, 321 .close = NULL, 322 .check = NULL, 323 .resize = NULL, 324 .copy = NULL, 325 .get_create_constraint = NULL, 326 .get_copy_constraint = NULL, 327 .get_resize_constraint = NULL 328 }; 329 static PedFileSystemOps _amufs3_ops = { 330 .probe = _amufs3_probe, 331 .clobber = NULL, 332 .open = NULL, 333 .create = NULL, 334 .close = NULL, 335 .check = NULL, 336 .resize = NULL, 337 .copy = NULL, 338 .get_create_constraint = NULL, 339 .get_copy_constraint = NULL, 340 .get_resize_constraint = NULL 341 }; 342 static PedFileSystemOps _amufs4_ops = { 343 .probe = _amufs4_probe, 344 .clobber = NULL, 345 .open = NULL, 346 .create = NULL, 347 .close = NULL, 348 .check = NULL, 349 .resize = NULL, 350 .copy = NULL, 351 .get_create_constraint = NULL, 352 .get_copy_constraint = NULL, 353 .get_resize_constraint = NULL 354 }; 355 static PedFileSystemOps _amufs5_ops = { 356 .probe = _amufs5_probe, 357 .clobber = NULL, 358 .open = NULL, 359 .create = NULL, 360 .close = NULL, 361 .check = NULL, 362 .resize = NULL, 363 .copy = NULL, 364 .get_create_constraint = NULL, 365 .get_copy_constraint = NULL, 366 .get_resize_constraint = NULL 367 }; 368 369 #define AFFS_BLOCK_SIZES ((int[5]){512, 1024, 2048, 4096, 0}) 370 #define AMUFS_BLOCK_SIZES ((int[2]){512, 0}) 371 372 373 PedFileSystemType _affs0_type = { 374 .next = NULL, 375 .ops = &_affs0_ops, 376 .name = "affs0", 377 .block_sizes = AFFS_BLOCK_SIZES 378 }; 379 PedFileSystemType _affs1_type = { 380 .next = NULL, 381 .ops = &_affs1_ops, 382 .name = "affs1", 383 .block_sizes = AFFS_BLOCK_SIZES 384 }; 385 PedFileSystemType _affs2_type = { 386 .next = NULL, 387 .ops = &_affs2_ops, 388 .name = "affs2", 389 .block_sizes = AFFS_BLOCK_SIZES 390 }; 391 PedFileSystemType _affs3_type = { 392 .next = NULL, 393 .ops = &_affs3_ops, 394 .name = "affs3", 395 .block_sizes = AFFS_BLOCK_SIZES 396 }; 397 PedFileSystemType _affs4_type = { 398 .next = NULL, 399 .ops = &_affs4_ops, 400 .name = "affs4", 401 .block_sizes = AFFS_BLOCK_SIZES 402 }; 403 PedFileSystemType _affs5_type = { 404 .next = NULL, 405 .ops = &_affs5_ops, 406 .name = "affs5", 407 .block_sizes = AFFS_BLOCK_SIZES 408 }; 409 PedFileSystemType _affs6_type = { 410 .next = NULL, 411 .ops = &_affs6_ops, 412 .name = "affs6", 413 .block_sizes = AFFS_BLOCK_SIZES 414 }; 415 PedFileSystemType _affs7_type = { 416 .next = NULL, 417 .ops = &_affs7_ops, 418 .name = "affs7", 419 .block_sizes = AFFS_BLOCK_SIZES 420 }; 421 PedFileSystemType _amufs_type = { 422 .next = NULL, 423 .ops = &_amufs_ops, 424 .name = "amufs", 425 .block_sizes = AMUFS_BLOCK_SIZES 426 }; 427 PedFileSystemType _amufs0_type = { 428 .next = NULL, 429 .ops = &_amufs0_ops, 430 .name = "amufs0", 431 .block_sizes = AMUFS_BLOCK_SIZES 432 }; 433 PedFileSystemType _amufs1_type = { 434 .next = NULL, 435 .ops = &_amufs1_ops, 436 .name = "amufs1", 437 .block_sizes = AMUFS_BLOCK_SIZES 438 }; 439 PedFileSystemType _amufs2_type = { 440 .next = NULL, 441 .ops = &_amufs2_ops, 442 .name = "amufs2", 443 .block_sizes = AMUFS_BLOCK_SIZES 444 }; 445 PedFileSystemType _amufs3_type = { 446 .next = NULL, 447 .ops = &_amufs3_ops, 448 .name = "amufs3", 449 .block_sizes = AMUFS_BLOCK_SIZES 450 }; 451 PedFileSystemType _amufs4_type = { 452 .next = NULL, 453 .ops = &_amufs4_ops, 454 .name = "amufs4", 455 .block_sizes = AMUFS_BLOCK_SIZES 456 }; 457 PedFileSystemType _amufs5_type = { 458 .next = NULL, 459 .ops = &_amufs5_ops, 460 .name = "amufs5", 461 .block_sizes = AMUFS_BLOCK_SIZES 462 };