diff options
| author | Michael Brown | 2006-03-17 15:09:45 +0100 |
|---|---|---|
| committer | Michael Brown | 2006-03-17 15:09:45 +0100 |
| commit | a2b15fd1febc77aecfc99b9d366b13f0bc17bebd (patch) | |
| tree | 47cef6e48756f1d39f6404af8de70023a72c10bb /src/filo/fs | |
| parent | Prefix semantics have changed (diff) | |
| download | ipxe-a2b15fd1febc77aecfc99b9d366b13f0bc17bebd.tar.gz ipxe-a2b15fd1febc77aecfc99b9d366b13f0bc17bebd.tar.xz ipxe-a2b15fd1febc77aecfc99b9d366b13f0bc17bebd.zip | |
GPXE code cleanup and purge.
Diffstat (limited to 'src/filo/fs')
| -rw-r--r-- | src/filo/fs/blockdev.c | 383 | ||||
| -rw-r--r-- | src/filo/fs/eltorito.c | 147 | ||||
| -rw-r--r-- | src/filo/fs/fat.h | 100 | ||||
| -rw-r--r-- | src/filo/fs/filesys.h | 233 | ||||
| -rw-r--r-- | src/filo/fs/fsys_ext2fs.c | 779 | ||||
| -rw-r--r-- | src/filo/fs/fsys_fat.c | 494 | ||||
| -rw-r--r-- | src/filo/fs/fsys_iso9660.c | 348 | ||||
| -rw-r--r-- | src/filo/fs/fsys_jfs.c | 403 | ||||
| -rw-r--r-- | src/filo/fs/fsys_minix.c | 534 | ||||
| -rw-r--r-- | src/filo/fs/fsys_reiserfs.c | 1239 | ||||
| -rw-r--r-- | src/filo/fs/fsys_xfs.c | 624 | ||||
| -rw-r--r-- | src/filo/fs/iso9660.h | 168 | ||||
| -rw-r--r-- | src/filo/fs/jfs.h | 601 | ||||
| -rw-r--r-- | src/filo/fs/shared.h | 1 | ||||
| -rw-r--r-- | src/filo/fs/vfs.c | 193 | ||||
| -rw-r--r-- | src/filo/fs/xfs.h | 546 |
16 files changed, 0 insertions, 6793 deletions
diff --git a/src/filo/fs/blockdev.c b/src/filo/fs/blockdev.c deleted file mode 100644 index f159ff2f5..000000000 --- a/src/filo/fs/blockdev.c +++ /dev/null @@ -1,383 +0,0 @@ -#include <etherboot.h> - -#include <lib.h> -#include <fs.h> - -#define DEBUG_THIS DEBUG_BLOCKDEV -#include <debug.h> - -#define NUM_CACHE 64 -static unsigned char buf_cache[NUM_CACHE][512]; -static unsigned long cache_sect[NUM_CACHE]; - -static char dev_name[256]; - -int dev_type = -1; -int dev_drive = -1; -unsigned long part_start; -unsigned long part_length; -int using_devsize; - -static inline int has_pc_part_magic(unsigned char *sect) -{ - return sect[510]==0x55 && sect[511]==0xAA; -} - -static inline int is_pc_extended_part(unsigned char type) -{ - return type==5 || type==0xf || type==0x85; -} - -/* IBM-PC/MS-DOS style partitioning scheme */ -static int open_pc_partition(int part, unsigned long *start_p, - unsigned long *length_p) -{ - /* Layout of PC partition table */ - struct pc_partition { - unsigned char boot; - unsigned char head; - unsigned char sector; - unsigned char cyl; - unsigned char type; - unsigned char e_head; - unsigned char e_sector; - unsigned char e_cyl; - unsigned char start_sect[4]; /* unaligned little endian */ - unsigned char nr_sects[4]; /* ditto */ - } *p; - unsigned char buf[512]; - - /* PC partition probe */ - if (!devread(0, 0, sizeof(buf), buf)) { - debug("device read failed\n"); - return 0; - } - if (!has_pc_part_magic(buf)) { - debug("pc partition magic number not found\n"); - //debug_hexdump(buf, 512); - return PARTITION_UNKNOWN; - } - p = (struct pc_partition *) (buf + 0x1be); - if (part < 4) { - /* Primary partition */ - p += part; - if (p->type==0 || is_pc_extended_part(p->type)) { - printf("Partition %d does not exist\n", part+1); - return 0; - } - *start_p = get_le32(p->start_sect); - *length_p = get_le32(p->nr_sects); - return 1; - } else { - /* Extended partition */ - int i; - int cur_part; - unsigned long ext_start, cur_table; - /* Search for the extended partition - * which contains logical partitions */ - for (i = 0; i < 4; i++) { - if (is_pc_extended_part(p[i].type)) - break; - } - if (i >= 4) { - printf("Extended partition not found\n"); - return 0; - } - debug("Extended partition at %d\n", i+1); - /* Visit each logical partition labels */ - ext_start = get_le32(p[i].start_sect); - cur_table = ext_start; - cur_part = 4; - for (;;) { - debug("cur_part=%d at %lu\n", cur_part, cur_table); - if (!devread(cur_table, 0, sizeof(buf), buf)) - return 0; - if (!has_pc_part_magic(buf)) { - debug("no magic\n"); - break; - } - - p = (struct pc_partition *) (buf + 0x1be); - /* First entry is the logical partition */ - if (cur_part == part) { - if (p->type==0) { - printf("Partition %d is empty\n", part+1); - return 0; - } - *start_p = cur_table + get_le32(p->start_sect); - *length_p = get_le32(p->nr_sects); - return 1; - } - /* Second entry is link to next partition */ - if (!is_pc_extended_part(p[1].type)) { - debug("no link\n"); - break; - } - cur_table = ext_start + get_le32(p[1].start_sect); - - cur_part++; - } - printf("Logical partition %d not exist\n", part+1); - return 0; - } -} - -static void flush_cache(void) -{ - int i; - for (i = 0; i < NUM_CACHE; i++) - cache_sect[i] = (unsigned long) -1; -} - -static int parse_device_name(const char *name, int *type, int *drive, - int *part, uint64_t *offset, uint64_t *length) -{ - *offset = *length = 0; - - if (memcmp(name, "hd", 2) == 0) { - *type = DISK_IDE; - name += 2; - if (*name < 'a' || *name > 'z') { - printf("Invalid drive\n"); - return 0; - } - *drive = *name - 'a'; - name++; - } else if (memcmp(name, "mem", 3) == 0) { - *type = DISK_MEM; - name += 3; - *drive = 0; - } else if (memcmp(name, "ud", 2) == 0) { - *type = DISK_USB; - name += 2; - if (*name < 'a' || *name > 'z') { - printf("Invalid drive\n"); - return 0; - } - *drive = *name - 'a'; - name++; - } else { - printf("Unknown device type\n"); - return 0; - } - - *part = (int) simple_strtoull(name, (char **)&name, 0); - - if (*name == '@') { - name++; - *offset = strtoull_with_suffix(name, (char **)&name, 0); - if (*name == ',') - *length = strtoull_with_suffix(name+1, (char **)&name, 0); -// debug("offset=%#Lx length=%#Lx\n", *offset, *length); - } - - if (*name != '\0') { - printf("Can't parse device name\n"); - return 0; - } - - return 1; -} - -int devopen(const char *name, int *reopen) -{ - int type, drive, part; - uint64_t offset, length; - uint32_t disk_size = 0; - - /* Don't re-open the device that's already open */ - if (strcmp(name, dev_name) == 0) { - debug("already open\n"); - *reopen = 1; - return 1; - } - *reopen = 0; - - if (!parse_device_name(name, &type, &drive, &part, &offset, &length)) { - debug("failed to parse device name: %s\n", name); - return 0; - } - - /* Do simple sanity check first */ - if (offset & 0x1ff) { - printf("Device offset must be multiple of 512\n"); - return 0; - } - if (length & 0x1ff) { - debugx("WARNING: length is rounded up to multiple of 512\n"); - length = (length + 0x1ff) & ~0x1ff; - } - - switch (type) { -#ifdef IDE_DISK - case DISK_IDE: - if (ide_probe(drive) != 0) { - debug("failed to open ide\n"); - return 0; - } - disk_size = (uint32_t) -1; /* FIXME */ - break; -#endif - case DISK_MEM: - disk_size = 1 << (32 - 9); /* 4GB/512-byte */ - break; -#ifdef USB_DISK - case DISK_USB: - if (usb_probe(drive) != 0) { - debug("failed to open usb\n"); - return 0; - } - disk_size = (uint32_t) -1; /* FIXME */ - break; -#endif - default: - printf("Unknown device type %d\n", type); - return 0; - } - - if (dev_type != type || dev_drive != drive) - flush_cache(); - - /* start with whole disk */ - dev_type = type; - dev_drive = drive; - part_start = 0; - part_length = disk_size; - using_devsize = 1; - - if (part != 0) { - /* partition is specified */ - int ret; - ret = open_pc_partition(part - 1, &part_start, &part_length); - if (ret == PARTITION_UNKNOWN) { - ret = open_eltorito_image(part - 1, &part_start, &part_length); - if (ret == PARTITION_UNKNOWN) { - printf("Unrecognized partitioning scheme\n"); - return 0; - } - } - if (ret == 0) { - debug("can't open partition %d\n", part); - return 0; - } - - debug("Partition %d start %lu length %lu\n", part, - part_start, part_length); - } - - if (offset) { - if (offset >= (uint64_t) part_length << 9) { - printf("Device offset is too high\n"); - return 0; - } - part_start += offset >> 9; - part_length -= offset >> 9; - debug("after offset: start %lu, length %lu\n", part_start, part_length); - } - - if (length) { - if (length > (uint64_t) part_length << 9) { - printf("Specified length exceeds the size of device\n"); - return 0; - } - part_length = length >> 9; - debug("after length: length %lu\n", part_length); - using_devsize = 0; - } - - strncpy(dev_name, name, sizeof(dev_name)-1); - - return 1; -} - -/* Read a sector from opened device with simple/stupid buffer cache */ -static void *read_sector(unsigned long sector) -{ - unsigned int hash; - void *buf; - int i; - - /* If reading memory, just return the memory as the buffer */ - if (dev_type == DISK_MEM) { - unsigned long phys = sector << 9; - //debug("mem: %#lx\n", phys); - return phys_to_virt(phys); - } - - /* Search in the cache */ - hash = sector % NUM_CACHE; - buf = buf_cache[hash]; - if (cache_sect[hash] != sector) { - cache_sect[hash] = (unsigned long) -1; - switch (dev_type) { -#ifdef IDE_DISK - case DISK_IDE: - if (ide_read(dev_drive, sector, buf) != 0) - goto readerr; - break; -#endif -#ifdef USB_DISK - case DISK_USB: - if (usb_read(dev_drive, sector, buf) != 0) - goto readerr; - break; -#endif - default: - printf("read_sector: device not open\n"); - return 0; - } - cache_sect[hash] = sector; - } -#if 0 - printf("in read_sector:\n"); - for(i=0;i<128;i++) { - if((i%4)==0) printf("\n %08x:",i*4); - printf(" %08x ",(uint32_t)*((uint32_t *)buf+i)); - } -#endif - - return buf; - -readerr: - printf("Disk read error dev_type=%d drive=%d sector=%x\n", - dev_type, dev_drive, sector); - dev_name[0] = '\0'; /* force re-open the device next time */ - return 0; -} - -int devread(unsigned long sector, unsigned long byte_offset, - unsigned long byte_len, void *buf) -{ - char *sector_buffer; - char *dest = buf; - unsigned long len; - int i; - - sector += byte_offset >> 9; - byte_offset &= 0x1ff; - - if (sector + ((byte_len + 0x1ff) >> 9) > part_length) { - printf("Attempt to read out of device/partition\n"); - debug("sector=%x part_length=%x byte_len=%x\n", - sector, part_length, byte_len); - return 0; - } - - while (byte_len > 0) { - sector_buffer = read_sector(part_start + sector); - if (!sector_buffer) { - debug("read sector failed\n"); - return 0; - } - len = 512 - byte_offset; - if (len > byte_len) - len = byte_len; - memcpy(dest, sector_buffer + byte_offset, len); - sector++; - byte_offset = 0; - byte_len -= len; - dest += len; - } - - return 1; -} diff --git a/src/filo/fs/eltorito.c b/src/filo/fs/eltorito.c deleted file mode 100644 index 30b663d0d..000000000 --- a/src/filo/fs/eltorito.c +++ /dev/null @@ -1,147 +0,0 @@ - -#include <etherboot.h> -#include <fs.h> -#include <lib.h> - -#define DEBUG_THIS DEBUG_ELTORITO -#include <debug.h> - -#define ELTORITO_PLATFORM_X86 0 -#define ELTORITO_PLATFORM_PPC 1 -#define ELTORITO_PLATFORM_MAC 2 -#include <bits/eltorito.h> - -#ifndef ELTORITO_PLATFORM -#error "ELTORITO_PLATFORM is not defined for this arch" -#endif - -/* El Torito boot record at sector 0x11 of bootable CD */ -struct boot_record { - uint8_t ind; - uint8_t iso_id[5]; - uint8_t version; - uint8_t boot_id[32]; - uint8_t reserved[32]; - uint8_t catalog_offset[4]; -}; - -/* First entry of the catalog */ -struct validation_entry { - uint8_t header_id; - uint8_t platform; - uint8_t reserved[2]; - uint8_t id[24]; - uint8_t checksum[2]; - uint8_t key55; - uint8_t keyAA; -}; - -/* Initial/Default catalog entry */ -struct default_entry { - uint8_t boot_id; - uint8_t media_type; -#define MEDIA_MASK 0x0f -#define MEDIA_NOEMU 0 -#define MEDIA_1200_FD 1 -#define MEDIA_1440_FD 2 -#define MEDIA_2880_FD 3 -#define MEDIA_HD 4 - uint8_t load_segment[2]; - uint8_t system_type; - uint8_t reserved; - uint8_t sector_count[2]; - uint8_t start_sector[4]; - uint8_t reserved_too[20]; -}; - -/* Find El-Torito boot disk image */ -int open_eltorito_image(int part, unsigned long *offset_p, - unsigned long *length_p) -{ - struct boot_record boot_record; - uint32_t cat_offset; - uint8_t catalog[2048]; - struct validation_entry *ve; - int i, sum; - struct default_entry *de; - - /* We always use 512-byte "soft sector", but - * El-Torito uses 2048-byte CD-ROM sector */ - - /* Boot Record is at sector 0x11 */ - if (!devread(0x11<<2, 0, sizeof boot_record, &boot_record)) - return 0; - - if (boot_record.ind != 0 - || memcmp(boot_record.iso_id, "CD001", 5) != 0 - || memcmp(boot_record.boot_id, "EL TORITO SPECIFICATION", 23) - != 0) { - debug("No El-Torito signature\n"); - return PARTITION_UNKNOWN; - } - - if (part != 0) { - printf("El-Torito entries other than Initial/Default is not supported\n"); - return 0; - } - - cat_offset = get_le32(boot_record.catalog_offset); - debug("El-Torito boot catalog at sector %u\n", cat_offset); - if (!devread(cat_offset<<2, 0, 2048, catalog)) - return 0; - - /* Validate the catalog */ - ve = (void *) catalog; - //debug_hexdump(ve, sizeof *ve); - if (ve->header_id != 1 || ve->key55 != 0x55 || ve->keyAA != 0xAA) { - printf("Invalid El Torito boot catalog\n"); - return 0; - } - /* All words must sum up to zero */ - sum = 0; - for (i = 0; i < sizeof(*ve); i += 2) - sum += get_le16(&catalog[i]); - sum &= 0xffff; - if (sum != 0) { - printf("El Torito boot catalog verify failed\n"); - return 0; - } - debug("id='%.*s'\n", sizeof ve->id, ve->id); - - /* Platform check is warning only, because we won't directly execute - * the image. Just mounting it should be safe. */ - if (ve->platform != ELTORITO_PLATFORM){ - debugx("WARNING: Boot disk for different platform: %d\n", ve->platform); - } - - /* Just support initial/default entry for now */ - de = (void *) (ve + 1); - if (de->boot_id != 0x88) { - debugx("WARNING: Default boot entry is not bootable\n"); - } - - switch (de->media_type & MEDIA_MASK) { - case MEDIA_NOEMU: - printf("Disc doesn't use boot disk emulation\n"); - return 0; - case MEDIA_1200_FD: - *length_p = 1200*1024/512; - break; - case MEDIA_1440_FD: - *length_p = 1440*1024/512; - break; - case MEDIA_2880_FD: - *length_p = 2880*1024/512; - break; - case MEDIA_HD: - /* FIXME: read partition table and return first partition. - * Spec states emulation HD has only one partition and it must - * be the first partition */ - printf("Disc uses hard disk emulation - not supported\n"); - return 0; - } - *offset_p = get_le32(de->start_sector) << 2; - debug("offset=%#lx length=%#lx\n", *offset_p, *length_p); - - return 1; -} diff --git a/src/filo/fs/fat.h b/src/filo/fs/fat.h deleted file mode 100644 index 7fed6bacb..000000000 --- a/src/filo/fs/fat.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2001 Free Software Foundation, Inc. - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - - -/* - * Defines for the FAT BIOS Parameter Block (embedded in the first block - * of the partition. - */ - -typedef __signed__ char __s8; -typedef unsigned char __u8; -typedef __signed__ short __s16; -typedef unsigned short __u16; -typedef __signed__ int __s32; -typedef unsigned int __u32; - -/* Note that some shorts are not aligned, and must therefore - * be declared as array of two bytes. - */ -struct fat_bpb { - __s8 ignored[3]; /* Boot strap short or near jump */ - __s8 system_id[8]; /* Name - can be used to special case - partition manager volumes */ - __u8 bytes_per_sect[2]; /* bytes per logical sector */ - __u8 sects_per_clust;/* sectors/cluster */ - __u8 reserved_sects[2]; /* reserved sectors */ - __u8 num_fats; /* number of FATs */ - __u8 dir_entries[2]; /* root directory entries */ - __u8 short_sectors[2]; /* number of sectors */ - __u8 media; /* media code (unused) */ - __u16 fat_length; /* sectors/FAT */ - __u16 secs_track; /* sectors per track */ - __u16 heads; /* number of heads */ - __u32 hidden; /* hidden sectors (unused) */ - __u32 long_sectors; /* number of sectors (if short_sectors == 0) */ - - /* The following fields are only used by FAT32 */ - __u32 fat32_length; /* sectors/FAT */ - __u16 flags; /* bit 8: fat mirroring, low 4: active fat */ - __u8 version[2]; /* major, minor filesystem version */ - __u32 root_cluster; /* first cluster in root directory */ - __u16 info_sector; /* filesystem info sector */ - __u16 backup_boot; /* backup boot sector */ - __u16 reserved2[6]; /* Unused */ -}; - -#define FAT_CVT_U16(bytarr) (* (__u16*)(bytarr)) - -/* - * Defines how to differentiate a 12-bit and 16-bit FAT. - */ - -#define FAT_MAX_12BIT_CLUST 4087 /* 4085 + 2 */ - -/* - * Defines for the file "attribute" byte - */ - -#define FAT_ATTRIB_OK_MASK 0x37 -#define FAT_ATTRIB_NOT_OK_MASK 0xC8 -#define FAT_ATTRIB_DIR 0x10 -#define FAT_ATTRIB_LONGNAME 0x0F - -/* - * Defines for FAT directory entries - */ - -#define FAT_DIRENTRY_LENGTH 32 - -#define FAT_DIRENTRY_ATTRIB(entry) \ - (*((unsigned char *) (entry+11))) -#define FAT_DIRENTRY_VALID(entry) \ - ( ((*((unsigned char *) entry)) != 0) \ - && ((*((unsigned char *) entry)) != 0xE5) \ - && !(FAT_DIRENTRY_ATTRIB(entry) & FAT_ATTRIB_NOT_OK_MASK) ) -#define FAT_DIRENTRY_FIRST_CLUSTER(entry) \ - ((*((unsigned short *) (entry+26)))+(*((unsigned short *) (entry+20)) << 16)) -#define FAT_DIRENTRY_FILELENGTH(entry) \ - (*((unsigned long *) (entry+28))) - -#define FAT_LONGDIR_ID(entry) \ - (*((unsigned char *) (entry))) -#define FAT_LONGDIR_ALIASCHECKSUM(entry) \ - (*((unsigned char *) (entry+13))) diff --git a/src/filo/fs/filesys.h b/src/filo/fs/filesys.h deleted file mode 100644 index f81bebe78..000000000 --- a/src/filo/fs/filesys.h +++ /dev/null @@ -1,233 +0,0 @@ -/* GRUB compatibility header */ - -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2003 Free Software Foundation, Inc. - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -//#include <lib.h> -#include <etherboot.h> - -#include <fs.h> - -/* This disables some portion of code */ -#define STAGE1_5 1 - -static inline int -substring (const char *s1, const char *s2) -{ - while (*s1 == *s2) - { - /* The strings match exactly. */ - if (! *(s1++)) - return 0; - s2 ++; - } - - /* S1 is a substring of S2. */ - if (*s1 == 0) - return -1; - - /* S1 isn't a substring. */ - return 1; -} - -#define grub_memmove memmove -#define grub_strcmp strcmp - -#define MAXINT 0x7fffffff - -/* This is only used by fsys_* to determine if it's hard disk. If it is, - * they try to guess filesystem type by partition type. I guess it is - * not necessory, so hardcoded to 0 (first floppy) --ts1 */ -#define current_drive 0 - -/* Ditto */ -#define current_slice 0 - -extern unsigned long part_start; -extern unsigned long part_length; -extern int filepos; -extern int filemax; -extern int fsmax; - -/* Error codes (descriptions are in common.c) */ -typedef enum -{ - ERR_NONE = 0, - ERR_BAD_FILENAME, - ERR_BAD_FILETYPE, - ERR_BAD_GZIP_DATA, - ERR_BAD_GZIP_HEADER, - ERR_BAD_PART_TABLE, - ERR_BAD_VERSION, - ERR_BELOW_1MB, - ERR_BOOT_COMMAND, - ERR_BOOT_FAILURE, - ERR_BOOT_FEATURES, - ERR_DEV_FORMAT, - ERR_DEV_VALUES, - ERR_EXEC_FORMAT, - ERR_FILELENGTH, - ERR_FILE_NOT_FOUND, - ERR_FSYS_CORRUPT, - ERR_FSYS_MOUNT, - ERR_GEOM, - ERR_NEED_LX_KERNEL, - ERR_NEED_MB_KERNEL, - ERR_NO_DISK, - ERR_NO_PART, - ERR_NUMBER_PARSING, - ERR_OUTSIDE_PART, - ERR_READ, - ERR_SYMLINK_LOOP, - ERR_UNRECOGNIZED, - ERR_WONT_FIT, - ERR_WRITE, - ERR_BAD_ARGUMENT, - ERR_UNALIGNED, - ERR_PRIVILEGED, - ERR_DEV_NEED_INIT, - ERR_NO_DISK_SPACE, - ERR_NUMBER_OVERFLOW, - - MAX_ERR_NUM -} grub_error_t; - -extern grub_error_t errnum; - -#define grub_open file_open -#define grub_read file_read -#define grub_seek file_seek -#define grub_close file_close - -/* instrumentation variables */ -/* (Not used in FILO) */ -extern void (*disk_read_hook) (int, int, int); -extern void (*disk_read_func) (int, int, int); - -#define FSYS_BUFLEN 0x8000 -extern char FSYS_BUF[FSYS_BUFLEN]; - -#define print_possibilities 0 - -#define SECTOR_SIZE 512 -#define SECTOR_BITS 9 - -#ifdef FSYS_FAT -int fat_mount (void); -int fat_read (char *buf, int len); -int fat_dir (char *dirname); -#endif - -#ifdef FSYS_EXT2FS -int ext2fs_mount (void); -int ext2fs_read (char *buf, int len); -int ext2fs_dir (char *dirname); -#endif - -#ifdef FSYS_MINIX -int minix_mount (void); -int minix_read (char *buf, int len); -int minix_dir (char *dirname); -#endif - -#ifdef FSYS_REISERFS -int reiserfs_mount (void); -int reiserfs_read (char *buf, int len); -int reiserfs_dir (char *dirname); -int reiserfs_embed (int *start_sector, int needed_sectors); -#endif - -#ifdef FSYS_JFS -int jfs_mount (void); -int jfs_read (char *buf, int len); -int jfs_dir (char *dirname); -int jfs_embed (int *start_sector, int needed_sectors); -#endif - -#ifdef FSYS_XFS -int xfs_mount (void); -int xfs_read (char *buf, int len); -int xfs_dir (char *dirname); -#endif - -#ifdef FSYS_ISO9660 -int iso9660_mount (void); -int iso9660_read (char *buf, int len); -int iso9660_dir (char *dirname); -#endif - -/* This is not a flag actually, but used as if it were a flag. */ -#define PC_SLICE_TYPE_HIDDEN_FLAG 0x10 - -#define PC_SLICE_TYPE_NONE 0 -#define PC_SLICE_TYPE_FAT12 1 -#define PC_SLICE_TYPE_FAT16_LT32M 4 -#define PC_SLICE_TYPE_EXTENDED 5 -#define PC_SLICE_TYPE_FAT16_GT32M 6 -#define PC_SLICE_TYPE_FAT32 0xb -#define PC_SLICE_TYPE_FAT32_LBA 0xc -#define PC_SLICE_TYPE_FAT16_LBA 0xe -#define PC_SLICE_TYPE_WIN95_EXTENDED 0xf -#define PC_SLICE_TYPE_EZD 0x55 -#define PC_SLICE_TYPE_MINIX 0x80 -#define PC_SLICE_TYPE_LINUX_MINIX 0x81 -#define PC_SLICE_TYPE_EXT2FS 0x83 -#define PC_SLICE_TYPE_LINUX_EXTENDED 0x85 -#define PC_SLICE_TYPE_VSTAFS 0x9e -#define PC_SLICE_TYPE_DELL_UTIL 0xde -#define PC_SLICE_TYPE_LINUX_RAID 0xfd - -/* For convinience. */ -/* Check if TYPE is a FAT partition type. Clear the hidden flag before - the check, to allow the user to mount a hidden partition in GRUB. */ -#define IS_PC_SLICE_TYPE_FAT(type) \ - ({ int _type = (type) & ~PC_SLICE_TYPE_HIDDEN_FLAG; \ - _type == PC_SLICE_TYPE_FAT12 \ - || _type == PC_SLICE_TYPE_FAT16_LT32M \ - || _type == PC_SLICE_TYPE_FAT16_GT32M \ - || _type == PC_SLICE_TYPE_FAT16_LBA \ - || _type == PC_SLICE_TYPE_FAT32 \ - || _type == PC_SLICE_TYPE_FAT32_LBA \ - || _type == PC_SLICE_TYPE_DELL_UTIL; }) - -#define IS_PC_SLICE_TYPE_MINIX(type) \ - (((type) == PC_SLICE_TYPE_MINIX) \ - || ((type) == PC_SLICE_TYPE_LINUX_MINIX)) - -#define IS_PC_SLICE_TYPE_BSD_WITH_FS(type,fs) 0 - -/* possible values for the *BSD-style partition type */ -#define FS_UNUSED 0 /* unused */ -#define FS_SWAP 1 /* swap */ -#define FS_V6 2 /* Sixth Edition */ -#define FS_V7 3 /* Seventh Edition */ -#define FS_SYSV 4 /* System V */ -#define FS_V71K 5 /* V7 with 1K blocks (4.1, 2.9) */ -#define FS_V8 6 /* Eighth Edition, 4K blocks */ -#define FS_BSDFFS 7 /* 4.2BSD fast file system */ -#define FS_MSDOS 8 /* MSDOS file system */ -#define FS_BSDLFS 9 /* 4.4BSD log-structured file system */ -#define FS_OTHER 10 /* in use, but unknown/unsupported */ -#define FS_HPFS 11 /* OS/2 high-performance file system */ -#define FS_ISO9660 12 /* ISO 9660, normally CD-ROM */ -#define FS_BOOT 13 /* partition contains bootstrap */ -#define FS_ADOS 14 /* AmigaDOS fast file system */ -#define FS_HFS 15 /* Macintosh HFS */ -#define FS_FILECORE 16 /* Acorn Filecore Filing System */ -#define FS_EXT2FS 17 /* Linux Extended 2 file system */ diff --git a/src/filo/fs/fsys_ext2fs.c b/src/filo/fs/fsys_ext2fs.c deleted file mode 100644 index 62c6e80fa..000000000 --- a/src/filo/fs/fsys_ext2fs.c +++ /dev/null @@ -1,779 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999, 2001 Free Software Foundation, Inc. - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifdef FSYS_EXT2FS - -#include "shared.h" -#include "filesys.h" -#include <lib.h> -#include "string.h" - -static int mapblock1, mapblock2; - -/* sizes are always in bytes, BLOCK values are always in DEV_BSIZE (sectors) */ -#define DEV_BSIZE 512 - -/* include/linux/fs.h */ -#define BLOCK_SIZE 1024 /* initial block size for superblock read */ -/* made up, defaults to 1 but can be passed via mount_opts */ -#define WHICH_SUPER 1 -/* kind of from fs/ext2/super.c */ -#define SBLOCK (WHICH_SUPER * BLOCK_SIZE / DEV_BSIZE) /* = 2 */ - -/* include/asm-i386/types.h */ -typedef __signed__ char __s8; -typedef unsigned char __u8; -typedef __signed__ short __s16; -typedef unsigned short __u16; -typedef __signed__ int __s32; -typedef unsigned int __u32; - -/* - * Constants relative to the data blocks, from ext2_fs.h - */ -#define EXT2_NDIR_BLOCKS 12 -#define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS -#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1) -#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1) -#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1) - -/* include/linux/ext2_fs.h */ -struct ext2_super_block - { - __u32 s_inodes_count; /* Inodes count */ - __u32 s_blocks_count; /* Blocks count */ - __u32 s_r_blocks_count; /* Reserved blocks count */ - __u32 s_free_blocks_count; /* Free blocks count */ - __u32 s_free_inodes_count; /* Free inodes count */ - __u32 s_first_data_block; /* First Data Block */ - __u32 s_log_block_size; /* Block size */ - __s32 s_log_frag_size; /* Fragment size */ - __u32 s_blocks_per_group; /* # Blocks per group */ - __u32 s_frags_per_group; /* # Fragments per group */ - __u32 s_inodes_per_group; /* # Inodes per group */ - __u32 s_mtime; /* Mount time */ - __u32 s_wtime; /* Write time */ - __u16 s_mnt_count; /* Mount count */ - __s16 s_max_mnt_count; /* Maximal mount count */ - __u16 s_magic; /* Magic signature */ - __u16 s_state; /* File system state */ - __u16 s_errors; /* Behaviour when detecting errors */ - __u16 s_pad; - __u32 s_lastcheck; /* time of last check */ - __u32 s_checkinterval; /* max. time between checks */ - __u32 s_creator_os; /* OS */ - __u32 s_rev_level; /* Revision level */ - __u16 s_def_resuid; /* Default uid for reserved blocks */ - __u16 s_def_resgid; /* Default gid for reserved blocks */ - __u32 s_reserved[235]; /* Padding to the end of the block */ - }; - -struct ext2_group_desc - { - __u32 bg_block_bitmap; /* Blocks bitmap block */ - __u32 bg_inode_bitmap; /* Inodes bitmap block */ - __u32 bg_inode_table; /* Inodes table block */ - __u16 bg_free_blocks_count; /* Free blocks count */ - __u16 bg_free_inodes_count; /* Free inodes count */ - __u16 bg_used_dirs_count; /* Directories count */ - __u16 bg_pad; - __u32 bg_reserved[3]; - }; - -struct ext2_inode - { - __u16 i_mode; /* File mode */ - __u16 i_uid; /* Owner Uid */ - __u32 i_size; /* 4: Size in bytes */ - __u32 i_atime; /* Access time */ - __u32 i_ctime; /* 12: Creation time */ - __u32 i_mtime; /* Modification time */ - __u32 i_dtime; /* 20: Deletion Time */ - __u16 i_gid; /* Group Id */ - __u16 i_links_count; /* 24: Links count */ - __u32 i_blocks; /* Blocks count */ - __u32 i_flags; /* 32: File flags */ - union - { - struct - { - __u32 l_i_reserved1; - } - linux1; - struct - { - __u32 h_i_translator; - } - hurd1; - struct - { - __u32 m_i_reserved1; - } - masix1; - } - osd1; /* OS dependent 1 */ - __u32 i_block[EXT2_N_BLOCKS]; /* 40: Pointers to blocks */ - __u32 i_version; /* File version (for NFS) */ - __u32 i_file_acl; /* File ACL */ - __u32 i_dir_acl; /* Directory ACL */ - __u32 i_faddr; /* Fragment address */ - union - { - struct - { - __u8 l_i_frag; /* Fragment number */ - __u8 l_i_fsize; /* Fragment size */ - __u16 i_pad1; - __u32 l_i_reserved2[2]; - } - linux2; - struct - { - __u8 h_i_frag; /* Fragment number */ - __u8 h_i_fsize; /* Fragment size */ - __u16 h_i_mode_high; - __u16 h_i_uid_high; - __u16 h_i_gid_high; - __u32 h_i_author; - } - hurd2; - struct - { - __u8 m_i_frag; /* Fragment number */ - __u8 m_i_fsize; /* Fragment size */ - __u16 m_pad1; - __u32 m_i_reserved2[2]; - } - masix2; - } - osd2; /* OS dependent 2 */ - }; - -/* linux/limits.h */ -#define NAME_MAX 255 /* # chars in a file name */ - -/* linux/posix_type.h */ -typedef long linux_off_t; - -/* linux/ext2fs.h */ -#define EXT2_NAME_LEN 255 -struct ext2_dir_entry - { - __u32 inode; /* Inode number */ - __u16 rec_len; /* Directory entry length */ - __u8 name_len; /* Name length */ - __u8 file_type; - char name[EXT2_NAME_LEN]; /* File name */ - }; - -/* linux/ext2fs.h */ -/* - * EXT2_DIR_PAD defines the directory entries boundaries - * - * NOTE: It must be a multiple of 4 - */ -#define EXT2_DIR_PAD 4 -#define EXT2_DIR_ROUND (EXT2_DIR_PAD - 1) -#define EXT2_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT2_DIR_ROUND) & \ - ~EXT2_DIR_ROUND) - - -/* ext2/super.c */ -#define log2(n) ffz(~(n)) - -#define EXT2_SUPER_MAGIC 0xEF53 /* include/linux/ext2_fs.h */ -#define EXT2_ROOT_INO 2 /* include/linux/ext2_fs.h */ -#define PATH_MAX 1024 /* include/linux/limits.h */ -#define MAX_LINK_COUNT 5 /* number of symbolic links to follow */ - -/* made up, these are pointers into FSYS_BUF */ -/* read once, always stays there: */ -#define SUPERBLOCK \ - ((struct ext2_super_block *)(FSYS_BUF)) -#define GROUP_DESC \ - ((struct ext2_group_desc *) \ - ((int)SUPERBLOCK + sizeof(struct ext2_super_block))) -#define INODE \ - ((struct ext2_inode *)((int)GROUP_DESC + EXT2_BLOCK_SIZE(SUPERBLOCK))) -#define DATABLOCK1 \ - ((int)((int)INODE + sizeof(struct ext2_inode))) -#define DATABLOCK2 \ - ((int)((int)DATABLOCK1 + EXT2_BLOCK_SIZE(SUPERBLOCK))) - -/* linux/ext2_fs.h */ -#define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (__u32)) -#define EXT2_ADDR_PER_BLOCK_BITS(s) (log2(EXT2_ADDR_PER_BLOCK(s))) - -/* linux/ext2_fs.h */ -#define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10) -/* kind of from ext2/super.c */ -#define EXT2_BLOCK_SIZE(s) (1 << EXT2_BLOCK_SIZE_BITS(s)) -/* linux/ext2fs.h */ -#define EXT2_DESC_PER_BLOCK(s) \ - (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc)) -/* linux/stat.h */ -#define S_IFMT 00170000 -#define S_IFLNK 0120000 -#define S_IFREG 0100000 -#define S_IFDIR 0040000 -#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) -#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) - -/* include/asm-i386/bitops.h */ -/* - * ffz = Find First Zero in word. Undefined if no zero exists, - * so code should check against ~0UL first.. - */ -static __inline__ unsigned long -ffz (unsigned long word) -{ - __asm__ ("bsfl %1,%0" -: "=r" (word) -: "r" (~word)); - return word; -} - -/* check filesystem types and read superblock into memory buffer */ -int -ext2fs_mount (void) -{ - int retval = 1; - - if ((((current_drive & 0x80) || (current_slice != 0)) - && (current_slice != PC_SLICE_TYPE_EXT2FS) - && (current_slice != PC_SLICE_TYPE_LINUX_RAID) - && (! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_EXT2FS)) - && (! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_OTHER))) - || part_length < (SBLOCK + (sizeof (struct ext2_super_block) / DEV_BSIZE)) - || !devread (SBLOCK, 0, sizeof (struct ext2_super_block), - (char *) SUPERBLOCK) - || SUPERBLOCK->s_magic != EXT2_SUPER_MAGIC) - retval = 0; - - return retval; -} - -/* Takes a file system block number and reads it into BUFFER. */ -static int -ext2_rdfsb (int fsblock, int buffer) -{ -#ifdef E2DEBUG - printf ("fsblock %d buffer %d\n", fsblock, buffer); -#endif /* E2DEBUG */ - return devread (fsblock * (EXT2_BLOCK_SIZE (SUPERBLOCK) / DEV_BSIZE), 0, - EXT2_BLOCK_SIZE (SUPERBLOCK), (char *) buffer); -} - -/* from - ext2/inode.c:ext2_bmap() -*/ -/* Maps LOGICAL_BLOCK (the file offset divided by the blocksize) into - a physical block (the location in the file system) via an inode. */ -static int -ext2fs_block_map (int logical_block) -{ - -#ifdef E2DEBUG - unsigned char *i; - for (i = (unsigned char *) INODE; - i < ((unsigned char *) INODE + sizeof (struct ext2_inode)); - i++) - { - printf ("%c", "0123456789abcdef"[*i >> 4]); - printf ("%c", "0123456789abcdef"[*i % 16]); - if (!((i + 1 - (unsigned char *) INODE) % 16)) - { - printf ("\n"); - } - else - { - printf (" "); - } - } - printf ("logical block %d\n", logical_block); -#endif /* E2DEBUG */ - - /* if it is directly pointed to by the inode, return that physical addr */ - if (logical_block < EXT2_NDIR_BLOCKS) - { -#ifdef E2DEBUG - printf ("returning %d\n", (unsigned char *) (INODE->i_block[logical_block])); - printf ("returning %d\n", INODE->i_block[logical_block]); -#endif /* E2DEBUG */ - return INODE->i_block[logical_block]; - } - /* else */ - logical_block -= EXT2_NDIR_BLOCKS; - /* try the indirect block */ - if (logical_block < EXT2_ADDR_PER_BLOCK (SUPERBLOCK)) - { - if (mapblock1 != 1 - && !ext2_rdfsb (INODE->i_block[EXT2_IND_BLOCK], DATABLOCK1)) - { - errnum = ERR_FSYS_CORRUPT; - return -1; - } - mapblock1 = 1; - return ((__u32 *) DATABLOCK1)[logical_block]; - } - /* else */ - logical_block -= EXT2_ADDR_PER_BLOCK (SUPERBLOCK); - /* now try the double indirect block */ - if (logical_block < (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2))) - { - int bnum; - if (mapblock1 != 2 - && !ext2_rdfsb (INODE->i_block[EXT2_DIND_BLOCK], DATABLOCK1)) - { - errnum = ERR_FSYS_CORRUPT; - return -1; - } - mapblock1 = 2; - if ((bnum = (((__u32 *) DATABLOCK1) - [logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)])) - != mapblock2 - && !ext2_rdfsb (bnum, DATABLOCK2)) - { - errnum = ERR_FSYS_CORRUPT; - return -1; - } - mapblock2 = bnum; - return ((__u32 *) DATABLOCK2) - [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)]; - } - /* else */ - mapblock2 = -1; - logical_block -= (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2)); - if (mapblock1 != 3 - && !ext2_rdfsb (INODE->i_block[EXT2_TIND_BLOCK], DATABLOCK1)) - { - errnum = ERR_FSYS_CORRUPT; - return -1; - } - mapblock1 = 3; - if (!ext2_rdfsb (((__u32 *) DATABLOCK1) - [logical_block >> (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) - * 2)], - DATABLOCK2)) - { - errnum = ERR_FSYS_CORRUPT; - return -1; - } - if (!ext2_rdfsb (((__u32 *) DATABLOCK2) - [(logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)) - & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)], - DATABLOCK2)) - { - errnum = ERR_FSYS_CORRUPT; - return -1; - } - return ((__u32 *) DATABLOCK2) - [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)]; -} - -/* preconditions: all preconds of ext2fs_block_map */ -int -ext2fs_read (char *buf, int len) -{ - int logical_block; - int offset; - int map; - int ret = 0; - int size = 0; - -#ifdef E2DEBUG - static char hexdigit[] = "0123456789abcdef"; - unsigned char *i; - for (i = (unsigned char *) INODE; - i < ((unsigned char *) INODE + sizeof (struct ext2_inode)); - i++) - { - printf ("%c", hexdigit[*i >> 4]); - printf ("%c", hexdigit[*i % 16]); - if (!((i + 1 - (unsigned char *) INODE) % 16)) - { - printf ("\n"); - } - else - { - printf (" "); - } - } -#endif /* E2DEBUG */ - while (len > 0) - { - /* find the (logical) block component of our location */ - logical_block = filepos >> EXT2_BLOCK_SIZE_BITS (SUPERBLOCK); - offset = filepos & (EXT2_BLOCK_SIZE (SUPERBLOCK) - 1); - map = ext2fs_block_map (logical_block); -#ifdef E2DEBUG - printf ("map=%d\n", map); -#endif /* E2DEBUG */ - if (map < 0) - break; - - size = EXT2_BLOCK_SIZE (SUPERBLOCK); - size -= offset; - if (size > len) - size = len; - - disk_read_func = disk_read_hook; - - devread (map * (EXT2_BLOCK_SIZE (SUPERBLOCK) / DEV_BSIZE), - offset, size, buf); - - disk_read_func = NULL; - - buf += size; - len -= size; - filepos += size; - ret += size; - } - - if (errnum) - ret = 0; - - return ret; -} - - -/* Based on: - def_blk_fops points to - blkdev_open, which calls (I think): - sys_open() - do_open() - open_namei() - dir_namei() which accesses current->fs->root - fs->root was set during original mount: - (something)... which calls (I think): - ext2_read_super() - iget() - __iget() - read_inode() - ext2_read_inode() - uses desc_per_block_bits, which is set in ext2_read_super() - also uses group descriptors loaded during ext2_read_super() - lookup() - ext2_lookup() - ext2_find_entry() - ext2_getblk() - -*/ - -/* preconditions: ext2fs_mount already executed, therefore supblk in buffer - * known as SUPERBLOCK - * returns: 0 if error, nonzero iff we were able to find the file successfully - * postconditions: on a nonzero return, buffer known as INODE contains the - * inode of the file we were trying to look up - * side effects: messes up GROUP_DESC buffer area - */ -int -ext2fs_dir (char *dirname) -{ - int current_ino = EXT2_ROOT_INO; /* start at the root */ - int updir_ino = current_ino; /* the parent of the current directory */ - int group_id; /* which group the inode is in */ - int group_desc; /* fs pointer to that group */ - int desc; /* index within that group */ - int ino_blk; /* fs pointer of the inode's information */ - int str_chk = 0; /* used to hold the results of a string compare */ - struct ext2_group_desc *gdp; - struct ext2_inode *raw_inode; /* inode info corresponding to current_ino */ - - char linkbuf[PATH_MAX]; /* buffer for following symbolic links */ - int link_count = 0; - - char *rest; - char ch; /* temp char holder */ - - int off; /* offset within block of directory entry (off mod blocksize) */ - int loc; /* location within a directory */ - int blk; /* which data blk within dir entry (off div blocksize) */ - long map; /* fs pointer of a particular block from dir entry */ - struct ext2_dir_entry *dp; /* pointer to directory entry */ -#ifdef E2DEBUG - unsigned char *i; -#endif /* E2DEBUG */ - - /* loop invariants: - current_ino = inode to lookup - dirname = pointer to filename component we are cur looking up within - the directory known pointed to by current_ino (if any) - */ - - while (1) - { -#ifdef E2DEBUG - printf ("inode %d\n", current_ino); - printf ("dirname=%s\n", dirname); -#endif /* E2DEBUG */ - - /* look up an inode */ - group_id = (current_ino - 1) / (SUPERBLOCK->s_inodes_per_group); - group_desc = group_id >> log2 (EXT2_DESC_PER_BLOCK (SUPERBLOCK)); - desc = group_id & (EXT2_DESC_PER_BLOCK (SUPERBLOCK) - 1); -#ifdef E2DEBUG - printf ("ipg=%d, dpb=%d\n", SUPERBLOCK->s_inodes_per_group, - EXT2_DESC_PER_BLOCK (SUPERBLOCK)); - printf ("group_id=%d group_desc=%d desc=%d\n", group_id, group_desc, desc); -#endif /* E2DEBUG */ - if (!ext2_rdfsb ( - (WHICH_SUPER + group_desc + SUPERBLOCK->s_first_data_block), - (int) GROUP_DESC)) - { - return 0; - } - gdp = GROUP_DESC; - ino_blk = gdp[desc].bg_inode_table + - (((current_ino - 1) % (SUPERBLOCK->s_inodes_per_group)) - >> log2 (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode))); -#ifdef E2DEBUG - printf ("inode table fsblock=%d\n", ino_blk); -#endif /* E2DEBUG */ - if (!ext2_rdfsb (ino_blk, (int) INODE)) - { - return 0; - } - - /* reset indirect blocks! */ - mapblock2 = mapblock1 = -1; - - raw_inode = INODE + - ((current_ino - 1) - & (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode) - 1)); -#ifdef E2DEBUG - printf ("ipb=%d, sizeof(inode)=%d\n", - (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode)), - sizeof (struct ext2_inode)); - printf ("inode=%x, raw_inode=%x\n", INODE, raw_inode); - printf ("offset into inode table block=%d\n", (int) raw_inode - (int) INODE); - for (i = (unsigned char *) INODE; i <= (unsigned char *) raw_inode; - i++) - { - printf ("%c", "0123456789abcdef"[*i >> 4]); - printf ("%c", "0123456789abcdef"[*i % 16]); - if (!((i + 1 - (unsigned char *) INODE) % 16)) - { - printf ("\n"); - } - else - { - printf (" "); - } - } - printf ("first word=%x\n", *((int *) raw_inode)); -#endif /* E2DEBUG */ - - /* copy inode to fixed location */ - memmove ((void *) INODE, (void *) raw_inode, sizeof (struct ext2_inode)); - -#ifdef E2DEBUG - printf ("first word=%x\n", *((int *) INODE)); -#endif /* E2DEBUG */ - - /* If we've got a symbolic link, then chase it. */ - if (S_ISLNK (INODE->i_mode)) - { - int len; - if (++link_count > MAX_LINK_COUNT) - { - errnum = ERR_SYMLINK_LOOP; - return 0; - } - - /* Find out how long our remaining name is. */ - len = 0; - while (dirname[len] && !isspace (dirname[len])) - len++; - - /* Get the symlink size. */ - filemax = (INODE->i_size); - if (filemax + len > sizeof (linkbuf) - 2) - { - errnum = ERR_FILELENGTH; - return 0; - } - - if (len) - { - /* Copy the remaining name to the end of the symlink data. - Note that DIRNAME and LINKBUF may overlap! */ - memmove (linkbuf + filemax, dirname, len); - } - linkbuf[filemax + len] = '\0'; - - /* Read the symlink data. */ - if (INODE->i_blocks) - { - /* Read the necessary blocks, and reset the file pointer. */ - len = grub_read (linkbuf, filemax); - filepos = 0; - if (!len) - return 0; - } - else - { - /* Copy the data directly from the inode. */ - len = filemax; - memmove (linkbuf, (char *) INODE->i_block, len); - } - -#ifdef E2DEBUG - printf ("symlink=%s\n", linkbuf); -#endif - - dirname = linkbuf; - if (*dirname == '/') - { - /* It's an absolute link, so look it up in root. */ - current_ino = EXT2_ROOT_INO; - updir_ino = current_ino; - } - else - { - /* Relative, so look it up in our parent directory. */ - current_ino = updir_ino; - } - - /* Try again using the new name. */ - continue; - } - - /* if end of filename, INODE points to the file's inode */ - if (!*dirname || isspace (*dirname)) - { - if (!S_ISREG (INODE->i_mode)) - { - errnum = ERR_BAD_FILETYPE; - return 0; - } - - filemax = (INODE->i_size); - return 1; - } - - /* else we have to traverse a directory */ - updir_ino = current_ino; - - /* skip over slashes */ - while (*dirname == '/') - dirname++; - - /* if this isn't a directory of sufficient size to hold our file, abort */ - if (!(INODE->i_size) || !S_ISDIR (INODE->i_mode)) - { - errnum = ERR_BAD_FILETYPE; - return 0; - } - - /* skip to next slash or end of filename (space) */ - for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/'; - rest++); - - /* look through this directory and find the next filename component */ - /* invariant: rest points to slash after the next filename component */ - *rest = 0; - loc = 0; - - do - { - -#ifdef E2DEBUG - printf ("dirname=%s, rest=%s, loc=%d\n", dirname, rest, loc); -#endif /* E2DEBUG */ - - /* if our location/byte offset into the directory exceeds the size, - give up */ - if (loc >= INODE->i_size) - { - if (print_possibilities < 0) - { -# if 0 - putchar ('\n'); -# endif - } - else - { - errnum = ERR_FILE_NOT_FOUND; - *rest = ch; - } - return (print_possibilities < 0); - } - - /* else, find the (logical) block component of our location */ - blk = loc >> EXT2_BLOCK_SIZE_BITS (SUPERBLOCK); - - /* we know which logical block of the directory entry we are looking - for, now we have to translate that to the physical (fs) block on - the disk */ - map = ext2fs_block_map (blk); -#ifdef E2DEBUG - printf ("fs block=%d\n", map); -#endif /* E2DEBUG */ - mapblock2 = -1; - if ((map < 0) || !ext2_rdfsb (map, DATABLOCK2)) - { - errnum = ERR_FSYS_CORRUPT; - *rest = ch; - return 0; - } - off = loc & (EXT2_BLOCK_SIZE (SUPERBLOCK) - 1); - dp = (struct ext2_dir_entry *) (DATABLOCK2 + off); - /* advance loc prematurely to next on-disk directory entry */ - loc += dp->rec_len; - - /* NOTE: ext2fs filenames are NOT null-terminated */ - -#ifdef E2DEBUG - printf ("directory entry ino=%d\n", dp->inode); - if (dp->inode) - printf ("entry=%s\n", dp->name); -#endif /* E2DEBUG */ - - if (dp->inode) - { - int saved_c = dp->name[dp->name_len]; - - dp->name[dp->name_len] = 0; - str_chk = substring (dirname, dp->name); - -# ifndef STAGE1_5 - if (print_possibilities && ch != '/' - && (!*dirname || str_chk <= 0)) - { - if (print_possibilities > 0) - print_possibilities = -print_possibilities; - print_a_completion (dp->name); - } -# endif - - dp->name[dp->name_len] = saved_c; - } - - } - while (!dp->inode || (str_chk || (print_possibilities && ch != '/'))); - - current_ino = dp->inode; - *(dirname = rest) = ch; - } - /* never get here */ -} - -#endif /* FSYS_EXT2_FS */ diff --git a/src/filo/fs/fsys_fat.c b/src/filo/fs/fsys_fat.c deleted file mode 100644 index 3f85bd6cb..000000000 --- a/src/filo/fs/fsys_fat.c +++ /dev/null @@ -1,494 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2000, 2001 Free Software Foundation, Inc. - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifdef FSYS_FAT - -#include "shared.h" -#include "filesys.h" -#include "fat.h" -#include <lib.h> -#include "string.h" - -struct fat_superblock -{ - int fat_offset; - int fat_length; - int fat_size; - int root_offset; - int root_max; - int data_offset; - - int num_sectors; - int num_clust; - int clust_eof_marker; - int sects_per_clust; - int sectsize_bits; - int clustsize_bits; - int root_cluster; - - int cached_fat; - int file_cluster; - int current_cluster_num; - int current_cluster; -}; - -/* pointer(s) into filesystem info buffer for DOS stuff */ -#define FAT_SUPER ( (struct fat_superblock *) \ - ( FSYS_BUF + 32256) )/* 512 bytes long */ -#define FAT_BUF ( FSYS_BUF + 30208 ) /* 4 sector FAT buffer */ -#define NAME_BUF ( FSYS_BUF + 29184 ) /* Filename buffer (833 bytes) */ - -#define FAT_CACHE_SIZE 2048 - -static __inline__ unsigned long -log2 (unsigned long word) -{ - __asm__ ("bsfl %1,%0" - : "=r" (word) - : "r" (word)); - return word; -} - -int -fat_mount (void) -{ - struct fat_bpb bpb; - __u32 magic, first_fat; - - /* Check partition type for harddisk */ - if (((current_drive & 0x80) || (current_slice != 0)) - && ! IS_PC_SLICE_TYPE_FAT (current_slice) - && (! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_MSDOS))) - return 0; - - /* Read bpb */ - if (! devread (0, 0, sizeof (bpb), (char *) &bpb)) - return 0; - - /* Check if the number of sectors per cluster is zero here, to avoid - zero division. */ - if (bpb.sects_per_clust == 0) - return 0; - - FAT_SUPER->sectsize_bits = log2 (FAT_CVT_U16 (bpb.bytes_per_sect)); - FAT_SUPER->clustsize_bits - = FAT_SUPER->sectsize_bits + log2 (bpb.sects_per_clust); - - /* Fill in info about super block */ - FAT_SUPER->num_sectors = FAT_CVT_U16 (bpb.short_sectors) - ? FAT_CVT_U16 (bpb.short_sectors) : bpb.long_sectors; - - /* FAT offset and length */ - FAT_SUPER->fat_offset = FAT_CVT_U16 (bpb.reserved_sects); - FAT_SUPER->fat_length = - bpb.fat_length ? bpb.fat_length : bpb.fat32_length; - - /* Rootdir offset and length for FAT12/16 */ - FAT_SUPER->root_offset = - FAT_SUPER->fat_offset + bpb.num_fats * FAT_SUPER->fat_length; - FAT_SUPER->root_max = FAT_DIRENTRY_LENGTH * FAT_CVT_U16(bpb.dir_entries); - - /* Data offset and number of clusters */ - FAT_SUPER->data_offset = - FAT_SUPER->root_offset - + ((FAT_SUPER->root_max - 1) >> FAT_SUPER->sectsize_bits) + 1; - FAT_SUPER->num_clust = - 2 + ((FAT_SUPER->num_sectors - FAT_SUPER->data_offset) - / bpb.sects_per_clust); - FAT_SUPER->sects_per_clust = bpb.sects_per_clust; - - if (!bpb.fat_length) - { - /* This is a FAT32 */ - if (FAT_CVT_U16(bpb.dir_entries)) - return 0; - - if (bpb.flags & 0x0080) - { - /* FAT mirroring is disabled, get active FAT */ - int active_fat = bpb.flags & 0x000f; - if (active_fat >= bpb.num_fats) - return 0; - FAT_SUPER->fat_offset += active_fat * FAT_SUPER->fat_length; - } - - FAT_SUPER->fat_size = 8; - FAT_SUPER->root_cluster = bpb.root_cluster; - - /* Yes the following is correct. FAT32 should be called FAT28 :) */ - FAT_SUPER->clust_eof_marker = 0xffffff8; - } - else - { - if (!FAT_SUPER->root_max) - return 0; - - FAT_SUPER->root_cluster = -1; - if (FAT_SUPER->num_clust > FAT_MAX_12BIT_CLUST) - { - FAT_SUPER->fat_size = 4; - FAT_SUPER->clust_eof_marker = 0xfff8; - } - else - { - FAT_SUPER->fat_size = 3; - FAT_SUPER->clust_eof_marker = 0xff8; - } - } - - - /* Now do some sanity checks */ - - if (FAT_CVT_U16(bpb.bytes_per_sect) != (1 << FAT_SUPER->sectsize_bits) - || FAT_CVT_U16(bpb.bytes_per_sect) != SECTOR_SIZE - || bpb.sects_per_clust != (1 << (FAT_SUPER->clustsize_bits - - FAT_SUPER->sectsize_bits)) - || FAT_SUPER->num_clust <= 2 - || (FAT_SUPER->fat_size * FAT_SUPER->num_clust / (2 * SECTOR_SIZE) - > FAT_SUPER->fat_length)) - return 0; - - /* kbs: Media check on first FAT entry [ported from PUPA] */ - - if (!devread(FAT_SUPER->fat_offset, 0, - sizeof(first_fat), (char *)&first_fat)) - return 0; - - if (FAT_SUPER->fat_size == 8) - { - first_fat &= 0x0fffffff; - magic = 0x0fffff00; - } - else if (FAT_SUPER->fat_size == 4) - { - first_fat &= 0x0000ffff; - magic = 0xff00; - } - else - { - first_fat &= 0x00000fff; - magic = 0x0f00; - } - - if (first_fat != (magic | bpb.media)) - return 0; - - FAT_SUPER->cached_fat = - 2 * FAT_CACHE_SIZE; - return 1; -} - -int -fat_read (char *buf, int len) -{ - int logical_clust; - int offset; - int ret = 0; - int size; - int count = 64; - - if (FAT_SUPER->file_cluster < 0) - { - /* root directory for fat16 */ - size = FAT_SUPER->root_max - filepos; - if (size > len) - size = len; - if (!devread(FAT_SUPER->root_offset, filepos, size, buf)) - return 0; - filepos += size; - return size; - } - - logical_clust = filepos >> FAT_SUPER->clustsize_bits; - offset = (filepos & ((1 << FAT_SUPER->clustsize_bits) - 1)); - if (logical_clust < FAT_SUPER->current_cluster_num) - { - FAT_SUPER->current_cluster_num = 0; - FAT_SUPER->current_cluster = FAT_SUPER->file_cluster; - } - - while (len > 0) - { - int sector; - while (logical_clust > FAT_SUPER->current_cluster_num) - { - /* calculate next cluster */ - int fat_entry = - FAT_SUPER->current_cluster * FAT_SUPER->fat_size; - int next_cluster; - int cached_pos = (fat_entry - FAT_SUPER->cached_fat); - - if (cached_pos < 0 || - (cached_pos + FAT_SUPER->fat_size) > 2*FAT_CACHE_SIZE) - { - FAT_SUPER->cached_fat = (fat_entry & ~(2*SECTOR_SIZE - 1)); - cached_pos = (fat_entry - FAT_SUPER->cached_fat); - sector = FAT_SUPER->fat_offset - + FAT_SUPER->cached_fat / (2*SECTOR_SIZE); - if (!devread (sector, 0, FAT_CACHE_SIZE, (char*) FAT_BUF)) - return 0; - } - next_cluster = * (unsigned long *) (FAT_BUF + (cached_pos >> 1)); - if (FAT_SUPER->fat_size == 3) - { - if (cached_pos & 1) - next_cluster >>= 4; - next_cluster &= 0xFFF; - } - else if (FAT_SUPER->fat_size == 4) - next_cluster &= 0xFFFF; - - if (next_cluster >= FAT_SUPER->clust_eof_marker) - return ret; - if (next_cluster < 2 || next_cluster >= FAT_SUPER->num_clust) - { - errnum = ERR_FSYS_CORRUPT; - return 0; - } - - FAT_SUPER->current_cluster = next_cluster; - FAT_SUPER->current_cluster_num++; - } - - sector = FAT_SUPER->data_offset + - ((FAT_SUPER->current_cluster - 2) << (FAT_SUPER->clustsize_bits - - FAT_SUPER->sectsize_bits)); - size = (1 << FAT_SUPER->clustsize_bits) - offset; - if (size > len) - size = len; - - disk_read_func = disk_read_hook; - - devread(sector, offset, size, buf); - - disk_read_func = NULL; - - len -= size; - buf += size; - ret += size; - filepos += size; - logical_clust++; - offset = 0; - if(count--==0) { - count = 32; - printf("."); - } - } - -// printf("\n"); - return errnum ? 0 : ret; -} - -int -fat_dir (char *dirname) -{ - char *rest, ch, dir_buf[FAT_DIRENTRY_LENGTH]; - char *filename = (char *) NAME_BUF; - int attrib = FAT_ATTRIB_DIR; -#ifndef STAGE1_5 - int do_possibilities = 0; -#endif - - /* XXX I18N: - * the positions 2,4,6 etc are high bytes of a 16 bit unicode char - */ - static unsigned char longdir_pos[] = - { 1, 3, 5, 7, 9, 14, 16, 18, 20, 22, 24, 28, 30 }; - int slot = -2; - int alias_checksum = -1; - - FAT_SUPER->file_cluster = FAT_SUPER->root_cluster; - filepos = 0; - FAT_SUPER->current_cluster_num = MAXINT; - - /* main loop to find desired directory entry */ - loop: - - /* if we have a real file (and we're not just printing possibilities), - then this is where we want to exit */ - - if (!*dirname || isspace (*dirname)) - { - if (attrib & FAT_ATTRIB_DIR) - { - errnum = ERR_BAD_FILETYPE; - return 0; - } - - return 1; - } - - /* continue with the file/directory name interpretation */ - - while (*dirname == '/') - dirname++; - - if (!(attrib & FAT_ATTRIB_DIR)) - { - errnum = ERR_BAD_FILETYPE; - return 0; - } - /* Directories don't have a file size */ - filemax = MAXINT; - - for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/'; rest++); - - *rest = 0; - -# ifndef STAGE1_5 - if (print_possibilities && ch != '/') - do_possibilities = 1; -# endif - - while (1) - { - if (fat_read (dir_buf, FAT_DIRENTRY_LENGTH) != FAT_DIRENTRY_LENGTH - || dir_buf[0] == 0) - { - if (!errnum) - { -# ifndef STAGE1_5 - if (print_possibilities < 0) - { -#if 0 - putchar ('\n'); -#endif - return 1; - } -# endif /* STAGE1_5 */ - - errnum = ERR_FILE_NOT_FOUND; - *rest = ch; - } - - return 0; - } - - if (FAT_DIRENTRY_ATTRIB (dir_buf) == FAT_ATTRIB_LONGNAME) - { - /* This is a long filename. The filename is build from back - * to front and may span multiple entries. To bind these - * entries together they all contain the same checksum over - * the short alias. - * - * The id field tells if this is the first entry (the last - * part) of the long filename, and also at which offset this - * belongs. - * - * We just write the part of the long filename this entry - * describes and continue with the next dir entry. - */ - int i, offset; - unsigned char id = FAT_LONGDIR_ID(dir_buf); - - if ((id & 0x40)) - { - id &= 0x3f; - slot = id; - filename[slot * 13] = 0; - alias_checksum = FAT_LONGDIR_ALIASCHECKSUM(dir_buf); - } - - if (id != slot || slot == 0 - || alias_checksum != FAT_LONGDIR_ALIASCHECKSUM(dir_buf)) - { - alias_checksum = -1; - continue; - } - - slot--; - offset = slot * 13; - - for (i=0; i < 13; i++) - filename[offset+i] = dir_buf[longdir_pos[i]]; - continue; - } - - if (!FAT_DIRENTRY_VALID (dir_buf)) - continue; - - if (alias_checksum != -1 && slot == 0) - { - int i; - unsigned char sum; - - slot = -2; - for (sum = 0, i = 0; i< 11; i++) - sum = ((sum >> 1) | (sum << 7)) + dir_buf[i]; - - if (sum == alias_checksum) - { -# ifndef STAGE1_5 - if (do_possibilities) - goto print_filename; -# endif /* STAGE1_5 */ - - if (substring (dirname, filename) == 0) - break; - } - } - - /* XXX convert to 8.3 filename format here */ - { - int i, j, c; - - for (i = 0; i < 8 && (c = filename[i] = tolower (dir_buf[i])) - && !isspace (c); i++); - - filename[i++] = '.'; - - for (j = 0; j < 3 && (c = filename[i + j] = tolower (dir_buf[8 + j])) - && !isspace (c); j++); - - if (j == 0) - i--; - - filename[i + j] = 0; - } - -# ifndef STAGE1_5 - if (do_possibilities) - { - print_filename: - if (substring (dirname, filename) <= 0) - { - if (print_possibilities > 0) - print_possibilities = -print_possibilities; - print_a_completion (filename); - } - continue; - } -# endif /* STAGE1_5 */ - - if (substring (dirname, filename) == 0) - break; - } - - *(dirname = rest) = ch; - - attrib = FAT_DIRENTRY_ATTRIB (dir_buf); - filemax = FAT_DIRENTRY_FILELENGTH (dir_buf); - filepos = 0; - FAT_SUPER->file_cluster = FAT_DIRENTRY_FIRST_CLUSTER (dir_buf); - FAT_SUPER->current_cluster_num = MAXINT; - - /* go back to main loop at top of function */ - goto loop; -} - -#endif /* FSYS_FAT */ diff --git a/src/filo/fs/fsys_iso9660.c b/src/filo/fs/fsys_iso9660.c deleted file mode 100644 index 9e6679145..000000000 --- a/src/filo/fs/fsys_iso9660.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * ISO 9660 filesystem backend for GRUB (GRand Unified Bootloader) - * including Rock Ridge Extensions support - * - * Copyright (C) 1998, 1999 Kousuke Takai <tak@kmc.kyoto-u.ac.jp> - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -/* - * References: - * linux/fs/isofs/rock.[ch] - * mkisofs-1.11.1/diag/isoinfo.c - * mkisofs-1.11.1/iso9660.h - * (all are written by Eric Youngdale) - * - * Modifications by: - * Leonid Lisovskiy <lly@pisem.net> 2003 - */ - -/* - * Modified to make it work with FILO - * 2003-10 by SONE Takeshi - */ - -#ifdef FSYS_ISO9660 - -#include <lib.h> -#include "string.h" -#include "shared.h" -#include "filesys.h" -#include "iso9660.h" -#define DEBUG_THIS 1 -#include <debug.h> - -struct iso_superblock { - unsigned long vol_sector; - - unsigned long file_start; -}; - -#define ISO_SUPER ((struct iso_superblock *)(FSYS_BUF)) -#define PRIMDESC ((struct iso_primary_descriptor *)(FSYS_BUF + 2048)) -#define DIRREC ((struct iso_directory_record *)(FSYS_BUF + 4096)) -#define RRCONT_BUF ((unsigned char *)(FSYS_BUF + 6144)) -#define NAME_BUF ((unsigned char *)(FSYS_BUF + 8192)) - - -static inline unsigned long -log2 (unsigned long word) -{ - asm volatile ("bsfl %1,%0" -: "=r" (word) -: "r" (word)); - return word; -} - -static int -iso9660_devread (int sector, int byte_offset, int byte_len, char *buf) -{ - /* FILO uses 512-byte "soft" sector, and ISO-9660 uses 2048-byte - * CD-ROM sector */ - return devread(sector<<2, byte_offset, byte_len, buf); -} - -int -iso9660_mount (void) -{ - unsigned int sector; - - /* - * Because there is no defined slice type ID for ISO-9660 filesystem, - * this test will pass only either (1) if entire disk is used, or - * (2) if current partition is BSD style sub-partition whose ID is - * ISO-9660. - */ - /*if ((current_partition != 0xFFFFFF) - && !IS_PC_SLICE_TYPE_BSD_WITH_FS(current_slice, FS_ISO9660)) - return 0;*/ - - /* - * Currently, only FIRST session of MultiSession disks are supported !!! - */ - for (sector = 16 ; sector < 32 ; sector++) - { - if (!iso9660_devread(sector, 0, sizeof(*PRIMDESC), (char *)PRIMDESC)) - break; - /* check ISO_VD_PRIMARY and ISO_STANDARD_ID */ - if (CHECK4(&PRIMDESC->type, ISO_VD_PRIMARY, 'C', 'D', '0') - && CHECK2(PRIMDESC->id + 3, '0', '1')) - { - ISO_SUPER->vol_sector = sector; - ISO_SUPER->file_start = 0; - fsmax = PRIMDESC->volume_space_size.l; - return 1; - } - } - - return 0; -} - -int -iso9660_dir (char *dirname) -{ - struct iso_directory_record *idr; - RR_ptr_t rr_ptr; - struct rock_ridge *ce_ptr; - unsigned int pathlen; - int size; - unsigned int extent; - unsigned int rr_len; - unsigned char file_type; - unsigned char rr_flag; - - idr = &PRIMDESC->root_directory_record; - ISO_SUPER->file_start = 0; - - do - { - while (*dirname == '/') /* skip leading slashes */ - dirname++; - /* pathlen = strcspn(dirname, "/\n\t "); */ - for (pathlen = 0 ; - dirname[pathlen] - && !isspace(dirname[pathlen]) && dirname[pathlen] != '/' ; - pathlen++) - ; - - size = idr->size.l; - extent = idr->extent.l; - - while (size > 0) - { - if (!iso9660_devread(extent, 0, ISO_SECTOR_SIZE, (char *)DIRREC)) - { - errnum = ERR_FSYS_CORRUPT; - return 0; - } - extent++; - - idr = (struct iso_directory_record *)DIRREC; - for (; idr->length.l > 0; - idr = (struct iso_directory_record *)((char *)idr + idr->length.l) ) - { - const char *name = idr->name; - unsigned int name_len = idr->name_len.l; - - file_type = (idr->flags.l & 2) ? ISO_DIRECTORY : ISO_REGULAR; - if (name_len == 1) - { - if ((name[0] == 0) || /* self */ - (name[0] == 1)) /* parent */ - continue; - } - if (name_len > 2 && CHECK2(name + name_len - 2, ';', '1')) - { - name_len -= 2; /* truncate trailing file version */ - if (name_len > 1 && name[name_len - 1] == '.') - name_len--; /* truncate trailing dot */ - } - - /* - * Parse Rock-Ridge extension - */ - rr_len = (idr->length.l - idr->name_len.l - - (unsigned char)sizeof(struct iso_directory_record) - + (unsigned char)sizeof(idr->name)); - rr_ptr.ptr = ((unsigned char *)idr + idr->name_len.l - + sizeof(struct iso_directory_record) - - sizeof(idr->name)); - if (rr_ptr.i & 1) - rr_ptr.i++, rr_len--; - ce_ptr = NULL; - rr_flag = RR_FLAG_NM | RR_FLAG_PX; - - while (rr_len >= 4) - { - if (rr_ptr.rr->version != 1) - { -#ifndef STAGE1_5 - if (debug) - printf( - "Non-supported version (%d) RockRidge chunk " - "`%c%c'\n", rr_ptr.rr->version, - rr_ptr.rr->signature & 0xFF, - rr_ptr.rr->signature >> 8); -#endif - } - else if (rr_ptr.rr->signature == RRMAGIC('R', 'R') - && rr_ptr.rr->len >= 5) - rr_flag &= rr_ptr.rr->u.rr.flags.l; - else if (rr_ptr.rr->signature == RRMAGIC('N', 'M')) - { - name = rr_ptr.rr->u.nm.name; - name_len = rr_ptr.rr->len - 5; - rr_flag &= ~RR_FLAG_NM; - } - else if (rr_ptr.rr->signature == RRMAGIC('P', 'X') - && rr_ptr.rr->len >= 36) - { - file_type = ((rr_ptr.rr->u.px.mode.l & POSIX_S_IFMT) - == POSIX_S_IFREG - ? ISO_REGULAR - : ((rr_ptr.rr->u.px.mode.l & POSIX_S_IFMT) - == POSIX_S_IFDIR - ? ISO_DIRECTORY : ISO_OTHER)); - rr_flag &= ~RR_FLAG_PX; - } - else if (rr_ptr.rr->signature == RRMAGIC('C', 'E') - && rr_ptr.rr->len >= 28) - ce_ptr = rr_ptr.rr; - if (!rr_flag) - /* - * There is no more extension we expects... - */ - break; - rr_len -= rr_ptr.rr->len; - rr_ptr.ptr += rr_ptr.rr->len; - if (rr_len < 4 && ce_ptr != NULL) - { - /* preserve name before loading new extent. */ - if( RRCONT_BUF <= (unsigned char *)name - && (unsigned char *)name < RRCONT_BUF + ISO_SECTOR_SIZE ) - { - memcpy(NAME_BUF, name, name_len); - name = NAME_BUF; - } - rr_ptr.ptr = RRCONT_BUF + ce_ptr->u.ce.offset.l; - rr_len = ce_ptr->u.ce.size.l; - if (!iso9660_devread(ce_ptr->u.ce.extent.l, 0, ISO_SECTOR_SIZE, RRCONT_BUF)) - { - errnum = 0; /* this is not fatal. */ - break; - } - ce_ptr = NULL; - } - } /* rr_len >= 4 */ - - filemax = MAXINT; - if (name_len >= pathlen - && !__builtin_memcmp(name, dirname, pathlen)) - { - if (dirname[pathlen] == '/' || !print_possibilities) - { - /* - * DIRNAME is directory component of pathname, - * or we are to open a file. - */ - if (pathlen == name_len) - { - if (dirname[pathlen] == '/') - { - if (file_type != ISO_DIRECTORY) - { - errnum = ERR_BAD_FILETYPE; - return 0; - } - goto next_dir_level; - } - if (file_type != ISO_REGULAR) - { - errnum = ERR_BAD_FILETYPE; - return 0; - } - ISO_SUPER->file_start = idr->extent.l; - filepos = 0; - filemax = idr->size.l; - return 1; - } - } - else /* Completion */ - { -#ifndef STAGE1_5 - if (print_possibilities > 0) - print_possibilities = -print_possibilities; - memcpy(NAME_BUF, name, name_len); - NAME_BUF[name_len] = '\0'; - print_a_completion (NAME_BUF); -#endif - } - } - } /* for */ - - size -= ISO_SECTOR_SIZE; - } /* size>0 */ - - if (dirname[pathlen] == '/' || print_possibilities >= 0) - { - errnum = ERR_FILE_NOT_FOUND; - return 0; - } - -next_dir_level: - dirname += pathlen; - - } while (*dirname == '/'); - - return 1; -} - -int -iso9660_read (char *buf, int len) -{ - int sector, blkoffset, size, ret; - - if (ISO_SUPER->file_start == 0) - return 0; - - ret = 0; - blkoffset = filepos & (ISO_SECTOR_SIZE - 1); - sector = filepos >> ISO_SECTOR_BITS; - while (len > 0) - { - size = ISO_SECTOR_SIZE - blkoffset; - if (size > len) - size = len; - - disk_read_func = disk_read_hook; - - if (!iso9660_devread(ISO_SUPER->file_start + sector, blkoffset, size, buf)) - return 0; - - disk_read_func = NULL; - - len -= size; - buf += size; - ret += size; - filepos += size; - sector++; - blkoffset = 0; - } - - return ret; -} - -#endif /* FSYS_ISO9660 */ - diff --git a/src/filo/fs/fsys_jfs.c b/src/filo/fs/fsys_jfs.c deleted file mode 100644 index 307f83633..000000000 --- a/src/filo/fs/fsys_jfs.c +++ /dev/null @@ -1,403 +0,0 @@ -/* fsys_jfs.c - an implementation for the IBM JFS file system */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2001,2002 Free Software Foundation, Inc. - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifdef FSYS_JFS - -#include "shared.h" -#include "filesys.h" -#include "jfs.h" - -#define MAX_LINK_COUNT 8 - -#define DTTYPE_INLINE 0 -#define DTTYPE_PAGE 1 - -struct jfs_info -{ - int bsize; - int l2bsize; - int bdlog; - int xindex; - int xlastindex; - int sindex; - int slastindex; - int de_index; - int dttype; - xad_t *xad; - ldtentry_t *de; -}; - -static struct jfs_info jfs; - -#define xtpage ((xtpage_t *)FSYS_BUF) -#define dtpage ((dtpage_t *)((char *)FSYS_BUF + 4096)) -#define fileset ((dinode_t *)((char *)FSYS_BUF + 8192)) -#define inode ((dinode_t *)((char *)FSYS_BUF + 8192 + sizeof(dinode_t))) -#define dtroot ((dtroot_t *)(&inode->di_btroot)) - -static ldtentry_t de_always[2] = { - {1, -1, 2, {'.', '.'}}, - {1, -1, 1, {'.'}} -}; - -static int -isinxt (s64 key, s64 offset, s64 len) -{ - return (key >= offset) ? (key < offset + len ? 1 : 0) : 0; -} - -static xad_t * -first_extent (dinode_t *di) -{ - xtpage_t *xtp; - - jfs.xindex = 2; - xtp = (xtpage_t *)&di->di_btroot; - jfs.xad = &xtp->xad[2]; - if (xtp->header.flag & BT_LEAF) { - jfs.xlastindex = xtp->header.nextindex; - } else { - do { - devread (addressXAD (jfs.xad) << jfs.bdlog, 0, - sizeof(xtpage_t), (char *)xtpage); - jfs.xad = &xtpage->xad[2]; - } while (!(xtpage->header.flag & BT_LEAF)); - jfs.xlastindex = xtpage->header.nextindex; - } - - return jfs.xad; -} - -static xad_t * -next_extent (void) -{ - if (++jfs.xindex < jfs.xlastindex) { - } else if (xtpage->header.next) { - devread (xtpage->header.next << jfs.bdlog, 0, - sizeof(xtpage_t), (char *)xtpage); - jfs.xlastindex = xtpage->header.nextindex; - jfs.xindex = XTENTRYSTART; - jfs.xad = &xtpage->xad[XTENTRYSTART]; - } else { - return NULL; - } - return ++jfs.xad; -} - - -static void -di_read (u32 inum, dinode_t *di) -{ - s64 key; - u32 xd, ioffset; - s64 offset; - xad_t *xad; - pxd_t pxd; - - key = (((inum >> L2INOSPERIAG) << L2INOSPERIAG) + 4096) >> jfs.l2bsize; - xd = (inum & (INOSPERIAG - 1)) >> L2INOSPEREXT; - ioffset = ((inum & (INOSPERIAG - 1)) & (INOSPEREXT - 1)) << L2DISIZE; - xad = first_extent (fileset); - do { - offset = offsetXAD (xad); - if (isinxt (key, offset, lengthXAD (xad))) { - devread ((addressXAD (xad) + key - offset) << jfs.bdlog, - 3072 + xd*sizeof(pxd_t), sizeof(pxd_t), (char *)&pxd); - devread (addressPXD (&pxd) << jfs.bdlog, - ioffset, DISIZE, (char *)di); - break; - } - } while ((xad = next_extent ())); -} - -static ldtentry_t * -next_dentry (void) -{ - ldtentry_t *de; - s8 *stbl; - - if (jfs.dttype == DTTYPE_INLINE) { - if (jfs.sindex < jfs.slastindex) { - return (ldtentry_t *)&dtroot->slot[(int)dtroot->header.stbl[jfs.sindex++]]; - } - } else { - de = (ldtentry_t *)dtpage->slot; - stbl = (s8 *)&de[(int)dtpage->header.stblindex]; - if (jfs.sindex < jfs.slastindex) { - return &de[(int)stbl[jfs.sindex++]]; - } else if (dtpage->header.next) { - devread (dtpage->header.next << jfs.bdlog, 0, - sizeof(dtpage_t), (char *)dtpage); - jfs.slastindex = dtpage->header.nextindex; - jfs.sindex = 1; - return &de[(int)((s8 *)&de[(int)dtpage->header.stblindex])[0]]; - } - } - - return (jfs.de_index < 2) ? &de_always[jfs.de_index++] : NULL; -} - -static ldtentry_t * -first_dentry (void) -{ - dtroot_t *dtr; - pxd_t *xd; - idtentry_t *de; - - dtr = (dtroot_t *)&inode->di_btroot; - jfs.sindex = 0; - jfs.de_index = 0; - - de_always[0].inumber = inode->di_parent; - de_always[1].inumber = inode->di_number; - if (dtr->header.flag & BT_LEAF) { - jfs.dttype = DTTYPE_INLINE; - jfs.slastindex = dtr->header.nextindex; - } else { - de = (idtentry_t *)dtpage->slot; - jfs.dttype = DTTYPE_PAGE; - xd = &((idtentry_t *)dtr->slot)[(int)dtr->header.stbl[0]].xd; - for (;;) { - devread (addressPXD (xd) << jfs.bdlog, 0, - sizeof(dtpage_t), (char *)dtpage); - if (dtpage->header.flag & BT_LEAF) - break; - xd = &de[(int)((s8 *)&de[(int)dtpage->header.stblindex])[0]].xd; - } - jfs.slastindex = dtpage->header.nextindex; - } - - return next_dentry (); -} - - -static dtslot_t * -next_dslot (int next) -{ - return (jfs.dttype == DTTYPE_INLINE) - ? (dtslot_t *)&dtroot->slot[next] - : &((dtslot_t *)dtpage->slot)[next]; -} - -static void -uni2ansi (UniChar *uni, char *ansi, int len) -{ - for (; len; len--, uni++) - *ansi++ = (*uni & 0xff80) ? '?' : *(char *)uni; -} - -int -jfs_mount (void) -{ - struct jfs_superblock super; - - if (part_length < MINJFS >> SECTOR_BITS - || !devread (SUPER1_OFF >> SECTOR_BITS, 0, - sizeof(struct jfs_superblock), (char *)&super) - || (super.s_magic != JFS_MAGIC) - || !devread ((AITBL_OFF >> SECTOR_BITS) + FILESYSTEM_I, - 0, DISIZE, (char*)fileset)) { - return 0; - } - - jfs.bsize = super.s_bsize; - jfs.l2bsize = super.s_l2bsize; - jfs.bdlog = jfs.l2bsize - SECTOR_BITS; - - return 1; -} - -int -jfs_read (char *buf, int len) -{ - xad_t *xad; - s64 endofprev, endofcur; - s64 offset, xadlen; - int toread, startpos, endpos; - - startpos = filepos; - endpos = filepos + len; - endofprev = (1ULL << 62) - 1; - xad = first_extent (inode); - do { - offset = offsetXAD (xad); - xadlen = lengthXAD (xad); - if (isinxt (filepos >> jfs.l2bsize, offset, xadlen)) { - endofcur = (offset + xadlen) << jfs.l2bsize; - toread = (endofcur >= endpos) - ? len : (endofcur - filepos); - - disk_read_func = disk_read_hook; - devread (addressXAD (xad) << jfs.bdlog, - filepos - (offset << jfs.l2bsize), toread, buf); - disk_read_func = NULL; - - buf += toread; - len -= toread; - filepos += toread; - } else if (offset > endofprev) { - toread = ((offset << jfs.l2bsize) >= endpos) - ? len : ((offset - endofprev) << jfs.l2bsize); - len -= toread; - filepos += toread; - for (; toread; toread--) { - *buf++ = 0; - } - continue; - } - endofprev = offset + xadlen; - xad = next_extent (); - } while (len > 0 && xad); - - return filepos - startpos; -} - -int -jfs_dir (char *dirname) -{ - char *ptr, *rest, ch; - ldtentry_t *de; - dtslot_t *ds; - u32 inum, parent_inum; - s64 di_size; - u32 di_mode; - int namlen, cmp, n, link_count; - char namebuf[JFS_NAME_MAX + 1], linkbuf[JFS_PATH_MAX]; - - parent_inum = inum = ROOT_I; - link_count = 0; - for (;;) { - di_read (inum, inode); - di_size = inode->di_size; - di_mode = inode->di_mode; - - if ((di_mode & IFMT) == IFLNK) { - if (++link_count > MAX_LINK_COUNT) { - errnum = ERR_SYMLINK_LOOP; - return 0; - } - if (di_size < (di_mode & INLINEEA ? 256 : 128)) { - grub_memmove (linkbuf, inode->di_fastsymlink, di_size); - n = di_size; - } else if (di_size < JFS_PATH_MAX - 1) { - filepos = 0; - filemax = di_size; - n = jfs_read (linkbuf, filemax); - } else { - errnum = ERR_FILELENGTH; - return 0; - } - - inum = (linkbuf[0] == '/') ? ROOT_I : parent_inum; - while (n < (JFS_PATH_MAX - 1) && (linkbuf[n++] = *dirname++)); - linkbuf[n] = 0; - dirname = linkbuf; - continue; - } - - if (!*dirname || isspace (*dirname)) { - if ((di_mode & IFMT) != IFREG) { - errnum = ERR_BAD_FILETYPE; - return 0; - } - filepos = 0; - filemax = di_size; - return 1; - } - - if ((di_mode & IFMT) != IFDIR) { - errnum = ERR_BAD_FILETYPE; - return 0; - } - - for (; *dirname == '/'; dirname++); - - for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/'; rest++); - *rest = 0; - - de = first_dentry (); - for (;;) { - namlen = de->namlen; - if (de->next == -1) { - uni2ansi (de->name, namebuf, namlen); - namebuf[namlen] = 0; - } else { - uni2ansi (de->name, namebuf, DTLHDRDATALEN); - ptr = namebuf; - ptr += DTLHDRDATALEN; - namlen -= DTLHDRDATALEN; - ds = next_dslot (de->next); - while (ds->next != -1) { - uni2ansi (ds->name, ptr, DTSLOTDATALEN); - ptr += DTSLOTDATALEN; - namlen -= DTSLOTDATALEN; - ds = next_dslot (ds->next); - } - uni2ansi (ds->name, ptr, namlen); - ptr += namlen; - *ptr = 0; - } - - cmp = (!*dirname) ? -1 : substring (dirname, namebuf); -#ifndef STAGE1_5 - if (print_possibilities && ch != '/' - && cmp <= 0) { - if (print_possibilities > 0) - print_possibilities = -print_possibilities; - print_a_completion (namebuf); - } else -#endif - if (cmp == 0) { - parent_inum = inum; - inum = de->inumber; - *(dirname = rest) = ch; - break; - } - de = next_dentry (); - if (de == NULL) { - if (print_possibilities < 0) - return 1; - - errnum = ERR_FILE_NOT_FOUND; - *rest = ch; - return 0; - } - } - } -} - -int -jfs_embed (int *start_sector, int needed_sectors) -{ - struct jfs_superblock super; - - if (needed_sectors > 63 - || !devread (SUPER1_OFF >> SECTOR_BITS, 0, - sizeof (struct jfs_superblock), - (char *)&super) - || (super.s_magic != JFS_MAGIC)) { - return 0; - } - - *start_sector = 1; - return 1; -} - -#endif /* FSYS_JFS */ diff --git a/src/filo/fs/fsys_minix.c b/src/filo/fs/fsys_minix.c deleted file mode 100644 index 5c76796a2..000000000 --- a/src/filo/fs/fsys_minix.c +++ /dev/null @@ -1,534 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002 Free Software Foundation, Inc. - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* Restrictions: - This is MINIX V1 only (yet) - Disk creation is like: - mkfs.minix -c DEVICE -*/ - -#ifdef FSYS_MINIX - -#include "shared.h" -#include "filesys.h" - -/* #define DEBUG_MINIX */ - -/* indirect blocks */ -static int mapblock1, mapblock2, namelen; - -/* sizes are always in bytes, BLOCK values are always in DEV_BSIZE (sectors) */ -#define DEV_BSIZE 512 - -/* include/linux/fs.h */ -#define BLOCK_SIZE_BITS 10 -#define BLOCK_SIZE (1<<BLOCK_SIZE_BITS) - -/* made up, defaults to 1 but can be passed via mount_opts */ -#define WHICH_SUPER 1 -/* kind of from fs/ext2/super.c (is OK for minix) */ -#define SBLOCK (WHICH_SUPER * BLOCK_SIZE / DEV_BSIZE) /* = 2 */ - -/* include/asm-i386/type.h */ -typedef __signed__ char __s8; -typedef unsigned char __u8; -typedef __signed__ short __s16; -typedef unsigned short __u16; -typedef __signed__ int __s32; -typedef unsigned int __u32; - -/* include/linux/minix_fs.h */ -#define MINIX_ROOT_INO 1 - -/* Not the same as the bogus LINK_MAX in <linux/limits.h>. Oh well. */ -#define MINIX_LINK_MAX 250 -#define MINIX2_LINK_MAX 65530 - -#define MINIX_I_MAP_SLOTS 8 -#define MINIX_Z_MAP_SLOTS 64 -#define MINIX_SUPER_MAGIC 0x137F /* original minix fs */ -#define MINIX_SUPER_MAGIC2 0x138F /* minix fs, 30 char names */ -#define MINIX2_SUPER_MAGIC 0x2468 /* minix V2 fs */ -#define MINIX2_SUPER_MAGIC2 0x2478 /* minix V2 fs, 30 char names */ -#define MINIX_VALID_FS 0x0001 /* Clean fs. */ -#define MINIX_ERROR_FS 0x0002 /* fs has errors. */ - -#define MINIX_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct minix_inode))) -#define MINIX2_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct minix2_inode))) - -#define MINIX_V1 0x0001 /* original minix fs */ -#define MINIX_V2 0x0002 /* minix V2 fs */ - -/* originally this is : -#define INODE_VERSION(inode) inode->i_sb->u.minix_sb.s_version - here we have */ -#define INODE_VERSION(inode) (SUPERBLOCK->s_version) - -/* - * This is the original minix inode layout on disk. - * Note the 8-bit gid and atime and ctime. - */ -struct minix_inode { - __u16 i_mode; - __u16 i_uid; - __u32 i_size; - __u32 i_time; - __u8 i_gid; - __u8 i_nlinks; - __u16 i_zone[9]; -}; - -/* - * The new minix inode has all the time entries, as well as - * long block numbers and a third indirect block (7+1+1+1 - * instead of 7+1+1). Also, some previously 8-bit values are - * now 16-bit. The inode is now 64 bytes instead of 32. - */ -struct minix2_inode { - __u16 i_mode; - __u16 i_nlinks; - __u16 i_uid; - __u16 i_gid; - __u32 i_size; - __u32 i_atime; - __u32 i_mtime; - __u32 i_ctime; - __u32 i_zone[10]; -}; - -/* - * minix super-block data on disk - */ -struct minix_super_block { - __u16 s_ninodes; - __u16 s_nzones; - __u16 s_imap_blocks; - __u16 s_zmap_blocks; - __u16 s_firstdatazone; - __u16 s_log_zone_size; - __u32 s_max_size; - __u16 s_magic; - __u16 s_state; - __u32 s_zones; -}; - -struct minix_dir_entry { - __u16 inode; - char name[0]; -}; - -/* made up, these are pointers into FSYS_BUF */ -/* read once, always stays there: */ -#define SUPERBLOCK \ - ((struct minix_super_block *)(FSYS_BUF)) -#define INODE \ - ((struct minix_inode *)((int) SUPERBLOCK + BLOCK_SIZE)) -#define DATABLOCK1 \ - ((int)((int)INODE + sizeof(struct minix_inode))) -#define DATABLOCK2 \ - ((int)((int)DATABLOCK1 + BLOCK_SIZE)) - -/* linux/stat.h */ -#define S_IFMT 00170000 -#define S_IFLNK 0120000 -#define S_IFREG 0100000 -#define S_IFDIR 0040000 -#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) -#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) - -#define PATH_MAX 1024 /* include/linux/limits.h */ -#define MAX_LINK_COUNT 5 /* number of symbolic links to follow */ - -/* check filesystem types and read superblock into memory buffer */ -int -minix_mount (void) -{ - if (((current_drive & 0x80) || current_slice != 0) - && ! IS_PC_SLICE_TYPE_MINIX (current_slice) - && ! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_OTHER)) - return 0; /* The partition is not of MINIX type */ - - if (part_length < (SBLOCK + - (sizeof (struct minix_super_block) / DEV_BSIZE))) - return 0; /* The partition is too short */ - - if (!devread (SBLOCK, 0, sizeof (struct minix_super_block), - (char *) SUPERBLOCK)) - return 0; /* Cannot read superblock */ - - switch (SUPERBLOCK->s_magic) - { - case MINIX_SUPER_MAGIC: - namelen = 14; - break; - case MINIX_SUPER_MAGIC2: - namelen = 30; - break; - default: - return 0; /* Unsupported type */ - } - - return 1; -} - -/* Takes a file system block number and reads it into BUFFER. */ -static int -minix_rdfsb (int fsblock, int buffer) -{ - return devread (fsblock * (BLOCK_SIZE / DEV_BSIZE), 0, - BLOCK_SIZE, (char *) buffer); -} - -/* Maps LOGICAL_BLOCK (the file offset divided by the blocksize) into - a physical block (the location in the file system) via an inode. */ -static int -minix_block_map (int logical_block) -{ - int i; - - if (logical_block < 7) - return INODE->i_zone[logical_block]; - - logical_block -= 7; - if (logical_block < 512) - { - i = INODE->i_zone[7]; - - if (!i || ((mapblock1 != 1) - && !minix_rdfsb (i, DATABLOCK1))) - { - errnum = ERR_FSYS_CORRUPT; - return -1; - } - mapblock1 = 1; - return ((__u16 *) DATABLOCK1) [logical_block]; - } - - logical_block -= 512; - i = INODE->i_zone[8]; - if (!i || ((mapblock1 != 2) - && !minix_rdfsb (i, DATABLOCK1))) - { - errnum = ERR_FSYS_CORRUPT; - return -1; - } - mapblock1 = 2; - i = ((__u16 *) DATABLOCK1)[logical_block >> 9]; - if (!i || ((mapblock2 != i) - && !minix_rdfsb (i, DATABLOCK2))) - { - errnum = ERR_FSYS_CORRUPT; - return -1; - } - mapblock2 = i; - return ((__u16 *) DATABLOCK2)[logical_block & 511]; -} - -/* read from INODE into BUF */ -int -minix_read (char *buf, int len) -{ - int logical_block; - int offset; - int map; - int ret = 0; - int size = 0; - - while (len > 0) - { - /* find the (logical) block component of our location */ - logical_block = filepos >> BLOCK_SIZE_BITS; - offset = filepos & (BLOCK_SIZE - 1); - map = minix_block_map (logical_block); -#ifdef DEBUG_MINIX - printf ("map=%d\n", map); -#endif - if (map < 0) - break; - - size = BLOCK_SIZE; - size -= offset; - if (size > len) - size = len; - - disk_read_func = disk_read_hook; - - devread (map * (BLOCK_SIZE / DEV_BSIZE), - offset, size, buf); - - disk_read_func = NULL; - - buf += size; - len -= size; - filepos += size; - ret += size; - } - - if (errnum) - ret = 0; - - return ret; -} - -/* preconditions: minix_mount already executed, therefore supblk in buffer - known as SUPERBLOCK - returns: 0 if error, nonzero iff we were able to find the file successfully - postconditions: on a nonzero return, buffer known as INODE contains the - inode of the file we were trying to look up - side effects: none yet */ -int -minix_dir (char *dirname) -{ - int current_ino = MINIX_ROOT_INO; /* start at the root */ - int updir_ino = current_ino; /* the parent of the current directory */ - int ino_blk; /* fs pointer of the inode's info */ - - int str_chk = 0; /* used ot hold the results of a string - compare */ - - struct minix_inode * raw_inode; /* inode info for current_ino */ - - char linkbuf[PATH_MAX]; /* buffer for following sym-links */ - int link_count = 0; - - char * rest; - char ch; - - int off; /* offset within block of directory - entry */ - int loc; /* location within a directory */ - int blk; /* which data blk within dir entry */ - long map; /* fs pointer of a particular block from - dir entry */ - struct minix_dir_entry * dp; /* pointer to directory entry */ - - /* loop invariants: - current_ino = inode to lookup - dirname = pointer to filename component we are cur looking up within - the directory known pointed to by current_ino (if any) */ - -#ifdef DEBUG_MINIX - printf ("\n"); -#endif - - while (1) - { -#ifdef DEBUG_MINIX - printf ("inode %d, dirname %s\n", current_ino, dirname); -#endif - - ino_blk = (2 + SUPERBLOCK->s_imap_blocks + SUPERBLOCK->s_zmap_blocks - + (current_ino - 1) / MINIX_INODES_PER_BLOCK); - if (! minix_rdfsb (ino_blk, (int) INODE)) - return 0; - - /* reset indirect blocks! */ - mapblock2 = mapblock1 = -1; - - raw_inode = INODE + ((current_ino - 1) % MINIX_INODES_PER_BLOCK); - - /* copy inode to fixed location */ - memmove ((void *) INODE, (void *) raw_inode, - sizeof (struct minix_inode)); - - /* If we've got a symbolic link, then chase it. */ - if (S_ISLNK (INODE->i_mode)) - { - int len; - - if (++link_count > MAX_LINK_COUNT) - { - errnum = ERR_SYMLINK_LOOP; - return 0; - } -#ifdef DEBUG_MINIX - printf ("S_ISLNK (%s)\n", dirname); -#endif - - /* Find out how long our remaining name is. */ - len = 0; - while (dirname[len] && !isspace (dirname[len])) - len++; - - /* Get the symlink size. */ - filemax = (INODE->i_size); - if (filemax + len > sizeof (linkbuf) - 2) - { - errnum = ERR_FILELENGTH; - return 0; - } - - if (len) - { - /* Copy the remaining name to the end of the symlink data. - Note that DIRNAME and LINKBUF may overlap! */ - memmove (linkbuf + filemax, dirname, len); - } - linkbuf[filemax + len] = '\0'; - - /* Read the necessary blocks, and reset the file pointer. */ - len = grub_read (linkbuf, filemax); - filepos = 0; - if (!len) - return 0; - -#ifdef DEBUG_MINIX - printf ("symlink=%s\n", linkbuf); -#endif - - dirname = linkbuf; - if (*dirname == '/') - { - /* It's an absolute link, so look it up in root. */ - current_ino = MINIX_ROOT_INO; - updir_ino = current_ino; - } - else - { - /* Relative, so look it up in our parent directory. */ - current_ino = updir_ino; - } - - /* Try again using the new name. */ - continue; - } - - /* If end of filename, INODE points to the file's inode */ - if (!*dirname || isspace (*dirname)) - { - if (!S_ISREG (INODE->i_mode)) - { - errnum = ERR_BAD_FILETYPE; - return 0; - } - - filemax = (INODE->i_size); - return 1; - } - - /* else we have to traverse a directory */ - updir_ino = current_ino; - - /* skip over slashes */ - while (*dirname == '/') - dirname++; - - /* if this isn't a directory of sufficient size to hold our file, - abort */ - if (!(INODE->i_size) || !S_ISDIR (INODE->i_mode)) - { - errnum = ERR_BAD_FILETYPE; - return 0; - } - - /* skip to next slash or end of filename (space) */ - for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/'; - rest++); - - /* look through this directory and find the next filename component */ - /* invariant: rest points to slash after the next filename component */ - *rest = 0; - loc = 0; - - do - { -#ifdef DEBUG_MINIX - printf ("dirname=`%s', rest=`%s', loc=%d\n", dirname, rest, loc); -#endif - - /* if our location/byte offset into the directory exceeds the size, - give up */ - if (loc >= INODE->i_size) - { - if (print_possibilities < 0) - { -#if 0 - putchar ('\n'); -#endif - } - else - { - errnum = ERR_FILE_NOT_FOUND; - *rest = ch; - } - return (print_possibilities < 0); - } - - /* else, find the (logical) block component of our location */ - blk = loc >> BLOCK_SIZE_BITS; - - /* we know which logical block of the directory entry we are looking - for, now we have to translate that to the physical (fs) block on - the disk */ - map = minix_block_map (blk); -#ifdef DEBUG_MINIX - printf ("fs block=%d\n", map); -#endif - mapblock2 = -1; - if ((map < 0) || !minix_rdfsb (map, DATABLOCK2)) - { - errnum = ERR_FSYS_CORRUPT; - *rest = ch; - return 0; - } - off = loc & (BLOCK_SIZE - 1); - dp = (struct minix_dir_entry *) (DATABLOCK2 + off); - /* advance loc prematurely to next on-disk directory entry */ - loc += sizeof (dp->inode) + namelen; - - /* NOTE: minix filenames are NULL terminated if < NAMELEN - else exact */ - -#ifdef DEBUG_MINIX - printf ("directory entry ino=%d\n", dp->inode); - if (dp->inode) - printf ("entry=%s\n", dp->name); -#endif - - if (dp->inode) - { - int saved_c = dp->name[namelen]; - - dp->name[namelen] = 0; - str_chk = substring (dirname, dp->name); - -# ifndef STAGE1_5 - if (print_possibilities && ch != '/' - && (!*dirname || str_chk <= 0)) - { - if (print_possibilities > 0) - print_possibilities = -print_possibilities; - print_a_completion (dp->name); - } -# endif - - dp->name[namelen] = saved_c; - } - - } - while (!dp->inode || (str_chk || (print_possibilities && ch != '/'))); - - current_ino = dp->inode; - *(dirname = rest) = ch; - } - /* never get here */ -} - -#endif /* FSYS_MINIX */ diff --git a/src/filo/fs/fsys_reiserfs.c b/src/filo/fs/fsys_reiserfs.c deleted file mode 100644 index fbc2d74af..000000000 --- a/src/filo/fs/fsys_reiserfs.c +++ /dev/null @@ -1,1239 +0,0 @@ -/* fsys_reiserfs.c - an implementation for the ReiserFS filesystem */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2000, 2001 Free Software Foundation, Inc. - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifdef FSYS_REISERFS -#include "shared.h" -#include "filesys.h" -#include <lib.h> -#include "string.h" - -#undef REISERDEBUG - -/* Some parts of this code (mainly the structures and defines) are - * from the original reiser fs code, as found in the linux kernel. - */ - -/* include/asm-i386/types.h */ -typedef __signed__ char __s8; -typedef unsigned char __u8; -typedef __signed__ short __s16; -typedef unsigned short __u16; -typedef __signed__ int __s32; -typedef unsigned int __u32; -typedef unsigned long long __u64; - -/* linux/posix_type.h */ -typedef long linux_off_t; - -/* linux/little_endian.h */ -#define __cpu_to_le64(x) ((__u64) (x)) -#define __le64_to_cpu(x) ((__u64) (x)) -#define __cpu_to_le32(x) ((__u32) (x)) -#define __le32_to_cpu(x) ((__u32) (x)) -#define __cpu_to_le16(x) ((__u16) (x)) -#define __le16_to_cpu(x) ((__u16) (x)) - -/* include/linux/reiser_fs.h */ -/* This is the new super block of a journaling reiserfs system */ -struct reiserfs_super_block -{ - __u32 s_block_count; /* blocks count */ - __u32 s_free_blocks; /* free blocks count */ - __u32 s_root_block; /* root block number */ - __u32 s_journal_block; /* journal block number */ - __u32 s_journal_dev; /* journal device number */ - __u32 s_journal_size; /* size of the journal on FS creation. used to make sure they don't overflow it */ - __u32 s_journal_trans_max; /* max number of blocks in a transaction. */ - __u32 s_journal_magic; /* random value made on fs creation */ - __u32 s_journal_max_batch; /* max number of blocks to batch into a trans */ - __u32 s_journal_max_commit_age; /* in seconds, how old can an async commit be */ - __u32 s_journal_max_trans_age; /* in seconds, how old can a transaction be */ - __u16 s_blocksize; /* block size */ - __u16 s_oid_maxsize; /* max size of object id array */ - __u16 s_oid_cursize; /* current size of object id array */ - __u16 s_state; /* valid or error */ - char s_magic[16]; /* reiserfs magic string indicates that file system is reiserfs */ - __u16 s_tree_height; /* height of disk tree */ - __u16 s_bmap_nr; /* amount of bitmap blocks needed to address each block of file system */ - __u16 s_version; - char s_unused[128]; /* zero filled by mkreiserfs */ -}; - -#define REISERFS_MAX_SUPPORTED_VERSION 2 -#define REISERFS_SUPER_MAGIC_STRING "ReIsErFs" -#define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs" - -#define MAX_HEIGHT 7 - -/* must be correct to keep the desc and commit structs at 4k */ -#define JOURNAL_TRANS_HALF 1018 - -/* first block written in a commit. */ -struct reiserfs_journal_desc { - __u32 j_trans_id; /* id of commit */ - __u32 j_len; /* length of commit. len +1 is the commit block */ - __u32 j_mount_id; /* mount id of this trans*/ - __u32 j_realblock[JOURNAL_TRANS_HALF]; /* real locations for the first blocks */ - char j_magic[12]; -}; - -/* last block written in a commit */ -struct reiserfs_journal_commit { - __u32 j_trans_id; /* must match j_trans_id from the desc block */ - __u32 j_len; /* ditto */ - __u32 j_realblock[JOURNAL_TRANS_HALF]; /* real locations for the last blocks */ - char j_digest[16]; /* md5 sum of all the blocks involved, including desc and commit. not used, kill it */ -}; - -/* this header block gets written whenever a transaction is considered - fully flushed, and is more recent than the last fully flushed - transaction. - fully flushed means all the log blocks and all the real blocks are - on disk, and this transaction does not need to be replayed. -*/ -struct reiserfs_journal_header { - /* id of last fully flushed transaction */ - __u32 j_last_flush_trans_id; - /* offset in the log of where to start replay after a crash */ - __u32 j_first_unflushed_offset; - /* mount id to detect very old transactions */ - __u32 j_mount_id; -}; - -/* magic string to find desc blocks in the journal */ -#define JOURNAL_DESC_MAGIC "ReIsErLB" - - -/* - * directories use this key as well as old files - */ -struct offset_v1 -{ - /* - * for regular files this is the offset to the first byte of the - * body, contained in the object-item, as measured from the start of - * the entire body of the object. - * - * for directory entries, k_offset consists of hash derived from - * hashing the name and using few bits (23 or more) of the resulting - * hash, and generation number that allows distinguishing names with - * hash collisions. If number of collisions overflows generation - * number, we return EEXIST. High order bit is 0 always - */ - __u32 k_offset; - __u32 k_uniqueness; -}; - -struct offset_v2 -{ - /* - * for regular files this is the offset to the first byte of the - * body, contained in the object-item, as measured from the start of - * the entire body of the object. - * - * for directory entries, k_offset consists of hash derived from - * hashing the name and using few bits (23 or more) of the resulting - * hash, and generation number that allows distinguishing names with - * hash collisions. If number of collisions overflows generation - * number, we return EEXIST. High order bit is 0 always - */ - __u64 k_offset:60; - __u64 k_type: 4; -}; - - -struct key -{ - /* packing locality: by default parent directory object id */ - __u32 k_dir_id; - /* object identifier */ - __u32 k_objectid; - /* the offset and node type (old and new form) */ - union - { - struct offset_v1 v1; - struct offset_v2 v2; - } - u; -}; - -#define KEY_SIZE (sizeof (struct key)) - -/* Header of a disk block. More precisely, header of a formatted leaf - or internal node, and not the header of an unformatted node. */ -struct block_head -{ - __u16 blk_level; /* Level of a block in the tree. */ - __u16 blk_nr_item; /* Number of keys/items in a block. */ - __u16 blk_free_space; /* Block free space in bytes. */ - struct key blk_right_delim_key; /* Right delimiting key for this block (supported for leaf level nodes - only) */ -}; -#define BLKH_SIZE (sizeof (struct block_head)) -#define DISK_LEAF_NODE_LEVEL 1 /* Leaf node level. */ - -struct item_head -{ - struct key ih_key; /* Everything in the tree is found by searching for it based on its key.*/ - - union - { - __u16 ih_free_space; /* The free space in the last unformatted node of an indirect item if this - is an indirect item. This equals 0xFFFF iff this is a direct item or - stat data item. Note that the key, not this field, is used to determine - the item type, and thus which field this union contains. */ - __u16 ih_entry_count; /* Iff this is a directory item, this field equals the number of directory - entries in the directory item. */ - } - u; - __u16 ih_item_len; /* total size of the item body */ - __u16 ih_item_location; /* an offset to the item body within the block */ - __u16 ih_version; /* ITEM_VERSION_1 for all old items, - ITEM_VERSION_2 for new ones. - Highest bit is set by fsck - temporary, cleaned after all done */ -}; -/* size of item header */ -#define IH_SIZE (sizeof (struct item_head)) - -#define ITEM_VERSION_1 0 -#define ITEM_VERSION_2 1 -#define IH_KEY_OFFSET(ih) ((ih)->ih_version == ITEM_VERSION_1 \ - ? (ih)->ih_key.u.v1.k_offset \ - : (ih)->ih_key.u.v2.k_offset) - -#define IH_KEY_ISTYPE(ih, type) ((ih)->ih_version == ITEM_VERSION_1 \ - ? (ih)->ih_key.u.v1.k_uniqueness == V1_##type \ - : (ih)->ih_key.u.v2.k_type == V2_##type) - -struct disk_child -{ - unsigned long dc_block_number; /* Disk child's block number. */ - unsigned short dc_size; /* Disk child's used space. */ -}; - -#define DC_SIZE (sizeof (struct disk_child)) - -/* Stat Data on disk. - * - * Note that reiserfs has two different forms of stat data. Luckily - * the fields needed by grub are at the same position. - */ -struct stat_data -{ - __u16 sd_mode; /* file type, permissions */ - __u16 sd_notused1[3]; /* fields not needed by reiserfs */ - __u32 sd_size; /* file size */ - __u32 sd_size_hi; /* file size high 32 bits (since version 2) */ -}; - -struct reiserfs_de_head -{ - __u32 deh_offset; /* third component of the directory entry key */ - __u32 deh_dir_id; /* objectid of the parent directory of the - object, that is referenced by directory entry */ - __u32 deh_objectid;/* objectid of the object, that is referenced by - directory entry */ - __u16 deh_location;/* offset of name in the whole item */ - __u16 deh_state; /* whether 1) entry contains stat data (for - future), and 2) whether entry is hidden - (unlinked) */ -}; - -#define DEH_SIZE (sizeof (struct reiserfs_de_head)) - -#define DEH_Statdata (1 << 0) /* not used now */ -#define DEH_Visible (1 << 2) - -#define SD_OFFSET 0 -#define SD_UNIQUENESS 0 -#define DOT_OFFSET 1 -#define DOT_DOT_OFFSET 2 -#define DIRENTRY_UNIQUENESS 500 - -#define V1_TYPE_STAT_DATA 0x0 -#define V1_TYPE_DIRECT 0xffffffff -#define V1_TYPE_INDIRECT 0xfffffffe -#define V1_TYPE_DIRECTORY_MAX 0xfffffffd -#define V2_TYPE_STAT_DATA 0 -#define V2_TYPE_INDIRECT 1 -#define V2_TYPE_DIRECT 2 -#define V2_TYPE_DIRENTRY 3 - -#define REISERFS_ROOT_OBJECTID 2 -#define REISERFS_ROOT_PARENT_OBJECTID 1 -#define REISERFS_DISK_OFFSET_IN_BYTES (64 * 1024) -/* the spot for the super in versions 3.5 - 3.5.11 (inclusive) */ -#define REISERFS_OLD_DISK_OFFSET_IN_BYTES (8 * 1024) -#define REISERFS_OLD_BLOCKSIZE 4096 - -#define S_ISREG(mode) (((mode) & 0170000) == 0100000) -#define S_ISDIR(mode) (((mode) & 0170000) == 0040000) -#define S_ISLNK(mode) (((mode) & 0170000) == 0120000) - -#define PATH_MAX 1024 /* include/linux/limits.h */ -#define MAX_LINK_COUNT 5 /* number of symbolic links to follow */ - -/* The size of the node cache */ -#define FSYSREISER_CACHE_SIZE 24*1024 -#define FSYSREISER_MIN_BLOCKSIZE SECTOR_SIZE -#define FSYSREISER_MAX_BLOCKSIZE FSYSREISER_CACHE_SIZE / 3 - -/* Info about currently opened file */ -struct fsys_reiser_fileinfo -{ - __u32 k_dir_id; - __u32 k_objectid; -}; - -/* In memory info about the currently mounted filesystem */ -struct fsys_reiser_info -{ - /* The last read item head */ - struct item_head *current_ih; - /* The last read item */ - char *current_item; - /* The information for the currently opened file */ - struct fsys_reiser_fileinfo fileinfo; - /* The start of the journal */ - __u32 journal_block; - /* The size of the journal */ - __u32 journal_block_count; - /* The first valid descriptor block in journal - (relative to journal_block) */ - __u32 journal_first_desc; - - /* The ReiserFS version. */ - __u16 version; - /* The current depth of the reiser tree. */ - __u16 tree_depth; - /* SECTOR_SIZE << blocksize_shift == blocksize. */ - __u8 blocksize_shift; - /* 1 << full_blocksize_shift == blocksize. */ - __u8 fullblocksize_shift; - /* The reiserfs block size (must be a power of 2) */ - __u16 blocksize; - /* The number of cached tree nodes */ - __u16 cached_slots; - /* The number of valid transactions in journal */ - __u16 journal_transactions; - - unsigned int blocks[MAX_HEIGHT]; - unsigned int next_key_nr[MAX_HEIGHT]; -}; - -/* The cached s+tree blocks in FSYS_BUF, see below - * for a more detailed description. - */ -#define ROOT ((char *) ((int) FSYS_BUF)) -#define CACHE(i) (ROOT + ((i) << INFO->fullblocksize_shift)) -#define LEAF CACHE (DISK_LEAF_NODE_LEVEL) - -#define BLOCKHEAD(cache) ((struct block_head *) cache) -#define ITEMHEAD ((struct item_head *) ((int) LEAF + BLKH_SIZE)) -#define KEY(cache) ((struct key *) ((int) cache + BLKH_SIZE)) -#define DC(cache) ((struct disk_child *) \ - ((int) cache + BLKH_SIZE + KEY_SIZE * nr_item)) -/* The fsys_reiser_info block. - */ -#define INFO \ - ((struct fsys_reiser_info *) ((int) FSYS_BUF + FSYSREISER_CACHE_SIZE)) -/* - * The journal cache. For each transaction it contains the number of - * blocks followed by the real block numbers of this transaction. - * - * If the block numbers of some transaction won't fit in this space, - * this list is stopped with a 0xffffffff marker and the remaining - * uncommitted transactions aren't cached. - */ -#define JOURNAL_START ((__u32 *) (INFO + 1)) -#define JOURNAL_END ((__u32 *) (FSYS_BUF + FSYS_BUFLEN)) - - -static __inline__ unsigned long -log2 (unsigned long word) -{ - __asm__ ("bsfl %1,%0" - : "=r" (word) - : "r" (word)); - return word; -} - -static __inline__ int -is_power_of_two (unsigned long word) -{ - return (word & -word) == word; -} - -static int -journal_read (int block, int len, char *buffer) -{ - return devread ((INFO->journal_block + block) << INFO->blocksize_shift, - 0, len, buffer); -} - -/* Read a block from ReiserFS file system, taking the journal into - * account. If the block nr is in the journal, the block from the - * journal taken. - */ -static int -block_read (int blockNr, int start, int len, char *buffer) -{ - int transactions = INFO->journal_transactions; - int desc_block = INFO->journal_first_desc; - int journal_mask = INFO->journal_block_count - 1; - int translatedNr = blockNr; - __u32 *journal_table = JOURNAL_START; - while (transactions-- > 0) - { - int i = 0; - int j_len; - if (*journal_table != 0xffffffff) - { - /* Search for the blockNr in cached journal */ - j_len = *journal_table++; - while (i++ < j_len) - { - if (*journal_table++ == blockNr) - { - journal_table += j_len - i; - goto found; - } - } - } - else - { - /* This is the end of cached journal marker. The remaining - * transactions are still on disk. - */ - struct reiserfs_journal_desc desc; - struct reiserfs_journal_commit commit; - - if (! journal_read (desc_block, sizeof (desc), (char *) &desc)) - return 0; - - j_len = desc.j_len; - while (i < j_len && i < JOURNAL_TRANS_HALF) - if (desc.j_realblock[i++] == blockNr) - goto found; - - if (j_len >= JOURNAL_TRANS_HALF) - { - int commit_block = (desc_block + 1 + j_len) & journal_mask; - if (! journal_read (commit_block, - sizeof (commit), (char *) &commit)) - return 0; - while (i < j_len) - if (commit.j_realblock[i++ - JOURNAL_TRANS_HALF] == blockNr) - goto found; - } - } - goto not_found; - - found: - translatedNr = INFO->journal_block + ((desc_block + i) & journal_mask); -#ifdef REISERDEBUG - printf ("block_read: block %d is mapped to journal block %d.\n", - blockNr, translatedNr - INFO->journal_block); -#endif - /* We must continue the search, as this block may be overwritten - * in later transactions. - */ - not_found: - desc_block = (desc_block + 2 + j_len) & journal_mask; - } - return devread (translatedNr << INFO->blocksize_shift, start, len, buffer); -} - -/* Init the journal data structure. We try to cache as much as - * possible in the JOURNAL_START-JOURNAL_END space, but if it is full - * we can still read the rest from the disk on demand. - * - * The first number of valid transactions and the descriptor block of the - * first valid transaction are held in INFO. The transactions are all - * adjacent, but we must take care of the journal wrap around. - */ -static int -journal_init (void) -{ - unsigned int block_count = INFO->journal_block_count; - unsigned int desc_block; - unsigned int commit_block; - unsigned int next_trans_id; - struct reiserfs_journal_header header; - struct reiserfs_journal_desc desc; - struct reiserfs_journal_commit commit; - __u32 *journal_table = JOURNAL_START; - - journal_read (block_count, sizeof (header), (char *) &header); - desc_block = header.j_first_unflushed_offset; - if (desc_block >= block_count) - return 0; - - INFO->journal_first_desc = desc_block; - next_trans_id = header.j_last_flush_trans_id + 1; - -#ifdef REISERDEBUG - printf ("journal_init: last flushed %d\n", - header.j_last_flush_trans_id); -#endif - - while (1) - { - journal_read (desc_block, sizeof (desc), (char *) &desc); - if (substring (JOURNAL_DESC_MAGIC, desc.j_magic) > 0 - || desc.j_trans_id != next_trans_id - || desc.j_mount_id != header.j_mount_id) - /* no more valid transactions */ - break; - - commit_block = (desc_block + desc.j_len + 1) & (block_count - 1); - journal_read (commit_block, sizeof (commit), (char *) &commit); - if (desc.j_trans_id != commit.j_trans_id - || desc.j_len != commit.j_len) - /* no more valid transactions */ - break; - -#ifdef REISERDEBUG - printf ("Found valid transaction %d/%d at %d.\n", - desc.j_trans_id, desc.j_mount_id, desc_block); -#endif - - next_trans_id++; - if (journal_table < JOURNAL_END) - { - if ((journal_table + 1 + desc.j_len) >= JOURNAL_END) - { - /* The table is almost full; mark the end of the cached - * journal.*/ - *journal_table = 0xffffffff; - journal_table = JOURNAL_END; - } - else - { - int i; - /* Cache the length and the realblock numbers in the table. - * The block number of descriptor can easily be computed. - * and need not to be stored here. - */ - *journal_table++ = desc.j_len; - for (i = 0; i < desc.j_len && i < JOURNAL_TRANS_HALF; i++) - { - *journal_table++ = desc.j_realblock[i]; -#ifdef REISERDEBUG - printf ("block %d is in journal %d.\n", - desc.j_realblock[i], desc_block); -#endif - } - for ( ; i < desc.j_len; i++) - { - *journal_table++ = commit.j_realblock[i-JOURNAL_TRANS_HALF]; -#ifdef REISERDEBUG - printf ("block %d is in journal %d.\n", - commit.j_realblock[i-JOURNAL_TRANS_HALF], - desc_block); -#endif - } - } - } - desc_block = (commit_block + 1) & (block_count - 1); - } -#ifdef REISERDEBUG - printf ("Transaction %d/%d at %d isn't valid.\n", - desc.j_trans_id, desc.j_mount_id, desc_block); -#endif - - INFO->journal_transactions - = next_trans_id - header.j_last_flush_trans_id - 1; - return errnum == 0; -} - -/* check filesystem types and read superblock into memory buffer */ -int -reiserfs_mount (void) -{ - struct reiserfs_super_block super; - int superblock = REISERFS_DISK_OFFSET_IN_BYTES >> SECTOR_BITS; - - if (part_length < superblock + (sizeof (super) >> SECTOR_BITS) - || ! devread (superblock, 0, sizeof (struct reiserfs_super_block), - (char *) &super) - || (substring (REISER2FS_SUPER_MAGIC_STRING, super.s_magic) > 0 - && substring (REISERFS_SUPER_MAGIC_STRING, super.s_magic) > 0) - || (/* check that this is not a copy inside the journal log */ - super.s_journal_block * super.s_blocksize - <= REISERFS_DISK_OFFSET_IN_BYTES)) - { - /* Try old super block position */ - superblock = REISERFS_OLD_DISK_OFFSET_IN_BYTES >> SECTOR_BITS; - if (part_length < superblock + (sizeof (super) >> SECTOR_BITS) - || ! devread (superblock, 0, sizeof (struct reiserfs_super_block), - (char *) &super)) - return 0; - - if (substring (REISER2FS_SUPER_MAGIC_STRING, super.s_magic) > 0 - && substring (REISERFS_SUPER_MAGIC_STRING, super.s_magic) > 0) - { - /* pre journaling super block ? */ - if (substring (REISERFS_SUPER_MAGIC_STRING, - (char*) ((int) &super + 20)) > 0) - return 0; - - super.s_blocksize = REISERFS_OLD_BLOCKSIZE; - super.s_journal_block = 0; - super.s_version = 0; - } - } - - /* check the version number. */ - if (super.s_version > REISERFS_MAX_SUPPORTED_VERSION) - return 0; - - INFO->version = super.s_version; - INFO->blocksize = super.s_blocksize; - INFO->fullblocksize_shift = log2 (super.s_blocksize); - INFO->blocksize_shift = INFO->fullblocksize_shift - SECTOR_BITS; - INFO->cached_slots = - (FSYSREISER_CACHE_SIZE >> INFO->fullblocksize_shift) - 1; - -#ifdef REISERDEBUG - printf ("reiserfs_mount: version=%d, blocksize=%d\n", - INFO->version, INFO->blocksize); -#endif /* REISERDEBUG */ - - /* Clear node cache. */ - memset (INFO->blocks, 0, sizeof (INFO->blocks)); - - if (super.s_blocksize < FSYSREISER_MIN_BLOCKSIZE - || super.s_blocksize > FSYSREISER_MAX_BLOCKSIZE - || (SECTOR_SIZE << INFO->blocksize_shift) != super.s_blocksize) - return 0; - - /* Initialize journal code. If something fails we end with zero - * journal_transactions, so we don't access the journal at all. - */ - INFO->journal_transactions = 0; - if (super.s_journal_block != 0 && super.s_journal_dev == 0) - { - INFO->journal_block = super.s_journal_block; - INFO->journal_block_count = super.s_journal_size; - if (is_power_of_two (INFO->journal_block_count)) - journal_init (); - - /* Read in super block again, maybe it is in the journal */ - block_read (superblock >> INFO->blocksize_shift, - 0, sizeof (struct reiserfs_super_block), (char *) &super); - } - - if (! block_read (super.s_root_block, 0, INFO->blocksize, (char*) ROOT)) - return 0; - - INFO->tree_depth = BLOCKHEAD (ROOT)->blk_level; - -#ifdef REISERDEBUG - printf ("root read_in: block=%d, depth=%d\n", - super.s_root_block, INFO->tree_depth); -#endif /* REISERDEBUG */ - - if (INFO->tree_depth >= MAX_HEIGHT) - return 0; - if (INFO->tree_depth == DISK_LEAF_NODE_LEVEL) - { - /* There is only one node in the whole filesystem, - * which is simultanously leaf and root */ - memcpy (LEAF, ROOT, INFO->blocksize); - } - return 1; -} - -/***************** TREE ACCESSING METHODS *****************************/ - -/* I assume you are familiar with the ReiserFS tree, if not go to - * http://www.namesys.com/content_table.html - * - * My tree node cache is organized as following - * 0 ROOT node - * 1 LEAF node (if the ROOT is also a LEAF it is copied here - * 2-n other nodes on current path from bottom to top. - * if there is not enough space in the cache, the top most are - * omitted. - * - * I have only two methods to find a key in the tree: - * search_stat(dir_id, objectid) searches for the stat entry (always - * the first entry) of an object. - * next_key() gets the next key in tree order. - * - * This means, that I can only sequential reads of files are - * efficient, but this really doesn't hurt for grub. - */ - -/* Read in the node at the current path and depth into the node cache. - * You must set INFO->blocks[depth] before. - */ -static char * -read_tree_node (unsigned int blockNr, int depth) -{ - char* cache = CACHE(depth); - int num_cached = INFO->cached_slots; - if (depth < num_cached) - { - /* This is the cached part of the path. Check if same block is - * needed. - */ - if (blockNr == INFO->blocks[depth]) - return cache; - } - else - cache = CACHE(num_cached); - -#ifdef REISERDEBUG - printf (" next read_in: block=%d (depth=%d)\n", - blockNr, depth); -#endif /* REISERDEBUG */ - if (! block_read (blockNr, 0, INFO->blocksize, cache)) - return 0; - /* Make sure it has the right node level */ - if (BLOCKHEAD (cache)->blk_level != depth) - { - errnum = ERR_FSYS_CORRUPT; - return 0; - } - - INFO->blocks[depth] = blockNr; - return cache; -} - -/* Get the next key, i.e. the key following the last retrieved key in - * tree order. INFO->current_ih and - * INFO->current_info are adapted accordingly. */ -static int -next_key (void) -{ - int depth; - struct item_head *ih = INFO->current_ih + 1; - char *cache; - -#ifdef REISERDEBUG - printf ("next_key:\n old ih: key %d:%d:%d:%d version:%d\n", - INFO->current_ih->ih_key.k_dir_id, - INFO->current_ih->ih_key.k_objectid, - INFO->current_ih->ih_key.u.v1.k_offset, - INFO->current_ih->ih_key.u.v1.k_uniqueness, - INFO->current_ih->ih_version); -#endif /* REISERDEBUG */ - - if (ih == &ITEMHEAD[BLOCKHEAD (LEAF)->blk_nr_item]) - { - depth = DISK_LEAF_NODE_LEVEL; - /* The last item, was the last in the leaf node. - * Read in the next block - */ - do - { - if (depth == INFO->tree_depth) - { - /* There are no more keys at all. - * Return a dummy item with MAX_KEY */ - ih = (struct item_head *) &BLOCKHEAD (LEAF)->blk_right_delim_key; - goto found; - } - depth++; -#ifdef REISERDEBUG - printf (" depth=%d, i=%d\n", depth, INFO->next_key_nr[depth]); -#endif /* REISERDEBUG */ - } - while (INFO->next_key_nr[depth] == 0); - - if (depth == INFO->tree_depth) - cache = ROOT; - else if (depth <= INFO->cached_slots) - cache = CACHE (depth); - else - { - cache = read_tree_node (INFO->blocks[depth], depth); - if (! cache) - return 0; - } - - do - { - int nr_item = BLOCKHEAD (cache)->blk_nr_item; - int key_nr = INFO->next_key_nr[depth]++; -#ifdef REISERDEBUG - printf (" depth=%d, i=%d/%d\n", depth, key_nr, nr_item); -#endif /* REISERDEBUG */ - if (key_nr == nr_item) - /* This is the last item in this block, set the next_key_nr to 0 */ - INFO->next_key_nr[depth] = 0; - - cache = read_tree_node (DC (cache)[key_nr].dc_block_number, --depth); - if (! cache) - return 0; - } - while (depth > DISK_LEAF_NODE_LEVEL); - - ih = ITEMHEAD; - } - found: - INFO->current_ih = ih; - INFO->current_item = &LEAF[ih->ih_item_location]; -#ifdef REISERDEBUG - printf (" new ih: key %d:%d:%d:%d version:%d\n", - INFO->current_ih->ih_key.k_dir_id, - INFO->current_ih->ih_key.k_objectid, - INFO->current_ih->ih_key.u.v1.k_offset, - INFO->current_ih->ih_key.u.v1.k_uniqueness, - INFO->current_ih->ih_version); -#endif /* REISERDEBUG */ - return 1; -} - -/* preconditions: reiserfs_mount already executed, therefore - * INFO block is valid - * returns: 0 if error (errnum is set), - * nonzero iff we were able to find the key successfully. - * postconditions: on a nonzero return, the current_ih and - * current_item fields describe the key that equals the - * searched key. INFO->next_key contains the next key after - * the searched key. - * side effects: messes around with the cache. - */ -static int -search_stat (__u32 dir_id, __u32 objectid) -{ - char *cache; - int depth; - int nr_item; - int i; - struct item_head *ih; -#ifdef REISERDEBUG - printf ("search_stat:\n key %d:%d:0:0\n", dir_id, objectid); -#endif /* REISERDEBUG */ - - depth = INFO->tree_depth; - cache = ROOT; - - while (depth > DISK_LEAF_NODE_LEVEL) - { - struct key *key; - nr_item = BLOCKHEAD (cache)->blk_nr_item; - - key = KEY (cache); - - for (i = 0; i < nr_item; i++) - { - if (key->k_dir_id > dir_id - || (key->k_dir_id == dir_id - && (key->k_objectid > objectid - || (key->k_objectid == objectid - && (key->u.v1.k_offset - | key->u.v1.k_uniqueness) > 0)))) - break; - key++; - } - -#ifdef REISERDEBUG - printf (" depth=%d, i=%d/%d\n", depth, i, nr_item); -#endif /* REISERDEBUG */ - INFO->next_key_nr[depth] = (i == nr_item) ? 0 : i+1; - cache = read_tree_node (DC (cache)[i].dc_block_number, --depth); - if (! cache) - return 0; - } - - /* cache == LEAF */ - nr_item = BLOCKHEAD (LEAF)->blk_nr_item; - ih = ITEMHEAD; - for (i = 0; i < nr_item; i++) - { - if (ih->ih_key.k_dir_id == dir_id - && ih->ih_key.k_objectid == objectid - && ih->ih_key.u.v1.k_offset == 0 - && ih->ih_key.u.v1.k_uniqueness == 0) - { -#ifdef REISERDEBUG - printf (" depth=%d, i=%d/%d\n", depth, i, nr_item); -#endif /* REISERDEBUG */ - INFO->current_ih = ih; - INFO->current_item = &LEAF[ih->ih_item_location]; - return 1; - } - ih++; - } - errnum = ERR_FSYS_CORRUPT; - return 0; -} - -int -reiserfs_read (char *buf, int len) -{ - unsigned int blocksize; - unsigned int offset; - unsigned int to_read; - char *prev_buf = buf; - -#ifdef REISERDEBUG - printf ("reiserfs_read: filepos=%d len=%d, offset=%x:%x\n", - filepos, len, (__u64) IH_KEY_OFFSET (INFO->current_ih) - 1); -#endif /* REISERDEBUG */ - - if (INFO->current_ih->ih_key.k_objectid != INFO->fileinfo.k_objectid - || IH_KEY_OFFSET (INFO->current_ih) > filepos + 1) - { - search_stat (INFO->fileinfo.k_dir_id, INFO->fileinfo.k_objectid); - goto get_next_key; - } - - while (! errnum) - { - if (INFO->current_ih->ih_key.k_objectid != INFO->fileinfo.k_objectid) - break; - - offset = filepos - IH_KEY_OFFSET (INFO->current_ih) + 1; - blocksize = INFO->current_ih->ih_item_len; - -#ifdef REISERDEBUG - printf (" loop: filepos=%d len=%d, offset=%d blocksize=%d\n", - filepos, len, offset, blocksize); -#endif /* REISERDEBUG */ - - if (IH_KEY_ISTYPE(INFO->current_ih, TYPE_DIRECT) - && offset < blocksize) - { -#ifdef REISERDEBUG - printf ("direct_read: offset=%d, blocksize=%d\n", - offset, blocksize); -#endif /* REISERDEBUG */ - to_read = blocksize - offset; - if (to_read > len) - to_read = len; - - if (disk_read_hook != NULL) - { - disk_read_func = disk_read_hook; - - block_read (INFO->blocks[DISK_LEAF_NODE_LEVEL], - (INFO->current_item - LEAF + offset), to_read, buf); - - disk_read_func = NULL; - } - else - memcpy (buf, INFO->current_item + offset, to_read); - goto update_buf_len; - } - else if (IH_KEY_ISTYPE(INFO->current_ih, TYPE_INDIRECT)) - { - blocksize = (blocksize >> 2) << INFO->fullblocksize_shift; -#ifdef REISERDEBUG - printf ("indirect_read: offset=%d, blocksize=%d\n", - offset, blocksize); -#endif /* REISERDEBUG */ - - while (offset < blocksize) - { - __u32 blocknr = ((__u32 *) INFO->current_item) - [offset >> INFO->fullblocksize_shift]; - int blk_offset = offset & (INFO->blocksize-1); - - to_read = INFO->blocksize - blk_offset; - if (to_read > len) - to_read = len; - - disk_read_func = disk_read_hook; - - /* Journal is only for meta data. Data blocks can be read - * directly without using block_read - */ - devread (blocknr << INFO->blocksize_shift, - blk_offset, to_read, buf); - - disk_read_func = NULL; - update_buf_len: - len -= to_read; - buf += to_read; - offset += to_read; - filepos += to_read; - if (len == 0) - goto done; - } - } - get_next_key: - next_key (); - } - done: - return errnum ? 0 : buf - prev_buf; -} - - -/* preconditions: reiserfs_mount already executed, therefore - * INFO block is valid - * returns: 0 if error, nonzero iff we were able to find the file successfully - * postconditions: on a nonzero return, INFO->fileinfo contains the info - * of the file we were trying to look up, filepos is 0 and filemax is - * the size of the file. - */ -int -reiserfs_dir (char *dirname) -{ - struct reiserfs_de_head *de_head; - char *rest, ch; - __u32 dir_id, objectid, parent_dir_id = 0, parent_objectid = 0; -#ifndef STAGE1_5 - int do_possibilities = 0; -#endif /* ! STAGE1_5 */ - char linkbuf[PATH_MAX]; /* buffer for following symbolic links */ - int link_count = 0; - int mode; - - dir_id = REISERFS_ROOT_PARENT_OBJECTID; - objectid = REISERFS_ROOT_OBJECTID; - - while (1) - { -#ifdef REISERDEBUG - printf ("dirname=%s\n", dirname); -#endif /* REISERDEBUG */ - - /* Search for the stat info first. */ - if (! search_stat (dir_id, objectid)) - return 0; - -#ifdef REISERDEBUG - printf ("sd_mode=%x sd_size=%d\n", - ((struct stat_data *) INFO->current_item)->sd_mode, - ((struct stat_data *) INFO->current_item)->sd_size); -#endif /* REISERDEBUG */ - - mode = ((struct stat_data *) INFO->current_item)->sd_mode; - - /* If we've got a symbolic link, then chase it. */ - if (S_ISLNK (mode)) - { - int len; - if (++link_count > MAX_LINK_COUNT) - { - errnum = ERR_SYMLINK_LOOP; - return 0; - } - - /* Get the symlink size. */ - filemax = ((struct stat_data *) INFO->current_item)->sd_size; - - /* Find out how long our remaining name is. */ - len = 0; - while (dirname[len] && !isspace (dirname[len])) - len++; - - if (filemax + len > sizeof (linkbuf) - 1) - { - errnum = ERR_FILELENGTH; - return 0; - } - - /* Copy the remaining name to the end of the symlink data. - Note that DIRNAME and LINKBUF may overlap! */ - grub_memmove (linkbuf + filemax, dirname, len+1); - - INFO->fileinfo.k_dir_id = dir_id; - INFO->fileinfo.k_objectid = objectid; - filepos = 0; - if (! next_key () - || reiserfs_read (linkbuf, filemax) != filemax) - { - if (! errnum) - errnum = ERR_FSYS_CORRUPT; - return 0; - } - -#ifdef REISERDEBUG - printf ("symlink=%s\n", linkbuf); -#endif /* REISERDEBUG */ - - dirname = linkbuf; - if (*dirname == '/') - { - /* It's an absolute link, so look it up in root. */ - dir_id = REISERFS_ROOT_PARENT_OBJECTID; - objectid = REISERFS_ROOT_OBJECTID; - } - else - { - /* Relative, so look it up in our parent directory. */ - dir_id = parent_dir_id; - objectid = parent_objectid; - } - - /* Now lookup the new name. */ - continue; - } - - /* if we have a real file (and we're not just printing possibilities), - then this is where we want to exit */ - - if (! *dirname || isspace (*dirname)) - { - if (! S_ISREG (mode)) - { - errnum = ERR_BAD_FILETYPE; - return 0; - } - - filepos = 0; - filemax = ((struct stat_data *) INFO->current_item)->sd_size; - - /* If this is a new stat data and size is > 4GB set filemax to - * maximum - */ - if (INFO->current_ih->ih_version == ITEM_VERSION_2 - && ((struct stat_data *) INFO->current_item)->sd_size_hi > 0) - filemax = 0xffffffff; - - INFO->fileinfo.k_dir_id = dir_id; - INFO->fileinfo.k_objectid = objectid; - return next_key (); - } - - /* continue with the file/directory name interpretation */ - while (*dirname == '/') - dirname++; - if (! S_ISDIR (mode)) - { - errnum = ERR_BAD_FILETYPE; - return 0; - } - for (rest = dirname; (ch = *rest) && ! isspace (ch) && ch != '/'; rest++); - *rest = 0; - -# ifndef STAGE1_5 - if (print_possibilities && ch != '/') - do_possibilities = 1; -# endif /* ! STAGE1_5 */ - - while (1) - { - char *name_end; - int num_entries; - - if (! next_key ()) - return 0; -#ifdef REISERDEBUG - printf ("ih: key %d:%d:%d:%d version:%d\n", - INFO->current_ih->ih_key.k_dir_id, - INFO->current_ih->ih_key.k_objectid, - INFO->current_ih->ih_key.u.v1.k_offset, - INFO->current_ih->ih_key.u.v1.k_uniqueness, - INFO->current_ih->ih_version); -#endif /* REISERDEBUG */ - - if (INFO->current_ih->ih_key.k_objectid != objectid) - break; - - name_end = INFO->current_item + INFO->current_ih->ih_item_len; - de_head = (struct reiserfs_de_head *) INFO->current_item; - num_entries = INFO->current_ih->u.ih_entry_count; - while (num_entries > 0) - { - char *filename = INFO->current_item + de_head->deh_location; - char tmp = *name_end; - if ((de_head->deh_state & DEH_Visible)) - { - int cmp; - /* Directory names in ReiserFS are not null - * terminated. We write a temporary 0 behind it. - * NOTE: that this may overwrite the first block in - * the tree cache. That doesn't hurt as long as we - * don't call next_key () in between. - */ - *name_end = 0; - cmp = substring (dirname, filename); - *name_end = tmp; -# ifndef STAGE1_5 - if (do_possibilities) - { - if (cmp <= 0) - { - if (print_possibilities > 0) - print_possibilities = -print_possibilities; - *name_end = 0; - print_a_completion (filename); - *name_end = tmp; - } - } - else -# endif /* ! STAGE1_5 */ - if (cmp == 0) - goto found; - } - /* The beginning of this name marks the end of the next name. - */ - name_end = filename; - de_head++; - num_entries--; - } - } - -# ifndef STAGE1_5 - if (print_possibilities < 0) - return 1; -# endif /* ! STAGE1_5 */ - - errnum = ERR_FILE_NOT_FOUND; - *rest = ch; - return 0; - - found: - - *rest = ch; - dirname = rest; - - parent_dir_id = dir_id; - parent_objectid = objectid; - dir_id = de_head->deh_dir_id; - objectid = de_head->deh_objectid; - - } - - return 1; -} - -int -reiserfs_embed (int *start_sector, int needed_sectors) -{ - struct reiserfs_super_block super; - int num_sectors; - - if (! devread (REISERFS_DISK_OFFSET_IN_BYTES >> SECTOR_BITS, 0, - sizeof (struct reiserfs_super_block), (char *) &super)) - return 0; - - *start_sector = 1; /* reserve first sector for stage1 */ - if ((substring (REISERFS_SUPER_MAGIC_STRING, super.s_magic) <= 0 - || substring (REISER2FS_SUPER_MAGIC_STRING, super.s_magic) <= 0) - && (/* check that this is not a super block copy inside - * the journal log */ - super.s_journal_block * super.s_blocksize - > REISERFS_DISK_OFFSET_IN_BYTES)) - num_sectors = (REISERFS_DISK_OFFSET_IN_BYTES >> SECTOR_BITS) - 1; - else - num_sectors = (REISERFS_OLD_DISK_OFFSET_IN_BYTES >> SECTOR_BITS) - 1; - - return (needed_sectors <= num_sectors); -} -#endif /* FSYS_REISERFS */ diff --git a/src/filo/fs/fsys_xfs.c b/src/filo/fs/fsys_xfs.c deleted file mode 100644 index b551c07a2..000000000 --- a/src/filo/fs/fsys_xfs.c +++ /dev/null @@ -1,624 +0,0 @@ -/* fsys_xfs.c - an implementation for the SGI XFS file system */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2001,2002 Free Software Foundation, Inc. - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifdef FSYS_XFS - -#include "shared.h" -#include "filesys.h" -#include "xfs.h" - -#define MAX_LINK_COUNT 8 - -typedef struct xad { - xfs_fileoff_t offset; - xfs_fsblock_t start; - xfs_filblks_t len; -} xad_t; - -struct xfs_info { - int bsize; - int dirbsize; - int isize; - unsigned int agblocks; - int bdlog; - int blklog; - int inopblog; - int agblklog; - int agnolog; - unsigned int nextents; - xfs_daddr_t next; - xfs_daddr_t daddr; - xfs_dablk_t forw; - xfs_dablk_t dablk; - xfs_bmbt_rec_32_t *xt; - xfs_bmbt_ptr_t ptr0; - int btnode_ptr0_off; - int i8param; - int dirpos; - int dirmax; - int blkoff; - int fpos; - xfs_ino_t rootino; -}; - -static struct xfs_info xfs; - -#define dirbuf ((char *)FSYS_BUF) -#define filebuf ((char *)FSYS_BUF + 4096) -#define inode ((xfs_dinode_t *)((char *)FSYS_BUF + 8192)) -#define icore (inode->di_core) - -#define mask32lo(n) (((__uint32_t)1 << (n)) - 1) - -#define XFS_INO_MASK(k) ((__uint32_t)((1ULL << (k)) - 1)) -#define XFS_INO_OFFSET_BITS xfs.inopblog -#define XFS_INO_AGBNO_BITS xfs.agblklog -#define XFS_INO_AGINO_BITS (xfs.agblklog + xfs.inopblog) -#define XFS_INO_AGNO_BITS xfs.agnolog - -static inline xfs_agblock_t -agino2agbno (xfs_agino_t agino) -{ - return agino >> XFS_INO_OFFSET_BITS; -} - -static inline xfs_agnumber_t -ino2agno (xfs_ino_t ino) -{ - return ino >> XFS_INO_AGINO_BITS; -} - -static inline xfs_agino_t -ino2agino (xfs_ino_t ino) -{ - return ino & XFS_INO_MASK(XFS_INO_AGINO_BITS); -} - -static inline int -ino2offset (xfs_ino_t ino) -{ - return ino & XFS_INO_MASK(XFS_INO_OFFSET_BITS); -} - -static inline __const__ __uint16_t -le16 (__uint16_t x) -{ - __asm__("xchgb %b0,%h0" \ - : "=q" (x) \ - : "0" (x)); \ - return x; -} - -static inline __const__ __uint32_t -le32 (__uint32_t x) -{ -#if 0 - /* 386 doesn't have bswap. */ - __asm__("bswap %0" : "=r" (x) : "0" (x)); -#else - /* This is slower but this works on all x86 architectures. */ - __asm__("xchgb %b0, %h0" \ - "\n\troll $16, %0" \ - "\n\txchgb %b0, %h0" \ - : "=q" (x) : "0" (x)); -#endif - return x; -} - -static inline __const__ __uint64_t -le64 (__uint64_t x) -{ - __uint32_t h = x >> 32; - __uint32_t l = x & ((1ULL<<32)-1); - return (((__uint64_t)le32(l)) << 32) | ((__uint64_t)(le32(h))); -} - - -static xfs_fsblock_t -xt_start (xfs_bmbt_rec_32_t *r) -{ - return (((xfs_fsblock_t)(le32 (r->l1) & mask32lo(9))) << 43) | - (((xfs_fsblock_t)le32 (r->l2)) << 11) | - (((xfs_fsblock_t)le32 (r->l3)) >> 21); -} - -static xfs_fileoff_t -xt_offset (xfs_bmbt_rec_32_t *r) -{ - return (((xfs_fileoff_t)le32 (r->l0) & - mask32lo(31)) << 23) | - (((xfs_fileoff_t)le32 (r->l1)) >> 9); -} - -static xfs_filblks_t -xt_len (xfs_bmbt_rec_32_t *r) -{ - return le32(r->l3) & mask32lo(21); -} - -static inline int -xfs_highbit32(__uint32_t v) -{ - int i; - - if (--v) { - for (i = 0; i < 31; i++, v >>= 1) { - if (v == 0) - return i; - } - } - return 0; -} - -static int -isinxt (xfs_fileoff_t key, xfs_fileoff_t offset, xfs_filblks_t len) -{ - return (key >= offset) ? (key < offset + len ? 1 : 0) : 0; -} - -static xfs_daddr_t -agb2daddr (xfs_agnumber_t agno, xfs_agblock_t agbno) -{ - return ((xfs_fsblock_t)agno*xfs.agblocks + agbno) << xfs.bdlog; -} - -static xfs_daddr_t -fsb2daddr (xfs_fsblock_t fsbno) -{ - return agb2daddr ((xfs_agnumber_t)(fsbno >> xfs.agblklog), - (xfs_agblock_t)(fsbno & mask32lo(xfs.agblklog))); -} - -#undef offsetof -#define offsetof(t,m) ((int)&(((t *)0)->m)) - -static inline int -btroot_maxrecs (void) -{ - int tmp = icore.di_forkoff ? (icore.di_forkoff << 3) : xfs.isize; - - return (tmp - sizeof(xfs_bmdr_block_t) - offsetof(xfs_dinode_t, di_u)) / - (sizeof (xfs_bmbt_key_t) + sizeof (xfs_bmbt_ptr_t)); -} - -static int -di_read (xfs_ino_t ino) -{ - xfs_agino_t agino; - xfs_agnumber_t agno; - xfs_agblock_t agbno; - xfs_daddr_t daddr; - int offset; - - agno = ino2agno (ino); - agino = ino2agino (ino); - agbno = agino2agbno (agino); - offset = ino2offset (ino); - daddr = agb2daddr (agno, agbno); - - devread (daddr, offset*xfs.isize, xfs.isize, (char *)inode); - - xfs.ptr0 = *(xfs_bmbt_ptr_t *) - (inode->di_u.di_c + sizeof(xfs_bmdr_block_t) - + btroot_maxrecs ()*sizeof(xfs_bmbt_key_t)); - - return 1; -} - -static void -init_extents (void) -{ - xfs_bmbt_ptr_t ptr0; - xfs_btree_lblock_t h; - - switch (icore.di_format) { - case XFS_DINODE_FMT_EXTENTS: - xfs.xt = inode->di_u.di_bmx; - xfs.nextents = le32 (icore.di_nextents); - break; - case XFS_DINODE_FMT_BTREE: - ptr0 = xfs.ptr0; - for (;;) { - xfs.daddr = fsb2daddr (le64(ptr0)); - devread (xfs.daddr, 0, - sizeof(xfs_btree_lblock_t), (char *)&h); - if (!h.bb_level) { - xfs.nextents = le16(h.bb_numrecs); - xfs.next = fsb2daddr (le64(h.bb_rightsib)); - xfs.fpos = sizeof(xfs_btree_block_t); - return; - } - devread (xfs.daddr, xfs.btnode_ptr0_off, - sizeof(xfs_bmbt_ptr_t), (char *)&ptr0); - } - } -} - -static xad_t * -next_extent (void) -{ - static xad_t xad; - - switch (icore.di_format) { - case XFS_DINODE_FMT_EXTENTS: - if (xfs.nextents == 0) - return NULL; - break; - case XFS_DINODE_FMT_BTREE: - if (xfs.nextents == 0) { - xfs_btree_lblock_t h; - if (xfs.next == 0) - return NULL; - xfs.daddr = xfs.next; - devread (xfs.daddr, 0, sizeof(xfs_btree_lblock_t), (char *)&h); - xfs.nextents = le16(h.bb_numrecs); - xfs.next = fsb2daddr (le64(h.bb_rightsib)); - xfs.fpos = sizeof(xfs_btree_block_t); - } - /* Yeah, I know that's slow, but I really don't care */ - devread (xfs.daddr, xfs.fpos, sizeof(xfs_bmbt_rec_t), filebuf); - xfs.xt = (xfs_bmbt_rec_32_t *)filebuf; - xfs.fpos += sizeof(xfs_bmbt_rec_32_t); - } - xad.offset = xt_offset (xfs.xt); - xad.start = xt_start (xfs.xt); - xad.len = xt_len (xfs.xt); - ++xfs.xt; - --xfs.nextents; - - return &xad; -} - -/* - * Name lies - the function reads only first 100 bytes - */ -static void -xfs_dabread (void) -{ - xad_t *xad; - xfs_fileoff_t offset;; - - init_extents (); - while ((xad = next_extent ())) { - offset = xad->offset; - if (isinxt (xfs.dablk, offset, xad->len)) { - devread (fsb2daddr (xad->start + xfs.dablk - offset), - 0, 100, dirbuf); - break; - } - } -} - -static inline xfs_ino_t -sf_ino (char *sfe, int namelen) -{ - void *p = sfe + namelen + 3; - - return (xfs.i8param == 0) - ? le64(*(xfs_ino_t *)p) : le32(*(__uint32_t *)p); -} - -static inline xfs_ino_t -sf_parent_ino (void) -{ - return (xfs.i8param == 0) - ? le64(*(xfs_ino_t *)(&inode->di_u.di_dir2sf.hdr.parent)) - : le32(*(__uint32_t *)(&inode->di_u.di_dir2sf.hdr.parent)); -} - -static inline int -roundup8 (int n) -{ - return ((n+7)&~7); -} - -static char * -next_dentry (xfs_ino_t *ino) -{ - int namelen = 1; - int toread; - static char *usual[2] = {".", ".."}; - static xfs_dir2_sf_entry_t *sfe; - char *name = usual[0]; - - if (xfs.dirpos >= xfs.dirmax) { - if (xfs.forw == 0) - return NULL; - xfs.dablk = xfs.forw; - xfs_dabread (); -#define h ((xfs_dir2_leaf_hdr_t *)dirbuf) - xfs.dirmax = le16 (h->count) - le16 (h->stale); - xfs.forw = le32 (h->info.forw); -#undef h - xfs.dirpos = 0; - } - - switch (icore.di_format) { - case XFS_DINODE_FMT_LOCAL: - switch (xfs.dirpos) { - case -2: - *ino = 0; - break; - case -1: - *ino = sf_parent_ino (); - ++name; - ++namelen; - sfe = (xfs_dir2_sf_entry_t *) - (inode->di_u.di_c - + sizeof(xfs_dir2_sf_hdr_t) - - xfs.i8param); - break; - default: - namelen = sfe->namelen; - *ino = sf_ino ((char *)sfe, namelen); - name = sfe->name; - sfe = (xfs_dir2_sf_entry_t *) - ((char *)sfe + namelen + 11 - xfs.i8param); - } - break; - case XFS_DINODE_FMT_BTREE: - case XFS_DINODE_FMT_EXTENTS: -#define dau ((xfs_dir2_data_union_t *)dirbuf) - for (;;) { - if (xfs.blkoff >= xfs.dirbsize) { - xfs.blkoff = sizeof(xfs_dir2_data_hdr_t); - filepos &= ~(xfs.dirbsize - 1); - filepos |= xfs.blkoff; - } - xfs_read (dirbuf, 4); - xfs.blkoff += 4; - if (dau->unused.freetag == XFS_DIR2_DATA_FREE_TAG) { - toread = roundup8 (le16(dau->unused.length)) - 4; - xfs.blkoff += toread; - filepos += toread; - continue; - } - break; - } - xfs_read ((char *)dirbuf + 4, 5); - *ino = le64 (dau->entry.inumber); - namelen = dau->entry.namelen; -#undef dau - toread = roundup8 (namelen + 11) - 9; - xfs_read (dirbuf, toread); - name = (char *)dirbuf; - xfs.blkoff += toread + 5; - } - ++xfs.dirpos; - name[namelen] = 0; - - return name; -} - -static char * -first_dentry (xfs_ino_t *ino) -{ - xfs.forw = 0; - switch (icore.di_format) { - case XFS_DINODE_FMT_LOCAL: - xfs.dirmax = inode->di_u.di_dir2sf.hdr.count; - xfs.i8param = inode->di_u.di_dir2sf.hdr.i8count ? 0 : 4; - xfs.dirpos = -2; - break; - case XFS_DINODE_FMT_EXTENTS: - case XFS_DINODE_FMT_BTREE: - filepos = 0; - xfs_read (dirbuf, sizeof(xfs_dir2_data_hdr_t)); - if (((xfs_dir2_data_hdr_t *)dirbuf)->magic == le32(XFS_DIR2_BLOCK_MAGIC)) { -#define tail ((xfs_dir2_block_tail_t *)dirbuf) - filepos = xfs.dirbsize - sizeof(*tail); - xfs_read (dirbuf, sizeof(*tail)); - xfs.dirmax = le32 (tail->count) - le32 (tail->stale); -#undef tail - } else { - xfs.dablk = (1ULL << 35) >> xfs.blklog; -#define h ((xfs_dir2_leaf_hdr_t *)dirbuf) -#define n ((xfs_da_intnode_t *)dirbuf) - for (;;) { - xfs_dabread (); - if ((n->hdr.info.magic == le16(XFS_DIR2_LEAFN_MAGIC)) - || (n->hdr.info.magic == le16(XFS_DIR2_LEAF1_MAGIC))) { - xfs.dirmax = le16 (h->count) - le16 (h->stale); - xfs.forw = le32 (h->info.forw); - break; - } - xfs.dablk = le32 (n->btree[0].before); - } -#undef n -#undef h - } - xfs.blkoff = sizeof(xfs_dir2_data_hdr_t); - filepos = xfs.blkoff; - xfs.dirpos = 0; - } - return next_dentry (ino); -} - -int -xfs_mount (void) -{ - xfs_sb_t super; - - if (!devread (0, 0, sizeof(super), (char *)&super) - || (le32(super.sb_magicnum) != XFS_SB_MAGIC) - || ((le16(super.sb_versionnum) - & XFS_SB_VERSION_NUMBITS) != XFS_SB_VERSION_4) ) { - return 0; - } - - xfs.bsize = le32 (super.sb_blocksize); - xfs.blklog = super.sb_blocklog; - xfs.bdlog = xfs.blklog - SECTOR_BITS; - xfs.rootino = le64 (super.sb_rootino); - xfs.isize = le16 (super.sb_inodesize); - xfs.agblocks = le32 (super.sb_agblocks); - xfs.dirbsize = xfs.bsize << super.sb_dirblklog; - - xfs.inopblog = super.sb_inopblog; - xfs.agblklog = super.sb_agblklog; - xfs.agnolog = xfs_highbit32 (le32(super.sb_agcount)); - - xfs.btnode_ptr0_off = - ((xfs.bsize - sizeof(xfs_btree_block_t)) / - (sizeof (xfs_bmbt_key_t) + sizeof (xfs_bmbt_ptr_t))) - * sizeof(xfs_bmbt_key_t) + sizeof(xfs_btree_block_t); - - return 1; -} - -int -xfs_read (char *buf, int len) -{ - xad_t *xad; - xfs_fileoff_t endofprev, endofcur, offset; - xfs_filblks_t xadlen; - int toread, startpos, endpos; - - if (icore.di_format == XFS_DINODE_FMT_LOCAL) { - grub_memmove (buf, inode->di_u.di_c + filepos, len); - filepos += len; - return len; - } - - startpos = filepos; - endpos = filepos + len; - endofprev = (xfs_fileoff_t)-1; - init_extents (); - while (len > 0 && (xad = next_extent ())) { - offset = xad->offset; - xadlen = xad->len; - if (isinxt (filepos >> xfs.blklog, offset, xadlen)) { - endofcur = (offset + xadlen) << xfs.blklog; - toread = (endofcur >= endpos) - ? len : (endofcur - filepos); - - disk_read_func = disk_read_hook; - devread (fsb2daddr (xad->start), - filepos - (offset << xfs.blklog), toread, buf); - disk_read_func = NULL; - - buf += toread; - len -= toread; - filepos += toread; - } else if (offset > endofprev) { - toread = ((offset << xfs.blklog) >= endpos) - ? len : ((offset - endofprev) << xfs.blklog); - len -= toread; - filepos += toread; - for (; toread; toread--) { - *buf++ = 0; - } - continue; - } - endofprev = offset + xadlen; - } - - return filepos - startpos; -} - -int -xfs_dir (char *dirname) -{ - xfs_ino_t ino, parent_ino, new_ino; - xfs_fsize_t di_size; - int di_mode; - int cmp, n, link_count; - char linkbuf[xfs.bsize]; - char *rest, *name, ch; - - parent_ino = ino = xfs.rootino; - link_count = 0; - for (;;) { - di_read (ino); - di_size = le64 (icore.di_size); - di_mode = le16 (icore.di_mode); - - if ((di_mode & IFMT) == IFLNK) { - if (++link_count > MAX_LINK_COUNT) { - errnum = ERR_SYMLINK_LOOP; - return 0; - } - if (di_size < xfs.bsize - 1) { - filepos = 0; - filemax = di_size; - n = xfs_read (linkbuf, filemax); - } else { - errnum = ERR_FILELENGTH; - return 0; - } - - ino = (linkbuf[0] == '/') ? xfs.rootino : parent_ino; - while (n < (xfs.bsize - 1) && (linkbuf[n++] = *dirname++)); - linkbuf[n] = 0; - dirname = linkbuf; - continue; - } - - if (!*dirname || isspace (*dirname)) { - if ((di_mode & IFMT) != IFREG) { - errnum = ERR_BAD_FILETYPE; - return 0; - } - filepos = 0; - filemax = di_size; - return 1; - } - - if ((di_mode & IFMT) != IFDIR) { - errnum = ERR_BAD_FILETYPE; - return 0; - } - - for (; *dirname == '/'; dirname++); - - for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/'; rest++); - *rest = 0; - - name = first_dentry (&new_ino); - for (;;) { - cmp = (!*dirname) ? -1 : substring (dirname, name); -#ifndef STAGE1_5 - if (print_possibilities && ch != '/' && cmp <= 0) { - if (print_possibilities > 0) - print_possibilities = -print_possibilities; - print_a_completion (name); - } else -#endif - if (cmp == 0) { - parent_ino = ino; - if (new_ino) - ino = new_ino; - *(dirname = rest) = ch; - break; - } - name = next_dentry (&new_ino); - if (name == NULL) { - if (print_possibilities < 0) - return 1; - - errnum = ERR_FILE_NOT_FOUND; - *rest = ch; - return 0; - } - } - } -} - -#endif /* FSYS_XFS */ diff --git a/src/filo/fs/iso9660.h b/src/filo/fs/iso9660.h deleted file mode 100644 index 06a79062f..000000000 --- a/src/filo/fs/iso9660.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * ISO 9660 filesystem backend for GRUB (GRand Unified Bootloader) - * including Rock Ridge Extensions support - * - * Copyright (C) 1998, 1999 Kousuke Takai <tak@kmc.kyoto-u.ac.jp> - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -/* - * References: - * linux/fs/isofs/rock.[ch] - * mkisofs-1.11.1/diag/isoinfo.c - * mkisofs-1.11.1/iso9660.h - * (all are written by Eric Youngdale) - */ - -/* - * Modified by SONE Takeshi to work with FILO - */ - -#ifndef _ISO9660_H_ -#define _ISO9660_H_ - -#define ISO_SECTOR_BITS (11) -#define ISO_SECTOR_SIZE (1<<ISO_SECTOR_BITS) - -#define ISO_REGULAR 1 /* regular file */ -#define ISO_DIRECTORY 2 /* directory */ -#define ISO_OTHER 0 /* other file (with Rock Ridge) */ - -#define RR_FLAG_PX 0x01 /* have POSIX file attributes */ -#define RR_FLAG_NM 0x08 /* have alternate file name */ - -/* POSIX file attributes for Rock Ridge extensions */ -#define POSIX_S_IFMT 0xF000 -#define POSIX_S_IFREG 0x8000 -#define POSIX_S_IFDIR 0x4000 - -/* volume descriptor types */ -#define ISO_VD_PRIMARY 1 -#define ISO_VD_END 255 - -#define ISO_STANDARD_ID "CD001" - -#ifndef ASM_FILE - -typedef uint8_t u_int8_t; -typedef uint16_t u_int16_t; -typedef uint32_t u_int32_t; - -typedef union { - u_int8_t l,b; -} iso_8bit_t; - -typedef struct __iso_16bit { - u_int16_t l, b; -} iso_16bit_t __attribute__ ((packed)); - -typedef struct __iso_32bit { - u_int32_t l, b; -} iso_32bit_t __attribute__ ((packed)); - -typedef u_int8_t iso_date_t[7]; - -struct iso_directory_record { - iso_8bit_t length; - iso_8bit_t ext_attr_length; - iso_32bit_t extent; - iso_32bit_t size; - iso_date_t date; - iso_8bit_t flags; - iso_8bit_t file_unit_size; - iso_8bit_t interleave; - iso_16bit_t volume_seq_number; - iso_8bit_t name_len; - u_int8_t name[1]; -} __attribute__ ((packed)); - -struct iso_primary_descriptor { - iso_8bit_t type; - u_int8_t id[5]; - iso_8bit_t version; - u_int8_t _unused1[1]; - u_int8_t system_id[32]; - u_int8_t volume_id[32]; - u_int8_t _unused2[8]; - iso_32bit_t volume_space_size; - u_int8_t _unused3[32]; - iso_16bit_t volume_set_size; - iso_16bit_t volume_seq_number; - iso_16bit_t logical_block_size; - iso_32bit_t path_table_size; - u_int8_t type_l_path_table[4]; - u_int8_t opt_type_l_path_table[4]; - u_int8_t type_m_path_table[4]; - u_int8_t opt_type_m_path_table[4]; - struct iso_directory_record root_directory_record; - u_int8_t volume_set_id[128]; - u_int8_t publisher_id[128]; - u_int8_t preparer_id[128]; - u_int8_t application_id[128]; - u_int8_t copyright_file_id[37]; - u_int8_t abstract_file_id[37]; - u_int8_t bibliographic_file_id[37]; - u_int8_t creation_date[17]; - u_int8_t modification_date[17]; - u_int8_t expiration_date[17]; - u_int8_t effective_date[17]; - iso_8bit_t file_structure_version; - u_int8_t _unused4[1]; - u_int8_t application_data[512]; - u_int8_t _unused5[653]; -} __attribute__ ((packed)); - -struct rock_ridge { - u_int16_t signature; - u_int8_t len; - u_int8_t version; - union { - struct CE { - iso_32bit_t extent; - iso_32bit_t offset; - iso_32bit_t size; - } ce; - struct NM { - iso_8bit_t flags; - u_int8_t name[0]; - } nm; - struct PX { - iso_32bit_t mode; - iso_32bit_t nlink; - iso_32bit_t uid; - iso_32bit_t gid; - } px; - struct RR { - iso_8bit_t flags; - } rr; - } u; -} __attribute__ ((packed)); - -typedef union RR_ptr { - struct rock_ridge *rr; - char *ptr; - int i; -} RR_ptr_t; - -#define RRMAGIC(c1, c2) ((c1)|(c2) << 8) - -#define CHECK2(ptr, c1, c2) \ - (*(unsigned short *)(ptr) == (((c1) | (c2) << 8) & 0xFFFF)) -#define CHECK4(ptr, c1, c2, c3, c4) \ - (*(unsigned long *)(ptr) == ((c1) | (c2)<<8 | (c3)<<16 | (c4)<<24)) - -#endif /* !ASM_FILE */ - -#endif /* _ISO9660_H_ */ diff --git a/src/filo/fs/jfs.h b/src/filo/fs/jfs.h deleted file mode 100644 index e596a1b8b..000000000 --- a/src/filo/fs/jfs.h +++ /dev/null @@ -1,601 +0,0 @@ -/* jfs.h - an extractions from linux/include/linux/jfs/jfs* into one file */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2000 International Business Machines Corp. - * Copyright (C) 2001 Free Software Foundation, Inc. - * - * 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 - */ - -#ifndef _JFS_H_ -#define _JFS_H_ - -/* those are from jfs_filsys.h */ - -/* - * file system option (superblock flag) - */ -/* platform option (conditional compilation) */ -#define JFS_AIX 0x80000000 /* AIX support */ -/* POSIX name/directory support */ - -#define JFS_OS2 0x40000000 /* OS/2 support */ -/* case-insensitive name/directory support */ - -#define JFS_LINUX 0x10000000 /* Linux support */ -/* case-sensitive name/directory support */ - -/* directory option */ -#define JFS_UNICODE 0x00000001 /* unicode name */ - -/* bba */ -#define JFS_SWAP_BYTES 0x00100000 /* running on big endian computer */ - - -/* - * buffer cache configuration - */ -/* page size */ -#ifdef PSIZE -#undef PSIZE -#endif -#define PSIZE 4096 /* page size (in byte) */ - -/* - * fs fundamental size - * - * PSIZE >= file system block size >= PBSIZE >= DISIZE - */ -#define PBSIZE 512 /* physical block size (in byte) */ -#define DISIZE 512 /* on-disk inode size (in byte) */ -#define L2DISIZE 9 -#define INOSPERIAG 4096 /* number of disk inodes per iag */ -#define L2INOSPERIAG 12 -#define INOSPEREXT 32 /* number of disk inode per extent */ -#define L2INOSPEREXT 5 - -/* Minimum number of bytes supported for a JFS partition */ -#define MINJFS (0x1000000) - -/* - * fixed byte offset address - */ -#define SUPER1_OFF 0x8000 /* primary superblock */ - -#define AITBL_OFF (SUPER1_OFF + PSIZE + (PSIZE << 1)) - -/* - * fixed reserved inode number - */ -/* aggregate inode */ -#define AGGREGATE_I 1 /* aggregate inode map inode */ -#define FILESYSTEM_I 16 /* 1st/only fileset inode in ait: - * fileset inode map inode - */ - -/* per fileset inode */ -#define ROOT_I 2 /* fileset root inode */ - -/* - * directory configuration - */ -#define JFS_NAME_MAX 255 -#define JFS_PATH_MAX PSIZE - -typedef unsigned char u8; -typedef char s8; -typedef unsigned short u16; -typedef short s16; -typedef unsigned int u32; -typedef int s32; -typedef unsigned long long u64; -typedef long long s64; - -typedef u16 UniChar; - -/* these from jfs_btree.h */ - -/* btpaget_t flag */ -#define BT_TYPE 0x07 /* B+-tree index */ -#define BT_ROOT 0x01 /* root page */ -#define BT_LEAF 0x02 /* leaf page */ -#define BT_INTERNAL 0x04 /* internal page */ -#define BT_RIGHTMOST 0x10 /* rightmost page */ -#define BT_LEFTMOST 0x20 /* leftmost page */ - -/* those are from jfs_types.h */ - -struct timestruc_t { - u32 tv_sec; - u32 tv_nsec; -}; - -/* - * physical xd (pxd) - */ -typedef struct { - unsigned len:24; - unsigned addr1:8; - u32 addr2; -} pxd_t; - -/* xd_t field extraction */ -#define lengthPXD(pxd) ((pxd)->len) -#define addressPXD(pxd) (((s64)((pxd)->addr1)) << 32 | ((pxd)->addr2)) - -/* - * data extent descriptor (dxd) - */ -typedef struct { - unsigned flag:8; /* 1: flags */ - unsigned rsrvd:24; /* 3: */ - u32 size; /* 4: size in byte */ - unsigned len:24; /* 3: length in unit of fsblksize */ - unsigned addr1:8; /* 1: address in unit of fsblksize */ - u32 addr2; /* 4: address in unit of fsblksize */ -} dxd_t; /* - 16 - */ - -/* - * DASD limit information - stored in directory inode - */ -typedef struct dasd { - u8 thresh; /* Alert Threshold (in percent) */ - u8 delta; /* Alert Threshold delta (in percent) */ - u8 rsrvd1; - u8 limit_hi; /* DASD limit (in logical blocks) */ - u32 limit_lo; /* DASD limit (in logical blocks) */ - u8 rsrvd2[3]; - u8 used_hi; /* DASD usage (in logical blocks) */ - u32 used_lo; /* DASD usage (in logical blocks) */ -} dasd_t; - - -/* from jfs_superblock.h */ - -#define JFS_MAGIC 0x3153464A /* "JFS1" */ - -struct jfs_superblock -{ - u32 s_magic; /* 4: magic number */ - u32 s_version; /* 4: version number */ - - s64 s_size; /* 8: aggregate size in hardware/LVM blocks; - * VFS: number of blocks - */ - s32 s_bsize; /* 4: aggregate block size in bytes; - * VFS: fragment size - */ - s16 s_l2bsize; /* 2: log2 of s_bsize */ - s16 s_l2bfactor; /* 2: log2(s_bsize/hardware block size) */ - s32 s_pbsize; /* 4: hardware/LVM block size in bytes */ - s16 s_l2pbsize; /* 2: log2 of s_pbsize */ - s16 pad; /* 2: padding necessary for alignment */ - - u32 s_agsize; /* 4: allocation group size in aggr. blocks */ - - u32 s_flag; /* 4: aggregate attributes: - * see jfs_filsys.h - */ - u32 s_state; /* 4: mount/unmount/recovery state: - * see jfs_filsys.h - */ - s32 s_compress; /* 4: > 0 if data compression */ - - pxd_t s_ait2; /* 8: first extent of secondary - * aggregate inode table - */ - - pxd_t s_aim2; /* 8: first extent of secondary - * aggregate inode map - */ - u32 s_logdev; /* 4: device address of log */ - s32 s_logserial; /* 4: log serial number at aggregate mount */ - pxd_t s_logpxd; /* 8: inline log extent */ - - pxd_t s_fsckpxd; /* 8: inline fsck work space extent */ - - struct timestruc_t s_time; /* 8: time last updated */ - - s32 s_fsckloglen; /* 4: Number of filesystem blocks reserved for - * the fsck service log. - * N.B. These blocks are divided among the - * versions kept. This is not a per - * version size. - * N.B. These blocks are included in the - * length field of s_fsckpxd. - */ - s8 s_fscklog; /* 1: which fsck service log is most recent - * 0 => no service log data yet - * 1 => the first one - * 2 => the 2nd one - */ - char s_fpack[11]; /* 11: file system volume name - * N.B. This must be 11 bytes to - * conform with the OS/2 BootSector - * requirements - */ - - /* extendfs() parameter under s_state & FM_EXTENDFS */ - s64 s_xsize; /* 8: extendfs s_size */ - pxd_t s_xfsckpxd; /* 8: extendfs fsckpxd */ - pxd_t s_xlogpxd; /* 8: extendfs logpxd */ - /* - 128 byte boundary - */ - - /* - * DFS VFS support (preliminary) - */ - char s_attach; /* 1: VFS: flag: set when aggregate is attached - */ - u8 rsrvd4[7]; /* 7: reserved - set to 0 */ - - u64 totalUsable; /* 8: VFS: total of 1K blocks which are - * available to "normal" (non-root) users. - */ - u64 minFree; /* 8: VFS: # of 1K blocks held in reserve for - * exclusive use of root. This value can be 0, - * and if it is then totalUsable will be equal - * to # of blocks in aggregate. I believe this - * means that minFree + totalUsable = # blocks. - * In that case, we don't need to store both - * totalUsable and minFree since we can compute - * one from the other. I would guess minFree - * would be the one we should store, and - * totalUsable would be the one we should - * compute. (Just a guess...) - */ - - u64 realFree; /* 8: VFS: # of free 1K blocks can be used by - * "normal" users. It may be this is something - * we should compute when asked for instead of - * storing in the superblock. I don't know how - * often this information is needed. - */ - /* - * graffiti area - */ -}; - -/* from jfs_dtree.h */ - -/* - * entry segment/slot - * - * an entry consists of type dependent head/only segment/slot and - * additional segments/slots linked vi next field; - * N.B. last/only segment of entry is terminated by next = -1; - */ -/* - * directory page slot - */ -typedef struct { - s8 next; /* 1: */ - s8 cnt; /* 1: */ - UniChar name[15]; /* 30: */ -} dtslot_t; /* (32) */ - -#define DTSLOTDATALEN 15 - -/* - * internal node entry head/only segment - */ -typedef struct { - pxd_t xd; /* 8: child extent descriptor */ - - s8 next; /* 1: */ - u8 namlen; /* 1: */ - UniChar name[11]; /* 22: 2-byte aligned */ -} idtentry_t; /* (32) */ - -/* - * leaf node entry head/only segment - * - * For legacy filesystems, name contains 13 unichars -- no index field - */ -typedef struct { - u32 inumber; /* 4: 4-byte aligned */ - s8 next; /* 1: */ - u8 namlen; /* 1: */ - UniChar name[11]; /* 22: 2-byte aligned */ - u32 index; /* 4: index into dir_table */ -} ldtentry_t; /* (32) */ - -#define DTLHDRDATALEN 11 - -/* - * dir_table used for directory traversal during readdir -*/ - -/* - * Maximum entry in inline directory table - */ - -typedef struct dir_table_slot { - u8 rsrvd; /* 1: */ - u8 flag; /* 1: 0 if free */ - u8 slot; /* 1: slot within leaf page of entry */ - u8 addr1; /* 1: upper 8 bits of leaf page address */ - u32 addr2; /* 4: lower 32 bits of leaf page address -OR- - index of next entry when this entry was deleted */ -} dir_table_slot_t; /* (8) */ - -/* - * directory root page (in-line in on-disk inode): - * - * cf. dtpage_t below. - */ -typedef union { - struct { - dasd_t DASD; /* 16: DASD limit/usage info F226941 */ - - u8 flag; /* 1: */ - s8 nextindex; /* 1: next free entry in stbl */ - s8 freecnt; /* 1: free count */ - s8 freelist; /* 1: freelist header */ - - u32 idotdot; /* 4: parent inode number */ - - s8 stbl[8]; /* 8: sorted entry index table */ - } header; /* (32) */ - - dtslot_t slot[9]; -} dtroot_t; - -/* - * directory regular page: - * - * entry slot array of 32 byte slot - * - * sorted entry slot index table (stbl): - * contiguous slots at slot specified by stblindex, - * 1-byte per entry - * 512 byte block: 16 entry tbl (1 slot) - * 1024 byte block: 32 entry tbl (1 slot) - * 2048 byte block: 64 entry tbl (2 slot) - * 4096 byte block: 128 entry tbl (4 slot) - * - * data area: - * 512 byte block: 16 - 2 = 14 slot - * 1024 byte block: 32 - 2 = 30 slot - * 2048 byte block: 64 - 3 = 61 slot - * 4096 byte block: 128 - 5 = 123 slot - * - * N.B. index is 0-based; index fields refer to slot index - * except nextindex which refers to entry index in stbl; - * end of entry stot list or freelist is marked with -1. - */ -typedef union { - struct { - s64 next; /* 8: next sibling */ - s64 prev; /* 8: previous sibling */ - - u8 flag; /* 1: */ - s8 nextindex; /* 1: next entry index in stbl */ - s8 freecnt; /* 1: */ - s8 freelist; /* 1: slot index of head of freelist */ - - u8 maxslot; /* 1: number of slots in page slot[] */ - s8 stblindex; /* 1: slot index of start of stbl */ - u8 rsrvd[2]; /* 2: */ - - pxd_t self; /* 8: self pxd */ - } header; /* (32) */ - - dtslot_t slot[128]; -} dtpage_t; - -/* from jfs_xtree.h */ - -/* - * extent allocation descriptor (xad) - */ -typedef struct xad { - unsigned flag:8; /* 1: flag */ - unsigned rsvrd:16; /* 2: reserved */ - unsigned off1:8; /* 1: offset in unit of fsblksize */ - u32 off2; /* 4: offset in unit of fsblksize */ - unsigned len:24; /* 3: length in unit of fsblksize */ - unsigned addr1:8; /* 1: address in unit of fsblksize */ - u32 addr2; /* 4: address in unit of fsblksize */ -} xad_t; /* (16) */ - -/* xad_t field extraction */ -#define offsetXAD(xad) (((s64)((xad)->off1)) << 32 | ((xad)->off2)) -#define addressXAD(xad) (((s64)((xad)->addr1)) << 32 | ((xad)->addr2)) -#define lengthXAD(xad) ((xad)->len) - -/* possible values for maxentry */ -#define XTPAGEMAXSLOT 256 -#define XTENTRYSTART 2 - -/* - * xtree page: - */ -typedef union { - struct xtheader { - s64 next; /* 8: */ - s64 prev; /* 8: */ - - u8 flag; /* 1: */ - u8 rsrvd1; /* 1: */ - s16 nextindex; /* 2: next index = number of entries */ - s16 maxentry; /* 2: max number of entries */ - s16 rsrvd2; /* 2: */ - - pxd_t self; /* 8: self */ - } header; /* (32) */ - - xad_t xad[XTPAGEMAXSLOT]; /* 16 * maxentry: xad array */ -} xtpage_t; - -/* from jfs_dinode.h */ - -struct dinode { - /* - * I. base area (128 bytes) - * ------------------------ - * - * define generic/POSIX attributes - */ - u32 di_inostamp; /* 4: stamp to show inode belongs to fileset */ - s32 di_fileset; /* 4: fileset number */ - u32 di_number; /* 4: inode number, aka file serial number */ - u32 di_gen; /* 4: inode generation number */ - - pxd_t di_ixpxd; /* 8: inode extent descriptor */ - - s64 di_size; /* 8: size */ - s64 di_nblocks; /* 8: number of blocks allocated */ - - u32 di_nlink; /* 4: number of links to the object */ - - u32 di_uid; /* 4: user id of owner */ - u32 di_gid; /* 4: group id of owner */ - - u32 di_mode; /* 4: attribute, format and permission */ - - struct timestruc_t di_atime; /* 8: time last data accessed */ - struct timestruc_t di_ctime; /* 8: time last status changed */ - struct timestruc_t di_mtime; /* 8: time last data modified */ - struct timestruc_t di_otime; /* 8: time created */ - - dxd_t di_acl; /* 16: acl descriptor */ - - dxd_t di_ea; /* 16: ea descriptor */ - - s32 di_next_index; /* 4: Next available dir_table index */ - - s32 di_acltype; /* 4: Type of ACL */ - - /* - * Extension Areas. - * - * Historically, the inode was partitioned into 4 128-byte areas, - * the last 3 being defined as unions which could have multiple - * uses. The first 96 bytes had been completely unused until - * an index table was added to the directory. It is now more - * useful to describe the last 3/4 of the inode as a single - * union. We would probably be better off redesigning the - * entire structure from scratch, but we don't want to break - * commonality with OS/2's JFS at this time. - */ - union { - struct { - /* - * This table contains the information needed to - * find a directory entry from a 32-bit index. - * If the index is small enough, the table is inline, - * otherwise, an x-tree root overlays this table - */ - dir_table_slot_t _table[12]; /* 96: inline */ - - dtroot_t _dtroot; /* 288: dtree root */ - } _dir; /* (384) */ -#define di_dirtable u._dir._table -#define di_dtroot u._dir._dtroot -#define di_parent di_dtroot.header.idotdot -#define di_DASD di_dtroot.header.DASD - - struct { - union { - u8 _data[96]; /* 96: unused */ - struct { - void *_imap; /* 4: unused */ - u32 _gengen; /* 4: generator */ - } _imap; - } _u1; /* 96: */ -#define di_gengen u._file._u1._imap._gengen - - union { - xtpage_t _xtroot; - struct { - u8 unused[16]; /* 16: */ - dxd_t _dxd; /* 16: */ - union { - u32 _rdev; /* 4: */ - u8 _fastsymlink[128]; - } _u; - u8 _inlineea[128]; - } _special; - } _u2; - } _file; -#define di_xtroot u._file._u2._xtroot -#define di_dxd u._file._u2._special._dxd -#define di_btroot di_xtroot -#define di_inlinedata u._file._u2._special._u -#define di_rdev u._file._u2._special._u._rdev -#define di_fastsymlink u._file._u2._special._u._fastsymlink -#define di_inlineea u._file._u2._special._inlineea - } u; -}; - -typedef struct dinode dinode_t; - -/* di_mode */ -#define IFMT 0xF000 /* S_IFMT - mask of file type */ -#define IFDIR 0x4000 /* S_IFDIR - directory */ -#define IFREG 0x8000 /* S_IFREG - regular file */ -#define IFLNK 0xA000 /* S_IFLNK - symbolic link */ - -/* extended mode bits (on-disk inode di_mode) */ -#define INLINEEA 0x00040000 /* inline EA area free */ - -/* from jfs_imap.h */ - -#define EXTSPERIAG 128 /* number of disk inode extent per iag */ -#define SMAPSZ 4 /* number of words per summary map */ -#define MAXAG 128 /* maximum number of allocation groups */ - -/* - * inode allocation map: - * - * inode allocation map consists of - * . the inode map control page and - * . inode allocation group pages (per 4096 inodes) - * which are addressed by standard JFS xtree. - */ -/* - * inode allocation group page (per 4096 inodes of an AG) - */ -typedef struct { - s64 agstart; /* 8: starting block of ag */ - s32 iagnum; /* 4: inode allocation group number */ - s32 inofreefwd; /* 4: ag inode free list forward */ - s32 inofreeback; /* 4: ag inode free list back */ - s32 extfreefwd; /* 4: ag inode extent free list forward */ - s32 extfreeback; /* 4: ag inode extent free list back */ - s32 iagfree; /* 4: iag free list */ - - /* summary map: 1 bit per inode extent */ - s32 inosmap[SMAPSZ]; /* 16: sum map of mapwords w/ free inodes; - * note: this indicates free and backed - * inodes, if the extent is not backed the - * value will be 1. if the extent is - * backed but all inodes are being used the - * value will be 1. if the extent is - * backed but at least one of the inodes is - * free the value will be 0. - */ - s32 extsmap[SMAPSZ]; /* 16: sum map of mapwords w/ free extents */ - s32 nfreeinos; /* 4: number of free inodes */ - s32 nfreeexts; /* 4: number of free extents */ - /* (72) */ - u8 pad[1976]; /* 1976: pad to 2048 bytes */ - /* allocation bit map: 1 bit per inode (0 - free, 1 - allocated) */ - u32 wmap[EXTSPERIAG]; /* 512: working allocation map */ - u32 pmap[EXTSPERIAG]; /* 512: persistent allocation map */ - pxd_t inoext[EXTSPERIAG]; /* 1024: inode extent addresses */ -} iag_t; /* (4096) */ - -#endif /* _JFS_H_ */ diff --git a/src/filo/fs/shared.h b/src/filo/fs/shared.h deleted file mode 100644 index 9f2090b3f..000000000 --- a/src/filo/fs/shared.h +++ /dev/null @@ -1 +0,0 @@ -/* Sorry, nothing is shared here ;) Just for GRUB compatibility. */ diff --git a/src/filo/fs/vfs.c b/src/filo/fs/vfs.c deleted file mode 100644 index 9131bf210..000000000 --- a/src/filo/fs/vfs.c +++ /dev/null @@ -1,193 +0,0 @@ -/* Interface between GRUB's fs drivers and application code */ -#include <lib.h> - -#include "filesys.h" -#include <fs.h> - -#define DEBUG_THIS DEBUG_VFS -#include <debug.h> - -int filepos; -int filemax; -grub_error_t errnum; -void (*disk_read_hook) (int, int, int); -void (*disk_read_func) (int, int, int); -char FSYS_BUF[FSYS_BUFLEN]; -int fsmax; - -struct fsys_entry { - char *name; - int (*mount_func) (void); - int (*read_func) (char *buf, int len); - int (*dir_func) (char *dirname); - void (*close_func) (void); - int (*embed_func) (int *start_sector, int needed_sectors); -}; - -struct fsys_entry fsys_table[] = { -# ifdef FSYS_FAT - {"fat", fat_mount, fat_read, fat_dir, 0, 0}, -# endif -# ifdef FSYS_EXT2FS - {"ext2fs", ext2fs_mount, ext2fs_read, ext2fs_dir, 0, 0}, -# endif -# ifdef FSYS_MINIX - {"minix", minix_mount, minix_read, minix_dir, 0, 0}, -# endif -# ifdef FSYS_REISERFS - {"reiserfs", reiserfs_mount, reiserfs_read, reiserfs_dir, 0, - reiserfs_embed}, -# endif -# ifdef FSYS_JFS - {"jfs", jfs_mount, jfs_read, jfs_dir, 0, jfs_embed}, -# endif -# ifdef FSYS_XFS - {"xfs", xfs_mount, xfs_read, xfs_dir, 0, 0}, -# endif -# ifdef FSYS_ISO9660 - {"iso9660", iso9660_mount, iso9660_read, iso9660_dir, 0, 0}, -# endif -}; - -/* NULLFS is used to read images from raw device */ -static int nullfs_dir(char *name) -{ - uint64_t dev_size; - - if (name) { - debug("can't have a named file\n"); - return 0; - } - - dev_size = (uint64_t) part_length << 9; - /* GRUB code doesn't like 2GB or bigger files */ - if (dev_size > 0x7fffffff) - dev_size = 0x7fffffff; - filemax = dev_size; - return 1; -} - -static int nullfs_read(char *buf, int len) -{ - if (devread(filepos>>9, filepos&0x1ff, len, buf)) { - filepos += len; - return len; - } else - return 0; -} - -static struct fsys_entry nullfs = - {"nullfs", 0, nullfs_read, nullfs_dir, 0, 0}; - -static struct fsys_entry *fsys; - -int mount_fs(void) -{ - int i; - - for (i = 0; i < sizeof(fsys_table)/sizeof(fsys_table[0]); i++) { - if (fsys_table[i].mount_func()) { - fsys = &fsys_table[i]; - printf("Mounted %s\n", fsys->name); - return 1; - } - } - fsys = 0; - printf("Unknown filesystem type\n"); - return 0; -} - -int file_open(const char *filename) -{ - - char dev[32]; -// char *dev=0; - const char *path; - int len; - int retval = 0; - int reopen; - - path = strchr(filename, ':'); - if (path) { - len = path - filename; - path++; - //dev = malloc(len + 1); - memcpy(dev, filename, len); - dev[len] = '\0'; - } else { - /* No colon is given. Is this device or filename? */ - if (filename[0] == '/') { - /* Anything starts with '/' must be a filename */ - // dev = 0; - dev[0]=0; - - path = filename; - } else { - memcpy(dev, filename, 32); -// dev = strdup(filename); - path = 0; - } - } - debug("dev=%s, path=%s\n", dev, path); - - if (dev && dev[0]) { - if (!devopen(dev, &reopen)) { - fsys = 0; - goto out; - } - if (!reopen) - fsys = 0; - } - - if (path) { - if (!fsys || fsys==&nullfs) { - if (!mount_fs()) - goto out; - } - using_devsize = 0; - if (!path[0]) { - printf("No filename is given\n"); - goto out; - } - } else - fsys = &nullfs; - - filepos = 0; - errnum = 0; - if (!fsys->dir_func((char *) path)) { - printf("errnum=%d\n",errnum); -// printf("File not found\n"); - goto out; - } - retval = 1; -out: -// if (dev) -// free(dev); - return retval; -} - -int file_read(void *buf, unsigned long len) -{ - if (filepos < 0 || filepos > filemax) - filepos = filemax; - if (len < 0 || len > filemax-filepos) - len = filemax - filepos; - errnum = 0; - return fsys->read_func(buf, len); -} - -int file_seek(unsigned long offset) -{ - filepos = offset; - return filepos; -} - -unsigned long file_size(void) -{ - return filemax; -} - -void file_close(void) -{ -} - diff --git a/src/filo/fs/xfs.h b/src/filo/fs/xfs.h deleted file mode 100644 index 6a2f8fe0e..000000000 --- a/src/filo/fs/xfs.h +++ /dev/null @@ -1,546 +0,0 @@ -/* xfs.h - an extraction from xfsprogs-1.3.5/include/xfs* into one file */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2000 Silicon Graphics, Inc. All Rights Reserved. - * Copyright (C) 2001 Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - * - * http://www.sgi.com - * - * For further information regarding this notice, see: - * - * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ - */ - -#ifndef _BITS_TYPES_H -typedef signed char __int8_t; -typedef unsigned char __uint8_t; -typedef short __int16_t; -typedef unsigned short __uint16_t; -typedef int __int32_t; -typedef unsigned int __uint32_t; -typedef long long __int64_t; -typedef unsigned long long __uint64_t; -#endif - -typedef __uint64_t xfs_ino_t; -typedef __uint32_t xfs_agino_t; -typedef __int64_t xfs_daddr_t; -typedef __int64_t xfs_off_t; -typedef __uint8_t uuid_t[16]; - - -/* those are from xfs_types.h */ - -typedef __uint32_t xfs_agblock_t; /* blockno in alloc. group */ -typedef __uint32_t xfs_extlen_t; /* extent length in blocks */ -typedef __uint32_t xfs_agnumber_t; /* allocation group number */ -typedef __int32_t xfs_extnum_t; /* # of extents in a file */ -typedef __int16_t xfs_aextnum_t; /* # extents in an attribute fork */ -typedef __int64_t xfs_fsize_t; /* bytes in a file */ - -typedef __uint32_t xfs_dablk_t; /* dir/attr block number (in file) */ -typedef __uint32_t xfs_dahash_t; /* dir/attr hash value */ - -/* - * Disk based types: - */ -typedef __uint64_t xfs_dfsbno_t; /* blockno in filesystem (agno|agbno) */ -typedef __uint64_t xfs_drfsbno_t; /* blockno in filesystem (raw) */ -typedef __uint64_t xfs_drtbno_t; /* extent (block) in realtime area */ -typedef __uint64_t xfs_dfiloff_t; /* block number in a file */ - -typedef __uint64_t xfs_fsblock_t; /* blockno in filesystem (agno|agbno) */ -typedef __uint64_t xfs_fileoff_t; /* block number in a file */ -typedef __uint64_t xfs_filblks_t; /* number of blocks in a file */ - - -/* those are from xfs_sb.h */ - -#define XFS_SB_MAGIC 0x58465342 /* 'XFSB'*/ -#define XFS_SB_VERSION_4 4 /* 6.2+ - bitmask version */ -#define XFS_SB_VERSION_NUMBITS 0x000f - -typedef struct xfs_sb -{ - __uint32_t sb_magicnum; /* magic number == XFS_SB_MAGIC */ - __uint32_t sb_blocksize; /* logical block size, bytes */ - xfs_drfsbno_t sb_dblocks; /* number of data blocks */ - xfs_drfsbno_t sb_rblocks; /* number of realtime blocks */ - xfs_drtbno_t sb_rextents; /* number of realtime extents */ - uuid_t sb_uuid; /* file system unique id */ - xfs_dfsbno_t sb_logstart; /* starting block of log if internal */ - xfs_ino_t sb_rootino; /* root inode number */ - xfs_ino_t sb_rbmino; /* bitmap inode for realtime extents */ - xfs_ino_t sb_rsumino; /* summary inode for rt bitmap */ - xfs_agblock_t sb_rextsize; /* realtime extent size, blocks */ - xfs_agblock_t sb_agblocks; /* size of an allocation group */ - xfs_agnumber_t sb_agcount; /* number of allocation groups */ - xfs_extlen_t sb_rbmblocks; /* number of rt bitmap blocks */ - xfs_extlen_t sb_logblocks; /* number of log blocks */ - __uint16_t sb_versionnum; /* header version == XFS_SB_VERSION */ - __uint16_t sb_sectsize; /* volume sector size, bytes */ - __uint16_t sb_inodesize; /* inode size, bytes */ - __uint16_t sb_inopblock; /* inodes per block */ - char sb_fname[12]; /* file system name */ - __uint8_t sb_blocklog; /* log2 of sb_blocksize */ - __uint8_t sb_sectlog; /* log2 of sb_sectsize */ - __uint8_t sb_inodelog; /* log2 of sb_inodesize */ - __uint8_t sb_inopblog; /* log2 of sb_inopblock */ - __uint8_t sb_agblklog; /* log2 of sb_agblocks (rounded up) */ - __uint8_t sb_rextslog; /* log2 of sb_rextents */ - __uint8_t sb_inprogress; /* mkfs is in progress, don't mount */ - __uint8_t sb_imax_pct; /* max % of fs for inode space */ - /* statistics */ - /* - * These fields must remain contiguous. If you really - * want to change their layout, make sure you fix the - * code in xfs_trans_apply_sb_deltas(). - */ - __uint64_t sb_icount; /* allocated inodes */ - __uint64_t sb_ifree; /* free inodes */ - __uint64_t sb_fdblocks; /* free data blocks */ - __uint64_t sb_frextents; /* free realtime extents */ - /* - * End contiguous fields. - */ - xfs_ino_t sb_uquotino; /* user quota inode */ - xfs_ino_t sb_gquotino; /* group quota inode */ - __uint16_t sb_qflags; /* quota flags */ - __uint8_t sb_flags; /* misc. flags */ - __uint8_t sb_shared_vn; /* shared version number */ - xfs_extlen_t sb_inoalignmt; /* inode chunk alignment, fsblocks */ - __uint32_t sb_unit; /* stripe or raid unit */ - __uint32_t sb_width; /* stripe or raid width */ - __uint8_t sb_dirblklog; /* log2 of dir block size (fsbs) */ - __uint8_t sb_dummy[7]; /* padding */ -} xfs_sb_t; - - -/* those are from xfs_btree.h */ - -/* - * Long form header: bmap btrees. - */ -typedef struct xfs_btree_lblock -{ - __uint32_t bb_magic; /* magic number for block type */ - __uint16_t bb_level; /* 0 is a leaf */ - __uint16_t bb_numrecs; /* current # of data records */ - xfs_dfsbno_t bb_leftsib; /* left sibling block or NULLDFSBNO */ - xfs_dfsbno_t bb_rightsib; /* right sibling block or NULLDFSBNO */ -} xfs_btree_lblock_t; - -/* - * Combined header and structure, used by common code. - */ -typedef struct xfs_btree_hdr -{ - __uint32_t bb_magic; /* magic number for block type */ - __uint16_t bb_level; /* 0 is a leaf */ - __uint16_t bb_numrecs; /* current # of data records */ -} xfs_btree_hdr_t; - -typedef struct xfs_btree_block -{ - xfs_btree_hdr_t bb_h; /* header */ - union { - struct { - xfs_agblock_t bb_leftsib; - xfs_agblock_t bb_rightsib; - } s; /* short form pointers */ - struct { - xfs_dfsbno_t bb_leftsib; - xfs_dfsbno_t bb_rightsib; - } l; /* long form pointers */ - } bb_u; /* rest */ -} xfs_btree_block_t; - -/* those are from xfs_bmap_btree.h */ - -/* - * Bmap root header, on-disk form only. - */ -typedef struct xfs_bmdr_block -{ - __uint16_t bb_level; /* 0 is a leaf */ - __uint16_t bb_numrecs; /* current # of data records */ -} xfs_bmdr_block_t; - -/* - * Bmap btree record and extent descriptor. - * For 32-bit kernels, - * l0:31 is an extent flag (value 1 indicates non-normal). - * l0:0-30 and l1:9-31 are startoff. - * l1:0-8, l2:0-31, and l3:21-31 are startblock. - * l3:0-20 are blockcount. - * For 64-bit kernels, - * l0:63 is an extent flag (value 1 indicates non-normal). - * l0:9-62 are startoff. - * l0:0-8 and l1:21-63 are startblock. - * l1:0-20 are blockcount. - */ - -#define BMBT_USE_64 1 - -typedef struct xfs_bmbt_rec_32 -{ - __uint32_t l0, l1, l2, l3; -} xfs_bmbt_rec_32_t; -typedef struct xfs_bmbt_rec_64 -{ - __uint64_t l0, l1; -} xfs_bmbt_rec_64_t; - -#if BMBT_USE_64 -typedef __uint64_t xfs_bmbt_rec_base_t; /* use this for casts */ -typedef xfs_bmbt_rec_64_t xfs_bmbt_rec_t, xfs_bmdr_rec_t; -#else /* !BMBT_USE_64 */ -typedef __uint32_t xfs_bmbt_rec_base_t; /* use this for casts */ -typedef xfs_bmbt_rec_32_t xfs_bmbt_rec_t, xfs_bmdr_rec_t; -#endif /* BMBT_USE_64 */ - -/* - * Key structure for non-leaf levels of the tree. - */ -typedef struct xfs_bmbt_key -{ - xfs_dfiloff_t br_startoff; /* starting file offset */ -} xfs_bmbt_key_t, xfs_bmdr_key_t; - -typedef xfs_dfsbno_t xfs_bmbt_ptr_t, xfs_bmdr_ptr_t; /* btree pointer type */ - /* btree block header type */ -typedef struct xfs_btree_lblock xfs_bmbt_block_t; - - -/* those are from xfs_dir2.h */ -/* - * Directory version 2. - * There are 4 possible formats: - * shortform - * single block - data with embedded leaf at the end - * multiple data blocks, single leaf+freeindex block - * data blocks, node&leaf blocks (btree), freeindex blocks - * - * The shortform format is in xfs_dir2_sf.h. - * The single block format is in xfs_dir2_block.h. - * The data block format is in xfs_dir2_data.h. - * The leaf and freeindex block formats are in xfs_dir2_leaf.h. - * Node blocks are the same as the other version, in xfs_da_btree.h. - */ - -/* - * Byte offset in data block and shortform entry. - */ -typedef __uint16_t xfs_dir2_data_off_t; - -/* - * Byte offset in a directory. - */ -typedef xfs_off_t xfs_dir2_off_t; - -/* those are from xfs_da_btree.h */ -/*======================================================================== - * Directory Structure when greater than XFS_LBSIZE(mp) bytes. - *========================================================================*/ - -/* - * This structure is common to both leaf nodes and non-leaf nodes in the Btree. - * - * Is is used to manage a doubly linked list of all blocks at the same - * level in the Btree, and to identify which type of block this is. - */ -#define XFS_DIR2_LEAF1_MAGIC 0xd2f1 /* magic number: v2 dirlf single blks */ -#define XFS_DIR2_LEAFN_MAGIC 0xd2ff /* magic number: v2 dirlf multi blks */ - -typedef struct xfs_da_blkinfo { - xfs_dablk_t forw; /* previous block in list */ - xfs_dablk_t back; /* following block in list */ - __uint16_t magic; /* validity check on block */ - __uint16_t pad; /* unused */ -} xfs_da_blkinfo_t; - -/* - * This is the structure of the root and intermediate nodes in the Btree. - * The leaf nodes are defined above. - * - * Entries are not packed. - * - * Since we have duplicate keys, use a binary search but always follow - * all match in the block, not just the first match found. - */ - -typedef struct xfs_da_intnode { - struct xfs_da_node_hdr { /* constant-structure header block */ - xfs_da_blkinfo_t info; /* block type, links, etc. */ - __uint16_t count; /* count of active entries */ - __uint16_t level; /* level above leaves (leaf == 0) */ - } hdr; - struct xfs_da_node_entry { - xfs_dahash_t hashval; /* hash value for this descendant */ - xfs_dablk_t before; /* Btree block before this key */ - } btree[1]; /* variable sized array of keys */ -} xfs_da_intnode_t; - - -/* those are from xfs_dir2_data.h */ -/* - * Directory format 2, data block structures. - */ - -/* - * Constants. - */ -#define XFS_DIR2_DATA_FREE_TAG 0xffff -#define XFS_DIR2_DATA_FD_COUNT 3 - -/* - * Structures. - */ - -/* - * Describe a free area in the data block. - * The freespace will be formatted as a xfs_dir2_data_unused_t. - */ -typedef struct xfs_dir2_data_free { - xfs_dir2_data_off_t offset; /* start of freespace */ - xfs_dir2_data_off_t length; /* length of freespace */ -} xfs_dir2_data_free_t; - -/* - * Header for the data blocks. - * Always at the beginning of a directory-sized block. - * The code knows that XFS_DIR2_DATA_FD_COUNT is 3. - */ -typedef struct xfs_dir2_data_hdr { - __uint32_t magic; /* XFS_DIR2_DATA_MAGIC */ - /* or XFS_DIR2_BLOCK_MAGIC */ - xfs_dir2_data_free_t bestfree[XFS_DIR2_DATA_FD_COUNT]; -} xfs_dir2_data_hdr_t; - -/* - * Active entry in a data block. Aligned to 8 bytes. - * Tag appears as the last 2 bytes. - */ -typedef struct xfs_dir2_data_entry { - xfs_ino_t inumber; /* inode number */ - __uint8_t namelen; /* name length */ - __uint8_t name[1]; /* name bytes, no null */ - /* variable offset */ - xfs_dir2_data_off_t tag; /* starting offset of us */ -} xfs_dir2_data_entry_t; - -/* - * Unused entry in a data block. Aligned to 8 bytes. - * Tag appears as the last 2 bytes. - */ -typedef struct xfs_dir2_data_unused { - __uint16_t freetag; /* XFS_DIR2_DATA_FREE_TAG */ - xfs_dir2_data_off_t length; /* total free length */ - /* variable offset */ - xfs_dir2_data_off_t tag; /* starting offset of us */ -} xfs_dir2_data_unused_t; - -typedef union { - xfs_dir2_data_entry_t entry; - xfs_dir2_data_unused_t unused; -} xfs_dir2_data_union_t; - - -/* those are from xfs_dir2_leaf.h */ -/* - * Directory version 2, leaf block structures. - */ - -/* - * Leaf block header. - */ -typedef struct xfs_dir2_leaf_hdr { - xfs_da_blkinfo_t info; /* header for da routines */ - __uint16_t count; /* count of entries */ - __uint16_t stale; /* count of stale entries */ -} xfs_dir2_leaf_hdr_t; - - -/* those are from xfs_dir2_block.h */ -/* - * xfs_dir2_block.h - * Directory version 2, single block format structures - */ - -/* - * The single block format is as follows: - * xfs_dir2_data_hdr_t structure - * xfs_dir2_data_entry_t and xfs_dir2_data_unused_t structures - * xfs_dir2_leaf_entry_t structures - * xfs_dir2_block_tail_t structure - */ - -#define XFS_DIR2_BLOCK_MAGIC 0x58443242 /* XD2B: for one block dirs */ - -typedef struct xfs_dir2_block_tail { - __uint32_t count; /* count of leaf entries */ - __uint32_t stale; /* count of stale lf entries */ -} xfs_dir2_block_tail_t; - - -/* those are from xfs_dir2_sf.h */ - -/* - * Directory layout when stored internal to an inode. - * - * Small directories are packed as tightly as possible so as to - * fit into the literal area of the inode. - */ - -/* - * Inode number stored as 8 8-bit values. - */ -typedef struct { __uint8_t i[8]; } xfs_dir2_ino8_t; - -/* - * Inode number stored as 4 8-bit values. - * Works a lot of the time, when all the inode numbers in a directory - * fit in 32 bits. - */ -typedef struct { __uint8_t i[4]; } xfs_dir2_ino4_t; - -typedef union { - xfs_dir2_ino8_t i8; - xfs_dir2_ino4_t i4; -} xfs_dir2_inou_t; - -/* - * Normalized offset (in a data block) of the entry, really xfs_dir2_data_off_t. - * Only need 16 bits, this is the byte offset into the single block form. - */ -typedef struct { __uint8_t i[2]; } xfs_dir2_sf_off_t; - -/* - * The parent directory has a dedicated field, and the self-pointer must - * be calculated on the fly. - * - * Entries are packed toward the top as tightly as possible. The header - * and the elements must be bcopy()'d out into a work area to get correct - * alignment for the inode number fields. - */ -typedef struct xfs_dir2_sf_hdr { - __uint8_t count; /* count of entries */ - __uint8_t i8count; /* count of 8-byte inode #s */ - xfs_dir2_inou_t parent; /* parent dir inode number */ -} xfs_dir2_sf_hdr_t; - -typedef struct xfs_dir2_sf_entry { - __uint8_t namelen; /* actual name length */ - xfs_dir2_sf_off_t offset; /* saved offset */ - __uint8_t name[1]; /* name, variable size */ - xfs_dir2_inou_t inumber; /* inode number, var. offset */ -} xfs_dir2_sf_entry_t; - -typedef struct xfs_dir2_sf { - xfs_dir2_sf_hdr_t hdr; /* shortform header */ - xfs_dir2_sf_entry_t list[1]; /* shortform entries */ -} xfs_dir2_sf_t; - -/* those are from xfs_dinode.h */ - -#define XFS_DINODE_VERSION_1 1 -#define XFS_DINODE_VERSION_2 2 -#define XFS_DINODE_MAGIC 0x494e /* 'IN' */ - -/* - * Disk inode structure. - * This is just the header; the inode is expanded to fill a variable size - * with the last field expanding. It is split into the core and "other" - * because we only need the core part in the in-core inode. - */ -typedef struct xfs_timestamp { - __int32_t t_sec; /* timestamp seconds */ - __int32_t t_nsec; /* timestamp nanoseconds */ -} xfs_timestamp_t; - -/* - * Note: Coordinate changes to this structure with the XFS_DI_* #defines - * below and the offsets table in xfs_ialloc_log_di(). - */ -typedef struct xfs_dinode_core -{ - __uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */ - __uint16_t di_mode; /* mode and type of file */ - __int8_t di_version; /* inode version */ - __int8_t di_format; /* format of di_c data */ - __uint16_t di_onlink; /* old number of links to file */ - __uint32_t di_uid; /* owner's user id */ - __uint32_t di_gid; /* owner's group id */ - __uint32_t di_nlink; /* number of links to file */ - __uint16_t di_projid; /* owner's project id */ - __uint8_t di_pad[10]; /* unused, zeroed space */ - xfs_timestamp_t di_atime; /* time last accessed */ - xfs_timestamp_t di_mtime; /* time last modified */ - xfs_timestamp_t di_ctime; /* time created/inode modified */ - xfs_fsize_t di_size; /* number of bytes in file */ - xfs_drfsbno_t di_nblocks; /* # of direct & btree blocks used */ - xfs_extlen_t di_extsize; /* basic/minimum extent size for file */ - xfs_extnum_t di_nextents; /* number of extents in data fork */ - xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/ - __uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */ - __int8_t di_aformat; /* format of attr fork's data */ - __uint32_t di_dmevmask; /* DMIG event mask */ - __uint16_t di_dmstate; /* DMIG state info */ - __uint16_t di_flags; /* random flags, XFS_DIFLAG_... */ - __uint32_t di_gen; /* generation number */ -} xfs_dinode_core_t; - -typedef struct xfs_dinode -{ - xfs_dinode_core_t di_core; - xfs_agino_t di_next_unlinked;/* agi unlinked list ptr */ - union { - xfs_bmdr_block_t di_bmbt; /* btree root block */ - xfs_bmbt_rec_32_t di_bmx[1]; /* extent list */ - xfs_dir2_sf_t di_dir2sf; /* shortform directory v2 */ - char di_c[1]; /* local contents */ - } di_u; -} xfs_dinode_t; - -/* - * Values for di_format - */ -typedef enum xfs_dinode_fmt -{ - XFS_DINODE_FMT_DEV, /* CHR, BLK: di_dev */ - XFS_DINODE_FMT_LOCAL, /* DIR, REG: di_c */ - /* LNK: di_symlink */ - XFS_DINODE_FMT_EXTENTS, /* DIR, REG, LNK: di_bmx */ - XFS_DINODE_FMT_BTREE, /* DIR, REG, LNK: di_bmbt */ - XFS_DINODE_FMT_UUID /* MNT: di_uuid */ -} xfs_dinode_fmt_t; - -/* - * File types (mode field) - */ -#define IFMT 0170000 /* type of file */ -#define IFDIR 0040000 /* directory */ -#define IFREG 0100000 /* regular */ -#define IFLNK 0120000 /* symbolic link */ |
