/* SILO I/O Manager for filesystem operations. Copyright (C) 1996 Maurizio Plaza 1996,1997,1999 Jakub Jelinek 2001 Ben Collins This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include static unsigned long long doff; /* Block where partition starts */ static int read_sun_partition (int partno) { int rc; sun_partition sdl; unsigned short csum, *ush; rc = silo_disk_read((char *) &sdl, 512, 0); if (rc != 512) { silo_fatal("Cannot read partition"); return 0; } if (sdl.magic != SUN_LABEL_MAGIC) silo_fatal("Wrong disklabel magic"); for (csum = 0, ush = ((unsigned short *) ((&sdl) + 1)) - 1; ush >= (unsigned short *) &sdl;) csum ^= *ush--; if (csum) printf ("\nWarning: Your disklabel has wrong checksum. Use fdisk to correct it."); doff = (((unsigned long long)sdl.ntrks) * sdl.nsect * sdl.partitions[partno - 1].start_cylinder) << 9; return 1; } static errcode_t silo_open (const char *name, int flags, io_channel * channel) { int partno; io_channel io; if (!name) return EXT2_ET_BAD_DEVICE_NAME; io = (io_channel) malloc (sizeof (struct struct_io_channel)); if (!io) return EXT2_ET_BAD_DEVICE_NAME; memset (io, 0, sizeof (struct struct_io_channel)); io->magic = EXT2_ET_MAGIC_IO_CHANNEL; io->manager = silo_io_manager; io->name = (char *) malloc (strlen (name) + 1); strcpy (io->name, name); io->block_size = bs; io->read_error = 0; io->write_error = 0; doff = 0LL; if (strncmp (name, "/dev/fd0", 8) && silo_disk_partitionable()) { partno = *(name + strlen (name) - 1) - '0'; if (partno && !read_sun_partition (partno)) return EXT2_ET_BAD_DEVICE_NAME; } *channel = io; return 0; } static errcode_t silo_close (io_channel channel) { return 0; } static errcode_t silo_set_blksize (io_channel channel, int blksize) { channel->block_size = bs = blksize; return 0; } static errcode_t silo_read_blk (io_channel channel, unsigned long block, int count, void *data) { int size, got; size = (count < 0) ? -count : count * bs; got = silo_disk_read(data, size, ((unsigned long long)block) * bs + doff); if (got != size) { printf ("\nRead error on block %d (tried %d, got %d)\n", block, size, got); return EXT2_ET_SHORT_READ; } return 0; } static errcode_t silo_write_blk (io_channel channel, unsigned long block, int count, const void *data) { return 0; } static errcode_t silo_flush (io_channel channel) { return 0; } /* The actual I/O Manager. */ static struct struct_io_manager struct_silo_manager = { .magic = EXT2_ET_MAGIC_IO_MANAGER, .name = "SILO I/O Manager", .open = silo_open, .close = silo_close, .set_blksize = silo_set_blksize, .read_blk = silo_read_blk, .write_blk = silo_write_blk, .flush = silo_flush }; io_manager silo_io_manager = &struct_silo_manager; .